@elizaos/plugin-sql 2.0.0-alpha.17 → 2.0.0-alpha.18
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/browser/index.browser.js +724 -719
- package/dist/browser/index.browser.js.map +7 -7
- package/dist/cjs/index.node.cjs +737 -729
- package/dist/cjs/index.node.cjs.map +7 -7
- package/dist/node/index.node.js +720 -712
- package/dist/node/index.node.js.map +7 -7
- package/package.json +4 -2
package/dist/node/index.node.js
CHANGED
|
@@ -1036,170 +1036,533 @@ var init_rls = __esm(() => {
|
|
|
1036
1036
|
init_server();
|
|
1037
1037
|
});
|
|
1038
1038
|
|
|
1039
|
-
// runtime-migrator/
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
}
|
|
1052
|
-
if (normalized === "serial") {
|
|
1053
|
-
return "integer";
|
|
1054
|
-
}
|
|
1055
|
-
if (normalized === "bigserial") {
|
|
1056
|
-
return "bigint";
|
|
1057
|
-
}
|
|
1058
|
-
if (normalized === "smallserial") {
|
|
1059
|
-
return "smallint";
|
|
1060
|
-
}
|
|
1061
|
-
if (normalized.startsWith("numeric") || normalized.startsWith("decimal")) {
|
|
1062
|
-
const match = normalized.match(/\((\d+)(?:,\s*(\d+))?\)/);
|
|
1063
|
-
if (match) {
|
|
1064
|
-
return `numeric(${match[1]}${match[2] ? `,${match[2]}` : ""})`;
|
|
1065
|
-
}
|
|
1066
|
-
return "numeric";
|
|
1067
|
-
}
|
|
1068
|
-
if (normalized.startsWith("character varying")) {
|
|
1069
|
-
return normalized.replace("character varying", "varchar");
|
|
1070
|
-
}
|
|
1071
|
-
if (normalized === "text[]" || normalized === "_text") {
|
|
1072
|
-
return "text[]";
|
|
1039
|
+
// runtime-migrator/crypto-utils.ts
|
|
1040
|
+
function extendedHash(str) {
|
|
1041
|
+
const h1 = hashWithSeed(str, 5381);
|
|
1042
|
+
const h2 = hashWithSeed(str, 7919);
|
|
1043
|
+
const h3 = hashWithSeed(str, 104729);
|
|
1044
|
+
const h4 = hashWithSeed(str, 224737);
|
|
1045
|
+
return h1 + h2 + h3 + h4;
|
|
1046
|
+
}
|
|
1047
|
+
function hashWithSeed(str, seed) {
|
|
1048
|
+
let hash = seed;
|
|
1049
|
+
for (let i = 0;i < str.length; i++) {
|
|
1050
|
+
hash = hash * 33 ^ str.charCodeAt(i);
|
|
1073
1051
|
}
|
|
1074
|
-
return
|
|
1052
|
+
return (hash >>> 0).toString(16).padStart(8, "0");
|
|
1075
1053
|
}
|
|
1076
|
-
function
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
if (
|
|
1082
|
-
|
|
1083
|
-
if (prevIndex.concurrently !== currIndex.concurrently)
|
|
1084
|
-
return true;
|
|
1085
|
-
const prevColumns = prevIndex.columns || [];
|
|
1086
|
-
const currColumns = currIndex.columns || [];
|
|
1087
|
-
if (prevColumns.length !== currColumns.length)
|
|
1088
|
-
return true;
|
|
1089
|
-
for (let i = 0;i < prevColumns.length; i++) {
|
|
1090
|
-
const prevCol = prevColumns[i];
|
|
1091
|
-
const currCol = currColumns[i];
|
|
1092
|
-
if (typeof prevCol === "string" && typeof currCol === "string") {
|
|
1093
|
-
if (prevCol !== currCol)
|
|
1094
|
-
return true;
|
|
1095
|
-
} else if (typeof prevCol === "object" && typeof currCol === "object") {
|
|
1096
|
-
if (prevCol.expression !== currCol.expression)
|
|
1097
|
-
return true;
|
|
1098
|
-
if (prevCol.isExpression !== currCol.isExpression)
|
|
1099
|
-
return true;
|
|
1100
|
-
if (prevCol.asc !== currCol.asc)
|
|
1101
|
-
return true;
|
|
1102
|
-
if (prevCol.nulls !== currCol.nulls)
|
|
1103
|
-
return true;
|
|
1104
|
-
} else {
|
|
1105
|
-
return true;
|
|
1106
|
-
}
|
|
1054
|
+
function stringToBigInt(str) {
|
|
1055
|
+
const hash = extendedHash(str);
|
|
1056
|
+
let lockId = BigInt(`0x${hash.slice(0, 16)}`);
|
|
1057
|
+
const mask63Bits = 0x7fffffffffffffffn;
|
|
1058
|
+
lockId = lockId & mask63Bits;
|
|
1059
|
+
if (lockId === 0n) {
|
|
1060
|
+
lockId = 1n;
|
|
1107
1061
|
}
|
|
1108
|
-
return
|
|
1062
|
+
return lockId;
|
|
1109
1063
|
}
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
}
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
const table = currentSnapshot.tables[tableName];
|
|
1145
|
-
if (table.indexes) {
|
|
1146
|
-
for (const indexName in table.indexes) {
|
|
1147
|
-
diff.indexes.created.push({
|
|
1148
|
-
...table.indexes[indexName],
|
|
1149
|
-
table: tableName
|
|
1150
|
-
});
|
|
1151
|
-
}
|
|
1064
|
+
|
|
1065
|
+
// runtime-migrator/drizzle-adapters/database-introspector.ts
|
|
1066
|
+
import { logger as logger3 } from "@elizaos/core";
|
|
1067
|
+
import { sql as sql21 } from "drizzle-orm";
|
|
1068
|
+
function getRows2(result) {
|
|
1069
|
+
return result.rows;
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
class DatabaseIntrospector {
|
|
1073
|
+
db;
|
|
1074
|
+
constructor(db) {
|
|
1075
|
+
this.db = db;
|
|
1076
|
+
}
|
|
1077
|
+
async introspectSchema(schemaName = "public") {
|
|
1078
|
+
logger3.info({ src: "plugin:sql", schemaName }, "Starting database introspection");
|
|
1079
|
+
const tables = {};
|
|
1080
|
+
const schemas = {};
|
|
1081
|
+
const enums = {};
|
|
1082
|
+
const allTables = await this.getTables(schemaName);
|
|
1083
|
+
for (const tableInfo of allTables) {
|
|
1084
|
+
const tableName = tableInfo.table_name;
|
|
1085
|
+
const tableSchema = tableInfo.table_schema || "public";
|
|
1086
|
+
logger3.debug({ src: "plugin:sql", tableSchema, tableName }, "Introspecting table");
|
|
1087
|
+
const columns = await this.getColumns(tableSchema, tableName);
|
|
1088
|
+
const columnsObject = {};
|
|
1089
|
+
const uniqueConstraintObject = {};
|
|
1090
|
+
for (const col of columns) {
|
|
1091
|
+
columnsObject[col.column_name] = {
|
|
1092
|
+
name: col.column_name,
|
|
1093
|
+
type: col.data_type,
|
|
1094
|
+
primaryKey: col.is_primary || false,
|
|
1095
|
+
notNull: col.is_nullable === "NO",
|
|
1096
|
+
default: col.column_default ? this.parseDefault(col.column_default, col.data_type) : undefined
|
|
1097
|
+
};
|
|
1152
1098
|
}
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1099
|
+
const indexes = await this.getIndexes(tableSchema, tableName);
|
|
1100
|
+
const indexesObject = {};
|
|
1101
|
+
for (const idx of indexes) {
|
|
1102
|
+
if (!idx.is_primary && !idx.is_unique_constraint) {
|
|
1103
|
+
if (idx.columns && Array.isArray(idx.columns) && idx.columns.length > 0) {
|
|
1104
|
+
indexesObject[idx.name] = {
|
|
1105
|
+
name: idx.name,
|
|
1106
|
+
columns: idx.columns.map((col) => ({
|
|
1107
|
+
expression: col,
|
|
1108
|
+
isExpression: false
|
|
1109
|
+
})),
|
|
1110
|
+
isUnique: idx.is_unique,
|
|
1111
|
+
method: idx.method || "btree"
|
|
1112
|
+
};
|
|
1113
|
+
}
|
|
1156
1114
|
}
|
|
1157
1115
|
}
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
});
|
|
1173
|
-
}
|
|
1116
|
+
const foreignKeys = await this.getForeignKeys(tableSchema, tableName);
|
|
1117
|
+
const foreignKeysObject = {};
|
|
1118
|
+
for (const fk of foreignKeys) {
|
|
1119
|
+
foreignKeysObject[fk.name] = {
|
|
1120
|
+
name: fk.name,
|
|
1121
|
+
tableFrom: tableName,
|
|
1122
|
+
schemaFrom: tableSchema,
|
|
1123
|
+
tableTo: fk.foreign_table_name,
|
|
1124
|
+
schemaTo: fk.foreign_table_schema || "public",
|
|
1125
|
+
columnsFrom: [fk.column_name],
|
|
1126
|
+
columnsTo: [fk.foreign_column_name],
|
|
1127
|
+
onDelete: fk.delete_rule?.toLowerCase() || "no action",
|
|
1128
|
+
onUpdate: fk.update_rule?.toLowerCase() || "no action"
|
|
1129
|
+
};
|
|
1174
1130
|
}
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
}
|
|
1131
|
+
const primaryKeys = await this.getPrimaryKeys(tableSchema, tableName);
|
|
1132
|
+
const primaryKeysObject = {};
|
|
1133
|
+
for (const pk of primaryKeys) {
|
|
1134
|
+
primaryKeysObject[pk.name] = {
|
|
1135
|
+
name: pk.name,
|
|
1136
|
+
columns: pk.columns
|
|
1137
|
+
};
|
|
1182
1138
|
}
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
}
|
|
1139
|
+
const uniqueConstraints = await this.getUniqueConstraints(tableSchema, tableName);
|
|
1140
|
+
for (const unq of uniqueConstraints) {
|
|
1141
|
+
uniqueConstraintObject[unq.name] = {
|
|
1142
|
+
name: unq.name,
|
|
1143
|
+
columns: unq.columns,
|
|
1144
|
+
nullsNotDistinct: false
|
|
1145
|
+
};
|
|
1190
1146
|
}
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1147
|
+
const checkConstraints = await this.getCheckConstraints(tableSchema, tableName);
|
|
1148
|
+
const checksObject = {};
|
|
1149
|
+
for (const check3 of checkConstraints) {
|
|
1150
|
+
checksObject[check3.name] = {
|
|
1151
|
+
name: check3.name,
|
|
1152
|
+
value: check3.definition
|
|
1153
|
+
};
|
|
1195
1154
|
}
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1155
|
+
tables[`${tableSchema}.${tableName}`] = {
|
|
1156
|
+
name: tableName,
|
|
1157
|
+
schema: tableSchema,
|
|
1158
|
+
columns: columnsObject,
|
|
1159
|
+
indexes: indexesObject,
|
|
1160
|
+
foreignKeys: foreignKeysObject,
|
|
1161
|
+
compositePrimaryKeys: primaryKeysObject,
|
|
1162
|
+
uniqueConstraints: uniqueConstraintObject,
|
|
1163
|
+
checkConstraints: checksObject
|
|
1164
|
+
};
|
|
1165
|
+
if (tableSchema && tableSchema !== "public") {
|
|
1166
|
+
schemas[tableSchema] = tableSchema;
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
1169
|
+
const enumsResult = await this.getEnums(schemaName);
|
|
1170
|
+
for (const enumInfo of enumsResult) {
|
|
1171
|
+
const key = `${enumInfo.schema}.${enumInfo.name}`;
|
|
1172
|
+
if (!enums[key]) {
|
|
1173
|
+
enums[key] = {
|
|
1174
|
+
name: enumInfo.name,
|
|
1175
|
+
schema: enumInfo.schema,
|
|
1176
|
+
values: []
|
|
1177
|
+
};
|
|
1178
|
+
}
|
|
1179
|
+
enums[key].values.push(enumInfo.value);
|
|
1180
|
+
}
|
|
1181
|
+
logger3.info({ src: "plugin:sql", tableCount: Object.keys(tables).length }, "Database introspection complete");
|
|
1182
|
+
return {
|
|
1183
|
+
version: "7",
|
|
1184
|
+
dialect: "postgresql",
|
|
1185
|
+
tables,
|
|
1186
|
+
schemas,
|
|
1187
|
+
enums,
|
|
1188
|
+
_meta: {
|
|
1189
|
+
schemas: {},
|
|
1190
|
+
tables: {},
|
|
1191
|
+
columns: {}
|
|
1192
|
+
}
|
|
1193
|
+
};
|
|
1194
|
+
}
|
|
1195
|
+
async getTables(schemaName) {
|
|
1196
|
+
const result = await this.db.execute(sql21`SELECT
|
|
1197
|
+
table_schema,
|
|
1198
|
+
table_name
|
|
1199
|
+
FROM information_schema.tables
|
|
1200
|
+
WHERE table_schema = ${schemaName}
|
|
1201
|
+
AND table_type = 'BASE TABLE'
|
|
1202
|
+
ORDER BY table_name`);
|
|
1203
|
+
return getRows2(result);
|
|
1204
|
+
}
|
|
1205
|
+
async getColumns(schemaName, tableName) {
|
|
1206
|
+
const result = await this.db.execute(sql21`SELECT
|
|
1207
|
+
a.attname AS column_name,
|
|
1208
|
+
CASE
|
|
1209
|
+
WHEN a.attnotnull THEN 'NO'
|
|
1210
|
+
ELSE 'YES'
|
|
1211
|
+
END AS is_nullable,
|
|
1212
|
+
CASE
|
|
1213
|
+
WHEN a.atttypid = ANY ('{int,int8,int2}'::regtype[])
|
|
1214
|
+
AND EXISTS (
|
|
1215
|
+
SELECT FROM pg_attrdef ad
|
|
1216
|
+
WHERE ad.adrelid = a.attrelid
|
|
1217
|
+
AND ad.adnum = a.attnum
|
|
1218
|
+
AND pg_get_expr(ad.adbin, ad.adrelid) = 'nextval('''
|
|
1219
|
+
|| pg_get_serial_sequence(a.attrelid::regclass::text, a.attname)::regclass || '''::regclass)'
|
|
1220
|
+
)
|
|
1221
|
+
THEN CASE a.atttypid
|
|
1222
|
+
WHEN 'int'::regtype THEN 'serial'
|
|
1223
|
+
WHEN 'int8'::regtype THEN 'bigserial'
|
|
1224
|
+
WHEN 'int2'::regtype THEN 'smallserial'
|
|
1225
|
+
END
|
|
1226
|
+
ELSE format_type(a.atttypid, a.atttypmod)
|
|
1227
|
+
END AS data_type,
|
|
1228
|
+
pg_get_expr(ad.adbin, ad.adrelid) AS column_default,
|
|
1229
|
+
CASE
|
|
1230
|
+
WHEN con.contype = 'p' THEN true
|
|
1231
|
+
ELSE false
|
|
1232
|
+
END AS is_primary
|
|
1233
|
+
FROM pg_attribute a
|
|
1234
|
+
JOIN pg_class cls ON cls.oid = a.attrelid
|
|
1235
|
+
JOIN pg_namespace ns ON ns.oid = cls.relnamespace
|
|
1236
|
+
LEFT JOIN pg_attrdef ad ON ad.adrelid = a.attrelid AND ad.adnum = a.attnum
|
|
1237
|
+
LEFT JOIN pg_constraint con ON con.conrelid = a.attrelid
|
|
1238
|
+
AND a.attnum = ANY(con.conkey)
|
|
1239
|
+
AND con.contype = 'p'
|
|
1240
|
+
WHERE
|
|
1241
|
+
a.attnum > 0
|
|
1242
|
+
AND NOT a.attisdropped
|
|
1243
|
+
AND ns.nspname = ${schemaName}
|
|
1244
|
+
AND cls.relname = ${tableName}
|
|
1245
|
+
ORDER BY a.attnum`);
|
|
1246
|
+
return getRows2(result);
|
|
1247
|
+
}
|
|
1248
|
+
async getIndexes(schemaName, tableName) {
|
|
1249
|
+
const result = await this.db.execute(sql21`SELECT
|
|
1250
|
+
i.relname AS name,
|
|
1251
|
+
idx.indisunique AS is_unique,
|
|
1252
|
+
idx.indisprimary AS is_primary,
|
|
1253
|
+
con.contype = 'u' AS is_unique_constraint,
|
|
1254
|
+
ARRAY(
|
|
1255
|
+
SELECT a.attname
|
|
1256
|
+
FROM pg_attribute a
|
|
1257
|
+
WHERE a.attrelid = idx.indrelid
|
|
1258
|
+
AND a.attnum = ANY(idx.indkey::int[])
|
|
1259
|
+
ORDER BY a.attnum
|
|
1260
|
+
) AS columns,
|
|
1261
|
+
am.amname AS method
|
|
1262
|
+
FROM pg_index idx
|
|
1263
|
+
JOIN pg_class i ON i.oid = idx.indexrelid
|
|
1264
|
+
JOIN pg_class c ON c.oid = idx.indrelid
|
|
1265
|
+
JOIN pg_namespace n ON n.oid = c.relnamespace
|
|
1266
|
+
JOIN pg_am am ON am.oid = i.relam
|
|
1267
|
+
LEFT JOIN pg_constraint con ON con.conindid = idx.indexrelid
|
|
1268
|
+
WHERE n.nspname = ${schemaName}
|
|
1269
|
+
AND c.relname = ${tableName}`);
|
|
1270
|
+
return getRows2(result);
|
|
1271
|
+
}
|
|
1272
|
+
async getForeignKeys(schemaName, tableName) {
|
|
1273
|
+
const result = await this.db.execute(sql21`SELECT
|
|
1274
|
+
con.conname AS name,
|
|
1275
|
+
att.attname AS column_name,
|
|
1276
|
+
fnsp.nspname AS foreign_table_schema,
|
|
1277
|
+
frel.relname AS foreign_table_name,
|
|
1278
|
+
fatt.attname AS foreign_column_name,
|
|
1279
|
+
CASE con.confupdtype
|
|
1280
|
+
WHEN 'a' THEN 'NO ACTION'
|
|
1281
|
+
WHEN 'r' THEN 'RESTRICT'
|
|
1282
|
+
WHEN 'n' THEN 'SET NULL'
|
|
1283
|
+
WHEN 'c' THEN 'CASCADE'
|
|
1284
|
+
WHEN 'd' THEN 'SET DEFAULT'
|
|
1285
|
+
END AS update_rule,
|
|
1286
|
+
CASE con.confdeltype
|
|
1287
|
+
WHEN 'a' THEN 'NO ACTION'
|
|
1288
|
+
WHEN 'r' THEN 'RESTRICT'
|
|
1289
|
+
WHEN 'n' THEN 'SET NULL'
|
|
1290
|
+
WHEN 'c' THEN 'CASCADE'
|
|
1291
|
+
WHEN 'd' THEN 'SET DEFAULT'
|
|
1292
|
+
END AS delete_rule
|
|
1293
|
+
FROM pg_catalog.pg_constraint con
|
|
1294
|
+
JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
|
|
1295
|
+
JOIN pg_catalog.pg_namespace nsp ON nsp.oid = con.connamespace
|
|
1296
|
+
LEFT JOIN pg_catalog.pg_attribute att ON att.attnum = ANY (con.conkey)
|
|
1297
|
+
AND att.attrelid = con.conrelid
|
|
1298
|
+
LEFT JOIN pg_catalog.pg_class frel ON frel.oid = con.confrelid
|
|
1299
|
+
LEFT JOIN pg_catalog.pg_namespace fnsp ON fnsp.oid = frel.relnamespace
|
|
1300
|
+
LEFT JOIN pg_catalog.pg_attribute fatt ON fatt.attnum = ANY (con.confkey)
|
|
1301
|
+
AND fatt.attrelid = con.confrelid
|
|
1302
|
+
WHERE con.contype = 'f'
|
|
1303
|
+
AND nsp.nspname = ${schemaName}
|
|
1304
|
+
AND rel.relname = ${tableName}`);
|
|
1305
|
+
return getRows2(result);
|
|
1306
|
+
}
|
|
1307
|
+
async getPrimaryKeys(schemaName, tableName) {
|
|
1308
|
+
const result = await this.db.execute(sql21`SELECT
|
|
1309
|
+
con.conname AS name,
|
|
1310
|
+
ARRAY(
|
|
1311
|
+
SELECT a.attname
|
|
1312
|
+
FROM pg_attribute a
|
|
1313
|
+
WHERE a.attrelid = con.conrelid
|
|
1314
|
+
AND a.attnum = ANY(con.conkey)
|
|
1315
|
+
ORDER BY a.attnum
|
|
1316
|
+
) AS columns
|
|
1317
|
+
FROM pg_constraint con
|
|
1318
|
+
JOIN pg_class rel ON rel.oid = con.conrelid
|
|
1319
|
+
JOIN pg_namespace nsp ON nsp.oid = con.connamespace
|
|
1320
|
+
WHERE con.contype = 'p'
|
|
1321
|
+
AND nsp.nspname = ${schemaName}
|
|
1322
|
+
AND rel.relname = ${tableName}`);
|
|
1323
|
+
return getRows2(result);
|
|
1324
|
+
}
|
|
1325
|
+
async getUniqueConstraints(schemaName, tableName) {
|
|
1326
|
+
const result = await this.db.execute(sql21`SELECT
|
|
1327
|
+
con.conname AS name,
|
|
1328
|
+
ARRAY(
|
|
1329
|
+
SELECT a.attname
|
|
1330
|
+
FROM pg_attribute a
|
|
1331
|
+
WHERE a.attrelid = con.conrelid
|
|
1332
|
+
AND a.attnum = ANY(con.conkey)
|
|
1333
|
+
ORDER BY a.attnum
|
|
1334
|
+
) AS columns
|
|
1335
|
+
FROM pg_constraint con
|
|
1336
|
+
JOIN pg_class rel ON rel.oid = con.conrelid
|
|
1337
|
+
JOIN pg_namespace nsp ON nsp.oid = con.connamespace
|
|
1338
|
+
WHERE con.contype = 'u'
|
|
1339
|
+
AND nsp.nspname = ${schemaName}
|
|
1340
|
+
AND rel.relname = ${tableName}`);
|
|
1341
|
+
return getRows2(result);
|
|
1342
|
+
}
|
|
1343
|
+
async getCheckConstraints(schemaName, tableName) {
|
|
1344
|
+
const result = await this.db.execute(sql21`SELECT
|
|
1345
|
+
con.conname AS name,
|
|
1346
|
+
pg_get_constraintdef(con.oid) AS definition
|
|
1347
|
+
FROM pg_constraint con
|
|
1348
|
+
JOIN pg_class rel ON rel.oid = con.conrelid
|
|
1349
|
+
JOIN pg_namespace nsp ON nsp.oid = con.connamespace
|
|
1350
|
+
WHERE con.contype = 'c'
|
|
1351
|
+
AND nsp.nspname = ${schemaName}
|
|
1352
|
+
AND rel.relname = ${tableName}`);
|
|
1353
|
+
return getRows2(result);
|
|
1354
|
+
}
|
|
1355
|
+
async getEnums(schemaName) {
|
|
1356
|
+
const result = await this.db.execute(sql21`SELECT
|
|
1357
|
+
n.nspname AS schema,
|
|
1358
|
+
t.typname AS name,
|
|
1359
|
+
e.enumlabel AS value,
|
|
1360
|
+
e.enumsortorder AS sort_order
|
|
1361
|
+
FROM pg_type t
|
|
1362
|
+
JOIN pg_enum e ON t.oid = e.enumtypid
|
|
1363
|
+
JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace
|
|
1364
|
+
WHERE n.nspname = ${schemaName}
|
|
1365
|
+
ORDER BY schema, name, sort_order`);
|
|
1366
|
+
return getRows2(result);
|
|
1367
|
+
}
|
|
1368
|
+
parseDefault(defaultValue, dataType) {
|
|
1369
|
+
if (!defaultValue)
|
|
1370
|
+
return;
|
|
1371
|
+
const match = defaultValue.match(/^'(.*)'::/);
|
|
1372
|
+
if (match) {
|
|
1373
|
+
return `'${match[1]}'`;
|
|
1374
|
+
}
|
|
1375
|
+
if (defaultValue.includes("nextval(")) {
|
|
1376
|
+
return;
|
|
1377
|
+
}
|
|
1378
|
+
if (dataType === "boolean") {
|
|
1379
|
+
if (defaultValue === "true")
|
|
1380
|
+
return "true";
|
|
1381
|
+
if (defaultValue === "false")
|
|
1382
|
+
return "false";
|
|
1383
|
+
}
|
|
1384
|
+
return defaultValue;
|
|
1385
|
+
}
|
|
1386
|
+
async hasExistingTables(pluginName) {
|
|
1387
|
+
const schemaName = pluginName === "@elizaos/plugin-sql" ? "public" : this.deriveSchemaName(pluginName);
|
|
1388
|
+
const result = await this.db.execute(sql21`SELECT COUNT(*) AS count
|
|
1389
|
+
FROM information_schema.tables
|
|
1390
|
+
WHERE table_schema = ${schemaName}
|
|
1391
|
+
AND table_type = 'BASE TABLE'`);
|
|
1392
|
+
const firstRow = result.rows?.[0];
|
|
1393
|
+
const count = parseInt(firstRow && firstRow.count || "0", 10);
|
|
1394
|
+
return count > 0;
|
|
1395
|
+
}
|
|
1396
|
+
deriveSchemaName(pluginName) {
|
|
1397
|
+
return pluginName.replace("@", "").replace("/", "_").replace(/-/g, "_").toLowerCase();
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1400
|
+
var init_database_introspector = () => {};
|
|
1401
|
+
|
|
1402
|
+
// runtime-migrator/drizzle-adapters/diff-calculator.ts
|
|
1403
|
+
var exports_diff_calculator = {};
|
|
1404
|
+
__export(exports_diff_calculator, {
|
|
1405
|
+
hasDiffChanges: () => hasDiffChanges,
|
|
1406
|
+
calculateDiff: () => calculateDiff
|
|
1407
|
+
});
|
|
1408
|
+
function normalizeType(type) {
|
|
1409
|
+
if (!type)
|
|
1410
|
+
return "";
|
|
1411
|
+
const normalized = type.toLowerCase().trim();
|
|
1412
|
+
if (normalized === "timestamp without time zone" || normalized === "timestamp with time zone") {
|
|
1413
|
+
return "timestamp";
|
|
1414
|
+
}
|
|
1415
|
+
if (normalized === "serial") {
|
|
1416
|
+
return "integer";
|
|
1417
|
+
}
|
|
1418
|
+
if (normalized === "bigserial") {
|
|
1419
|
+
return "bigint";
|
|
1420
|
+
}
|
|
1421
|
+
if (normalized === "smallserial") {
|
|
1422
|
+
return "smallint";
|
|
1423
|
+
}
|
|
1424
|
+
if (normalized.startsWith("numeric") || normalized.startsWith("decimal")) {
|
|
1425
|
+
const match = normalized.match(/\((\d+)(?:,\s*(\d+))?\)/);
|
|
1426
|
+
if (match) {
|
|
1427
|
+
return `numeric(${match[1]}${match[2] ? `,${match[2]}` : ""})`;
|
|
1428
|
+
}
|
|
1429
|
+
return "numeric";
|
|
1430
|
+
}
|
|
1431
|
+
if (normalized.startsWith("character varying")) {
|
|
1432
|
+
return normalized.replace("character varying", "varchar");
|
|
1433
|
+
}
|
|
1434
|
+
if (normalized === "text[]" || normalized === "_text") {
|
|
1435
|
+
return "text[]";
|
|
1436
|
+
}
|
|
1437
|
+
return normalized;
|
|
1438
|
+
}
|
|
1439
|
+
function isIndexChanged(prevIndex, currIndex) {
|
|
1440
|
+
if (prevIndex.isUnique !== currIndex.isUnique)
|
|
1441
|
+
return true;
|
|
1442
|
+
if (prevIndex.method !== currIndex.method)
|
|
1443
|
+
return true;
|
|
1444
|
+
if (prevIndex.where !== currIndex.where)
|
|
1445
|
+
return true;
|
|
1446
|
+
if (prevIndex.concurrently !== currIndex.concurrently)
|
|
1447
|
+
return true;
|
|
1448
|
+
const prevColumns = prevIndex.columns || [];
|
|
1449
|
+
const currColumns = currIndex.columns || [];
|
|
1450
|
+
if (prevColumns.length !== currColumns.length)
|
|
1451
|
+
return true;
|
|
1452
|
+
for (let i = 0;i < prevColumns.length; i++) {
|
|
1453
|
+
const prevCol = prevColumns[i];
|
|
1454
|
+
const currCol = currColumns[i];
|
|
1455
|
+
if (typeof prevCol === "string" && typeof currCol === "string") {
|
|
1456
|
+
if (prevCol !== currCol)
|
|
1457
|
+
return true;
|
|
1458
|
+
} else if (typeof prevCol === "object" && typeof currCol === "object") {
|
|
1459
|
+
if (prevCol.expression !== currCol.expression)
|
|
1460
|
+
return true;
|
|
1461
|
+
if (prevCol.isExpression !== currCol.isExpression)
|
|
1462
|
+
return true;
|
|
1463
|
+
if (prevCol.asc !== currCol.asc)
|
|
1464
|
+
return true;
|
|
1465
|
+
if (prevCol.nulls !== currCol.nulls)
|
|
1466
|
+
return true;
|
|
1467
|
+
} else {
|
|
1468
|
+
return true;
|
|
1469
|
+
}
|
|
1470
|
+
}
|
|
1471
|
+
return false;
|
|
1472
|
+
}
|
|
1473
|
+
async function calculateDiff(previousSnapshot, currentSnapshot) {
|
|
1474
|
+
const diff = {
|
|
1475
|
+
tables: {
|
|
1476
|
+
created: [],
|
|
1477
|
+
deleted: [],
|
|
1478
|
+
modified: []
|
|
1479
|
+
},
|
|
1480
|
+
columns: {
|
|
1481
|
+
added: [],
|
|
1482
|
+
deleted: [],
|
|
1483
|
+
modified: []
|
|
1484
|
+
},
|
|
1485
|
+
indexes: {
|
|
1486
|
+
created: [],
|
|
1487
|
+
deleted: [],
|
|
1488
|
+
altered: []
|
|
1489
|
+
},
|
|
1490
|
+
foreignKeys: {
|
|
1491
|
+
created: [],
|
|
1492
|
+
deleted: [],
|
|
1493
|
+
altered: []
|
|
1494
|
+
},
|
|
1495
|
+
uniqueConstraints: {
|
|
1496
|
+
created: [],
|
|
1497
|
+
deleted: []
|
|
1498
|
+
},
|
|
1499
|
+
checkConstraints: {
|
|
1500
|
+
created: [],
|
|
1501
|
+
deleted: []
|
|
1502
|
+
}
|
|
1503
|
+
};
|
|
1504
|
+
if (!previousSnapshot) {
|
|
1505
|
+
diff.tables.created = Object.keys(currentSnapshot.tables);
|
|
1506
|
+
for (const tableName in currentSnapshot.tables) {
|
|
1507
|
+
const table = currentSnapshot.tables[tableName];
|
|
1508
|
+
if (table.indexes) {
|
|
1509
|
+
for (const indexName in table.indexes) {
|
|
1510
|
+
diff.indexes.created.push({
|
|
1511
|
+
...table.indexes[indexName],
|
|
1512
|
+
table: tableName
|
|
1513
|
+
});
|
|
1514
|
+
}
|
|
1515
|
+
}
|
|
1516
|
+
if (table.foreignKeys) {
|
|
1517
|
+
for (const fkName in table.foreignKeys) {
|
|
1518
|
+
diff.foreignKeys.created.push(table.foreignKeys[fkName]);
|
|
1519
|
+
}
|
|
1520
|
+
}
|
|
1521
|
+
}
|
|
1522
|
+
return diff;
|
|
1523
|
+
}
|
|
1524
|
+
const prevTables = previousSnapshot.tables || {};
|
|
1525
|
+
const currTables = currentSnapshot.tables || {};
|
|
1526
|
+
for (const tableName in currTables) {
|
|
1527
|
+
if (!(tableName in prevTables)) {
|
|
1528
|
+
diff.tables.created.push(tableName);
|
|
1529
|
+
const table = currTables[tableName];
|
|
1530
|
+
if (table.indexes) {
|
|
1531
|
+
for (const indexName in table.indexes) {
|
|
1532
|
+
diff.indexes.created.push({
|
|
1533
|
+
...table.indexes[indexName],
|
|
1534
|
+
table: tableName
|
|
1535
|
+
});
|
|
1536
|
+
}
|
|
1537
|
+
}
|
|
1538
|
+
if (table.uniqueConstraints) {
|
|
1539
|
+
for (const uqName in table.uniqueConstraints) {
|
|
1540
|
+
diff.uniqueConstraints.created.push({
|
|
1541
|
+
...table.uniqueConstraints[uqName],
|
|
1542
|
+
table: tableName
|
|
1543
|
+
});
|
|
1544
|
+
}
|
|
1545
|
+
}
|
|
1546
|
+
if (table.checkConstraints) {
|
|
1547
|
+
for (const checkName in table.checkConstraints) {
|
|
1548
|
+
diff.checkConstraints.created.push({
|
|
1549
|
+
...table.checkConstraints[checkName],
|
|
1550
|
+
table: tableName
|
|
1551
|
+
});
|
|
1552
|
+
}
|
|
1553
|
+
}
|
|
1554
|
+
if (table.foreignKeys) {
|
|
1555
|
+
for (const fkName in table.foreignKeys) {
|
|
1556
|
+
diff.foreignKeys.created.push(table.foreignKeys[fkName]);
|
|
1557
|
+
}
|
|
1558
|
+
}
|
|
1559
|
+
}
|
|
1560
|
+
}
|
|
1561
|
+
for (const tableName in prevTables) {
|
|
1562
|
+
if (!(tableName in currTables)) {
|
|
1563
|
+
diff.tables.deleted.push(tableName);
|
|
1564
|
+
}
|
|
1565
|
+
}
|
|
1203
1566
|
for (const tableName in currTables) {
|
|
1204
1567
|
if (tableName in prevTables) {
|
|
1205
1568
|
const prevTable = prevTables[tableName];
|
|
@@ -1367,32 +1730,6 @@ function hasDiffChanges(diff) {
|
|
|
1367
1730
|
return diff.tables.created.length > 0 || diff.tables.deleted.length > 0 || diff.tables.modified.length > 0 || diff.columns.added.length > 0 || diff.columns.deleted.length > 0 || diff.columns.modified.length > 0 || diff.indexes.created.length > 0 || diff.indexes.deleted.length > 0 || diff.indexes.altered.length > 0 || diff.foreignKeys.created.length > 0 || diff.foreignKeys.deleted.length > 0 || diff.foreignKeys.altered.length > 0 || diff.uniqueConstraints.created.length > 0 || diff.uniqueConstraints.deleted.length > 0 || diff.checkConstraints.created.length > 0 || diff.checkConstraints.deleted.length > 0;
|
|
1368
1731
|
}
|
|
1369
1732
|
|
|
1370
|
-
// runtime-migrator/crypto-utils.ts
|
|
1371
|
-
function extendedHash(str) {
|
|
1372
|
-
const h1 = hashWithSeed(str, 5381);
|
|
1373
|
-
const h2 = hashWithSeed(str, 7919);
|
|
1374
|
-
const h3 = hashWithSeed(str, 104729);
|
|
1375
|
-
const h4 = hashWithSeed(str, 224737);
|
|
1376
|
-
return h1 + h2 + h3 + h4;
|
|
1377
|
-
}
|
|
1378
|
-
function hashWithSeed(str, seed) {
|
|
1379
|
-
let hash = seed;
|
|
1380
|
-
for (let i = 0;i < str.length; i++) {
|
|
1381
|
-
hash = hash * 33 ^ str.charCodeAt(i);
|
|
1382
|
-
}
|
|
1383
|
-
return (hash >>> 0).toString(16).padStart(8, "0");
|
|
1384
|
-
}
|
|
1385
|
-
function stringToBigInt(str) {
|
|
1386
|
-
const hash = extendedHash(str);
|
|
1387
|
-
let lockId = BigInt(`0x${hash.slice(0, 16)}`);
|
|
1388
|
-
const mask63Bits = 0x7fffffffffffffffn;
|
|
1389
|
-
lockId = lockId & mask63Bits;
|
|
1390
|
-
if (lockId === 0n) {
|
|
1391
|
-
lockId = 1n;
|
|
1392
|
-
}
|
|
1393
|
-
return lockId;
|
|
1394
|
-
}
|
|
1395
|
-
|
|
1396
1733
|
// runtime-migrator/drizzle-adapters/snapshot-generator.ts
|
|
1397
1734
|
import { is, SQL } from "drizzle-orm";
|
|
1398
1735
|
import { getTableConfig, PgDialect, PgTable } from "drizzle-orm/pg-core";
|
|
@@ -1621,7 +1958,7 @@ function hasChanges(previousSnapshot, currentSnapshot) {
|
|
|
1621
1958
|
const currHash = hashSnapshot(currentSnapshot);
|
|
1622
1959
|
return prevHash !== currHash;
|
|
1623
1960
|
}
|
|
1624
|
-
var sqlToStr = (
|
|
1961
|
+
var sqlToStr = (sql22, _casing) => {
|
|
1625
1962
|
const config = {
|
|
1626
1963
|
escapeName: () => {
|
|
1627
1964
|
throw new Error("we don't support params for `sql` default values");
|
|
@@ -1634,12 +1971,12 @@ var sqlToStr = (sql21, _casing) => {
|
|
|
1634
1971
|
},
|
|
1635
1972
|
casing: undefined
|
|
1636
1973
|
};
|
|
1637
|
-
return
|
|
1974
|
+
return sql22.toQuery(config).sql;
|
|
1638
1975
|
};
|
|
1639
1976
|
var init_snapshot_generator = () => {};
|
|
1640
1977
|
|
|
1641
1978
|
// runtime-migrator/drizzle-adapters/sql-generator.ts
|
|
1642
|
-
import { logger as
|
|
1979
|
+
import { logger as logger4 } from "@elizaos/core";
|
|
1643
1980
|
function checkForDataLoss(diff) {
|
|
1644
1981
|
const result = {
|
|
1645
1982
|
hasDataLoss: false,
|
|
@@ -1769,7 +2106,7 @@ async function generateMigrationSQL(previousSnapshot, currentSnapshot, diff) {
|
|
|
1769
2106
|
}
|
|
1770
2107
|
const dataLossCheck = checkForDataLoss(diff);
|
|
1771
2108
|
if (dataLossCheck.warnings.length > 0) {
|
|
1772
|
-
|
|
2109
|
+
logger4.warn({ src: "plugin:sql", warnings: dataLossCheck.warnings }, "Schema changes may cause data loss");
|
|
1773
2110
|
}
|
|
1774
2111
|
const schemasToCreate = new Set;
|
|
1775
2112
|
for (const tableName of diff.tables.created) {
|
|
@@ -1922,24 +2259,29 @@ function generateCreateTableSQL(fullTableName, table) {
|
|
|
1922
2259
|
const foreignKeys = table.foreignKeys || {};
|
|
1923
2260
|
for (const [fkName, fkDef] of Object.entries(foreignKeys)) {
|
|
1924
2261
|
const fk = fkDef;
|
|
1925
|
-
const fkSQL =
|
|
2262
|
+
const fkSQL = wrapConstraintCreationGuard(fkName, buildCreateForeignKeyBodySQL({
|
|
2263
|
+
...fk,
|
|
2264
|
+
name: fkName,
|
|
2265
|
+
schemaFrom: schema,
|
|
2266
|
+
tableFrom: tableName
|
|
2267
|
+
}));
|
|
1926
2268
|
fkSQLs.push(fkSQL);
|
|
1927
2269
|
}
|
|
1928
2270
|
return { tableSQL, fkSQLs };
|
|
1929
2271
|
}
|
|
1930
2272
|
function generateColumnDefinition(name, def) {
|
|
1931
|
-
let
|
|
2273
|
+
let sql22 = `"${name}" ${def.type}`;
|
|
1932
2274
|
if (def.primaryKey && !def.type.includes("SERIAL")) {
|
|
1933
|
-
|
|
2275
|
+
sql22 += " PRIMARY KEY";
|
|
1934
2276
|
}
|
|
1935
2277
|
if (def.notNull) {
|
|
1936
|
-
|
|
2278
|
+
sql22 += " NOT NULL";
|
|
1937
2279
|
}
|
|
1938
2280
|
if (def.default !== undefined) {
|
|
1939
2281
|
const defaultValue = formatDefaultValue(def.default, def.type);
|
|
1940
|
-
|
|
2282
|
+
sql22 += ` DEFAULT ${defaultValue}`;
|
|
1941
2283
|
}
|
|
1942
|
-
return
|
|
2284
|
+
return sql22;
|
|
1943
2285
|
}
|
|
1944
2286
|
function generateAddColumnSQL(table, column, definition) {
|
|
1945
2287
|
const [schema, tableName] = table.includes(".") ? table.split(".") : ["public", table];
|
|
@@ -1949,543 +2291,213 @@ function generateAddColumnSQL(table, column, definition) {
|
|
|
1949
2291
|
if (definition.primaryKey) {
|
|
1950
2292
|
parts.push("PRIMARY KEY");
|
|
1951
2293
|
}
|
|
1952
|
-
if (definition.default !== undefined) {
|
|
1953
|
-
const defaultValue = formatDefaultValue(definition.default, definition.type);
|
|
1954
|
-
if (defaultValue) {
|
|
1955
|
-
parts.push(`DEFAULT ${defaultValue}`);
|
|
1956
|
-
}
|
|
1957
|
-
}
|
|
1958
|
-
const definitionWithGenerated = definition;
|
|
1959
|
-
if (definitionWithGenerated.generated) {
|
|
1960
|
-
parts.push(`GENERATED ALWAYS AS (${definitionWithGenerated.generated}) STORED`);
|
|
1961
|
-
}
|
|
1962
|
-
if (definition.notNull) {
|
|
1963
|
-
parts.push("NOT NULL");
|
|
1964
|
-
}
|
|
1965
|
-
return `ALTER TABLE ${tableNameWithSchema} ADD COLUMN ${parts.join(" ")};`;
|
|
1966
|
-
}
|
|
1967
|
-
function generateDropColumnSQL(table, column) {
|
|
1968
|
-
const [schema, tableName] = table.includes(".") ? table.split(".") : ["public", table];
|
|
1969
|
-
const tableNameWithSchema = `"${schema}"."${tableName}"`;
|
|
1970
|
-
return `ALTER TABLE ${tableNameWithSchema} DROP COLUMN "${column}" CASCADE;`;
|
|
1971
|
-
}
|
|
1972
|
-
function generateAlterColumnSQL(table, column, changes) {
|
|
1973
|
-
const [schema, tableName] = table.includes(".") ? table.split(".") : ["public", table];
|
|
1974
|
-
const tableNameWithSchema = `"${schema}"."${tableName}"`;
|
|
1975
|
-
const statements = [];
|
|
1976
|
-
const changesTo = changes.to;
|
|
1977
|
-
const changesFrom = changes.from;
|
|
1978
|
-
const changesToType = changesTo?.type;
|
|
1979
|
-
const changesFromType = changesFrom?.type;
|
|
1980
|
-
if (changesToType !== changesFromType) {
|
|
1981
|
-
const newType = changesToType || "TEXT";
|
|
1982
|
-
const needsUsing = checkIfNeedsUsingClause(changesFromType || "", newType);
|
|
1983
|
-
if (needsUsing) {
|
|
1984
|
-
statements.push(`ALTER TABLE ${tableNameWithSchema} ALTER COLUMN "${column}" TYPE ${newType} USING "${column}"::text::${newType};`);
|
|
1985
|
-
} else {
|
|
1986
|
-
statements.push(`ALTER TABLE ${tableNameWithSchema} ALTER COLUMN "${column}" SET DATA TYPE ${newType};`);
|
|
1987
|
-
}
|
|
1988
|
-
}
|
|
1989
|
-
const changesToNotNull = changesTo?.notNull;
|
|
1990
|
-
const changesFromNotNull = changesFrom?.notNull;
|
|
1991
|
-
if (changesToNotNull !== changesFromNotNull) {
|
|
1992
|
-
if (changesToNotNull) {
|
|
1993
|
-
statements.push(`ALTER TABLE ${tableNameWithSchema} ALTER COLUMN "${column}" SET NOT NULL;`);
|
|
1994
|
-
} else {
|
|
1995
|
-
statements.push(`ALTER TABLE ${tableNameWithSchema} ALTER COLUMN "${column}" DROP NOT NULL;`);
|
|
1996
|
-
}
|
|
1997
|
-
}
|
|
1998
|
-
const changesToDefault = changesTo?.default;
|
|
1999
|
-
const changesFromDefault = changesFrom?.default;
|
|
2000
|
-
if (changesToDefault !== changesFromDefault) {
|
|
2001
|
-
if (changesToDefault !== undefined) {
|
|
2002
|
-
const defaultValue = formatDefaultValue(changesToDefault, changesToType || "");
|
|
2003
|
-
statements.push(`ALTER TABLE ${tableNameWithSchema} ALTER COLUMN "${column}" SET DEFAULT ${defaultValue};`);
|
|
2004
|
-
} else {
|
|
2005
|
-
statements.push(`ALTER TABLE ${tableNameWithSchema} ALTER COLUMN "${column}" DROP DEFAULT;`);
|
|
2006
|
-
}
|
|
2007
|
-
}
|
|
2008
|
-
return statements;
|
|
2009
|
-
}
|
|
2010
|
-
function checkIfNeedsUsingClause(fromType, toType) {
|
|
2011
|
-
if (!fromType || !toType)
|
|
2012
|
-
return false;
|
|
2013
|
-
if (fromType.includes("enum") || toType.includes("enum")) {
|
|
2014
|
-
return true;
|
|
2015
|
-
}
|
|
2016
|
-
const fromBase = fromType.split("(")[0].toLowerCase();
|
|
2017
|
-
const toBase = toType.split("(")[0].toLowerCase();
|
|
2018
|
-
if ((fromBase === "text" || fromBase === "varchar" || fromBase === "character varying") && (toBase === "jsonb" || toBase === "json")) {
|
|
2019
|
-
return true;
|
|
2020
|
-
}
|
|
2021
|
-
const needsUsingPairs = [
|
|
2022
|
-
["integer", "boolean"],
|
|
2023
|
-
["boolean", "integer"],
|
|
2024
|
-
["text", "integer"],
|
|
2025
|
-
["text", "numeric"],
|
|
2026
|
-
["text", "boolean"],
|
|
2027
|
-
["text", "uuid"],
|
|
2028
|
-
["text", "jsonb"],
|
|
2029
|
-
["text", "json"],
|
|
2030
|
-
["varchar", "integer"],
|
|
2031
|
-
["varchar", "numeric"],
|
|
2032
|
-
["varchar", "boolean"],
|
|
2033
|
-
["varchar", "uuid"],
|
|
2034
|
-
["varchar", "jsonb"],
|
|
2035
|
-
["varchar", "json"],
|
|
2036
|
-
["character varying", "jsonb"],
|
|
2037
|
-
["character varying", "json"]
|
|
2038
|
-
];
|
|
2039
|
-
for (const [from, to] of needsUsingPairs) {
|
|
2040
|
-
if (fromBase === from && toBase === to || fromBase === to && toBase === from) {
|
|
2041
|
-
return true;
|
|
2042
|
-
}
|
|
2043
|
-
}
|
|
2044
|
-
return false;
|
|
2045
|
-
}
|
|
2046
|
-
function formatDefaultValue(value, type) {
|
|
2047
|
-
if (value === null || value === "NULL") {
|
|
2048
|
-
return "NULL";
|
|
2049
|
-
}
|
|
2050
|
-
if (type && (type.toLowerCase().includes("boolean") || type.toLowerCase() === "bool")) {
|
|
2051
|
-
if (value === true || value === "true" || value === "t" || value === 1) {
|
|
2052
|
-
return "true";
|
|
2053
|
-
}
|
|
2054
|
-
if (value === false || value === "false" || value === "f" || value === 0) {
|
|
2055
|
-
return "false";
|
|
2056
|
-
}
|
|
2057
|
-
}
|
|
2058
|
-
if (type?.match(/^(integer|bigint|smallint|numeric|decimal|real|double)/i)) {
|
|
2059
|
-
return String(value);
|
|
2060
|
-
}
|
|
2061
|
-
if (typeof value === "string") {
|
|
2062
|
-
if (value.includes("::")) {
|
|
2063
|
-
return value;
|
|
2064
|
-
}
|
|
2065
|
-
if (value.startsWith("'") && value.endsWith("'")) {
|
|
2066
|
-
return value;
|
|
2067
|
-
}
|
|
2068
|
-
if (value.match(/^\w+\(\)/i) || value.includes("(") && value.includes(")")) {
|
|
2069
|
-
return value;
|
|
2070
|
-
}
|
|
2071
|
-
if (value.toUpperCase().startsWith("CURRENT_")) {
|
|
2072
|
-
return value;
|
|
2073
|
-
}
|
|
2074
|
-
return `'${value.replace(/'/g, "''")}'`;
|
|
2075
|
-
}
|
|
2076
|
-
return String(value);
|
|
2077
|
-
}
|
|
2078
|
-
function generateCreateIndexSQL(index7) {
|
|
2079
|
-
const unique3 = index7.isUnique ? "UNIQUE " : "";
|
|
2080
|
-
const method = index7.method || "btree";
|
|
2081
|
-
const columns = index7.columns.map((c) => {
|
|
2082
|
-
if (c.isExpression) {
|
|
2083
|
-
return c.expression;
|
|
2084
|
-
}
|
|
2085
|
-
return `"${c.expression}"${c.asc === false ? " DESC" : ""}`;
|
|
2086
|
-
}).join(", ");
|
|
2087
|
-
const indexName = index7.name.includes(".") ? index7.name.split(".")[1] : index7.name;
|
|
2088
|
-
let tableRef;
|
|
2089
|
-
const indexTable = index7.table;
|
|
2090
|
-
if (indexTable?.includes(".")) {
|
|
2091
|
-
const [schema, table] = indexTable.split(".");
|
|
2092
|
-
tableRef = `"${schema}"."${table}"`;
|
|
2093
|
-
} else {
|
|
2094
|
-
tableRef = `"${indexTable || ""}"`;
|
|
2095
|
-
}
|
|
2096
|
-
return `CREATE ${unique3}INDEX "${indexName}" ON ${tableRef} USING ${method} (${columns});`;
|
|
2097
|
-
}
|
|
2098
|
-
function generateDropIndexSQL(index7) {
|
|
2099
|
-
const indexNameFull = typeof index7 === "string" ? index7 : index7.name;
|
|
2100
|
-
const indexName = indexNameFull.includes(".") ? indexNameFull.split(".")[1] : indexNameFull;
|
|
2101
|
-
return `DROP INDEX IF EXISTS "${indexName}";`;
|
|
2102
|
-
}
|
|
2103
|
-
function generateCreateForeignKeySQL(fk) {
|
|
2104
|
-
const schemaFrom = fk.schemaFrom || "public";
|
|
2105
|
-
const schemaTo = fk.schemaTo || "public";
|
|
2106
|
-
const tableFrom = fk.tableFrom;
|
|
2107
|
-
const columnsFrom = fk.columnsFrom.map((c) => `"${c}"`).join(", ");
|
|
2108
|
-
const columnsTo = fk.columnsTo.map((c) => `"${c}"`).join(", ");
|
|
2109
|
-
let sql21 = `ALTER TABLE "${schemaFrom}"."${tableFrom}" ADD CONSTRAINT "${fk.name}" FOREIGN KEY (${columnsFrom}) REFERENCES "${schemaTo}"."${fk.tableTo}" (${columnsTo})`;
|
|
2110
|
-
if (fk.onDelete) {
|
|
2111
|
-
sql21 += ` ON DELETE ${fk.onDelete}`;
|
|
2112
|
-
}
|
|
2113
|
-
if (fk.onUpdate) {
|
|
2114
|
-
sql21 += ` ON UPDATE ${fk.onUpdate}`;
|
|
2115
|
-
}
|
|
2116
|
-
return `${sql21};`;
|
|
2117
|
-
}
|
|
2118
|
-
function generateDropForeignKeySQL(fk) {
|
|
2119
|
-
const [schema, tableName] = fk.tableFrom ? fk.tableFrom.includes(".") ? fk.tableFrom.split(".") : ["public", fk.tableFrom] : ["public", ""];
|
|
2120
|
-
return `ALTER TABLE "${schema}"."${tableName}" DROP CONSTRAINT "${fk.name}";`;
|
|
2121
|
-
}
|
|
2122
|
-
function generateCreateUniqueConstraintSQL(constraint) {
|
|
2123
|
-
const table = constraint.table || "";
|
|
2124
|
-
const [schema, tableName] = table.includes(".") ? table.split(".") : ["public", table];
|
|
2125
|
-
const name = constraint.name;
|
|
2126
|
-
const columns = constraint.columns.map((c) => `"${c}"`).join(", ");
|
|
2127
|
-
let sql21 = `ALTER TABLE "${schema}"."${tableName}" ADD CONSTRAINT "${name}" UNIQUE`;
|
|
2128
|
-
if (constraint.nullsNotDistinct) {
|
|
2129
|
-
sql21 += ` NULLS NOT DISTINCT`;
|
|
2294
|
+
if (definition.default !== undefined) {
|
|
2295
|
+
const defaultValue = formatDefaultValue(definition.default, definition.type);
|
|
2296
|
+
if (defaultValue) {
|
|
2297
|
+
parts.push(`DEFAULT ${defaultValue}`);
|
|
2298
|
+
}
|
|
2130
2299
|
}
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
}
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2300
|
+
const definitionWithGenerated = definition;
|
|
2301
|
+
if (definitionWithGenerated.generated) {
|
|
2302
|
+
parts.push(`GENERATED ALWAYS AS (${definitionWithGenerated.generated}) STORED`);
|
|
2303
|
+
}
|
|
2304
|
+
if (definition.notNull) {
|
|
2305
|
+
parts.push("NOT NULL");
|
|
2306
|
+
}
|
|
2307
|
+
return `ALTER TABLE ${tableNameWithSchema} ADD COLUMN ${parts.join(" ")};`;
|
|
2138
2308
|
}
|
|
2139
|
-
function
|
|
2140
|
-
const table = constraint.table || "";
|
|
2309
|
+
function generateDropColumnSQL(table, column) {
|
|
2141
2310
|
const [schema, tableName] = table.includes(".") ? table.split(".") : ["public", table];
|
|
2142
|
-
const
|
|
2143
|
-
|
|
2144
|
-
return `ALTER TABLE "${schema}"."${tableName}" ADD CONSTRAINT "${name}" CHECK (${value});`;
|
|
2311
|
+
const tableNameWithSchema = `"${schema}"."${tableName}"`;
|
|
2312
|
+
return `ALTER TABLE ${tableNameWithSchema} DROP COLUMN "${column}" CASCADE;`;
|
|
2145
2313
|
}
|
|
2146
|
-
function
|
|
2147
|
-
const table = constraint.table || "";
|
|
2314
|
+
function generateAlterColumnSQL(table, column, changes) {
|
|
2148
2315
|
const [schema, tableName] = table.includes(".") ? table.split(".") : ["public", table];
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
constructor(db) {
|
|
2163
|
-
this.db = db;
|
|
2164
|
-
}
|
|
2165
|
-
async introspectSchema(schemaName = "public") {
|
|
2166
|
-
logger4.info({ src: "plugin:sql", schemaName }, "Starting database introspection");
|
|
2167
|
-
const tables = {};
|
|
2168
|
-
const schemas = {};
|
|
2169
|
-
const enums = {};
|
|
2170
|
-
const allTables = await this.getTables(schemaName);
|
|
2171
|
-
for (const tableInfo of allTables) {
|
|
2172
|
-
const tableName = tableInfo.table_name;
|
|
2173
|
-
const tableSchema = tableInfo.table_schema || "public";
|
|
2174
|
-
logger4.debug({ src: "plugin:sql", tableSchema, tableName }, "Introspecting table");
|
|
2175
|
-
const columns = await this.getColumns(tableSchema, tableName);
|
|
2176
|
-
const columnsObject = {};
|
|
2177
|
-
const uniqueConstraintObject = {};
|
|
2178
|
-
for (const col of columns) {
|
|
2179
|
-
columnsObject[col.column_name] = {
|
|
2180
|
-
name: col.column_name,
|
|
2181
|
-
type: col.data_type,
|
|
2182
|
-
primaryKey: col.is_primary || false,
|
|
2183
|
-
notNull: col.is_nullable === "NO",
|
|
2184
|
-
default: col.column_default ? this.parseDefault(col.column_default, col.data_type) : undefined
|
|
2185
|
-
};
|
|
2186
|
-
}
|
|
2187
|
-
const indexes = await this.getIndexes(tableSchema, tableName);
|
|
2188
|
-
const indexesObject = {};
|
|
2189
|
-
for (const idx of indexes) {
|
|
2190
|
-
if (!idx.is_primary && !idx.is_unique_constraint) {
|
|
2191
|
-
if (idx.columns && Array.isArray(idx.columns) && idx.columns.length > 0) {
|
|
2192
|
-
indexesObject[idx.name] = {
|
|
2193
|
-
name: idx.name,
|
|
2194
|
-
columns: idx.columns.map((col) => ({
|
|
2195
|
-
expression: col,
|
|
2196
|
-
isExpression: false
|
|
2197
|
-
})),
|
|
2198
|
-
isUnique: idx.is_unique,
|
|
2199
|
-
method: idx.method || "btree"
|
|
2200
|
-
};
|
|
2201
|
-
}
|
|
2202
|
-
}
|
|
2203
|
-
}
|
|
2204
|
-
const foreignKeys = await this.getForeignKeys(tableSchema, tableName);
|
|
2205
|
-
const foreignKeysObject = {};
|
|
2206
|
-
for (const fk of foreignKeys) {
|
|
2207
|
-
foreignKeysObject[fk.name] = {
|
|
2208
|
-
name: fk.name,
|
|
2209
|
-
tableFrom: tableName,
|
|
2210
|
-
schemaFrom: tableSchema,
|
|
2211
|
-
tableTo: fk.foreign_table_name,
|
|
2212
|
-
schemaTo: fk.foreign_table_schema || "public",
|
|
2213
|
-
columnsFrom: [fk.column_name],
|
|
2214
|
-
columnsTo: [fk.foreign_column_name],
|
|
2215
|
-
onDelete: fk.delete_rule?.toLowerCase() || "no action",
|
|
2216
|
-
onUpdate: fk.update_rule?.toLowerCase() || "no action"
|
|
2217
|
-
};
|
|
2218
|
-
}
|
|
2219
|
-
const primaryKeys = await this.getPrimaryKeys(tableSchema, tableName);
|
|
2220
|
-
const primaryKeysObject = {};
|
|
2221
|
-
for (const pk of primaryKeys) {
|
|
2222
|
-
primaryKeysObject[pk.name] = {
|
|
2223
|
-
name: pk.name,
|
|
2224
|
-
columns: pk.columns
|
|
2225
|
-
};
|
|
2226
|
-
}
|
|
2227
|
-
const uniqueConstraints = await this.getUniqueConstraints(tableSchema, tableName);
|
|
2228
|
-
for (const unq of uniqueConstraints) {
|
|
2229
|
-
uniqueConstraintObject[unq.name] = {
|
|
2230
|
-
name: unq.name,
|
|
2231
|
-
columns: unq.columns,
|
|
2232
|
-
nullsNotDistinct: false
|
|
2233
|
-
};
|
|
2234
|
-
}
|
|
2235
|
-
const checkConstraints = await this.getCheckConstraints(tableSchema, tableName);
|
|
2236
|
-
const checksObject = {};
|
|
2237
|
-
for (const check3 of checkConstraints) {
|
|
2238
|
-
checksObject[check3.name] = {
|
|
2239
|
-
name: check3.name,
|
|
2240
|
-
value: check3.definition
|
|
2241
|
-
};
|
|
2242
|
-
}
|
|
2243
|
-
tables[`${tableSchema}.${tableName}`] = {
|
|
2244
|
-
name: tableName,
|
|
2245
|
-
schema: tableSchema,
|
|
2246
|
-
columns: columnsObject,
|
|
2247
|
-
indexes: indexesObject,
|
|
2248
|
-
foreignKeys: foreignKeysObject,
|
|
2249
|
-
compositePrimaryKeys: primaryKeysObject,
|
|
2250
|
-
uniqueConstraints: uniqueConstraintObject,
|
|
2251
|
-
checkConstraints: checksObject
|
|
2252
|
-
};
|
|
2253
|
-
if (tableSchema && tableSchema !== "public") {
|
|
2254
|
-
schemas[tableSchema] = tableSchema;
|
|
2255
|
-
}
|
|
2256
|
-
}
|
|
2257
|
-
const enumsResult = await this.getEnums(schemaName);
|
|
2258
|
-
for (const enumInfo of enumsResult) {
|
|
2259
|
-
const key = `${enumInfo.schema}.${enumInfo.name}`;
|
|
2260
|
-
if (!enums[key]) {
|
|
2261
|
-
enums[key] = {
|
|
2262
|
-
name: enumInfo.name,
|
|
2263
|
-
schema: enumInfo.schema,
|
|
2264
|
-
values: []
|
|
2265
|
-
};
|
|
2266
|
-
}
|
|
2267
|
-
enums[key].values.push(enumInfo.value);
|
|
2316
|
+
const tableNameWithSchema = `"${schema}"."${tableName}"`;
|
|
2317
|
+
const statements = [];
|
|
2318
|
+
const changesTo = changes.to;
|
|
2319
|
+
const changesFrom = changes.from;
|
|
2320
|
+
const changesToType = changesTo?.type;
|
|
2321
|
+
const changesFromType = changesFrom?.type;
|
|
2322
|
+
if (changesToType !== changesFromType) {
|
|
2323
|
+
const newType = changesToType || "TEXT";
|
|
2324
|
+
const needsUsing = checkIfNeedsUsingClause(changesFromType || "", newType);
|
|
2325
|
+
if (needsUsing) {
|
|
2326
|
+
statements.push(`ALTER TABLE ${tableNameWithSchema} ALTER COLUMN "${column}" TYPE ${newType} USING "${column}"::text::${newType};`);
|
|
2327
|
+
} else {
|
|
2328
|
+
statements.push(`ALTER TABLE ${tableNameWithSchema} ALTER COLUMN "${column}" SET DATA TYPE ${newType};`);
|
|
2268
2329
|
}
|
|
2269
|
-
logger4.info({ src: "plugin:sql", tableCount: Object.keys(tables).length }, "Database introspection complete");
|
|
2270
|
-
return {
|
|
2271
|
-
version: "7",
|
|
2272
|
-
dialect: "postgresql",
|
|
2273
|
-
tables,
|
|
2274
|
-
schemas,
|
|
2275
|
-
enums,
|
|
2276
|
-
_meta: {
|
|
2277
|
-
schemas: {},
|
|
2278
|
-
tables: {},
|
|
2279
|
-
columns: {}
|
|
2280
|
-
}
|
|
2281
|
-
};
|
|
2282
|
-
}
|
|
2283
|
-
async getTables(schemaName) {
|
|
2284
|
-
const result = await this.db.execute(sql21`SELECT
|
|
2285
|
-
table_schema,
|
|
2286
|
-
table_name
|
|
2287
|
-
FROM information_schema.tables
|
|
2288
|
-
WHERE table_schema = ${schemaName}
|
|
2289
|
-
AND table_type = 'BASE TABLE'
|
|
2290
|
-
ORDER BY table_name`);
|
|
2291
|
-
return getRows2(result);
|
|
2292
2330
|
}
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
WHEN a.atttypid = ANY ('{int,int8,int2}'::regtype[])
|
|
2302
|
-
AND EXISTS (
|
|
2303
|
-
SELECT FROM pg_attrdef ad
|
|
2304
|
-
WHERE ad.adrelid = a.attrelid
|
|
2305
|
-
AND ad.adnum = a.attnum
|
|
2306
|
-
AND pg_get_expr(ad.adbin, ad.adrelid) = 'nextval('''
|
|
2307
|
-
|| pg_get_serial_sequence(a.attrelid::regclass::text, a.attname)::regclass || '''::regclass)'
|
|
2308
|
-
)
|
|
2309
|
-
THEN CASE a.atttypid
|
|
2310
|
-
WHEN 'int'::regtype THEN 'serial'
|
|
2311
|
-
WHEN 'int8'::regtype THEN 'bigserial'
|
|
2312
|
-
WHEN 'int2'::regtype THEN 'smallserial'
|
|
2313
|
-
END
|
|
2314
|
-
ELSE format_type(a.atttypid, a.atttypmod)
|
|
2315
|
-
END AS data_type,
|
|
2316
|
-
pg_get_expr(ad.adbin, ad.adrelid) AS column_default,
|
|
2317
|
-
CASE
|
|
2318
|
-
WHEN con.contype = 'p' THEN true
|
|
2319
|
-
ELSE false
|
|
2320
|
-
END AS is_primary
|
|
2321
|
-
FROM pg_attribute a
|
|
2322
|
-
JOIN pg_class cls ON cls.oid = a.attrelid
|
|
2323
|
-
JOIN pg_namespace ns ON ns.oid = cls.relnamespace
|
|
2324
|
-
LEFT JOIN pg_attrdef ad ON ad.adrelid = a.attrelid AND ad.adnum = a.attnum
|
|
2325
|
-
LEFT JOIN pg_constraint con ON con.conrelid = a.attrelid
|
|
2326
|
-
AND a.attnum = ANY(con.conkey)
|
|
2327
|
-
AND con.contype = 'p'
|
|
2328
|
-
WHERE
|
|
2329
|
-
a.attnum > 0
|
|
2330
|
-
AND NOT a.attisdropped
|
|
2331
|
-
AND ns.nspname = ${schemaName}
|
|
2332
|
-
AND cls.relname = ${tableName}
|
|
2333
|
-
ORDER BY a.attnum`);
|
|
2334
|
-
return getRows2(result);
|
|
2331
|
+
const changesToNotNull = changesTo?.notNull;
|
|
2332
|
+
const changesFromNotNull = changesFrom?.notNull;
|
|
2333
|
+
if (changesToNotNull !== changesFromNotNull) {
|
|
2334
|
+
if (changesToNotNull) {
|
|
2335
|
+
statements.push(`ALTER TABLE ${tableNameWithSchema} ALTER COLUMN "${column}" SET NOT NULL;`);
|
|
2336
|
+
} else {
|
|
2337
|
+
statements.push(`ALTER TABLE ${tableNameWithSchema} ALTER COLUMN "${column}" DROP NOT NULL;`);
|
|
2338
|
+
}
|
|
2335
2339
|
}
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
WHERE a.attrelid = idx.indrelid
|
|
2346
|
-
AND a.attnum = ANY(idx.indkey::int[])
|
|
2347
|
-
ORDER BY a.attnum
|
|
2348
|
-
) AS columns,
|
|
2349
|
-
am.amname AS method
|
|
2350
|
-
FROM pg_index idx
|
|
2351
|
-
JOIN pg_class i ON i.oid = idx.indexrelid
|
|
2352
|
-
JOIN pg_class c ON c.oid = idx.indrelid
|
|
2353
|
-
JOIN pg_namespace n ON n.oid = c.relnamespace
|
|
2354
|
-
JOIN pg_am am ON am.oid = i.relam
|
|
2355
|
-
LEFT JOIN pg_constraint con ON con.conindid = idx.indexrelid
|
|
2356
|
-
WHERE n.nspname = ${schemaName}
|
|
2357
|
-
AND c.relname = ${tableName}`);
|
|
2358
|
-
return getRows2(result);
|
|
2340
|
+
const changesToDefault = changesTo?.default;
|
|
2341
|
+
const changesFromDefault = changesFrom?.default;
|
|
2342
|
+
if (changesToDefault !== changesFromDefault) {
|
|
2343
|
+
if (changesToDefault !== undefined) {
|
|
2344
|
+
const defaultValue = formatDefaultValue(changesToDefault, changesToType || "");
|
|
2345
|
+
statements.push(`ALTER TABLE ${tableNameWithSchema} ALTER COLUMN "${column}" SET DEFAULT ${defaultValue};`);
|
|
2346
|
+
} else {
|
|
2347
|
+
statements.push(`ALTER TABLE ${tableNameWithSchema} ALTER COLUMN "${column}" DROP DEFAULT;`);
|
|
2348
|
+
}
|
|
2359
2349
|
}
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
CASE con.confupdtype
|
|
2368
|
-
WHEN 'a' THEN 'NO ACTION'
|
|
2369
|
-
WHEN 'r' THEN 'RESTRICT'
|
|
2370
|
-
WHEN 'n' THEN 'SET NULL'
|
|
2371
|
-
WHEN 'c' THEN 'CASCADE'
|
|
2372
|
-
WHEN 'd' THEN 'SET DEFAULT'
|
|
2373
|
-
END AS update_rule,
|
|
2374
|
-
CASE con.confdeltype
|
|
2375
|
-
WHEN 'a' THEN 'NO ACTION'
|
|
2376
|
-
WHEN 'r' THEN 'RESTRICT'
|
|
2377
|
-
WHEN 'n' THEN 'SET NULL'
|
|
2378
|
-
WHEN 'c' THEN 'CASCADE'
|
|
2379
|
-
WHEN 'd' THEN 'SET DEFAULT'
|
|
2380
|
-
END AS delete_rule
|
|
2381
|
-
FROM pg_catalog.pg_constraint con
|
|
2382
|
-
JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
|
|
2383
|
-
JOIN pg_catalog.pg_namespace nsp ON nsp.oid = con.connamespace
|
|
2384
|
-
LEFT JOIN pg_catalog.pg_attribute att ON att.attnum = ANY (con.conkey)
|
|
2385
|
-
AND att.attrelid = con.conrelid
|
|
2386
|
-
LEFT JOIN pg_catalog.pg_class frel ON frel.oid = con.confrelid
|
|
2387
|
-
LEFT JOIN pg_catalog.pg_namespace fnsp ON fnsp.oid = frel.relnamespace
|
|
2388
|
-
LEFT JOIN pg_catalog.pg_attribute fatt ON fatt.attnum = ANY (con.confkey)
|
|
2389
|
-
AND fatt.attrelid = con.confrelid
|
|
2390
|
-
WHERE con.contype = 'f'
|
|
2391
|
-
AND nsp.nspname = ${schemaName}
|
|
2392
|
-
AND rel.relname = ${tableName}`);
|
|
2393
|
-
return getRows2(result);
|
|
2350
|
+
return statements;
|
|
2351
|
+
}
|
|
2352
|
+
function checkIfNeedsUsingClause(fromType, toType) {
|
|
2353
|
+
if (!fromType || !toType)
|
|
2354
|
+
return false;
|
|
2355
|
+
if (fromType.includes("enum") || toType.includes("enum")) {
|
|
2356
|
+
return true;
|
|
2394
2357
|
}
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
SELECT a.attname
|
|
2400
|
-
FROM pg_attribute a
|
|
2401
|
-
WHERE a.attrelid = con.conrelid
|
|
2402
|
-
AND a.attnum = ANY(con.conkey)
|
|
2403
|
-
ORDER BY a.attnum
|
|
2404
|
-
) AS columns
|
|
2405
|
-
FROM pg_constraint con
|
|
2406
|
-
JOIN pg_class rel ON rel.oid = con.conrelid
|
|
2407
|
-
JOIN pg_namespace nsp ON nsp.oid = con.connamespace
|
|
2408
|
-
WHERE con.contype = 'p'
|
|
2409
|
-
AND nsp.nspname = ${schemaName}
|
|
2410
|
-
AND rel.relname = ${tableName}`);
|
|
2411
|
-
return getRows2(result);
|
|
2358
|
+
const fromBase = fromType.split("(")[0].toLowerCase();
|
|
2359
|
+
const toBase = toType.split("(")[0].toLowerCase();
|
|
2360
|
+
if ((fromBase === "text" || fromBase === "varchar" || fromBase === "character varying") && (toBase === "jsonb" || toBase === "json")) {
|
|
2361
|
+
return true;
|
|
2412
2362
|
}
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2363
|
+
const needsUsingPairs = [
|
|
2364
|
+
["integer", "boolean"],
|
|
2365
|
+
["boolean", "integer"],
|
|
2366
|
+
["text", "integer"],
|
|
2367
|
+
["text", "numeric"],
|
|
2368
|
+
["text", "boolean"],
|
|
2369
|
+
["text", "uuid"],
|
|
2370
|
+
["text", "jsonb"],
|
|
2371
|
+
["text", "json"],
|
|
2372
|
+
["varchar", "integer"],
|
|
2373
|
+
["varchar", "numeric"],
|
|
2374
|
+
["varchar", "boolean"],
|
|
2375
|
+
["varchar", "uuid"],
|
|
2376
|
+
["varchar", "jsonb"],
|
|
2377
|
+
["varchar", "json"],
|
|
2378
|
+
["character varying", "jsonb"],
|
|
2379
|
+
["character varying", "json"]
|
|
2380
|
+
];
|
|
2381
|
+
for (const [from, to] of needsUsingPairs) {
|
|
2382
|
+
if (fromBase === from && toBase === to || fromBase === to && toBase === from) {
|
|
2383
|
+
return true;
|
|
2384
|
+
}
|
|
2430
2385
|
}
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
JOIN pg_class rel ON rel.oid = con.conrelid
|
|
2437
|
-
JOIN pg_namespace nsp ON nsp.oid = con.connamespace
|
|
2438
|
-
WHERE con.contype = 'c'
|
|
2439
|
-
AND nsp.nspname = ${schemaName}
|
|
2440
|
-
AND rel.relname = ${tableName}`);
|
|
2441
|
-
return getRows2(result);
|
|
2386
|
+
return false;
|
|
2387
|
+
}
|
|
2388
|
+
function formatDefaultValue(value, type) {
|
|
2389
|
+
if (value === null || value === "NULL") {
|
|
2390
|
+
return "NULL";
|
|
2442
2391
|
}
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
JOIN pg_enum e ON t.oid = e.enumtypid
|
|
2451
|
-
JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace
|
|
2452
|
-
WHERE n.nspname = ${schemaName}
|
|
2453
|
-
ORDER BY schema, name, sort_order`);
|
|
2454
|
-
return getRows2(result);
|
|
2392
|
+
if (type && (type.toLowerCase().includes("boolean") || type.toLowerCase() === "bool")) {
|
|
2393
|
+
if (value === true || value === "true" || value === "t" || value === 1) {
|
|
2394
|
+
return "true";
|
|
2395
|
+
}
|
|
2396
|
+
if (value === false || value === "false" || value === "f" || value === 0) {
|
|
2397
|
+
return "false";
|
|
2398
|
+
}
|
|
2455
2399
|
}
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
if (
|
|
2461
|
-
return
|
|
2400
|
+
if (type?.match(/^(integer|bigint|smallint|numeric|decimal|real|double)/i)) {
|
|
2401
|
+
return String(value);
|
|
2402
|
+
}
|
|
2403
|
+
if (typeof value === "string") {
|
|
2404
|
+
if (value.includes("::")) {
|
|
2405
|
+
return value;
|
|
2462
2406
|
}
|
|
2463
|
-
if (
|
|
2464
|
-
return;
|
|
2407
|
+
if (value.startsWith("'") && value.endsWith("'")) {
|
|
2408
|
+
return value;
|
|
2465
2409
|
}
|
|
2466
|
-
if (
|
|
2467
|
-
|
|
2468
|
-
return "true";
|
|
2469
|
-
if (defaultValue === "false")
|
|
2470
|
-
return "false";
|
|
2410
|
+
if (value.match(/^\w+\(\)/i) || value.includes("(") && value.includes(")")) {
|
|
2411
|
+
return value;
|
|
2471
2412
|
}
|
|
2472
|
-
|
|
2413
|
+
if (value.toUpperCase().startsWith("CURRENT_")) {
|
|
2414
|
+
return value;
|
|
2415
|
+
}
|
|
2416
|
+
return `'${value.replace(/'/g, "''")}'`;
|
|
2473
2417
|
}
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2418
|
+
return String(value);
|
|
2419
|
+
}
|
|
2420
|
+
function generateCreateIndexSQL(index7) {
|
|
2421
|
+
const unique3 = index7.isUnique ? "UNIQUE " : "";
|
|
2422
|
+
const method = index7.method || "btree";
|
|
2423
|
+
const columns = index7.columns.map((c) => {
|
|
2424
|
+
if (c.isExpression) {
|
|
2425
|
+
return c.expression;
|
|
2426
|
+
}
|
|
2427
|
+
return `"${c.expression}"${c.asc === false ? " DESC" : ""}`;
|
|
2428
|
+
}).join(", ");
|
|
2429
|
+
const indexName = index7.name.includes(".") ? index7.name.split(".")[1] : index7.name;
|
|
2430
|
+
let tableRef;
|
|
2431
|
+
const indexTable = index7.table;
|
|
2432
|
+
if (indexTable?.includes(".")) {
|
|
2433
|
+
const [schema, table] = indexTable.split(".");
|
|
2434
|
+
tableRef = `"${schema}"."${table}"`;
|
|
2435
|
+
} else {
|
|
2436
|
+
tableRef = `"${indexTable || ""}"`;
|
|
2483
2437
|
}
|
|
2484
|
-
|
|
2485
|
-
|
|
2438
|
+
return `CREATE ${unique3}INDEX "${indexName}" ON ${tableRef} USING ${method} (${columns});`;
|
|
2439
|
+
}
|
|
2440
|
+
function generateDropIndexSQL(index7) {
|
|
2441
|
+
const indexNameFull = typeof index7 === "string" ? index7 : index7.name;
|
|
2442
|
+
const indexName = indexNameFull.includes(".") ? indexNameFull.split(".")[1] : indexNameFull;
|
|
2443
|
+
return `DROP INDEX IF EXISTS "${indexName}";`;
|
|
2444
|
+
}
|
|
2445
|
+
function generateCreateForeignKeySQL(fk) {
|
|
2446
|
+
return wrapConstraintCreationGuard(fk.name, buildCreateForeignKeyBodySQL(fk));
|
|
2447
|
+
}
|
|
2448
|
+
function generateDropForeignKeySQL(fk) {
|
|
2449
|
+
const [schema, tableName] = fk.tableFrom ? fk.tableFrom.includes(".") ? fk.tableFrom.split(".") : ["public", fk.tableFrom] : ["public", ""];
|
|
2450
|
+
return `ALTER TABLE "${schema}"."${tableName}" DROP CONSTRAINT "${fk.name}";`;
|
|
2451
|
+
}
|
|
2452
|
+
function generateCreateUniqueConstraintSQL(constraint) {
|
|
2453
|
+
const table = constraint.table || "";
|
|
2454
|
+
const [schema, tableName] = table.includes(".") ? table.split(".") : ["public", table];
|
|
2455
|
+
const name = constraint.name;
|
|
2456
|
+
const columns = constraint.columns.map((c) => `"${c}"`).join(", ");
|
|
2457
|
+
let sql22 = `ALTER TABLE "${schema}"."${tableName}" ADD CONSTRAINT "${name}" UNIQUE`;
|
|
2458
|
+
if (constraint.nullsNotDistinct) {
|
|
2459
|
+
sql22 += ` NULLS NOT DISTINCT`;
|
|
2486
2460
|
}
|
|
2461
|
+
sql22 += ` (${columns});`;
|
|
2462
|
+
return sql22;
|
|
2487
2463
|
}
|
|
2488
|
-
|
|
2464
|
+
function generateDropUniqueConstraintSQL(constraint) {
|
|
2465
|
+
const table = constraint.table || "";
|
|
2466
|
+
const [schema, tableName] = table.includes(".") ? table.split(".") : ["public", table];
|
|
2467
|
+
return `ALTER TABLE "${schema}"."${tableName}" DROP CONSTRAINT "${constraint.name}";`;
|
|
2468
|
+
}
|
|
2469
|
+
function generateCreateCheckConstraintSQL(constraint) {
|
|
2470
|
+
const table = constraint.table || "";
|
|
2471
|
+
const [schema, tableName] = table.includes(".") ? table.split(".") : ["public", table];
|
|
2472
|
+
const name = constraint.name;
|
|
2473
|
+
const value = constraint.value;
|
|
2474
|
+
return `ALTER TABLE "${schema}"."${tableName}" ADD CONSTRAINT "${name}" CHECK (${value});`;
|
|
2475
|
+
}
|
|
2476
|
+
function generateDropCheckConstraintSQL(constraint) {
|
|
2477
|
+
const table = constraint.table || "";
|
|
2478
|
+
const [schema, tableName] = table.includes(".") ? table.split(".") : ["public", table];
|
|
2479
|
+
return `ALTER TABLE "${schema}"."${tableName}" DROP CONSTRAINT "${constraint.name}";`;
|
|
2480
|
+
}
|
|
2481
|
+
function buildCreateForeignKeyBodySQL(fk) {
|
|
2482
|
+
const schemaFrom = fk.schemaFrom || "public";
|
|
2483
|
+
const schemaTo = fk.schemaTo || "public";
|
|
2484
|
+
const tableFrom = fk.tableFrom;
|
|
2485
|
+
const columnsFrom = fk.columnsFrom.map((c) => `"${c}"`).join(", ");
|
|
2486
|
+
const columnsTo = fk.columnsTo.map((c) => `"${c}"`).join(", ");
|
|
2487
|
+
let sql22 = `ALTER TABLE "${schemaFrom}"."${tableFrom}" ADD CONSTRAINT "${fk.name}" FOREIGN KEY (${columnsFrom}) REFERENCES "${schemaTo}"."${fk.tableTo}" (${columnsTo})`;
|
|
2488
|
+
if (fk.onDelete) {
|
|
2489
|
+
sql22 += ` ON DELETE ${fk.onDelete}`;
|
|
2490
|
+
}
|
|
2491
|
+
if (fk.onUpdate) {
|
|
2492
|
+
sql22 += ` ON UPDATE ${fk.onUpdate}`;
|
|
2493
|
+
}
|
|
2494
|
+
return sql22;
|
|
2495
|
+
}
|
|
2496
|
+
function wrapConstraintCreationGuard(constraintName, statement) {
|
|
2497
|
+
const escapedConstraintName = constraintName.replace(/'/g, "''");
|
|
2498
|
+
return `DO $$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = '${escapedConstraintName}') THEN ${statement}; END IF; END $$;`;
|
|
2499
|
+
}
|
|
2500
|
+
var init_sql_generator = () => {};
|
|
2489
2501
|
|
|
2490
2502
|
// runtime-migrator/extension-manager.ts
|
|
2491
2503
|
import { logger as logger5 } from "@elizaos/core";
|
|
@@ -3161,14 +3173,10 @@ var init_runtime_migrator = __esm(() => {
|
|
|
3161
3173
|
init_migration_tracker();
|
|
3162
3174
|
init_snapshot_storage();
|
|
3163
3175
|
});
|
|
3176
|
+
|
|
3164
3177
|
// runtime-migrator/index.ts
|
|
3165
3178
|
var init_runtime_migrator2 = __esm(() => {
|
|
3166
|
-
init_snapshot_generator();
|
|
3167
|
-
init_sql_generator();
|
|
3168
3179
|
init_runtime_migrator();
|
|
3169
|
-
init_journal_storage();
|
|
3170
|
-
init_migration_tracker();
|
|
3171
|
-
init_snapshot_storage();
|
|
3172
3180
|
});
|
|
3173
3181
|
|
|
3174
3182
|
// migration-service.ts
|
|
@@ -3782,7 +3790,7 @@ class BaseDrizzleAdapter extends DatabaseAdapter {
|
|
|
3782
3790
|
return [String(names)];
|
|
3783
3791
|
}
|
|
3784
3792
|
isValidUUID(value) {
|
|
3785
|
-
return /^[0-9a-f]{8}-[0-9a-f]{4}-[
|
|
3793
|
+
return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value);
|
|
3786
3794
|
}
|
|
3787
3795
|
normalizeWorldData(world) {
|
|
3788
3796
|
const worldData = {
|
|
@@ -7095,5 +7103,5 @@ export {
|
|
|
7095
7103
|
DatabaseMigrationService
|
|
7096
7104
|
};
|
|
7097
7105
|
|
|
7098
|
-
//# debugId=
|
|
7106
|
+
//# debugId=11DF3BC6739C08E664756E2164756E21
|
|
7099
7107
|
//# sourceMappingURL=index.node.js.map
|