update
This commit is contained in:
1 parent
31dd2b0049
commit
7039b10df2
32 files changed
+415
-192
No files matched your search
@@ -0,0 +1,99 @@
|
||||
import sqlite3 from 'better-sqlite3'
|
||||
import * as z from 'zod'
|
||||
|
||||
const zMatter = z.object({
|
||||
date: z.date().optional(),
|
||||
createdAt: z.date().optional(),
|
||||
updatedAt: z.date().optional(),
|
||||
title: z.string(),
|
||||
image: z.string().optional(),
|
||||
tag: z.array(z.string()).optional(),
|
||||
category: z.string().optional(),
|
||||
})
|
||||
|
||||
export type IMatter = z.infer<typeof zMatter>
|
||||
|
||||
export const zPost = z
|
||||
.object({
|
||||
path: z.string(),
|
||||
/**
|
||||
* Cleaned and jieba-separated markdown
|
||||
*/
|
||||
content: z.string(),
|
||||
excerptHtml: z.string(),
|
||||
contentHtml: z.string(),
|
||||
})
|
||||
.merge(zMatter.nonstrict())
|
||||
|
||||
export type IPost = z.infer<typeof zPost>
|
||||
|
||||
export class Database {
|
||||
db: sqlite3.Database
|
||||
|
||||
constructor(public filepath: string, opts?: sqlite3.Options) {
|
||||
this.db = sqlite3(filepath, opts)
|
||||
}
|
||||
|
||||
public init(): void {
|
||||
this.db.exec(/* sql */ `
|
||||
CREATE TABLE IF NOT EXISTS files (
|
||||
[path] TEXT PRIMARY KEY,
|
||||
[date] INT, -- epoch milli
|
||||
[createdAt] INT, -- epoch milli
|
||||
[updatedAt] INT, -- epoch milli
|
||||
-- q.title
|
||||
[image] TEXT,
|
||||
-- q.tag.split(/ /g)
|
||||
-- q.category
|
||||
-- q.content
|
||||
excerptHtml TEXT NOT NULL,
|
||||
contentHtml TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS files_date ON files([date]);
|
||||
CREATE INDEX IF NOT EXISTS files_createdAt ON files(createdAt);
|
||||
CREATE INDEX IF NOT EXISTS files_updatedAt ON files(updatedAt);
|
||||
`)
|
||||
|
||||
this.db.exec(/* sql */ `
|
||||
CREATE VIRTUAL TABLE IF NOT EXISTS q USING fts5 (
|
||||
[path], -- REFERENCES files([path])
|
||||
title,
|
||||
tag, -- space separated
|
||||
category, -- can compare via equal
|
||||
content -- cleaned markdown
|
||||
);
|
||||
`)
|
||||
}
|
||||
|
||||
public insert(...ps: IPost[]): void {
|
||||
const fStmt = this.db.prepare(/* sql */ `
|
||||
INSERT INTO files ([path], [date], [createdAt], [updatedAt], [image], excerptHtml, contentHtml)
|
||||
VALUES (@path, @date, @createdAt, @updatedAt, @image, @excerptHtml, @contentHtml)
|
||||
`)
|
||||
|
||||
const qStmt = this.db.prepare(/* sql */ `
|
||||
INSERT INTO q ([path], title, tag, category, content)
|
||||
VALUES (@path, @title, @tag, @category, @content)
|
||||
`)
|
||||
|
||||
this.db.transaction(() => {
|
||||
// eslint-disable-next-line array-callback-return
|
||||
ps.map((p) => {
|
||||
p = zPost.parse(p)
|
||||
|
||||
fStmt.run({
|
||||
...p,
|
||||
date: p.date ? p.date.getTime() : undefined,
|
||||
createdAt: p.createdAt ? p.createdAt.getTime() : undefined,
|
||||
updatedAt: p.updatedAt ? p.updatedAt.getTime() : undefined,
|
||||
})
|
||||
|
||||
qStmt.run({
|
||||
...p,
|
||||
tag: p.tag ? p.tag.join(' ') : undefined,
|
||||
})
|
||||
})
|
||||
})()
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user