clone basic database structure from zhquiz
This commit is contained in:
1 parent
6be2365fc6
commit
11d44ccfd3
18 files changed
+1594
No files matched your search
@@ -0,0 +1,4 @@
|
||||
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
||||
|
||||
CREATE EXTENSION IF NOT EXISTS pgroonga;
|
||||
CREATE EXTENSION IF NOT EXISTS "postgres-json-schema";
|
||||
@@ -0,0 +1,3 @@
|
||||
CREATE FUNCTION array_distinct(anyarray) RETURNS anyarray AS $f$
|
||||
SELECT array_agg(DISTINCT x) FROM unnest($1) t(x);
|
||||
$f$ LANGUAGE SQL IMMUTABLE;
|
||||
@@ -0,0 +1,22 @@
|
||||
CREATE TABLE "user" (
|
||||
"id" UUID NOT NULL PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
"createdAt" TIMESTAMPTZ DEFAULT now(),
|
||||
"updatedAt" TIMESTAMPTZ DEFAULT now(),
|
||||
"identifier" TEXT UNIQUE NOT NULL,
|
||||
"wk_hash" TEXT NOT NULL,
|
||||
"level.min" INT DEFAULT 1,
|
||||
"level.max" INT DEFAULT 3,
|
||||
"level.vocabulary.showing" TEXT[],
|
||||
"quiz.settings" JSONB
|
||||
);
|
||||
|
||||
CREATE TRIGGER "t_user_updatedAt"
|
||||
BEFORE UPDATE ON "user"
|
||||
FOR EACH ROW
|
||||
EXECUTE PROCEDURE "f_updatedAt"();
|
||||
|
||||
CREATE INDEX "idx_user_updatedAt" ON "user" ("updatedAt");
|
||||
CREATE INDEX "idx_user_identifier" ON "user" ("identifier");
|
||||
CREATE INDEX "idx_user_wk_hash" ON "user" ("wk_hash");
|
||||
|
||||
INSERT INTO "user" ("id", "identifier") VALUES (uuid_nil(), '');
|
||||
@@ -0,0 +1,44 @@
|
||||
CREATE TABLE "quiz" (
|
||||
"id" UUID NOT NULL PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
"createdAt" TIMESTAMPTZ DEFAULT now(),
|
||||
"updatedAt" TIMESTAMPTZ DEFAULT now(),
|
||||
"userId" UUID NOT NULL REFERENCES "user"("id") ON DELETE CASCADE,
|
||||
"entry" TEXT NOT NULL,
|
||||
"type" TEXT NOT NULL,
|
||||
"direction" TEXT NOT NULL,
|
||||
"front" TEXT NOT NULL DEFAULT '',
|
||||
"back" TEXT NOT NULL DEFAULT '',
|
||||
"hint" TEXT NOT NULL DEFAULT '',
|
||||
"mnemonic" TEXT NOT NULL DEFAULT '',
|
||||
"srsLevel" INT,
|
||||
"nextReview" TIMESTAMPTZ,
|
||||
"lastRight" TIMESTAMPTZ,
|
||||
"lastWrong" TIMESTAMPTZ,
|
||||
"maxRight" INT,
|
||||
"maxWrong" INT,
|
||||
"rightStreak" INT,
|
||||
"wrongStreak" INT
|
||||
);
|
||||
|
||||
CREATE TRIGGER "t_quiz_updatedAt"
|
||||
BEFORE UPDATE ON "quiz"
|
||||
FOR EACH ROW
|
||||
EXECUTE PROCEDURE "f_updatedAt"();
|
||||
|
||||
CREATE UNIQUE INDEX "idx_u_quiz" ON "quiz" ("userId", "entry", "type", "direction");
|
||||
|
||||
CREATE INDEX "idx_quiz_q" ON "quiz"
|
||||
USING pgroonga ("front", "back", "hint", "mnemonic")
|
||||
WITH (plugins='token_filters/stem', token_filters='TokenFilterStem');
|
||||
|
||||
CREATE INDEX "idx_quiz_entry" ON "quiz" ("entry");
|
||||
CREATE INDEX "idx_quiz_updatedAt" ON "quiz" ("updatedAt");
|
||||
CREATE INDEX "idx_quiz_userId" ON "quiz" ("userId");
|
||||
CREATE INDEX "idx_quiz_srsLevel" ON "quiz" ("srsLevel");
|
||||
CREATE INDEX "idx_quiz_nextReview" ON "quiz" ("nextReview");
|
||||
CREATE INDEX "idx_quiz_lastRight" ON "quiz" ("lastRight");
|
||||
CREATE INDEX "idx_quiz_lastWrong" ON "quiz" ("lastWrong");
|
||||
CREATE INDEX "idx_quiz_maxRight" ON "quiz" ("maxRight");
|
||||
CREATE INDEX "idx_quiz_maxWrong" ON "quiz" ("maxWrong");
|
||||
CREATE INDEX "idx_quiz_rightStreak" ON "quiz" ("rightStreak");
|
||||
CREATE INDEX "idx_quiz_wrongStreak" ON "quiz" ("wrongStreak");
|
||||
@@ -0,0 +1,48 @@
|
||||
CREATE OR REPLACE FUNCTION unwrap_entries (JSONB) RETURNS TEXT[] AS
|
||||
$func$
|
||||
DECLARE
|
||||
it JSONB;
|
||||
"out" TEXT[] := '{}'::text[];
|
||||
BEGIN
|
||||
FOR it IN (SELECT * FROM jsonb_array_elements($1))
|
||||
LOOP
|
||||
"out" := "out"||(it ->> 'entry');
|
||||
END LOOP;
|
||||
|
||||
RETURN "out";
|
||||
END;
|
||||
$func$ LANGUAGE plpgsql IMMUTABLE;
|
||||
|
||||
CREATE TABLE "library" (
|
||||
"id" UUID NOT NULL PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
"createdAt" TIMESTAMPTZ DEFAULT now(),
|
||||
"updatedAt" TIMESTAMPTZ DEFAULT now(),
|
||||
"userId" UUID NOT NULL DEFAULT uuid_nil() REFERENCES "user"("id") ON DELETE CASCADE,
|
||||
"isShared" BOOLEAN,
|
||||
"type" TEXT NOT NULL,
|
||||
"entries" JSONB NOT NULL CHECK ("entries" -> 0 -> 'entry' IS NOT NULL),
|
||||
"entry" TEXT[] GENERATED ALWAYS AS (unwrap_entries("entries")) STORED,
|
||||
"title" TEXT NOT NULL,
|
||||
"description" TEXT NOT NULL DEFAULT '',
|
||||
"tag" TEXT[] NOT NULL DEFAULT '{}'::TEXT[]
|
||||
);
|
||||
|
||||
CREATE TRIGGER "t_library_updatedAt"
|
||||
BEFORE UPDATE ON "library"
|
||||
FOR EACH ROW
|
||||
EXECUTE PROCEDURE "f_updatedAt"();
|
||||
|
||||
CREATE INDEX "idx_library_updatedAt" ON "library" ("updatedAt");
|
||||
CREATE INDEX "idx_library_userId" ON "library" ("userId");
|
||||
CREATE INDEX "idx_library_isShared" ON "library" ("isShared");
|
||||
CREATE INDEX "idx_library_type" ON "library" ("type");
|
||||
|
||||
CREATE INDEX "idx_library_entry" ON "library"
|
||||
USING pgroonga("entry");
|
||||
CREATE INDEX "idx_library_title_description" ON "library"
|
||||
USING pgroonga(
|
||||
"title",
|
||||
"description"
|
||||
)
|
||||
WITH (plugins='token_filters/stem', token_filters='TokenFilterStem');
|
||||
CREATE INDEX "idx_library_tag" ON "library" USING pgroonga ("tag");
|
||||
@@ -0,0 +1,18 @@
|
||||
CREATE TABLE "quiz_preset" (
|
||||
"id" UUID NOT NULL PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
"createdAt" TIMESTAMPTZ DEFAULT now(),
|
||||
"updatedAt" TIMESTAMPTZ DEFAULT now(),
|
||||
"userId" UUID NOT NULL REFERENCES "user"("id") ON DELETE CASCADE,
|
||||
"name" TEXT NOT NULL,
|
||||
"settings" JSONB NOT NULL
|
||||
);
|
||||
|
||||
CREATE TRIGGER "t_quiz_preset_updatedAt"
|
||||
BEFORE UPDATE ON "quiz_preset"
|
||||
FOR EACH ROW
|
||||
EXECUTE PROCEDURE "f_updatedAt"();
|
||||
|
||||
CREATE INDEX "idx_quiz_preset_updatedAt" ON "quiz_preset" ("updatedAt");
|
||||
CREATE INDEX "idx_quiz_preset_userId" ON "quiz_preset" ("userId");
|
||||
CREATE INDEX "idx_quiz_preset_name" ON "quiz_preset"
|
||||
USING pgroonga ("name");
|
||||
@@ -0,0 +1,26 @@
|
||||
CREATE TABLE radical (
|
||||
"entry" TEXT NOT NULL PRIMARY KEY,
|
||||
"sub" TEXT[] NOT NULL,
|
||||
"sup" TEXT[] NOT NULL,
|
||||
"var" TEXT[] NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX idx_radical_search ON radical
|
||||
USING pgroonga ("entry", "sub", "sup", "var")
|
||||
WITH (tokenizer='TokenUnigram');
|
||||
|
||||
CREATE INDEX idx_radical_synonyms ON radical
|
||||
USING pgroonga ("entry" pgroonga_text_term_search_ops_v2)
|
||||
WITH (tokenizer='TokenUnigram');
|
||||
|
||||
CREATE OR REPLACE FUNCTION character_expand (TEXT) RETURNS TEXT AS
|
||||
$func$
|
||||
DECLARE
|
||||
exp TEXT := pgroonga_query_expand('radical',
|
||||
'entry',
|
||||
'var',
|
||||
$1);
|
||||
BEGIN
|
||||
RETURN $1||' OR '||exp;
|
||||
END;
|
||||
$func$ LANGUAGE plpgsql IMMUTABLE;
|
||||
@@ -0,0 +1,12 @@
|
||||
-- cat ./node_modules/connect-pg-simple/table.sql
|
||||
|
||||
CREATE TABLE "session" (
|
||||
"sid" varchar NOT NULL COLLATE "default",
|
||||
"sess" json NOT NULL,
|
||||
"expire" timestamp(6) NOT NULL
|
||||
)
|
||||
WITH (OIDS=FALSE);
|
||||
|
||||
ALTER TABLE "session" ADD CONSTRAINT "session_pkey" PRIMARY KEY ("sid") NOT DEFERRABLE INITIALLY IMMEDIATE;
|
||||
|
||||
CREATE INDEX "IDX_session_expire" ON "session" ("expire");
|
||||
Executable
+11
@@ -0,0 +1,11 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
pg_ctl -o "-c listen_addresses='localhost'" -w restart
|
||||
|
||||
cd /app
|
||||
|
||||
if [[ -d "./lib" ]]; then
|
||||
node ./lib/init.js
|
||||
else
|
||||
yarn ts ./src/init.ts
|
||||
fi
|
||||
Reference in new issue
Block a user