@elizaos/plugin-sql 2.0.0-alpha.16 → 2.0.0-alpha.17

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.
@@ -1036,525 +1036,162 @@ var init_rls = __esm(() => {
1036
1036
  init_server();
1037
1037
  });
1038
1038
 
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);
1039
+ // runtime-migrator/drizzle-adapters/diff-calculator.ts
1040
+ var exports_diff_calculator = {};
1041
+ __export(exports_diff_calculator, {
1042
+ hasDiffChanges: () => hasDiffChanges,
1043
+ calculateDiff: () => calculateDiff
1044
+ });
1045
+ function normalizeType(type) {
1046
+ if (!type)
1047
+ return "";
1048
+ const normalized = type.toLowerCase().trim();
1049
+ if (normalized === "timestamp without time zone" || normalized === "timestamp with time zone") {
1050
+ return "timestamp";
1051
1051
  }
1052
- return (hash >>> 0).toString(16).padStart(8, "0");
1053
- }
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;
1052
+ if (normalized === "serial") {
1053
+ return "integer";
1061
1054
  }
1062
- return lockId;
1063
- }
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;
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[]";
1073
+ }
1074
+ return normalized;
1070
1075
  }
1071
-
1072
- class DatabaseIntrospector {
1073
- db;
1074
- constructor(db) {
1075
- this.db = db;
1076
+ function isIndexChanged(prevIndex, currIndex) {
1077
+ if (prevIndex.isUnique !== currIndex.isUnique)
1078
+ return true;
1079
+ if (prevIndex.method !== currIndex.method)
1080
+ return true;
1081
+ if (prevIndex.where !== currIndex.where)
1082
+ return true;
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
+ }
1076
1107
  }
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
- };
1108
+ return false;
1109
+ }
1110
+ async function calculateDiff(previousSnapshot, currentSnapshot) {
1111
+ const diff = {
1112
+ tables: {
1113
+ created: [],
1114
+ deleted: [],
1115
+ modified: []
1116
+ },
1117
+ columns: {
1118
+ added: [],
1119
+ deleted: [],
1120
+ modified: []
1121
+ },
1122
+ indexes: {
1123
+ created: [],
1124
+ deleted: [],
1125
+ altered: []
1126
+ },
1127
+ foreignKeys: {
1128
+ created: [],
1129
+ deleted: [],
1130
+ altered: []
1131
+ },
1132
+ uniqueConstraints: {
1133
+ created: [],
1134
+ deleted: []
1135
+ },
1136
+ checkConstraints: {
1137
+ created: [],
1138
+ deleted: []
1139
+ }
1140
+ };
1141
+ if (!previousSnapshot) {
1142
+ diff.tables.created = Object.keys(currentSnapshot.tables);
1143
+ for (const tableName in currentSnapshot.tables) {
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
+ }
1098
1152
  }
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
- }
1153
+ if (table.foreignKeys) {
1154
+ for (const fkName in table.foreignKeys) {
1155
+ diff.foreignKeys.created.push(table.foreignKeys[fkName]);
1114
1156
  }
1115
1157
  }
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
- };
1158
+ }
1159
+ return diff;
1160
+ }
1161
+ const prevTables = previousSnapshot.tables || {};
1162
+ const currTables = currentSnapshot.tables || {};
1163
+ for (const tableName in currTables) {
1164
+ if (!(tableName in prevTables)) {
1165
+ diff.tables.created.push(tableName);
1166
+ const table = currTables[tableName];
1167
+ if (table.indexes) {
1168
+ for (const indexName in table.indexes) {
1169
+ diff.indexes.created.push({
1170
+ ...table.indexes[indexName],
1171
+ table: tableName
1172
+ });
1173
+ }
1130
1174
  }
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
- };
1175
+ if (table.uniqueConstraints) {
1176
+ for (const uqName in table.uniqueConstraints) {
1177
+ diff.uniqueConstraints.created.push({
1178
+ ...table.uniqueConstraints[uqName],
1179
+ table: tableName
1180
+ });
1181
+ }
1138
1182
  }
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
- };
1183
+ if (table.checkConstraints) {
1184
+ for (const checkName in table.checkConstraints) {
1185
+ diff.checkConstraints.created.push({
1186
+ ...table.checkConstraints[checkName],
1187
+ table: tableName
1188
+ });
1189
+ }
1146
1190
  }
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
- };
1154
- }
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
- }
1191
+ if (table.foreignKeys) {
1192
+ for (const fkName in table.foreignKeys) {
1193
+ diff.foreignKeys.created.push(table.foreignKeys[fkName]);
1194
+ }
1558
1195
  }
