@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.
- package/dist/browser/index.browser.js +1264 -1244
- package/dist/browser/index.browser.js.map +7 -7
- package/dist/cjs/index.node.cjs +753 -730
- package/dist/cjs/index.node.cjs.map +7 -7
- package/dist/node/index.node.js +1260 -1237
- package/dist/node/index.node.js.map +7 -7
- package/package.json +3 -2
|
@@ -885,174 +885,534 @@ async function applyEntityRLSToAllTables(adapter) {
|
|
|
885
885
|
logger2.warn("[Entity RLS] Failed to apply entity RLS to some tables:", String(error));
|
|
886
886
|
}
|
|
887
887
|
}
|
|
888
|
-
var init_rls =
|
|
889
|
-
init_agent();
|
|
890
|
-
init_server();
|
|
891
|
-
});
|
|
888
|
+
var init_rls = () => {};
|
|
892
889
|
|
|
893
|
-
// runtime-migrator/
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
}
|
|
906
|
-
if (normalized === "serial") {
|
|
907
|
-
return "integer";
|
|
908
|
-
}
|
|
909
|
-
if (normalized === "bigserial") {
|
|
910
|
-
return "bigint";
|
|
911
|
-
}
|
|
912
|
-
if (normalized === "smallserial") {
|
|
913
|
-
return "smallint";
|
|
914
|
-
}
|
|
915
|
-
if (normalized.startsWith("numeric") || normalized.startsWith("decimal")) {
|
|
916
|
-
const match = normalized.match(/\((\d+)(?:,\s*(\d+))?\)/);
|
|
917
|
-
if (match) {
|
|
918
|
-
return `numeric(${match[1]}${match[2] ? `,${match[2]}` : ""})`;
|
|
919
|
-
}
|
|
920
|
-
return "numeric";
|
|
921
|
-
}
|
|
922
|
-
if (normalized.startsWith("character varying")) {
|
|
923
|
-
return normalized.replace("character varying", "varchar");
|
|
924
|
-
}
|
|
925
|
-
if (normalized === "text[]" || normalized === "_text") {
|
|
926
|
-
return "text[]";
|
|
890
|
+
// runtime-migrator/crypto-utils.ts
|
|
891
|
+
function extendedHash(str) {
|
|
892
|
+
const h1 = hashWithSeed(str, 5381);
|
|
893
|
+
const h2 = hashWithSeed(str, 7919);
|
|
894
|
+
const h3 = hashWithSeed(str, 104729);
|
|
895
|
+
const h4 = hashWithSeed(str, 224737);
|
|
896
|
+
return h1 + h2 + h3 + h4;
|
|
897
|
+
}
|
|
898
|
+
function hashWithSeed(str, seed) {
|
|
899
|
+
let hash = seed;
|
|
900
|
+
for (let i = 0;i < str.length; i++) {
|
|
901
|
+
hash = hash * 33 ^ str.charCodeAt(i);
|
|
927
902
|
}
|
|
928
|
-
return
|
|
903
|
+
return (hash >>> 0).toString(16).padStart(8, "0");
|
|
929
904
|
}
|
|
930
|
-
function
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
if (
|
|
936
|
-
|
|
937
|
-
if (prevIndex.concurrently !== currIndex.concurrently)
|
|
938
|
-
return true;
|
|
939
|
-
const prevColumns = prevIndex.columns || [];
|
|
940
|
-
const currColumns = currIndex.columns || [];
|
|
941
|
-
if (prevColumns.length !== currColumns.length)
|
|
942
|
-
return true;
|
|
943
|
-
for (let i = 0;i < prevColumns.length; i++) {
|
|
944
|
-
const prevCol = prevColumns[i];
|
|
945
|
-
const currCol = currColumns[i];
|
|
946
|
-
if (typeof prevCol === "string" && typeof currCol === "string") {
|
|
947
|
-
if (prevCol !== currCol)
|
|
948
|
-
return true;
|
|
949
|
-
} else if (typeof prevCol === "object" && typeof currCol === "object") {
|
|
950
|
-
if (prevCol.expression !== currCol.expression)
|
|
951
|
-
return true;
|
|
952
|
-
if (prevCol.isExpression !== currCol.isExpression)
|
|
953
|
-
return true;
|
|
954
|
-
if (prevCol.asc !== currCol.asc)
|
|
955
|
-
return true;
|
|
956
|
-
if (prevCol.nulls !== currCol.nulls)
|
|
957
|
-
return true;
|
|
958
|
-
} else {
|
|
959
|
-
return true;
|
|
960
|
-
}
|
|
905
|
+
function stringToBigInt(str) {
|
|
906
|
+
const hash = extendedHash(str);
|
|
907
|
+
let lockId = BigInt(`0x${hash.slice(0, 16)}`);
|
|
908
|
+
const mask63Bits = 0x7fffffffffffffffn;
|
|
909
|
+
lockId = lockId & mask63Bits;
|
|
910
|
+
if (lockId === 0n) {
|
|
911
|
+
lockId = 1n;
|
|
961
912
|
}
|
|
962
|
-
return
|
|
913
|
+
return lockId;
|
|
963
914
|
}
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
}
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
const table = currentSnapshot.tables[tableName];
|
|
999
|
-
if (table.indexes) {
|
|
1000
|
-
for (const indexName in table.indexes) {
|
|
1001
|
-
diff.indexes.created.push({
|
|
1002
|
-
...table.indexes[indexName],
|
|
1003
|
-
table: tableName
|
|
1004
|
-
});
|
|
1005
|
-
}
|
|
915
|
+
|
|
916
|
+
// runtime-migrator/drizzle-adapters/database-introspector.ts
|
|
917
|
+
import { logger as logger3 } from "@elizaos/core";
|
|
918
|
+
import { sql as sql21 } from "drizzle-orm";
|
|
919
|
+
function getRows2(result) {
|
|
920
|
+
return result.rows;
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
class DatabaseIntrospector {
|
|
924
|
+
db;
|
|
925
|
+
constructor(db) {
|
|
926
|
+
this.db = db;
|
|
927
|
+
}
|
|
928
|
+
async introspectSchema(schemaName = "public") {
|
|
929
|
+
logger3.info({ src: "plugin:sql", schemaName }, "Starting database introspection");
|
|
930
|
+
const tables = {};
|
|
931
|
+
const schemas = {};
|
|
932
|
+
const enums = {};
|
|
933
|
+
const allTables = await this.getTables(schemaName);
|
|
934
|
+
for (const tableInfo of allTables) {
|
|
935
|
+
const tableName = tableInfo.table_name;
|
|
936
|
+
const tableSchema = tableInfo.table_schema || "public";
|
|
937
|
+
logger3.debug({ src: "plugin:sql", tableSchema, tableName }, "Introspecting table");
|
|
938
|
+
const columns = await this.getColumns(tableSchema, tableName);
|
|
939
|
+
const columnsObject = {};
|
|
940
|
+
const uniqueConstraintObject = {};
|
|
941
|
+
for (const col of columns) {
|
|
942
|
+
columnsObject[col.column_name] = {
|
|
943
|
+
name: col.column_name,
|
|
944
|
+
type: col.data_type,
|
|
945
|
+
primaryKey: col.is_primary || false,
|
|
946
|
+
notNull: col.is_nullable === "NO",
|
|
947
|
+
default: col.column_default ? this.parseDefault(col.column_default, col.data_type) : undefined
|
|
948
|
+
};
|
|
1006
949
|
}
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
950
|
+
const indexes = await this.getIndexes(tableSchema, tableName);
|
|
951
|
+
const indexesObject = {};
|
|
952
|
+
for (const idx of indexes) {
|
|
953
|
+
if (!idx.is_primary && !idx.is_unique_constraint) {
|
|
954
|
+
if (idx.columns && Array.isArray(idx.columns) && idx.columns.length > 0) {
|
|
955
|
+
indexesObject[idx.name] = {
|
|
956
|
+
name: idx.name,
|
|
957
|
+
columns: idx.columns.map((col) => ({
|
|
958
|
+
expression: col,
|
|
959
|
+
isExpression: false
|
|
960
|
+
})),
|
|
961
|
+
isUnique: idx.is_unique,
|
|
962
|
+
method: idx.method || "btree"
|
|
963
|
+
};
|
|
964
|
+
}
|
|
1010
965
|
}
|
|
1011
966
|
}
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
});
|
|
1027
|
-
}
|
|
967
|
+
const foreignKeys = await this.getForeignKeys(tableSchema, tableName);
|
|
968
|
+
const foreignKeysObject = {};
|
|
969
|
+
for (const fk of foreignKeys) {
|
|
970
|
+
foreignKeysObject[fk.name] = {
|
|
971
|
+
name: fk.name,
|
|
972
|
+
tableFrom: tableName,
|
|
973
|
+
schemaFrom: tableSchema,
|
|
974
|
+
tableTo: fk.foreign_table_name,
|
|
975
|
+
schemaTo: fk.foreign_table_schema || "public",
|
|
976
|
+
columnsFrom: [fk.column_name],
|
|
977
|
+
columnsTo: [fk.foreign_column_name],
|
|
978
|
+
onDelete: fk.delete_rule?.toLowerCase() || "no action",
|
|
979
|
+
onUpdate: fk.update_rule?.toLowerCase() || "no action"
|
|
980
|
+
};
|
|
1028
981
|
}
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
}
|
|
982
|
+
const primaryKeys = await this.getPrimaryKeys(tableSchema, tableName);
|
|
983
|
+
const primaryKeysObject = {};
|
|
984
|
+
for (const pk of primaryKeys) {
|
|
985
|
+
primaryKeysObject[pk.name] = {
|
|
986
|
+
name: pk.name,
|
|
987
|
+
columns: pk.columns
|
|
988
|
+
};
|
|
1036
989
|
}
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
}
|
|
990
|
+
const uniqueConstraints = await this.getUniqueConstraints(tableSchema, tableName);
|
|
991
|
+
for (const unq of uniqueConstraints) {
|
|
992
|
+
uniqueConstraintObject[unq.name] = {
|
|
993
|
+
name: unq.name,
|
|
994
|
+
columns: unq.columns,
|
|
995
|
+
nullsNotDistinct: false
|
|
996
|
+
};
|
|
1044
997
|
}
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
998
|
+
const checkConstraints = await this.getCheckConstraints(tableSchema, tableName);
|
|
999
|
+
const checksObject = {};
|
|
1000
|
+
for (const check3 of checkConstraints) {
|
|
1001
|
+
checksObject[check3.name] = {
|
|
1002
|
+
name: check3.name,
|
|
1003
|
+
value: check3.definition
|
|
1004
|
+
};
|
|
1049
1005
|
}
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1006
|
+
tables[`${tableSchema}.${tableName}`] = {
|
|
1007
|
+
name: tableName,
|
|
1008
|
+
schema: tableSchema,
|
|
1009
|
+
columns: columnsObject,
|
|
1010
|
+
indexes: indexesObject,
|
|
1011
|
+
foreignKeys: foreignKeysObject,
|
|
1012
|
+
compositePrimaryKeys: primaryKeysObject,
|
|
1013
|
+
uniqueConstraints: uniqueConstraintObject,
|
|
1014
|
+
checkConstraints: checksObject
|
|
1015
|
+
};
|
|
1016
|
+
if (tableSchema && tableSchema !== "public") {
|
|
1017
|
+
schemas[tableSchema] = tableSchema;
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
const enumsResult = await this.getEnums(schemaName);
|
|
1021
|
+
for (const enumInfo of enumsResult) {
|
|
1022
|
+
const key = `${enumInfo.schema}.${enumInfo.name}`;
|
|
1023
|
+
if (!enums[key]) {
|
|
1024
|
+
enums[key] = {
|
|
1025
|
+
name: enumInfo.name,
|
|
1026
|
+
schema: enumInfo.schema,
|
|
1027
|
+
values: []
|
|
1028
|
+
};
|
|
1029
|
+
}
|
|
1030
|
+
enums[key].values.push(enumInfo.value);
|
|
1031
|
+
}
|
|
1032
|
+
logger3.info({ src: "plugin:sql", tableCount: Object.keys(tables).length }, "Database introspection complete");
|
|
1033
|
+
return {
|
|
1034
|
+
version: "7",
|
|
1035
|
+
dialect: "postgresql",
|
|
1036
|
+
tables,
|
|
1037
|
+
schemas,
|
|
1038
|
+
enums,
|
|
1039
|
+
_meta: {
|
|
1040
|
+
schemas: {},
|
|
1041
|
+
tables: {},
|
|
1042
|
+
columns: {}
|
|
1043
|
+
}
|
|
1044
|
+
};
|
|
1045
|
+
}
|
|
1046
|
+
async getTables(schemaName) {
|
|
1047
|
+
const result = await this.db.execute(sql21`SELECT
|
|
1048
|
+
table_schema,
|
|
1049
|
+
table_name
|
|
1050
|
+
FROM information_schema.tables
|
|
1051
|
+
WHERE table_schema = ${schemaName}
|
|
1052
|
+
AND table_type = 'BASE TABLE'
|
|
1053
|
+
ORDER BY table_name`);
|
|
1054
|
+
return getRows2(result);
|
|
1055
|
+
}
|
|
1056
|
+
async getColumns(schemaName, tableName) {
|
|
1057
|
+
const result = await this.db.execute(sql21`SELECT
|
|
1058
|
+
a.attname AS column_name,
|
|
1059
|
+
CASE
|
|
1060
|
+
WHEN a.attnotnull THEN 'NO'
|
|
1061
|
+
ELSE 'YES'
|
|
1062
|
+
END AS is_nullable,
|
|
1063
|
+
CASE
|
|
1064
|
+
WHEN a.atttypid = ANY ('{int,int8,int2}'::regtype[])
|
|
1065
|
+
AND EXISTS (
|
|
1066
|
+
SELECT FROM pg_attrdef ad
|
|
1067
|
+
WHERE ad.adrelid = a.attrelid
|
|
1068
|
+
AND ad.adnum = a.attnum
|
|
1069
|
+
AND pg_get_expr(ad.adbin, ad.adrelid) = 'nextval('''
|
|
1070
|
+
|| pg_get_serial_sequence(a.attrelid::regclass::text, a.attname)::regclass || '''::regclass)'
|
|
1071
|
+
)
|
|
1072
|
+
THEN CASE a.atttypid
|
|
1073
|
+
WHEN 'int'::regtype THEN 'serial'
|
|
1074
|
+
WHEN 'int8'::regtype THEN 'bigserial'
|
|
1075
|
+
WHEN 'int2'::regtype THEN 'smallserial'
|
|
1076
|
+
END
|
|
1077
|
+
ELSE format_type(a.atttypid, a.atttypmod)
|
|
1078
|
+
END AS data_type,
|
|
1079
|
+
pg_get_expr(ad.adbin, ad.adrelid) AS column_default,
|
|
1080
|
+
CASE
|
|
1081
|
+
WHEN con.contype = 'p' THEN true
|
|
1082
|
+
ELSE false
|
|
1083
|
+
END AS is_primary
|
|
1084
|
+
FROM pg_attribute a
|
|
1085
|
+
JOIN pg_class cls ON cls.oid = a.attrelid
|
|
1086
|
+
JOIN pg_namespace ns ON ns.oid = cls.relnamespace
|
|
1087
|
+
LEFT JOIN pg_attrdef ad ON ad.adrelid = a.attrelid AND ad.adnum = a.attnum
|
|
1088
|
+
LEFT JOIN pg_constraint con ON con.conrelid = a.attrelid
|
|
1089
|
+
AND a.attnum = ANY(con.conkey)
|
|
1090
|
+
AND con.contype = 'p'
|
|
1091
|
+
WHERE
|
|
1092
|
+
a.attnum > 0
|
|
1093
|
+
AND NOT a.attisdropped
|
|
1094
|
+
AND ns.nspname = ${schemaName}
|
|
1095
|
+
AND cls.relname = ${tableName}
|
|
1096
|
+
ORDER BY a.attnum`);
|
|
1097
|
+
return getRows2(result);
|
|
1098
|
+
}
|
|
1099
|
+
async getIndexes(schemaName, tableName) {
|
|
1100
|
+
const result = await this.db.execute(sql21`SELECT
|
|
1101
|
+
i.relname AS name,
|
|
1102
|
+
idx.indisunique AS is_unique,
|
|
1103
|
+
idx.indisprimary AS is_primary,
|
|
1104
|
+
con.contype = 'u' AS is_unique_constraint,
|
|
1105
|
+
ARRAY(
|
|
1106
|
+
SELECT a.attname
|
|
1107
|
+
FROM pg_attribute a
|
|
1108
|
+
WHERE a.attrelid = idx.indrelid
|
|
1109
|
+
AND a.attnum = ANY(idx.indkey::int[])
|
|
1110
|
+
ORDER BY a.attnum
|
|
1111
|
+
) AS columns,
|
|
1112
|
+
am.amname AS method
|
|
1113
|
+
FROM pg_index idx
|
|
1114
|
+
JOIN pg_class i ON i.oid = idx.indexrelid
|
|
1115
|
+
JOIN pg_class c ON c.oid = idx.indrelid
|
|
1116
|
+
JOIN pg_namespace n ON n.oid = c.relnamespace
|
|
1117
|
+
JOIN pg_am am ON am.oid = i.relam
|
|
1118
|
+
LEFT JOIN pg_constraint con ON con.conindid = idx.indexrelid
|
|
1119
|
+
WHERE n.nspname = ${schemaName}
|
|
1120
|
+
AND c.relname = ${tableName}`);
|
|
1121
|
+
return getRows2(result);
|
|
1122
|
+
}
|
|
1123
|
+
async getForeignKeys(schemaName, tableName) {
|
|
1124
|
+
const result = await this.db.execute(sql21`SELECT
|
|
1125
|
+
con.conname AS name,
|
|
1126
|
+
att.attname AS column_name,
|
|
1127
|
+
fnsp.nspname AS foreign_table_schema,
|
|
1128
|
+
frel.relname AS foreign_table_name,
|
|
1129
|
+
fatt.attname AS foreign_column_name,
|
|
1130
|
+
CASE con.confupdtype
|
|
1131
|
+
WHEN 'a' THEN 'NO ACTION'
|
|
1132
|
+
WHEN 'r' THEN 'RESTRICT'
|
|
1133
|
+
WHEN 'n' THEN 'SET NULL'
|
|
1134
|
+
WHEN 'c' THEN 'CASCADE'
|
|
1135
|
+
WHEN 'd' THEN 'SET DEFAULT'
|
|
1136
|
+
END AS update_rule,
|
|
1137
|
+
CASE con.confdeltype
|
|
1138
|
+
WHEN 'a' THEN 'NO ACTION'
|
|
1139
|
+
WHEN 'r' THEN 'RESTRICT'
|
|
1140
|
+
WHEN 'n' THEN 'SET NULL'
|
|
1141
|
+
WHEN 'c' THEN 'CASCADE'
|
|
1142
|
+
WHEN 'd' THEN 'SET DEFAULT'
|
|
1143
|
+
END AS delete_rule
|
|
1144
|
+
FROM pg_catalog.pg_constraint con
|
|
1145
|
+
JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
|
|
1146
|
+
JOIN pg_catalog.pg_namespace nsp ON nsp.oid = con.connamespace
|
|
1147
|
+
LEFT JOIN pg_catalog.pg_attribute att ON att.attnum = ANY (con.conkey)
|
|
1148
|
+
AND att.attrelid = con.conrelid
|
|
1149
|
+
LEFT JOIN pg_catalog.pg_class frel ON frel.oid = con.confrelid
|
|
1150
|
+
LEFT JOIN pg_catalog.pg_namespace fnsp ON fnsp.oid = frel.relnamespace
|
|
1151
|
+
LEFT JOIN pg_catalog.pg_attribute fatt ON fatt.attnum = ANY (con.confkey)
|
|
1152
|
+
AND fatt.attrelid = con.confrelid
|
|
1153
|
+
WHERE con.contype = 'f'
|
|
1154
|
+
AND nsp.nspname = ${schemaName}
|
|
1155
|
+
AND rel.relname = ${tableName}`);
|
|
1156
|
+
return getRows2(result);
|
|
1157
|
+
}
|
|
1158
|
+
async getPrimaryKeys(schemaName, tableName) {
|
|
1159
|
+
const result = await this.db.execute(sql21`SELECT
|
|
1160
|
+
con.conname AS name,
|
|
1161
|
+
ARRAY(
|
|
1162
|
+
SELECT a.attname
|
|
1163
|
+
FROM pg_attribute a
|
|
1164
|
+
WHERE a.attrelid = con.conrelid
|
|
1165
|
+
AND a.attnum = ANY(con.conkey)
|
|
1166
|
+
ORDER BY a.attnum
|
|
1167
|
+
) AS columns
|
|
1168
|
+
FROM pg_constraint con
|
|
1169
|
+
JOIN pg_class rel ON rel.oid = con.conrelid
|
|
1170
|
+
JOIN pg_namespace nsp ON nsp.oid = con.connamespace
|
|
1171
|
+
WHERE con.contype = 'p'
|
|
1172
|
+
AND nsp.nspname = ${schemaName}
|
|
1173
|
+
AND rel.relname = ${tableName}`);
|
|
1174
|
+
return getRows2(result);
|
|
1175
|
+
}
|
|
1176
|
+
async getUniqueConstraints(schemaName, tableName) {
|
|
1177
|
+
const result = await this.db.execute(sql21`SELECT
|
|
1178
|
+
con.conname AS name,
|
|
1179
|
+
ARRAY(
|
|
1180
|
+
SELECT a.attname
|
|
1181
|
+
FROM pg_attribute a
|
|
1182
|
+
WHERE a.attrelid = con.conrelid
|
|
1183
|
+
AND a.attnum = ANY(con.conkey)
|
|
1184
|
+
ORDER BY a.attnum
|
|
1185
|
+
) AS columns
|
|
1186
|
+
FROM pg_constraint con
|
|
1187
|
+
JOIN pg_class rel ON rel.oid = con.conrelid
|
|
1188
|
+
JOIN pg_namespace nsp ON nsp.oid = con.connamespace
|
|
1189
|
+
WHERE con.contype = 'u'
|
|
1190
|
+
AND nsp.nspname = ${schemaName}
|
|
1191
|
+
AND rel.relname = ${tableName}`);
|
|
1192
|
+
return getRows2(result);
|
|
1193
|
+
}
|
|
1194
|
+
async getCheckConstraints(schemaName, tableName) {
|
|
1195
|
+
const result = await this.db.execute(sql21`SELECT
|
|
1196
|
+
con.conname AS name,
|
|
1197
|
+
pg_get_constraintdef(con.oid) AS definition
|
|
1198
|
+
FROM pg_constraint con
|
|
1199
|
+
JOIN pg_class rel ON rel.oid = con.conrelid
|
|
1200
|
+
JOIN pg_namespace nsp ON nsp.oid = con.connamespace
|
|
1201
|
+
WHERE con.contype = 'c'
|
|
1202
|
+
AND nsp.nspname = ${schemaName}
|
|
1203
|
+
AND rel.relname = ${tableName}`);
|
|
1204
|
+
return getRows2(result);
|
|
1205
|
+
}
|
|
1206
|
+
async getEnums(schemaName) {
|
|
1207
|
+
const result = await this.db.execute(sql21`SELECT
|
|
1208
|
+
n.nspname AS schema,
|
|
1209
|
+
t.typname AS name,
|
|
1210
|
+
e.enumlabel AS value,
|
|
1211
|
+
e.enumsortorder AS sort_order
|
|
1212
|
+
FROM pg_type t
|
|
1213
|
+
JOIN pg_enum e ON t.oid = e.enumtypid
|
|
1214
|
+
JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace
|
|
1215
|
+
WHERE n.nspname = ${schemaName}
|
|
1216
|
+
ORDER BY schema, name, sort_order`);
|
|
1217
|
+
return getRows2(result);
|
|
1218
|
+
}
|
|
1219
|
+
parseDefault(defaultValue, dataType) {
|
|
1220
|
+
if (!defaultValue)
|
|
1221
|
+
return;
|
|
1222
|
+
const match = defaultValue.match(/^'(.*)'::/);
|
|
1223
|
+
if (match) {
|
|
1224
|
+
return `'${match[1]}'`;
|
|
1225
|
+
}
|
|
1226
|
+
if (defaultValue.includes("nextval(")) {
|
|
1227
|
+
return;
|
|
1228
|
+
}
|
|
1229
|
+
if (dataType === "boolean") {
|
|
1230
|
+
if (defaultValue === "true")
|
|
1231
|
+
return "true";
|
|
1232
|
+
if (defaultValue === "false")
|
|
1233
|
+
return "false";
|
|
1234
|
+
}
|
|
1235
|
+
return defaultValue;
|
|
1236
|
+
}
|
|
1237
|
+
async hasExistingTables(pluginName) {
|
|
1238
|
+
const schemaName = pluginName === "@elizaos/plugin-sql" ? "public" : this.deriveSchemaName(pluginName);
|
|
1239
|
+
const result = await this.db.execute(sql21`SELECT COUNT(*) AS count
|
|
1240
|
+
FROM information_schema.tables
|
|
1241
|
+
WHERE table_schema = ${schemaName}
|
|
1242
|
+
AND table_type = 'BASE TABLE'`);
|
|
1243
|
+
const firstRow = result.rows?.[0];
|
|
1244
|
+
const count = parseInt(firstRow && firstRow.count || "0", 10);
|
|
1245
|
+
return count > 0;
|
|
1246
|
+
}
|
|
1247
|
+
deriveSchemaName(pluginName) {
|
|
1248
|
+
return pluginName.replace("@", "").replace("/", "_").replace(/-/g, "_").toLowerCase();
|
|
1249
|
+
}
|
|
1250
|
+
}
|
|
1251
|
+
var init_database_introspector = () => {};
|
|
1252
|
+
|
|
1253
|
+
// runtime-migrator/drizzle-adapters/diff-calculator.ts
|
|
1254
|
+
var exports_diff_calculator = {};
|
|
1255
|
+
__export(exports_diff_calculator, {
|
|
1256
|
+
hasDiffChanges: () => hasDiffChanges,
|
|
1257
|
+
calculateDiff: () => calculateDiff
|
|
1258
|
+
});
|
|
1259
|
+
function normalizeType(type) {
|
|
1260
|
+
if (!type)
|
|
1261
|
+
return "";
|
|
1262
|
+
const normalized = type.toLowerCase().trim();
|
|
1263
|
+
if (normalized === "timestamp without time zone" || normalized === "timestamp with time zone") {
|
|
1264
|
+
return "timestamp";
|
|
1265
|
+
}
|
|
1266
|
+
if (normalized === "serial") {
|
|
1267
|
+
return "integer";
|
|
1268
|
+
}
|
|
1269
|
+
if (normalized === "bigserial") {
|
|
1270
|
+
return "bigint";
|
|
1271
|
+
}
|
|
1272
|
+
if (normalized === "smallserial") {
|
|
1273
|
+
return "smallint";
|
|
1274
|
+
}
|
|
1275
|
+
if (normalized.startsWith("numeric") || normalized.startsWith("decimal")) {
|
|
1276
|
+
const match = normalized.match(/\((\d+)(?:,\s*(\d+))?\)/);
|
|
1277
|
+
if (match) {
|
|
1278
|
+
return `numeric(${match[1]}${match[2] ? `,${match[2]}` : ""})`;
|
|
1279
|
+
}
|
|
1280
|
+
return "numeric";
|
|
1281
|
+
}
|
|
1282
|
+
if (normalized.startsWith("character varying")) {
|
|
1283
|
+
return normalized.replace("character varying", "varchar");
|
|
1284
|
+
}
|
|
1285
|
+
if (normalized === "text[]" || normalized === "_text") {
|
|
1286
|
+
return "text[]";
|
|
1287
|
+
}
|
|
1288
|
+
return normalized;
|
|
1289
|
+
}
|
|
1290
|
+
function isIndexChanged(prevIndex, currIndex) {
|
|
1291
|
+
if (prevIndex.isUnique !== currIndex.isUnique)
|
|
1292
|
+
return true;
|
|
1293
|
+
if (prevIndex.method !== currIndex.method)
|
|
1294
|
+
return true;
|
|
1295
|
+
if (prevIndex.where !== currIndex.where)
|
|
1296
|
+
return true;
|
|
1297
|
+
if (prevIndex.concurrently !== currIndex.concurrently)
|
|
1298
|
+
return true;
|
|
1299
|
+
const prevColumns = prevIndex.columns || [];
|
|
1300
|
+
const currColumns = currIndex.columns || [];
|
|
1301
|
+
if (prevColumns.length !== currColumns.length)
|
|
1302
|
+
return true;
|
|
1303
|
+
for (let i = 0;i < prevColumns.length; i++) {
|
|
1304
|
+
const prevCol = prevColumns[i];
|
|
1305
|
+
const currCol = currColumns[i];
|
|
1306
|
+
if (typeof prevCol === "string" && typeof currCol === "string") {
|
|
1307
|
+
if (prevCol !== currCol)
|
|
1308
|
+
return true;
|
|
1309
|
+
} else if (typeof prevCol === "object" && typeof currCol === "object") {
|
|
1310
|
+
if (prevCol.expression !== currCol.expression)
|
|
1311
|
+
return true;
|
|
1312
|
+
if (prevCol.isExpression !== currCol.isExpression)
|
|
1313
|
+
return true;
|
|
1314
|
+
if (prevCol.asc !== currCol.asc)
|
|
1315
|
+
return true;
|
|
1316
|
+
if (prevCol.nulls !== currCol.nulls)
|
|
1317
|
+
return true;
|
|
1318
|
+
} else {
|
|
1319
|
+
return true;
|
|
1320
|
+
}
|
|
1321
|
+
}
|
|
1322
|
+
return false;
|
|
1323
|
+
}
|
|
1324
|
+
async function calculateDiff(previousSnapshot, currentSnapshot) {
|
|
1325
|
+
const diff = {
|
|
1326
|
+
tables: {
|
|
1327
|
+
created: [],
|
|
1328
|
+
deleted: [],
|
|
1329
|
+
modified: []
|
|
1330
|
+
},
|
|
1331
|
+
columns: {
|
|
1332
|
+
added: [],
|
|
1333
|
+
deleted: [],
|
|
1334
|
+
modified: []
|
|
1335
|
+
},
|
|
1336
|
+
indexes: {
|
|
1337
|
+
created: [],
|
|
1338
|
+
deleted: [],
|
|
1339
|
+
altered: []
|
|
1340
|
+
},
|
|
1341
|
+
foreignKeys: {
|
|
1342
|
+
created: [],
|
|
1343
|
+
deleted: [],
|
|
1344
|
+
altered: []
|
|
1345
|
+
},
|
|
1346
|
+
uniqueConstraints: {
|
|
1347
|
+
created: [],
|
|
1348
|
+
deleted: []
|
|
1349
|
+
},
|
|
1350
|
+
checkConstraints: {
|
|
1351
|
+
created: [],
|
|
1352
|
+
deleted: []
|
|
1353
|
+
}
|
|
1354
|
+
};
|
|
1355
|
+
if (!previousSnapshot) {
|
|
1356
|
+
diff.tables.created = Object.keys(currentSnapshot.tables);
|
|
1357
|
+
for (const tableName in currentSnapshot.tables) {
|
|
1358
|
+
const table = currentSnapshot.tables[tableName];
|
|
1359
|
+
if (table.indexes) {
|
|
1360
|
+
for (const indexName in table.indexes) {
|
|
1361
|
+
diff.indexes.created.push({
|
|
1362
|
+
...table.indexes[indexName],
|
|
1363
|
+
table: tableName
|
|
1364
|
+
});
|
|
1365
|
+
}
|
|
1366
|
+
}
|
|
1367
|
+
if (table.foreignKeys) {
|
|
1368
|
+
for (const fkName in table.foreignKeys) {
|
|
1369
|
+
diff.foreignKeys.created.push(table.foreignKeys[fkName]);
|
|
1370
|
+
}
|
|
1371
|
+
}
|
|
1372
|
+
}
|
|
1373
|
+
return diff;
|
|
1374
|
+
}
|
|
1375
|
+
const prevTables = previousSnapshot.tables || {};
|
|
1376
|
+
const currTables = currentSnapshot.tables || {};
|
|
1377
|
+
for (const tableName in currTables) {
|
|
1378
|
+
if (!(tableName in prevTables)) {
|
|
1379
|
+
diff.tables.created.push(tableName);
|
|
1380
|
+
const table = currTables[tableName];
|
|
1381
|
+
if (table.indexes) {
|
|
1382
|
+
for (const indexName in table.indexes) {
|
|
1383
|
+
diff.indexes.created.push({
|
|
1384
|
+
...table.indexes[indexName],
|
|
1385
|
+
table: tableName
|
|
1386
|
+
});
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1389
|
+
if (table.uniqueConstraints) {
|
|
1390
|
+
for (const uqName in table.uniqueConstraints) {
|
|
1391
|
+
diff.uniqueConstraints.created.push({
|
|
1392
|
+
...table.uniqueConstraints[uqName],
|
|
1393
|
+
table: tableName
|
|
1394
|
+
});
|
|
1395
|
+
}
|
|
1396
|
+
}
|
|
1397
|
+
if (table.checkConstraints) {
|
|
1398
|
+
for (const checkName in table.checkConstraints) {
|
|
1399
|
+
diff.checkConstraints.created.push({
|
|
1400
|
+
...table.checkConstraints[checkName],
|
|
1401
|
+
table: tableName
|
|
1402
|
+
});
|
|
1403
|
+
}
|
|
1404
|
+
}
|
|
1405
|
+
if (table.foreignKeys) {
|
|
1406
|
+
for (const fkName in table.foreignKeys) {
|
|
1407
|
+
diff.foreignKeys.created.push(table.foreignKeys[fkName]);
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1410
|
+
}
|
|
1411
|
+
}
|
|
1412
|
+
for (const tableName in prevTables) {
|
|
1413
|
+
if (!(tableName in currTables)) {
|
|
1414
|
+
diff.tables.deleted.push(tableName);
|
|
1415
|
+
}
|
|
1056
1416
|
}
|
|
1057
1417
|
for (const tableName in currTables) {
|
|
1058
1418
|
if (tableName in prevTables) {
|
|
@@ -1212,1134 +1572,783 @@ async function calculateDiff(previousSnapshot, currentSnapshot) {
|
|
|
1212
1572
|
tableFrom: tableName
|
|
1213
1573
|
});
|
|
1214
1574
|
}
|
|
1215
|
-
}
|
|
1216
|
-
}
|
|
1217
|
-
}
|
|
1218
|
-
return diff;
|
|
1219
|
-
}
|
|
1220
|
-
function hasDiffChanges(diff) {
|
|
1221
|
-
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;
|
|
1222
|
-
}
|
|
1223
|
-
|
|
1224
|
-
// runtime-migrator/crypto-utils.ts
|
|
1225
|
-
function extendedHash(str) {
|
|
1226
|
-
const h1 = hashWithSeed(str, 5381);
|
|
1227
|
-
const h2 = hashWithSeed(str, 7919);
|
|
1228
|
-
const h3 = hashWithSeed(str, 104729);
|
|
1229
|
-
const h4 = hashWithSeed(str, 224737);
|
|
1230
|
-
return h1 + h2 + h3 + h4;
|
|
1231
|
-
}
|
|
1232
|
-
function hashWithSeed(str, seed) {
|
|
1233
|
-
let hash = seed;
|
|
1234
|
-
for (let i = 0;i < str.length; i++) {
|
|
1235
|
-
hash = hash * 33 ^ str.charCodeAt(i);
|
|
1236
|
-
}
|
|
1237
|
-
return (hash >>> 0).toString(16).padStart(8, "0");
|
|
1238
|
-
}
|
|
1239
|
-
function stringToBigInt(str) {
|
|
1240
|
-
const hash = extendedHash(str);
|
|
1241
|
-
let lockId = BigInt(`0x${hash.slice(0, 16)}`);
|
|
1242
|
-
const mask63Bits = 0x7fffffffffffffffn;
|
|
1243
|
-
lockId = lockId & mask63Bits;
|
|
1244
|
-
if (lockId === 0n) {
|
|
1245
|
-
lockId = 1n;
|
|
1246
|
-
}
|
|
1247
|
-
return lockId;
|
|
1248
|
-
}
|
|
1249
|
-
|
|
1250
|
-
// runtime-migrator/drizzle-adapters/snapshot-generator.ts
|
|
1251
|
-
import { is, SQL } from "drizzle-orm";
|
|
1252
|
-
import { getTableConfig, PgDialect, PgTable } from "drizzle-orm/pg-core";
|
|
1253
|
-
function escapeSingleQuotes(str) {
|
|
1254
|
-
return str.replace(/'/g, "''");
|
|
1255
|
-
}
|
|
1256
|
-
function isPgArrayType(sqlType) {
|
|
1257
|
-
return sqlType.match(/.*\[\d*\].*|.*\[\].*/g) !== null;
|
|
1258
|
-
}
|
|
1259
|
-
function buildArrayString(array, sqlType) {
|
|
1260
|
-
sqlType = sqlType.split("[")[0];
|
|
1261
|
-
const values = array.map((value) => {
|
|
1262
|
-
if (typeof value === "number" || typeof value === "bigint") {
|
|
1263
|
-
return value.toString();
|
|
1264
|
-
} else if (typeof value === "boolean") {
|
|
1265
|
-
return value ? "true" : "false";
|
|
1266
|
-
} else if (Array.isArray(value)) {
|
|
1267
|
-
return buildArrayString(value, sqlType);
|
|
1268
|
-
} else if (value instanceof Date) {
|
|
1269
|
-
if (sqlType === "date") {
|
|
1270
|
-
return `"${value.toISOString().split("T")[0]}"`;
|
|
1271
|
-
} else if (sqlType === "timestamp") {
|
|
1272
|
-
return `"${value.toISOString().replace("T", " ").slice(0, 23)}"`;
|
|
1273
|
-
} else {
|
|
1274
|
-
return `"${value.toISOString()}"`;
|
|
1275
|
-
}
|
|
1276
|
-
} else if (typeof value === "object") {
|
|
1277
|
-
return `"${JSON.stringify(value).replaceAll('"', "\\\"")}"`;
|
|
1278
|
-
}
|
|
1279
|
-
return `"${value}"`;
|
|
1280
|
-
}).join(",");
|
|
1281
|
-
return `{${values}}`;
|
|
1282
|
-
}
|
|
1283
|
-
function extractTablesFromSchema(schema) {
|
|
1284
|
-
const tables = [];
|
|
1285
|
-
const exports = Object.values(schema);
|
|
1286
|
-
exports.forEach((t) => {
|
|
1287
|
-
if (is(t, PgTable)) {
|
|
1288
|
-
tables.push(t);
|
|
1289
|
-
}
|
|
1290
|
-
});
|
|
1291
|
-
return tables;
|
|
1292
|
-
}
|
|
1293
|
-
async function generateSnapshot(schema) {
|
|
1294
|
-
const dialect = new PgDialect({ casing: undefined });
|
|
1295
|
-
const tables = {};
|
|
1296
|
-
const schemas = {};
|
|
1297
|
-
const enums = {};
|
|
1298
|
-
const pgTables = extractTablesFromSchema(schema);
|
|
1299
|
-
for (const table of pgTables) {
|
|
1300
|
-
const config = getTableConfig(table);
|
|
1301
|
-
const {
|
|
1302
|
-
name: tableName,
|
|
1303
|
-
columns,
|
|
1304
|
-
indexes,
|
|
1305
|
-
foreignKeys,
|
|
1306
|
-
schema: tableSchema,
|
|
1307
|
-
primaryKeys,
|
|
1308
|
-
uniqueConstraints,
|
|
1309
|
-
checks
|
|
1310
|
-
} = config;
|
|
1311
|
-
const columnsObject = {};
|
|
1312
|
-
const indexesObject = {};
|
|
1313
|
-
const foreignKeysObject = {};
|
|
1314
|
-
const primaryKeysObject = {};
|
|
1315
|
-
const uniqueConstraintObject = {};
|
|
1316
|
-
const checksObject = {};
|
|
1317
|
-
columns.forEach((column) => {
|
|
1318
|
-
const name = column.name;
|
|
1319
|
-
const notNull = column.notNull;
|
|
1320
|
-
const primaryKey4 = column.primary;
|
|
1321
|
-
const sqlType = column.getSQLType();
|
|
1322
|
-
const sqlTypeLowered = sqlType.toLowerCase();
|
|
1323
|
-
const columnToSet = {
|
|
1324
|
-
name,
|
|
1325
|
-
type: sqlType,
|
|
1326
|
-
primaryKey: primaryKey4,
|
|
1327
|
-
notNull
|
|
1328
|
-
};
|
|
1329
|
-
if (column.default !== undefined) {
|
|
1330
|
-
if (is(column.default, SQL)) {
|
|
1331
|
-
columnToSet.default = sqlToStr(column.default, undefined);
|
|
1332
|
-
} else {
|
|
1333
|
-
if (typeof column.default === "string") {
|
|
1334
|
-
columnToSet.default = `'${escapeSingleQuotes(column.default)}'`;
|
|
1335
|
-
} else {
|
|
1336
|
-
if (sqlTypeLowered === "jsonb" || sqlTypeLowered === "json") {
|
|
1337
|
-
columnToSet.default = `'${JSON.stringify(column.default)}'::${sqlTypeLowered}`;
|
|
1338
|
-
} else if (column.default instanceof Date) {
|
|
1339
|
-
if (sqlTypeLowered === "date") {
|
|
1340
|
-
columnToSet.default = `'${column.default.toISOString().split("T")[0]}'`;
|
|
1341
|
-
} else if (sqlTypeLowered === "timestamp") {
|
|
1342
|
-
columnToSet.default = `'${column.default.toISOString().replace("T", " ").slice(0, 23)}'`;
|
|
1343
|
-
} else {
|
|
1344
|
-
columnToSet.default = `'${column.default.toISOString()}'`;
|
|
1345
|
-
}
|
|
1346
|
-
} else if (isPgArrayType(sqlTypeLowered) && Array.isArray(column.default)) {
|
|
1347
|
-
columnToSet.default = `'${buildArrayString(column.default, sqlTypeLowered)}'`;
|
|
1348
|
-
} else {
|
|
1349
|
-
columnToSet.default = column.default;
|
|
1350
|
-
}
|
|
1351
|
-
}
|
|
1352
|
-
}
|
|
1353
|
-
}
|
|
1354
|
-
const columnWithConfig = column;
|
|
1355
|
-
const columnConfig = columnWithConfig.config;
|
|
1356
|
-
if (columnWithConfig.isUnique && columnConfig && columnConfig.uniqueName) {
|
|
1357
|
-
uniqueConstraintObject[columnConfig.uniqueName] = {
|
|
1358
|
-
name: columnConfig.uniqueName,
|
|
1359
|
-
columns: [name],
|
|
1360
|
-
nullsNotDistinct: columnConfig.uniqueType === "not distinct"
|
|
1361
|
-
};
|
|
1362
|
-
}
|
|
1363
|
-
columnsObject[name] = columnToSet;
|
|
1364
|
-
});
|
|
1365
|
-
primaryKeys.forEach((pk) => {
|
|
1366
|
-
const columnNames = pk.columns.map((c) => c.name);
|
|
1367
|
-
const name = pk.getName();
|
|
1368
|
-
primaryKeysObject[name] = {
|
|
1369
|
-
name,
|
|
1370
|
-
columns: columnNames
|
|
1371
|
-
};
|
|
1372
|
-
});
|
|
1373
|
-
uniqueConstraints?.forEach((unq) => {
|
|
1374
|
-
const columnNames = unq.columns.map((c) => c.name);
|
|
1375
|
-
const name = unq.name || `${tableName}_${columnNames.join("_")}_unique`;
|
|
1376
|
-
uniqueConstraintObject[name] = {
|
|
1377
|
-
name,
|
|
1378
|
-
columns: columnNames,
|
|
1379
|
-
nullsNotDistinct: unq.nullsNotDistinct
|
|
1380
|
-
};
|
|
1381
|
-
});
|
|
1382
|
-
foreignKeys.forEach((fk) => {
|
|
1383
|
-
const reference = fk.reference();
|
|
1384
|
-
const columnsFrom = reference.columns.map((it) => it.name);
|
|
1385
|
-
const columnsTo = reference.foreignColumns.map((it) => it.name);
|
|
1386
|
-
const tableTo = getTableConfig(reference.foreignTable).name;
|
|
1387
|
-
const schemaTo = getTableConfig(reference.foreignTable).schema || "public";
|
|
1388
|
-
const name = fk.getName();
|
|
1389
|
-
foreignKeysObject[name] = {
|
|
1390
|
-
name,
|
|
1391
|
-
tableFrom: tableName,
|
|
1392
|
-
schemaFrom: tableSchema,
|
|
1393
|
-
tableTo,
|
|
1394
|
-
schemaTo,
|
|
1395
|
-
columnsFrom,
|
|
1396
|
-
columnsTo,
|
|
1397
|
-
onDelete: fk.onDelete || "no action",
|
|
1398
|
-
onUpdate: fk.onUpdate || "no action"
|
|
1399
|
-
};
|
|
1400
|
-
});
|
|
1401
|
-
indexes.forEach((idx) => {
|
|
1402
|
-
const indexCols = idx.config.columns;
|
|
1403
|
-
const indexColumns = indexCols.map((col) => {
|
|
1404
|
-
if (is(col, SQL)) {
|
|
1405
|
-
return {
|
|
1406
|
-
expression: dialect.sqlToQuery(col).sql,
|
|
1407
|
-
isExpression: true
|
|
1408
|
-
};
|
|
1409
|
-
} else {
|
|
1410
|
-
const indexCol = {
|
|
1411
|
-
expression: col.name,
|
|
1412
|
-
isExpression: false,
|
|
1413
|
-
asc: col.indexConfig && col.indexConfig.order === "asc"
|
|
1414
|
-
};
|
|
1415
|
-
if (col.indexConfig?.nulls) {
|
|
1416
|
-
indexCol.nulls = col.indexConfig.nulls;
|
|
1417
|
-
}
|
|
1418
|
-
return indexCol;
|
|
1419
|
-
}
|
|
1420
|
-
});
|
|
1421
|
-
const name = idx.config.name || `${tableName}_${indexColumns.map((c) => c.expression).join("_")}_index`;
|
|
1422
|
-
indexesObject[name] = {
|
|
1423
|
-
name,
|
|
1424
|
-
columns: indexColumns,
|
|
1425
|
-
isUnique: idx.config.unique || false,
|
|
1426
|
-
method: idx.config.method || "btree"
|
|
1427
|
-
};
|
|
1428
|
-
});
|
|
1429
|
-
if (checks) {
|
|
1430
|
-
checks.forEach((check3) => {
|
|
1431
|
-
const checkName = check3.name;
|
|
1432
|
-
checksObject[checkName] = {
|
|
1433
|
-
name: checkName,
|
|
1434
|
-
value: dialect.sqlToQuery(check3.value).sql
|
|
1435
|
-
};
|
|
1436
|
-
});
|
|
1437
|
-
}
|
|
1438
|
-
tables[`${tableSchema || "public"}.${tableName}`] = {
|
|
1439
|
-
name: tableName,
|
|
1440
|
-
schema: tableSchema || "public",
|
|
1441
|
-
columns: columnsObject,
|
|
1442
|
-
indexes: indexesObject,
|
|
1443
|
-
foreignKeys: foreignKeysObject,
|
|
1444
|
-
compositePrimaryKeys: primaryKeysObject,
|
|
1445
|
-
uniqueConstraints: uniqueConstraintObject,
|
|
1446
|
-
checkConstraints: checksObject
|
|
1447
|
-
};
|
|
1448
|
-
if (tableSchema && tableSchema !== "public") {
|
|
1449
|
-
schemas[tableSchema] = tableSchema;
|
|
1575
|
+
}
|
|
1450
1576
|
}
|
|
1451
1577
|
}
|
|
1452
|
-
|
|
1453
|
-
version: "7",
|
|
1454
|
-
dialect: "postgresql",
|
|
1455
|
-
tables,
|
|
1456
|
-
schemas,
|
|
1457
|
-
enums,
|
|
1458
|
-
_meta: {
|
|
1459
|
-
schemas: {},
|
|
1460
|
-
tables: {},
|
|
1461
|
-
columns: {}
|
|
1462
|
-
}
|
|
1463
|
-
};
|
|
1464
|
-
return snapshot;
|
|
1465
|
-
}
|
|
1466
|
-
function hashSnapshot(snapshot) {
|
|
1467
|
-
const content = JSON.stringify(snapshot);
|
|
1468
|
-
return extendedHash(content);
|
|
1578
|
+
return diff;
|
|
1469
1579
|
}
|
|
1470
|
-
function
|
|
1471
|
-
|
|
1472
|
-
return Object.keys(currentSnapshot.tables).length > 0;
|
|
1473
|
-
}
|
|
1474
|
-
const prevHash = hashSnapshot(previousSnapshot);
|
|
1475
|
-
const currHash = hashSnapshot(currentSnapshot);
|
|
1476
|
-
return prevHash !== currHash;
|
|
1580
|
+
function hasDiffChanges(diff) {
|
|
1581
|
+
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;
|
|
1477
1582
|
}
|
|
1478
|
-
var sqlToStr = (sql21, _casing) => {
|
|
1479
|
-
const config = {
|
|
1480
|
-
escapeName: () => {
|
|
1481
|
-
throw new Error("we don't support params for `sql` default values");
|
|
1482
|
-
},
|
|
1483
|
-
escapeParam: () => {
|
|
1484
|
-
throw new Error("we don't support params for `sql` default values");
|
|
1485
|
-
},
|
|
1486
|
-
escapeString: () => {
|
|
1487
|
-
throw new Error("we don't support params for `sql` default values");
|
|
1488
|
-
},
|
|
1489
|
-
casing: undefined
|
|
1490
|
-
};
|
|
1491
|
-
return sql21.toQuery(config).sql;
|
|
1492
|
-
};
|
|
1493
|
-
var init_snapshot_generator = () => {};
|
|
1494
1583
|
|
|
1495
|
-
// runtime-migrator/drizzle-adapters/
|
|
1496
|
-
import {
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
}
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
result.warnings.push(`Column "${col.column}" in table "${col.table}" will be dropped`);
|
|
1521
|
-
}
|
|
1522
|
-
}
|
|
1523
|
-
for (const modified of diff.columns.modified) {
|
|
1524
|
-
const from = modified.changes.from;
|
|
1525
|
-
const to = modified.changes.to;
|
|
1526
|
-
if (!from || !to)
|
|
1527
|
-
continue;
|
|
1528
|
-
if (from.type !== to.type) {
|
|
1529
|
-
const isDestructive = checkIfTypeChangeIsDestructive(from.type, to.type);
|
|
1530
|
-
if (isDestructive) {
|
|
1531
|
-
result.hasDataLoss = true;
|
|
1532
|
-
result.requiresConfirmation = true;
|
|
1533
|
-
result.typeChanges.push({
|
|
1534
|
-
table: modified.table,
|
|
1535
|
-
column: modified.column,
|
|
1536
|
-
from: from.type,
|
|
1537
|
-
to: to.type
|
|
1538
|
-
});
|
|
1539
|
-
result.tablesToTruncate.push(modified.table);
|
|
1540
|
-
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.`);
|
|
1584
|
+
// runtime-migrator/drizzle-adapters/snapshot-generator.ts
|
|
1585
|
+
import { is, SQL } from "drizzle-orm";
|
|
1586
|
+
import { getTableConfig, PgDialect, PgTable } from "drizzle-orm/pg-core";
|
|
1587
|
+
function escapeSingleQuotes(str) {
|
|
1588
|
+
return str.replace(/'/g, "''");
|
|
1589
|
+
}
|
|
1590
|
+
function isPgArrayType(sqlType) {
|
|
1591
|
+
return sqlType.match(/.*\[\d*\].*|.*\[\].*/g) !== null;
|
|
1592
|
+
}
|
|
1593
|
+
function buildArrayString(array, sqlType) {
|
|
1594
|
+
sqlType = sqlType.split("[")[0];
|
|
1595
|
+
const values = array.map((value) => {
|
|
1596
|
+
if (typeof value === "number" || typeof value === "bigint") {
|
|
1597
|
+
return value.toString();
|
|
1598
|
+
} else if (typeof value === "boolean") {
|
|
1599
|
+
return value ? "true" : "false";
|
|
1600
|
+
} else if (Array.isArray(value)) {
|
|
1601
|
+
return buildArrayString(value, sqlType);
|
|
1602
|
+
} else if (value instanceof Date) {
|
|
1603
|
+
if (sqlType === "date") {
|
|
1604
|
+
return `"${value.toISOString().split("T")[0]}"`;
|
|
1605
|
+
} else if (sqlType === "timestamp") {
|
|
1606
|
+
return `"${value.toISOString().replace("T", " ").slice(0, 23)}"`;
|
|
1607
|
+
} else {
|
|
1608
|
+
return `"${value.toISOString()}"`;
|
|
1541
1609
|
}
|
|
1610
|
+
} else if (typeof value === "object") {
|
|
1611
|
+
return `"${JSON.stringify(value).replaceAll('"', "\\\"")}"`;
|
|
1542
1612
|
}
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
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.`);
|
|
1547
|
-
}
|
|
1548
|
-
}
|
|
1549
|
-
for (const added of diff.columns.added) {
|
|
1550
|
-
if (added.definition.notNull && !added.definition.default) {
|
|
1551
|
-
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.`);
|
|
1552
|
-
}
|
|
1553
|
-
}
|
|
1554
|
-
return result;
|
|
1613
|
+
return `"${value}"`;
|
|
1614
|
+
}).join(",");
|
|
1615
|
+
return `{${values}}`;
|
|
1555
1616
|
}
|
|
1556
|
-
function
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
}
|
|
1563
|
-
if (normalized === "serial") {
|
|
1564
|
-
return "integer";
|
|
1565
|
-
}
|
|
1566
|
-
if (normalized === "bigserial") {
|
|
1567
|
-
return "bigint";
|
|
1568
|
-
}
|
|
1569
|
-
if (normalized === "smallserial") {
|
|
1570
|
-
return "smallint";
|
|
1571
|
-
}
|
|
1572
|
-
if (normalized.startsWith("numeric") || normalized.startsWith("decimal")) {
|
|
1573
|
-
const match = normalized.match(/\((\d+)(?:,\s*(\d+))?\)/);
|
|
1574
|
-
if (match) {
|
|
1575
|
-
return `numeric(${match[1]}${match[2] ? `,${match[2]}` : ""})`;
|
|
1617
|
+
function extractTablesFromSchema(schema) {
|
|
1618
|
+
const tables = [];
|
|
1619
|
+
const exports = Object.values(schema);
|
|
1620
|
+
exports.forEach((t) => {
|
|
1621
|
+
if (is(t, PgTable)) {
|
|
1622
|
+
tables.push(t);
|
|
1576
1623
|
}
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
if (normalized.startsWith("character varying")) {
|
|
1580
|
-
return normalized.replace("character varying", "varchar");
|
|
1581
|
-
}
|
|
1582
|
-
if (normalized === "text[]" || normalized === "_text") {
|
|
1583
|
-
return "text[]";
|
|
1584
|
-
}
|
|
1585
|
-
return normalized;
|
|
1586
|
-
}
|
|
1587
|
-
function checkIfTypeChangeIsDestructive(fromType, toType) {
|
|
1588
|
-
const normalizedFrom = normalizeType2(fromType);
|
|
1589
|
-
const normalizedTo = normalizeType2(toType);
|
|
1590
|
-
if (normalizedFrom === normalizedTo) {
|
|
1591
|
-
return false;
|
|
1592
|
-
}
|
|
1593
|
-
const safeConversions = {
|
|
1594
|
-
smallint: ["integer", "bigint", "numeric", "real", "double precision"],
|
|
1595
|
-
integer: ["bigint", "numeric", "real", "double precision"],
|
|
1596
|
-
bigint: ["numeric"],
|
|
1597
|
-
real: ["double precision"],
|
|
1598
|
-
varchar: ["text"],
|
|
1599
|
-
char: ["varchar", "text"],
|
|
1600
|
-
citext: ["text"],
|
|
1601
|
-
text: ["citext"],
|
|
1602
|
-
uuid: ["text", "varchar"],
|
|
1603
|
-
timestamp: ["timestamp"],
|
|
1604
|
-
date: ["timestamp"],
|
|
1605
|
-
time: ["timetz"]
|
|
1606
|
-
};
|
|
1607
|
-
const fromBase = normalizedFrom.split("(")[0];
|
|
1608
|
-
const toBase = normalizedTo.split("(")[0];
|
|
1609
|
-
if (fromBase === toBase) {
|
|
1610
|
-
return false;
|
|
1611
|
-
}
|
|
1612
|
-
const safeTo = safeConversions[fromBase];
|
|
1613
|
-
if (safeTo?.includes(toBase)) {
|
|
1614
|
-
return false;
|
|
1615
|
-
}
|
|
1616
|
-
return true;
|
|
1624
|
+
});
|
|
1625
|
+
return tables;
|
|
1617
1626
|
}
|
|
1618
|
-
async function
|
|
1619
|
-
const
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
const
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1627
|
+
async function generateSnapshot(schema) {
|
|
1628
|
+
const dialect = new PgDialect({ casing: undefined });
|
|
1629
|
+
const tables = {};
|
|
1630
|
+
const schemas = {};
|
|
1631
|
+
const enums = {};
|
|
1632
|
+
const pgTables = extractTablesFromSchema(schema);
|
|
1633
|
+
for (const table of pgTables) {
|
|
1634
|
+
const config = getTableConfig(table);
|
|
1635
|
+
const {
|
|
1636
|
+
name: tableName,
|
|
1637
|
+
columns,
|
|
1638
|
+
indexes,
|
|
1639
|
+
foreignKeys,
|
|
1640
|
+
schema: tableSchema,
|
|
1641
|
+
primaryKeys,
|
|
1642
|
+
uniqueConstraints,
|
|
1643
|
+
checks
|
|
1644
|
+
} = config;
|
|
1645
|
+
const columnsObject = {};
|
|
1646
|
+
const indexesObject = {};
|
|
1647
|
+
const foreignKeysObject = {};
|
|
1648
|
+
const primaryKeysObject = {};
|
|
1649
|
+
const uniqueConstraintObject = {};
|
|
1650
|
+
const checksObject = {};
|
|
1651
|
+
columns.forEach((column) => {
|
|
1652
|
+
const name = column.name;
|
|
1653
|
+
const notNull = column.notNull;
|
|
1654
|
+
const primaryKey4 = column.primary;
|
|
1655
|
+
const sqlType = column.getSQLType();
|
|
1656
|
+
const sqlTypeLowered = sqlType.toLowerCase();
|
|
1657
|
+
const columnToSet = {
|
|
1658
|
+
name,
|
|
1659
|
+
type: sqlType,
|
|
1660
|
+
primaryKey: primaryKey4,
|
|
1661
|
+
notNull
|
|
1662
|
+
};
|
|
1663
|
+
if (column.default !== undefined) {
|
|
1664
|
+
if (is(column.default, SQL)) {
|
|
1665
|
+
columnToSet.default = sqlToStr(column.default, undefined);
|
|
1666
|
+
} else {
|
|
1667
|
+
if (typeof column.default === "string") {
|
|
1668
|
+
columnToSet.default = `'${escapeSingleQuotes(column.default)}'`;
|
|
1669
|
+
} else {
|
|
1670
|
+
if (sqlTypeLowered === "jsonb" || sqlTypeLowered === "json") {
|
|
1671
|
+
columnToSet.default = `'${JSON.stringify(column.default)}'::${sqlTypeLowered}`;
|
|
1672
|
+
} else if (column.default instanceof Date) {
|
|
1673
|
+
if (sqlTypeLowered === "date") {
|
|
1674
|
+
columnToSet.default = `'${column.default.toISOString().split("T")[0]}'`;
|
|
1675
|
+
} else if (sqlTypeLowered === "timestamp") {
|
|
1676
|
+
columnToSet.default = `'${column.default.toISOString().replace("T", " ").slice(0, 23)}'`;
|
|
1677
|
+
} else {
|
|
1678
|
+
columnToSet.default = `'${column.default.toISOString()}'`;
|
|
1679
|
+
}
|
|
1680
|
+
} else if (isPgArrayType(sqlTypeLowered) && Array.isArray(column.default)) {
|
|
1681
|
+
columnToSet.default = `'${buildArrayString(column.default, sqlTypeLowered)}'`;
|
|
1682
|
+
} else {
|
|
1683
|
+
columnToSet.default = column.default;
|
|
1684
|
+
}
|
|
1685
|
+
}
|
|
1686
|
+
}
|
|
1635
1687
|
}
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
const table = currentSnapshot.tables[tableName];
|
|
1645
|
-
if (table) {
|
|
1646
|
-
const { tableSQL, fkSQLs } = generateCreateTableSQL(tableName, table);
|
|
1647
|
-
createTableStatements.push(tableSQL);
|
|
1648
|
-
foreignKeyStatements.push(...fkSQLs);
|
|
1649
|
-
}
|
|
1650
|
-
}
|
|
1651
|
-
statements.push(...createTableStatements);
|
|
1652
|
-
const uniqueFKs = new Set;
|
|
1653
|
-
const dedupedFKStatements = [];
|
|
1654
|
-
for (const fkSQL of foreignKeyStatements) {
|
|
1655
|
-
const match = fkSQL.match(/ADD CONSTRAINT "([^"]+)"/);
|
|
1656
|
-
if (match) {
|
|
1657
|
-
const constraintName = match[1];
|
|
1658
|
-
if (!uniqueFKs.has(constraintName)) {
|
|
1659
|
-
uniqueFKs.add(constraintName);
|
|
1660
|
-
dedupedFKStatements.push(fkSQL);
|
|
1688
|
+
const columnWithConfig = column;
|
|
1689
|
+
const columnConfig = columnWithConfig.config;
|
|
1690
|
+
if (columnWithConfig.isUnique && columnConfig && columnConfig.uniqueName) {
|
|
1691
|
+
uniqueConstraintObject[columnConfig.uniqueName] = {
|
|
1692
|
+
name: columnConfig.uniqueName,
|
|
1693
|
+
columns: [name],
|
|
1694
|
+
nullsNotDistinct: columnConfig.uniqueType === "not distinct"
|
|
1695
|
+
};
|
|
1661
1696
|
}
|
|
1662
|
-
|
|
1663
|
-
dedupedFKStatements.push(fkSQL);
|
|
1664
|
-
}
|
|
1665
|
-
}
|
|
1666
|
-
statements.push(...dedupedFKStatements);
|
|
1667
|
-
for (const tableName of diff.tables.deleted) {
|
|
1668
|
-
const [schema, name] = tableName.includes(".") ? tableName.split(".") : ["public", tableName];
|
|
1669
|
-
statements.push(`DROP TABLE IF EXISTS "${schema}"."${name}" CASCADE;`);
|
|
1670
|
-
}
|
|
1671
|
-
for (const added of diff.columns.added) {
|
|
1672
|
-
statements.push(generateAddColumnSQL(added.table, added.column, added.definition));
|
|
1673
|
-
}
|
|
1674
|
-
for (const deleted of diff.columns.deleted) {
|
|
1675
|
-
statements.push(generateDropColumnSQL(deleted.table, deleted.column));
|
|
1676
|
-
}
|
|
1677
|
-
for (const modified of diff.columns.modified) {
|
|
1678
|
-
const alterStatements = generateAlterColumnSQL(modified.table, modified.column, modified.changes);
|
|
1679
|
-
statements.push(...alterStatements);
|
|
1680
|
-
}
|
|
1681
|
-
for (const index7 of diff.indexes.deleted) {
|
|
1682
|
-
statements.push(generateDropIndexSQL(index7));
|
|
1683
|
-
}
|
|
1684
|
-
for (const alteredIndex of diff.indexes.altered) {
|
|
1685
|
-
statements.push(generateDropIndexSQL(alteredIndex.old));
|
|
1686
|
-
}
|
|
1687
|
-
for (const index7 of diff.indexes.created) {
|
|
1688
|
-
statements.push(generateCreateIndexSQL(index7));
|
|
1689
|
-
}
|
|
1690
|
-
for (const alteredIndex of diff.indexes.altered) {
|
|
1691
|
-
statements.push(generateCreateIndexSQL(alteredIndex.new));
|
|
1692
|
-
}
|
|
1693
|
-
for (const constraint of diff.uniqueConstraints.created) {
|
|
1694
|
-
const isNewTable = diff.tables.created.some((tableName) => {
|
|
1695
|
-
const [schema, table] = tableName.includes(".") ? tableName.split(".") : ["public", tableName];
|
|
1696
|
-
const constraintTable = constraint.table || "";
|
|
1697
|
-
const [constraintSchema, constraintTableName] = constraintTable.includes(".") ? constraintTable.split(".") : ["public", constraintTable];
|
|
1698
|
-
return table === constraintTableName && schema === constraintSchema;
|
|
1697
|
+
columnsObject[name] = columnToSet;
|
|
1699
1698
|
});
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
for (const constraint of diff.checkConstraints.created) {
|
|
1708
|
-
const isNewTable = diff.tables.created.some((tableName) => {
|
|
1709
|
-
const [schema, table] = tableName.includes(".") ? tableName.split(".") : ["public", tableName];
|
|
1710
|
-
const constraintTable = constraint.table || "";
|
|
1711
|
-
const [constraintSchema, constraintTableName] = constraintTable.includes(".") ? constraintTable.split(".") : ["public", constraintTable];
|
|
1712
|
-
return table === constraintTableName && schema === constraintSchema;
|
|
1699
|
+
primaryKeys.forEach((pk) => {
|
|
1700
|
+
const columnNames = pk.columns.map((c) => c.name);
|
|
1701
|
+
const name = pk.getName();
|
|
1702
|
+
primaryKeysObject[name] = {
|
|
1703
|
+
name,
|
|
1704
|
+
columns: columnNames
|
|
1705
|
+
};
|
|
1713
1706
|
});
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
statements.push(generateDropForeignKeySQL(fk));
|
|
1723
|
-
}
|
|
1724
|
-
for (const alteredFK of diff.foreignKeys.altered) {
|
|
1725
|
-
statements.push(generateDropForeignKeySQL(alteredFK.old));
|
|
1726
|
-
}
|
|
1727
|
-
for (const fk of diff.foreignKeys.created) {
|
|
1728
|
-
const tableFrom = fk.tableFrom || "";
|
|
1729
|
-
const schemaFrom = fk.schemaFrom || "public";
|
|
1730
|
-
const isNewTable = diff.tables.created.some((tableName) => {
|
|
1731
|
-
const [createdSchema, createdTable] = tableName.includes(".") ? tableName.split(".") : ["public", tableName];
|
|
1732
|
-
return createdTable === tableFrom && createdSchema === schemaFrom;
|
|
1707
|
+
uniqueConstraints?.forEach((unq) => {
|
|
1708
|
+
const columnNames = unq.columns.map((c) => c.name);
|
|
1709
|
+
const name = unq.name || `${tableName}_${columnNames.join("_")}_unique`;
|
|
1710
|
+
uniqueConstraintObject[name] = {
|
|
1711
|
+
name,
|
|
1712
|
+
columns: columnNames,
|
|
1713
|
+
nullsNotDistinct: unq.nullsNotDistinct
|
|
1714
|
+
};
|
|
1733
1715
|
});
|
|
1734
|
-
|
|
1735
|
-
|
|
1716
|
+
foreignKeys.forEach((fk) => {
|
|
1717
|
+
const reference = fk.reference();
|
|
1718
|
+
const columnsFrom = reference.columns.map((it) => it.name);
|
|
1719
|
+
const columnsTo = reference.foreignColumns.map((it) => it.name);
|
|
1720
|
+
const tableTo = getTableConfig(reference.foreignTable).name;
|
|
1721
|
+
const schemaTo = getTableConfig(reference.foreignTable).schema || "public";
|
|
1722
|
+
const name = fk.getName();
|
|
1723
|
+
foreignKeysObject[name] = {
|
|
1724
|
+
name,
|
|
1725
|
+
tableFrom: tableName,
|
|
1726
|
+
schemaFrom: tableSchema,
|
|
1727
|
+
tableTo,
|
|
1728
|
+
schemaTo,
|
|
1729
|
+
columnsFrom,
|
|
1730
|
+
columnsTo,
|
|
1731
|
+
onDelete: fk.onDelete || "no action",
|
|
1732
|
+
onUpdate: fk.onUpdate || "no action"
|
|
1733
|
+
};
|
|
1734
|
+
});
|
|
1735
|
+
indexes.forEach((idx) => {
|
|
1736
|
+
const indexCols = idx.config.columns;
|
|
1737
|
+
const indexColumns = indexCols.map((col) => {
|
|
1738
|
+
if (is(col, SQL)) {
|
|
1739
|
+
return {
|
|
1740
|
+
expression: dialect.sqlToQuery(col).sql,
|
|
1741
|
+
isExpression: true
|
|
1742
|
+
};
|
|
1743
|
+
} else {
|
|
1744
|
+
const indexCol = {
|
|
1745
|
+
expression: col.name,
|
|
1746
|
+
isExpression: false,
|
|
1747
|
+
asc: col.indexConfig && col.indexConfig.order === "asc"
|
|
1748
|
+
};
|
|
1749
|
+
if (col.indexConfig?.nulls) {
|
|
1750
|
+
indexCol.nulls = col.indexConfig.nulls;
|
|
1751
|
+
}
|
|
1752
|
+
return indexCol;
|
|
1753
|
+
}
|
|
1754
|
+
});
|
|
1755
|
+
const name = idx.config.name || `${tableName}_${indexColumns.map((c) => c.expression).join("_")}_index`;
|
|
1756
|
+
indexesObject[name] = {
|
|
1757
|
+
name,
|
|
1758
|
+
columns: indexColumns,
|
|
1759
|
+
isUnique: idx.config.unique || false,
|
|
1760
|
+
method: idx.config.method || "btree"
|
|
1761
|
+
};
|
|
1762
|
+
});
|
|
1763
|
+
if (checks) {
|
|
1764
|
+
checks.forEach((check3) => {
|
|
1765
|
+
const checkName = check3.name;
|
|
1766
|
+
checksObject[checkName] = {
|
|
1767
|
+
name: checkName,
|
|
1768
|
+
value: dialect.sqlToQuery(check3.value).sql
|
|
1769
|
+
};
|
|
1770
|
+
});
|
|
1771
|
+
}
|
|
1772
|
+
tables[`${tableSchema || "public"}.${tableName}`] = {
|
|
1773
|
+
name: tableName,
|
|
1774
|
+
schema: tableSchema || "public",
|
|
1775
|
+
columns: columnsObject,
|
|
1776
|
+
indexes: indexesObject,
|
|
1777
|
+
foreignKeys: foreignKeysObject,
|
|
1778
|
+
compositePrimaryKeys: primaryKeysObject,
|
|
1779
|
+
uniqueConstraints: uniqueConstraintObject,
|
|
1780
|
+
checkConstraints: checksObject
|
|
1781
|
+
};
|
|
1782
|
+
if (tableSchema && tableSchema !== "public") {
|
|
1783
|
+
schemas[tableSchema] = tableSchema;
|
|
1736
1784
|
}
|
|
1737
1785
|
}
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1786
|
+
const snapshot = {
|
|
1787
|
+
version: "7",
|
|
1788
|
+
dialect: "postgresql",
|
|
1789
|
+
tables,
|
|
1790
|
+
schemas,
|
|
1791
|
+
enums,
|
|
1792
|
+
_meta: {
|
|
1793
|
+
schemas: {},
|
|
1794
|
+
tables: {},
|
|
1795
|
+
columns: {}
|
|
1796
|
+
}
|
|
1797
|
+
};
|
|
1798
|
+
return snapshot;
|
|
1799
|
+
}
|
|
1800
|
+
function hashSnapshot(snapshot) {
|
|
1801
|
+
const content = JSON.stringify(snapshot);
|
|
1802
|
+
return extendedHash(content);
|
|
1742
1803
|
}
|
|
1743
|
-
function
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
const fkSQLs = [];
|
|
1747
|
-
for (const [colName, colDef] of Object.entries(table.columns || {})) {
|
|
1748
|
-
columns.push(generateColumnDefinition(colName, colDef));
|
|
1804
|
+
function hasChanges(previousSnapshot, currentSnapshot) {
|
|
1805
|
+
if (!previousSnapshot) {
|
|
1806
|
+
return Object.keys(currentSnapshot.tables).length > 0;
|
|
1749
1807
|
}
|
|
1750
|
-
const
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1808
|
+
const prevHash = hashSnapshot(previousSnapshot);
|
|
1809
|
+
const currHash = hashSnapshot(currentSnapshot);
|
|
1810
|
+
return prevHash !== currHash;
|
|
1811
|
+
}
|
|
1812
|
+
var sqlToStr = (sql22, _casing) => {
|
|
1813
|
+
const config = {
|
|
1814
|
+
escapeName: () => {
|
|
1815
|
+
throw new Error("we don't support params for `sql` default values");
|
|
1816
|
+
},
|
|
1817
|
+
escapeParam: () => {
|
|
1818
|
+
throw new Error("we don't support params for `sql` default values");
|
|
1819
|
+
},
|
|
1820
|
+
escapeString: () => {
|
|
1821
|
+
throw new Error("we don't support params for `sql` default values");
|
|
1822
|
+
},
|
|
1823
|
+
casing: undefined
|
|
1824
|
+
};
|
|
1825
|
+
return sql22.toQuery(config).sql;
|
|
1826
|
+
};
|
|
1827
|
+
var init_snapshot_generator = () => {};
|
|
1828
|
+
|
|
1829
|
+
// runtime-migrator/drizzle-adapters/sql-generator.ts
|
|
1830
|
+
import { logger as logger4 } from "@elizaos/core";
|
|
1831
|
+
function checkForDataLoss(diff) {
|
|
1832
|
+
const result = {
|
|
1833
|
+
hasDataLoss: false,
|
|
1834
|
+
tablesToRemove: [],
|
|
1835
|
+
columnsToRemove: [],
|
|
1836
|
+
tablesToTruncate: [],
|
|
1837
|
+
typeChanges: [],
|
|
1838
|
+
warnings: [],
|
|
1839
|
+
requiresConfirmation: false
|
|
1840
|
+
};
|
|
1841
|
+
if (diff.tables.deleted.length > 0) {
|
|
1842
|
+
result.hasDataLoss = true;
|
|
1843
|
+
result.requiresConfirmation = true;
|
|
1844
|
+
result.tablesToRemove = [...diff.tables.deleted];
|
|
1845
|
+
for (const table of diff.tables.deleted) {
|
|
1846
|
+
result.warnings.push(`Table "${table}" will be dropped with all its data`);
|
|
1755
1847
|
}
|
|
1756
1848
|
}
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1849
|
+
if (diff.columns.deleted.length > 0) {
|
|
1850
|
+
result.hasDataLoss = true;
|
|
1851
|
+
result.requiresConfirmation = true;
|
|
1852
|
+
for (const col of diff.columns.deleted) {
|
|
1853
|
+
result.columnsToRemove.push(`${col.table}.${col.column}`);
|
|
1854
|
+
result.warnings.push(`Column "${col.column}" in table "${col.table}" will be dropped`);
|
|
1763
1855
|
}
|
|
1764
1856
|
}
|
|
1765
|
-
const
|
|
1766
|
-
|
|
1767
|
-
const
|
|
1768
|
-
if (
|
|
1769
|
-
|
|
1857
|
+
for (const modified of diff.columns.modified) {
|
|
1858
|
+
const from = modified.changes.from;
|
|
1859
|
+
const to = modified.changes.to;
|
|
1860
|
+
if (!from || !to)
|
|
1861
|
+
continue;
|
|
1862
|
+
if (from.type !== to.type) {
|
|
1863
|
+
const isDestructive = checkIfTypeChangeIsDestructive(from.type, to.type);
|
|
1864
|
+
if (isDestructive) {
|
|
1865
|
+
result.hasDataLoss = true;
|
|
1866
|
+
result.requiresConfirmation = true;
|
|
1867
|
+
result.typeChanges.push({
|
|
1868
|
+
table: modified.table,
|
|
1869
|
+
column: modified.column,
|
|
1870
|
+
from: from.type,
|
|
1871
|
+
to: to.type
|
|
1872
|
+
});
|
|
1873
|
+
result.tablesToTruncate.push(modified.table);
|
|
1874
|
+
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.`);
|
|
1875
|
+
}
|
|
1876
|
+
}
|
|
1877
|
+
if (!from.notNull && to.notNull && !to.default) {
|
|
1878
|
+
result.hasDataLoss = true;
|
|
1879
|
+
result.requiresConfirmation = true;
|
|
1880
|
+
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.`);
|
|
1770
1881
|
}
|
|
1771
1882
|
}
|
|
1772
|
-
const
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
const foreignKeys = table.foreignKeys || {};
|
|
1777
|
-
for (const [fkName, fkDef] of Object.entries(foreignKeys)) {
|
|
1778
|
-
const fk = fkDef;
|
|
1779
|
-
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}` : ""};`;
|
|
1780
|
-
fkSQLs.push(fkSQL);
|
|
1883
|
+
for (const added of diff.columns.added) {
|
|
1884
|
+
if (added.definition.notNull && !added.definition.default) {
|
|
1885
|
+
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.`);
|
|
1886
|
+
}
|
|
1781
1887
|
}
|
|
1782
|
-
return
|
|
1888
|
+
return result;
|
|
1783
1889
|
}
|
|
1784
|
-
function
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1890
|
+
function normalizeType2(type) {
|
|
1891
|
+
if (!type)
|
|
1892
|
+
return "";
|
|
1893
|
+
const normalized = type.toLowerCase().trim();
|
|
1894
|
+
if (normalized === "timestamp without time zone" || normalized === "timestamp with time zone" || normalized === "timestamptz") {
|
|
1895
|
+
return "timestamp";
|
|
1788
1896
|
}
|
|
1789
|
-
if (
|
|
1790
|
-
|
|
1897
|
+
if (normalized === "serial") {
|
|
1898
|
+
return "integer";
|
|
1791
1899
|
}
|
|
1792
|
-
if (
|
|
1793
|
-
|
|
1794
|
-
sql21 += ` DEFAULT ${defaultValue}`;
|
|
1900
|
+
if (normalized === "bigserial") {
|
|
1901
|
+
return "bigint";
|
|
1795
1902
|
}
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
function generateAddColumnSQL(table, column, definition) {
|
|
1799
|
-
const [schema, tableName] = table.includes(".") ? table.split(".") : ["public", table];
|
|
1800
|
-
const tableNameWithSchema = `"${schema}"."${tableName}"`;
|
|
1801
|
-
const parts = [`"${column}"`];
|
|
1802
|
-
parts.push(definition.type);
|
|
1803
|
-
if (definition.primaryKey) {
|
|
1804
|
-
parts.push("PRIMARY KEY");
|
|
1903
|
+
if (normalized === "smallserial") {
|
|
1904
|
+
return "smallint";
|
|
1805
1905
|
}
|
|
1806
|
-
if (
|
|
1807
|
-
const
|
|
1808
|
-
if (
|
|
1809
|
-
|
|
1906
|
+
if (normalized.startsWith("numeric") || normalized.startsWith("decimal")) {
|
|
1907
|
+
const match = normalized.match(/\((\d+)(?:,\s*(\d+))?\)/);
|
|
1908
|
+
if (match) {
|
|
1909
|
+
return `numeric(${match[1]}${match[2] ? `,${match[2]}` : ""})`;
|
|
1810
1910
|
}
|
|
1911
|
+
return "numeric";
|
|
1811
1912
|
}
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
parts.push(`GENERATED ALWAYS AS (${definitionWithGenerated.generated}) STORED`);
|
|
1913
|
+
if (normalized.startsWith("character varying")) {
|
|
1914
|
+
return normalized.replace("character varying", "varchar");
|
|
1815
1915
|
}
|
|
1816
|
-
if (
|
|
1817
|
-
|
|
1916
|
+
if (normalized === "text[]" || normalized === "_text") {
|
|
1917
|
+
return "text[]";
|
|
1818
1918
|
}
|
|
1819
|
-
return
|
|
1820
|
-
}
|
|
1821
|
-
function generateDropColumnSQL(table, column) {
|
|
1822
|
-
const [schema, tableName] = table.includes(".") ? table.split(".") : ["public", table];
|
|
1823
|
-
const tableNameWithSchema = `"${schema}"."${tableName}"`;
|
|
1824
|
-
return `ALTER TABLE ${tableNameWithSchema} DROP COLUMN "${column}" CASCADE;`;
|
|
1919
|
+
return normalized;
|
|
1825
1920
|
}
|
|
1826
|
-
function
|
|
1827
|
-
const
|
|
1828
|
-
const
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
const changesFrom = changes.from;
|
|
1832
|
-
const changesToType = changesTo?.type;
|
|
1833
|
-
const changesFromType = changesFrom?.type;
|
|
1834
|
-
if (changesToType !== changesFromType) {
|
|
1835
|
-
const newType = changesToType || "TEXT";
|
|
1836
|
-
const needsUsing = checkIfNeedsUsingClause(changesFromType || "", newType);
|
|
1837
|
-
if (needsUsing) {
|
|
1838
|
-
statements.push(`ALTER TABLE ${tableNameWithSchema} ALTER COLUMN "${column}" TYPE ${newType} USING "${column}"::text::${newType};`);
|
|
1839
|
-
} else {
|
|
1840
|
-
statements.push(`ALTER TABLE ${tableNameWithSchema} ALTER COLUMN "${column}" SET DATA TYPE ${newType};`);
|
|
1841
|
-
}
|
|
1842
|
-
}
|
|
1843
|
-
const changesToNotNull = changesTo?.notNull;
|
|
1844
|
-
const changesFromNotNull = changesFrom?.notNull;
|
|
1845
|
-
if (changesToNotNull !== changesFromNotNull) {
|
|
1846
|
-
if (changesToNotNull) {
|
|
1847
|
-
statements.push(`ALTER TABLE ${tableNameWithSchema} ALTER COLUMN "${column}" SET NOT NULL;`);
|
|
1848
|
-
} else {
|
|
1849
|
-
statements.push(`ALTER TABLE ${tableNameWithSchema} ALTER COLUMN "${column}" DROP NOT NULL;`);
|
|
1850
|
-
}
|
|
1851
|
-
}
|
|
1852
|
-
const changesToDefault = changesTo?.default;
|
|
1853
|
-
const changesFromDefault = changesFrom?.default;
|
|
1854
|
-
if (changesToDefault !== changesFromDefault) {
|
|
1855
|
-
if (changesToDefault !== undefined) {
|
|
1856
|
-
const defaultValue = formatDefaultValue(changesToDefault, changesToType || "");
|
|
1857
|
-
statements.push(`ALTER TABLE ${tableNameWithSchema} ALTER COLUMN "${column}" SET DEFAULT ${defaultValue};`);
|
|
1858
|
-
} else {
|
|
1859
|
-
statements.push(`ALTER TABLE ${tableNameWithSchema} ALTER COLUMN "${column}" DROP DEFAULT;`);
|
|
1860
|
-
}
|
|
1921
|
+
function checkIfTypeChangeIsDestructive(fromType, toType) {
|
|
1922
|
+
const normalizedFrom = normalizeType2(fromType);
|
|
1923
|
+
const normalizedTo = normalizeType2(toType);
|
|
1924
|
+
if (normalizedFrom === normalizedTo) {
|
|
1925
|
+
return false;
|
|
1861
1926
|
}
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1927
|
+
const safeConversions = {
|
|
1928
|
+
smallint: ["integer", "bigint", "numeric", "real", "double precision"],
|
|
1929
|
+
integer: ["bigint", "numeric", "real", "double precision"],
|
|
1930
|
+
bigint: ["numeric"],
|
|
1931
|
+
real: ["double precision"],
|
|
1932
|
+
varchar: ["text"],
|
|
1933
|
+
char: ["varchar", "text"],
|
|
1934
|
+
citext: ["text"],
|
|
1935
|
+
text: ["citext"],
|
|
1936
|
+
uuid: ["text", "varchar"],
|
|
1937
|
+
timestamp: ["timestamp"],
|
|
1938
|
+
date: ["timestamp"],
|
|
1939
|
+
time: ["timetz"]
|
|
1940
|
+
};
|
|
1941
|
+
const fromBase = normalizedFrom.split("(")[0];
|
|
1942
|
+
const toBase = normalizedTo.split("(")[0];
|
|
1943
|
+
if (fromBase === toBase) {
|
|
1866
1944
|
return false;
|
|
1867
|
-
if (fromType.includes("enum") || toType.includes("enum")) {
|
|
1868
|
-
return true;
|
|
1869
1945
|
}
|
|
1870
|
-
const
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
return true;
|
|
1946
|
+
const safeTo = safeConversions[fromBase];
|
|
1947
|
+
if (safeTo?.includes(toBase)) {
|
|
1948
|
+
return false;
|
|
1874
1949
|
}
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
["text", "jsonb"],
|
|
1883
|
-
["text", "json"],
|
|
1884
|
-
["varchar", "integer"],
|
|
1885
|
-
["varchar", "numeric"],
|
|
1886
|
-
["varchar", "boolean"],
|
|
1887
|
-
["varchar", "uuid"],
|
|
1888
|
-
["varchar", "jsonb"],
|
|
1889
|
-
["varchar", "json"],
|
|
1890
|
-
["character varying", "jsonb"],
|
|
1891
|
-
["character varying", "json"]
|
|
1892
|
-
];
|
|
1893
|
-
for (const [from, to] of needsUsingPairs) {
|
|
1894
|
-
if (fromBase === from && toBase === to || fromBase === to && toBase === from) {
|
|
1895
|
-
return true;
|
|
1896
|
-
}
|
|
1950
|
+
return true;
|
|
1951
|
+
}
|
|
1952
|
+
async function generateMigrationSQL(previousSnapshot, currentSnapshot, diff) {
|
|
1953
|
+
const statements = [];
|
|
1954
|
+
if (!diff) {
|
|
1955
|
+
const { calculateDiff: calculateDiff2 } = await Promise.resolve().then(() => exports_diff_calculator);
|
|
1956
|
+
diff = await calculateDiff2(previousSnapshot, currentSnapshot);
|
|
1897
1957
|
}
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
if (value === null || value === "NULL") {
|
|
1902
|
-
return "NULL";
|
|
1958
|
+
const dataLossCheck = checkForDataLoss(diff);
|
|
1959
|
+
if (dataLossCheck.warnings.length > 0) {
|
|
1960
|
+
logger4.warn({ src: "plugin:sql", warnings: dataLossCheck.warnings }, "Schema changes may cause data loss");
|
|
1903
1961
|
}
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1962
|
+
const schemasToCreate = new Set;
|
|
1963
|
+
for (const tableName of diff.tables.created) {
|
|
1964
|
+
const table = currentSnapshot.tables[tableName];
|
|
1965
|
+
if (table) {
|
|
1966
|
+
const schema = table.schema || "public";
|
|
1967
|
+
if (schema !== "public") {
|
|
1968
|
+
schemasToCreate.add(schema);
|
|
1969
|
+
}
|
|
1910
1970
|
}
|
|
1911
1971
|
}
|
|
1912
|
-
|
|
1913
|
-
|
|
1972
|
+
for (const schema of schemasToCreate) {
|
|
1973
|
+
statements.push(`CREATE SCHEMA IF NOT EXISTS "${schema}";`);
|
|
1914
1974
|
}
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
if (
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
return value;
|
|
1924
|
-
}
|
|
1925
|
-
if (value.toUpperCase().startsWith("CURRENT_")) {
|
|
1926
|
-
return value;
|
|
1975
|
+
const createTableStatements = [];
|
|
1976
|
+
const foreignKeyStatements = [];
|
|
1977
|
+
for (const tableName of diff.tables.created) {
|
|
1978
|
+
const table = currentSnapshot.tables[tableName];
|
|
1979
|
+
if (table) {
|
|
1980
|
+
const { tableSQL, fkSQLs } = generateCreateTableSQL(tableName, table);
|
|
1981
|
+
createTableStatements.push(tableSQL);
|
|
1982
|
+
foreignKeyStatements.push(...fkSQLs);
|
|
1927
1983
|
}
|
|
1928
|
-
return `'${value.replace(/'/g, "''")}'`;
|
|
1929
1984
|
}
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
const
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1985
|
+
statements.push(...createTableStatements);
|
|
1986
|
+
const uniqueFKs = new Set;
|
|
1987
|
+
const dedupedFKStatements = [];
|
|
1988
|
+
for (const fkSQL of foreignKeyStatements) {
|
|
1989
|
+
const match = fkSQL.match(/ADD CONSTRAINT "([^"]+)"/);
|
|
1990
|
+
if (match) {
|
|
1991
|
+
const constraintName = match[1];
|
|
1992
|
+
if (!uniqueFKs.has(constraintName)) {
|
|
1993
|
+
uniqueFKs.add(constraintName);
|
|
1994
|
+
dedupedFKStatements.push(fkSQL);
|
|
1995
|
+
}
|
|
1996
|
+
} else {
|
|
1997
|
+
dedupedFKStatements.push(fkSQL);
|
|
1938
1998
|
}
|
|
1939
|
-
return `"${c.expression}"${c.asc === false ? " DESC" : ""}`;
|
|
1940
|
-
}).join(", ");
|
|
1941
|
-
const indexName = index7.name.includes(".") ? index7.name.split(".")[1] : index7.name;
|
|
1942
|
-
let tableRef;
|
|
1943
|
-
const indexTable = index7.table;
|
|
1944
|
-
if (indexTable?.includes(".")) {
|
|
1945
|
-
const [schema, table] = indexTable.split(".");
|
|
1946
|
-
tableRef = `"${schema}"."${table}"`;
|
|
1947
|
-
} else {
|
|
1948
|
-
tableRef = `"${indexTable || ""}"`;
|
|
1949
1999
|
}
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
const indexName = indexNameFull.includes(".") ? indexNameFull.split(".")[1] : indexNameFull;
|
|
1955
|
-
return `DROP INDEX IF EXISTS "${indexName}";`;
|
|
1956
|
-
}
|
|
1957
|
-
function generateCreateForeignKeySQL(fk) {
|
|
1958
|
-
const schemaFrom = fk.schemaFrom || "public";
|
|
1959
|
-
const schemaTo = fk.schemaTo || "public";
|
|
1960
|
-
const tableFrom = fk.tableFrom;
|
|
1961
|
-
const columnsFrom = fk.columnsFrom.map((c) => `"${c}"`).join(", ");
|
|
1962
|
-
const columnsTo = fk.columnsTo.map((c) => `"${c}"`).join(", ");
|
|
1963
|
-
let sql21 = `ALTER TABLE "${schemaFrom}"."${tableFrom}" ADD CONSTRAINT "${fk.name}" FOREIGN KEY (${columnsFrom}) REFERENCES "${schemaTo}"."${fk.tableTo}" (${columnsTo})`;
|
|
1964
|
-
if (fk.onDelete) {
|
|
1965
|
-
sql21 += ` ON DELETE ${fk.onDelete}`;
|
|
2000
|
+
statements.push(...dedupedFKStatements);
|
|
2001
|
+
for (const tableName of diff.tables.deleted) {
|
|
2002
|
+
const [schema, name] = tableName.includes(".") ? tableName.split(".") : ["public", tableName];
|
|
2003
|
+
statements.push(`DROP TABLE IF EXISTS "${schema}"."${name}" CASCADE;`);
|
|
1966
2004
|
}
|
|
1967
|
-
|
|
1968
|
-
|
|
2005
|
+
for (const added of diff.columns.added) {
|
|
2006
|
+
statements.push(generateAddColumnSQL(added.table, added.column, added.definition));
|
|
1969
2007
|
}
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
function generateDropForeignKeySQL(fk) {
|
|
1973
|
-
const [schema, tableName] = fk.tableFrom ? fk.tableFrom.includes(".") ? fk.tableFrom.split(".") : ["public", fk.tableFrom] : ["public", ""];
|
|
1974
|
-
return `ALTER TABLE "${schema}"."${tableName}" DROP CONSTRAINT "${fk.name}";`;
|
|
1975
|
-
}
|
|
1976
|
-
function generateCreateUniqueConstraintSQL(constraint) {
|
|
1977
|
-
const table = constraint.table || "";
|
|
1978
|
-
const [schema, tableName] = table.includes(".") ? table.split(".") : ["public", table];
|
|
1979
|
-
const name = constraint.name;
|
|
1980
|
-
const columns = constraint.columns.map((c) => `"${c}"`).join(", ");
|
|
1981
|
-
let sql21 = `ALTER TABLE "${schema}"."${tableName}" ADD CONSTRAINT "${name}" UNIQUE`;
|
|
1982
|
-
if (constraint.nullsNotDistinct) {
|
|
1983
|
-
sql21 += ` NULLS NOT DISTINCT`;
|
|
2008
|
+
for (const deleted of diff.columns.deleted) {
|
|
2009
|
+
statements.push(generateDropColumnSQL(deleted.table, deleted.column));
|
|
1984
2010
|
}
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
function generateDropUniqueConstraintSQL(constraint) {
|
|
1989
|
-
const table = constraint.table || "";
|
|
1990
|
-
const [schema, tableName] = table.includes(".") ? table.split(".") : ["public", table];
|
|
1991
|
-
return `ALTER TABLE "${schema}"."${tableName}" DROP CONSTRAINT "${constraint.name}";`;
|
|
1992
|
-
}
|
|
1993
|
-
function generateCreateCheckConstraintSQL(constraint) {
|
|
1994
|
-
const table = constraint.table || "";
|
|
1995
|
-
const [schema, tableName] = table.includes(".") ? table.split(".") : ["public", table];
|
|
1996
|
-
const name = constraint.name;
|
|
1997
|
-
const value = constraint.value;
|
|
1998
|
-
return `ALTER TABLE "${schema}"."${tableName}" ADD CONSTRAINT "${name}" CHECK (${value});`;
|
|
1999
|
-
}
|
|
2000
|
-
function generateDropCheckConstraintSQL(constraint) {
|
|
2001
|
-
const table = constraint.table || "";
|
|
2002
|
-
const [schema, tableName] = table.includes(".") ? table.split(".") : ["public", table];
|
|
2003
|
-
return `ALTER TABLE "${schema}"."${tableName}" DROP CONSTRAINT "${constraint.name}";`;
|
|
2004
|
-
}
|
|
2005
|
-
var init_sql_generator = () => {};
|
|
2006
|
-
|
|
2007
|
-
// runtime-migrator/drizzle-adapters/database-introspector.ts
|
|
2008
|
-
import { logger as logger4 } from "@elizaos/core";
|
|
2009
|
-
import { sql as sql21 } from "drizzle-orm";
|
|
2010
|
-
function getRows2(result) {
|
|
2011
|
-
return result.rows;
|
|
2012
|
-
}
|
|
2013
|
-
|
|
2014
|
-
class DatabaseIntrospector {
|
|
2015
|
-
db;
|
|
2016
|
-
constructor(db) {
|
|
2017
|
-
this.db = db;
|
|
2011
|
+
for (const modified of diff.columns.modified) {
|
|
2012
|
+
const alterStatements = generateAlterColumnSQL(modified.table, modified.column, modified.changes);
|
|
2013
|
+
statements.push(...alterStatements);
|
|
2018
2014
|
}
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
};
|
|
2055
|
-
}
|
|
2056
|
-
}
|
|
2057
|
-
}
|
|
2058
|
-
const foreignKeys = await this.getForeignKeys(tableSchema, tableName);
|
|
2059
|
-
const foreignKeysObject = {};
|
|
2060
|
-
for (const fk of foreignKeys) {
|
|
2061
|
-
foreignKeysObject[fk.name] = {
|
|
2062
|
-
name: fk.name,
|
|
2063
|
-
tableFrom: tableName,
|
|
2064
|
-
schemaFrom: tableSchema,
|
|
2065
|
-
tableTo: fk.foreign_table_name,
|
|
2066
|
-
schemaTo: fk.foreign_table_schema || "public",
|
|
2067
|
-
columnsFrom: [fk.column_name],
|
|
2068
|
-
columnsTo: [fk.foreign_column_name],
|
|
2069
|
-
onDelete: fk.delete_rule?.toLowerCase() || "no action",
|
|
2070
|
-
onUpdate: fk.update_rule?.toLowerCase() || "no action"
|
|
2071
|
-
};
|
|
2072
|
-
}
|
|
2073
|
-
const primaryKeys = await this.getPrimaryKeys(tableSchema, tableName);
|
|
2074
|
-
const primaryKeysObject = {};
|
|
2075
|
-
for (const pk of primaryKeys) {
|
|
2076
|
-
primaryKeysObject[pk.name] = {
|
|
2077
|
-
name: pk.name,
|
|
2078
|
-
columns: pk.columns
|
|
2079
|
-
};
|
|
2080
|
-
}
|
|
2081
|
-
const uniqueConstraints = await this.getUniqueConstraints(tableSchema, tableName);
|
|
2082
|
-
for (const unq of uniqueConstraints) {
|
|
2083
|
-
uniqueConstraintObject[unq.name] = {
|
|
2084
|
-
name: unq.name,
|
|
2085
|
-
columns: unq.columns,
|
|
2086
|
-
nullsNotDistinct: false
|
|
2087
|
-
};
|
|
2088
|
-
}
|
|
2089
|
-
const checkConstraints = await this.getCheckConstraints(tableSchema, tableName);
|
|
2090
|
-
const checksObject = {};
|
|
2091
|
-
for (const check3 of checkConstraints) {
|
|
2092
|
-
checksObject[check3.name] = {
|
|
2093
|
-
name: check3.name,
|
|
2094
|
-
value: check3.definition
|
|
2095
|
-
};
|
|
2096
|
-
}
|
|
2097
|
-
tables[`${tableSchema}.${tableName}`] = {
|
|
2098
|
-
name: tableName,
|
|
2099
|
-
schema: tableSchema,
|
|
2100
|
-
columns: columnsObject,
|
|
2101
|
-
indexes: indexesObject,
|
|
2102
|
-
foreignKeys: foreignKeysObject,
|
|
2103
|
-
compositePrimaryKeys: primaryKeysObject,
|
|
2104
|
-
uniqueConstraints: uniqueConstraintObject,
|
|
2105
|
-
checkConstraints: checksObject
|
|
2106
|
-
};
|
|
2107
|
-
if (tableSchema && tableSchema !== "public") {
|
|
2108
|
-
schemas[tableSchema] = tableSchema;
|
|
2109
|
-
}
|
|
2015
|
+
for (const index7 of diff.indexes.deleted) {
|
|
2016
|
+
statements.push(generateDropIndexSQL(index7));
|
|
2017
|
+
}
|
|
2018
|
+
for (const alteredIndex of diff.indexes.altered) {
|
|
2019
|
+
statements.push(generateDropIndexSQL(alteredIndex.old));
|
|
2020
|
+
}
|
|
2021
|
+
for (const index7 of diff.indexes.created) {
|
|
2022
|
+
statements.push(generateCreateIndexSQL(index7));
|
|
2023
|
+
}
|
|
2024
|
+
for (const alteredIndex of diff.indexes.altered) {
|
|
2025
|
+
statements.push(generateCreateIndexSQL(alteredIndex.new));
|
|
2026
|
+
}
|
|
2027
|
+
for (const constraint of diff.uniqueConstraints.created) {
|
|
2028
|
+
const isNewTable = diff.tables.created.some((tableName) => {
|
|
2029
|
+
const [schema, table] = tableName.includes(".") ? tableName.split(".") : ["public", tableName];
|
|
2030
|
+
const constraintTable = constraint.table || "";
|
|
2031
|
+
const [constraintSchema, constraintTableName] = constraintTable.includes(".") ? constraintTable.split(".") : ["public", constraintTable];
|
|
2032
|
+
return table === constraintTableName && schema === constraintSchema;
|
|
2033
|
+
});
|
|
2034
|
+
if (!isNewTable) {
|
|
2035
|
+
statements.push(generateCreateUniqueConstraintSQL(constraint));
|
|
2036
|
+
}
|
|
2037
|
+
}
|
|
2038
|
+
for (const constraint of diff.uniqueConstraints.deleted) {
|
|
2039
|
+
statements.push(generateDropUniqueConstraintSQL(constraint));
|
|
2040
|
+
}
|
|
2041
|
+
for (const constraint of diff.checkConstraints.created) {
|
|
2042
|
+
const isNewTable = diff.tables.created.some((tableName) => {
|
|
2043
|
+
const [schema, table] = tableName.includes(".") ? tableName.split(".") : ["public", tableName];
|
|
2044
|
+
const constraintTable = constraint.table || "";
|
|
2045
|
+
const [constraintSchema, constraintTableName] = constraintTable.includes(".") ? constraintTable.split(".") : ["public", constraintTable];
|
|
2046
|
+
return table === constraintTableName && schema === constraintSchema;
|
|
2047
|
+
});
|
|
2048
|
+
if (!isNewTable) {
|
|
2049
|
+
statements.push(generateCreateCheckConstraintSQL(constraint));
|
|
2110
2050
|
}
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2051
|
+
}
|
|
2052
|
+
for (const constraint of diff.checkConstraints.deleted) {
|
|
2053
|
+
statements.push(generateDropCheckConstraintSQL(constraint));
|
|
2054
|
+
}
|
|
2055
|
+
for (const fk of diff.foreignKeys.deleted) {
|
|
2056
|
+
statements.push(generateDropForeignKeySQL(fk));
|
|
2057
|
+
}
|
|
2058
|
+
for (const alteredFK of diff.foreignKeys.altered) {
|
|
2059
|
+
statements.push(generateDropForeignKeySQL(alteredFK.old));
|
|
2060
|
+
}
|
|
2061
|
+
for (const fk of diff.foreignKeys.created) {
|
|
2062
|
+
const tableFrom = fk.tableFrom || "";
|
|
2063
|
+
const schemaFrom = fk.schemaFrom || "public";
|
|
2064
|
+
const isNewTable = diff.tables.created.some((tableName) => {
|
|
2065
|
+
const [createdSchema, createdTable] = tableName.includes(".") ? tableName.split(".") : ["public", tableName];
|
|
2066
|
+
return createdTable === tableFrom && createdSchema === schemaFrom;
|
|
2067
|
+
});
|
|
2068
|
+
if (!isNewTable) {
|
|
2069
|
+
statements.push(generateCreateForeignKeySQL(fk));
|
|
2122
2070
|
}
|
|
2123
|
-
logger4.info({ src: "plugin:sql", tableCount: Object.keys(tables).length }, "Database introspection complete");
|
|
2124
|
-
return {
|
|
2125
|
-
version: "7",
|
|
2126
|
-
dialect: "postgresql",
|
|
2127
|
-
tables,
|
|
2128
|
-
schemas,
|
|
2129
|
-
enums,
|
|
2130
|
-
_meta: {
|
|
2131
|
-
schemas: {},
|
|
2132
|
-
tables: {},
|
|
2133
|
-
columns: {}
|
|
2134
|
-
}
|
|
2135
|
-
};
|
|
2136
2071
|
}
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
table_schema,
|
|
2140
|
-
table_name
|
|
2141
|
-
FROM information_schema.tables
|
|
2142
|
-
WHERE table_schema = ${schemaName}
|
|
2143
|
-
AND table_type = 'BASE TABLE'
|
|
2144
|
-
ORDER BY table_name`);
|
|
2145
|
-
return getRows2(result);
|
|
2072
|
+
for (const alteredFK of diff.foreignKeys.altered) {
|
|
2073
|
+
statements.push(generateCreateForeignKeySQL(alteredFK.new));
|
|
2146
2074
|
}
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
WHEN a.atttypid = ANY ('{int,int8,int2}'::regtype[])
|
|
2156
|
-
AND EXISTS (
|
|
2157
|
-
SELECT FROM pg_attrdef ad
|
|
2158
|
-
WHERE ad.adrelid = a.attrelid
|
|
2159
|
-
AND ad.adnum = a.attnum
|
|
2160
|
-
AND pg_get_expr(ad.adbin, ad.adrelid) = 'nextval('''
|
|
2161
|
-
|| pg_get_serial_sequence(a.attrelid::regclass::text, a.attname)::regclass || '''::regclass)'
|
|
2162
|
-
)
|
|
2163
|
-
THEN CASE a.atttypid
|
|
2164
|
-
WHEN 'int'::regtype THEN 'serial'
|
|
2165
|
-
WHEN 'int8'::regtype THEN 'bigserial'
|
|
2166
|
-
WHEN 'int2'::regtype THEN 'smallserial'
|
|
2167
|
-
END
|
|
2168
|
-
ELSE format_type(a.atttypid, a.atttypmod)
|
|
2169
|
-
END AS data_type,
|
|
2170
|
-
pg_get_expr(ad.adbin, ad.adrelid) AS column_default,
|
|
2171
|
-
CASE
|
|
2172
|
-
WHEN con.contype = 'p' THEN true
|
|
2173
|
-
ELSE false
|
|
2174
|
-
END AS is_primary
|
|
2175
|
-
FROM pg_attribute a
|
|
2176
|
-
JOIN pg_class cls ON cls.oid = a.attrelid
|
|
2177
|
-
JOIN pg_namespace ns ON ns.oid = cls.relnamespace
|
|
2178
|
-
LEFT JOIN pg_attrdef ad ON ad.adrelid = a.attrelid AND ad.adnum = a.attnum
|
|
2179
|
-
LEFT JOIN pg_constraint con ON con.conrelid = a.attrelid
|
|
2180
|
-
AND a.attnum = ANY(con.conkey)
|
|
2181
|
-
AND con.contype = 'p'
|
|
2182
|
-
WHERE
|
|
2183
|
-
a.attnum > 0
|
|
2184
|
-
AND NOT a.attisdropped
|
|
2185
|
-
AND ns.nspname = ${schemaName}
|
|
2186
|
-
AND cls.relname = ${tableName}
|
|
2187
|
-
ORDER BY a.attnum`);
|
|
2188
|
-
return getRows2(result);
|
|
2075
|
+
return statements;
|
|
2076
|
+
}
|
|
2077
|
+
function generateCreateTableSQL(fullTableName, table) {
|
|
2078
|
+
const [schema, tableName] = fullTableName.includes(".") ? fullTableName.split(".") : ["public", fullTableName];
|
|
2079
|
+
const columns = [];
|
|
2080
|
+
const fkSQLs = [];
|
|
2081
|
+
for (const [colName, colDef] of Object.entries(table.columns || {})) {
|
|
2082
|
+
columns.push(generateColumnDefinition(colName, colDef));
|
|
2189
2083
|
}
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
ARRAY(
|
|
2197
|
-
SELECT a.attname
|
|
2198
|
-
FROM pg_attribute a
|
|
2199
|
-
WHERE a.attrelid = idx.indrelid
|
|
2200
|
-
AND a.attnum = ANY(idx.indkey::int[])
|
|
2201
|
-
ORDER BY a.attnum
|
|
2202
|
-
) AS columns,
|
|
2203
|
-
am.amname AS method
|
|
2204
|
-
FROM pg_index idx
|
|
2205
|
-
JOIN pg_class i ON i.oid = idx.indexrelid
|
|
2206
|
-
JOIN pg_class c ON c.oid = idx.indrelid
|
|
2207
|
-
JOIN pg_namespace n ON n.oid = c.relnamespace
|
|
2208
|
-
JOIN pg_am am ON am.oid = i.relam
|
|
2209
|
-
LEFT JOIN pg_constraint con ON con.conindid = idx.indexrelid
|
|
2210
|
-
WHERE n.nspname = ${schemaName}
|
|
2211
|
-
AND c.relname = ${tableName}`);
|
|
2212
|
-
return getRows2(result);
|
|
2084
|
+
const primaryKeys = table.compositePrimaryKeys || {};
|
|
2085
|
+
for (const [pkName, pkDef] of Object.entries(primaryKeys)) {
|
|
2086
|
+
const pk = pkDef;
|
|
2087
|
+
if (pk.columns && pk.columns.length > 0) {
|
|
2088
|
+
columns.push(`CONSTRAINT "${pkName}" PRIMARY KEY (${pk.columns.map((c) => `"${c}"`).join(", ")})`);
|
|
2089
|
+
}
|
|
2213
2090
|
}
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2091
|
+
const uniqueConstraints = table.uniqueConstraints || {};
|
|
2092
|
+
for (const [uqName, uqDef] of Object.entries(uniqueConstraints)) {
|
|
2093
|
+
const uq = uqDef;
|
|
2094
|
+
if (uq.columns && uq.columns.length > 0) {
|
|
2095
|
+
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(", ")})`;
|
|
2096
|
+
columns.push(uniqueDef);
|
|
2097
|
+
}
|
|
2098
|
+
}
|
|
2099
|
+
const checkConstraints = table.checkConstraints || {};
|
|
2100
|
+
for (const [checkName, checkDef] of Object.entries(checkConstraints)) {
|
|
2101
|
+
const check3 = checkDef;
|
|
2102
|
+
if (check3.value) {
|
|
2103
|
+
columns.push(`CONSTRAINT "${checkName}" CHECK (${check3.value})`);
|
|
2104
|
+
}
|
|
2105
|
+
}
|
|
2106
|
+
const tableSQL = `CREATE TABLE IF NOT EXISTS "${schema}"."${tableName}" (
|
|
2107
|
+
${columns.join(`,
|
|
2108
|
+
`)}
|
|
2109
|
+
);`;
|
|
2110
|
+
const foreignKeys = table.foreignKeys || {};
|
|
2111
|
+
for (const [fkName, fkDef] of Object.entries(foreignKeys)) {
|
|
2112
|
+
const fk = fkDef;
|
|
2113
|
+
const fkSQL = wrapConstraintCreationGuard(fkName, buildCreateForeignKeyBodySQL({
|
|
2114
|
+
...fk,
|
|
2115
|
+
name: fkName,
|
|
2116
|
+
schemaFrom: schema,
|
|
2117
|
+
tableFrom: tableName
|
|
2118
|
+
}));
|
|
2119
|
+
fkSQLs.push(fkSQL);
|
|
2120
|
+
}
|
|
2121
|
+
return { tableSQL, fkSQLs };
|
|
2122
|
+
}
|
|
2123
|
+
function generateColumnDefinition(name, def) {
|
|
2124
|
+
let sql22 = `"${name}" ${def.type}`;
|
|
2125
|
+
if (def.primaryKey && !def.type.includes("SERIAL")) {
|
|
2126
|
+
sql22 += " PRIMARY KEY";
|
|
2127
|
+
}
|
|
2128
|
+
if (def.notNull) {
|
|
2129
|
+
sql22 += " NOT NULL";
|
|
2130
|
+
}
|
|
2131
|
+
if (def.default !== undefined) {
|
|
2132
|
+
const defaultValue = formatDefaultValue(def.default, def.type);
|
|
2133
|
+
sql22 += ` DEFAULT ${defaultValue}`;
|
|
2134
|
+
}
|
|
2135
|
+
return sql22;
|
|
2136
|
+
}
|
|
2137
|
+
function generateAddColumnSQL(table, column, definition) {
|
|
2138
|
+
const [schema, tableName] = table.includes(".") ? table.split(".") : ["public", table];
|
|
2139
|
+
const tableNameWithSchema = `"${schema}"."${tableName}"`;
|
|
2140
|
+
const parts = [`"${column}"`];
|
|
2141
|
+
parts.push(definition.type);
|
|
2142
|
+
if (definition.primaryKey) {
|
|
2143
|
+
parts.push("PRIMARY KEY");
|
|
2144
|
+
}
|
|
2145
|
+
if (definition.default !== undefined) {
|
|
2146
|
+
const defaultValue = formatDefaultValue(definition.default, definition.type);
|
|
2147
|
+
if (defaultValue) {
|
|
2148
|
+
parts.push(`DEFAULT ${defaultValue}`);
|
|
2149
|
+
}
|
|
2150
|
+
}
|
|
2151
|
+
const definitionWithGenerated = definition;
|
|
2152
|
+
if (definitionWithGenerated.generated) {
|
|
2153
|
+
parts.push(`GENERATED ALWAYS AS (${definitionWithGenerated.generated}) STORED`);
|
|
2154
|
+
}
|
|
2155
|
+
if (definition.notNull) {
|
|
2156
|
+
parts.push("NOT NULL");
|
|
2157
|
+
}
|
|
2158
|
+
return `ALTER TABLE ${tableNameWithSchema} ADD COLUMN ${parts.join(" ")};`;
|
|
2159
|
+
}
|
|
2160
|
+
function generateDropColumnSQL(table, column) {
|
|
2161
|
+
const [schema, tableName] = table.includes(".") ? table.split(".") : ["public", table];
|
|
2162
|
+
const tableNameWithSchema = `"${schema}"."${tableName}"`;
|
|
2163
|
+
return `ALTER TABLE ${tableNameWithSchema} DROP COLUMN "${column}" CASCADE;`;
|
|
2164
|
+
}
|
|
2165
|
+
function generateAlterColumnSQL(table, column, changes) {
|
|
2166
|
+
const [schema, tableName] = table.includes(".") ? table.split(".") : ["public", table];
|
|
2167
|
+
const tableNameWithSchema = `"${schema}"."${tableName}"`;
|
|
2168
|
+
const statements = [];
|
|
2169
|
+
const changesTo = changes.to;
|
|
2170
|
+
const changesFrom = changes.from;
|
|
2171
|
+
const changesToType = changesTo?.type;
|
|
2172
|
+
const changesFromType = changesFrom?.type;
|
|
2173
|
+
if (changesToType !== changesFromType) {
|
|
2174
|
+
const newType = changesToType || "TEXT";
|
|
2175
|
+
const needsUsing = checkIfNeedsUsingClause(changesFromType || "", newType);
|
|
2176
|
+
if (needsUsing) {
|
|
2177
|
+
statements.push(`ALTER TABLE ${tableNameWithSchema} ALTER COLUMN "${column}" TYPE ${newType} USING "${column}"::text::${newType};`);
|
|
2178
|
+
} else {
|
|
2179
|
+
statements.push(`ALTER TABLE ${tableNameWithSchema} ALTER COLUMN "${column}" SET DATA TYPE ${newType};`);
|
|
2180
|
+
}
|
|
2248
2181
|
}
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
ORDER BY a.attnum
|
|
2258
|
-
) AS columns
|
|
2259
|
-
FROM pg_constraint con
|
|
2260
|
-
JOIN pg_class rel ON rel.oid = con.conrelid
|
|
2261
|
-
JOIN pg_namespace nsp ON nsp.oid = con.connamespace
|
|
2262
|
-
WHERE con.contype = 'p'
|
|
2263
|
-
AND nsp.nspname = ${schemaName}
|
|
2264
|
-
AND rel.relname = ${tableName}`);
|
|
2265
|
-
return getRows2(result);
|
|
2182
|
+
const changesToNotNull = changesTo?.notNull;
|
|
2183
|
+
const changesFromNotNull = changesFrom?.notNull;
|
|
2184
|
+
if (changesToNotNull !== changesFromNotNull) {
|
|
2185
|
+
if (changesToNotNull) {
|
|
2186
|
+
statements.push(`ALTER TABLE ${tableNameWithSchema} ALTER COLUMN "${column}" SET NOT NULL;`);
|
|
2187
|
+
} else {
|
|
2188
|
+
statements.push(`ALTER TABLE ${tableNameWithSchema} ALTER COLUMN "${column}" DROP NOT NULL;`);
|
|
2189
|
+
}
|
|
2266
2190
|
}
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
) AS columns
|
|
2277
|
-
FROM pg_constraint con
|
|
2278
|
-
JOIN pg_class rel ON rel.oid = con.conrelid
|
|
2279
|
-
JOIN pg_namespace nsp ON nsp.oid = con.connamespace
|
|
2280
|
-
WHERE con.contype = 'u'
|
|
2281
|
-
AND nsp.nspname = ${schemaName}
|
|
2282
|
-
AND rel.relname = ${tableName}`);
|
|
2283
|
-
return getRows2(result);
|
|
2191
|
+
const changesToDefault = changesTo?.default;
|
|
2192
|
+
const changesFromDefault = changesFrom?.default;
|
|
2193
|
+
if (changesToDefault !== changesFromDefault) {
|
|
2194
|
+
if (changesToDefault !== undefined) {
|
|
2195
|
+
const defaultValue = formatDefaultValue(changesToDefault, changesToType || "");
|
|
2196
|
+
statements.push(`ALTER TABLE ${tableNameWithSchema} ALTER COLUMN "${column}" SET DEFAULT ${defaultValue};`);
|
|
2197
|
+
} else {
|
|
2198
|
+
statements.push(`ALTER TABLE ${tableNameWithSchema} ALTER COLUMN "${column}" DROP DEFAULT;`);
|
|
2199
|
+
}
|
|
2284
2200
|
}
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
WHERE con.contype = 'c'
|
|
2293
|
-
AND nsp.nspname = ${schemaName}
|
|
2294
|
-
AND rel.relname = ${tableName}`);
|
|
2295
|
-
return getRows2(result);
|
|
2201
|
+
return statements;
|
|
2202
|
+
}
|
|
2203
|
+
function checkIfNeedsUsingClause(fromType, toType) {
|
|
2204
|
+
if (!fromType || !toType)
|
|
2205
|
+
return false;
|
|
2206
|
+
if (fromType.includes("enum") || toType.includes("enum")) {
|
|
2207
|
+
return true;
|
|
2296
2208
|
}
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
e.enumlabel AS value,
|
|
2302
|
-
e.enumsortorder AS sort_order
|
|
2303
|
-
FROM pg_type t
|
|
2304
|
-
JOIN pg_enum e ON t.oid = e.enumtypid
|
|
2305
|
-
JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace
|
|
2306
|
-
WHERE n.nspname = ${schemaName}
|
|
2307
|
-
ORDER BY schema, name, sort_order`);
|
|
2308
|
-
return getRows2(result);
|
|
2209
|
+
const fromBase = fromType.split("(")[0].toLowerCase();
|
|
2210
|
+
const toBase = toType.split("(")[0].toLowerCase();
|
|
2211
|
+
if ((fromBase === "text" || fromBase === "varchar" || fromBase === "character varying") && (toBase === "jsonb" || toBase === "json")) {
|
|
2212
|
+
return true;
|
|
2309
2213
|
}
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2214
|
+
const needsUsingPairs = [
|
|
2215
|
+
["integer", "boolean"],
|
|
2216
|
+
["boolean", "integer"],
|
|
2217
|
+
["text", "integer"],
|
|
2218
|
+
["text", "numeric"],
|
|
2219
|
+
["text", "boolean"],
|
|
2220
|
+
["text", "uuid"],
|
|
2221
|
+
["text", "jsonb"],
|
|
2222
|
+
["text", "json"],
|
|
2223
|
+
["varchar", "integer"],
|
|
2224
|
+
["varchar", "numeric"],
|
|
2225
|
+
["varchar", "boolean"],
|
|
2226
|
+
["varchar", "uuid"],
|
|
2227
|
+
["varchar", "jsonb"],
|
|
2228
|
+
["varchar", "json"],
|
|
2229
|
+
["character varying", "jsonb"],
|
|
2230
|
+
["character varying", "json"]
|
|
2231
|
+
];
|
|
2232
|
+
for (const [from, to] of needsUsingPairs) {
|
|
2233
|
+
if (fromBase === from && toBase === to || fromBase === to && toBase === from) {
|
|
2234
|
+
return true;
|
|
2316
2235
|
}
|
|
2317
|
-
|
|
2318
|
-
|
|
2236
|
+
}
|
|
2237
|
+
return false;
|
|
2238
|
+
}
|
|
2239
|
+
function formatDefaultValue(value, type) {
|
|
2240
|
+
if (value === null || value === "NULL") {
|
|
2241
|
+
return "NULL";
|
|
2242
|
+
}
|
|
2243
|
+
if (type && (type.toLowerCase().includes("boolean") || type.toLowerCase() === "bool")) {
|
|
2244
|
+
if (value === true || value === "true" || value === "t" || value === 1) {
|
|
2245
|
+
return "true";
|
|
2319
2246
|
}
|
|
2320
|
-
if (
|
|
2321
|
-
|
|
2322
|
-
return "true";
|
|
2323
|
-
if (defaultValue === "false")
|
|
2324
|
-
return "false";
|
|
2247
|
+
if (value === false || value === "false" || value === "f" || value === 0) {
|
|
2248
|
+
return "false";
|
|
2325
2249
|
}
|
|
2326
|
-
return defaultValue;
|
|
2327
2250
|
}
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
const result = await this.db.execute(sql21`SELECT COUNT(*) AS count
|
|
2331
|
-
FROM information_schema.tables
|
|
2332
|
-
WHERE table_schema = ${schemaName}
|
|
2333
|
-
AND table_type = 'BASE TABLE'`);
|
|
2334
|
-
const firstRow = result.rows?.[0];
|
|
2335
|
-
const count = parseInt(firstRow && firstRow.count || "0", 10);
|
|
2336
|
-
return count > 0;
|
|
2251
|
+
if (type?.match(/^(integer|bigint|smallint|numeric|decimal|real|double)/i)) {
|
|
2252
|
+
return String(value);
|
|
2337
2253
|
}
|
|
2338
|
-
|
|
2339
|
-
|
|
2254
|
+
if (typeof value === "string") {
|
|
2255
|
+
if (value.includes("::")) {
|
|
2256
|
+
return value;
|
|
2257
|
+
}
|
|
2258
|
+
if (value.startsWith("'") && value.endsWith("'")) {
|
|
2259
|
+
return value;
|
|
2260
|
+
}
|
|
2261
|
+
if (value.match(/^\w+\(\)/i) || value.includes("(") && value.includes(")")) {
|
|
2262
|
+
return value;
|
|
2263
|
+
}
|
|
2264
|
+
if (value.toUpperCase().startsWith("CURRENT_")) {
|
|
2265
|
+
return value;
|
|
2266
|
+
}
|
|
2267
|
+
return `'${value.replace(/'/g, "''")}'`;
|
|
2340
2268
|
}
|
|
2269
|
+
return String(value);
|
|
2341
2270
|
}
|
|
2342
|
-
|
|
2271
|
+
function generateCreateIndexSQL(index7) {
|
|
2272
|
+
const unique3 = index7.isUnique ? "UNIQUE " : "";
|
|
2273
|
+
const method = index7.method || "btree";
|
|
2274
|
+
const columns = index7.columns.map((c) => {
|
|
2275
|
+
if (c.isExpression) {
|
|
2276
|
+
return c.expression;
|
|
2277
|
+
}
|
|
2278
|
+
return `"${c.expression}"${c.asc === false ? " DESC" : ""}`;
|
|
2279
|
+
}).join(", ");
|
|
2280
|
+
const indexName = index7.name.includes(".") ? index7.name.split(".")[1] : index7.name;
|
|
2281
|
+
let tableRef;
|
|
2282
|
+
const indexTable = index7.table;
|
|
2283
|
+
if (indexTable?.includes(".")) {
|
|
2284
|
+
const [schema, table] = indexTable.split(".");
|
|
2285
|
+
tableRef = `"${schema}"."${table}"`;
|
|
2286
|
+
} else {
|
|
2287
|
+
tableRef = `"${indexTable || ""}"`;
|
|
2288
|
+
}
|
|
2289
|
+
return `CREATE ${unique3}INDEX "${indexName}" ON ${tableRef} USING ${method} (${columns});`;
|
|
2290
|
+
}
|
|
2291
|
+
function generateDropIndexSQL(index7) {
|
|
2292
|
+
const indexNameFull = typeof index7 === "string" ? index7 : index7.name;
|
|
2293
|
+
const indexName = indexNameFull.includes(".") ? indexNameFull.split(".")[1] : indexNameFull;
|
|
2294
|
+
return `DROP INDEX IF EXISTS "${indexName}";`;
|
|
2295
|
+
}
|
|
2296
|
+
function generateCreateForeignKeySQL(fk) {
|
|
2297
|
+
return wrapConstraintCreationGuard(fk.name, buildCreateForeignKeyBodySQL(fk));
|
|
2298
|
+
}
|
|
2299
|
+
function generateDropForeignKeySQL(fk) {
|
|
2300
|
+
const [schema, tableName] = fk.tableFrom ? fk.tableFrom.includes(".") ? fk.tableFrom.split(".") : ["public", fk.tableFrom] : ["public", ""];
|
|
2301
|
+
return `ALTER TABLE "${schema}"."${tableName}" DROP CONSTRAINT "${fk.name}";`;
|
|
2302
|
+
}
|
|
2303
|
+
function generateCreateUniqueConstraintSQL(constraint) {
|
|
2304
|
+
const table = constraint.table || "";
|
|
2305
|
+
const [schema, tableName] = table.includes(".") ? table.split(".") : ["public", table];
|
|
2306
|
+
const name = constraint.name;
|
|
2307
|
+
const columns = constraint.columns.map((c) => `"${c}"`).join(", ");
|
|
2308
|
+
let sql22 = `ALTER TABLE "${schema}"."${tableName}" ADD CONSTRAINT "${name}" UNIQUE`;
|
|
2309
|
+
if (constraint.nullsNotDistinct) {
|
|
2310
|
+
sql22 += ` NULLS NOT DISTINCT`;
|
|
2311
|
+
}
|
|
2312
|
+
sql22 += ` (${columns});`;
|
|
2313
|
+
return sql22;
|
|
2314
|
+
}
|
|
2315
|
+
function generateDropUniqueConstraintSQL(constraint) {
|
|
2316
|
+
const table = constraint.table || "";
|
|
2317
|
+
const [schema, tableName] = table.includes(".") ? table.split(".") : ["public", table];
|
|
2318
|
+
return `ALTER TABLE "${schema}"."${tableName}" DROP CONSTRAINT "${constraint.name}";`;
|
|
2319
|
+
}
|
|
2320
|
+
function generateCreateCheckConstraintSQL(constraint) {
|
|
2321
|
+
const table = constraint.table || "";
|
|
2322
|
+
const [schema, tableName] = table.includes(".") ? table.split(".") : ["public", table];
|
|
2323
|
+
const name = constraint.name;
|
|
2324
|
+
const value = constraint.value;
|
|
2325
|
+
return `ALTER TABLE "${schema}"."${tableName}" ADD CONSTRAINT "${name}" CHECK (${value});`;
|
|
2326
|
+
}
|
|
2327
|
+
function generateDropCheckConstraintSQL(constraint) {
|
|
2328
|
+
const table = constraint.table || "";
|
|
2329
|
+
const [schema, tableName] = table.includes(".") ? table.split(".") : ["public", table];
|
|
2330
|
+
return `ALTER TABLE "${schema}"."${tableName}" DROP CONSTRAINT "${constraint.name}";`;
|
|
2331
|
+
}
|
|
2332
|
+
function buildCreateForeignKeyBodySQL(fk) {
|
|
2333
|
+
const schemaFrom = fk.schemaFrom || "public";
|
|
2334
|
+
const schemaTo = fk.schemaTo || "public";
|
|
2335
|
+
const tableFrom = fk.tableFrom;
|
|
2336
|
+
const columnsFrom = fk.columnsFrom.map((c) => `"${c}"`).join(", ");
|
|
2337
|
+
const columnsTo = fk.columnsTo.map((c) => `"${c}"`).join(", ");
|
|
2338
|
+
let sql22 = `ALTER TABLE "${schemaFrom}"."${tableFrom}" ADD CONSTRAINT "${fk.name}" FOREIGN KEY (${columnsFrom}) REFERENCES "${schemaTo}"."${fk.tableTo}" (${columnsTo})`;
|
|
2339
|
+
if (fk.onDelete) {
|
|
2340
|
+
sql22 += ` ON DELETE ${fk.onDelete}`;
|
|
2341
|
+
}
|
|
2342
|
+
if (fk.onUpdate) {
|
|
2343
|
+
sql22 += ` ON UPDATE ${fk.onUpdate}`;
|
|
2344
|
+
}
|
|
2345
|
+
return sql22;
|
|
2346
|
+
}
|
|
2347
|
+
function wrapConstraintCreationGuard(constraintName, statement) {
|
|
2348
|
+
const escapedConstraintName = constraintName.replace(/'/g, "''");
|
|
2349
|
+
return `DO $$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = '${escapedConstraintName}') THEN ${statement}; END IF; END $$;`;
|
|
2350
|
+
}
|
|
2351
|
+
var init_sql_generator = () => {};
|
|
2343
2352
|
|
|
2344
2353
|
// runtime-migrator/extension-manager.ts
|
|
2345
2354
|
import { logger as logger5 } from "@elizaos/core";
|
|
@@ -3015,14 +3024,10 @@ var init_runtime_migrator = __esm(() => {
|
|
|
3015
3024
|
init_migration_tracker();
|
|
3016
3025
|
init_snapshot_storage();
|
|
3017
3026
|
});
|
|
3027
|
+
|
|
3018
3028
|
// runtime-migrator/index.ts
|
|
3019
3029
|
var init_runtime_migrator2 = __esm(() => {
|
|
3020
|
-
init_snapshot_generator();
|
|
3021
|
-
init_sql_generator();
|
|
3022
3030
|
init_runtime_migrator();
|
|
3023
|
-
init_journal_storage();
|
|
3024
|
-
init_migration_tracker();
|
|
3025
|
-
init_snapshot_storage();
|
|
3026
3031
|
});
|
|
3027
3032
|
|
|
3028
3033
|
// migration-service.ts
|
|
@@ -3162,11 +3167,11 @@ import {
|
|
|
3162
3167
|
or,
|
|
3163
3168
|
sql as sql27
|
|
3164
3169
|
} from "drizzle-orm";
|
|
3165
|
-
//
|
|
3170
|
+
// ../../../node_modules/.bun/uuid@13.0.0/node_modules/uuid/dist/native.js
|
|
3166
3171
|
var randomUUID = typeof crypto !== "undefined" && crypto.randomUUID && crypto.randomUUID.bind(crypto);
|
|
3167
3172
|
var native_default = { randomUUID };
|
|
3168
3173
|
|
|
3169
|
-
//
|
|
3174
|
+
// ../../../node_modules/.bun/uuid@13.0.0/node_modules/uuid/dist/rng.js
|
|
3170
3175
|
var getRandomValues;
|
|
3171
3176
|
var rnds8 = new Uint8Array(16);
|
|
3172
3177
|
function rng() {
|
|
@@ -3179,7 +3184,7 @@ function rng() {
|
|
|
3179
3184
|
return getRandomValues(rnds8);
|
|
3180
3185
|
}
|
|
3181
3186
|
|
|
3182
|
-
//
|
|
3187
|
+
// ../../../node_modules/.bun/uuid@13.0.0/node_modules/uuid/dist/stringify.js
|
|
3183
3188
|
var byteToHex = [];
|
|
3184
3189
|
for (let i = 0;i < 256; ++i) {
|
|
3185
3190
|
byteToHex.push((i + 256).toString(16).slice(1));
|
|
@@ -3188,7 +3193,7 @@ function unsafeStringify(arr, offset = 0) {
|
|
|
3188
3193
|
return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();
|
|
3189
3194
|
}
|
|
3190
3195
|
|
|
3191
|
-
//
|
|
3196
|
+
// ../../../node_modules/.bun/uuid@13.0.0/node_modules/uuid/dist/v4.js
|
|
3192
3197
|
function _v4(options, buf, offset) {
|
|
3193
3198
|
options = options || {};
|
|
3194
3199
|
const rnds = options.random ?? options.rng?.() ?? rng();
|
|
@@ -3688,7 +3693,7 @@ class BaseDrizzleAdapter extends DatabaseAdapter {
|
|
|
3688
3693
|
return [String(names)];
|
|
3689
3694
|
}
|
|
3690
3695
|
isValidUUID(value) {
|
|
3691
|
-
return /^[0-9a-f]{8}-[0-9a-f]{4}-[
|
|
3696
|
+
return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value);
|
|
3692
3697
|
}
|
|
3693
3698
|
normalizeWorldData(world) {
|
|
3694
3699
|
const worldData = {
|
|
@@ -5075,11 +5080,14 @@ class BaseDrizzleAdapter extends DatabaseAdapter {
|
|
|
5075
5080
|
async addParticipant(entityId, roomId) {
|
|
5076
5081
|
return this.withDatabase(async () => {
|
|
5077
5082
|
try {
|
|
5078
|
-
await this.db.
|
|
5079
|
-
|
|
5080
|
-
|
|
5081
|
-
|
|
5082
|
-
|
|
5083
|
+
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);
|
|
5084
|
+
if (existing.length === 0) {
|
|
5085
|
+
await this.db.insert(participantTable).values({
|
|
5086
|
+
entityId,
|
|
5087
|
+
roomId,
|
|
5088
|
+
agentId: this.agentId
|
|
5089
|
+
});
|
|
5090
|
+
}
|
|
5083
5091
|
return true;
|
|
5084
5092
|
} catch (error) {
|
|
5085
5093
|
logger9.error({
|
|
@@ -5096,12 +5104,16 @@ class BaseDrizzleAdapter extends DatabaseAdapter {
|
|
|
5096
5104
|
async addParticipantsRoom(entityIds, roomId) {
|
|
5097
5105
|
return this.withDatabase(async () => {
|
|
5098
5106
|
try {
|
|
5099
|
-
const
|
|
5100
|
-
|
|
5101
|
-
|
|
5102
|
-
|
|
5103
|
-
|
|
5104
|
-
|
|
5107
|
+
for (const id of entityIds) {
|
|
5108
|
+
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);
|
|
5109
|
+
if (existing.length === 0) {
|
|
5110
|
+
await this.db.insert(participantTable).values({
|
|
5111
|
+
entityId: id,
|
|
5112
|
+
roomId,
|
|
5113
|
+
agentId: this.agentId
|
|
5114
|
+
});
|
|
5115
|
+
}
|
|
5116
|
+
}
|
|
5105
5117
|
return true;
|
|
5106
5118
|
} catch (error) {
|
|
5107
5119
|
logger9.error({
|
|
@@ -5251,19 +5263,27 @@ class BaseDrizzleAdapter extends DatabaseAdapter {
|
|
|
5251
5263
|
}
|
|
5252
5264
|
async getRelationships(params) {
|
|
5253
5265
|
return this.withDatabase(async () => {
|
|
5254
|
-
const { entityId, tags } = params;
|
|
5255
|
-
|
|
5266
|
+
const { entityIds: rawEntityIds, entityId, tags, limit, offset } = params;
|
|
5267
|
+
const entityIds = (rawEntityIds && rawEntityIds.length > 0 ? rawEntityIds : entityId ? [entityId] : []).filter((id) => typeof id === "string" && id.trim().length > 0);
|
|
5268
|
+
if (entityIds.length === 0) {
|
|
5269
|
+
return [];
|
|
5270
|
+
}
|
|
5271
|
+
const entityFilter = sql27.join(entityIds.map((id) => sql27`(${relationshipTable.sourceEntityId} = ${id} OR ${relationshipTable.targetEntityId} = ${id})`), sql27` OR `);
|
|
5272
|
+
let query = sql27`
|
|
5273
|
+
SELECT * FROM ${relationshipTable}
|
|
5274
|
+
WHERE (${entityFilter})
|
|
5275
|
+
`;
|
|
5256
5276
|
if (tags && tags.length > 0) {
|
|
5257
5277
|
query = sql27`
|
|
5258
|
-
|
|
5259
|
-
WHERE (${relationshipTable.sourceEntityId} = ${entityId} OR ${relationshipTable.targetEntityId} = ${entityId})
|
|
5278
|
+
${query}
|
|
5260
5279
|
AND ${relationshipTable.tags} && CAST(ARRAY[${sql27.join(tags, sql27`, `)}] AS text[])
|
|
5261
5280
|
`;
|
|
5262
|
-
}
|
|
5263
|
-
|
|
5264
|
-
|
|
5265
|
-
|
|
5266
|
-
|
|
5281
|
+
}
|
|
5282
|
+
if (typeof limit === "number") {
|
|
5283
|
+
query = sql27`${query} LIMIT ${limit}`;
|
|
5284
|
+
}
|
|
5285
|
+
if (typeof offset === "number" && offset > 0) {
|
|
5286
|
+
query = sql27`${query} OFFSET ${offset}`;
|
|
5267
5287
|
}
|
|
5268
5288
|
const result = await this.db.execute(query);
|
|
5269
5289
|
return result.rows.map((relationship) => ({
|
|
@@ -6715,5 +6735,5 @@ export {
|
|
|
6715
6735
|
DatabaseMigrationService
|
|
6716
6736
|
};
|
|
6717
6737
|
|
|
6718
|
-
//# debugId=
|
|
6738
|
+
//# debugId=3F35670A53EFAB1F64756E2164756E21
|
|
6719
6739
|
//# sourceMappingURL=index.browser.js.map
|