mirror of https://github.com/AMT-Cheif/drift.git
Escape column names during insert
This commit is contained in:
parent
a0ce3421c9
commit
092f64d7cf
|
@ -54,6 +54,7 @@ mixin TableInfo<TableDsl extends Table, D extends DataClass> on Table {
|
||||||
/// The keys should represent the column name in sql, the values the
|
/// The keys should represent the column name in sql, the values the
|
||||||
/// corresponding values of the field. All fields of the [instance] which are
|
/// corresponding values of the field. All fields of the [instance] which are
|
||||||
/// present will be written, absent fields will be omitted.
|
/// present will be written, absent fields will be omitted.
|
||||||
|
/// Note that column names aren't escaped in the [Map.keys].
|
||||||
Map<String, Variable> entityToSql(covariant UpdateCompanion<D> instance);
|
Map<String, Variable> entityToSql(covariant UpdateCompanion<D> instance);
|
||||||
|
|
||||||
/// Maps the given row returned by the database into the fitting data class.
|
/// Maps the given row returned by the database into the fitting data class.
|
||||||
|
|
|
@ -106,9 +106,11 @@ class InsertStatement<D extends DataClass> {
|
||||||
if (map.isEmpty) {
|
if (map.isEmpty) {
|
||||||
ctx.buffer.write('DEFAULT VALUES');
|
ctx.buffer.write('DEFAULT VALUES');
|
||||||
} else {
|
} else {
|
||||||
|
final columns = map.keys.map(escapeIfNeeded);
|
||||||
|
|
||||||
ctx.buffer
|
ctx.buffer
|
||||||
..write('(')
|
..write('(')
|
||||||
..write(map.keys.join(', '))
|
..write(columns.join(', '))
|
||||||
..write(') ')
|
..write(') ')
|
||||||
..write('VALUES (');
|
..write('VALUES (');
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,8 @@ class TableWithoutPK extends Table {
|
||||||
}
|
}
|
||||||
|
|
||||||
class PureDefaults extends Table with AutoIncrement {
|
class PureDefaults extends Table with AutoIncrement {
|
||||||
TextColumn get txt => text().nullable()();
|
// name after keyword to ensure it's escaped properly
|
||||||
|
TextColumn get txt => text().named('insert').nullable()();
|
||||||
}
|
}
|
||||||
|
|
||||||
// example object used for custom mapping
|
// example object used for custom mapping
|
||||||
|
|
|
@ -1165,7 +1165,7 @@ class PureDefault extends DataClass implements Insertable<PureDefault> {
|
||||||
final stringType = db.typeSystem.forDartType<String>();
|
final stringType = db.typeSystem.forDartType<String>();
|
||||||
return PureDefault(
|
return PureDefault(
|
||||||
id: intType.mapFromDatabaseResponse(data['${effectivePrefix}id']),
|
id: intType.mapFromDatabaseResponse(data['${effectivePrefix}id']),
|
||||||
txt: stringType.mapFromDatabaseResponse(data['${effectivePrefix}txt']),
|
txt: stringType.mapFromDatabaseResponse(data['${effectivePrefix}insert']),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
factory PureDefault.fromJson(Map<String, dynamic> json,
|
factory PureDefault.fromJson(Map<String, dynamic> json,
|
||||||
|
@ -1257,7 +1257,7 @@ class $PureDefaultsTable extends PureDefaults
|
||||||
GeneratedTextColumn get txt => _txt ??= _constructTxt();
|
GeneratedTextColumn get txt => _txt ??= _constructTxt();
|
||||||
GeneratedTextColumn _constructTxt() {
|
GeneratedTextColumn _constructTxt() {
|
||||||
return GeneratedTextColumn(
|
return GeneratedTextColumn(
|
||||||
'txt',
|
'insert',
|
||||||
$tableName,
|
$tableName,
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
|
@ -1303,7 +1303,7 @@ class $PureDefaultsTable extends PureDefaults
|
||||||
map['id'] = Variable<int, IntType>(d.id.value);
|
map['id'] = Variable<int, IntType>(d.id.value);
|
||||||
}
|
}
|
||||||
if (d.txt.present) {
|
if (d.txt.present) {
|
||||||
map['txt'] = Variable<String, StringType>(d.txt.value);
|
map['insert'] = Variable<String, StringType>(d.txt.value);
|
||||||
}
|
}
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
|
@ -157,4 +157,13 @@ void main() {
|
||||||
completion(42),
|
completion(42),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('escaped when column name is keyword', () async {
|
||||||
|
await db
|
||||||
|
.into(db.pureDefaults)
|
||||||
|
.insert(PureDefaultsCompanion.insert(txt: const Value('foo')));
|
||||||
|
|
||||||
|
verify(executor
|
||||||
|
.runInsert('INSERT INTO pure_defaults (`insert`) VALUES (?)', ['foo']));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,18 @@ import 'package:moor_generator/src/backends/build/moor_builder.dart';
|
||||||
import 'package:moor_generator/src/writer/database_writer.dart';
|
import 'package:moor_generator/src/writer/database_writer.dart';
|
||||||
import 'package:source_gen/source_gen.dart';
|
import 'package:source_gen/source_gen.dart';
|
||||||
|
|
||||||
|
const _ignoredLints = [
|
||||||
|
'unnecessary_brace_in_string_interps',
|
||||||
|
'unnecessary_this',
|
||||||
|
// more style rules from the Flutter repo we're violating. Should we fix
|
||||||
|
// those?
|
||||||
|
/*
|
||||||
|
'always_specify_types',
|
||||||
|
'implicit_dynamic_parameter',
|
||||||
|
'sort_constructors_first',
|
||||||
|
'lines_longer_than_80_chars',*/
|
||||||
|
];
|
||||||
|
|
||||||
class MoorGenerator extends Generator implements BaseGenerator {
|
class MoorGenerator extends Generator implements BaseGenerator {
|
||||||
@override
|
@override
|
||||||
MoorBuilder builder;
|
MoorBuilder builder;
|
||||||
|
@ -13,8 +25,8 @@ class MoorGenerator extends Generator implements BaseGenerator {
|
||||||
final writer = builder.createWriter();
|
final writer = builder.createWriter();
|
||||||
|
|
||||||
if (parsed.declaredDatabases.isNotEmpty) {
|
if (parsed.declaredDatabases.isNotEmpty) {
|
||||||
writer.leaf().write(
|
final ignore = '// ignore_for_file: ${_ignoredLints.join(', ')}\n';
|
||||||
'// ignore_for_file: unnecessary_brace_in_string_interps, unnecessary_this\n');
|
writer.leaf().write(ignore);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var db in parsed.declaredDatabases) {
|
for (var db in parsed.declaredDatabases) {
|
||||||
|
|
Loading…
Reference in New Issue