Merge pull request #1929 from ChabanovX/add-column-exists-check

Add column exists check
This commit is contained in:
Hiddify
2026-02-22 12:08:17 +01:00
committed by GitHub
2 changed files with 89 additions and 3 deletions
+29 -3
View File
@@ -46,18 +46,44 @@ class Db extends _$Db with InfraLogger {
await m.createTable(schema.geoAssetEntries);
},
from3To4: (m, schema) async {
await m.addColumn(schema.profileEntries, schema.profileEntries.testUrl);
final testUrlExists = await _columnExists(
schema.profileEntries.actualTableName,
schema.profileEntries.testUrl.name,
);
if (!testUrlExists) {
await m.addColumn(schema.profileEntries, schema.profileEntries.testUrl);
}
},
from4To5: (m, schema) async {
await m.deleteTable('geo_asset_entries');
await m.renameColumn(schema.profileEntries, 'test_url', schema.profileEntries.profileOverride);
await m.addColumn(schema.profileEntries, schema.profileEntries.userOverride);
await m.addColumn(schema.profileEntries, schema.profileEntries.populatedHeaders);
final userOverrideExists = await _columnExists(
schema.profileEntries.actualTableName,
schema.profileEntries.userOverride.name,
);
if (!userOverrideExists) {
await m.addColumn(schema.profileEntries, schema.profileEntries.userOverride);
}
final populatedHeadersExists = await _columnExists(
schema.profileEntries.actualTableName,
schema.profileEntries.populatedHeaders.name,
);
if (!populatedHeadersExists) {
await m.addColumn(schema.profileEntries, schema.profileEntries.populatedHeaders);
}
await m.createTable(schema.appProxyEntries);
},
),
);
}
Future<bool> _columnExists(String table, String column) async {
final result = await customSelect('PRAGMA table_info($table);').get();
return result.any((row) => row.data['name'] == column);
}
}
@DataClassName('ProfileEntry')
+60
View File
@@ -8,6 +8,8 @@ import 'generated/schema.dart';
import 'generated/schema_v1.dart' as v1;
import 'generated/schema_v2.dart' as v2;
import 'generated/schema_v3.dart' as v3;
import 'generated/schema_v4.dart' as v4;
void main() {
driftRuntimeOptions.dontWarnAboutMultipleDatabases = true;
@@ -68,4 +70,62 @@ void main() {
},
);
});
group('_columnExists-backed migrations', () {
test('migration from v3 to v4 adds test_url when missing', () async {
final schema = await verifier.schemaAt(3);
addTearDown(() => schema.rawDatabase.dispose());
final oldDb = v3.DatabaseAtV3(schema.newConnection());
final oldColumns = await oldDb
.customSelect('PRAGMA table_info(profile_entries);')
.get();
expect(
oldColumns.where((row) => row.data['name'] == 'test_url'),
isEmpty,
);
await oldDb.close();
final migratedDb = Db(schema.newConnection());
await verifier.migrateAndValidate(migratedDb, 4);
await migratedDb.close();
final newDb = v4.DatabaseAtV4(schema.newConnection());
final newColumns = await newDb
.customSelect('PRAGMA table_info(profile_entries);')
.get();
expect(
newColumns.where((row) => row.data['name'] == 'test_url'),
hasLength(1),
);
await newDb.close();
});
test(
'migration from v3 to v4 skips adding test_url when it already exists',
() async {
final schema = await verifier.schemaAt(3);
addTearDown(() => schema.rawDatabase.dispose());
schema.rawDatabase.execute(
'ALTER TABLE profile_entries ADD COLUMN test_url TEXT NULL;',
);
final migratedDb = Db(schema.newConnection());
await verifier.migrateAndValidate(migratedDb, 4);
await migratedDb.close();
final newDb = v4.DatabaseAtV4(schema.newConnection());
final newColumns = await newDb
.customSelect('PRAGMA table_info(profile_entries);')
.get();
expect(
newColumns.where((row) => row.data['name'] == 'test_url'),
hasLength(1),
);
await newDb.close();
},
);
});
}