@uql/core 3.1.0 → 3.1.2
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/CHANGELOG.md +134 -176
- package/README.md +413 -0
- package/package.json +31 -26
- package/dist/package.json +0 -131
- package/src/@types/index.d.ts +0 -1
- package/src/@types/jest.d.ts +0 -6
- package/src/browser/http/bus.spec.ts +0 -22
- package/src/browser/http/bus.ts +0 -17
- package/src/browser/http/http.spec.ts +0 -70
- package/src/browser/http/http.ts +0 -55
- package/src/browser/http/index.ts +0 -2
- package/src/browser/index.ts +0 -4
- package/src/browser/options.spec.ts +0 -37
- package/src/browser/options.ts +0 -18
- package/src/browser/querier/genericClientRepository.spec.ts +0 -105
- package/src/browser/querier/genericClientRepository.ts +0 -49
- package/src/browser/querier/httpQuerier.ts +0 -82
- package/src/browser/querier/index.ts +0 -3
- package/src/browser/querier/querier.util.spec.ts +0 -35
- package/src/browser/querier/querier.util.ts +0 -18
- package/src/browser/type/clientQuerier.ts +0 -45
- package/src/browser/type/clientQuerierPool.ts +0 -5
- package/src/browser/type/clientRepository.ts +0 -22
- package/src/browser/type/index.ts +0 -4
- package/src/browser/type/request.ts +0 -25
- package/src/dialect/abstractDialect.ts +0 -28
- package/src/dialect/abstractSqlDialect-spec.ts +0 -1309
- package/src/dialect/abstractSqlDialect.ts +0 -805
- package/src/dialect/index.ts +0 -3
- package/src/dialect/namingStrategy.spec.ts +0 -52
- package/src/dialect/queryContext.ts +0 -69
- package/src/entity/decorator/definition.spec.ts +0 -736
- package/src/entity/decorator/definition.ts +0 -265
- package/src/entity/decorator/entity.ts +0 -8
- package/src/entity/decorator/field.ts +0 -9
- package/src/entity/decorator/id.ts +0 -9
- package/src/entity/decorator/index.ts +0 -5
- package/src/entity/decorator/relation.spec.ts +0 -41
- package/src/entity/decorator/relation.ts +0 -34
- package/src/entity/index.ts +0 -1
- package/src/express/@types/express.d.ts +0 -8
- package/src/express/@types/index.d.ts +0 -1
- package/src/express/index.ts +0 -2
- package/src/express/querierMiddleware.ts +0 -217
- package/src/express/query.util.spec.ts +0 -40
- package/src/express/query.util.ts +0 -21
- package/src/index.ts +0 -9
- package/src/maria/index.ts +0 -3
- package/src/maria/mariaDialect.spec.ts +0 -207
- package/src/maria/mariaDialect.ts +0 -42
- package/src/maria/mariaQuerierPool.test.ts +0 -23
- package/src/maria/mariadbQuerier.test.ts +0 -23
- package/src/maria/mariadbQuerier.ts +0 -45
- package/src/maria/mariadbQuerierPool.ts +0 -21
- package/src/migrate/cli.ts +0 -301
- package/src/migrate/generator/index.ts +0 -4
- package/src/migrate/generator/mongoSchemaGenerator.spec.ts +0 -112
- package/src/migrate/generator/mongoSchemaGenerator.ts +0 -115
- package/src/migrate/generator/mysqlSchemaGenerator.spec.ts +0 -34
- package/src/migrate/generator/mysqlSchemaGenerator.ts +0 -92
- package/src/migrate/generator/postgresSchemaGenerator.spec.ts +0 -44
- package/src/migrate/generator/postgresSchemaGenerator.ts +0 -127
- package/src/migrate/generator/sqliteSchemaGenerator.spec.ts +0 -33
- package/src/migrate/generator/sqliteSchemaGenerator.ts +0 -81
- package/src/migrate/index.ts +0 -41
- package/src/migrate/introspection/index.ts +0 -4
- package/src/migrate/introspection/mongoIntrospector.spec.ts +0 -75
- package/src/migrate/introspection/mongoIntrospector.ts +0 -47
- package/src/migrate/introspection/mysqlIntrospector.spec.ts +0 -113
- package/src/migrate/introspection/mysqlIntrospector.ts +0 -278
- package/src/migrate/introspection/postgresIntrospector.spec.ts +0 -112
- package/src/migrate/introspection/postgresIntrospector.ts +0 -329
- package/src/migrate/introspection/sqliteIntrospector.spec.ts +0 -112
- package/src/migrate/introspection/sqliteIntrospector.ts +0 -296
- package/src/migrate/migrator-mongo.test.ts +0 -54
- package/src/migrate/migrator.spec.ts +0 -255
- package/src/migrate/migrator.test.ts +0 -94
- package/src/migrate/migrator.ts +0 -719
- package/src/migrate/namingStrategy.spec.ts +0 -22
- package/src/migrate/schemaGenerator-advanced.spec.ts +0 -138
- package/src/migrate/schemaGenerator.spec.ts +0 -190
- package/src/migrate/schemaGenerator.ts +0 -478
- package/src/migrate/storage/databaseStorage.spec.ts +0 -69
- package/src/migrate/storage/databaseStorage.ts +0 -100
- package/src/migrate/storage/index.ts +0 -2
- package/src/migrate/storage/jsonStorage.ts +0 -58
- package/src/migrate/type.ts +0 -1
- package/src/mongo/index.ts +0 -3
- package/src/mongo/mongoDialect.spec.ts +0 -251
- package/src/mongo/mongoDialect.ts +0 -238
- package/src/mongo/mongodbQuerier.test.ts +0 -45
- package/src/mongo/mongodbQuerier.ts +0 -256
- package/src/mongo/mongodbQuerierPool.test.ts +0 -25
- package/src/mongo/mongodbQuerierPool.ts +0 -24
- package/src/mysql/index.ts +0 -3
- package/src/mysql/mysql2Querier.test.ts +0 -20
- package/src/mysql/mysql2Querier.ts +0 -49
- package/src/mysql/mysql2QuerierPool.test.ts +0 -20
- package/src/mysql/mysql2QuerierPool.ts +0 -21
- package/src/mysql/mysqlDialect.spec.ts +0 -20
- package/src/mysql/mysqlDialect.ts +0 -16
- package/src/namingStrategy/defaultNamingStrategy.ts +0 -18
- package/src/namingStrategy/index.spec.ts +0 -36
- package/src/namingStrategy/index.ts +0 -2
- package/src/namingStrategy/snakeCaseNamingStrategy.ts +0 -15
- package/src/options.spec.ts +0 -41
- package/src/options.ts +0 -18
- package/src/postgres/index.ts +0 -3
- package/src/postgres/manual-types.d.ts +0 -4
- package/src/postgres/pgQuerier.test.ts +0 -25
- package/src/postgres/pgQuerier.ts +0 -45
- package/src/postgres/pgQuerierPool.test.ts +0 -28
- package/src/postgres/pgQuerierPool.ts +0 -21
- package/src/postgres/postgresDialect.spec.ts +0 -428
- package/src/postgres/postgresDialect.ts +0 -144
- package/src/querier/abstractQuerier-test.ts +0 -584
- package/src/querier/abstractQuerier.ts +0 -353
- package/src/querier/abstractQuerierPool-test.ts +0 -20
- package/src/querier/abstractQuerierPool.ts +0 -18
- package/src/querier/abstractSqlQuerier-spec.ts +0 -979
- package/src/querier/abstractSqlQuerier-test.ts +0 -21
- package/src/querier/abstractSqlQuerier.ts +0 -138
- package/src/querier/decorator/index.ts +0 -3
- package/src/querier/decorator/injectQuerier.spec.ts +0 -74
- package/src/querier/decorator/injectQuerier.ts +0 -45
- package/src/querier/decorator/serialized.spec.ts +0 -98
- package/src/querier/decorator/serialized.ts +0 -13
- package/src/querier/decorator/transactional.spec.ts +0 -240
- package/src/querier/decorator/transactional.ts +0 -56
- package/src/querier/index.ts +0 -4
- package/src/repository/genericRepository.spec.ts +0 -111
- package/src/repository/genericRepository.ts +0 -74
- package/src/repository/index.ts +0 -1
- package/src/sqlite/index.ts +0 -3
- package/src/sqlite/manual-types.d.ts +0 -4
- package/src/sqlite/sqliteDialect.spec.ts +0 -155
- package/src/sqlite/sqliteDialect.ts +0 -76
- package/src/sqlite/sqliteQuerier.spec.ts +0 -36
- package/src/sqlite/sqliteQuerier.test.ts +0 -21
- package/src/sqlite/sqliteQuerier.ts +0 -37
- package/src/sqlite/sqliteQuerierPool.test.ts +0 -12
- package/src/sqlite/sqliteQuerierPool.ts +0 -38
- package/src/test/entityMock.ts +0 -375
- package/src/test/index.ts +0 -3
- package/src/test/it.util.ts +0 -69
- package/src/test/spec.util.ts +0 -57
- package/src/type/entity.ts +0 -218
- package/src/type/index.ts +0 -9
- package/src/type/migration.ts +0 -241
- package/src/type/namingStrategy.ts +0 -17
- package/src/type/querier.ts +0 -143
- package/src/type/querierPool.ts +0 -26
- package/src/type/query.ts +0 -506
- package/src/type/repository.ts +0 -142
- package/src/type/universalQuerier.ts +0 -133
- package/src/type/utility.ts +0 -21
- package/src/util/dialect.util-extra.spec.ts +0 -96
- package/src/util/dialect.util.spec.ts +0 -23
- package/src/util/dialect.util.ts +0 -134
- package/src/util/index.ts +0 -5
- package/src/util/object.util.spec.ts +0 -29
- package/src/util/object.util.ts +0 -27
- package/src/util/raw.ts +0 -11
- package/src/util/sql.util-extra.spec.ts +0 -17
- package/src/util/sql.util.spec.ts +0 -208
- package/src/util/sql.util.ts +0 -104
- package/src/util/string.util.spec.ts +0 -46
- package/src/util/string.util.ts +0 -35
- package/tsconfig.build.json +0 -5
- package/tsconfig.json +0 -8
|
@@ -1,207 +0,0 @@
|
|
|
1
|
-
import { expect } from 'bun:test';
|
|
2
|
-
import { AbstractSqlDialectSpec } from '../dialect/abstractSqlDialect-spec.js';
|
|
3
|
-
import { InventoryAdjustment, ItemTag, TaxCategory, User } from '../test/index.js';
|
|
4
|
-
import { createSpec } from '../test/spec.util.js';
|
|
5
|
-
import type { FieldKey } from '../type/index.js';
|
|
6
|
-
import { MariaDialect } from './mariaDialect.js';
|
|
7
|
-
|
|
8
|
-
export class MariaDialectSpec extends AbstractSqlDialectSpec {
|
|
9
|
-
constructor() {
|
|
10
|
-
super(new MariaDialect());
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
shouldHandleDate() {
|
|
14
|
-
const dialect = new MariaDialect();
|
|
15
|
-
const values: unknown[] = [];
|
|
16
|
-
expect(dialect.addValue(values, new Date())).toBe('?');
|
|
17
|
-
expect(values).toHaveLength(1);
|
|
18
|
-
expect(values[0]).toBeInstanceOf(Date);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
shouldUpsertWithNoUpdateFields() {
|
|
22
|
-
const { sql } = this.exec((ctx) => this.dialect.upsert(ctx, ItemTag, { id: true }, { id: 123 }));
|
|
23
|
-
expect(sql).toContain('INSERT IGNORE');
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
override shouldInsertMany() {
|
|
27
|
-
const { sql, values } = this.exec((ctx) =>
|
|
28
|
-
this.dialect.insert(ctx, User, [
|
|
29
|
-
{
|
|
30
|
-
name: 'Some name 1',
|
|
31
|
-
email: 'someemail1@example.com',
|
|
32
|
-
createdAt: 123,
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
name: 'Some name 2',
|
|
36
|
-
email: 'someemail2@example.com',
|
|
37
|
-
createdAt: 456,
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
name: 'Some name 3',
|
|
41
|
-
email: 'someemail3@example.com',
|
|
42
|
-
createdAt: 789,
|
|
43
|
-
},
|
|
44
|
-
]),
|
|
45
|
-
);
|
|
46
|
-
expect(sql).toBe(
|
|
47
|
-
'INSERT INTO `User` (`name`, `email`, `createdAt`) VALUES (?, ?, ?), (?, ?, ?), (?, ?, ?) RETURNING `id` `id`',
|
|
48
|
-
);
|
|
49
|
-
expect(values).toEqual([
|
|
50
|
-
'Some name 1',
|
|
51
|
-
'someemail1@example.com',
|
|
52
|
-
123,
|
|
53
|
-
'Some name 2',
|
|
54
|
-
'someemail2@example.com',
|
|
55
|
-
456,
|
|
56
|
-
'Some name 3',
|
|
57
|
-
'someemail3@example.com',
|
|
58
|
-
789,
|
|
59
|
-
]);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
override shouldBeSecure() {
|
|
63
|
-
let res = this.exec((ctx) =>
|
|
64
|
-
this.dialect.find(ctx, User, {
|
|
65
|
-
$select: ['id', 'something' as FieldKey<User>],
|
|
66
|
-
$where: {
|
|
67
|
-
id: 1,
|
|
68
|
-
something: 1,
|
|
69
|
-
} as any,
|
|
70
|
-
$sort: {
|
|
71
|
-
id: 1,
|
|
72
|
-
something: 1,
|
|
73
|
-
} as any,
|
|
74
|
-
}),
|
|
75
|
-
);
|
|
76
|
-
expect(res.sql).toBe('SELECT `id` FROM `User` WHERE `id` = ? AND `something` = ? ORDER BY `id`, `something`');
|
|
77
|
-
expect(res.values).toEqual([1, 1]);
|
|
78
|
-
|
|
79
|
-
res = this.exec((ctx) =>
|
|
80
|
-
this.dialect.insert(ctx, User, {
|
|
81
|
-
name: 'Some Name',
|
|
82
|
-
something: 'anything',
|
|
83
|
-
createdAt: 1,
|
|
84
|
-
} as any),
|
|
85
|
-
);
|
|
86
|
-
expect(res.sql).toBe('INSERT INTO `User` (`name`, `createdAt`) VALUES (?, ?) RETURNING `id` `id`');
|
|
87
|
-
expect(res.values).toEqual(['Some Name', 1]);
|
|
88
|
-
|
|
89
|
-
res = this.exec((ctx) =>
|
|
90
|
-
this.dialect.update(
|
|
91
|
-
ctx,
|
|
92
|
-
User,
|
|
93
|
-
{
|
|
94
|
-
$where: { something: 'anything' },
|
|
95
|
-
},
|
|
96
|
-
{
|
|
97
|
-
name: 'Some Name',
|
|
98
|
-
something: 'anything',
|
|
99
|
-
updatedAt: 1,
|
|
100
|
-
} as any,
|
|
101
|
-
),
|
|
102
|
-
);
|
|
103
|
-
expect(res.sql).toBe('UPDATE `User` SET `name` = ?, `updatedAt` = ? WHERE `something` = ?');
|
|
104
|
-
expect(res.values).toEqual(['Some Name', 1, 'anything']);
|
|
105
|
-
|
|
106
|
-
res = this.exec((ctx) =>
|
|
107
|
-
this.dialect.delete(ctx, User, {
|
|
108
|
-
$where: { something: 'anything' } as any,
|
|
109
|
-
}),
|
|
110
|
-
);
|
|
111
|
-
expect(res.sql).toBe('DELETE FROM `User` WHERE `something` = ?');
|
|
112
|
-
expect(res.values).toEqual(['anything']);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
override shouldUpsert() {
|
|
116
|
-
const { sql, values } = this.exec((ctx) =>
|
|
117
|
-
this.dialect.upsert(
|
|
118
|
-
ctx,
|
|
119
|
-
User,
|
|
120
|
-
{ email: true },
|
|
121
|
-
{
|
|
122
|
-
name: 'Some Name',
|
|
123
|
-
email: 'someemail@example.com',
|
|
124
|
-
createdAt: 123,
|
|
125
|
-
},
|
|
126
|
-
),
|
|
127
|
-
);
|
|
128
|
-
expect(sql).toBe(
|
|
129
|
-
'INSERT INTO `User` (`name`, `email`, `createdAt`, `updatedAt`) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE `name` = VALUES(`name`), `createdAt` = VALUES(`createdAt`), `updatedAt` = VALUES(`updatedAt`) RETURNING `id` `id`',
|
|
130
|
-
);
|
|
131
|
-
expect(values).toEqual(['Some Name', 'someemail@example.com', 123, expect.any(Number)]);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
override shouldInsertManyWithSpecifiedIdsAndOnInsertIdAsDefault() {
|
|
135
|
-
const { sql, values } = this.exec((ctx) =>
|
|
136
|
-
this.dialect.insert(ctx, TaxCategory, [
|
|
137
|
-
{
|
|
138
|
-
name: 'Some Name A',
|
|
139
|
-
},
|
|
140
|
-
{
|
|
141
|
-
pk: '50',
|
|
142
|
-
name: 'Some Name B',
|
|
143
|
-
},
|
|
144
|
-
{
|
|
145
|
-
name: 'Some Name C',
|
|
146
|
-
},
|
|
147
|
-
{
|
|
148
|
-
pk: '70',
|
|
149
|
-
name: 'Some Name D',
|
|
150
|
-
},
|
|
151
|
-
]),
|
|
152
|
-
);
|
|
153
|
-
expect(sql).toMatch(
|
|
154
|
-
/^INSERT INTO `TaxCategory` \(`name`, `createdAt`, `pk`\) VALUES \(\?, \?, \?\), \(\?, \?, \?\), \(\?, \?, \?\), \(\?, \?, \?\) RETURNING `pk` `id`$/,
|
|
155
|
-
);
|
|
156
|
-
expect(values).toEqual([
|
|
157
|
-
'Some Name A',
|
|
158
|
-
expect.any(Number),
|
|
159
|
-
expect.any(String),
|
|
160
|
-
'Some Name B',
|
|
161
|
-
expect.any(Number),
|
|
162
|
-
'50',
|
|
163
|
-
'Some Name C',
|
|
164
|
-
expect.any(Number),
|
|
165
|
-
expect.any(String),
|
|
166
|
-
'Some Name D',
|
|
167
|
-
expect.any(Number),
|
|
168
|
-
'70',
|
|
169
|
-
]);
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
override shouldInsertOne() {
|
|
173
|
-
let res = this.exec((ctx) =>
|
|
174
|
-
this.dialect.insert(ctx, User, {
|
|
175
|
-
name: 'Some Name',
|
|
176
|
-
email: 'someemail@example.com',
|
|
177
|
-
createdAt: 123,
|
|
178
|
-
}),
|
|
179
|
-
);
|
|
180
|
-
expect(res.sql).toBe('INSERT INTO `User` (`name`, `email`, `createdAt`) VALUES (?, ?, ?) RETURNING `id` `id`');
|
|
181
|
-
expect(res.values).toEqual(['Some Name', 'someemail@example.com', 123]);
|
|
182
|
-
|
|
183
|
-
res = this.exec((ctx) =>
|
|
184
|
-
this.dialect.insert(ctx, InventoryAdjustment, {
|
|
185
|
-
date: new Date(2021, 11, 31, 23, 59, 59, 999),
|
|
186
|
-
createdAt: 123,
|
|
187
|
-
}),
|
|
188
|
-
);
|
|
189
|
-
expect(res.sql).toBe('INSERT INTO `InventoryAdjustment` (`date`, `createdAt`) VALUES (?, ?) RETURNING `id` `id`');
|
|
190
|
-
expect(res.values).toEqual([new Date(2021, 11, 31, 23, 59, 59, 999), 123]);
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
override shouldInsertWithOnInsertId() {
|
|
194
|
-
const { sql, values } = this.exec((ctx) =>
|
|
195
|
-
this.dialect.insert(ctx, TaxCategory, {
|
|
196
|
-
name: 'Some Name',
|
|
197
|
-
createdAt: 123,
|
|
198
|
-
}),
|
|
199
|
-
);
|
|
200
|
-
expect(sql).toMatch(
|
|
201
|
-
/^INSERT INTO `TaxCategory` \(`name`, `createdAt`, `pk`\) VALUES \(\?, \?, \?\) RETURNING `pk` `id`$/,
|
|
202
|
-
);
|
|
203
|
-
expect(values).toEqual(['Some Name', 123, expect.any(String)]);
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
createSpec(new MariaDialectSpec());
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import SqlString from 'sqlstring';
|
|
2
|
-
import { AbstractSqlDialect } from '../dialect/index.js';
|
|
3
|
-
import { getMeta } from '../entity/index.js';
|
|
4
|
-
import type { QueryConflictPaths, QueryContext, QueryOptions, Type } from '../type/index.js';
|
|
5
|
-
|
|
6
|
-
export class MariaDialect extends AbstractSqlDialect {
|
|
7
|
-
override addValue(values: unknown[], value: unknown): string {
|
|
8
|
-
if (value instanceof Date) {
|
|
9
|
-
values.push(value);
|
|
10
|
-
return '?';
|
|
11
|
-
}
|
|
12
|
-
return super.addValue(values, value);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
override insert<E>(ctx: QueryContext, entity: Type<E>, payload: E | E[], opts?: QueryOptions): void {
|
|
16
|
-
super.insert(ctx, entity, payload, opts);
|
|
17
|
-
ctx.append(' ' + this.returningId(entity));
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
override upsert<E>(ctx: QueryContext, entity: Type<E>, conflictPaths: QueryConflictPaths<E>, payload: E): void {
|
|
21
|
-
const meta = getMeta(entity);
|
|
22
|
-
const update = this.getUpsertUpdateAssignments(ctx, meta, conflictPaths, payload, (name) => `VALUES(${name})`);
|
|
23
|
-
const returning = this.returningId(entity);
|
|
24
|
-
|
|
25
|
-
if (update) {
|
|
26
|
-
super.insert(ctx, entity, payload);
|
|
27
|
-
ctx.append(` ON DUPLICATE KEY UPDATE ${update} ${returning}`);
|
|
28
|
-
} else {
|
|
29
|
-
const insertCtx = this.createContext();
|
|
30
|
-
super.insert(insertCtx, entity, payload);
|
|
31
|
-
ctx.append(insertCtx.sql.replace(/^INSERT/, 'INSERT IGNORE'));
|
|
32
|
-
ctx.append(' ' + returning);
|
|
33
|
-
insertCtx.values.forEach((val) => {
|
|
34
|
-
ctx.pushValue(val);
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
override escape(value: unknown): string {
|
|
40
|
-
return SqlString.escape(value);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { AbstractQuerierPoolIt } from '../querier/abstractQuerierPool-test.js';
|
|
2
|
-
import { createSpec } from '../test/index.js';
|
|
3
|
-
import type { MariadbQuerier } from './mariadbQuerier.js';
|
|
4
|
-
import { MariadbQuerierPool } from './mariadbQuerierPool.js';
|
|
5
|
-
|
|
6
|
-
export class MariadbQuerierPoolIt extends AbstractQuerierPoolIt<MariadbQuerier> {
|
|
7
|
-
constructor() {
|
|
8
|
-
super(
|
|
9
|
-
new MariadbQuerierPool({
|
|
10
|
-
host: '0.0.0.0',
|
|
11
|
-
port: 3326,
|
|
12
|
-
user: 'test',
|
|
13
|
-
password: 'test',
|
|
14
|
-
database: 'test',
|
|
15
|
-
connectionLimit: 5,
|
|
16
|
-
trace: true,
|
|
17
|
-
bigIntAsNumber: true,
|
|
18
|
-
}),
|
|
19
|
-
);
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
createSpec(new MariadbQuerierPoolIt());
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { AbstractSqlQuerierIt } from '../querier/abstractSqlQuerier-test.js';
|
|
2
|
-
import { createSpec } from '../test/index.js';
|
|
3
|
-
import { MariadbQuerierPool } from './mariadbQuerierPool.js';
|
|
4
|
-
|
|
5
|
-
export class MariadbQuerierIt extends AbstractSqlQuerierIt {
|
|
6
|
-
constructor() {
|
|
7
|
-
super(
|
|
8
|
-
new MariadbQuerierPool({
|
|
9
|
-
host: '0.0.0.0',
|
|
10
|
-
port: 3326,
|
|
11
|
-
user: 'test',
|
|
12
|
-
password: 'test',
|
|
13
|
-
database: 'test',
|
|
14
|
-
connectionLimit: 5,
|
|
15
|
-
trace: true,
|
|
16
|
-
bigIntAsNumber: true,
|
|
17
|
-
}),
|
|
18
|
-
'INT AUTO_INCREMENT PRIMARY KEY',
|
|
19
|
-
);
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
createSpec(new MariadbQuerierIt());
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import type { PoolConnection } from 'mariadb';
|
|
2
|
-
import { AbstractSqlQuerier } from '../querier/index.js';
|
|
3
|
-
import type { ExtraOptions, QueryUpdateResult } from '../type/index.js';
|
|
4
|
-
import { MariaDialect } from './mariaDialect.js';
|
|
5
|
-
|
|
6
|
-
export class MariadbQuerier extends AbstractSqlQuerier {
|
|
7
|
-
conn: PoolConnection;
|
|
8
|
-
|
|
9
|
-
constructor(
|
|
10
|
-
readonly connect: () => Promise<PoolConnection>,
|
|
11
|
-
readonly extra?: ExtraOptions,
|
|
12
|
-
) {
|
|
13
|
-
super(new MariaDialect(extra?.namingStrategy));
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
override async internalAll<T>(query: string, values?: unknown[]) {
|
|
17
|
-
this.extra?.logger?.(query, values);
|
|
18
|
-
await this.lazyConnect();
|
|
19
|
-
const res: T[] = await this.conn.query(query, values);
|
|
20
|
-
return res.slice(0, res.length);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
override async internalRun(query: string, values?: unknown[]) {
|
|
24
|
-
this.extra?.logger?.(query, values);
|
|
25
|
-
await this.lazyConnect();
|
|
26
|
-
const res = await this.conn.query(query, values);
|
|
27
|
-
const ids = res.length ? res.map((r: any) => r.id) : [];
|
|
28
|
-
return { changes: res.affectedRows, ids, firstId: ids[0] } satisfies QueryUpdateResult;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
async lazyConnect() {
|
|
32
|
-
this.conn ??= await this.connect();
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
override async internalRelease() {
|
|
36
|
-
if (this.hasOpenTransaction) {
|
|
37
|
-
throw TypeError('pending transaction');
|
|
38
|
-
}
|
|
39
|
-
if (!this.conn) {
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
await this.conn.release();
|
|
43
|
-
this.conn = undefined;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { createPool, type Pool, type PoolConfig } from 'mariadb';
|
|
2
|
-
import { AbstractQuerierPool } from '../querier/index.js';
|
|
3
|
-
import type { ExtraOptions } from '../type/index.js';
|
|
4
|
-
import { MariadbQuerier } from './mariadbQuerier.js';
|
|
5
|
-
|
|
6
|
-
export class MariadbQuerierPool extends AbstractQuerierPool<MariadbQuerier> {
|
|
7
|
-
readonly pool: Pool;
|
|
8
|
-
|
|
9
|
-
constructor(opts: PoolConfig, extra?: ExtraOptions) {
|
|
10
|
-
super('mariadb', extra);
|
|
11
|
-
this.pool = createPool(opts);
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
async getQuerier() {
|
|
15
|
-
return new MariadbQuerier(() => this.pool.getConnection(), this.extra);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
async end() {
|
|
19
|
-
await this.pool.end();
|
|
20
|
-
}
|
|
21
|
-
}
|
package/src/migrate/cli.ts
DELETED
|
@@ -1,301 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { resolve } from 'node:path';
|
|
4
|
-
import { pathToFileURL } from 'node:url';
|
|
5
|
-
import type { Dialect, MigratorOptions, NamingStrategy, QuerierPool } from '../type/index.js';
|
|
6
|
-
import { MongoSchemaGenerator } from './generator/mongoSchemaGenerator.js';
|
|
7
|
-
import { MysqlSchemaGenerator } from './generator/mysqlSchemaGenerator.js';
|
|
8
|
-
import { PostgresSchemaGenerator } from './generator/postgresSchemaGenerator.js';
|
|
9
|
-
import { SqliteSchemaGenerator } from './generator/sqliteSchemaGenerator.js';
|
|
10
|
-
import { Migrator } from './migrator.js';
|
|
11
|
-
|
|
12
|
-
interface CliConfig {
|
|
13
|
-
querierPool?: QuerierPool;
|
|
14
|
-
migrationsPath?: string;
|
|
15
|
-
tableName?: string;
|
|
16
|
-
dialect?: Dialect;
|
|
17
|
-
entities?: unknown[];
|
|
18
|
-
namingStrategy?: NamingStrategy;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
async function loadConfig(): Promise<CliConfig> {
|
|
22
|
-
const configPaths = ['uql.config.ts', 'uql.config.js', 'uql.config.mjs', '.uqlrc.ts', '.uqlrc.js'];
|
|
23
|
-
|
|
24
|
-
for (const configPath of configPaths) {
|
|
25
|
-
try {
|
|
26
|
-
const fullPath = resolve(process.cwd(), configPath);
|
|
27
|
-
const fileUrl = pathToFileURL(fullPath).href;
|
|
28
|
-
const module = await import(fileUrl);
|
|
29
|
-
return module.default ?? module;
|
|
30
|
-
} catch {
|
|
31
|
-
// Config file not found, try next one
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
throw new Error(
|
|
36
|
-
'Could not find uql configuration file. ' + 'Create a uql.config.ts or uql.config.js file in your project root.',
|
|
37
|
-
);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function getSchemaGenerator(dialect: Dialect, namingStrategy?: NamingStrategy) {
|
|
41
|
-
switch (dialect) {
|
|
42
|
-
case 'postgres':
|
|
43
|
-
return new PostgresSchemaGenerator(namingStrategy);
|
|
44
|
-
case 'mysql':
|
|
45
|
-
case 'mariadb':
|
|
46
|
-
return new MysqlSchemaGenerator(namingStrategy);
|
|
47
|
-
case 'sqlite':
|
|
48
|
-
return new SqliteSchemaGenerator(namingStrategy);
|
|
49
|
-
case 'mongodb':
|
|
50
|
-
return new MongoSchemaGenerator(namingStrategy);
|
|
51
|
-
default:
|
|
52
|
-
throw new TypeError(`Unknown dialect: ${dialect}`);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
async function main() {
|
|
57
|
-
const args = process.argv.slice(2);
|
|
58
|
-
const command = args[0];
|
|
59
|
-
|
|
60
|
-
if (!command || command === '--help' || command === '-h') {
|
|
61
|
-
printHelp();
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
try {
|
|
66
|
-
const config = await loadConfig();
|
|
67
|
-
|
|
68
|
-
if (!config.querierPool) {
|
|
69
|
-
throw new Error('querierPool is required in configuration');
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
const dialect = config.dialect ?? 'postgres';
|
|
73
|
-
|
|
74
|
-
const options: MigratorOptions & { dialect: Dialect } = {
|
|
75
|
-
migrationsPath: config.migrationsPath ?? './migrations',
|
|
76
|
-
tableName: config.tableName,
|
|
77
|
-
logger: console.log,
|
|
78
|
-
entities: config.entities as MigratorOptions['entities'],
|
|
79
|
-
dialect,
|
|
80
|
-
namingStrategy: config.namingStrategy,
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
const migrator = new Migrator(config.querierPool, options);
|
|
84
|
-
migrator.setSchemaGenerator(getSchemaGenerator(dialect, config.namingStrategy));
|
|
85
|
-
|
|
86
|
-
switch (command) {
|
|
87
|
-
case 'up':
|
|
88
|
-
await runUp(migrator, args.slice(1));
|
|
89
|
-
break;
|
|
90
|
-
case 'down':
|
|
91
|
-
await runDown(migrator, args.slice(1));
|
|
92
|
-
break;
|
|
93
|
-
case 'status':
|
|
94
|
-
await runStatus(migrator);
|
|
95
|
-
break;
|
|
96
|
-
case 'generate':
|
|
97
|
-
case 'create':
|
|
98
|
-
await runGenerate(migrator, args.slice(1));
|
|
99
|
-
break;
|
|
100
|
-
case 'generate:entities':
|
|
101
|
-
case 'generate-entities':
|
|
102
|
-
await runGenerateFromEntities(migrator, args.slice(1));
|
|
103
|
-
break;
|
|
104
|
-
case 'sync':
|
|
105
|
-
await runSync(migrator, args.slice(1));
|
|
106
|
-
break;
|
|
107
|
-
case 'pending':
|
|
108
|
-
await runPending(migrator);
|
|
109
|
-
break;
|
|
110
|
-
default:
|
|
111
|
-
console.error(`Unknown command: ${command}`);
|
|
112
|
-
printHelp();
|
|
113
|
-
process.exit(1);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// Close the connection pool
|
|
117
|
-
const pool = config.querierPool as { end?: () => Promise<void> };
|
|
118
|
-
if (pool.end) {
|
|
119
|
-
await pool.end();
|
|
120
|
-
}
|
|
121
|
-
} catch (error) {
|
|
122
|
-
console.error('Error:', (error as Error).message);
|
|
123
|
-
process.exit(1);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
async function runUp(migrator: Migrator, args: string[]) {
|
|
128
|
-
const options: { to?: string; step?: number } = {};
|
|
129
|
-
|
|
130
|
-
for (let i = 0; i < args.length; i++) {
|
|
131
|
-
if (args[i] === '--to' && args[i + 1]) {
|
|
132
|
-
options.to = args[++i];
|
|
133
|
-
} else if (args[i] === '--step' && args[i + 1]) {
|
|
134
|
-
options.step = Number.parseInt(args[++i], 10);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
const results = await migrator.up(options);
|
|
139
|
-
|
|
140
|
-
if (results.length === 0) {
|
|
141
|
-
console.log('No pending migrations.');
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
const successful = results.filter((r: any) => r.success).length;
|
|
146
|
-
const failed = results.filter((r: any) => !r.success).length;
|
|
147
|
-
|
|
148
|
-
console.log(`\nMigrations complete: ${successful} successful, ${failed} failed`);
|
|
149
|
-
|
|
150
|
-
if (failed > 0) {
|
|
151
|
-
process.exit(1);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
async function runDown(migrator: Migrator, args: string[]) {
|
|
156
|
-
const options: { to?: string; step?: number } = { step: 1 }; // Default to 1 step
|
|
157
|
-
|
|
158
|
-
for (let i = 0; i < args.length; i++) {
|
|
159
|
-
if (args[i] === '--to' && args[i + 1]) {
|
|
160
|
-
options.to = args[++i];
|
|
161
|
-
delete options.step;
|
|
162
|
-
} else if (args[i] === '--step' && args[i + 1]) {
|
|
163
|
-
options.step = Number.parseInt(args[++i], 10);
|
|
164
|
-
} else if (args[i] === '--all') {
|
|
165
|
-
delete options.step;
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
const results = await migrator.down(options);
|
|
170
|
-
|
|
171
|
-
if (results.length === 0) {
|
|
172
|
-
console.log('No migrations to rollback.');
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
const successful = results.filter((r: any) => r.success).length;
|
|
177
|
-
const failed = results.filter((r: any) => !r.success).length;
|
|
178
|
-
|
|
179
|
-
console.log(`\nRollback complete: ${successful} successful, ${failed} failed`);
|
|
180
|
-
|
|
181
|
-
if (failed > 0) {
|
|
182
|
-
process.exit(1);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
async function runStatus(migrator: Migrator) {
|
|
187
|
-
const status = await migrator.status();
|
|
188
|
-
|
|
189
|
-
console.log('\n=== Migration Status ===\n');
|
|
190
|
-
|
|
191
|
-
console.log('Executed migrations:');
|
|
192
|
-
if (status.executed.length === 0) {
|
|
193
|
-
console.log(' (none)');
|
|
194
|
-
} else {
|
|
195
|
-
for (const name of status.executed) {
|
|
196
|
-
console.log(` ✓ ${name}`);
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
console.log('\nPending migrations:');
|
|
201
|
-
if (status.pending.length === 0) {
|
|
202
|
-
console.log(' (none)');
|
|
203
|
-
} else {
|
|
204
|
-
for (const name of status.pending) {
|
|
205
|
-
console.log(` ○ ${name}`);
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
console.log('');
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
async function runPending(migrator: Migrator) {
|
|
213
|
-
const pending = await migrator.pending();
|
|
214
|
-
|
|
215
|
-
if (pending.length === 0) {
|
|
216
|
-
console.log('No pending migrations.');
|
|
217
|
-
return;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
console.log('Pending migrations:');
|
|
221
|
-
for (const migration of pending) {
|
|
222
|
-
console.log(` ○ ${migration.name}`);
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
async function runGenerate(migrator: Migrator, args: string[]) {
|
|
227
|
-
const name = args.join('_') || 'migration';
|
|
228
|
-
const filePath = await migrator.generate(name);
|
|
229
|
-
console.log(`\nCreated migration: ${filePath}`);
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
async function runGenerateFromEntities(migrator: Migrator, args: string[]) {
|
|
233
|
-
const name = args.join('_') || 'schema';
|
|
234
|
-
const filePath = await migrator.generateFromEntities(name);
|
|
235
|
-
console.log(`\nCreated migration from entities: ${filePath}`);
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
async function runSync(migrator: Migrator, args: string[]) {
|
|
239
|
-
const force = args.includes('--force');
|
|
240
|
-
|
|
241
|
-
if (force) {
|
|
242
|
-
console.log('\n⚠️ WARNING: This will drop and recreate all tables!');
|
|
243
|
-
console.log(' All data will be lost. This should only be used in development.\n');
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
await migrator.sync({ force });
|
|
247
|
-
console.log('\nSchema sync completed.');
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
function printHelp() {
|
|
251
|
-
console.log(`
|
|
252
|
-
@uql/migrate - Database migration tool for uql ORM
|
|
253
|
-
|
|
254
|
-
Usage: @uql/migrate <command> [options]
|
|
255
|
-
|
|
256
|
-
Commands:
|
|
257
|
-
up Run all pending migrations
|
|
258
|
-
--to <name> Run migrations up to and including <name>
|
|
259
|
-
--step <n> Run only <n> migrations
|
|
260
|
-
|
|
261
|
-
down Rollback the last migration
|
|
262
|
-
--to <name> Rollback to (and including) migration <name>
|
|
263
|
-
--step <n> Rollback <n> migrations (default: 1)
|
|
264
|
-
--all Rollback all migrations
|
|
265
|
-
|
|
266
|
-
status Show migration status
|
|
267
|
-
|
|
268
|
-
pending Show pending migrations
|
|
269
|
-
|
|
270
|
-
generate <name> Create a new empty migration file
|
|
271
|
-
create <name> Alias for generate
|
|
272
|
-
|
|
273
|
-
generate:entities Generate migration from entity definitions
|
|
274
|
-
<name> Optional name for the migration
|
|
275
|
-
|
|
276
|
-
sync Sync schema directly (development only!)
|
|
277
|
-
--force Drop and recreate all tables
|
|
278
|
-
|
|
279
|
-
Configuration:
|
|
280
|
-
Create a uql.config.ts or uql.config.js file in your project root:
|
|
281
|
-
|
|
282
|
-
export default {
|
|
283
|
-
querierPool: new PgQuerierPool({ ... }),
|
|
284
|
-
migrationsPath: './migrations',
|
|
285
|
-
tableName: 'uql_migrations',
|
|
286
|
-
dialect: 'postgres', // 'postgres' | 'mysql' | 'mariadb' | 'sqlite'
|
|
287
|
-
entities: [User, Post, ...],
|
|
288
|
-
};
|
|
289
|
-
|
|
290
|
-
Examples:
|
|
291
|
-
@uql/migrate up
|
|
292
|
-
@uql/migrate up --step 1
|
|
293
|
-
@uql/migrate down
|
|
294
|
-
@uql/migrate down --step 3
|
|
295
|
-
@uql/migrate status
|
|
296
|
-
@uql/migrate generate add_users_table
|
|
297
|
-
@uql/migrate generate:entities initial_schema
|
|
298
|
-
`);
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
main().catch(console.error);
|