Skip to content

Commit 98a037a

Browse files
author
Joshua Wise
committed
fixed edge case bug when binding buffers and using .each()
1 parent e5866c7 commit 98a037a

File tree

5 files changed

+20
-6
lines changed

5 files changed

+20
-6
lines changed

src/binder/bind-buffer.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
void Binder::BindBuffer(v8::Local<v8::Object> value, int index) {
66
if (!index) {index = NextAnonIndex();}
77

8-
int status = sqlite3_bind_blob(handle, index, (void*)node::Buffer::Data(value), node::Buffer::Length(value), bind_type);
8+
int status = sqlite3_bind_blob(handle, index, (void*)node::Buffer::Data(value), node::Buffer::Length(value), transient_buffers ? SQLITE_TRANSIENT : bind_type);
99

1010
SetBindingError(status);
1111
}

src/binder/binder.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,15 @@
2525
#include "bind-object.cc"
2626
#include "bind.cc"
2727

28-
Binder::Binder(sqlite3_stmt* handle, sqlite3_destructor_type bind_type)
28+
Binder::Binder(sqlite3_stmt* handle, sqlite3_destructor_type bind_type, bool transient_buffers)
2929
: handle(handle)
3030
, param_count(sqlite3_bind_parameter_count(handle))
3131
, anon_index(0)
3232
, error(NULL)
3333
, error_extra(NULL)
3434
, error_full(NULL)
35-
, bind_type(bind_type) {}
35+
, bind_type(bind_type)
36+
, transient_buffers(transient_buffers) {}
3637

3738
Binder::~Binder() {
3839
delete[] error_extra;

src/binder/binder.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ class Int64;
88

99
class Binder {
1010
public:
11-
Binder(sqlite3_stmt*, sqlite3_destructor_type);
11+
Binder(sqlite3_stmt*, sqlite3_destructor_type, bool = false);
1212
~Binder();
1313
virtual void Bind(Nan::NAN_METHOD_ARGS_TYPE, int, Query*);
1414
const char* GetError();
@@ -39,6 +39,7 @@ class Binder {
3939
const char* error_full;
4040

4141
sqlite3_destructor_type bind_type;
42+
bool transient_buffers;
4243
};
4344

4445
#endif

src/objects/statement/each.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ NAN_METHOD(Statement::Each) {
66
return Nan::ThrowTypeError("This statement is not read-only. Use run() instead.");
77
}
88
REQUIRE_LAST_ARGUMENT_FUNCTION(func_index, callback);
9-
QUERY_START(stmt, statement, STATEMENT_BIND, info, func_index);
9+
QUERY_START(stmt, statement, STATEMENT_BIND_T_BUFFERS, info, func_index);
1010
stmt->db->in_each = true;
1111

1212

src/util/macros.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ inline bool IS_32BIT_INT(double num) {
160160
sqlite3_clear_bindings(trans->handles[i]); \
161161
}
162162

163-
// Common bind logic for statements.
163+
// Common bind logic for statements (must match STATEMENT_BIND_T_BUFFERS).
164164
#define STATEMENT_BIND(stmt, info, info_length, bind_type) \
165165
if (info_length > 0) { \
166166
Binder _binder(stmt->st_handle, bind_type); \
@@ -172,6 +172,18 @@ inline bool IS_32BIT_INT(double num) {
172172
} \
173173
}
174174

175+
// Should be the same as STATEMENT_BIND, but uses the transient_buffers option.
176+
#define STATEMENT_BIND_T_BUFFERS(stmt, info, info_length, bind_type) \
177+
if (info_length > 0) { \
178+
Binder _binder(stmt->st_handle, bind_type, true); \
179+
_binder.Bind(info, info_length, stmt); \
180+
const char* _err = _binder.GetError(); \
181+
if (_err) { \
182+
STATEMENT_CLEAR_BINDINGS(stmt); \
183+
return Nan::ThrowError(_err); \
184+
} \
185+
}
186+
175187
// Common bind logic for transactions.
176188
#define TRANSACTION_BIND(trans, info, info_length, bind_type) \
177189
if (info_length > 0) { \

0 commit comments

Comments
 (0)