@@ -474,14 +474,75 @@ class WasmDatabaseEngine implements DatabaseOperations {
474474 await this . executeQuery ( sql , validIds ) ;
475475 }
476476
477+ /**
478+ * Find indexes that depend on specific columns.
479+ *
480+ * @param table - Table name
481+ * @param columns - Column names to check
482+ * @returns Array of index names that reference any of the columns
483+ */
484+ async findDependentIndexes ( table : string , columns : string [ ] ) : Promise < string [ ] > {
485+ const dependentIndexes : string [ ] = [ ] ;
486+
487+ // Query sqlite_master for indexes on this table
488+ const indexQuery = `
489+ SELECT name, sql FROM sqlite_master
490+ WHERE type = 'index'
491+ AND tbl_name = ?
492+ AND sql IS NOT NULL
493+ ` ;
494+ const indexResult = await this . executeQuery ( indexQuery , [ table ] ) ;
495+
496+ if ( indexResult . length > 0 && indexResult [ 0 ] . rows ) {
497+ for ( const row of indexResult [ 0 ] . rows ) {
498+ const indexName = row [ 0 ] as string ;
499+ const indexSql = row [ 1 ] as string ;
500+
501+ // Check if this index references any of the columns
502+ const referencesColumn = columns . some ( col => {
503+ const colLower = col . toLowerCase ( ) ;
504+ // Match column name in index definition (quoted or unquoted)
505+ const patterns = [
506+ new RegExp ( `[\\(,]\\s*${ colLower } \\s*[\\),]` , 'i' ) ,
507+ new RegExp ( `[\\(,]\\s*"${ colLower } "\\s*[\\),]` , 'i' ) ,
508+ new RegExp ( `[\\(,]\\s*\\[${ colLower } \\]\\s*[\\),]` , 'i' ) ,
509+ new RegExp ( `[\\(,]\\s*\`${ colLower } \`\\s*[\\),]` , 'i' )
510+ ] ;
511+ return patterns . some ( p => p . test ( indexSql ) ) ;
512+ } ) ;
513+
514+ if ( referencesColumn ) {
515+ dependentIndexes . push ( indexName ) ;
516+ }
517+ }
518+ }
519+
520+ return dependentIndexes ;
521+ }
522+
477523 /**
478524 * Delete columns by name.
525+ *
526+ * If dropDependentIndexes is provided, those indexes will be dropped first.
527+ * Otherwise, deletion may fail if indexes reference the columns.
528+ *
529+ * @param table - Table name
530+ * @param columns - Column names to delete
531+ * @param dropDependentIndexes - Optional list of indexes to drop first
479532 */
480- async deleteColumns ( table : string , columns : string [ ] ) : Promise < void > {
533+ async deleteColumns ( table : string , columns : string [ ] , dropDependentIndexes ?: string [ ] ) : Promise < void > {
481534 if ( columns . length === 0 ) return ;
482535
483536 const escapedTable = escapeIdentifier ( table ) ;
484537
538+ // Drop specified dependent indexes first
539+ if ( dropDependentIndexes && dropDependentIndexes . length > 0 ) {
540+ for ( const indexName of dropDependentIndexes ) {
541+ await this . executeQuery ( `DROP INDEX IF EXISTS ${ escapeIdentifier ( indexName ) } ` ) ;
542+ }
543+ }
544+
545+ // Now drop the columns
485546 for ( const col of columns ) {
486547 const sql = `ALTER TABLE ${ escapedTable } DROP COLUMN ${ escapeIdentifier ( col ) } ` ;
487548 await this . executeQuery ( sql ) ;
@@ -967,9 +1028,14 @@ export function createWorkerEndpoint() {
9671028 return activeEngine . deleteRows ( table , rowIds ) ;
9681029 } ,
9691030
970- async deleteColumns ( table : string , columns : string [ ] ) : Promise < void > {
1031+ async deleteColumns ( table : string , columns : string [ ] , dropDependentIndexes ?: string [ ] ) : Promise < void > {
1032+ if ( ! activeEngine ) throw new Error ( 'No database initialized' ) ;
1033+ return activeEngine . deleteColumns ( table , columns , dropDependentIndexes ) ;
1034+ } ,
1035+
1036+ async findDependentIndexes ( table : string , columns : string [ ] ) : Promise < string [ ] > {
9711037 if ( ! activeEngine ) throw new Error ( 'No database initialized' ) ;
972- return activeEngine . deleteColumns ( table , columns ) ;
1038+ return activeEngine . findDependentIndexes ( table , columns ) ;
9731039 } ,
9741040
9751041 async createTable ( table : string , columns : ColumnDefinition [ ] ) : Promise < void > {
0 commit comments