From 48a9c39caacd8346d241faf4156f7856204fd4c2 Mon Sep 17 00:00:00 2001 From: Alexander Zhirov Date: Sun, 14 Sep 2025 19:10:35 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=BD=D0=BE=D0=B2=D0=B0=D1=8F=20=D1=82=D0=B0?= =?UTF-8?q?=D0=B1=D0=BB=D0=B8=D1=86=D0=B0=20labels.=20=D0=A2=D0=B5=D0=BF?= =?UTF-8?q?=D0=B5=D1=80=D1=8C=20=D0=BC=D0=B5=D1=82=D0=BA=D0=B8=20=D0=B2?= =?UTF-8?q?=D1=8B=D0=BD=D0=B5=D1=81=D0=B5=D0=BD=D1=8B=20=D0=B2=20=D0=BE?= =?UTF-8?q?=D1=82=D0=B4=D0=B5=D0=BB=D1=8C=D0=BD=D1=83=D1=8E=20=D1=82=D0=B0?= =?UTF-8?q?=D0=B1=D0=BB=D0=B8=D1=86=D1=83,=20=D0=BD=D0=B5=20=D0=B4=D1=83?= =?UTF-8?q?=D0=B1=D0=BB=D0=B8=D1=80=D1=83=D1=8F=20=D0=B7=D0=B0=D0=BF=D0=B8?= =?UTF-8?q?=D1=81=D0=B8.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/cdcdb/dblite.d | 69 ++++++++++++++++++++++++++++++++++------- source/cdcdb/scheme.d | 39 +++++++++++++++++++++-- source/cdcdb/storage.d | 26 +++++++++------- source/cdcdb/version_.d | 2 +- 4 files changed, 109 insertions(+), 27 deletions(-) diff --git a/source/cdcdb/dblite.d b/source/cdcdb/dblite.d index 3e01338..217652a 100644 --- a/source/cdcdb/dblite.d +++ b/source/cdcdb/dblite.d @@ -176,10 +176,14 @@ public: auto queryResult = sql( q{ SELECT COALESCE( - (SELECT (label = ? AND sha256 = ?) - FROM snapshots - ORDER BY created_utc DESC - LIMIT 1), + ( + SELECT (s.sha256 = ?2) + FROM snapshots s + JOIN labels l ON l.id = s.label + WHERE l.name = ?1 + ORDER BY s.created_utc DESC + LIMIT 1 + ), 0 ) AS is_last; }, label, sha256 @@ -205,7 +209,10 @@ public: mask_s, mask_l, status - ) VALUES (?,?,?,?,?,?,?,?,?,?) + ) + SELECT + (SELECT id FROM labels WHERE name = ?), + ?,?,?,?,?,?,?,?,? RETURNING id }, snapshot.label, @@ -247,6 +254,18 @@ public: return !queryResult.empty(); } + bool addLabel(string name) + { + auto queryResult = sql( + q{ + INSERT INTO labels (name) VALUES (?) + ON CONFLICT(name) DO NOTHING + }, name + ); + + return !queryResult.empty(); + } + bool addSnapshotChunk(DBSnapshotChunk snapshotChunk) { auto queryResult = sql( @@ -268,9 +287,22 @@ public: { auto queryResult = sql( q{ - SELECT id, label, sha256, description, created_utc, source_length, - algo_min, algo_normal, algo_max, mask_s, mask_l, status - FROM snapshots WHERE id = ? + SELECT + s.id, + l.name label, + s.sha256, + s.description, + s.created_utc, + s.source_length, + s.algo_min, + s.algo_normal, + s.algo_max, + s.mask_s, + s.mask_l, + s.status + FROM snapshots s + JOIN labels l ON l.id = s.label + WHERE s.id = ? }, id ); @@ -301,9 +333,22 @@ public: { auto queryResult = sql( q{ - SELECT id, label, sha256, description, created_utc, source_length, - algo_min, algo_normal, algo_max, mask_s, mask_l, status - FROM snapshots WHERE (length(?) = 0 OR label = ?1); + SELECT + s.id, + l.name label, + s.sha256, + s.description, + s.created_utc, + s.source_length, + s.algo_min, + s.algo_normal, + s.algo_max, + s.mask_s, + s.mask_l, + s.status + FROM snapshots s + JOIN labels l ON l.id = s.label AND (length(?) = 0 OR l.name = ?1) + ORDER BY s.created_utc, s.id; }, label ); @@ -379,7 +424,7 @@ public: auto queryResult = sql( q{ DELETE FROM snapshots - WHERE label = ? + WHERE label = (SELECT id FROM labels WHERE name = ?) RETURNING 1; }, label); diff --git a/source/cdcdb/scheme.d b/source/cdcdb/scheme.d index b3b10c4..1527ea1 100644 --- a/source/cdcdb/scheme.d +++ b/source/cdcdb/scheme.d @@ -1,4 +1,20 @@ auto _scheme = [ + q{ + -- ------------------------------------------------------------ + -- Таблица labels + -- ------------------------------------------------------------ + CREATE TABLE IF NOT EXISTS labels ( + -- идентификатор метки + id INTEGER PRIMARY KEY AUTOINCREMENT, + -- имя метки + name TEXT NOT NULL UNIQUE + ) + }, + q{ + -- Индекс по имени метки + CREATE INDEX IF NOT EXISTS idx_labels_name + ON labels(name) + }, q{ -- ------------------------------------------------------------ -- Таблица snapshots @@ -7,7 +23,7 @@ auto _scheme = [ -- идентификатор снимка id INTEGER PRIMARY KEY AUTOINCREMENT, -- метка/название снимка - label TEXT NOT NULL, + label INTEGER NOT NULL, -- SHA-256 всего файла (BLOB(32)) sha256 BLOB NOT NULL CHECK (length(sha256) = 32), -- Комментарий/описание @@ -28,7 +44,11 @@ auto _scheme = [ mask_l INTEGER NOT NULL, -- 0=pending, 1=ready status INTEGER NOT NULL DEFAULT 0 - CHECK (status IN (0,1)) + CHECK (status IN (0,1)), + FOREIGN KEY (label) + REFERENCES labels(id) + ON UPDATE CASCADE + ON DELETE CASCADE ) }, q{ @@ -249,5 +269,20 @@ auto _scheme = [ BEGIN SELECT RAISE(ABORT, "blobs: разрешён UPDATE только полей last_seen_utc и refcount"); END + }, + q{ + -- ------------------------------------------------------------ + -- Удаление записи из labels, если удалён последний snapshot + -- ------------------------------------------------------------ + CREATE TRIGGER IF NOT EXISTS trg_snapshots_delete_label + AFTER DELETE ON snapshots + FOR EACH ROW + BEGIN + DELETE FROM labels + WHERE id = OLD.label + AND NOT EXISTS ( + SELECT 1 FROM snapshots WHERE label = OLD.label + ); + END; } ]; diff --git a/source/cdcdb/storage.d b/source/cdcdb/storage.d index 74df78d..ee7424b 100644 --- a/source/cdcdb/storage.d +++ b/source/cdcdb/storage.d @@ -112,18 +112,6 @@ public: if (_db.isLast(label, sha256)) return null; - DBSnapshot dbSnapshot; - - dbSnapshot.label = label; - dbSnapshot.sha256 = sha256; - dbSnapshot.description = description; - dbSnapshot.sourceLength = data.length; - dbSnapshot.algoMin = _minSize; - dbSnapshot.algoNormal = _normalSize; - dbSnapshot.algoMax = _maxSize; - dbSnapshot.maskS = _maskS; - dbSnapshot.maskL = _maskL; - _db.beginImmediate(); bool ok; @@ -138,6 +126,20 @@ public: _db.commit(); } + _db.addLabel(label); + + DBSnapshot dbSnapshot; + + dbSnapshot.label = label; + dbSnapshot.sha256 = sha256; + dbSnapshot.description = description; + dbSnapshot.sourceLength = data.length; + dbSnapshot.algoMin = _minSize; + dbSnapshot.algoNormal = _normalSize; + dbSnapshot.algoMax = _maxSize; + dbSnapshot.maskS = _maskS; + dbSnapshot.maskL = _maskL; + auto idSnapshot = _db.addSnapshot(dbSnapshot); DBSnapshotChunk dbSnapshotChunk; diff --git a/source/cdcdb/version_.d b/source/cdcdb/version_.d index ac00177..142c1db 100644 --- a/source/cdcdb/version_.d +++ b/source/cdcdb/version_.d @@ -1,3 +1,3 @@ module cdcdb.version_; -enum cdcdbVersion = "0.1.0"; +enum cdcdbVersion = "0.1.1";