@travetto/model-mysql 8.0.0-alpha.23 → 8.0.0-alpha.25
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/README.md +7 -8
- package/__index__.ts +1 -1
- package/package.json +7 -7
- package/src/connection.ts +21 -18
- package/src/dialect.ts +11 -16
- package/support/service.mysql.ts +2 -2
package/README.md
CHANGED
|
@@ -13,18 +13,18 @@ npm install @travetto/model-mysql
|
|
|
13
13
|
yarn add @travetto/model-mysql
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
This module provides a [MySQL](https://www.mysql.com/)-based implementation for the [Data Modeling Support](https://github.com/travetto/travetto/tree/main/module/model#readme "Datastore abstraction for core operations.") module.
|
|
16
|
+
This module provides a [MySQL](https://www.mysql.com/)-based implementation for the [Data Modeling Support](https://github.com/travetto/travetto/tree/main/module/model#readme "Datastore abstraction for core operations.") module. This source allows the [Data Modeling Support](https://github.com/travetto/travetto/tree/main/module/model#readme "Datastore abstraction for core operations.") module to read, write and query against [SQL](https://en.wikipedia.org/wiki/SQL) databases. In development mode, the [SQLModelService](https://github.com/travetto/travetto/tree/main/module/model-sql/src/service.ts#L69) will also modify the database schema in real time to minimize impact to development.
|
|
17
17
|
|
|
18
|
-
The schema generated will not generally map to existing tables as it is attempting to produce a document store like experience on top of a [SQL](https://en.wikipedia.org/wiki/SQL) database.
|
|
18
|
+
The schema generated will not generally map to existing tables as it is attempting to produce a document store like experience on top of a [SQL](https://en.wikipedia.org/wiki/SQL) database. Every table generated will have a `path_id` which determines it's location in the document hierarchy as well as sub tables will have a `parent_path_id` to associate records with the parent values.
|
|
19
19
|
|
|
20
20
|
Supported features:
|
|
21
|
-
* [
|
|
22
|
-
* [
|
|
23
|
-
* [Indexed](https://github.com/travetto/travetto/tree/main/module/model-indexed/src/types/service.ts#
|
|
21
|
+
* [Bulk](https://github.com/travetto/travetto/tree/main/module/model/src/types/bulk.ts#L60)
|
|
22
|
+
* [CRUD](https://github.com/travetto/travetto/tree/main/module/model/src/types/crud.ts#L10)
|
|
23
|
+
* [Indexed](https://github.com/travetto/travetto/tree/main/module/model-indexed/src/types/service.ts#L21)
|
|
24
24
|
* [Query Crud](https://github.com/travetto/travetto/tree/main/module/model-query/src/types/crud.ts#L11)
|
|
25
25
|
* [Facet](https://github.com/travetto/travetto/tree/main/module/model-query/src/types/facet.ts#L14)
|
|
26
|
-
* [Query](https://github.com/travetto/travetto/tree/main/module/model-query/src/types/query.ts#L10)
|
|
27
26
|
* [Suggest](https://github.com/travetto/travetto/tree/main/module/model-query/src/types/suggest.ts#L12)
|
|
27
|
+
* [Query](https://github.com/travetto/travetto/tree/main/module/model-query/src/types/query.ts#L10)
|
|
28
28
|
|
|
29
29
|
Out of the box, by installing the module, everything should be wired up by default.If you need to customize any aspect of the source or config, you can override and register it with the [Dependency Injection](https://github.com/travetto/travetto/tree/main/module/di#readme "Dependency registration/management and injection support.") module.
|
|
30
30
|
|
|
@@ -32,9 +32,8 @@ Out of the box, by installing the module, everything should be wired up by defau
|
|
|
32
32
|
```typescript
|
|
33
33
|
import type { AsyncContext } from '@travetto/context';
|
|
34
34
|
import { InjectableFactory } from '@travetto/di';
|
|
35
|
-
|
|
36
|
-
import { SQLModelService, type SQLModelConfig } from '@travetto/model-sql';
|
|
37
35
|
import { MySQLDialect } from '@travetto/model-mysql';
|
|
36
|
+
import { type SQLModelConfig, SQLModelService } from '@travetto/model-sql';
|
|
38
37
|
|
|
39
38
|
export class Init {
|
|
40
39
|
@InjectableFactory({ primary: true })
|
package/__index__.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/model-mysql",
|
|
3
|
-
"version": "8.0.0-alpha.
|
|
3
|
+
"version": "8.0.0-alpha.25",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "MySQL backing for the travetto model module, with real-time modeling support for SQL schemas.",
|
|
6
6
|
"keywords": [
|
|
@@ -28,15 +28,15 @@
|
|
|
28
28
|
"directory": "module/model-mysql"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@travetto/config": "^8.0.0-alpha.
|
|
32
|
-
"@travetto/context": "^8.0.0-alpha.
|
|
33
|
-
"@travetto/model": "^8.0.0-alpha.
|
|
34
|
-
"@travetto/model-query": "^8.0.0-alpha.
|
|
35
|
-
"@travetto/model-sql": "^8.0.0-alpha.
|
|
31
|
+
"@travetto/config": "^8.0.0-alpha.22",
|
|
32
|
+
"@travetto/context": "^8.0.0-alpha.20",
|
|
33
|
+
"@travetto/model": "^8.0.0-alpha.23",
|
|
34
|
+
"@travetto/model-query": "^8.0.0-alpha.24",
|
|
35
|
+
"@travetto/model-sql": "^8.0.0-alpha.25",
|
|
36
36
|
"mysql2": "^3.22.6"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
|
-
"@travetto/cli": "^8.0.0-alpha.
|
|
39
|
+
"@travetto/cli": "^8.0.0-alpha.28"
|
|
40
40
|
},
|
|
41
41
|
"peerDependenciesMeta": {
|
|
42
42
|
"@travetto/cli": {
|
package/src/connection.ts
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import { createPool } from 'mysql2';
|
|
2
|
-
import type {
|
|
2
|
+
import type { OkPacket, Pool, PoolConnection, PreparedStatementInfo, ResultSetHeader, TypeCastField } from 'mysql2/promise';
|
|
3
3
|
|
|
4
|
-
import { castTo, JSONUtil, ShutdownManager } from '@travetto/runtime';
|
|
5
4
|
import type { AsyncContext } from '@travetto/context';
|
|
6
5
|
import { ExistsError } from '@travetto/model';
|
|
7
6
|
import { Connection, type SQLModelConfig } from '@travetto/model-sql';
|
|
7
|
+
import { castTo, JSONUtil, ShutdownManager } from '@travetto/runtime';
|
|
8
8
|
|
|
9
9
|
function isSimplePacket(value: unknown): value is OkPacket | ResultSetHeader {
|
|
10
|
-
return
|
|
11
|
-
value
|
|
10
|
+
return (
|
|
11
|
+
value !== null &&
|
|
12
|
+
value !== undefined &&
|
|
13
|
+
typeof value === 'object' &&
|
|
14
|
+
'constructor' in value &&
|
|
15
|
+
(value.constructor.name === 'OkPacket' || value.constructor.name === 'ResultSetHeader')
|
|
12
16
|
);
|
|
13
17
|
}
|
|
14
18
|
|
|
@@ -16,14 +20,10 @@ function isSimplePacket(value: unknown): value is OkPacket | ResultSetHeader {
|
|
|
16
20
|
* Connection support for mysql
|
|
17
21
|
*/
|
|
18
22
|
export class MySQLConnection extends Connection<PoolConnection> {
|
|
19
|
-
|
|
20
23
|
#pool: Pool;
|
|
21
24
|
#config: SQLModelConfig;
|
|
22
25
|
|
|
23
|
-
constructor(
|
|
24
|
-
context: AsyncContext,
|
|
25
|
-
config: SQLModelConfig
|
|
26
|
-
) {
|
|
26
|
+
constructor(context: AsyncContext, config: SQLModelConfig) {
|
|
27
27
|
super(context);
|
|
28
28
|
this.#config = config;
|
|
29
29
|
}
|
|
@@ -56,7 +56,7 @@ export class MySQLConnection extends Connection<PoolConnection> {
|
|
|
56
56
|
if (typeof result === 'string' && result.charAt(0) === '{' && result.charAt(result.length - 1) === '}') {
|
|
57
57
|
try {
|
|
58
58
|
return JSONUtil.fromUTF8(result);
|
|
59
|
-
} catch {
|
|
59
|
+
} catch {}
|
|
60
60
|
}
|
|
61
61
|
break;
|
|
62
62
|
}
|
|
@@ -64,12 +64,12 @@ export class MySQLConnection extends Connection<PoolConnection> {
|
|
|
64
64
|
return result;
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
async execute<T = unknown>(pool: PoolConnection, query: string, values?: unknown[]): Promise<{ count: number
|
|
67
|
+
async execute<T = unknown>(pool: PoolConnection, query: string, values?: unknown[]): Promise<{ count: number; records: T[] }> {
|
|
68
68
|
console.debug('Executing query', { query });
|
|
69
|
-
let prepared;
|
|
69
|
+
let prepared: PreparedStatementInfo | undefined;
|
|
70
70
|
try {
|
|
71
71
|
prepared = (values?.length ?? 0) > 0 ? await pool.prepare(query) : undefined;
|
|
72
|
-
const [results
|
|
72
|
+
const [results] = await (prepared ? prepared.execute(values) : pool.query(query));
|
|
73
73
|
if (isSimplePacket(results)) {
|
|
74
74
|
return { records: [], count: results.affectedRows };
|
|
75
75
|
} else {
|
|
@@ -83,14 +83,17 @@ export class MySQLConnection extends Connection<PoolConnection> {
|
|
|
83
83
|
console.debug('Failed query', { error, query });
|
|
84
84
|
const code = error && typeof error === 'object' && 'code' in error ? error.code : undefined;
|
|
85
85
|
switch (code) {
|
|
86
|
-
case 'ER_DUP_ENTRY':
|
|
87
|
-
|
|
88
|
-
|
|
86
|
+
case 'ER_DUP_ENTRY':
|
|
87
|
+
throw new ExistsError('query', query);
|
|
88
|
+
case 'ER_DUP_KEYNAME':
|
|
89
|
+
throw new ExistsError('index', query);
|
|
90
|
+
default:
|
|
91
|
+
throw error;
|
|
89
92
|
}
|
|
90
93
|
} finally {
|
|
91
94
|
try {
|
|
92
95
|
await prepared?.close();
|
|
93
|
-
} catch {
|
|
96
|
+
} catch {}
|
|
94
97
|
}
|
|
95
98
|
}
|
|
96
99
|
|
|
@@ -101,4 +104,4 @@ export class MySQLConnection extends Connection<PoolConnection> {
|
|
|
101
104
|
release(pool: PoolConnection): void {
|
|
102
105
|
pool.release();
|
|
103
106
|
}
|
|
104
|
-
}
|
|
107
|
+
}
|
package/src/dialect.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type { SchemaFieldConfig } from '@travetto/schema';
|
|
2
|
-
import { Injectable } from '@travetto/di';
|
|
3
1
|
import type { AsyncContext } from '@travetto/context';
|
|
2
|
+
import { Injectable } from '@travetto/di';
|
|
3
|
+
import type { IndexConfig, ModelType } from '@travetto/model';
|
|
4
4
|
import type { WhereClause } from '@travetto/model-query';
|
|
5
|
-
import {
|
|
6
|
-
import type
|
|
7
|
-
import
|
|
5
|
+
import { SQLDialect, type SQLModelConfig, SQLModelUtil, type SQLTableDescription, type VisitStack } from '@travetto/model-sql';
|
|
6
|
+
import { type Class, castTo } from '@travetto/runtime';
|
|
7
|
+
import type { SchemaFieldConfig } from '@travetto/schema';
|
|
8
8
|
|
|
9
9
|
import { MySQLConnection } from './connection.ts';
|
|
10
10
|
|
|
@@ -13,7 +13,6 @@ import { MySQLConnection } from './connection.ts';
|
|
|
13
13
|
*/
|
|
14
14
|
@Injectable()
|
|
15
15
|
export class MySQLDialect extends SQLDialect {
|
|
16
|
-
|
|
17
16
|
connection: MySQLConnection;
|
|
18
17
|
tablePostfix = 'COLLATE=utf8mb4_bin ENGINE=InnoDB';
|
|
19
18
|
|
|
@@ -47,7 +46,7 @@ export class MySQLDialect extends SQLDialect {
|
|
|
47
46
|
} else {
|
|
48
47
|
// Customer operators
|
|
49
48
|
Object.assign(this.SQL_OPS, {
|
|
50
|
-
$regex: 'REGEXP'
|
|
49
|
+
$regex: 'REGEXP'
|
|
51
50
|
});
|
|
52
51
|
// Double escape
|
|
53
52
|
this.regexWordBoundary = '\\\\b';
|
|
@@ -73,7 +72,7 @@ export class MySQLDialect extends SQLDialect {
|
|
|
73
72
|
const IGNORE_FIELDS = [this.pathField.name, this.parentPathField.name, this.idxField.name].map(field => `'${field}'`);
|
|
74
73
|
const [columns, foreignKeys, indices] = await Promise.all([
|
|
75
74
|
// 1. Columns
|
|
76
|
-
this.executeSQL<{ name: string
|
|
75
|
+
this.executeSQL<{ name: string; type: string; is_not_null: boolean }>(`
|
|
77
76
|
SELECT
|
|
78
77
|
COLUMN_NAME AS name,
|
|
79
78
|
COLUMN_TYPE AS type,
|
|
@@ -86,7 +85,7 @@ export class MySQLDialect extends SQLDialect {
|
|
|
86
85
|
`),
|
|
87
86
|
|
|
88
87
|
// 2. Foreign Keys
|
|
89
|
-
this.executeSQL<{ name: string
|
|
88
|
+
this.executeSQL<{ name: string; from_column: string; to_column: string; to_table: string }>(`
|
|
90
89
|
SELECT
|
|
91
90
|
CONSTRAINT_NAME AS name,
|
|
92
91
|
COLUMN_NAME AS from_column,
|
|
@@ -99,7 +98,7 @@ export class MySQLDialect extends SQLDialect {
|
|
|
99
98
|
`),
|
|
100
99
|
|
|
101
100
|
// 3. Indices
|
|
102
|
-
this.executeSQL<{ name: string
|
|
101
|
+
this.executeSQL<{ name: string; is_unique: number; columns: string }>(`
|
|
103
102
|
SELECT
|
|
104
103
|
stat.INDEX_NAME AS name,
|
|
105
104
|
stat.NON_UNIQUE = 0 AS is_unique,
|
|
@@ -167,10 +166,6 @@ export class MySQLDialect extends SQLDialect {
|
|
|
167
166
|
* Suppress foreign key checks
|
|
168
167
|
*/
|
|
169
168
|
override getTruncateAllTablesSQL<T extends ModelType>(cls: Class<T>): string[] {
|
|
170
|
-
return [
|
|
171
|
-
'SET FOREIGN_KEY_CHECKS = 0;',
|
|
172
|
-
...super.getTruncateAllTablesSQL(cls),
|
|
173
|
-
'SET FOREIGN_KEY_CHECKS = 1;'
|
|
174
|
-
];
|
|
169
|
+
return ['SET FOREIGN_KEY_CHECKS = 0;', ...super.getTruncateAllTablesSQL(cls), 'SET FOREIGN_KEY_CHECKS = 1;'];
|
|
175
170
|
}
|
|
176
|
-
}
|
|
171
|
+
}
|
package/support/service.mysql.ts
CHANGED