diff --git a/moor/lib/src/runtime/query_builder/statements/insert.dart b/moor/lib/src/runtime/query_builder/statements/insert.dart index d9014730..6df7ef4f 100644 --- a/moor/lib/src/runtime/query_builder/statements/insert.dart +++ b/moor/lib/src/runtime/query_builder/statements/insert.dart @@ -96,19 +96,19 @@ class InsertStatement { final rawValues = table.entityToSql(entry.createCompanion(true)); - // strip out null values, apply client defaults where applicable + // apply default values for columns that have one final map = {}; - for (final columnName in rawValues.keys) { - final value = rawValues[columnName]; + for (final column in table.$columns) { + final columnName = column.$name; - if (value != null) { - map[columnName] = value; + if (rawValues.containsKey(columnName)) { + map[columnName] = rawValues[columnName]; } else { - final column = table.columnsByName[columnName]; - if (column.defaultValue != null) { + if (column.clientDefault != null) { map[columnName] = column._evaluateClientDefault(); } } + // column not set, and doesn't have a client default. So just don't // include this column } diff --git a/moor/test/insert_test.dart b/moor/test/insert_test.dart index 69ea6741..d2be92a6 100644 --- a/moor/test/insert_test.dart +++ b/moor/test/insert_test.dart @@ -34,8 +34,8 @@ void main() { verify(executor.runInsert( 'INSERT INTO table_without_p_k ' - '(not_really_an_id, some_float) VALUES (?, ?)', - [42, 3.1415])); + '(not_really_an_id, some_float, custom) VALUES (?, ?, ?)', + [42, 3.1415, anything])); }); test('generates insert or replace statements', () async { @@ -147,7 +147,17 @@ void main() { expect(exception.toString(), startsWith('InvalidDataException')); }); - test('reports auto-increment id', () async { + test("doesn't allow writing null rows", () { + expect( + () { + return db.into(db.todosTable).insert(null); + }, + throwsA(const TypeMatcher().having( + (e) => e.message, 'message', contains('Cannot write null row'))), + ); + }); + + test('reports auto-increment id', () { when(executor.runInsert(any, any)).thenAnswer((_) => Future.value(42)); expect( @@ -158,6 +168,21 @@ void main() { ); }); + test('evaluates client-default functions', () async { + await db.into(db.tableWithoutPK).insert( + TableWithoutPKCompanion.insert(notReallyAnId: 3, someFloat: 3.14)); + + // the client default generates a uuid + final uuidRegex = RegExp( + r'[0-9a-f]{8}\-[0-9a-f]{4}\-[0-9a-f]{4}\-[0-9a-f]{4}\-[0-9a-f]{12}'); + + verify(executor.runInsert( + 'INSERT INTO table_without_p_k (not_really_an_id, some_float, custom) ' + 'VALUES (?, ?, ?)', + [3, 3.14, matches(uuidRegex)], + )); + }); + test('escaped when column name is keyword', () async { await db .into(db.pureDefaults) diff --git a/moor/test/join_test.dart b/moor/test/join_test.dart index f062c6e9..43782d20 100644 --- a/moor/test/join_test.dart +++ b/moor/test/join_test.dart @@ -116,6 +116,37 @@ void main() { argThat(contains('WHERE t.id < ? ORDER BY t.title ASC')), [3])); }); + test('can be watched', () { + final todos = db.alias(db.todosTable, 't'); + final categories = db.alias(db.categories, 'c'); + + final query = db + .select(todos) + .join([innerJoin(categories, todos.category.equalsExp(categories.id))]); + + final stream = query.watch(); + expectLater(stream, emitsInOrder([[], []])); + + db.markTablesUpdated({todos}); + db.markTablesUpdated({categories}); + }); + + test('setting where multiple times forms conjunction', () async { + final todos = db.alias(db.todosTable, 't'); + final categories = db.alias(db.categories, 'c'); + + final query = db + .select(todos) + .join([innerJoin(categories, todos.category.equalsExp(categories.id))]) + ..where(todos.id.isSmallerThanValue(5)) + ..where(categories.id.isBiggerOrEqualValue(10)); + + await query.get(); + + verify(executor + .runSelect(argThat(contains('WHERE t.id < ? AND c.id >= ?')), [5, 10])); + }); + test('supports custom columns and results', () async { final categories = db.alias(db.categories, 'c'); final descriptionLength = categories.description.length;