Refactor database API to use for-comprehensions.

This commit is contained in:
digimint 2024-06-25 00:52:04 -05:00
parent 86b247c481
commit 0109b2d87a
Signed by: digimint
GPG key ID: 8DF1C6FD85ABF748

View file

@ -35,113 +35,75 @@ class UACAPI(
def setup: DBIO[Unit] =
DBIO.seq(
(queries.UACBase.schema ++ queries.tokenScopeBase.schema).createIfNotExists
(
queries.UACBase.schema
++ queries.tokenScopeBase.schema
).createIfNotExists
)
def create(cred: UserAuthenticationCredential)(implicit ec: ExecutionContext): DBIO[Option[Int]] =
queries.UACBase.returning(queries.UACBase.map(_.id)).+=(
queries.schema.RawUAC(
0,
cred.userId,
cred.accessToken,
cred.refreshToken,
cred.expires
)
).flatMap(uacId =>
queries.tokenScopeBase.++=(
/**
* Construct a query to add a new UserAuthenticationCredential to the
* database.
*
* @param cred Credential to insert.
* @return A query object. Pass it to `exec.execute()` to run it.
*/
def create(
cred: UserAuthenticationCredential
)(
implicit ec: ExecutionContext
): DBIO[Option[Int]] =
for
// Insert base UAC
base <- queries.UACBase.returning(queries.UACBase.map(_.id)) +=
queries.schema.RawUAC(
0,
cred.userId,
cred.accessToken,
cred.refreshToken,
cred.expires
)
// Insert scopes for UAC
scopes <- queries.tokenScopeBase ++=
cred.scopes.map(scope =>
queries.schema.UACTokenScope(
uacId,
base,
scope.uid
)
)
)
)
yield scopes
def retrieve(user: TwitchUID)(implicit ec: ExecutionContext): DBIO[UserAuthenticationCredential] =
// Construct query for base UAC data
queries.UACBase.filter(
_.userId === user
).take(1)
.result.headOption // Take only the first UAC that matches (there should never be more than one)
.flatMap(res => // With the result of that query:
res match
case None => slick.dbio.FailureAction(NotFoundException()) // Don't attempt to retrieve scopes if there's no matching UAC
def retrieve(
user: TwitchUID
)(
implicit ec: ExecutionContext
): DBIO[UserAuthenticationCredential] =
for
// Query the base UAC
uac <- queries.UACBase.filter(
_.userId === user
).take(1).result.headOption
// Query the scopes (if the base UAC returns)
scopes <- uac match
case None => slick.dbio.FailureAction(NotFoundException())
case Some(uac) =>
// Construct a query to retrieve relevant scopes
queries.tokenScopeBase.filter( scope =>
queries.tokenScopeBase.filter(scope =>
scope.tokenId === uac.id
).result.map(res =>
val convertedScopes = res.map(scope =>
// Convert UIDs to TokenScope enums
TokenScope.fromUid(scope.scopeId)
).filter(mappedScope =>
// Filter any UIDs that didn't match TokenScopes.
mappedScope match
case None => false
case _ => true
).map(convertedScope =>
// Strip the Options.
convertedScope.get
)
).result
UserAuthenticationCredential(
uac.userId,
uac.accessToken,
uac.refreshToken,
uac.expires,
convertedScopes.toList
)
)
yield UserAuthenticationCredential(
uac.get.userId,
uac.get.accessToken,
uac.get.refreshToken,
uac.get.expires,
// n.b. - `flatten` removes scope IDs that don't map properly.
scopes.map(scope =>
TokenScope.fromUid(scope.scopeId)
).flatten.toList
)
// val action = database.run(query).flatMap( res =>
// res match
// case None => Future{None}
// case Some(uac) =>
// // Construct query for
// val scopesQuery = queries.tokenScopeBase.filter( scope =>
// scope.tokenId === uac.id
// ).result.map(res =>
// res.map(scope =>
// // Convert UIDs to TokenScope enums
// TokenScope.fromUid(scope.scopeId)
// ).filter(mappedScope =>
// // Filter any UIDs that didn't match TokenScopes.
// mappedScope match
// case None => false
// case _ => true
// ).map(convertedScope =>
// // Strip the Options.
// convertedScope.get
// )
// )
// database.run(scopesQuery).map(res =>
// UserAuthenticationCredential(
// uac.userId,
// uac.accessToken,
// uac.refreshToken,
// uac.expires,
// res.toList
// )
// )
// )
// .map((res) =>
// val queryResult: Option[queries.schema.RawUAC] =
// if res.length > 0 then Some(res[0]) else None
// if queryResult == None then
// throw Exception
// val scopesQuery = queries.tokenScopeBase.filter(
// _.tokenId === queryResult.accessToken
// ).take(1).result
// )
// action
def delete(user: TwitchUID): Future[Unit] = ???