@@ -2260,20 +2260,38 @@ bool StatementSync::BindValue(const Local<Value>& value, const int index) {
22602260 // Dates could be supported by converting them to numbers. However, there
22612261 // would not be a good way to read the values back from SQLite with the
22622262 // original type.
2263+ Isolate* isolate = env ()->isolate ();
22632264 int r;
22642265 if (value->IsNumber ()) {
2265- double val = value.As <Number>()->Value ();
2266+ const double val = value.As <Number>()->Value ();
22662267 r = sqlite3_bind_double (statement_, index, val);
22672268 } else if (value->IsString ()) {
2268- Utf8Value val (env ()->isolate (), value.As <String>());
2269- r = sqlite3_bind_text (
2270- statement_, index, *val, val.length (), SQLITE_TRANSIENT);
2269+ Utf8Value val (isolate, value.As <String>());
2270+ if (val.IsAllocated ()) {
2271+ // Avoid an extra SQLite copy for large strings by transferring ownership
2272+ // of the malloc()'d buffer to SQLite.
2273+ char * data = *val;
2274+ const sqlite3_uint64 length = static_cast <sqlite3_uint64>(val.length ());
2275+ val.Release ();
2276+ r = sqlite3_bind_text64 (
2277+ statement_, index, data, length, std::free, SQLITE_UTF8);
2278+ } else {
2279+ r = sqlite3_bind_text64 (statement_,
2280+ index,
2281+ *val,
2282+ static_cast <sqlite3_uint64>(val.length ()),
2283+ SQLITE_TRANSIENT,
2284+ SQLITE_UTF8);
2285+ }
22712286 } else if (value->IsNull ()) {
22722287 r = sqlite3_bind_null (statement_, index);
22732288 } else if (value->IsArrayBufferView ()) {
22742289 ArrayBufferViewContents<uint8_t > buf (value);
2275- r = sqlite3_bind_blob (
2276- statement_, index, buf.data (), buf.length (), SQLITE_TRANSIENT);
2290+ r = sqlite3_bind_blob64 (statement_,
2291+ index,
2292+ buf.data (),
2293+ static_cast <sqlite3_uint64>(buf.length ()),
2294+ SQLITE_TRANSIENT);
22772295 } else if (value->IsBigInt ()) {
22782296 bool lossless;
22792297 int64_t as_int = value.As <BigInt>()->Int64Value (&lossless);
@@ -2284,13 +2302,13 @@ bool StatementSync::BindValue(const Local<Value>& value, const int index) {
22842302 r = sqlite3_bind_int64 (statement_, index, as_int);
22852303 } else {
22862304 THROW_ERR_INVALID_ARG_TYPE (
2287- env ()-> isolate () ,
2305+ isolate,
22882306 " Provided value cannot be bound to SQLite parameter %d." ,
22892307 index);
22902308 return false ;
22912309 }
22922310
2293- CHECK_ERROR_OR_THROW (env ()-> isolate () , db_.get (), r, SQLITE_OK, false );
2311+ CHECK_ERROR_OR_THROW (isolate, db_.get (), r, SQLITE_OK, false );
22942312 return true ;
22952313}
22962314
0 commit comments