@travetto/model-mysql 8.0.0-alpha.26 → 8.0.0-alpha.27

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@travetto/model-mysql",
3
- "version": "8.0.0-alpha.26",
3
+ "version": "8.0.0-alpha.27",
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.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.26",
31
+ "@travetto/config": "^8.0.0-alpha.23",
32
+ "@travetto/context": "^8.0.0-alpha.21",
33
+ "@travetto/model": "^8.0.0-alpha.24",
34
+ "@travetto/model-query": "^8.0.0-alpha.25",
35
+ "@travetto/model-sql": "^8.0.0-alpha.27",
36
36
  "mysql2": "^3.22.6"
37
37
  },
38
38
  "peerDependencies": {
39
- "@travetto/cli": "^8.0.0-alpha.28"
39
+ "@travetto/cli": "^8.0.0-alpha.29"
40
40
  },
41
41
  "peerDependenciesMeta": {
42
42
  "@travetto/cli": {
package/src/connection.ts CHANGED
@@ -3,7 +3,7 @@ import type { OkPacket, Pool, PoolConnection, ResultSetHeader, TypeCastField } f
3
3
 
4
4
  import type { AsyncContext } from '@travetto/context';
5
5
  import { Injectable } from '@travetto/di';
6
- import { ExistsError, type ModelType } from '@travetto/model';
6
+ import { ExistsError, type ModelType, UniqueError } from '@travetto/model';
7
7
  import { SQLConnection, type TableContext } from '@travetto/model-sql';
8
8
  import { type Class, castTo, JSONUtil, ShutdownManager } from '@travetto/runtime';
9
9
 
@@ -113,8 +113,12 @@ export class MysqlConnection extends SQLConnection<PoolConnection> {
113
113
  } catch (error) {
114
114
  const code = error && typeof error === 'object' && 'code' in error ? error.code : undefined;
115
115
  switch (code) {
116
- case 'ER_DUP_ENTRY':
117
- throw new ExistsError('query', query);
116
+ case 'ER_DUP_ENTRY': {
117
+ const message = error instanceof Error ? error.message : '';
118
+ const match = message.match(/for key '([^']+)'/);
119
+ const key = match ? match[1] : 'query';
120
+ throw new UniqueError('query', key, { message, query });
121
+ }
118
122
  case 'ER_DUP_KEYNAME':
119
123
  throw new ExistsError('index', query);
120
124
  default:
package/src/dialect.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { AbstractANSI99Dialect, type JSONSqlPathMode, type TableContext } from '@travetto/model-sql';
1
+ import { AbstractANSI99Dialect, type JSONSqlPathMode, type ResolvedPathContext, type TableContext } from '@travetto/model-sql';
2
2
  import { type Class, castTo, JSONUtil } from '@travetto/runtime';
3
3
  import type { SchemaFieldConfig } from '@travetto/schema';
4
4
 
@@ -64,38 +64,35 @@ export class MysqlDialect extends AbstractANSI99Dialect {
64
64
  }
65
65
  }
66
66
 
67
- compileArrayAll(
68
- sqlPath: string,
69
- identifier: string,
70
- value: unknown[],
71
- field: SchemaFieldConfig,
72
- topLevel?: boolean
73
- ): { sql: string; formatted: unknown } {
74
- return { sql: `JSON_CONTAINS(${sqlPath}, ${identifier})`, formatted: JSONUtil.toUTF8(value) };
67
+ #getArraySqlPath(context: ResolvedPathContext): string {
68
+ if (!context.arrayPath || context.arrayPath.length === 0 || !context.subPath || context.subPath.length === 0) {
69
+ return context.sqlPath;
70
+ }
71
+ const columnName = this.escapeIdentifier(context.arrayPath[0]);
72
+ const arrayPathPart = context.arrayPath.length > 1 ? context.arrayPath.slice(1).join('.') : '';
73
+ const jsonPathExpr = arrayPathPart ? `$.${arrayPathPart}[*].${context.subPath.join('.')}` : `$[*].${context.subPath.join('.')}`;
74
+ return `JSON_EXTRACT(${columnName}, '${jsonPathExpr}')`;
75
+ }
76
+
77
+ compileArrayAll(context: ResolvedPathContext, identifier: string, value: unknown[]): { sql: string; formatted: unknown } {
78
+ const targetSqlPath = this.#getArraySqlPath(context);
79
+ return { sql: `JSON_CONTAINS(${targetSqlPath}, ${identifier})`, formatted: JSONUtil.toUTF8(value) };
75
80
  }
76
81
 
77
- compileArrayEquals(
78
- sqlPath: string,
79
- identifier: string,
80
- values: unknown,
81
- field: SchemaFieldConfig,
82
- topLevel?: boolean
83
- ): { sql: string; formatted: unknown } {
84
- return { sql: `JSON_CONTAINS(${sqlPath}, ${identifier})`, formatted: JSONUtil.toUTF8(values) };
82
+ compileArrayEquals(context: ResolvedPathContext, identifier: string, values: unknown): { sql: string; formatted: unknown } {
83
+ const targetSqlPath = this.#getArraySqlPath(context);
84
+ const val = context.subPath?.length && !Array.isArray(values) ? [values] : values;
85
+ return { sql: `JSON_CONTAINS(${targetSqlPath}, ${identifier})`, formatted: JSONUtil.toUTF8(val) };
85
86
  }
86
87
 
87
- compileArrayAny(
88
- sqlPath: string,
89
- identifier: string,
90
- values: unknown[],
91
- field: SchemaFieldConfig,
92
- topLevel?: boolean
93
- ): { sql: string; formatted: unknown } {
94
- return { sql: `JSON_OVERLAPS(${sqlPath}, ${identifier})`, formatted: JSONUtil.toUTF8(values) };
88
+ compileArrayAny(context: ResolvedPathContext, identifier: string, values: unknown[]): { sql: string; formatted: unknown } {
89
+ const targetSqlPath = this.#getArraySqlPath(context);
90
+ return { sql: `JSON_OVERLAPS(${targetSqlPath}, ${identifier})`, formatted: JSONUtil.toUTF8(values) };
95
91
  }
96
92
 
97
- compileArrayExists(sqlPath: string, identifier: string, field: SchemaFieldConfig, topLevel?: boolean): { sql: string } {
98
- return { sql: `(${sqlPath} IS NOT NULL AND JSON_LENGTH(${sqlPath}) > 0)` };
93
+ compileArrayExists(context: ResolvedPathContext, identifier?: string): { sql: string } {
94
+ const targetSqlPath = this.#getArraySqlPath(context);
95
+ return { sql: `(${targetSqlPath} IS NOT NULL AND JSON_LENGTH(${targetSqlPath}) > 0)` };
99
96
  }
100
97
 
101
98
  compileJsonEquality(sqlPath: string, identifier: string): string {