@@ -413,6 +413,53 @@ class Database
413413 @ handleError sqlite3_close_v2 @db
414414 FS .unlink ' /' + @filename
415415 @db = null
416+
417+ ### Register a custom function with SQLite
418+ @param name [String] the name of the function as referenced in SQL statements.
419+ @param numParams [Number] the number of parameters the function expects.
420+ @param func [Function] the actual function to be executed.
421+ @param dbg_func [Function, optional] useful for breakpointing and testing the wrapper function.
422+ ###
423+ ' create_function' : (name, numParams, func, dbg_func = (-> )) ->
424+ wrapped_func = (cx , argc , argv ) ->
425+ # Debug function, useful for breakpointing if you need to debug this
426+ dbg_func ()
427+
428+ # Parse the args from sqlite into JS objects
429+ args = []
430+ for i in [0 .. argc]
431+ value_ptr = getValue (argv+ (4 * i), ' i32' )
432+ value_type = sqlite3_value_type (value_ptr)
433+ data_func = switch
434+ when value_type == 1 then sqlite3_value_int
435+ when value_type == 2 then sqlite3_value_double
436+ when value_type == 3 then sqlite3_value_text
437+ when value_type == 4 then (ptr ) ->
438+ size = sqlite3_value_bytes (ptr)
439+ blob_ptr = sqlite3_value_blob (ptr)
440+ blob_arg = new Uint8Array (size)
441+ blob_arg[j] = HEAP8[blob_ptr+ j] for j in [0 ... size]
442+ blob_arg
443+ else (ptr ) -> null
444+
445+ arg = data_func (value_ptr)
446+ args .push arg
447+
448+ # Invoke the user defined function with arguments from SQLite
449+ result = func .apply (null , args)
450+
451+ # Return the result of the user defined function to SQLite
452+ if not result
453+ sqlite3_result_null cx
454+ else
455+ switch typeof (result)
456+ when ' number' then sqlite3_result_double (cx, result)
457+ when ' string' then sqlite3_result_text (cx, result, - 1 , - 1 )
458+
459+ # Generate a pointer to the wrapped, user defined function, and register with SQLite.
460+ func_ptr = Runtime .addFunction (wrapped_func)
461+ @ handleError sqlite3_create_function_v2 @db , name, numParams, SQLite .UTF8 , 0 , func_ptr, 0 , 0 , 0
462+ return @
416463
417464 ### Analyze a result code, return null if no error occured, and throw
418465 an error with a descriptive message otherwise
0 commit comments