1559
1196
  }
1560
1197
  }
@@ -1730,6 +1367,32 @@ function hasDiffChanges(diff) {
1730
1367
  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;
1731
1368
  }
1732
1369
 
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
+
1733
1396
  // runtime-migrator/drizzle-adapters/snapshot-generator.ts
1734
1397
  import { is, SQL } from "drizzle-orm";
1735
1398
  import { getTableConfig, PgDialect, PgTable } from "drizzle-orm/pg-core";
@@ -1958,7 +1621,7 @@ function hasChanges(previousSnapshot, currentSnapshot) {
1958
1621
  const currHash = hashSnapshot(currentSnapshot);
1959
1622
  return prevHash !== currHash;
1960
1623
  }
1961
- var sqlToStr = (sql22, _casing) => {
1624
+ var sqlToStr = (sql21, _casing) => {
1962
1625
  const config = {
1963
1626
  escapeName: () => {
1964
1627
  throw new Error("we don't support params for `sql` default values");
@@ -1971,12 +1634,12 @@ var sqlToStr = (sql22, _casing) => {
1971
1634
  },
1972
1635
  casing: undefined
1973
1636
  };
1974
- return sql22.toQuery(config).sql;
1637
+ return sql21.toQuery(config).sql;
1975
1638
  };
1976
1639
  var init_snapshot_generator = () => {};
1977
1640
 
1978
1641
  // runtime-migrator/drizzle-adapters/sql-generator.ts
1979
- import { logger as logger4 } from "@elizaos/core";
1642
+ import { logger as logger3 } from "@elizaos/core";
1980
1643
  function checkForDataLoss(diff) {
1981
1644
  const result = {
1982
1645
  hasDataLoss: false,
@@ -2106,7 +1769,7 @@ async function generateMigrationSQL(previousSnapshot, currentSnapshot, diff) {
2106
1769
  }
2107
1770
  const dataLossCheck = checkForDataLoss(diff);
2108
1771
  if (dataLossCheck.warnings.length > 0) {
2109
- logger4.warn({ src: "plugin:sql", warnings: dataLossCheck.warnings }, "Schema changes may cause data loss");
1772
+ logger3.warn({ src: "plugin:sql", warnings: dataLossCheck.warnings }, "Schema changes may cause data loss");
2110
1773
  }
2111
1774
  const schemasToCreate = new Set;
2112
1775
  for (const tableName of diff.tables.created) {
@@ -2265,18 +1928,18 @@ function generateCreateTableSQL(fullTableName, table) {
2265
1928
  return { tableSQL, fkSQLs };
2266
1929
  }
2267
1930
  function generateColumnDefinition(name, def) {
2268
- let sql22 = `"${name}" ${def.type}`;
1931
+ let sql21 = `"${name}" ${def.type}`;
2269
1932
  if (def.primaryKey && !def.type.includes("SERIAL")) {
2270
- sql22 += " PRIMARY KEY";
1933
+ sql21 += " PRIMARY KEY";
2271
1934
  }
2272
1935
  if (def.notNull) {
2273
- sql22 += " NOT NULL";
1936
+ sql21 += " NOT NULL";
2274
1937
  }
2275
1938
  if (def.default !== undefined) {
2276
1939
  const defaultValue = formatDefaultValue(def.default, def.type);
2277
- sql22 += ` DEFAULT ${defaultValue}`;
1940
+ sql21 += ` DEFAULT ${defaultValue}`;
2278
1941
  }
2279
- return sql22;
1942
+ return sql21;
2280
1943
  }
2281
1944
  function generateAddColumnSQL(table, column, definition) {
2282
1945
  const [schema, tableName] = table.includes(".") ? table.split(".") : ["public", table];
@@ -2296,196 +1959,533 @@ function generateAddColumnSQL(table, column, definition) {
2296
1959
  if (definitionWithGenerated.generated) {
2297
1960
  parts.push(`GENERATED ALWAYS AS (${definitionWithGenerated.generated}) STORED`);
2298
1961
  }
2299
- if (definition.notNull) {
2300
- parts.push("NOT NULL");
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}`;
2301
2115
  }
2302
- return `ALTER TABLE ${tableNameWithSchema} ADD COLUMN ${parts.join(" ")};`;
2116
+ return `${sql21};`;
2303
2117
  }
2304
- function generateDropColumnSQL(table, column) {
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 || "";
2305
2124
  const [schema, tableName] = table.includes(".") ? table.split(".") : ["public", table];
2306
- const tableNameWithSchema = `"${schema}"."${tableName}"`;
2307
- return `ALTER TABLE ${tableNameWithSchema} DROP COLUMN "${column}" CASCADE;`;
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`;
2130
+ }
2131
+ sql21 += ` (${columns});`;
2132
+ return sql21;
2308
2133
  }
2309
- function generateAlterColumnSQL(table, column, changes) {
2134
+ function generateDropUniqueConstraintSQL(constraint) {
2135
+ const table = constraint.table || "";
2310
2136
  const [schema, tableName] = table.includes(".") ? table.split(".") : ["public", table];
2311
- const tableNameWithSchema = `"${schema}"."${tableName}"`;
2312
- const statements = [];
2313
- const changesTo = changes.to;
2314
- const changesFrom = changes.from;
2315
- const changesToType = changesTo?.type;
2316
- const changesFromType = changesFrom?.type;
2317
- if (changesToType !== changesFromType) {
2318
- const newType = changesToType || "TEXT";
2319
- const needsUsing = checkIfNeedsUsingClause(changesFromType || "", newType);
2320
- if (needsUsing) {
2321
- statements.push(`ALTER TABLE ${tableNameWithSchema} ALTER COLUMN "${column}" TYPE ${newType} USING "${column}"::text::${newType};`);
2322
- } else {
2323
- statements.push(`ALTER TABLE ${tableNameWithSchema} ALTER COLUMN "${column}" SET DATA TYPE ${newType};`);
2324
- }
2137
+ return `ALTER TABLE "${schema}"."${tableName}" DROP CONSTRAINT "${constraint.name}";`;
2138
+ }
2139
+ function generateCreateCheckConstraintSQL(constraint) {
2140
+ const table = constraint.table || "";
2141
+ const [schema, tableName] = table.includes(".") ? table.split(".") : ["public", table];
2142
+ const name = constraint.name;
2143
+ const value = constraint.value;
2144
+ return `ALTER TABLE "${schema}"."${tableName}" ADD CONSTRAINT "${name}" CHECK (${value});`;
2145
+ }
2146
+ function generateDropCheckConstraintSQL(constraint) {
2147
+ const table = constraint.table || "";
2148
+ const [schema, tableName] = table.includes(".") ? table.split(".") : ["public", table];
2149
+ return `ALTER TABLE "${schema}"."${tableName}" DROP CONSTRAINT "${constraint.name}";`;
2150
+ }
2151
+ var init_sql_generator = () => {};
2152
+
2153
+ // runtime-migrator/drizzle-adapters/database-introspector.ts
2154
+ import { logger as logger4 } from "@elizaos/core";
2155
+ import { sql as sql21 } from "drizzle-orm";
2156
+ function getRows2(result) {
2157
+ return result.rows;
2158
+ }
2159
+
2160
+ class DatabaseIntrospector {
2161
+ db;
2162
+ constructor(db) {
2163
+ this.db = db;
2325
2164
  }
2326
- const changesToNotNull = changesTo?.notNull;
2327
- const changesFromNotNull = changesFrom?.notNull;
2328
- if (changesToNotNull !== changesFromNotNull) {
2329
- if (changesToNotNull) {
2330
- statements.push(`ALTER TABLE ${tableNameWithSchema} ALTER COLUMN "${column}" SET NOT NULL;`);
2331
- } else {
2332
- statements.push(`ALTER TABLE ${tableNameWithSchema} ALTER COLUMN "${column}" DROP NOT NULL;`);
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
+ }
2333
2256
  }
2334
- }
2335
- const changesToDefault = changesTo?.default;
2336
- const changesFromDefault = changesFrom?.default;
2337
- if (changesToDefault !== changesFromDefault) {
2338
- if (changesToDefault !== undefined) {
2339
- const defaultValue = formatDefaultValue(changesToDefault, changesToType || "");
2340
- statements.push(`ALTER TABLE ${tableNameWithSchema} ALTER COLUMN "${column}" SET DEFAULT ${defaultValue};`);
2341
- } else {
2342
- statements.push(`ALTER TABLE ${tableNameWithSchema} ALTER COLUMN "${column}" DROP DEFAULT;`);
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);
2343
2268
  }
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
+ };
2344
2282
  }
2345
- return statements;
2346
- }
2347
- function checkIfNeedsUsingClause(fromType, toType) {
2348
- if (!fromType || !toType)
2349
- return false;
2350
- if (fromType.includes("enum") || toType.includes("enum")) {
2351
- return true;
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
+ }
2293
+ async getColumns(schemaName, tableName) {
2294
+ const result = await this.db.execute(sql21`SELECT
2295
+ a.attname AS column_name,
2296
+ CASE
2297
+ WHEN a.attnotnull THEN 'NO'
2298
+ ELSE 'YES'
2299
+ END AS is_nullable,
2300
+ CASE
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);
2335
+ }
2336
+ async getIndexes(schemaName, tableName) {
2337
+ const result = await this.db.execute(sql21`SELECT
2338
+ i.relname AS name,
2339
+ idx.indisunique AS is_unique,
2340
+ idx.indisprimary AS is_primary,
2341
+ con.contype = 'u' AS is_unique_constraint,
2342
+ ARRAY(
2343
+ SELECT a.attname
2344
+ FROM pg_attribute a
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);
2352
2359
  }
2353
- const fromBase = fromType.split("(")[0].toLowerCase();
2354
- const toBase = toType.split("(")[0].toLowerCase();
2355
- if ((fromBase === "text" || fromBase === "varchar" || fromBase === "character varying") && (toBase === "jsonb" || toBase === "json")) {
2356
- return true;
2360
+ async getForeignKeys(schemaName, tableName) {
2361
+ const result = await this.db.execute(sql21`SELECT
2362
+ con.conname AS name,
2363
+ att.attname AS column_name,
2364
+ fnsp.nspname AS foreign_table_schema,
2365
+ frel.relname AS foreign_table_name,
2366
+ fatt.attname AS foreign_column_name,
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);
2357
2394
  }
2358
- const needsUsingPairs = [
2359
- ["integer", "boolean"],
2360
- ["boolean", "integer"],
2361
- ["text", "integer"],
2362
- ["text", "numeric"],
2363
- ["text", "boolean"],
2364
- ["text", "uuid"],
2365
- ["text", "jsonb"],
2366
- ["text", "json"],
2367
- ["varchar", "integer"],
2368
- ["varchar", "numeric"],
2369
- ["varchar", "boolean"],
2370
- ["varchar", "uuid"],
2371
- ["varchar", "jsonb"],
2372
- ["varchar", "json"],
2373
- ["character varying", "jsonb"],
2374
- ["character varying", "json"]
2375
- ];
2376
- for (const [from, to] of needsUsingPairs) {
2377
- if (fromBase === from && toBase === to || fromBase === to && toBase === from) {
2378
- return true;
2379
- }
2395
+ async getPrimaryKeys(schemaName, tableName) {
2396
+ const result = await this.db.execute(sql21`SELECT
2397
+ con.conname AS name,
2398
+ ARRAY(
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);
2380
2412
  }
2381
- return false;
2382
- }
2383
- function formatDefaultValue(value, type) {
2384
- if (value === null || value === "NULL") {
2385
- return "NULL";
2413
+ async getUniqueConstraints(schemaName, tableName) {
2414
+ const result = await this.db.execute(sql21`SELECT
2415
+ con.conname AS name,
2416
+ ARRAY(
2417
+ SELECT a.attname
2418
+ FROM pg_attribute a
2419
+ WHERE a.attrelid = con.conrelid
2420
+ AND a.attnum = ANY(con.conkey)
2421
+ ORDER BY a.attnum
2422
+ ) AS columns
2423
+ FROM pg_constraint con
2424
+ JOIN pg_class rel ON rel.oid = con.conrelid
2425
+ JOIN pg_namespace nsp ON nsp.oid = con.connamespace
2426
+ WHERE con.contype = 'u'
2427
+ AND nsp.nspname = ${schemaName}
2428
+ AND rel.relname = ${tableName}`);
2429
+ return getRows2(result);
2386
2430
  }
2387
- if (type && (type.toLowerCase().includes("boolean") || type.toLowerCase() === "bool")) {
2388
- if (value === true || value === "true" || value === "t" || value === 1) {
2389
- return "true";
2390
- }
2391
- if (value === false || value === "false" || value === "f" || value === 0) {
2392
- return "false";
2393
- }
2431
+ async getCheckConstraints(schemaName, tableName) {
2432
+ const result = await this.db.execute(sql21`SELECT
2433
+ con.conname AS name,
2434
+ pg_get_constraintdef(con.oid) AS definition
2435
+ FROM pg_constraint con
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);
2394
2442
  }
2395
- if (type?.match(/^(integer|bigint|smallint|numeric|decimal|real|double)/i)) {
2396
- return String(value);
2443
+ async getEnums(schemaName) {
2444
+ const result = await this.db.execute(sql21`SELECT
2445
+ n.nspname AS schema,
2446
+ t.typname AS name,
2447
+ e.enumlabel AS value,
2448
+ e.enumsortorder AS sort_order
2449
+ FROM pg_type t
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);
2397
2455
  }
2398
- if (typeof value === "string") {
2399
- if (value.includes("::")) {
2400
- return value;
2401
- }
2402
- if (value.startsWith("'") && value.endsWith("'")) {
2403
- return value;
2404
- }
2405
- if (value.match(/^\w+\(\)/i) || value.includes("(") && value.includes(")")) {
2406
- return value;
2456
+ parseDefault(defaultValue, dataType) {
2457
+ if (!defaultValue)
2458
+ return;
2459
+ const match = defaultValue.match(/^'(.*)'::/);
2460
+ if (match) {
2461
+ return `'${match[1]}'`;
2407
2462
  }
2408
- if (value.toUpperCase().startsWith("CURRENT_")) {
2409
- return value;
2463
+ if (defaultValue.includes("nextval(")) {
2464
+ return;
2410
2465
  }
2411
- return `'${value.replace(/'/g, "''")}'`;
2412
- }
2413
- return String(value);
2414
- }
2415
- function generateCreateIndexSQL(index7) {
2416
- const unique3 = index7.isUnique ? "UNIQUE " : "";
2417
- const method = index7.method || "btree";
2418
- const columns = index7.columns.map((c) => {
2419
- if (c.isExpression) {
2420
- return c.expression;
2466
+ if (dataType === "boolean") {
2467
+ if (defaultValue === "true")
2468
+ return "true";
2469
+ if (defaultValue === "false")
2470
+ return "false";
2421
2471
  }
2422
- return `"${c.expression}"${c.asc === false ? " DESC" : ""}`;
2423
- }).join(", ");
2424
- const indexName = index7.name.includes(".") ? index7.name.split(".")[1] : index7.name;
2425
- let tableRef;
2426
- const indexTable = index7.table;
2427
- if (indexTable?.includes(".")) {
2428
- const [schema, table] = indexTable.split(".");
2429
- tableRef = `"${schema}"."${table}"`;
2430
- } else {
2431
- tableRef = `"${indexTable || ""}"`;
2432
- }
2433
- return `CREATE ${unique3}INDEX "${indexName}" ON ${tableRef} USING ${method} (${columns});`;
2434
- }
2435
- function generateDropIndexSQL(index7) {
2436
- const indexNameFull = typeof index7 === "string" ? index7 : index7.name;
2437
- const indexName = indexNameFull.includes(".") ? indexNameFull.split(".")[1] : indexNameFull;
2438
- return `DROP INDEX IF EXISTS "${indexName}";`;
2439
- }
2440
- function generateCreateForeignKeySQL(fk) {
2441
- const schemaFrom = fk.schemaFrom || "public";
2442
- const schemaTo = fk.schemaTo || "public";
2443
- const tableFrom = fk.tableFrom;
2444
- const columnsFrom = fk.columnsFrom.map((c) => `"${c}"`).join(", ");
2445
- const columnsTo = fk.columnsTo.map((c) => `"${c}"`).join(", ");
2446
- let sql22 = `ALTER TABLE "${schemaFrom}"."${tableFrom}" ADD CONSTRAINT "${fk.name}" FOREIGN KEY (${columnsFrom}) REFERENCES "${schemaTo}"."${fk.tableTo}" (${columnsTo})`;
2447
- if (fk.onDelete) {
2448
- sql22 += ` ON DELETE ${fk.onDelete}`;
2472
+ return defaultValue;
2449
2473
  }
2450
- if (fk.onUpdate) {
2451
- sql22 += ` ON UPDATE ${fk.onUpdate}`;
2474
+ async hasExistingTables(pluginName) {
2475
+ const schemaName = pluginName === "@elizaos/plugin-sql" ? "public" : this.deriveSchemaName(pluginName);
2476
+ const result = await this.db.execute(sql21`SELECT COUNT(*) AS count
2477
+ FROM information_schema.tables
2478
+ WHERE table_schema = ${schemaName}
2479
+ AND table_type = 'BASE TABLE'`);
2480
+ const firstRow = result.rows?.[0];
2481
+ const count = parseInt(firstRow && firstRow.count || "0", 10);
2482
+ return count > 0;
2452
2483
  }
2453
- return `${sql22};`;
2454
- }
2455
- function generateDropForeignKeySQL(fk) {
2456
- const [schema, tableName] = fk.tableFrom ? fk.tableFrom.includes(".") ? fk.tableFrom.split(".") : ["public", fk.tableFrom] : ["public", ""];
2457
- return `ALTER TABLE "${schema}"."${tableName}" DROP CONSTRAINT "${fk.name}";`;
2458
- }
2459
- function generateCreateUniqueConstraintSQL(constraint) {
2460
- const table = constraint.table || "";
2461
- const [schema, tableName] = table.includes(".") ? table.split(".") : ["public", table];
2462
- const name = constraint.name;
2463
- const columns = constraint.columns.map((c) => `"${c}"`).join(", ");
2464
- let sql22 = `ALTER TABLE "${schema}"."${tableName}" ADD CONSTRAINT "${name}" UNIQUE`;
2465
- if (constraint.nullsNotDistinct) {
2466
- sql22 += ` NULLS NOT DISTINCT`;
2484
+ deriveSchemaName(pluginName) {
2485
+ return pluginName.replace("@", "").replace("/", "_").replace(/-/g, "_").toLowerCase();
2467
2486
  }
2468
- sql22 += ` (${columns});`;
2469
- return sql22;
2470
- }
2471
- function generateDropUniqueConstraintSQL(constraint) {
2472
- const table = constraint.table || "";
2473
- const [schema, tableName] = table.includes(".") ? table.split(".") : ["public", table];
2474
- return `ALTER TABLE "${schema}"."${tableName}" DROP CONSTRAINT "${constraint.name}";`;
2475
- }
2476
- function generateCreateCheckConstraintSQL(constraint) {
2477
- const table = constraint.table || "";
2478
- const [schema, tableName] = table.includes(".") ? table.split(".") : ["public", table];
2479
- const name = constraint.name;
2480
- const value = constraint.value;
2481
- return `ALTER TABLE "${schema}"."${tableName}" ADD CONSTRAINT "${name}" CHECK (${value});`;
2482
- }
2483
- function generateDropCheckConstraintSQL(constraint) {
2484
- const table = constraint.table || "";
2485
- const [schema, tableName] = table.includes(".") ? table.split(".") : ["public", table];
2486
- return `ALTER TABLE "${schema}"."${tableName}" DROP CONSTRAINT "${constraint.name}";`;
2487
2487
  }
2488
- var init_sql_generator = () => {};
2488
+ var init_database_introspector = () => {};
2489
2489
 
2490
2490
  // runtime-migrator/extension-manager.ts
2491
2491
  import { logger as logger5 } from "@elizaos/core";
@@ -3161,10 +3161,14 @@ var init_runtime_migrator = __esm(() => {
3161
3161
  init_migration_tracker();
3162
3162
  init_snapshot_storage();
3163
3163
  });
3164
-
3165
3164
  // runtime-migrator/index.ts
3166
3165
  var init_runtime_migrator2 = __esm(() => {
3166
+ init_snapshot_generator();
3167
+ init_sql_generator();
3167
3168
  init_runtime_migrator();
3169
+ init_journal_storage();
3170
+ init_migration_tracker();
3171
+ init_snapshot_storage();
3168
3172
  });
3169
3173
 
3170
3174
  // migration-service.ts
@@ -7091,5 +7095,5 @@ export {
7091
7095
  DatabaseMigrationService
7092
7096
  };
7093
7097
 
7094
- //# debugId=42019694876F4CEA64756E2164756E21
7098
+ //# debugId=65F51AC9F4802DC764756E2164756E21
7095
7099
  //# sourceMappingURL=index.node.js.map