rado 1.0.13 → 1.0.14
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/core/Column.js +1 -1
- package/dist/core/query/Insert.js +5 -1
- package/dist/core/query/Update.js +3 -3
- package/dist/mysql/diff.js +197 -1
- package/dist/sqlite/diff.js +34 -30
- package/package.json +2 -2
package/dist/core/Column.js
CHANGED
|
@@ -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
|
-
|
|
35
|
-
|
|
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
|
);
|
package/dist/mysql/diff.js
CHANGED
|
@@ -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
|
-
|
|
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
|
package/dist/sqlite/diff.js
CHANGED
|
@@ -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 = (
|
|
26
|
+
var sqliteDiff = (targetTable) => {
|
|
27
27
|
return txGenerator(function* (tx) {
|
|
28
|
-
const tableApi = getTable(
|
|
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 =
|
|
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(
|
|
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.
|
|
3
|
+
"version": "1.0.14",
|
|
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.
|
|
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",
|