@@ -13,42 +13,21 @@ import TableProPluginKit
1313// MARK: - Schema Changes
1414
1515extension DatabaseManager {
16- /// Execute schema changes (ALTER TABLE, CREATE INDEX, etc.) in a transaction of their own,
16+ /// Execute schema statements (ALTER TABLE, CREATE INDEX, etc.) in a transaction of their own,
1717 /// on the schema change route rather than the session driver a query tab may have left
1818 /// mid-transaction. The connection, database and schema all come from the editing tab's
1919 /// own scope, never from ambient session state that another window or tab can move.
2020 ///
21- /// Authorization sits between two scoped blocks rather than inside one : it awaits a
22- /// confirmation sheet and Touch ID, and holding the connection's driver gate across a
23- /// human prompt would freeze every other tab on that connection.
21+ /// Authorization sits outside the scoped block : it awaits a confirmation sheet and Touch ID,
22+ /// and holding the connection's driver gate across a human prompt would freeze every other
23+ /// tab on that connection.
2424 func executeSchemaChanges(
25- tableName: String ,
26- changes: [ SchemaChange ] ,
25+ _ statements: [ SchemaStatement ] ,
2726 databaseType: DatabaseType ,
2827 scope: DatabaseScope
2928 ) async throws {
3029 let route = schemaChangeRoute ( for: scope)
3130
32- let statements = try await withScopedDriver (
33- scope: scope, route: route, cancellation: . untracked
34- ) { driver in
35- let pkConstraintName = await Self . fetchPrimaryKeyConstraintName (
36- tableName: tableName,
37- databaseType: databaseType,
38- changes: changes,
39- driver: driver
40- )
41- guard let resolvedPluginDriver = ( driver as? PluginDriverAdapter ) ? . schemaPluginDriver else {
42- throw DatabaseError . unsupportedOperation
43- }
44- let generator = SchemaStatementGenerator (
45- tableName: tableName,
46- primaryKeyConstraintName: pkConstraintName,
47- pluginDriver: resolvedPluginDriver
48- )
49- return try generator. generate ( changes: changes)
50- }
51-
5231 let combinedSQL = statements. map ( \. sql) . joined ( separator: " \n " )
5332 let schemaKind : OperationKind =
5433 QueryClassifier . classifyTier ( combinedSQL, databaseType: databaseType) == . destructive
@@ -229,59 +208,4 @@ extension DatabaseManager {
229208 . changed( CatalogChange ( connectionId: scope. connectionId, database: scope. database, kinds: . tables) )
230209 )
231210 }
232-
233- /// Query the actual primary key constraint name for PostgreSQL.
234- /// Returns nil if the database is not PostgreSQL, no PK modification is pending,
235- /// or the query fails (caller falls back to `{table}_pkey` convention).
236- private static func fetchPrimaryKeyConstraintName(
237- tableName: String ,
238- databaseType: DatabaseType ,
239- changes: [ SchemaChange ] ,
240- driver: DatabaseDriver
241- ) async -> String ? {
242- // Only needed for PostgreSQL PK modifications
243- guard databaseType == . postgresql || databaseType == . redshift
244- || databaseType == . cockroachdb || databaseType == . duckdb else { return nil }
245- guard
246- changes. contains ( where: {
247- if case . modifyPrimaryKey = $0 { return true }
248- return false
249- } )
250- else {
251- return nil
252- }
253-
254- let escapedTable = tableName. replacingOccurrences ( of: " ' " , with: " '' " )
255- let schema : String
256- if let schemaDriver = driver as? SchemaSwitchable ,
257- let escaped = schemaDriver. escapedSchema {
258- schema = escaped
259- } else {
260- schema = " public "
261- }
262- let query = """
263- SELECT con.conname
264- FROM pg_constraint con
265- JOIN pg_class rel ON rel.oid = con.conrelid
266- JOIN pg_namespace nsp ON nsp.oid = rel.relnamespace
267- WHERE rel.relname = ' \( escapedTable) '
268- AND nsp.nspname = ' \( schema) '
269- AND con.contype = 'p'
270- LIMIT 1
271- """
272-
273- do {
274- let result = try await driver. execute ( query: query)
275- if let row = result. rows. first, let name = row [ 0 ] . asText, !name. isEmpty {
276- return name
277- }
278- } catch {
279- // Query failed - fall back to convention in SchemaStatementGenerator
280- Self . logger. warning (
281- " Failed to query PK constraint name for ' \( tableName) ': \( error. localizedDescription) "
282- )
283- }
284-
285- return nil
286- }
287211}
0 commit comments