Some kind of select statements with result parsing

This commit is contained in:
Simon Binder 2019-06-24 20:06:59 +02:00
parent e23e3ae424
commit 65ccd49d9a
No known key found for this signature in database
GPG Key ID: 7891917E4147B8C0
3 changed files with 83 additions and 13 deletions

View File

@ -1,7 +1,20 @@
import 'package:moor/moor_web.dart'; import 'package:moor/moor_web.dart';
class TestDb extends GeneratedDatabase {
TestDb(QueryExecutor executor)
: super(const SqlTypeSystem.withDefaults(), executor);
@override
List<TableInfo<Table, DataClass>> get allTables => const [];
@override
int get schemaVersion => 1;
}
void main() async { void main() async {
final executor = AlaSqlDatabase('database'); final executor = AlaSqlDatabase('database');
executor.databaseInfo = TestDb(executor);
final result = await executor.doWhenOpened((e) { final result = await executor.doWhenOpened((e) {
return e.runSelect('SELECT 1', const []); return e.runSelect('SELECT 1', const []);
}); });

View File

@ -7,9 +7,13 @@
library moor_web; library moor_web;
import 'dart:async'; import 'dart:async';
import 'dart:convert' show json;
import 'dart:html'; import 'dart:html';
import 'dart:indexed_db';
import 'dart:js'; import 'dart:js';
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
import 'moor.dart'; import 'moor.dart';
export 'moor.dart'; export 'moor.dart';

View File

@ -1,6 +1,7 @@
part of 'package:moor/moor_web.dart'; part of 'package:moor/moor_web.dart';
JsObject _alasql = context['alasql'] as JsObject; JsObject _alasql = context['alasql'] as JsObject;
JsFunction _jsonStringify = context['JSON']['stringify'] as JsFunction;
class AlaSqlDatabase extends QueryExecutor { class AlaSqlDatabase extends QueryExecutor {
JsObject _database; JsObject _database;
@ -38,10 +39,40 @@ class AlaSqlDatabase extends QueryExecutor {
} }
Future<void> _openInternal() async { Future<void> _openInternal() async {
// AlaSQL doesn't give us any information about the schema version, so we
// first need to access the database without AlaSQL to find that out
if (!IdbFactory.supported) {
throw UnsupportedError("This browser doesn't support IndexedDb");
}
int version;
var upgradeNeeded = false;
final db = await window.indexedDB.open(
name,
version: databaseInfo.schemaVersion,
onUpgradeNeeded: (event) {
upgradeNeeded = true;
version = event.oldVersion;
},
);
db.close();
// todo handle possible injection vulnerability of $name // todo handle possible injection vulnerability of $name
await _run('CREATE INDEXEDDB DATABASE IF NOT EXISTS `$name`;', const []); await _run('CREATE INDEXEDDB DATABASE IF NOT EXISTS `$name`;', const []);
await _run('ATTACH INDEXEDDB DATABASE `$name`;', const []); await _run('ATTACH INDEXEDDB DATABASE `$name`;', const []);
await _run('USE `$name`;', const []); await _run('USE `$name`;', const []);
if (upgradeNeeded) {
if (version == null || version < 1) {
await databaseInfo.handleDatabaseCreation(executor: _runWithoutArgs);
} else {
await databaseInfo.handleDatabaseVersionChange(
executor: _runWithoutArgs,
from: version,
to: databaseInfo.schemaVersion);
}
}
} }
@override @override
@ -50,21 +81,33 @@ class AlaSqlDatabase extends QueryExecutor {
'Batched statements are not currently supported with AlaSQL'); 'Batched statements are not currently supported with AlaSQL');
} }
Future<dynamic> _run(String query, List variables) { Future<dynamic> _runWithoutArgs(String query) {
JsObject promise; return _run(query, const []);
if (variables.isEmpty) { }
promise = _database.callMethod('promise', [query]) as JsObject;
} else {
promise = _database
.callMethod('promise', [query, JsArray.from(variables)]) as JsObject;
}
return promiseToFuture(promise); Future<dynamic> _run(String query, List variables) {
final completer = Completer<dynamic>();
final args = [
query,
JsArray.from(variables),
allowInterop((data, error) {
if (error != null) {
completer.completeError(error);
} else {
completer.complete(data);
}
})
];
_database.callMethod('exec', args);
return completer.future;
} }
@override @override
Future<void> runCustom(String statement) { Future<void> runCustom(String statement) {
_run(statement, const []); _runWithoutArgs(statement);
return Future.value(); return Future.value();
} }
@ -83,9 +126,19 @@ class AlaSqlDatabase extends QueryExecutor {
} }
@override @override
Future<List<Map<String, dynamic>>> runSelect(String statement, List args) { Future<List<Map<String, dynamic>>> runSelect(
// TODO: implement runSelect String statement, List args) async {
return null; final result = await _run(statement, args) as JsArray;
return result.map((row) {
final jsRow = row as JsObject;
// todo this is a desperate attempt at converting the JsObject to a Map.
// Surely, there must be a better way to do this?
final objJson = _jsonStringify.apply([jsRow]) as String;
final dartMap = json.decode(objJson);
return dartMap as Map<String, dynamic>;
}).toList();
} }
@override @override