182 lines
4.1 KiB
JavaScript
182 lines
4.1 KiB
JavaScript
/**
|
|
* Database interactions.
|
|
*/
|
|
import Database from "better-sqlite3";
|
|
import { migrate } from "@blackglory/better-sqlite3-migrations";
|
|
|
|
import utils from "./utils.mjs";
|
|
import config from "./config.mjs";
|
|
|
|
// Interface.
|
|
|
|
export class DB {
|
|
/**
|
|
* Connect to a database and perform migrations.
|
|
*/
|
|
constructor() {
|
|
this.my_db = createDB();
|
|
}
|
|
/**
|
|
* Fetch information about a site.
|
|
* @param {!string} site url.
|
|
* @return {!ObjType} site information.
|
|
*/
|
|
siteInfo(site_url) {
|
|
return getSiteInfo(this.my_db, site_url);
|
|
}
|
|
/**
|
|
* Fetch all comments from a specific site.
|
|
* @param {!string} site url.
|
|
* @return {!Array<!ObjType>} comment objects.
|
|
*/
|
|
siteComments(site_url) {
|
|
return getSiteComments(this.my_db, site_url);
|
|
}
|
|
/**
|
|
* Fetch comments from a specific page in a specific site.
|
|
* @param {!string} site url.
|
|
* @param {!string} page path.
|
|
* @return {!Array<!ObjType>} comment objects.
|
|
*/
|
|
pageComments(site_url, page) {
|
|
return getPageComments(this.my_db, site_url, page);
|
|
}
|
|
/**
|
|
* Insert a comment into the database.
|
|
* @param {!string} site url.
|
|
* @param {!string} page path.
|
|
* @param {!ObjType} comment.
|
|
* @return {!Array<!ObjType>} page comments.
|
|
*/
|
|
insertPageComment(site_url, path, comment) {
|
|
return insertPageComment(this.my_db, site_url, path, comment);
|
|
}
|
|
}
|
|
|
|
const db = new DB();
|
|
export default db;
|
|
|
|
// Migrations
|
|
|
|
function migrations() {
|
|
return [
|
|
{
|
|
version: 1,
|
|
up: `
|
|
CREATE TABLE comment (
|
|
id integer not null,
|
|
site integer not null,
|
|
path text not null,
|
|
user text not null,
|
|
user_website text,
|
|
message text not null,
|
|
published text default (datetime('now')),
|
|
reply_to integer,
|
|
PRIMARY KEY (site, path, id)
|
|
);
|
|
`,
|
|
down: `
|
|
DROP TABLE comment;
|
|
`,
|
|
},
|
|
];
|
|
}
|
|
|
|
// setup
|
|
|
|
function createDB() {
|
|
const db = new Database(utils.db_path);
|
|
db.pragma("journal_mode = WAL");
|
|
migrate(db, migrations(), 1);
|
|
return db;
|
|
}
|
|
|
|
// queries
|
|
|
|
function getSiteInfo(db, site_url) {
|
|
const site = config.getSite(site_url);
|
|
if (!site || !site.info) {
|
|
throw "Unknown site";
|
|
}
|
|
return site;
|
|
}
|
|
|
|
function insertPageComment(db, site_url, path, comment) {
|
|
const site = config.getSite(site_url);
|
|
if (!site || !site.info.id) {
|
|
throw "Unknown site";
|
|
}
|
|
|
|
let object = { ...comment, site_id: site.info.id, path: path };
|
|
|
|
const stmt = db.prepare(`
|
|
INSERT INTO comment(id, site, path, user, user_website, message, reply_to)
|
|
SELECT
|
|
( SELECT count(*)
|
|
FROM comment
|
|
WHERE site = @site_id AND path = @path
|
|
),
|
|
@site_id,
|
|
@path,
|
|
@user,
|
|
@user_website,
|
|
@message,
|
|
@reply_to
|
|
RETURNING
|
|
id,
|
|
user,
|
|
user_website,
|
|
message,
|
|
published,
|
|
reply_to
|
|
;
|
|
`);
|
|
stmt.all(object);
|
|
|
|
// return all comments because a new comment might have been added
|
|
// since the user loaded the page.
|
|
return getPageComments(db, site_url, path);
|
|
}
|
|
|
|
function getPageComments(db, site_url, path) {
|
|
const site = config.getSite(site_url);
|
|
if (!site || !site.info.id) {
|
|
return [];
|
|
}
|
|
const stmt = db.prepare(`
|
|
SELECT
|
|
id,
|
|
user,
|
|
user_website,
|
|
message,
|
|
published,
|
|
reply_to
|
|
FROM comment
|
|
WHERE site = @site_id AND path = @path
|
|
ORDER BY id
|
|
;`);
|
|
return stmt.all({ site_id: site.info.id, path });
|
|
}
|
|
|
|
function getSiteComments(db, site_url) {
|
|
const site = config.getSite(site_url);
|
|
if (!site || !site.info.id) {
|
|
return [];
|
|
}
|
|
const stmt = db.prepare(`
|
|
SELECT
|
|
id,
|
|
@site_url as site,
|
|
path,
|
|
user,
|
|
user_website,
|
|
message,
|
|
published
|
|
FROM
|
|
comment
|
|
WHERE site = @site_id
|
|
ORDER BY published DESC
|
|
;
|
|
`);
|
|
return stmt.all({ site_id: site.info.id, site_url });
|
|
}
|