Add routes for storing/retrieving client settings

This commit is contained in:
Eike Kettner
2021-05-25 00:06:13 +02:00
parent 8c127cde5f
commit 25788a0b23
10 changed files with 342 additions and 20 deletions

View File

@ -0,0 +1,10 @@
CREATE TABLE "client_settings" (
"id" varchar(254) not null primary key,
"client_id" varchar(254) not null,
"user_id" varchar(254) not null,
"settings_data" text not null,
"created" timestamp not null,
"updated" timestamp not null,
foreign key ("user_id") references "user_"("uid") on delete cascade,
unique ("client_id", "user_id")
);

View File

@ -0,0 +1,10 @@
CREATE TABLE `client_settings` (
`id` varchar(254) not null primary key,
`client_id` varchar(254) not null,
`user_id` varchar(254) not null,
`settings_data` longtext not null,
`created` timestamp not null,
`updated` timestamp not null,
foreign key (`user_id`) references `user_`(`uid`) on delete cascade,
unique (`client_id`, `user_id`)
);

View File

@ -0,0 +1,10 @@
CREATE TABLE "client_settings" (
"id" varchar(254) not null primary key,
"client_id" varchar(254) not null,
"user_id" varchar(254) not null,
"settings_data" text not null,
"created" timestamp not null,
"updated" timestamp not null,
foreign key ("user_id") references "user_"("uid") on delete cascade,
unique ("client_id", "user_id")
);

View File

@ -11,6 +11,7 @@ import doobie._
import doobie.implicits.legacy.instant._
import doobie.util.log.Success
import emil.doobie.EmilDoobieMeta
import io.circe.Json
import io.circe.{Decoder, Encoder}
trait DoobieMeta extends EmilDoobieMeta {
@ -112,10 +113,18 @@ trait DoobieMeta extends EmilDoobieMeta {
implicit val metaOrgUse: Meta[OrgUse] =
Meta[String].timap(OrgUse.unsafeFromString)(_.name)
implicit val metaJsonString: Meta[Json] =
Meta[String].timap(DoobieMeta.parseJsonUnsafe)(_.noSpaces)
}
object DoobieMeta extends DoobieMeta {
import org.log4s._
private val logger = getLogger
private def parseJsonUnsafe(str: String): Json =
io.circe.parser
.parse(str)
.fold(throw _, identity)
}

View File

@ -0,0 +1,79 @@
package docspell.store.records
import cats.data.NonEmptyList
import cats.implicits._
import docspell.common._
import docspell.store.qb.DSL._
import docspell.store.qb._
import doobie._
import doobie.implicits._
import io.circe.Json
case class RClientSettings(
id: Ident,
clientId: Ident,
userId: Ident,
settingsData: Json,
updated: Timestamp,
created: Timestamp
) {}
object RClientSettings {
final case class Table(alias: Option[String]) extends TableDef {
val tableName = "client_settings"
val id = Column[Ident]("id", this)
val clientId = Column[Ident]("client_id", this)
val userId = Column[Ident]("user_id", this)
val settingsData = Column[Json]("settings_data", this)
val updated = Column[Timestamp]("updated", this)
val created = Column[Timestamp]("created", this)
val all =
NonEmptyList.of[Column[_]](id, clientId, userId, settingsData, updated, created)
}
def as(alias: String): Table = Table(Some(alias))
val T = Table(None)
def insert(v: RClientSettings): ConnectionIO[Int] = {
val t = Table(None)
DML.insert(
t,
t.all,
fr"${v.id},${v.clientId},${v.userId},${v.settingsData},${v.updated},${v.created}"
)
}
def updateSettings(
clientId: Ident,
userId: Ident,
data: Json,
updateTs: Timestamp
): ConnectionIO[Int] =
DML.update(
T,
T.clientId === clientId && T.userId === userId,
DML.set(T.settingsData.setTo(data), T.updated.setTo(updateTs))
)
def upsert(clientId: Ident, userId: Ident, data: Json): ConnectionIO[Int] =
for {
id <- Ident.randomId[ConnectionIO]
now <- Timestamp.current[ConnectionIO]
nup <- updateSettings(clientId, userId, data, now)
nin <-
if (nup <= 0) insert(RClientSettings(id, clientId, userId, data, now, now))
else 0.pure[ConnectionIO]
} yield nup + nin
def delete(clientId: Ident, userId: Ident): ConnectionIO[Int] =
DML.delete(T, T.clientId === clientId && T.userId === userId)
def find(clientId: Ident, userId: Ident): ConnectionIO[Option[RClientSettings]] =
run(select(T.all), from(T), T.clientId === clientId && T.userId === userId)
.query[RClientSettings]
.option
}