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

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,170 +1036,533 @@ var init_rls = __esm(() => {
1036
1036
  init_server();
1037
1037
  });
1038
1038
 
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
- }
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 normalized;
1052
+ return (hash >>> 0).toString(16).padStart(8, "0");
1075
1053
  }
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
- }
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 false;
1062
+ return lockId;
1109
1063
  }
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
- }
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
- if (table.foreignKeys) {
1154
- for (const fkName in table.foreignKeys) {
1155
- diff.foreignKeys.created.push(table.foreignKeys[fkName]);
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
- 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
- }
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
- if (table.uniqueConstraints) {
1176
- for (const uqName in table.uniqueConstraints) {
1177
- diff.uniqueConstraints.created.push({
1178
- ...table.uniqueConstraints[uqName],
1179
- table: tableName
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
- if (table.checkConstraints) {
1184
- for (const checkName in table.checkConstraints) {
1185
- diff.checkConstraints.created.push({
1186
- ...table.checkConstraints[checkName],
1187
- table: tableName
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
- if (table.foreignKeys) {
1192
- for (const fkName in table.foreignKeys) {
1193
- diff.foreignKeys.created.push(table.foreignKeys[fkName]);
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
- for (const tableName in prevTables) {
1199
- if (!(tableName in currTables)) {
1200
- diff.tables.deleted.push(tableName);
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];
@@ -1358,1134 +1721,783 @@ async function calculateDiff(previousSnapshot, currentSnapshot) {
1358
1721
  tableFrom: tableName
1359
1722
  });
1360
1723
  }
1361
- }
1362
- }
1363
- }
1364
- return diff;
1365
- }
1366
- function hasDiffChanges(diff) {
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;
1368
- }
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
-
1396
- // runtime-migrator/drizzle-adapters/snapshot-generator.ts
1397
- import { is, SQL } from "drizzle-orm";
1398
- import { getTableConfig, PgDialect, PgTable } from "drizzle-orm/pg-core";
1399
- function escapeSingleQuotes(str) {
1400
- return str.replace(/'/g, "''");
1401
- }
1402
- function isPgArrayType(sqlType) {
1403
- return sqlType.match(/.*\[\d*\].*|.*\[\].*/g) !== null;
1404
- }
1405
- function buildArrayString(array, sqlType) {
1406
- sqlType = sqlType.split("[")[0];
1407
- const values = array.map((value) => {
1408
- if (typeof value === "number" || typeof value === "bigint") {
1409
- return value.toString();
1410
- } else if (typeof value === "boolean") {
1411
- return value ? "true" : "false";
1412
- } else if (Array.isArray(value)) {
1413
- return buildArrayString(value, sqlType);
1414
- } else if (value instanceof Date) {
1415
- if (sqlType === "date") {
1416
- return `"${value.toISOString().split("T")[0]}"`;
1417
- } else if (sqlType === "timestamp") {
1418
- return `"${value.toISOString().replace("T", " ").slice(0, 23)}"`;
1419
- } else {
1420
- return `"${value.toISOString()}"`;
1421
- }
1422
- } else if (typeof value === "object") {
1423
- return `"${JSON.stringify(value).replaceAll('"', "\\\"")}"`;
1424
- }
1425
- return `"${value}"`;
1426
- }).join(",");
1427
- return `{${values}}`;
1428
- }
1429
- function extractTablesFromSchema(schema) {
1430
- const tables = [];
1431
- const exports = Object.values(schema);
1432
- exports.forEach((t) => {
1433
- if (is(t, PgTable)) {
1434
- tables.push(t);
1435
- }
1436
- });
1437
- return tables;
1438
- }
1439
- async function generateSnapshot(schema) {
1440
- const dialect = new PgDialect({ casing: undefined });
1441
- const tables = {};
1442
- const schemas = {};
1443
- const enums = {};
1444
- const pgTables = extractTablesFromSchema(schema);
1445
- for (const table of pgTables) {
1446
- const config = getTableConfig(table);
1447
- const {
1448
- name: tableName,
1449
- columns,
1450
- indexes,
1451
- foreignKeys,
1452
- schema: tableSchema,
1453
- primaryKeys,
1454
- uniqueConstraints,
1455
- checks
1456
- } = config;
1457
- const columnsObject = {};
1458
- const indexesObject = {};
1459
- const foreignKeysObject = {};
1460
- const primaryKeysObject = {};
1461
- const uniqueConstraintObject = {};
1462
- const checksObject = {};
1463
- columns.forEach((column) => {
1464
- const name = column.name;
1465
- const notNull = column.notNull;
1466
- const primaryKey4 = column.primary;
1467
- const sqlType = column.getSQLType();
1468
- const sqlTypeLowered = sqlType.toLowerCase();
1469
- const columnToSet = {
1470
- name,
1471
- type: sqlType,
1472
- primaryKey: primaryKey4,
1473
- notNull
1474
- };
1475
- if (column.default !== undefined) {
1476
- if (is(column.default, SQL)) {
1477
- columnToSet.default = sqlToStr(column.default, undefined);
1478
- } else {
1479
- if (typeof column.default === "string") {
1480
- columnToSet.default = `'${escapeSingleQuotes(column.default)}'`;
1481
- } else {
1482
- if (sqlTypeLowered === "jsonb" || sqlTypeLowered === "json") {
1483
- columnToSet.default = `'${JSON.stringify(column.default)}'::${sqlTypeLowered}`;
1484
- } else if (column.default instanceof Date) {
1485
- if (sqlTypeLowered === "date") {
1486
- columnToSet.default = `'${column.default.toISOString().split("T")[0]}'`;
1487
- } else if (sqlTypeLowered === "timestamp") {
1488
- columnToSet.default = `'${column.default.toISOString().replace("T", " ").slice(0, 23)}'`;
1489
- } else {
1490
- columnToSet.default = `'${column.default.toISOString()}'`;
1491
- }
1492
- } else if (isPgArrayType(sqlTypeLowered) && Array.isArray(column.default)) {
1493
- columnToSet.default = `'${buildArrayString(column.default, sqlTypeLowered)}'`;
1494
- } else {
1495
- columnToSet.default = column.default;
1496
- }
1497
- }
1498
- }
1499
- }
1500
- const columnWithConfig = column;
1501
- const columnConfig = columnWithConfig.config;
1502
- if (columnWithConfig.isUnique && columnConfig && columnConfig.uniqueName) {
1503
- uniqueConstraintObject[columnConfig.uniqueName] = {
1504
- name: columnConfig.uniqueName,
1505
- columns: [name],
1506
- nullsNotDistinct: columnConfig.uniqueType === "not distinct"
1507
- };
1508
- }
1509
- columnsObject[name] = columnToSet;
1510
- });
1511
- primaryKeys.forEach((pk) => {
1512
- const columnNames = pk.columns.map((c) => c.name);
1513
- const name = pk.getName();
1514
- primaryKeysObject[name] = {
1515
- name,
1516
- columns: columnNames
1517
- };
1518
- });
1519
- uniqueConstraints?.forEach((unq) => {
1520
- const columnNames = unq.columns.map((c) => c.name);
1521
- const name = unq.name || `${tableName}_${columnNames.join("_")}_unique`;
1522
- uniqueConstraintObject[name] = {
1523
- name,
1524
- columns: columnNames,
1525
- nullsNotDistinct: unq.nullsNotDistinct
1526
- };
1527
- });
1528
- foreignKeys.forEach((fk) => {
1529
- const reference = fk.reference();
1530
- const columnsFrom = reference.columns.map((it) => it.name);
1531
- const columnsTo = reference.foreignColumns.map((it) => it.name);
1532
- const tableTo = getTableConfig(reference.foreignTable).name;
1533
- const schemaTo = getTableConfig(reference.foreignTable).schema || "public";
1534
- const name = fk.getName();
1535
- foreignKeysObject[name] = {
1536
- name,
1537
- tableFrom: tableName,
1538
- schemaFrom: tableSchema,
1539
- tableTo,
1540
- schemaTo,
1541
- columnsFrom,
1542
- columnsTo,
1543
- onDelete: fk.onDelete || "no action",
1544
- onUpdate: fk.onUpdate || "no action"
1545
- };
1546
- });
1547
- indexes.forEach((idx) => {
1548
- const indexCols = idx.config.columns;
1549
- const indexColumns = indexCols.map((col) => {
1550
- if (is(col, SQL)) {
1551
- return {
1552
- expression: dialect.sqlToQuery(col).sql,
1553
- isExpression: true
1554
- };
1555
- } else {
1556
- const indexCol = {
1557
- expression: col.name,
1558
- isExpression: false,
1559
- asc: col.indexConfig && col.indexConfig.order === "asc"
1560
- };
1561
- if (col.indexConfig?.nulls) {
1562
- indexCol.nulls = col.indexConfig.nulls;
1563
- }
1564
- return indexCol;
1565
- }
1566
- });
1567
- const name = idx.config.name || `${tableName}_${indexColumns.map((c) => c.expression).join("_")}_index`;
1568
- indexesObject[name] = {
1569
- name,
1570
- columns: indexColumns,
1571
- isUnique: idx.config.unique || false,
1572
- method: idx.config.method || "btree"
1573
- };
1574
- });
1575
- if (checks) {
1576
- checks.forEach((check3) => {
1577
- const checkName = check3.name;
1578
- checksObject[checkName] = {
1579
- name: checkName,
1580
- value: dialect.sqlToQuery(check3.value).sql
1581
- };
1582
- });
1583
- }
1584
- tables[`${tableSchema || "public"}.${tableName}`] = {
1585
- name: tableName,
1586
- schema: tableSchema || "public",
1587
- columns: columnsObject,
1588
- indexes: indexesObject,
1589
- foreignKeys: foreignKeysObject,
1590
- compositePrimaryKeys: primaryKeysObject,
1591
- uniqueConstraints: uniqueConstraintObject,
1592
- checkConstraints: checksObject
1593
- };
1594
- if (tableSchema && tableSchema !== "public") {
1595
- schemas[tableSchema] = tableSchema;
1724
+ }
1596
1725
  }
1597
1726
  }
1598
- const snapshot = {
1599
- version: "7",
1600
- dialect: "postgresql",
1601
- tables,
1602
- schemas,
1603
- enums,
1604
- _meta: {
1605
- schemas: {},
1606
- tables: {},
1607
- columns: {}
1608
- }
1609
- };
1610
- return snapshot;
1611
- }
1612
- function hashSnapshot(snapshot) {
1613
- const content = JSON.stringify(snapshot);
1614
- return extendedHash(content);
1727
+ return diff;
1615
1728
  }
1616
- function hasChanges(previousSnapshot, currentSnapshot) {
1617
- if (!previousSnapshot) {
1618
- return Object.keys(currentSnapshot.tables).length > 0;
1619
- }
1620
- const prevHash = hashSnapshot(previousSnapshot);
1621
- const currHash = hashSnapshot(currentSnapshot);
1622
- return prevHash !== currHash;
1729
+ function hasDiffChanges(diff) {
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;
1623
1731
  }
1624
- var sqlToStr = (sql21, _casing) => {
1625
- const config = {
1626
- escapeName: () => {
1627
- throw new Error("we don't support params for `sql` default values");
1628
- },
1629
- escapeParam: () => {
1630
- throw new Error("we don't support params for `sql` default values");
1631
- },
1632
- escapeString: () => {
1633
- throw new Error("we don't support params for `sql` default values");
1634
- },
1635
- casing: undefined
1636
- };
1637
- return sql21.toQuery(config).sql;
1638
- };
1639
- var init_snapshot_generator = () => {};
1640
1732
 
1641
- // runtime-migrator/drizzle-adapters/sql-generator.ts
1642
- import { logger as logger3 } from "@elizaos/core";
1643
- function checkForDataLoss(diff) {
1644
- const result = {
1645
- hasDataLoss: false,
1646
- tablesToRemove: [],
1647
- columnsToRemove: [],
1648
- tablesToTruncate: [],
1649
- typeChanges: [],
1650
- warnings: [],
1651
- requiresConfirmation: false
1652
- };
1653
- if (diff.tables.deleted.length > 0) {
1654
- result.hasDataLoss = true;
1655
- result.requiresConfirmation = true;
1656
- result.tablesToRemove = [...diff.tables.deleted];
1657
- for (const table of diff.tables.deleted) {
1658
- result.warnings.push(`Table "${table}" will be dropped with all its data`);
1659
- }
1660
- }
1661
- if (diff.columns.deleted.length > 0) {
1662
- result.hasDataLoss = true;
1663
- result.requiresConfirmation = true;
1664
- for (const col of diff.columns.deleted) {
1665
- result.columnsToRemove.push(`${col.table}.${col.column}`);
1666
- result.warnings.push(`Column "${col.column}" in table "${col.table}" will be dropped`);
1667
- }
1668
- }
1669
- for (const modified of diff.columns.modified) {
1670
- const from = modified.changes.from;
1671
- const to = modified.changes.to;
1672
- if (!from || !to)
1673
- continue;
1674
- if (from.type !== to.type) {
1675
- const isDestructive = checkIfTypeChangeIsDestructive(from.type, to.type);
1676
- if (isDestructive) {
1677
- result.hasDataLoss = true;
1678
- result.requiresConfirmation = true;
1679
- result.typeChanges.push({
1680
- table: modified.table,
1681
- column: modified.column,
1682
- from: from.type,
1683
- to: to.type
1684
- });
1685
- result.tablesToTruncate.push(modified.table);
1686
- result.warnings.push(`Column "${modified.column}" in table "${modified.table}" changes type from "${from.type}" to "${to.type}". ` + `This may require truncating the table to avoid data conversion errors.`);
1733
+ // runtime-migrator/drizzle-adapters/snapshot-generator.ts
1734
+ import { is, SQL } from "drizzle-orm";
1735
+ import { getTableConfig, PgDialect, PgTable } from "drizzle-orm/pg-core";
1736
+ function escapeSingleQuotes(str) {
1737
+ return str.replace(/'/g, "''");
1738
+ }
1739
+ function isPgArrayType(sqlType) {
1740
+ return sqlType.match(/.*\[\d*\].*|.*\[\].*/g) !== null;
1741
+ }
1742
+ function buildArrayString(array, sqlType) {
1743
+ sqlType = sqlType.split("[")[0];
1744
+ const values = array.map((value) => {
1745
+ if (typeof value === "number" || typeof value === "bigint") {
1746
+ return value.toString();
1747
+ } else if (typeof value === "boolean") {
1748
+ return value ? "true" : "false";
1749
+ } else if (Array.isArray(value)) {
1750
+ return buildArrayString(value, sqlType);
1751
+ } else if (value instanceof Date) {
1752
+ if (sqlType === "date") {
1753
+ return `"${value.toISOString().split("T")[0]}"`;
1754
+ } else if (sqlType === "timestamp") {
1755
+ return `"${value.toISOString().replace("T", " ").slice(0, 23)}"`;
1756
+ } else {
1757
+ return `"${value.toISOString()}"`;
1687
1758
  }
1759
+ } else if (typeof value === "object") {
1760
+ return `"${JSON.stringify(value).replaceAll('"', "\\\"")}"`;
1688
1761
  }
1689
- if (!from.notNull && to.notNull && !to.default) {
1690
- result.hasDataLoss = true;
1691
- result.requiresConfirmation = true;
1692
- result.warnings.push(`Column "${modified.column}" in table "${modified.table}" is becoming NOT NULL without a default value. ` + `This will fail if the table contains NULL values.`);
1693
- }
1694
- }
1695
- for (const added of diff.columns.added) {
1696
- if (added.definition.notNull && !added.definition.default) {
1697
- result.warnings.push(`Column "${added.column}" is being added to table "${added.table}" as NOT NULL without a default value. ` + `This will fail if the table contains data.`);
1698
- }
1699
- }
1700
- return result;
1762
+ return `"${value}"`;
1763
+ }).join(",");
1764
+ return `{${values}}`;
1701
1765
  }
1702
- function normalizeType2(type) {
1703
- if (!type)
1704
- return "";
1705
- const normalized = type.toLowerCase().trim();
1706
- if (normalized === "timestamp without time zone" || normalized === "timestamp with time zone" || normalized === "timestamptz") {
1707
- return "timestamp";
1708
- }
1709
- if (normalized === "serial") {
1710
- return "integer";
1711
- }
1712
- if (normalized === "bigserial") {
1713
- return "bigint";
1714
- }
1715
- if (normalized === "smallserial") {
1716
- return "smallint";
1717
- }
1718
- if (normalized.startsWith("numeric") || normalized.startsWith("decimal")) {
1719
- const match = normalized.match(/\((\d+)(?:,\s*(\d+))?\)/);
1720
- if (match) {
1721
- return `numeric(${match[1]}${match[2] ? `,${match[2]}` : ""})`;
1766
+ function extractTablesFromSchema(schema) {
1767
+ const tables = [];
1768
+ const exports = Object.values(schema);
1769
+ exports.forEach((t) => {
1770
+ if (is(t, PgTable)) {
1771
+ tables.push(t);
1722
1772
  }
1723
- return "numeric";
1724
- }
1725
- if (normalized.startsWith("character varying")) {
1726
- return normalized.replace("character varying", "varchar");
1727
- }
1728
- if (normalized === "text[]" || normalized === "_text") {
1729
- return "text[]";
1730
- }
1731
- return normalized;
1732
- }
1733
- function checkIfTypeChangeIsDestructive(fromType, toType) {
1734
- const normalizedFrom = normalizeType2(fromType);
1735
- const normalizedTo = normalizeType2(toType);
1736
- if (normalizedFrom === normalizedTo) {
1737
- return false;
1738
- }
1739
- const safeConversions = {
1740
- smallint: ["integer", "bigint", "numeric", "real", "double precision"],
1741
- integer: ["bigint", "numeric", "real", "double precision"],
1742
- bigint: ["numeric"],
1743
- real: ["double precision"],
1744
- varchar: ["text"],
1745
- char: ["varchar", "text"],
1746
- citext: ["text"],
1747
- text: ["citext"],
1748
- uuid: ["text", "varchar"],
1749
- timestamp: ["timestamp"],
1750
- date: ["timestamp"],
1751
- time: ["timetz"]
1752
- };
1753
- const fromBase = normalizedFrom.split("(")[0];
1754
- const toBase = normalizedTo.split("(")[0];
1755
- if (fromBase === toBase) {
1756
- return false;
1757
- }
1758
- const safeTo = safeConversions[fromBase];
1759
- if (safeTo?.includes(toBase)) {
1760
- return false;
1761
- }
1762
- return true;
1773
+ });
1774
+ return tables;
1763
1775
  }
1764
- async function generateMigrationSQL(previousSnapshot, currentSnapshot, diff) {
1765
- const statements = [];
1766
- if (!diff) {
1767
- const { calculateDiff: calculateDiff2 } = await Promise.resolve().then(() => exports_diff_calculator);
1768
- diff = await calculateDiff2(previousSnapshot, currentSnapshot);
1769
- }
1770
- const dataLossCheck = checkForDataLoss(diff);
1771
- if (dataLossCheck.warnings.length > 0) {
1772
- logger3.warn({ src: "plugin:sql", warnings: dataLossCheck.warnings }, "Schema changes may cause data loss");
1773
- }
1774
- const schemasToCreate = new Set;
1775
- for (const tableName of diff.tables.created) {
1776
- const table = currentSnapshot.tables[tableName];
1777
- if (table) {
1778
- const schema = table.schema || "public";
1779
- if (schema !== "public") {
1780
- schemasToCreate.add(schema);
1776
+ async function generateSnapshot(schema) {
1777
+ const dialect = new PgDialect({ casing: undefined });
1778
+ const tables = {};
1779
+ const schemas = {};
1780
+ const enums = {};
1781
+ const pgTables = extractTablesFromSchema(schema);
1782
+ for (const table of pgTables) {
1783
+ const config = getTableConfig(table);
1784
+ const {
1785
+ name: tableName,
1786
+ columns,
1787
+ indexes,
1788
+ foreignKeys,
1789
+ schema: tableSchema,
1790
+ primaryKeys,
1791
+ uniqueConstraints,
1792
+ checks
1793
+ } = config;
1794
+ const columnsObject = {};
1795
+ const indexesObject = {};
1796
+ const foreignKeysObject = {};
1797
+ const primaryKeysObject = {};
1798
+ const uniqueConstraintObject = {};
1799
+ const checksObject = {};
1800
+ columns.forEach((column) => {
1801
+ const name = column.name;
1802
+ const notNull = column.notNull;
1803
+ const primaryKey4 = column.primary;
1804
+ const sqlType = column.getSQLType();
1805
+ const sqlTypeLowered = sqlType.toLowerCase();
1806
+ const columnToSet = {
1807
+ name,
1808
+ type: sqlType,
1809
+ primaryKey: primaryKey4,
1810
+ notNull
1811
+ };
1812
+ if (column.default !== undefined) {
1813
+ if (is(column.default, SQL)) {
1814
+ columnToSet.default = sqlToStr(column.default, undefined);
1815
+ } else {
1816
+ if (typeof column.default === "string") {
1817
+ columnToSet.default = `'${escapeSingleQuotes(column.default)}'`;
1818
+ } else {
1819
+ if (sqlTypeLowered === "jsonb" || sqlTypeLowered === "json") {
1820
+ columnToSet.default = `'${JSON.stringify(column.default)}'::${sqlTypeLowered}`;
1821
+ } else if (column.default instanceof Date) {
1822
+ if (sqlTypeLowered === "date") {
1823
+ columnToSet.default = `'${column.default.toISOString().split("T")[0]}'`;
1824
+ } else if (sqlTypeLowered === "timestamp") {
1825
+ columnToSet.default = `'${column.default.toISOString().replace("T", " ").slice(0, 23)}'`;
1826
+ } else {
1827
+ columnToSet.default = `'${column.default.toISOString()}'`;
1828
+ }
1829
+ } else if (isPgArrayType(sqlTypeLowered) && Array.isArray(column.default)) {
1830
+ columnToSet.default = `'${buildArrayString(column.default, sqlTypeLowered)}'`;
1831
+ } else {
1832
+ columnToSet.default = column.default;
1833
+ }
1834
+ }
1835
+ }
1781
1836
  }
1782
- }
1783
- }
1784
- for (const schema of schemasToCreate) {
1785
- statements.push(`CREATE SCHEMA IF NOT EXISTS "${schema}";`);
1786
- }
1787
- const createTableStatements = [];
1788
- const foreignKeyStatements = [];
1789
- for (const tableName of diff.tables.created) {
1790
- const table = currentSnapshot.tables[tableName];
1791
- if (table) {
1792
- const { tableSQL, fkSQLs } = generateCreateTableSQL(tableName, table);
1793
- createTableStatements.push(tableSQL);
1794
- foreignKeyStatements.push(...fkSQLs);
1795
- }
1796
- }
1797
- statements.push(...createTableStatements);
1798
- const uniqueFKs = new Set;
1799
- const dedupedFKStatements = [];
1800
- for (const fkSQL of foreignKeyStatements) {
1801
- const match = fkSQL.match(/ADD CONSTRAINT "([^"]+)"/);
1802
- if (match) {
1803
- const constraintName = match[1];
1804
- if (!uniqueFKs.has(constraintName)) {
1805
- uniqueFKs.add(constraintName);
1806
- dedupedFKStatements.push(fkSQL);
1837
+ const columnWithConfig = column;
1838
+ const columnConfig = columnWithConfig.config;
1839
+ if (columnWithConfig.isUnique && columnConfig && columnConfig.uniqueName) {
1840
+ uniqueConstraintObject[columnConfig.uniqueName] = {
1841
+ name: columnConfig.uniqueName,
1842
+ columns: [name],
1843
+ nullsNotDistinct: columnConfig.uniqueType === "not distinct"
1844
+ };
1807
1845
  }
1808
- } else {
1809
- dedupedFKStatements.push(fkSQL);
1810
- }
1811
- }
1812
- statements.push(...dedupedFKStatements);
1813
- for (const tableName of diff.tables.deleted) {
1814
- const [schema, name] = tableName.includes(".") ? tableName.split(".") : ["public", tableName];
1815
- statements.push(`DROP TABLE IF EXISTS "${schema}"."${name}" CASCADE;`);
1816
- }
1817
- for (const added of diff.columns.added) {
1818
- statements.push(generateAddColumnSQL(added.table, added.column, added.definition));
1819
- }
1820
- for (const deleted of diff.columns.deleted) {
1821
- statements.push(generateDropColumnSQL(deleted.table, deleted.column));
1822
- }
1823
- for (const modified of diff.columns.modified) {
1824
- const alterStatements = generateAlterColumnSQL(modified.table, modified.column, modified.changes);
1825
- statements.push(...alterStatements);
1826
- }
1827
- for (const index7 of diff.indexes.deleted) {
1828
- statements.push(generateDropIndexSQL(index7));
1829
- }
1830
- for (const alteredIndex of diff.indexes.altered) {
1831
- statements.push(generateDropIndexSQL(alteredIndex.old));
1832
- }
1833
- for (const index7 of diff.indexes.created) {
1834
- statements.push(generateCreateIndexSQL(index7));
1835
- }
1836
- for (const alteredIndex of diff.indexes.altered) {
1837
- statements.push(generateCreateIndexSQL(alteredIndex.new));
1838
- }
1839
- for (const constraint of diff.uniqueConstraints.created) {
1840
- const isNewTable = diff.tables.created.some((tableName) => {
1841
- const [schema, table] = tableName.includes(".") ? tableName.split(".") : ["public", tableName];
1842
- const constraintTable = constraint.table || "";
1843
- const [constraintSchema, constraintTableName] = constraintTable.includes(".") ? constraintTable.split(".") : ["public", constraintTable];
1844
- return table === constraintTableName && schema === constraintSchema;
1846
+ columnsObject[name] = columnToSet;
1845
1847
  });
1846
- if (!isNewTable) {
1847
- statements.push(generateCreateUniqueConstraintSQL(constraint));
1848
- }
1849
- }
1850
- for (const constraint of diff.uniqueConstraints.deleted) {
1851
- statements.push(generateDropUniqueConstraintSQL(constraint));
1852
- }
1853
- for (const constraint of diff.checkConstraints.created) {
1854
- const isNewTable = diff.tables.created.some((tableName) => {
1855
- const [schema, table] = tableName.includes(".") ? tableName.split(".") : ["public", tableName];
1856
- const constraintTable = constraint.table || "";
1857
- const [constraintSchema, constraintTableName] = constraintTable.includes(".") ? constraintTable.split(".") : ["public", constraintTable];
1858
- return table === constraintTableName && schema === constraintSchema;
1848
+ primaryKeys.forEach((pk) => {
1849
+ const columnNames = pk.columns.map((c) => c.name);
1850
+ const name = pk.getName();
1851
+ primaryKeysObject[name] = {
1852
+ name,
1853
+ columns: columnNames
1854
+ };
1859
1855
  });
1860
- if (!isNewTable) {
1861
- statements.push(generateCreateCheckConstraintSQL(constraint));
1862
- }
1863
- }
1864
- for (const constraint of diff.checkConstraints.deleted) {
1865
- statements.push(generateDropCheckConstraintSQL(constraint));
1866
- }
1867
- for (const fk of diff.foreignKeys.deleted) {
1868
- statements.push(generateDropForeignKeySQL(fk));
1869
- }
1870
- for (const alteredFK of diff.foreignKeys.altered) {
1871
- statements.push(generateDropForeignKeySQL(alteredFK.old));
1872
- }
1873
- for (const fk of diff.foreignKeys.created) {
1874
- const tableFrom = fk.tableFrom || "";
1875
- const schemaFrom = fk.schemaFrom || "public";
1876
- const isNewTable = diff.tables.created.some((tableName) => {
1877
- const [createdSchema, createdTable] = tableName.includes(".") ? tableName.split(".") : ["public", tableName];
1878
- return createdTable === tableFrom && createdSchema === schemaFrom;
1856
+ uniqueConstraints?.forEach((unq) => {
1857
+ const columnNames = unq.columns.map((c) => c.name);
1858
+ const name = unq.name || `${tableName}_${columnNames.join("_")}_unique`;
1859
+ uniqueConstraintObject[name] = {
1860
+ name,
1861
+ columns: columnNames,
1862
+ nullsNotDistinct: unq.nullsNotDistinct
1863
+ };
1879
1864
  });
1880
- if (!isNewTable) {
1881
- statements.push(generateCreateForeignKeySQL(fk));
1865
+ foreignKeys.forEach((fk) => {
1866
+ const reference = fk.reference();
1867
+ const columnsFrom = reference.columns.map((it) => it.name);
1868
+ const columnsTo = reference.foreignColumns.map((it) => it.name);
1869
+ const tableTo = getTableConfig(reference.foreignTable).name;
1870
+ const schemaTo = getTableConfig(reference.foreignTable).schema || "public";
1871
+ const name = fk.getName();
1872
+ foreignKeysObject[name] = {
1873
+ name,
1874
+ tableFrom: tableName,
1875
+ schemaFrom: tableSchema,
1876
+ tableTo,
1877
+ schemaTo,
1878
+ columnsFrom,
1879
+ columnsTo,
1880
+ onDelete: fk.onDelete || "no action",
1881
+ onUpdate: fk.onUpdate || "no action"
1882
+ };
1883
+ });
1884
+ indexes.forEach((idx) => {
1885
+ const indexCols = idx.config.columns;
1886
+ const indexColumns = indexCols.map((col) => {
1887
+ if (is(col, SQL)) {
1888
+ return {
1889
+ expression: dialect.sqlToQuery(col).sql,
1890
+ isExpression: true
1891
+ };
1892
+ } else {
1893
+ const indexCol = {
1894
+ expression: col.name,
1895
+ isExpression: false,
1896
+ asc: col.indexConfig && col.indexConfig.order === "asc"
1897
+ };
1898
+ if (col.indexConfig?.nulls) {
1899
+ indexCol.nulls = col.indexConfig.nulls;
1900
+ }
1901
+ return indexCol;
1902
+ }
1903
+ });
1904
+ const name = idx.config.name || `${tableName}_${indexColumns.map((c) => c.expression).join("_")}_index`;
1905
+ indexesObject[name] = {
1906
+ name,
1907
+ columns: indexColumns,
1908
+ isUnique: idx.config.unique || false,
1909
+ method: idx.config.method || "btree"
1910
+ };
1911
+ });
1912
+ if (checks) {
1913
+ checks.forEach((check3) => {
1914
+ const checkName = check3.name;
1915
+ checksObject[checkName] = {
1916
+ name: checkName,
1917
+ value: dialect.sqlToQuery(check3.value).sql
1918
+ };
1919
+ });
1920
+ }
1921
+ tables[`${tableSchema || "public"}.${tableName}`] = {
1922
+ name: tableName,
1923
+ schema: tableSchema || "public",
1924
+ columns: columnsObject,
1925
+ indexes: indexesObject,
1926
+ foreignKeys: foreignKeysObject,
1927
+ compositePrimaryKeys: primaryKeysObject,
1928
+ uniqueConstraints: uniqueConstraintObject,
1929
+ checkConstraints: checksObject
1930
+ };
1931
+ if (tableSchema && tableSchema !== "public") {
1932
+ schemas[tableSchema] = tableSchema;
1882
1933
  }
1883
1934
  }
1884
- for (const alteredFK of diff.foreignKeys.altered) {
1885
- statements.push(generateCreateForeignKeySQL(alteredFK.new));
1886
- }
1887
- return statements;
1935
+ const snapshot = {
1936
+ version: "7",
1937
+ dialect: "postgresql",
1938
+ tables,
1939
+ schemas,
1940
+ enums,
1941
+ _meta: {
1942
+ schemas: {},
1943
+ tables: {},
1944
+ columns: {}
1945
+ }
1946
+ };
1947
+ return snapshot;
1948
+ }
1949
+ function hashSnapshot(snapshot) {
1950
+ const content = JSON.stringify(snapshot);
1951
+ return extendedHash(content);
1888
1952
  }
1889
- function generateCreateTableSQL(fullTableName, table) {
1890
- const [schema, tableName] = fullTableName.includes(".") ? fullTableName.split(".") : ["public", fullTableName];
1891
- const columns = [];
1892
- const fkSQLs = [];
1893
- for (const [colName, colDef] of Object.entries(table.columns || {})) {
1894
- columns.push(generateColumnDefinition(colName, colDef));
1953
+ function hasChanges(previousSnapshot, currentSnapshot) {
1954
+ if (!previousSnapshot) {
1955
+ return Object.keys(currentSnapshot.tables).length > 0;
1895
1956
  }
1896
- const primaryKeys = table.compositePrimaryKeys || {};
1897
- for (const [pkName, pkDef] of Object.entries(primaryKeys)) {
1898
- const pk = pkDef;
1899
- if (pk.columns && pk.columns.length > 0) {
1900
- columns.push(`CONSTRAINT "${pkName}" PRIMARY KEY (${pk.columns.map((c) => `"${c}"`).join(", ")})`);
1957
+ const prevHash = hashSnapshot(previousSnapshot);
1958
+ const currHash = hashSnapshot(currentSnapshot);
1959
+ return prevHash !== currHash;
1960
+ }
1961
+ var sqlToStr = (sql22, _casing) => {
1962
+ const config = {
1963
+ escapeName: () => {
1964
+ throw new Error("we don't support params for `sql` default values");
1965
+ },
1966
+ escapeParam: () => {
1967
+ throw new Error("we don't support params for `sql` default values");
1968
+ },
1969
+ escapeString: () => {
1970
+ throw new Error("we don't support params for `sql` default values");
1971
+ },
1972
+ casing: undefined
1973
+ };
1974
+ return sql22.toQuery(config).sql;
1975
+ };
1976
+ var init_snapshot_generator = () => {};
1977
+
1978
+ // runtime-migrator/drizzle-adapters/sql-generator.ts
1979
+ import { logger as logger4 } from "@elizaos/core";
1980
+ function checkForDataLoss(diff) {
1981
+ const result = {
1982
+ hasDataLoss: false,
1983
+ tablesToRemove: [],
1984
+ columnsToRemove: [],
1985
+ tablesToTruncate: [],
1986
+ typeChanges: [],
1987
+ warnings: [],
1988
+ requiresConfirmation: false
1989
+ };
1990
+ if (diff.tables.deleted.length > 0) {
1991
+ result.hasDataLoss = true;
1992
+ result.requiresConfirmation = true;
1993
+ result.tablesToRemove = [...diff.tables.deleted];
1994
+ for (const table of diff.tables.deleted) {
1995
+ result.warnings.push(`Table "${table}" will be dropped with all its data`);
1901
1996
  }
1902
1997
  }
1903
- const uniqueConstraints = table.uniqueConstraints || {};
1904
- for (const [uqName, uqDef] of Object.entries(uniqueConstraints)) {
1905
- const uq = uqDef;
1906
- if (uq.columns && uq.columns.length > 0) {
1907
- const uniqueDef = uq.nullsNotDistinct ? `CONSTRAINT "${uqName}" UNIQUE NULLS NOT DISTINCT (${uq.columns.map((c) => `"${c}"`).join(", ")})` : `CONSTRAINT "${uqName}" UNIQUE (${uq.columns.map((c) => `"${c}"`).join(", ")})`;
1908
- columns.push(uniqueDef);
1998
+ if (diff.columns.deleted.length > 0) {
1999
+ result.hasDataLoss = true;
2000
+ result.requiresConfirmation = true;
2001
+ for (const col of diff.columns.deleted) {
2002
+ result.columnsToRemove.push(`${col.table}.${col.column}`);
2003
+ result.warnings.push(`Column "${col.column}" in table "${col.table}" will be dropped`);
1909
2004
  }
1910
2005
  }
1911
- const checkConstraints = table.checkConstraints || {};
1912
- for (const [checkName, checkDef] of Object.entries(checkConstraints)) {
1913
- const check3 = checkDef;
1914
- if (check3.value) {
1915
- columns.push(`CONSTRAINT "${checkName}" CHECK (${check3.value})`);
2006
+ for (const modified of diff.columns.modified) {
2007
+ const from = modified.changes.from;
2008
+ const to = modified.changes.to;
2009
+ if (!from || !to)
2010
+ continue;
2011
+ if (from.type !== to.type) {
2012
+ const isDestructive = checkIfTypeChangeIsDestructive(from.type, to.type);
2013
+ if (isDestructive) {
2014
+ result.hasDataLoss = true;
2015
+ result.requiresConfirmation = true;
2016
+ result.typeChanges.push({
2017
+ table: modified.table,
2018
+ column: modified.column,
2019
+ from: from.type,
2020
+ to: to.type
2021
+ });
2022
+ result.tablesToTruncate.push(modified.table);
2023
+ result.warnings.push(`Column "${modified.column}" in table "${modified.table}" changes type from "${from.type}" to "${to.type}". ` + `This may require truncating the table to avoid data conversion errors.`);
2024
+ }
2025
+ }
2026
+ if (!from.notNull && to.notNull && !to.default) {
2027
+ result.hasDataLoss = true;
2028
+ result.requiresConfirmation = true;
2029
+ result.warnings.push(`Column "${modified.column}" in table "${modified.table}" is becoming NOT NULL without a default value. ` + `This will fail if the table contains NULL values.`);
1916
2030
  }
1917
2031
  }
1918
- const tableSQL = `CREATE TABLE IF NOT EXISTS "${schema}"."${tableName}" (
1919
- ${columns.join(`,
1920
- `)}
1921
- );`;
1922
- const foreignKeys = table.foreignKeys || {};
1923
- for (const [fkName, fkDef] of Object.entries(foreignKeys)) {
1924
- const fk = fkDef;
1925
- const fkSQL = `ALTER TABLE "${schema}"."${tableName}" ADD CONSTRAINT "${fkName}" FOREIGN KEY (${fk.columnsFrom.map((c) => `"${c}"`).join(", ")}) REFERENCES "${fk.schemaTo || "public"}"."${fk.tableTo}" (${fk.columnsTo.map((c) => `"${c}"`).join(", ")})${fk.onDelete ? ` ON DELETE ${fk.onDelete}` : ""}${fk.onUpdate ? ` ON UPDATE ${fk.onUpdate}` : ""};`;
1926
- fkSQLs.push(fkSQL);
2032
+ for (const added of diff.columns.added) {
2033
+ if (added.definition.notNull && !added.definition.default) {
2034
+ result.warnings.push(`Column "${added.column}" is being added to table "${added.table}" as NOT NULL without a default value. ` + `This will fail if the table contains data.`);
2035
+ }
1927
2036
  }
1928
- return { tableSQL, fkSQLs };
2037
+ return result;
1929
2038
  }
1930
- function generateColumnDefinition(name, def) {
1931
- let sql21 = `"${name}" ${def.type}`;
1932
- if (def.primaryKey && !def.type.includes("SERIAL")) {
1933
- sql21 += " PRIMARY KEY";
2039
+ function normalizeType2(type) {
2040
+ if (!type)
2041
+ return "";
2042
+ const normalized = type.toLowerCase().trim();
2043
+ if (normalized === "timestamp without time zone" || normalized === "timestamp with time zone" || normalized === "timestamptz") {
2044
+ return "timestamp";
1934
2045
  }
1935
- if (def.notNull) {
1936
- sql21 += " NOT NULL";
2046
+ if (normalized === "serial") {
2047
+ return "integer";
1937
2048
  }
1938
- if (def.default !== undefined) {
1939
- const defaultValue = formatDefaultValue(def.default, def.type);
1940
- sql21 += ` DEFAULT ${defaultValue}`;
2049
+ if (normalized === "bigserial") {
2050
+ return "bigint";
1941
2051
  }
1942
- return sql21;
1943
- }
1944
- function generateAddColumnSQL(table, column, definition) {
1945
- const [schema, tableName] = table.includes(".") ? table.split(".") : ["public", table];
1946
- const tableNameWithSchema = `"${schema}"."${tableName}"`;
1947
- const parts = [`"${column}"`];
1948
- parts.push(definition.type);
1949
- if (definition.primaryKey) {
1950
- parts.push("PRIMARY KEY");
2052
+ if (normalized === "smallserial") {
2053
+ return "smallint";
1951
2054
  }
1952
- if (definition.default !== undefined) {
1953
- const defaultValue = formatDefaultValue(definition.default, definition.type);
1954
- if (defaultValue) {
1955
- parts.push(`DEFAULT ${defaultValue}`);
2055
+ if (normalized.startsWith("numeric") || normalized.startsWith("decimal")) {
2056
+ const match = normalized.match(/\((\d+)(?:,\s*(\d+))?\)/);
2057
+ if (match) {
2058
+ return `numeric(${match[1]}${match[2] ? `,${match[2]}` : ""})`;
1956
2059
  }
2060
+ return "numeric";
1957
2061
  }
1958
- const definitionWithGenerated = definition;
1959
- if (definitionWithGenerated.generated) {
1960
- parts.push(`GENERATED ALWAYS AS (${definitionWithGenerated.generated}) STORED`);
2062
+ if (normalized.startsWith("character varying")) {
2063
+ return normalized.replace("character varying", "varchar");
1961
2064
  }
1962
- if (definition.notNull) {
1963
- parts.push("NOT NULL");
2065
+ if (normalized === "text[]" || normalized === "_text") {
2066
+ return "text[]";
1964
2067
  }
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;`;
2068
+ return normalized;
1971
2069
  }
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
- }
2070
+ function checkIfTypeChangeIsDestructive(fromType, toType) {
2071
+ const normalizedFrom = normalizeType2(fromType);
2072
+ const normalizedTo = normalizeType2(toType);
2073
+ if (normalizedFrom === normalizedTo) {
2074
+ return false;
2007
2075
  }
2008
- return statements;
2009
- }
2010
- function checkIfNeedsUsingClause(fromType, toType) {
2011
- if (!fromType || !toType)
2076
+ const safeConversions = {
2077
+ smallint: ["integer", "bigint", "numeric", "real", "double precision"],
2078
+ integer: ["bigint", "numeric", "real", "double precision"],
2079
+ bigint: ["numeric"],
2080
+ real: ["double precision"],
2081
+ varchar: ["text"],
2082
+ char: ["varchar", "text"],
2083
+ citext: ["text"],
2084
+ text: ["citext"],
2085
+ uuid: ["text", "varchar"],
2086
+ timestamp: ["timestamp"],
2087
+ date: ["timestamp"],
2088
+ time: ["timetz"]
2089
+ };
2090
+ const fromBase = normalizedFrom.split("(")[0];
2091
+ const toBase = normalizedTo.split("(")[0];
2092
+ if (fromBase === toBase) {
2012
2093
  return false;
2013
- if (fromType.includes("enum") || toType.includes("enum")) {
2014
- return true;
2015
2094
  }
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;
2095
+ const safeTo = safeConversions[fromBase];
2096
+ if (safeTo?.includes(toBase)) {
2097
+ return false;
2020
2098
  }
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
- }
2099
+ return true;
2100
+ }
2101
+ async function generateMigrationSQL(previousSnapshot, currentSnapshot, diff) {
2102
+ const statements = [];
2103
+ if (!diff) {
2104
+ const { calculateDiff: calculateDiff2 } = await Promise.resolve().then(() => exports_diff_calculator);
2105
+ diff = await calculateDiff2(previousSnapshot, currentSnapshot);
2043
2106
  }
2044
- return false;
2045
- }
2046
- function formatDefaultValue(value, type) {
2047
- if (value === null || value === "NULL") {
2048
- return "NULL";
2107
+ const dataLossCheck = checkForDataLoss(diff);
2108
+ if (dataLossCheck.warnings.length > 0) {
2109
+ logger4.warn({ src: "plugin:sql", warnings: dataLossCheck.warnings }, "Schema changes may cause data loss");
2049
2110
  }
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";
2111
+ const schemasToCreate = new Set;
2112
+ for (const tableName of diff.tables.created) {
2113
+ const table = currentSnapshot.tables[tableName];
2114
+ if (table) {
2115
+ const schema = table.schema || "public";
2116
+ if (schema !== "public") {
2117
+ schemasToCreate.add(schema);
2118
+ }
2056
2119
  }
2057
2120
  }
2058
- if (type?.match(/^(integer|bigint|smallint|numeric|decimal|real|double)/i)) {
2059
- return String(value);
2121
+ for (const schema of schemasToCreate) {
2122
+ statements.push(`CREATE SCHEMA IF NOT EXISTS "${schema}";`);
2060
2123
  }
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;
2124
+ const createTableStatements = [];
2125
+ const foreignKeyStatements = [];
2126
+ for (const tableName of diff.tables.created) {
2127
+ const table = currentSnapshot.tables[tableName];
2128
+ if (table) {
2129
+ const { tableSQL, fkSQLs } = generateCreateTableSQL(tableName, table);
2130
+ createTableStatements.push(tableSQL);
2131
+ foreignKeyStatements.push(...fkSQLs);
2073
2132
  }
2074
- return `'${value.replace(/'/g, "''")}'`;
2075
2133
  }
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;
2134
+ statements.push(...createTableStatements);
2135
+ const uniqueFKs = new Set;
2136
+ const dedupedFKStatements = [];
2137
+ for (const fkSQL of foreignKeyStatements) {
2138
+ const match = fkSQL.match(/ADD CONSTRAINT "([^"]+)"/);
2139
+ if (match) {
2140
+ const constraintName = match[1];
2141
+ if (!uniqueFKs.has(constraintName)) {
2142
+ uniqueFKs.add(constraintName);
2143
+ dedupedFKStatements.push(fkSQL);
2144
+ }
2145
+ } else {
2146
+ dedupedFKStatements.push(fkSQL);
2084
2147
  }
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
2148
  }
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}`;
2149
+ statements.push(...dedupedFKStatements);
2150
+ for (const tableName of diff.tables.deleted) {
2151
+ const [schema, name] = tableName.includes(".") ? tableName.split(".") : ["public", tableName];
2152
+ statements.push(`DROP TABLE IF EXISTS "${schema}"."${name}" CASCADE;`);
2112
2153
  }
2113
- if (fk.onUpdate) {
2114
- sql21 += ` ON UPDATE ${fk.onUpdate}`;
2154
+ for (const added of diff.columns.added) {
2155
+ statements.push(generateAddColumnSQL(added.table, added.column, added.definition));
2115
2156
  }
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`;
2157
+ for (const deleted of diff.columns.deleted) {
2158
+ statements.push(generateDropColumnSQL(deleted.table, deleted.column));
2130
2159
  }
2131
- sql21 += ` (${columns});`;
2132
- return sql21;
2133
- }
2134
- function generateDropUniqueConstraintSQL(constraint) {
2135
- const table = constraint.table || "";
2136
- const [schema, tableName] = table.includes(".") ? table.split(".") : ["public", table];
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;
2160
+ for (const modified of diff.columns.modified) {
2161
+ const alterStatements = generateAlterColumnSQL(modified.table, modified.column, modified.changes);
2162
+ statements.push(...alterStatements);
2164
2163
  }
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
- }
2164
+ for (const index7 of diff.indexes.deleted) {
2165
+ statements.push(generateDropIndexSQL(index7));
2166
+ }
2167
+ for (const alteredIndex of diff.indexes.altered) {
2168
+ statements.push(generateDropIndexSQL(alteredIndex.old));
2169
+ }
2170
+ for (const index7 of diff.indexes.created) {
2171
+ statements.push(generateCreateIndexSQL(index7));
2172
+ }
2173
+ for (const alteredIndex of diff.indexes.altered) {
2174
+ statements.push(generateCreateIndexSQL(alteredIndex.new));
2175
+ }
2176
+ for (const constraint of diff.uniqueConstraints.created) {
2177
+ const isNewTable = diff.tables.created.some((tableName) => {
2178
+ const [schema, table] = tableName.includes(".") ? tableName.split(".") : ["public", tableName];
2179
+ const constraintTable = constraint.table || "";
2180
+ const [constraintSchema, constraintTableName] = constraintTable.includes(".") ? constraintTable.split(".") : ["public", constraintTable];
2181
+ return table === constraintTableName && schema === constraintSchema;
2182
+ });
2183
+ if (!isNewTable) {
2184
+ statements.push(generateCreateUniqueConstraintSQL(constraint));
2185
+ }
2186
+ }
2187
+ for (const constraint of diff.uniqueConstraints.deleted) {
2188
+ statements.push(generateDropUniqueConstraintSQL(constraint));
2189
+ }
2190
+ for (const constraint of diff.checkConstraints.created) {
2191
+ const isNewTable = diff.tables.created.some((tableName) => {
2192
+ const [schema, table] = tableName.includes(".") ? tableName.split(".") : ["public", tableName];
2193
+ const constraintTable = constraint.table || "";
2194
+ const [constraintSchema, constraintTableName] = constraintTable.includes(".") ? constraintTable.split(".") : ["public", constraintTable];
2195
+ return table === constraintTableName && schema === constraintSchema;
2196
+ });
2197
+ if (!isNewTable) {
2198
+ statements.push(generateCreateCheckConstraintSQL(constraint));
2256
2199
  }
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);
2200
+ }
2201
+ for (const constraint of diff.checkConstraints.deleted) {
2202
+ statements.push(generateDropCheckConstraintSQL(constraint));
2203
+ }
2204
+ for (const fk of diff.foreignKeys.deleted) {
2205
+ statements.push(generateDropForeignKeySQL(fk));
2206
+ }
2207
+ for (const alteredFK of diff.foreignKeys.altered) {
2208
+ statements.push(generateDropForeignKeySQL(alteredFK.old));
2209
+ }
2210
+ for (const fk of diff.foreignKeys.created) {
2211
+ const tableFrom = fk.tableFrom || "";
2212
+ const schemaFrom = fk.schemaFrom || "public";
2213
+ const isNewTable = diff.tables.created.some((tableName) => {
2214
+ const [createdSchema, createdTable] = tableName.includes(".") ? tableName.split(".") : ["public", tableName];
2215
+ return createdTable === tableFrom && createdSchema === schemaFrom;
2216
+ });
2217
+ if (!isNewTable) {
2218
+ statements.push(generateCreateForeignKeySQL(fk));
2268
2219
  }
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
2220
  }
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);
2221
+ for (const alteredFK of diff.foreignKeys.altered) {
2222
+ statements.push(generateCreateForeignKeySQL(alteredFK.new));
2292
2223
  }
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);
2224
+ return statements;
2225
+ }
2226
+ function generateCreateTableSQL(fullTableName, table) {
2227
+ const [schema, tableName] = fullTableName.includes(".") ? fullTableName.split(".") : ["public", fullTableName];
2228
+ const columns = [];
2229
+ const fkSQLs = [];
2230
+ for (const [colName, colDef] of Object.entries(table.columns || {})) {
2231
+ columns.push(generateColumnDefinition(colName, colDef));
2335
2232
  }
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);
2233
+ const primaryKeys = table.compositePrimaryKeys || {};
2234
+ for (const [pkName, pkDef] of Object.entries(primaryKeys)) {
2235
+ const pk = pkDef;
2236
+ if (pk.columns && pk.columns.length > 0) {
2237
+ columns.push(`CONSTRAINT "${pkName}" PRIMARY KEY (${pk.columns.map((c) => `"${c}"`).join(", ")})`);
2238
+ }
2359
2239
  }
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);
2240
+ const uniqueConstraints = table.uniqueConstraints || {};
2241
+ for (const [uqName, uqDef] of Object.entries(uniqueConstraints)) {
2242
+ const uq = uqDef;
2243
+ if (uq.columns && uq.columns.length > 0) {
2244
+ const uniqueDef = uq.nullsNotDistinct ? `CONSTRAINT "${uqName}" UNIQUE NULLS NOT DISTINCT (${uq.columns.map((c) => `"${c}"`).join(", ")})` : `CONSTRAINT "${uqName}" UNIQUE (${uq.columns.map((c) => `"${c}"`).join(", ")})`;
2245
+ columns.push(uniqueDef);
2246
+ }
2247
+ }
2248
+ const checkConstraints = table.checkConstraints || {};
2249
+ for (const [checkName, checkDef] of Object.entries(checkConstraints)) {
2250
+ const check3 = checkDef;
2251
+ if (check3.value) {
2252
+ columns.push(`CONSTRAINT "${checkName}" CHECK (${check3.value})`);
2253
+ }
2254
+ }
2255
+ const tableSQL = `CREATE TABLE IF NOT EXISTS "${schema}"."${tableName}" (
2256
+ ${columns.join(`,
2257
+ `)}
2258
+ );`;
2259
+ const foreignKeys = table.foreignKeys || {};
2260
+ for (const [fkName, fkDef] of Object.entries(foreignKeys)) {
2261
+ const fk = fkDef;
2262
+ const fkSQL = wrapConstraintCreationGuard(fkName, buildCreateForeignKeyBodySQL({
2263
+ ...fk,
2264
+ name: fkName,
2265
+ schemaFrom: schema,
2266
+ tableFrom: tableName
2267
+ }));
2268
+ fkSQLs.push(fkSQL);
2269
+ }
2270
+ return { tableSQL, fkSQLs };
2271
+ }
2272
+ function generateColumnDefinition(name, def) {
2273
+ let sql22 = `"${name}" ${def.type}`;
2274
+ if (def.primaryKey && !def.type.includes("SERIAL")) {
2275
+ sql22 += " PRIMARY KEY";
2276
+ }
2277
+ if (def.notNull) {
2278
+ sql22 += " NOT NULL";
2279
+ }
2280
+ if (def.default !== undefined) {
2281
+ const defaultValue = formatDefaultValue(def.default, def.type);
2282
+ sql22 += ` DEFAULT ${defaultValue}`;
2283
+ }
2284
+ return sql22;
2285
+ }
2286
+ function generateAddColumnSQL(table, column, definition) {
2287
+ const [schema, tableName] = table.includes(".") ? table.split(".") : ["public", table];
2288
+ const tableNameWithSchema = `"${schema}"."${tableName}"`;
2289
+ const parts = [`"${column}"`];
2290
+ parts.push(definition.type);
2291
+ if (definition.primaryKey) {
2292
+ parts.push("PRIMARY KEY");
2293
+ }
2294
+ if (definition.default !== undefined) {
2295
+ const defaultValue = formatDefaultValue(definition.default, definition.type);
2296
+ if (defaultValue) {
2297
+ parts.push(`DEFAULT ${defaultValue}`);
2298
+ }
2299
+ }
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(" ")};`;
2308
+ }
2309
+ function generateDropColumnSQL(table, column) {
2310
+ const [schema, tableName] = table.includes(".") ? table.split(".") : ["public", table];
2311
+ const tableNameWithSchema = `"${schema}"."${tableName}"`;
2312
+ return `ALTER TABLE ${tableNameWithSchema} DROP COLUMN "${column}" CASCADE;`;
2313
+ }
2314
+ function generateAlterColumnSQL(table, column, changes) {
2315
+ const [schema, tableName] = table.includes(".") ? table.split(".") : ["public", table];
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};`);
2329
+ }
2394
2330
  }
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);
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
+ }
2412
2339
  }
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);
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
+ }
2430
2349
  }
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);
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;
2442
2357
  }
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);
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;
2455
2362
  }
2456
- parseDefault(defaultValue, dataType) {
2457
- if (!defaultValue)
2458
- return;
2459
- const match = defaultValue.match(/^'(.*)'::/);
2460
- if (match) {
2461
- return `'${match[1]}'`;
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;
2462
2384
  }
2463
- if (defaultValue.includes("nextval(")) {
2464
- return;
2385
+ }
2386
+ return false;
2387
+ }
2388
+ function formatDefaultValue(value, type) {
2389
+ if (value === null || value === "NULL") {
2390
+ return "NULL";
2391
+ }
2392
+ if (type && (type.toLowerCase().includes("boolean") || type.toLowerCase() === "bool")) {
2393
+ if (value === true || value === "true" || value === "t" || value === 1) {
2394
+ return "true";
2465
2395
  }
2466
- if (dataType === "boolean") {
2467
- if (defaultValue === "true")
2468
- return "true";
2469
- if (defaultValue === "false")
2470
- return "false";
2396
+ if (value === false || value === "false" || value === "f" || value === 0) {
2397
+ return "false";
2471
2398
  }
2472
- return defaultValue;
2473
2399
  }
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;
2400
+ if (type?.match(/^(integer|bigint|smallint|numeric|decimal|real|double)/i)) {
2401
+ return String(value);
2483
2402
  }
2484
- deriveSchemaName(pluginName) {
2485
- return pluginName.replace("@", "").replace("/", "_").replace(/-/g, "_").toLowerCase();
2403
+ if (typeof value === "string") {
2404
+ if (value.includes("::")) {
2405
+ return value;
2406
+ }
2407
+ if (value.startsWith("'") && value.endsWith("'")) {
2408
+ return value;
2409
+ }
2410
+ if (value.match(/^\w+\(\)/i) || value.includes("(") && value.includes(")")) {
2411
+ return value;
2412
+ }
2413
+ if (value.toUpperCase().startsWith("CURRENT_")) {
2414
+ return value;
2415
+ }
2416
+ return `'${value.replace(/'/g, "''")}'`;
2486
2417
  }
2418
+ return String(value);
2487
2419
  }
2488
- var init_database_introspector = () => {};
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 || ""}"`;
2437
+ }
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`;
2460
+ }
2461
+ sql22 += ` (${columns});`;
2462
+ return sql22;
2463
+ }
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}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value);
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 = {
@@ -5169,11 +5177,14 @@ class BaseDrizzleAdapter extends DatabaseAdapter {
5169
5177
  async addParticipant(entityId, roomId) {
5170
5178
  return this.withDatabase(async () => {
5171
5179
  try {
5172
- await this.db.insert(participantTable).values({
5173
- entityId,
5174
- roomId,
5175
- agentId: this.agentId
5176
- }).onConflictDoNothing();
5180
+ const existing = await this.db.select({ id: participantTable.id }).from(participantTable).where(and(eq2(participantTable.entityId, entityId), eq2(participantTable.roomId, roomId), eq2(participantTable.agentId, this.agentId))).limit(1);
5181
+ if (existing.length === 0) {
5182
+ await this.db.insert(participantTable).values({
5183
+ entityId,
5184
+ roomId,
5185
+ agentId: this.agentId
5186
+ });
5187
+ }
5177
5188
  return true;
5178
5189
  } catch (error) {
5179
5190
  logger9.error({
@@ -5190,12 +5201,16 @@ class BaseDrizzleAdapter extends DatabaseAdapter {
5190
5201
  async addParticipantsRoom(entityIds, roomId) {
5191
5202
  return this.withDatabase(async () => {
5192
5203
  try {
5193
- const values = entityIds.map((id) => ({
5194
- entityId: id,
5195
- roomId,
5196
- agentId: this.agentId
5197
- }));
5198
- await this.db.insert(participantTable).values(values).onConflictDoNothing().execute();
5204
+ for (const id of entityIds) {
5205
+ const existing = await this.db.select({ id: participantTable.id }).from(participantTable).where(and(eq2(participantTable.entityId, id), eq2(participantTable.roomId, roomId), eq2(participantTable.agentId, this.agentId))).limit(1);
5206
+ if (existing.length === 0) {
5207
+ await this.db.insert(participantTable).values({
5208
+ entityId: id,
5209
+ roomId,
5210
+ agentId: this.agentId
5211
+ });
5212
+ }
5213
+ }
5199
5214
  return true;
5200
5215
  } catch (error) {
5201
5216
  logger9.error({
@@ -5345,19 +5360,27 @@ class BaseDrizzleAdapter extends DatabaseAdapter {
5345
5360
  }
5346
5361
  async getRelationships(params) {
5347
5362
  return this.withDatabase(async () => {
5348
- const { entityId, tags } = params;
5349
- let query;
5363
+ const { entityIds: rawEntityIds, entityId, tags, limit, offset } = params;
5364
+ const entityIds = (rawEntityIds && rawEntityIds.length > 0 ? rawEntityIds : entityId ? [entityId] : []).filter((id) => typeof id === "string" && id.trim().length > 0);
5365
+ if (entityIds.length === 0) {
5366
+ return [];
5367
+ }
5368
+ const entityFilter = sql27.join(entityIds.map((id) => sql27`(${relationshipTable.sourceEntityId} = ${id} OR ${relationshipTable.targetEntityId} = ${id})`), sql27` OR `);
5369
+ let query = sql27`
5370
+ SELECT * FROM ${relationshipTable}
5371
+ WHERE (${entityFilter})
5372
+ `;
5350
5373
  if (tags && tags.length > 0) {
5351
5374
  query = sql27`
5352
- SELECT * FROM ${relationshipTable}
5353
- WHERE (${relationshipTable.sourceEntityId} = ${entityId} OR ${relationshipTable.targetEntityId} = ${entityId})
5375
+ ${query}
5354
5376
  AND ${relationshipTable.tags} && CAST(ARRAY[${sql27.join(tags, sql27`, `)}] AS text[])
5355
5377
  `;
5356
- } else {
5357
- query = sql27`
5358
- SELECT * FROM ${relationshipTable}
5359
- WHERE ${relationshipTable.sourceEntityId} = ${entityId} OR ${relationshipTable.targetEntityId} = ${entityId}
5360
- `;
5378
+ }
5379
+ if (typeof limit === "number") {
5380
+ query = sql27`${query} LIMIT ${limit}`;
5381
+ }
5382
+ if (typeof offset === "number" && offset > 0) {
5383
+ query = sql27`${query} OFFSET ${offset}`;
5361
5384
  }
5362
5385
  const result = await this.db.execute(query);
5363
5386
  return result.rows.map((relationship) => ({
@@ -7095,5 +7118,5 @@ export {
7095
7118
  DatabaseMigrationService
7096
7119
  };
7097
7120
 
7098
- //# debugId=65F51AC9F4802DC764756E2164756E21
7121
+ //# debugId=606A9AD08C7E6C2364756E2164756E21
7099
7122
  //# sourceMappingURL=index.node.js.map