@koishijs/plugin-database-memory 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/browser.js +1 -145
- package/lib/browser.js.map +1 -1
- package/lib/index.d.ts +10 -12
- package/lib/node.js +23 -35
- package/lib/node.js.map +2 -2
- package/package.json +9 -11
package/lib/browser.js
CHANGED
|
@@ -1,145 +1 @@
|
|
|
1
|
-
var
|
|
2
|
-
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
-
|
|
4
|
-
// plugins/database/memory/src/index.ts
|
|
5
|
-
import { Database, Query, clone, makeArray, pick, Model, noop, KoishiError } from "koishi";
|
|
6
|
-
import { executeQuery, executeEval, executeUpdate, executeSort } from "@koishijs/orm-utils";
|
|
7
|
-
|
|
8
|
-
// plugins/database/memory/src/storage/browser.ts
|
|
9
|
-
var Storage = class {
|
|
10
|
-
constructor(ctx, config) {
|
|
11
|
-
this.config = config;
|
|
12
|
-
config.prefix ||= "koishi.database.";
|
|
13
|
-
}
|
|
14
|
-
async start(tables) {
|
|
15
|
-
for (const key in localStorage) {
|
|
16
|
-
if (!key.startsWith(this.config.prefix))
|
|
17
|
-
break;
|
|
18
|
-
const buffer = localStorage.getItem(key);
|
|
19
|
-
if (!buffer)
|
|
20
|
-
return;
|
|
21
|
-
try {
|
|
22
|
-
const data = JSON.parse(buffer);
|
|
23
|
-
tables[key.slice(this.config.prefix.length)] = data;
|
|
24
|
-
} catch {
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
async drop(name) {
|
|
29
|
-
if (name) {
|
|
30
|
-
localStorage.removeItem(this.config.prefix + name);
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
for (const key in localStorage) {
|
|
34
|
-
if (key.startsWith(this.config.prefix)) {
|
|
35
|
-
localStorage.removeItem(key);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
async save(name, table) {
|
|
40
|
-
try {
|
|
41
|
-
const buffer = JSON.stringify(table);
|
|
42
|
-
localStorage.setItem(this.config.prefix + name, buffer);
|
|
43
|
-
} catch {
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
__name(Storage, "Storage");
|
|
48
|
-
|
|
49
|
-
// plugins/database/memory/src/index.ts
|
|
50
|
-
var MemoryDatabase = class extends Database {
|
|
51
|
-
constructor(ctx, config = {}) {
|
|
52
|
-
super(ctx);
|
|
53
|
-
this.ctx = ctx;
|
|
54
|
-
this.config = config;
|
|
55
|
-
this.memory = this;
|
|
56
|
-
this.#store = {};
|
|
57
|
-
if (config.storage) {
|
|
58
|
-
this.#loader = new Storage(ctx, config);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
#store;
|
|
62
|
-
#loader;
|
|
63
|
-
async start() {
|
|
64
|
-
await this.#loader?.start(this.#store);
|
|
65
|
-
}
|
|
66
|
-
async $save(name) {
|
|
67
|
-
await this.#loader?.save(name, this.#store[name]);
|
|
68
|
-
}
|
|
69
|
-
stop() {
|
|
70
|
-
}
|
|
71
|
-
$table(table) {
|
|
72
|
-
return this.#store[table] ||= [];
|
|
73
|
-
}
|
|
74
|
-
async drop() {
|
|
75
|
-
this.#store = {};
|
|
76
|
-
await this.#loader?.drop();
|
|
77
|
-
}
|
|
78
|
-
async stats() {
|
|
79
|
-
return {};
|
|
80
|
-
}
|
|
81
|
-
$query(name, query) {
|
|
82
|
-
const expr = this.ctx.model.resolveQuery(name, query);
|
|
83
|
-
return this.$table(name).filter((row) => executeQuery(row, expr));
|
|
84
|
-
}
|
|
85
|
-
async get(name, query, modifier) {
|
|
86
|
-
const { fields, limit = Infinity, offset = 0, sort = {} } = Query.resolveModifier(modifier);
|
|
87
|
-
return executeSort(this.$query(name, query), sort).map((row) => clone(pick(row, fields))).slice(offset, offset + limit);
|
|
88
|
-
}
|
|
89
|
-
async set(name, query, data) {
|
|
90
|
-
this.$query(name, query).forEach((row) => executeUpdate(row, data));
|
|
91
|
-
this.$save(name);
|
|
92
|
-
}
|
|
93
|
-
async remove(name, query) {
|
|
94
|
-
const expr = this.ctx.model.resolveQuery(name, query);
|
|
95
|
-
this.#store[name] = this.$table(name).filter((row) => !executeQuery(row, expr));
|
|
96
|
-
this.$save(name);
|
|
97
|
-
}
|
|
98
|
-
async create(name, data) {
|
|
99
|
-
const store = this.$table(name);
|
|
100
|
-
const { primary, fields, autoInc } = this.ctx.model.config[name];
|
|
101
|
-
data = clone(data);
|
|
102
|
-
if (!Array.isArray(primary) && autoInc && !(primary in data)) {
|
|
103
|
-
const max = store.length ? Math.max(...store.map((row) => +row[primary])) : 0;
|
|
104
|
-
data[primary] = max + 1;
|
|
105
|
-
if (Model.Field.string.includes(fields[primary].type)) {
|
|
106
|
-
data[primary] += "";
|
|
107
|
-
}
|
|
108
|
-
} else {
|
|
109
|
-
const duplicated = await this.get(name, pick(data, makeArray(primary)));
|
|
110
|
-
if (duplicated.length) {
|
|
111
|
-
throw new KoishiError("duplicate entry", "database.duplicate-entry");
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
const copy = { ...this.ctx.model.create(name), ...data };
|
|
115
|
-
store.push(copy);
|
|
116
|
-
this.$save(name);
|
|
117
|
-
return clone(copy);
|
|
118
|
-
}
|
|
119
|
-
async upsert(name, data, key) {
|
|
120
|
-
const keys = makeArray(key || this.ctx.model.config[name].primary);
|
|
121
|
-
for (const item of data) {
|
|
122
|
-
const row = this.$table(name).find((row2) => {
|
|
123
|
-
return keys.every((key2) => row2[key2] === item[key2]);
|
|
124
|
-
});
|
|
125
|
-
if (row) {
|
|
126
|
-
executeUpdate(row, item);
|
|
127
|
-
} else {
|
|
128
|
-
const data2 = this.ctx.model.create(name);
|
|
129
|
-
await this.create(name, executeUpdate(data2, item)).catch(noop);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
this.$save(name);
|
|
133
|
-
}
|
|
134
|
-
async eval(name, expr, query) {
|
|
135
|
-
const table = this.$query(name, query);
|
|
136
|
-
return executeEval(table, expr);
|
|
137
|
-
}
|
|
138
|
-
};
|
|
139
|
-
__name(MemoryDatabase, "MemoryDatabase");
|
|
140
|
-
var src_default = MemoryDatabase;
|
|
141
|
-
export {
|
|
142
|
-
MemoryDatabase,
|
|
143
|
-
src_default as default
|
|
144
|
-
};
|
|
145
|
-
//# sourceMappingURL=browser.js.map
|
|
1
|
+
var x=Object.defineProperty;var l=(y,t)=>x(y,"name",{value:t,configurable:!0});import{clone as p,Database as b,DriverError as v,makeArray as g,Model as m,noop as k,pick as $}from"koishi";import{executeEval as T,executeQuery as d,executeSort as S,executeUpdate as h}from"@koishijs/orm";var f=class{constructor(t,e){this.config=e;e.prefix||="koishi.database."}async start(t){for(let e in localStorage){if(!e.startsWith(this.config.prefix))break;let s=localStorage.getItem(e);if(!s)return;try{let r=JSON.parse(s);t[e.slice(this.config.prefix.length)]=r}catch{}}}async drop(t){if(t){localStorage.removeItem(this.config.prefix+t);return}for(let e in localStorage)e.startsWith(this.config.prefix)&&localStorage.removeItem(e)}async save(t,e){try{let s=JSON.stringify(e);localStorage.setItem(this.config.prefix+t,s)}catch{}}};l(f,"Storage");var u=class extends b{constructor(t,e={}){super(t);this.ctx=t;this.config=e;this.memory=this;this.#t={};e.storage&&(this.#e=new f(t,e))}#t;#e;async start(){await this.#e?.start(this.#t)}async $save(t){await this.#e?.save(t,this.#t[t])}stop(){}$table(t){return this.#t[t]||=[]}async drop(){this.#t={},await this.#e?.drop()}async stats(){return{}}$query(t,e){let s=this.resolveQuery(t,e);return this.$table(t).filter(r=>d(r,s))}async get(t,e,s){let{fields:r,limit:c=1/0,offset:i=0,sort:a={}}=this.resolveModifier(t,s);return S(this.$query(t,e),a).slice(i,i+c).map(o=>this.resolveData(t,o,r))}async set(t,e,s){s=this.resolveUpdate(t,s),this.$query(t,e).forEach(r=>h(r,s)),this.$save(t)}async remove(t,e){let s=this.resolveQuery(t,e);this.#t[t]=this.$table(t).filter(r=>!d(r,s)),this.$save(t)}async create(t,e){let s=this.$table(t),{primary:r,fields:c,autoInc:i}=this.model.config[t];if(e=this.model.format(t,p(e)),!Array.isArray(r)&&i&&!(r in e)){let o=s.length?Math.max(...s.map(n=>+n[r])):0;e[r]=o+1,m.Field.string.includes(c[r].type)&&(e[r]+="")}else if((await this.get(t,$(e,g(r)))).length)throw new v("duplicate-entry");let a=this.model.create(t,e);return s.push(a),this.$save(t),p(a)}async upsert(t,e,s){let r=g(s||this.model.config[t].primary);for(let c of e){let i=this.model.format(t,c),a=this.$table(t).find(o=>r.every(n=>o[n]===i[n]));if(a)h(a,i);else{let o=this.model.create(t);await this.create(t,h(o,i)).catch(k)}}this.$save(t)}async eval(t,e,s){let r=this.$query(t,s);return T(r,e)}};l(u,"MemoryDatabase");var N=u;export{u as MemoryDatabase,N as default};
|
package/lib/browser.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/index.ts", "../src/storage/browser.ts"],
|
|
4
|
-
"sourcesContent": ["import { Context, Database,
|
|
4
|
+
"sourcesContent": ["import { clone, Context, Database, Dict, KoishiError, makeArray, Model, noop, pick, Query, TableType } from 'koishi'\nimport { executeEval, executeQuery, executeSort, executeUpdate } from '@koishijs/orm-utils'\nimport { Config, Storage } from './storage'\n\ndeclare module 'koishi' {\n interface Database {\n memory: MemoryDatabase\n }\n\n interface Modules {\n 'database-memory': typeof import('.')\n }\n}\n\nexport class MemoryDatabase extends Database {\n public memory = this\n\n #store: Dict<any[]> = {}\n #loader: Storage\n\n constructor(public ctx: Context, public config: Config = {}) {\n super(ctx)\n\n if (config.storage) {\n this.#loader = new Storage(ctx, config)\n }\n }\n\n async start() {\n await this.#loader?.start(this.#store)\n }\n\n async $save(name: string) {\n await this.#loader?.save(name, this.#store[name])\n }\n\n stop() {}\n\n $table<K extends TableType>(table: K) {\n return this.#store[table] ||= []\n }\n\n async drop() {\n this.#store = {}\n await this.#loader?.drop()\n }\n\n async stats() {\n return {}\n }\n\n $query(name: TableType, query: Query) {\n const expr = this.ctx.model.resolveQuery(name, query)\n return this.$table(name).filter(row => executeQuery(row, expr))\n }\n\n async get(name: TableType, query: Query, modifier?: Query.Modifier) {\n const { fields, limit = Infinity, offset = 0, sort = {} } = Query.resolveModifier(modifier)\n return executeSort(this.$query(name, query), sort)\n .map(row => clone(pick(row, fields)))\n .slice(offset, offset + limit)\n }\n\n async set(name: TableType, query: Query, data: {}) {\n this.$query(name, query).forEach(row => executeUpdate(row, data))\n this.$save(name)\n }\n\n async remove(name: TableType, query: Query) {\n const expr = this.ctx.model.resolveQuery(name, query)\n this.#store[name] = this.$table(name)\n .filter(row => !executeQuery(row, expr))\n this.$save(name)\n }\n\n async create(name: TableType, data: any) {\n const store = this.$table(name)\n const { primary, fields, autoInc } = this.ctx.model.config[name]\n data = clone(data)\n if (!Array.isArray(primary) && autoInc && !(primary in data)) {\n const max = store.length ? Math.max(...store.map(row => +row[primary])) : 0\n data[primary] = max + 1\n if (Model.Field.string.includes(fields[primary].type)) {\n data[primary] += ''\n }\n } else {\n const duplicated = await this.get(name, pick(data, makeArray(primary)))\n if (duplicated.length) {\n throw new KoishiError('duplicate entry', 'database.duplicate-entry')\n }\n }\n const copy = { ...this.ctx.model.create(name), ...data }\n store.push(copy)\n this.$save(name)\n return clone(copy)\n }\n\n async upsert(name: TableType, data: any[], key: string | string[]) {\n const keys = makeArray(key || this.ctx.model.config[name].primary)\n for (const item of data) {\n const row = this.$table(name).find(row => {\n return keys.every(key => row[key] === item[key])\n })\n if (row) {\n executeUpdate(row, item)\n } else {\n const data = this.ctx.model.create(name)\n await this.create(name, executeUpdate(data, item)).catch(noop)\n }\n }\n this.$save(name)\n }\n\n async eval(name: TableType, expr: any, query: Query) {\n const table = this.$query(name, query)\n return executeEval(table, expr)\n }\n}\n\nexport default MemoryDatabase\n", "import { Context } from 'koishi'\n\nexport interface Config {\n prefix?: string\n}\n\nexport class Storage {\n constructor(ctx: Context, private config: Config) {\n config.prefix ||= 'koishi.database.'\n }\n\n async start(tables: Record<string, any[]>) {\n for (const key in localStorage) {\n if (!key.startsWith(this.config.prefix)) break\n const buffer = localStorage.getItem(key)\n if (!buffer) return\n try {\n const data = JSON.parse(buffer)\n tables[key.slice(this.config.prefix.length)] = data\n } catch {}\n }\n }\n\n async drop(name?: string) {\n if (name) {\n localStorage.removeItem(this.config.prefix + name)\n return\n }\n\n for (const key in localStorage) {\n if (key.startsWith(this.config.prefix)) {\n localStorage.removeItem(key)\n }\n }\n }\n\n async save(name: string, table: any[]) {\n try {\n const buffer = JSON.stringify(table)\n localStorage.setItem(this.config.prefix + name, buffer)\n } catch {}\n }\n}\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/lib/index.d.ts
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
/// <reference types="koishi/lib" />
|
|
2
|
-
import { Context, Database,
|
|
2
|
+
import { Context, Database, Tables } from 'koishi';
|
|
3
|
+
import { Modifier, Query } from '@koishijs/orm';
|
|
3
4
|
import { Config } from './storage';
|
|
4
5
|
declare module 'koishi' {
|
|
5
6
|
interface Database {
|
|
6
7
|
memory: MemoryDatabase;
|
|
7
8
|
}
|
|
8
|
-
interface Modules {
|
|
9
|
-
'database-memory': typeof import('.');
|
|
10
|
-
}
|
|
11
9
|
}
|
|
12
10
|
export declare class MemoryDatabase extends Database {
|
|
13
11
|
#private;
|
|
@@ -18,15 +16,15 @@ export declare class MemoryDatabase extends Database {
|
|
|
18
16
|
start(): Promise<void>;
|
|
19
17
|
$save(name: string): Promise<void>;
|
|
20
18
|
stop(): void;
|
|
21
|
-
$table<K extends
|
|
19
|
+
$table<K extends keyof Tables>(table: K): any[];
|
|
22
20
|
drop(): Promise<void>;
|
|
23
21
|
stats(): Promise<{}>;
|
|
24
|
-
$query(name:
|
|
25
|
-
get(name:
|
|
26
|
-
set(name:
|
|
27
|
-
remove(name:
|
|
28
|
-
create(name:
|
|
29
|
-
upsert(name:
|
|
30
|
-
eval(name:
|
|
22
|
+
$query(name: keyof Tables, query: Query): any[];
|
|
23
|
+
get(name: keyof Tables, query: Query, modifier?: Modifier): Promise<any[]>;
|
|
24
|
+
set(name: keyof Tables, query: Query, data: {}): Promise<void>;
|
|
25
|
+
remove(name: keyof Tables, query: Query): Promise<void>;
|
|
26
|
+
create<T extends keyof Tables>(name: T, data: any): Promise<Tables[T]>;
|
|
27
|
+
upsert(name: keyof Tables, data: any[], key: string | string[]): Promise<void>;
|
|
28
|
+
eval(name: keyof Tables, expr: any, query: Query): Promise<any>;
|
|
31
29
|
}
|
|
32
30
|
export default MemoryDatabase;
|
package/lib/node.js
CHANGED
|
@@ -2,22 +2,8 @@ var __create = Object.create;
|
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
6
5
|
var __getProtoOf = Object.getPrototypeOf;
|
|
7
6
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
9
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
10
|
-
var __spreadValues = (a, b) => {
|
|
11
|
-
for (var prop in b || (b = {}))
|
|
12
|
-
if (__hasOwnProp.call(b, prop))
|
|
13
|
-
__defNormalProp(a, prop, b[prop]);
|
|
14
|
-
if (__getOwnPropSymbols)
|
|
15
|
-
for (var prop of __getOwnPropSymbols(b)) {
|
|
16
|
-
if (__propIsEnum.call(b, prop))
|
|
17
|
-
__defNormalProp(a, prop, b[prop]);
|
|
18
|
-
}
|
|
19
|
-
return a;
|
|
20
|
-
};
|
|
21
7
|
var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
|
|
22
8
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
23
9
|
var __export = (target, all) => {
|
|
@@ -61,7 +47,7 @@ __export(exports, {
|
|
|
61
47
|
default: () => src_default
|
|
62
48
|
});
|
|
63
49
|
var import_koishi = __toModule(require("koishi"));
|
|
64
|
-
var
|
|
50
|
+
var import_orm = __toModule(require("@koishijs/orm"));
|
|
65
51
|
|
|
66
52
|
// plugins/database/memory/src/storage/node.ts
|
|
67
53
|
var import_fs = __toModule(require("fs"));
|
|
@@ -82,12 +68,12 @@ var Storage = class {
|
|
|
82
68
|
const files = await import_fs.promises.readdir(root);
|
|
83
69
|
await Promise.all(files.map(async (filename) => {
|
|
84
70
|
const extension = (0, import_path.extname)(filename);
|
|
85
|
-
if (extension !== loader)
|
|
71
|
+
if (extension !== `.${loader}`)
|
|
86
72
|
return;
|
|
87
|
-
const buffer = await import_fs.promises.readFile(filename);
|
|
73
|
+
const buffer = await import_fs.promises.readFile((0, import_path.resolve)(root, filename));
|
|
88
74
|
try {
|
|
89
75
|
const data = await this.load(buffer, loader);
|
|
90
|
-
const name = filename.slice(0,
|
|
76
|
+
const name = filename.slice(0, filename.length - extension.length);
|
|
91
77
|
tables[name] = data;
|
|
92
78
|
} catch {
|
|
93
79
|
}
|
|
@@ -165,26 +151,27 @@ var MemoryDatabase = class extends import_koishi.Database {
|
|
|
165
151
|
return {};
|
|
166
152
|
}
|
|
167
153
|
$query(name, query) {
|
|
168
|
-
const expr = this.
|
|
169
|
-
return this.$table(name).filter((row) => (0,
|
|
154
|
+
const expr = this.resolveQuery(name, query);
|
|
155
|
+
return this.$table(name).filter((row) => (0, import_orm.executeQuery)(row, expr));
|
|
170
156
|
}
|
|
171
157
|
async get(name, query, modifier) {
|
|
172
|
-
const { fields, limit = Infinity, offset = 0, sort = {} } =
|
|
173
|
-
return (0,
|
|
158
|
+
const { fields, limit = Infinity, offset = 0, sort = {} } = this.resolveModifier(name, modifier);
|
|
159
|
+
return (0, import_orm.executeSort)(this.$query(name, query), sort).slice(offset, offset + limit).map((row) => this.resolveData(name, row, fields));
|
|
174
160
|
}
|
|
175
161
|
async set(name, query, data) {
|
|
176
|
-
|
|
162
|
+
data = this.resolveUpdate(name, data);
|
|
163
|
+
this.$query(name, query).forEach((row) => (0, import_orm.executeUpdate)(row, data));
|
|
177
164
|
this.$save(name);
|
|
178
165
|
}
|
|
179
166
|
async remove(name, query) {
|
|
180
|
-
const expr = this.
|
|
181
|
-
__privateGet(this, _store)[name] = this.$table(name).filter((row) => !(0,
|
|
167
|
+
const expr = this.resolveQuery(name, query);
|
|
168
|
+
__privateGet(this, _store)[name] = this.$table(name).filter((row) => !(0, import_orm.executeQuery)(row, expr));
|
|
182
169
|
this.$save(name);
|
|
183
170
|
}
|
|
184
171
|
async create(name, data) {
|
|
185
172
|
const store = this.$table(name);
|
|
186
|
-
const { primary, fields, autoInc } = this.
|
|
187
|
-
data = (0, import_koishi.clone)(data);
|
|
173
|
+
const { primary, fields, autoInc } = this.model.config[name];
|
|
174
|
+
data = this.model.format(name, (0, import_koishi.clone)(data));
|
|
188
175
|
if (!Array.isArray(primary) && autoInc && !(primary in data)) {
|
|
189
176
|
const max = store.length ? Math.max(...store.map((row) => +row[primary])) : 0;
|
|
190
177
|
data[primary] = max + 1;
|
|
@@ -194,32 +181,33 @@ var MemoryDatabase = class extends import_koishi.Database {
|
|
|
194
181
|
} else {
|
|
195
182
|
const duplicated = await this.get(name, (0, import_koishi.pick)(data, (0, import_koishi.makeArray)(primary)));
|
|
196
183
|
if (duplicated.length) {
|
|
197
|
-
throw new import_koishi.
|
|
184
|
+
throw new import_koishi.DriverError("duplicate-entry");
|
|
198
185
|
}
|
|
199
186
|
}
|
|
200
|
-
const copy =
|
|
187
|
+
const copy = this.model.create(name, data);
|
|
201
188
|
store.push(copy);
|
|
202
189
|
this.$save(name);
|
|
203
190
|
return (0, import_koishi.clone)(copy);
|
|
204
191
|
}
|
|
205
192
|
async upsert(name, data, key) {
|
|
206
|
-
const keys = (0, import_koishi.makeArray)(key || this.
|
|
207
|
-
for (const
|
|
193
|
+
const keys = (0, import_koishi.makeArray)(key || this.model.config[name].primary);
|
|
194
|
+
for (const _item of data) {
|
|
195
|
+
const item = this.model.format(name, _item);
|
|
208
196
|
const row = this.$table(name).find((row2) => {
|
|
209
197
|
return keys.every((key2) => row2[key2] === item[key2]);
|
|
210
198
|
});
|
|
211
199
|
if (row) {
|
|
212
|
-
(0,
|
|
200
|
+
(0, import_orm.executeUpdate)(row, item);
|
|
213
201
|
} else {
|
|
214
|
-
const data2 = this.
|
|
215
|
-
await this.create(name, (0,
|
|
202
|
+
const data2 = this.model.create(name);
|
|
203
|
+
await this.create(name, (0, import_orm.executeUpdate)(data2, item)).catch(import_koishi.noop);
|
|
216
204
|
}
|
|
217
205
|
}
|
|
218
206
|
this.$save(name);
|
|
219
207
|
}
|
|
220
208
|
async eval(name, expr, query) {
|
|
221
209
|
const table = this.$query(name, query);
|
|
222
|
-
return (0,
|
|
210
|
+
return (0, import_orm.executeEval)(table, expr);
|
|
223
211
|
}
|
|
224
212
|
};
|
|
225
213
|
__name(MemoryDatabase, "MemoryDatabase");
|
package/lib/node.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/index.ts", "../src/storage/node.ts"],
|
|
4
|
-
"sourcesContent": ["import { Context, Database,
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["import { clone, Context, Database, Dict, DriverError, makeArray, Model, noop, pick, Tables } from 'koishi'\nimport { executeEval, executeQuery, executeSort, executeUpdate, Modifier, Query } from '@koishijs/orm'\nimport { Config, Storage } from './storage'\n\ndeclare module 'koishi' {\n interface Database {\n memory: MemoryDatabase\n }\n}\n\nexport class MemoryDatabase extends Database {\n public memory = this\n\n #store: Dict<any[]> = {}\n #loader: Storage\n\n constructor(public ctx: Context, public config: Config = {}) {\n super(ctx)\n\n if (config.storage) {\n this.#loader = new Storage(ctx, config)\n }\n }\n\n async start() {\n await this.#loader?.start(this.#store)\n }\n\n async $save(name: string) {\n await this.#loader?.save(name, this.#store[name])\n }\n\n stop() {}\n\n $table<K extends keyof Tables>(table: K) {\n return this.#store[table] ||= []\n }\n\n async drop() {\n this.#store = {}\n await this.#loader?.drop()\n }\n\n async stats() {\n return {}\n }\n\n $query(name: keyof Tables, query: Query) {\n const expr = this.resolveQuery(name, query)\n return this.$table(name).filter(row => executeQuery(row, expr))\n }\n\n async get(name: keyof Tables, query: Query, modifier?: Modifier) {\n const { fields, limit = Infinity, offset = 0, sort = {} } = this.resolveModifier(name, modifier)\n return executeSort(this.$query(name, query), sort)\n .slice(offset, offset + limit)\n .map(row => this.resolveData(name, row, fields))\n }\n\n async set(name: keyof Tables, query: Query, data: {}) {\n data = this.resolveUpdate(name, data)\n this.$query(name, query).forEach(row => executeUpdate(row, data))\n this.$save(name)\n }\n\n async remove(name: keyof Tables, query: Query) {\n const expr = this.resolveQuery(name, query)\n this.#store[name] = this.$table(name)\n .filter(row => !executeQuery(row, expr))\n this.$save(name)\n }\n\n async create<T extends keyof Tables>(name: T, data: any) {\n const store = this.$table(name)\n const { primary, fields, autoInc } = this.model.config[name]\n data = this.model.format(name, clone(data))\n if (!Array.isArray(primary) && autoInc && !(primary in data)) {\n const max = store.length ? Math.max(...store.map(row => +row[primary])) : 0\n data[primary] = max + 1\n if (Model.Field.string.includes(fields[primary].type)) {\n data[primary] += ''\n }\n } else {\n const duplicated = await this.get(name, pick(data, makeArray(primary)))\n if (duplicated.length) {\n throw new DriverError('duplicate-entry')\n }\n }\n const copy = this.model.create(name, data)\n store.push(copy)\n this.$save(name)\n return clone(copy)\n }\n\n async upsert(name: keyof Tables, data: any[], key: string | string[]) {\n const keys = makeArray(key || this.model.config[name].primary)\n for (const _item of data) {\n const item = this.model.format(name, _item)\n const row = this.$table(name).find(row => {\n return keys.every(key => row[key] === item[key])\n })\n if (row) {\n executeUpdate(row, item)\n } else {\n const data = this.model.create(name)\n await this.create(name, executeUpdate(data, item)).catch(noop)\n }\n }\n this.$save(name)\n }\n\n async eval(name: keyof Tables, expr: any, query: Query) {\n const table = this.$query(name, query)\n return executeEval(table, expr)\n }\n}\n\nexport default MemoryDatabase\n", "import type * as yaml from 'js-yaml'\nimport { Context } from 'koishi'\nimport { promises as fs } from 'fs'\nimport { extname, resolve } from 'path'\n\ntype Loader = 'json' | 'yaml' | 'yml'\nconst loaders = ['json', 'yaml', 'yml']\n\nexport interface Config {\n loader?: Loader\n root?: string\n}\n\nexport class Storage {\n constructor(ctx: Context, private config: Config) {\n config.loader ||= 'json'\n config.root ||= resolve(ctx.app.baseDir, '.koishi/database')\n if (!loaders.includes(config.loader)) {\n throw new Error(`unsupported loader \"${config.loader}\"`)\n }\n }\n\n async start(tables: Record<string, any[]>) {\n const { root, loader } = this.config\n await fs.mkdir(root, { recursive: true })\n const files = await fs.readdir(root)\n await Promise.all(files.map(async (filename) => {\n const extension = extname(filename)\n if (extension !== `.${loader}`) return\n const buffer = await fs.readFile(resolve(root, filename))\n try {\n const data = await this.load(buffer, loader)\n const name = filename.slice(0, filename.length - extension.length)\n tables[name] = data\n } catch {}\n }))\n }\n\n async load(buffer: Buffer, loader: Loader) {\n if (loader === 'json') {\n return JSON.parse(buffer.toString())\n } else if (loader === 'yaml' || loader === 'yml') {\n const { load } = require('js-yaml') as typeof yaml\n return load(buffer.toString())\n }\n }\n\n async drop(name?: string) {\n const { root, loader } = this.config\n if (name) {\n await fs.rm(resolve(root, `${name}.${loader}`))\n } else {\n await fs.rm(root, { recursive: true, force: true })\n }\n }\n\n async save(name: string, table: any[]) {\n const { root, loader } = this.config\n try {\n const buffer = await this.dump(table, loader)\n await fs.writeFile(resolve(root, `${name}.${loader}`), buffer)\n } catch {}\n }\n\n async dump(data: any, loader: Loader) {\n if (loader === 'json') {\n return JSON.stringify(data)\n } else if (loader === 'yaml' || loader === 'yml') {\n const { dump } = require('js-yaml') as typeof yaml\n return dump(data)\n }\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@koishijs/plugin-database-memory",
|
|
3
3
|
"description": "A in-memory database implementation for Koishi",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.1.0",
|
|
5
5
|
"main": "lib/node.js",
|
|
6
6
|
"module": "lib/browser.js",
|
|
7
7
|
"typings": "lib/index.d.ts",
|
|
@@ -20,25 +20,23 @@
|
|
|
20
20
|
"homepage": "https://koishi.js.org/plugins/other/database",
|
|
21
21
|
"keywords": [
|
|
22
22
|
"bot",
|
|
23
|
-
"qqbot",
|
|
24
|
-
"cqhttp",
|
|
25
|
-
"coolq",
|
|
26
23
|
"chatbot",
|
|
27
24
|
"koishi",
|
|
28
25
|
"plugin",
|
|
29
26
|
"database",
|
|
30
|
-
"server"
|
|
27
|
+
"server",
|
|
28
|
+
"impl:database"
|
|
31
29
|
],
|
|
32
30
|
"peerDependencies": {
|
|
33
|
-
"koishi": "^4.
|
|
31
|
+
"koishi": "^4.5.0"
|
|
34
32
|
},
|
|
35
33
|
"devDependencies": {
|
|
36
|
-
"@koishijs/
|
|
37
|
-
"@koishijs/
|
|
38
|
-
"@types/js-yaml": "^4.0.
|
|
34
|
+
"@koishijs/database-tests": "^1.0.0",
|
|
35
|
+
"@koishijs/plugin-mock": "^1.0.3",
|
|
36
|
+
"@types/js-yaml": "^4.0.5",
|
|
39
37
|
"js-yaml": "^4.1.0"
|
|
40
38
|
},
|
|
41
39
|
"dependencies": {
|
|
42
|
-
"@koishijs/orm
|
|
40
|
+
"@koishijs/orm": "^1.0.0"
|
|
43
41
|
}
|
|
44
|
-
}
|
|
42
|
+
}
|