/* ** Implementation of the sha3(X,SIZE) function. ** ** Return a BLOB which is the SIZE-bit SHA3 hash of X. The default ** size is 256. If X is a BLOB, it is hashed as is. ** For all other non-NULL types of input, X is converted into a UTF-8 string ** and the string is hashed without the trailing 0x00 terminator. The hash ** of a NULL value is NULL. */ static void sha3Func( sqlite3_context *context, int argc, sqlite3_value **argv ){ SHA3Context cx; int eType = sqlite3_value_type(argv[0]); int nByte = sqlite3_value_bytes(argv[0]); int iSize; if( argc==1 ){ iSize = 256; }else{ iSize = sqlite3_value_int(argv[1]); if( iSize!=224 && iSize!=256 && iSize!=384 && iSize!=512 ){ sqlite3_result_error(context, "SHA3 size should be one of: 224 256 " "384 512", -1); return; } } if( eType==SQLITE_NULL ) return; SHA3Init(&cx, iSize); if( eType==SQLITE_BLOB ){ SHA3Update(&cx, sqlite3_value_blob(argv[0]), nByte); }else{ SHA3Update(&cx, sqlite3_value_text(argv[0]), nByte); } sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT); }
static void test_auxdata( sqlite3_context *pCtx, int nArg, sqlite3_value **argv ){ int i; char *zRet = sqliteMalloc(nArg*2); if( !zRet ) return; for(i=0; i<nArg; i++){ char const *z = (char*)sqlite3_value_text(argv[i]); if( z ){ char *zAux = sqlite3_get_auxdata(pCtx, i); if( zAux ){ zRet[i*2] = '1'; if( strcmp(zAux, z) ){ free_test_auxdata((void *)zRet); sqlite3_result_error(pCtx, "Auxilary data corruption", -1); return; } }else{ zRet[i*2] = '0'; zAux = sqliteStrDup(z); sqlite3_set_auxdata(pCtx, i, zAux, free_test_auxdata); } zRet[i*2+1] = ' '; } } sqlite3_result_text(pCtx, zRet, 2*nArg-1, free_test_auxdata); }
void pho_h_wrapper(sqlite3_context *ctx, int n_values, sqlite3_value **value) { // check for NULL values, return NULL if input string is NULL if(sqlite3_value_type(value[0]) == SQLITE_NULL) { sqlite3_result_null(ctx); return; } const unsigned char *str1 = sqlite3_value_text(value[0]); int str1len = strlen(str1) + 1; // save string length with(!) delimiter char *dest = (char*) R_alloc(sizeof(char), str1len); #ifdef DEBUG Rprintf("String: %s\n", str1); #endif int result; /* Cast removes const qualifier, avoids warning. This is okay because phonet does not write to first arg unless it is equal to the second */ result = phonet((unsigned char *) str1, dest, str1len, 1); /* throw error if phonet fails (result <0) */ if (result < 0) { sqlite3_result_error(ctx, "phonet() terminated with an error", -1); return; } #ifdef DEBUG Rprintf("Ergebnis von phonet(): %s\n", dest); #endif sqlite3_result_text(ctx, dest, -1, SQLITE_STATIC); }
static void sqlite_checksum_int8( sqlite3_context * ctx, int argc, sqlite3_value ** argv) { assert(argc==1); const unsigned char * txt; size_t len; switch (sqlite3_value_type(argv[0])) { case SQLITE_NULL: txt = NULL; len = 0; break; case SQLITE_TEXT: txt = sqlite3_value_text(argv[0]); len = sqlite3_value_bytes(argv[0]); break; // hmmm... should I do something else? case SQLITE_INTEGER: case SQLITE_FLOAT: case SQLITE_BLOB: default: sqlite3_result_error(ctx, "expecting TEXT or NULL", -1); return; } sqlite3_result_int64(ctx, checksum_int8(txt, len)); }
/* ** Implementation of the abs() function */ static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ assert( argc==1 ); switch( sqlite3_value_type(argv[0]) ){ case SQLITE_INTEGER: { i64 iVal = sqlite3_value_int64(argv[0]); if( iVal<0 ){ if( (iVal<<1)==0 ){ sqlite3_result_error(context, "integer overflow", -1); return; } iVal = -iVal; } sqlite3_result_int64(context, iVal); break; } case SQLITE_NULL: { sqlite3_result_null(context); break; } default: { double rVal = sqlite3_value_double(argv[0]); if( rVal<0 ) rVal = -rVal; sqlite3_result_double(context, rVal); break; } } }
static void ST_SRID(sqlite3_context *context, int nbArgs, sqlite3_value **args) { spatialdb_t *spatialdb; FUNCTION_GEOM_ARG(geomblob); FUNCTION_START_STATIC(context, 256); spatialdb = (spatialdb_t *)sqlite3_user_data(context); FUNCTION_GET_GEOM_ARG_UNSAFE(context, spatialdb, geomblob, 0); if (nbArgs == 1) { sqlite3_result_int(context, geomblob.srid); } else { FUNCTION_GET_INT_ARG(geomblob.srid, 1); if (binstream_seek(&FUNCTION_GEOM_ARG_STREAM(geomblob), 0) != SQLITE_OK) { sqlite3_result_error(context, "Error writing geometry blob header", -1); goto exit; } if (spatialdb->write_blob_header(&FUNCTION_GEOM_ARG_STREAM(geomblob), &geomblob, FUNCTION_ERROR) != SQLITE_OK) { if (error_count(FUNCTION_ERROR) == 0) { error_append(FUNCTION_ERROR, "Error writing geometry blob header"); } goto exit; } binstream_seek(&FUNCTION_GEOM_ARG_STREAM(geomblob), 0); sqlite3_result_blob(context, binstream_data(&FUNCTION_GEOM_ARG_STREAM(geomblob)), (int) binstream_available(&FUNCTION_GEOM_ARG_STREAM(geomblob)), SQLITE_TRANSIENT); } FUNCTION_END(context); FUNCTION_FREE_GEOM_ARG(geomblob); }
static void sqlite_file_exists(sqlite3_context *ctx, int argc, sqlite3_value **argv) { char fpath[MAXPATHLEN]; sqlite3 *db = sqlite3_context_db_handle(ctx); char *path = dirname(sqlite3_db_filename(db, "main")); char cksum[SHA256_DIGEST_LENGTH * 2 +1]; if (argc != 2) { sqlite3_result_error(ctx, "file_exists needs two argument", -1); return; } snprintf(fpath, sizeof(fpath), "%s/%s", path, sqlite3_value_text(argv[0])); if (access(fpath, R_OK) == 0) { sha256_file(fpath, cksum); if (strcmp(cksum, sqlite3_value_text(argv[1])) == 0) sqlite3_result_int(ctx, 1); else sqlite3_result_int(ctx, 0); } else { sqlite3_result_int(ctx, 0); } }
/* ** An SQL function invoked as follows: ** ** sqlite_readint32(BLOB) -- Decode 32-bit integer from start of blob */ static void readint_function( sqlite3_context *pCtx, int nArg, sqlite3_value **apArg ){ const u8 *zBlob; int nBlob; int iOff = 0; u32 iRet = 0; if( nArg!=1 && nArg!=2 ){ sqlite3_result_error( pCtx, "wrong number of arguments to function sqlite_readint32()", -1 ); return; } if( nArg==2 ){ iOff = sqlite3_value_int(apArg[1]); } zBlob = sqlite3_value_blob(apArg[0]); nBlob = sqlite3_value_bytes(apArg[0]); if( nBlob>=(iOff+4) ){ iRet = get4byte(&zBlob[iOff]); } sqlite3_result_int64(pCtx, (sqlite3_int64)iRet); }
static void function_rank (sqlite3_context *context, int argc, sqlite3_value *argv[]) { guint *matchinfo, *weights; gdouble rank = 0; gint i, n_columns; if (argc != 2) { sqlite3_result_error(context, "wrong number of arguments to function rank()", -1); return; } matchinfo = (unsigned int *) sqlite3_value_blob (argv[0]); weights = (unsigned int *) sqlite3_value_blob (argv[1]); n_columns = matchinfo[0]; for (i = 0; i < n_columns; i++) { if (matchinfo[i + 1] != 0) { rank += (gdouble) weights[i]; } } sqlite3_result_double(context, rank); }
/* * The BFileFullPathFunc() SQL function returns full path of a BFile */ static void BFileFullPathFunc( sqlite3_context *context, int argc, sqlite3_value **argv) { int rc; sqlite3 *db; int loc_size; char *pLoc, *full_path; assert(context != NULL && argc == 1 && argv != NULL); loc_size = sqlite3_value_bytes(argv[0]); if (loc_size == 0) { sqlite3_result_null(context); return; } pLoc = (char *)sqlite3_value_text(argv[0]); db = (sqlite3 *)sqlite3_user_data(context); rc = get_full_path(db, pLoc, loc_size, &full_path); if (rc) { if (rc == SQLITE_NOMEM) sqlite3_result_error_nomem(context); else sqlite3_result_error(context, "internal error", -1); return; } sqlite3_result_text(context, full_path, strlen(full_path), sqlite3_free); }
/* ** Implementation of the eval(X) and eval(X,Y) SQL functions. ** ** Evaluate the SQL text in X. Return the results, using string ** Y as the separator. If Y is omitted, use a single space character. */ static void sqlEvalFunc( sqlite3_context *context, int argc, sqlite3_value **argv ){ const char *zSql; sqlite3 *db; char *zErr = 0; int rc; struct EvalResult x; memset(&x, 0, sizeof(x)); x.zSep = " "; zSql = (const char*)sqlite3_value_text(argv[0]); if( zSql==0 ) return; if( argc>1 ){ x.zSep = (const char*)sqlite3_value_text(argv[1]); if( x.zSep==0 ) return; } x.szSep = (int)strlen(x.zSep); db = sqlite3_context_db_handle(context); rc = sqlite3_exec(db, zSql, callback, &x, &zErr); if( rc!=SQLITE_OK ){ sqlite3_result_error(context, zErr, -1); sqlite3_free(zErr); }else if( x.zSep==0 ){ sqlite3_result_error_nomem(context); sqlite3_free(x.z); }else{ sqlite3_result_text(context, x.z, (int)x.nUsed, sqlite3_free); } }
static void wrapped_func(sqlite3_context *context, int argc, sqlite3_value *values[]) { struct function_wrapper_baton_t *fwb = sqlite3_user_data(context); svn_sqlite__context_t sctx = { context }; svn_sqlite__value_t **local_vals = apr_palloc(fwb->scratch_pool, sizeof(svn_sqlite__value_t *) * argc); svn_error_t *err; int i; for (i = 0; i < argc; i++) { local_vals[i] = apr_palloc(fwb->scratch_pool, sizeof(*local_vals[i])); local_vals[i]->value = values[i]; } err = fwb->func(&sctx, argc, local_vals, fwb->scratch_pool); svn_pool_clear(fwb->scratch_pool); if (err) { char buf[256]; sqlite3_result_error(context, svn_err_best_message(err, buf, sizeof(buf)), -1); svn_error_clear(err); } }
/* ** Implementation of the like() SQL function. This function implements ** the build-in LIKE operator. The first argument to the function is the ** pattern and the second argument is the string. So, the SQL statements: ** ** A LIKE B ** ** is implemented as like(B,A). ** ** This same function (with a different compareInfo structure) computes ** the GLOB operator. */ static void likeFunc( sqlite3_context *context, int argc, sqlite3_value **argv ) { const unsigned char *zA = sqlite3_value_text(argv[0]); const unsigned char *zB = sqlite3_value_text(argv[1]); int escape = 0; if( argc==3 ) { /* The escape character string must consist of a single UTF-8 character. ** Otherwise, return an error. */ const unsigned char *zEsc = sqlite3_value_text(argv[2]); if( sqlite3utf8CharLen(zEsc, -1)!=1 ) { sqlite3_result_error(context, "ESCAPE expression must be a single character", -1); return; } escape = sqlite3ReadUtf8(zEsc); } if( zA && zB ) { struct compareInfo *pInfo = sqlite3_user_data(context); #ifdef SQLITE_TEST sqlite3_like_count++; #endif sqlite3_result_int(context, patternCompare(zA, zB, pInfo, escape)); } }
/* ** Implementation of the scalar function icu_load_collation(). ** ** This scalar function is used to add ICU collation based collation ** types to an SQLite database connection. It is intended to be called ** as follows: ** ** SELECT icu_load_collation(<locale>, <collation-name>); ** ** Where <locale> is a string containing an ICU locale identifier (i.e. ** "en_AU", "tr_TR" etc.) and <collation-name> is the name of the ** collation sequence to create. */ static void icuLoadCollation( sqlite3_context *p, int nArg, sqlite3_value **apArg ){ sqlite3 *db = (sqlite3 *)sqlite3_user_data(p); UErrorCode status = U_ZERO_ERROR; const char *zLocale; /* Locale identifier - (eg. "jp_JP") */ const char *zName; /* SQL Collation sequence name (eg. "japanese") */ UCollator *pUCollator; /* ICU library collation object */ int rc; /* Return code from sqlite3_create_collation_x() */ assert(nArg==2); zLocale = (const char *)sqlite3_value_text(apArg[0]); zName = (const char *)sqlite3_value_text(apArg[1]); if( !zLocale || !zName ){ return; } pUCollator = ucol_open(zLocale, &status); if( !U_SUCCESS(status) ){ icuFunctionError(p, "ucol_open", status); return; } assert(p); rc = sqlite3_create_collation_v2(db, zName, SQLITE_UTF16, (void *)pUCollator, icuCollationColl, icuCollationDel ); if( rc!=SQLITE_OK ){ ucol_close(pUCollator); sqlite3_result_error(p, "Error registering collation function", -1); } }
/* ** A function to test error reporting from user functions. This function ** returns a copy of it's first argument as an error. */ static void test_error( sqlite3_context *pCtx, int nArg, sqlite3_value **argv ){ sqlite3_result_error(pCtx, (char*)sqlite3_value_text(argv[0]), 0); }
/* ** Implementation of the like() SQL function. This function implements ** the build-in LIKE operator. The first argument to the function is the ** pattern and the second argument is the string. So, the SQL statements: ** ** A LIKE B ** ** is implemented as like(B,A). ** ** This same function (with a different compareInfo structure) computes ** the GLOB operator. */ static void likeFunc( sqlite3_context *context, int argc, sqlite3_value **argv ){ const unsigned char *zA, *zB; int escape = 0; int nPat; sqlite3 *db = sqlite3_context_db_handle(context); zB = sqlite3_value_text(argv[0]); zA = sqlite3_value_text(argv[1]); /* Limit the length of the LIKE or GLOB pattern to avoid problems ** of deep recursion and N*N behavior in patternCompare(). */ nPat = sqlite3_value_bytes(argv[0]); testcase( nPat==db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH] ); testcase( nPat==db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]+1 ); if( nPat > db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH] ){ sqlite3_result_error(context, "LIKE or GLOB pattern too complex", -1); return; } assert( zB==sqlite3_value_text(argv[0]) ); /* Encoding did not change */ if( argc==3 ){ /* The escape character string must consist of a single UTF-8 character. ** Otherwise, return an error. */ const unsigned char *zEsc = sqlite3_value_text(argv[2]); if( zEsc==0 ) return; if( sqlite3Utf8CharLen((char*)zEsc, -1)!=1 ){ sqlite3_result_error(context, "ESCAPE expression must be a single character", -1); return; } escape = sqlite3Utf8Read(zEsc, &zEsc); } if( zA && zB ){ struct compareInfo *pInfo = sqlite3_user_data(context); #ifdef SQLITE_TEST sqlite3_like_count++; #endif sqlite3_result_int(context, patternCompare(zB, zA, pInfo, escape)); } }
/* * The BFileReplaceDirectoryFunc() SQL function replace a directory object. */ static void BFileReplaceDirectoryFunc( sqlite3_context *context, int argc, sqlite3_value **argv) { sqlite3 *db; sqlite3_stmt *stmt = NULL; char *alias, *path; int alias_size, path_size, changed = 1; #define DIR_UPD "update "DIRECTORY" set PATH=? where ALIAS=?;" assert(context != NULL && argv != NULL && argc == 2); alias = (char *)sqlite3_value_text(argv[0]); alias_size = sqlite3_value_bytes(argv[0]); path = (char *)sqlite3_value_text(argv[1]); path_size = sqlite3_value_bytes(argv[1]); db = (sqlite3 *)sqlite3_user_data(context); if (sqlite3_prepare(db, DIR_UPD, sizeof(DIR_UPD) - 1, &stmt, NULL)) goto err; if (sqlite3_bind_text(stmt, 1, path, path_size, SQLITE_STATIC)) goto err; if (sqlite3_bind_text(stmt, 2, alias, alias_size, SQLITE_STATIC)) goto err; if (sqlite3_step(stmt) != SQLITE_DONE) goto err; if ((changed = sqlite3_changes(db)) < 1) goto err; sqlite3_finalize(stmt); return; err: if (stmt) sqlite3_finalize(stmt); if (changed < 1) sqlite3_result_error(context, NOT_EXIST_ERR_MSG, -1); else sqlite3_result_error(context, INTERNAL_ERR_MSG, -1); }
/* ** EXPERIMENTAL - This is not an official function. The interface may ** change. This function may disappear. Do not write code that depends ** on this function. ** ** Implementation of the QUOTE() function. This function takes a single ** argument. If the argument is numeric, the return value is the same as ** the argument. If the argument is NULL, the return value is the string ** "NULL". Otherwise, the argument is enclosed in single quotes with ** single-quote escapes. */ static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv) { if( argc<1 ) return; switch( sqlite3_value_type(argv[0]) ) { case SQLITE_NULL: { sqlite3_result_text(context, "NULL", 4, SQLITE_STATIC); break; } case SQLITE_INTEGER: case SQLITE_FLOAT: { sqlite3_result_value(context, argv[0]); break; } case SQLITE_BLOB: { char *zText = 0; int nBlob = sqlite3_value_bytes(argv[0]); char const *zBlob = sqlite3_value_blob(argv[0]); zText = (char *)sqliteMalloc((2*nBlob)+4); if( !zText ) { sqlite3_result_error(context, "out of memory", -1); } else { int i; for(i=0; i<nBlob; i++) { zText[(i*2)+2] = hexdigits[(zBlob[i]>>4)&0x0F]; zText[(i*2)+3] = hexdigits[(zBlob[i])&0x0F]; } zText[(nBlob*2)+2] = '\''; zText[(nBlob*2)+3] = '\0'; zText[0] = 'X'; zText[1] = '\''; sqlite3_result_text(context, zText, -1, SQLITE_TRANSIENT); sqliteFree(zText); } break; } case SQLITE_TEXT: { int i,j,n; const unsigned char *zArg = sqlite3_value_text(argv[0]); char *z; for(i=n=0; zArg[i]; i++) { if( zArg[i]=='\'' ) n++; } z = sqliteMalloc( i+n+3 ); if( z==0 ) return; z[0] = '\''; for(i=0, j=1; zArg[i]; i++) { z[j++] = zArg[i]; if( zArg[i]=='\'' ) { z[j++] = '\''; } } z[j++] = '\''; z[j] = 0; sqlite3_result_text(context, z, j, SQLITE_TRANSIENT); sqliteFree(z); } } }
/* * The BFileCreateDirectoryFunc() SQL function create a directory object. */ static void BFileCreateDirectoryFunc( sqlite3_context *context, int argc, sqlite3_value **argv) { sqlite3 *db; sqlite3_stmt *stmt = NULL; char *alias, *path; int alias_size, path_size, rc = 0; #define DIR_INS "insert into "DIRECTORY" values(?,?);" assert(context != NULL && argv != NULL && argc == 2); alias = (char *)sqlite3_value_text(argv[0]); alias_size = sqlite3_value_bytes(argv[0]); path = (char *)sqlite3_value_text(argv[1]); path_size = sqlite3_value_bytes(argv[1]); db = (sqlite3 *)sqlite3_user_data(context); if (sqlite3_prepare_v2(db, DIR_INS, sizeof(DIR_INS) - 1, &stmt, NULL)) goto err; if (sqlite3_bind_text(stmt, 1, alias, alias_size, SQLITE_STATIC)) goto err; if (sqlite3_bind_text(stmt, 2, path, path_size, SQLITE_STATIC)) goto err; if ((rc = sqlite3_step(stmt)) != SQLITE_DONE) goto err; sqlite3_finalize(stmt); return; err: if (stmt) sqlite3_finalize(stmt); if (rc == SQLITE_CONSTRAINT) sqlite3_result_error(context, UNIQUE_ERR_MSG, -1); else sqlite3_result_error(context, INTERNAL_ERR_MSG, -1); }
SQLITE_EXTENSION_INIT1 static void hunupper(sqlite3_context *ctx, int argc, sqlite3_value **argv) { const unsigned char *input; int length, pos = 0; unsigned char *result; if (argc != 1) { sqlite3_result_error(ctx, "invalid number of arguments", -1); return; } if (sqlite3_value_type(argv[0]) == SQLITE_NULL) return; input = (const unsigned char *) sqlite3_value_text(argv[0]); if (!input) { sqlite3_result_error(ctx, "no input specified", -1); return; } length = strlen((const char*) input); result = (unsigned char *)sqlite3_malloc(length); if (!result) { sqlite3_result_error(ctx, "cannot allocate result", -1); return; } while (pos < length) { result[pos] = input[pos] >= 'a' && input[pos] <= 'z' ? 0xDF & input[pos] : input[pos]; switch (input[pos++]) { case 0xc3: /* á-a1>81 é-a9>89 í-ad>8d ó-b3>93 ö-b6>96 ú-ba>9a ü-bc>9c */ result[pos] = input[pos] & 0xdf; pos++; break; case 0xc5: /* ő-91>90 ű-b1>b0 */ result[pos] = input[pos] & 0xfe; pos++; break; } } sqlite3_result_text(ctx, (char *)result, length, sqlite3_free); return; }
static void handle_lua_error(lua_State *L, sqlite3_context *ctx) { const char *error; size_t error_len; error = lua_tolstring(L, -1, &error_len); sqlite3_result_error(ctx, error, error_len); lua_pop(L, 1); }
/* * Get File size of a BFILE */ static void BFileSizeFunc( sqlite3_context *context, int argc, sqlite3_value **argv) { int rc; sqlite3 *db; int loc_size; off_t size; char *pLoc, *full_path; assert(context != NULL && argc == 1 && argv != NULL); full_path = NULL; loc_size = sqlite3_value_bytes(argv[0]); if (loc_size <= strlen(BFILE_PREFIX)) { sqlite3_result_int(context, -1); return; } db = (sqlite3 *)sqlite3_user_data(context); pLoc = (char *)sqlite3_value_text(argv[0]); assert(db != NULL && pLoc != NULL); rc = get_full_path(db, pLoc, loc_size, &full_path); if (rc) { if (rc == SQLITE_NOMEM) sqlite3_result_error_nomem(context); else sqlite3_result_error(context, "internal error", -1); return; } /* check existence, if not exits at at set size as -1 */ if (access(full_path, F_OK)) sqlite3_result_int(context, -1); else if (__bfile_get_size(full_path, &size) == SQLITE_OK) sqlite3_result_int(context, size); else sqlite3_result_error(context, "internal error", -1); sqlite3_free(full_path); }
/* ** A function to test error reporting from user functions. This function ** returns a copy of its first argument as the error message. If the ** second argument exists, it becomes the error code. */ static void test_error( sqlite3_context *pCtx, int nArg, sqlite3_value **argv ){ sqlite3_result_error(pCtx, (char*)sqlite3_value_text(argv[0]), -1); if( nArg==2 ){ sqlite3_result_error_code(pCtx, sqlite3_value_int(argv[1])); } }
/* ** This function is called when an ICU function called from within ** the implementation of an SQL scalar function returns an error. ** ** The scalar function context passed as the first argument is ** loaded with an error message based on the following two args. */ static void icuFunctionError( sqlite3_context *pCtx, /* SQLite scalar function context */ const char *zName, /* Name of ICU function that failed */ UErrorCode e /* Error code returned by ICU function */ ){ char zBuf[128]; sqlite3_snprintf(128, zBuf, "ICU error: %s(): %s", zName, u_errorName(e)); zBuf[127] = '\0'; sqlite3_result_error(pCtx, zBuf, -1); }
static Fts5MatchinfoCtx *fts5MatchinfoNew( const Fts5ExtensionApi *pApi, /* API offered by current FTS version */ Fts5Context *pFts, /* First arg to pass to pApi functions */ sqlite3_context *pCtx, /* Context for returning error message */ const char *zArg /* Matchinfo flag string */ ){ Fts5MatchinfoCtx *p; int nCol; int nPhrase; int i; int nInt; int nByte; int rc; nCol = pApi->xColumnCount(pFts); nPhrase = pApi->xPhraseCount(pFts); nInt = 0; for(i=0; zArg[i]; i++){ int n = fts5MatchinfoFlagsize(nCol, nPhrase, zArg[i]); if( n<0 ){ char *zErr = sqlite3_mprintf("unrecognized matchinfo flag: %c", zArg[i]); sqlite3_result_error(pCtx, zErr, -1); sqlite3_free(zErr); return 0; } nInt += n; } nByte = sizeof(Fts5MatchinfoCtx) /* The struct itself */ + sizeof(u32) * nInt /* The p->aRet[] array */ + (i+1); /* The p->zArg string */ p = (Fts5MatchinfoCtx*)sqlite3_malloc(nByte); if( p==0 ){ sqlite3_result_error_nomem(pCtx); return 0; } memset(p, 0, nByte); p->nCol = nCol; p->nPhrase = nPhrase; p->aRet = (u32*)&p[1]; p->nRet = nInt; p->zArg = (char*)&p->aRet[nInt]; memcpy(p->zArg, zArg, i); rc = fts5MatchinfoIter(pApi, pFts, p, fts5MatchinfoGlobalCb); if( rc!=SQLITE_OK ){ sqlite3_result_error_code(pCtx, rc); sqlite3_free(p); p = 0; } return p; }
/* ** Implementation of the SQL scalar function for accessing the underlying ** hash table. This function may be called as follows: ** ** SELECT <function-name>(<key-name>); ** SELECT <function-name>(<key-name>, <pointer>); ** ** where <function-name> is the name passed as the second argument ** to the sqlite3Fts3InitHashTable() function (e.g. 'fts3_tokenizer'). ** ** If the <pointer> argument is specified, it must be a blob value ** containing a pointer to be stored as the hash data corresponding ** to the string <key-name>. If <pointer> is not specified, then ** the string <key-name> must already exist in the has table. Otherwise, ** an error is returned. ** ** Whether or not the <pointer> argument is specified, the value returned ** is a blob containing the pointer stored as the hash data corresponding ** to string <key-name> (after the hash-table is updated, if applicable). */ static void scalarFunc( sqlite3_context *context, int argc, sqlite3_value **argv ){ Fts3Hash *pHash; void *pPtr = 0; const unsigned char *zName; int nName; assert( argc==1 || argc==2 ); pHash = (Fts3Hash *)sqlite3_user_data(context); zName = sqlite3_value_text(argv[0]); nName = sqlite3_value_bytes(argv[0])+1; if( argc==2 ){ void *pOld; int n = sqlite3_value_bytes(argv[1]); if( n!=sizeof(pPtr) ){ sqlite3_result_error(context, "argument type mismatch", -1); return; } pPtr = *(void **)sqlite3_value_blob(argv[1]); pOld = sqlite3Fts3HashInsert(pHash, (void *)zName, nName, pPtr); if( pOld==pPtr ){ sqlite3_result_error(context, "out of memory", -1); return; } }else{ pPtr = sqlite3Fts3HashFind(pHash, zName, nName); if( !pPtr ){ char *zErr = sqlite3_mprintf("unknown tokenizer: %s", zName); sqlite3_result_error(context, zErr, -1); sqlite3_free(zErr); return; } } sqlite3_result_blob(context, (void *)&pPtr, sizeof(pPtr), SQLITE_TRANSIENT); }
static void _sqlite3_result_error(sqlite3_context* ctx, const char* errmsg, int len) { /* in older SQLite versions, calling sqlite3_result_error in callbacks * triggers a bug in SQLite that leads either to irritating results or * segfaults, depending on the SQLite version */ #if SQLITE_VERSION_NUMBER >= 3003003 sqlite3_result_error(ctx, errmsg, len); #else PyErr_SetString(pysqlite_OperationalError, errmsg); #endif }
// sql function. takes ESSID and PASSWD, gives PMK void sql_calcpmk(sqlite3_context* context, int argc, sqlite3_value** values) { unsigned char pmk[40]; char* passwd = (char*)sqlite3_value_blob(values[1]); char* essid = (char*)sqlite3_value_blob(values[0]); if (argc < 2 || passwd == 0 || essid == 0) { sqlite3_result_error(context, "SQL function PMK() called with invalid arguments.\n", -1); return; } calc_pmk(passwd,essid,pmk); sqlite3_result_blob(context,pmk,32,SQLITE_TRANSIENT); }
/* ** Compute the difference (in milliseconds) between localtime and UTC ** (a.k.a. GMT) for the time value p where p is in UTC. If no error occurs, ** return this value and set *pRc to SQLITE_OK. ** ** Or, if an error does occur, set *pRc to SQLITE_ERROR. The returned value ** is undefined in this case. */ static sqlite3_int64 localtimeOffset( DateTime *p, /* Date at which to calculate offset */ sqlite3_context *pCtx, /* Write error here if one occurs */ int *pRc /* OUT: Error code. SQLITE_OK or ERROR */ ){ DateTime x, y; time_t t; struct tm sLocal; /* Initialize the contents of sLocal to avoid a compiler warning. */ memset(&sLocal, 0, sizeof(sLocal)); x = *p; computeYMD_HMS(&x); if( x.Y<1971 || x.Y>=2038 ){ /* EVIDENCE-OF: R-55269-29598 The localtime_r() C function normally only ** works for years between 1970 and 2037. For dates outside this range, ** SQLite attempts to map the year into an equivalent year within this ** range, do the calculation, then map the year back. */ x.Y = 2000; x.M = 1; x.D = 1; x.h = 0; x.m = 0; x.s = 0.0; } else { int s = (int)(x.s + 0.5); x.s = s; } x.tz = 0; x.validJD = 0; computeJD(&x); t = (time_t)(x.iJD/1000 - 21086676*(i64)10000); if( osLocaltime(&t, &sLocal) ){ sqlite3_result_error(pCtx, "local time unavailable", -1); *pRc = SQLITE_ERROR; return 0; } y.Y = sLocal.tm_year + 1900; y.M = sLocal.tm_mon + 1; y.D = sLocal.tm_mday; y.h = sLocal.tm_hour; y.m = sLocal.tm_min; y.s = sLocal.tm_sec; y.validYMD = 1; y.validHMS = 1; y.validJD = 0; y.validTZ = 0; computeJD(&y); *pRc = SQLITE_OK; return y.iJD - x.iJD; }
/* ** The following is the implementation of an SQL function that always ** fails with an error message stating that the function is used in the ** wrong context. The sqlite3_overload_function() API might construct ** SQL function that use this routine so that the functions will exist ** for name resolution but are actually overloaded by the xFindFunction ** method of virtual tables. */ void sqlite3InvalidFunction( sqlite3_context *context, /* The function calling context */ int argc, /* Number of arguments to the function */ sqlite3_value **argv /* Value of each argument */ ){ const char *zName = context->pFunc->zName; char *zErr; zErr = sqlite3MPrintf( "unable to use function %s in the requested context", zName); sqlite3_result_error(context, zErr, -1); sqliteFree(zErr); }