Добавлена новая таблица labels. Теперь метки вынесены в отдельную таблицу, не дублируя записи.

This commit is contained in:
Alexander Zhirov 2025-09-14 19:10:35 +03:00
parent 5bb4d65c92
commit 48a9c39caa
Signed by: alexander
GPG key ID: C8D8BE544A27C511
4 changed files with 109 additions and 27 deletions

View file

@ -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);

View file

@ -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;
}
];

View file

@ -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;

View file

@ -1,3 +1,3 @@
module cdcdb.version_;
enum cdcdbVersion = "0.1.0";
enum cdcdbVersion = "0.1.1";