Fix (and then, use) the binary encoding to persist data

This commit is contained in:
Simon Binder 2019-07-10 19:14:55 +02:00
parent 02a8dabd63
commit 91c455d077
No known key found for this signature in database
GPG Key ID: 7891917E4147B8C0
5 changed files with 72 additions and 21 deletions

View File

@ -187,10 +187,39 @@ class $TodoEntriesTable extends TodoEntries
}
}
class HiddenEntryCountResult {
final int entries;
HiddenEntryCountResult({
this.entries,
});
}
abstract class _$Database extends GeneratedDatabase {
_$Database(QueryExecutor e) : super(const SqlTypeSystem.withDefaults(), e);
$TodoEntriesTable _todoEntries;
$TodoEntriesTable get todoEntries => _todoEntries ??= $TodoEntriesTable(this);
HiddenEntryCountResult _rowToHiddenEntryCountResult(QueryRow row) {
return HiddenEntryCountResult(
entries: row.readInt('entries'),
);
}
Future<List<HiddenEntryCountResult>> hiddenEntryCount(
{@Deprecated('No longer needed with Moor 1.6 - see the changelog for details')
QueryEngine operateOn}) {
return (operateOn ?? this).customSelect(
'SELECT COUNT(*) - 20 AS entries FROM todo_entries WHERE done',
variables: []).then((rows) => rows.map(_rowToHiddenEntryCountResult).toList());
}
Stream<List<HiddenEntryCountResult>> watchHiddenEntryCount() {
return customSelectStream(
'SELECT COUNT(*) - 20 AS entries FROM todo_entries WHERE done',
variables: [],
readsFrom: {todoEntries})
.map((rows) => rows.map(_rowToHiddenEntryCountResult).toList());
}
@override
List<TableInfo> get allTables => [todoEntries];
}

View File

@ -5,7 +5,6 @@
library moor_web;
import 'dart:async';
import 'dart:convert';
import 'dart:html';
import 'package:meta/meta.dart';
@ -13,9 +12,9 @@ import 'package:meta/dart2js.dart';
import 'package:synchronized/synchronized.dart';
import 'moor.dart';
import 'src/web/binary_string_conversion.dart';
import 'src/web/sql_js.dart';
export 'moor.dart';
part 'src/web/binary_string_conversion.dart';
part 'src/web/web_db.dart';

View File

@ -1,18 +1,19 @@
part of 'package:moor/moor_web.dart';
/*
const _bin2str = _BinaryStringConversion();
import 'dart:convert';
import 'dart:math' as math;
import 'dart:typed_data';
class _BinaryStringConversion extends Encoding {
/// Converts [Uint8List]s to binary strings. Used internally by moor to store
/// a database inside `window.localStorage`.
const bin2str = _BinaryStringConversion();
class _BinaryStringConversion extends Codec<Uint8List, String> {
const _BinaryStringConversion();
@override
Converter<List<int>, String> get decoder => const _Bin2String();
Converter<String, Uint8List> get decoder => const _String2Bin();
@override
Converter<String, List<int>> get encoder => const _String2Bin();
@override
String get name => 'bin';
Converter<Uint8List, String> get encoder => const _Bin2String();
}
class _String2Bin extends Converter<String, Uint8List> {
@ -24,22 +25,28 @@ class _String2Bin extends Converter<String, Uint8List> {
final list = Uint8List(codeUnits.length);
for (var i = 0; i < codeUnits.length; i++) {
list[i] = i;
list[i] = codeUnits[i];
}
return list;
}
}
class _Bin2String extends Converter<List<int>, String> {
class _Bin2String extends Converter<Uint8List, String> {
const _Bin2String();
// There is a browser limit on the amount of chars one can give to
// String.fromCharCodes https://github.com/kripken/sql.js/wiki/Persisting-a-Modified-Database#save-a-database-to-a-string
final int _chunkSize = 0xffff;
@override
String convert(List<int> input) {
String convert(Uint8List input) {
final buffer = StringBuffer();
for (var byte in input) {
buffer.writeCharCode(byte);
for (var pos = 0; pos < input.length; pos += _chunkSize) {
final endPos = math.min(pos + _chunkSize, input.length);
buffer.write(String.fromCharCodes(input.sublist(pos, endPos)));
}
return buffer.toString();
}
}
*/

View File

@ -33,19 +33,17 @@ abstract class _DatabaseUser extends QueryExecutor {
return await lock.synchronized(computation);
}
// 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 bin2str.decode(raw);
}
return null;
}
void _storeDb() {
final data = _db.export();
final binStr = base64.encode(data);
final binStr = bin2str.encode(data);
window.localStorage[_persistenceKey] = binStr;
}

View File

@ -0,0 +1,18 @@
import 'dart:typed_data';
import 'package:moor/src/web/binary_string_conversion.dart';
import 'package:test_api/test_api.dart';
void main() {
final data = Uint8List(256 * 2);
for (var i = 0; i < 256; i++) {
data[i] = i % 256;
}
test('converts binary data from and to strings', () {
final asStr = bin2str.encode(data);
final backToBin = bin2str.decode(asStr);
expect(backToBin, data);
});
}