Skip to content

Commit 3bb129a

Browse files
committed
Refactor SqliteResult
1 parent 98e2ed5 commit 3bb129a

File tree

8 files changed

+60
-43
lines changed

8 files changed

+60
-43
lines changed

sqlite3/lib/src/ffi/bindings.dart

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ final supportsPrepareV3 = sqlite3_libversion_number() >= _firstVersionForV3;
3434
final supportsErrorOffset =
3535
sqlite3_libversion_number() >= _firstVersionForErrorOffset;
3636

37+
final databaseFinalizer = NativeFinalizer(addresses.sqlite3_close_v2.cast());
38+
final statementFinalizer = NativeFinalizer(addresses.sqlite3_finalize.cast());
39+
3740
final sessionDeleteFinalizer = NativeFinalizer(
3841
addresses.sqlite3session_delete.cast(),
3942
);
@@ -225,7 +228,10 @@ final class FfiBindings implements RawSqliteBindings {
225228
flags,
226229
vfsPtr,
227230
);
228-
final result = SqliteResult(resultCode, FfiDatabase(outDb.value));
231+
final result = (
232+
resultCode: resultCode,
233+
result: outDb.value.isNullPointer ? null : FfiDatabase(outDb.value),
234+
);
229235

230236
namePtr.free();
231237
outDb.free();
@@ -730,7 +736,7 @@ final class FfiChangesetIterator implements RawChangesetIterator, Finalizable {
730736
}
731737

