Skip to content

Commit

Permalink
nnbd: experiment migration from Map<String, dynamic> to Map<String, O…
Browse files Browse the repository at this point in the history
…bject?>
  • Loading branch information
alextekartik committed Nov 20, 2020
1 parent 1832ec7 commit 844a691
Show file tree
Hide file tree
Showing 39 changed files with 439 additions and 445 deletions.
12 changes: 6 additions & 6 deletions sqflite/README.md
Expand Up @@ -138,8 +138,8 @@ class Todo {
String title;
bool done;
Map<String, dynamic> toMap() {
var map = <String, dynamic>{
Map<String, Object?> toMap() {
var map = <String, Object?>{
columnTitle: title,
columnDone: done == true ? 1 : 0
};
Expand All @@ -151,7 +151,7 @@ class Todo {
Todo();
Todo.fromMap(Map<String, dynamic> map) {
Todo.fromMap(Map<String, Object?> map) {
id = map[columnId];
title = map[columnTitle];
done = map[columnDone] == 1;
Expand Down Expand Up @@ -207,14 +207,14 @@ create table $tableTodo (
Assuming the following read results:

```dart
List<Map<String, dynamic>> records = await db.query('my_table');
List<Map<String, Object?>> records = await db.query('my_table');
```

Resulting map items are read-only

```dart
// get the first record
Map<String, dynamic> mapRead = records.first;
Map<String, Object?> mapRead = records.first;
// Update it in memory...this will throw an exception
mapRead['my_column'] = 1;
// Crash... `mapRead` is read-only
Expand All @@ -224,7 +224,7 @@ You need to create a new map if you want to modify it in memory:

```dart
// get the first record
Map<String, dynamic> map = Map<String, dynamic>.from(mapRead);
Map<String, Object?> map = Map<String, Object?>.from(mapRead);
// Update it in memory now
map['my_column'] = 1;
```
Expand Down
2 changes: 1 addition & 1 deletion sqflite/doc/supported_types.md
@@ -1,6 +1,6 @@
# Supported types

The API offers a way to save a record as map of type `Map<String, dynamic>`. This map cannot be an
The API offers a way to save a record as map of type `Map<String, Object?>`. This map cannot be an
arbitrary map:
- Keys are column in a table (declared when creating the table)
- Values are field values in the record of type `num`, `String` or `Uint8List`
Expand Down
4 changes: 2 additions & 2 deletions sqflite/doc/troubleshooting.md
Expand Up @@ -28,14 +28,14 @@ analyzer:
## Cast error

```
Unhandled exception: type '_InternalLinkedHashMap' is not a subtype of type 'Map<String, dynamic>'
Unhandled exception: type '_InternalLinkedHashMap' is not a subtype of type 'Map<String, Object?>'
where
_InternalLinkedHashMap is from dart:collection
Map is from dart:core
String is from dart:core
```

Make sure you create object of type `Map<String, dynamic>` and not simply `Map` for records you
Make sure you create object of type `Map<String, Object?>` and not simply `Map` for records you
insert and update. The option `implicit-casts: false` explained above helps to find such issues

## MissingPluginException
Expand Down
11 changes: 8 additions & 3 deletions sqflite/example/lib/exception_test_page.dart
Expand Up @@ -23,7 +23,7 @@ class ExceptionTestPage extends TestPage {
try {
await db.transaction((txn) async {
await txn.rawInsert(
'INSERT INTO Test (name) VALUES (?)', <dynamic>['item']);
'INSERT INTO Test (name) VALUES (?)', <Object>['item']);
var afterCount = Sqflite.firstIntValue(
await txn.rawQuery('SELECT COUNT(*) FROM Test'));
expect(afterCount, 1);
Expand Down Expand Up @@ -54,7 +54,7 @@ class ExceptionTestPage extends TestPage {
await db.execute('CREATE TABLE Test (id INTEGER PRIMARY KEY, name TEXT)');

var batch = db.batch();
batch.rawInsert('INSERT INTO Test (name) VALUES (?)', <dynamic>['item']);
batch.rawInsert('INSERT INTO Test (name) VALUES (?)', ['item']);
batch.execute('DUMMY CALL');

var hasFailed = true;
Expand Down Expand Up @@ -99,7 +99,7 @@ class ExceptionTestPage extends TestPage {
}

try {
await db.rawQuery('malformed query with args ?', <dynamic>[1]);
await db.rawQuery('malformed query with args ?', [1]);
fail(); // should fail before
} on DatabaseException catch (e) {
verify(e.isSyntaxError());
Expand Down Expand Up @@ -404,6 +404,9 @@ class ExceptionTestPage extends TestPage {
await db.execute('CREATE TABLE Test (name TEXT)');

//await db.rawInsert("INSERT INTO Test (name) VALUES (\"?\")", [null]);
/*
nnbd this can no longer be tested!
try {
await db.rawInsert('INSERT INTO Test (name) VALUES (?)', [null]);
} on DatabaseException catch (e) {
Expand All @@ -425,6 +428,8 @@ class ExceptionTestPage extends TestPage {
expect(e.toString().contains("sql 'DELETE FROM Test"), true);
}
*/

await db.close();
});

Expand Down
6 changes: 3 additions & 3 deletions sqflite/example/lib/exp_test_page.dart
Expand Up @@ -538,7 +538,7 @@ CREATE TABLE test (
int index = 0;
SendPort sendPort;
List<Map<String, dynamic>> results;
List<Map<String, Object?>> results;
var completer = Completer();
var subscription = receivePort.listen((data) {
switch (index++) {
Expand All @@ -550,7 +550,7 @@ CREATE TABLE test (
break;
case 1:
// second is result
results = data as List<Map<String, dynamic>>;
results = data as List<Map<String, Object?>>;
completer.complete();
break;
}
Expand Down Expand Up @@ -588,7 +588,7 @@ Future simpleInsertQueryIsolate(SendPort sendPort) async {
var db = await openDatabase(path, version: 1, onCreate: (db, version) {
db.execute('CREATE TABLE Test (id INTEGER PRIMARY KEY, name TEXT)');
});
List<Map<String, dynamic>> results;
List<Map<String, Object?>> results;
try {
await insert(db, 2);
results = await db.rawQuery('SELECT id, name FROM Test');
Expand Down
4 changes: 2 additions & 2 deletions sqflite/example/lib/open_test_page.dart
Expand Up @@ -267,7 +267,7 @@ class OpenTestPage extends TestPage {
});
try {
await database
.insert('Test', <String, dynamic>{'id': 1, 'name': 'test'});
.insert('Test', <String, Object?>{'id': 1, 'name': 'test'});
fail('should fail');
} on DatabaseException catch (e) {
print(e);
Expand All @@ -286,7 +286,7 @@ class OpenTestPage extends TestPage {
try {
expect(
await database
.insert('Test', <String, dynamic>{'id': 1, 'name': 'test'}),
.insert('Test', <String, Object?>{'id': 1, 'name': 'test'}),
1);
} finally {
await database.close();
Expand Down
6 changes: 3 additions & 3 deletions sqflite/example/lib/todo_test_page.dart
Expand Up @@ -38,8 +38,8 @@ class Todo {
bool? done;

/// Convert to a record.
Map<String, dynamic> toMap() {
var map = <String, dynamic>{
Map<String, Object?> toMap() {
var map = <String, Object?>{
columnTitle: title,
columnDone: done == true ? 1 : 0
};
Expand Down Expand Up @@ -94,7 +94,7 @@ create table $tableTodo (
/// Update a todo.
Future<int> update(Todo todo) async {
return await db.update(tableTodo, todo.toMap(),
where: '$columnId = ?', whereArgs: [todo.id]);
where: '$columnId = ?', whereArgs: [todo.id!]);
}

/// Close database.
Expand Down
2 changes: 1 addition & 1 deletion sqflite/lib/sqflite.dart
Expand Up @@ -57,7 +57,7 @@ class Sqflite {

/// helper to get the first int value in a query
/// Useful for COUNT(*) queries
static int? firstIntValue(List<Map<String, dynamic>> list) =>
static int? firstIntValue(List<Map<String, Object?>> list) =>
utils.firstIntValue(list);

/// Utility to encode a blob to allow blob query using
Expand Down
20 changes: 10 additions & 10 deletions sqflite/test/sqflite_test.dart
Expand Up @@ -60,25 +60,25 @@ void main() {

test('firstIntValue', () {
expect(
Sqflite.firstIntValue(<Map<String, dynamic>>[
<String, dynamic>{'test': 1}
Sqflite.firstIntValue(<Map<String, Object?>>[
<String, Object?>{'test': 1}
]),
1);
expect(
Sqflite.firstIntValue(<Map<String, dynamic>>[
<String, dynamic>{'test': 1},
<String, dynamic>{'test': 1}
Sqflite.firstIntValue(<Map<String, Object?>>[
<String, Object?>{'test': 1},
<String, Object?>{'test': 1}
]),
1);
expect(
Sqflite.firstIntValue(<Map<String, dynamic>>[
<String, dynamic>{'test': null}
Sqflite.firstIntValue(<Map<String, Object?>>[
<String, Object?>{'test': null}
]),
null);
expect(Sqflite.firstIntValue(<Map<String, dynamic>>[<String, dynamic>{}]),
expect(Sqflite.firstIntValue(<Map<String, Object?>>[<String, Object?>{}]),
isNull);
expect(Sqflite.firstIntValue(<Map<String, dynamic>>[]), isNull);
expect(Sqflite.firstIntValue(<Map<String, dynamic>>[<String, dynamic>{}]),
expect(Sqflite.firstIntValue(<Map<String, Object?>>[]), isNull);
expect(Sqflite.firstIntValue(<Map<String, Object?>>[<String, Object?>{}]),
isNull);
});

Expand Down

0 comments on commit 844a691

Please sign in to comment.