55// NOTE: We want this tool to be part of the typed_sql package, do not depend
66// on libraries that typed_sql itself wouldn't depend.
77
8- // TODO(https://github.com/google/dart-neats/issues/347): remove this after typed_sql supports automatic snake_case convention
9- // ignore_for_file: non_constant_identifier_names
10-
118import 'dart:convert' ;
129
1310import 'package:crypto/crypto.dart' ;
1411import 'package:typed_sql/typed_sql.dart' ;
1512
1613part 'migration.g.dart' ;
1714
15+ @SqlOverride .schema (naming: .snake_case)
1816abstract final class SchemaMigrationSchema extends Schema {
19- Table <SchemaMigration > get schema_migrations ;
17+ Table <SchemaMigration > get schemaMigrations ;
2018}
2119
22- @PrimaryKey (['schema_name ' , 'script_name ' ])
20+ @PrimaryKey (['schemaName ' , 'scriptName ' ])
2321abstract final class SchemaMigration extends Row {
2422 /// The name of the schema (major group, e.g. `main` , `accounts` ...).
25- String get schema_name ;
23+ String get schemaName ;
2624
2725 /// The name of the script.
28- String get script_name ;
26+ String get scriptName ;
2927
3028 /// The SHA-256 of the script at the time of execution.
31- String get script_sha256 ;
29+ String get scriptSha256 ;
3230
3331 /// The timestamp of the execution.
34- DateTime get executed_at ;
32+ DateTime get executedAt ;
3533}
3634
3735/// Executes migrations [scripts] in alphabetical order into
@@ -47,7 +45,7 @@ Future<void> migrateScripts({
4745
4846 // sanity check on the table, no update attempts
4947 final existingRows = await table
50- .where ((m) => m.schema_name .equalsValue (schemaName))
48+ .where ((m) => m.schemaName .equalsValue (schemaName))
5149 .fetch ();
5250
5351 final hashes = < String , String > {};
@@ -64,27 +62,27 @@ Future<void> migrateScripts({
6462
6563 // check existing row
6664 final existingRow = existingRows
67- .where ((r) => r.script_name == script.name)
65+ .where ((r) => r.scriptName == script.name)
6866 .firstOrNull;
69- if (existingRow != null && existingRow.script_sha256 != hash) {
67+ if (existingRow != null && existingRow.scriptSha256 != hash) {
7068 throw ArgumentError ('Script hash difference detected: `${script .name }`.' );
7169 }
7270 }
7371
7472 // early exit if everything matches
7573 if (scripts.length == existingRows.length &&
76- existingRows.every ((row) => hashes.containsKey (row.script_name ))) {
74+ existingRows.every ((row) => hashes.containsKey (row.scriptName ))) {
7775 return ;
7876 }
7977
8078 // check if all the rows have corresponding scripts
8179 final rowsWithoutScript = existingRows
82- .where ((row) => ! hashes.containsKey (row.script_name ))
80+ .where ((row) => ! hashes.containsKey (row.scriptName ))
8381 .toList ();
8482 if (rowsWithoutScript.isNotEmpty) {
8583 throw ArgumentError (
8684 'Existing history without local files (${rowsWithoutScript .length } items): '
87- '${rowsWithoutScript .take (5 ).map ((row ) => '`${row .script_name }`' ).join (', ' )}' ,
85+ '${rowsWithoutScript .take (5 ).map ((row ) => '`${row .scriptName }`' ).join (', ' )}' ,
8886 );
8987 }
9088
@@ -97,26 +95,24 @@ Future<void> migrateScripts({
9795 // QUESTION: can we scope this with schema prefix so that it is part of the same transaction?
9896 final unexpectedRows = await table
9997 .where ((m) {
100- final mn = m.schema_name .equalsValue (schemaName);
98+ final mn = m.schemaName .equalsValue (schemaName);
10199 if (i == 0 ) {
102100 return mn;
103101 }
104- return mn.and (
105- m.script_name.greaterThan (scripts[i - 1 ].name.asExpr),
106- );
102+ return mn.and (m.scriptName.greaterThan (scripts[i - 1 ].name.asExpr));
107103 })
108- .orderBy ((m) => [(m.script_name , Order .ascending)])
104+ .orderBy ((m) => [(m.scriptName , Order .ascending)])
109105 .fetch ();
110106
111107 if (unexpectedRows.isNotEmpty) {
112108 final first = unexpectedRows.first;
113109 // check race + idempotency, continue migrations with the next script if matching
114- if (first.script_name == script.name && first.script_sha256 == hash) {
110+ if (first.scriptName == script.name && first.scriptSha256 == hash) {
115111 return ;
116112 }
117113 // otherwise abort migrations
118114 throw ArgumentError (
119- 'Incompatible existing history: `${first .script_name }` preceeds `${script .name }`.' ,
115+ 'Incompatible existing history: `${first .scriptName }` preceeds `${script .name }`.' ,
120116 );
121117 }
122118
@@ -126,10 +122,10 @@ Future<void> migrateScripts({
126122 // QUESTION: can we scope this with schema prefix so that it is part of the same transaction?
127123 await table
128124 .insert (
129- schema_name : schemaName.asExpr,
130- script_name : script.name.asExpr,
131- script_sha256 : hash.asExpr,
132- executed_at : Expr .currentTimestamp,
125+ schemaName : schemaName.asExpr,
126+ scriptName : script.name.asExpr,
127+ scriptSha256 : hash.asExpr,
128+ executedAt : Expr .currentTimestamp,
133129 )
134130 .execute ();
135131 });
0 commit comments