Skip to content

Commit 26e081d

Browse files
authored
Merge pull request #1929 from ChabanovX/add-column-exists-check
Add column exists check
2 parents d1dd752 + 5041165 commit 26e081d

File tree

2 files changed

+89
-3
lines changed

2 files changed

+89
-3
lines changed

lib/core/db/db.dart

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,18 +46,44 @@ class Db extends _$Db with InfraLogger {
4646
await m.createTable(schema.geoAssetEntries);
4747
},
4848
from3To4: (m, schema) async {
49-
await m.addColumn(schema.profileEntries, schema.profileEntries.testUrl);
49+
final testUrlExists = await _columnExists(
50+
schema.profileEntries.actualTableName,
51+
schema.profileEntries.testUrl.name,
52+
);
53+
if (!testUrlExists) {
54+
await m.addColumn(schema.profileEntries, schema.profileEntries.testUrl);
55+
}
5056
},
5157
from4To5: (m, schema) async {
5258
await m.deleteTable('geo_asset_entries');
5359
await m.renameColumn(schema.profileEntries, 'test_url', schema.profileEntries.profileOverride);
54-
await m.addColumn(schema.profileEntries, schema.profileEntries.userOverride);
55-
await m.addColumn(schema.profileEntries, schema.profileEntries.populatedHeaders);
60+
61+
final userOverrideExists = await _columnExists(
62+
schema.profileEntries.actualTableName,
63+
schema.profileEntries.userOverride.name,
64+
);
65+
if (!userOverrideExists) {
66+
await m.addColumn(schema.profileEntries, schema.profileEntries.userOverride);
67+
}
68+
69+
final populatedHeadersExists = await _columnExists(
70+
schema.profileEntries.actualTableName,
71+
schema.profileEntries.populatedHeaders.name,
72+
);
73+
if (!populatedHeadersExists) {
74+
await m.addColumn(schema.profileEntries, schema.profileEntries.populatedHeaders);
75+
}
76+
5677
await m.createTable(schema.appProxyEntries);
5778
},
5879
),
5980
);
6081
}
82+
83+
Future<bool> _columnExists(String table, String column) async {
84+
final result = await customSelect('PRAGMA table_info($table);').get();
85+
return result.any((row) => row.data['name'] == column);
86+
}
6187
}
6288

6389
@DataClassName('ProfileEntry')

test/drift/db/migration_test.dart

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import 'generated/schema.dart';
88

99
import 'generated/schema_v1.dart' as v1;
1010
import 'generated/schema_v2.dart' as v2;
11+
import 'generated/schema_v3.dart' as v3;
12+
import 'generated/schema_v4.dart' as v4;
1113

1214
void main() {
1315
driftRuntimeOptions.dontWarnAboutMultipleDatabases = true;
@@ -68,4 +70,62 @@ void main() {
6870
},
6971
);
7072
});
73+
74+
group('_columnExists-backed migrations', () {
75+
test('migration from v3 to v4 adds test_url when missing', () async {
76+
final schema = await verifier.schemaAt(3);
77+
addTearDown(() => schema.rawDatabase.dispose());
78+
79+
final oldDb = v3.DatabaseAtV3(schema.newConnection());
80+
final oldColumns = await oldDb
81+
.customSelect('PRAGMA table_info(profile_entries);')
82+
.get();
83+
84+
expect(
85+
oldColumns.where((row) => row.data['name'] == 'test_url'),
86+
isEmpty,
87+
);
88+
await oldDb.close();
89+
90+
final migratedDb = Db(schema.newConnection());
91+
await verifier.migrateAndValidate(migratedDb, 4);
92+
await migratedDb.close();
93+
94+
final newDb = v4.DatabaseAtV4(schema.newConnection());
95+
final newColumns = await newDb
96+
.customSelect('PRAGMA table_info(profile_entries);')
97+
.get();
98+
expect(
99+
newColumns.where((row) => row.data['name'] == 'test_url'),
100+
hasLength(1),
101+
);
102+
await newDb.close();
103+
});
104+
105+
test(
106+
'migration from v3 to v4 skips adding test_url when it already exists',
107+
() async {
108+
final schema = await verifier.schemaAt(3);
109+
addTearDown(() => schema.rawDatabase.dispose());
110+
111+
schema.rawDatabase.execute(
112+
'ALTER TABLE profile_entries ADD COLUMN test_url TEXT NULL;',
113+
);
114+
115+
final migratedDb = Db(schema.newConnection());
116+
await verifier.migrateAndValidate(migratedDb, 4);
117+
await migratedDb.close();
118+
119+
final newDb = v4.DatabaseAtV4(schema.newConnection());
120+
final newColumns = await newDb
121+
.customSelect('PRAGMA table_info(profile_entries);')
122+
.get();
123+
expect(
124+
newColumns.where((row) => row.data['name'] == 'test_url'),
125+
hasLength(1),
126+
);
127+
await newDb.close();
128+
},
129+
);
130+
});
71131
}

0 commit comments

Comments
 (0)