Skip to content

Commit 5a638a0

Browse files
committed
Add protocol utilities
1 parent 0b128d2 commit 5a638a0

File tree

2 files changed

+73
-27
lines changed

2 files changed

+73
-27
lines changed

sqlite3_web/lib/protocol_utils.dart

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/// Utilities for encoding sqlite3 types across web message ports.
2+
library;
3+
4+
import 'dart:js_interop';
5+
6+
import 'package:sqlite3/wasm.dart';
7+
import 'src/protocol.dart';
8+
9+
/// Serializes a list of [parameters] compatible with the sqlite3 package into
10+
/// a pair of an [JSArrayBuffer] and a [JSArray].
11+
///
12+
/// The [JSArray] is backwards-compatible with clients calling `toDart` on the
13+
/// array and `dartify()` on the entries.
14+
/// However, the [JSArrayBuffer] provides out-of-band type information about
15+
/// the entries in the array. When one of the communication partners was
16+
/// compiled with dart2wasm, this is useful to tell integers and doubles apart
17+
/// reliably.
18+
(JSArray, JSArrayBuffer) serializeParameters(List<Object?> parameters) {
19+
return TypeCode.encodeValues(parameters);
20+
}
21+
22+
/// Given an array of values and optionally also type information obtained from
23+
/// [serializeParameters], return the parameters.
24+
List<Object?> deserializeParameters(JSArray values, JSArrayBuffer? types) {
25+
return TypeCode.decodeValues(values, types);
26+
}
27+
28+
/// Serializes a [ResultSet] into a serializable [JSObject].
29+
JSObject serializeResultSet(ResultSet resultSet) {
30+
final msg = JSObject();
31+
RowsResponse(resultSet: resultSet, requestId: 0).serialize(msg, []);
32+
return msg;
33+
}
34+
35+
/// Deserializes a result set from the format in [serializeResultSet].
36+
ResultSet deserializeResultSet(JSObject object) {
37+
return RowsResponse.deserialize(object).resultSet;
38+
}

sqlite3_web/lib/src/protocol.dart

Lines changed: 35 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -454,25 +454,14 @@ final class RunQuery extends Request {
454454
});
455455

456456
factory RunQuery.deserialize(JSObject object) {
457-
final rawParameters =
458-
(object[_UniqueFieldNames.parameters] as JSArray).toDart;
459-
final typeVector = switch (object[_UniqueFieldNames.typeVector]) {
460-
final types? => (types as JSArrayBuffer).toDart.asUint8List(),
461-
null => null,
462-
};
463-
464-
final parameters = List<Object?>.filled(rawParameters.length, null);
465-
for (var i = 0; i < parameters.length; i++) {
466-
final typeCode =
467-
typeVector != null ? TypeCode.of(typeVector[i]) : TypeCode.unknown;
468-
parameters[i] = typeCode.decodeColumn(rawParameters[i]);
469-
}
470-
471457
return RunQuery(
472458
requestId: object.requestId,
473459
databaseId: object.databaseId,
474460
sql: (object[_UniqueFieldNames.sql] as JSString).toDart,
475-
parameters: parameters,
461+
parameters: TypeCode.decodeValues(
462+
object[_UniqueFieldNames.parameters] as JSArray,
463+
object[_UniqueFieldNames.typeVector] as JSArrayBuffer?,
464+
),
476465
returnRows: (object[_UniqueFieldNames.returnRows] as JSBoolean).toDart,
477466
);
478467
}
@@ -487,19 +476,11 @@ final class RunQuery extends Request {
487476
object[_UniqueFieldNames.returnRows] = returnRows.toJS;
488477

489478
if (parameters.isNotEmpty) {
490-
final jsParams = <JSAny?>[];
491-
final typeCodes = Uint8List(parameters.length);
492-
for (var i = 0; i < parameters.length; i++) {
493-
final (code, jsParam) = TypeCode.encodeValue(parameters[i]);
494-
typeCodes[i] = code.index;
495-
jsParams.add(jsParam);
496-
}
497-
498-
final jsTypes = typeCodes.buffer.toJS;
499-
transferred.add(jsTypes);
479+
final (array, types) = TypeCode.encodeValues(parameters);
500480

501-
object[_UniqueFieldNames.parameters] = jsParams.toJS;
502-
object[_UniqueFieldNames.typeVector] = jsTypes;
481+
object[_UniqueFieldNames.parameters] = array;
482+
object[_UniqueFieldNames.typeVector] = types;
483+
transferred.add(types);
503484
} else {
504485
object[_UniqueFieldNames.parameters] = JSArray();
505486
}
@@ -660,6 +641,33 @@ enum TypeCode {
660641

661642
return (code, value);
662643
}
644+
645+
static (JSArray, JSArrayBuffer) encodeValues(List<Object?> values) {
646+
final jsParams = <JSAny?>[];
647+
final typeCodes = Uint8List(values.length);
648+
for (var i = 0; i < values.length; i++) {
649+
final (code, jsParam) = TypeCode.encodeValue(values[i]);
650+
typeCodes[i] = code.index;
651+
jsParams.add(jsParam);
652+
}
653+
654+
final jsTypes = typeCodes.buffer.toJS;
655+
return (jsParams.toJS, jsTypes);
656+
}
657+
658+
static List<Object?> decodeValues(JSArray array, JSArrayBuffer? types) {
659+
final rawParameters = array.toDart;
660+
final typeVector = types?.toDart.asUint8List();
661+
662+
final parameters = List<Object?>.filled(rawParameters.length, null);
663+
for (var i = 0; i < parameters.length; i++) {
664+
final typeCode =
665+
typeVector != null ? TypeCode.of(typeVector[i]) : TypeCode.unknown;
666+
parameters[i] = typeCode.decodeColumn(rawParameters[i]);
667+
}
668+
669+
return parameters;
670+
}
663671
}
664672

665673
final class RowsResponse extends Response {

0 commit comments

Comments
 (0)