@travetto/model-mysql 3.0.0-rc.1 → 3.0.0-rc.11

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 CHANGED
@@ -1,5 +1,5 @@
1
1
  <!-- This file was generated by @travetto/doc and should not be modified directly -->
2
- <!-- Please modify https://github.com/travetto/travetto/tree/main/module/model-mysql/doc.ts and execute "npx trv doc" to rebuild -->
2
+ <!-- Please modify https://github.com/travetto/travetto/tree/main/module/model-mysql/DOC.ts and execute "npx trv doc" to rebuild -->
3
3
  # MySQL Model Service
4
4
  ## MySQL backing for the travetto model module, with real-time modeling support for SQL schemas.
5
5
 
@@ -16,7 +16,7 @@ a [SQL](https://en.wikipedia.org/wiki/SQL) database. Every table generated will
16
16
  Supported features:
17
17
 
18
18
  * [CRUD](https://github.com/travetto/travetto/tree/main/module/model/src/service/crud.ts#L11)
19
- * [Bulk](https://github.com/travetto/travetto/tree/main/module/model/src/service/bulk.ts#L23)
19
+ * [Bulk](https://github.com/travetto/travetto/tree/main/module/model/src/service/bulk.ts#L19)
20
20
  * [Query Crud](https://github.com/travetto/travetto/tree/main/module/model-query/src/service/crud.ts#L11)
21
21
  * [Facet](https://github.com/travetto/travetto/tree/main/module/model-query/src/service/facet.ts#L12)
22
22
  * [Query](https://github.com/travetto/travetto/tree/main/module/model-query/src/service/query.ts#L10)
@@ -53,7 +53,7 @@ import { Config } from '@travetto/config';
53
53
  * SQL Model Config
54
54
  */
55
55
  @Config('model.sql')
56
- export class SQLModelConfig {
56
+ export class SQLModelConfig<T extends {} = {}> {
57
57
  /**
58
58
  * Host to connect to
59
59
  */
@@ -89,9 +89,10 @@ export class SQLModelConfig {
89
89
  /**
90
90
  * Raw client options
91
91
  */
92
- options = {};
92
+
93
+ options: T = {} as T;
93
94
  }
94
95
  ```
95
96
 
96
- Additionally, you can see that the class is registered with the [@Config](https://github.com/travetto/travetto/tree/main/module/config/src/decorator.ts#L9) annotation, and so these values can be overridden using the
97
- standard [Configuration](https://github.com/travetto/travetto/tree/main/module/config#readme "Environment-aware config management using yaml files")resolution paths.
97
+ Additionally, you can see that the class is registered with the [@Config](https://github.com/travetto/travetto/tree/main/module/config/src/decorator.ts#L13) annotation, and so these values can be overridden using the
98
+ standard [Configuration](https://github.com/travetto/travetto/tree/main/module/config#readme "Configuration support")resolution paths.
File without changes
package/package.json CHANGED
@@ -1,7 +1,6 @@
1
1
  {
2
2
  "name": "@travetto/model-mysql",
3
- "displayName": "MySQL Model Service",
4
- "version": "3.0.0-rc.1",
3
+ "version": "3.0.0-rc.11",
5
4
  "description": "MySQL backing for the travetto model module, with real-time modeling support for SQL schemas.",
6
5
  "keywords": [
7
6
  "sql",
@@ -18,26 +17,34 @@
18
17
  "name": "Travetto Framework"
19
18
  },
20
19
  "files": [
21
- "index.ts",
20
+ "__index__.ts",
22
21
  "src",
23
22
  "support"
24
23
  ],
25
- "main": "index.ts",
24
+ "main": "__index__.ts",
26
25
  "repository": {
27
26
  "url": "https://github.com/travetto/travetto.git",
28
27
  "directory": "module/model-mysql"
29
28
  },
30
29
  "dependencies": {
31
- "@travetto/config": "^3.0.0-rc.1",
32
- "@travetto/context": "^3.0.0-rc.1",
33
- "@travetto/model": "^3.0.0-rc.1",
34
- "@travetto/model-query": "3.0.0-rc.1",
35
- "@travetto/model-sql": "^3.0.0-rc.1",
36
- "mysql": "^2.18.1",
37
- "@types/mysql": "^2.15.21"
30
+ "@travetto/config": "^3.0.0-rc.11",
31
+ "@travetto/context": "^3.0.0-rc.11",
32
+ "@travetto/model": "^3.0.0-rc.11",
33
+ "@travetto/model-query": "^3.0.0-rc.11",
34
+ "@travetto/model-sql": "^3.0.0-rc.11",
35
+ "@types/mysql": "^2.15.21",
36
+ "mysql2": "^3.1.0"
38
37
  },
39
- "devDependencies": {
40
- "@travetto/app": "^3.0.0-rc.1"
38
+ "peerDependencies": {
39
+ "@travetto/command": "^3.0.0-rc.8"
40
+ },
41
+ "peerDependenciesMeta": {
42
+ "@travetto/command": {
43
+ "optional": true
44
+ }
45
+ },
46
+ "travetto": {
47
+ "displayName": "MySQL Model Service"
41
48
  },
42
49
  "publishConfig": {
43
50
  "access": "public"
package/src/connection.ts CHANGED
@@ -1,10 +1,16 @@
1
- import * as mysql from 'mysql';
1
+ import mysql, { OkPacket, ResultSetHeader } from 'mysql2';
2
2
 
3
3
  import { ShutdownManager } from '@travetto/base';
4
4
  import { AsyncContext } from '@travetto/context';
5
5
  import { ExistsError } from '@travetto/model';
6
6
  import { Connection, SQLModelConfig } from '@travetto/model-sql';
7
7
 
8
+ function isSimplePacket(o: unknown): o is OkPacket | ResultSetHeader {
9
+ return o !== null && o !== undefined && typeof o === 'object' && 'constructor' in o && (
10
+ o.constructor.name === 'OkPacket' || o.constructor.name === 'ResultSetHeader'
11
+ );
12
+ }
13
+
8
14
  /**
9
15
  * Connection support for mysql
10
16
  */
@@ -28,21 +34,21 @@ export class MySQLConnection extends Connection<mysql.PoolConnection> {
28
34
  database: this.#config.database,
29
35
  host: this.#config.host,
30
36
  port: this.#config.port,
31
- timezone: 'utc',
37
+ timezone: '+00:00',
32
38
  typeCast: this.typeCast.bind(this),
33
39
  ...(this.#config.options || {})
34
40
  });
35
41
 
36
42
  // Close mysql
37
- ShutdownManager.onShutdown(this.constructor.ᚕid, () => new Promise(r => this.#pool.end(r)));
43
+ ShutdownManager.onShutdown(this, () => new Promise(r => this.#pool.end(r)));
38
44
  }
39
45
 
40
46
  /**
41
47
  * Support some basic type support for JSON data
42
48
  */
43
- typeCast(field: Parameters<Exclude<mysql.TypeCast, boolean>>[0], next: () => unknown): unknown {
49
+ typeCast(field: unknown, next: () => unknown): unknown {
44
50
  const res = next();
45
- if (typeof res === 'string' && (field.type === 'JSON' || field.type === 'BLOB')) {
51
+ if (typeof res === 'string' && (field && typeof field === 'object' && 'type' in field) && (field.type === 'JSON' || field.type === 'BLOB')) {
46
52
  if (res.charAt(0) === '{' && res.charAt(res.length - 1) === '}') {
47
53
  try {
48
54
  return JSON.parse(res);
@@ -58,14 +64,22 @@ export class MySQLConnection extends Connection<mysql.PoolConnection> {
58
64
  conn.query(query, (err, results, fields) => {
59
65
  if (err) {
60
66
  console.debug('Failed query', { error: err, query });
61
- if (err.message.startsWith('ER_DUP_ENTRY')) {
67
+ if (err.message.startsWith('Duplicate entry')) {
62
68
  rej(new ExistsError('query', query));
63
69
  } else {
64
70
  rej(err);
65
71
  }
66
72
  } else {
67
- const records: T[] = Array.isArray(results) ? [...results].map(v => ({ ...v })) : [{ ...results }];
68
- res({ records, count: results.affectedRows });
73
+ if (isSimplePacket(results)) {
74
+ return res({ records: [], count: results.affectedRows });
75
+ } else {
76
+ if (isSimplePacket(results[0])) {
77
+ return res({ records: [], count: results[0].affectedRows });
78
+ }
79
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
80
+ const records: T[] = [...results].map(v => ({ ...v }) as T);
81
+ return res({ records, count: records.length });
82
+ }
69
83
  }
70
84
  });
71
85
  });
package/src/dialect.ts CHANGED
@@ -5,7 +5,7 @@ import { WhereClause } from '@travetto/model-query';
5
5
  import { Class } from '@travetto/base';
6
6
  import { ModelType } from '@travetto/model';
7
7
  import { SQLModelConfig, SQLDialect } from '@travetto/model-sql';
8
- import { SQLDialect } from '@travetto/model-sql/srcinternal/util';
8
+ import { VisitStack } from '@travetto/model-sql/src/internal/util';
9
9
 
10
10
  import { MySQLConnection } from './connection';
11
11
 
@@ -16,18 +16,12 @@ import { MySQLConnection } from './connection';
16
16
  export class MySQLDialect extends SQLDialect {
17
17
 
18
18
  conn: MySQLConnection;
19
- tablePostfix = "COLLATE='utf8mb4_unicode_ci' ENGINE=InnoDB";
19
+ tablePostfix = 'COLLATE=utf8mb4_bin ENGINE=InnoDB';
20
20
 
21
21
  constructor(context: AsyncContext, public config: SQLModelConfig) {
22
22
  super(config.namespace);
23
23
  this.conn = new MySQLConnection(context, config);
24
24
 
25
- // Customer operators
26
- Object.assign(this.SQL_OPS, {
27
- $regex: 'REGEXP BINARY',
28
- $iregex: 'REGEXP'
29
- });
30
-
31
25
  // Custom types
32
26
  Object.assign(this.COLUMN_TYPES, {
33
27
  TIMESTAMP: 'DATETIME(3)',
@@ -35,7 +29,6 @@ export class MySQLDialect extends SQLDialect {
35
29
  });
36
30
 
37
31
  // Word boundary
38
- this.regexWordBoundary = '([[:<:]]|[[:>:]])';
39
32
  // Field maxlength
40
33
  this.idField.minlength = this.idField.maxlength = { n: this.KEY_LEN };
41
34
 
@@ -44,6 +37,25 @@ export class MySQLDialect extends SQLDialect {
44
37
  */
45
38
  if (/^5[.][56]/.test(this.config.version)) {
46
39
  this.DEFAULT_STRING_LEN = 191; // Mysql limitation with utf8 and keys
40
+ } else {
41
+ this.DEFAULT_STRING_LEN = 3072 / 4 - 1;
42
+ }
43
+
44
+ if (/^5[.].*/.test(this.config.version)) {
45
+ // Customer operators
46
+ Object.assign(this.SQL_OPS, {
47
+ $regex: 'REGEXP BINARY',
48
+ $iregex: 'REGEXP'
49
+ });
50
+
51
+ this.regexWordBoundary = '([[:<:]]|[[:>:]])';
52
+ } else {
53
+ // Customer operators
54
+ Object.assign(this.SQL_OPS, {
55
+ $regex: 'REGEXP',
56
+ });
57
+ // Double escape
58
+ this.regexWordBoundary = '\\\\b';
47
59
  }
48
60
  }
49
61
 
@@ -1,9 +1,9 @@
1
- import { EnvUtil } from '@travetto/boot';
2
- import type { Service } from '@travetto/command/bin/lib/service';
1
+ import { Env } from '@travetto/base';
2
+ import type { CommandService } from '@travetto/command';
3
3
 
4
- const version = EnvUtil.get('TRV_SERVICE_MYSQL', '5.6');
4
+ const version = Env.get('MYSQL_VERSION', '8.0');
5
5
 
6
- export const service: Service = {
6
+ export const service: CommandService = {
7
7
  name: 'mysql',
8
8
  version,
9
9
  image: `mysql:${version}`,