diff --git a/moor/lib/moor_web.dart b/moor/lib/moor_web.dart index d81fde37..f7f824c4 100644 --- a/moor/lib/moor_web.dart +++ b/moor/lib/moor_web.dart @@ -5,6 +5,7 @@ library moor_web; import 'dart:async'; +import 'dart:convert'; import 'dart:html'; import 'dart:indexed_db'; import 'dart:js'; @@ -17,3 +18,4 @@ import 'moor.dart'; export 'moor.dart'; part 'src/web/sql_js.dart'; +part 'src/web/binary_string_conversion.dart'; diff --git a/moor/lib/src/web/binary_string_conversion.dart b/moor/lib/src/web/binary_string_conversion.dart new file mode 100644 index 00000000..4c24413a --- /dev/null +++ b/moor/lib/src/web/binary_string_conversion.dart @@ -0,0 +1,45 @@ +part of 'package:moor/moor_web.dart'; +/* +const _bin2str = _BinaryStringConversion(); + +class _BinaryStringConversion extends Encoding { + const _BinaryStringConversion(); + + @override + Converter, String> get decoder => const _Bin2String(); + + @override + Converter> get encoder => const _String2Bin(); + + @override + String get name => 'bin'; +} + +class _String2Bin extends Converter { + const _String2Bin(); + + @override + Uint8List convert(String input) { + final codeUnits = input.codeUnits; + final list = Uint8List(codeUnits.length); + + for (var i = 0; i < codeUnits.length; i++) { + list[i] = i; + } + return list; + } +} + +class _Bin2String extends Converter, String> { + const _Bin2String(); + + @override + String convert(List input) { + final buffer = StringBuffer(); + for (var byte in input) { + buffer.writeCharCode(byte); + } + return buffer.toString(); + } +} +*/ diff --git a/moor/lib/src/web/sql_js.dart b/moor/lib/src/web/sql_js.dart index 25da348e..3d9087f8 100644 --- a/moor/lib/src/web/sql_js.dart +++ b/moor/lib/src/web/sql_js.dart @@ -79,8 +79,10 @@ class WebDatabase extends QueryExecutor { db.close(); final sql = await _initializedWasm.future; + final restored = _restoreDb(); // var db = new SQL.Database() - _database = JsObject(sql['Database'] as JsFunction); + _database = JsObject(sql['Database'] as JsFunction, + restored != null ? [restored] : const []); assert(() { // set the window.db variable to make debugging easier context['db'] = _database; @@ -99,6 +101,24 @@ class WebDatabase extends QueryExecutor { } } + String get _persistenceKey => 'moor_db_str_$name'; + + // todo base64 works, but is very slow. Figure out why bin2str is broken + + Uint8List _restoreDb() { + final raw = window.localStorage[_persistenceKey]; + if (raw != null) { + return base64.decode(raw); + } + return null; + } + + void _storeDb() { + final data = _database.callMethod('export') as Uint8List; + final binStr = base64.encode(data); + window.localStorage[_persistenceKey] = binStr; + } + @override Future runBatched(List statements) { throw StateError( @@ -141,21 +161,29 @@ class WebDatabase extends QueryExecutor { @override Future runDelete(String statement, List args) { _runSimple(statement, args); - return Future.value(_getModifiedRows()); - } - - @override - Future runInsert(String statement, List args) { - // todo get last insert id -// _runSimple("INSERT INTO todo_entries (content) VALUES ('test')", const []); - _runSimple(statement, args); - return Future.value(42); + return _handlePotentialUpdate(); } @override Future runUpdate(String statement, List args) { _runSimple(statement, args); - return Future.value(_getModifiedRows()); + return _handlePotentialUpdate(); + } + + Future _handlePotentialUpdate() { + final modified = _getModifiedRows(); + if (modified > 0) { + _storeDb(); + } + return Future.value(modified); + } + + @override + Future runInsert(String statement, List args) { + // todo get last insert id + _runSimple(statement, args); + _handlePotentialUpdate(); + return Future.value(42); } @override