@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
package/src/querier/index.ts
DELETED
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, it, jest } from 'bun:test';
|
|
2
|
-
import { User } from '../test/index.js';
|
|
3
|
-
import type { Querier, Repository } from '../type/index.js';
|
|
4
|
-
import { GenericRepository } from './genericRepository.js';
|
|
5
|
-
|
|
6
|
-
describe('repository', () => {
|
|
7
|
-
let repository: Repository<User>;
|
|
8
|
-
let querier: Record<keyof Querier, jest.Mock>;
|
|
9
|
-
|
|
10
|
-
beforeEach(() => {
|
|
11
|
-
querier = {
|
|
12
|
-
count: jest.fn(),
|
|
13
|
-
findOneById: jest.fn(),
|
|
14
|
-
findOne: jest.fn(),
|
|
15
|
-
findMany: jest.fn(),
|
|
16
|
-
findManyAndCount: jest.fn(),
|
|
17
|
-
insertOne: jest.fn(),
|
|
18
|
-
insertMany: jest.fn(),
|
|
19
|
-
updateOneById: jest.fn(),
|
|
20
|
-
updateMany: jest.fn(),
|
|
21
|
-
saveOne: jest.fn(),
|
|
22
|
-
saveMany: jest.fn(),
|
|
23
|
-
deleteOneById: jest.fn(),
|
|
24
|
-
deleteMany: jest.fn(),
|
|
25
|
-
upsertOne: jest.fn(),
|
|
26
|
-
getRepository: jest.fn(),
|
|
27
|
-
hasOpenTransaction: undefined,
|
|
28
|
-
transaction: jest.fn(),
|
|
29
|
-
beginTransaction: jest.fn(),
|
|
30
|
-
commitTransaction: jest.fn(),
|
|
31
|
-
rollbackTransaction: jest.fn(),
|
|
32
|
-
release: jest.fn(),
|
|
33
|
-
};
|
|
34
|
-
repository = new GenericRepository(User, querier as unknown as Querier);
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
it('count', async () => {
|
|
38
|
-
await repository.count({});
|
|
39
|
-
expect(querier.count).toHaveBeenCalledWith(User, {});
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
it('findOneById', async () => {
|
|
43
|
-
await repository.findOneById(1);
|
|
44
|
-
expect(querier.findOneById).toHaveBeenCalledWith(User, 1, undefined);
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it('findOne', async () => {
|
|
48
|
-
await repository.findOne({});
|
|
49
|
-
expect(querier.findOne).toHaveBeenCalledWith(User, {});
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
it('findMany', async () => {
|
|
53
|
-
await repository.findMany({});
|
|
54
|
-
expect(querier.findMany).toHaveBeenCalledWith(User, {});
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
it('findManyAndCount', async () => {
|
|
58
|
-
await repository.findManyAndCount({});
|
|
59
|
-
expect(querier.findManyAndCount).toHaveBeenCalledWith(User, {});
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
it('insertOne', async () => {
|
|
63
|
-
await repository.insertOne({});
|
|
64
|
-
expect(querier.insertOne).toHaveBeenCalledWith(User, {});
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
it('insertMany', async () => {
|
|
68
|
-
await repository.insertMany([{}]);
|
|
69
|
-
expect(querier.insertMany).toHaveBeenCalledWith(User, [{}]);
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
it('updateMany', async () => {
|
|
73
|
-
await repository.updateMany({}, {});
|
|
74
|
-
expect(querier.updateMany).toHaveBeenCalledWith(User, {}, {});
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
it('updateOneById', async () => {
|
|
78
|
-
await repository.updateOneById(1, {});
|
|
79
|
-
expect(querier.updateOneById).toHaveBeenCalledWith(User, 1, {});
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
it('saveOne', async () => {
|
|
83
|
-
await repository.saveOne({});
|
|
84
|
-
expect(querier.saveOne).toHaveBeenCalledWith(User, {});
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
it('insertMany', async () => {
|
|
88
|
-
await repository.saveMany([{}]);
|
|
89
|
-
expect(querier.saveMany).toHaveBeenCalledWith(User, [{}]);
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
it('deleteOneById', async () => {
|
|
93
|
-
await repository.deleteOneById(1);
|
|
94
|
-
expect(querier.deleteOneById).toHaveBeenCalledWith(User, 1, undefined);
|
|
95
|
-
|
|
96
|
-
await repository.deleteOneById(1, { softDelete: false });
|
|
97
|
-
expect(querier.deleteOneById).toHaveBeenCalledWith(User, 1, { softDelete: false });
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
it('deleteMany', async () => {
|
|
101
|
-
await repository.deleteMany({});
|
|
102
|
-
expect(querier.deleteMany).toHaveBeenCalledWith(User, {}, undefined);
|
|
103
|
-
|
|
104
|
-
await repository.deleteMany({}, { softDelete: false });
|
|
105
|
-
expect(querier.deleteMany).toHaveBeenCalledWith(User, {}, { softDelete: false });
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
it('repository property', () => {
|
|
109
|
-
expect(repository.querier).toBe(querier);
|
|
110
|
-
});
|
|
111
|
-
});
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
IdValue,
|
|
3
|
-
Querier,
|
|
4
|
-
Query,
|
|
5
|
-
QueryConflictPaths,
|
|
6
|
-
QueryOne,
|
|
7
|
-
QueryOptions,
|
|
8
|
-
QuerySearch,
|
|
9
|
-
Repository,
|
|
10
|
-
Type,
|
|
11
|
-
} from '../type/index.js';
|
|
12
|
-
|
|
13
|
-
export class GenericRepository<E> implements Repository<E> {
|
|
14
|
-
constructor(
|
|
15
|
-
readonly entity: Type<E>,
|
|
16
|
-
readonly querier: Querier,
|
|
17
|
-
) {}
|
|
18
|
-
|
|
19
|
-
findOneById(id: IdValue<E>, q?: QueryOne<E>) {
|
|
20
|
-
return this.querier.findOneById(this.entity, id, q);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
findOne(q: QueryOne<E>) {
|
|
24
|
-
return this.querier.findOne(this.entity, q);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
findMany(q: Query<E>) {
|
|
28
|
-
return this.querier.findMany(this.entity, q);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
findManyAndCount(q: Query<E>) {
|
|
32
|
-
return this.querier.findManyAndCount(this.entity, q);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
count(q?: QuerySearch<E>) {
|
|
36
|
-
return this.querier.count(this.entity, q);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
insertOne(payload: E) {
|
|
40
|
-
return this.querier.insertOne(this.entity, payload);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
upsertOne(conflictPaths: QueryConflictPaths<E>, payload: E) {
|
|
44
|
-
return this.querier.upsertOne(this.entity, conflictPaths, payload);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
insertMany(payload: E[]) {
|
|
48
|
-
return this.querier.insertMany(this.entity, payload);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
updateOneById(id: IdValue<E>, payload: E) {
|
|
52
|
-
return this.querier.updateOneById(this.entity, id, payload);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
updateMany(qm: QuerySearch<E>, payload: E) {
|
|
56
|
-
return this.querier.updateMany(this.entity, qm, payload);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
saveOne(payload: E) {
|
|
60
|
-
return this.querier.saveOne(this.entity, payload);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
saveMany(payload: E[]) {
|
|
64
|
-
return this.querier.saveMany(this.entity, payload);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
deleteOneById(id: IdValue<E>, opts?: QueryOptions) {
|
|
68
|
-
return this.querier.deleteOneById(this.entity, id, opts);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
deleteMany(qm: QuerySearch<E>, opts?: QueryOptions) {
|
|
72
|
-
return this.querier.deleteMany(this.entity, qm, opts);
|
|
73
|
-
}
|
|
74
|
-
}
|
package/src/repository/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './genericRepository.js';
|
package/src/sqlite/index.ts
DELETED
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
import { expect } from 'bun:test';
|
|
2
|
-
import { AbstractSqlDialectSpec } from '../dialect/abstractSqlDialect-spec.js';
|
|
3
|
-
import { Company, createSpec, InventoryAdjustment, Item, ItemTag, Profile, TaxCategory, User } from '../test/index.js';
|
|
4
|
-
import { SqliteDialect } from './sqliteDialect.js';
|
|
5
|
-
|
|
6
|
-
class SqliteDialectSpec extends AbstractSqlDialectSpec {
|
|
7
|
-
constructor() {
|
|
8
|
-
super(new SqliteDialect());
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
override shouldBeginTransaction() {
|
|
12
|
-
expect(this.dialect.beginTransactionCommand).toBe('BEGIN TRANSACTION');
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
override shouldUpsert() {
|
|
16
|
-
const { sql, values } = this.exec((ctx) =>
|
|
17
|
-
this.dialect.upsert(
|
|
18
|
-
ctx,
|
|
19
|
-
TaxCategory,
|
|
20
|
-
{ pk: true },
|
|
21
|
-
{
|
|
22
|
-
pk: 'a',
|
|
23
|
-
name: 'Some Name D',
|
|
24
|
-
createdAt: 1,
|
|
25
|
-
updatedAt: 1,
|
|
26
|
-
},
|
|
27
|
-
),
|
|
28
|
-
);
|
|
29
|
-
expect(sql).toMatch(
|
|
30
|
-
/^INSERT INTO `TaxCategory` \(.*`pk`.*`name`.*`createdAt`.*`updatedAt`.*\) VALUES \(\?, \?, \?, \?\) ON CONFLICT \(`pk`\) DO UPDATE SET .*`name` = EXCLUDED.`name`.*`createdAt` = EXCLUDED.`createdAt`.*`updatedAt` = EXCLUDED.`updatedAt`.*$/,
|
|
31
|
-
);
|
|
32
|
-
expect(values).toEqual(['a', 'Some Name D', 1, 1]);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
shouldUpsertWithDifferentColumnNames() {
|
|
36
|
-
const { sql, values } = this.exec((ctx) =>
|
|
37
|
-
this.dialect.upsert(
|
|
38
|
-
ctx,
|
|
39
|
-
Profile,
|
|
40
|
-
{ pk: true },
|
|
41
|
-
{
|
|
42
|
-
pk: 1,
|
|
43
|
-
picture: 'image.jpg',
|
|
44
|
-
},
|
|
45
|
-
),
|
|
46
|
-
);
|
|
47
|
-
expect(sql).toMatch(
|
|
48
|
-
/^INSERT INTO `user_profile` \(.*`pk`.*`image`.*`updatedAt`.*`createdAt`.*\) VALUES \(\?, \?, \?, \?\) ON CONFLICT \(`pk`\) DO UPDATE SET .*`image` = EXCLUDED.`image`.*`updatedAt` = EXCLUDED.`updatedAt`.*$/,
|
|
49
|
-
);
|
|
50
|
-
expect(values).toEqual([1, 'image.jpg', expect.any(Number), expect.any(Number)]);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
shouldUpsertWithNonUpdatableFields() {
|
|
54
|
-
const { sql, values } = this.exec((ctx) =>
|
|
55
|
-
this.dialect.upsert(
|
|
56
|
-
ctx,
|
|
57
|
-
User,
|
|
58
|
-
{ id: true },
|
|
59
|
-
{
|
|
60
|
-
id: 1,
|
|
61
|
-
email: 'a@b.com',
|
|
62
|
-
},
|
|
63
|
-
),
|
|
64
|
-
);
|
|
65
|
-
expect(sql).toMatch(
|
|
66
|
-
/^INSERT INTO `User` \(.*`id`.*`email`.*`updatedAt`.*`createdAt`.*\) VALUES \(\?, \?, \?, \?\) ON CONFLICT \(`id`\) DO UPDATE SET .*`updatedAt` = EXCLUDED.`updatedAt`.*$/,
|
|
67
|
-
);
|
|
68
|
-
expect(values).toEqual([1, 'a@b.com', expect.any(Number), expect.any(Number)]);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
override shouldInsertOne() {
|
|
72
|
-
let res = this.exec((ctx) =>
|
|
73
|
-
this.dialect.insert(ctx, User, {
|
|
74
|
-
name: 'Some Name',
|
|
75
|
-
email: 'someemail@example.com',
|
|
76
|
-
createdAt: 123,
|
|
77
|
-
}),
|
|
78
|
-
);
|
|
79
|
-
expect(res.sql).toBe('INSERT INTO `User` (`name`, `email`, `createdAt`) VALUES (?, ?, ?)');
|
|
80
|
-
expect(res.values).toEqual(['Some Name', 'someemail@example.com', 123]);
|
|
81
|
-
|
|
82
|
-
res = this.exec((ctx) =>
|
|
83
|
-
this.dialect.insert(ctx, InventoryAdjustment, {
|
|
84
|
-
date: new Date(2021, 11, 31, 23, 59, 59, 999),
|
|
85
|
-
createdAt: 123,
|
|
86
|
-
}),
|
|
87
|
-
);
|
|
88
|
-
expect(res.sql).toBe('INSERT INTO `InventoryAdjustment` (`date`, `createdAt`) VALUES (?, ?)');
|
|
89
|
-
expect(res.values[0]).toBe(1640995199999);
|
|
90
|
-
expect(res.values[1]).toBe(123);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
shouldUpsertWithDoNothing() {
|
|
94
|
-
const { sql, values } = this.exec((ctx) =>
|
|
95
|
-
this.dialect.upsert(
|
|
96
|
-
ctx,
|
|
97
|
-
ItemTag,
|
|
98
|
-
{ id: true },
|
|
99
|
-
{
|
|
100
|
-
id: 1,
|
|
101
|
-
},
|
|
102
|
-
),
|
|
103
|
-
);
|
|
104
|
-
expect(sql).toBe('INSERT INTO `ItemTag` (`id`) VALUES (?) ON CONFLICT (`id`) DO NOTHING');
|
|
105
|
-
expect(values).toEqual([1]);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
override shouldFind$text() {
|
|
109
|
-
let res = this.exec((ctx) =>
|
|
110
|
-
this.dialect.find(ctx, Item, {
|
|
111
|
-
$select: { id: true },
|
|
112
|
-
$where: { $text: { $fields: ['name', 'description'], $value: 'some text' }, companyId: 1 },
|
|
113
|
-
$limit: 30,
|
|
114
|
-
}),
|
|
115
|
-
);
|
|
116
|
-
expect(res.sql).toBe(
|
|
117
|
-
'SELECT `id` FROM `Item` WHERE `Item` MATCH {`name` `description`} : ? AND `companyId` = ? LIMIT 30',
|
|
118
|
-
);
|
|
119
|
-
expect(res.values).toEqual(['some text', 1]);
|
|
120
|
-
|
|
121
|
-
res = this.exec((ctx) =>
|
|
122
|
-
this.dialect.find(ctx, User, {
|
|
123
|
-
$select: { id: 1 },
|
|
124
|
-
$where: {
|
|
125
|
-
$text: { $fields: ['name'], $value: 'something' },
|
|
126
|
-
name: { $ne: 'other unwanted' },
|
|
127
|
-
companyId: 1,
|
|
128
|
-
},
|
|
129
|
-
$limit: 10,
|
|
130
|
-
}),
|
|
131
|
-
);
|
|
132
|
-
expect(res.sql).toBe(
|
|
133
|
-
'SELECT `id` FROM `User` WHERE `User` MATCH {`name`} : ? AND `name` <> ? AND `companyId` = ? LIMIT 10',
|
|
134
|
-
);
|
|
135
|
-
expect(res.values).toEqual(['something', 'other unwanted', 1]);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
override shouldUpdateWithJsonbField() {
|
|
139
|
-
const { sql, values } = this.exec((ctx) =>
|
|
140
|
-
this.dialect.update(
|
|
141
|
-
ctx,
|
|
142
|
-
Company,
|
|
143
|
-
{ $where: { id: 1 } },
|
|
144
|
-
{
|
|
145
|
-
kind: { private: 1 },
|
|
146
|
-
updatedAt: 123,
|
|
147
|
-
},
|
|
148
|
-
),
|
|
149
|
-
);
|
|
150
|
-
expect(sql).toBe('UPDATE `Company` SET `kind` = ?, `updatedAt` = ? WHERE `id` = ?');
|
|
151
|
-
expect(values).toEqual(['{"private":1}', 123, 1]);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
createSpec(new SqliteDialectSpec());
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import sqlstring from 'sqlstring-sqlite';
|
|
2
|
-
import { AbstractSqlDialect } from '../dialect/index.js';
|
|
3
|
-
import { getMeta } from '../entity/index.js';
|
|
4
|
-
import type {
|
|
5
|
-
FieldKey,
|
|
6
|
-
NamingStrategy,
|
|
7
|
-
QueryComparisonOptions,
|
|
8
|
-
QueryConflictPaths,
|
|
9
|
-
QueryContext,
|
|
10
|
-
QueryTextSearchOptions,
|
|
11
|
-
QueryWhereFieldOperatorMap,
|
|
12
|
-
QueryWhereMap,
|
|
13
|
-
Type,
|
|
14
|
-
} from '../type/index.js';
|
|
15
|
-
|
|
16
|
-
export class SqliteDialect extends AbstractSqlDialect {
|
|
17
|
-
constructor(namingStrategy?: NamingStrategy) {
|
|
18
|
-
super(namingStrategy, '`', 'BEGIN TRANSACTION');
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
override addValue(values: unknown[], value: unknown): string {
|
|
22
|
-
if (value instanceof Date) {
|
|
23
|
-
value = value.getTime();
|
|
24
|
-
} else if (typeof value === 'boolean') {
|
|
25
|
-
value = value ? 1 : 0;
|
|
26
|
-
}
|
|
27
|
-
return super.addValue(values, value);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
override compare<E, K extends keyof QueryWhereMap<E>>(
|
|
31
|
-
ctx: QueryContext,
|
|
32
|
-
entity: Type<E>,
|
|
33
|
-
key: K,
|
|
34
|
-
val: QueryWhereMap<E>[K],
|
|
35
|
-
opts?: QueryComparisonOptions,
|
|
36
|
-
): void {
|
|
37
|
-
if (key === '$text') {
|
|
38
|
-
const meta = getMeta(entity);
|
|
39
|
-
const search = val as QueryTextSearchOptions<E>;
|
|
40
|
-
const fields = search.$fields.map((fKey) => {
|
|
41
|
-
const field = meta.fields[fKey];
|
|
42
|
-
const columnName = this.resolveColumnName(fKey as string, field);
|
|
43
|
-
return this.escapeId(columnName);
|
|
44
|
-
});
|
|
45
|
-
const tableName = this.resolveTableName(entity, meta);
|
|
46
|
-
ctx.append(`${this.escapeId(tableName)} MATCH {${fields.join(' ')}} : `);
|
|
47
|
-
ctx.addValue(search.$value);
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
super.compare(ctx, entity, key, val, opts);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
override compareFieldOperator<E, K extends keyof QueryWhereFieldOperatorMap<E>>(
|
|
54
|
-
ctx: QueryContext,
|
|
55
|
-
entity: Type<E>,
|
|
56
|
-
key: FieldKey<E>,
|
|
57
|
-
op: K,
|
|
58
|
-
val: QueryWhereFieldOperatorMap<E>[K],
|
|
59
|
-
opts: QueryComparisonOptions = {},
|
|
60
|
-
): void {
|
|
61
|
-
super.compareFieldOperator(ctx, entity, key, op, val, opts);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
override upsert<E>(ctx: QueryContext, entity: Type<E>, conflictPaths: QueryConflictPaths<E>, payload: E): void {
|
|
65
|
-
const meta = getMeta(entity);
|
|
66
|
-
const update = this.getUpsertUpdateAssignments(ctx, meta, conflictPaths, payload, (name) => `EXCLUDED.${name}`);
|
|
67
|
-
const keysStr = this.getUpsertConflictPathsStr(meta, conflictPaths);
|
|
68
|
-
const onConflict = update ? `DO UPDATE SET ${update}` : 'DO NOTHING';
|
|
69
|
-
this.insert(ctx, entity, payload);
|
|
70
|
-
ctx.append(` ON CONFLICT (${keysStr}) ${onConflict}`);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
override escape(value: unknown): string {
|
|
74
|
-
return sqlstring.escape(value);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { jest, mock } from 'bun:test';
|
|
2
|
-
import { AbstractSqlQuerierSpec } from '../querier/abstractSqlQuerier-spec.js';
|
|
3
|
-
import { createSpec } from '../test/index.js';
|
|
4
|
-
|
|
5
|
-
mock.module('better-sqlite3', () => {
|
|
6
|
-
const { Database } = require('bun:sqlite');
|
|
7
|
-
class BetterSqlite3 extends Database {
|
|
8
|
-
pragma(source: string) {
|
|
9
|
-
return this.query(`PRAGMA ${source}`).all();
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
return {
|
|
13
|
-
default: BetterSqlite3,
|
|
14
|
-
};
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
import { Sqlite3QuerierPool } from './sqliteQuerierPool.js';
|
|
18
|
-
|
|
19
|
-
class SqliteQuerierSpec extends AbstractSqlQuerierSpec {
|
|
20
|
-
constructor() {
|
|
21
|
-
super(new Sqlite3QuerierPool(':memory:'), 'INTEGER PRIMARY KEY');
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
override async beforeEach() {
|
|
25
|
-
await super.beforeEach();
|
|
26
|
-
await Promise.all([
|
|
27
|
-
this.querier.run('PRAGMA foreign_keys = ON'),
|
|
28
|
-
this.querier.run('PRAGMA journal_mode = WAL'),
|
|
29
|
-
this.querier.run('PRAGMA synchronous = normal'),
|
|
30
|
-
this.querier.run('PRAGMA temp_store = memory'),
|
|
31
|
-
]);
|
|
32
|
-
jest.spyOn(this.querier, 'run').mockClear();
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
createSpec(new SqliteQuerierSpec());
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { AbstractSqlQuerierIt } from '../querier/abstractSqlQuerier-test.js';
|
|
2
|
-
import { createSpec } from '../test/index.js';
|
|
3
|
-
import { Sqlite3QuerierPool } from './sqliteQuerierPool.js';
|
|
4
|
-
|
|
5
|
-
export class Sqlite3QuerierIt extends AbstractSqlQuerierIt {
|
|
6
|
-
constructor() {
|
|
7
|
-
super(new Sqlite3QuerierPool(':memory:'), 'INTEGER PRIMARY KEY');
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
override async beforeEach() {
|
|
11
|
-
await super.beforeEach();
|
|
12
|
-
await Promise.all([
|
|
13
|
-
this.querier.run('PRAGMA foreign_keys = ON'),
|
|
14
|
-
this.querier.run('PRAGMA journal_mode = WAL'),
|
|
15
|
-
this.querier.run('PRAGMA synchronous = normal'),
|
|
16
|
-
this.querier.run('PRAGMA temp_store = memory'),
|
|
17
|
-
]);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
createSpec(new Sqlite3QuerierIt());
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import type { Database } from 'better-sqlite3';
|
|
2
|
-
import { AbstractSqlQuerier } from '../querier/index.js';
|
|
3
|
-
import type { ExtraOptions, QueryUpdateResult } from '../type/index.js';
|
|
4
|
-
import { SqliteDialect } from './sqliteDialect.js';
|
|
5
|
-
|
|
6
|
-
export class SqliteQuerier extends AbstractSqlQuerier {
|
|
7
|
-
constructor(
|
|
8
|
-
readonly db: Database,
|
|
9
|
-
readonly extra?: ExtraOptions,
|
|
10
|
-
) {
|
|
11
|
-
super(new SqliteDialect(extra?.namingStrategy));
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
override async internalAll<T>(query: string, values?: unknown[]) {
|
|
15
|
-
this.extra?.logger?.(query, values);
|
|
16
|
-
return this.db.prepare(query).all(values || []) as T[];
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
override async internalRun(query: string, values?: unknown[]) {
|
|
20
|
-
this.extra?.logger?.(query, values);
|
|
21
|
-
const { changes, lastInsertRowid } = this.db.prepare(query).run(values || []);
|
|
22
|
-
const firstId = lastInsertRowid ? Number(lastInsertRowid) - (changes - 1) : undefined;
|
|
23
|
-
const ids = firstId
|
|
24
|
-
? Array(changes)
|
|
25
|
-
.fill(firstId)
|
|
26
|
-
.map((i, index) => i + index)
|
|
27
|
-
: [];
|
|
28
|
-
return { changes, ids, firstId } satisfies QueryUpdateResult;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
override async internalRelease() {
|
|
32
|
-
if (this.hasOpenTransaction) {
|
|
33
|
-
throw TypeError('pending transaction');
|
|
34
|
-
}
|
|
35
|
-
// no-op
|
|
36
|
-
}
|
|
37
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { AbstractQuerierPoolIt } from '../querier/abstractQuerierPool-test.js';
|
|
2
|
-
import { createSpec } from '../test/index.js';
|
|
3
|
-
import type { SqliteQuerier } from './sqliteQuerier.js';
|
|
4
|
-
import { Sqlite3QuerierPool } from './sqliteQuerierPool.js';
|
|
5
|
-
|
|
6
|
-
export class Sqlite3QuerierPoolIt extends AbstractQuerierPoolIt<SqliteQuerier> {
|
|
7
|
-
constructor() {
|
|
8
|
-
super(new Sqlite3QuerierPool(':memory:'));
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
createSpec(new Sqlite3QuerierPoolIt());
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import type { Options } from 'better-sqlite3';
|
|
2
|
-
import { AbstractQuerierPool } from '../querier/index.js';
|
|
3
|
-
import type { ExtraOptions } from '../type/index.js';
|
|
4
|
-
import { SqliteQuerier } from './sqliteQuerier.js';
|
|
5
|
-
|
|
6
|
-
export class Sqlite3QuerierPool extends AbstractQuerierPool<SqliteQuerier> {
|
|
7
|
-
private querier: SqliteQuerier;
|
|
8
|
-
|
|
9
|
-
constructor(
|
|
10
|
-
readonly filename?: string | Buffer,
|
|
11
|
-
readonly opts?: Options,
|
|
12
|
-
extra?: ExtraOptions,
|
|
13
|
-
) {
|
|
14
|
-
super('sqlite', extra);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
async getQuerier() {
|
|
18
|
-
if (!this.querier) {
|
|
19
|
-
let db: any;
|
|
20
|
-
if (typeof Bun !== 'undefined') {
|
|
21
|
-
const { Database } = await import('bun:sqlite');
|
|
22
|
-
db = new Database(this.filename as string, this.opts as any);
|
|
23
|
-
db.run('PRAGMA journal_mode = WAL');
|
|
24
|
-
} else {
|
|
25
|
-
const { default: Database } = await import('better-sqlite3');
|
|
26
|
-
db = new Database(this.filename, this.opts);
|
|
27
|
-
db.pragma('journal_mode = WAL');
|
|
28
|
-
}
|
|
29
|
-
this.querier = new SqliteQuerier(db, this.extra);
|
|
30
|
-
}
|
|
31
|
-
return this.querier;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
async end() {
|
|
35
|
-
await this.querier.db.close();
|
|
36
|
-
delete this.querier;
|
|
37
|
-
}
|
|
38
|
-
}
|