@carno.js/orm 0.2.3
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/LICENSE +674 -0
- package/dist/SqlBuilder.d.ts +103 -0
- package/dist/SqlBuilder.js +618 -0
- package/dist/cache/cache-key-generator.d.ts +13 -0
- package/dist/cache/cache-key-generator.js +66 -0
- package/dist/cache/query-cache-manager.d.ts +14 -0
- package/dist/cache/query-cache-manager.js +44 -0
- package/dist/common/email.vo.d.ts +4 -0
- package/dist/common/email.vo.js +11 -0
- package/dist/common/uuid.d.ts +4 -0
- package/dist/common/uuid.js +10 -0
- package/dist/common/value-object.d.ts +95 -0
- package/dist/common/value-object.js +99 -0
- package/dist/constants.d.ts +6 -0
- package/dist/constants.js +9 -0
- package/dist/decorators/computed.decorator.d.ts +1 -0
- package/dist/decorators/computed.decorator.js +12 -0
- package/dist/decorators/entity.decorator.d.ts +3 -0
- package/dist/decorators/entity.decorator.js +12 -0
- package/dist/decorators/enum.decorator.d.ts +2 -0
- package/dist/decorators/enum.decorator.js +16 -0
- package/dist/decorators/event-hook.decorator.d.ts +4 -0
- package/dist/decorators/event-hook.decorator.js +31 -0
- package/dist/decorators/index.decorator.d.ts +17 -0
- package/dist/decorators/index.decorator.js +36 -0
- package/dist/decorators/one-many.decorator.d.ts +6 -0
- package/dist/decorators/one-many.decorator.js +42 -0
- package/dist/decorators/primary-key.decorator.d.ts +2 -0
- package/dist/decorators/primary-key.decorator.js +8 -0
- package/dist/decorators/property.decorator.d.ts +24 -0
- package/dist/decorators/property.decorator.js +44 -0
- package/dist/decorators/unique.decorator.d.ts +9 -0
- package/dist/decorators/unique.decorator.js +44 -0
- package/dist/domain/base-entity.d.ts +57 -0
- package/dist/domain/base-entity.js +198 -0
- package/dist/domain/collection.d.ts +6 -0
- package/dist/domain/collection.js +15 -0
- package/dist/domain/entities.d.ts +49 -0
- package/dist/domain/entities.js +259 -0
- package/dist/domain/reference.d.ts +86 -0
- package/dist/domain/reference.js +86 -0
- package/dist/driver/bun-driver.base.d.ts +72 -0
- package/dist/driver/bun-driver.base.js +270 -0
- package/dist/driver/bun-mysql.driver.d.ts +53 -0
- package/dist/driver/bun-mysql.driver.js +256 -0
- package/dist/driver/bun-pg.driver.d.ts +52 -0
- package/dist/driver/bun-pg.driver.js +263 -0
- package/dist/driver/driver.interface.d.ts +333 -0
- package/dist/driver/driver.interface.js +2 -0
- package/dist/entry.d.ts +2 -0
- package/dist/entry.js +13 -0
- package/dist/identity-map/entity-key-generator.d.ts +10 -0
- package/dist/identity-map/entity-key-generator.js +45 -0
- package/dist/identity-map/entity-registry.d.ts +11 -0
- package/dist/identity-map/entity-registry.js +41 -0
- package/dist/identity-map/identity-map-context.d.ts +9 -0
- package/dist/identity-map/identity-map-context.js +22 -0
- package/dist/identity-map/identity-map-integration.d.ts +5 -0
- package/dist/identity-map/identity-map-integration.js +37 -0
- package/dist/identity-map/identity-map.d.ts +11 -0
- package/dist/identity-map/identity-map.js +35 -0
- package/dist/identity-map/index.d.ts +5 -0
- package/dist/identity-map/index.js +14 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.js +48 -0
- package/dist/middleware/identity-map.middleware.d.ts +4 -0
- package/dist/middleware/identity-map.middleware.js +22 -0
- package/dist/orm-session-context.d.ts +16 -0
- package/dist/orm-session-context.js +22 -0
- package/dist/orm.d.ts +20 -0
- package/dist/orm.js +69 -0
- package/dist/orm.service.d.ts +13 -0
- package/dist/orm.service.js +361 -0
- package/dist/query/index-condition-builder.d.ts +41 -0
- package/dist/query/index-condition-builder.js +235 -0
- package/dist/query/model-transformer.d.ts +27 -0
- package/dist/query/model-transformer.js +201 -0
- package/dist/query/sql-column-manager.d.ts +28 -0
- package/dist/query/sql-column-manager.js +157 -0
- package/dist/query/sql-condition-builder.d.ts +51 -0
- package/dist/query/sql-condition-builder.js +264 -0
- package/dist/query/sql-join-manager.d.ts +39 -0
- package/dist/query/sql-join-manager.js +242 -0
- package/dist/query/sql-subquery-builder.d.ts +20 -0
- package/dist/query/sql-subquery-builder.js +119 -0
- package/dist/repository/Repository.d.ts +121 -0
- package/dist/repository/Repository.js +174 -0
- package/dist/testing/index.d.ts +1 -0
- package/dist/testing/index.js +17 -0
- package/dist/testing/with-database.d.ts +20 -0
- package/dist/testing/with-database.js +311 -0
- package/dist/transaction/transaction-context.d.ts +10 -0
- package/dist/transaction/transaction-context.js +19 -0
- package/dist/utils/value-processor.d.ts +14 -0
- package/dist/utils/value-processor.js +94 -0
- package/dist/utils.d.ts +3 -0
- package/dist/utils.js +24 -0
- package/package.json +59 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Reference = void 0;
|
|
4
|
+
exports.ref = ref;
|
|
5
|
+
exports.unwrap = unwrap;
|
|
6
|
+
exports.isLoaded = isLoaded;
|
|
7
|
+
exports.refById = refById;
|
|
8
|
+
/**
|
|
9
|
+
* Creates a reference to an entity.
|
|
10
|
+
* This is an identity function - it returns the input unchanged.
|
|
11
|
+
* Useful for explicit ref creation when needed.
|
|
12
|
+
*
|
|
13
|
+
* @param entity - The entity to wrap in a reference
|
|
14
|
+
* @returns The same entity (identity function)
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* const user = new User();
|
|
19
|
+
* const userRef = ref(user); // userRef === user (same reference)
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
function ref(entity) {
|
|
23
|
+
return entity;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Unwraps a reference to get the underlying entity.
|
|
27
|
+
* This is an identity function - it returns the input unchanged.
|
|
28
|
+
* Provided for API consistency and explicitness.
|
|
29
|
+
*
|
|
30
|
+
* @param reference - The reference to unwrap
|
|
31
|
+
* @returns The underlying entity (same as input)
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```typescript
|
|
35
|
+
* const post = await Post.findOne({ id: 1 });
|
|
36
|
+
* const author = unwrap(post.author); // author === post.author
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
function unwrap(reference) {
|
|
40
|
+
return reference;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Type guard to check if a value is not null or undefined.
|
|
44
|
+
* Useful when working with optional references.
|
|
45
|
+
*
|
|
46
|
+
* @param value - The value to check
|
|
47
|
+
* @returns True if value is not null/undefined
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```typescript
|
|
51
|
+
* const post = await Post.findOne({ id: 1 });
|
|
52
|
+
* if (isLoaded(post.author)) {
|
|
53
|
+
* console.log(post.author.name); // TypeScript knows author is defined
|
|
54
|
+
* }
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
function isLoaded(value) {
|
|
58
|
+
return value != null;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* @deprecated Use `Ref<T>` type instead. This class is kept for backward compatibility.
|
|
62
|
+
*/
|
|
63
|
+
class Reference {
|
|
64
|
+
constructor(entity) {
|
|
65
|
+
this.entity = entity;
|
|
66
|
+
}
|
|
67
|
+
get() {
|
|
68
|
+
return this.entity;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
exports.Reference = Reference;
|
|
72
|
+
/**
|
|
73
|
+
* Creates a lightweight entity reference by class and id without hitting the DB.
|
|
74
|
+
* Useful to assign many-to-one relations when only the id is known.
|
|
75
|
+
*
|
|
76
|
+
* Example:
|
|
77
|
+
* const library = await UserLibrary.create({
|
|
78
|
+
* user: refById(User, userId),
|
|
79
|
+
* course: refById(Course, courseId),
|
|
80
|
+
* });
|
|
81
|
+
*/
|
|
82
|
+
function refById(Cls, id) {
|
|
83
|
+
const entity = new Cls();
|
|
84
|
+
entity.id = id;
|
|
85
|
+
return entity;
|
|
86
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { SQL } from "bun";
|
|
2
|
+
import { ConnectionSettings, DriverInterface, Statement, SnapshotConstraintInfo, ColDiff } from "./driver.interface";
|
|
3
|
+
export declare abstract class BunDriverBase implements Partial<DriverInterface> {
|
|
4
|
+
protected sql: SQL;
|
|
5
|
+
connectionString: string;
|
|
6
|
+
protected readonly poolOptions: {
|
|
7
|
+
max: number;
|
|
8
|
+
idleTimeout: number;
|
|
9
|
+
maxLifetime: number;
|
|
10
|
+
connectionTimeout: number;
|
|
11
|
+
};
|
|
12
|
+
abstract readonly dbType: "postgres" | "mysql";
|
|
13
|
+
constructor(options: ConnectionSettings);
|
|
14
|
+
protected buildConnectionString(options: ConnectionSettings): string;
|
|
15
|
+
protected abstract getProtocol(): string;
|
|
16
|
+
protected abstract getIdentifierQuote(): string;
|
|
17
|
+
connect(): Promise<void>;
|
|
18
|
+
protected buildPoolOptions(options: ConnectionSettings): {
|
|
19
|
+
max: number;
|
|
20
|
+
idleTimeout: number;
|
|
21
|
+
maxLifetime: number;
|
|
22
|
+
connectionTimeout: number;
|
|
23
|
+
};
|
|
24
|
+
private createSqlInstance;
|
|
25
|
+
protected validateConnection(): Promise<void>;
|
|
26
|
+
disconnect(): Promise<void>;
|
|
27
|
+
executeSql(sqlString: string): Promise<any>;
|
|
28
|
+
private getExecutionContext;
|
|
29
|
+
transaction<T>(callback: (tx: SQL) => Promise<T>): Promise<T>;
|
|
30
|
+
protected toDatabaseValue(value: unknown): string | number | boolean;
|
|
31
|
+
protected escapeString(value: string): string;
|
|
32
|
+
protected escapeIdentifier(identifier: string): string;
|
|
33
|
+
protected buildWhereClause(where: string | undefined): string;
|
|
34
|
+
protected buildOrderByClause(orderBy: string[] | undefined): string;
|
|
35
|
+
protected buildLimitClause(limit: number | undefined): string;
|
|
36
|
+
protected buildOffsetClause(offset: number | undefined): string;
|
|
37
|
+
protected quote(identifier: string): string;
|
|
38
|
+
protected buildTableIdentifier(schema: string | undefined, tableName: string): string;
|
|
39
|
+
protected buildColumnConstraints(colDiff: ColDiff): string;
|
|
40
|
+
protected abstract buildAutoIncrementType(colDiff: ColDiff): string;
|
|
41
|
+
protected abstract buildEnumType(schema: string | undefined, tableName: string, colDiff: ColDiff): {
|
|
42
|
+
beforeSql: string;
|
|
43
|
+
columnType: string;
|
|
44
|
+
};
|
|
45
|
+
protected abstract handleInsertReturn(statement: Statement<any>, result: any, sql: string, startTime: number): Promise<{
|
|
46
|
+
query: any;
|
|
47
|
+
startTime: number;
|
|
48
|
+
sql: string;
|
|
49
|
+
}>;
|
|
50
|
+
executeStatement(statement: Statement<any>): Promise<{
|
|
51
|
+
query: any;
|
|
52
|
+
startTime: number;
|
|
53
|
+
sql: string;
|
|
54
|
+
}>;
|
|
55
|
+
protected buildInsertSqlWithReturn(statement: Statement<any>): string;
|
|
56
|
+
protected abstract appendReturningClause(sql: string, statement: Statement<any>): string;
|
|
57
|
+
protected buildStatementSql(statement: Statement<any>): string;
|
|
58
|
+
protected buildBaseSql(statement: Statement<any>): string;
|
|
59
|
+
protected buildInsertSql(table: string, values: any, columns: string[] | undefined, alias: string): string;
|
|
60
|
+
protected buildUpdateSql(table: string, values: any, alias: string): string;
|
|
61
|
+
protected buildDeleteSql(table: string, alias: string): string;
|
|
62
|
+
protected buildJoinClause(statement: Statement<any>): string;
|
|
63
|
+
protected buildWhereAndOrderClauses(statement: Statement<any>): string;
|
|
64
|
+
protected buildLimitAndOffsetClause(statement: Statement<any>): string;
|
|
65
|
+
protected getForeignKeysFromConstraints(constraints: SnapshotConstraintInfo[], row: any, columnNameField: string): any[];
|
|
66
|
+
protected isForeignKeyConstraint(constraint: SnapshotConstraintInfo, columnName: string): boolean;
|
|
67
|
+
protected parseForeignKeyDefinition(consDef: string): {
|
|
68
|
+
referencedColumnName: string;
|
|
69
|
+
referencedTableName: string;
|
|
70
|
+
} | null;
|
|
71
|
+
private escapeRegex;
|
|
72
|
+
}
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BunDriverBase = void 0;
|
|
4
|
+
const bun_1 = require("bun");
|
|
5
|
+
const transaction_context_1 = require("../transaction/transaction-context");
|
|
6
|
+
class BunDriverBase {
|
|
7
|
+
constructor(options) {
|
|
8
|
+
this.connectionString = this.buildConnectionString(options);
|
|
9
|
+
this.poolOptions = this.buildPoolOptions(options);
|
|
10
|
+
}
|
|
11
|
+
buildConnectionString(options) {
|
|
12
|
+
if (options.connectionString) {
|
|
13
|
+
return options.connectionString;
|
|
14
|
+
}
|
|
15
|
+
const { host, port, username, password, database } = options;
|
|
16
|
+
const protocol = this.getProtocol();
|
|
17
|
+
return `${protocol}://${username}:${password}@${host}:${port}/${database}`;
|
|
18
|
+
}
|
|
19
|
+
async connect() {
|
|
20
|
+
if (this.sql) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
this.sql = this.createSqlInstance();
|
|
24
|
+
await this.validateConnection();
|
|
25
|
+
}
|
|
26
|
+
buildPoolOptions(options) {
|
|
27
|
+
return {
|
|
28
|
+
max: options.max ?? undefined,
|
|
29
|
+
idleTimeout: options.idleTimeout ?? undefined,
|
|
30
|
+
maxLifetime: options.maxLifetime ?? undefined,
|
|
31
|
+
connectionTimeout: options.connectionTimeout ?? undefined,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
createSqlInstance() {
|
|
35
|
+
return new bun_1.SQL({
|
|
36
|
+
url: this.connectionString,
|
|
37
|
+
max: this.poolOptions.max,
|
|
38
|
+
idleTimeout: this.poolOptions.idleTimeout,
|
|
39
|
+
maxLifetime: this.poolOptions.maxLifetime,
|
|
40
|
+
connectionTimeout: this.poolOptions.connectionTimeout,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
async validateConnection() {
|
|
44
|
+
await this.sql.unsafe("SELECT 1");
|
|
45
|
+
}
|
|
46
|
+
async disconnect() {
|
|
47
|
+
if (!this.sql) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
await this.sql.close();
|
|
51
|
+
this.sql = null;
|
|
52
|
+
}
|
|
53
|
+
async executeSql(sqlString) {
|
|
54
|
+
const context = this.getExecutionContext();
|
|
55
|
+
return await context.unsafe(sqlString);
|
|
56
|
+
}
|
|
57
|
+
getExecutionContext() {
|
|
58
|
+
const txContext = transaction_context_1.transactionContext.getContext();
|
|
59
|
+
if (txContext) {
|
|
60
|
+
return txContext;
|
|
61
|
+
}
|
|
62
|
+
if (!this.sql) {
|
|
63
|
+
throw new Error("Database not connected");
|
|
64
|
+
}
|
|
65
|
+
return this.sql;
|
|
66
|
+
}
|
|
67
|
+
async transaction(callback) {
|
|
68
|
+
if (!this.sql) {
|
|
69
|
+
throw new Error("Database not connected");
|
|
70
|
+
}
|
|
71
|
+
return await this.sql.begin(callback);
|
|
72
|
+
}
|
|
73
|
+
toDatabaseValue(value) {
|
|
74
|
+
if (value === null || value === undefined) {
|
|
75
|
+
return "NULL";
|
|
76
|
+
}
|
|
77
|
+
if (value instanceof Date) {
|
|
78
|
+
return `'${value.toISOString()}'`;
|
|
79
|
+
}
|
|
80
|
+
switch (typeof value) {
|
|
81
|
+
case "string":
|
|
82
|
+
return `'${this.escapeString(value)}'`;
|
|
83
|
+
case "number":
|
|
84
|
+
return value;
|
|
85
|
+
case "boolean":
|
|
86
|
+
return value;
|
|
87
|
+
case "object":
|
|
88
|
+
return `'${this.escapeString(JSON.stringify(value))}'`;
|
|
89
|
+
default:
|
|
90
|
+
return `'${this.escapeString(String(value))}'`;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
escapeString(value) {
|
|
94
|
+
return value.replace(/'/g, "''");
|
|
95
|
+
}
|
|
96
|
+
escapeIdentifier(identifier) {
|
|
97
|
+
return `"${identifier}"`;
|
|
98
|
+
}
|
|
99
|
+
buildWhereClause(where) {
|
|
100
|
+
if (!where) {
|
|
101
|
+
return "";
|
|
102
|
+
}
|
|
103
|
+
return ` WHERE ${where}`;
|
|
104
|
+
}
|
|
105
|
+
buildOrderByClause(orderBy) {
|
|
106
|
+
if (!orderBy || orderBy.length === 0) {
|
|
107
|
+
return "";
|
|
108
|
+
}
|
|
109
|
+
return ` ORDER BY ${orderBy.join(", ")}`;
|
|
110
|
+
}
|
|
111
|
+
buildLimitClause(limit) {
|
|
112
|
+
if (!limit) {
|
|
113
|
+
return "";
|
|
114
|
+
}
|
|
115
|
+
return ` LIMIT ${limit}`;
|
|
116
|
+
}
|
|
117
|
+
buildOffsetClause(offset) {
|
|
118
|
+
if (!offset) {
|
|
119
|
+
return "";
|
|
120
|
+
}
|
|
121
|
+
return ` OFFSET ${offset}`;
|
|
122
|
+
}
|
|
123
|
+
quote(identifier) {
|
|
124
|
+
const q = this.getIdentifierQuote();
|
|
125
|
+
return `${q}${identifier}${q}`;
|
|
126
|
+
}
|
|
127
|
+
buildTableIdentifier(schema, tableName) {
|
|
128
|
+
return schema
|
|
129
|
+
? `${this.quote(schema)}.${this.quote(tableName)}`
|
|
130
|
+
: this.quote(tableName);
|
|
131
|
+
}
|
|
132
|
+
buildColumnConstraints(colDiff) {
|
|
133
|
+
const parts = [];
|
|
134
|
+
if (!colDiff.colChanges?.nullable) {
|
|
135
|
+
parts.push("NOT NULL");
|
|
136
|
+
}
|
|
137
|
+
if (colDiff.colChanges?.primary) {
|
|
138
|
+
parts.push("PRIMARY KEY");
|
|
139
|
+
}
|
|
140
|
+
if (colDiff.colChanges?.unique) {
|
|
141
|
+
parts.push("UNIQUE");
|
|
142
|
+
}
|
|
143
|
+
if (colDiff.colChanges?.default) {
|
|
144
|
+
parts.push(`DEFAULT ${colDiff.colChanges.default}`);
|
|
145
|
+
}
|
|
146
|
+
return parts.length > 0 ? " " + parts.join(" ") : "";
|
|
147
|
+
}
|
|
148
|
+
async executeStatement(statement) {
|
|
149
|
+
const startTime = Date.now();
|
|
150
|
+
const context = this.getExecutionContext();
|
|
151
|
+
if (statement.statement === "insert") {
|
|
152
|
+
const sql = this.buildInsertSqlWithReturn(statement);
|
|
153
|
+
const result = await context.unsafe(sql);
|
|
154
|
+
return this.handleInsertReturn(statement, result, sql, startTime);
|
|
155
|
+
}
|
|
156
|
+
const sql = this.buildStatementSql(statement);
|
|
157
|
+
const result = await context.unsafe(sql);
|
|
158
|
+
return {
|
|
159
|
+
query: { rows: Array.isArray(result) ? result : [] },
|
|
160
|
+
startTime,
|
|
161
|
+
sql,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
buildInsertSqlWithReturn(statement) {
|
|
165
|
+
const baseSql = this.buildInsertSql(statement.table, statement.values, statement.columns, statement.alias);
|
|
166
|
+
return this.appendReturningClause(baseSql, statement);
|
|
167
|
+
}
|
|
168
|
+
buildStatementSql(statement) {
|
|
169
|
+
let sql = this.buildBaseSql(statement);
|
|
170
|
+
sql += this.buildJoinClause(statement);
|
|
171
|
+
sql += this.buildWhereAndOrderClauses(statement);
|
|
172
|
+
return sql;
|
|
173
|
+
}
|
|
174
|
+
buildBaseSql(statement) {
|
|
175
|
+
const { statement: type, table, columns, values, alias } = statement;
|
|
176
|
+
switch (type) {
|
|
177
|
+
case "select":
|
|
178
|
+
return `SELECT ${columns ? columns.join(", ") : "*"} FROM ${table} ${alias}`;
|
|
179
|
+
case "insert":
|
|
180
|
+
return this.buildInsertSql(table, values, columns, alias);
|
|
181
|
+
case "update":
|
|
182
|
+
return this.buildUpdateSql(table, values, alias);
|
|
183
|
+
case "delete":
|
|
184
|
+
return this.buildDeleteSql(table, alias);
|
|
185
|
+
case "count":
|
|
186
|
+
return `SELECT COUNT(*) as count FROM ${table} ${alias}`;
|
|
187
|
+
default:
|
|
188
|
+
return "";
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
buildInsertSql(table, values, columns, alias) {
|
|
192
|
+
const q = this.getIdentifierQuote();
|
|
193
|
+
const fields = Object.keys(values)
|
|
194
|
+
.map((v) => `${q}${v}${q}`)
|
|
195
|
+
.join(", ");
|
|
196
|
+
const vals = Object.values(values)
|
|
197
|
+
.map((value) => this.toDatabaseValue(value))
|
|
198
|
+
.join(", ");
|
|
199
|
+
return `INSERT INTO ${table} (${fields}) VALUES (${vals})`;
|
|
200
|
+
}
|
|
201
|
+
buildUpdateSql(table, values, alias) {
|
|
202
|
+
const sets = Object.entries(values)
|
|
203
|
+
.map(([key, value]) => `${key} = ${this.toDatabaseValue(value)}`)
|
|
204
|
+
.join(", ");
|
|
205
|
+
return `UPDATE ${table} as ${alias} SET ${sets}`;
|
|
206
|
+
}
|
|
207
|
+
buildDeleteSql(table, alias) {
|
|
208
|
+
return `DELETE FROM ${table} AS ${alias}`;
|
|
209
|
+
}
|
|
210
|
+
buildJoinClause(statement) {
|
|
211
|
+
if (!statement.join)
|
|
212
|
+
return "";
|
|
213
|
+
return statement.join
|
|
214
|
+
.map((join) => {
|
|
215
|
+
const table = `${join.joinSchema}.${join.joinTable}`;
|
|
216
|
+
return ` ${join.type} JOIN ${table} ${join.joinAlias} ON ${join.on}`;
|
|
217
|
+
})
|
|
218
|
+
.join("");
|
|
219
|
+
}
|
|
220
|
+
buildWhereAndOrderClauses(statement) {
|
|
221
|
+
if (statement.statement === "insert")
|
|
222
|
+
return "";
|
|
223
|
+
let sql = this.buildWhereClause(statement.where);
|
|
224
|
+
sql += this.buildOrderByClause(statement.orderBy);
|
|
225
|
+
sql += this.buildLimitAndOffsetClause(statement);
|
|
226
|
+
return sql;
|
|
227
|
+
}
|
|
228
|
+
buildLimitAndOffsetClause(statement) {
|
|
229
|
+
const { offset, limit } = statement;
|
|
230
|
+
if (offset && limit) {
|
|
231
|
+
return this.buildOffsetClause(offset) + this.buildLimitClause(limit);
|
|
232
|
+
}
|
|
233
|
+
if (limit) {
|
|
234
|
+
return this.buildLimitClause(limit);
|
|
235
|
+
}
|
|
236
|
+
return "";
|
|
237
|
+
}
|
|
238
|
+
getForeignKeysFromConstraints(constraints, row, columnNameField) {
|
|
239
|
+
const columnName = row[columnNameField];
|
|
240
|
+
return constraints
|
|
241
|
+
.filter((c) => this.isForeignKeyConstraint(c, columnName))
|
|
242
|
+
.map((c) => this.parseForeignKeyDefinition(c.consDef))
|
|
243
|
+
.filter(Boolean);
|
|
244
|
+
}
|
|
245
|
+
isForeignKeyConstraint(constraint, columnName) {
|
|
246
|
+
return (constraint.type === "FOREIGN KEY" &&
|
|
247
|
+
constraint.consDef.includes(columnName));
|
|
248
|
+
}
|
|
249
|
+
parseForeignKeyDefinition(consDef) {
|
|
250
|
+
const quote = this.getIdentifierQuote();
|
|
251
|
+
const escapedQuote = this.escapeRegex(quote);
|
|
252
|
+
const pattern = new RegExp(`REFERENCES\\s+(?:${escapedQuote}([^${escapedQuote}]+)${escapedQuote}|([\\w.]+))\\s*\\(([^)]+)\\)`, "i");
|
|
253
|
+
const match = consDef.match(pattern);
|
|
254
|
+
if (!match)
|
|
255
|
+
return null;
|
|
256
|
+
const tableName = (match[1] || match[2]).trim();
|
|
257
|
+
const columnName = match[3]
|
|
258
|
+
.split(",")[0]
|
|
259
|
+
.trim()
|
|
260
|
+
.replace(new RegExp(escapedQuote, "g"), "");
|
|
261
|
+
return {
|
|
262
|
+
referencedColumnName: columnName,
|
|
263
|
+
referencedTableName: tableName,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
escapeRegex(str) {
|
|
267
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
exports.BunDriverBase = BunDriverBase;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { ColDiff, ConnectionSettings, DriverInterface, ForeignKeyInfo, IndexStatement, SnapshotConstraintInfo, SnapshotIndexInfo, SnapshotTable, Statement } from './driver.interface';
|
|
2
|
+
import { BunDriverBase } from './bun-driver.base';
|
|
3
|
+
export declare class BunMysqlDriver extends BunDriverBase implements DriverInterface {
|
|
4
|
+
readonly dbType: "mysql";
|
|
5
|
+
constructor(options: ConnectionSettings);
|
|
6
|
+
protected getProtocol(): string;
|
|
7
|
+
protected getIdentifierQuote(): string;
|
|
8
|
+
protected buildAutoIncrementType(colDiff: ColDiff): string;
|
|
9
|
+
protected buildEnumType(schema: string | undefined, tableName: string, colDiff: ColDiff): {
|
|
10
|
+
beforeSql: string;
|
|
11
|
+
columnType: string;
|
|
12
|
+
};
|
|
13
|
+
protected appendReturningClause(sql: string, statement: Statement<any>): string;
|
|
14
|
+
protected handleInsertReturn(statement: Statement<any>, result: any, sql: string, startTime: number): Promise<{
|
|
15
|
+
query: any;
|
|
16
|
+
startTime: number;
|
|
17
|
+
sql: string;
|
|
18
|
+
}>;
|
|
19
|
+
protected buildLimitAndOffsetClause(statement: Statement<any>): string;
|
|
20
|
+
getCreateTableInstruction(schema: string | undefined, tableName: string, creates: ColDiff[]): string;
|
|
21
|
+
getAlterTableFkInstruction(schema: string | undefined, tableName: string, colDiff: ColDiff, fk: ForeignKeyInfo): string;
|
|
22
|
+
getCreateIndex(index: IndexStatement, schema: string | undefined, tableName: string): string;
|
|
23
|
+
getAddColumn(schema: string | undefined, tableName: string, colName: string, colDiff: ColDiff, colDiffInstructions: string[]): void;
|
|
24
|
+
getDropColumn(colDiffInstructions: string[], schema: string | undefined, tableName: string, colName: string): void;
|
|
25
|
+
getDropIndex(index: {
|
|
26
|
+
name: string;
|
|
27
|
+
properties?: string[];
|
|
28
|
+
}, schema: string | undefined, tableName: string): string;
|
|
29
|
+
getCreateUniqueConstraint(unique: {
|
|
30
|
+
name: string;
|
|
31
|
+
properties?: string[];
|
|
32
|
+
}, schema: string | undefined, tableName: string): string;
|
|
33
|
+
getDropUniqueConstraint(unique: {
|
|
34
|
+
name: string;
|
|
35
|
+
}, schema: string | undefined, tableName: string): string;
|
|
36
|
+
getAlterTableType(schema: string | undefined, tableName: string, colName: string, colDiff: ColDiff): string;
|
|
37
|
+
getAlterTableDefaultInstruction(schema: string | undefined, tableName: string, colName: string, colDiff: ColDiff): string;
|
|
38
|
+
getAlterTablePrimaryKeyInstruction(schema: string | undefined, tableName: string, colName: string, colDiff: ColDiff): string;
|
|
39
|
+
getDropConstraint(param: {
|
|
40
|
+
name: string;
|
|
41
|
+
}, schema: string | undefined, tableName: string): string;
|
|
42
|
+
getAddUniqueConstraint(schema: string | undefined, tableName: string, colName: string): string;
|
|
43
|
+
getAlterTableDropNullInstruction(schema: string | undefined, tableName: string, colName: string, colDiff: ColDiff): string;
|
|
44
|
+
getAlterTableDropNotNullInstruction(schema: string | undefined, tableName: string, colName: string, colDiff: ColDiff): string;
|
|
45
|
+
getAlterTableEnumInstruction(schema: string, tableName: string, colName: string, colDiff: ColDiff): string;
|
|
46
|
+
getDropTypeEnumInstruction(param: {
|
|
47
|
+
name: string;
|
|
48
|
+
}, schema: string | undefined, tableName: string): string;
|
|
49
|
+
snapshot(tableName: string, options: any): Promise<SnapshotTable | undefined>;
|
|
50
|
+
private parseEnumValues;
|
|
51
|
+
index(tableName: string, options: any): Promise<SnapshotIndexInfo[] | undefined>;
|
|
52
|
+
constraints(tableName: string, options: any): Promise<SnapshotConstraintInfo[] | undefined>;
|
|
53
|
+
}
|