@dyrected/db-mysql 2.16.0 → 2.17.0

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/dist/index.cjs CHANGED
@@ -85,6 +85,7 @@ var MysqlAdapter = class {
85
85
  inTransaction = false;
86
86
  tableLocks = /* @__PURE__ */ new Map();
87
87
  ensuredTables = /* @__PURE__ */ new Set();
88
+ failedIndexes = /* @__PURE__ */ new Set();
88
89
  tableColumnsCache = /* @__PURE__ */ new Map();
89
90
  collectionConfigs = /* @__PURE__ */ new Map();
90
91
  constructor(config) {
@@ -388,7 +389,7 @@ FIX INSTRUCTIONS:
388
389
  for (const field of fields) {
389
390
  if (field.unique) {
390
391
  const idxName = `uniq_${tableName}_${field.name}`;
391
- if (!existingIndexNames.has(idxName) && !existingIndexNames.has(field.name)) {
392
+ if (!existingIndexNames.has(idxName) && !existingIndexNames.has(field.name) && !this.failedIndexes.has(idxName)) {
392
393
  try {
393
394
  const [colInfoRows] = await this.query(`SHOW COLUMNS FROM \`${tableName}\` WHERE Field = ?`, [field.name]);
394
395
  const colType = colInfoRows?.[0]?.Type?.toLowerCase() || "";
@@ -402,7 +403,14 @@ FIX INSTRUCTIONS:
402
403
  existingIndexNames.add(idxName);
403
404
  } catch (err) {
404
405
  if (err.errno !== 1061 && err.code !== "ER_DUP_KEYNAME") {
405
- console.warn(`[dyrected/mysql] Could not create unique index ${idxName} on ${tableName}:`, err.message);
406
+ this.failedIndexes.add(idxName);
407
+ if (err.errno === 1062 || err.code === "ER_DUP_ENTRY") {
408
+ console.warn(
409
+ `[dyrected/mysql] Could not create unique index ${idxName} on ${tableName} because duplicate values already exist: ${err.message}. To enforce uniqueness, remove duplicate records.`
410
+ );
411
+ } else {
412
+ console.warn(`[dyrected/mysql] Could not create unique index ${idxName} on ${tableName}:`, err.message);
413
+ }
406
414
  }
407
415
  }
408
416
  }
@@ -413,7 +421,7 @@ FIX INSTRUCTIONS:
413
421
  if (!Array.isArray(idx.fields) || idx.fields.length === 0) continue;
414
422
  const isUnique = Boolean(idx.unique);
415
423
  const idxName = idx.name || `${isUnique ? "uniq" : "idx"}_${tableName}_${idx.fields.join("_")}`;
416
- if (!existingIndexNames.has(idxName)) {
424
+ if (!existingIndexNames.has(idxName) && !this.failedIndexes.has(idxName)) {
417
425
  for (const fName of idx.fields) {
418
426
  try {
419
427
  const [colInfoRows] = await this.query(`SHOW COLUMNS FROM \`${tableName}\` WHERE Field = ?`, [fName]);
@@ -431,7 +439,14 @@ FIX INSTRUCTIONS:
431
439
  existingIndexNames.add(idxName);
432
440
  } catch (err) {
433
441
  if (err.errno !== 1061 && err.code !== "ER_DUP_KEYNAME") {
434
- console.warn(`[dyrected/mysql] Could not create index ${idxName} on ${tableName}:`, err.message);
442
+ this.failedIndexes.add(idxName);
443
+ if (err.errno === 1062 || err.code === "ER_DUP_ENTRY") {
444
+ console.warn(
445
+ `[dyrected/mysql] Could not create ${isUnique ? "unique " : ""}index ${idxName} on ${tableName} because duplicate values already exist: ${err.message}. To enforce uniqueness, remove duplicate records.`
446
+ );
447
+ } else {
448
+ console.warn(`[dyrected/mysql] Could not create index ${idxName} on ${tableName}:`, err.message);
449
+ }
435
450
  }
436
451
  }
437
452
  }
@@ -730,7 +745,7 @@ FIX INSTRUCTIONS:
730
745
  const base = toFieldExpr(rawField);
731
746
  if (cast === "string") return base;
732
747
  if (cast === "boolean") return `IF(${base} IS NOT NULL, IF(${base} IN ('true','1'), 1, 0), NULL)`;
733
- if (cast === "date") return `CAST(${base} AS DATETIME)`;
748
+ if (cast === "date") return `IF(${base} REGEXP '^[0-9]{4}-[0-9]{2}-[0-9]{2}', CAST(${base} AS DATETIME), NULL)`;
734
749
  const sqlType = cast === "integer" ? "SIGNED" : "DECIMAL(20,6)";
735
750
  return `IF(${base} REGEXP '^-?[0-9]+(\\\\.[0-9]+)?([eE][+-]?[0-9]+)?$', CAST(${base} AS ${sqlType}), NULL)`;
736
751
  };
@@ -800,11 +815,16 @@ FIX INSTRUCTIONS:
800
815
  const result = {};
801
816
  for (const name of Object.keys(args.aggregates)) {
802
817
  const raw = row[name];
818
+ const op = args.aggregates[name];
803
819
  if (isDistinctMap[name]) {
804
820
  const parsed = Array.isArray(raw) ? raw : typeof raw === "string" ? JSON.parse(raw) : raw ?? [];
805
821
  result[name] = Array.isArray(parsed) ? parsed.filter((v) => v !== null && v !== void 0) : [];
822
+ } else if (raw instanceof Date) {
823
+ result[name] = raw.toISOString();
824
+ } else if (op?.cast === "date") {
825
+ result[name] = raw === null || raw === void 0 ? null : String(raw);
806
826
  } else {
807
- result[name] = raw === null || raw === void 0 ? null : Number(raw);
827
+ result[name] = raw === null || raw === void 0 ? null : isNaN(Number(raw)) ? raw : Number(raw);
808
828
  }
809
829
  }
810
830
  return result;
@@ -814,6 +834,7 @@ FIX INSTRUCTIONS:
814
834
  const cacheKey = getMysqlCacheKey(this.config);
815
835
  cache.delete(cacheKey);
816
836
  this.ensuredTables.clear();
837
+ this.failedIndexes.clear();
817
838
  this.tableColumnsCache.clear();
818
839
  if (this.initPromise) {
819
840
  try {
package/dist/index.d.cts CHANGED
@@ -19,6 +19,7 @@ declare class MysqlAdapter implements DatabaseAdapter {
19
19
  private inTransaction;
20
20
  private tableLocks;
21
21
  private ensuredTables;
22
+ private failedIndexes;
22
23
  private tableColumnsCache;
23
24
  private collectionConfigs;
24
25
  constructor(config: MysqlAdapterConfig);
package/dist/index.d.ts CHANGED
@@ -19,6 +19,7 @@ declare class MysqlAdapter implements DatabaseAdapter {
19
19
  private inTransaction;
20
20
  private tableLocks;
21
21
  private ensuredTables;
22
+ private failedIndexes;
22
23
  private tableColumnsCache;
23
24
  private collectionConfigs;
24
25
  constructor(config: MysqlAdapterConfig);
package/dist/index.js CHANGED
@@ -49,6 +49,7 @@ var MysqlAdapter = class {
49
49
  inTransaction = false;
50
50
  tableLocks = /* @__PURE__ */ new Map();
51
51
  ensuredTables = /* @__PURE__ */ new Set();
52
+ failedIndexes = /* @__PURE__ */ new Set();
52
53
  tableColumnsCache = /* @__PURE__ */ new Map();
53
54
  collectionConfigs = /* @__PURE__ */ new Map();
54
55
  constructor(config) {
@@ -352,7 +353,7 @@ FIX INSTRUCTIONS:
352
353
  for (const field of fields) {
353
354
  if (field.unique) {
354
355
  const idxName = `uniq_${tableName}_${field.name}`;
355
- if (!existingIndexNames.has(idxName) && !existingIndexNames.has(field.name)) {
356
+ if (!existingIndexNames.has(idxName) && !existingIndexNames.has(field.name) && !this.failedIndexes.has(idxName)) {
356
357
  try {
357
358
  const [colInfoRows] = await this.query(`SHOW COLUMNS FROM \`${tableName}\` WHERE Field = ?`, [field.name]);
358
359
  const colType = colInfoRows?.[0]?.Type?.toLowerCase() || "";
@@ -366,7 +367,14 @@ FIX INSTRUCTIONS:
366
367
  existingIndexNames.add(idxName);
367
368
  } catch (err) {
368
369
  if (err.errno !== 1061 && err.code !== "ER_DUP_KEYNAME") {
369
- console.warn(`[dyrected/mysql] Could not create unique index ${idxName} on ${tableName}:`, err.message);
370
+ this.failedIndexes.add(idxName);
371
+ if (err.errno === 1062 || err.code === "ER_DUP_ENTRY") {
372
+ console.warn(
373
+ `[dyrected/mysql] Could not create unique index ${idxName} on ${tableName} because duplicate values already exist: ${err.message}. To enforce uniqueness, remove duplicate records.`
374
+ );
375
+ } else {
376
+ console.warn(`[dyrected/mysql] Could not create unique index ${idxName} on ${tableName}:`, err.message);
377
+ }
370
378
  }
371
379
  }
372
380
  }
@@ -377,7 +385,7 @@ FIX INSTRUCTIONS:
377
385
  if (!Array.isArray(idx.fields) || idx.fields.length === 0) continue;
378
386
  const isUnique = Boolean(idx.unique);
379
387
  const idxName = idx.name || `${isUnique ? "uniq" : "idx"}_${tableName}_${idx.fields.join("_")}`;
380
- if (!existingIndexNames.has(idxName)) {
388
+ if (!existingIndexNames.has(idxName) && !this.failedIndexes.has(idxName)) {
381
389
  for (const fName of idx.fields) {
382
390
  try {
383
391
  const [colInfoRows] = await this.query(`SHOW COLUMNS FROM \`${tableName}\` WHERE Field = ?`, [fName]);
@@ -395,7 +403,14 @@ FIX INSTRUCTIONS:
395
403
  existingIndexNames.add(idxName);
396
404
  } catch (err) {
397
405
  if (err.errno !== 1061 && err.code !== "ER_DUP_KEYNAME") {
398
- console.warn(`[dyrected/mysql] Could not create index ${idxName} on ${tableName}:`, err.message);
406
+ this.failedIndexes.add(idxName);
407
+ if (err.errno === 1062 || err.code === "ER_DUP_ENTRY") {
408
+ console.warn(
409
+ `[dyrected/mysql] Could not create ${isUnique ? "unique " : ""}index ${idxName} on ${tableName} because duplicate values already exist: ${err.message}. To enforce uniqueness, remove duplicate records.`
410
+ );
411
+ } else {
412
+ console.warn(`[dyrected/mysql] Could not create index ${idxName} on ${tableName}:`, err.message);
413
+ }
399
414
  }
400
415
  }
401
416
  }
@@ -694,7 +709,7 @@ FIX INSTRUCTIONS:
694
709
  const base = toFieldExpr(rawField);
695
710
  if (cast === "string") return base;
696
711
  if (cast === "boolean") return `IF(${base} IS NOT NULL, IF(${base} IN ('true','1'), 1, 0), NULL)`;
697
- if (cast === "date") return `CAST(${base} AS DATETIME)`;
712
+ if (cast === "date") return `IF(${base} REGEXP '^[0-9]{4}-[0-9]{2}-[0-9]{2}', CAST(${base} AS DATETIME), NULL)`;
698
713
  const sqlType = cast === "integer" ? "SIGNED" : "DECIMAL(20,6)";
699
714
  return `IF(${base} REGEXP '^-?[0-9]+(\\\\.[0-9]+)?([eE][+-]?[0-9]+)?$', CAST(${base} AS ${sqlType}), NULL)`;
700
715
  };
@@ -764,11 +779,16 @@ FIX INSTRUCTIONS:
764
779
  const result = {};
765
780
  for (const name of Object.keys(args.aggregates)) {
766
781
  const raw = row[name];
782
+ const op = args.aggregates[name];
767
783
  if (isDistinctMap[name]) {
768
784
  const parsed = Array.isArray(raw) ? raw : typeof raw === "string" ? JSON.parse(raw) : raw ?? [];
769
785
  result[name] = Array.isArray(parsed) ? parsed.filter((v) => v !== null && v !== void 0) : [];
786
+ } else if (raw instanceof Date) {
787
+ result[name] = raw.toISOString();
788
+ } else if (op?.cast === "date") {
789
+ result[name] = raw === null || raw === void 0 ? null : String(raw);
770
790
  } else {
771
- result[name] = raw === null || raw === void 0 ? null : Number(raw);
791
+ result[name] = raw === null || raw === void 0 ? null : isNaN(Number(raw)) ? raw : Number(raw);
772
792
  }
773
793
  }
774
794
  return result;
@@ -778,6 +798,7 @@ FIX INSTRUCTIONS:
778
798
  const cacheKey = getMysqlCacheKey(this.config);
779
799
  cache.delete(cacheKey);
780
800
  this.ensuredTables.clear();
801
+ this.failedIndexes.clear();
781
802
  this.tableColumnsCache.clear();
782
803
  if (this.initPromise) {
783
804
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dyrected/db-mysql",
3
- "version": "2.16.0",
3
+ "version": "2.17.0",
4
4
  "description": "MySQL adapter for Dyrected CMS",
5
5
  "type": "module",
6
6
  "files": [
@@ -18,7 +18,7 @@
18
18
  },
19
19
  "dependencies": {
20
20
  "mysql2": "^3.22.3",
21
- "@dyrected/core": "^2.16.0"
21
+ "@dyrected/core": "^2.17.0"
22
22
  },
23
23
  "devDependencies": {
24
24
  "tsup": "^8.0.0",