@ghom/orm 1.5.2 → 1.6.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/dist/cjs/app/orm.js +19 -2
- package/dist/cjs/app/table.js +13 -5
- package/dist/esm/app/orm.js +19 -2
- package/dist/esm/app/table.js +13 -5
- package/dist/typings/app/orm.d.ts +8 -0
- package/dist/typings/app/table.d.ts +6 -4
- package/package.json +1 -1
- package/src/app/orm.ts +27 -5
- package/src/app/table.ts +20 -10
- package/tests/test.js +29 -6
package/dist/cjs/app/orm.js
CHANGED
|
@@ -50,9 +50,23 @@ class ORM {
|
|
|
50
50
|
pattern: /\.js$/,
|
|
51
51
|
});
|
|
52
52
|
}
|
|
53
|
+
get cachedTables() {
|
|
54
|
+
return [...this.handler.elements.values()];
|
|
55
|
+
}
|
|
56
|
+
get cachedTableNames() {
|
|
57
|
+
return this.cachedTables.map((table) => table.options.name);
|
|
58
|
+
}
|
|
59
|
+
hasCachedTable(name) {
|
|
60
|
+
return this.cachedTables.some((table) => table.options.name);
|
|
61
|
+
}
|
|
62
|
+
async hasTable(name) {
|
|
63
|
+
return this.database.schema.hasTable(name);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Handle the table files and create the tables in the database.
|
|
67
|
+
*/
|
|
53
68
|
async init() {
|
|
54
69
|
await this.handler.init();
|
|
55
|
-
const tables = [...this.handler.elements.values()];
|
|
56
70
|
try {
|
|
57
71
|
await this.database.raw("PRAGMA foreign_keys = ON;");
|
|
58
72
|
}
|
|
@@ -67,11 +81,14 @@ class ORM {
|
|
|
67
81
|
});
|
|
68
82
|
migration.orm = this;
|
|
69
83
|
await migration.make();
|
|
70
|
-
for (const table of
|
|
84
|
+
for (const table of this.cachedTables.sort((a, b) => (b.options.priority ?? 0) - (a.options.priority ?? 0))) {
|
|
71
85
|
table.orm = this;
|
|
72
86
|
await table.make();
|
|
73
87
|
}
|
|
74
88
|
}
|
|
89
|
+
async raw(sql) {
|
|
90
|
+
return this.database.raw(sql);
|
|
91
|
+
}
|
|
75
92
|
/**
|
|
76
93
|
* Extract the database to a CSV file.
|
|
77
94
|
*/
|
package/dist/cjs/app/table.js
CHANGED
|
@@ -17,9 +17,18 @@ class Table {
|
|
|
17
17
|
get query() {
|
|
18
18
|
return this.db(this.options.name);
|
|
19
19
|
}
|
|
20
|
+
async count(where) {
|
|
21
|
+
return this.query
|
|
22
|
+
.select(this.db.raw("count(*) as total"))
|
|
23
|
+
.whereRaw(where ?? "1=1")
|
|
24
|
+
.then((rows) => rows[0].total);
|
|
25
|
+
}
|
|
20
26
|
async hasColumn(name) {
|
|
21
27
|
return this.db.schema.hasColumn(this.options.name, name);
|
|
22
28
|
}
|
|
29
|
+
async getColumn(name) {
|
|
30
|
+
return this.db(this.options.name).columnInfo(name);
|
|
31
|
+
}
|
|
23
32
|
async getColumns() {
|
|
24
33
|
return this.db(this.options.name).columnInfo();
|
|
25
34
|
}
|
|
@@ -27,10 +36,7 @@ class Table {
|
|
|
27
36
|
return this.getColumns().then(Object.keys);
|
|
28
37
|
}
|
|
29
38
|
async isEmpty() {
|
|
30
|
-
return this.
|
|
31
|
-
.select()
|
|
32
|
-
.limit(1)
|
|
33
|
-
.then((rows) => rows.length === 0);
|
|
39
|
+
return this.count().then((count) => count === 0);
|
|
34
40
|
}
|
|
35
41
|
async make() {
|
|
36
42
|
if (!this.orm)
|
|
@@ -56,8 +62,10 @@ class Table {
|
|
|
56
62
|
}
|
|
57
63
|
catch (error) {
|
|
58
64
|
this.orm.config.logger?.error(error);
|
|
65
|
+
throw error;
|
|
59
66
|
}
|
|
60
|
-
await this.
|
|
67
|
+
if ((await this.count()) === 0)
|
|
68
|
+
await this.options.then?.bind(this)(this);
|
|
61
69
|
return this;
|
|
62
70
|
}
|
|
63
71
|
async migrate() {
|
package/dist/esm/app/orm.js
CHANGED
|
@@ -24,9 +24,23 @@ export class ORM {
|
|
|
24
24
|
pattern: /\.js$/,
|
|
25
25
|
});
|
|
26
26
|
}
|
|
27
|
+
get cachedTables() {
|
|
28
|
+
return [...this.handler.elements.values()];
|
|
29
|
+
}
|
|
30
|
+
get cachedTableNames() {
|
|
31
|
+
return this.cachedTables.map((table) => table.options.name);
|
|
32
|
+
}
|
|
33
|
+
hasCachedTable(name) {
|
|
34
|
+
return this.cachedTables.some((table) => table.options.name);
|
|
35
|
+
}
|
|
36
|
+
async hasTable(name) {
|
|
37
|
+
return this.database.schema.hasTable(name);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Handle the table files and create the tables in the database.
|
|
41
|
+
*/
|
|
27
42
|
async init() {
|
|
28
43
|
await this.handler.init();
|
|
29
|
-
const tables = [...this.handler.elements.values()];
|
|
30
44
|
try {
|
|
31
45
|
await this.database.raw("PRAGMA foreign_keys = ON;");
|
|
32
46
|
}
|
|
@@ -41,11 +55,14 @@ export class ORM {
|
|
|
41
55
|
});
|
|
42
56
|
migration.orm = this;
|
|
43
57
|
await migration.make();
|
|
44
|
-
for (const table of
|
|
58
|
+
for (const table of this.cachedTables.sort((a, b) => (b.options.priority ?? 0) - (a.options.priority ?? 0))) {
|
|
45
59
|
table.orm = this;
|
|
46
60
|
await table.make();
|
|
47
61
|
}
|
|
48
62
|
}
|
|
63
|
+
async raw(sql) {
|
|
64
|
+
return this.database.raw(sql);
|
|
65
|
+
}
|
|
49
66
|
/**
|
|
50
67
|
* Extract the database to a CSV file.
|
|
51
68
|
*/
|
package/dist/esm/app/table.js
CHANGED
|
@@ -13,9 +13,18 @@ export class Table {
|
|
|
13
13
|
get query() {
|
|
14
14
|
return this.db(this.options.name);
|
|
15
15
|
}
|
|
16
|
+
async count(where) {
|
|
17
|
+
return this.query
|
|
18
|
+
.select(this.db.raw("count(*) as total"))
|
|
19
|
+
.whereRaw(where ?? "1=1")
|
|
20
|
+
.then((rows) => rows[0].total);
|
|
21
|
+
}
|
|
16
22
|
async hasColumn(name) {
|
|
17
23
|
return this.db.schema.hasColumn(this.options.name, name);
|
|
18
24
|
}
|
|
25
|
+
async getColumn(name) {
|
|
26
|
+
return this.db(this.options.name).columnInfo(name);
|
|
27
|
+
}
|
|
19
28
|
async getColumns() {
|
|
20
29
|
return this.db(this.options.name).columnInfo();
|
|
21
30
|
}
|
|
@@ -23,10 +32,7 @@ export class Table {
|
|
|
23
32
|
return this.getColumns().then(Object.keys);
|
|
24
33
|
}
|
|
25
34
|
async isEmpty() {
|
|
26
|
-
return this.
|
|
27
|
-
.select()
|
|
28
|
-
.limit(1)
|
|
29
|
-
.then((rows) => rows.length === 0);
|
|
35
|
+
return this.count().then((count) => count === 0);
|
|
30
36
|
}
|
|
31
37
|
async make() {
|
|
32
38
|
if (!this.orm)
|
|
@@ -52,8 +58,10 @@ export class Table {
|
|
|
52
58
|
}
|
|
53
59
|
catch (error) {
|
|
54
60
|
this.orm.config.logger?.error(error);
|
|
61
|
+
throw error;
|
|
55
62
|
}
|
|
56
|
-
await this.
|
|
63
|
+
if ((await this.count()) === 0)
|
|
64
|
+
await this.options.then?.bind(this)(this);
|
|
57
65
|
return this;
|
|
58
66
|
}
|
|
59
67
|
async migrate() {
|
|
@@ -33,7 +33,15 @@ export declare class ORM {
|
|
|
33
33
|
database: Knex;
|
|
34
34
|
handler: Handler<Table<any>>;
|
|
35
35
|
constructor(config: ORMConfig);
|
|
36
|
+
get cachedTables(): Table<any>[];
|
|
37
|
+
get cachedTableNames(): string[];
|
|
38
|
+
hasCachedTable(name: string): boolean;
|
|
39
|
+
hasTable(name: string): Promise<boolean>;
|
|
40
|
+
/**
|
|
41
|
+
* Handle the table files and create the tables in the database.
|
|
42
|
+
*/
|
|
36
43
|
init(): Promise<void>;
|
|
44
|
+
raw(sql: Knex.Value): Promise<Knex.Raw>;
|
|
37
45
|
/**
|
|
38
46
|
* Extract the database to a CSV file.
|
|
39
47
|
*/
|
|
@@ -4,7 +4,7 @@ export interface MigrationData {
|
|
|
4
4
|
table: string;
|
|
5
5
|
version: number;
|
|
6
6
|
}
|
|
7
|
-
export interface TableOptions<Type extends
|
|
7
|
+
export interface TableOptions<Type extends object = object> {
|
|
8
8
|
name: string;
|
|
9
9
|
priority?: number;
|
|
10
10
|
migrations?: {
|
|
@@ -13,7 +13,7 @@ export interface TableOptions<Type extends {}> {
|
|
|
13
13
|
then?: (this: Table<Type>, table: Table<Type>) => unknown;
|
|
14
14
|
setup: (table: Knex.CreateTableBuilder) => void;
|
|
15
15
|
}
|
|
16
|
-
export declare class Table<Type extends
|
|
16
|
+
export declare class Table<Type extends object = object> {
|
|
17
17
|
readonly options: TableOptions<Type>;
|
|
18
18
|
orm?: ORM;
|
|
19
19
|
constructor(options: TableOptions<Type>);
|
|
@@ -27,9 +27,11 @@ export declare class Table<Type extends {}> {
|
|
|
27
27
|
_intersectProps: {};
|
|
28
28
|
_unionProps: never;
|
|
29
29
|
}[]>;
|
|
30
|
+
count(where?: string): Promise<number>;
|
|
30
31
|
hasColumn(name: keyof Type): Promise<boolean>;
|
|
31
|
-
|
|
32
|
-
|
|
32
|
+
getColumn(name: keyof Type): Promise<Knex.ColumnInfo>;
|
|
33
|
+
getColumns(): Promise<Record<keyof Type, Knex.ColumnInfo>>;
|
|
34
|
+
getColumnNames(): Promise<Array<keyof Type>>;
|
|
33
35
|
isEmpty(): Promise<boolean>;
|
|
34
36
|
make(): Promise<this>;
|
|
35
37
|
private migrate;
|
package/package.json
CHANGED
package/src/app/orm.ts
CHANGED
|
@@ -43,8 +43,8 @@ export interface ORMConfig {
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
export class ORM {
|
|
46
|
-
database: Knex
|
|
47
|
-
handler: Handler<Table<any>>
|
|
46
|
+
public database: Knex
|
|
47
|
+
public handler: Handler<Table<any>>
|
|
48
48
|
|
|
49
49
|
constructor(public config: ORMConfig) {
|
|
50
50
|
this.database = knex(
|
|
@@ -56,6 +56,7 @@ export class ORM {
|
|
|
56
56
|
},
|
|
57
57
|
}
|
|
58
58
|
)
|
|
59
|
+
|
|
59
60
|
this.handler = new Handler(config.location, {
|
|
60
61
|
loader: (filepath) =>
|
|
61
62
|
import(isCJS ? filepath : url.pathToFileURL(filepath).href).then(
|
|
@@ -65,11 +66,28 @@ export class ORM {
|
|
|
65
66
|
})
|
|
66
67
|
}
|
|
67
68
|
|
|
69
|
+
get cachedTables() {
|
|
70
|
+
return [...this.handler.elements.values()]
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
get cachedTableNames() {
|
|
74
|
+
return this.cachedTables.map((table) => table.options.name)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
hasCachedTable(name: string) {
|
|
78
|
+
return this.cachedTables.some((table) => table.options.name)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
async hasTable(name: string): Promise<boolean> {
|
|
82
|
+
return this.database.schema.hasTable(name)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Handle the table files and create the tables in the database.
|
|
87
|
+
*/
|
|
68
88
|
async init() {
|
|
69
89
|
await this.handler.init()
|
|
70
90
|
|
|
71
|
-
const tables = [...this.handler.elements.values()]
|
|
72
|
-
|
|
73
91
|
try {
|
|
74
92
|
await this.database.raw("PRAGMA foreign_keys = ON;")
|
|
75
93
|
} catch (error) {}
|
|
@@ -86,7 +104,7 @@ export class ORM {
|
|
|
86
104
|
migration.orm = this
|
|
87
105
|
await migration.make()
|
|
88
106
|
|
|
89
|
-
for (const table of
|
|
107
|
+
for (const table of this.cachedTables.sort(
|
|
90
108
|
(a, b) => (b.options.priority ?? 0) - (a.options.priority ?? 0)
|
|
91
109
|
)) {
|
|
92
110
|
table.orm = this
|
|
@@ -94,6 +112,10 @@ export class ORM {
|
|
|
94
112
|
}
|
|
95
113
|
}
|
|
96
114
|
|
|
115
|
+
async raw(sql: Knex.Value): Promise<Knex.Raw> {
|
|
116
|
+
return this.database.raw(sql)
|
|
117
|
+
}
|
|
118
|
+
|
|
97
119
|
/**
|
|
98
120
|
* Extract the database to a CSV file.
|
|
99
121
|
*/
|
package/src/app/table.ts
CHANGED
|
@@ -7,7 +7,7 @@ export interface MigrationData {
|
|
|
7
7
|
version: number
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
export interface TableOptions<Type extends
|
|
10
|
+
export interface TableOptions<Type extends object = object> {
|
|
11
11
|
name: string
|
|
12
12
|
priority?: number
|
|
13
13
|
migrations?: { [version: number]: (table: Knex.CreateTableBuilder) => void }
|
|
@@ -15,7 +15,7 @@ export interface TableOptions<Type extends {}> {
|
|
|
15
15
|
setup: (table: Knex.CreateTableBuilder) => void
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
export class Table<Type extends
|
|
18
|
+
export class Table<Type extends object = object> {
|
|
19
19
|
orm?: ORM
|
|
20
20
|
|
|
21
21
|
constructor(public readonly options: TableOptions<Type>) {}
|
|
@@ -29,23 +29,31 @@ export class Table<Type extends {}> {
|
|
|
29
29
|
return this.db<Type>(this.options.name)
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
async count(where?: string): Promise<number> {
|
|
33
|
+
return this.query
|
|
34
|
+
.select(this.db.raw("count(*) as total"))
|
|
35
|
+
.whereRaw(where ?? "1=1")
|
|
36
|
+
.then((rows) => (rows[0] as unknown as { total: number }).total)
|
|
37
|
+
}
|
|
38
|
+
|
|
32
39
|
async hasColumn(name: keyof Type): Promise<boolean> {
|
|
33
40
|
return this.db.schema.hasColumn(this.options.name, name as string)
|
|
34
41
|
}
|
|
35
42
|
|
|
36
|
-
async
|
|
43
|
+
async getColumn(name: keyof Type): Promise<Knex.ColumnInfo> {
|
|
44
|
+
return this.db(this.options.name).columnInfo(name)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async getColumns(): Promise<Record<keyof Type, Knex.ColumnInfo>> {
|
|
37
48
|
return this.db(this.options.name).columnInfo()
|
|
38
49
|
}
|
|
39
50
|
|
|
40
|
-
async getColumnNames() {
|
|
41
|
-
return this.getColumns().then(Object.keys)
|
|
51
|
+
async getColumnNames(): Promise<Array<keyof Type>> {
|
|
52
|
+
return this.getColumns().then(Object.keys) as Promise<Array<keyof Type>>
|
|
42
53
|
}
|
|
43
54
|
|
|
44
55
|
async isEmpty(): Promise<boolean> {
|
|
45
|
-
return this.
|
|
46
|
-
.select()
|
|
47
|
-
.limit(1)
|
|
48
|
-
.then((rows) => rows.length === 0)
|
|
56
|
+
return this.count().then((count) => count === 0)
|
|
49
57
|
}
|
|
50
58
|
|
|
51
59
|
async make(): Promise<this> {
|
|
@@ -91,9 +99,11 @@ export class Table<Type extends {}> {
|
|
|
91
99
|
}
|
|
92
100
|
} catch (error: any) {
|
|
93
101
|
this.orm.config.logger?.error(error)
|
|
102
|
+
|
|
103
|
+
throw error
|
|
94
104
|
}
|
|
95
105
|
|
|
96
|
-
await this.options.then?.bind(this)(this)
|
|
106
|
+
if ((await this.count()) === 0) await this.options.then?.bind(this)(this)
|
|
97
107
|
|
|
98
108
|
return this
|
|
99
109
|
}
|
package/tests/test.js
CHANGED
|
@@ -20,18 +20,23 @@ beforeAll(async () => {
|
|
|
20
20
|
|
|
21
21
|
describe("table management", () => {
|
|
22
22
|
test("tables created", async () => {
|
|
23
|
-
expect(await orm.
|
|
24
|
-
expect(await orm.
|
|
25
|
-
expect(await orm.
|
|
26
|
-
expect(await orm.
|
|
23
|
+
expect(await orm.hasTable("migration")).toBeTruthy()
|
|
24
|
+
expect(await orm.hasTable("a")).toBeTruthy()
|
|
25
|
+
expect(await orm.hasTable("b")).toBeTruthy()
|
|
26
|
+
expect(await orm.hasTable("c")).toBeTruthy()
|
|
27
|
+
|
|
28
|
+
expect(orm.hasCachedTable("migration")).toBeTruthy()
|
|
29
|
+
expect(orm.hasCachedTable("a")).toBeTruthy()
|
|
30
|
+
expect(orm.hasCachedTable("b")).toBeTruthy()
|
|
31
|
+
expect(orm.hasCachedTable("c")).toBeTruthy()
|
|
27
32
|
})
|
|
28
33
|
|
|
29
34
|
test("migrations ran", async () => {
|
|
30
|
-
expect(await
|
|
35
|
+
expect(await b.hasColumn("c_id")).toBeTruthy()
|
|
31
36
|
})
|
|
32
37
|
|
|
33
38
|
test("then ran", async () => {
|
|
34
|
-
const rows = await
|
|
39
|
+
const rows = await a.query.select()
|
|
35
40
|
|
|
36
41
|
expect(rows.length).toBe(1)
|
|
37
42
|
})
|
|
@@ -103,6 +108,24 @@ describe("database migration", () => {
|
|
|
103
108
|
})
|
|
104
109
|
})
|
|
105
110
|
|
|
111
|
+
describe("table getters", () => {
|
|
112
|
+
test("table info", async () => {
|
|
113
|
+
expect(await a.getColumnNames()).toContain("id")
|
|
114
|
+
expect(await a.getColumnNames()).toContain("b_id")
|
|
115
|
+
|
|
116
|
+
expect(await b.getColumnNames()).toContain("id")
|
|
117
|
+
expect(await b.getColumnNames()).toContain("c_id")
|
|
118
|
+
|
|
119
|
+
expect(await c.getColumnNames()).toContain("id")
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
test("table names", async () => {
|
|
123
|
+
expect(orm.cachedTableNames).toContain("a")
|
|
124
|
+
expect(orm.cachedTableNames).toContain("b")
|
|
125
|
+
expect(orm.cachedTableNames).toContain("c")
|
|
126
|
+
})
|
|
127
|
+
})
|
|
128
|
+
|
|
106
129
|
afterAll(async () => {
|
|
107
130
|
await orm.database.destroy()
|
|
108
131
|
fs.unlinkSync("a.csv")
|