caching system + add extension entries to metadata pool
This commit is contained in:
@@ -7,9 +7,46 @@ const databases = new Map();
|
||||
|
||||
const DEFAULT_PATHS = {
|
||||
anilist: path.join(__dirname, '..', 'metadata', 'anilist_anime.db'),
|
||||
favorites: path.join(os.homedir(), "WaifuBoards", "favorites.db")
|
||||
favorites: path.join(os.homedir(), "WaifuBoards", "favorites.db"),
|
||||
|
||||
cache: path.join(os.homedir(), "WaifuBoards", "cache.db")
|
||||
};
|
||||
|
||||
async function ensureExtensionsTable(db) {
|
||||
return new Promise((resolve, reject) => {
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS extension (
|
||||
ext_name TEXT NOT NULL,
|
||||
id TEXT NOT NULL,
|
||||
title TEXT NOT NULL,
|
||||
metadata TEXT NOT NULL,
|
||||
updated_at INTEGER NOT NULL,
|
||||
|
||||
PRIMARY KEY(ext_name, id)
|
||||
);
|
||||
`, (err) => {
|
||||
if (err) reject(err);
|
||||
else resolve(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function ensureCacheTable(db) {
|
||||
return new Promise((resolve, reject) => {
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS cache (
|
||||
key TEXT PRIMARY KEY,
|
||||
result TEXT NOT NULL,
|
||||
created_at INTEGER NOT NULL,
|
||||
ttl_ms INTEGER NOT NULL
|
||||
);
|
||||
`, (err) => {
|
||||
if (err) reject(err);
|
||||
else resolve(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function ensureFavoritesDB(dbPath) {
|
||||
const dir = path.dirname(dbPath);
|
||||
|
||||
@@ -25,7 +62,6 @@ function ensureFavoritesDB(dbPath) {
|
||||
);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
if (!exists) {
|
||||
const schema = `
|
||||
CREATE TABLE IF NOT EXISTS favorites (
|
||||
@@ -56,15 +92,11 @@ function ensureFavoritesDB(dbPath) {
|
||||
const queries = [];
|
||||
|
||||
if (!hasHeaders) {
|
||||
queries.push(
|
||||
`ALTER TABLE favorites ADD COLUMN headers TEXT NOT NULL DEFAULT ""`
|
||||
);
|
||||
queries.push(`ALTER TABLE favorites ADD COLUMN headers TEXT NOT NULL DEFAULT ""`);
|
||||
}
|
||||
|
||||
if (!hasProvider) {
|
||||
queries.push(
|
||||
`ALTER TABLE favorites ADD COLUMN provider TEXT NOT NULL DEFAULT ""`
|
||||
);
|
||||
queries.push(`ALTER TABLE favorites ADD COLUMN provider TEXT NOT NULL DEFAULT ""`);
|
||||
}
|
||||
|
||||
if (queries.length === 0) {
|
||||
@@ -91,6 +123,13 @@ function initDatabase(name = 'anilist', dbPath = null, readOnly = false) {
|
||||
.catch(err => console.error("Error creando favorites:", err));
|
||||
}
|
||||
|
||||
if (name === "cache") {
|
||||
const dir = path.dirname(finalPath);
|
||||
if (!fs.existsSync(dir)) {
|
||||
fs.mkdirSync(dir, { recursive: true });
|
||||
}
|
||||
}
|
||||
|
||||
const mode = readOnly ? sqlite3.OPEN_READONLY : (sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE);
|
||||
|
||||
const db = new sqlite3.Database(finalPath, mode, (err) => {
|
||||
@@ -102,12 +141,25 @@ function initDatabase(name = 'anilist', dbPath = null, readOnly = false) {
|
||||
});
|
||||
|
||||
databases.set(name, db);
|
||||
|
||||
if (name === "anilist") {
|
||||
ensureExtensionsTable(db)
|
||||
.catch(err => console.error("Error creating extension table:", err));
|
||||
}
|
||||
|
||||
if (name === "cache") {
|
||||
ensureCacheTable(db)
|
||||
.catch(err => console.error("Error creating cache table:", err));
|
||||
}
|
||||
|
||||
return db;
|
||||
}
|
||||
|
||||
function getDatabase(name = 'anilist') {
|
||||
if (!databases.has(name)) {
|
||||
return initDatabase(name, null, name === 'anilist');
|
||||
|
||||
const readOnly = (name === 'anilist');
|
||||
return initDatabase(name, null, readOnly);
|
||||
}
|
||||
return databases.get(name);
|
||||
}
|
||||
@@ -156,11 +208,73 @@ function closeDatabase(name = null) {
|
||||
}
|
||||
}
|
||||
|
||||
async function getCachedExtension(extName, id) {
|
||||
return queryOne(
|
||||
"SELECT metadata FROM extension WHERE ext_name = ? AND id = ?",
|
||||
[extName, id]
|
||||
);
|
||||
}
|
||||
|
||||
async function cacheExtension(extName, id, title, metadata) {
|
||||
return run(
|
||||
`
|
||||
INSERT INTO extension (ext_name, id, title, metadata, updated_at)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
ON CONFLICT(ext_name, id)
|
||||
DO UPDATE SET
|
||||
title = excluded.title,
|
||||
metadata = excluded.metadata,
|
||||
updated_at = ?
|
||||
`,
|
||||
[extName, id, title, JSON.stringify(metadata), Date.now(), Date.now()]
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
async function getExtensionTitle(extName, id) {
|
||||
|
||||
const sql = "SELECT title FROM extension WHERE ext_name = ? AND id = ?";
|
||||
|
||||
const row = await queryOne(sql, [extName, id], 'anilist');
|
||||
|
||||
return row ? row.title : null;
|
||||
}
|
||||
|
||||
async function deleteExtension(extName) {
|
||||
return run(
|
||||
"DELETE FROM extension WHERE ext_name = ?",
|
||||
[extName]
|
||||
);
|
||||
}
|
||||
|
||||
async function getCache(key) {
|
||||
return queryOne("SELECT result, created_at, ttl_ms FROM cache WHERE key = ?", [key], "cache");
|
||||
}
|
||||
|
||||
async function setCache(key, result, ttl_ms) {
|
||||
return run(
|
||||
`
|
||||
INSERT INTO cache (key, result, created_at, ttl_ms)
|
||||
VALUES (?, ?, ?, ?)
|
||||
ON CONFLICT(key)
|
||||
DO UPDATE SET result = excluded.result, created_at = excluded.created_at, ttl_ms = excluded.ttl_ms
|
||||
`,
|
||||
[key, JSON.stringify(result), Date.now(), ttl_ms],
|
||||
"cache"
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
initDatabase,
|
||||
getDatabase,
|
||||
queryOne,
|
||||
queryAll,
|
||||
run,
|
||||
closeDatabase
|
||||
getCachedExtension,
|
||||
cacheExtension,
|
||||
getExtensionTitle,
|
||||
deleteExtension,
|
||||
closeDatabase,
|
||||
getCache,
|
||||
setCache
|
||||
};
|
||||
Reference in New Issue
Block a user