@nextlyhq/adapter-drizzle 0.0.2-alpha.58 → 0.0.2-alpha.60

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.
@@ -498,6 +498,23 @@ declare abstract class DrizzleAdapter {
498
498
  * ```
499
499
  */
500
500
  update<T = unknown>(table: string, data: Record<string, unknown>, where: WhereClause, options?: UpdateOptions, executor?: unknown): Promise<T[]>;
501
+ /**
502
+ * Update records in a table and report how many rows the statement affected.
503
+ *
504
+ * The count is the whole return value, mirroring `delete`. `update` cannot answer this: without
505
+ * `returning` it discards the driver's count, and WITH `returning` on a dialect that lacks
506
+ * RETURNING it re-SELECTs using the same WHERE — so a conditional update that just changed a
507
+ * column named in that WHERE reads back zero rows and a write that landed reports as unmatched.
508
+ * Reading the driver's own count has no second query to disagree with the first.
509
+ *
510
+ * 🔴 MySQL reports CHANGED rows, not matched rows: an UPDATE that matches a row but writes values
511
+ * identical to what it holds counts zero. A caller using this as a compare-and-set must therefore
512
+ * include a column the write always moves — a version bump, a timestamp with enough resolution —
513
+ * so that matched implies changed. Postgres (`rowCount`) and SQLite (`changes`) count matched
514
+ * rows and do not need the precaution, which is exactly why it cannot be dropped: the dialect
515
+ * where the distinction exists is the one with no RETURNING to fall back on.
516
+ */
517
+ updateCount(table: string, data: Record<string, unknown>, where: WhereClause, executor?: unknown): Promise<number>;
501
518
  /**
502
519
  * Delete records from a table.
503
520
  *
@@ -498,6 +498,23 @@ declare abstract class DrizzleAdapter {
498
498
  * ```
499
499
  */
500
500
  update<T = unknown>(table: string, data: Record<string, unknown>, where: WhereClause, options?: UpdateOptions, executor?: unknown): Promise<T[]>;
501
+ /**
502
+ * Update records in a table and report how many rows the statement affected.
503
+ *
504
+ * The count is the whole return value, mirroring `delete`. `update` cannot answer this: without
505
+ * `returning` it discards the driver's count, and WITH `returning` on a dialect that lacks
506
+ * RETURNING it re-SELECTs using the same WHERE — so a conditional update that just changed a
507
+ * column named in that WHERE reads back zero rows and a write that landed reports as unmatched.
508
+ * Reading the driver's own count has no second query to disagree with the first.
509
+ *
510
+ * 🔴 MySQL reports CHANGED rows, not matched rows: an UPDATE that matches a row but writes values
511
+ * identical to what it holds counts zero. A caller using this as a compare-and-set must therefore
512
+ * include a column the write always moves — a version bump, a timestamp with enough resolution —
513
+ * so that matched implies changed. Postgres (`rowCount`) and SQLite (`changes`) count matched
514
+ * rows and do not need the precaution, which is exactly why it cannot be dropped: the dialect
515
+ * where the distinction exists is the one with no RETURNING to fall back on.
516
+ */
517
+ updateCount(table: string, data: Record<string, unknown>, where: WhereClause, executor?: unknown): Promise<number>;
501
518
  /**
502
519
  * Delete records from a table.
503
520
  *
package/dist/index.cjs CHANGED
@@ -913,6 +913,42 @@ var DrizzleAdapter = class {
913
913
  void 0
914
914
  );
915
915
  }
916
+ /**
917
+ * Update records in a table and report how many rows the statement affected.
918
+ *
919
+ * The count is the whole return value, mirroring `delete`. `update` cannot answer this: without
920
+ * `returning` it discards the driver's count, and WITH `returning` on a dialect that lacks
921
+ * RETURNING it re-SELECTs using the same WHERE — so a conditional update that just changed a
922
+ * column named in that WHERE reads back zero rows and a write that landed reports as unmatched.
923
+ * Reading the driver's own count has no second query to disagree with the first.
924
+ *
925
+ * 🔴 MySQL reports CHANGED rows, not matched rows: an UPDATE that matches a row but writes values
926
+ * identical to what it holds counts zero. A caller using this as a compare-and-set must therefore
927
+ * include a column the write always moves — a version bump, a timestamp with enough resolution —
928
+ * so that matched implies changed. Postgres (`rowCount`) and SQLite (`changes`) count matched
929
+ * rows and do not need the precaution, which is exactly why it cannot be dropped: the dialect
930
+ * where the distinction exists is the one with no RETURNING to fall back on.
931
+ */
932
+ async updateCount(table, data, where, executor) {
933
+ const tableObj = this.getTableObject(table);
934
+ if (tableObj) {
935
+ try {
936
+ const db = executor ?? this.getDrizzle();
937
+ const mappedData = this.mapDataToColumnNames(tableObj, data);
938
+ const statement = db.update(tableObj).set(mappedData);
939
+ const whereCondition = buildDrizzleWhere(tableObj, where);
940
+ const result = await (whereCondition ? statement.where(whereCondition) : statement);
941
+ return affectedRowCount(result);
942
+ } catch (error) {
943
+ throw this.handleQueryError(error, "update", table);
944
+ }
945
+ }
946
+ throw this.createDatabaseError(
947
+ "query",
948
+ `Table "${table}" not found in schema registry. Ensure setTableResolver() has been called during boot.`,
949
+ void 0
950
+ );
951
+ }
916
952
  /**
917
953
  * Delete records from a table.
918
954
  *