From c5d998211b1c59a0af997cc9d7539a5e3b3fcb95 Mon Sep 17 00:00:00 2001 From: gcxfd Date: Wed, 26 May 2021 10:32:18 +0800 Subject: [PATCH 1/3] use Uint8List instead of List --- sqlite3/lib/src/api/functions.dart | 2 +- sqlite3/lib/src/ffi/ffi.dart | 4 ++-- sqlite3/lib/src/ffi/memory.dart | 2 +- sqlite3/lib/src/impl/statement.dart | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/sqlite3/lib/src/api/functions.dart b/sqlite3/lib/src/api/functions.dart index b41bd910..4c0a0d02 100644 --- a/sqlite3/lib/src/api/functions.dart +++ b/sqlite3/lib/src/api/functions.dart @@ -3,7 +3,7 @@ import 'package:meta/meta.dart'; /// A scalar function exposed to sql. /// /// {@template sqlite3_function_behavior} -/// The function must either return a `bool`, `num`, `String`, `List` or +/// The function must either return a `bool`, `num`, `String`, `Uint8List` or /// `null`. /// /// If invoking the function throws a Dart exception, the sql function will diff --git a/sqlite3/lib/src/ffi/ffi.dart b/sqlite3/lib/src/ffi/ffi.dart index 38328bec..75062af9 100644 --- a/sqlite3/lib/src/ffi/ffi.dart +++ b/sqlite3/lib/src/ffi/ffi.dart @@ -94,7 +94,7 @@ extension ContextUtils on Pointer { bindings.sqlite3_result_text( this, ptr.cast(), bytes.length, SQLITE_TRANSIENT); ptr.free(); - } else if (result is List) { + } else if (result is Uint8List) { final ptr = allocateBytes(result); bindings.sqlite3_result_blob64( @@ -148,7 +148,7 @@ class ValueList extends ListBase { } final result = argArray[index].read(bindings); - if (result is String || result is List) { + if (result is String || result is Uint8List) { // Cache to avoid excessive copying in case the argument is loaded // multiple times _cachedCopies[index] = result; diff --git a/sqlite3/lib/src/ffi/memory.dart b/sqlite3/lib/src/ffi/memory.dart index 147e8f62..701e1dfb 100644 --- a/sqlite3/lib/src/ffi/memory.dart +++ b/sqlite3/lib/src/ffi/memory.dart @@ -31,7 +31,7 @@ extension FreePointerExtension on Pointer { void free() => allocate.free(this); } -Pointer allocateBytes(List bytes, {int additionalLength = 0}) { +Pointer allocateBytes(Uint8List bytes, {int additionalLength = 0}) { final ptr = allocate.allocate(bytes.length + additionalLength); final data = Uint8List(bytes.length + additionalLength)..setAll(0, bytes); diff --git a/sqlite3/lib/src/impl/statement.dart b/sqlite3/lib/src/impl/statement.dart index 13182f59..62e7616b 100644 --- a/sqlite3/lib/src/impl/statement.dart +++ b/sqlite3/lib/src/impl/statement.dart @@ -115,7 +115,7 @@ class PreparedStatementImpl implements PreparedStatement { _bindings.sqlite3_bind_text( _stmt, i, ptr.cast(), bytes.length, nullPtr()); - } else if (param is List) { + } else if (param is Uint8List) { if (param.isEmpty) { // malloc(0) is implementation-defined and might return a null // pointer, which is not what we want: Passing a null-pointer to @@ -134,7 +134,7 @@ class PreparedStatementImpl implements PreparedStatement { param, 'params[$i]', 'Allowed parameters must either be null or an int, num, String or ' - 'List.', + 'Uint8List.', ); } } From f66400c6a5b93f7529f564a1374907241e78bb3e Mon Sep 17 00:00:00 2001 From: gcxfd Date: Wed, 26 May 2021 11:34:36 +0800 Subject: [PATCH 2/3] utf8.encode to utf8.encoder.convert --- sqlite3/lib/src/ffi/ffi.dart | 6 ++++-- sqlite3/lib/src/ffi/memory.dart | 3 ++- sqlite3/lib/src/impl/database.dart | 4 ++-- sqlite3/lib/src/impl/statement.dart | 2 +- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/sqlite3/lib/src/ffi/ffi.dart b/sqlite3/lib/src/ffi/ffi.dart index 75062af9..9181e95e 100644 --- a/sqlite3/lib/src/ffi/ffi.dart +++ b/sqlite3/lib/src/ffi/ffi.dart @@ -69,6 +69,8 @@ extension ValueUtils on Pointer { } } +final utf8Encode = utf8.encoder.convert; + extension ContextUtils on Pointer { Pointer aggregateContext(Bindings bindings, int bytes) { return bindings.sqlite3_aggregate_context(this, bytes); @@ -88,7 +90,7 @@ extension ContextUtils on Pointer { } else if (result is bool) { bindings.sqlite3_result_int64(this, result ? 1 : 0); } else if (result is String) { - final bytes = utf8.encode(result); + Uint8List bytes = utf8Encode(result); final ptr = allocateBytes(bytes); bindings.sqlite3_result_text( @@ -104,7 +106,7 @@ extension ContextUtils on Pointer { } void setError(Bindings bindings, String description) { - final bytes = utf8.encode(description); + final Uint8List bytes = utf8Encode(description); final ptr = allocateBytes(bytes); bindings.sqlite3_result_error(this, ptr.cast(), bytes.length); diff --git a/sqlite3/lib/src/ffi/memory.dart b/sqlite3/lib/src/ffi/memory.dart index 701e1dfb..97d4617e 100644 --- a/sqlite3/lib/src/ffi/memory.dart +++ b/sqlite3/lib/src/ffi/memory.dart @@ -40,6 +40,7 @@ Pointer allocateBytes(Uint8List bytes, {int additionalLength = 0}) { return ptr; } +final utf8Encode = utf8.encoder.convert; Pointer allocateZeroTerminated(String string) { - return allocateBytes(utf8.encode(string), additionalLength: 1).cast(); + return allocateBytes(utf8Encode(string), additionalLength: 1).cast(); } diff --git a/sqlite3/lib/src/impl/database.dart b/sqlite3/lib/src/impl/database.dart index d8ceca75..7cf9a524 100644 --- a/sqlite3/lib/src/impl/database.dart +++ b/sqlite3/lib/src/impl/database.dart @@ -145,7 +145,7 @@ class DatabaseImpl implements Database { final pzTail = checkNoTail ? allocate>() : nullPtr>(); - final bytes = utf8.encode(sql); + final bytes = utf8Encode(sql); final sqlPtr = allocateBytes(bytes); var prepFlags = 0; @@ -229,7 +229,7 @@ class DatabaseImpl implements Database { } Pointer _functionName(String functionName) { - final functionNameBytes = utf8.encode(functionName); + final functionNameBytes = utf8Encode(functionName); if (functionNameBytes.length > 255) { throw ArgumentError.value(functionName, 'functionName', diff --git a/sqlite3/lib/src/impl/statement.dart b/sqlite3/lib/src/impl/statement.dart index 62e7616b..a3c9bc65 100644 --- a/sqlite3/lib/src/impl/statement.dart +++ b/sqlite3/lib/src/impl/statement.dart @@ -109,7 +109,7 @@ class PreparedStatementImpl implements PreparedStatement { } else if (param is double) { _bindings.sqlite3_bind_double(_stmt, i, param.toDouble()); } else if (param is String) { - final bytes = utf8.encode(param); + final bytes = utf8Encode(param); final ptr = allocateBytes(bytes); _allocatedWhileBinding.add(ptr); From f4d6fda704c7a64183cc79884c3b08da9a6793b5 Mon Sep 17 00:00:00 2001 From: gcxfd Date: Wed, 26 May 2021 16:40:41 +0800 Subject: [PATCH 3/3] can use List --- sqlite3/lib/src/api/functions.dart | 2 +- sqlite3/lib/src/impl/statement.dart | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/sqlite3/lib/src/api/functions.dart b/sqlite3/lib/src/api/functions.dart index 4c0a0d02..60802c36 100644 --- a/sqlite3/lib/src/api/functions.dart +++ b/sqlite3/lib/src/api/functions.dart @@ -3,7 +3,7 @@ import 'package:meta/meta.dart'; /// A scalar function exposed to sql. /// /// {@template sqlite3_function_behavior} -/// The function must either return a `bool`, `num`, `String`, `Uint8List` or +/// The function must either return a `bool`, `num`, `String`, `Uint8List`, `List` or /// `null`. /// /// If invoking the function throws a Dart exception, the sql function will diff --git a/sqlite3/lib/src/impl/statement.dart b/sqlite3/lib/src/impl/statement.dart index a3c9bc65..1cb04081 100644 --- a/sqlite3/lib/src/impl/statement.dart +++ b/sqlite3/lib/src/impl/statement.dart @@ -100,7 +100,10 @@ class PreparedStatementImpl implements PreparedStatement { // variables in sqlite are 1-indexed for (var i = 1; i <= params.length; i++) { - final Object? param = params[i - 1]; + Object? param = params[i - 1]; + if (param is List) { + param = Uint8List.fromList(param); + } if (param == null) { _bindings.sqlite3_bind_null(_stmt, i); @@ -133,7 +136,7 @@ class PreparedStatementImpl implements PreparedStatement { throw ArgumentError.value( param, 'params[$i]', - 'Allowed parameters must either be null or an int, num, String or ' + 'Allowed parameters must either be null or an int, num, String, List or ' 'Uint8List.', ); }