First experiment on the web using AlaSLQ

This commit is contained in:
Simon Binder 2019-06-20 21:04:22 +02:00
parent d98449407e
commit e23e3ae424
No known key found for this signature in database
GPG Key ID: 7891917E4147B8C0
9 changed files with 185 additions and 0 deletions

11
moor/example_web/.gitignore vendored Normal file
View File

@ -0,0 +1,11 @@
# Files and directories created by pub
.dart_tool/
.packages
# Remove the following pattern if you wish to check in your lock file
pubspec.lock
# Conventional directory for build outputs
build/
# Directory created by dartdoc
doc/api/

View File

@ -0,0 +1 @@
Experimental example for using moor on the web.

View File

@ -0,0 +1,16 @@
name: example_web
description: Experimental usage of moor on the web
environment:
sdk: '>=2.2.0 <3.0.0'
dependencies:
moor: ^1.4.0
dependency_overrides:
moor:
path: ../
dev_dependencies:
build_runner: ^1.1.2
build_web_compilers: ^1.0.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@ -0,0 +1,22 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="scaffolded-by" content="https://github.com/google/stagehand">
<title>example_web</title>
<link rel="stylesheet" href="styles.css">
<link rel="icon" href="favicon.ico">
<script defer src="main.dart.js"></script>
<script defer src="https://cdn.jsdelivr.net/npm/alasql@0.4"></script>
</head>
<body>
<div id="output"></div>
</body>
</html>

View File

@ -0,0 +1,9 @@
import 'package:moor/moor_web.dart';
void main() async {
final executor = AlaSqlDatabase('database');
final result = await executor.doWhenOpened((e) {
return e.runSelect('SELECT 1', const []);
});
print(result);
}

View File

@ -0,0 +1,14 @@
@import url(https://fonts.googleapis.com/css?family=Roboto);
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
font-family: 'Roboto', sans-serif;
}
#output {
padding: 20px;
text-align: center;
}

17
moor/lib/moor_web.dart Normal file
View File

@ -0,0 +1,17 @@
/// A version of moor that runs on the web by using [AlaSQL.js](https://alasql.org/)
/// You manually need to include that library into your website by using
/// ```html
/// <script src="https://cdn.jsdelivr.net/npm/alasql@0.4"></script>
/// ```
@experimental
library moor_web;
import 'dart:async';
import 'dart:html';
import 'dart:js';
import 'package:meta/meta.dart';
import 'moor.dart';
export 'moor.dart';
part 'src/web/alasql.dart';

View File

@ -0,0 +1,95 @@
part of 'package:moor/moor_web.dart';
JsObject _alasql = context['alasql'] as JsObject;
class AlaSqlDatabase extends QueryExecutor {
JsObject _database;
final bool logStatements;
final String name;
Completer<bool> _opening;
AlaSqlDatabase(this.name, {this.logStatements = false}) {
if (_alasql == null) {
throw UnsupportedError('Could not access the alasql javascript library. '
'The moor documentation contains instructions on how to setup moor '
'the web, which might help you fix this.');
}
_database = JsObject(_alasql['Database'] as JsFunction);
}
@override
TransactionExecutor beginTransaction() {
throw StateError('Transactions are not currently supported with AlaSQL');
}
@override
Future<bool> ensureOpen() async {
if (_opening == null) {
_opening = Completer();
await _openInternal();
_opening.complete();
} else {
await _opening.future;
}
return true;
}
Future<void> _openInternal() async {
// todo handle possible injection vulnerability of $name
await _run('CREATE INDEXEDDB DATABASE IF NOT EXISTS `$name`;', const []);
await _run('ATTACH INDEXEDDB DATABASE `$name`;', const []);
await _run('USE `$name`;', const []);
}
@override
Future<void> runBatched(List<BatchedStatement> statements) {
throw StateError(
'Batched statements are not currently supported with AlaSQL');
}
Future<dynamic> _run(String query, List variables) {
JsObject promise;
if (variables.isEmpty) {
promise = _database.callMethod('promise', [query]) as JsObject;
} else {
promise = _database
.callMethod('promise', [query, JsArray.from(variables)]) as JsObject;
}
return promiseToFuture(promise);
}
@override
Future<void> runCustom(String statement) {
_run(statement, const []);
return Future.value();
}
@override
Future<int> runDelete(String statement, List args) {
return Future.value(_run(statement, args) as int);
}
@override
Future<int> runInsert(String statement, List args) {
// todo (needs api change). We need to know the table and column name
// to get the last insert id in AlaSQL. See https://github.com/agershun/alasql/wiki/AUTOINCREMENT
_run(statement, args);
return Future.value(42);
}
@override
Future<List<Map<String, dynamic>>> runSelect(String statement, List args) {
// TODO: implement runSelect
return null;
}
@override
Future<int> runUpdate(String statement, List args) {
return Future.value(_run(statement, args) as int);
}
}