diff --git a/src/main/scala/db/DatabaseLayer.scala b/src/main/scala/db/DatabaseLayer.scala index d304f84..af32e48 100644 --- a/src/main/scala/db/DatabaseLayer.scala +++ b/src/main/scala/db/DatabaseLayer.scala @@ -8,34 +8,34 @@ import slick.jdbc.JdbcProfile import scala.concurrent.ExecutionContext class DatabaseLayer( - val uac: UACModule, - val exec: ExecutorModule + val uac: UACModule, + val exec: ExecutorModule ) object DatabaseLayer: - def setup( - profile: JdbcProfile, - config_loc: String = "db_conf" - )(implicit ec: ExecutionContext): Future[DatabaseLayer] = - import profile.api._ - val database = Database.forConfig(config_loc) + def setup( + profile: JdbcProfile, + config_loc: String = "db_conf" + )(implicit ec: ExecutionContext): Future[DatabaseLayer] = + import profile.api._ + val database = Database.forConfig(config_loc) - // Construct and initialize modules - val uacModule = UACModule(profile, database) - val uacSetupActions = uacModule.setup + // Construct and initialize modules + val uacModule = UACModule(profile, database) + val uacSetupActions = uacModule.setup - val executorModule = ExecutorModule(profile, database) - val executorSetupOptions = executorModule.setup + val executorModule = ExecutorModule(profile, database) + val executorSetupOptions = executorModule.setup - // Run initialization actions - val initActions = DBIO.seq( - uacSetupActions, - executorSetupOptions - ) + // Run initialization actions + val initActions = DBIO.seq( + uacSetupActions, + executorSetupOptions + ) - database.run(initActions).map(_ => - DatabaseLayer(uacModule, executorModule) - ) + database.run(initActions).map(_ => + DatabaseLayer(uacModule, executorModule) + ) - + diff --git a/src/main/scala/db/modules/DatabaseModule.scala b/src/main/scala/db/modules/DatabaseModule.scala index fd3da75..9c150e5 100644 --- a/src/main/scala/db/modules/DatabaseModule.scala +++ b/src/main/scala/db/modules/DatabaseModule.scala @@ -4,4 +4,4 @@ import slick.dbio.DBIO import slick.jdbc.JdbcProfile trait DatabaseModule: - def setup: DBIO[Unit] + def setup: DBIO[Unit] diff --git a/src/main/scala/db/modules/executor/ExecutorModule.scala b/src/main/scala/db/modules/executor/ExecutorModule.scala index 31caf4e..4056812 100644 --- a/src/main/scala/db/modules/executor/ExecutorModule.scala +++ b/src/main/scala/db/modules/executor/ExecutorModule.scala @@ -5,12 +5,12 @@ import db.modules.DatabaseModule import scala.concurrent.Future class ExecutorModule( - profile: JdbcProfile, - database: profile.backend.Database + profile: JdbcProfile, + database: profile.backend.Database ) extends DatabaseModule: - import profile.api._ + import profile.api._ - def execute[A](query: DBIO[A]): Future[A] = - database.run(query) + def execute[A](query: DBIO[A]): Future[A] = + database.run(query) - def setup: DBIO[Unit] = DBIO.successful(None) \ No newline at end of file + def setup: DBIO[Unit] = DBIO.successful(None) \ No newline at end of file diff --git a/src/main/scala/db/modules/uac/UACAPI.scala b/src/main/scala/db/modules/uac/UACAPI.scala index fe791b0..afa7784 100644 --- a/src/main/scala/db/modules/uac/UACAPI.scala +++ b/src/main/scala/db/modules/uac/UACAPI.scala @@ -9,121 +9,121 @@ import slick.jdbc.JdbcProfile import scala.concurrent.ExecutionContext class UACAPI( - val profile: JdbcProfile, - val queries: UACQueries, - val database: profile.backend.Database + val profile: JdbcProfile, + val queries: UACQueries, + val database: profile.backend.Database ): - import profile.api._ - - def setup: DBIO[Unit] = - DBIO.seq( - (queries.UACBase.schema ++ queries.tokenScopeBase.schema).createIfNotExists - ) + import profile.api._ + + def setup: DBIO[Unit] = + DBIO.seq( + (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.++=( - cred.scopes.map(scope => - queries.schema.UACTokenScope( - uacId, - scope.uid - ) - ) - ) - ) + 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.++=( + cred.scopes.map(scope => + queries.schema.UACTokenScope( + uacId, + scope.uid + ) + ) + ) + ) - 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 - case Some(uac) => - // Construct a query to retrieve relevant scopes - 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 - ) + 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 + case Some(uac) => + // Construct a query to retrieve relevant scopes + 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 + ) - UserAuthenticationCredential( - uac.userId, - uac.accessToken, - uac.refreshToken, - uac.expires, - convertedScopes.toList - ) - ) - ) + UserAuthenticationCredential( + uac.userId, + uac.accessToken, + uac.refreshToken, + uac.expires, + convertedScopes.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 - // ) - // ) + // 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 + // 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 + // if queryResult == None then + // throw Exception - // val scopesQuery = queries.tokenScopeBase.filter( - // _.tokenId === queryResult.accessToken - // ).take(1).result - // ) + // val scopesQuery = queries.tokenScopeBase.filter( + // _.tokenId === queryResult.accessToken + // ).take(1).result + // ) - // action + // action - def delete(user: TwitchUID): Future[Unit] = ??? + def delete(user: TwitchUID): Future[Unit] = ??? - \ No newline at end of file + \ No newline at end of file diff --git a/src/main/scala/db/modules/uac/UACModule.scala b/src/main/scala/db/modules/uac/UACModule.scala index d354fad..d0e2fae 100644 --- a/src/main/scala/db/modules/uac/UACModule.scala +++ b/src/main/scala/db/modules/uac/UACModule.scala @@ -7,12 +7,12 @@ import slick.jdbc.JdbcProfile import slick.dbio.DBIO class UACModule( - val profile: JdbcProfile, - val database: profile.backend.Database + val profile: JdbcProfile, + val database: profile.backend.Database ) extends DatabaseModule: - val schema = UACSchema(profile) - val queries = UACQueries(profile, schema) - val api = UACAPI(profile, queries, database) + val schema = UACSchema(profile) + val queries = UACQueries(profile, schema) + val api = UACAPI(profile, queries, database) - def setup: DBIO[Unit] = - api.setup + def setup: DBIO[Unit] = + api.setup diff --git a/src/main/scala/db/modules/uac/UACQueries.scala b/src/main/scala/db/modules/uac/UACQueries.scala index 49daac5..c67ebcb 100644 --- a/src/main/scala/db/modules/uac/UACQueries.scala +++ b/src/main/scala/db/modules/uac/UACQueries.scala @@ -5,9 +5,9 @@ import db.modules.uac.UACSchema import slick.jdbc.JdbcProfile class UACQueries( - val profile: JdbcProfile, - val schema: UACSchema + val profile: JdbcProfile, + val schema: UACSchema ): - import profile.api._ - val UACBase = schema._uacTable - val tokenScopeBase = schema._uacTokenScopeTable \ No newline at end of file + import profile.api._ + val UACBase = schema._uacTable + val tokenScopeBase = schema._uacTokenScopeTable \ No newline at end of file diff --git a/src/main/scala/db/modules/uac/UACSchema.scala b/src/main/scala/db/modules/uac/UACSchema.scala index 7c76b1c..3e2539c 100644 --- a/src/main/scala/db/modules/uac/UACSchema.scala +++ b/src/main/scala/db/modules/uac/UACSchema.scala @@ -1,19 +1,19 @@ /* - UNIT_CA5 - Stream management bot - Copyright (C) 2024 digimint + UNIT_CA5 - Stream management bot + Copyright (C) 2024 digimint - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ package db.modules.uac @@ -25,64 +25,64 @@ import java.time.Instant import slick.jdbc.JdbcProfile class UACSchema(val profile: JdbcProfile): - import profile.api._ - case class RawUAC( - id: Long = 0, - userId: TwitchUID, - accessToken: AccessToken, - refreshToken: RefreshToken, - expires: Instant - ) + import profile.api._ + case class RawUAC( + id: Long = 0, + userId: TwitchUID, + accessToken: AccessToken, + refreshToken: RefreshToken, + expires: Instant + ) - case class UACTokenScope( - tokenId: Long, - scopeId: Long - ) + case class UACTokenScope( + tokenId: Long, + scopeId: Long + ) - class UACTable(tag: Tag) extends Table[RawUAC](tag, "USER_TOKENS"): - def id = column[Long]("TKN_ID", O.PrimaryKey, O.AutoInc) - def userId = column[TwitchUID]("USER_ID") - def accessToken = column[AccessToken]("ACCESS_TKN") - def refreshToken = column[RefreshToken]("REFRESH_TKN") - def expires = column[Instant]("EXPIRES") + class UACTable(tag: Tag) extends Table[RawUAC](tag, "USER_TOKENS"): + def id = column[Long]("TKN_ID", O.PrimaryKey, O.AutoInc) + def userId = column[TwitchUID]("USER_ID") + def accessToken = column[AccessToken]("ACCESS_TKN") + def refreshToken = column[RefreshToken]("REFRESH_TKN") + def expires = column[Instant]("EXPIRES") - def * = (id, userId, accessToken, refreshToken, expires).mapTo[RawUAC] + def * = (id, userId, accessToken, refreshToken, expires).mapTo[RawUAC] - val _uacTable = TableQuery[UACTable] + val _uacTable = TableQuery[UACTable] - class UACTokenScopeTable(tag: Tag) extends Table[UACTokenScope](tag, "USER_TOKEN_SCOPES"): - def tokenId = column[Long]("TKN_ID") - def scopeId = column[Long]("SCOPE") + class UACTokenScopeTable(tag: Tag) extends Table[UACTokenScope](tag, "USER_TOKEN_SCOPES"): + def tokenId = column[Long]("TKN_ID") + def scopeId = column[Long]("SCOPE") - def token = foreignKey( - "TKN", - tokenId, - _uacTable - )( - _.id, - onDelete=ForeignKeyAction.Cascade - ) + def token = foreignKey( + "TKN", + tokenId, + _uacTable + )( + _.id, + onDelete=ForeignKeyAction.Cascade + ) - def * = (tokenId, scopeId).mapTo[UACTokenScope] + def * = (tokenId, scopeId).mapTo[UACTokenScope] - val _uacTokenScopeTable = TableQuery[UACTokenScopeTable] - // object api: - // def setup: DBIO[Unit] = - // DBIO.seq( - // (queries.UACBase.schema ++ queries.tokenScopeBase.schema).createIfNotExists - // ) + val _uacTokenScopeTable = TableQuery[UACTokenScopeTable] + // object api: + // def setup: DBIO[Unit] = + // DBIO.seq( + // (queries.UACBase.schema ++ queries.tokenScopeBase.schema).createIfNotExists + // ) - // val queryScopesForCredential = - // tokenScopesQuery.join(rawUACs).on(_.tokenId === _.id) - // .groupBy( - // (token, cred) => cred.userId - // ) - // .map( - // (userId, group) => userId -> group.map( - // (scope, user) => scope.scopeId - // ) - // ) - \ No newline at end of file + // val queryScopesForCredential = + // tokenScopesQuery.join(rawUACs).on(_.tokenId === _.id) + // .groupBy( + // (token, cred) => cred.userId + // ) + // .map( + // (userId, group) => userId -> group.map( + // (scope, user) => scope.scopeId + // ) + // ) + \ No newline at end of file diff --git a/src/test/scala/MySuite.scala b/src/test/scala/MySuite.scala index 621784d..29d14e5 100644 --- a/src/test/scala/MySuite.scala +++ b/src/test/scala/MySuite.scala @@ -1,9 +1,9 @@ // For more information on writing tests, see // https://scalameta.org/munit/docs/getting-started.html class MySuite extends munit.FunSuite { - test("example test that succeeds") { - val obtained = 42 - val expected = 42 - assertEquals(obtained, expected) - } + test("example test that succeeds") { + val obtained = 42 + val expected = 42 + assertEquals(obtained, expected) + } }