mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Added support for user-defined normal functions. Support for user-defined
aggregates is pending. (CVS 390) FossilOrigin-Name: c490a1ff951c5d4a2de8e4f8d349189bfaef7f74
This commit is contained in:
83
src/main.c
83
src/main.c
@@ -14,8 +14,9 @@
|
||||
** other files are for internal use by SQLite and should not be
|
||||
** accessed by users of the library.
|
||||
**
|
||||
** $Id: main.c,v 1.61 2002/02/21 12:01:27 drh Exp $
|
||||
** $Id: main.c,v 1.62 2002/02/23 23:45:45 drh Exp $
|
||||
*/
|
||||
#include <ctype.h>
|
||||
#include "sqliteInt.h"
|
||||
#include "os.h"
|
||||
|
||||
@@ -292,6 +293,30 @@ const char sqlite_encoding[] = "UTF-8";
|
||||
const char sqlite_encoding[] = "iso8859";
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Implementation of the upper() and lower() SQL functions.
|
||||
*/
|
||||
static void upperFunc(void *context, int argc, const char **argv){
|
||||
char *z;
|
||||
int i;
|
||||
if( argc<1 || argv[0]==0 ) return;
|
||||
z = sqlite_set_result_string(context, argv[0], -1);
|
||||
if( z==0 ) return;
|
||||
for(i=0; z[i]; i++){
|
||||
if( islower(z[i]) ) z[i] = toupper(z[i]);
|
||||
}
|
||||
}
|
||||
static void lowerFunc(void *context, int argc, const char **argv){
|
||||
char *z;
|
||||
int i;
|
||||
if( argc<1 || argv[0]==0 ) return;
|
||||
z = sqlite_set_result_string(context, argv[0], -1);
|
||||
if( z==0 ) return;
|
||||
for(i=0; z[i]; i++){
|
||||
if( isupper(z[i]) ) z[i] = tolower(z[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Open a new SQLite database. Construct an "sqlite" structure to define
|
||||
** the state of this database and return a pointer to that structure.
|
||||
@@ -313,6 +338,9 @@ sqlite *sqlite_open(const char *zFilename, int mode, char **pzErrMsg){
|
||||
sqliteHashInit(&db->idxHash, SQLITE_HASH_STRING, 0);
|
||||
sqliteHashInit(&db->tblDrop, SQLITE_HASH_POINTER, 0);
|
||||
sqliteHashInit(&db->idxDrop, SQLITE_HASH_POINTER, 0);
|
||||
sqliteHashInit(&db->userFunc, SQLITE_HASH_STRING, 1);
|
||||
sqlite_create_function(db, "upper", 1, upperFunc);
|
||||
sqlite_create_function(db, "lower", 1, lowerFunc);
|
||||
db->onError = OE_Default;
|
||||
db->priorNewRowid = 0;
|
||||
|
||||
@@ -408,11 +436,20 @@ int sqlite_last_insert_rowid(sqlite *db){
|
||||
** Close an existing SQLite database
|
||||
*/
|
||||
void sqlite_close(sqlite *db){
|
||||
HashElem *i;
|
||||
sqliteBtreeClose(db->pBe);
|
||||
clearHashTable(db, 0);
|
||||
if( db->pBeTemp ){
|
||||
sqliteBtreeClose(db->pBeTemp);
|
||||
}
|
||||
for(i=sqliteHashFirst(&db->userFunc); i; i=sqliteHashNext(i)){
|
||||
UserFunc *pFunc, *pNext;
|
||||
for(pFunc = (UserFunc*)sqliteHashData(i); pFunc; pFunc=pNext){
|
||||
pNext = pFunc->pNext;
|
||||
sqliteFree(pFunc);
|
||||
}
|
||||
}
|
||||
sqliteHashClear(&db->userFunc);
|
||||
sqliteFree(db);
|
||||
}
|
||||
|
||||
@@ -613,3 +650,47 @@ void sqlite_freemem(void *p){ free(p); }
|
||||
*/
|
||||
const char *sqlite_libversion(void){ return sqlite_version; }
|
||||
const char *sqlite_libencoding(void){ return sqlite_encoding; }
|
||||
|
||||
/*
|
||||
** Create new user-defined functions. The sqlite_create_function()
|
||||
** routine creates a regular function and sqlite_create_aggregate()
|
||||
** creates an aggregate function.
|
||||
**
|
||||
** Passing a NULL xFunc argument or NULL xStep and xFinalize arguments
|
||||
** disables the function. Calling sqlite_create_function() with the
|
||||
** same name and number of arguments as a prior call to
|
||||
** sqlite_create_aggregate() disables the prior call to
|
||||
** sqlite_create_aggregate(), and vice versa.
|
||||
**
|
||||
** If nArg is -1 it means that this function will accept any number
|
||||
** of arguments, including 0.
|
||||
*/
|
||||
int sqlite_create_function(
|
||||
sqlite *db, /* Add the function to this database connection */
|
||||
const char *zName, /* Name of the function to add */
|
||||
int nArg, /* Number of arguments */
|
||||
void (*xFunc)(void*,int,const char**) /* Implementation of the function */
|
||||
){
|
||||
UserFunc *p;
|
||||
if( db==0 || zName==0 ) return 1;
|
||||
p = sqliteFindUserFunction(db, zName, strlen(zName), nArg, 1);
|
||||
p->xFunc = xFunc;
|
||||
p->xStep = 0;
|
||||
p->xFinalize = 0;
|
||||
return 0;
|
||||
}
|
||||
int sqlite_create_aggregate(
|
||||
sqlite *db, /* Add the function to this database connection */
|
||||
const char *zName, /* Name of the function to add */
|
||||
int nArg, /* Number of arguments */
|
||||
void *(*xStep)(void*,int,const char**), /* The step function */
|
||||
void (*xFinalize)(void*,void*) /* The finalizer */
|
||||
){
|
||||
UserFunc *p;
|
||||
if( db==0 || zName==0 ) return 1;
|
||||
p = sqliteFindUserFunction(db, zName, strlen(zName), nArg, 1);
|
||||
p->xFunc = 0;
|
||||
p->xStep = xStep;
|
||||
p->xFinalize = xFinalize;
|
||||
return 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user