@ghom/orm 1.7.2 → 1.8.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/.github/workflows/test.yml +40 -0
- package/.run/All Tests.run.xml +22 -0
- package/dist/app/backup.js +119 -0
- package/dist/app/caching.js +36 -0
- package/dist/app/orm.js +109 -0
- package/dist/{esm/app → app}/table.js +40 -8
- package/dist/app/util.js +18 -0
- package/dist/index.js +5 -0
- package/package.json +17 -6
- package/readme.md +95 -8
- package/src/app/backup.ts +211 -0
- package/src/app/caching.ts +51 -0
- package/src/app/orm.ts +100 -104
- package/src/app/table.ts +107 -19
- package/src/app/util.ts +30 -0
- package/src/index.ts +3 -0
- package/tests/tables/a.js +24 -21
- package/tests/tables/b.js +27 -24
- package/tests/tables/c.js +15 -12
- package/tests/test.js +120 -43
- package/tsconfig.json +7 -4
- package/dist/cjs/app/orm.js +0 -94
- package/dist/cjs/app/table.js +0 -104
- package/dist/cjs/index.js +0 -18
- package/dist/esm/app/orm.js +0 -67
- package/dist/esm/index.js +0 -2
- package/dist/typings/app/orm.d.ts +0 -47
- package/dist/typings/app/table.d.ts +0 -39
- package/dist/typings/index.d.ts +0 -2
- package/fixup.sh +0 -11
- package/tsconfig-cjs.json +0 -10
- package/tsconfig-esm.json +0 -8
package/src/app/table.ts
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
|
-
import
|
|
1
|
+
import util from "util"
|
|
2
2
|
import { Knex } from "knex"
|
|
3
3
|
import { ORM } from "./orm.js"
|
|
4
|
+
import { ResponseCache } from "./caching.js"
|
|
5
|
+
import {
|
|
6
|
+
DEFAULT_LOGGER_DESCRIPTION,
|
|
7
|
+
DEFAULT_LOGGER_HIGHLIGHT,
|
|
8
|
+
DEFAULT_LOGGER_RAW_VALUE,
|
|
9
|
+
} from "./util.js"
|
|
4
10
|
|
|
5
11
|
export interface MigrationData {
|
|
6
12
|
table: string
|
|
@@ -11,13 +17,25 @@ export interface TableOptions<Type extends object = object> {
|
|
|
11
17
|
name: string
|
|
12
18
|
description?: string
|
|
13
19
|
priority?: number
|
|
20
|
+
/**
|
|
21
|
+
* The cache time in milliseconds. <br>
|
|
22
|
+
* Default is `Infinity`.
|
|
23
|
+
*/
|
|
24
|
+
caching?: number
|
|
14
25
|
migrations?: { [version: number]: (table: Knex.CreateTableBuilder) => void }
|
|
15
26
|
then?: (this: Table<Type>, table: Table<Type>) => unknown
|
|
16
27
|
setup: (table: Knex.CreateTableBuilder) => void
|
|
17
28
|
}
|
|
18
29
|
|
|
19
30
|
export class Table<Type extends object = object> {
|
|
20
|
-
orm?: ORM
|
|
31
|
+
public orm?: ORM
|
|
32
|
+
|
|
33
|
+
public _whereCache?: ResponseCache<
|
|
34
|
+
[cb: (query: Table<Type>["query"]) => unknown],
|
|
35
|
+
unknown
|
|
36
|
+
>
|
|
37
|
+
|
|
38
|
+
public _countCache?: ResponseCache<[where: string | null], Promise<number>>
|
|
21
39
|
|
|
22
40
|
constructor(public readonly options: TableOptions<Type>) {}
|
|
23
41
|
|
|
@@ -30,6 +48,57 @@ export class Table<Type extends object = object> {
|
|
|
30
48
|
return this.db<Type>(this.options.name)
|
|
31
49
|
}
|
|
32
50
|
|
|
51
|
+
get cache() {
|
|
52
|
+
if (!this._whereCache || !this._countCache) throw new Error("missing cache")
|
|
53
|
+
|
|
54
|
+
if (!this.orm) throw new Error("missing ORM")
|
|
55
|
+
|
|
56
|
+
return {
|
|
57
|
+
get: <Return>(
|
|
58
|
+
id: string,
|
|
59
|
+
cb: (
|
|
60
|
+
table: Pick<
|
|
61
|
+
Table<Type>["query"],
|
|
62
|
+
| "select"
|
|
63
|
+
| "count"
|
|
64
|
+
| "avg"
|
|
65
|
+
| "sum"
|
|
66
|
+
| "countDistinct"
|
|
67
|
+
| "avgDistinct"
|
|
68
|
+
| "sumDistinct"
|
|
69
|
+
>,
|
|
70
|
+
) => Return,
|
|
71
|
+
): Return => {
|
|
72
|
+
return this._whereCache!.get(id, cb) as Return
|
|
73
|
+
},
|
|
74
|
+
set: <Return>(
|
|
75
|
+
cb: (
|
|
76
|
+
table: Pick<
|
|
77
|
+
Table<Type>["query"],
|
|
78
|
+
| "update"
|
|
79
|
+
| "delete"
|
|
80
|
+
| "insert"
|
|
81
|
+
| "upsert"
|
|
82
|
+
| "truncate"
|
|
83
|
+
| "jsonInsert"
|
|
84
|
+
>,
|
|
85
|
+
) => Return,
|
|
86
|
+
) => {
|
|
87
|
+
// todo: invalidate only the related tables
|
|
88
|
+
this.orm!.cache.invalidate()
|
|
89
|
+
return cb(this.query)
|
|
90
|
+
},
|
|
91
|
+
count: (where?: string) => {
|
|
92
|
+
return this._countCache!.get(where ?? "*", where ?? null)
|
|
93
|
+
},
|
|
94
|
+
invalidate: () => {
|
|
95
|
+
this._whereCache!.invalidate()
|
|
96
|
+
this._countCache!.invalidate()
|
|
97
|
+
this.orm!._rawCache.invalidate()
|
|
98
|
+
},
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
33
102
|
async count(where?: string): Promise<number> {
|
|
34
103
|
return this.query
|
|
35
104
|
.select(this.db.raw("count(*) as total"))
|
|
@@ -56,21 +125,34 @@ export class Table<Type extends object = object> {
|
|
|
56
125
|
}
|
|
57
126
|
|
|
58
127
|
async isEmpty(): Promise<boolean> {
|
|
59
|
-
return this.count().then((count) => count === 0)
|
|
128
|
+
return this.count().then((count) => +count === 0)
|
|
60
129
|
}
|
|
61
130
|
|
|
62
131
|
async make(): Promise<this> {
|
|
63
132
|
if (!this.orm) throw new Error("missing ORM")
|
|
64
133
|
|
|
134
|
+
this._whereCache = new ResponseCache(
|
|
135
|
+
(cb: (query: Knex.QueryBuilder<Type>) => unknown) => cb(this.query),
|
|
136
|
+
this.options.caching ?? this.orm?.config.caching ?? Infinity,
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
this._countCache = new ResponseCache(
|
|
140
|
+
(where: string | null) => this.count(where ?? undefined),
|
|
141
|
+
this.options.caching ?? this.orm?.config.caching ?? Infinity,
|
|
142
|
+
)
|
|
143
|
+
|
|
65
144
|
try {
|
|
66
145
|
await this.db.schema.createTable(this.options.name, this.options.setup)
|
|
67
146
|
|
|
68
147
|
this.orm.config.logger?.log(
|
|
69
|
-
`created table ${
|
|
70
|
-
this.orm.config.
|
|
71
|
-
|
|
148
|
+
`created table ${util.styleText(
|
|
149
|
+
this.orm.config.loggerStyles?.highlight ?? DEFAULT_LOGGER_HIGHLIGHT,
|
|
150
|
+
this.options.name,
|
|
151
|
+
)}${
|
|
72
152
|
this.options.description
|
|
73
|
-
? ` ${
|
|
153
|
+
? ` ${util.styleText(
|
|
154
|
+
this.orm.config.loggerStyles?.description ??
|
|
155
|
+
DEFAULT_LOGGER_DESCRIPTION,
|
|
74
156
|
this.options.description,
|
|
75
157
|
)}`
|
|
76
158
|
: ""
|
|
@@ -79,19 +161,23 @@ export class Table<Type extends object = object> {
|
|
|
79
161
|
} catch (error: any) {
|
|
80
162
|
if (error.toString().includes("syntax error")) {
|
|
81
163
|
this.orm.config.logger?.error(
|
|
82
|
-
`you need to implement the "setup" method in options of your ${
|
|
83
|
-
this.orm.config.
|
|
84
|
-
|
|
164
|
+
`you need to implement the "setup" method in options of your ${util.styleText(
|
|
165
|
+
this.orm.config.loggerStyles?.highlight ?? DEFAULT_LOGGER_HIGHLIGHT,
|
|
166
|
+
this.options.name,
|
|
167
|
+
)} table!`,
|
|
85
168
|
)
|
|
86
169
|
|
|
87
170
|
throw error
|
|
88
171
|
} else {
|
|
89
172
|
this.orm.config.logger?.log(
|
|
90
|
-
`loaded table ${
|
|
91
|
-
this.orm.config.
|
|
92
|
-
|
|
173
|
+
`loaded table ${util.styleText(
|
|
174
|
+
this.orm.config.loggerStyles?.highlight ?? DEFAULT_LOGGER_HIGHLIGHT,
|
|
175
|
+
this.options.name,
|
|
176
|
+
)}${
|
|
93
177
|
this.options.description
|
|
94
|
-
? ` ${
|
|
178
|
+
? ` ${util.styleText(
|
|
179
|
+
this.orm.config.loggerStyles?.description ??
|
|
180
|
+
DEFAULT_LOGGER_DESCRIPTION,
|
|
95
181
|
this.options.description,
|
|
96
182
|
)}`
|
|
97
183
|
: ""
|
|
@@ -105,11 +191,13 @@ export class Table<Type extends object = object> {
|
|
|
105
191
|
|
|
106
192
|
if (migrated !== false) {
|
|
107
193
|
this.orm.config.logger?.log(
|
|
108
|
-
`migrated table ${
|
|
109
|
-
this.orm.config.
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
194
|
+
`migrated table ${util.styleText(
|
|
195
|
+
this.orm.config.loggerStyles?.highlight ?? DEFAULT_LOGGER_HIGHLIGHT,
|
|
196
|
+
this.options.name,
|
|
197
|
+
)} to version ${util.styleText(
|
|
198
|
+
this.orm.config.loggerStyles?.rawValue ?? DEFAULT_LOGGER_RAW_VALUE,
|
|
199
|
+
String(migrated),
|
|
200
|
+
)}`,
|
|
113
201
|
)
|
|
114
202
|
}
|
|
115
203
|
} catch (error: any) {
|
package/src/app/util.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import util from "util"
|
|
2
|
+
import path from "path"
|
|
3
|
+
import fs from "fs"
|
|
4
|
+
|
|
5
|
+
export type TextStyle = Parameters<typeof util.styleText>[0]
|
|
6
|
+
|
|
7
|
+
export const DEFAULT_BACKUP_LOCATION = path.join(process.cwd(), "backup")
|
|
8
|
+
export const DEFAULT_BACKUP_CHUNK_SIZE = 5 * 1024 * 1024 // 5MB
|
|
9
|
+
|
|
10
|
+
export const DEFAULT_LOGGER_HIGHLIGHT = "blueBright"
|
|
11
|
+
export const DEFAULT_LOGGER_DESCRIPTION = "grey"
|
|
12
|
+
export const DEFAULT_LOGGER_RAW_VALUE = "magentaBright"
|
|
13
|
+
|
|
14
|
+
let isCJS: boolean = false
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
const pack = JSON.parse(
|
|
18
|
+
fs.readFileSync(path.join(process.cwd(), "package.json"), "utf8"),
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
isCJS = pack.type === "commonjs" || pack.type == void 0
|
|
22
|
+
} catch {
|
|
23
|
+
throw new Error(
|
|
24
|
+
"Missing package.json: Can't detect the type of modules.\n" +
|
|
25
|
+
"The ORM needs a package.json file present in the process's current working directory.\n" +
|
|
26
|
+
"Please create a package.json file or run the project from another entry point.",
|
|
27
|
+
)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export { isCJS }
|
package/src/index.ts
CHANGED
package/tests/tables/a.js
CHANGED
|
@@ -1,21 +1,24 @@
|
|
|
1
|
-
import { Table } from "../.."
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
.
|
|
13
|
-
.
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
1
|
+
import { Table } from "../.."
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @type {Table<{ id: number; b_id: number }>}
|
|
5
|
+
*/
|
|
6
|
+
export default new Table({
|
|
7
|
+
name: "a",
|
|
8
|
+
priority: 0,
|
|
9
|
+
setup(table) {
|
|
10
|
+
table.increments("id").primary().notNullable()
|
|
11
|
+
table
|
|
12
|
+
.integer("b_id")
|
|
13
|
+
.references("id")
|
|
14
|
+
.inTable("b")
|
|
15
|
+
.onDelete("cascade")
|
|
16
|
+
.notNullable()
|
|
17
|
+
},
|
|
18
|
+
async then({ query }) {
|
|
19
|
+
await query.insert({
|
|
20
|
+
id: 0,
|
|
21
|
+
b_id: 0,
|
|
22
|
+
})
|
|
23
|
+
},
|
|
24
|
+
})
|
package/tests/tables/b.js
CHANGED
|
@@ -1,24 +1,27 @@
|
|
|
1
|
-
import { Table } from "../.."
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
.
|
|
12
|
-
.
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
1
|
+
import { Table } from "../.."
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @type {Table<{ id: number; c_id: number }>}
|
|
5
|
+
*/
|
|
6
|
+
export default new Table({
|
|
7
|
+
name: "b",
|
|
8
|
+
migrations: {
|
|
9
|
+
0: (table) =>
|
|
10
|
+
table
|
|
11
|
+
.integer("c_id")
|
|
12
|
+
.references("id")
|
|
13
|
+
.inTable("c")
|
|
14
|
+
.onDelete("cascade")
|
|
15
|
+
.notNullable(),
|
|
16
|
+
},
|
|
17
|
+
priority: 1,
|
|
18
|
+
setup(table) {
|
|
19
|
+
table.increments("id").primary().notNullable()
|
|
20
|
+
},
|
|
21
|
+
async then({ query }) {
|
|
22
|
+
await query.insert({
|
|
23
|
+
id: 0,
|
|
24
|
+
c_id: 0,
|
|
25
|
+
})
|
|
26
|
+
},
|
|
27
|
+
})
|
package/tests/tables/c.js
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
import { Table } from "../.."
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
},
|
|
12
|
-
})
|
|
1
|
+
import { Table } from "../.."
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @type {Table<{ id: number }>}
|
|
5
|
+
*/
|
|
6
|
+
export default new Table({
|
|
7
|
+
name: "c",
|
|
8
|
+
priority: 2,
|
|
9
|
+
setup(table) {
|
|
10
|
+
table.increments("id").primary().notNullable()
|
|
11
|
+
},
|
|
12
|
+
async then({ query }) {
|
|
13
|
+
await query.insert({ id: 0 })
|
|
14
|
+
},
|
|
15
|
+
})
|
package/tests/test.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import dotenv from "dotenv"
|
|
2
|
+
import { rimraf } from "rimraf"
|
|
2
3
|
import path from "path"
|
|
3
4
|
import fs from "fs"
|
|
4
5
|
|
|
@@ -11,7 +12,10 @@ import b from "./tables/b"
|
|
|
11
12
|
import c from "./tables/c"
|
|
12
13
|
|
|
13
14
|
const orm = new ORM({
|
|
14
|
-
|
|
15
|
+
tableLocation: path.join(process.cwd(), "tests", "tables"),
|
|
16
|
+
backups: {
|
|
17
|
+
location: path.join(process.cwd(), "backups"),
|
|
18
|
+
},
|
|
15
19
|
})
|
|
16
20
|
|
|
17
21
|
beforeAll(async () => {
|
|
@@ -24,7 +28,9 @@ describe("table management", () => {
|
|
|
24
28
|
expect(await orm.hasTable("a")).toBeTruthy()
|
|
25
29
|
expect(await orm.hasTable("b")).toBeTruthy()
|
|
26
30
|
expect(await orm.hasTable("c")).toBeTruthy()
|
|
31
|
+
})
|
|
27
32
|
|
|
33
|
+
test("table cached", async () => {
|
|
28
34
|
expect(orm.hasCachedTable("migration")).toBeTruthy()
|
|
29
35
|
expect(orm.hasCachedTable("a")).toBeTruthy()
|
|
30
36
|
expect(orm.hasCachedTable("b")).toBeTruthy()
|
|
@@ -42,6 +48,8 @@ describe("table management", () => {
|
|
|
42
48
|
})
|
|
43
49
|
|
|
44
50
|
test("cascade delete", async () => {
|
|
51
|
+
expect(await a.isEmpty()).toBeFalsy()
|
|
52
|
+
|
|
45
53
|
await c.query.del()
|
|
46
54
|
|
|
47
55
|
expect(await a.isEmpty()).toBeTruthy()
|
|
@@ -68,45 +76,51 @@ describe("table column types", () => {
|
|
|
68
76
|
})
|
|
69
77
|
})
|
|
70
78
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
79
|
+
describe("database extraction", () => {
|
|
80
|
+
beforeAll(async () => {
|
|
81
|
+
await c.query.insert({ id: 0 })
|
|
82
|
+
await b.query.insert({
|
|
83
|
+
id: 0,
|
|
84
|
+
c_id: 0,
|
|
85
|
+
})
|
|
86
|
+
await a.query.insert({
|
|
87
|
+
id: 0,
|
|
88
|
+
b_id: 0,
|
|
89
|
+
})
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
test("extract CSV", async () => {
|
|
93
|
+
await orm.createBackup()
|
|
94
|
+
|
|
95
|
+
expect(
|
|
96
|
+
fs.existsSync(path.join(orm.config.backups.location, "a_chunk_0.csv")),
|
|
97
|
+
).toBeTruthy()
|
|
98
|
+
expect(
|
|
99
|
+
fs.existsSync(path.join(orm.config.backups.location, "b_chunk_0.csv")),
|
|
100
|
+
).toBeTruthy()
|
|
101
|
+
expect(
|
|
102
|
+
fs.existsSync(path.join(orm.config.backups.location, "c_chunk_0.csv")),
|
|
103
|
+
).toBeTruthy()
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
test("empty tables", async () => {
|
|
107
|
+
await a.query.del()
|
|
108
|
+
await b.query.del()
|
|
109
|
+
await c.query.del()
|
|
110
|
+
|
|
111
|
+
expect(await a.isEmpty()).toBeTruthy()
|
|
112
|
+
expect(await b.isEmpty()).toBeTruthy()
|
|
113
|
+
expect(await c.isEmpty()).toBeTruthy()
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
test("import CSV", async () => {
|
|
117
|
+
await orm.restoreBackup()
|
|
118
|
+
|
|
119
|
+
expect(await a.isEmpty()).toBeFalsy()
|
|
120
|
+
expect(await b.isEmpty()).toBeFalsy()
|
|
121
|
+
expect(await c.isEmpty()).toBeFalsy()
|
|
122
|
+
})
|
|
123
|
+
})
|
|
110
124
|
|
|
111
125
|
describe("table getters", () => {
|
|
112
126
|
test("table info", async () => {
|
|
@@ -126,9 +140,72 @@ describe("table getters", () => {
|
|
|
126
140
|
})
|
|
127
141
|
})
|
|
128
142
|
|
|
143
|
+
describe("data caching", () => {
|
|
144
|
+
beforeAll(async () => {
|
|
145
|
+
await c.query.del()
|
|
146
|
+
await c.query.insert([{ id: 1 }, { id: 2 }, { id: 3 }])
|
|
147
|
+
await b.query.insert([
|
|
148
|
+
{ id: 1, c_id: 1 },
|
|
149
|
+
{ id: 2, c_id: 2 },
|
|
150
|
+
{ id: 3, c_id: 3 },
|
|
151
|
+
])
|
|
152
|
+
await a.query.insert([
|
|
153
|
+
{ id: 1, b_id: 1 },
|
|
154
|
+
{ id: 2, b_id: 2 },
|
|
155
|
+
{ id: 3, b_id: 3 },
|
|
156
|
+
])
|
|
157
|
+
})
|
|
158
|
+
|
|
159
|
+
test("select with caching", async () => {
|
|
160
|
+
const rows = await a.cache.get("all a", (query) => {
|
|
161
|
+
return query.select("*")
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
expect(rows.length).toBe(3)
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
test("insert with caching", async () => {
|
|
168
|
+
await a.cache.set((query) => {
|
|
169
|
+
return query.insert({ id: 4, b_id: 1 })
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
expect(await a.cache.count()).toBe(4)
|
|
173
|
+
})
|
|
174
|
+
|
|
175
|
+
test("update with caching", async () => {
|
|
176
|
+
await a.cache.set((query) => {
|
|
177
|
+
return query.update({ b_id: 3 }).where({ id: 1 })
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
const row = await a.cache.get("a 1", (query) => {
|
|
181
|
+
return query.select("b_id").where({ id: 1 }).first()
|
|
182
|
+
})
|
|
183
|
+
|
|
184
|
+
expect(row.b_id).toBe(3)
|
|
185
|
+
})
|
|
186
|
+
|
|
187
|
+
test("delete with caching", async () => {
|
|
188
|
+
await a.cache.set((query) => {
|
|
189
|
+
return query.delete().where({ id: 1 })
|
|
190
|
+
})
|
|
191
|
+
|
|
192
|
+
expect(await a.cache.count()).toBe(3)
|
|
193
|
+
})
|
|
194
|
+
|
|
195
|
+
test("cache invalidation", async () => {
|
|
196
|
+
expect(await a.cache.count()).toBe(3)
|
|
197
|
+
|
|
198
|
+
await a.query.insert({ id: 5, b_id: 1 })
|
|
199
|
+
|
|
200
|
+
expect(await a.cache.count()).toBe(3)
|
|
201
|
+
|
|
202
|
+
orm.cache.invalidate()
|
|
203
|
+
|
|
204
|
+
expect(await a.cache.count()).toBe(4)
|
|
205
|
+
})
|
|
206
|
+
})
|
|
207
|
+
|
|
129
208
|
afterAll(async () => {
|
|
130
209
|
await orm.database.destroy()
|
|
131
|
-
|
|
132
|
-
// fs.unlinkSync("b.csv")
|
|
133
|
-
// fs.unlinkSync("c.csv")
|
|
210
|
+
await rimraf(orm.config.backups.location)
|
|
134
211
|
})
|
package/tsconfig.json
CHANGED
|
@@ -2,10 +2,13 @@
|
|
|
2
2
|
"compilerOptions": {
|
|
3
3
|
"strict": true,
|
|
4
4
|
"rootDir": "src",
|
|
5
|
-
"
|
|
6
|
-
"module": "
|
|
5
|
+
"outDir": "dist",
|
|
6
|
+
"module": "esnext",
|
|
7
|
+
"target": "esnext",
|
|
7
8
|
"lib": ["es2020", "dom"],
|
|
8
9
|
"moduleResolution": "Node",
|
|
9
|
-
"esModuleInterop": true
|
|
10
|
-
|
|
10
|
+
"esModuleInterop": true,
|
|
11
|
+
"typeRoots": ["./node_modules/@types", "./dist/typings"]
|
|
12
|
+
},
|
|
13
|
+
"include": ["src/**/*", "dist/typings/**/*"]
|
|
11
14
|
}
|
package/dist/cjs/app/orm.js
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
-
};
|
|
28
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.ORM = void 0;
|
|
30
|
-
const fs_1 = __importDefault(require("fs"));
|
|
31
|
-
const url_1 = __importDefault(require("url"));
|
|
32
|
-
const path_1 = __importDefault(require("path"));
|
|
33
|
-
const handler_1 = require("@ghom/handler");
|
|
34
|
-
const knex_1 = __importDefault(require("knex"));
|
|
35
|
-
const table_js_1 = require("./table.js");
|
|
36
|
-
const defaultBackupDir = path_1.default.join(process.cwd(), "backup");
|
|
37
|
-
const pack = JSON.parse(fs_1.default.readFileSync(path_1.default.join(process.cwd(), "package.json"), "utf8"));
|
|
38
|
-
const isCJS = pack.type === "commonjs" || pack.type == void 0;
|
|
39
|
-
class ORM {
|
|
40
|
-
constructor(config) {
|
|
41
|
-
this.config = config;
|
|
42
|
-
this.database = (0, knex_1.default)(config.database ?? {
|
|
43
|
-
client: "sqlite3",
|
|
44
|
-
useNullAsDefault: true,
|
|
45
|
-
connection: {
|
|
46
|
-
filename: ":memory:",
|
|
47
|
-
},
|
|
48
|
-
});
|
|
49
|
-
this.handler = new handler_1.Handler(config.location, {
|
|
50
|
-
loader: (filepath) => Promise.resolve(`${isCJS ? filepath : url_1.default.pathToFileURL(filepath).href}`).then(s => __importStar(require(s))).then((file) => file.default),
|
|
51
|
-
pattern: /\.js$/,
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
get cachedTables() {
|
|
55
|
-
return [...this.handler.elements.values()];
|
|
56
|
-
}
|
|
57
|
-
get cachedTableNames() {
|
|
58
|
-
return this.cachedTables.map((table) => table.options.name);
|
|
59
|
-
}
|
|
60
|
-
hasCachedTable(name) {
|
|
61
|
-
return this.cachedTables.some((table) => table.options.name);
|
|
62
|
-
}
|
|
63
|
-
async hasTable(name) {
|
|
64
|
-
return this.database.schema.hasTable(name);
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Handle the table files and create the tables in the database.
|
|
68
|
-
*/
|
|
69
|
-
async init() {
|
|
70
|
-
await this.handler.init();
|
|
71
|
-
try {
|
|
72
|
-
await this.database.raw("PRAGMA foreign_keys = ON;");
|
|
73
|
-
}
|
|
74
|
-
catch (error) { }
|
|
75
|
-
const migration = new table_js_1.Table({
|
|
76
|
-
name: "migration",
|
|
77
|
-
priority: Infinity,
|
|
78
|
-
setup: (table) => {
|
|
79
|
-
table.string("table").unique().notNullable();
|
|
80
|
-
table.integer("version").notNullable();
|
|
81
|
-
},
|
|
82
|
-
});
|
|
83
|
-
migration.orm = this;
|
|
84
|
-
await migration.make();
|
|
85
|
-
for (const table of this.cachedTables.sort((a, b) => (b.options.priority ?? 0) - (a.options.priority ?? 0))) {
|
|
86
|
-
table.orm = this;
|
|
87
|
-
await table.make();
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
raw(sql) {
|
|
91
|
-
return this.database.raw(sql);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
exports.ORM = ORM;
|