This commit is contained in:
parent
203df76d6c
commit
81134dc0dd
16 changed files with 435 additions and 145 deletions
6
.cargo/config.toml
Normal file
6
.cargo/config.toml
Normal file
|
@ -0,0 +1,6 @@
|
|||
[build]
|
||||
rustflags = ["--cfg", "uuid_unstable"]
|
||||
|
||||
[target.x86_64-unknown-linux-gnu]
|
||||
linker = "clang"
|
||||
rustflags = ["-Clink-arg=-fuse-ld=mold", "--cfg", "uuid_unstable"]
|
6
Cargo.lock
generated
6
Cargo.lock
generated
|
@ -1830,12 +1830,12 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.3.4"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fa2982af2eec27de306107c027578ff7f423d65f7250e40ce0fea8f45248b81"
|
||||
checksum = "d023da39d1fde5a8a3fe1f3e01ca9632ada0a63e9797de55a879d6e2236277be"
|
||||
dependencies = [
|
||||
"atomic",
|
||||
"getrandom",
|
||||
"rand",
|
||||
"serde",
|
||||
]
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ tracing = "0.1"
|
|||
tracing-subscriber = "0.3"
|
||||
tokio = { version = "1.28", features = ["full"] }
|
||||
sqlx = { version = "0.6", features = [ "runtime-tokio-rustls", "postgres", "uuid", "chrono", "macros", "migrate", "json", "offline"] }
|
||||
uuid = { version = "1.3", features = ["v4", "fast-rng", "serde"] }
|
||||
uuid = { version = "1.4", features = ["v7", "serde", "std"] }
|
||||
serde = { version = "1" }
|
||||
serde_json = { version = "1", features = ["raw_value"] }
|
||||
figment = { version = "0.10", features = ["toml", "env", "test"] }
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; -- noqa: RF05
|
||||
|
||||
CREATE TABLE users (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
id UUID PRIMARY KEY,
|
||||
name VARCHAR UNIQUE NOT NULL,
|
||||
email VARCHAR,
|
||||
password VARCHAR,
|
||||
|
@ -14,7 +14,7 @@ CREATE TABLE users (
|
|||
);
|
||||
|
||||
CREATE TABLE sites (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
id UUID PRIMARY KEY,
|
||||
owner UUID NOT NULL REFERENCES users (id) ON DELETE CASCADE,
|
||||
name VARCHAR UNIQUE NOT NULL,
|
||||
title VARCHAR NOT NULL,
|
||||
|
@ -25,7 +25,7 @@ CREATE TABLE sites (
|
|||
);
|
||||
|
||||
CREATE TABLE pages (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
id UUID PRIMARY KEY,
|
||||
site UUID NOT NULL REFERENCES sites (id) ON DELETE CASCADE,
|
||||
author UUID REFERENCES users (id) ON DELETE SET NULL,
|
||||
slug VARCHAR NOT NULL,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; -- noqa: RF05
|
||||
|
||||
CREATE TABLE sessions (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
id UUID PRIMARY KEY,
|
||||
actor UUID NOT NULL REFERENCES users (id) ON DELETE CASCADE,
|
||||
secret VARCHAR NOT NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT now(),
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; -- noqa: RF05
|
||||
|
||||
CREATE TABLE collections (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
id UUID PRIMARY KEY,
|
||||
site UUID NOT NULL REFERENCES sites (id) ON DELETE CASCADE,
|
||||
slug VARCHAR NOT NULL,
|
||||
name VARCHAR NOT NULL,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
-- Remove constraint and index (collections_site_slug_unique, collections_site_slug_idx)
|
||||
-- Remove constraint and index
|
||||
ALTER TABLE collections DROP CONSTRAINT collections_site_slug_unique;
|
||||
|
||||
DROP INDEX IF EXISTS collections_site_slug_unique;
|
||||
|
|
431
sqlx-data.json
431
sqlx-data.json
|
@ -1,28 +1,5 @@
|
|||
{
|
||||
"db": "PostgreSQL",
|
||||
"0e89d76bdba2178afc2fb2c2a5eba0404e68e7a1d26d9fd5f1161f055dad92df": {
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id",
|
||||
"ordinal": 0,
|
||||
"type_info": "Uuid"
|
||||
}
|
||||
],
|
||||
"nullable": [
|
||||
false
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Uuid",
|
||||
"Varchar",
|
||||
"Timestamp",
|
||||
"Timestamp"
|
||||
]
|
||||
}
|
||||
},
|
||||
"query": "INSERT INTO sessions (actor, secret, created_at, expires_at) VALUES ($1, $2, $3, $4) RETURNING id"
|
||||
},
|
||||
"11e96cfd8c2736f13ce55975ea910dd68640f6f14e38a4b3342d514804e3de27": {
|
||||
"describe": {
|
||||
"columns": [],
|
||||
|
@ -35,20 +12,228 @@
|
|||
},
|
||||
"query": "DELETE FROM sessions WHERE id = $1"
|
||||
},
|
||||
"244e021e36237f5e9ce0f17b6eb3ba58d42fe292e7517a33938c5191bc8787e1": {
|
||||
"23f1a1f2aa96a5a23880f330d04f5dc695a148f4aa50b8c76378b68944569e44": {
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "author_display_name",
|
||||
"ordinal": 0,
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"name": "author_username",
|
||||
"ordinal": 1,
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"name": "slug",
|
||||
"ordinal": 2,
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"name": "title",
|
||||
"ordinal": 3,
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"name": "description",
|
||||
"ordinal": 4,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "tags",
|
||||
"ordinal": 5,
|
||||
"type_info": "VarcharArray"
|
||||
},
|
||||
{
|
||||
"name": "blocks!: Json<Vec<PostBlock>>",
|
||||
"ordinal": 6,
|
||||
"type_info": "Jsonb"
|
||||
},
|
||||
{
|
||||
"name": "created_at",
|
||||
"ordinal": 7,
|
||||
"type_info": "Timestamp"
|
||||
},
|
||||
{
|
||||
"name": "modified_at",
|
||||
"ordinal": 8,
|
||||
"type_info": "Timestamp"
|
||||
},
|
||||
{
|
||||
"name": "published",
|
||||
"ordinal": 9,
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
"nullable": [
|
||||
null,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text",
|
||||
"Text"
|
||||
]
|
||||
}
|
||||
},
|
||||
"query": "SELECT\n COALESCE(users.display_name,users.name) as author_display_name,\n users.name as author_username,\n pages.slug,\n pages.title,\n pages.description,\n pages.tags,\n pages.blocks as \"blocks!: Json<Vec<PostBlock>>\",\n pages.created_at,\n pages.modified_at,\n pages.published\n FROM pages \n JOIN\n sites ON site = sites.id\n JOIN\n users ON author = users.id\n WHERE\n slug = $1\n AND sites.name = $2 \n AND pages.deleted_at IS NULL\n AND sites.deleted_at IS NULL"
|
||||
},
|
||||
"28ec2833283df836e457161f44f0fbc75ed37dcc0ba63eb09bf285aae2f7a380": {
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"nullable": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Varchar",
|
||||
"Uuid",
|
||||
"Uuid",
|
||||
"Varchar",
|
||||
"Varchar"
|
||||
]
|
||||
}
|
||||
},
|
||||
"query": "INSERT INTO collections (id, site, slug, name)\n VALUES ($1, $2, $3, $4)"
|
||||
},
|
||||
"29e0259def5c6fdc34c6a18345150d2714736b91c1f3040fcb07d77cbe2552e1": {
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "name",
|
||||
"ordinal": 0,
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"name": "owner",
|
||||
"ordinal": 1,
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"name": "owner_display_name",
|
||||
"ordinal": 2,
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"name": "title",
|
||||
"ordinal": 3,
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"name": "description",
|
||||
"ordinal": 4,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "created_at",
|
||||
"ordinal": 5,
|
||||
"type_info": "Timestamp"
|
||||
},
|
||||
{
|
||||
"name": "collections!: Vec<CollectionNameAndSlug>",
|
||||
"ordinal": 6,
|
||||
"type_info": "RecordArray"
|
||||
}
|
||||
],
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
null,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
null
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text"
|
||||
]
|
||||
}
|
||||
},
|
||||
"query": "INSERT INTO sites (name, owner, title, description) VALUES ($1, $2, $3, $4)"
|
||||
"query": "SELECT\n sites.name,\n users.name as owner,\n COALESCE(users.display_name,users.name) as owner_display_name,\n title,\n description,\n sites.created_at,\n array_agg(row(collections.slug, collections.name)) as \"collections!: Vec<CollectionNameAndSlug>\"\n FROM sites\n JOIN\n users ON sites.owner = users.id\n JOIN\n collections ON collections.site = sites.id\n WHERE\n sites.name = $1\n AND sites.deleted_at IS NULL\n GROUP BY\n sites.name, users.name, users.display_name, title, description, sites.created_at"
|
||||
},
|
||||
"320625aa3fac73cb43d6a68592767174558ab1a6923d3574ad629d1a1bd0d4a6": {
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "author_display_name",
|
||||
"ordinal": 0,
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"name": "author_username",
|
||||
"ordinal": 1,
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"name": "slug",
|
||||
"ordinal": 2,
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"name": "title",
|
||||
"ordinal": 3,
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"name": "description",
|
||||
"ordinal": 4,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "tags",
|
||||
"ordinal": 5,
|
||||
"type_info": "VarcharArray"
|
||||
},
|
||||
{
|
||||
"name": "blocks!: Json<Vec<PostBlock>>",
|
||||
"ordinal": 6,
|
||||
"type_info": "Jsonb"
|
||||
},
|
||||
{
|
||||
"name": "created_at",
|
||||
"ordinal": 7,
|
||||
"type_info": "Timestamp"
|
||||
},
|
||||
{
|
||||
"name": "modified_at",
|
||||
"ordinal": 8,
|
||||
"type_info": "Timestamp"
|
||||
},
|
||||
{
|
||||
"name": "published",
|
||||
"ordinal": 9,
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
"nullable": [
|
||||
null,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Uuid",
|
||||
"Uuid",
|
||||
"Timestamp",
|
||||
"Int8"
|
||||
]
|
||||
}
|
||||
},
|
||||
"query": "SELECT\n COALESCE(users.display_name,users.name) as author_display_name,\n users.name as author_username,\n pages.slug,\n pages.title,\n pages.description,\n pages.tags,\n pages.blocks as \"blocks!: Json<Vec<PostBlock>>\",\n pages.created_at,\n pages.modified_at,\n pages.published\n FROM pages\n JOIN\n users ON author = users.id\n WHERE\n site = $1\n AND $2 = ANY(collections)\n AND pages.deleted_at IS NULL\n AND published = true\n AND pages.created_at <= $3\n ORDER BY created_at DESC\n LIMIT $4\n "
|
||||
},
|
||||
"35deaad55b84124dcba02c555718fe815003e3f50b1c8ee2fc7e540009fa5aef": {
|
||||
"describe": {
|
||||
|
@ -68,23 +253,50 @@
|
|||
},
|
||||
"query": "SELECT CASE WHEN EXISTS(SELECT 1 FROM users) THEN false ELSE true END AS empty;"
|
||||
},
|
||||
"51786c014e6f0863b0462646121bed527cc5c0bac343974f2d3b049e46c14e72": {
|
||||
"39237d1e40ce33ce386320212a53986cb21949dd07014772a150242caf4fa610": {
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"nullable": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Uuid",
|
||||
"Uuid",
|
||||
"Uuid",
|
||||
"Varchar",
|
||||
"Varchar",
|
||||
"Text",
|
||||
"VarcharArray",
|
||||
"Jsonb",
|
||||
"Uuid",
|
||||
"Uuid",
|
||||
"Text"
|
||||
"UuidArray",
|
||||
"Bool"
|
||||
]
|
||||
}
|
||||
},
|
||||
"query": "UPDATE pages SET title = COALESCE($1, title), description = COALESCE($2, description), tags = COALESCE($3, tags), blocks = COALESCE($4, blocks) WHERE author = $5 AND site = $6 AND slug = $7 AND deleted_at IS NULL"
|
||||
"query": "INSERT INTO pages (id, author, site, slug, title, description, tags, blocks, collections, published)\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)"
|
||||
},
|
||||
"562254387ad52ad5ee3cf806085873485d6b8a0b372ac59a0796b9f0c8910cf2": {
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id",
|
||||
"ordinal": 0,
|
||||
"type_info": "Uuid"
|
||||
}
|
||||
],
|
||||
"nullable": [
|
||||
false
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Uuid",
|
||||
"Uuid",
|
||||
"Varchar",
|
||||
"Timestamp",
|
||||
"Timestamp"
|
||||
]
|
||||
}
|
||||
},
|
||||
"query": "INSERT INTO sessions (id, actor, secret, created_at, expires_at) VALUES ($1, $2, $3, $4, $5) RETURNING id"
|
||||
},
|
||||
"61fcf083e6abcfed9480164f3ed4ff2f396c8041a30df002f6e4af920b41f4e4": {
|
||||
"describe": {
|
||||
|
@ -111,24 +323,6 @@
|
|||
},
|
||||
"query": "DELETE FROM sessions WHERE expires_at < $1"
|
||||
},
|
||||
"7b294c850a2feba882b52cc479ae943fdd4a3d26278274ea19eb6a3a0393b4ad": {
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"nullable": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Uuid",
|
||||
"Uuid",
|
||||
"Varchar",
|
||||
"Varchar",
|
||||
"Text",
|
||||
"VarcharArray",
|
||||
"Jsonb"
|
||||
]
|
||||
}
|
||||
},
|
||||
"query": "INSERT INTO pages (author, site, slug, title, description, tags, blocks) VALUES ($1, $2, $3, $4, $5, $6, $7)"
|
||||
},
|
||||
"7bdb55b060b5e81b50c1bf86cb117215cba7010c91f8384a397efac06a88507d": {
|
||||
"describe": {
|
||||
"columns": [],
|
||||
|
@ -143,6 +337,35 @@
|
|||
},
|
||||
"query": "DELETE FROM pages WHERE author = $1 AND site = $2 AND slug = $3"
|
||||
},
|
||||
"82450bdd6a4a7ac9ee66fb98fd87993b70fa58577876b0761ceac9e31af27b8a": {
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id",
|
||||
"ordinal": 0,
|
||||
"type_info": "Uuid"
|
||||
},
|
||||
{
|
||||
"name": "created_at",
|
||||
"ordinal": 1,
|
||||
"type_info": "Timestamp"
|
||||
}
|
||||
],
|
||||
"nullable": [
|
||||
false,
|
||||
false
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Uuid",
|
||||
"Varchar",
|
||||
"Varchar",
|
||||
"UuidArray"
|
||||
]
|
||||
}
|
||||
},
|
||||
"query": "INSERT INTO users ( id, name, password, roles )\n VALUES ( $1,$2,$3,$4 ) RETURNING id, created_at"
|
||||
},
|
||||
"9f37c6f3929ca1bf2a6ec55291d652b216419fd13e27b3d61d23c9cf900c501e": {
|
||||
"describe": {
|
||||
"columns": [
|
||||
|
@ -164,66 +387,6 @@
|
|||
},
|
||||
"query": "UPDATE sessions SET expires_at = $1 WHERE id = $2 RETURNING id"
|
||||
},
|
||||
"c04874a0f4ab7409f53ee50ec34679f6b274b350aff39a8710575c54fcaef1e4": {
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"nullable": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Varchar",
|
||||
"Varchar",
|
||||
"Text",
|
||||
"Text",
|
||||
"Uuid"
|
||||
]
|
||||
}
|
||||
},
|
||||
"query": "UPDATE sites SET name = COALESCE($1, name), title = COALESCE($2, title), description = COALESCE($3, description), modified_at = NOW() WHERE name = $4 AND owner = $5 AND deleted_at IS NULL"
|
||||
},
|
||||
"c1121a7da8dc099e6eb3ed8d1008a247524f7b953f2d0db674371714f09c6530": {
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "name",
|
||||
"ordinal": 0,
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"name": "owner",
|
||||
"ordinal": 1,
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"name": "title",
|
||||
"ordinal": 2,
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"name": "description",
|
||||
"ordinal": 3,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "created_at",
|
||||
"ordinal": 4,
|
||||
"type_info": "Timestamp"
|
||||
}
|
||||
],
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text"
|
||||
]
|
||||
}
|
||||
},
|
||||
"query": "SELECT sites.name, users.name as owner, title, description, sites.created_at FROM sites JOIN users ON sites.owner = users.id WHERE sites.name = $1 AND sites.deleted_at IS NULL"
|
||||
},
|
||||
"c567d96c92638902bc90f5fc0aa5bbbe0b6d26607767720a87fdbe67335a0180": {
|
||||
"describe": {
|
||||
"columns": [
|
||||
|
@ -335,6 +498,22 @@
|
|||
},
|
||||
"query": "DELETE FROM sites WHERE name = $1 AND owner = $2"
|
||||
},
|
||||
"d0005084c0ae3939460c3c727b29899c65a05e53fbc477cdda9665e7f243d5e9": {
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"nullable": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Varchar",
|
||||
"Varchar",
|
||||
"Text",
|
||||
"Text",
|
||||
"Uuid"
|
||||
]
|
||||
}
|
||||
},
|
||||
"query": "UPDATE sites SET\n name = COALESCE($1, name),\n title = COALESCE($2, title),\n description = COALESCE($3, description),\n modified_at = NOW()\n WHERE\n name = $4\n AND owner = $5\n AND deleted_at IS NULL"
|
||||
},
|
||||
"d9649c375db5825adda3b91c52468235fd9c361b827df64350c7e65bca0f00b4": {
|
||||
"describe": {
|
||||
"columns": [],
|
||||
|
@ -349,33 +528,49 @@
|
|||
},
|
||||
"query": "UPDATE pages SET deleted_at = NOW() WHERE author = $1 AND site = $2 AND slug = $3 AND deleted_at IS NULL"
|
||||
},
|
||||
"f054746ab3092a8671604c9388e02220d62d337e9d199fa9102c0363a72f6940": {
|
||||
"e9f521d288a92f1e70b4de35b0d75792007d910ee65e2782eee4a3cdd30560a0": {
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id",
|
||||
"ordinal": 0,
|
||||
"type_info": "Uuid"
|
||||
},
|
||||
{
|
||||
"name": "created_at",
|
||||
"ordinal": 1,
|
||||
"type_info": "Timestamp"
|
||||
}
|
||||
],
|
||||
"nullable": [
|
||||
false,
|
||||
false
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Uuid",
|
||||
"Varchar",
|
||||
"Uuid",
|
||||
"Varchar",
|
||||
"UuidArray"
|
||||
"Text"
|
||||
]
|
||||
}
|
||||
},
|
||||
"query": "INSERT INTO users ( name, password, roles ) VALUES ( $1,$2,$3 ) RETURNING id, created_at"
|
||||
"query": "INSERT INTO sites (id, name, owner, title, description)\n VALUES ($1, $2, $3, $4, $5) RETURNING id"
|
||||
},
|
||||
"ecbbf6f400e058cd6e8695354d65a1883f974a39e11ac5ba0f7fba408fcf6b2a": {
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"nullable": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Varchar",
|
||||
"Text",
|
||||
"VarcharArray",
|
||||
"Jsonb",
|
||||
"Uuid",
|
||||
"Uuid",
|
||||
"Text",
|
||||
"UuidArray",
|
||||
"Bool"
|
||||
]
|
||||
}
|
||||
},
|
||||
"query": "UPDATE pages SET title = COALESCE($1, title), description = COALESCE($2, description), tags = COALESCE($3, tags), blocks = COALESCE($4, blocks), collections = COALESCE($8, collections), published = COALESCE($9, published) WHERE author = $5 AND site = $6 AND slug = $7 AND deleted_at IS NULL"
|
||||
},
|
||||
"f3d0f52ab3c9d7ed46086d21cd88207a75d9f2e2990f3fb721f0e14e1ec52e10": {
|
||||
"describe": {
|
||||
|
|
|
@ -38,7 +38,8 @@ impl Session {
|
|||
let expires = now + duration;
|
||||
let secret = random();
|
||||
let result = sqlx::query!(
|
||||
"INSERT INTO sessions (actor, secret, created_at, expires_at) VALUES ($1, $2, $3, $4) RETURNING id",
|
||||
"INSERT INTO sessions (id, actor, secret, created_at, expires_at) VALUES ($1, $2, $3, $4, $5) RETURNING id",
|
||||
Uuid::now_v7(),
|
||||
user_id,
|
||||
secret,
|
||||
now,
|
||||
|
|
|
@ -60,13 +60,15 @@ impl User {
|
|||
roles: &Vec<Uuid>,
|
||||
) -> Result<Self> {
|
||||
let result = sqlx::query!(
|
||||
r#"INSERT INTO users ( name, password, roles ) VALUES ( $1,$2,$3 ) RETURNING id, created_at"#,
|
||||
username,
|
||||
hash(&password)?,
|
||||
roles,
|
||||
)
|
||||
.fetch_one(pool)
|
||||
.await?;
|
||||
r#"INSERT INTO users ( id, name, password, roles )
|
||||
VALUES ( $1,$2,$3,$4 ) RETURNING id, created_at"#,
|
||||
Uuid::now_v7(),
|
||||
username,
|
||||
hash(&password)?,
|
||||
roles,
|
||||
)
|
||||
.fetch_one(pool)
|
||||
.await?;
|
||||
Ok(Self {
|
||||
id: result.id,
|
||||
name: username.to_owned(),
|
||||
|
|
|
@ -4,6 +4,8 @@ use serde::{Deserialize, Serialize};
|
|||
use sqlx::{types::Json, FromRow};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::cursor::{AsCursor, CursorList};
|
||||
|
||||
use super::Error;
|
||||
|
||||
#[derive(Deserialize, Serialize, FromRow)]
|
||||
|
@ -115,15 +117,29 @@ pub struct PostWithAuthor {
|
|||
pub blocks: Json<Vec<PostBlock>>,
|
||||
pub created_at: NaiveDateTime,
|
||||
pub modified_at: Option<NaiveDateTime>,
|
||||
pub deleted_at: Option<NaiveDateTime>,
|
||||
pub published: bool,
|
||||
}
|
||||
|
||||
impl AsCursor<NaiveDateTime> for PostWithAuthor {
|
||||
fn cursor(&self) -> NaiveDateTime {
|
||||
self.created_at
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
pub trait PostRepository {
|
||||
/// Get a post from its slug
|
||||
async fn get_post_from_url(&self, site: &str, slug: &str) -> Result<PostWithAuthor, Error>;
|
||||
|
||||
/// List posts in a collection
|
||||
async fn list_posts_in_collection(
|
||||
&self,
|
||||
site: &Uuid,
|
||||
collection: &Uuid,
|
||||
cursor: Option<NaiveDateTime>,
|
||||
limit: i64,
|
||||
) -> Result<CursorList<PostWithAuthor, NaiveDateTime>, Error>;
|
||||
|
||||
/// Create a new post
|
||||
async fn create_post(
|
||||
&self,
|
||||
|
|
17
src/cursor.rs
Normal file
17
src/cursor.rs
Normal file
|
@ -0,0 +1,17 @@
|
|||
pub struct CursorList<T, C> {
|
||||
pub items: Vec<T>,
|
||||
pub next_cursor: Option<C>,
|
||||
}
|
||||
|
||||
pub trait AsCursor<C> {
|
||||
fn cursor(&self) -> C;
|
||||
}
|
||||
|
||||
impl<T: AsCursor<C>, C> CursorList<T, C> {
|
||||
pub fn new(items: Vec<T>, limit: usize) -> Self {
|
||||
CursorList {
|
||||
next_cursor: items.get(limit - 1).map(|x| x.cursor()),
|
||||
items,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,7 +15,9 @@ impl CollectionRepository for Database {
|
|||
|
||||
for (slug, name) in DEFAULT_COLLECTIONS {
|
||||
sqlx::query!(
|
||||
r#"INSERT INTO collections (site, slug, name) VALUES ($1, $2, $3)"#,
|
||||
r#"INSERT INTO collections (id, site, slug, name)
|
||||
VALUES ($1, $2, $3, $4)"#,
|
||||
Uuid::now_v7(),
|
||||
site,
|
||||
slug,
|
||||
name
|
||||
|
|
|
@ -1,19 +1,66 @@
|
|||
use async_trait::async_trait;
|
||||
use chrono::NaiveDateTime;
|
||||
use content::post::PostBlock;
|
||||
use serde_json::json;
|
||||
use sqlx::types::Json;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::content::{
|
||||
self,
|
||||
post::{CreatePostData, PostRepository, PostWithAuthor, UpdatePostData},
|
||||
Error,
|
||||
use crate::{
|
||||
content::{
|
||||
self,
|
||||
post::{CreatePostData, PostRepository, PostWithAuthor, UpdatePostData},
|
||||
Error,
|
||||
},
|
||||
cursor::CursorList,
|
||||
};
|
||||
|
||||
use super::Database;
|
||||
|
||||
#[async_trait]
|
||||
impl PostRepository for Database {
|
||||
async fn list_posts_in_collection(
|
||||
&self,
|
||||
site: &Uuid,
|
||||
collection: &Uuid,
|
||||
from: Option<NaiveDateTime>,
|
||||
limit: i64,
|
||||
) -> Result<CursorList<PostWithAuthor, NaiveDateTime>, Error> {
|
||||
let posts = sqlx::query_as!(
|
||||
PostWithAuthor,
|
||||
r#"SELECT
|
||||
COALESCE(users.display_name,users.name) as author_display_name,
|
||||
users.name as author_username,
|
||||
pages.slug,
|
||||
pages.title,
|
||||
pages.description,
|
||||
pages.tags,
|
||||
pages.blocks as "blocks!: Json<Vec<PostBlock>>",
|
||||
pages.created_at,
|
||||
pages.modified_at,
|
||||
pages.published
|
||||
FROM pages
|
||||
JOIN
|
||||
users ON author = users.id
|
||||
WHERE
|
||||
site = $1
|
||||
AND $2 = ANY(collections)
|
||||
AND pages.deleted_at IS NULL
|
||||
AND published = true
|
||||
AND pages.created_at <= $3
|
||||
ORDER BY created_at DESC
|
||||
LIMIT $4
|
||||
"#,
|
||||
site,
|
||||
collection,
|
||||
from.unwrap_or_else(|| NaiveDateTime::MAX),
|
||||
limit
|
||||
)
|
||||
.fetch_all(&self.pool)
|
||||
.await?;
|
||||
|
||||
Ok(CursorList::new(posts, limit as usize))
|
||||
}
|
||||
|
||||
async fn get_post_from_url(
|
||||
&self,
|
||||
site: &str,
|
||||
|
@ -31,7 +78,6 @@ impl PostRepository for Database {
|
|||
pages.blocks as "blocks!: Json<Vec<PostBlock>>",
|
||||
pages.created_at,
|
||||
pages.modified_at,
|
||||
pages.deleted_at,
|
||||
pages.published
|
||||
FROM pages
|
||||
JOIN
|
||||
|
@ -62,7 +108,9 @@ impl PostRepository for Database {
|
|||
data: CreatePostData,
|
||||
) -> Result<(), Error> {
|
||||
sqlx::query!(
|
||||
"INSERT INTO pages (author, site, slug, title, description, tags, blocks, collections, published) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
|
||||
"INSERT INTO pages (id, author, site, slug, title, description, tags, blocks, collections, published)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
|
||||
Uuid::now_v7(),
|
||||
owner,
|
||||
site,
|
||||
data.slug,
|
||||
|
|
|
@ -69,7 +69,9 @@ impl SiteRepository for Database {
|
|||
|
||||
async fn create_site(&self, owner: &Uuid, options: CreateSiteData) -> Result<Uuid, Error> {
|
||||
let result = sqlx::query!(
|
||||
"INSERT INTO sites (name, owner, title, description) VALUES ($1, $2, $3, $4) RETURNING id",
|
||||
"INSERT INTO sites (id, name, owner, title, description)
|
||||
VALUES ($1, $2, $3, $4, $5) RETURNING id",
|
||||
Uuid::now_v7(),
|
||||
options.name,
|
||||
owner,
|
||||
options.title,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
mod auth;
|
||||
mod builtins;
|
||||
mod content;
|
||||
mod cursor;
|
||||
mod database;
|
||||
mod http;
|
||||
mod routes;
|
||||
|
|
Loading…
Reference in a new issue