@@ -664,66 +664,6 @@ void UserDefinedFunction::xDestroy(void* self) {
664664 delete static_cast <UserDefinedFunction*>(self);
665665}
666666
667- AuthorizerFunction::AuthorizerFunction (Environment* env,
668- Local<Function> fn,
669- DatabaseSync* db)
670- : env_(env), fn_(env->isolate (), fn), db_(db) {}
671-
672- AuthorizerFunction::~AuthorizerFunction () {}
673-
674- int AuthorizerFunction::xAuthorizer (void * user_data,
675- int action_code,
676- const char * param1,
677- const char * param2,
678- const char * param3,
679- const char * param4) {
680- AuthorizerFunction* self = static_cast <AuthorizerFunction*>(user_data);
681- Environment* env = self->env_ ;
682- Isolate* isolate = env->isolate ();
683- HandleScope handle_scope (isolate);
684- Local<Context> context = env->context ();
685-
686- auto fn = self->fn_ .Get (isolate);
687- LocalVector<Value> js_argv (isolate);
688-
689- // Convert SQLite authorizer parameters to JavaScript values
690- js_argv.emplace_back (Integer::New (isolate, action_code));
691- js_argv.emplace_back (
692- NullableSQLiteStringToValue (isolate, param1).ToLocalChecked ());
693- js_argv.emplace_back (
694- NullableSQLiteStringToValue (isolate, param2).ToLocalChecked ());
695- js_argv.emplace_back (
696- NullableSQLiteStringToValue (isolate, param3).ToLocalChecked ());
697- js_argv.emplace_back (
698- NullableSQLiteStringToValue (isolate, param4).ToLocalChecked ());
699-
700- TryCatch try_catch (isolate);
701- MaybeLocal<Value> retval =
702- fn->Call (context, Undefined (isolate), js_argv.size (), js_argv.data ());
703-
704- if (try_catch.HasCaught ()) {
705- // If there's an exception in the callback, deny the operation
706- return SQLITE_DENY;
707- }
708-
709- Local<Value> result;
710- if (!retval.ToLocal (&result)) {
711- return SQLITE_DENY;
712- }
713-
714- if (result->IsNumber ()) {
715- double num_result = result.As <Number>()->Value ();
716- return static_cast <int >(num_result);
717- }
718-
719- // Default to OK if the result isn't a number
720- return SQLITE_OK;
721- }
722-
723- void AuthorizerFunction::xDestroy (void * self) {
724- delete static_cast <AuthorizerFunction*>(self);
725- }
726-
727667DatabaseSync::DatabaseSync (Environment* env,
728668 Local<Object> object,
729669 DatabaseOpenConfiguration&& open_config,
@@ -1929,6 +1869,7 @@ void DatabaseSync::SetAuthorizer(const FunctionCallbackInfo<Value>& args) {
19291869 if (args[0 ]->IsNull ()) {
19301870 // Clear the authorizer
19311871 sqlite3_set_authorizer (db->connection_ , nullptr , nullptr );
1872+ db->object ()->SetInternalField (kAuthorizerCallback , Null (isolate));
19321873 return ;
19331874 }
19341875
@@ -1939,17 +1880,74 @@ void DatabaseSync::SetAuthorizer(const FunctionCallbackInfo<Value>& args) {
19391880 }
19401881
19411882 Local<Function> fn = args[0 ].As <Function>();
1942- AuthorizerFunction* user_data = new AuthorizerFunction (env, fn, db);
1883+
1884+ db->object ()->SetInternalField (kAuthorizerCallback , fn);
19431885
19441886 int r = sqlite3_set_authorizer (
1945- db->connection_ , AuthorizerFunction::xAuthorizer, user_data );
1887+ db->connection_ , DatabaseSync::AuthorizerCallback, db );
19461888
19471889 if (r != SQLITE_OK) {
1948- delete user_data;
19491890 CHECK_ERROR_OR_THROW (isolate, db, r, SQLITE_OK, void ());
19501891 }
19511892}
19521893
1894+ int DatabaseSync::AuthorizerCallback (void * user_data,
1895+ int action_code,
1896+ const char * param1,
1897+ const char * param2,
1898+ const char * param3,
1899+ const char * param4) {
1900+ DatabaseSync* db = static_cast <DatabaseSync*>(user_data);
1901+ Environment* env = db->env ();
1902+ Isolate* isolate = env->isolate ();
1903+ HandleScope handle_scope (isolate);
1904+ Local<Context> context = env->context ();
1905+
1906+ Local<Value> cb =
1907+ db->object ()->GetInternalField (kAuthorizerCallback ).template As <Value>();
1908+
1909+ if (!cb->IsFunction ()) {
1910+ return SQLITE_DENY;
1911+ }
1912+
1913+ Local<Function> callback = cb.As <Function>();
1914+ LocalVector<Value> js_argv (isolate);
1915+
1916+ // Convert SQLite authorizer parameters to JavaScript values
1917+ js_argv.emplace_back (Integer::New (isolate, action_code));
1918+ js_argv.emplace_back (
1919+ NullableSQLiteStringToValue (isolate, param1).ToLocalChecked ());
1920+ js_argv.emplace_back (
1921+ NullableSQLiteStringToValue (isolate, param2).ToLocalChecked ());
1922+ js_argv.emplace_back (
1923+ NullableSQLiteStringToValue (isolate, param3).ToLocalChecked ());
1924+ js_argv.emplace_back (
1925+ NullableSQLiteStringToValue (isolate, param4).ToLocalChecked ());
1926+
1927+ TryCatch try_catch (isolate);
1928+ MaybeLocal<Value> retval = callback->Call (
1929+ context, Undefined (isolate), js_argv.size (), js_argv.data ());
1930+
1931+ if (try_catch.HasCaught ()) {
1932+ // If there's an exception in the callback, deny the operation
1933+ // TODO: Rethrow exepction
1934+ return SQLITE_DENY;
1935+ }
1936+
1937+ Local<Value> result;
1938+ if (!retval.ToLocal (&result)) {
1939+ return SQLITE_DENY;
1940+ }
1941+
1942+ if (result->IsNumber ()) {
1943+ double num_result = result.As <Number>()->Value ();
1944+ return static_cast <int >(num_result);
1945+ }
1946+
1947+ // Default to OK if the result isn't a number
1948+ return SQLITE_OK;
1949+ }
1950+
19531951StatementSync::StatementSync (Environment* env,
19541952 Local<Object> object,
19551953 BaseObjectPtr<DatabaseSync> db,
0 commit comments