@@ -1623,26 +1623,28 @@ void Backup(const FunctionCallbackInfo<Value>& args) {
16231623 job->ScheduleBackup ();
16241624}
16251625
1626+ struct ConflictCallbackContext {
1627+ std::function<bool (std::string_view)> filterCallback;
1628+ std::function<int (int )> conflictCallback;
1629+ };
1630+
16261631// the reason for using static functions here is that SQLite needs a
16271632// function pointer
1628- static std::function<int (int )> conflictCallback;
16291633
16301634static int xConflict (void * pCtx, int eConflict, sqlite3_changeset_iter* pIter) {
1631- if (!conflictCallback) return SQLITE_CHANGESET_ABORT;
1632- return conflictCallback (eConflict);
1635+ auto ctx = static_cast <ConflictCallbackContext*>(pCtx);
1636+ if (!ctx->conflictCallback ) return SQLITE_CHANGESET_ABORT;
1637+ return ctx->conflictCallback (eConflict);
16331638}
16341639
1635- static std::function<bool (std::string)> filterCallback;
1636-
16371640static int xFilter (void * pCtx, const char * zTab) {
1638- if (!filterCallback) return 1 ;
1639-
1640- return filterCallback (zTab) ? 1 : 0 ;
1641+ auto ctx = static_cast <ConflictCallbackContext*>(pCtx) ;
1642+ if (!ctx-> filterCallback ) return 1 ;
1643+ return ctx-> filterCallback (zTab) ? 1 : 0 ;
16411644}
16421645
16431646void DatabaseSync::ApplyChangeset (const FunctionCallbackInfo<Value>& args) {
1644- conflictCallback = nullptr ;
1645- filterCallback = nullptr ;
1647+ ConflictCallbackContext context;
16461648
16471649 DatabaseSync* db;
16481650 ASSIGN_OR_RETURN_UNWRAP (&db, args.This ());
@@ -1678,7 +1680,7 @@ void DatabaseSync::ApplyChangeset(const FunctionCallbackInfo<Value>& args) {
16781680 return ;
16791681 }
16801682 Local<Function> conflictFunc = conflictValue.As <Function>();
1681- conflictCallback = [env, conflictFunc](int conflictType) -> int {
1683+ context. conflictCallback = [env, conflictFunc](int conflictType) -> int {
16821684 Local<Value> argv[] = {Integer::New (env->isolate (), conflictType)};
16831685 TryCatch try_catch (env->isolate ());
16841686 Local<Value> result =
@@ -1716,15 +1718,18 @@ void DatabaseSync::ApplyChangeset(const FunctionCallbackInfo<Value>& args) {
17161718
17171719 Local<Function> filterFunc = filterValue.As <Function>();
17181720
1719- filterCallback = [env, filterFunc](std::string item) -> bool {
1721+ context.filterCallback = [env,
1722+ filterFunc](std::string_view item) -> bool {
17201723 // TODO(@jasnell): The use of ToLocalChecked here means that if
17211724 // the filter function throws an error the process will crash.
17221725 // The filterCallback should be updated to avoid the check and
17231726 // propagate the error correctly.
1724- Local<Value> argv[] = {String::NewFromUtf8 (env->isolate (),
1725- item.c_str (),
1726- NewStringType::kNormal )
1727- .ToLocalChecked ()};
1727+ Local<Value> argv[] = {
1728+ String::NewFromUtf8 (env->isolate (),
1729+ item.data (),
1730+ NewStringType::kNormal ,
1731+ static_cast <int >(item.size ()))
1732+ .ToLocalChecked ()};
17281733 Local<Value> result =
17291734 filterFunc->Call (env->context (), Null (env->isolate ()), 1 , argv)
17301735 .ToLocalChecked ();
@@ -1740,7 +1745,7 @@ void DatabaseSync::ApplyChangeset(const FunctionCallbackInfo<Value>& args) {
17401745 const_cast <void *>(static_cast <const void *>(buf.data ())),
17411746 xFilter,
17421747 xConflict,
1743- nullptr );
1748+ static_cast < void *>(&context) );
17441749 if (r == SQLITE_OK) {
17451750 args.GetReturnValue ().Set (true );
17461751 return ;
0 commit comments