From 2eda10dfce5c7462c74b86d09906d46a4524c6ed Mon Sep 17 00:00:00 2001 From: Michael Bryzek Date: Tue, 30 Jul 2024 22:21:00 +0200 Subject: [PATCH 01/25] wip --- api/app/util/IdGenerator.scala | 11 ----------- dao/spec/psql-apibuilder.json | 33 ++++++++++++++++++++------------- 2 files changed, 20 insertions(+), 24 deletions(-) delete mode 100644 api/app/util/IdGenerator.scala diff --git a/api/app/util/IdGenerator.scala b/api/app/util/IdGenerator.scala deleted file mode 100644 index 0f2115e5b..000000000 --- a/api/app/util/IdGenerator.scala +++ /dev/null @@ -1,11 +0,0 @@ -package util - -import java.util.UUID - -case class IdGenerator() { - - def randomId(): String = { - UUID.randomUUID().toString - } - -} diff --git a/dao/spec/psql-apibuilder.json b/dao/spec/psql-apibuilder.json index 52708ca52..d6ca4ab45 100644 --- a/dao/spec/psql-apibuilder.json +++ b/dao/spec/psql-apibuilder.json @@ -1,7 +1,26 @@ { "name": "psql-apibuilder", "attributes": [ - { "name": "scala", "value": { "version": "3.4" } } + { + "name": "scala", + "value": { + "version": "3.4", + "package": "db.generated", + "dao_user_class": "java.util.UUID" + } + }, + { + "name": "psql", + "value": { + "pkey": "id", + "hash_code": {}, + "audit": { + "created_at": { "type": "date-time-iso8601" }, + "updated_at": { "type": "date-time-iso8601" }, + "updated_by_user_id": { "type": "string" } + } + } + } ], "models": { @@ -30,19 +49,11 @@ { "name": "scala", "value": { - "package": "db.generated", - "dao_user_class": "java.util.UUID", "id_generator": { "class": "com.mbryzek.util.IdGenerator", "prefix": "gni" } } - }, - { - "name": "psql", - "value": { - "pkey": "id" - } } ] }, @@ -63,16 +74,12 @@ { "name": "scala", "value": { - "package": "db.generated", - "dao_user_class": "java.util.UUID", "order_by": { "optional": true } } }, { "name": "psql", "value": { - "pkey": "id", - "authorization": { "type": "disabled" }, "on_conflict": { "fields": ["type_id", "type"] }, From 23158f73043bf337688035e44803dee8e8715f6a Mon Sep 17 00:00:00 2001 From: Michael Bryzek Date: Tue, 30 Jul 2024 22:23:49 +0200 Subject: [PATCH 02/25] wip --- DEVELOPER.md | 3 +- .../GeneratorApibuilderSessionsDao.scala | 238 ------- ...sqlApibuilderGeneratorInvocationsDao.scala | 329 ---------- .../db/generated/PsqlApibuilderTasksDao.scala | 614 ------------------ .../ApicollectiveApibuilderSpecV0Client.scala | 16 +- .../ApicollectiveApibuilderSpecV0Models.scala | 16 +- script/lib/ask.rb | 30 + script/lib/common.rb | 85 +++ script/lib/tag.rb | 30 + script/{upload => update} | 91 ++- script/update_daos | 65 ++ 11 files changed, 277 insertions(+), 1240 deletions(-) delete mode 100644 api/app/db/generated/GeneratorApibuilderSessionsDao.scala delete mode 100644 api/app/db/generated/PsqlApibuilderGeneratorInvocationsDao.scala delete mode 100644 api/app/db/generated/PsqlApibuilderTasksDao.scala create mode 100644 script/lib/ask.rb create mode 100755 script/lib/common.rb create mode 100644 script/lib/tag.rb rename script/{upload => update} (67%) create mode 100755 script/update_daos diff --git a/DEVELOPER.md b/DEVELOPER.md index 4e3ce7f2e..11bb7fbe1 100644 --- a/DEVELOPER.md +++ b/DEVELOPER.md @@ -43,7 +43,8 @@ In development: Updating apibuilder.me ================== - script/upload + script/update + script/update_daos SBT ========== diff --git a/api/app/db/generated/GeneratorApibuilderSessionsDao.scala b/api/app/db/generated/GeneratorApibuilderSessionsDao.scala deleted file mode 100644 index f6b90ff46..000000000 --- a/api/app/db/generated/GeneratorApibuilderSessionsDao.scala +++ /dev/null @@ -1,238 +0,0 @@ -package db.generated - -import anorm._ -import db.DbHelpers -import io.flow.postgresql.{OrderBy, Query} -import java.sql.Connection -import java.util.UUID -import javax.inject.{Inject, Singleton} -import org.joda.time.DateTime -import play.api.db.{Database, NamedDatabase} - -case class Session( - id: String, - userGuid: UUID, - expiresAt: DateTime, - createdAt: DateTime, - createdByGuid: UUID, - updatedAt: DateTime, - updatedByGuid: UUID, - deletedAt: Option[DateTime], - deletedByGuid: Option[UUID] -) { - - lazy val form: SessionForm = SessionForm( - id = id, - userGuid = userGuid, - expiresAt = expiresAt, - createdAt = createdAt, - createdByGuid = createdByGuid, - updatedAt = updatedAt, - updatedByGuid = updatedByGuid, - deletedAt = deletedAt, - deletedByGuid = deletedByGuid - ) - -} - -case class SessionForm( - id: String, - userGuid: UUID, - expiresAt: DateTime, - createdAt: DateTime, - createdByGuid: UUID, - updatedAt: DateTime, - updatedByGuid: UUID, - deletedAt: Option[DateTime], - deletedByGuid: Option[UUID] -) - -@Singleton -class SessionsDao @Inject() ( - @NamedDatabase("default") db: Database -) { - - private val dbHelpers = DbHelpers(db, "sessions") - - private val BaseQuery = Query(""" - | select sessions.id, - | sessions.user_guid, - | sessions.expires_at, - | sessions.created_at, - | sessions.created_by_guid, - | sessions.updated_at, - | sessions.updated_by_guid, - | sessions.deleted_at, - | sessions.deleted_by_guid, - | sessions.hash_code - | from sessions - """.stripMargin) - - private val InsertQuery = Query(""" - | insert into sessions - | (id, user_guid, expires_at, created_at, created_by_guid, updated_at, updated_by_guid, deleted_at, deleted_by_guid, hash_code) - | values - | ({id}, {user_guid}::uuid, {expires_at}::timestamptz, {created_at}::timestamptz, {created_by_guid}::uuid, {updated_at}::timestamptz, {updated_by_guid}::uuid, {deleted_at}::timestamptz, {deleted_by_guid}::uuid, {hash_code}::bigint) - """.stripMargin) - - private val UpdateQuery = Query(""" - | update sessions - | set user_guid = {user_guid}::uuid, - | expires_at = {expires_at}::timestamptz, - | created_at = {created_at}::timestamptz, - | created_by_guid = {created_by_guid}::uuid, - | updated_at = {updated_at}::timestamptz, - | updated_by_guid = {updated_by_guid}::uuid, - | deleted_at = {deleted_at}::timestamptz, - | deleted_by_guid = {deleted_by_guid}::uuid, - | hash_code = {hash_code}::bigint - | where id = {id} - | and (sessions.hash_code is null or sessions.hash_code != {hash_code}::bigint) - """.stripMargin) - - private def bindQuery(query: Query, form: SessionForm): Query = { - query. - bind("user_guid", form.userGuid). - bind("expires_at", form.expiresAt). - bind("created_at", form.createdAt). - bind("created_by_guid", form.createdByGuid). - bind("updated_at", form.updatedAt). - bind("updated_by_guid", form.updatedByGuid). - bind("deleted_at", form.deletedAt). - bind("deleted_by_guid", form.deletedByGuid). - bind("hash_code", form.hashCode()) - } - - def insert(updatedBy: UUID, form: SessionForm): Unit = { - db.withConnection { implicit c => - insert(c, updatedBy, form) - } - } - - def insert(implicit c: Connection, updatedBy: UUID, form: SessionForm): Unit = { - bindQuery(InsertQuery, form). - bind("id", form.id). - anormSql().execute() - } - - def updateIfChangedById(updatedBy: UUID, id: String, form: SessionForm): Unit ={ - if (!findById(id).map(_.form).contains(form)) { - updateById(updatedBy, id, form) - } - } - - def updateById(updatedBy: UUID, id: String, form: SessionForm): Unit = { - db.withConnection { implicit c => - updateById(c, updatedBy, id, form) - } - } - - def updateById(implicit c: Connection, updatedBy: UUID, id: String, form: SessionForm): Unit = { - bindQuery(UpdateQuery, form). - bind("id", id). - anormSql().execute() - } - - def update(updatedBy: UUID, existing: Session, form: SessionForm): Unit = { - db.withConnection { implicit c => - update(c, updatedBy, existing, form) - } - } - - def update(implicit c: Connection, updatedBy: UUID, existing: Session, form: SessionForm): Unit = { - updateById(c, updatedBy, existing.id, form) - } - - def delete(deletedBy: UUID, session: Session): Unit = { - dbHelpers.delete(deletedBy, session.id) - } - - def deleteById(deletedBy: UUID, id: String): Unit = { - db.withConnection { implicit c => - deleteById(c, deletedBy, id) - } - } - - def deleteById(c: java.sql.Connection, deletedBy: UUID, id: String): Unit = { - dbHelpers.delete(c, deletedBy, id) - } - - def findById(id: String): Option[Session] = { - db.withConnection { implicit c => - findByIdWithConnection(c, id) - } - } - - def findByIdWithConnection(c: java.sql.Connection, id: String): Option[Session] = { - findAllWithConnection(c, ids = Some(Seq(id)), limit = 1).headOption - } - - def findAll( - ids: Option[Seq[String]] = None, - userGuid: Option[UUID] = None, - limit: Long, - offset: Long = 0, - orderBy: OrderBy = OrderBy("sessions.id") - ) ( - implicit customQueryModifier: Query => Query = { q => q } - ): Seq[Session] = { - db.withConnection { implicit c => - findAllWithConnection( - c, - ids = ids, - userGuid = userGuid, - limit = limit, - offset = offset, - orderBy = orderBy - )(customQueryModifier) - } - } - - def findAllWithConnection( - c: java.sql.Connection, - ids: Option[Seq[String]] = None, - userGuid: Option[UUID] = None, - limit: Long, - offset: Long = 0, - orderBy: OrderBy = OrderBy("sessions.id") - ) ( - implicit customQueryModifier: Query => Query = { q => q } - ): Seq[Session] = { - customQueryModifier(BaseQuery). - optionalIn("sessions.id", ids). - equals("sessions.user_guid", userGuid). - limit(limit). - offset(offset). - orderBy(orderBy.sql). - as(SessionsDao.parser().*)(c) - } - -} - -object SessionsDao { - - def parser(): RowParser[Session] = { - SqlParser.str("id") ~ - SqlParser.get[UUID]("user_guid") ~ - SqlParser.get[DateTime]("expires_at") ~ - SqlParser.get[DateTime]("created_at") ~ - SqlParser.get[UUID]("created_by_guid") ~ - SqlParser.get[DateTime]("updated_at") ~ - SqlParser.get[UUID]("updated_by_guid") ~ - SqlParser.get[DateTime]("deleted_at").? ~ - SqlParser.get[UUID]("deleted_by_guid").? map { - case id ~ userGuid ~ expiresAt ~ createdAt ~ createdByGuid ~ updatedAt ~ updatedByGuid ~ deletedAt ~ deletedByGuid => Session( - id = id, - userGuid = userGuid, - expiresAt = expiresAt, - createdAt = createdAt, - createdByGuid = createdByGuid, - updatedAt = updatedAt, - updatedByGuid = updatedByGuid, - deletedAt = deletedAt, - deletedByGuid = deletedByGuid - ) - } - } - -} \ No newline at end of file diff --git a/api/app/db/generated/PsqlApibuilderGeneratorInvocationsDao.scala b/api/app/db/generated/PsqlApibuilderGeneratorInvocationsDao.scala deleted file mode 100644 index 4d813e176..000000000 --- a/api/app/db/generated/PsqlApibuilderGeneratorInvocationsDao.scala +++ /dev/null @@ -1,329 +0,0 @@ -package db.generated - -import anorm._ -import com.mbryzek.util.IdGenerator -import io.flow.postgresql.{OrderBy, Query} -import java.sql.Connection -import java.util.UUID -import javax.inject.{Inject, Singleton} -import org.joda.time.DateTime -import play.api.db.Database - -case class GeneratorInvocation( - id: String, - key: String, - organizationKey: Option[String], - applicationKey: Option[String], - updatedByGuid: String, - createdAt: DateTime, - updatedAt: DateTime -) { - - lazy val form: GeneratorInvocationForm = GeneratorInvocationForm( - key = key, - organizationKey = organizationKey, - applicationKey = applicationKey - ) - -} - -case class GeneratorInvocationForm( - key: String, - organizationKey: Option[String], - applicationKey: Option[String] -) - -object GeneratorInvocationsTable { - val Schema: String = "public" - val Name: String = "generator_invocations" - val QualifiedName: String = s"$Schema.$Name" - - object Columns { - val Id: String = "id" - val Key: String = "key" - val OrganizationKey: String = "organization_key" - val ApplicationKey: String = "application_key" - val UpdatedByGuid: String = "updated_by_guid" - val CreatedAt: String = "created_at" - val UpdatedAt: String = "updated_at" - val HashCode: String = "hash_code" - val all: List[String] = List(Id, Key, OrganizationKey, ApplicationKey, UpdatedByGuid, CreatedAt, UpdatedAt, HashCode) - } -} - -trait BaseGeneratorInvocationsDao { - - def db: Database - - private val BaseQuery = Query(""" - | select generator_invocations.id, - | generator_invocations.key, - | generator_invocations.organization_key, - | generator_invocations.application_key, - | generator_invocations.updated_by_guid, - | generator_invocations.created_at, - | generator_invocations.updated_at, - | generator_invocations.hash_code - | from generator_invocations - """.stripMargin) - - def findById(id: String): Option[GeneratorInvocation] = { - db.withConnection { c => - findByIdWithConnection(c, id) - } - } - - def findByIdWithConnection(c: java.sql.Connection, id: String): Option[GeneratorInvocation] = { - findAllWithConnection(c, ids = Some(Seq(id)), limit = Some(1L)).headOption - } - - def iterateAll( - ids: Option[Seq[String]] = None, - pageSize: Long = 2000L, - ) ( - implicit customQueryModifier: Query => Query = { q => q } - ): Iterator[GeneratorInvocation] = { - def iterate(lastValue: Option[GeneratorInvocation]): Iterator[GeneratorInvocation] = { - val page = findAll( - ids = ids, - limit = Some(pageSize), - orderBy = OrderBy("generator_invocations.id"), - ) { q => customQueryModifier(q).greaterThan("generator_invocations.id", lastValue.map(_.id)) } - - page.lastOption match { - case None => Iterator.empty - case lastValue => page.iterator ++ iterate(lastValue) - } - } - - iterate(None) - } - - def findAll( - ids: Option[Seq[String]] = None, - limit: Option[Long], - offset: Long = 0, - orderBy: OrderBy = OrderBy("generator_invocations.id") - ) ( - implicit customQueryModifier: Query => Query = { q => q } - ): Seq[GeneratorInvocation] = { - db.withConnection { c => - findAllWithConnection( - c, - ids = ids, - limit = limit, - offset = offset, - orderBy = orderBy - )(customQueryModifier) - } - } - - def findAllWithConnection( - c: java.sql.Connection, - ids: Option[Seq[String]] = None, - limit: Option[Long], - offset: Long = 0, - orderBy: OrderBy = OrderBy("generator_invocations.id") - ) ( - implicit customQueryModifier: Query => Query = { q => q } - ): Seq[GeneratorInvocation] = { - customQueryModifier(BaseQuery). - optionalIn("generator_invocations.id", ids). - optionalLimit(limit). - offset(offset). - orderBy(orderBy.sql). - as(GeneratorInvocationsDao.parser.*)(c) - } - -} - -object GeneratorInvocationsDao { - - val parser: RowParser[GeneratorInvocation] = { - SqlParser.str("id") ~ - SqlParser.str("key") ~ - SqlParser.str("organization_key").? ~ - SqlParser.str("application_key").? ~ - SqlParser.str("updated_by_guid") ~ - SqlParser.get[DateTime]("created_at") ~ - SqlParser.get[DateTime]("updated_at") map { - case id ~ key ~ organizationKey ~ applicationKey ~ updatedByGuid ~ createdAt ~ updatedAt => GeneratorInvocation( - id = id, - key = key, - organizationKey = organizationKey, - applicationKey = applicationKey, - updatedByGuid = updatedByGuid, - createdAt = createdAt, - updatedAt = updatedAt - ) - } - } - -} - -@Singleton -class GeneratorInvocationsDao @Inject() ( - override val db: Database -) extends BaseGeneratorInvocationsDao { - - private val idGenerator = com.mbryzek.util.IdGenerator("gni") - - def randomId(): String = idGenerator.randomId() - - private val InsertQuery = Query(""" - | insert into generator_invocations - | (id, key, organization_key, application_key, updated_by_guid, hash_code) - | values - | ({id}, {key}, {organization_key}, {application_key}, {updated_by_guid}, {hash_code}::bigint) - """.stripMargin) - - private val UpdateQuery = Query(""" - | update generator_invocations - | set key = {key}, - | organization_key = {organization_key}, - | application_key = {application_key}, - | updated_by_guid = {updated_by_guid}, - | hash_code = {hash_code}::bigint - | where id = {id} - | and generator_invocations.hash_code != {hash_code}::bigint - """.stripMargin) - - private def bindQuery(query: Query, form: GeneratorInvocationForm): Query = { - query. - bind("key", form.key). - bind("organization_key", form.organizationKey). - bind("application_key", form.applicationKey). - bind("hash_code", form.hashCode()) - } - - private def toNamedParameter(updatedBy: UUID, id: String, form: GeneratorInvocationForm): Seq[NamedParameter] = { - Seq( - "id" -> id, - "key" -> form.key, - "organization_key" -> form.organizationKey, - "application_key" -> form.applicationKey, - "updated_by_guid" -> updatedBy, - "hash_code" -> form.hashCode() - ) - } - - def insert(updatedBy: UUID, form: GeneratorInvocationForm): String = { - db.withConnection { c => - insert(c, updatedBy, form) - } - } - - def insert(c: Connection, updatedBy: UUID, form: GeneratorInvocationForm): String = { - val id = randomId() - bindQuery(InsertQuery, form). - bind("id", id). - bind("updated_by_guid", updatedBy). - anormSql().execute()(c) - id - } - - def insertBatch(updatedBy: UUID, forms: Seq[GeneratorInvocationForm]): Seq[String] = { - db.withConnection { c => - insertBatchWithConnection(c, updatedBy, forms) - } - } - - def insertBatchWithConnection(c: Connection, updatedBy: UUID, forms: Seq[GeneratorInvocationForm]): Seq[String] = { - if (forms.nonEmpty) { - val ids = forms.map(_ => randomId()) - val params = ids.zip(forms).map { case (id, form) => toNamedParameter(updatedBy, id, form) } - BatchSql(InsertQuery.sql(), params.head, params.tail*).execute()(c) - ids - } else { - Nil - } - } - - def updateIfChangedById(updatedBy: UUID, id: String, form: GeneratorInvocationForm): Unit = { - if (!findById(id).map(_.form).contains(form)) { - updateById(updatedBy, id, form) - } - } - - def updateById(updatedBy: UUID, id: String, form: GeneratorInvocationForm): Unit = { - db.withConnection { c => - updateById(c, updatedBy, id, form) - } - } - - def updateById(c: Connection, updatedBy: UUID, id: String, form: GeneratorInvocationForm): Unit = { - bindQuery(UpdateQuery, form). - bind("id", id). - bind("updated_by_guid", updatedBy). - anormSql().execute()(c) - () - } - - def update(updatedBy: UUID, existing: GeneratorInvocation, form: GeneratorInvocationForm): Unit = { - db.withConnection { c => - update(c, updatedBy, existing, form) - } - } - - def update(c: Connection, updatedBy: UUID, existing: GeneratorInvocation, form: GeneratorInvocationForm): Unit = { - updateById(c, updatedBy, existing.id, form) - } - - def updateBatch(updatedBy: UUID, idsAndForms: Seq[(String, GeneratorInvocationForm)]): Unit = { - db.withConnection { c => - updateBatchWithConnection(c, updatedBy, idsAndForms) - } - } - - def updateBatchWithConnection(c: Connection, updatedBy: UUID, idsAndForms: Seq[(String, GeneratorInvocationForm)]): Unit = { - if (idsAndForms.nonEmpty) { - val params = idsAndForms.map { case (id, form) => toNamedParameter(updatedBy, id, form) } - BatchSql(UpdateQuery.sql(), params.head, params.tail*).execute()(c) - () - } - } - - def delete(deletedBy: UUID, generatorInvocation: GeneratorInvocation): Unit = { - db.withConnection { c => - delete(c, deletedBy, generatorInvocation) - } - } - - def delete(c: Connection, deletedBy: UUID, generatorInvocation: GeneratorInvocation): Unit = { - deleteById(c, deletedBy, generatorInvocation.id) - } - - def deleteById(deletedBy: UUID, id: String): Unit = { - db.withConnection { c => - deleteById(c, deletedBy, id) - } - } - - def deleteById(c: Connection, deletedBy: UUID, id: String): Unit = { - setJournalDeletedByUserId(c, deletedBy) - Query("delete from generator_invocations") - .equals("id", id) - .anormSql().executeUpdate()(c) - () - } - - def deleteAllByIds(deletedBy: UUID, ids: Seq[String]): Unit = { - db.withConnection { c => - deleteAllByIds(c, deletedBy, ids) - } - } - - def deleteAllByIds(c: Connection, deletedBy: UUID, ids: Seq[String]): Unit = { - setJournalDeletedByUserId(c, deletedBy) - Query("delete from generator_invocations") - .in("id", ids) - .anormSql().executeUpdate()(c) - () - } - - def setJournalDeletedByUserId(c: Connection, deletedBy: UUID): Unit = { - Query(s"SET journal.deleted_by_user_id = '${deletedBy}'").anormSql().executeUpdate()(c) - () - } - -} \ No newline at end of file diff --git a/api/app/db/generated/PsqlApibuilderTasksDao.scala b/api/app/db/generated/PsqlApibuilderTasksDao.scala deleted file mode 100644 index e3f31c7c2..000000000 --- a/api/app/db/generated/PsqlApibuilderTasksDao.scala +++ /dev/null @@ -1,614 +0,0 @@ -package db.generated - -import anorm.JodaParameterMetaData._ -import anorm._ -import io.flow.postgresql.{OrderBy, Query} -import java.sql.Connection -import java.util.UUID -import javax.inject.{Inject, Singleton} -import org.joda.time.DateTime -import play.api.db.Database -import play.api.libs.json.{JsValue, Json} - -case class Task( - id: String, - `type`: String, - typeId: String, - organizationGuid: Option[UUID], - numAttempts: Int, - nextAttemptAt: DateTime, - errors: Option[Seq[String]], - stacktrace: Option[String], - data: JsValue, - updatedByGuid: String, - createdAt: DateTime, - updatedAt: DateTime -) { - - lazy val form: TaskForm = TaskForm( - id = id, - `type` = `type`, - typeId = typeId, - organizationGuid = organizationGuid, - numAttempts = numAttempts, - nextAttemptAt = nextAttemptAt, - errors = errors, - stacktrace = stacktrace, - data = data - ) - -} - -case class TaskForm( - id: String, - `type`: String, - typeId: String, - organizationGuid: Option[UUID], - numAttempts: Int, - nextAttemptAt: DateTime, - errors: Option[Seq[String]], - stacktrace: Option[String], - data: JsValue -) - -object TasksTable { - val Schema: String = "public" - val Name: String = "tasks" - val QualifiedName: String = s"$Schema.$Name" - - object Columns { - val Id: String = "id" - val Type: String = "type" - val TypeId: String = "type_id" - val OrganizationGuid: String = "organization_guid" - val NumAttempts: String = "num_attempts" - val NextAttemptAt: String = "next_attempt_at" - val Errors: String = "errors" - val Stacktrace: String = "stacktrace" - val Data: String = "data" - val UpdatedByGuid: String = "updated_by_guid" - val CreatedAt: String = "created_at" - val UpdatedAt: String = "updated_at" - val HashCode: String = "hash_code" - val all: List[String] = List(Id, Type, TypeId, OrganizationGuid, NumAttempts, NextAttemptAt, Errors, Stacktrace, Data, UpdatedByGuid, CreatedAt, UpdatedAt, HashCode) - } -} - -trait BaseTasksDao { - - def db: Database - - private val BaseQuery = Query(""" - | select tasks.id, - | tasks.type, - | tasks.type_id, - | tasks.organization_guid, - | tasks.num_attempts, - | tasks.next_attempt_at, - | tasks.errors::text as errors_text, - | tasks.stacktrace, - | tasks.data::text as data_text, - | tasks.updated_by_guid, - | tasks.created_at, - | tasks.updated_at, - | tasks.hash_code - | from tasks - """.stripMargin) - - def findById(id: String): Option[Task] = { - db.withConnection { c => - findByIdWithConnection(c, id) - } - } - - def findByIdWithConnection(c: java.sql.Connection, id: String): Option[Task] = { - findAllWithConnection(c, ids = Some(Seq(id)), limit = Some(1L), orderBy = None).headOption - } - - def findByTypeIdAndType(typeId: String, `type`: String): Option[Task] = { - db.withConnection { c => - findByTypeIdAndTypeWithConnection(c, typeId, `type`) - } - } - - def findByTypeIdAndTypeWithConnection(c: java.sql.Connection, typeId: String, `type`: String): Option[Task] = { - findAllWithConnection(c, typeId = Some(typeId), `type` = Some(`type`), limit = Some(1L), orderBy = None).headOption - } - - def iterateAll( - ids: Option[Seq[String]] = None, - typeId: Option[String] = None, - typeIds: Option[Seq[String]] = None, - `type`: Option[String] = None, - types: Option[Seq[String]] = None, - numAttempts: Option[Int] = None, - numAttemptsGreaterThanOrEquals: Option[Int] = None, - numAttemptsGreaterThan: Option[Int] = None, - numAttemptsLessThanOrEquals: Option[Int] = None, - numAttemptsLessThan: Option[Int] = None, - nextAttemptAt: Option[DateTime] = None, - nextAttemptAtGreaterThanOrEquals: Option[DateTime] = None, - nextAttemptAtGreaterThan: Option[DateTime] = None, - nextAttemptAtLessThanOrEquals: Option[DateTime] = None, - nextAttemptAtLessThan: Option[DateTime] = None, - numAttemptsNextAttemptAts: Option[Seq[(Int, DateTime)]] = None, - typeIdTypes: Option[Seq[(String, String)]] = None, - pageSize: Long = 2000L, - ) ( - implicit customQueryModifier: Query => Query = { q => q } - ): Iterator[Task] = { - def iterate(lastValue: Option[Task]): Iterator[Task] = { - val page = findAll( - ids = ids, - typeId = typeId, - typeIds = typeIds, - `type` = `type`, - types = types, - numAttempts = numAttempts, - numAttemptsGreaterThanOrEquals = numAttemptsGreaterThanOrEquals, - numAttemptsGreaterThan = numAttemptsGreaterThan, - numAttemptsLessThanOrEquals = numAttemptsLessThanOrEquals, - numAttemptsLessThan = numAttemptsLessThan, - nextAttemptAt = nextAttemptAt, - nextAttemptAtGreaterThanOrEquals = nextAttemptAtGreaterThanOrEquals, - nextAttemptAtGreaterThan = nextAttemptAtGreaterThan, - nextAttemptAtLessThanOrEquals = nextAttemptAtLessThanOrEquals, - nextAttemptAtLessThan = nextAttemptAtLessThan, - numAttemptsNextAttemptAts = numAttemptsNextAttemptAts, - typeIdTypes = typeIdTypes, - limit = Some(pageSize), - orderBy = Some(OrderBy("tasks.id")), - ) { q => customQueryModifier(q).greaterThan("tasks.id", lastValue.map(_.id)) } - - page.lastOption match { - case None => Iterator.empty - case lastValue => page.iterator ++ iterate(lastValue) - } - } - - iterate(None) - } - - def findAll( - ids: Option[Seq[String]] = None, - typeId: Option[String] = None, - typeIds: Option[Seq[String]] = None, - `type`: Option[String] = None, - types: Option[Seq[String]] = None, - numAttempts: Option[Int] = None, - numAttemptsGreaterThanOrEquals: Option[Int] = None, - numAttemptsGreaterThan: Option[Int] = None, - numAttemptsLessThanOrEquals: Option[Int] = None, - numAttemptsLessThan: Option[Int] = None, - nextAttemptAt: Option[DateTime] = None, - nextAttemptAtGreaterThanOrEquals: Option[DateTime] = None, - nextAttemptAtGreaterThan: Option[DateTime] = None, - nextAttemptAtLessThanOrEquals: Option[DateTime] = None, - nextAttemptAtLessThan: Option[DateTime] = None, - numAttemptsNextAttemptAts: Option[Seq[(Int, DateTime)]] = None, - typeIdTypes: Option[Seq[(String, String)]] = None, - limit: Option[Long], - offset: Long = 0, - orderBy: Option[OrderBy] = Some(OrderBy("tasks.id")) - ) ( - implicit customQueryModifier: Query => Query = { q => q } - ): Seq[Task] = { - db.withConnection { c => - findAllWithConnection( - c, - ids = ids, - typeId = typeId, - typeIds = typeIds, - `type` = `type`, - types = types, - numAttempts = numAttempts, - numAttemptsGreaterThanOrEquals = numAttemptsGreaterThanOrEquals, - numAttemptsGreaterThan = numAttemptsGreaterThan, - numAttemptsLessThanOrEquals = numAttemptsLessThanOrEquals, - numAttemptsLessThan = numAttemptsLessThan, - nextAttemptAt = nextAttemptAt, - nextAttemptAtGreaterThanOrEquals = nextAttemptAtGreaterThanOrEquals, - nextAttemptAtGreaterThan = nextAttemptAtGreaterThan, - nextAttemptAtLessThanOrEquals = nextAttemptAtLessThanOrEquals, - nextAttemptAtLessThan = nextAttemptAtLessThan, - numAttemptsNextAttemptAts = numAttemptsNextAttemptAts, - typeIdTypes = typeIdTypes, - limit = limit, - offset = offset, - orderBy = orderBy - )(customQueryModifier) - } - } - - def findAllWithConnection( - c: java.sql.Connection, - ids: Option[Seq[String]] = None, - typeId: Option[String] = None, - typeIds: Option[Seq[String]] = None, - `type`: Option[String] = None, - types: Option[Seq[String]] = None, - numAttempts: Option[Int] = None, - numAttemptsGreaterThanOrEquals: Option[Int] = None, - numAttemptsGreaterThan: Option[Int] = None, - numAttemptsLessThanOrEquals: Option[Int] = None, - numAttemptsLessThan: Option[Int] = None, - nextAttemptAt: Option[DateTime] = None, - nextAttemptAtGreaterThanOrEquals: Option[DateTime] = None, - nextAttemptAtGreaterThan: Option[DateTime] = None, - nextAttemptAtLessThanOrEquals: Option[DateTime] = None, - nextAttemptAtLessThan: Option[DateTime] = None, - numAttemptsNextAttemptAts: Option[Seq[(Int, DateTime)]] = None, - typeIdTypes: Option[Seq[(String, String)]] = None, - limit: Option[Long], - offset: Long = 0, - orderBy: Option[OrderBy] = Some(OrderBy("tasks.id")) - ) ( - implicit customQueryModifier: Query => Query = { q => q } - ): Seq[Task] = { - customQueryModifier(BaseQuery). - optionalIn("tasks.id", ids). - equals("tasks.type_id", typeId). - optionalIn("tasks.type_id", typeIds). - equals("tasks.type", `type`). - optionalIn("tasks.type", types). - equals("tasks.num_attempts", numAttempts). - greaterThanOrEquals("tasks.num_attempts", numAttemptsGreaterThanOrEquals). - greaterThan("tasks.num_attempts", numAttemptsGreaterThan). - lessThanOrEquals("tasks.num_attempts", numAttemptsLessThanOrEquals). - lessThan("tasks.num_attempts", numAttemptsLessThan). - equals("tasks.next_attempt_at", nextAttemptAt). - greaterThanOrEquals("tasks.next_attempt_at", nextAttemptAtGreaterThanOrEquals). - greaterThan("tasks.next_attempt_at", nextAttemptAtGreaterThan). - lessThanOrEquals("tasks.next_attempt_at", nextAttemptAtLessThanOrEquals). - lessThan("tasks.next_attempt_at", nextAttemptAtLessThan). - optionalIn2(("tasks.num_attempts", "tasks.next_attempt_at"), numAttemptsNextAttemptAts). - optionalIn2(("tasks.type_id", "tasks.type"), typeIdTypes). - optionalLimit(limit). - offset(offset). - orderBy(orderBy.flatMap(_.sql)). - as(TasksDao.parser.*)(c) - } - -} - -object TasksDao { - - val parser: RowParser[Task] = { - SqlParser.str("id") ~ - SqlParser.str("type") ~ - SqlParser.str("type_id") ~ - SqlParser.get[UUID]("organization_guid").? ~ - SqlParser.int("num_attempts") ~ - SqlParser.get[DateTime]("next_attempt_at") ~ - SqlParser.str("errors_text").? ~ - SqlParser.str("stacktrace").? ~ - SqlParser.str("data_text") ~ - SqlParser.str("updated_by_guid") ~ - SqlParser.get[DateTime]("created_at") ~ - SqlParser.get[DateTime]("updated_at") map { - case id ~ type_ ~ typeId ~ organizationGuid ~ numAttempts ~ nextAttemptAt ~ errors ~ stacktrace ~ data ~ updatedByGuid ~ createdAt ~ updatedAt => Task( - id = id, - `type` = type_, - typeId = typeId, - organizationGuid = organizationGuid, - numAttempts = numAttempts, - nextAttemptAt = nextAttemptAt, - errors = errors.map { text => Json.parse(text).as[Seq[String]] }, - stacktrace = stacktrace, - data = Json.parse(data), - updatedByGuid = updatedByGuid, - createdAt = createdAt, - updatedAt = updatedAt - ) - } - } - -} - -@Singleton -class TasksDao @Inject() ( - override val db: Database -) extends BaseTasksDao { - - private val UpsertQuery = Query(""" - | insert into tasks - | (id, type, type_id, organization_guid, num_attempts, next_attempt_at, errors, stacktrace, data, updated_by_guid, hash_code) - | values - | ({id}, {type}, {type_id}, {organization_guid}::uuid, {num_attempts}::int, {next_attempt_at}::timestamptz, {errors}::json, {stacktrace}, {data}::json, {updated_by_guid}, {hash_code}::bigint) - | on conflict (type_id, type) - | do update - | set organization_guid = {organization_guid}::uuid, - | num_attempts = {num_attempts}::int, - | next_attempt_at = {next_attempt_at}::timestamptz, - | errors = {errors}::json, - | stacktrace = {stacktrace}, - | data = {data}::json, - | updated_by_guid = {updated_by_guid}, - | hash_code = {hash_code}::bigint - | where tasks.hash_code != {hash_code}::bigint - | returning id - """.stripMargin) - - private val UpdateQuery = Query(""" - | update tasks - | set type = {type}, - | type_id = {type_id}, - | organization_guid = {organization_guid}::uuid, - | num_attempts = {num_attempts}::int, - | next_attempt_at = {next_attempt_at}::timestamptz, - | errors = {errors}::json, - | stacktrace = {stacktrace}, - | data = {data}::json, - | updated_by_guid = {updated_by_guid}, - | hash_code = {hash_code}::bigint - | where id = {id} - | and tasks.hash_code != {hash_code}::bigint - """.stripMargin) - - private def bindQuery(query: Query, form: TaskForm): Query = { - query. - bind("type", form.`type`). - bind("type_id", form.typeId). - bind("organization_guid", form.organizationGuid). - bind("num_attempts", form.numAttempts). - bind("next_attempt_at", form.nextAttemptAt). - bind("errors", form.errors.map { v => Json.toJson(v) }). - bind("stacktrace", form.stacktrace). - bind("data", form.data). - bind("hash_code", form.hashCode()) - } - - private def toNamedParameter(updatedBy: UUID, form: TaskForm): Seq[NamedParameter] = { - Seq( - "id" -> form.id, - "type" -> form.`type`, - "type_id" -> form.typeId, - "organization_guid" -> form.organizationGuid, - "num_attempts" -> form.numAttempts, - "next_attempt_at" -> form.nextAttemptAt, - "errors" -> form.errors.map { v => Json.toJson(v).toString }, - "stacktrace" -> form.stacktrace, - "data" -> form.data.toString, - "updated_by_guid" -> updatedBy, - "hash_code" -> form.hashCode() - ) - } - - def upsertIfChangedByTypeIdAndType(updatedBy: UUID, form: TaskForm): Unit = { - if (!findByTypeIdAndType(form.typeId, form.`type`).map(_.form).contains(form)) { - upsertByTypeIdAndType(updatedBy, form) - } - } - - def upsertByTypeIdAndType(updatedBy: UUID, form: TaskForm): Unit = { - db.withConnection { c => - upsertByTypeIdAndType(c, updatedBy, form) - } - } - - def upsertByTypeIdAndType(c: Connection, updatedBy: UUID, form: TaskForm): Unit = { - bindQuery(UpsertQuery, form). - bind("id", form.id). - bind("updated_by_guid", updatedBy). - anormSql().execute()(c) - () - } - - def upsertBatchByTypeIdAndType(updatedBy: UUID, forms: Seq[TaskForm]): Unit = { - db.withConnection { c => - upsertBatchByTypeIdAndType(c, updatedBy, forms) - } - } - - def upsertBatchByTypeIdAndType(c: Connection, updatedBy: UUID, forms: Seq[TaskForm]): Unit = { - if (forms.nonEmpty) { - val params = forms.map(toNamedParameter(updatedBy, _)) - BatchSql(UpsertQuery.sql(), params.head, params.tail*).execute()(c) - () - } - } - - def updateIfChangedById(updatedBy: UUID, id: String, form: TaskForm): Unit = { - if (!findById(id).map(_.form).contains(form)) { - updateById(updatedBy, id, form) - } - } - - def updateById(updatedBy: UUID, id: String, form: TaskForm): Unit = { - db.withConnection { c => - updateById(c, updatedBy, id, form) - } - } - - def updateById(c: Connection, updatedBy: UUID, id: String, form: TaskForm): Unit = { - bindQuery(UpdateQuery, form). - bind("id", id). - bind("updated_by_guid", updatedBy). - anormSql().execute()(c) - () - } - - def update(updatedBy: UUID, existing: Task, form: TaskForm): Unit = { - db.withConnection { c => - update(c, updatedBy, existing, form) - } - } - - def update(c: Connection, updatedBy: UUID, existing: Task, form: TaskForm): Unit = { - updateById(c, updatedBy, existing.id, form) - } - - def updateBatch(updatedBy: UUID, forms: Seq[TaskForm]): Unit = { - db.withConnection { c => - updateBatchWithConnection(c, updatedBy, forms) - } - } - - def updateBatchWithConnection(c: Connection, updatedBy: UUID, forms: Seq[TaskForm]): Unit = { - if (forms.nonEmpty) { - val params = forms.map(toNamedParameter(updatedBy, _)) - BatchSql(UpdateQuery.sql(), params.head, params.tail*).execute()(c) - () - } - } - - def delete(deletedBy: UUID, task: Task): Unit = { - db.withConnection { c => - delete(c, deletedBy, task) - } - } - - def delete(c: Connection, deletedBy: UUID, task: Task): Unit = { - deleteById(c, deletedBy, task.id) - } - - def deleteById(deletedBy: UUID, id: String): Unit = { - db.withConnection { c => - deleteById(c, deletedBy, id) - } - } - - def deleteById(c: Connection, deletedBy: UUID, id: String): Unit = { - setJournalDeletedByUserId(c, deletedBy) - Query("delete from tasks") - .equals("id", id) - .anormSql().executeUpdate()(c) - () - } - - def deleteAllByIds(deletedBy: UUID, ids: Seq[String]): Unit = { - db.withConnection { c => - deleteAllByIds(c, deletedBy, ids) - } - } - - def deleteAllByIds(c: Connection, deletedBy: UUID, ids: Seq[String]): Unit = { - setJournalDeletedByUserId(c, deletedBy) - Query("delete from tasks") - .in("id", ids) - .anormSql().executeUpdate()(c) - () - } - - def deleteAllByNumAttempts(deletedBy: UUID, numAttempts: Int): Unit = { - db.withConnection { c => - deleteAllByNumAttempts(c, deletedBy, numAttempts) - } - } - - def deleteAllByNumAttempts(c: Connection, deletedBy: UUID, numAttempts: Int): Unit = { - setJournalDeletedByUserId(c, deletedBy) - Query("delete from tasks") - .equals("num_attempts", numAttempts) - .anormSql().executeUpdate()(c) - () - } - - def deleteAllByNumAttemptses(deletedBy: UUID, numAttemptses: Seq[Int]): Unit = { - db.withConnection { c => - deleteAllByNumAttemptses(c, deletedBy, numAttemptses) - } - } - - def deleteAllByNumAttemptses(c: Connection, deletedBy: UUID, numAttemptses: Seq[Int]): Unit = { - setJournalDeletedByUserId(c, deletedBy) - Query("delete from tasks") - .in("num_attempts", numAttemptses) - .anormSql().executeUpdate()(c) - () - } - - def deleteAllByNumAttemptsAndNextAttemptAt(deletedBy: UUID, numAttempts: Int, nextAttemptAt: DateTime): Unit = { - db.withConnection { c => - deleteAllByNumAttemptsAndNextAttemptAt(c, deletedBy, numAttempts, nextAttemptAt) - } - } - - def deleteAllByNumAttemptsAndNextAttemptAt(c: Connection, deletedBy: UUID, numAttempts: Int, nextAttemptAt: DateTime): Unit = { - setJournalDeletedByUserId(c, deletedBy) - Query("delete from tasks") - .equals("num_attempts", numAttempts) - .equals("next_attempt_at", nextAttemptAt) - .anormSql().executeUpdate()(c) - () - } - - def deleteAllByNumAttemptsAndNextAttemptAts(deletedBy: UUID, numAttempts: Int, nextAttemptAts: Seq[DateTime]): Unit = { - db.withConnection { c => - deleteAllByNumAttemptsAndNextAttemptAts(c, deletedBy, numAttempts, nextAttemptAts) - } - } - - def deleteAllByNumAttemptsAndNextAttemptAts(c: Connection, deletedBy: UUID, numAttempts: Int, nextAttemptAts: Seq[DateTime]): Unit = { - setJournalDeletedByUserId(c, deletedBy) - Query("delete from tasks") - .equals("num_attempts", numAttempts) - .in("next_attempt_at", nextAttemptAts) - .anormSql().executeUpdate()(c) - () - } - - def deleteAllByTypeId(deletedBy: UUID, typeId: String): Unit = { - db.withConnection { c => - deleteAllByTypeId(c, deletedBy, typeId) - } - } - - def deleteAllByTypeId(c: Connection, deletedBy: UUID, typeId: String): Unit = { - setJournalDeletedByUserId(c, deletedBy) - Query("delete from tasks") - .equals("type_id", typeId) - .anormSql().executeUpdate()(c) - () - } - - def deleteAllByTypeIds(deletedBy: UUID, typeIds: Seq[String]): Unit = { - db.withConnection { c => - deleteAllByTypeIds(c, deletedBy, typeIds) - } - } - - def deleteAllByTypeIds(c: Connection, deletedBy: UUID, typeIds: Seq[String]): Unit = { - setJournalDeletedByUserId(c, deletedBy) - Query("delete from tasks") - .in("type_id", typeIds) - .anormSql().executeUpdate()(c) - () - } - - def deleteByTypeIdAndType(deletedBy: UUID, typeId: String, `type`: String): Unit = { - db.withConnection { c => - deleteByTypeIdAndType(c, deletedBy, typeId, `type`) - } - } - - def deleteByTypeIdAndType(c: Connection, deletedBy: UUID, typeId: String, `type`: String): Unit = { - setJournalDeletedByUserId(c, deletedBy) - Query("delete from tasks") - .equals("type_id", typeId) - .equals("type", `type`) - .anormSql().executeUpdate()(c) - () - } - - def deleteAllByTypeIdAndTypes(deletedBy: UUID, typeId: String, types: Seq[String]): Unit = { - db.withConnection { c => - deleteAllByTypeIdAndTypes(c, deletedBy, typeId, types) - } - } - - def deleteAllByTypeIdAndTypes(c: Connection, deletedBy: UUID, typeId: String, types: Seq[String]): Unit = { - setJournalDeletedByUserId(c, deletedBy) - Query("delete from tasks") - .equals("type_id", typeId) - .in("type", types) - .anormSql().executeUpdate()(c) - () - } - - def setJournalDeletedByUserId(c: Connection, deletedBy: UUID): Unit = { - Query(s"SET journal.deleted_by_user_id = '${deletedBy}'").anormSql().executeUpdate()(c) - () - } - -} \ No newline at end of file diff --git a/generated/app/ApicollectiveApibuilderSpecV0Client.scala b/generated/app/ApicollectiveApibuilderSpecV0Client.scala index 461b713fa..a38a4435e 100644 --- a/generated/app/ApicollectiveApibuilderSpecV0Client.scala +++ b/generated/app/ApicollectiveApibuilderSpecV0Client.scala @@ -1,7 +1,7 @@ /** * Generated by API Builder - https://www.apibuilder.io * Service version: 0.16.53 - * User agent: apibuilder app.apibuilder.io/apicollective/apibuilder-spec/latest/play_2_9_scala_3_client + * User agent: apibuilder localhost 9000/apicollective/apibuilder-spec/latest/play_2_9_scala_3_client */ package io.apibuilder.spec.v0.models { @@ -1416,7 +1416,17 @@ package io.apibuilder.spec.v0.models { obj match { case x: io.apibuilder.spec.v0.models.ResponseCodeInt => play.api.libs.json.Json.obj("integer" -> play.api.libs.json.Json.obj("value" -> play.api.libs.json.JsNumber(x.value))) case x: io.apibuilder.spec.v0.models.ResponseCodeOption => play.api.libs.json.Json.obj("response_code_option" -> play.api.libs.json.JsString(x.toString)) - case x: io.apibuilder.spec.v0.models.ResponseCodeUndefinedType => sys.error(s"The type[io.apibuilder.spec.v0.models.ResponseCodeUndefinedType] should never be serialized") + case x: io.apibuilder.spec.v0.models.ResponseCodeUndefinedType => { + scala.util.Try { + // If we received a JSON object - echo it back. This is a workaround for a bug in + // serialization for unions w/out discriminators where they sometimes have the + // type wrapper and sometimes do not + play.api.libs.json.Json.parse(x.description).asInstanceOf[play.api.libs.json.JsObject] + } match { + case scala.util.Success(o) => o + case scala.util.Failure(_) => sys.error("The type[io.apibuilder.spec.v0.models.ResponseCodeUndefinedType] should never be serialized") + } + } } } @@ -1564,7 +1574,7 @@ package io.apibuilder.spec.v0 { object Constants { val Namespace = "io.apibuilder.spec.v0" - val UserAgent = "apibuilder app.apibuilder.io/apicollective/apibuilder-spec/latest/play_2_9_scala_3_client" + val UserAgent = "apibuilder localhost 9000/apicollective/apibuilder-spec/latest/play_2_9_scala_3_client" val Version = "0.16.53" val VersionMajor = 0 diff --git a/lib/src/main/scala/generated/ApicollectiveApibuilderSpecV0Models.scala b/lib/src/main/scala/generated/ApicollectiveApibuilderSpecV0Models.scala index 36564f7fb..c6f32fb6a 100644 --- a/lib/src/main/scala/generated/ApicollectiveApibuilderSpecV0Models.scala +++ b/lib/src/main/scala/generated/ApicollectiveApibuilderSpecV0Models.scala @@ -1,7 +1,7 @@ /** * Generated by API Builder - https://www.apibuilder.io - * Service version: 0.16.50 - * User agent: apibuilder app.apibuilder.io/apicollective/apibuilder-spec/latest/play_2_x_standalone_json + * Service version: 0.16.53 + * User agent: apibuilder localhost 9000/apicollective/apibuilder-spec/latest/play_2_x_standalone_json */ package io.apibuilder.spec.v0.models { @@ -1403,7 +1403,17 @@ package io.apibuilder.spec.v0.models { obj match { case x: io.apibuilder.spec.v0.models.ResponseCodeInt => play.api.libs.json.Json.obj("integer" -> play.api.libs.json.Json.obj("value" -> play.api.libs.json.JsNumber(x.value))) case x: io.apibuilder.spec.v0.models.ResponseCodeOption => play.api.libs.json.Json.obj("response_code_option" -> play.api.libs.json.JsString(x.toString)) - case x: io.apibuilder.spec.v0.models.ResponseCodeUndefinedType => sys.error(s"The type[io.apibuilder.spec.v0.models.ResponseCodeUndefinedType] should never be serialized") + case x: io.apibuilder.spec.v0.models.ResponseCodeUndefinedType => { + scala.util.Try { + // If we received a JSON object - echo it back. This is a workaround for a bug in + // serialization for unions w/out discriminators where they sometimes have the + // type wrapper and sometimes do not + play.api.libs.json.Json.parse(x.description).asInstanceOf[play.api.libs.json.JsObject] + } match { + case scala.util.Success(o) => o + case scala.util.Failure(_) => sys.error("The type[io.apibuilder.spec.v0.models.ResponseCodeUndefinedType] should never be serialized") + } + } } } implicit def jsonWritesApibuilderSpecResponseCode: play.api.libs.json.Writes[ResponseCode] = { diff --git a/script/lib/ask.rb b/script/lib/ask.rb new file mode 100644 index 000000000..d4f832c04 --- /dev/null +++ b/script/lib/ask.rb @@ -0,0 +1,30 @@ +class Ask + + TRUE = ['y', 'yes'] + FALSE = ['n', 'no'] + + def Ask.for_string(msg) + value = "" + while value.empty? + puts msg + value = STDIN.gets + value.strip! + end + value + end + + def Ask.for_boolean(msg) + result = nil + while result.nil? + value = Ask.for_string(msg).downcase + if TRUE.include?(value) + result = true + elsif FALSE.include?(value) + result = false + end + end + result + end + +end + diff --git a/script/lib/common.rb b/script/lib/common.rb new file mode 100755 index 000000000..1288bc265 --- /dev/null +++ b/script/lib/common.rb @@ -0,0 +1,85 @@ +Dir.glob("#{File.dirname(__FILE__)}/*.rb") + .select { |f| File.basename(f) != "common.rb" } + .each { |f| load f } + +class Verbosity + + attr_reader :enabled + + def initialize + @enabled = false + end + + def set(value) + @enabled = value ? true : false + end +end + +VERBOSITY = Verbosity.new unless defined?(VERBOSITY) + +def err(msg) + puts "" + puts "ERROR" + puts " " + msg + puts "" + exit(1) +end + +def run(cmd) + puts "==> #{cmd}" if VERBOSITY.enabled + if !system(cmd) + err("Command failed: #{cmd}") + end +end + +def assert_installed(cmd, url) + if !system("which %s > /dev/null" % cmd) + err("Please install %s: %s" % [cmd, url]) + end +end + +def assert_sem_installed + assert_installed("sem-info", "https://github.com/mbryzek/schema-evolution-manager") +end + + +def args_from_stdin(opts={}) + arrays = opts.delete(:arrays) || [] + flags = opts.delete(:flags) || [] + flags << ":v" + if !opts.empty? + err("Unexpected options: #{opts.keys}") + end + + args = {} + + i = 0 + while i < ARGV.length + name = ARGV[i].to_s.strip.sub(/^\-\-/, '').to_sym + i+=1 + if name + if flags.include?(name) + args[name] = true + else + value = ARGV[i] + i+=1 + if arrays.include?(name) + args[name] ||= [] + args[name] << value + elsif args[name] + err("Argument '#{name}' specified more than once") + elsif value.start_with?("--") + err("Argument '#{name}' missing value") + else + args[name] = value + end + end + end + end + + if args[:v] + VERBOSITY.set(args[:v]) + end + + args +end diff --git a/script/lib/tag.rb b/script/lib/tag.rb new file mode 100644 index 000000000..d342f9eec --- /dev/null +++ b/script/lib/tag.rb @@ -0,0 +1,30 @@ +class Tag + def Tag.ask + assert_sem_installed + + next_standard_tag = `sem-info tag next`.strip + next_tag = replace_hundreds(next_standard_tag) + puts "" + if Ask.for_boolean("Create new tag #{next_tag}?") + run("git tag -a -m #{next_tag} #{next_tag}") + run("git push --tags origin") + end + + `sem-info tag latest`.strip + end + + def Tag.replace_hundreds(tag) + parts = tag.split('.', 3) + if parts.length == 3 && parts.all? { |p| p.to_i.to_s == p } + if parts[2].to_i >= 100 + Tag.replace_hundreds("%s.%s.%s" % [parts[0], parts[1].to_i + 1, 0]) + elsif parts[1].to_i >= 100 + Tag.replace_hundreds("%s.%s.%s" % [parts[0] + 1, 0, 0]) + else + tag + end + else + tag + end + end +end diff --git a/script/upload b/script/update similarity index 67% rename from script/upload rename to script/update index 34305743f..8c76a0627 100755 --- a/script/upload +++ b/script/update @@ -12,7 +12,7 @@ # # Upload specific specifications # -# upload --spec organization --spec user +# upload --app organization --app user # # Upload a specific tag # @@ -30,31 +30,22 @@ # # upload --dir examples # +# Skip apibuilder update +# +# upload --no_download +# + +load File.join(File.dirname(__FILE__), "lib/common.rb") require 'pathname' require 'json' ORGANIZATION = "apicollective" -args = {} -ARGV.each_slice(2) { |pair| - key = pair[0].to_s.sub(/^\-\-/, '').to_sym - value = pair[1].to_s.strip - if args[key] - args[key] << value - elsif key == :spec - args[key] = [value] - else - args[key] = value - end -} +args = args_from_stdin(:arrays => [:app], :flags => [:no_download]) -def assert_installed(cmd, url) - if !system("which %s > /dev/null" % cmd) - puts "** ERROR: Please install %s: %s" % [cmd, url] - exit(1) - end -end +assert_installed("apibuilder", "https://github.com/apicollective/apibuilder-cli") +assert_installed("sem-info", "https://github.com/mbryzek/schema-evolution-manager") def calculate_next_tag assert_installed("sem-info", "https://github.com/mbryzek/schema-evolution-manager") @@ -66,16 +57,10 @@ end # # @param remaining List of Spec instances def resolve_dependencies(remaining, ordered=[]) - if remaining.empty? - ordered - elsif next_spec = remaining.find { |spec| resolved?(ordered, spec) } + if next_spec = remaining.find { |spec| resolved?(ordered, spec) } resolve_dependencies(remaining - [next_spec], ordered + [next_spec]) else - puts "** ERROR: Could not resolve dependencies. Remaining specifications are:" - remaining.each do |spec| - puts " - %s/%s" % [spec.organization, spec.application] - end - exit(1) + ordered + remaining end end @@ -92,11 +77,8 @@ def resolved?(specs, spec) } end -assert_installed("apibuilder", "https://github.com/apicollective/apibuilder-cli") - tag = args[:tag] || calculate_next_tag -dir = args[:dir] || 'spec' -spec_dir = Pathname.new(File.join(File.dirname(__FILE__), "/../#{dir}")).cleanpath +spec_dir = args[:dir] || Pathname.new(File.join(File.dirname(__FILE__), "/../spec")).cleanpath class Dependency @@ -112,7 +94,7 @@ class Dependency elsif md = uri.match(/^https?:\/\/www.apibuilder.io\/([^\/]+)\/([^\/]+)/) Dependency.new(md[1], md[2]) else - raise "Could not parse import uri[%s]" % uri + err("Could not parse import uri[%s]" % uri) end end @@ -141,7 +123,7 @@ class Spec (json['imports'] || []).map { |imp| Dependency.from_uri(imp['uri']) } end - def command(tag, profile=nil) + def upload_command(tag, profile=nil) cmds = [] if profile cmds << "PROFILE=%s" % profile @@ -149,7 +131,16 @@ class Spec cmds << "apibuilder upload %s %s %s --version %s" % [ORGANIZATION, @application, @path, tag] cmds.join(" ") end - + + def download_command(profile=nil) + cmds = [] + if profile + cmds << "PROFILE=%s" % profile + end + cmds << "apibuilder update --app %s" % @application + cmds.join(" ") + end + end specs = Dir.glob("#{spec_dir}/*.json").map do |path| @@ -158,31 +149,27 @@ specs = Dir.glob("#{spec_dir}/*.json").map do |path| end ordered = resolve_dependencies(specs.sort_by { |s| [s.organization, s.application] }) +filtered = args[:app].nil? ? ordered : ordered.select { |spec| args[:app].include?(spec.application) } -filtered = args[:spec].nil? ? ordered : ordered.select { |spec| args[:spec].include?(spec.application) } - -if args[:spec] && filtered.size != args[:spec].size - missing = args[:spec].select { |n| !filtered.map(&:application).include?(n) } +if args[:app] && filtered.size != args[:app].size + missing = args[:app].select { |n| !filtered.map(&:application).include?(n) } if missing.size == 1 - puts "** ERROR: Did not find spec: %s" % missing.join(", ") + msg = "** ERROR: Did not find spec: %s\n" % missing.join(", ") else - puts "** ERROR: Did not find specs: %s" % missing.join(", ") + msg = "** ERROR: Did not find specs: %s\n" % missing.join(", ") end - puts " Available specs: " - puts " " + specs.map(&:application).join("\n ") - puts "" - exit(1) + msg << " Available specs:\n" + msg << " " + specs.map(&:application).join("\n ") + err(msg) end filtered.each do |spec| - command = spec.command(tag, args[:profile]) - puts command - if !system(command) - puts "" - puts "** ERROR: Exiting as last command failed" - exit(1) - end - puts "" + run(spec.upload_command(tag, args[:profile])) end +if !args[:no_download] + filtered.each do |spec| + run(spec.download_command(args[:profile])) + end +end diff --git a/script/update_daos b/script/update_daos new file mode 100755 index 000000000..d5061f076 --- /dev/null +++ b/script/update_daos @@ -0,0 +1,65 @@ +#!/usr/bin/env ruby + +require 'pathname' + +load File.join(File.dirname(__FILE__), "lib/common.rb") + +args = args_from_stdin(:arrays => [:app], :flags => [:no_download]) + +ORGANIZATION = "apicollective" + +def path_from_root(path) + Pathname.new(File.join(File.dirname(__FILE__), "../#{path}")).cleanpath.to_s +end + +UPDATE_SCRIPT = path_from_root("script/update") +DAO_SPEC_DIR = path_from_root("dao/spec") + +def upload(args, apps) + cmd = "#{UPDATE_SCRIPT} --dir #{DAO_SPEC_DIR} --no_download" + if profile = args[:profile] + cmd << " --profile #{profile}" + end + apps.each do |app| + cmd << " --app #{app}" + end + + run cmd +end + +def download(apps, profile=nil) + apps.each do |app| + cmd = "apibuilder code #{ORGANIZATION} #{app} latest psql_scala ./generated/app/db" + if profile + cmd = "PROFILE=#{profile} #{cmd}" + end + puts cmd + run cmd + end +end + +apps = Dir.glob("#{DAO_SPEC_DIR}/*.json").map do |path| + File.basename(path).sub(/\.json$/, '') +end + +if apps.empty? + err("Did not find any .json files in #{DAO_SPEC_DIR}") +end + +filtered = if args[:app] + args[:app].each do |name| + a = apps.find { |a| a == name } + if a.nil? + err("Application '#{name}' not found in #{DAO_SPEC_DIR}") + end + end + args[:app].uniq + else + apps + end + +upload(args, filtered) + +if !args[:no_download] + download(filtered, args[:profile]) +end From b25af7a50f65a3d0b387db7d9533947cdfb8d26f Mon Sep 17 00:00:00 2001 From: Michael Bryzek Date: Tue, 30 Jul 2024 22:24:00 +0200 Subject: [PATCH 03/25] wip --- .../app/db/GeneratorInvocationsDao.scala | 431 ++++++++++ generated/app/db/TasksDao.scala | 739 ++++++++++++++++++ 2 files changed, 1170 insertions(+) create mode 100644 generated/app/db/GeneratorInvocationsDao.scala create mode 100644 generated/app/db/TasksDao.scala diff --git a/generated/app/db/GeneratorInvocationsDao.scala b/generated/app/db/GeneratorInvocationsDao.scala new file mode 100644 index 000000000..8c8f3d5c6 --- /dev/null +++ b/generated/app/db/GeneratorInvocationsDao.scala @@ -0,0 +1,431 @@ +package db.generated + +case class GeneratorInvocation( + id: String, + key: String, + organizationKey: Option[String], + applicationKey: Option[String], + createdAt: org.joda.time.DateTime, + updatedAt: org.joda.time.DateTime, + updatedByUserId: String +) { + def form: GeneratorInvocationForm = { + GeneratorInvocationForm( + key = key, + organizationKey = organizationKey, + applicationKey = applicationKey, + ) + } +} + +case class GeneratorInvocationForm( + key: String, + organizationKey: Option[String], + applicationKey: Option[String] +) + +case object GeneratorInvocationsTable { + val SchemaName: String = "public" + + val TableName: String = "generator_invocations" + + val QualifiedName: String = "public.generator_invocations" + + sealed trait Column { + def name: String + } + + object Columns { + case object Id extends Column { + override val name: String = "id" + } + + case object Key extends Column { + override val name: String = "key" + } + + case object OrganizationKey extends Column { + override val name: String = "organization_key" + } + + case object ApplicationKey extends Column { + override val name: String = "application_key" + } + + case object CreatedAt extends Column { + override val name: String = "created_at" + } + + case object UpdatedAt extends Column { + override val name: String = "updated_at" + } + + case object UpdatedByUserId extends Column { + override val name: String = "updated_by_user_id" + } + + case object HashCode extends Column { + override val name: String = "hash_code" + } + + val all: List[Column] = List(Id, Key, OrganizationKey, ApplicationKey, CreatedAt, UpdatedAt, UpdatedByUserId, HashCode) + } +} + +trait BaseGeneratorInvocationsDao { + import anorm.* + + import anorm.JodaParameterMetaData.* + + import anorm.postgresql.* + + def db: play.api.db.Database + + private val BaseQuery: io.flow.postgresql.Query = { + io.flow.postgresql.Query(""" + | select id, + | key, + | organization_key, + | application_key, + | created_at, + | updated_at, + | updated_by_user_id, + | hash_code + | from public.generator_invocations + |""".stripMargin.stripTrailing + ) + } + + def findAll( + id: Option[String] = None, + ids: Option[Seq[String]] = None, + limit: Option[Long], + offset: Long = 0, + orderBy: Option[io.flow.postgresql.OrderBy] = None + )(implicit customQueryModifier: io.flow.postgresql.Query => io.flow.postgresql.Query = identity): Seq[GeneratorInvocation] = { + db.withConnection { c => + findAllWithConnection(c, id, ids, limit, offset, orderBy) + } + } + + def findAllWithConnection( + c: java.sql.Connection, + id: Option[String] = None, + ids: Option[Seq[String]] = None, + limit: Option[Long], + offset: Long = 0, + orderBy: Option[io.flow.postgresql.OrderBy] = None + )(implicit customQueryModifier: io.flow.postgresql.Query => io.flow.postgresql.Query = identity): Seq[GeneratorInvocation] = { + customQueryModifier(BaseQuery) + .equals("generator_invocations.id", id) + .optionalIn("generator_invocations.id", ids) + .optionalLimit(limit) + .offset(offset) + .orderBy(orderBy.flatMap(_.sql)) + .as(parser.*)(c) + } + + def iterateAll( + id: Option[String] = None, + ids: Option[Seq[String]] = None, + pageSize: Long = 1000 + )(implicit customQueryModifier: io.flow.postgresql.Query => io.flow.postgresql.Query = identity): Iterator[GeneratorInvocation] = { + assert(pageSize > 0, "pageSize must be > 0") + + def iterate(lastValue: Option[GeneratorInvocation]): Iterator[GeneratorInvocation] = { + val page: Seq[GeneratorInvocation] = db.withConnection { c => + customQueryModifier(BaseQuery) + .equals("generator_invocations.id", id) + .optionalIn("generator_invocations.id", ids) + .greaterThan("generator_invocations.id", lastValue.map(_.id)) + .orderBy("generator_invocations.id") + .limit(pageSize) + .as(parser.*)(c) + } + if (page.length >= pageSize) { + page.iterator ++ iterate(page.lastOption) + } else { + page.iterator + } + } + + iterate(None) + } + + def findById(id: String): Option[GeneratorInvocation] = { + db.withConnection { c => + findByIdWithConnection(c, id) + } + } + + def findByIdWithConnection( + c: java.sql.Connection, + id: String + ): Option[GeneratorInvocation] = { + findAllWithConnection( + c = c, + id = Some(id), + limit = Some(1) + ).headOption + } + + private val parser: anorm.RowParser[GeneratorInvocation] = { + anorm.SqlParser.str("id") ~ + anorm.SqlParser.str("key") ~ + anorm.SqlParser.str("organization_key").? ~ + anorm.SqlParser.str("application_key").? ~ + anorm.SqlParser.get[org.joda.time.DateTime]("created_at") ~ + anorm.SqlParser.get[org.joda.time.DateTime]("updated_at") ~ + anorm.SqlParser.str("updated_by_user_id") ~ + anorm.SqlParser.long("hash_code") map { case id ~ key ~ organizationKey ~ applicationKey ~ createdAt ~ updatedAt ~ updatedByUserId ~ hashCode => + GeneratorInvocation( + id = id, + key = key, + organizationKey = organizationKey, + applicationKey = applicationKey, + createdAt = createdAt, + updatedAt = updatedAt, + updatedByUserId = updatedByUserId + ) + } + } +} + +class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api.db.Database) extends BaseGeneratorInvocationsDao { + import anorm.JodaParameterMetaData.* + + import anorm.postgresql.* + + private val idGenerator: com.mbryzek.util.IdGenerator = { + com.mbryzek.util.IdGenerator("gni") + } + + def randomId: String = { + idGenerator.randomId() + } + + private val InsertQuery: io.flow.postgresql.Query = { + io.flow.postgresql.Query(""" + | insert into public.generator_invocations + | (id, key, organization_key, application_key, created_at, updated_at, updated_by_user_id, hash_code) + | values + | ({id}, {key}, {organization_key}, {application_key}, {created_at}::timestamptz, {updated_at}::timestamptz, {updated_by_user_id}, {hash_code}::bigint) + """.stripMargin) + } + + private val UpdateQuery: io.flow.postgresql.Query = { + io.flow.postgresql.Query(""" + | update public.generator_invocations + | set key = {key}, + | organization_key = {organization_key}, + | application_key = {application_key}, + | updated_at = {updated_at}::timestamptz, + | updated_by_user_id = {updated_by_user_id}, + | hash_code = {hash_code}::bigint + | where id = {id} and generator_invocations.hash_code != {hash_code}::bigint + """.stripMargin) + } + + private val DeleteQuery: io.flow.postgresql.Query = { + io.flow.postgresql.Query("delete from public.generator_invocations") + } + + def insert( + user: String, + form: GeneratorInvocationForm + ): String = { + db.withConnection { c => + insert(c, user, form) + } + } + + def insert( + c: java.sql.Connection, + user: String, + form: GeneratorInvocationForm + ): String = { + val id = randomId + bindQuery(InsertQuery, form) + .bind("created_at", org.joda.time.DateTime.now) + .bind("updated_by_user_id", user) + .bind("id", id) + .execute(c) + id + } + + def insertBatch( + user: String, + forms: Seq[GeneratorInvocationForm] + ): Seq[String] = { + db.withConnection { c => + insertBatch(c, user, forms) + } + } + + def insertBatch( + c: java.sql.Connection, + user: String, + forms: Seq[GeneratorInvocationForm] + ): Seq[String] = { + forms.map { f => + val id = randomId + (id, Seq(anorm.NamedParameter("created_at", org.joda.time.DateTime.now)) ++ toNamedParameter(user, id, f)) + }.toList match { + case Nil => Nil + case one :: rest => { + anorm.BatchSql(InsertQuery.sql(), one._2, rest.map(_._2)*).execute()(c) + Seq(one._1) ++ rest.map(_._1) + } + } + } + + def update( + user: String, + generatorInvocation: GeneratorInvocation, + form: GeneratorInvocationForm + ): Unit = { + db.withConnection { c => + update(c, user, generatorInvocation, form) + } + } + + def update( + c: java.sql.Connection, + user: String, + generatorInvocation: GeneratorInvocation, + form: GeneratorInvocationForm + ): Unit = { + updateById( + c = c, + user = user, + id = generatorInvocation.id, + form = form + ) + } + + def updateById( + user: String, + id: String, + form: GeneratorInvocationForm + ): Unit = { + db.withConnection { c => + updateById(c, user, id, form) + } + } + + def updateById( + c: java.sql.Connection, + user: String, + id: String, + form: GeneratorInvocationForm + ): Unit = { + bindQuery(UpdateQuery, form) + .bind("id", id) + .bind("updated_by_user_id", user) + .execute(c) + () + } + + def updateBatch( + user: String, + forms: Seq[(String, GeneratorInvocationForm)] + ): Unit = { + db.withConnection { c => + updateBatch(c, user, forms) + } + } + + def updateBatch( + c: java.sql.Connection, + user: String, + forms: Seq[(String, GeneratorInvocationForm)] + ): Unit = { + forms.map { case (id, f) => toNamedParameter(user, id, f) }.toList match { + case Nil => // no-op + case first :: rest => anorm.BatchSql(UpdateQuery.sql(), first, rest*).execute()(c) + } + } + + def delete( + user: String, + generatorInvocation: GeneratorInvocation + ): Unit = { + db.withConnection { c => + delete(c, user, generatorInvocation) + } + } + + def delete( + c: java.sql.Connection, + user: String, + generatorInvocation: GeneratorInvocation + ): Unit = { + deleteById( + c = c, + user = user, + id = generatorInvocation.id + ) + } + + def deleteById( + user: String, + id: String + ): Unit = { + db.withConnection { c => + deleteById(c, user, id) + } + } + + def deleteById( + c: java.sql.Connection, + user: String, + id: String + ): Unit = { + DeleteQuery.equals("id", id).execute(c) + } + + def deleteAllByIds( + user: String, + ids: Seq[String] + ): Unit = { + db.withConnection { c => + deleteAllByIds(c, user, ids) + } + } + + def deleteAllByIds( + c: java.sql.Connection, + user: String, + ids: Seq[String] + ): Unit = { + DeleteQuery.in("id", ids).execute(c) + } + + private def bindQuery( + query: io.flow.postgresql.Query, + form: GeneratorInvocationForm + ): io.flow.postgresql.Query = { + query + .bind("key", form.key) + .bind("organization_key", form.organizationKey) + .bind("application_key", form.applicationKey) + .bind("updated_at", org.joda.time.DateTime.now) + .bind("hash_code", form.hashCode()) + } + + private def toNamedParameter( + user: String, + id: String, + form: GeneratorInvocationForm + ): Seq[anorm.NamedParameter] = { + Seq( + anorm.NamedParameter("id", id), + anorm.NamedParameter("key", form.key), + anorm.NamedParameter("organization_key", form.organizationKey), + anorm.NamedParameter("application_key", form.applicationKey), + anorm.NamedParameter("updated_at", org.joda.time.DateTime.now), + anorm.NamedParameter("updated_by_user_id", user), + anorm.NamedParameter("hash_code", form.hashCode()) + ) + } +} \ No newline at end of file diff --git a/generated/app/db/TasksDao.scala b/generated/app/db/TasksDao.scala new file mode 100644 index 000000000..bfc6af768 --- /dev/null +++ b/generated/app/db/TasksDao.scala @@ -0,0 +1,739 @@ +package db.generated + +case class Task( + id: String, + `type`: String, + typeId: String, + organizationGuid: Option[java.util.UUID], + numAttempts: Int, + nextAttemptAt: org.joda.time.DateTime, + errors: Option[Seq[String]], + stacktrace: Option[String], + data: play.api.libs.json.JsValue, + createdAt: org.joda.time.DateTime, + updatedAt: org.joda.time.DateTime, + updatedByUserId: String +) { + def form: TaskForm = { + TaskForm( + id = id, + `type` = `type`, + typeId = typeId, + organizationGuid = organizationGuid, + numAttempts = numAttempts, + nextAttemptAt = nextAttemptAt, + errors = errors, + stacktrace = stacktrace, + data = data, + ) + } +} + +case class TaskForm( + id: String, + `type`: String, + typeId: String, + organizationGuid: Option[java.util.UUID], + numAttempts: Int, + nextAttemptAt: org.joda.time.DateTime, + errors: Option[Seq[String]], + stacktrace: Option[String], + data: play.api.libs.json.JsValue +) + +case object TasksTable { + val SchemaName: String = "public" + + val TableName: String = "tasks" + + val QualifiedName: String = "public.tasks" + + sealed trait Column { + def name: String + } + + object Columns { + case object Id extends Column { + override val name: String = "id" + } + + case object Type extends Column { + override val name: String = "type" + } + + case object TypeId extends Column { + override val name: String = "type_id" + } + + case object OrganizationGuid extends Column { + override val name: String = "organization_guid" + } + + case object NumAttempts extends Column { + override val name: String = "num_attempts" + } + + case object NextAttemptAt extends Column { + override val name: String = "next_attempt_at" + } + + case object Errors extends Column { + override val name: String = "errors" + } + + case object Stacktrace extends Column { + override val name: String = "stacktrace" + } + + case object Data extends Column { + override val name: String = "data" + } + + case object CreatedAt extends Column { + override val name: String = "created_at" + } + + case object UpdatedAt extends Column { + override val name: String = "updated_at" + } + + case object UpdatedByUserId extends Column { + override val name: String = "updated_by_user_id" + } + + case object HashCode extends Column { + override val name: String = "hash_code" + } + + val all: List[Column] = List(Id, Type, TypeId, OrganizationGuid, NumAttempts, NextAttemptAt, Errors, Stacktrace, Data, CreatedAt, UpdatedAt, UpdatedByUserId, HashCode) + } +} + +trait BaseTasksDao { + import anorm.* + + import anorm.JodaParameterMetaData.* + + import anorm.postgresql.* + + def db: play.api.db.Database + + private val BaseQuery: io.flow.postgresql.Query = { + io.flow.postgresql.Query(""" + | select id, + | type, + | type_id, + | organization_guid, + | num_attempts, + | next_attempt_at, + | errors::text, + | stacktrace, + | data::text, + | created_at, + | updated_at, + | updated_by_user_id, + | hash_code + | from public.tasks + |""".stripMargin.stripTrailing + ) + } + + def findAll( + id: Option[String] = None, + ids: Option[Seq[String]] = None, + typeId: Option[String] = None, + typeIds: Option[Seq[String]] = None, + typeIdAndType: Option[(String, String)] = None, + typeIdsAndTypes: Option[Seq[(String, String)]] = None, + numAttempts: Option[Int] = None, + numAttemptses: Option[Seq[Int]] = None, + numAttemptsAndNextAttemptAt: Option[(Int, org.joda.time.DateTime)] = None, + numAttemptsesAndNextAttemptAts: Option[Seq[(Int, org.joda.time.DateTime)]] = None, + limit: Option[Long], + offset: Long = 0, + orderBy: Option[io.flow.postgresql.OrderBy] = None + )(implicit customQueryModifier: io.flow.postgresql.Query => io.flow.postgresql.Query = identity): Seq[Task] = { + db.withConnection { c => + findAllWithConnection(c, id, ids, typeId, typeIds, typeIdAndType, typeIdsAndTypes, numAttempts, numAttemptses, numAttemptsAndNextAttemptAt, numAttemptsesAndNextAttemptAts, limit, offset, orderBy) + } + } + + def findAllWithConnection( + c: java.sql.Connection, + id: Option[String] = None, + ids: Option[Seq[String]] = None, + typeId: Option[String] = None, + typeIds: Option[Seq[String]] = None, + typeIdAndType: Option[(String, String)] = None, + typeIdsAndTypes: Option[Seq[(String, String)]] = None, + numAttempts: Option[Int] = None, + numAttemptses: Option[Seq[Int]] = None, + numAttemptsAndNextAttemptAt: Option[(Int, org.joda.time.DateTime)] = None, + numAttemptsesAndNextAttemptAts: Option[Seq[(Int, org.joda.time.DateTime)]] = None, + limit: Option[Long], + offset: Long = 0, + orderBy: Option[io.flow.postgresql.OrderBy] = None + )(implicit customQueryModifier: io.flow.postgresql.Query => io.flow.postgresql.Query = identity): Seq[Task] = { + customQueryModifier(BaseQuery) + .equals("tasks.id", id) + .optionalIn("tasks.id", ids) + .equals("tasks.type_id", typeId) + .optionalIn("tasks.type_id", typeIds) + .optionalIn2(("tasks.type_id", "tasks.type"), typeIdAndType.map(Seq(_))) + .optionalIn2(("tasks.type_id", "tasks.type"), typeIdsAndTypes) + .equals("tasks.num_attempts", numAttempts) + .optionalIn("tasks.num_attempts", numAttemptses) + .optionalIn2(("tasks.num_attempts", "tasks.next_attempt_at"), numAttemptsAndNextAttemptAt.map(Seq(_))) + .optionalIn2(("tasks.num_attempts", "tasks.next_attempt_at"), numAttemptsesAndNextAttemptAts) + .optionalLimit(limit) + .offset(offset) + .orderBy(orderBy.flatMap(_.sql)) + .as(parser.*)(c) + } + + def iterateAll( + id: Option[String] = None, + ids: Option[Seq[String]] = None, + typeId: Option[String] = None, + typeIds: Option[Seq[String]] = None, + typeIdAndType: Option[(String, String)] = None, + typeIdsAndTypes: Option[Seq[(String, String)]] = None, + numAttempts: Option[Int] = None, + numAttemptses: Option[Seq[Int]] = None, + numAttemptsAndNextAttemptAt: Option[(Int, org.joda.time.DateTime)] = None, + numAttemptsesAndNextAttemptAts: Option[Seq[(Int, org.joda.time.DateTime)]] = None, + pageSize: Long = 1000 + )(implicit customQueryModifier: io.flow.postgresql.Query => io.flow.postgresql.Query = identity): Iterator[Task] = { + assert(pageSize > 0, "pageSize must be > 0") + + def iterate(lastValue: Option[Task]): Iterator[Task] = { + val page: Seq[Task] = db.withConnection { c => + customQueryModifier(BaseQuery) + .equals("tasks.id", id) + .optionalIn("tasks.id", ids) + .equals("tasks.type_id", typeId) + .optionalIn("tasks.type_id", typeIds) + .optionalIn2(("tasks.type_id", "tasks.type"), typeIdAndType.map(Seq(_))) + .optionalIn2(("tasks.type_id", "tasks.type"), typeIdsAndTypes) + .equals("tasks.num_attempts", numAttempts) + .optionalIn("tasks.num_attempts", numAttemptses) + .optionalIn2(("tasks.num_attempts", "tasks.next_attempt_at"), numAttemptsAndNextAttemptAt.map(Seq(_))) + .optionalIn2(("tasks.num_attempts", "tasks.next_attempt_at"), numAttemptsesAndNextAttemptAts) + .greaterThan("tasks.id", lastValue.map(_.id)) + .orderBy("tasks.id") + .limit(pageSize) + .as(parser.*)(c) + } + if (page.length >= pageSize) { + page.iterator ++ iterate(page.lastOption) + } else { + page.iterator + } + } + + iterate(None) + } + + def findById(id: String): Option[Task] = { + db.withConnection { c => + findByIdWithConnection(c, id) + } + } + + def findByIdWithConnection( + c: java.sql.Connection, + id: String + ): Option[Task] = { + findAllWithConnection( + c = c, + id = Some(id), + limit = Some(1) + ).headOption + } + + def findAllByTypeId(typeId: String): Seq[Task] = { + db.withConnection { c => + findAllByTypeIdWithConnection(c, typeId) + } + } + + def findAllByTypeIdWithConnection( + c: java.sql.Connection, + typeId: String + ): Seq[Task] = { + findAllWithConnection( + c = c, + typeId = Some(typeId), + limit = None + ) + } + + def findByTypeIdAndType(typeIdAndType: (String, String)): Option[Task] = { + db.withConnection { c => + findByTypeIdAndTypeWithConnection(c, typeIdAndType) + } + } + + def findByTypeIdAndTypeWithConnection( + c: java.sql.Connection, + typeIdAndType: (String, String) + ): Option[Task] = { + findAllWithConnection( + c = c, + typeIdAndType = Some(typeIdAndType), + limit = Some(1) + ).headOption + } + + def findAllByNumAttempts(numAttempts: Int): Seq[Task] = { + db.withConnection { c => + findAllByNumAttemptsWithConnection(c, numAttempts) + } + } + + def findAllByNumAttemptsWithConnection( + c: java.sql.Connection, + numAttempts: Int + ): Seq[Task] = { + findAllWithConnection( + c = c, + numAttempts = Some(numAttempts), + limit = None + ) + } + + def findAllByNumAttemptsAndNextAttemptAt(numAttemptsAndNextAttemptAt: (Int, org.joda.time.DateTime)): Seq[Task] = { + db.withConnection { c => + findAllByNumAttemptsAndNextAttemptAtWithConnection(c, numAttemptsAndNextAttemptAt) + } + } + + def findAllByNumAttemptsAndNextAttemptAtWithConnection( + c: java.sql.Connection, + numAttemptsAndNextAttemptAt: (Int, org.joda.time.DateTime) + ): Seq[Task] = { + findAllWithConnection( + c = c, + numAttemptsAndNextAttemptAt = Some(numAttemptsAndNextAttemptAt), + limit = None + ) + } + + private val parser: anorm.RowParser[Task] = { + anorm.SqlParser.str("id") ~ + anorm.SqlParser.str("type") ~ + anorm.SqlParser.str("type_id") ~ + anorm.SqlParser.scalar[java.util.UUID]("organization_guid").? ~ + anorm.SqlParser.int("num_attempts") ~ + anorm.SqlParser.get[org.joda.time.DateTime]("next_attempt_at") ~ + anorm.SqlParser.str("errors").? ~ + anorm.SqlParser.str("stacktrace").? ~ + anorm.SqlParser.str("data") ~ + anorm.SqlParser.get[org.joda.time.DateTime]("created_at") ~ + anorm.SqlParser.get[org.joda.time.DateTime]("updated_at") ~ + anorm.SqlParser.str("updated_by_user_id") ~ + anorm.SqlParser.long("hash_code") map { case id ~ type_ ~ typeId ~ organizationGuid ~ numAttempts ~ nextAttemptAt ~ errors ~ stacktrace ~ data ~ createdAt ~ updatedAt ~ updatedByUserId ~ hashCode => + Task( + id = id, + `type` = type_, + typeId = typeId, + organizationGuid = organizationGuid, + numAttempts = numAttempts, + nextAttemptAt = nextAttemptAt, + errors = errors.map { v => play.api.libs.json.Json.parse(v).asInstanceOf[play.api.libs.json.JsArray].value.toSeq.map(_.asInstanceOf[play.api.libs.json.JsString].value) }, + stacktrace = stacktrace, + data = play.api.libs.json.Json.parse(data), + createdAt = createdAt, + updatedAt = updatedAt, + updatedByUserId = updatedByUserId + ) + } + } +} + +class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) extends BaseTasksDao { + import anorm.JodaParameterMetaData.* + + import anorm.postgresql.* + + private val UpsertQuery: io.flow.postgresql.Query = { + io.flow.postgresql.Query(""" + | insert into public.tasks + | (id, type, type_id, organization_guid, num_attempts, next_attempt_at, errors, stacktrace, data, created_at, updated_at, updated_by_user_id, hash_code) + | values + | ({id}, {type}, {type_id}, {organization_guid}::uuid, {num_attempts}::integer, {next_attempt_at}::timestamptz, {errors}::json, {stacktrace}, {data}::json, {created_at}::timestamptz, {updated_at}::timestamptz, {updated_by_user_id}, {hash_code}::bigint) + | on conflict(type_id, type) do update + | set organization_guid = {organization_guid}::uuid, + | num_attempts = {num_attempts}::integer, + | next_attempt_at = {next_attempt_at}::timestamptz, + | errors = {errors}::json, + | stacktrace = {stacktrace}, + | data = {data}::json, + | updated_at = {updated_at}::timestamptz, + | updated_by_user_id = {updated_by_user_id}, + | hash_code = {hash_code}::bigint + | where tasks.hash_code != {hash_code}::bigint + """.stripMargin) + } + + private val UpdateQuery: io.flow.postgresql.Query = { + io.flow.postgresql.Query(""" + | update public.tasks + | set type = {type}, + | type_id = {type_id}, + | organization_guid = {organization_guid}::uuid, + | num_attempts = {num_attempts}::integer, + | next_attempt_at = {next_attempt_at}::timestamptz, + | errors = {errors}::json, + | stacktrace = {stacktrace}, + | data = {data}::json, + | updated_at = {updated_at}::timestamptz, + | updated_by_user_id = {updated_by_user_id}, + | hash_code = {hash_code}::bigint + | where id = {id} and tasks.hash_code != {hash_code}::bigint + """.stripMargin) + } + + private val DeleteQuery: io.flow.postgresql.Query = { + io.flow.postgresql.Query("delete from public.tasks") + } + + def upsertByTypeIdAndType( + user: String, + form: TaskForm + ): Unit = { + db.withConnection { c => + upsertByTypeIdAndType(c, user, form) + } + } + + def upsertByTypeIdAndType( + c: java.sql.Connection, + user: String, + form: TaskForm + ): Unit = { + bindQuery(UpsertQuery, form) + .bind("created_at", org.joda.time.DateTime.now) + .bind("updated_by_user_id", user) + .execute(c) + } + + def upsertBatchByTypeIdAndType( + user: String, + forms: Seq[TaskForm] + ): Seq[Unit] = { + db.withConnection { c => + upsertBatchByTypeIdAndType(c, user, forms) + } + } + + def upsertBatchByTypeIdAndType( + c: java.sql.Connection, + user: String, + forms: Seq[TaskForm] + ): Seq[Unit] = { + forms.map { f => Seq(anorm.NamedParameter("created_at", org.joda.time.DateTime.now)) ++ toNamedParameter(user, f) }.toList match { + case Nil => Nil + case one :: rest => { + anorm.BatchSql(UpsertQuery.sql(), one, rest*).execute()(c) + (Seq(one) ++ rest).map { _ => () } + } + } + } + + def update( + user: String, + task: Task, + form: TaskForm + ): Unit = { + db.withConnection { c => + update(c, user, task, form) + } + } + + def update( + c: java.sql.Connection, + user: String, + task: Task, + form: TaskForm + ): Unit = { + updateById( + c = c, + user = user, + id = task.id, + form = form + ) + } + + def updateById( + user: String, + id: String, + form: TaskForm + ): Unit = { + db.withConnection { c => + updateById(c, user, id, form) + } + } + + def updateById( + c: java.sql.Connection, + user: String, + id: String, + form: TaskForm + ): Unit = { + bindQuery(UpdateQuery, form) + .bind("id", id) + .bind("updated_by_user_id", user) + .execute(c) + () + } + + def updateBatch( + user: String, + forms: Seq[TaskForm] + ): Unit = { + db.withConnection { c => + updateBatch(c, user, forms) + } + } + + def updateBatch( + c: java.sql.Connection, + user: String, + forms: Seq[TaskForm] + ): Unit = { + forms.map { f => toNamedParameter(user, f) }.toList match { + case Nil => // no-op + case first :: rest => anorm.BatchSql(UpdateQuery.sql(), first, rest*).execute()(c) + } + } + + def delete( + user: String, + task: Task + ): Unit = { + db.withConnection { c => + delete(c, user, task) + } + } + + def delete( + c: java.sql.Connection, + user: String, + task: Task + ): Unit = { + deleteById( + c = c, + user = user, + id = task.id + ) + } + + def deleteById( + user: String, + id: String + ): Unit = { + db.withConnection { c => + deleteById(c, user, id) + } + } + + def deleteById( + c: java.sql.Connection, + user: String, + id: String + ): Unit = { + DeleteQuery.equals("id", id).execute(c) + } + + def deleteAllByIds( + user: String, + ids: Seq[String] + ): Unit = { + db.withConnection { c => + deleteAllByIds(c, user, ids) + } + } + + def deleteAllByIds( + c: java.sql.Connection, + user: String, + ids: Seq[String] + ): Unit = { + DeleteQuery.in("id", ids).execute(c) + } + + def deleteAllByTypeId( + user: String, + typeId: String + ): Unit = { + db.withConnection { c => + deleteAllByTypeId(c, user, typeId) + } + } + + def deleteAllByTypeId( + c: java.sql.Connection, + user: String, + typeId: String + ): Unit = { + DeleteQuery.equals("type_id", typeId).execute(c) + } + + def deleteAllByTypeIds( + user: String, + typeIds: Seq[String] + ): Unit = { + db.withConnection { c => + deleteAllByTypeIds(c, user, typeIds) + } + } + + def deleteAllByTypeIds( + c: java.sql.Connection, + user: String, + typeIds: Seq[String] + ): Unit = { + DeleteQuery.in("type_id", typeIds).execute(c) + } + + def deleteByTypeIdAndType( + user: String, + typeIdAndType: (String, String) + ): Unit = { + db.withConnection { c => + deleteByTypeIdAndType(c, user, typeIdAndType) + } + } + + def deleteByTypeIdAndType( + c: java.sql.Connection, + user: String, + typeIdAndType: (String, String) + ): Unit = { + DeleteQuery.in2(("type_id", "type"), Seq(typeIdAndType)).execute(c) + } + + def deleteAllByTypeIdsAndTypes( + user: String, + typeIdsAndTypes: Seq[(String, String)] + ): Unit = { + db.withConnection { c => + deleteAllByTypeIdsAndTypes(c, user, typeIdsAndTypes) + } + } + + def deleteAllByTypeIdsAndTypes( + c: java.sql.Connection, + user: String, + typeIdsAndTypes: Seq[(String, String)] + ): Unit = { + DeleteQuery.in2(("type_id", "type"), typeIdsAndTypes).execute(c) + } + + def deleteAllByNumAttempts( + user: String, + numAttempts: Int + ): Unit = { + db.withConnection { c => + deleteAllByNumAttempts(c, user, numAttempts) + } + } + + def deleteAllByNumAttempts( + c: java.sql.Connection, + user: String, + numAttempts: Int + ): Unit = { + DeleteQuery.equals("num_attempts", numAttempts).execute(c) + } + + def deleteAllByNumAttemptses( + user: String, + numAttemptses: Seq[Int] + ): Unit = { + db.withConnection { c => + deleteAllByNumAttemptses(c, user, numAttemptses) + } + } + + def deleteAllByNumAttemptses( + c: java.sql.Connection, + user: String, + numAttemptses: Seq[Int] + ): Unit = { + DeleteQuery.in("num_attempts", numAttemptses).execute(c) + } + + def deleteAllByNumAttemptsAndNextAttemptAt( + user: String, + numAttemptsAndNextAttemptAt: (Int, org.joda.time.DateTime) + ): Unit = { + db.withConnection { c => + deleteAllByNumAttemptsAndNextAttemptAt(c, user, numAttemptsAndNextAttemptAt) + } + } + + def deleteAllByNumAttemptsAndNextAttemptAt( + c: java.sql.Connection, + user: String, + numAttemptsAndNextAttemptAt: (Int, org.joda.time.DateTime) + ): Unit = { + DeleteQuery.in2(("num_attempts", "next_attempt_at"), Seq(numAttemptsAndNextAttemptAt)).execute(c) + } + + def deleteAllByNumAttemptsesAndNextAttemptAts( + user: String, + numAttemptsesAndNextAttemptAts: Seq[(Int, org.joda.time.DateTime)] + ): Unit = { + db.withConnection { c => + deleteAllByNumAttemptsesAndNextAttemptAts(c, user, numAttemptsesAndNextAttemptAts) + } + } + + def deleteAllByNumAttemptsesAndNextAttemptAts( + c: java.sql.Connection, + user: String, + numAttemptsesAndNextAttemptAts: Seq[(Int, org.joda.time.DateTime)] + ): Unit = { + DeleteQuery.in2(("num_attempts", "next_attempt_at"), numAttemptsesAndNextAttemptAts).execute(c) + } + + private def bindQuery( + query: io.flow.postgresql.Query, + form: TaskForm + ): io.flow.postgresql.Query = { + query + .bind("id", form.id) + .bind("type", form.`type`) + .bind("type_id", form.typeId) + .bind("organization_guid", form.organizationGuid) + .bind("num_attempts", form.numAttempts) + .bind("next_attempt_at", form.nextAttemptAt) + .bind("errors", form.errors.map { v => play.api.libs.json.Json.toJson(v).toString }) + .bind("stacktrace", form.stacktrace) + .bind("data", play.api.libs.json.Json.toJson(form.data).toString) + .bind("updated_at", org.joda.time.DateTime.now) + .bind("hash_code", form.hashCode()) + } + + private def toNamedParameter( + user: String, + form: TaskForm + ): Seq[anorm.NamedParameter] = { + Seq( + anorm.NamedParameter("id", form.id), + anorm.NamedParameter("type", form.`type`), + anorm.NamedParameter("type_id", form.typeId), + anorm.NamedParameter("organization_guid", form.organizationGuid), + anorm.NamedParameter("num_attempts", form.numAttempts), + anorm.NamedParameter("next_attempt_at", form.nextAttemptAt), + anorm.NamedParameter("errors", form.errors.map { v => play.api.libs.json.Json.toJson(v).toString }), + anorm.NamedParameter("stacktrace", form.stacktrace), + anorm.NamedParameter("data", play.api.libs.json.Json.toJson(form.data).toString), + anorm.NamedParameter("updated_at", org.joda.time.DateTime.now), + anorm.NamedParameter("updated_by_user_id", user), + anorm.NamedParameter("hash_code", form.hashCode()) + ) + } +} \ No newline at end of file From 6fe3f9a4c2167bb1e156bbba7de69099fc773a19 Mon Sep 17 00:00:00 2001 From: Michael Bryzek Date: Tue, 30 Jul 2024 22:24:31 +0200 Subject: [PATCH 04/25] wip --- build.sbt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.sbt b/build.sbt index cf84f70ec..1c2f02679 100644 --- a/build.sbt +++ b/build.sbt @@ -84,6 +84,8 @@ lazy val generated = project scalacOptions ++= Seq("-deprecation:false"), libraryDependencies ++= Seq( ws, + "com.github.mbryzek" % "lib-query" % "0.0.5", + "com.github.mbryzek" % "lib-util" % "0.0.7", "joda-time" % "joda-time" % "2.12.7", "org.playframework.anorm" %% "anorm-postgres" % "2.7.0", "org.postgresql" % "postgresql" % "42.7.3", From e54df4cc8dd1be42b3aede9cbe209d06975d3e1e Mon Sep 17 00:00:00 2001 From: Michael Bryzek Date: Tue, 30 Jul 2024 22:26:06 +0200 Subject: [PATCH 05/25] wip --- build.sbt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.sbt b/build.sbt index 1c2f02679..f587163ae 100644 --- a/build.sbt +++ b/build.sbt @@ -80,10 +80,12 @@ lazy val generated = project .in(file("generated")) .enablePlugins(PlayScala) .settings(commonSettings*) + .settings(resolversSettings) .settings( scalacOptions ++= Seq("-deprecation:false"), libraryDependencies ++= Seq( ws, + jdbc, "com.github.mbryzek" % "lib-query" % "0.0.5", "com.github.mbryzek" % "lib-util" % "0.0.7", "joda-time" % "joda-time" % "2.12.7", From 6463d3482f4de41fae6f180432a633568dbf5154 Mon Sep 17 00:00:00 2001 From: Michael Bryzek Date: Tue, 30 Jul 2024 22:31:56 +0200 Subject: [PATCH 06/25] wip --- generated/app/db/TasksDao.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/generated/app/db/TasksDao.scala b/generated/app/db/TasksDao.scala index bfc6af768..f494ab1d8 100644 --- a/generated/app/db/TasksDao.scala +++ b/generated/app/db/TasksDao.scala @@ -323,7 +323,7 @@ trait BaseTasksDao { anorm.SqlParser.str("id") ~ anorm.SqlParser.str("type") ~ anorm.SqlParser.str("type_id") ~ - anorm.SqlParser.scalar[java.util.UUID]("organization_guid").? ~ + anorm.SqlParser.str("organization_guid").? ~ anorm.SqlParser.int("num_attempts") ~ anorm.SqlParser.get[org.joda.time.DateTime]("next_attempt_at") ~ anorm.SqlParser.str("errors").? ~ @@ -337,7 +337,7 @@ trait BaseTasksDao { id = id, `type` = type_, typeId = typeId, - organizationGuid = organizationGuid, + organizationGuid = organizationGuid.map { v => java.util.UUID.fromString(v) }, numAttempts = numAttempts, nextAttemptAt = nextAttemptAt, errors = errors.map { v => play.api.libs.json.Json.parse(v).asInstanceOf[play.api.libs.json.JsArray].value.toSeq.map(_.asInstanceOf[play.api.libs.json.JsString].value) }, @@ -707,7 +707,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex .bind("id", form.id) .bind("type", form.`type`) .bind("type_id", form.typeId) - .bind("organization_guid", form.organizationGuid) + .bind("organization_guid", form.organizationGuid.map(_.toString)) .bind("num_attempts", form.numAttempts) .bind("next_attempt_at", form.nextAttemptAt) .bind("errors", form.errors.map { v => play.api.libs.json.Json.toJson(v).toString }) @@ -725,7 +725,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex anorm.NamedParameter("id", form.id), anorm.NamedParameter("type", form.`type`), anorm.NamedParameter("type_id", form.typeId), - anorm.NamedParameter("organization_guid", form.organizationGuid), + anorm.NamedParameter("organization_guid", form.organizationGuid.map(_.toString)), anorm.NamedParameter("num_attempts", form.numAttempts), anorm.NamedParameter("next_attempt_at", form.nextAttemptAt), anorm.NamedParameter("errors", form.errors.map { v => play.api.libs.json.Json.toJson(v).toString }), From ebe985292cf3a9f7106a89773a77061e8b6345b0 Mon Sep 17 00:00:00 2001 From: Michael Bryzek Date: Tue, 30 Jul 2024 22:33:14 +0200 Subject: [PATCH 07/25] wip --- .../db/GeneratorApibuilderSessionsDao.scala | 231 ++++++++++++++++++ 1 file changed, 231 insertions(+) create mode 100644 generated/app/db/GeneratorApibuilderSessionsDao.scala diff --git a/generated/app/db/GeneratorApibuilderSessionsDao.scala b/generated/app/db/GeneratorApibuilderSessionsDao.scala new file mode 100644 index 000000000..627465261 --- /dev/null +++ b/generated/app/db/GeneratorApibuilderSessionsDao.scala @@ -0,0 +1,231 @@ +package db.generated + +import anorm._ +import io.flow.postgresql.{OrderBy, Query} +import java.sql.Connection +import java.util.UUID +import javax.inject.{Inject, Singleton} +import org.joda.time.DateTime +import play.api.db.{Database, NamedDatabase} + +case class Session( + id: String, + userGuid: UUID, + expiresAt: DateTime, + createdAt: DateTime, + createdByGuid: UUID, + updatedAt: DateTime, + updatedByGuid: UUID, + deletedAt: Option[DateTime], + deletedByGuid: Option[UUID] +) { + + lazy val form: SessionForm = SessionForm( + id = id, + userGuid = userGuid, + expiresAt = expiresAt, + createdAt = createdAt, + createdByGuid = createdByGuid, + updatedAt = updatedAt, + updatedByGuid = updatedByGuid, + deletedAt = deletedAt, + deletedByGuid = deletedByGuid + ) + +} + +case class SessionForm( + id: String, + userGuid: UUID, + expiresAt: DateTime, + createdAt: DateTime, + createdByGuid: UUID, + updatedAt: DateTime, + updatedByGuid: UUID, + deletedAt: Option[DateTime], + deletedByGuid: Option[UUID] +) + +@Singleton +class SessionsDao @Inject() ( + @NamedDatabase("default") db: Database +) { + + private val BaseQuery = Query(""" + | select sessions.id, + | sessions.user_guid, + | sessions.expires_at, + | sessions.created_at, + | sessions.created_by_guid, + | sessions.updated_at, + | sessions.updated_by_guid, + | sessions.deleted_at, + | sessions.deleted_by_guid, + | sessions.hash_code + | from sessions + """.stripMargin) + + private val InsertQuery = Query(""" + | insert into sessions + | (id, user_guid, expires_at, created_at, created_by_guid, updated_at, updated_by_guid, deleted_at, deleted_by_guid, hash_code) + | values + | ({id}, {user_guid}::uuid, {expires_at}::timestamptz, {created_at}::timestamptz, {created_by_guid}::uuid, {updated_at}::timestamptz, {updated_by_guid}::uuid, {deleted_at}::timestamptz, {deleted_by_guid}::uuid, {hash_code}::bigint) + """.stripMargin) + + private val UpdateQuery = Query(""" + | update sessions + | set user_guid = {user_guid}::uuid, + | expires_at = {expires_at}::timestamptz, + | created_at = {created_at}::timestamptz, + | created_by_guid = {created_by_guid}::uuid, + | updated_at = {updated_at}::timestamptz, + | updated_by_guid = {updated_by_guid}::uuid, + | deleted_at = {deleted_at}::timestamptz, + | deleted_by_guid = {deleted_by_guid}::uuid, + | hash_code = {hash_code}::bigint + | where id = {id} + | and (sessions.hash_code is null or sessions.hash_code != {hash_code}::bigint) + """.stripMargin) + + private def bindQuery(query: Query, form: SessionForm): Query = { + query. + bind("user_guid", form.userGuid). + bind("expires_at", form.expiresAt). + bind("created_at", form.createdAt). + bind("created_by_guid", form.createdByGuid). + bind("updated_at", form.updatedAt). + bind("updated_by_guid", form.updatedByGuid). + bind("deleted_at", form.deletedAt). + bind("deleted_by_guid", form.deletedByGuid). + bind("hash_code", form.hashCode()) + } + + def insert(updatedBy: UUID, form: SessionForm): Unit = { + db.withConnection { implicit c => + insert(c, updatedBy, form) + } + } + + def insert(implicit c: Connection, updatedBy: UUID, form: SessionForm): Unit = { + bindQuery(InsertQuery, form). + bind("id", form.id). + anormSql().execute() + } + + def updateIfChangedById(updatedBy: UUID, id: String, form: SessionForm): Unit ={ + if (!findById(id).map(_.form).contains(form)) { + updateById(updatedBy, id, form) + } + } + + def updateById(updatedBy: UUID, id: String, form: SessionForm): Unit = { + db.withConnection { implicit c => + updateById(c, updatedBy, id, form) + } + } + + def updateById(implicit c: Connection, updatedBy: UUID, id: String, form: SessionForm): Unit = { + bindQuery(UpdateQuery, form). + bind("id", id). + anormSql().execute() + } + + def update(updatedBy: UUID, existing: Session, form: SessionForm): Unit = { + db.withConnection { implicit c => + update(c, updatedBy, existing, form) + } + } + + def update(implicit c: Connection, updatedBy: UUID, existing: Session, form: SessionForm): Unit = { + updateById(c, updatedBy, existing.id, form) + } + + def delete(deletedBy: UUID, session: Session): Unit = ??? + + def deleteById(deletedBy: UUID, id: String): Unit = { + db.withConnection { implicit c => + deleteById(c, deletedBy, id) + } + } + + def deleteById(c: java.sql.Connection, deletedBy: UUID, id: String): Unit = ??? + + def findById(id: String): Option[Session] = { + db.withConnection { implicit c => + findByIdWithConnection(c, id) + } + } + + def findByIdWithConnection(c: java.sql.Connection, id: String): Option[Session] = { + findAllWithConnection(c, ids = Some(Seq(id)), limit = 1).headOption + } + + def findAll( + ids: Option[Seq[String]] = None, + userGuid: Option[UUID] = None, + limit: Long, + offset: Long = 0, + orderBy: OrderBy = OrderBy("sessions.id") + ) ( + implicit customQueryModifier: Query => Query = { q => q } + ): Seq[Session] = { + db.withConnection { implicit c => + findAllWithConnection( + c, + ids = ids, + userGuid = userGuid, + limit = limit, + offset = offset, + orderBy = orderBy + )(customQueryModifier) + } + } + + def findAllWithConnection( + c: java.sql.Connection, + ids: Option[Seq[String]] = None, + userGuid: Option[UUID] = None, + limit: Long, + offset: Long = 0, + orderBy: OrderBy = OrderBy("sessions.id") + ) ( + implicit customQueryModifier: Query => Query = { q => q } + ): Seq[Session] = { + customQueryModifier(BaseQuery). + optionalIn("sessions.id", ids). + equals("sessions.user_guid", userGuid). + limit(limit). + offset(offset). + orderBy(orderBy.sql). + as(SessionsDao.parser().*)(c) + } + +} + +object SessionsDao { + + def parser(): RowParser[Session] = { + SqlParser.str("id") ~ + SqlParser.get[UUID]("user_guid") ~ + SqlParser.get[DateTime]("expires_at") ~ + SqlParser.get[DateTime]("created_at") ~ + SqlParser.get[UUID]("created_by_guid") ~ + SqlParser.get[DateTime]("updated_at") ~ + SqlParser.get[UUID]("updated_by_guid") ~ + SqlParser.get[DateTime]("deleted_at").? ~ + SqlParser.get[UUID]("deleted_by_guid").? map { + case id ~ userGuid ~ expiresAt ~ createdAt ~ createdByGuid ~ updatedAt ~ updatedByGuid ~ deletedAt ~ deletedByGuid => Session( + id = id, + userGuid = userGuid, + expiresAt = expiresAt, + createdAt = createdAt, + createdByGuid = createdByGuid, + updatedAt = updatedAt, + updatedByGuid = updatedByGuid, + deletedAt = deletedAt, + deletedByGuid = deletedByGuid + ) + } + } + +} \ No newline at end of file From 16e8eb6a46db3f9306d0c3abcca8146fbef42b4c Mon Sep 17 00:00:00 2001 From: Michael Bryzek Date: Tue, 30 Jul 2024 22:35:31 +0200 Subject: [PATCH 08/25] wip --- api/app/db/InternalTasksDao.scala | 2 +- api/app/processor/TaskProcessor.scala | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/api/app/db/InternalTasksDao.scala b/api/app/db/InternalTasksDao.scala index 6f87a0b1a..43789bb8e 100644 --- a/api/app/db/InternalTasksDao.scala +++ b/api/app/db/InternalTasksDao.scala @@ -37,7 +37,7 @@ class InternalTasksDao @Inject() ( organizationGuid: Option[UUID] = None, data: JsValue = Json.obj() ): Unit = { - if (dao.findByTypeIdAndTypeWithConnection(c, id, typ.toString).isEmpty) { + if (dao.findByTypeIdAndTypeWithConnection(c, (id, typ.toString)).isEmpty) { dao.upsertByTypeIdAndType( c, Constants.DefaultUserGuid, diff --git a/api/app/processor/TaskProcessor.scala b/api/app/processor/TaskProcessor.scala index 230441c9a..3c52af136 100644 --- a/api/app/processor/TaskProcessor.scala +++ b/api/app/processor/TaskProcessor.scala @@ -89,11 +89,12 @@ abstract class BaseTaskProcessor( args.lockUtil.lock(s"tasks:$typ") { _ => args.dao .findAll( - `type` = Some(typ.toString), - nextAttemptAtLessThanOrEquals = Some(DateTime.now), limit = Some(Limit), orderBy = Some(OrderBy("num_attempts, next_attempt_at")) - ) + ) { q => + q.equals("type", typ.toString) + .and("next_attempt_at <= now()") + } .foreach(processRecordSafe) } } @@ -155,7 +156,7 @@ abstract class BaseTaskProcessor( } final protected def insertIfNew(c: Connection, form: TaskForm): Unit = { - if (args.dao.findByTypeIdAndTypeWithConnection(c, form.typeId, form.`type`).isEmpty) { + if (args.dao.findByTypeIdAndTypeWithConnection(c, (form.typeId, form.`type`)).isEmpty) { args.dao.upsertByTypeIdAndType(c, Constants.DefaultUserGuid, form) } } From d4be91326d569ab9fdce3d79523fdebc9a288e4a Mon Sep 17 00:00:00 2001 From: Michael Bryzek Date: Tue, 30 Jul 2024 22:37:55 +0200 Subject: [PATCH 09/25] wip --- dao/spec/psql-apibuilder.json | 2 +- .../app/db/GeneratorInvocationsDao.scala | 34 +++++----- generated/app/db/TasksDao.scala | 66 +++++++++---------- 3 files changed, 51 insertions(+), 51 deletions(-) diff --git a/dao/spec/psql-apibuilder.json b/dao/spec/psql-apibuilder.json index d6ca4ab45..39791931d 100644 --- a/dao/spec/psql-apibuilder.json +++ b/dao/spec/psql-apibuilder.json @@ -6,7 +6,7 @@ "value": { "version": "3.4", "package": "db.generated", - "dao_user_class": "java.util.UUID" + "user_class": "java.util.UUID" } }, { diff --git a/generated/app/db/GeneratorInvocationsDao.scala b/generated/app/db/GeneratorInvocationsDao.scala index 8c8f3d5c6..6f71224e3 100644 --- a/generated/app/db/GeneratorInvocationsDao.scala +++ b/generated/app/db/GeneratorInvocationsDao.scala @@ -231,7 +231,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. } def insert( - user: String, + user: java.util.UUID, form: GeneratorInvocationForm ): String = { db.withConnection { c => @@ -241,7 +241,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. def insert( c: java.sql.Connection, - user: String, + user: java.util.UUID, form: GeneratorInvocationForm ): String = { val id = randomId @@ -254,7 +254,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. } def insertBatch( - user: String, + user: java.util.UUID, forms: Seq[GeneratorInvocationForm] ): Seq[String] = { db.withConnection { c => @@ -264,7 +264,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. def insertBatch( c: java.sql.Connection, - user: String, + user: java.util.UUID, forms: Seq[GeneratorInvocationForm] ): Seq[String] = { forms.map { f => @@ -280,7 +280,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. } def update( - user: String, + user: java.util.UUID, generatorInvocation: GeneratorInvocation, form: GeneratorInvocationForm ): Unit = { @@ -291,7 +291,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. def update( c: java.sql.Connection, - user: String, + user: java.util.UUID, generatorInvocation: GeneratorInvocation, form: GeneratorInvocationForm ): Unit = { @@ -304,7 +304,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. } def updateById( - user: String, + user: java.util.UUID, id: String, form: GeneratorInvocationForm ): Unit = { @@ -315,7 +315,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. def updateById( c: java.sql.Connection, - user: String, + user: java.util.UUID, id: String, form: GeneratorInvocationForm ): Unit = { @@ -327,7 +327,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. } def updateBatch( - user: String, + user: java.util.UUID, forms: Seq[(String, GeneratorInvocationForm)] ): Unit = { db.withConnection { c => @@ -337,7 +337,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. def updateBatch( c: java.sql.Connection, - user: String, + user: java.util.UUID, forms: Seq[(String, GeneratorInvocationForm)] ): Unit = { forms.map { case (id, f) => toNamedParameter(user, id, f) }.toList match { @@ -347,7 +347,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. } def delete( - user: String, + user: java.util.UUID, generatorInvocation: GeneratorInvocation ): Unit = { db.withConnection { c => @@ -357,7 +357,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. def delete( c: java.sql.Connection, - user: String, + user: java.util.UUID, generatorInvocation: GeneratorInvocation ): Unit = { deleteById( @@ -368,7 +368,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. } def deleteById( - user: String, + user: java.util.UUID, id: String ): Unit = { db.withConnection { c => @@ -378,14 +378,14 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. def deleteById( c: java.sql.Connection, - user: String, + user: java.util.UUID, id: String ): Unit = { DeleteQuery.equals("id", id).execute(c) } def deleteAllByIds( - user: String, + user: java.util.UUID, ids: Seq[String] ): Unit = { db.withConnection { c => @@ -395,7 +395,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. def deleteAllByIds( c: java.sql.Connection, - user: String, + user: java.util.UUID, ids: Seq[String] ): Unit = { DeleteQuery.in("id", ids).execute(c) @@ -414,7 +414,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. } private def toNamedParameter( - user: String, + user: java.util.UUID, id: String, form: GeneratorInvocationForm ): Seq[anorm.NamedParameter] = { diff --git a/generated/app/db/TasksDao.scala b/generated/app/db/TasksDao.scala index f494ab1d8..1c59ee54a 100644 --- a/generated/app/db/TasksDao.scala +++ b/generated/app/db/TasksDao.scala @@ -399,7 +399,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex } def upsertByTypeIdAndType( - user: String, + user: java.util.UUID, form: TaskForm ): Unit = { db.withConnection { c => @@ -409,7 +409,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def upsertByTypeIdAndType( c: java.sql.Connection, - user: String, + user: java.util.UUID, form: TaskForm ): Unit = { bindQuery(UpsertQuery, form) @@ -419,7 +419,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex } def upsertBatchByTypeIdAndType( - user: String, + user: java.util.UUID, forms: Seq[TaskForm] ): Seq[Unit] = { db.withConnection { c => @@ -429,7 +429,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def upsertBatchByTypeIdAndType( c: java.sql.Connection, - user: String, + user: java.util.UUID, forms: Seq[TaskForm] ): Seq[Unit] = { forms.map { f => Seq(anorm.NamedParameter("created_at", org.joda.time.DateTime.now)) ++ toNamedParameter(user, f) }.toList match { @@ -442,7 +442,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex } def update( - user: String, + user: java.util.UUID, task: Task, form: TaskForm ): Unit = { @@ -453,7 +453,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def update( c: java.sql.Connection, - user: String, + user: java.util.UUID, task: Task, form: TaskForm ): Unit = { @@ -466,7 +466,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex } def updateById( - user: String, + user: java.util.UUID, id: String, form: TaskForm ): Unit = { @@ -477,7 +477,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def updateById( c: java.sql.Connection, - user: String, + user: java.util.UUID, id: String, form: TaskForm ): Unit = { @@ -489,7 +489,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex } def updateBatch( - user: String, + user: java.util.UUID, forms: Seq[TaskForm] ): Unit = { db.withConnection { c => @@ -499,7 +499,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def updateBatch( c: java.sql.Connection, - user: String, + user: java.util.UUID, forms: Seq[TaskForm] ): Unit = { forms.map { f => toNamedParameter(user, f) }.toList match { @@ -509,7 +509,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex } def delete( - user: String, + user: java.util.UUID, task: Task ): Unit = { db.withConnection { c => @@ -519,7 +519,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def delete( c: java.sql.Connection, - user: String, + user: java.util.UUID, task: Task ): Unit = { deleteById( @@ -530,7 +530,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex } def deleteById( - user: String, + user: java.util.UUID, id: String ): Unit = { db.withConnection { c => @@ -540,14 +540,14 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def deleteById( c: java.sql.Connection, - user: String, + user: java.util.UUID, id: String ): Unit = { DeleteQuery.equals("id", id).execute(c) } def deleteAllByIds( - user: String, + user: java.util.UUID, ids: Seq[String] ): Unit = { db.withConnection { c => @@ -557,14 +557,14 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def deleteAllByIds( c: java.sql.Connection, - user: String, + user: java.util.UUID, ids: Seq[String] ): Unit = { DeleteQuery.in("id", ids).execute(c) } def deleteAllByTypeId( - user: String, + user: java.util.UUID, typeId: String ): Unit = { db.withConnection { c => @@ -574,14 +574,14 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def deleteAllByTypeId( c: java.sql.Connection, - user: String, + user: java.util.UUID, typeId: String ): Unit = { DeleteQuery.equals("type_id", typeId).execute(c) } def deleteAllByTypeIds( - user: String, + user: java.util.UUID, typeIds: Seq[String] ): Unit = { db.withConnection { c => @@ -591,14 +591,14 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def deleteAllByTypeIds( c: java.sql.Connection, - user: String, + user: java.util.UUID, typeIds: Seq[String] ): Unit = { DeleteQuery.in("type_id", typeIds).execute(c) } def deleteByTypeIdAndType( - user: String, + user: java.util.UUID, typeIdAndType: (String, String) ): Unit = { db.withConnection { c => @@ -608,14 +608,14 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def deleteByTypeIdAndType( c: java.sql.Connection, - user: String, + user: java.util.UUID, typeIdAndType: (String, String) ): Unit = { DeleteQuery.in2(("type_id", "type"), Seq(typeIdAndType)).execute(c) } def deleteAllByTypeIdsAndTypes( - user: String, + user: java.util.UUID, typeIdsAndTypes: Seq[(String, String)] ): Unit = { db.withConnection { c => @@ -625,14 +625,14 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def deleteAllByTypeIdsAndTypes( c: java.sql.Connection, - user: String, + user: java.util.UUID, typeIdsAndTypes: Seq[(String, String)] ): Unit = { DeleteQuery.in2(("type_id", "type"), typeIdsAndTypes).execute(c) } def deleteAllByNumAttempts( - user: String, + user: java.util.UUID, numAttempts: Int ): Unit = { db.withConnection { c => @@ -642,14 +642,14 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def deleteAllByNumAttempts( c: java.sql.Connection, - user: String, + user: java.util.UUID, numAttempts: Int ): Unit = { DeleteQuery.equals("num_attempts", numAttempts).execute(c) } def deleteAllByNumAttemptses( - user: String, + user: java.util.UUID, numAttemptses: Seq[Int] ): Unit = { db.withConnection { c => @@ -659,14 +659,14 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def deleteAllByNumAttemptses( c: java.sql.Connection, - user: String, + user: java.util.UUID, numAttemptses: Seq[Int] ): Unit = { DeleteQuery.in("num_attempts", numAttemptses).execute(c) } def deleteAllByNumAttemptsAndNextAttemptAt( - user: String, + user: java.util.UUID, numAttemptsAndNextAttemptAt: (Int, org.joda.time.DateTime) ): Unit = { db.withConnection { c => @@ -676,14 +676,14 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def deleteAllByNumAttemptsAndNextAttemptAt( c: java.sql.Connection, - user: String, + user: java.util.UUID, numAttemptsAndNextAttemptAt: (Int, org.joda.time.DateTime) ): Unit = { DeleteQuery.in2(("num_attempts", "next_attempt_at"), Seq(numAttemptsAndNextAttemptAt)).execute(c) } def deleteAllByNumAttemptsesAndNextAttemptAts( - user: String, + user: java.util.UUID, numAttemptsesAndNextAttemptAts: Seq[(Int, org.joda.time.DateTime)] ): Unit = { db.withConnection { c => @@ -693,7 +693,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def deleteAllByNumAttemptsesAndNextAttemptAts( c: java.sql.Connection, - user: String, + user: java.util.UUID, numAttemptsesAndNextAttemptAts: Seq[(Int, org.joda.time.DateTime)] ): Unit = { DeleteQuery.in2(("num_attempts", "next_attempt_at"), numAttemptsesAndNextAttemptAts).execute(c) @@ -718,7 +718,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex } private def toNamedParameter( - user: String, + user: java.util.UUID, form: TaskForm ): Seq[anorm.NamedParameter] = { Seq( From 4decd94ffff956a4d087b84e6db28ad7f995a1a4 Mon Sep 17 00:00:00 2001 From: Michael Bryzek Date: Tue, 30 Jul 2024 22:52:35 +0200 Subject: [PATCH 10/25] wip --- dao/spec/psql-apibuilder.json | 2 +- .../app/db/GeneratorInvocationsDao.scala | 88 +++------- generated/app/db/TasksDao.scala | 158 +++++------------- 3 files changed, 73 insertions(+), 175 deletions(-) diff --git a/dao/spec/psql-apibuilder.json b/dao/spec/psql-apibuilder.json index 39791931d..0568de30b 100644 --- a/dao/spec/psql-apibuilder.json +++ b/dao/spec/psql-apibuilder.json @@ -17,7 +17,7 @@ "audit": { "created_at": { "type": "date-time-iso8601" }, "updated_at": { "type": "date-time-iso8601" }, - "updated_by_user_id": { "type": "string" } + "updated_by": { "name": "updated_by_guid", "type": "string" } } } } diff --git a/generated/app/db/GeneratorInvocationsDao.scala b/generated/app/db/GeneratorInvocationsDao.scala index 6f71224e3..5425a5c96 100644 --- a/generated/app/db/GeneratorInvocationsDao.scala +++ b/generated/app/db/GeneratorInvocationsDao.scala @@ -7,7 +7,7 @@ case class GeneratorInvocation( applicationKey: Option[String], createdAt: org.joda.time.DateTime, updatedAt: org.joda.time.DateTime, - updatedByUserId: String + updatedByGuid: String ) { def form: GeneratorInvocationForm = { GeneratorInvocationForm( @@ -60,15 +60,15 @@ case object GeneratorInvocationsTable { override val name: String = "updated_at" } - case object UpdatedByUserId extends Column { - override val name: String = "updated_by_user_id" + case object UpdatedByGuid extends Column { + override val name: String = "updated_by_guid" } case object HashCode extends Column { override val name: String = "hash_code" } - val all: List[Column] = List(Id, Key, OrganizationKey, ApplicationKey, CreatedAt, UpdatedAt, UpdatedByUserId, HashCode) + val all: List[Column] = List(Id, Key, OrganizationKey, ApplicationKey, CreatedAt, UpdatedAt, UpdatedByGuid, HashCode) } } @@ -89,7 +89,7 @@ trait BaseGeneratorInvocationsDao { | application_key, | created_at, | updated_at, - | updated_by_user_id, + | updated_by_guid, | hash_code | from public.generator_invocations |""".stripMargin.stripTrailing @@ -176,8 +176,8 @@ trait BaseGeneratorInvocationsDao { anorm.SqlParser.str("application_key").? ~ anorm.SqlParser.get[org.joda.time.DateTime]("created_at") ~ anorm.SqlParser.get[org.joda.time.DateTime]("updated_at") ~ - anorm.SqlParser.str("updated_by_user_id") ~ - anorm.SqlParser.long("hash_code") map { case id ~ key ~ organizationKey ~ applicationKey ~ createdAt ~ updatedAt ~ updatedByUserId ~ hashCode => + anorm.SqlParser.str("updated_by_guid") ~ + anorm.SqlParser.long("hash_code") map { case id ~ key ~ organizationKey ~ applicationKey ~ createdAt ~ updatedAt ~ updatedByGuid ~ hashCode => GeneratorInvocation( id = id, key = key, @@ -185,7 +185,7 @@ trait BaseGeneratorInvocationsDao { applicationKey = applicationKey, createdAt = createdAt, updatedAt = updatedAt, - updatedByUserId = updatedByUserId + updatedByGuid = updatedByGuid ) } } @@ -207,9 +207,9 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. private val InsertQuery: io.flow.postgresql.Query = { io.flow.postgresql.Query(""" | insert into public.generator_invocations - | (id, key, organization_key, application_key, created_at, updated_at, updated_by_user_id, hash_code) + | (id, key, organization_key, application_key, created_at, updated_at, updated_by_guid, hash_code) | values - | ({id}, {key}, {organization_key}, {application_key}, {created_at}::timestamptz, {updated_at}::timestamptz, {updated_by_user_id}, {hash_code}::bigint) + | ({id}, {key}, {organization_key}, {application_key}, {created_at}::timestamptz, {updated_at}::timestamptz, {updated_by_guid}, {hash_code}::bigint) """.stripMargin) } @@ -220,7 +220,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. | organization_key = {organization_key}, | application_key = {application_key}, | updated_at = {updated_at}::timestamptz, - | updated_by_user_id = {updated_by_user_id}, + | updated_by_guid = {updated_by_guid}, | hash_code = {hash_code}::bigint | where id = {id} and generator_invocations.hash_code != {hash_code}::bigint """.stripMargin) @@ -230,46 +230,37 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. io.flow.postgresql.Query("delete from public.generator_invocations") } - def insert( - user: java.util.UUID, - form: GeneratorInvocationForm - ): String = { + def insert(form: GeneratorInvocationForm): String = { db.withConnection { c => - insert(c, user, form) + insert(c, form) } } def insert( c: java.sql.Connection, - user: java.util.UUID, form: GeneratorInvocationForm ): String = { val id = randomId bindQuery(InsertQuery, form) .bind("created_at", org.joda.time.DateTime.now) - .bind("updated_by_user_id", user) .bind("id", id) .execute(c) id } - def insertBatch( - user: java.util.UUID, - forms: Seq[GeneratorInvocationForm] - ): Seq[String] = { + def insertBatch(forms: Seq[GeneratorInvocationForm]): Seq[String] = { db.withConnection { c => - insertBatch(c, user, forms) + insertBatch(c, forms) } } def insertBatch( c: java.sql.Connection, - user: java.util.UUID, forms: Seq[GeneratorInvocationForm] ): Seq[String] = { forms.map { f => val id = randomId - (id, Seq(anorm.NamedParameter("created_at", org.joda.time.DateTime.now)) ++ toNamedParameter(user, id, f)) + (id, Seq(anorm.NamedParameter("created_at", org.joda.time.DateTime.now)) ++ toNamedParameter(id, f)) }.toList match { case Nil => Nil case one :: rest => { @@ -280,122 +271,99 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. } def update( - user: java.util.UUID, generatorInvocation: GeneratorInvocation, form: GeneratorInvocationForm ): Unit = { db.withConnection { c => - update(c, user, generatorInvocation, form) + update(c, generatorInvocation, form) } } def update( c: java.sql.Connection, - user: java.util.UUID, generatorInvocation: GeneratorInvocation, form: GeneratorInvocationForm ): Unit = { updateById( c = c, - user = user, id = generatorInvocation.id, form = form ) } def updateById( - user: java.util.UUID, id: String, form: GeneratorInvocationForm ): Unit = { db.withConnection { c => - updateById(c, user, id, form) + updateById(c, id, form) } } def updateById( c: java.sql.Connection, - user: java.util.UUID, id: String, form: GeneratorInvocationForm ): Unit = { bindQuery(UpdateQuery, form) .bind("id", id) - .bind("updated_by_user_id", user) .execute(c) () } - def updateBatch( - user: java.util.UUID, - forms: Seq[(String, GeneratorInvocationForm)] - ): Unit = { + def updateBatch(forms: Seq[(String, GeneratorInvocationForm)]): Unit = { db.withConnection { c => - updateBatch(c, user, forms) + updateBatch(c, forms) } } def updateBatch( c: java.sql.Connection, - user: java.util.UUID, forms: Seq[(String, GeneratorInvocationForm)] ): Unit = { - forms.map { case (id, f) => toNamedParameter(user, id, f) }.toList match { + forms.map { case (id, f) => toNamedParameter(id, f) }.toList match { case Nil => // no-op case first :: rest => anorm.BatchSql(UpdateQuery.sql(), first, rest*).execute()(c) } } - def delete( - user: java.util.UUID, - generatorInvocation: GeneratorInvocation - ): Unit = { + def delete(generatorInvocation: GeneratorInvocation): Unit = { db.withConnection { c => - delete(c, user, generatorInvocation) + delete(c, generatorInvocation) } } def delete( c: java.sql.Connection, - user: java.util.UUID, generatorInvocation: GeneratorInvocation ): Unit = { deleteById( c = c, - user = user, id = generatorInvocation.id ) } - def deleteById( - user: java.util.UUID, - id: String - ): Unit = { + def deleteById(id: String): Unit = { db.withConnection { c => - deleteById(c, user, id) + deleteById(c, id) } } def deleteById( c: java.sql.Connection, - user: java.util.UUID, id: String ): Unit = { DeleteQuery.equals("id", id).execute(c) } - def deleteAllByIds( - user: java.util.UUID, - ids: Seq[String] - ): Unit = { + def deleteAllByIds(ids: Seq[String]): Unit = { db.withConnection { c => - deleteAllByIds(c, user, ids) + deleteAllByIds(c, ids) } } def deleteAllByIds( c: java.sql.Connection, - user: java.util.UUID, ids: Seq[String] ): Unit = { DeleteQuery.in("id", ids).execute(c) @@ -414,7 +382,6 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. } private def toNamedParameter( - user: java.util.UUID, id: String, form: GeneratorInvocationForm ): Seq[anorm.NamedParameter] = { @@ -424,7 +391,6 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. anorm.NamedParameter("organization_key", form.organizationKey), anorm.NamedParameter("application_key", form.applicationKey), anorm.NamedParameter("updated_at", org.joda.time.DateTime.now), - anorm.NamedParameter("updated_by_user_id", user), anorm.NamedParameter("hash_code", form.hashCode()) ) } diff --git a/generated/app/db/TasksDao.scala b/generated/app/db/TasksDao.scala index 1c59ee54a..0dd2a756c 100644 --- a/generated/app/db/TasksDao.scala +++ b/generated/app/db/TasksDao.scala @@ -12,7 +12,7 @@ case class Task( data: play.api.libs.json.JsValue, createdAt: org.joda.time.DateTime, updatedAt: org.joda.time.DateTime, - updatedByUserId: String + updatedByGuid: String ) { def form: TaskForm = { TaskForm( @@ -97,15 +97,15 @@ case object TasksTable { override val name: String = "updated_at" } - case object UpdatedByUserId extends Column { - override val name: String = "updated_by_user_id" + case object UpdatedByGuid extends Column { + override val name: String = "updated_by_guid" } case object HashCode extends Column { override val name: String = "hash_code" } - val all: List[Column] = List(Id, Type, TypeId, OrganizationGuid, NumAttempts, NextAttemptAt, Errors, Stacktrace, Data, CreatedAt, UpdatedAt, UpdatedByUserId, HashCode) + val all: List[Column] = List(Id, Type, TypeId, OrganizationGuid, NumAttempts, NextAttemptAt, Errors, Stacktrace, Data, CreatedAt, UpdatedAt, UpdatedByGuid, HashCode) } } @@ -131,7 +131,7 @@ trait BaseTasksDao { | data::text, | created_at, | updated_at, - | updated_by_user_id, + | updated_by_guid, | hash_code | from public.tasks |""".stripMargin.stripTrailing @@ -331,8 +331,8 @@ trait BaseTasksDao { anorm.SqlParser.str("data") ~ anorm.SqlParser.get[org.joda.time.DateTime]("created_at") ~ anorm.SqlParser.get[org.joda.time.DateTime]("updated_at") ~ - anorm.SqlParser.str("updated_by_user_id") ~ - anorm.SqlParser.long("hash_code") map { case id ~ type_ ~ typeId ~ organizationGuid ~ numAttempts ~ nextAttemptAt ~ errors ~ stacktrace ~ data ~ createdAt ~ updatedAt ~ updatedByUserId ~ hashCode => + anorm.SqlParser.str("updated_by_guid") ~ + anorm.SqlParser.long("hash_code") map { case id ~ type_ ~ typeId ~ organizationGuid ~ numAttempts ~ nextAttemptAt ~ errors ~ stacktrace ~ data ~ createdAt ~ updatedAt ~ updatedByGuid ~ hashCode => Task( id = id, `type` = type_, @@ -345,7 +345,7 @@ trait BaseTasksDao { data = play.api.libs.json.Json.parse(data), createdAt = createdAt, updatedAt = updatedAt, - updatedByUserId = updatedByUserId + updatedByGuid = updatedByGuid ) } } @@ -359,9 +359,9 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex private val UpsertQuery: io.flow.postgresql.Query = { io.flow.postgresql.Query(""" | insert into public.tasks - | (id, type, type_id, organization_guid, num_attempts, next_attempt_at, errors, stacktrace, data, created_at, updated_at, updated_by_user_id, hash_code) + | (id, type, type_id, organization_guid, num_attempts, next_attempt_at, errors, stacktrace, data, created_at, updated_at, updated_by_guid, hash_code) | values - | ({id}, {type}, {type_id}, {organization_guid}::uuid, {num_attempts}::integer, {next_attempt_at}::timestamptz, {errors}::json, {stacktrace}, {data}::json, {created_at}::timestamptz, {updated_at}::timestamptz, {updated_by_user_id}, {hash_code}::bigint) + | ({id}, {type}, {type_id}, {organization_guid}::uuid, {num_attempts}::integer, {next_attempt_at}::timestamptz, {errors}::json, {stacktrace}, {data}::json, {created_at}::timestamptz, {updated_at}::timestamptz, {updated_by_guid}, {hash_code}::bigint) | on conflict(type_id, type) do update | set organization_guid = {organization_guid}::uuid, | num_attempts = {num_attempts}::integer, @@ -370,7 +370,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex | stacktrace = {stacktrace}, | data = {data}::json, | updated_at = {updated_at}::timestamptz, - | updated_by_user_id = {updated_by_user_id}, + | updated_by_guid = {updated_by_guid}, | hash_code = {hash_code}::bigint | where tasks.hash_code != {hash_code}::bigint """.stripMargin) @@ -388,7 +388,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex | stacktrace = {stacktrace}, | data = {data}::json, | updated_at = {updated_at}::timestamptz, - | updated_by_user_id = {updated_by_user_id}, + | updated_by_guid = {updated_by_guid}, | hash_code = {hash_code}::bigint | where id = {id} and tasks.hash_code != {hash_code}::bigint """.stripMargin) @@ -398,41 +398,32 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex io.flow.postgresql.Query("delete from public.tasks") } - def upsertByTypeIdAndType( - user: java.util.UUID, - form: TaskForm - ): Unit = { + def upsertByTypeIdAndType(form: TaskForm): Unit = { db.withConnection { c => - upsertByTypeIdAndType(c, user, form) + upsertByTypeIdAndType(c, form) } } def upsertByTypeIdAndType( c: java.sql.Connection, - user: java.util.UUID, form: TaskForm ): Unit = { bindQuery(UpsertQuery, form) .bind("created_at", org.joda.time.DateTime.now) - .bind("updated_by_user_id", user) .execute(c) } - def upsertBatchByTypeIdAndType( - user: java.util.UUID, - forms: Seq[TaskForm] - ): Seq[Unit] = { + def upsertBatchByTypeIdAndType(forms: Seq[TaskForm]): Seq[Unit] = { db.withConnection { c => - upsertBatchByTypeIdAndType(c, user, forms) + upsertBatchByTypeIdAndType(c, forms) } } def upsertBatchByTypeIdAndType( c: java.sql.Connection, - user: java.util.UUID, forms: Seq[TaskForm] ): Seq[Unit] = { - forms.map { f => Seq(anorm.NamedParameter("created_at", org.joda.time.DateTime.now)) ++ toNamedParameter(user, f) }.toList match { + forms.map { f => Seq(anorm.NamedParameter("created_at", org.joda.time.DateTime.now)) ++ toNamedParameter(f) }.toList match { case Nil => Nil case one :: rest => { anorm.BatchSql(UpsertQuery.sql(), one, rest*).execute()(c) @@ -442,258 +433,203 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex } def update( - user: java.util.UUID, task: Task, form: TaskForm ): Unit = { db.withConnection { c => - update(c, user, task, form) + update(c, task, form) } } def update( c: java.sql.Connection, - user: java.util.UUID, task: Task, form: TaskForm ): Unit = { updateById( c = c, - user = user, id = task.id, form = form ) } def updateById( - user: java.util.UUID, id: String, form: TaskForm ): Unit = { db.withConnection { c => - updateById(c, user, id, form) + updateById(c, id, form) } } def updateById( c: java.sql.Connection, - user: java.util.UUID, id: String, form: TaskForm ): Unit = { bindQuery(UpdateQuery, form) .bind("id", id) - .bind("updated_by_user_id", user) .execute(c) () } - def updateBatch( - user: java.util.UUID, - forms: Seq[TaskForm] - ): Unit = { + def updateBatch(forms: Seq[TaskForm]): Unit = { db.withConnection { c => - updateBatch(c, user, forms) + updateBatch(c, forms) } } def updateBatch( c: java.sql.Connection, - user: java.util.UUID, forms: Seq[TaskForm] ): Unit = { - forms.map { f => toNamedParameter(user, f) }.toList match { + forms.map { f => toNamedParameter(f) }.toList match { case Nil => // no-op case first :: rest => anorm.BatchSql(UpdateQuery.sql(), first, rest*).execute()(c) } } - def delete( - user: java.util.UUID, - task: Task - ): Unit = { + def delete(task: Task): Unit = { db.withConnection { c => - delete(c, user, task) + delete(c, task) } } def delete( c: java.sql.Connection, - user: java.util.UUID, task: Task ): Unit = { deleteById( c = c, - user = user, id = task.id ) } - def deleteById( - user: java.util.UUID, - id: String - ): Unit = { + def deleteById(id: String): Unit = { db.withConnection { c => - deleteById(c, user, id) + deleteById(c, id) } } def deleteById( c: java.sql.Connection, - user: java.util.UUID, id: String ): Unit = { DeleteQuery.equals("id", id).execute(c) } - def deleteAllByIds( - user: java.util.UUID, - ids: Seq[String] - ): Unit = { + def deleteAllByIds(ids: Seq[String]): Unit = { db.withConnection { c => - deleteAllByIds(c, user, ids) + deleteAllByIds(c, ids) } } def deleteAllByIds( c: java.sql.Connection, - user: java.util.UUID, ids: Seq[String] ): Unit = { DeleteQuery.in("id", ids).execute(c) } - def deleteAllByTypeId( - user: java.util.UUID, - typeId: String - ): Unit = { + def deleteAllByTypeId(typeId: String): Unit = { db.withConnection { c => - deleteAllByTypeId(c, user, typeId) + deleteAllByTypeId(c, typeId) } } def deleteAllByTypeId( c: java.sql.Connection, - user: java.util.UUID, typeId: String ): Unit = { DeleteQuery.equals("type_id", typeId).execute(c) } - def deleteAllByTypeIds( - user: java.util.UUID, - typeIds: Seq[String] - ): Unit = { + def deleteAllByTypeIds(typeIds: Seq[String]): Unit = { db.withConnection { c => - deleteAllByTypeIds(c, user, typeIds) + deleteAllByTypeIds(c, typeIds) } } def deleteAllByTypeIds( c: java.sql.Connection, - user: java.util.UUID, typeIds: Seq[String] ): Unit = { DeleteQuery.in("type_id", typeIds).execute(c) } - def deleteByTypeIdAndType( - user: java.util.UUID, - typeIdAndType: (String, String) - ): Unit = { + def deleteByTypeIdAndType(typeIdAndType: (String, String)): Unit = { db.withConnection { c => - deleteByTypeIdAndType(c, user, typeIdAndType) + deleteByTypeIdAndType(c, typeIdAndType) } } def deleteByTypeIdAndType( c: java.sql.Connection, - user: java.util.UUID, typeIdAndType: (String, String) ): Unit = { DeleteQuery.in2(("type_id", "type"), Seq(typeIdAndType)).execute(c) } - def deleteAllByTypeIdsAndTypes( - user: java.util.UUID, - typeIdsAndTypes: Seq[(String, String)] - ): Unit = { + def deleteAllByTypeIdsAndTypes(typeIdsAndTypes: Seq[(String, String)]): Unit = { db.withConnection { c => - deleteAllByTypeIdsAndTypes(c, user, typeIdsAndTypes) + deleteAllByTypeIdsAndTypes(c, typeIdsAndTypes) } } def deleteAllByTypeIdsAndTypes( c: java.sql.Connection, - user: java.util.UUID, typeIdsAndTypes: Seq[(String, String)] ): Unit = { DeleteQuery.in2(("type_id", "type"), typeIdsAndTypes).execute(c) } - def deleteAllByNumAttempts( - user: java.util.UUID, - numAttempts: Int - ): Unit = { + def deleteAllByNumAttempts(numAttempts: Int): Unit = { db.withConnection { c => - deleteAllByNumAttempts(c, user, numAttempts) + deleteAllByNumAttempts(c, numAttempts) } } def deleteAllByNumAttempts( c: java.sql.Connection, - user: java.util.UUID, numAttempts: Int ): Unit = { DeleteQuery.equals("num_attempts", numAttempts).execute(c) } - def deleteAllByNumAttemptses( - user: java.util.UUID, - numAttemptses: Seq[Int] - ): Unit = { + def deleteAllByNumAttemptses(numAttemptses: Seq[Int]): Unit = { db.withConnection { c => - deleteAllByNumAttemptses(c, user, numAttemptses) + deleteAllByNumAttemptses(c, numAttemptses) } } def deleteAllByNumAttemptses( c: java.sql.Connection, - user: java.util.UUID, numAttemptses: Seq[Int] ): Unit = { DeleteQuery.in("num_attempts", numAttemptses).execute(c) } - def deleteAllByNumAttemptsAndNextAttemptAt( - user: java.util.UUID, - numAttemptsAndNextAttemptAt: (Int, org.joda.time.DateTime) - ): Unit = { + def deleteAllByNumAttemptsAndNextAttemptAt(numAttemptsAndNextAttemptAt: (Int, org.joda.time.DateTime)): Unit = { db.withConnection { c => - deleteAllByNumAttemptsAndNextAttemptAt(c, user, numAttemptsAndNextAttemptAt) + deleteAllByNumAttemptsAndNextAttemptAt(c, numAttemptsAndNextAttemptAt) } } def deleteAllByNumAttemptsAndNextAttemptAt( c: java.sql.Connection, - user: java.util.UUID, numAttemptsAndNextAttemptAt: (Int, org.joda.time.DateTime) ): Unit = { DeleteQuery.in2(("num_attempts", "next_attempt_at"), Seq(numAttemptsAndNextAttemptAt)).execute(c) } - def deleteAllByNumAttemptsesAndNextAttemptAts( - user: java.util.UUID, - numAttemptsesAndNextAttemptAts: Seq[(Int, org.joda.time.DateTime)] - ): Unit = { + def deleteAllByNumAttemptsesAndNextAttemptAts(numAttemptsesAndNextAttemptAts: Seq[(Int, org.joda.time.DateTime)]): Unit = { db.withConnection { c => - deleteAllByNumAttemptsesAndNextAttemptAts(c, user, numAttemptsesAndNextAttemptAts) + deleteAllByNumAttemptsesAndNextAttemptAts(c, numAttemptsesAndNextAttemptAts) } } def deleteAllByNumAttemptsesAndNextAttemptAts( c: java.sql.Connection, - user: java.util.UUID, numAttemptsesAndNextAttemptAts: Seq[(Int, org.joda.time.DateTime)] ): Unit = { DeleteQuery.in2(("num_attempts", "next_attempt_at"), numAttemptsesAndNextAttemptAts).execute(c) @@ -717,10 +653,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex .bind("hash_code", form.hashCode()) } - private def toNamedParameter( - user: java.util.UUID, - form: TaskForm - ): Seq[anorm.NamedParameter] = { + private def toNamedParameter(form: TaskForm): Seq[anorm.NamedParameter] = { Seq( anorm.NamedParameter("id", form.id), anorm.NamedParameter("type", form.`type`), @@ -732,7 +665,6 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex anorm.NamedParameter("stacktrace", form.stacktrace), anorm.NamedParameter("data", play.api.libs.json.Json.toJson(form.data).toString), anorm.NamedParameter("updated_at", org.joda.time.DateTime.now), - anorm.NamedParameter("updated_by_user_id", user), anorm.NamedParameter("hash_code", form.hashCode()) ) } From 996dc23fffb61a45d6568bcb87374568cbbb6377 Mon Sep 17 00:00:00 2001 From: Michael Bryzek Date: Tue, 30 Jul 2024 22:57:04 +0200 Subject: [PATCH 11/25] wip --- .../app/db/GeneratorInvocationsDao.scala | 66 ++++++--- generated/app/db/TasksDao.scala | 134 +++++++++++++----- 2 files changed, 151 insertions(+), 49 deletions(-) diff --git a/generated/app/db/GeneratorInvocationsDao.scala b/generated/app/db/GeneratorInvocationsDao.scala index 5425a5c96..eb4d955fd 100644 --- a/generated/app/db/GeneratorInvocationsDao.scala +++ b/generated/app/db/GeneratorInvocationsDao.scala @@ -230,37 +230,46 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. io.flow.postgresql.Query("delete from public.generator_invocations") } - def insert(form: GeneratorInvocationForm): String = { + def insert( + user: java.util.UUID, + form: GeneratorInvocationForm + ): String = { db.withConnection { c => - insert(c, form) + insert(c, user, form) } } def insert( c: java.sql.Connection, + user: java.util.UUID, form: GeneratorInvocationForm ): String = { val id = randomId bindQuery(InsertQuery, form) .bind("created_at", org.joda.time.DateTime.now) + .bind("updated_by_guid", user) .bind("id", id) .execute(c) id } - def insertBatch(forms: Seq[GeneratorInvocationForm]): Seq[String] = { + def insertBatch( + user: java.util.UUID, + forms: Seq[GeneratorInvocationForm] + ): Seq[String] = { db.withConnection { c => - insertBatch(c, forms) + insertBatch(c, user, forms) } } def insertBatch( c: java.sql.Connection, + user: java.util.UUID, forms: Seq[GeneratorInvocationForm] ): Seq[String] = { forms.map { f => val id = randomId - (id, Seq(anorm.NamedParameter("created_at", org.joda.time.DateTime.now)) ++ toNamedParameter(id, f)) + (id, Seq(anorm.NamedParameter("created_at", org.joda.time.DateTime.now)) ++ toNamedParameter(user, id, f)) }.toList match { case Nil => Nil case one :: rest => { @@ -271,99 +280,122 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. } def update( + user: java.util.UUID, generatorInvocation: GeneratorInvocation, form: GeneratorInvocationForm ): Unit = { db.withConnection { c => - update(c, generatorInvocation, form) + update(c, user, generatorInvocation, form) } } def update( c: java.sql.Connection, + user: java.util.UUID, generatorInvocation: GeneratorInvocation, form: GeneratorInvocationForm ): Unit = { updateById( c = c, + user = user, id = generatorInvocation.id, form = form ) } def updateById( + user: java.util.UUID, id: String, form: GeneratorInvocationForm ): Unit = { db.withConnection { c => - updateById(c, id, form) + updateById(c, user, id, form) } } def updateById( c: java.sql.Connection, + user: java.util.UUID, id: String, form: GeneratorInvocationForm ): Unit = { bindQuery(UpdateQuery, form) .bind("id", id) + .bind("updated_by_guid", user) .execute(c) () } - def updateBatch(forms: Seq[(String, GeneratorInvocationForm)]): Unit = { + def updateBatch( + user: java.util.UUID, + forms: Seq[(String, GeneratorInvocationForm)] + ): Unit = { db.withConnection { c => - updateBatch(c, forms) + updateBatch(c, user, forms) } } def updateBatch( c: java.sql.Connection, + user: java.util.UUID, forms: Seq[(String, GeneratorInvocationForm)] ): Unit = { - forms.map { case (id, f) => toNamedParameter(id, f) }.toList match { + forms.map { case (id, f) => toNamedParameter(user, id, f) }.toList match { case Nil => // no-op case first :: rest => anorm.BatchSql(UpdateQuery.sql(), first, rest*).execute()(c) } } - def delete(generatorInvocation: GeneratorInvocation): Unit = { + def delete( + user: java.util.UUID, + generatorInvocation: GeneratorInvocation + ): Unit = { db.withConnection { c => - delete(c, generatorInvocation) + delete(c, user, generatorInvocation) } } def delete( c: java.sql.Connection, + user: java.util.UUID, generatorInvocation: GeneratorInvocation ): Unit = { deleteById( c = c, + user = user, id = generatorInvocation.id ) } - def deleteById(id: String): Unit = { + def deleteById( + user: java.util.UUID, + id: String + ): Unit = { db.withConnection { c => - deleteById(c, id) + deleteById(c, user, id) } } def deleteById( c: java.sql.Connection, + user: java.util.UUID, id: String ): Unit = { DeleteQuery.equals("id", id).execute(c) } - def deleteAllByIds(ids: Seq[String]): Unit = { + def deleteAllByIds( + user: java.util.UUID, + ids: Seq[String] + ): Unit = { db.withConnection { c => - deleteAllByIds(c, ids) + deleteAllByIds(c, user, ids) } } def deleteAllByIds( c: java.sql.Connection, + user: java.util.UUID, ids: Seq[String] ): Unit = { DeleteQuery.in("id", ids).execute(c) @@ -382,6 +414,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. } private def toNamedParameter( + user: java.util.UUID, id: String, form: GeneratorInvocationForm ): Seq[anorm.NamedParameter] = { @@ -391,6 +424,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. anorm.NamedParameter("organization_key", form.organizationKey), anorm.NamedParameter("application_key", form.applicationKey), anorm.NamedParameter("updated_at", org.joda.time.DateTime.now), + anorm.NamedParameter("updated_by_guid", user), anorm.NamedParameter("hash_code", form.hashCode()) ) } diff --git a/generated/app/db/TasksDao.scala b/generated/app/db/TasksDao.scala index 0dd2a756c..78317e31d 100644 --- a/generated/app/db/TasksDao.scala +++ b/generated/app/db/TasksDao.scala @@ -398,32 +398,41 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex io.flow.postgresql.Query("delete from public.tasks") } - def upsertByTypeIdAndType(form: TaskForm): Unit = { + def upsertByTypeIdAndType( + user: java.util.UUID, + form: TaskForm + ): Unit = { db.withConnection { c => - upsertByTypeIdAndType(c, form) + upsertByTypeIdAndType(c, user, form) } } def upsertByTypeIdAndType( c: java.sql.Connection, + user: java.util.UUID, form: TaskForm ): Unit = { bindQuery(UpsertQuery, form) .bind("created_at", org.joda.time.DateTime.now) + .bind("updated_by_guid", user) .execute(c) } - def upsertBatchByTypeIdAndType(forms: Seq[TaskForm]): Seq[Unit] = { + def upsertBatchByTypeIdAndType( + user: java.util.UUID, + forms: Seq[TaskForm] + ): Seq[Unit] = { db.withConnection { c => - upsertBatchByTypeIdAndType(c, forms) + upsertBatchByTypeIdAndType(c, user, forms) } } def upsertBatchByTypeIdAndType( c: java.sql.Connection, + user: java.util.UUID, forms: Seq[TaskForm] ): Seq[Unit] = { - forms.map { f => Seq(anorm.NamedParameter("created_at", org.joda.time.DateTime.now)) ++ toNamedParameter(f) }.toList match { + forms.map { f => Seq(anorm.NamedParameter("created_at", org.joda.time.DateTime.now)) ++ toNamedParameter(user, f) }.toList match { case Nil => Nil case one :: rest => { anorm.BatchSql(UpsertQuery.sql(), one, rest*).execute()(c) @@ -433,203 +442,258 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex } def update( + user: java.util.UUID, task: Task, form: TaskForm ): Unit = { db.withConnection { c => - update(c, task, form) + update(c, user, task, form) } } def update( c: java.sql.Connection, + user: java.util.UUID, task: Task, form: TaskForm ): Unit = { updateById( c = c, + user = user, id = task.id, form = form ) } def updateById( + user: java.util.UUID, id: String, form: TaskForm ): Unit = { db.withConnection { c => - updateById(c, id, form) + updateById(c, user, id, form) } } def updateById( c: java.sql.Connection, + user: java.util.UUID, id: String, form: TaskForm ): Unit = { bindQuery(UpdateQuery, form) .bind("id", id) + .bind("updated_by_guid", user) .execute(c) () } - def updateBatch(forms: Seq[TaskForm]): Unit = { + def updateBatch( + user: java.util.UUID, + forms: Seq[TaskForm] + ): Unit = { db.withConnection { c => - updateBatch(c, forms) + updateBatch(c, user, forms) } } def updateBatch( c: java.sql.Connection, + user: java.util.UUID, forms: Seq[TaskForm] ): Unit = { - forms.map { f => toNamedParameter(f) }.toList match { + forms.map { f => toNamedParameter(user, f) }.toList match { case Nil => // no-op case first :: rest => anorm.BatchSql(UpdateQuery.sql(), first, rest*).execute()(c) } } - def delete(task: Task): Unit = { + def delete( + user: java.util.UUID, + task: Task + ): Unit = { db.withConnection { c => - delete(c, task) + delete(c, user, task) } } def delete( c: java.sql.Connection, + user: java.util.UUID, task: Task ): Unit = { deleteById( c = c, + user = user, id = task.id ) } - def deleteById(id: String): Unit = { + def deleteById( + user: java.util.UUID, + id: String + ): Unit = { db.withConnection { c => - deleteById(c, id) + deleteById(c, user, id) } } def deleteById( c: java.sql.Connection, + user: java.util.UUID, id: String ): Unit = { DeleteQuery.equals("id", id).execute(c) } - def deleteAllByIds(ids: Seq[String]): Unit = { + def deleteAllByIds( + user: java.util.UUID, + ids: Seq[String] + ): Unit = { db.withConnection { c => - deleteAllByIds(c, ids) + deleteAllByIds(c, user, ids) } } def deleteAllByIds( c: java.sql.Connection, + user: java.util.UUID, ids: Seq[String] ): Unit = { DeleteQuery.in("id", ids).execute(c) } - def deleteAllByTypeId(typeId: String): Unit = { + def deleteAllByTypeId( + user: java.util.UUID, + typeId: String + ): Unit = { db.withConnection { c => - deleteAllByTypeId(c, typeId) + deleteAllByTypeId(c, user, typeId) } } def deleteAllByTypeId( c: java.sql.Connection, + user: java.util.UUID, typeId: String ): Unit = { DeleteQuery.equals("type_id", typeId).execute(c) } - def deleteAllByTypeIds(typeIds: Seq[String]): Unit = { + def deleteAllByTypeIds( + user: java.util.UUID, + typeIds: Seq[String] + ): Unit = { db.withConnection { c => - deleteAllByTypeIds(c, typeIds) + deleteAllByTypeIds(c, user, typeIds) } } def deleteAllByTypeIds( c: java.sql.Connection, + user: java.util.UUID, typeIds: Seq[String] ): Unit = { DeleteQuery.in("type_id", typeIds).execute(c) } - def deleteByTypeIdAndType(typeIdAndType: (String, String)): Unit = { + def deleteByTypeIdAndType( + user: java.util.UUID, + typeIdAndType: (String, String) + ): Unit = { db.withConnection { c => - deleteByTypeIdAndType(c, typeIdAndType) + deleteByTypeIdAndType(c, user, typeIdAndType) } } def deleteByTypeIdAndType( c: java.sql.Connection, + user: java.util.UUID, typeIdAndType: (String, String) ): Unit = { DeleteQuery.in2(("type_id", "type"), Seq(typeIdAndType)).execute(c) } - def deleteAllByTypeIdsAndTypes(typeIdsAndTypes: Seq[(String, String)]): Unit = { + def deleteAllByTypeIdsAndTypes( + user: java.util.UUID, + typeIdsAndTypes: Seq[(String, String)] + ): Unit = { db.withConnection { c => - deleteAllByTypeIdsAndTypes(c, typeIdsAndTypes) + deleteAllByTypeIdsAndTypes(c, user, typeIdsAndTypes) } } def deleteAllByTypeIdsAndTypes( c: java.sql.Connection, + user: java.util.UUID, typeIdsAndTypes: Seq[(String, String)] ): Unit = { DeleteQuery.in2(("type_id", "type"), typeIdsAndTypes).execute(c) } - def deleteAllByNumAttempts(numAttempts: Int): Unit = { + def deleteAllByNumAttempts( + user: java.util.UUID, + numAttempts: Int + ): Unit = { db.withConnection { c => - deleteAllByNumAttempts(c, numAttempts) + deleteAllByNumAttempts(c, user, numAttempts) } } def deleteAllByNumAttempts( c: java.sql.Connection, + user: java.util.UUID, numAttempts: Int ): Unit = { DeleteQuery.equals("num_attempts", numAttempts).execute(c) } - def deleteAllByNumAttemptses(numAttemptses: Seq[Int]): Unit = { + def deleteAllByNumAttemptses( + user: java.util.UUID, + numAttemptses: Seq[Int] + ): Unit = { db.withConnection { c => - deleteAllByNumAttemptses(c, numAttemptses) + deleteAllByNumAttemptses(c, user, numAttemptses) } } def deleteAllByNumAttemptses( c: java.sql.Connection, + user: java.util.UUID, numAttemptses: Seq[Int] ): Unit = { DeleteQuery.in("num_attempts", numAttemptses).execute(c) } - def deleteAllByNumAttemptsAndNextAttemptAt(numAttemptsAndNextAttemptAt: (Int, org.joda.time.DateTime)): Unit = { + def deleteAllByNumAttemptsAndNextAttemptAt( + user: java.util.UUID, + numAttemptsAndNextAttemptAt: (Int, org.joda.time.DateTime) + ): Unit = { db.withConnection { c => - deleteAllByNumAttemptsAndNextAttemptAt(c, numAttemptsAndNextAttemptAt) + deleteAllByNumAttemptsAndNextAttemptAt(c, user, numAttemptsAndNextAttemptAt) } } def deleteAllByNumAttemptsAndNextAttemptAt( c: java.sql.Connection, + user: java.util.UUID, numAttemptsAndNextAttemptAt: (Int, org.joda.time.DateTime) ): Unit = { DeleteQuery.in2(("num_attempts", "next_attempt_at"), Seq(numAttemptsAndNextAttemptAt)).execute(c) } - def deleteAllByNumAttemptsesAndNextAttemptAts(numAttemptsesAndNextAttemptAts: Seq[(Int, org.joda.time.DateTime)]): Unit = { + def deleteAllByNumAttemptsesAndNextAttemptAts( + user: java.util.UUID, + numAttemptsesAndNextAttemptAts: Seq[(Int, org.joda.time.DateTime)] + ): Unit = { db.withConnection { c => - deleteAllByNumAttemptsesAndNextAttemptAts(c, numAttemptsesAndNextAttemptAts) + deleteAllByNumAttemptsesAndNextAttemptAts(c, user, numAttemptsesAndNextAttemptAts) } } def deleteAllByNumAttemptsesAndNextAttemptAts( c: java.sql.Connection, + user: java.util.UUID, numAttemptsesAndNextAttemptAts: Seq[(Int, org.joda.time.DateTime)] ): Unit = { DeleteQuery.in2(("num_attempts", "next_attempt_at"), numAttemptsesAndNextAttemptAts).execute(c) @@ -653,7 +717,10 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex .bind("hash_code", form.hashCode()) } - private def toNamedParameter(form: TaskForm): Seq[anorm.NamedParameter] = { + private def toNamedParameter( + user: java.util.UUID, + form: TaskForm + ): Seq[anorm.NamedParameter] = { Seq( anorm.NamedParameter("id", form.id), anorm.NamedParameter("type", form.`type`), @@ -665,6 +732,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex anorm.NamedParameter("stacktrace", form.stacktrace), anorm.NamedParameter("data", play.api.libs.json.Json.toJson(form.data).toString), anorm.NamedParameter("updated_at", org.joda.time.DateTime.now), + anorm.NamedParameter("updated_by_guid", user), anorm.NamedParameter("hash_code", form.hashCode()) ) } From 2237781ddb9db8069a62970fe967cd12e9442e11 Mon Sep 17 00:00:00 2001 From: Michael Bryzek Date: Wed, 31 Jul 2024 11:52:18 +0200 Subject: [PATCH 12/25] wip --- dao/spec/psql-apibuilder.json | 10 +++++++--- generated/app/db/GeneratorInvocationsDao.scala | 7 ++++--- generated/app/db/TasksDao.scala | 7 ++++--- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/dao/spec/psql-apibuilder.json b/dao/spec/psql-apibuilder.json index 0568de30b..a087b0f29 100644 --- a/dao/spec/psql-apibuilder.json +++ b/dao/spec/psql-apibuilder.json @@ -15,9 +15,13 @@ "pkey": "id", "hash_code": {}, "audit": { - "created_at": { "type": "date-time-iso8601" }, - "updated_at": { "type": "date-time-iso8601" }, - "updated_by": { "name": "updated_by_guid", "type": "string" } + "created": { + "at": { "type": "date-time-iso8601" } + }, + "updated": { + "at": { "type": "date-time-iso8601" }, + "by": { "name": "updated_by_guid", "type": "string" } + } } } } diff --git a/generated/app/db/GeneratorInvocationsDao.scala b/generated/app/db/GeneratorInvocationsDao.scala index eb4d955fd..4a841da8a 100644 --- a/generated/app/db/GeneratorInvocationsDao.scala +++ b/generated/app/db/GeneratorInvocationsDao.scala @@ -245,9 +245,8 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. form: GeneratorInvocationForm ): String = { val id = randomId - bindQuery(InsertQuery, form) + bindQuery(InsertQuery,user, form) .bind("created_at", org.joda.time.DateTime.now) - .bind("updated_by_guid", user) .bind("id", id) .execute(c) id @@ -319,7 +318,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. id: String, form: GeneratorInvocationForm ): Unit = { - bindQuery(UpdateQuery, form) + bindQuery(UpdateQuery,user, form) .bind("id", id) .bind("updated_by_guid", user) .execute(c) @@ -403,6 +402,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. private def bindQuery( query: io.flow.postgresql.Query, + user: java.util.UUID, form: GeneratorInvocationForm ): io.flow.postgresql.Query = { query @@ -410,6 +410,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. .bind("organization_key", form.organizationKey) .bind("application_key", form.applicationKey) .bind("updated_at", org.joda.time.DateTime.now) + .bind("updated_by_guid", user) .bind("hash_code", form.hashCode()) } diff --git a/generated/app/db/TasksDao.scala b/generated/app/db/TasksDao.scala index 78317e31d..5057feb54 100644 --- a/generated/app/db/TasksDao.scala +++ b/generated/app/db/TasksDao.scala @@ -412,9 +412,8 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex user: java.util.UUID, form: TaskForm ): Unit = { - bindQuery(UpsertQuery, form) + bindQuery(UpsertQuery,user, form) .bind("created_at", org.joda.time.DateTime.now) - .bind("updated_by_guid", user) .execute(c) } @@ -481,7 +480,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex id: String, form: TaskForm ): Unit = { - bindQuery(UpdateQuery, form) + bindQuery(UpdateQuery,user, form) .bind("id", id) .bind("updated_by_guid", user) .execute(c) @@ -701,6 +700,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex private def bindQuery( query: io.flow.postgresql.Query, + user: java.util.UUID, form: TaskForm ): io.flow.postgresql.Query = { query @@ -714,6 +714,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex .bind("stacktrace", form.stacktrace) .bind("data", play.api.libs.json.Json.toJson(form.data).toString) .bind("updated_at", org.joda.time.DateTime.now) + .bind("updated_by_guid", user) .bind("hash_code", form.hashCode()) } From 38914e5da89125b319c9dab2308fb70e52a12d45 Mon Sep 17 00:00:00 2001 From: Michael Bryzek Date: Wed, 31 Jul 2024 12:13:06 +0200 Subject: [PATCH 13/25] wip --- dao/spec/psql-apibuilder.json | 40 ++- .../db/GeneratorApibuilderSessionsDao.scala | 231 ------------------ .../app/db/GeneratorInvocationsDao.scala | 36 +-- generated/app/db/TasksDao.scala | 68 +++--- 4 files changed, 85 insertions(+), 290 deletions(-) delete mode 100644 generated/app/db/GeneratorApibuilderSessionsDao.scala diff --git a/dao/spec/psql-apibuilder.json b/dao/spec/psql-apibuilder.json index a087b0f29..43ab3df54 100644 --- a/dao/spec/psql-apibuilder.json +++ b/dao/spec/psql-apibuilder.json @@ -6,7 +6,7 @@ "value": { "version": "3.4", "package": "db.generated", - "user_class": "java.util.UUID" + "user_class": "uuid" } }, { @@ -75,12 +75,6 @@ { "name": "data", "type": "json" } ], "attributes": [ - { - "name": "scala", - "value": { - "order_by": { "optional": true } - } - }, { "name": "psql", "value": { @@ -93,6 +87,38 @@ } } ] + }, + + "session": { + "fields": [ + { "name": "id", "type": "string" }, + { "name": "user_guid", "type": "uuid" }, + { "name": "expires_at", "type": "date-time-iso8601" } + ], + "attributes": [ + { + "name": "psql", + "value": { + "indexes": [ + { "fields": ["user_guid"] } + ], + "audit": { + "created": { + "at": { "type": "date-time-iso8601" }, + "by": { "name": "updated_by_guid", "type": "uuid" } + }, + "updated": { + "at": { "type": "date-time-iso8601" }, + "by": { "name": "updated_by_guid", "type": "uuid" } + }, + "deleted": { + "at": { "type": "date-time-iso8601" }, + "by": { "name": "updated_by_guid", "type": "uuid" } + } + } + } + } + ] } } } diff --git a/generated/app/db/GeneratorApibuilderSessionsDao.scala b/generated/app/db/GeneratorApibuilderSessionsDao.scala deleted file mode 100644 index 627465261..000000000 --- a/generated/app/db/GeneratorApibuilderSessionsDao.scala +++ /dev/null @@ -1,231 +0,0 @@ -package db.generated - -import anorm._ -import io.flow.postgresql.{OrderBy, Query} -import java.sql.Connection -import java.util.UUID -import javax.inject.{Inject, Singleton} -import org.joda.time.DateTime -import play.api.db.{Database, NamedDatabase} - -case class Session( - id: String, - userGuid: UUID, - expiresAt: DateTime, - createdAt: DateTime, - createdByGuid: UUID, - updatedAt: DateTime, - updatedByGuid: UUID, - deletedAt: Option[DateTime], - deletedByGuid: Option[UUID] -) { - - lazy val form: SessionForm = SessionForm( - id = id, - userGuid = userGuid, - expiresAt = expiresAt, - createdAt = createdAt, - createdByGuid = createdByGuid, - updatedAt = updatedAt, - updatedByGuid = updatedByGuid, - deletedAt = deletedAt, - deletedByGuid = deletedByGuid - ) - -} - -case class SessionForm( - id: String, - userGuid: UUID, - expiresAt: DateTime, - createdAt: DateTime, - createdByGuid: UUID, - updatedAt: DateTime, - updatedByGuid: UUID, - deletedAt: Option[DateTime], - deletedByGuid: Option[UUID] -) - -@Singleton -class SessionsDao @Inject() ( - @NamedDatabase("default") db: Database -) { - - private val BaseQuery = Query(""" - | select sessions.id, - | sessions.user_guid, - | sessions.expires_at, - | sessions.created_at, - | sessions.created_by_guid, - | sessions.updated_at, - | sessions.updated_by_guid, - | sessions.deleted_at, - | sessions.deleted_by_guid, - | sessions.hash_code - | from sessions - """.stripMargin) - - private val InsertQuery = Query(""" - | insert into sessions - | (id, user_guid, expires_at, created_at, created_by_guid, updated_at, updated_by_guid, deleted_at, deleted_by_guid, hash_code) - | values - | ({id}, {user_guid}::uuid, {expires_at}::timestamptz, {created_at}::timestamptz, {created_by_guid}::uuid, {updated_at}::timestamptz, {updated_by_guid}::uuid, {deleted_at}::timestamptz, {deleted_by_guid}::uuid, {hash_code}::bigint) - """.stripMargin) - - private val UpdateQuery = Query(""" - | update sessions - | set user_guid = {user_guid}::uuid, - | expires_at = {expires_at}::timestamptz, - | created_at = {created_at}::timestamptz, - | created_by_guid = {created_by_guid}::uuid, - | updated_at = {updated_at}::timestamptz, - | updated_by_guid = {updated_by_guid}::uuid, - | deleted_at = {deleted_at}::timestamptz, - | deleted_by_guid = {deleted_by_guid}::uuid, - | hash_code = {hash_code}::bigint - | where id = {id} - | and (sessions.hash_code is null or sessions.hash_code != {hash_code}::bigint) - """.stripMargin) - - private def bindQuery(query: Query, form: SessionForm): Query = { - query. - bind("user_guid", form.userGuid). - bind("expires_at", form.expiresAt). - bind("created_at", form.createdAt). - bind("created_by_guid", form.createdByGuid). - bind("updated_at", form.updatedAt). - bind("updated_by_guid", form.updatedByGuid). - bind("deleted_at", form.deletedAt). - bind("deleted_by_guid", form.deletedByGuid). - bind("hash_code", form.hashCode()) - } - - def insert(updatedBy: UUID, form: SessionForm): Unit = { - db.withConnection { implicit c => - insert(c, updatedBy, form) - } - } - - def insert(implicit c: Connection, updatedBy: UUID, form: SessionForm): Unit = { - bindQuery(InsertQuery, form). - bind("id", form.id). - anormSql().execute() - } - - def updateIfChangedById(updatedBy: UUID, id: String, form: SessionForm): Unit ={ - if (!findById(id).map(_.form).contains(form)) { - updateById(updatedBy, id, form) - } - } - - def updateById(updatedBy: UUID, id: String, form: SessionForm): Unit = { - db.withConnection { implicit c => - updateById(c, updatedBy, id, form) - } - } - - def updateById(implicit c: Connection, updatedBy: UUID, id: String, form: SessionForm): Unit = { - bindQuery(UpdateQuery, form). - bind("id", id). - anormSql().execute() - } - - def update(updatedBy: UUID, existing: Session, form: SessionForm): Unit = { - db.withConnection { implicit c => - update(c, updatedBy, existing, form) - } - } - - def update(implicit c: Connection, updatedBy: UUID, existing: Session, form: SessionForm): Unit = { - updateById(c, updatedBy, existing.id, form) - } - - def delete(deletedBy: UUID, session: Session): Unit = ??? - - def deleteById(deletedBy: UUID, id: String): Unit = { - db.withConnection { implicit c => - deleteById(c, deletedBy, id) - } - } - - def deleteById(c: java.sql.Connection, deletedBy: UUID, id: String): Unit = ??? - - def findById(id: String): Option[Session] = { - db.withConnection { implicit c => - findByIdWithConnection(c, id) - } - } - - def findByIdWithConnection(c: java.sql.Connection, id: String): Option[Session] = { - findAllWithConnection(c, ids = Some(Seq(id)), limit = 1).headOption - } - - def findAll( - ids: Option[Seq[String]] = None, - userGuid: Option[UUID] = None, - limit: Long, - offset: Long = 0, - orderBy: OrderBy = OrderBy("sessions.id") - ) ( - implicit customQueryModifier: Query => Query = { q => q } - ): Seq[Session] = { - db.withConnection { implicit c => - findAllWithConnection( - c, - ids = ids, - userGuid = userGuid, - limit = limit, - offset = offset, - orderBy = orderBy - )(customQueryModifier) - } - } - - def findAllWithConnection( - c: java.sql.Connection, - ids: Option[Seq[String]] = None, - userGuid: Option[UUID] = None, - limit: Long, - offset: Long = 0, - orderBy: OrderBy = OrderBy("sessions.id") - ) ( - implicit customQueryModifier: Query => Query = { q => q } - ): Seq[Session] = { - customQueryModifier(BaseQuery). - optionalIn("sessions.id", ids). - equals("sessions.user_guid", userGuid). - limit(limit). - offset(offset). - orderBy(orderBy.sql). - as(SessionsDao.parser().*)(c) - } - -} - -object SessionsDao { - - def parser(): RowParser[Session] = { - SqlParser.str("id") ~ - SqlParser.get[UUID]("user_guid") ~ - SqlParser.get[DateTime]("expires_at") ~ - SqlParser.get[DateTime]("created_at") ~ - SqlParser.get[UUID]("created_by_guid") ~ - SqlParser.get[DateTime]("updated_at") ~ - SqlParser.get[UUID]("updated_by_guid") ~ - SqlParser.get[DateTime]("deleted_at").? ~ - SqlParser.get[UUID]("deleted_by_guid").? map { - case id ~ userGuid ~ expiresAt ~ createdAt ~ createdByGuid ~ updatedAt ~ updatedByGuid ~ deletedAt ~ deletedByGuid => Session( - id = id, - userGuid = userGuid, - expiresAt = expiresAt, - createdAt = createdAt, - createdByGuid = createdByGuid, - updatedAt = updatedAt, - updatedByGuid = updatedByGuid, - deletedAt = deletedAt, - deletedByGuid = deletedByGuid - ) - } - } - -} \ No newline at end of file diff --git a/generated/app/db/GeneratorInvocationsDao.scala b/generated/app/db/GeneratorInvocationsDao.scala index 4a841da8a..2a2884217 100644 --- a/generated/app/db/GeneratorInvocationsDao.scala +++ b/generated/app/db/GeneratorInvocationsDao.scala @@ -231,7 +231,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. } def insert( - user: java.util.UUID, + user: uuid, form: GeneratorInvocationForm ): String = { db.withConnection { c => @@ -241,7 +241,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. def insert( c: java.sql.Connection, - user: java.util.UUID, + user: uuid, form: GeneratorInvocationForm ): String = { val id = randomId @@ -253,7 +253,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. } def insertBatch( - user: java.util.UUID, + user: uuid, forms: Seq[GeneratorInvocationForm] ): Seq[String] = { db.withConnection { c => @@ -263,7 +263,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. def insertBatch( c: java.sql.Connection, - user: java.util.UUID, + user: uuid, forms: Seq[GeneratorInvocationForm] ): Seq[String] = { forms.map { f => @@ -279,7 +279,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. } def update( - user: java.util.UUID, + user: uuid, generatorInvocation: GeneratorInvocation, form: GeneratorInvocationForm ): Unit = { @@ -290,7 +290,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. def update( c: java.sql.Connection, - user: java.util.UUID, + user: uuid, generatorInvocation: GeneratorInvocation, form: GeneratorInvocationForm ): Unit = { @@ -303,7 +303,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. } def updateById( - user: java.util.UUID, + user: uuid, id: String, form: GeneratorInvocationForm ): Unit = { @@ -314,7 +314,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. def updateById( c: java.sql.Connection, - user: java.util.UUID, + user: uuid, id: String, form: GeneratorInvocationForm ): Unit = { @@ -326,7 +326,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. } def updateBatch( - user: java.util.UUID, + user: uuid, forms: Seq[(String, GeneratorInvocationForm)] ): Unit = { db.withConnection { c => @@ -336,7 +336,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. def updateBatch( c: java.sql.Connection, - user: java.util.UUID, + user: uuid, forms: Seq[(String, GeneratorInvocationForm)] ): Unit = { forms.map { case (id, f) => toNamedParameter(user, id, f) }.toList match { @@ -346,7 +346,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. } def delete( - user: java.util.UUID, + user: uuid, generatorInvocation: GeneratorInvocation ): Unit = { db.withConnection { c => @@ -356,7 +356,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. def delete( c: java.sql.Connection, - user: java.util.UUID, + user: uuid, generatorInvocation: GeneratorInvocation ): Unit = { deleteById( @@ -367,7 +367,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. } def deleteById( - user: java.util.UUID, + user: uuid, id: String ): Unit = { db.withConnection { c => @@ -377,14 +377,14 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. def deleteById( c: java.sql.Connection, - user: java.util.UUID, + user: uuid, id: String ): Unit = { DeleteQuery.equals("id", id).execute(c) } def deleteAllByIds( - user: java.util.UUID, + user: uuid, ids: Seq[String] ): Unit = { db.withConnection { c => @@ -394,7 +394,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. def deleteAllByIds( c: java.sql.Connection, - user: java.util.UUID, + user: uuid, ids: Seq[String] ): Unit = { DeleteQuery.in("id", ids).execute(c) @@ -402,7 +402,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. private def bindQuery( query: io.flow.postgresql.Query, - user: java.util.UUID, + user: uuid, form: GeneratorInvocationForm ): io.flow.postgresql.Query = { query @@ -415,7 +415,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. } private def toNamedParameter( - user: java.util.UUID, + user: uuid, id: String, form: GeneratorInvocationForm ): Seq[anorm.NamedParameter] = { diff --git a/generated/app/db/TasksDao.scala b/generated/app/db/TasksDao.scala index 5057feb54..3db74dd8f 100644 --- a/generated/app/db/TasksDao.scala +++ b/generated/app/db/TasksDao.scala @@ -399,7 +399,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex } def upsertByTypeIdAndType( - user: java.util.UUID, + user: uuid, form: TaskForm ): Unit = { db.withConnection { c => @@ -409,7 +409,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def upsertByTypeIdAndType( c: java.sql.Connection, - user: java.util.UUID, + user: uuid, form: TaskForm ): Unit = { bindQuery(UpsertQuery,user, form) @@ -418,7 +418,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex } def upsertBatchByTypeIdAndType( - user: java.util.UUID, + user: uuid, forms: Seq[TaskForm] ): Seq[Unit] = { db.withConnection { c => @@ -428,7 +428,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def upsertBatchByTypeIdAndType( c: java.sql.Connection, - user: java.util.UUID, + user: uuid, forms: Seq[TaskForm] ): Seq[Unit] = { forms.map { f => Seq(anorm.NamedParameter("created_at", org.joda.time.DateTime.now)) ++ toNamedParameter(user, f) }.toList match { @@ -441,7 +441,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex } def update( - user: java.util.UUID, + user: uuid, task: Task, form: TaskForm ): Unit = { @@ -452,7 +452,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def update( c: java.sql.Connection, - user: java.util.UUID, + user: uuid, task: Task, form: TaskForm ): Unit = { @@ -465,7 +465,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex } def updateById( - user: java.util.UUID, + user: uuid, id: String, form: TaskForm ): Unit = { @@ -476,7 +476,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def updateById( c: java.sql.Connection, - user: java.util.UUID, + user: uuid, id: String, form: TaskForm ): Unit = { @@ -488,7 +488,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex } def updateBatch( - user: java.util.UUID, + user: uuid, forms: Seq[TaskForm] ): Unit = { db.withConnection { c => @@ -498,7 +498,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def updateBatch( c: java.sql.Connection, - user: java.util.UUID, + user: uuid, forms: Seq[TaskForm] ): Unit = { forms.map { f => toNamedParameter(user, f) }.toList match { @@ -508,7 +508,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex } def delete( - user: java.util.UUID, + user: uuid, task: Task ): Unit = { db.withConnection { c => @@ -518,7 +518,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def delete( c: java.sql.Connection, - user: java.util.UUID, + user: uuid, task: Task ): Unit = { deleteById( @@ -529,7 +529,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex } def deleteById( - user: java.util.UUID, + user: uuid, id: String ): Unit = { db.withConnection { c => @@ -539,14 +539,14 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def deleteById( c: java.sql.Connection, - user: java.util.UUID, + user: uuid, id: String ): Unit = { DeleteQuery.equals("id", id).execute(c) } def deleteAllByIds( - user: java.util.UUID, + user: uuid, ids: Seq[String] ): Unit = { db.withConnection { c => @@ -556,14 +556,14 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def deleteAllByIds( c: java.sql.Connection, - user: java.util.UUID, + user: uuid, ids: Seq[String] ): Unit = { DeleteQuery.in("id", ids).execute(c) } def deleteAllByTypeId( - user: java.util.UUID, + user: uuid, typeId: String ): Unit = { db.withConnection { c => @@ -573,14 +573,14 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def deleteAllByTypeId( c: java.sql.Connection, - user: java.util.UUID, + user: uuid, typeId: String ): Unit = { DeleteQuery.equals("type_id", typeId).execute(c) } def deleteAllByTypeIds( - user: java.util.UUID, + user: uuid, typeIds: Seq[String] ): Unit = { db.withConnection { c => @@ -590,14 +590,14 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def deleteAllByTypeIds( c: java.sql.Connection, - user: java.util.UUID, + user: uuid, typeIds: Seq[String] ): Unit = { DeleteQuery.in("type_id", typeIds).execute(c) } def deleteByTypeIdAndType( - user: java.util.UUID, + user: uuid, typeIdAndType: (String, String) ): Unit = { db.withConnection { c => @@ -607,14 +607,14 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def deleteByTypeIdAndType( c: java.sql.Connection, - user: java.util.UUID, + user: uuid, typeIdAndType: (String, String) ): Unit = { DeleteQuery.in2(("type_id", "type"), Seq(typeIdAndType)).execute(c) } def deleteAllByTypeIdsAndTypes( - user: java.util.UUID, + user: uuid, typeIdsAndTypes: Seq[(String, String)] ): Unit = { db.withConnection { c => @@ -624,14 +624,14 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def deleteAllByTypeIdsAndTypes( c: java.sql.Connection, - user: java.util.UUID, + user: uuid, typeIdsAndTypes: Seq[(String, String)] ): Unit = { DeleteQuery.in2(("type_id", "type"), typeIdsAndTypes).execute(c) } def deleteAllByNumAttempts( - user: java.util.UUID, + user: uuid, numAttempts: Int ): Unit = { db.withConnection { c => @@ -641,14 +641,14 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def deleteAllByNumAttempts( c: java.sql.Connection, - user: java.util.UUID, + user: uuid, numAttempts: Int ): Unit = { DeleteQuery.equals("num_attempts", numAttempts).execute(c) } def deleteAllByNumAttemptses( - user: java.util.UUID, + user: uuid, numAttemptses: Seq[Int] ): Unit = { db.withConnection { c => @@ -658,14 +658,14 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def deleteAllByNumAttemptses( c: java.sql.Connection, - user: java.util.UUID, + user: uuid, numAttemptses: Seq[Int] ): Unit = { DeleteQuery.in("num_attempts", numAttemptses).execute(c) } def deleteAllByNumAttemptsAndNextAttemptAt( - user: java.util.UUID, + user: uuid, numAttemptsAndNextAttemptAt: (Int, org.joda.time.DateTime) ): Unit = { db.withConnection { c => @@ -675,14 +675,14 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def deleteAllByNumAttemptsAndNextAttemptAt( c: java.sql.Connection, - user: java.util.UUID, + user: uuid, numAttemptsAndNextAttemptAt: (Int, org.joda.time.DateTime) ): Unit = { DeleteQuery.in2(("num_attempts", "next_attempt_at"), Seq(numAttemptsAndNextAttemptAt)).execute(c) } def deleteAllByNumAttemptsesAndNextAttemptAts( - user: java.util.UUID, + user: uuid, numAttemptsesAndNextAttemptAts: Seq[(Int, org.joda.time.DateTime)] ): Unit = { db.withConnection { c => @@ -692,7 +692,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def deleteAllByNumAttemptsesAndNextAttemptAts( c: java.sql.Connection, - user: java.util.UUID, + user: uuid, numAttemptsesAndNextAttemptAts: Seq[(Int, org.joda.time.DateTime)] ): Unit = { DeleteQuery.in2(("num_attempts", "next_attempt_at"), numAttemptsesAndNextAttemptAts).execute(c) @@ -700,7 +700,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex private def bindQuery( query: io.flow.postgresql.Query, - user: java.util.UUID, + user: uuid, form: TaskForm ): io.flow.postgresql.Query = { query @@ -719,7 +719,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex } private def toNamedParameter( - user: java.util.UUID, + user: uuid, form: TaskForm ): Seq[anorm.NamedParameter] = { Seq( From ecaf08fdb1a10fabc6bb3371524cd3a5e3dd29f3 Mon Sep 17 00:00:00 2001 From: Michael Bryzek Date: Wed, 31 Jul 2024 12:16:44 +0200 Subject: [PATCH 14/25] wip --- dao/spec/psql-apibuilder.json | 6 +- .../app/db/GeneratorInvocationsDao.scala | 36 +++++----- generated/app/db/TasksDao.scala | 68 +++++++++---------- 3 files changed, 55 insertions(+), 55 deletions(-) diff --git a/dao/spec/psql-apibuilder.json b/dao/spec/psql-apibuilder.json index 43ab3df54..b3ab3fcef 100644 --- a/dao/spec/psql-apibuilder.json +++ b/dao/spec/psql-apibuilder.json @@ -6,7 +6,7 @@ "value": { "version": "3.4", "package": "db.generated", - "user_class": "uuid" + "user_class": "java.util.UUID" } }, { @@ -105,7 +105,7 @@ "audit": { "created": { "at": { "type": "date-time-iso8601" }, - "by": { "name": "updated_by_guid", "type": "uuid" } + "by": { "name": "created_by_guid", "type": "uuid" } }, "updated": { "at": { "type": "date-time-iso8601" }, @@ -113,7 +113,7 @@ }, "deleted": { "at": { "type": "date-time-iso8601" }, - "by": { "name": "updated_by_guid", "type": "uuid" } + "by": { "name": "deleted_by_guid", "type": "uuid" } } } } diff --git a/generated/app/db/GeneratorInvocationsDao.scala b/generated/app/db/GeneratorInvocationsDao.scala index 2a2884217..4a841da8a 100644 --- a/generated/app/db/GeneratorInvocationsDao.scala +++ b/generated/app/db/GeneratorInvocationsDao.scala @@ -231,7 +231,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. } def insert( - user: uuid, + user: java.util.UUID, form: GeneratorInvocationForm ): String = { db.withConnection { c => @@ -241,7 +241,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. def insert( c: java.sql.Connection, - user: uuid, + user: java.util.UUID, form: GeneratorInvocationForm ): String = { val id = randomId @@ -253,7 +253,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. } def insertBatch( - user: uuid, + user: java.util.UUID, forms: Seq[GeneratorInvocationForm] ): Seq[String] = { db.withConnection { c => @@ -263,7 +263,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. def insertBatch( c: java.sql.Connection, - user: uuid, + user: java.util.UUID, forms: Seq[GeneratorInvocationForm] ): Seq[String] = { forms.map { f => @@ -279,7 +279,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. } def update( - user: uuid, + user: java.util.UUID, generatorInvocation: GeneratorInvocation, form: GeneratorInvocationForm ): Unit = { @@ -290,7 +290,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. def update( c: java.sql.Connection, - user: uuid, + user: java.util.UUID, generatorInvocation: GeneratorInvocation, form: GeneratorInvocationForm ): Unit = { @@ -303,7 +303,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. } def updateById( - user: uuid, + user: java.util.UUID, id: String, form: GeneratorInvocationForm ): Unit = { @@ -314,7 +314,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. def updateById( c: java.sql.Connection, - user: uuid, + user: java.util.UUID, id: String, form: GeneratorInvocationForm ): Unit = { @@ -326,7 +326,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. } def updateBatch( - user: uuid, + user: java.util.UUID, forms: Seq[(String, GeneratorInvocationForm)] ): Unit = { db.withConnection { c => @@ -336,7 +336,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. def updateBatch( c: java.sql.Connection, - user: uuid, + user: java.util.UUID, forms: Seq[(String, GeneratorInvocationForm)] ): Unit = { forms.map { case (id, f) => toNamedParameter(user, id, f) }.toList match { @@ -346,7 +346,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. } def delete( - user: uuid, + user: java.util.UUID, generatorInvocation: GeneratorInvocation ): Unit = { db.withConnection { c => @@ -356,7 +356,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. def delete( c: java.sql.Connection, - user: uuid, + user: java.util.UUID, generatorInvocation: GeneratorInvocation ): Unit = { deleteById( @@ -367,7 +367,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. } def deleteById( - user: uuid, + user: java.util.UUID, id: String ): Unit = { db.withConnection { c => @@ -377,14 +377,14 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. def deleteById( c: java.sql.Connection, - user: uuid, + user: java.util.UUID, id: String ): Unit = { DeleteQuery.equals("id", id).execute(c) } def deleteAllByIds( - user: uuid, + user: java.util.UUID, ids: Seq[String] ): Unit = { db.withConnection { c => @@ -394,7 +394,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. def deleteAllByIds( c: java.sql.Connection, - user: uuid, + user: java.util.UUID, ids: Seq[String] ): Unit = { DeleteQuery.in("id", ids).execute(c) @@ -402,7 +402,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. private def bindQuery( query: io.flow.postgresql.Query, - user: uuid, + user: java.util.UUID, form: GeneratorInvocationForm ): io.flow.postgresql.Query = { query @@ -415,7 +415,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. } private def toNamedParameter( - user: uuid, + user: java.util.UUID, id: String, form: GeneratorInvocationForm ): Seq[anorm.NamedParameter] = { diff --git a/generated/app/db/TasksDao.scala b/generated/app/db/TasksDao.scala index 3db74dd8f..5057feb54 100644 --- a/generated/app/db/TasksDao.scala +++ b/generated/app/db/TasksDao.scala @@ -399,7 +399,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex } def upsertByTypeIdAndType( - user: uuid, + user: java.util.UUID, form: TaskForm ): Unit = { db.withConnection { c => @@ -409,7 +409,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def upsertByTypeIdAndType( c: java.sql.Connection, - user: uuid, + user: java.util.UUID, form: TaskForm ): Unit = { bindQuery(UpsertQuery,user, form) @@ -418,7 +418,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex } def upsertBatchByTypeIdAndType( - user: uuid, + user: java.util.UUID, forms: Seq[TaskForm] ): Seq[Unit] = { db.withConnection { c => @@ -428,7 +428,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def upsertBatchByTypeIdAndType( c: java.sql.Connection, - user: uuid, + user: java.util.UUID, forms: Seq[TaskForm] ): Seq[Unit] = { forms.map { f => Seq(anorm.NamedParameter("created_at", org.joda.time.DateTime.now)) ++ toNamedParameter(user, f) }.toList match { @@ -441,7 +441,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex } def update( - user: uuid, + user: java.util.UUID, task: Task, form: TaskForm ): Unit = { @@ -452,7 +452,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def update( c: java.sql.Connection, - user: uuid, + user: java.util.UUID, task: Task, form: TaskForm ): Unit = { @@ -465,7 +465,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex } def updateById( - user: uuid, + user: java.util.UUID, id: String, form: TaskForm ): Unit = { @@ -476,7 +476,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def updateById( c: java.sql.Connection, - user: uuid, + user: java.util.UUID, id: String, form: TaskForm ): Unit = { @@ -488,7 +488,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex } def updateBatch( - user: uuid, + user: java.util.UUID, forms: Seq[TaskForm] ): Unit = { db.withConnection { c => @@ -498,7 +498,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def updateBatch( c: java.sql.Connection, - user: uuid, + user: java.util.UUID, forms: Seq[TaskForm] ): Unit = { forms.map { f => toNamedParameter(user, f) }.toList match { @@ -508,7 +508,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex } def delete( - user: uuid, + user: java.util.UUID, task: Task ): Unit = { db.withConnection { c => @@ -518,7 +518,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def delete( c: java.sql.Connection, - user: uuid, + user: java.util.UUID, task: Task ): Unit = { deleteById( @@ -529,7 +529,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex } def deleteById( - user: uuid, + user: java.util.UUID, id: String ): Unit = { db.withConnection { c => @@ -539,14 +539,14 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def deleteById( c: java.sql.Connection, - user: uuid, + user: java.util.UUID, id: String ): Unit = { DeleteQuery.equals("id", id).execute(c) } def deleteAllByIds( - user: uuid, + user: java.util.UUID, ids: Seq[String] ): Unit = { db.withConnection { c => @@ -556,14 +556,14 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def deleteAllByIds( c: java.sql.Connection, - user: uuid, + user: java.util.UUID, ids: Seq[String] ): Unit = { DeleteQuery.in("id", ids).execute(c) } def deleteAllByTypeId( - user: uuid, + user: java.util.UUID, typeId: String ): Unit = { db.withConnection { c => @@ -573,14 +573,14 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def deleteAllByTypeId( c: java.sql.Connection, - user: uuid, + user: java.util.UUID, typeId: String ): Unit = { DeleteQuery.equals("type_id", typeId).execute(c) } def deleteAllByTypeIds( - user: uuid, + user: java.util.UUID, typeIds: Seq[String] ): Unit = { db.withConnection { c => @@ -590,14 +590,14 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def deleteAllByTypeIds( c: java.sql.Connection, - user: uuid, + user: java.util.UUID, typeIds: Seq[String] ): Unit = { DeleteQuery.in("type_id", typeIds).execute(c) } def deleteByTypeIdAndType( - user: uuid, + user: java.util.UUID, typeIdAndType: (String, String) ): Unit = { db.withConnection { c => @@ -607,14 +607,14 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def deleteByTypeIdAndType( c: java.sql.Connection, - user: uuid, + user: java.util.UUID, typeIdAndType: (String, String) ): Unit = { DeleteQuery.in2(("type_id", "type"), Seq(typeIdAndType)).execute(c) } def deleteAllByTypeIdsAndTypes( - user: uuid, + user: java.util.UUID, typeIdsAndTypes: Seq[(String, String)] ): Unit = { db.withConnection { c => @@ -624,14 +624,14 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def deleteAllByTypeIdsAndTypes( c: java.sql.Connection, - user: uuid, + user: java.util.UUID, typeIdsAndTypes: Seq[(String, String)] ): Unit = { DeleteQuery.in2(("type_id", "type"), typeIdsAndTypes).execute(c) } def deleteAllByNumAttempts( - user: uuid, + user: java.util.UUID, numAttempts: Int ): Unit = { db.withConnection { c => @@ -641,14 +641,14 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def deleteAllByNumAttempts( c: java.sql.Connection, - user: uuid, + user: java.util.UUID, numAttempts: Int ): Unit = { DeleteQuery.equals("num_attempts", numAttempts).execute(c) } def deleteAllByNumAttemptses( - user: uuid, + user: java.util.UUID, numAttemptses: Seq[Int] ): Unit = { db.withConnection { c => @@ -658,14 +658,14 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def deleteAllByNumAttemptses( c: java.sql.Connection, - user: uuid, + user: java.util.UUID, numAttemptses: Seq[Int] ): Unit = { DeleteQuery.in("num_attempts", numAttemptses).execute(c) } def deleteAllByNumAttemptsAndNextAttemptAt( - user: uuid, + user: java.util.UUID, numAttemptsAndNextAttemptAt: (Int, org.joda.time.DateTime) ): Unit = { db.withConnection { c => @@ -675,14 +675,14 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def deleteAllByNumAttemptsAndNextAttemptAt( c: java.sql.Connection, - user: uuid, + user: java.util.UUID, numAttemptsAndNextAttemptAt: (Int, org.joda.time.DateTime) ): Unit = { DeleteQuery.in2(("num_attempts", "next_attempt_at"), Seq(numAttemptsAndNextAttemptAt)).execute(c) } def deleteAllByNumAttemptsesAndNextAttemptAts( - user: uuid, + user: java.util.UUID, numAttemptsesAndNextAttemptAts: Seq[(Int, org.joda.time.DateTime)] ): Unit = { db.withConnection { c => @@ -692,7 +692,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex def deleteAllByNumAttemptsesAndNextAttemptAts( c: java.sql.Connection, - user: uuid, + user: java.util.UUID, numAttemptsesAndNextAttemptAts: Seq[(Int, org.joda.time.DateTime)] ): Unit = { DeleteQuery.in2(("num_attempts", "next_attempt_at"), numAttemptsesAndNextAttemptAts).execute(c) @@ -700,7 +700,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex private def bindQuery( query: io.flow.postgresql.Query, - user: uuid, + user: java.util.UUID, form: TaskForm ): io.flow.postgresql.Query = { query @@ -719,7 +719,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex } private def toNamedParameter( - user: uuid, + user: java.util.UUID, form: TaskForm ): Seq[anorm.NamedParameter] = { Seq( From b2de375e19ebfe22915d96e652f1d3fbe7102771 Mon Sep 17 00:00:00 2001 From: Michael Bryzek Date: Wed, 31 Jul 2024 12:19:18 +0200 Subject: [PATCH 15/25] wip --- dao/spec/psql-apibuilder.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dao/spec/psql-apibuilder.json b/dao/spec/psql-apibuilder.json index b3ab3fcef..9676a12f8 100644 --- a/dao/spec/psql-apibuilder.json +++ b/dao/spec/psql-apibuilder.json @@ -112,8 +112,8 @@ "by": { "name": "updated_by_guid", "type": "uuid" } }, "deleted": { - "at": { "type": "date-time-iso8601" }, - "by": { "name": "deleted_by_guid", "type": "uuid" } + "at": { "type": "date-time-iso8601", "required": false }, + "by": { "name": "deleted_by_guid", "type": "uuid", "required": false } } } } From 1d00e548ce0a3ac5c4042ee7f577bd6d044fcc3d Mon Sep 17 00:00:00 2001 From: Michael Bryzek Date: Wed, 31 Jul 2024 12:26:10 +0200 Subject: [PATCH 16/25] wip --- generated/app/db/GeneratorInvocationsDao.scala | 4 ++-- generated/app/db/TasksDao.scala | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/generated/app/db/GeneratorInvocationsDao.scala b/generated/app/db/GeneratorInvocationsDao.scala index 4a841da8a..018ded529 100644 --- a/generated/app/db/GeneratorInvocationsDao.scala +++ b/generated/app/db/GeneratorInvocationsDao.scala @@ -245,7 +245,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. form: GeneratorInvocationForm ): String = { val id = randomId - bindQuery(InsertQuery,user, form) + bindQuery(InsertQuery, user, form) .bind("created_at", org.joda.time.DateTime.now) .bind("id", id) .execute(c) @@ -318,7 +318,7 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. id: String, form: GeneratorInvocationForm ): Unit = { - bindQuery(UpdateQuery,user, form) + bindQuery(UpdateQuery, user, form) .bind("id", id) .bind("updated_by_guid", user) .execute(c) diff --git a/generated/app/db/TasksDao.scala b/generated/app/db/TasksDao.scala index 5057feb54..09f2334e5 100644 --- a/generated/app/db/TasksDao.scala +++ b/generated/app/db/TasksDao.scala @@ -412,7 +412,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex user: java.util.UUID, form: TaskForm ): Unit = { - bindQuery(UpsertQuery,user, form) + bindQuery(UpsertQuery, user, form) .bind("created_at", org.joda.time.DateTime.now) .execute(c) } @@ -480,7 +480,7 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex id: String, form: TaskForm ): Unit = { - bindQuery(UpdateQuery,user, form) + bindQuery(UpdateQuery, user, form) .bind("id", id) .bind("updated_by_guid", user) .execute(c) From 939ae69ada5544d3f2411b0edd7026f9875c6542 Mon Sep 17 00:00:00 2001 From: Michael Bryzek Date: Wed, 31 Jul 2024 12:37:38 +0200 Subject: [PATCH 17/25] wip --- api/app/util/SessionHelper.scala | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/api/app/util/SessionHelper.scala b/api/app/util/SessionHelper.scala index 51847cced..aa0d57d02 100644 --- a/api/app/util/SessionHelper.scala +++ b/api/app/util/SessionHelper.scala @@ -21,13 +21,7 @@ class SessionHelper @Inject() ( _root_.db.generated.SessionForm( id = id, userGuid = u.guid, - expiresAt = ts.plusHours(DefaultSessionExpirationHours), - createdAt = ts, - createdByGuid = u.guid, - updatedAt = ts, - updatedByGuid = u.guid, - deletedAt = None, - deletedByGuid = None + expiresAt = ts.plusHours(DefaultSessionExpirationHours) ) ) From 1af3896111247f03b220563416c5f790e415f4eb Mon Sep 17 00:00:00 2001 From: Michael Bryzek Date: Wed, 31 Jul 2024 12:38:18 +0200 Subject: [PATCH 18/25] wip --- generated/app/db/SessionsDao.scala | 498 +++++++++++++++++++++++++++++ 1 file changed, 498 insertions(+) create mode 100644 generated/app/db/SessionsDao.scala diff --git a/generated/app/db/SessionsDao.scala b/generated/app/db/SessionsDao.scala new file mode 100644 index 000000000..f6b590b0e --- /dev/null +++ b/generated/app/db/SessionsDao.scala @@ -0,0 +1,498 @@ +package db.generated + +case class Session( + id: String, + userGuid: java.util.UUID, + expiresAt: org.joda.time.DateTime, + createdAt: org.joda.time.DateTime, + createdByGuid: java.util.UUID, + updatedAt: org.joda.time.DateTime, + updatedByGuid: java.util.UUID, + deletedAt: Option[org.joda.time.DateTime], + deletedByGuid: Option[java.util.UUID] +) { + def form: SessionForm = { + SessionForm( + id = id, + userGuid = userGuid, + expiresAt = expiresAt, + ) + } +} + +case class SessionForm( + id: String, + userGuid: java.util.UUID, + expiresAt: org.joda.time.DateTime +) + +case object SessionsTable { + val SchemaName: String = "public" + + val TableName: String = "sessions" + + val QualifiedName: String = "public.sessions" + + sealed trait Column { + def name: String + } + + object Columns { + case object Id extends Column { + override val name: String = "id" + } + + case object UserGuid extends Column { + override val name: String = "user_guid" + } + + case object ExpiresAt extends Column { + override val name: String = "expires_at" + } + + case object CreatedAt extends Column { + override val name: String = "created_at" + } + + case object CreatedByGuid extends Column { + override val name: String = "created_by_guid" + } + + case object UpdatedAt extends Column { + override val name: String = "updated_at" + } + + case object UpdatedByGuid extends Column { + override val name: String = "updated_by_guid" + } + + case object DeletedAt extends Column { + override val name: String = "deleted_at" + } + + case object DeletedByGuid extends Column { + override val name: String = "deleted_by_guid" + } + + case object HashCode extends Column { + override val name: String = "hash_code" + } + + val all: List[Column] = List(Id, UserGuid, ExpiresAt, CreatedAt, CreatedByGuid, UpdatedAt, UpdatedByGuid, DeletedAt, DeletedByGuid, HashCode) + } +} + +trait BaseSessionsDao { + import anorm.* + + import anorm.JodaParameterMetaData.* + + import anorm.postgresql.* + + def db: play.api.db.Database + + private val BaseQuery: io.flow.postgresql.Query = { + io.flow.postgresql.Query(""" + | select id, + | user_guid, + | expires_at, + | created_at, + | created_by_guid, + | updated_at, + | updated_by_guid, + | deleted_at, + | deleted_by_guid, + | hash_code + | from public.sessions + |""".stripMargin.stripTrailing + ) + } + + def findAll( + id: Option[String] = None, + ids: Option[Seq[String]] = None, + userGuid: Option[java.util.UUID] = None, + userGuids: Option[Seq[java.util.UUID]] = None, + limit: Option[Long], + offset: Long = 0, + orderBy: Option[io.flow.postgresql.OrderBy] = None + )(implicit customQueryModifier: io.flow.postgresql.Query => io.flow.postgresql.Query = identity): Seq[Session] = { + db.withConnection { c => + findAllWithConnection(c, id, ids, userGuid, userGuids, limit, offset, orderBy) + } + } + + def findAllWithConnection( + c: java.sql.Connection, + id: Option[String] = None, + ids: Option[Seq[String]] = None, + userGuid: Option[java.util.UUID] = None, + userGuids: Option[Seq[java.util.UUID]] = None, + limit: Option[Long], + offset: Long = 0, + orderBy: Option[io.flow.postgresql.OrderBy] = None + )(implicit customQueryModifier: io.flow.postgresql.Query => io.flow.postgresql.Query = identity): Seq[Session] = { + customQueryModifier(BaseQuery) + .equals("sessions.id", id) + .optionalIn("sessions.id", ids) + .equals("sessions.user_guid", userGuid) + .optionalIn("sessions.user_guid", userGuids) + .optionalLimit(limit) + .offset(offset) + .orderBy(orderBy.flatMap(_.sql)) + .as(parser.*)(c) + } + + def iterateAll( + id: Option[String] = None, + ids: Option[Seq[String]] = None, + userGuid: Option[java.util.UUID] = None, + userGuids: Option[Seq[java.util.UUID]] = None, + pageSize: Long = 1000 + )(implicit customQueryModifier: io.flow.postgresql.Query => io.flow.postgresql.Query = identity): Iterator[Session] = { + assert(pageSize > 0, "pageSize must be > 0") + + def iterate(lastValue: Option[Session]): Iterator[Session] = { + val page: Seq[Session] = db.withConnection { c => + customQueryModifier(BaseQuery) + .equals("sessions.id", id) + .optionalIn("sessions.id", ids) + .equals("sessions.user_guid", userGuid) + .optionalIn("sessions.user_guid", userGuids) + .greaterThan("sessions.id", lastValue.map(_.id)) + .orderBy("sessions.id") + .limit(pageSize) + .as(parser.*)(c) + } + if (page.length >= pageSize) { + page.iterator ++ iterate(page.lastOption) + } else { + page.iterator + } + } + + iterate(None) + } + + def findById(id: String): Option[Session] = { + db.withConnection { c => + findByIdWithConnection(c, id) + } + } + + def findByIdWithConnection( + c: java.sql.Connection, + id: String + ): Option[Session] = { + findAllWithConnection( + c = c, + id = Some(id), + limit = Some(1) + ).headOption + } + + def findAllByUserGuid(userGuid: java.util.UUID): Seq[Session] = { + db.withConnection { c => + findAllByUserGuidWithConnection(c, userGuid) + } + } + + def findAllByUserGuidWithConnection( + c: java.sql.Connection, + userGuid: java.util.UUID + ): Seq[Session] = { + findAllWithConnection( + c = c, + userGuid = Some(userGuid), + limit = None + ) + } + + private val parser: anorm.RowParser[Session] = { + anorm.SqlParser.str("id") ~ + anorm.SqlParser.str("user_guid") ~ + anorm.SqlParser.get[org.joda.time.DateTime]("expires_at") ~ + anorm.SqlParser.get[org.joda.time.DateTime]("created_at") ~ + anorm.SqlParser.str("created_by_guid") ~ + anorm.SqlParser.get[org.joda.time.DateTime]("updated_at") ~ + anorm.SqlParser.str("updated_by_guid") ~ + anorm.SqlParser.get[org.joda.time.DateTime]("deleted_at").? ~ + anorm.SqlParser.str("deleted_by_guid").? ~ + anorm.SqlParser.long("hash_code") map { case id ~ userGuid ~ expiresAt ~ createdAt ~ createdByGuid ~ updatedAt ~ updatedByGuid ~ deletedAt ~ deletedByGuid ~ hashCode => + Session( + id = id, + userGuid = java.util.UUID.fromString(userGuid), + expiresAt = expiresAt, + createdAt = createdAt, + createdByGuid = java.util.UUID.fromString(createdByGuid), + updatedAt = updatedAt, + updatedByGuid = java.util.UUID.fromString(updatedByGuid), + deletedAt = deletedAt, + deletedByGuid = deletedByGuid.map { v => java.util.UUID.fromString(v) } + ) + } + } +} + +class SessionsDao @javax.inject.Inject() (override val db: play.api.db.Database) extends BaseSessionsDao { + import anorm.JodaParameterMetaData.* + + import anorm.postgresql.* + + private val InsertQuery: io.flow.postgresql.Query = { + io.flow.postgresql.Query(""" + | insert into public.sessions + | (id, user_guid, expires_at, created_at, created_by_guid, updated_at, updated_by_guid, deleted_at, deleted_by_guid, hash_code) + | values + | ({id}, {user_guid}::uuid, {expires_at}::timestamptz, {created_at}::timestamptz, {created_by_guid}::uuid, {updated_at}::timestamptz, {updated_by_guid}::uuid, {deleted_at}::timestamptz, {deleted_by_guid}::uuid, {hash_code}::bigint) + """.stripMargin) + } + + private val UpdateQuery: io.flow.postgresql.Query = { + io.flow.postgresql.Query(""" + | update public.sessions + | set user_guid = {user_guid}::uuid, + | expires_at = {expires_at}::timestamptz, + | updated_at = {updated_at}::timestamptz, + | updated_by_guid = {updated_by_guid}::uuid, + | hash_code = {hash_code}::bigint + | where id = {id} and sessions.hash_code != {hash_code}::bigint + """.stripMargin) + } + + private val DeleteQuery: io.flow.postgresql.Query = { + io.flow.postgresql.Query(""" + | delete from public.sessions + | + .bind("deleted_by_guid", org.joda.time.DateTime.now) + .bind("deleted_by_guid", user) + """.stripMargin) + } + + def insert( + user: java.util.UUID, + form: SessionForm + ): Unit = { + db.withConnection { c => + insert(c, user, form) + } + } + + def insert( + c: java.sql.Connection, + user: java.util.UUID, + form: SessionForm + ): Unit = { + bindQuery(InsertQuery, user, form) + .bind("created_at", org.joda.time.DateTime.now) + .bind("created_by_guid", user) + .execute(c) + } + + def insertBatch( + user: java.util.UUID, + forms: Seq[SessionForm] + ): Seq[Unit] = { + db.withConnection { c => + insertBatch(c, user, forms) + } + } + + def insertBatch( + c: java.sql.Connection, + user: java.util.UUID, + forms: Seq[SessionForm] + ): Seq[Unit] = { + forms.map { f => Seq(anorm.NamedParameter("created_at", org.joda.time.DateTime.now)) ++ toNamedParameter(user, f) }.toList match { + case Nil => Nil + case one :: rest => { + anorm.BatchSql(InsertQuery.sql(), one, rest*).execute()(c) + (Seq(one) ++ rest).map { _ => () } + } + } + } + + def update( + user: java.util.UUID, + session: Session, + form: SessionForm + ): Unit = { + db.withConnection { c => + update(c, user, session, form) + } + } + + def update( + c: java.sql.Connection, + user: java.util.UUID, + session: Session, + form: SessionForm + ): Unit = { + updateById( + c = c, + user = user, + id = session.id, + form = form + ) + } + + def updateById( + user: java.util.UUID, + id: String, + form: SessionForm + ): Unit = { + db.withConnection { c => + updateById(c, user, id, form) + } + } + + def updateById( + c: java.sql.Connection, + user: java.util.UUID, + id: String, + form: SessionForm + ): Unit = { + bindQuery(UpdateQuery, user, form) + .bind("id", id) + .bind("updated_by_guid", user) + .execute(c) + () + } + + def updateBatch( + user: java.util.UUID, + forms: Seq[SessionForm] + ): Unit = { + db.withConnection { c => + updateBatch(c, user, forms) + } + } + + def updateBatch( + c: java.sql.Connection, + user: java.util.UUID, + forms: Seq[SessionForm] + ): Unit = { + forms.map { f => toNamedParameter(user, f) }.toList match { + case Nil => // no-op + case first :: rest => anorm.BatchSql(UpdateQuery.sql(), first, rest*).execute()(c) + } + } + + def delete( + user: java.util.UUID, + session: Session + ): Unit = { + db.withConnection { c => + delete(c, user, session) + } + } + + def delete( + c: java.sql.Connection, + user: java.util.UUID, + session: Session + ): Unit = { + deleteById( + c = c, + user = user, + id = session.id + ) + } + + def deleteById( + user: java.util.UUID, + id: String + ): Unit = { + db.withConnection { c => + deleteById(c, user, id) + } + } + + def deleteById( + c: java.sql.Connection, + user: java.util.UUID, + id: String + ): Unit = { + DeleteQuery.equals("id", id).execute(c) + } + + def deleteAllByIds( + user: java.util.UUID, + ids: Seq[String] + ): Unit = { + db.withConnection { c => + deleteAllByIds(c, user, ids) + } + } + + def deleteAllByIds( + c: java.sql.Connection, + user: java.util.UUID, + ids: Seq[String] + ): Unit = { + DeleteQuery.in("id", ids).execute(c) + } + + def deleteAllByUserGuid( + user: java.util.UUID, + userGuid: java.util.UUID + ): Unit = { + db.withConnection { c => + deleteAllByUserGuid(c, user, userGuid) + } + } + + def deleteAllByUserGuid( + c: java.sql.Connection, + user: java.util.UUID, + userGuid: java.util.UUID + ): Unit = { + DeleteQuery.equals("user_guid", userGuid).execute(c) + } + + def deleteAllByUserGuids( + user: java.util.UUID, + userGuids: Seq[java.util.UUID] + ): Unit = { + db.withConnection { c => + deleteAllByUserGuids(c, user, userGuids) + } + } + + def deleteAllByUserGuids( + c: java.sql.Connection, + user: java.util.UUID, + userGuids: Seq[java.util.UUID] + ): Unit = { + DeleteQuery.in("user_guid", userGuids).execute(c) + } + + private def bindQuery( + query: io.flow.postgresql.Query, + user: java.util.UUID, + form: SessionForm + ): io.flow.postgresql.Query = { + query + .bind("id", form.id) + .bind("user_guid", form.userGuid.toString) + .bind("expires_at", form.expiresAt) + .bind("updated_at", org.joda.time.DateTime.now) + .bind("updated_by_guid", user) + .bind("hash_code", form.hashCode()) + } + + private def toNamedParameter( + user: java.util.UUID, + form: SessionForm + ): Seq[anorm.NamedParameter] = { + Seq( + anorm.NamedParameter("id", form.id), + anorm.NamedParameter("user_guid", form.userGuid.toString), + anorm.NamedParameter("expires_at", form.expiresAt), + anorm.NamedParameter("updated_at", org.joda.time.DateTime.now), + anorm.NamedParameter("updated_by_guid", user.toString), + anorm.NamedParameter("hash_code", form.hashCode()) + ) + } +} \ No newline at end of file From 463dd9a3563b11adb7c5c24ad21601913b752007 Mon Sep 17 00:00:00 2001 From: Michael Bryzek Date: Wed, 31 Jul 2024 12:42:06 +0200 Subject: [PATCH 19/25] wip --- generated/app/db/GeneratorInvocationsDao.scala | 4 ++-- generated/app/db/SessionsDao.scala | 4 ++-- generated/app/db/TasksDao.scala | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/generated/app/db/GeneratorInvocationsDao.scala b/generated/app/db/GeneratorInvocationsDao.scala index 018ded529..ba0e11c42 100644 --- a/generated/app/db/GeneratorInvocationsDao.scala +++ b/generated/app/db/GeneratorInvocationsDao.scala @@ -207,9 +207,9 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. private val InsertQuery: io.flow.postgresql.Query = { io.flow.postgresql.Query(""" | insert into public.generator_invocations - | (id, key, organization_key, application_key, created_at, updated_at, updated_by_guid, hash_code) + | (key, organization_key, application_key, created_at, updated_at, updated_by_guid, hash_code) | values - | ({id}, {key}, {organization_key}, {application_key}, {created_at}::timestamptz, {updated_at}::timestamptz, {updated_by_guid}, {hash_code}::bigint) + | ({key}, {organization_key}, {application_key}, {created_at}::timestamptz, {updated_at}::timestamptz, {updated_by_guid}, {hash_code}::bigint) """.stripMargin) } diff --git a/generated/app/db/SessionsDao.scala b/generated/app/db/SessionsDao.scala index f6b590b0e..748b73dee 100644 --- a/generated/app/db/SessionsDao.scala +++ b/generated/app/db/SessionsDao.scala @@ -242,9 +242,9 @@ class SessionsDao @javax.inject.Inject() (override val db: play.api.db.Database) private val InsertQuery: io.flow.postgresql.Query = { io.flow.postgresql.Query(""" | insert into public.sessions - | (id, user_guid, expires_at, created_at, created_by_guid, updated_at, updated_by_guid, deleted_at, deleted_by_guid, hash_code) + | (user_guid, expires_at, created_at, created_by_guid, updated_at, updated_by_guid, hash_code) | values - | ({id}, {user_guid}::uuid, {expires_at}::timestamptz, {created_at}::timestamptz, {created_by_guid}::uuid, {updated_at}::timestamptz, {updated_by_guid}::uuid, {deleted_at}::timestamptz, {deleted_by_guid}::uuid, {hash_code}::bigint) + | ({user_guid}::uuid, {expires_at}::timestamptz, {created_at}::timestamptz, {created_by_guid}::uuid, {updated_at}::timestamptz, {updated_by_guid}::uuid, {hash_code}::bigint) """.stripMargin) } diff --git a/generated/app/db/TasksDao.scala b/generated/app/db/TasksDao.scala index 09f2334e5..6f755f4d8 100644 --- a/generated/app/db/TasksDao.scala +++ b/generated/app/db/TasksDao.scala @@ -359,9 +359,9 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex private val UpsertQuery: io.flow.postgresql.Query = { io.flow.postgresql.Query(""" | insert into public.tasks - | (id, type, type_id, organization_guid, num_attempts, next_attempt_at, errors, stacktrace, data, created_at, updated_at, updated_by_guid, hash_code) + | (type, type_id, organization_guid, num_attempts, next_attempt_at, errors, stacktrace, data, created_at, updated_at, updated_by_guid, hash_code) | values - | ({id}, {type}, {type_id}, {organization_guid}::uuid, {num_attempts}::integer, {next_attempt_at}::timestamptz, {errors}::json, {stacktrace}, {data}::json, {created_at}::timestamptz, {updated_at}::timestamptz, {updated_by_guid}, {hash_code}::bigint) + | ({type}, {type_id}, {organization_guid}::uuid, {num_attempts}::integer, {next_attempt_at}::timestamptz, {errors}::json, {stacktrace}, {data}::json, {created_at}::timestamptz, {updated_at}::timestamptz, {updated_by_guid}, {hash_code}::bigint) | on conflict(type_id, type) do update | set organization_guid = {organization_guid}::uuid, | num_attempts = {num_attempts}::integer, From 87ed275505f5297172f48265346b007d2cf07671 Mon Sep 17 00:00:00 2001 From: Michael Bryzek Date: Wed, 31 Jul 2024 12:44:10 +0200 Subject: [PATCH 20/25] wip --- generated/app/db/GeneratorInvocationsDao.scala | 4 ++-- generated/app/db/SessionsDao.scala | 4 ++-- generated/app/db/TasksDao.scala | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/generated/app/db/GeneratorInvocationsDao.scala b/generated/app/db/GeneratorInvocationsDao.scala index ba0e11c42..018ded529 100644 --- a/generated/app/db/GeneratorInvocationsDao.scala +++ b/generated/app/db/GeneratorInvocationsDao.scala @@ -207,9 +207,9 @@ class GeneratorInvocationsDao @javax.inject.Inject() (override val db: play.api. private val InsertQuery: io.flow.postgresql.Query = { io.flow.postgresql.Query(""" | insert into public.generator_invocations - | (key, organization_key, application_key, created_at, updated_at, updated_by_guid, hash_code) + | (id, key, organization_key, application_key, created_at, updated_at, updated_by_guid, hash_code) | values - | ({key}, {organization_key}, {application_key}, {created_at}::timestamptz, {updated_at}::timestamptz, {updated_by_guid}, {hash_code}::bigint) + | ({id}, {key}, {organization_key}, {application_key}, {created_at}::timestamptz, {updated_at}::timestamptz, {updated_by_guid}, {hash_code}::bigint) """.stripMargin) } diff --git a/generated/app/db/SessionsDao.scala b/generated/app/db/SessionsDao.scala index 748b73dee..b5ecbfb36 100644 --- a/generated/app/db/SessionsDao.scala +++ b/generated/app/db/SessionsDao.scala @@ -242,9 +242,9 @@ class SessionsDao @javax.inject.Inject() (override val db: play.api.db.Database) private val InsertQuery: io.flow.postgresql.Query = { io.flow.postgresql.Query(""" | insert into public.sessions - | (user_guid, expires_at, created_at, created_by_guid, updated_at, updated_by_guid, hash_code) + | (id, user_guid, expires_at, created_at, created_by_guid, updated_at, updated_by_guid, hash_code) | values - | ({user_guid}::uuid, {expires_at}::timestamptz, {created_at}::timestamptz, {created_by_guid}::uuid, {updated_at}::timestamptz, {updated_by_guid}::uuid, {hash_code}::bigint) + | ({id}, {user_guid}::uuid, {expires_at}::timestamptz, {created_at}::timestamptz, {created_by_guid}::uuid, {updated_at}::timestamptz, {updated_by_guid}::uuid, {hash_code}::bigint) """.stripMargin) } diff --git a/generated/app/db/TasksDao.scala b/generated/app/db/TasksDao.scala index 6f755f4d8..09f2334e5 100644 --- a/generated/app/db/TasksDao.scala +++ b/generated/app/db/TasksDao.scala @@ -359,9 +359,9 @@ class TasksDao @javax.inject.Inject() (override val db: play.api.db.Database) ex private val UpsertQuery: io.flow.postgresql.Query = { io.flow.postgresql.Query(""" | insert into public.tasks - | (type, type_id, organization_guid, num_attempts, next_attempt_at, errors, stacktrace, data, created_at, updated_at, updated_by_guid, hash_code) + | (id, type, type_id, organization_guid, num_attempts, next_attempt_at, errors, stacktrace, data, created_at, updated_at, updated_by_guid, hash_code) | values - | ({type}, {type_id}, {organization_guid}::uuid, {num_attempts}::integer, {next_attempt_at}::timestamptz, {errors}::json, {stacktrace}, {data}::json, {created_at}::timestamptz, {updated_at}::timestamptz, {updated_by_guid}, {hash_code}::bigint) + | ({id}, {type}, {type_id}, {organization_guid}::uuid, {num_attempts}::integer, {next_attempt_at}::timestamptz, {errors}::json, {stacktrace}, {data}::json, {created_at}::timestamptz, {updated_at}::timestamptz, {updated_by_guid}, {hash_code}::bigint) | on conflict(type_id, type) do update | set organization_guid = {organization_guid}::uuid, | num_attempts = {num_attempts}::integer, From 8bd54f9ce2e7ce9eba443cdf4e8e6f1a6e3b397a Mon Sep 17 00:00:00 2001 From: Michael Bryzek Date: Wed, 31 Jul 2024 12:47:30 +0200 Subject: [PATCH 21/25] wip --- generated/app/db/SessionsDao.scala | 8 ++++---- generated/app/db/TasksDao.scala | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/generated/app/db/SessionsDao.scala b/generated/app/db/SessionsDao.scala index b5ecbfb36..c08bd7ec2 100644 --- a/generated/app/db/SessionsDao.scala +++ b/generated/app/db/SessionsDao.scala @@ -94,14 +94,14 @@ trait BaseSessionsDao { private val BaseQuery: io.flow.postgresql.Query = { io.flow.postgresql.Query(""" | select id, - | user_guid, + | user_guid::text, | expires_at, | created_at, - | created_by_guid, + | created_by_guid::text, | updated_at, - | updated_by_guid, + | updated_by_guid::text, | deleted_at, - | deleted_by_guid, + | deleted_by_guid::text, | hash_code | from public.sessions |""".stripMargin.stripTrailing diff --git a/generated/app/db/TasksDao.scala b/generated/app/db/TasksDao.scala index 09f2334e5..2cd74e8a2 100644 --- a/generated/app/db/TasksDao.scala +++ b/generated/app/db/TasksDao.scala @@ -123,7 +123,7 @@ trait BaseTasksDao { | select id, | type, | type_id, - | organization_guid, + | organization_guid::text, | num_attempts, | next_attempt_at, | errors::text, From 2417bf7fc2d57e8485d14ea3956762d997837c67 Mon Sep 17 00:00:00 2001 From: Michael Bryzek Date: Wed, 31 Jul 2024 12:53:37 +0200 Subject: [PATCH 22/25] wip --- generated/app/db/SessionsDao.scala | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/generated/app/db/SessionsDao.scala b/generated/app/db/SessionsDao.scala index c08bd7ec2..18d27db4c 100644 --- a/generated/app/db/SessionsDao.scala +++ b/generated/app/db/SessionsDao.scala @@ -261,12 +261,7 @@ class SessionsDao @javax.inject.Inject() (override val db: play.api.db.Database) } private val DeleteQuery: io.flow.postgresql.Query = { - io.flow.postgresql.Query(""" - | delete from public.sessions - | - .bind("deleted_by_guid", org.joda.time.DateTime.now) - .bind("deleted_by_guid", user) - """.stripMargin) + io.flow.postgresql.Query("delete from public.sessions") } def insert( @@ -414,7 +409,10 @@ class SessionsDao @javax.inject.Inject() (override val db: play.api.db.Database) user: java.util.UUID, id: String ): Unit = { - DeleteQuery.equals("id", id).execute(c) + DeleteQuery.equals("id", id) + .bind("deleted_at", org.joda.time.DateTime.now) + .bind("deleted_by_guid", user) + .execute(c) } def deleteAllByIds( @@ -431,7 +429,10 @@ class SessionsDao @javax.inject.Inject() (override val db: play.api.db.Database) user: java.util.UUID, ids: Seq[String] ): Unit = { - DeleteQuery.in("id", ids).execute(c) + DeleteQuery.in("id", ids) + .bind("deleted_at", org.joda.time.DateTime.now) + .bind("deleted_by_guid", user) + .execute(c) } def deleteAllByUserGuid( @@ -448,7 +449,10 @@ class SessionsDao @javax.inject.Inject() (override val db: play.api.db.Database) user: java.util.UUID, userGuid: java.util.UUID ): Unit = { - DeleteQuery.equals("user_guid", userGuid).execute(c) + DeleteQuery.equals("user_guid", userGuid) + .bind("deleted_at", org.joda.time.DateTime.now) + .bind("deleted_by_guid", user) + .execute(c) } def deleteAllByUserGuids( @@ -465,7 +469,10 @@ class SessionsDao @javax.inject.Inject() (override val db: play.api.db.Database) user: java.util.UUID, userGuids: Seq[java.util.UUID] ): Unit = { - DeleteQuery.in("user_guid", userGuids).execute(c) + DeleteQuery.in("user_guid", userGuids) + .bind("deleted_at", org.joda.time.DateTime.now) + .bind("deleted_by_guid", user) + .execute(c) } private def bindQuery( From 896dc2337ca06ee7446622d2b9c4d3e895590f87 Mon Sep 17 00:00:00 2001 From: Michael Bryzek Date: Wed, 31 Jul 2024 12:58:40 +0200 Subject: [PATCH 23/25] wip --- generated/app/db/SessionsDao.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generated/app/db/SessionsDao.scala b/generated/app/db/SessionsDao.scala index 18d27db4c..c9c9c2533 100644 --- a/generated/app/db/SessionsDao.scala +++ b/generated/app/db/SessionsDao.scala @@ -261,7 +261,7 @@ class SessionsDao @javax.inject.Inject() (override val db: play.api.db.Database) } private val DeleteQuery: io.flow.postgresql.Query = { - io.flow.postgresql.Query("delete from public.sessions") + io.flow.postgresql.Query("update public.sessions set {deleted_at}::timestamptz, {deleted_by_guid}::uuid").withDebugging() } def insert( From 662269a9a97f28b1933b6c4a0d9cf9e120b514c3 Mon Sep 17 00:00:00 2001 From: Michael Bryzek Date: Wed, 31 Jul 2024 13:00:32 +0200 Subject: [PATCH 24/25] wip --- generated/app/db/SessionsDao.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generated/app/db/SessionsDao.scala b/generated/app/db/SessionsDao.scala index c9c9c2533..e4bca6e8d 100644 --- a/generated/app/db/SessionsDao.scala +++ b/generated/app/db/SessionsDao.scala @@ -261,7 +261,7 @@ class SessionsDao @javax.inject.Inject() (override val db: play.api.db.Database) } private val DeleteQuery: io.flow.postgresql.Query = { - io.flow.postgresql.Query("update public.sessions set {deleted_at}::timestamptz, {deleted_by_guid}::uuid").withDebugging() + io.flow.postgresql.Query("update public.sessions set deleted_at = {deleted_at}::timestamptz, deleted_by_guid = {deleted_by_guid}::uuid") } def insert( From f4af139261150058c55c895d36bc4924e5899b43 Mon Sep 17 00:00:00 2001 From: Michael Bryzek Date: Wed, 31 Jul 2024 13:16:58 +0200 Subject: [PATCH 25/25] wip --- dao/spec/psql-apibuilder.json | 68 +++++++++++++++++------------------ 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/dao/spec/psql-apibuilder.json b/dao/spec/psql-apibuilder.json index 9676a12f8..637842fbf 100644 --- a/dao/spec/psql-apibuilder.json +++ b/dao/spec/psql-apibuilder.json @@ -28,40 +28,6 @@ ], "models": { - "generator_invocation": { - "fields": [ - { - "name": "id", - "type": "string" - }, - { - "name": "key", - "type": "string" - }, - { - "name": "organization_key", - "type": "string", - "required": false - }, - { - "name": "application_key", - "type": "string", - "required": false - } - ], - "attributes": [ - { - "name": "scala", - "value": { - "id_generator": { - "class": "com.mbryzek.util.IdGenerator", - "prefix": "gni" - } - } - } - ] - }, - "task": { "fields": [ { "name": "id", "type": "string" }, @@ -119,6 +85,40 @@ } } ] + }, + + "generator_invocation": { + "fields": [ + { "name": "id", "type": "string" }, + { "name": "key", "type": "string" }, + { "name": "organization_key", "type": "string", "required": false }, + { "name": "application_key", "type": "string", "required": false } + ], + "attributes": [ + { + "name": "scala", + "value": { + "id_generator": { + "class": "com.mbryzek.util.IdGenerator", + "prefix": "gni" + } + } + }, + { + "name": "psql", + "value": { + "audit": { + "created": { + "at": { "type": "date-time-iso8601" } + }, + "updated": { + "at": { "type": "date-time-iso8601" }, + "by": { "name": "updated_by_guid", "type": "string" } + } + } + } + } + ] } } }