github.com/ncruces/go-sqlite3@v0.15.1-0.20240520133447-53eef1510ff0/sqlite3/func.c (about)

     1  #include <stdbool.h>
     2  #include <stddef.h>
     3  
     4  #include "include.h"
     5  #include "sqlite3.h"
     6  
     7  void go_collation_needed(void *, sqlite3 *, int, const char *);
     8  
     9  int go_compare(go_handle, int, const void *, int, const void *);
    10  
    11  void go_func(sqlite3_context *, go_handle, int, sqlite3_value **);
    12  
    13  void go_step(sqlite3_context *, go_handle *, go_handle, int, sqlite3_value **);
    14  void go_final(sqlite3_context *, go_handle, go_handle);
    15  void go_value(sqlite3_context *, go_handle);
    16  void go_inverse(sqlite3_context *, go_handle *, int, sqlite3_value **);
    17  
    18  void go_func_wrapper(sqlite3_context *ctx, int nArg, sqlite3_value **pArg) {
    19    go_func(ctx, sqlite3_user_data(ctx), nArg, pArg);
    20  }
    21  
    22  void go_step_wrapper(sqlite3_context *ctx, int nArg, sqlite3_value **pArg) {
    23    go_handle *agg = sqlite3_aggregate_context(ctx, 4);
    24    go_handle data = NULL;
    25    if (agg == NULL || *agg == NULL) {
    26      data = sqlite3_user_data(ctx);
    27    }
    28    go_step(ctx, agg, data, nArg, pArg);
    29  }
    30  
    31  void go_final_wrapper(sqlite3_context *ctx) {
    32    go_handle *agg = sqlite3_aggregate_context(ctx, 0);
    33    go_handle data = NULL;
    34    if (agg == NULL || *agg == NULL) {
    35      data = sqlite3_user_data(ctx);
    36    }
    37    go_final(ctx, agg, data);
    38  }
    39  
    40  void go_value_wrapper(sqlite3_context *ctx) {
    41    go_handle *agg = sqlite3_aggregate_context(ctx, 4);
    42    go_value(ctx, *agg);
    43  }
    44  
    45  void go_inverse_wrapper(sqlite3_context *ctx, int nArg, sqlite3_value **pArg) {
    46    go_handle *agg = sqlite3_aggregate_context(ctx, 4);
    47    go_inverse(ctx, *agg, nArg, pArg);
    48  }
    49  
    50  int sqlite3_collation_needed_go(sqlite3 *db, bool enable) {
    51    return sqlite3_collation_needed(db, /*arg=*/NULL,
    52                                    enable ? go_collation_needed : NULL);
    53  }
    54  
    55  int sqlite3_create_collation_go(sqlite3 *db, const char *name, go_handle app) {
    56    int rc = sqlite3_create_collation_v2(db, name, SQLITE_UTF8, app, go_compare,
    57                                         go_destroy);
    58    if (rc) go_destroy(app);
    59    return rc;
    60  }
    61  
    62  int sqlite3_create_function_go(sqlite3 *db, const char *name, int argc,
    63                                 int flags, go_handle app) {
    64    return sqlite3_create_function_v2(db, name, argc, SQLITE_UTF8 | flags, app,
    65                                      go_func_wrapper, /*step=*/NULL,
    66                                      /*final=*/NULL, go_destroy);
    67  }
    68  
    69  int sqlite3_create_aggregate_function_go(sqlite3 *db, const char *name,
    70                                           int argc, int flags, go_handle app) {
    71    return sqlite3_create_function_v2(db, name, argc, SQLITE_UTF8 | flags, app,
    72                                      /*func=*/NULL, go_step_wrapper,
    73                                      go_final_wrapper, go_destroy);
    74  }
    75  
    76  int sqlite3_create_window_function_go(sqlite3 *db, const char *name, int argc,
    77                                        int flags, go_handle app) {
    78    return sqlite3_create_window_function(
    79        db, name, argc, SQLITE_UTF8 | flags, app, go_step_wrapper,
    80        go_final_wrapper, go_value_wrapper, go_inverse_wrapper, go_destroy);
    81  }
    82  
    83  void sqlite3_set_auxdata_go(sqlite3_context *ctx, int i, go_handle aux) {
    84    sqlite3_set_auxdata(ctx, i, aux, go_destroy);
    85  }