diff --git a/docs/pubspec.yaml b/docs/pubspec.yaml index 9d99359c..fa1b2e30 100644 --- a/docs/pubspec.yaml +++ b/docs/pubspec.yaml @@ -6,6 +6,8 @@ environment: sdk: '>=2.15.0 <3.0.0' dependencies: + json_annotation: ^4.5.0 + json_serializable: ^6.2.0 docsy: hosted: https://simonbinder.eu version: ^0.2.2 diff --git a/drift/test/generated/todos.g.dart b/drift/test/generated/todos.g.dart index c76968cf..8cfa3936 100644 --- a/drift/test/generated/todos.g.dart +++ b/drift/test/generated/todos.g.dart @@ -37,7 +37,7 @@ class Category extends DataClass implements Insertable { map['desc'] = Variable(description); { final converter = $CategoriesTable.$converter0; - map['priority'] = Variable(converter.toSql(priority)!); + map['priority'] = Variable(converter.toSql(priority)); } return map; } @@ -162,7 +162,7 @@ class CategoriesCompanion extends UpdateCompanion { } if (priority.present) { final converter = $CategoriesTable.$converter0; - map['priority'] = Variable(converter.toSql(priority.value)!); + map['priority'] = Variable(converter.toSql(priority.value)); } return map; } @@ -1109,7 +1109,7 @@ class TableWithoutPKCompanion extends UpdateCompanion { } if (custom.present) { final converter = $TableWithoutPKTable.$converter0; - map['custom'] = Variable(converter.toSql(custom.value)!); + map['custom'] = Variable(converter.toSql(custom.value)); } return map; } @@ -1689,7 +1689,7 @@ abstract class _$TodoDb extends GeneratedDatabase { readsFrom: { tableWithoutPK, }).map((QueryRow row) => - $TableWithoutPKTable.$converter0.fromSql(row.read('custom'))!); + $TableWithoutPKTable.$converter0.fromSql(row.read('custom'))); } @override diff --git a/drift_dev/lib/src/analyzer/options.dart b/drift_dev/lib/src/analyzer/options.dart index 1bdb74e0..a20e7fff 100644 --- a/drift_dev/lib/src/analyzer/options.dart +++ b/drift_dev/lib/src/analyzer/options.dart @@ -203,7 +203,7 @@ class DialectOptions { @JsonSerializable() class SqliteAnalysisOptions { - @JsonKey(name: 'modules', defaultValue: []) + @JsonKey(name: 'modules') final List modules; @JsonKey(fromJson: _parseSqliteVersion) diff --git a/drift_dev/lib/src/analyzer/options.g.dart b/drift_dev/lib/src/analyzer/options.g.dart index ac5ab90b..427b7a52 100644 --- a/drift_dev/lib/src/analyzer/options.g.dart +++ b/drift_dev/lib/src/analyzer/options.g.dart @@ -164,7 +164,7 @@ SqliteAnalysisOptions _$SqliteAnalysisOptionsFromJson(Map json) => (v as List?) ?.map((e) => $enumDecode(_$SqlModuleEnumMap, e)) .toList() ?? - []), + const []), version: $checkedConvert( 'version', (v) => _parseSqliteVersion(v as String?)), ); diff --git a/drift_dev/lib/src/writer/queries/query_writer.dart b/drift_dev/lib/src/writer/queries/query_writer.dart index c75d115a..50ee5558 100644 --- a/drift_dev/lib/src/writer/queries/query_writer.dart +++ b/drift_dev/lib/src/writer/queries/query_writer.dart @@ -183,12 +183,8 @@ class QueryWriter { var code = 'row.read<$rawDartType>($dartLiteral)'; if (column.typeConverter != null) { - final nullableDartType = column.typeConverter!.mapsToNullableDart; - final needsAssert = !nullableDartType && generationOptions.nnbd; - final converter = column.typeConverter; code = '${_converter(converter!)}.fromSql($code)'; - if (needsAssert) code += '!'; } return code; } diff --git a/drift_dev/lib/src/writer/tables/data_class_writer.dart b/drift_dev/lib/src/writer/tables/data_class_writer.dart index 1294dc56..f934a8d3 100644 --- a/drift_dev/lib/src/writer/tables/data_class_writer.dart +++ b/drift_dev/lib/src/writer/tables/data_class_writer.dart @@ -269,8 +269,9 @@ class DataClassWriter { // apply type converter before writing the variable final converter = column.typeConverter; final fieldName = converter!.tableAndField; - final assertNotNull = !column.nullable && scope.generationOptions.nnbd; - + final assertNotNull = !column.nullable && + converter.sqlTypeIsNullable && + scope.generationOptions.nnbd; _buffer ..write('final converter = $fieldName;\n') ..write(mapSetter) diff --git a/drift_dev/lib/src/writer/tables/update_companion_writer.dart b/drift_dev/lib/src/writer/tables/update_companion_writer.dart index c9cc95b5..60edbd0d 100644 --- a/drift_dev/lib/src/writer/tables/update_companion_writer.dart +++ b/drift_dev/lib/src/writer/tables/update_companion_writer.dart @@ -194,7 +194,9 @@ class UpdateCompanionWriter { ..write(mapSetter) ..write('(converter.toSql($getterName.value)'); - if (!column.nullable && scope.generationOptions.nnbd) { + if (!column.nullable && + converter.sqlTypeIsNullable && + scope.generationOptions.nnbd) { _buffer.write('!'); } _buffer.write(');'); diff --git a/drift_dev/pubspec.yaml b/drift_dev/pubspec.yaml index 5e08f7f2..5d0b07e2 100644 --- a/drift_dev/pubspec.yaml +++ b/drift_dev/pubspec.yaml @@ -14,7 +14,7 @@ dependencies: recase: '>=2.0.1 <5.0.0' meta: ^1.1.0 path: ^1.6.0 - json_annotation: ^4.1.0 + json_annotation: ^4.5.0 stream_transform: '>=0.1.0 <3.0.0' # CLI @@ -49,7 +49,7 @@ dev_dependencies: test_descriptor: ^2.0.0 build_runner: ^2.0.0 build_test: ^2.0.0 - json_serializable: ^6.1.3 + json_serializable: ^6.2.0 # Used to test the migration from moor to drift moor: any diff --git a/examples/app/lib/database/database.g.dart b/examples/app/lib/database/database.g.dart index 269a967f..d45f97c7 100644 --- a/examples/app/lib/database/database.g.dart +++ b/examples/app/lib/database/database.g.dart @@ -10,8 +10,8 @@ part of 'database.dart'; class Category extends DataClass implements Insertable { final int id; final String name; - final Color color; - Category({required this.id, required this.name, required this.color}); + final Color? color; + Category({required this.id, required this.name, this.color}); factory Category.fromData(Map data, {String? prefix}) { final effectivePrefix = prefix ?? ''; return Category( @@ -20,7 +20,7 @@ class Category extends DataClass implements Insertable { name: const StringType() .mapFromDatabaseResponse(data['${effectivePrefix}name'])!, color: $CategoriesTable.$converter0.fromSql(const IntType() - .mapFromDatabaseResponse(data['${effectivePrefix}color']))!, + .mapFromDatabaseResponse(data['${effectivePrefix}color'])!), ); } @override @@ -49,7 +49,7 @@ class Category extends DataClass implements Insertable { return Category( id: serializer.fromJson(json['id']), name: serializer.fromJson(json['name']), - color: serializer.fromJson(json['color']), + color: serializer.fromJson(json['color']), ); } @override @@ -58,14 +58,18 @@ class Category extends DataClass implements Insertable { return { 'id': serializer.toJson(id), 'name': serializer.toJson(name), - 'color': serializer.toJson(color), + 'color': serializer.toJson(color), }; } - Category copyWith({int? id, String? name, Color? color}) => Category( + Category copyWith( + {int? id, + String? name, + Value color = const Value.absent()}) => + Category( id: id ?? this.id, name: name ?? this.name, - color: color ?? this.color, + color: color.present ? color.value : this.color, ); @override String toString() { @@ -91,7 +95,7 @@ class Category extends DataClass implements Insertable { class CategoriesCompanion extends UpdateCompanion { final Value id; final Value name; - final Value color; + final Value color; const CategoriesCompanion({ this.id = const Value.absent(), this.name = const Value.absent(), @@ -100,13 +104,13 @@ class CategoriesCompanion extends UpdateCompanion { CategoriesCompanion.insert({ this.id = const Value.absent(), required String name, - required Color color, + required Color? color, }) : name = Value(name), color = Value(color); static Insertable custom({ Expression? id, Expression? name, - Expression? color, + Expression? color, }) { return RawValuesInsertable({ if (id != null) 'id': id, @@ -116,7 +120,7 @@ class CategoriesCompanion extends UpdateCompanion { } CategoriesCompanion copyWith( - {Value? id, Value? name, Value? color}) { + {Value? id, Value? name, Value? color}) { return CategoriesCompanion( id: id ?? this.id, name: name ?? this.name, @@ -171,10 +175,10 @@ class $CategoriesTable extends Categories type: const StringType(), requiredDuringInsert: true); final VerificationMeta _colorMeta = const VerificationMeta('color'); @override - late final GeneratedColumnWithTypeConverter color = + late final GeneratedColumnWithTypeConverter color = GeneratedColumn('color', aliasedName, false, type: const IntType(), requiredDuringInsert: true) - .withConverter($CategoriesTable.$converter0); + .withConverter($CategoriesTable.$converter0); @override List get $columns => [id, name, color]; @override @@ -212,7 +216,7 @@ class $CategoriesTable extends Categories return $CategoriesTable(attachedDatabase, alias); } - static TypeConverter $converter0 = const ColorConverter(); + static TypeConverter $converter0 = const ColorConverter(); } class TodoEntry extends DataClass implements Insertable { diff --git a/examples/app/lib/screens/home/drawer.dart b/examples/app/lib/screens/home/drawer.dart index 336e01c4..67657feb 100644 --- a/examples/app/lib/screens/home/drawer.dart +++ b/examples/app/lib/screens/home/drawer.dart @@ -69,7 +69,7 @@ class _CategoryDrawerEntry extends ConsumerWidget { padding: const EdgeInsets.only(right: 10), child: GestureDetector( onTap: () async { - final newColor = await _selectColor(context, category.color); + final newColor = await _selectColor(context, category.color!); if (newColor != null) { final update = ref .read(AppDatabase.provider) diff --git a/examples/flutter_web_worker_example/lib/src/database/database.g.dart b/examples/flutter_web_worker_example/lib/src/database/database.g.dart index fd151ea6..36129483 100644 --- a/examples/flutter_web_worker_example/lib/src/database/database.g.dart +++ b/examples/flutter_web_worker_example/lib/src/database/database.g.dart @@ -166,8 +166,6 @@ class Entries extends Table with TableInfo { @override Set get $primaryKey => {id}; @override - List> get uniqueKeys => []; - @override Entrie map(Map data, {String? tablePrefix}) { return Entrie.fromData(data, prefix: tablePrefix != null ? '$tablePrefix.' : null); diff --git a/examples/with_built_value/lib/database.drift.dart b/examples/with_built_value/lib/database.drift.dart index a70dbf61..416a3df8 100644 --- a/examples/with_built_value/lib/database.drift.dart +++ b/examples/with_built_value/lib/database.drift.dart @@ -171,8 +171,6 @@ class Users extends Table with TableInfo { @override Set get $primaryKey => {id}; @override - List> get uniqueKeys => []; - @override User map(Map data, {String tablePrefix}) { return User.fromData(data, prefix: tablePrefix != null ? '$tablePrefix.' : null); diff --git a/examples/with_built_value/lib/database.g.dart b/examples/with_built_value/lib/database.g.dart index 3ca7cd9c..0471981e 100644 --- a/examples/with_built_value/lib/database.g.dart +++ b/examples/with_built_value/lib/database.g.dart @@ -11,10 +11,10 @@ class _$Foo extends Foo { final User moorField; factory _$Foo([void Function(FooBuilder) updates]) => - (new FooBuilder()..update(updates)).build(); + (new FooBuilder()..update(updates))._build(); _$Foo._({this.moorField}) : super._() { - BuiltValueNullFieldError.checkNotNull(moorField, 'Foo', 'moorField'); + BuiltValueNullFieldError.checkNotNull(moorField, r'Foo', 'moorField'); } @override @@ -37,7 +37,7 @@ class _$Foo extends Foo { @override String toString() { - return (newBuiltValueToStringHelper('Foo')..add('moorField', moorField)) + return (newBuiltValueToStringHelper(r'Foo')..add('moorField', moorField)) .toString(); } } @@ -72,14 +72,16 @@ class FooBuilder implements Builder { } @override - _$Foo build() { + Foo build() => _build(); + + _$Foo _build() { final _$result = _$v ?? new _$Foo._( moorField: BuiltValueNullFieldError.checkNotNull( - moorField, 'Foo', 'moorField')); + moorField, r'Foo', 'moorField')); replace(_$result); return _$result; } } -// ignore_for_file: always_put_control_body_on_new_line,always_specify_types,annotate_overrides,avoid_annotating_with_dynamic,avoid_as,avoid_catches_without_on_clauses,avoid_returning_this,deprecated_member_use_from_same_package,lines_longer_than_80_chars,omit_local_variable_types,prefer_expression_function_bodies,sort_constructors_first,test_types_in_equals,unnecessary_const,unnecessary_new +// ignore_for_file: always_put_control_body_on_new_line,always_specify_types,annotate_overrides,avoid_annotating_with_dynamic,avoid_as,avoid_catches_without_on_clauses,avoid_returning_this,deprecated_member_use_from_same_package,lines_longer_than_80_chars,no_leading_underscores_for_local_identifiers,omit_local_variable_types,prefer_expression_function_bodies,sort_constructors_first,test_types_in_equals,unnecessary_const,unnecessary_new,unnecessary_lambdas diff --git a/extras/benchmarks/lib/src/moor/database.g.dart b/extras/benchmarks/lib/src/moor/database.g.dart index a52e95e2..f551dd8d 100644 --- a/extras/benchmarks/lib/src/moor/database.g.dart +++ b/extras/benchmarks/lib/src/moor/database.g.dart @@ -6,7 +6,7 @@ part of 'database.dart'; // MoorGenerator // ************************************************************************** -// ignore_for_file: unnecessary_brace_in_string_interps, unnecessary_this +// ignore_for_file: type=lint class KeyValue extends DataClass implements Insertable { final String key; final String value; @@ -169,8 +169,6 @@ class $KeyValuesTable extends KeyValues @override Set get $primaryKey => {key}; @override - List> get uniqueKeys => []; - @override KeyValue map(Map data, {String? tablePrefix}) { return KeyValue.fromData(data, prefix: tablePrefix != null ? '$tablePrefix.' : null); diff --git a/extras/integration_tests/drift_testcases/build.yaml b/extras/integration_tests/drift_testcases/build.yaml new file mode 100644 index 00000000..9e6ddfa6 --- /dev/null +++ b/extras/integration_tests/drift_testcases/build.yaml @@ -0,0 +1,14 @@ +targets: + $default: + builders: + drift_dev: + options: + override_hash_and_equals_in_result_sets: true + generate_connect_constructor: true + sql: + dialect: sqlite + options: + version: "3.37" + modules: + - json1 + - fts5 \ No newline at end of file diff --git a/extras/integration_tests/drift_testcases/lib/database/database.g.dart b/extras/integration_tests/drift_testcases/lib/database/database.g.dart index 5700f756..c5188b12 100644 --- a/extras/integration_tests/drift_testcases/lib/database/database.g.dart +++ b/extras/integration_tests/drift_testcases/lib/database/database.g.dart @@ -549,7 +549,7 @@ abstract class _$Database extends GeneratedDatabase { late final $FriendshipsTable friendships = $FriendshipsTable(this); Selectable mostPopularUsers(int amount) { return customSelect( - 'SELECT * FROM users AS u ORDER BY (SELECT COUNT(*) FROM friendships WHERE first_user = u.id OR second_user = u.id) DESC LIMIT @1', + 'SELECT * FROM users u ORDER BY (SELECT COUNT(*) FROM friendships WHERE first_user = u.id OR second_user = u.id) DESC LIMIT :amount', variables: [ Variable(amount) ], @@ -561,18 +561,18 @@ abstract class _$Database extends GeneratedDatabase { Selectable amountOfGoodFriends(int user) { return customSelect( - 'SELECT COUNT(*) AS _c0 FROM friendships AS f WHERE f.really_good_friends = 1 AND(f.first_user = @1 OR f.second_user = @1)', + 'SELECT COUNT(*) FROM friendships f WHERE f.really_good_friends = 1 AND (f.first_user = :user OR f.second_user = :user)', variables: [ Variable(user) ], readsFrom: { friendships, - }).map((QueryRow row) => row.read('_c0')); + }).map((QueryRow row) => row.read('COUNT(*)')); } Selectable friendshipsOf(int user) { return customSelect( - 'SELECT f.really_good_friends,"user"."id" AS "nested_0.id", "user"."name" AS "nested_0.name", "user"."birth_date" AS "nested_0.birth_date", "user"."profile_picture" AS "nested_0.profile_picture", "user"."preferences" AS "nested_0.preferences" FROM friendships AS f INNER JOIN users AS "user" ON "user".id IN (f.first_user, f.second_user) AND "user".id != @1 WHERE(f.first_user = @1 OR f.second_user = @1)', + 'SELECT\n f.really_good_friends, "user"."id" AS "nested_0.id", "user"."name" AS "nested_0.name", "user"."birth_date" AS "nested_0.birth_date", "user"."profile_picture" AS "nested_0.profile_picture", "user"."preferences" AS "nested_0.preferences"\n FROM friendships f\n INNER JOIN users "user" ON "user".id IN (f.first_user, f.second_user) AND\n "user".id != :user\n WHERE (f.first_user = :user OR f.second_user = :user)', variables: [ Variable(user) ], @@ -588,15 +588,15 @@ abstract class _$Database extends GeneratedDatabase { } Selectable userCount() { - return customSelect('SELECT COUNT(id) AS _c0 FROM users', + return customSelect('SELECT COUNT(id) FROM users', variables: [], readsFrom: { users, - }).map((QueryRow row) => row.read('_c0')); + }).map((QueryRow row) => row.read('COUNT(id)')); } Selectable settingsFor(int user) { - return customSelect('SELECT preferences FROM users WHERE id = @1', + return customSelect('SELECT preferences FROM users WHERE id = :user', variables: [ Variable(user) ], @@ -621,7 +621,7 @@ abstract class _$Database extends GeneratedDatabase { Future> returning(int var1, int var2, bool var3) { return customWriteReturning( - 'INSERT INTO friendships VALUES (@1, @2, @3) RETURNING *', + 'INSERT INTO friendships VALUES (?, ?, ?) RETURNING *;', variables: [ Variable(var1), Variable(var2), diff --git a/extras/integration_tests/web/pubspec.yaml b/extras/integration_tests/web/pubspec.yaml index d0687366..834b41f6 100644 --- a/extras/integration_tests/web/pubspec.yaml +++ b/extras/integration_tests/web/pubspec.yaml @@ -1,7 +1,7 @@ name: web description: Run integration tests for Moor on the web environment: - sdk: '>=2.4.0 <3.0.0' + sdk: '>=2.6.0 <3.0.0' dependencies: drift: diff --git a/extras/integration_tests/web/test/saves_after_migration_regression_test.g.dart b/extras/integration_tests/web/test/saves_after_migration_regression_test.g.dart index 6700f642..899c60af 100644 --- a/extras/integration_tests/web/test/saves_after_migration_regression_test.g.dart +++ b/extras/integration_tests/web/test/saves_after_migration_regression_test.g.dart @@ -6,7 +6,7 @@ part of 'saves_after_migration_regression_test.dart'; // MoorGenerator // ************************************************************************** -// ignore_for_file: unnecessary_brace_in_string_interps, unnecessary_this +// ignore_for_file: type=lint class Foo extends DataClass implements Insertable { final int id; Foo({@required this.id}); @@ -137,8 +137,6 @@ class $FoosTable extends Foos with TableInfo<$FoosTable, Foo> { @override Set get $primaryKey => {id}; @override - List> get uniqueKeys => []; - @override Foo map(Map data, {String tablePrefix}) { return Foo.fromData(data, prefix: tablePrefix != null ? '$tablePrefix.' : null); @@ -280,8 +278,6 @@ class $BarsTable extends Bars with TableInfo<$BarsTable, Bar> { @override Set get $primaryKey => {id}; @override - List> get uniqueKeys => []; - @override Bar map(Map data, {String tablePrefix}) { return Bar.fromData(data, prefix: tablePrefix != null ? '$tablePrefix.' : null); diff --git a/tool/generate_all.sh b/tool/generate_all.sh index ab4bc78a..0893a2f8 100755 --- a/tool/generate_all.sh +++ b/tool/generate_all.sh @@ -1,20 +1,24 @@ #!/bin/bash set -e -echo "- Generate drift" -(cd ../drift && rm -rf .dart_tool && dart pub get && dart run build_runner build --delete-conflicting-outputs) -echo "- Generate docs" -(cd ../docs && rm -rf .dart_tool && dart pub get && dart run build_runner build --delete-conflicting-outputs) -echo "- Generate benchmarks" -(cd ../extras/benchmarks && rm -rf .dart_tool && dart pub get && dart run build_runner build --delete-conflicting-outputs) -echo "- Generate integration_tests/tests" -(cd ../extras/integration_tests/tests && rm -rf .dart_tool && dart pub get && dart run build_runner build --delete-conflicting-outputs) -echo "- Generate integration_tests/web" -(cd ../extras/integration_tests/web && rm -rf .dart_tool && dart pub get && dart run build_runner build --delete-conflicting-outputs) -echo "- Generate migrations_example" -(cd ../extras/migrations_example && rm -rf .dart_tool && dart pub get && dart run build_runner build --delete-conflicting-outputs) -echo "- Generate web_worker_example" -(cd ../extras/web_worker_example && rm -rf .dart_tool && dart pub get && dart run build_runner build --delete-conflicting-outputs) -echo "- Generate with_built_value" -(cd ../extras/with_built_value && rm -rf .dart_tool && dart pub get && dart run build_runner build --delete-conflicting-outputs) -echo "- Generate flutter_web_worker_example" -(cd ../extras/flutter_web_worker_example && rm -rf .dart_tool && dart pub get && dart run build_runner build --delete-conflicting-outputs) + +function generate() { + echo "------------- Generate: $1 -------------" + pushd $1 > /dev/null + rm -rf .dart_tool + dart pub get + dart run build_runner build --delete-conflicting-outputs + popd > /dev/null +} + +cd .. +generate 'drift' +generate 'drift_dev' +generate 'docs' +generate 'extras/benchmarks' +generate 'extras/integration_tests/drift_testcases' +generate 'extras/integration_tests/web' +generate 'examples/app' +generate 'examples/flutter_web_worker_example' +generate 'examples/migrations_example' +generate 'examples/web_worker_example' +generate 'examples/with_built_value' \ No newline at end of file diff --git a/tool/misc_integration_test.sh b/tool/misc_integration_test.sh old mode 100755 new mode 100644 diff --git a/tool/test_all.sh b/tool/test_all.sh index 04963dc0..1305d765 100755 --- a/tool/test_all.sh +++ b/tool/test_all.sh @@ -1,27 +1,43 @@ #!/bin/bash set -e -cd ../drift -rm -rf .dart_tool -dart pub get -dart format -o none --set-exit-if-changed . -dart analyze --fatal-infos --fatal-warnings -dart run build_runner build --delete-conflicting-outputs -dart test -dart test -p chrome -cd ../drift_dev -rm -rf .dart_tool -dart pub get -dart format -o none --set-exit-if-changed . -dart analyze --fatal-infos --fatal-warnings -dart test +function run_test() { + echo "------------- Running test: $1 -------------" + pushd $1 > /dev/null + rm -rf .dart_tool + dart pub get + dart format -o none --set-exit-if-changed . + dart analyze --fatal-infos --fatal-warnings + if [[ "$2" == 'vm+web' ]]; then + dart test + dart test -p chrome + elif [[ "$2" == 'web-only' ]]; then + dart test -p chrome + else + dart test + fi + popd > /dev/null +} -cd ../sqlparser -rm -rf .dart_tool -dart pub get -dart format -o none --set-exit-if-changed . -dart analyze --fatal-infos --fatal-warnings -dart test +function run_test_flutter() { + echo "------------- Running flutter test: $1 -------------" + pushd $1 > /dev/null + rm -rf .dart_tool + flutter pub get + flutter clean + dart format -o none --set-exit-if-changed . + flutter analyze --fatal-infos --fatal-warnings + flutter test $2 + popd > /dev/null +} cd .. -./tool/misc_integration_test.sh +run_test 'drift' 'vm+web' +run_test 'drift_dev' +run_test 'sqlparser' +run_test_flutter 'drift_sqflite' 'integration_test' +run_test_flutter 'examples/app' +run_test 'examples/migrations_example' +run_test_flutter 'extras/integration_tests/ffi_on_flutter' 'integration_test/drift_native.dart' +run_test 'extras/integration_tests/web' 'web-only' +#run_test 'extras/drift_postgres' \ No newline at end of file