summaryrefslogtreecommitdiffstats
path: root/src/services/postDatabase.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/services/postDatabase.ts')
-rw-r--r--src/services/postDatabase.ts86
1 files changed, 86 insertions, 0 deletions
diff --git a/src/services/postDatabase.ts b/src/services/postDatabase.ts
new file mode 100644
index 0000000..e3be7bb
--- /dev/null
+++ b/src/services/postDatabase.ts
@@ -0,0 +1,86 @@
1import fs from "fs/promises";
2import path from "path";
3import * as f from "fp-ts";
4import * as t from "io-ts";
5
6export const PostDatabaseEntryC = t.type({
7 provider: t.literal("e926"),
8 id: t.number,
9});
10
11export type PostDatabaseEntry = t.TypeOf<typeof PostDatabaseEntryC>;
12
13export class PostDatabase {
14 private entries: PostDatabaseEntry[] = [];
15
16 private readonly filePath: string;
17
18 private isLoaded = false;
19
20 constructor(filename: string, private max?: number) {
21 this.filePath = path.join(process.cwd(), filename);
22 }
23
24 private async load() {
25 if (this.isLoaded) {
26 return;
27 }
28
29 try {
30 await fs.stat(this.filePath);
31 } catch {
32 await this.save();
33 }
34
35 const fileContent = await fs.readFile(this.filePath, "utf8");
36 const entries = t.array(PostDatabaseEntryC).decode(fileContent);
37
38 if (f.either.isRight(entries)) {
39 this.entries = this.max ? entries.right.slice(0, -1 * this.max) : entries.right;
40 }
41 }
42
43 private async save() {
44 await fs.writeFile(this.filePath, JSON.stringify(this.entries), "utf8");
45 }
46
47 async insertIfNotExists(entry: PostDatabaseEntry): Promise<boolean> {
48 await this.load();
49
50 const has = !!this.entries.find((e) => e.provider === entry.provider && e.id === entry.id);
51
52 if (!has) {
53 this.entries.push(entry);
54 await this.save();
55 }
56
57 return has;
58 }
59
60 async takeFirst(): Promise<PostDatabaseEntry | undefined> {
61 await this.load();
62 const entry = this.entries.shift();
63 await this.save();
64 return entry;
65 }
66
67 async remove(entry: PostDatabaseEntry): Promise<boolean> {
68 await this.load();
69 const i = this.entries.findIndex((e) => e.provider === entry.provider && e.id === entry.id);
70
71 if (i === -1) {
72 return false;
73 }
74
75 this.entries.splice(i, 1);
76 await this.save();
77 return true;
78 }
79
80 async getCount() {
81 await this.load();
82 return this.entries.length;
83 }
84}
85
86export default PostDatabase;