@@ -1668,26 +1668,28 @@ void Backup(const FunctionCallbackInfo<Value>& args) {
1668
1668
job->ScheduleBackup ();
1669
1669
}
1670
1670
1671
+ struct ConflictCallbackContext {
1672
+ std::function<bool (std::string_view)> filterCallback;
1673
+ std::function<int (int )> conflictCallback;
1674
+ };
1675
+
1671
1676
// the reason for using static functions here is that SQLite needs a
1672
1677
// function pointer
1673
- static std::function<int (int )> conflictCallback;
1674
1678
1675
1679
static 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);
1678
1683
}
1679
1684
1680
- static std::function<bool (std::string)> filterCallback;
1681
-
1682
1685
static 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 ;
1686
1689
}
1687
1690
1688
1691
void DatabaseSync::ApplyChangeset (const FunctionCallbackInfo<Value>& args) {
1689
- conflictCallback = nullptr ;
1690
- filterCallback = nullptr ;
1692
+ ConflictCallbackContext context;
1691
1693
1692
1694
DatabaseSync* db;
1693
1695
ASSIGN_OR_RETURN_UNWRAP (&db, args.This ());
@@ -1723,7 +1725,7 @@ void DatabaseSync::ApplyChangeset(const FunctionCallbackInfo<Value>& args) {
1723
1725
return ;
1724
1726
}
1725
1727
Local<Function> conflictFunc = conflictValue.As <Function>();
1726
- conflictCallback = [env, conflictFunc](int conflictType) -> int {
1728
+ context. conflictCallback = [env, conflictFunc](int conflictType) -> int {
1727
1729
Local<Value> argv[] = {Integer::New (env->isolate (), conflictType)};
1728
1730
TryCatch try_catch (env->isolate ());
1729
1731
Local<Value> result =
@@ -1761,15 +1763,18 @@ void DatabaseSync::ApplyChangeset(const FunctionCallbackInfo<Value>& args) {
1761
1763
1762
1764
Local<Function> filterFunc = filterValue.As <Function>();
1763
1765
1764
- filterCallback = [env, filterFunc](std::string item) -> bool {
1766
+ context.filterCallback = [env,
1767
+ filterFunc](std::string_view item) -> bool {
1765
1768
// TODO(@jasnell): The use of ToLocalChecked here means that if
1766
1769
// the filter function throws an error the process will crash.
1767
1770
// The filterCallback should be updated to avoid the check and
1768
1771
// 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 ()};
1773
1778
Local<Value> result =
1774
1779
filterFunc->Call (env->context (), Null (env->isolate ()), 1 , argv)
1775
1780
.ToLocalChecked ();
@@ -1785,7 +1790,7 @@ void DatabaseSync::ApplyChangeset(const FunctionCallbackInfo<Value>& args) {
1785
1790
const_cast <void *>(static_cast <const void *>(buf.data ())),
1786
1791
xFilter,
1787
1792
xConflict,
1788
- nullptr );
1793
+ static_cast < void *>(&context) );
1789
1794
if (r == SQLITE_OK) {
1790
1795
args.GetReturnValue ().Set (true );
1791
1796
return ;
0 commit comments