diff --git a/docker-compose.yml b/docker-compose.yml index fc03639..dd632ce 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -12,3 +12,15 @@ services: TAP_MAX_DB_CONNS: 12 TAP_SIGNAL_COLLECTION: social.scrumble.beta.account.profile TAP_COLLECTION_FILTERS: social.scrumble.* + postgres: + image: postgres:18-alpine + environment: + - POSTGRES_USER=scrumbledev + - POSTGRES_PASSWORD=scrumbledev + ports: + - "5454:5432" + healthcheck: + test: "pg_isready -U scrumbledev" + interval: 500ms + timeout: 10s + retries: 20 diff --git a/sqlc.yaml b/sqlc.yaml new file mode 100644 index 0000000..7ac4031 --- /dev/null +++ b/sqlc.yaml @@ -0,0 +1,10 @@ +version: "2" +sql: + - engine: "postgresql" + queries: "store/schemas/query.sql" + schema: "store/schemas/" + gen: + go: + package: "db" + out: "store/db" + sql_package: "pgx/v5" diff --git a/store/db/db.go b/store/db/db.go new file mode 100644 index 0000000..468d1fa --- /dev/null +++ b/store/db/db.go @@ -0,0 +1,32 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.31.1 + +package db + +import ( + "context" + + "github.com/jackc/pgx/v5" + "github.com/jackc/pgx/v5/pgconn" +) + +type DBTX interface { + Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error) + Query(context.Context, string, ...interface{}) (pgx.Rows, error) + QueryRow(context.Context, string, ...interface{}) pgx.Row +} + +func New(db DBTX) *Queries { + return &Queries{db: db} +} + +type Queries struct { + db DBTX +} + +func (q *Queries) WithTx(tx pgx.Tx) *Queries { + return &Queries{ + db: tx, + } +} diff --git a/store/db/models.go b/store/db/models.go new file mode 100644 index 0000000..e48a8b8 --- /dev/null +++ b/store/db/models.go @@ -0,0 +1,77 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.31.1 + +package db + +import ( + "github.com/jackc/pgx/v5/pgtype" +) + +type Account struct { + Did string + Handle pgtype.Text + UpstreamStatus string + Status string +} + +type Comment struct { + SceneDid string + AccountDid string + Rkey string + Version pgtype.Text + ItemAccountDid pgtype.Text + ItemRkey pgtype.Text + Parent pgtype.Text +} + +type Feedback struct { + SceneDid string + AccountDid string + Rkey string + Version pgtype.Text + ItemAccountDid string + ItemRkey string + Value pgtype.Bool + CreatedAt pgtype.Timestamp +} + +type Item struct { + SceneDid string + AccountDid string + Rkey string + Version pgtype.Text +} + +type Membership struct { + SceneDid string + AccountDid string + MemberRkey pgtype.Text + JoinRkey pgtype.Text + Role pgtype.Text +} + +type Reaction struct { + SceneDid string + AccountDid string + Rkey string + Version pgtype.Text + ItemAccountDid string + ItemRkey string + Emoji string +} + +type Record struct { + Collection string + AccountDid string + Rkey string + Version pgtype.Text + DataJson pgtype.Text +} + +type Scene struct { + Did string + Handle pgtype.Text + UpstreamStatus string + Status string +} diff --git a/store/db/query.sql.go b/store/db/query.sql.go new file mode 100644 index 0000000..02ad5b7 --- /dev/null +++ b/store/db/query.sql.go @@ -0,0 +1,27 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.31.1 +// source: query.sql + +package db + +import ( + "context" +) + +const getAccount = `-- name: GetAccount :one +SELECT did, handle, upstream_status, status FROM account +WHERE did = $1 LIMIT 1 +` + +func (q *Queries) GetAccount(ctx context.Context, did string) (Account, error) { + row := q.db.QueryRow(ctx, getAccount, did) + var i Account + err := row.Scan( + &i.Did, + &i.Handle, + &i.UpstreamStatus, + &i.Status, + ) + return i, err +} diff --git a/store/schemas/000001_init.down.sql b/store/schemas/000001_init.down.sql new file mode 100644 index 0000000..e6dcefd --- /dev/null +++ b/store/schemas/000001_init.down.sql @@ -0,0 +1,12 @@ + +DROP INDEX idx_reaction_item; +DROP TABLE reaction; +DROP INDEX idx_feedback_item; +DROP TABLE feedback; +DROP INDEX idx_comment_item; +DROP TABLE comment; +DROP TABLE item; +DROP TABLE membership; +DROP TABLE record; +DROP TABLE scene; +DROP TABLE account; diff --git a/store/schemas/000001_init.up.sql b/store/schemas/000001_init.up.sql new file mode 100644 index 0000000..e43fab9 --- /dev/null +++ b/store/schemas/000001_init.up.sql @@ -0,0 +1,93 @@ + +CREATE TABLE account ( + did TEXT PRIMARY KEY NOT NULL, + handle TEXT, + upstream_status TEXT NOT NULL DEFAULT "active", + status TEXT NOT NULL DEFAULT "active" +); + +CREATE TABLE scene ( + did TEXT PRIMARY KEY NOT NULL, + handle TEXT, + upstream_status TEXT NOT NULL DEFAULT "active", + status TEXT NOT NULL DEFAULT "active" +); + +CREATE TABLE record ( + collection TEXT NOT NULL, + account_did TEXT NOT NULL, + rkey TEXT NOT NULL, + + version TEXT, + data_json TEXT, + + PRIMARY KEY(collection, account_did, rkey) +); + +CREATE TABLE membership ( + scene_did TEXT NOT NULL, + account_did TEXT NOT NULL, + + member_rkey TEXT, + join_rkey TEXT, + role TEXT, + + PRIMARY KEY (scene_did, account_did) +); + +CREATE TABLE item ( + scene_did TEXT NOT NULL, + account_did TEXT NOT NULL, + rkey TEXT NOT NULL, + + version TEXT, + + PRIMARY KEY (scene_did, account_did, rkey) +); + +-- NOTE: 'comment' is not a reserved keyword in most SQL implementations +CREATE TABLE comment ( + scene_did TEXT NOT NULL, + account_did TEXT NOT NULL, + rkey TEXT NOT NULL, + + version TEXT, + item_account_did TEXT, + item_rkey TEXT, + parent TEXT, + + PRIMARY KEY (scene_did, account_did, rkey) +); + +CREATE INDEX idx_comments_item ON comments(item_account_did, item_rkey); + +CREATE TABLE feedback ( + scene_did TEXT NOT NULL, + account_did TEXT NOT NULL, + rkey TEXT NOT NULL, + + version TEXT, + item_account_did TEXT NOT NULL, + item_rkey TEXT NOT NULL, + value BOOLEAN, + created_at TIMESTAMP WITHOUT TIME ZONE, + + PRIMARY KEY (scene_did, account_did, rkey) +); + +CREATE INDEX idx_feedback_item ON feedback(item_account_did, item_rkey); + +CREATE TABLE reaction ( + scene_did TEXT NOT NULL, + account_did TEXT NOT NULL, + rkey TEXT NOT NULL, + + version TEXT, + item_account_did TEXT NOT NULL, + item_rkey TEXT NOT NULL, + emoji TEXT NOT NULL, + + PRIMARY KEY (scene_did, account_did, rkey) +); + +CREATE INDEX idx_reaction_item ON reaction(item_account_did, item_rkey); diff --git a/store/schemas/query.sql b/store/schemas/query.sql new file mode 100644 index 0000000..1fd784f --- /dev/null +++ b/store/schemas/query.sql @@ -0,0 +1,3 @@ +-- name: GetAccount :one +SELECT * FROM account +WHERE did = $1 LIMIT 1;