73 lines
2.2 KiB
TypeScript
73 lines
2.2 KiB
TypeScript
const db = getDb("cache.sqlite");
|
|
db.table(
|
|
"asset_refs",
|
|
/* SQL */ `
|
|
create table if not exists asset_refs (
|
|
id integer primary key autoincrement,
|
|
key text not null UNIQUE,
|
|
refs integer not null
|
|
);
|
|
create table if not exists asset_ref_files (
|
|
file text not null,
|
|
id integer not null,
|
|
foreign key (id) references asset_refs(id) ON DELETE CASCADE
|
|
);
|
|
create index asset_ref_files_id on asset_ref_files(id);
|
|
`,
|
|
);
|
|
|
|
/**
|
|
* Uncompressed files are read directly from the media store root. Derivied
|
|
* assets like compressed files, optimized images, and streamable video are
|
|
* stored in the `derived` folder. After scanning, the derived assets are
|
|
* uploaded into the store (storage1/clofi-derived dataset on NAS). Since
|
|
* multiple files can share the same hash, the number of references is
|
|
* tracked, and the derived content is only produced once. This means if a
|
|
* file is deleted, it should only decrement a reference count; deleting it
|
|
* once all references are removed.
|
|
*/
|
|
export class AssetRef {
|
|
/** Key which aws referenced */
|
|
id!: number;
|
|
key!: string;
|
|
refs!: number;
|
|
|
|
unref() {
|
|
decrementQuery.run(this.key);
|
|
deleteUnreferencedQuery.run().changes > 0;
|
|
}
|
|
|
|
addFiles(files: string[]) {
|
|
for (const file of files) {
|
|
addFileQuery.run({ id: this.id, file });
|
|
}
|
|
}
|
|
|
|
static get(key: string) {
|
|
return getQuery.get(key);
|
|
}
|
|
|
|
static putOrIncrement(key: string) {
|
|
putOrIncrementQuery.get(key);
|
|
return UNWRAP(AssetRef.get(key));
|
|
}
|
|
}
|
|
|
|
const getQuery = db.prepare<[key: string]>(/* SQL */ `
|
|
select * from asset_refs where key = ?;
|
|
`).as(AssetRef);
|
|
const putOrIncrementQuery = db.prepare<[key: string]>(/* SQL */ `
|
|
insert into asset_refs (key, refs) values (?, 1)
|
|
on conflict(key) do update set refs = refs + 1;
|
|
`);
|
|
const decrementQuery = db.prepare<[key: string]>(/* SQL */ `
|
|
update asset_refs set refs = refs - 1 where key = ? and refs > 0;
|
|
`);
|
|
const deleteUnreferencedQuery = db.prepare(/* SQL */ `
|
|
delete from asset_refs where refs <= 0;
|
|
`);
|
|
const addFileQuery = db.prepare<[{ id: number; file: string }]>(/* SQL */ `
|
|
insert into asset_ref_files (id, file) values ($id, $file);
|
|
`);
|
|
|
|
import { getDb } from "#sitegen/sqlite";
|