@uql/core 3.1.1 → 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 -187
- package/package.json +31 -26
- package/dist/CHANGELOG.md +0 -186
- 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/{dist/README.md → README.md} +0 -0
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'bun:test';
|
|
2
|
-
import { Entity, Field, Id } from '../../entity/index.js';
|
|
3
|
-
import type { IndexSchema, TableSchema } from '../../type/index.js';
|
|
4
|
-
import { MongoSchemaGenerator } from './mongoSchemaGenerator.js';
|
|
5
|
-
|
|
6
|
-
@Entity()
|
|
7
|
-
class MongoUser {
|
|
8
|
-
@Id() id?: string;
|
|
9
|
-
@Field({ index: true }) username?: string;
|
|
10
|
-
@Field({ index: 'idx_email', unique: true }) email?: string;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
describe('MongoSchemaGenerator', () => {
|
|
14
|
-
const generator = new MongoSchemaGenerator();
|
|
15
|
-
|
|
16
|
-
it('should generate createCollection statement', () => {
|
|
17
|
-
const json = generator.generateCreateTable(MongoUser);
|
|
18
|
-
const cmd = JSON.parse(json);
|
|
19
|
-
|
|
20
|
-
expect(cmd).toMatchObject({
|
|
21
|
-
action: 'createCollection',
|
|
22
|
-
name: 'MongoUser',
|
|
23
|
-
});
|
|
24
|
-
expect(cmd.indexes).toHaveLength(2);
|
|
25
|
-
expect(cmd.indexes).toContainEqual({
|
|
26
|
-
name: 'idx_MongoUser_username',
|
|
27
|
-
columns: ['username'],
|
|
28
|
-
unique: false,
|
|
29
|
-
});
|
|
30
|
-
expect(cmd.indexes).toContainEqual({
|
|
31
|
-
name: 'idx_email',
|
|
32
|
-
columns: ['email'],
|
|
33
|
-
unique: true,
|
|
34
|
-
});
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
it('should generate dropCollection statement', () => {
|
|
38
|
-
const json = generator.generateDropTable(MongoUser);
|
|
39
|
-
const cmd = JSON.parse(json);
|
|
40
|
-
|
|
41
|
-
expect(cmd).toMatchObject({
|
|
42
|
-
action: 'dropCollection',
|
|
43
|
-
name: 'MongoUser',
|
|
44
|
-
});
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it('should generate createIndex statement', () => {
|
|
48
|
-
const json = generator.generateCreateIndex('MongoUser', {
|
|
49
|
-
name: 'idx_test',
|
|
50
|
-
columns: ['test'],
|
|
51
|
-
unique: true,
|
|
52
|
-
} as IndexSchema);
|
|
53
|
-
const cmd = JSON.parse(json);
|
|
54
|
-
|
|
55
|
-
expect(cmd).toMatchObject({
|
|
56
|
-
action: 'createIndex',
|
|
57
|
-
collection: 'MongoUser',
|
|
58
|
-
name: 'idx_test',
|
|
59
|
-
key: { test: 1 },
|
|
60
|
-
options: { unique: true, name: 'idx_test' },
|
|
61
|
-
});
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
it('should generate dropIndex statement', () => {
|
|
65
|
-
const json = generator.generateDropIndex('MongoUser', 'idx_test');
|
|
66
|
-
const cmd = JSON.parse(json);
|
|
67
|
-
|
|
68
|
-
expect(cmd).toMatchObject({
|
|
69
|
-
action: 'dropIndex',
|
|
70
|
-
collection: 'MongoUser',
|
|
71
|
-
name: 'idx_test',
|
|
72
|
-
});
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
it('diffSchema should return create if currentSchema is undefined', () => {
|
|
76
|
-
const diff = generator.diffSchema(MongoUser, undefined);
|
|
77
|
-
expect(diff).toMatchObject({
|
|
78
|
-
tableName: 'MongoUser',
|
|
79
|
-
type: 'create',
|
|
80
|
-
});
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
it('diffSchema should return alter if indexes are missing', () => {
|
|
84
|
-
const currentSchema: TableSchema = {
|
|
85
|
-
name: 'MongoUser',
|
|
86
|
-
columns: [],
|
|
87
|
-
indexes: [{ name: 'idx_MongoUser_username', columns: ['username'], unique: false }],
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
const diff = generator.diffSchema(MongoUser, currentSchema);
|
|
91
|
-
expect(diff).toMatchObject({
|
|
92
|
-
tableName: 'MongoUser',
|
|
93
|
-
type: 'alter',
|
|
94
|
-
});
|
|
95
|
-
expect(diff?.indexesToAdd).toHaveLength(1);
|
|
96
|
-
expect(diff?.indexesToAdd?.[0].name).toBe('idx_email');
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
it('diffSchema should return undefined if in sync', () => {
|
|
100
|
-
const currentSchema: import('../../type/index.js').TableSchema = {
|
|
101
|
-
name: 'MongoUser',
|
|
102
|
-
columns: [],
|
|
103
|
-
indexes: [
|
|
104
|
-
{ name: 'idx_MongoUser_username', columns: ['username'], unique: false },
|
|
105
|
-
{ name: 'idx_email', columns: ['email'], unique: true },
|
|
106
|
-
],
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
const diff = generator.diffSchema(MongoUser, currentSchema);
|
|
110
|
-
expect(diff).toBeUndefined();
|
|
111
|
-
});
|
|
112
|
-
});
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
import { AbstractDialect } from '../../dialect/index.js';
|
|
2
|
-
import { getMeta } from '../../entity/index.js';
|
|
3
|
-
import type { IndexSchema, SchemaDiff, SchemaGenerator, TableSchema, Type } from '../../type/index.js';
|
|
4
|
-
|
|
5
|
-
export class MongoSchemaGenerator extends AbstractDialect implements SchemaGenerator {
|
|
6
|
-
generateCreateTable<E>(entity: Type<E>): string {
|
|
7
|
-
const meta = getMeta(entity);
|
|
8
|
-
const collectionName = this.resolveTableName(entity, meta);
|
|
9
|
-
const indexes: IndexSchema[] = [];
|
|
10
|
-
|
|
11
|
-
for (const key in meta.fields) {
|
|
12
|
-
const field = meta.fields[key];
|
|
13
|
-
if (field.index) {
|
|
14
|
-
const columnName = this.resolveColumnName(key, field);
|
|
15
|
-
const indexName = typeof field.index === 'string' ? field.index : `idx_${collectionName}_${columnName}`;
|
|
16
|
-
indexes.push({
|
|
17
|
-
name: indexName,
|
|
18
|
-
columns: [columnName],
|
|
19
|
-
unique: !!field.unique,
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
return JSON.stringify({ action: 'createCollection', name: collectionName, indexes });
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
generateDropTable<E>(entity: Type<E>): string {
|
|
28
|
-
const meta = getMeta(entity);
|
|
29
|
-
const collectionName = this.resolveTableName(entity, meta);
|
|
30
|
-
return JSON.stringify({ action: 'dropCollection', name: collectionName });
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
generateAlterTable(diff: SchemaDiff): string[] {
|
|
34
|
-
const statements: string[] = [];
|
|
35
|
-
if (diff.indexesToAdd?.length) {
|
|
36
|
-
for (const index of diff.indexesToAdd) {
|
|
37
|
-
statements.push(this.generateCreateIndex(diff.tableName, index));
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
return statements;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
generateAlterTableDown(diff: SchemaDiff): string[] {
|
|
44
|
-
const statements: string[] = [];
|
|
45
|
-
if (diff.indexesToAdd?.length) {
|
|
46
|
-
for (const index of diff.indexesToAdd) {
|
|
47
|
-
statements.push(this.generateDropIndex(diff.tableName, index.name));
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
return statements;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
generateCreateIndex(tableName: string, index: IndexSchema): string {
|
|
54
|
-
const key: Record<string, number> = {};
|
|
55
|
-
for (const col of index.columns) {
|
|
56
|
-
key[col] = 1;
|
|
57
|
-
}
|
|
58
|
-
return JSON.stringify({
|
|
59
|
-
action: 'createIndex',
|
|
60
|
-
collection: tableName,
|
|
61
|
-
name: index.name,
|
|
62
|
-
key,
|
|
63
|
-
options: { unique: index.unique, name: index.name },
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
generateDropIndex(tableName: string, indexName: string): string {
|
|
68
|
-
return JSON.stringify({
|
|
69
|
-
action: 'dropIndex',
|
|
70
|
-
collection: tableName,
|
|
71
|
-
name: indexName,
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
getSqlType(): string {
|
|
76
|
-
return '';
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
diffSchema<E>(entity: Type<E>, currentSchema: TableSchema | undefined): SchemaDiff | undefined {
|
|
80
|
-
const meta = getMeta(entity);
|
|
81
|
-
const collectionName = this.resolveTableName(entity, meta);
|
|
82
|
-
|
|
83
|
-
if (!currentSchema) {
|
|
84
|
-
return { tableName: collectionName, type: 'create' };
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const indexesToAdd: IndexSchema[] = [];
|
|
88
|
-
const existingIndexes = new Set(currentSchema.indexes?.map((i: IndexSchema) => i.name) ?? []);
|
|
89
|
-
|
|
90
|
-
for (const key in meta.fields) {
|
|
91
|
-
const field = meta.fields[key];
|
|
92
|
-
if (field.index) {
|
|
93
|
-
const columnName = this.resolveColumnName(key, field);
|
|
94
|
-
const indexName = typeof field.index === 'string' ? field.index : `idx_${collectionName}_${columnName}`;
|
|
95
|
-
if (!existingIndexes.has(indexName)) {
|
|
96
|
-
indexesToAdd.push({
|
|
97
|
-
name: indexName,
|
|
98
|
-
columns: [columnName],
|
|
99
|
-
unique: !!field.unique,
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
if (indexesToAdd.length === 0) {
|
|
106
|
-
return undefined;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
return {
|
|
110
|
-
tableName: collectionName,
|
|
111
|
-
type: 'alter',
|
|
112
|
-
indexesToAdd,
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'bun:test';
|
|
2
|
-
import { MysqlSchemaGenerator } from './mysqlSchemaGenerator.js';
|
|
3
|
-
|
|
4
|
-
describe('MysqlSchemaGenerator Specifics', () => {
|
|
5
|
-
const generator = new MysqlSchemaGenerator();
|
|
6
|
-
|
|
7
|
-
it('should map column types correctly', () => {
|
|
8
|
-
expect(generator.getSqlType({ columnType: 'varchar', length: 100 }, String)).toBe('VARCHAR(100)');
|
|
9
|
-
expect(generator.getSqlType({ columnType: 'text' }, String)).toBe('TEXT');
|
|
10
|
-
expect(generator.getSqlType({ columnType: 'int' }, Number)).toBe('INT');
|
|
11
|
-
expect(generator.getSqlType({ columnType: 'bigint' }, Number)).toBe('BIGINT');
|
|
12
|
-
expect(generator.getSqlType({ type: Boolean }, Boolean)).toBe('TINYINT(1)');
|
|
13
|
-
expect(generator.getSqlType({ columnType: 'decimal', precision: 10, scale: 2 }, Number)).toBe('DECIMAL(10, 2)');
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
it('should generate ALTER COLUMN statements', () => {
|
|
17
|
-
const col = {
|
|
18
|
-
name: 'age',
|
|
19
|
-
type: 'INT',
|
|
20
|
-
nullable: false,
|
|
21
|
-
defaultValue: 18,
|
|
22
|
-
isPrimaryKey: false,
|
|
23
|
-
isAutoIncrement: false,
|
|
24
|
-
isUnique: false,
|
|
25
|
-
};
|
|
26
|
-
const statements = generator.generateAlterColumnStatements('users', col, 'INT NOT NULL DEFAULT 18');
|
|
27
|
-
|
|
28
|
-
expect(statements).toEqual(['ALTER TABLE `users` MODIFY COLUMN INT NOT NULL DEFAULT 18;']);
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
it('should get table options', () => {
|
|
32
|
-
expect(generator.getTableOptions()).toContain('ENGINE=InnoDB');
|
|
33
|
-
});
|
|
34
|
-
});
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
import type { ColumnSchema, ColumnType, FieldOptions } from '../../type/index.js';
|
|
2
|
-
import { AbstractSchemaGenerator } from '../schemaGenerator.js';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* MySQL/MariaDB-specific schema generator
|
|
6
|
-
*/
|
|
7
|
-
export class MysqlSchemaGenerator extends AbstractSchemaGenerator {
|
|
8
|
-
protected readonly serialPrimaryKeyType = 'INT AUTO_INCREMENT PRIMARY KEY';
|
|
9
|
-
|
|
10
|
-
public override mapColumnType(columnType: ColumnType, field: FieldOptions): string {
|
|
11
|
-
switch (columnType) {
|
|
12
|
-
case 'int':
|
|
13
|
-
return 'INT';
|
|
14
|
-
case 'smallint':
|
|
15
|
-
return 'SMALLINT';
|
|
16
|
-
case 'bigint':
|
|
17
|
-
return 'BIGINT';
|
|
18
|
-
case 'float':
|
|
19
|
-
return 'FLOAT';
|
|
20
|
-
case 'double':
|
|
21
|
-
case 'real':
|
|
22
|
-
return 'DOUBLE';
|
|
23
|
-
case 'decimal':
|
|
24
|
-
case 'numeric':
|
|
25
|
-
if (field.precision !== undefined) {
|
|
26
|
-
if (field.scale !== undefined) {
|
|
27
|
-
return `DECIMAL(${field.precision}, ${field.scale})`;
|
|
28
|
-
}
|
|
29
|
-
return `DECIMAL(${field.precision})`;
|
|
30
|
-
}
|
|
31
|
-
return 'DECIMAL(10, 2)';
|
|
32
|
-
case 'boolean':
|
|
33
|
-
return 'TINYINT(1)';
|
|
34
|
-
case 'char':
|
|
35
|
-
return `CHAR(${field.length ?? 1})`;
|
|
36
|
-
case 'varchar':
|
|
37
|
-
return `VARCHAR(${field.length ?? 255})`;
|
|
38
|
-
case 'text':
|
|
39
|
-
return 'TEXT';
|
|
40
|
-
case 'uuid':
|
|
41
|
-
return 'CHAR(36)';
|
|
42
|
-
case 'date':
|
|
43
|
-
return 'DATE';
|
|
44
|
-
case 'time':
|
|
45
|
-
return 'TIME';
|
|
46
|
-
case 'timestamp':
|
|
47
|
-
case 'timestamptz':
|
|
48
|
-
return 'TIMESTAMP';
|
|
49
|
-
case 'json':
|
|
50
|
-
case 'jsonb':
|
|
51
|
-
return 'JSON';
|
|
52
|
-
case 'blob':
|
|
53
|
-
case 'bytea':
|
|
54
|
-
return 'BLOB';
|
|
55
|
-
case 'vector':
|
|
56
|
-
// MySQL doesn't have native vector support, use JSON
|
|
57
|
-
return 'JSON';
|
|
58
|
-
case 'serial':
|
|
59
|
-
return 'INT AUTO_INCREMENT';
|
|
60
|
-
case 'bigserial':
|
|
61
|
-
return 'BIGINT AUTO_INCREMENT';
|
|
62
|
-
default:
|
|
63
|
-
return 'TEXT';
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
public override getBooleanType(): string {
|
|
68
|
-
return 'TINYINT(1)';
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
public override generateAlterColumnStatements(
|
|
72
|
-
tableName: string,
|
|
73
|
-
column: ColumnSchema,
|
|
74
|
-
newDefinition: string,
|
|
75
|
-
): string[] {
|
|
76
|
-
return [`ALTER TABLE ${this.escapeId(tableName)} MODIFY COLUMN ${newDefinition};`];
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
public override generateColumnComment(tableName: string, columnName: string, comment: string): string {
|
|
80
|
-
const escapedComment = comment.replace(/'/g, "''");
|
|
81
|
-
return ` COMMENT '${escapedComment}'`;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
override getTableOptions<E>(): string {
|
|
85
|
-
return ' ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci';
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
override generateDropIndex(tableName: string, indexName: string): string {
|
|
89
|
-
// MySQL requires table name in DROP INDEX
|
|
90
|
-
return `DROP INDEX ${this.escapeId(indexName)} ON ${this.escapeId(tableName)};`;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'bun:test';
|
|
2
|
-
import { PostgresSchemaGenerator } from './postgresSchemaGenerator.js';
|
|
3
|
-
|
|
4
|
-
describe('PostgresSchemaGenerator Specifics', () => {
|
|
5
|
-
const generator = new PostgresSchemaGenerator();
|
|
6
|
-
|
|
7
|
-
it('should format default values correctly', () => {
|
|
8
|
-
expect(generator.formatDefaultValue('test')).toBe("'test'");
|
|
9
|
-
expect(generator.formatDefaultValue(123)).toBe('123');
|
|
10
|
-
expect(generator.formatDefaultValue(true)).toBe('TRUE');
|
|
11
|
-
expect(generator.formatDefaultValue(false)).toBe('FALSE');
|
|
12
|
-
expect(generator.formatDefaultValue(null)).toBe('NULL');
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
it('should map column types correctly', () => {
|
|
16
|
-
expect(generator.getSqlType({ columnType: 'varchar', length: 100 }, String)).toBe('VARCHAR(100)');
|
|
17
|
-
expect(generator.getSqlType({ columnType: 'text' }, String)).toBe('TEXT');
|
|
18
|
-
expect(generator.getSqlType({ columnType: 'int' }, Number)).toBe('INTEGER');
|
|
19
|
-
expect(generator.getSqlType({ columnType: 'bigint' }, Number)).toBe('BIGINT');
|
|
20
|
-
expect(generator.getSqlType({ type: Boolean }, Boolean)).toBe('BOOLEAN');
|
|
21
|
-
expect(generator.getSqlType({ columnType: 'decimal', precision: 10, scale: 2 }, Number)).toBe('NUMERIC(10, 2)');
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
it('should generate DROP INDEX statement', () => {
|
|
25
|
-
expect(generator.generateDropIndex('users', 'idx_test')).toBe('DROP INDEX IF EXISTS "idx_test";');
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
it('should generate ALTER COLUMN statements', () => {
|
|
29
|
-
const col = {
|
|
30
|
-
name: 'age',
|
|
31
|
-
type: 'INTEGER',
|
|
32
|
-
nullable: false,
|
|
33
|
-
defaultValue: 18,
|
|
34
|
-
isPrimaryKey: false,
|
|
35
|
-
isAutoIncrement: false,
|
|
36
|
-
isUnique: false,
|
|
37
|
-
};
|
|
38
|
-
const statements = generator.generateAlterColumnStatements('users', col, 'INTEGER');
|
|
39
|
-
|
|
40
|
-
expect(statements).toContain('ALTER TABLE "users" ALTER COLUMN "age" TYPE INTEGER;');
|
|
41
|
-
expect(statements).toContain('ALTER TABLE "users" ALTER COLUMN "age" SET NOT NULL;');
|
|
42
|
-
expect(statements).toContain('ALTER TABLE "users" ALTER COLUMN "age" SET DEFAULT 18;');
|
|
43
|
-
});
|
|
44
|
-
});
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
import type { ColumnSchema, ColumnType, FieldOptions, NamingStrategy } from '../../type/index.js';
|
|
2
|
-
import { AbstractSchemaGenerator } from '../schemaGenerator.js';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* PostgreSQL-specific schema generator
|
|
6
|
-
*/
|
|
7
|
-
export class PostgresSchemaGenerator extends AbstractSchemaGenerator {
|
|
8
|
-
protected readonly serialPrimaryKeyType = 'SERIAL PRIMARY KEY';
|
|
9
|
-
|
|
10
|
-
constructor(namingStrategy?: NamingStrategy) {
|
|
11
|
-
super(namingStrategy, '"');
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
public override mapColumnType(columnType: ColumnType, field: FieldOptions): string {
|
|
15
|
-
switch (columnType) {
|
|
16
|
-
case 'int':
|
|
17
|
-
return 'INTEGER';
|
|
18
|
-
case 'smallint':
|
|
19
|
-
return 'SMALLINT';
|
|
20
|
-
case 'bigint':
|
|
21
|
-
return 'BIGINT';
|
|
22
|
-
case 'float':
|
|
23
|
-
case 'double':
|
|
24
|
-
case 'real':
|
|
25
|
-
return 'DOUBLE PRECISION';
|
|
26
|
-
case 'decimal':
|
|
27
|
-
case 'numeric':
|
|
28
|
-
if (field.precision !== undefined) {
|
|
29
|
-
if (field.scale !== undefined) {
|
|
30
|
-
return `NUMERIC(${field.precision}, ${field.scale})`;
|
|
31
|
-
}
|
|
32
|
-
return `NUMERIC(${field.precision})`;
|
|
33
|
-
}
|
|
34
|
-
return 'NUMERIC';
|
|
35
|
-
case 'boolean':
|
|
36
|
-
return 'BOOLEAN';
|
|
37
|
-
case 'char':
|
|
38
|
-
return `CHAR(${field.length ?? 1})`;
|
|
39
|
-
case 'varchar':
|
|
40
|
-
return `VARCHAR(${field.length ?? 255})`;
|
|
41
|
-
case 'text':
|
|
42
|
-
return 'TEXT';
|
|
43
|
-
case 'uuid':
|
|
44
|
-
return 'UUID';
|
|
45
|
-
case 'date':
|
|
46
|
-
return 'DATE';
|
|
47
|
-
case 'time':
|
|
48
|
-
return 'TIME';
|
|
49
|
-
case 'timestamp':
|
|
50
|
-
return 'TIMESTAMP';
|
|
51
|
-
case 'timestamptz':
|
|
52
|
-
return 'TIMESTAMPTZ';
|
|
53
|
-
case 'json':
|
|
54
|
-
return 'JSON';
|
|
55
|
-
case 'jsonb':
|
|
56
|
-
return 'JSONB';
|
|
57
|
-
case 'blob':
|
|
58
|
-
case 'bytea':
|
|
59
|
-
return 'BYTEA';
|
|
60
|
-
case 'vector':
|
|
61
|
-
if (field.length) {
|
|
62
|
-
return `VECTOR(${field.length})`;
|
|
63
|
-
}
|
|
64
|
-
return 'VECTOR';
|
|
65
|
-
case 'serial':
|
|
66
|
-
return 'SERIAL';
|
|
67
|
-
case 'bigserial':
|
|
68
|
-
return 'BIGSERIAL';
|
|
69
|
-
default:
|
|
70
|
-
return 'TEXT';
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
public override getBooleanType(): string {
|
|
75
|
-
return 'BOOLEAN';
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
public override generateAlterColumnStatements(
|
|
79
|
-
tableName: string,
|
|
80
|
-
column: ColumnSchema,
|
|
81
|
-
newDefinition: string,
|
|
82
|
-
): string[] {
|
|
83
|
-
const statements: string[] = [];
|
|
84
|
-
const escapedTableName = this.escapeId(tableName);
|
|
85
|
-
const escapedColumnName = this.escapeId(column.name);
|
|
86
|
-
|
|
87
|
-
// PostgreSQL uses separate ALTER COLUMN clauses for different changes
|
|
88
|
-
// 1. Change type
|
|
89
|
-
statements.push(`ALTER TABLE ${escapedTableName} ALTER COLUMN ${escapedColumnName} TYPE ${column.type};`);
|
|
90
|
-
|
|
91
|
-
// 2. Change nullability
|
|
92
|
-
if (column.nullable) {
|
|
93
|
-
statements.push(`ALTER TABLE ${escapedTableName} ALTER COLUMN ${escapedColumnName} DROP NOT NULL;`);
|
|
94
|
-
} else {
|
|
95
|
-
statements.push(`ALTER TABLE ${escapedTableName} ALTER COLUMN ${escapedColumnName} SET NOT NULL;`);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// 3. Change default value
|
|
99
|
-
if (column.defaultValue !== undefined) {
|
|
100
|
-
statements.push(
|
|
101
|
-
`ALTER TABLE ${escapedTableName} ALTER COLUMN ${escapedColumnName} SET DEFAULT ${this.formatDefaultValue(column.defaultValue)};`,
|
|
102
|
-
);
|
|
103
|
-
} else {
|
|
104
|
-
statements.push(`ALTER TABLE ${escapedTableName} ALTER COLUMN ${escapedColumnName} DROP DEFAULT;`);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
return statements;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
public override generateColumnComment(tableName: string, columnName: string, comment: string): string {
|
|
111
|
-
// PostgreSQL handles comments separately via COMMENT ON COLUMN
|
|
112
|
-
return '';
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Generate COMMENT ON COLUMN statement for PostgreSQL
|
|
117
|
-
*/
|
|
118
|
-
generateColumnCommentStatement(tableName: string, columnName: string, comment: string): string {
|
|
119
|
-
const escapedComment = comment.replace(/'/g, "''");
|
|
120
|
-
return `COMMENT ON COLUMN ${this.escapeId(tableName)}.${this.escapeId(columnName)} IS '${escapedComment}';`;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
override generateDropIndex(tableName: string, indexName: string): string {
|
|
124
|
-
// PostgreSQL doesn't require table name in DROP INDEX
|
|
125
|
-
return `DROP INDEX IF EXISTS ${this.escapeId(indexName)};`;
|
|
126
|
-
}
|
|
127
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'bun:test';
|
|
2
|
-
import { SqliteSchemaGenerator } from './sqliteSchemaGenerator.js';
|
|
3
|
-
|
|
4
|
-
describe('SqliteSchemaGenerator Specifics', () => {
|
|
5
|
-
const generator = new SqliteSchemaGenerator();
|
|
6
|
-
|
|
7
|
-
it('should map column types correctly', () => {
|
|
8
|
-
expect(generator.getSqlType({ columnType: 'varchar', length: 100 }, String)).toBe('TEXT');
|
|
9
|
-
expect(generator.getSqlType({ columnType: 'int' }, Number)).toBe('INTEGER');
|
|
10
|
-
expect(generator.getSqlType({ type: Boolean }, Boolean)).toBe('INTEGER');
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
it('should throw error on generateAlterColumnStatements', () => {
|
|
14
|
-
const col = {
|
|
15
|
-
name: 'age',
|
|
16
|
-
type: 'INTEGER',
|
|
17
|
-
nullable: false,
|
|
18
|
-
isPrimaryKey: false,
|
|
19
|
-
isAutoIncrement: false,
|
|
20
|
-
isUnique: false,
|
|
21
|
-
};
|
|
22
|
-
expect(() => generator.generateAlterColumnStatements('users', col, 'INTEGER')).toThrow(
|
|
23
|
-
'SQLite does not support altering column',
|
|
24
|
-
);
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
it('should format default values correctly', () => {
|
|
28
|
-
expect(generator.formatDefaultValue('test')).toBe("'test'");
|
|
29
|
-
expect(generator.formatDefaultValue(123)).toBe('123');
|
|
30
|
-
expect(generator.formatDefaultValue(true)).toBe('1');
|
|
31
|
-
expect(generator.formatDefaultValue(false)).toBe('0');
|
|
32
|
-
});
|
|
33
|
-
});
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import type { ColumnSchema, ColumnType, FieldOptions } from '../../type/index.js';
|
|
2
|
-
import { AbstractSchemaGenerator } from '../schemaGenerator.js';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* SQLite-specific schema generator
|
|
6
|
-
*/
|
|
7
|
-
export class SqliteSchemaGenerator extends AbstractSchemaGenerator {
|
|
8
|
-
protected readonly serialPrimaryKeyType = 'INTEGER PRIMARY KEY AUTOINCREMENT';
|
|
9
|
-
|
|
10
|
-
public override mapColumnType(columnType: ColumnType, field: FieldOptions): string {
|
|
11
|
-
// SQLite has dynamic typing, but we use type affinity
|
|
12
|
-
switch (columnType) {
|
|
13
|
-
case 'int':
|
|
14
|
-
case 'smallint':
|
|
15
|
-
case 'bigint':
|
|
16
|
-
case 'serial':
|
|
17
|
-
case 'bigserial':
|
|
18
|
-
return 'INTEGER';
|
|
19
|
-
case 'float':
|
|
20
|
-
case 'double':
|
|
21
|
-
case 'real':
|
|
22
|
-
case 'decimal':
|
|
23
|
-
case 'numeric':
|
|
24
|
-
return 'REAL';
|
|
25
|
-
case 'boolean':
|
|
26
|
-
return 'INTEGER'; // SQLite uses 0/1 for booleans
|
|
27
|
-
case 'char':
|
|
28
|
-
case 'varchar':
|
|
29
|
-
case 'text':
|
|
30
|
-
case 'uuid':
|
|
31
|
-
return 'TEXT';
|
|
32
|
-
case 'date':
|
|
33
|
-
case 'time':
|
|
34
|
-
case 'timestamp':
|
|
35
|
-
case 'timestamptz':
|
|
36
|
-
return 'TEXT'; // SQLite stores dates as TEXT or INTEGER
|
|
37
|
-
case 'json':
|
|
38
|
-
case 'jsonb':
|
|
39
|
-
return 'TEXT'; // SQLite stores JSON as TEXT
|
|
40
|
-
case 'blob':
|
|
41
|
-
case 'bytea':
|
|
42
|
-
return 'BLOB';
|
|
43
|
-
case 'vector':
|
|
44
|
-
return 'TEXT'; // Store as JSON array
|
|
45
|
-
default:
|
|
46
|
-
return 'TEXT';
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
public override getBooleanType(): string {
|
|
51
|
-
return 'INTEGER';
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
public override generateAlterColumnStatements(
|
|
55
|
-
tableName: string,
|
|
56
|
-
column: ColumnSchema,
|
|
57
|
-
newDefinition: string,
|
|
58
|
-
): string[] {
|
|
59
|
-
// SQLite has very limited ALTER TABLE support
|
|
60
|
-
// Column type changes require recreating the table
|
|
61
|
-
throw new Error(
|
|
62
|
-
`SQLite does not support altering column '${column.name}' in table '${tableName}'. ` +
|
|
63
|
-
'You need to recreate the table to change column types.',
|
|
64
|
-
);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
public override generateColumnComment(tableName: string, columnName: string, comment: string): string {
|
|
68
|
-
return '';
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
override generateDropIndex(tableName: string, indexName: string): string {
|
|
72
|
-
return `DROP INDEX IF EXISTS ${this.escapeId(indexName)};`;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
override formatDefaultValue(value: unknown): string {
|
|
76
|
-
if (typeof value === 'boolean') {
|
|
77
|
-
return value ? '1' : '0';
|
|
78
|
-
}
|
|
79
|
-
return super.formatDefaultValue(value);
|
|
80
|
-
}
|
|
81
|
-
}
|
package/src/migrate/index.ts
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
// Core types
|
|
2
|
-
|
|
3
|
-
// Re-export core types for convenience
|
|
4
|
-
// Migration-specific types
|
|
5
|
-
export type {
|
|
6
|
-
ColumnSchema,
|
|
7
|
-
Dialect,
|
|
8
|
-
ForeignKeySchema,
|
|
9
|
-
IndexSchema,
|
|
10
|
-
Migration,
|
|
11
|
-
MigrationDefinition,
|
|
12
|
-
MigrationResult,
|
|
13
|
-
MigrationStorage,
|
|
14
|
-
MigratorOptions,
|
|
15
|
-
MongoQuerier,
|
|
16
|
-
SchemaDiff,
|
|
17
|
-
SchemaGenerator,
|
|
18
|
-
SchemaIntrospector,
|
|
19
|
-
SqlDialect,
|
|
20
|
-
SqlQuerier,
|
|
21
|
-
SqlQueryDialect,
|
|
22
|
-
TableSchema,
|
|
23
|
-
} from '../type/index.js';
|
|
24
|
-
export { isSqlQuerier } from '../type/index.js';
|
|
25
|
-
export {
|
|
26
|
-
MysqlSchemaGenerator,
|
|
27
|
-
MysqlSchemaGenerator as MariadbSchemaGenerator,
|
|
28
|
-
} from './generator/mysqlSchemaGenerator.js';
|
|
29
|
-
export { PostgresSchemaGenerator } from './generator/postgresSchemaGenerator.js';
|
|
30
|
-
export { SqliteSchemaGenerator } from './generator/sqliteSchemaGenerator.js';
|
|
31
|
-
// Schema introspection
|
|
32
|
-
export { MariadbSchemaIntrospector, MysqlSchemaIntrospector } from './introspection/mysqlIntrospector.js';
|
|
33
|
-
export { PostgresSchemaIntrospector } from './introspection/postgresIntrospector.js';
|
|
34
|
-
export { SqliteSchemaIntrospector } from './introspection/sqliteIntrospector.js';
|
|
35
|
-
// Main migrator
|
|
36
|
-
export { defineMigration, Migrator } from './migrator.js';
|
|
37
|
-
// Schema generators
|
|
38
|
-
export { AbstractSchemaGenerator } from './schemaGenerator.js';
|
|
39
|
-
// Storage implementations
|
|
40
|
-
export { DatabaseMigrationStorage } from './storage/databaseStorage.js';
|
|
41
|
-
export { JsonMigrationStorage } from './storage/jsonStorage.js';
|