From 0109b2d87add1efb7c8a3ecd84f212ef3e5a30f6 Mon Sep 17 00:00:00 2001 From: digimint Date: Tue, 25 Jun 2024 00:52:04 -0500 Subject: [PATCH] Refactor database API to use for-comprehensions. --- .../unit_ca5/db/modules/uac/UACAPI.scala | 150 +++++++----------- 1 file changed, 56 insertions(+), 94 deletions(-) diff --git a/src/main/scala/gay/creatures/unit_ca5/db/modules/uac/UACAPI.scala b/src/main/scala/gay/creatures/unit_ca5/db/modules/uac/UACAPI.scala index 7417eec..b85dfb6 100644 --- a/src/main/scala/gay/creatures/unit_ca5/db/modules/uac/UACAPI.scala +++ b/src/main/scala/gay/creatures/unit_ca5/db/modules/uac/UACAPI.scala @@ -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] = ??? \ No newline at end of file