proofdb/scripts/setup_database.php
2026-05-01 23:40:14 +08:00

90 lines
2.7 KiB
PHP

#!/usr/bin/env php
<?php
use support\Db;
require __DIR__ . '/../vendor/autoload.php';
require __DIR__ . '/../support/bootstrap.php';
require __DIR__ . '/../vendor/webman/database/src/support/Db.php';
$statements = [
<<<SQL
CREATE TABLE IF NOT EXISTS archives (
id BIGSERIAL PRIMARY KEY,
archive_uid VARCHAR(26) NOT NULL UNIQUE,
title TEXT,
summary TEXT,
year INTEGER,
author TEXT,
source TEXT,
series TEXT,
tags JSONB NOT NULL DEFAULT '[]'::jsonb,
metadata JSONB NOT NULL DEFAULT '{}'::jsonb,
content TEXT,
raw TEXT,
chunks JSONB NOT NULL DEFAULT '[]'::jsonb,
created_time TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_time TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
)
SQL,
'ALTER TABLE archives ADD COLUMN IF NOT EXISTS summary TEXT',
<<<SQL
CREATE TABLE IF NOT EXISTS chunks (
id BIGSERIAL PRIMARY KEY,
chunk_uid VARCHAR(64) NOT NULL UNIQUE,
archive_uid VARCHAR(26) NOT NULL,
chunk_index INTEGER NOT NULL,
page_start INTEGER,
page_end INTEGER,
text TEXT,
length INTEGER,
embedding_status INTEGER NOT NULL DEFAULT 0,
embedding_ref JSONB,
embedding_model TEXT,
CONSTRAINT chunks_archive_uid_foreign
FOREIGN KEY (archive_uid)
REFERENCES archives (archive_uid)
ON DELETE CASCADE,
CONSTRAINT chunks_archive_index_unique
UNIQUE (archive_uid, chunk_index)
)
SQL,
'CREATE INDEX IF NOT EXISTS archives_year_index ON archives (year)',
'CREATE INDEX IF NOT EXISTS archives_series_index ON archives (series)',
'CREATE INDEX IF NOT EXISTS archives_tags_gin_index ON archives USING GIN (tags)',
'CREATE INDEX IF NOT EXISTS archives_metadata_gin_index ON archives USING GIN (metadata)',
'CREATE INDEX IF NOT EXISTS chunks_archive_uid_index ON chunks (archive_uid)',
'CREATE INDEX IF NOT EXISTS chunks_page_range_index ON chunks (archive_uid, page_start, page_end)',
'CREATE INDEX IF NOT EXISTS chunks_embedding_status_index ON chunks (embedding_status)',
<<<SQL
CREATE OR REPLACE FUNCTION set_updated_time()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_time = CURRENT_TIMESTAMP;
RETURN NEW;
END;
$$ LANGUAGE plpgsql
SQL,
'DROP TRIGGER IF EXISTS archives_set_updated_time ON archives',
<<<SQL
CREATE TRIGGER archives_set_updated_time
BEFORE UPDATE ON archives
FOR EACH ROW
EXECUTE FUNCTION set_updated_time()
SQL,
];
try {
Db::connection()->getPdo();
echo 'Database connection ok: ' . config('database.default') . PHP_EOL;
foreach ($statements as $statement) {
Db::statement($statement);
}
echo 'Tables initialized: archives, chunks' . PHP_EOL;
} catch (Throwable $exception) {
fwrite(STDERR, $exception::class . ': ' . $exception->getMessage() . PHP_EOL);
exit(1);
}