732738
@override
733-
SqliteResult<RawSqliteValue?> sqlite3changeset_new(int columnNumber) {
739+
SqliteResult<RawSqliteValue> sqlite3changeset_new(int columnNumber) {
734740
final outValue = allocate<Pointer<sqlite3_value>>();
735741
final result = libsqlite3.sqlite3changeset_new(
736742
iterator,
@@ -740,7 +746,10 @@ final class FfiChangesetIterator implements RawChangesetIterator, Finalizable {
740746
final value = outValue.value;
741747
outValue.free();
742748

743-
return SqliteResult(result, value.isNullPointer ? null : FfiValue(value));
749+
return (
750+
resultCode: result,
751+
result: value.isNullPointer ? null : FfiValue(value),
752+
);
744753
}
745754

746755
@override
@@ -749,7 +758,7 @@ final class FfiChangesetIterator implements RawChangesetIterator, Finalizable {
749758
}
750759

751760
@override
752-
SqliteResult<RawSqliteValue?> sqlite3changeset_old(int columnNumber) {
761+
SqliteResult<RawSqliteValue> sqlite3changeset_old(int columnNumber) {
753762
final outValue = allocate<Pointer<sqlite3_value>>();
754763
final result = libsqlite3.sqlite3changeset_old(
755764
iterator,
@@ -759,7 +768,10 @@ final class FfiChangesetIterator implements RawChangesetIterator, Finalizable {
759768
final value = outValue.value;
760769
outValue.free();
761770

762-
return SqliteResult(result, value.isNullPointer ? null : FfiValue(value));
771+
return (
772+
resultCode: result,
773+
result: value.isNullPointer ? null : FfiValue(value),
774+
);
763775
}
764776

765777
@override
@@ -1050,7 +1062,7 @@ final class FfiStatementCompiler implements RawStatementCompiler {
10501062
int get endOffset => pzTail.value.address - sql.address;
10511063

10521064
@override
1053-
SqliteResult<RawSqliteStatement?> sqlite3_prepare(
1065+
SqliteResult<RawSqliteStatement> sqlite3_prepare(
10541066
int byteOffset,
10551067
int length,
10561068
int prepFlag,
@@ -1085,7 +1097,7 @@ final class FfiStatementCompiler implements RawStatementCompiler {
10851097
final stmt = stmtOut.value;
10861098
final libraryStatement = stmt.isNullPointer ? null : FfiStatement(stmt);
10871099

1088-
return SqliteResult(result, libraryStatement);
1100+
return (resultCode: result, result: libraryStatement);
10891101
}
10901102
}
10911103

sqlite3/lib/src/ffi/libsqlite3.g.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -866,6 +866,10 @@ class _SymbolAddresses {
866866
const _SymbolAddresses();
867867
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
868868
get sqlite3_free => ffi.Native.addressOf(self.sqlite3_free);
869+
ffi.Pointer<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3>)>>
870+
get sqlite3_close_v2 => ffi.Native.addressOf(self.sqlite3_close_v2);
871+
ffi.Pointer<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_stmt>)>>
872+
get sqlite3_finalize => ffi.Native.addressOf(self.sqlite3_finalize);
869873
ffi.Pointer<
870874
ffi.NativeFunction<ffi.Void Function(ffi.Pointer<sqlite3_session>)>
871875
>

sqlite3/lib/src/implementation/bindings.dart

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ abstract interface class RawChangesetIterator {
1919
// int iVal, /* Column number */
2020
// sqlite3_value **ppValue /* OUT: New value (or NULL pointer) */
2121
// );
22-
SqliteResult<RawSqliteValue?> sqlite3changeset_new(int columnNumber);
22+
SqliteResult<RawSqliteValue> sqlite3changeset_new(int columnNumber);
2323

2424
// int sqlite3changeset_next(sqlite3_changeset_iter *pIter);
2525
int sqlite3changeset_next();
@@ -29,7 +29,7 @@ abstract interface class RawChangesetIterator {
2929
// int iVal, /* Column number */
3030
// sqlite3_value **ppValue /* OUT: Old value (or NULL pointer) */
3131
// );
32-
SqliteResult<RawSqliteValue?> sqlite3changeset_old(int columnNumber);
32+
SqliteResult<RawSqliteValue> sqlite3changeset_old(int columnNumber);
3333

3434
// int sqlite3changeset_op(
3535
// sqlite3_changeset_iter *pIter, /* Iterator object */
@@ -166,15 +166,7 @@ abstract interface class RawSqliteSession {
166166
}
167167

168168
/// Combines a sqlite result code and the result object.
169-
final class SqliteResult<T> {
170-
final int resultCode;
171-
172-
/// The result of the operation, which is assumed to be valid if [resultCode]
173-
/// is zero.
174-
final T result;
175-
176-
SqliteResult(this.resultCode, this.result);
177-
}
169+
typedef SqliteResult<T extends Object> = ({T? result, int resultCode});
178170

179171
typedef RawXFunc = void Function(RawSqliteContext, List<RawSqliteValue>);
180172
typedef RawXStep = void Function(RawSqliteContext, List<RawSqliteValue>);
@@ -257,7 +249,7 @@ abstract interface class RawStatementCompiler {
257249

258250
/// Compile a statement from the substring at [byteOffset] with a maximum
259251
/// length of [length].
260-
SqliteResult<RawSqliteStatement?> sqlite3_prepare(
252+
SqliteResult<RawSqliteStatement> sqlite3_prepare(
261253
int byteOffset,
262254
int length,
263255
int prepFlag,

sqlite3/lib/src/implementation/session.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ final class ChangesetIteratorImplementation implements ChangesetIterator {
195195
(i) => raw
196196
.sqlite3changeset_old(i)
197197
.okOrThrowOutsideOfDatabase(bindings)
198-
?.read(),
198+
.read(),
199199
)
200200
: null;
201201
final newColumns = kind != SqliteUpdateKind.delete
@@ -204,7 +204,7 @@ final class ChangesetIteratorImplementation implements ChangesetIterator {
204204
(i) => raw
205205
.sqlite3changeset_new(i)
206206
.okOrThrowOutsideOfDatabase(bindings)
207-
?.read(),
207+
.read(),
208208
)
209209
: null;
210210
current = ChangesetOperation(

sqlite3/lib/src/implementation/sqlite3.dart

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -70,19 +70,26 @@ base class Sqlite3Implementation implements CommonSqlite3 {
7070

7171
final result = bindings.sqlite3_open_v2(filename, flags, vfs);
7272
if (result.resultCode != SqlError.SQLITE_OK) {
73-
final exception = createExceptionRaw(
74-
bindings,
75-
result.result,
76-
result.resultCode,
77-
operation: 'opening the database',
78-
);
79-
// Close the database after creating the exception, which needs to read
80-
// the extended error from the database.
81-
result.result.sqlite3_close_v2();
82-
throw exception;
73+
// It's possible for us to have a database even if opening it failed. Only
74+
// if allocating memory for the connection failed would we not have a
75+
// database.
76+
if (result.result case final database?) {
77+
final exception = createExceptionRaw(
78+
bindings,
79+
database,
80+
result.resultCode,
81+
operation: 'opening the database',
82+
);
83+
// Close the database after creating the exception, which needs to read
84+
// the extended error from the database.
85+
database.sqlite3_close_v2();
86+
throw exception;
87+
} else {
88+
throw createExceptionOutsideOfDatabase(bindings, result.resultCode);
89+
}
8390
}
8491

85-
return wrapDatabase(result.result..sqlite3_extended_result_codes(1));
92+
return wrapDatabase(result.result!..sqlite3_extended_result_codes(1));
8693
}
8794

8895
@override

sqlite3/lib/src/implementation/utils.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@ int eTextRep(bool deterministic, bool directOnly, bool subtype) {
2727
return flags;
2828
}
2929

30-
extension HandleResult<T> on SqliteResult<T> {
30+
extension HandleResult<T extends Object> on SqliteResult<T> {
3131
T okOrThrowOutsideOfDatabase(RawSqliteBindings bindings) {
3232
if (resultCode != SqlError.SQLITE_OK) {
3333
throw createExceptionOutsideOfDatabase(bindings, resultCode);
3434
}
3535

36-
return result;
36+
return result!;
3737
}
3838
}
3939

sqlite3/lib/src/wasm/bindings.dart

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ final class WasmSqliteBindings implements RawSqliteBindings {
7474
..free(vfsPtr);
7575
if (zVfs != null) bindings.free(vfsPtr);
7676

77-
return SqliteResult(result, WasmDatabase(bindings, dbPtr));
77+
return (resultCode: result, result: WasmDatabase(bindings, dbPtr));
7878
}
7979

8080
@override
@@ -426,7 +426,7 @@ final class WasmStatementCompiler implements RawStatementCompiler {
426426
}
427427

428428
@override
429-
SqliteResult<RawSqliteStatement?> sqlite3_prepare(
429+
SqliteResult<RawSqliteStatement> sqlite3_prepare(
430430
int byteOffset,
431431
int length,
432432
int prepFlag,
@@ -443,7 +443,7 @@ final class WasmStatementCompiler implements RawStatementCompiler {
443443
final stmt = database.bindings.memory.int32ValueOfPointer(stmtOut);
444444
final libraryStatement = stmt == 0 ? null : WasmStatement(database, stmt);
445445

446-
return SqliteResult(result, libraryStatement);
446+
return (resultCode: result, result: libraryStatement);
447447
}
448448
}
449449

@@ -912,7 +912,7 @@ final class WasmChangesetIterator implements RawChangesetIterator {
912912
@override
913913
int sqlite3changeset_next() => _bindings.sqlite3changeset_next(pointer);
914914

915-
SqliteResult<RawSqliteValue?> _extractValue(
915+
SqliteResult<RawSqliteValue> _extractValue(
916916
int Function(Pointer, int, Pointer) extract,
917917
int index,
918918
) {
@@ -921,19 +921,19 @@ final class WasmChangesetIterator implements RawChangesetIterator {
921921
final value = _bindings.memory.int32ValueOfPointer(outValue);
922922
_bindings.free(outValue);
923923

924-
return SqliteResult(
925-
resultCode,
926-
value != 0 ? WasmValue(_bindings, value) : null,
924+
return (
925+
resultCode: resultCode,
926+
result: value != 0 ? WasmValue(_bindings, value) : null,
927927
);
928928
}
929929

930930
@override
931-
SqliteResult<RawSqliteValue?> sqlite3changeset_old(int columnNumber) {
931+
SqliteResult<RawSqliteValue> sqlite3changeset_old(int columnNumber) {
932932
return _extractValue(_bindings.sqlite3changeset_old, columnNumber);
933933
}
934934

935935
@override
936-
SqliteResult<RawSqliteValue?> sqlite3changeset_new(int columnNumber) {
936+
SqliteResult<RawSqliteValue> sqlite3changeset_new(int columnNumber) {
937937
return _extractValue(_bindings.sqlite3changeset_new, columnNumber);
938938
}
939939

sqlite3/tool/generate_bindings.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ DeclarationFilters _includeSqlite3Only = DeclarationFilters(
4646
shouldInclude: (d) => d.isSqlite3Symbol,
4747
shouldIncludeSymbolAddress: (decl) {
4848
return switch (decl.originalName) {
49+
'sqlite3_close_v2' => true,
50+
'sqlite3_finalize' => true,
4951
'sqlite3changeset_finalize' => true,
5052
'sqlite3session_delete' => true,
5153
'sqlite3_free' => true,

0 commit comments

Comments
 (0)