如何在onUpgrade方法(sqflite)中执行rawquery



我的onUpgrade方法(与sqflite包)中有这段代码。

FutureOr<void> _onUpgrade(Database db, int oldVersion, int newVersion) {
if (oldVersion < 2) {
db.execute(
"ALTER TABLE bookmarks ADD COLUMN expression TEXT;");
var results = db.rawQuery("select * from bookmarks order by bookmark_position asc");
results.forEach((row) {  //error on forEach statement
db.execute(...specific query... involving parts of this row);
});
}

但是,我有forEach上的错误:&;静态方法'forEach'不能通过实例访问。&;;

那么我怎么能做到这一点:在onMigrate中执行一个查询,然后,对于我的结果的每一行,执行UPDATE sql来迁移一些数据。

编辑

下面是我的类的完整代码:
import 'dart:async';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path_provider/path_provider.dart';
class Db {
static const _dbName = 'db.db';
static final _dbVersion = 1;
Db._internal();
static final Db instance = Db._internal();
static Database _db;
factory Db() {
return instance;
}
Future<Database> get db async {
if (_db != null) return _db;
_db = await _initDatabase();
return _db;
}
Future<Database> _initDatabase() async {
String path =
join((await getApplicationDocumentsDirectory()).path, _dbName);
return await openDatabase(
path,
version: _dbVersion,
onCreate: _onCreate,
onUpgrade: _onUpgrade,
);
}
FutureOr<void> _onCreate(Database db, int version) {
db.execute('''
CREATE TABLE bookmarks (
bookmark_id INTEGER PRIMARY KEY,
bookmark TEXT,
bookmark_position INTEGER
);''');
db.execute(
"CREATE UNIQUE INDEX bookmark_idx ON bookmarks(bookmark_position);");
}
FutureOr<void> _onUpgrade(Database db, int oldVersion, int newVersion) {
if (oldVersion < 2) {
db.execute(
"ALTER TABLE bookmarks ADD COLUMN expression TEXT;");
//migrate expression stored in "bookmark" into expression
//then transform this expression into http://google...

//I cannot put await before db.rawQuery...
var results = db.rawQuery("select * from bookmarks order by bookmark_position asc"); 
results.forEach((row) {
//manipulating row here BUT PROBLEM
//Static method 'forEach' can't be accessed through an instance.
});
}
}
}

您应该等待所有数据库操作。不建议使用forEach,因为无法等待。

未测试的代码解决方案(或找到解决方案的提示):

FutureOr<void> _onUpgrade(Database db, int oldVersion, int newVersion) async {
if (oldVersion < 2) {
await db.execute(
"ALTER TABLE bookmarks ADD COLUMN expression TEXT;");
var results = await db.rawQuery("select * from bookmarks order by bookmark_position asc");
for (var row in results) {
await db.execute(...specific query... involving parts of this row);
}
}
}

@alextk的答案更好,但是,在Android Studio为我生成的功能(FutureOr…)的背景下,下面的解决方案有效:

我使用了then语法,因为rawQuery返回Future:

FutureOr<void> _onUpgrade(Database db, int oldVersion, int newVersion) {
if (oldVersion < 2) {
final results = db.rawQuery("select * from bookmarks");
results.then((value) => {
value.forEach((row) {
final title = row['bookmark'].toString().toLowerCase();
if (!(title.startsWith('http://') ||
title.startsWith('https://'))) {
final url =
'https://www.google.com/search?q=${Uri.encodeComponent(row['bookmark'])}';
db.execute(
'update bookmarks set expression = ?, bookmark = ? where bookmark_id = ?',
[title, url, row['bookmark_id']]);
}
})
});
}
}

最新更新