@ghom/orm 1.9.2 → 2.0.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 +9 -9
- package/biome.json +45 -0
- package/bun.lock +488 -0
- package/dist/app/backup.d.ts +3 -3
- package/dist/app/backup.js +21 -13
- package/dist/app/column.d.ts +225 -0
- package/dist/app/column.js +342 -0
- package/dist/app/orm.d.ts +42 -8
- package/dist/app/orm.js +68 -14
- package/dist/app/table.d.ts +52 -21
- package/dist/app/table.js +43 -21
- package/dist/app/util.d.ts +1 -1
- package/dist/app/util.js +6 -5
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/package.json +43 -47
- package/readme.md +19 -0
- package/tests/orm.test.ts +288 -0
- package/tests/tables/a.ts +16 -0
- package/tests/tables/b.ts +16 -0
- package/tests/tables/c.ts +14 -0
- package/tests/tables/d.ts +32 -0
- package/tsconfig.json +1 -0
- package/tests/tables/a.js +0 -25
- package/tests/tables/b.js +0 -30
- package/tests/tables/c.js +0 -17
- package/tests/test.js +0 -205
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
import { afterAll, beforeAll, describe, expect, test } from "bun:test"
|
|
2
|
+
import fs from "fs"
|
|
3
|
+
import path from "path"
|
|
4
|
+
import { rimraf } from "rimraf"
|
|
5
|
+
|
|
6
|
+
import { col, ORM, type ORMConfig, Table } from "../src"
|
|
7
|
+
|
|
8
|
+
import a from "./tables/a"
|
|
9
|
+
import b from "./tables/b"
|
|
10
|
+
import c from "./tables/c"
|
|
11
|
+
import d from "./tables/d"
|
|
12
|
+
|
|
13
|
+
describe("typed columns", () => {
|
|
14
|
+
test("new Table() infers types correctly", () => {
|
|
15
|
+
const userTable = new Table({
|
|
16
|
+
name: "test_user",
|
|
17
|
+
columns: (col) => ({
|
|
18
|
+
id: col.increments(),
|
|
19
|
+
username: col.string().unique(),
|
|
20
|
+
age: col.integer().nullable(),
|
|
21
|
+
role: col.enum(["admin", "user"] as const),
|
|
22
|
+
isActive: col.boolean().defaultTo(true),
|
|
23
|
+
}),
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
expect(userTable).toBeInstanceOf(Table)
|
|
27
|
+
expect(userTable.options.name).toBe("test_user")
|
|
28
|
+
expect("columns" in userTable.options).toBe(true)
|
|
29
|
+
|
|
30
|
+
// Type inference check - this line would fail at compile time if types weren't inferred
|
|
31
|
+
type ExpectedType = typeof userTable.$type
|
|
32
|
+
const _typeCheck: ExpectedType = {
|
|
33
|
+
id: 1,
|
|
34
|
+
username: "test",
|
|
35
|
+
age: null,
|
|
36
|
+
role: "admin",
|
|
37
|
+
isActive: true,
|
|
38
|
+
}
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
test("col factory creates column definitions", () => {
|
|
42
|
+
const idCol = col.increments()
|
|
43
|
+
const stringCol = col.string()
|
|
44
|
+
const nullableInt = col.integer().nullable()
|
|
45
|
+
const enumCol = col.enum(["a", "b", "c"] as const)
|
|
46
|
+
|
|
47
|
+
expect(idCol).toBeDefined()
|
|
48
|
+
expect(stringCol).toBeDefined()
|
|
49
|
+
expect(nullableInt._isNullable).toBe(true)
|
|
50
|
+
expect(enumCol).toBeDefined()
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
test("typed table d has correct options", () => {
|
|
54
|
+
expect(d).toBeInstanceOf(Table)
|
|
55
|
+
expect(d.options.name).toBe("d")
|
|
56
|
+
expect("columns" in d.options).toBe(true)
|
|
57
|
+
})
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
describe("unconnected ORM", () => {
|
|
61
|
+
test("can be initialized with false", () => {
|
|
62
|
+
const unconnectedOrm = new ORM(false)
|
|
63
|
+
|
|
64
|
+
expect(unconnectedOrm).toBeInstanceOf(ORM)
|
|
65
|
+
expect(unconnectedOrm.isConnected).toBe(false)
|
|
66
|
+
expect(unconnectedOrm.config).toBe(false)
|
|
67
|
+
expect(unconnectedOrm.handler).toBeUndefined()
|
|
68
|
+
expect(unconnectedOrm.cachedTables).toEqual([])
|
|
69
|
+
expect(unconnectedOrm.cachedTableNames).toEqual([])
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
test("throws when calling methods requiring client", async () => {
|
|
73
|
+
const unconnectedOrm = new ORM(false)
|
|
74
|
+
|
|
75
|
+
expect(() => unconnectedOrm.client).toThrow()
|
|
76
|
+
expect(unconnectedOrm.init()).rejects.toThrow()
|
|
77
|
+
expect(unconnectedOrm.hasTable("test")).rejects.toThrow()
|
|
78
|
+
expect(() => unconnectedOrm.raw("SELECT 1")).toThrow()
|
|
79
|
+
expect(unconnectedOrm.createBackup()).rejects.toThrow()
|
|
80
|
+
expect(unconnectedOrm.restoreBackup()).rejects.toThrow()
|
|
81
|
+
})
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
const orm = new ORM({
|
|
85
|
+
tableLocation: path.join(process.cwd(), "tests", "tables"),
|
|
86
|
+
backups: {
|
|
87
|
+
location: path.join(process.cwd(), "backups"),
|
|
88
|
+
},
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
beforeAll(async () => {
|
|
92
|
+
await orm.init()
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
describe("table management", () => {
|
|
96
|
+
test("tables created", async () => {
|
|
97
|
+
expect(await orm.hasTable("migration")).toBeTruthy()
|
|
98
|
+
expect(await orm.hasTable("a")).toBeTruthy()
|
|
99
|
+
expect(await orm.hasTable("b")).toBeTruthy()
|
|
100
|
+
expect(await orm.hasTable("c")).toBeTruthy()
|
|
101
|
+
expect(await orm.hasTable("d")).toBeTruthy()
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
test("table cached", () => {
|
|
105
|
+
expect(orm.hasCachedTable("migration")).toBeTruthy()
|
|
106
|
+
expect(orm.hasCachedTable("a")).toBeTruthy()
|
|
107
|
+
expect(orm.hasCachedTable("b")).toBeTruthy()
|
|
108
|
+
expect(orm.hasCachedTable("c")).toBeTruthy()
|
|
109
|
+
expect(orm.hasCachedTable("d")).toBeTruthy()
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
test("table migrations ran", async () => {
|
|
113
|
+
expect(await b.hasColumn("c_id")).toBeTruthy()
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
test("table then ran", async () => {
|
|
117
|
+
const rows = await a.query.select()
|
|
118
|
+
expect(rows.length).toBe(1)
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
test("typed table d was created with correct columns", async () => {
|
|
122
|
+
expect(await d.hasColumn("id")).toBeTruthy()
|
|
123
|
+
expect(await d.hasColumn("name")).toBeTruthy()
|
|
124
|
+
expect(await d.hasColumn("email")).toBeTruthy()
|
|
125
|
+
expect(await d.hasColumn("age")).toBeTruthy()
|
|
126
|
+
expect(await d.hasColumn("role")).toBeTruthy()
|
|
127
|
+
expect(await d.hasColumn("isActive")).toBeTruthy()
|
|
128
|
+
expect(await d.hasColumn("metadata")).toBeTruthy()
|
|
129
|
+
expect(await d.hasColumn("createdAt")).toBeTruthy()
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
test("typed table d then ran", async () => {
|
|
133
|
+
const rows = await d.query.select()
|
|
134
|
+
expect(rows.length).toBe(1)
|
|
135
|
+
expect(rows[0].name).toBe("Test User")
|
|
136
|
+
expect(rows[0].role).toBe("admin")
|
|
137
|
+
})
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
describe("table column types", () => {
|
|
141
|
+
test("increments", async () => {
|
|
142
|
+
const info = await orm.client!("a").columnInfo("id")
|
|
143
|
+
expect(info.type).toMatch(/^int/)
|
|
144
|
+
})
|
|
145
|
+
|
|
146
|
+
test("integer", async () => {
|
|
147
|
+
const info = await orm.client!("a").columnInfo("b_id")
|
|
148
|
+
expect(info.type).toMatch(/^int/)
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
test("typed table d column types", async () => {
|
|
152
|
+
const nameInfo = await orm.client!("d").columnInfo("name")
|
|
153
|
+
expect(nameInfo.type).toMatch(/varchar|text|character/i)
|
|
154
|
+
|
|
155
|
+
const ageInfo = await orm.client!("d").columnInfo("age")
|
|
156
|
+
expect(ageInfo.type).toMatch(/^int/)
|
|
157
|
+
expect(ageInfo.nullable).toBe(true)
|
|
158
|
+
})
|
|
159
|
+
})
|
|
160
|
+
|
|
161
|
+
describe("database extraction", () => {
|
|
162
|
+
test("create backup", async () => {
|
|
163
|
+
await orm.createBackup()
|
|
164
|
+
|
|
165
|
+
const config = orm.config as ORMConfig
|
|
166
|
+
expect(fs.existsSync(path.join(config.backups!.location!, "a_chunk_0.csv"))).toBeTruthy()
|
|
167
|
+
expect(fs.existsSync(path.join(config.backups!.location!, "b_chunk_0.csv"))).toBeTruthy()
|
|
168
|
+
expect(fs.existsSync(path.join(config.backups!.location!, "c_chunk_0.csv"))).toBeTruthy()
|
|
169
|
+
expect(fs.existsSync(path.join(config.backups!.location!, "d_chunk_0.csv"))).toBeTruthy()
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
test("cascade delete", async () => {
|
|
173
|
+
expect(await a.isEmpty()).toBeFalsy()
|
|
174
|
+
await c.query.del()
|
|
175
|
+
expect(await a.isEmpty()).toBeTruthy()
|
|
176
|
+
})
|
|
177
|
+
|
|
178
|
+
test("restore backup", async () => {
|
|
179
|
+
await orm.restoreBackup()
|
|
180
|
+
|
|
181
|
+
expect(await a.isEmpty()).toBeFalsy()
|
|
182
|
+
expect(await b.isEmpty()).toBeFalsy()
|
|
183
|
+
expect(await c.isEmpty()).toBeFalsy()
|
|
184
|
+
expect(await d.isEmpty()).toBeFalsy()
|
|
185
|
+
})
|
|
186
|
+
|
|
187
|
+
afterAll(async () => {
|
|
188
|
+
const config = orm.config as ORMConfig
|
|
189
|
+
await rimraf(config.backups!.location!)
|
|
190
|
+
})
|
|
191
|
+
})
|
|
192
|
+
|
|
193
|
+
describe("table getters", () => {
|
|
194
|
+
test("table info", async () => {
|
|
195
|
+
expect(await a.getColumnNames()).toContain("id")
|
|
196
|
+
expect(await a.getColumnNames()).toContain("b_id")
|
|
197
|
+
|
|
198
|
+
expect(await b.getColumnNames()).toContain("id")
|
|
199
|
+
expect(await b.getColumnNames()).toContain("c_id")
|
|
200
|
+
|
|
201
|
+
expect(await c.getColumnNames()).toContain("id")
|
|
202
|
+
|
|
203
|
+
expect(await d.getColumnNames()).toContain("id")
|
|
204
|
+
expect(await d.getColumnNames()).toContain("name")
|
|
205
|
+
expect(await d.getColumnNames()).toContain("role")
|
|
206
|
+
})
|
|
207
|
+
|
|
208
|
+
test("table names", () => {
|
|
209
|
+
expect(orm.cachedTableNames).toContain("a")
|
|
210
|
+
expect(orm.cachedTableNames).toContain("b")
|
|
211
|
+
expect(orm.cachedTableNames).toContain("c")
|
|
212
|
+
expect(orm.cachedTableNames).toContain("d")
|
|
213
|
+
})
|
|
214
|
+
})
|
|
215
|
+
|
|
216
|
+
describe("data caching", () => {
|
|
217
|
+
beforeAll(async () => {
|
|
218
|
+
await c.query.del()
|
|
219
|
+
await c.query.insert([{ id: 1 }, { id: 2 }, { id: 3 }])
|
|
220
|
+
await b.query.insert([
|
|
221
|
+
{ id: 1, c_id: 1 },
|
|
222
|
+
{ id: 2, c_id: 2 },
|
|
223
|
+
{ id: 3, c_id: 3 },
|
|
224
|
+
])
|
|
225
|
+
await a.query.insert([
|
|
226
|
+
{ id: 1, b_id: 1 },
|
|
227
|
+
{ id: 2, b_id: 2 },
|
|
228
|
+
{ id: 3, b_id: 3 },
|
|
229
|
+
])
|
|
230
|
+
})
|
|
231
|
+
|
|
232
|
+
test("select with caching", async () => {
|
|
233
|
+
const rows = await a.cache.get("all a", (query) => {
|
|
234
|
+
return query.select("*")
|
|
235
|
+
})
|
|
236
|
+
|
|
237
|
+
expect(rows.length).toBe(3)
|
|
238
|
+
})
|
|
239
|
+
|
|
240
|
+
test("insert with caching", async () => {
|
|
241
|
+
await a.cache.set((query) => {
|
|
242
|
+
return query.insert({ id: 4, b_id: 1 })
|
|
243
|
+
})
|
|
244
|
+
|
|
245
|
+
expect(await a.cache.count()).toBe(4)
|
|
246
|
+
})
|
|
247
|
+
|
|
248
|
+
test("update with caching", async () => {
|
|
249
|
+
await a.cache.set((query) => {
|
|
250
|
+
return query.update({ b_id: 3 }).where({ id: 1 })
|
|
251
|
+
})
|
|
252
|
+
|
|
253
|
+
const row = await a.cache.get("a 1", (query) => {
|
|
254
|
+
return query.select("b_id").where({ id: 1 }).first()
|
|
255
|
+
})
|
|
256
|
+
|
|
257
|
+
expect(row!.b_id).toBe(3)
|
|
258
|
+
})
|
|
259
|
+
|
|
260
|
+
test("delete with caching", async () => {
|
|
261
|
+
await a.cache.set((query) => {
|
|
262
|
+
return query.delete().where({ id: 1 })
|
|
263
|
+
})
|
|
264
|
+
|
|
265
|
+
expect(await a.cache.count()).toBe(3)
|
|
266
|
+
})
|
|
267
|
+
|
|
268
|
+
test("cache invalidation", async () => {
|
|
269
|
+
expect(await a.cache.count()).toBe(3)
|
|
270
|
+
|
|
271
|
+
await a.query.insert({ id: 5, b_id: 1 })
|
|
272
|
+
|
|
273
|
+
expect(await a.cache.count()).toBe(3)
|
|
274
|
+
|
|
275
|
+
orm.cache.invalidate()
|
|
276
|
+
|
|
277
|
+
expect(await a.cache.count()).toBe(4)
|
|
278
|
+
})
|
|
279
|
+
})
|
|
280
|
+
|
|
281
|
+
afterAll(async () => {
|
|
282
|
+
await orm.client!.schema.dropTable("migration")
|
|
283
|
+
await orm.client!.schema.dropTable("a")
|
|
284
|
+
await orm.client!.schema.dropTable("b")
|
|
285
|
+
await orm.client!.schema.dropTable("c")
|
|
286
|
+
await orm.client!.schema.dropTable("d")
|
|
287
|
+
await orm.client!.destroy()
|
|
288
|
+
})
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Table } from "../../src"
|
|
2
|
+
|
|
3
|
+
export default new Table({
|
|
4
|
+
name: "a",
|
|
5
|
+
priority: 0,
|
|
6
|
+
columns: (col) => ({
|
|
7
|
+
id: col.increments(),
|
|
8
|
+
b_id: col.integer().unsigned().references("id").inTable("b").onDelete("CASCADE"),
|
|
9
|
+
}),
|
|
10
|
+
async then({ query }) {
|
|
11
|
+
await query.insert({
|
|
12
|
+
id: 1,
|
|
13
|
+
b_id: 1,
|
|
14
|
+
})
|
|
15
|
+
},
|
|
16
|
+
})
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Table } from "../../src"
|
|
2
|
+
|
|
3
|
+
export default new Table({
|
|
4
|
+
name: "b",
|
|
5
|
+
priority: 1,
|
|
6
|
+
columns: (col) => ({
|
|
7
|
+
id: col.increments(),
|
|
8
|
+
c_id: col.integer().unsigned().references("id").inTable("c").onDelete("CASCADE"),
|
|
9
|
+
}),
|
|
10
|
+
async then({ query }) {
|
|
11
|
+
await query.insert({
|
|
12
|
+
id: 1,
|
|
13
|
+
c_id: 1,
|
|
14
|
+
})
|
|
15
|
+
},
|
|
16
|
+
})
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Table } from "../../src"
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Table using the new typed columns system.
|
|
5
|
+
* Type is automatically inferred from the column definitions.
|
|
6
|
+
*/
|
|
7
|
+
export default new Table({
|
|
8
|
+
name: "d",
|
|
9
|
+
priority: 0,
|
|
10
|
+
columns: (col) => ({
|
|
11
|
+
id: col.increments(),
|
|
12
|
+
name: col.string(100).unique(),
|
|
13
|
+
email: col.string(255),
|
|
14
|
+
age: col.integer().nullable().unsigned(),
|
|
15
|
+
role: col.enum(["admin", "user", "guest"] as const).defaultTo("user"),
|
|
16
|
+
isActive: col.boolean().defaultTo(true),
|
|
17
|
+
metadata: col.json<{ tags: string[]; score: number }>().nullable(),
|
|
18
|
+
createdAt: col.timestamp().nullable(),
|
|
19
|
+
}),
|
|
20
|
+
async then({ query }) {
|
|
21
|
+
await query.insert({
|
|
22
|
+
id: 1,
|
|
23
|
+
name: "Test User",
|
|
24
|
+
email: "test@example.com",
|
|
25
|
+
age: 25,
|
|
26
|
+
role: "admin",
|
|
27
|
+
isActive: true,
|
|
28
|
+
metadata: { tags: ["test"], score: 100 },
|
|
29
|
+
createdAt: new Date(),
|
|
30
|
+
})
|
|
31
|
+
},
|
|
32
|
+
})
|
package/tsconfig.json
CHANGED
package/tests/tables/a.js
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
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
|
-
.unsigned()
|
|
14
|
-
.references("id")
|
|
15
|
-
.inTable("b")
|
|
16
|
-
.onDelete("cascade")
|
|
17
|
-
.notNullable()
|
|
18
|
-
},
|
|
19
|
-
async then({ query }) {
|
|
20
|
-
await query.insert({
|
|
21
|
-
id: 1,
|
|
22
|
-
b_id: 1,
|
|
23
|
-
})
|
|
24
|
-
},
|
|
25
|
-
})
|
package/tests/tables/b.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
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) => table.string("c_id"),
|
|
10
|
-
1: (table) => table.dropColumn("c_id"),
|
|
11
|
-
2: (table) =>
|
|
12
|
-
table
|
|
13
|
-
.integer("c_id")
|
|
14
|
-
.unsigned()
|
|
15
|
-
.references("id")
|
|
16
|
-
.inTable("c")
|
|
17
|
-
.onDelete("cascade")
|
|
18
|
-
.notNullable(),
|
|
19
|
-
},
|
|
20
|
-
priority: 1,
|
|
21
|
-
setup(table) {
|
|
22
|
-
table.increments("id").primary().notNullable()
|
|
23
|
-
},
|
|
24
|
-
async then({ query }) {
|
|
25
|
-
await query.insert({
|
|
26
|
-
id: 1,
|
|
27
|
-
c_id: 1,
|
|
28
|
-
})
|
|
29
|
-
},
|
|
30
|
-
})
|
package/tests/tables/c.js
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
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({
|
|
14
|
-
id: 1,
|
|
15
|
-
})
|
|
16
|
-
},
|
|
17
|
-
})
|
package/tests/test.js
DELETED
|
@@ -1,205 +0,0 @@
|
|
|
1
|
-
import dotenv from "dotenv"
|
|
2
|
-
import { rimraf } from "rimraf"
|
|
3
|
-
import path from "path"
|
|
4
|
-
import fs from "fs"
|
|
5
|
-
|
|
6
|
-
dotenv.config({
|
|
7
|
-
// path: path.join(process.cwd(), "tests", ".pg.env"),
|
|
8
|
-
// path: path.join(process.cwd(), "tests", ".mysql2.env"),
|
|
9
|
-
})
|
|
10
|
-
|
|
11
|
-
process.env.DEBUG = "knex*"
|
|
12
|
-
|
|
13
|
-
import { ORM } from "../"
|
|
14
|
-
|
|
15
|
-
import a from "./tables/a"
|
|
16
|
-
import b from "./tables/b"
|
|
17
|
-
import c from "./tables/c"
|
|
18
|
-
|
|
19
|
-
const orm = new ORM({
|
|
20
|
-
tableLocation: path.join(process.cwd(), "tests", "tables"),
|
|
21
|
-
backups: {
|
|
22
|
-
location: path.join(process.cwd(), "backups"),
|
|
23
|
-
},
|
|
24
|
-
database: process.env.DB_CLIENT && {
|
|
25
|
-
client: process.env.DB_CLIENT,
|
|
26
|
-
connection: process.env.DB_CONNECTION,
|
|
27
|
-
},
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
beforeAll(async () => {
|
|
31
|
-
await orm.init()
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
describe("table management", () => {
|
|
35
|
-
test("tables created", async () => {
|
|
36
|
-
expect(await orm.hasTable("migration")).toBeTruthy()
|
|
37
|
-
expect(await orm.hasTable("a")).toBeTruthy()
|
|
38
|
-
expect(await orm.hasTable("b")).toBeTruthy()
|
|
39
|
-
expect(await orm.hasTable("c")).toBeTruthy()
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
test("table cached", async () => {
|
|
43
|
-
expect(orm.hasCachedTable("migration")).toBeTruthy()
|
|
44
|
-
expect(orm.hasCachedTable("a")).toBeTruthy()
|
|
45
|
-
expect(orm.hasCachedTable("b")).toBeTruthy()
|
|
46
|
-
expect(orm.hasCachedTable("c")).toBeTruthy()
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
test("table migrations ran", async () => {
|
|
50
|
-
expect(await b.hasColumn("c_id")).toBeTruthy()
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
test("table then ran", async () => {
|
|
54
|
-
const rows = await a.query.select()
|
|
55
|
-
|
|
56
|
-
expect(rows.length).toBe(1)
|
|
57
|
-
})
|
|
58
|
-
})
|
|
59
|
-
|
|
60
|
-
describe("table column types", () => {
|
|
61
|
-
test("increments", async () => {
|
|
62
|
-
expect(
|
|
63
|
-
await orm
|
|
64
|
-
.client("a")
|
|
65
|
-
.columnInfo("id")
|
|
66
|
-
.then((info) => info.type),
|
|
67
|
-
).toMatch(/^int/)
|
|
68
|
-
})
|
|
69
|
-
|
|
70
|
-
test("integer", async () => {
|
|
71
|
-
expect(
|
|
72
|
-
await orm
|
|
73
|
-
.client("a")
|
|
74
|
-
.columnInfo("b_id")
|
|
75
|
-
.then((info) => info.type),
|
|
76
|
-
).toMatch(/^int/)
|
|
77
|
-
})
|
|
78
|
-
})
|
|
79
|
-
|
|
80
|
-
describe("database extraction", () => {
|
|
81
|
-
test("create backup", async () => {
|
|
82
|
-
await orm.createBackup()
|
|
83
|
-
|
|
84
|
-
expect(
|
|
85
|
-
fs.existsSync(path.join(orm.config.backups.location, "a_chunk_0.csv")),
|
|
86
|
-
).toBeTruthy()
|
|
87
|
-
expect(
|
|
88
|
-
fs.existsSync(path.join(orm.config.backups.location, "b_chunk_0.csv")),
|
|
89
|
-
).toBeTruthy()
|
|
90
|
-
expect(
|
|
91
|
-
fs.existsSync(path.join(orm.config.backups.location, "c_chunk_0.csv")),
|
|
92
|
-
).toBeTruthy()
|
|
93
|
-
})
|
|
94
|
-
|
|
95
|
-
test("cascade delete", async () => {
|
|
96
|
-
expect(await a.isEmpty()).toBeFalsy()
|
|
97
|
-
|
|
98
|
-
await c.query.del()
|
|
99
|
-
|
|
100
|
-
expect(await a.isEmpty()).toBeTruthy()
|
|
101
|
-
})
|
|
102
|
-
|
|
103
|
-
test("restore backup", async () => {
|
|
104
|
-
await orm.restoreBackup()
|
|
105
|
-
|
|
106
|
-
expect(await a.isEmpty()).toBeFalsy()
|
|
107
|
-
expect(await b.isEmpty()).toBeFalsy()
|
|
108
|
-
expect(await c.isEmpty()).toBeFalsy()
|
|
109
|
-
}, 10_000)
|
|
110
|
-
|
|
111
|
-
afterAll(async () => {
|
|
112
|
-
await rimraf(orm.config.backups.location)
|
|
113
|
-
})
|
|
114
|
-
})
|
|
115
|
-
|
|
116
|
-
describe("table getters", () => {
|
|
117
|
-
test("table info", async () => {
|
|
118
|
-
expect(await a.getColumnNames()).toContain("id")
|
|
119
|
-
expect(await a.getColumnNames()).toContain("b_id")
|
|
120
|
-
|
|
121
|
-
expect(await b.getColumnNames()).toContain("id")
|
|
122
|
-
expect(await b.getColumnNames()).toContain("c_id")
|
|
123
|
-
|
|
124
|
-
expect(await c.getColumnNames()).toContain("id")
|
|
125
|
-
})
|
|
126
|
-
|
|
127
|
-
test("table names", async () => {
|
|
128
|
-
expect(orm.cachedTableNames).toContain("a")
|
|
129
|
-
expect(orm.cachedTableNames).toContain("b")
|
|
130
|
-
expect(orm.cachedTableNames).toContain("c")
|
|
131
|
-
})
|
|
132
|
-
})
|
|
133
|
-
|
|
134
|
-
describe("data caching", () => {
|
|
135
|
-
beforeAll(async () => {
|
|
136
|
-
await c.query.del()
|
|
137
|
-
await c.query.insert([{ id: 1 }, { id: 2 }, { id: 3 }])
|
|
138
|
-
await b.query.insert([
|
|
139
|
-
{ id: 1, c_id: 1 },
|
|
140
|
-
{ id: 2, c_id: 2 },
|
|
141
|
-
{ id: 3, c_id: 3 },
|
|
142
|
-
])
|
|
143
|
-
await a.query.insert([
|
|
144
|
-
{ id: 1, b_id: 1 },
|
|
145
|
-
{ id: 2, b_id: 2 },
|
|
146
|
-
{ id: 3, b_id: 3 },
|
|
147
|
-
])
|
|
148
|
-
})
|
|
149
|
-
|
|
150
|
-
test("select with caching", async () => {
|
|
151
|
-
const rows = await a.cache.get("all a", (query) => {
|
|
152
|
-
return query.select("*")
|
|
153
|
-
})
|
|
154
|
-
|
|
155
|
-
expect(rows.length).toBe(3)
|
|
156
|
-
})
|
|
157
|
-
|
|
158
|
-
test("insert with caching", async () => {
|
|
159
|
-
await a.cache.set((query) => {
|
|
160
|
-
return query.insert({ id: 4, b_id: 1 })
|
|
161
|
-
})
|
|
162
|
-
|
|
163
|
-
expect(await a.cache.count()).toBe(4)
|
|
164
|
-
})
|
|
165
|
-
|
|
166
|
-
test("update with caching", async () => {
|
|
167
|
-
await a.cache.set((query) => {
|
|
168
|
-
return query.update({ b_id: 3 }).where({ id: 1 })
|
|
169
|
-
})
|
|
170
|
-
|
|
171
|
-
const row = await a.cache.get("a 1", (query) => {
|
|
172
|
-
return query.select("b_id").where({ id: 1 }).first()
|
|
173
|
-
})
|
|
174
|
-
|
|
175
|
-
expect(row.b_id).toBe(3)
|
|
176
|
-
})
|
|
177
|
-
|
|
178
|
-
test("delete with caching", async () => {
|
|
179
|
-
await a.cache.set((query) => {
|
|
180
|
-
return query.delete().where({ id: 1 })
|
|
181
|
-
})
|
|
182
|
-
|
|
183
|
-
expect(await a.cache.count()).toBe(3)
|
|
184
|
-
})
|
|
185
|
-
|
|
186
|
-
test("cache invalidation", async () => {
|
|
187
|
-
expect(await a.cache.count()).toBe(3)
|
|
188
|
-
|
|
189
|
-
await a.query.insert({ id: 5, b_id: 1 })
|
|
190
|
-
|
|
191
|
-
expect(await a.cache.count()).toBe(3)
|
|
192
|
-
|
|
193
|
-
orm.cache.invalidate()
|
|
194
|
-
|
|
195
|
-
expect(await a.cache.count()).toBe(4)
|
|
196
|
-
})
|
|
197
|
-
})
|
|
198
|
-
|
|
199
|
-
afterAll(async () => {
|
|
200
|
-
await orm.client.schema.dropTable("migration")
|
|
201
|
-
await orm.client.schema.dropTable("a")
|
|
202
|
-
await orm.client.schema.dropTable("b")
|
|
203
|
-
await orm.client.schema.dropTable("c")
|
|
204
|
-
await orm.client.destroy()
|
|
205
|
-
})
|