First pass implementation of an SQLite backing store for fetched opportunities
This commit is contained in:
1 parent
9b0e6dccfe
commit
045492a148
29 files changed
+3132
-9
No files matched your search
@@ -0,0 +1,40 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
CREATE TABLE IF NOT EXISTS "opportunities" (
|
||||
-- Surrogate key. "uuid" is the real identifier; "id" exists only to give
|
||||
-- the title search index (opportunities_fts) a stable rowid to point at.
|
||||
"id" INTEGER PRIMARY KEY,
|
||||
"uuid" TEXT NOT NULL UNIQUE,
|
||||
"uuid_type" TEXT NOT NULL,
|
||||
"title" TEXT NOT NULL,
|
||||
"status" TEXT NOT NULL,
|
||||
"description" TEXT NOT NULL DEFAULT '',
|
||||
"buyer_name" TEXT NOT NULL DEFAULT '',
|
||||
-- classifications: see tender_classifications
|
||||
"buyer_id" TEXT NOT NULL DEFAULT '',
|
||||
"main_category" TEXT NOT NULL DEFAULT '',
|
||||
"procurement_method" TEXT NOT NULL DEFAULT '',
|
||||
"multi_lot" BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
"sme_suitable" BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
"vcse_suitable" BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
"start_date" DATETIME,
|
||||
"end_date" DATETIME,
|
||||
"gross_value" REAL NOT NULL DEFAULT 0,
|
||||
"has_documents" BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
"source" TEXT NOT NULL DEFAULT '',
|
||||
-- Release date of the newest release applied to this row. A release
|
||||
-- older than this never overwrites the tender.
|
||||
"latest_release_date" DATETIME NOT NULL
|
||||
-- releases: see tender_ocds_releases
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS "opportunities_status"
|
||||
ON "opportunities" ("status");
|
||||
CREATE INDEX IF NOT EXISTS "opportunities_latest_release_date"
|
||||
ON "opportunities" ("latest_release_date");
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
DROP TABLE IF EXISTS "opportunities";
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,19 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
-- Write-once: a release is never modified after it is stored.
|
||||
-- "release_id" is the OCDS release id, unique only within its OCID ("uuid").
|
||||
CREATE TABLE IF NOT EXISTS "opportunity_releases" (
|
||||
"uuid" TEXT NOT NULL
|
||||
REFERENCES "opportunities" ("uuid") ON DELETE CASCADE,
|
||||
"release_id" TEXT NOT NULL,
|
||||
"release_date" DATETIME NOT NULL,
|
||||
-- tags: see release_tags
|
||||
"data" TEXT NOT NULL,
|
||||
PRIMARY KEY ("uuid", "release_id")
|
||||
) WITHOUT ROWID;
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
DROP TABLE IF EXISTS "opportunity_releases";
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,18 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
-- Write-once, inserted together with the release it belongs to.
|
||||
CREATE TABLE IF NOT EXISTS "opportunity_release_tags" (
|
||||
"uuid" TEXT NOT NULL,
|
||||
"release_id" TEXT NOT NULL,
|
||||
"tag" TEXT NOT NULL,
|
||||
PRIMARY KEY ("uuid", "release_id", "tag"),
|
||||
FOREIGN KEY ("uuid", "release_id")
|
||||
REFERENCES "opportunity_releases" ("uuid", "release_id")
|
||||
ON DELETE CASCADE
|
||||
) WITHOUT ROWID;
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
DROP TABLE IF EXISTS "opportunity_release_tags";
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,26 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
-- Shared, write-once lookup of classifications. A row is reused only when
|
||||
-- every content column matches; any difference (e.g. a changed description)
|
||||
-- creates a new row.
|
||||
--
|
||||
-- When adding a new scheme flag column (e.g. "is_unspsc"), the same migration
|
||||
-- must drop and recreate "classification_codes_content" with the new column
|
||||
-- included, otherwise rows differing only by that flag would be merged.
|
||||
CREATE TABLE IF NOT EXISTS "classification_codes" (
|
||||
"id" INTEGER PRIMARY KEY,
|
||||
"is_cpv" BOOLEAN NOT NULL,
|
||||
"code" TEXT NOT NULL,
|
||||
"classification" TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "classification_codes_content"
|
||||
ON "classification_codes" ("is_cpv", "code", "classification");
|
||||
CREATE INDEX IF NOT EXISTS "classification_codes_code"
|
||||
ON "classification_codes" ("code");
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
DROP TABLE IF EXISTS "classification_codes";
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,20 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
-- Maps opportunities to classification codes. Replaced as a set whenever the
|
||||
-- opportunity row is updated.
|
||||
CREATE TABLE IF NOT EXISTS "opportunity_classifications" (
|
||||
"opportunity_uuid" TEXT NOT NULL
|
||||
REFERENCES "opportunities" ("uuid") ON DELETE CASCADE,
|
||||
"classification_id" INTEGER NOT NULL
|
||||
REFERENCES "classification_codes" ("id"),
|
||||
PRIMARY KEY ("opportunity_uuid", "classification_id")
|
||||
) WITHOUT ROWID;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS "opportunity_classifications_classification_id"
|
||||
ON "opportunity_classifications" ("classification_id");
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
DROP TABLE IF EXISTS "opportunity_classifications";
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,40 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
-- Full-text index over opportunities.title. Requires mattn/go-sqlite3 to be
|
||||
-- built with -tags sqlite_fts5. Kept in sync by the triggers below.
|
||||
CREATE VIRTUAL TABLE IF NOT EXISTS "opportunities_fts" USING fts5(
|
||||
"title",
|
||||
content = 'opportunities',
|
||||
content_rowid = 'id',
|
||||
tokenize = 'porter unicode61 remove_diacritics 2'
|
||||
);
|
||||
|
||||
CREATE TRIGGER IF NOT EXISTS "opportunities_fts_insert" AFTER INSERT ON "opportunities"
|
||||
BEGIN
|
||||
INSERT INTO "opportunities_fts" ("rowid", "title") VALUES (new."id", new."title");
|
||||
END;
|
||||
|
||||
CREATE TRIGGER IF NOT EXISTS "opportunities_fts_delete" AFTER DELETE ON "opportunities"
|
||||
BEGIN
|
||||
INSERT INTO "opportunities_fts" ("opportunities_fts", "rowid", "title")
|
||||
VALUES ('delete', old."id", old."title");
|
||||
END;
|
||||
|
||||
CREATE TRIGGER IF NOT EXISTS "opportunities_fts_update" AFTER UPDATE OF "title" ON "opportunities"
|
||||
BEGIN
|
||||
INSERT INTO "opportunities_fts" ("opportunities_fts", "rowid", "title")
|
||||
VALUES ('delete', old."id", old."title");
|
||||
INSERT INTO "opportunities_fts" ("rowid", "title") VALUES (new."id", new."title");
|
||||
END;
|
||||
|
||||
-- Index any opportunities that existed before this migration.
|
||||
INSERT INTO "opportunities_fts" ("opportunities_fts") VALUES ('rebuild');
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
DROP TRIGGER IF EXISTS "opportunities_fts_update";
|
||||
DROP TRIGGER IF EXISTS "opportunities_fts_delete";
|
||||
DROP TRIGGER IF EXISTS "opportunities_fts_insert";
|
||||
DROP TABLE IF EXISTS "opportunities_fts";
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,22 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
CREATE TABLE IF NOT EXISTS "opportunity_marks" (
|
||||
"uuid" TEXT NOT NULL UNIQUE,
|
||||
"hidden" BOOLEAN NOT NULL DEFAULT 0,
|
||||
"skipped" BOOLEAN NOT NULL DEFAULT 0,
|
||||
"interested" BOOLEAN NOT NULL DEFAULT 0,
|
||||
"bid_submitted" BOOLEAN NOT NULL DEFAULT 0,
|
||||
"lost" BOOLEAN NOT NULL DEFAULT 0,
|
||||
"won" BOOLEAN NOT NULL DEFAULT 0,
|
||||
CHECK (NOT ("won" AND "lost")),
|
||||
PRIMARY KEY ("uuid"),
|
||||
FOREIGN KEY ("uuid")
|
||||
REFERENCES "opportunities" ("uuid")
|
||||
ON DELETE CASCADE
|
||||
);
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
DROP TABLE IF EXISTS "opportunity_marks";
|
||||
-- +goose StatementEnd
|
||||
Reference in new issue
Block a user