@@ -1668,26 +1668,28 @@ void Backup(const FunctionCallbackInfo<Value>& args) {
16681668 job->ScheduleBackup ();
16691669}
16701670
1671+ struct ConflictCallbackContext {
1672+ std::function<bool (std::string_view)> filterCallback;
1673+ std::function<int (int )> conflictCallback;
1674+ };
1675+
16711676// the reason for using static functions here is that SQLite needs a
16721677// function pointer
1673- static std::function<int (int )> conflictCallback;
16741678
16751679static int xConflict (void * pCtx, int eConflict, sqlite3_changeset_iter* pIter) {
1676- if (!conflictCallback) return SQLITE_CHANGESET_ABORT;
1677- return conflictCallback (eConflict);
1680+ auto ctx = static_cast <ConflictCallbackContext*>(pCtx);
1681+ if (!ctx->conflictCallback ) return SQLITE_CHANGESET_ABORT;
1682+ return ctx->conflictCallback (eConflict);
16781683}
16791684
1680- static std::function<bool (std::string)> filterCallback;
1681-
16821685static int xFilter (void * pCtx, const char * zTab) {
1683- if (!filterCallback) return 1 ;
1684-
1685- return filterCallback (zTab) ? 1 : 0 ;
1686+ auto ctx = static_cast <ConflictCallbackContext*>(pCtx) ;
1687+ if (!ctx-> filterCallback ) return 1 ;
1688+ return ctx-> filterCallback (zTab) ? 1 : 0 ;
16861689}
16871690
16881691void DatabaseSync::ApplyChangeset (const FunctionCallbackInfo<Value>& args) {
1689- conflictCallback = nullptr ;
1690- filterCallback = nullptr ;
1692+ ConflictCallbackContext context;
16911693
16921694 DatabaseSync* db;
16931695 ASSIGN_OR_RETURN_UNWRAP (&db, args.This ());
@@ -1723,7 +1725,7 @@ void DatabaseSync::ApplyChangeset(const FunctionCallbackInfo<Value>& args) {
17231725 return ;
17241726 }
17251727 Local<Function> conflictFunc = conflictValue.As <Function>();
1726- conflictCallback = [env, conflictFunc](int conflictType) -> int {
1728+ context. conflictCallback = [env, conflictFunc](int conflictType) -> int {
17271729 Local<Value> argv[] = {Integer::New (env->isolate (), conflictType)};
17281730 TryCatch try_catch (env->isolate ());
17291731 Local<Value> result =
@@ -1761,15 +1763,18 @@ void DatabaseSync::ApplyChangeset(const FunctionCallbackInfo<Value>& args) {
17611763
17621764 Local<Function> filterFunc = filterValue.As <Function>();
17631765
1764- filterCallback = [env, filterFunc](std::string item) -> bool {
1766+ context.filterCallback = [env,
1767+ filterFunc](std::string_view item) -> bool {
17651768 // TODO(@jasnell): The use of ToLocalChecked here means that if
17661769 // the filter function throws an error the process will crash.
17671770 // The filterCallback should be updated to avoid the check and
17681771 // propagate the error correctly.
1769- Local<Value> argv[] = {String::NewFromUtf8 (env->isolate (),
1770- item.c_str (),
1771- NewStringType::kNormal )
1772- .ToLocalChecked ()};
1772+ Local<Value> argv[] = {
1773+ String::NewFromUtf8 (env->isolate (),
1774+ item.data (),
1775+ NewStringType::kNormal ,
1776+ static_cast <int >(item.size ()))
1777+ .ToLocalChecked ()};
17731778 Local<Value> result =
17741779 filterFunc->Call (env->context (), Null (env->isolate ()), 1 , argv)
17751780 .ToLocalChecked ();
@@ -1785,7 +1790,7 @@ void DatabaseSync::ApplyChangeset(const FunctionCallbackInfo<Value>& args) {
17851790 const_cast <void *>(static_cast <const void *>(buf.data ())),
17861791 xFilter,
17871792 xConflict,
1788- nullptr );
1793+ static_cast < void *>(&context) );
17891794 if (r == SQLITE_OK) {
17901795 args.GetReturnValue ().Set (true );
17911796 return ;
0 commit comments