update db schema
This commit is contained in:
1 parent
11d44ccfd3
commit
0908e51791
4 files changed
+109
-24
No files matched your search
@@ -1,3 +1,24 @@
|
|||||||
|
CREATE OR REPLACE FUNCTION "f_updatedAt"()
|
||||||
|
RETURNS TRIGGER AS $$
|
||||||
|
BEGIN
|
||||||
|
NEW."updatedAt" = now();
|
||||||
|
RETURN NEW;
|
||||||
|
END;
|
||||||
|
$$ language 'plpgsql';
|
||||||
|
|
||||||
CREATE FUNCTION array_distinct(anyarray) RETURNS anyarray AS $f$
|
CREATE FUNCTION array_distinct(anyarray) RETURNS anyarray AS $f$
|
||||||
SELECT array_agg(DISTINCT x) FROM unnest($1) t(x);
|
SELECT array_agg(DISTINCT x) FROM unnest($1) t(x);
|
||||||
$f$ LANGUAGE SQL IMMUTABLE;
|
$f$ LANGUAGE SQL IMMUTABLE;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION normalize_reading (TEXT[]) RETURNS TEXT[] AS
|
||||||
|
$func$
|
||||||
|
DECLARE
|
||||||
|
s TEXT;
|
||||||
|
new_arr TEXT[] := '{}';
|
||||||
|
BEGIN
|
||||||
|
FOREACH s IN ARRAY $1||'{}'::text[] LOOP
|
||||||
|
new_arr := new_arr||ARRAY[split_part(s,'.',1), replace(s,'.','')];
|
||||||
|
END LOOP;
|
||||||
|
RETURN new_arr;
|
||||||
|
END;
|
||||||
|
$func$ LANGUAGE plpgsql IMMUTABLE;
|
||||||
@@ -1,11 +1,10 @@
|
|||||||
CREATE TABLE "user" (
|
CREATE TABLE "user" (
|
||||||
"id" UUID NOT NULL PRIMARY KEY DEFAULT uuid_generate_v4(),
|
"id" UUID NOT NULL PRIMARY KEY,
|
||||||
"createdAt" TIMESTAMPTZ DEFAULT now(),
|
"createdAt" TIMESTAMPTZ DEFAULT now(),
|
||||||
"updatedAt" TIMESTAMPTZ DEFAULT now(),
|
"updatedAt" TIMESTAMPTZ DEFAULT now(),
|
||||||
"identifier" TEXT UNIQUE NOT NULL,
|
"identifier" TEXT UNIQUE NOT NULL,
|
||||||
"wk_hash" TEXT NOT NULL,
|
|
||||||
"level.min" INT DEFAULT 1,
|
"level.min" INT DEFAULT 1,
|
||||||
"level.max" INT DEFAULT 3,
|
"level.max" INT NOT NULL,
|
||||||
"level.vocabulary.showing" TEXT[],
|
"level.vocabulary.showing" TEXT[],
|
||||||
"quiz.settings" JSONB
|
"quiz.settings" JSONB
|
||||||
);
|
);
|
||||||
@@ -17,6 +16,7 @@ CREATE TRIGGER "t_user_updatedAt"
|
|||||||
|
|
||||||
CREATE INDEX "idx_user_updatedAt" ON "user" ("updatedAt");
|
CREATE INDEX "idx_user_updatedAt" ON "user" ("updatedAt");
|
||||||
CREATE INDEX "idx_user_identifier" ON "user" ("identifier");
|
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(), '');
|
INSERT INTO "user" ("id", "identifier") VALUES
|
||||||
|
(uuid_nil(), '', 1),
|
||||||
|
('00000000-0000-0000-0000-000000000001', 'wanikani', 1);
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
CREATE TABLE "entry" (
|
||||||
|
"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,
|
||||||
|
"type" TEXT NOT NULL,
|
||||||
|
"entry" TEXT[] NOT NULL CHECK ("entry"[1] IS NOT NULL),
|
||||||
|
-- "reading" -- backref "entry.reading"
|
||||||
|
-- "translation" -- backref "entry.translation"
|
||||||
|
"description" TEXT NOT NULL DEFAULT '',
|
||||||
|
"tag" TEXT[] NOT NULL DEFAULT '{}',
|
||||||
|
"level" FLOAT NOT NULL,
|
||||||
|
"level.kanji" INT NOT NULL,
|
||||||
|
"frequency" FLOAT
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TRIGGER "t_entry_updatedAt"
|
||||||
|
BEFORE UPDATE ON "entry"
|
||||||
|
FOR EACH ROW
|
||||||
|
EXECUTE PROCEDURE "f_updatedAt"();
|
||||||
|
|
||||||
|
CREATE UNIQUE INDEX idx_entry_u ON "entry" (("entry"[1]), "type", "userId");
|
||||||
|
|
||||||
|
CREATE INDEX "idx_entry_updatedAt" ON "entry" ("updatedAt");
|
||||||
|
CREATE INDEX "idx_entry_userId" ON "entry" ("userId");
|
||||||
|
CREATE INDEX "idx_entry_type" ON "entry" ("type");
|
||||||
|
CREATE INDEX "idx_entry_level" ON "entry" ("level");
|
||||||
|
CREATE INDEX "idx_entry_level.kanji" ON "entry" ("level.kanji");
|
||||||
|
CREATE INDEX "idx_entry_frequency" ON "entry" ("frequency");
|
||||||
|
|
||||||
|
CREATE INDEX "idx_entry_description" ON "entry"
|
||||||
|
USING pgroonga("description")
|
||||||
|
WITH (plugins='token_filters/stem', token_filters='TokenFilterStem');
|
||||||
|
|
||||||
|
CREATE INDEX "idx_entry_entry" ON "entry"
|
||||||
|
USING pgroonga("entry")
|
||||||
|
WITH (
|
||||||
|
tokenizer='TokenMecab',
|
||||||
|
normalizer='NormalizerNFKC100("unify_kana", true)'
|
||||||
|
);
|
||||||
|
CREATE INDEX "idx_entry_entry_gin" ON "entry" USING GIN("entry");
|
||||||
|
CREATE INDEX "idx_entry_tag" ON "entry" USING pgroonga ("tag");
|
||||||
|
|
||||||
|
CREATE TABLE "entry.reading" (
|
||||||
|
"id" UUID NOT NULL PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||||
|
"createdAt" TIMESTAMPTZ DEFAULT now(),
|
||||||
|
"updatedAt" TIMESTAMPTZ DEFAULT now(),
|
||||||
|
"userId" UUID REFERENCES "user"("id") ON DELETE CASCADE,
|
||||||
|
"entryId" UUID REFERENCES "entry"("id") ON DELETE CASCADE
|
||||||
|
"type" TEXT NOT NULL,
|
||||||
|
"reading" TEXT[] NOT NULL DEFAULT '{}' CHECK ("reading"[1] IS NOT NULL)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX "idx_entry.reading_updatedAt" ON "entry.reading" ("updatedAt");
|
||||||
|
CREATE INDEX "idx_entry.reading_userId" ON "entry.reading" ("userId")
|
||||||
|
CREATE INDEX "idx_entry.reading_type" ON "entry.reading" ("type");
|
||||||
|
CREATE INDEX "idx_entry.reading_reading" ON "entry.reading"
|
||||||
|
USING pgroonga (normalize_reading("reading"))
|
||||||
|
WITH (
|
||||||
|
tokenizer='TokenMecab',
|
||||||
|
normalizer='NormalizerNFKC100("unify_kana", true)'
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE "entry.translation" (
|
||||||
|
"id" UUID NOT NULL PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||||
|
"createdAt" TIMESTAMPTZ DEFAULT now(),
|
||||||
|
"updatedAt" TIMESTAMPTZ DEFAULT now(),
|
||||||
|
"userId" UUID REFERENCES "user"("id") ON DELETE CASCADE,
|
||||||
|
"entryId" UUID REFERENCES "entry"("id") ON DELETE CASCADE
|
||||||
|
"language" TEXT NOT NULL,
|
||||||
|
"translation" TEXT[] NOT NULL DEFAULT '{}' CHECK ("translation"[1] IS NOT NULL)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX "idx_entry.translation_updatedAt" ON "entry.translation" ("updatedAt");
|
||||||
|
CREATE INDEX "idx_entry.translation_userId" ON "entry.translation" ("userId")
|
||||||
|
CREATE INDEX "idx_entry.translation_language" ON "entry.trnalsation" ("language");
|
||||||
|
CREATE INDEX "idx_entry.translation_translation" ON "entry.translation"
|
||||||
|
USING pgroonga("translation")
|
||||||
|
WITH (plugins='token_filters/stem', token_filters='TokenFilterStem');
|
||||||
+4
-19
@@ -1,30 +1,15 @@
|
|||||||
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" (
|
CREATE TABLE "library" (
|
||||||
"id" UUID NOT NULL PRIMARY KEY DEFAULT uuid_generate_v4(),
|
"id" UUID NOT NULL PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||||
"createdAt" TIMESTAMPTZ DEFAULT now(),
|
"createdAt" TIMESTAMPTZ DEFAULT now(),
|
||||||
"updatedAt" TIMESTAMPTZ DEFAULT now(),
|
"updatedAt" TIMESTAMPTZ DEFAULT now(),
|
||||||
"userId" UUID NOT NULL DEFAULT uuid_nil() REFERENCES "user"("id") ON DELETE CASCADE,
|
"userId" UUID NOT NULL REFERENCES "user"("id") ON DELETE CASCADE,
|
||||||
"isShared" BOOLEAN,
|
"isShared" BOOLEAN,
|
||||||
"type" TEXT NOT NULL,
|
"type" TEXT NOT NULL,
|
||||||
"entries" JSONB NOT NULL CHECK ("entries" -> 0 -> 'entry' IS NOT NULL),
|
"entry" TEXT[] NOT NULL CHECK ("entry"[1] IS NOT NULL),
|
||||||
"entry" TEXT[] GENERATED ALWAYS AS (unwrap_entries("entries")) STORED,
|
"entry.meta" JSONB DEFAULT '{}',
|
||||||
"title" TEXT NOT NULL,
|
"title" TEXT NOT NULL,
|
||||||
"description" TEXT NOT NULL DEFAULT '',
|
"description" TEXT NOT NULL DEFAULT '',
|
||||||
"tag" TEXT[] NOT NULL DEFAULT '{}'::TEXT[]
|
"tag" TEXT[] NOT NULL DEFAULT '{}'
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TRIGGER "t_library_updatedAt"
|
CREATE TRIGGER "t_library_updatedAt"
|
||||||
|
|||||||
Reference in new issue
Block a user