Skip to content

Commit cc8bd75

Browse files
committed
Fix statement arguments not being freed (#225)
1 parent 34b7454 commit cc8bd75

File tree

5 files changed

+42
-6
lines changed

5 files changed

+42
-6
lines changed

sqlite3/CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## 2.4.2
2+
3+
- Fix string and blob arguments to prepared statements never being
4+
deallocated ([#225](https://github.com/simolus3/sqlite3.dart/issues/225)).
5+
16
## 2.4.1+1
27

38
- Allow version `0.7.x` of the `js` package.

sqlite3/lib/src/ffi/bindings.dart

+5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import 'dart:convert';
33
import 'dart:ffi';
44
import 'dart:typed_data';
55

6+
import 'package:meta/meta.dart';
7+
68
import '../constants.dart';
79
import '../functions.dart';
810
import '../implementation/bindings.dart';
@@ -378,6 +380,9 @@ final class FfiStatement extends RawSqliteStatement {
378380
FfiStatement(this.database, this.stmt)
379381
: bindings = database.bindings.bindings;
380382

383+
@visibleForTesting
384+
List<Pointer> get allocatedArguments => _allocatedArguments;
385+
381386
@override
382387
void deallocateArguments() {
383388
for (final arg in _allocatedArguments) {

sqlite3/lib/src/implementation/statement.dart

+1-5
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ final class FinalizableStatement extends FinalizablePart {
1111
final RawSqliteStatement statement;
1212

1313
bool _inResetState = true;
14-
bool _hasAllocatedArguments = false;
1514
bool _closed = false;
1615

1716
FinalizableStatement(this.statement);
@@ -34,10 +33,7 @@ final class FinalizableStatement extends FinalizablePart {
3433
}
3534

3635
void _deallocateArguments() {
37-
if (_hasAllocatedArguments) {
38-
_hasAllocatedArguments = false;
39-
statement.deallocateArguments();
40-
}
36+
statement.deallocateArguments();
4137
}
4238
}
4339

sqlite3/pubspec.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: sqlite3
22
description: Provides lightweight yet convenient bindings to SQLite by using dart:ffi
3-
version: 2.4.1+1
3+
version: 2.4.2
44
homepage: https://github.com/simolus3/sqlite3.dart/tree/main/sqlite3
55
issue_tracker: https://github.com/simolus3/sqlite3.dart/issues
66

sqlite3/test/ffi/prepared_statement_test.dart

+30
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
@Tags(['ffi'])
22
import 'package:sqlite3/sqlite3.dart';
3+
import 'package:sqlite3/src/ffi/implementation.dart';
34
import 'package:test/test.dart';
45

56
import '../common/prepared_statement.dart';
@@ -9,4 +10,33 @@ void main() {
910
final hasReturning = version.versionNumber > 3035000;
1011

1112
testPreparedStatements(() => sqlite3, supportsReturning: hasReturning);
13+
14+
group('deallocates statement arguments', () {
15+
late Database database;
16+
17+
setUp(() => database = sqlite3.openInMemory());
18+
tearDown(() => database.dispose());
19+
20+
test('after binding different args', () {
21+
final stmt = database.prepare('SELECT ?;');
22+
stmt.execute(['this needs to be allocated and copied into ffi buffer']);
23+
expect(
24+
(stmt as FfiStatementImplementation).ffiStatement.allocatedArguments,
25+
isNotEmpty);
26+
27+
stmt.execute([3]);
28+
expect(stmt.ffiStatement.allocatedArguments, isEmpty);
29+
});
30+
31+
test('after disposing statement', () {
32+
final stmt = database.prepare('SELECT ?;');
33+
stmt.execute(['this needs to be allocated and copied into ffi buffer']);
34+
expect(
35+
(stmt as FfiStatementImplementation).ffiStatement.allocatedArguments,
36+
isNotEmpty);
37+
38+
stmt.dispose();
39+
expect(stmt.ffiStatement.allocatedArguments, isEmpty);
40+
});
41+
});
1242
}

0 commit comments

Comments
 (0)