rado 1.0.13 → 1.0.15

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.
@@ -27,7 +27,7 @@ var Column = class _Column {
27
27
  default(value) {
28
28
  return new _Column({
29
29
  ...getData(this),
30
- defaultValue: input(value)
30
+ defaultValue: input(value).inlineValues()
31
31
  });
32
32
  }
33
33
  defaultNow() {
@@ -91,21 +91,18 @@ var Selection = class {
91
91
  names.add(exprName);
92
92
  if (hasField(input)) {
93
93
  const field = getField(input);
94
- if (field.fieldName === exprName) return expr;
94
+ if (field.fieldName === exprName) return [expr];
95
95
  }
96
- return sql`${expr.forSelection()} as ${sql.identifier(exprName)}`;
96
+ return [sql`${expr.forSelection()} as ${sql.identifier(exprName)}`];
97
97
  }
98
- return expr;
98
+ return [expr];
99
99
  }
100
- return sql.join(
101
- Object.entries(input).map(
102
- ([name2, value]) => this.#selectionToSql(value, names, name2)
103
- ),
104
- sql`, `
100
+ return Object.entries(input).flatMap(
101
+ ([name2, value]) => this.#selectionToSql(value, names, name2)
105
102
  );
106
103
  }
107
104
  get [internalSql]() {
108
- return this.#selectionToSql(this.input, /* @__PURE__ */ new Set());
105
+ return sql.join(this.#selectionToSql(this.input, /* @__PURE__ */ new Set()), sql`, `);
109
106
  }
110
107
  join(right, operator) {
111
108
  return this;
@@ -3,6 +3,7 @@ import {
3
3
  getData,
4
4
  getQuery,
5
5
  getTable,
6
+ hasSql,
6
7
  internalData,
7
8
  internalQuery,
8
9
  internalSelection
@@ -93,8 +94,11 @@ var InsertInto = class {
93
94
  Object.entries(table.columns).map(([key, column]) => {
94
95
  const value = row[key];
95
96
  const { $default, mapToDriverValue } = getData(column);
96
- if (value !== void 0)
97
+ if (value !== void 0) {
98
+ if (value && typeof value === "object" && hasSql(value))
99
+ return value;
97
100
  return input(mapToDriverValue?.(value) ?? value);
101
+ }
98
102
  if ($default) return $default();
99
103
  return defaultKeyword;
100
104
  }),
@@ -2,6 +2,7 @@
2
2
  import {
3
3
  getData,
4
4
  getTable,
5
+ hasSql,
5
6
  internalData,
6
7
  internalQuery,
7
8
  internalSelection
@@ -31,9 +32,8 @@ var UpdateTable = class _UpdateTable extends Update {
31
32
  Object.entries(values).map(([key, value]) => {
32
33
  const column = getTable(table).columns[key];
33
34
  const { mapToDriverValue } = getData(column);
34
- return sql`${sql.identifier(key)} = ${input(
35
- mapToDriverValue?.(value) ?? value
36
- )}`;
35
+ const expr = value && typeof value === "object" && hasSql(value) ? value : input(mapToDriverValue?.(value) ?? value);
36
+ return sql`${sql.identifier(key)} = ${expr}`;
37
37
  }),
38
38
  sql`, `
39
39
  );
@@ -1,7 +1,203 @@
1
1
  // src/mysql/diff.ts
2
+ import { getData, getTable } from "../core/Internal.js";
3
+ import { schema } from "../core/Schema.js";
4
+ import { sql } from "../core/Sql.js";
5
+ import { eq } from "../core/expr/Conditions.js";
6
+ import { txGenerator } from "../universal.js";
7
+ import * as column from "./columns.js";
2
8
  import { mysqlDialect } from "./dialect.js";
9
+ var ns = schema("information_schema");
10
+ var Information = ns.table("columns", {
11
+ table_name: column.text().notNull(),
12
+ column_name: column.text().notNull(),
13
+ column_type: column.text().notNull(),
14
+ is_nullable: column.text().notNull(),
15
+ column_default: column.text(),
16
+ extra: column.text().notNull(),
17
+ table_schema: column.text().notNull()
18
+ });
19
+ var Statistics = ns.table("statistics", {
20
+ table_name: column.text().notNull(),
21
+ column_name: column.text().notNull(),
22
+ index_name: column.text().notNull(),
23
+ non_unique: column.integer().notNull(),
24
+ seq_in_index: column.integer().notNull(),
25
+ table_schema: column.text().notNull()
26
+ });
27
+ var TableConstraints = ns.table("table_constraints", {
28
+ constraint_name: column.text().notNull(),
29
+ table_name: column.text().notNull(),
30
+ constraint_type: column.text().notNull(),
31
+ table_schema: column.text().notNull()
32
+ });
33
+ var inline = (sql2) => mysqlDialect.inline(sql2);
3
34
  var mysqlDiff = (hasTable) => {
4
- throw new Error("Diffing for MySQL is not yet implemented");
35
+ return txGenerator(function* (tx) {
36
+ const tableApi = getTable(hasTable);
37
+ const stmts = [];
38
+ const columnInfo = yield* tx.select({
39
+ name: Information.column_name,
40
+ type: Information.column_type,
41
+ notNull: eq(Information.is_nullable, "NO"),
42
+ defaultValue: Information.column_default,
43
+ extra: Information.extra
44
+ }).from(Information).where(
45
+ eq(Information.table_name, tableApi.name),
46
+ eq(Information.table_schema, sql`database()`)
47
+ );
48
+ const indexInfo = yield* tx.select({
49
+ index_name: Statistics.index_name,
50
+ column_name: Statistics.column_name,
51
+ non_unique: Statistics.non_unique,
52
+ seq_in_index: Statistics.seq_in_index
53
+ }).from(Statistics).where(
54
+ eq(Statistics.table_name, tableApi.name),
55
+ eq(Statistics.table_schema, sql`database()`)
56
+ ).orderBy(Statistics.index_name, Statistics.seq_in_index);
57
+ const indexMap = /* @__PURE__ */ new Map();
58
+ for (const index of indexInfo) {
59
+ if (!indexMap.has(index.index_name)) {
60
+ indexMap.set(index.index_name, []);
61
+ }
62
+ indexMap.get(index.index_name).push(index.column_name);
63
+ }
64
+ const localColumns = new Map(
65
+ columnInfo.map((column2) => {
66
+ let type = column2.type.toLowerCase();
67
+ const isAutoIncrement = column2.extra.toLowerCase().includes("auto_increment");
68
+ if (isAutoIncrement) {
69
+ if (type.includes("bigint")) type = "bigserial";
70
+ else if (type.includes("smallint")) type = "smallserial";
71
+ else type = "serial";
72
+ }
73
+ return [
74
+ column2.name,
75
+ {
76
+ type: sql.unsafe(type),
77
+ notNull: column2.notNull && !isAutoIncrement,
78
+ defaultValue: column2.defaultValue && !isAutoIncrement ? sql.unsafe(column2.defaultValue) : void 0
79
+ }
80
+ ];
81
+ })
82
+ );
83
+ const schemaColumns = new Map(
84
+ Object.entries(tableApi.columns).map(([name, column2]) => {
85
+ const columnApi = getData(column2);
86
+ return [columnApi.name ?? name, columnApi];
87
+ })
88
+ );
89
+ const columnNames = /* @__PURE__ */ new Set([
90
+ ...localColumns.keys(),
91
+ ...schemaColumns.keys()
92
+ ]);
93
+ for (const columnName of columnNames) {
94
+ const alterTable = sql.identifier(tableApi.name);
95
+ const column2 = sql.identifier(columnName);
96
+ const localInstruction = localColumns.get(columnName);
97
+ const schemaInstruction = schemaColumns.get(columnName);
98
+ if (!schemaInstruction) {
99
+ stmts.push(
100
+ sql.query({
101
+ alterTable,
102
+ dropColumn: column2
103
+ })
104
+ );
105
+ } else if (!localInstruction) {
106
+ stmts.push(
107
+ sql.query({
108
+ alterTable,
109
+ addColumn: [column2, sql.chunk("emitColumn", schemaInstruction)]
110
+ })
111
+ );
112
+ } else {
113
+ if (inline(localInstruction.type) !== inline(schemaInstruction.type)) {
114
+ stmts.push(
115
+ sql.query({
116
+ alterTable,
117
+ modifyColumn: [column2, schemaInstruction.type]
118
+ })
119
+ );
120
+ }
121
+ if (Boolean(localInstruction.notNull) !== Boolean(schemaInstruction.notNull)) {
122
+ stmts.push(
123
+ sql.query({
124
+ alterTable,
125
+ modifyColumn: [
126
+ column2,
127
+ schemaInstruction.notNull ? sql`${schemaInstruction.type} not null` : sql`${schemaInstruction.type} null`
128
+ ]
129
+ })
130
+ );
131
+ }
132
+ const localDefault = localInstruction.defaultValue;
133
+ const schemaDefault = schemaInstruction.defaultValue;
134
+ const localDefaultStr = localDefault && inline(localDefault);
135
+ const schemaDefaultStr = schemaDefault && inline(schemaDefault);
136
+ if (localDefaultStr !== schemaDefaultStr) {
137
+ stmts.push(
138
+ sql.query({
139
+ alterTable,
140
+ alterColumn: [
141
+ column2,
142
+ schemaDefault ? sql`set default ${schemaDefault}` : sql`drop default`
143
+ ]
144
+ })
145
+ );
146
+ }
147
+ }
148
+ }
149
+ const localIndexes = new Map(
150
+ Array.from(indexMap.entries()).filter(([name]) => name !== "PRIMARY").map(([name, columns]) => {
151
+ return [
152
+ name,
153
+ sql`index ${sql.identifier(name)} (${sql.join(columns.map(sql.identifier), sql`, `)})`
154
+ ];
155
+ })
156
+ );
157
+ const schemaIndexes = new Map(
158
+ Object.entries(tableApi.indexes()).map(([name, index]) => {
159
+ const indexApi = getData(index);
160
+ return [name, indexApi.toSql(tableApi.name, name, false)];
161
+ })
162
+ );
163
+ const indexNames = /* @__PURE__ */ new Set([
164
+ ...localIndexes.keys(),
165
+ ...schemaIndexes.keys()
166
+ ]);
167
+ for (const indexName of indexNames) {
168
+ const localInstruction = localIndexes.get(indexName);
169
+ const schemaInstruction = schemaIndexes.get(indexName);
170
+ if (!schemaInstruction) {
171
+ stmts.unshift(
172
+ sql.query({
173
+ alterTable: sql.identifier(tableApi.name),
174
+ dropIndex: sql.identifier(indexName)
175
+ })
176
+ );
177
+ } else if (!localInstruction) {
178
+ stmts.push(schemaInstruction);
179
+ } else if (inline(localInstruction) !== inline(schemaInstruction)) {
180
+ if (indexName === "PRIMARY") {
181
+ stmts.unshift(
182
+ sql.query({
183
+ alterTable: sql.identifier(tableApi.name),
184
+ dropPrimaryKey: true
185
+ })
186
+ );
187
+ stmts.push(schemaInstruction);
188
+ } else {
189
+ stmts.unshift(
190
+ sql.query({
191
+ alterTable: sql.identifier(tableApi.name),
192
+ dropIndex: sql.identifier(indexName)
193
+ })
194
+ );
195
+ stmts.push(schemaInstruction);
196
+ }
197
+ }
198
+ }
199
+ return stmts.map(inline);
200
+ });
5
201
  };
6
202
  export {
7
203
  mysqlDiff
@@ -23,9 +23,9 @@ var SqliteMaster = table("SqliteMaster", {
23
23
  sql: column.text().notNull()
24
24
  });
25
25
  var inline = (sql2) => sqliteDialect.inline(sql2);
26
- var sqliteDiff = (hasTable) => {
26
+ var sqliteDiff = (targetTable) => {
27
27
  return txGenerator(function* (tx) {
28
- const tableApi = getTable(hasTable);
28
+ const tableApi = getTable(targetTable);
29
29
  const columnInfo = yield* tx.select(TableInfo).from(sql`pragma_table_info(${sql.inline(tableApi.name)}) as "TableInfo"`);
30
30
  const indexInfo = yield* tx.select(SqliteMaster).from(sql`sqlite_master as "SqliteMaster"`).where(
31
31
  eq(SqliteMaster.tbl_name, tableApi.name),
@@ -57,7 +57,7 @@ var sqliteDiff = (hasTable) => {
57
57
  })
58
58
  );
59
59
  const localIndexes = new Map(
60
- indexInfo.map((index) => [index.name, index.sql])
60
+ indexInfo.filter((index) => !index.name.startsWith("sqlite_autoindex_")).map((index) => [index.name, index.sql])
61
61
  );
62
62
  const schemaIndexes = new Map(
63
63
  Object.entries(tableApi.indexes()).map(([name, index]) => {
@@ -94,6 +94,25 @@ var sqliteDiff = (hasTable) => {
94
94
  return recreate();
95
95
  }
96
96
  }
97
+ const indexNames = /* @__PURE__ */ new Set([
98
+ ...localIndexes.keys(),
99
+ ...schemaIndexes.keys()
100
+ ]);
101
+ for (const indexName of indexNames) {
102
+ const localInstruction = localIndexes.get(indexName);
103
+ const schemaInstruction = schemaIndexes.get(indexName);
104
+ const dropLocal = sql.query({
105
+ dropIndex: sql.identifier(indexName)
106
+ });
107
+ if (!schemaInstruction) {
108
+ stmts.unshift(dropLocal);
109
+ } else if (schemaInstruction && !localInstruction) {
110
+ stmts.push(sql.unsafe(schemaInstruction));
111
+ } else if (schemaInstruction && localInstruction !== schemaInstruction) {
112
+ stmts.unshift(dropLocal);
113
+ stmts.push(sql.unsafe(schemaInstruction));
114
+ }
115
+ }
97
116
  try {
98
117
  yield* txGenerator(function* (sp) {
99
118
  yield* sp.batch(stmts);
@@ -112,43 +131,28 @@ var sqliteDiff = (hasTable) => {
112
131
  return recreate();
113
132
  }
114
133
  }
115
- const indexNames = /* @__PURE__ */ new Set([
116
- ...localIndexes.keys(),
117
- ...schemaIndexes.keys()
118
- ]);
119
- for (const indexName of indexNames) {
120
- const localInstruction = localIndexes.get(indexName);
121
- const schemaInstruction = schemaIndexes.get(indexName);
122
- const dropLocal = sql.query({
123
- dropIndex: sql.identifier(indexName),
124
- on: sql.identifier(tableApi.name)
125
- });
126
- if (!schemaInstruction) {
127
- stmts.unshift(dropLocal);
128
- } else if (!localInstruction) {
129
- stmts.push(sql.unsafe(schemaInstruction));
130
- } else if (localInstruction !== schemaInstruction) {
131
- stmts.unshift(dropLocal);
132
- stmts.push(sql.unsafe(schemaInstruction));
133
- }
134
- }
135
134
  return stmts.map(inline);
136
135
  function recreate() {
137
136
  const tempName = `new_${tableApi.name}`;
138
137
  const tempTable = table(tempName, tableApi.columns);
139
- const missingColumns = Array.from(columnNames).filter(
140
- (name) => !localColumns.has(name)
138
+ const missingColumns = new Set(
139
+ Array.from(columnNames).filter((name) => !localColumns.has(name))
140
+ );
141
+ const selection = Object.fromEntries(
142
+ Object.entries(tableApi.columns).map(([name, column2]) => {
143
+ const columnApi = getData(column2);
144
+ const key = columnApi.name ?? name;
145
+ if (missingColumns.has(key))
146
+ return [name, columnApi.defaultValue ?? sql`null`];
147
+ return [name, targetTable[name]];
148
+ })
141
149
  );
142
- const selection = { ...hasTable };
143
- for (const name of missingColumns) {
144
- selection[name] = getData(tableApi.columns[name]).defaultValue ?? sql`null`;
145
- }
146
150
  return [
147
151
  // Create a new temporary table with the new definition
148
152
  tableApi.createTable(tempName),
149
153
  // Copy the data from the old table to the new table
150
154
  getQuery(
151
- tx.insert(tempTable).select(tx.select(selection).from(hasTable))
155
+ tx.insert(tempTable).select(tx.select(selection).from(targetTable))
152
156
  ),
153
157
  // Drop the old table
154
158
  sql.query({ dropTable: sql.identifier(tableApi.name) }),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rado",
3
- "version": "1.0.13",
3
+ "version": "1.0.15",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -29,7 +29,7 @@
29
29
  "@alinea/suite": "^0.4.0",
30
30
  "@biomejs/biome": "^1.8.3",
31
31
  "@cloudflare/workers-types": "^4.20230628.0",
32
- "@electric-sql/pglite": "^0.1.5",
32
+ "@electric-sql/pglite": "^0.2.12",
33
33
  "@libsql/client": "^0.10.0",
34
34
  "@miniflare/d1": "^2.14.2",
35
35
  "@miniflare/shared": "^2.14.2",