static void sqlite3AlterFunctions() { aAlterTableFuncs = new FuncDef[] { FUNCTION("sqlite_rename_table", 2, 0, 0, renameTableFunc), #if !SQLITE_OMIT_TRIGGER FUNCTION("sqlite_rename_trigger", 2, 0, 0, renameTriggerFunc), #endif #if !SQLITE_OMIT_FOREIGN_KEY FUNCTION("sqlite_rename_parent", 3, 0, 0, renameParentFunc), #endif }; int i; #if SQLITE_OMIT_WSD FuncDefHash pHash = GLOBAL(FuncDefHash, sqlite3GlobalFunctions); FuncDef[] aFunc = GLOBAL(FuncDef, aAlterTableFuncs); #else FuncDefHash pHash = sqlite3GlobalFunctions; FuncDef[] aFunc = aAlterTableFuncs; #endif for (i = 0; i < ArraySize(aAlterTableFuncs); i++) { sqlite3FuncDefInsert(pHash, aFunc[i]); } }
static void RegisterDateTimeFunctions() { FuncDefHash hash = Context.GlobalFunctions; FuncDef[] funcs = _dateTimeFuncs; for (int i = 0; i < _dateTimeFuncs.Length; i++) hash.Insert(_dateTimeFuncs[i]); }
public static void Functions() { FuncDefHash hash = Main.GlobalFunctions; FuncDef[] funcs = _alterTableFuncs; for (int i = 0; i < _alterTableFuncs.Length; i++) { Callback.FuncDefInsert(hash, funcs[i]); } }
/* ** Search a FuncDefHash for a function with the given name. Return ** a pointer to the matching FuncDef if found, or 0 if there is no match. */ static FuncDef functionSearch( FuncDefHash pHash, /* Hash table to search */ int h, /* Hash of the name */ string zFunc, /* Name of function */ int nFunc /* Number of bytes in zFunc */ ) { FuncDef p; for (p = pHash.a[h]; p != null; p = p.pHash) { if (p.zName.Length == nFunc && p.zName.StartsWith(zFunc, StringComparison.InvariantCultureIgnoreCase)) { return(p); } } return(null); }
/* ** Search a FuncDefHash for a function with the given name. Return ** a pointer to the matching FuncDef if found, or 0 if there is no match. */ private static FuncDef functionSearch( FuncDefHash pHash, /* Hash table to search */ int h, /* Hash of the name */ string zFunc, /* Name of function */ int nFunc /* Number of bytes in zFunc */ ) { FuncDef p; for (p = pHash.a[h]; p != null; p = p.pHash) { if (sqlite3StrNICmp(p.zName, zFunc, nFunc) == 0 && p.zName.Length == nFunc) { return(p); } } return(null); }
/* ** Insert a new FuncDef into a FuncDefHash hash table. */ static void sqlite3FuncDefInsert( FuncDefHash pHash, /* The hash table into which to insert */ FuncDef pDef /* The function definition to insert */ ) { FuncDef pOther; int nName = sqlite3Strlen30(pDef.zName); u8 c1 = (u8)pDef.zName[0]; int h = (sqlite3UpperToLower[c1] + nName) % ArraySize(pHash.a); pOther = functionSearch(pHash, h, pDef.zName, nName); if (pOther != null) { Debug.Assert(pOther != pDef && pOther.pNext != pDef); pDef.pNext = pOther.pNext; pOther.pNext = pDef; } else { pDef.pNext = null; pDef.pHash = pHash.a[h]; pHash.a[h] = pDef; } }
/* ** Locate a user function given a name, a number of arguments and a flag ** indicating whether the function prefers UTF-16 over UTF-8. Return a ** pointer to the FuncDef structure that defines that function, or return ** NULL if the function does not exist. ** ** If the createFlag argument is true, then a new (blank) FuncDef ** structure is created and liked into the "db" structure if a ** no matching function previously existed. When createFlag is true ** and the nArg parameter is -1, then only a function that accepts ** any number of arguments will be returned. ** ** If createFlag is false and nArg is -1, then the first valid ** function found is returned. A function is valid if either xFunc ** or xStep is non-zero. ** ** If createFlag is false, then a function with the required name and ** number of arguments may be returned even if the eTextRep flag does not ** match that requested. */ static FuncDef sqlite3FindFunction( sqlite3 db, /* An open database */ string zName, /* Name of the function. Not null-terminated */ int nName, /* Number of characters in the name */ int nArg, /* Number of arguments. -1 means any number */ u8 enc, /* Preferred text encoding */ u8 createFlag /* Create new entry if true and does not otherwise exist */ ) { FuncDef p; /* Iterator variable */ FuncDef pBest = null; /* Best match found so far */ int bestScore = 0; int h; /* Hash value */ Debug.Assert(enc == SQLITE_UTF8 || enc == SQLITE_UTF16LE || enc == SQLITE_UTF16BE); h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % ArraySize(db.aFunc.a); /* First search for a match amongst the application-defined functions. */ p = functionSearch(db.aFunc, h, zName, nName); while (p != null) { int score = matchQuality(p, nArg, enc); if (score > bestScore) { pBest = p; bestScore = score; } p = p.pNext; } /* If no match is found, search the built-in functions. ** ** If the SQLITE_PreferBuiltin flag is set, then search the built-in ** functions even if a prior app-defined function was found. And give ** priority to built-in functions. ** ** Except, if createFlag is true, that means that we are trying to ** install a new function. Whatever FuncDef structure is returned it will ** have fields overwritten with new information appropriate for the ** new function. But the FuncDefs for built-in functions are read-only. ** So we must not search for built-ins when creating a new function. */ if (0 == createFlag && (pBest == null || (db.flags & SQLITE_PreferBuiltin) != 0)) { #if SQLITE_OMIT_WSD FuncDefHash pHash = GLOBAL(FuncDefHash, sqlite3GlobalFunctions); #else FuncDefHash pHash = sqlite3GlobalFunctions; #endif bestScore = 0; p = functionSearch(pHash, h, zName, nName); while (p != null) { int score = matchQuality(p, nArg, enc); if (score > bestScore) { pBest = p; bestScore = score; } p = p.pNext; } } /* If the createFlag parameter is true and the search did not reveal an ** exact match for the name, number of arguments and encoding, then add a ** new entry to the hash table and return it. */ if (createFlag != 0 && (bestScore < 6 || pBest.nArg != nArg) && (pBest = new FuncDef()) != null) { //sqlite3DbMallocZero(db, sizeof(*pBest)+nName+1))!=0 ){ //pBest.zName = (char *)&pBest[1]; pBest.nArg = (i16)nArg; pBest.iPrefEnc = enc; pBest.zName = zName; //memcpy(pBest.zName, zName, nName); //pBest.zName[nName] = 0; sqlite3FuncDefInsert(db.aFunc, pBest); } if (pBest != null && (pBest.xStep != null || pBest.xFunc != null || createFlag != 0)) { return(pBest); } return(null); }
static string sqlite3_temp_directory = "";//string sqlite3_temp_directory = 0; /* ** Initialize SQLite. ** ** This routine must be called to initialize the memory allocation, ** VFS, and mutex subsystems prior to doing any serious work with ** SQLite. But as long as you do not compile with SQLITE_OMIT_AUTOINIT ** this routine will be called automatically by key routines such as ** sqlite3_open(). ** ** This routine is a no-op except on its very first call for the process, ** or for the first call after a call to sqlite3_shutdown. ** ** The first thread to call this routine runs the initialization to ** completion. If subsequent threads call this routine before the first ** thread has finished the initialization process, then the subsequent ** threads must block until the first thread finishes with the initialization. ** ** The first thread might call this routine recursively. Recursive ** calls to this routine should not block, of course. Otherwise the ** initialization process would never complete. ** ** Let X be the first thread to enter this routine. Let Y be some other ** thread. Then while the initial invocation of this routine by X is ** incomplete, it is required that: ** ** * Calls to this routine from Y must block until the outer-most ** call by X completes. ** ** * Recursive calls to this routine from thread X return immediately ** without blocking. */ static int sqlite3_initialize() { //-------------------------------------------------------------------- // Under C#, Need to initialize some static variables // if ( sqlite3_version == null ) sqlite3_version = SQLITE_VERSION; if ( sqlite3OpcodeProperty == null ) sqlite3OpcodeProperty = OPFLG_INITIALIZER; if ( sqlite3GlobalConfig == null ) sqlite3GlobalConfig = sqlite3Config; //-------------------------------------------------------------------- sqlite3_mutex pMaster; /* The main static mutex */ int rc; /* Result code */ #if SQLITE_OMIT_WSD rc = sqlite3_wsd_init(4096, 24); if( rc!=SQLITE_OK ){ return rc; } #endif /* If SQLite is already completely initialized, then this call ** to sqlite3_initialize() should be a no-op. But the initialization ** must be complete. So isInit must not be set until the very end ** of this routine. */ if ( sqlite3GlobalConfig.isInit != 0 ) return SQLITE_OK; /* Make sure the mutex subsystem is initialized. If unable to ** initialize the mutex subsystem, return early with the error. ** If the system is so sick that we are unable to allocate a mutex, ** there is not much SQLite is going to be able to do. ** ** The mutex subsystem must take care of serializing its own ** initialization. */ rc = sqlite3MutexInit(); if ( rc != 0 ) return rc; /* Initialize the malloc() system and the recursive pInitMutex mutex. ** This operation is protected by the STATIC_MASTER mutex. Note that ** MutexAlloc() is called for a static mutex prior to initializing the ** malloc subsystem - this implies that the allocation of a static ** mutex must not require support from the malloc subsystem. */ pMaster = sqlite3MutexAlloc( SQLITE_MUTEX_STATIC_MASTER ); //sqlite3_mutex_enter( pMaster ); lock ( pMaster ) { sqlite3GlobalConfig.isMutexInit = 1; if ( sqlite3GlobalConfig.isMallocInit == 0 ) { rc = sqlite3MallocInit(); } if ( rc == SQLITE_OK ) { sqlite3GlobalConfig.isMallocInit = 1; if ( sqlite3GlobalConfig.pInitMutex == null ) { sqlite3GlobalConfig.pInitMutex = sqlite3MutexAlloc( SQLITE_MUTEX_RECURSIVE ); if ( sqlite3GlobalConfig.bCoreMutex && sqlite3GlobalConfig.pInitMutex == null ) { rc = SQLITE_NOMEM; } } } if ( rc == SQLITE_OK ) { sqlite3GlobalConfig.nRefInitMutex++; } } //sqlite3_mutex_leave( pMaster ); /* If rc is not SQLITE_OK at this point, then either the malloc ** subsystem could not be initialized or the system failed to allocate ** the pInitMutex mutex. Return an error in either case. */ if ( rc != SQLITE_OK ) { return rc; } /* Do the rest of the initialization under the recursive mutex so ** that we will be able to handle recursive calls into ** sqlite3_initialize(). The recursive calls normally come through ** sqlite3_os_init() when it invokes sqlite3_vfs_register(), but other ** recursive calls might also be possible. ** ** IMPLEMENTATION-OF: R-00140-37445 SQLite automatically serializes calls ** to the xInit method, so the xInit method need not be threadsafe. ** ** The following mutex is what serializes access to the appdef pcache xInit ** methods. The sqlite3_pcache_methods.xInit() all is embedded in the ** call to sqlite3PcacheInitialize(). */ //sqlite3_mutex_enter( sqlite3GlobalConfig.pInitMutex ); lock ( sqlite3GlobalConfig.pInitMutex ) { if ( sqlite3GlobalConfig.isInit == 0 && sqlite3GlobalConfig.inProgress == 0 ) { sqlite3GlobalConfig.inProgress = 1; #if SQLITE_OMIT_WSD FuncDefHash *pHash = GLOBAL(FuncDefHash, sqlite3GlobalFunctions); memset( pHash, 0, sizeof( sqlite3GlobalFunctions ) ); #else sqlite3GlobalFunctions = new FuncDefHash(); FuncDefHash pHash = sqlite3GlobalFunctions; #endif sqlite3RegisterGlobalFunctions(); if ( sqlite3GlobalConfig.isPCacheInit == 0 ) { rc = sqlite3PcacheInitialize(); } if ( rc == SQLITE_OK ) { sqlite3GlobalConfig.isPCacheInit = 1; rc = sqlite3_os_init(); } if ( rc == SQLITE_OK ) { sqlite3PCacheBufferSetup( sqlite3GlobalConfig.pPage, sqlite3GlobalConfig.szPage, sqlite3GlobalConfig.nPage ); sqlite3GlobalConfig.isInit = 1; } sqlite3GlobalConfig.inProgress = 0; } } //sqlite3_mutex_leave( sqlite3GlobalConfig.pInitMutex ); /* Go back under the static mutex and clean up the recursive ** mutex to prevent a resource leak. */ //sqlite3_mutex_enter( pMaster ); lock ( pMaster ) { sqlite3GlobalConfig.nRefInitMutex--; if ( sqlite3GlobalConfig.nRefInitMutex <= 0 ) { Debug.Assert( sqlite3GlobalConfig.nRefInitMutex == 0 ); //sqlite3_mutex_free( ref sqlite3GlobalConfig.pInitMutex ); sqlite3GlobalConfig.pInitMutex = null; } } //sqlite3_mutex_leave( pMaster ); /* The following is just a sanity check to make sure SQLite has ** been compiled correctly. It is important to run this code, but ** we don't want to run it too often and soak up CPU cycles for no ** reason. So we run it once during initialization. */ #if !NDEBUG #if !SQLITE_OMIT_FLOATING_POINT /* This section of code's only "output" is via Debug.Assert() statements. */ if ( rc == SQLITE_OK ) { //u64 x = ( ( (u64)1 ) << 63 ) - 1; //double y; //Debug.Assert( sizeof( u64 ) == 8 ); //Debug.Assert( sizeof( u64 ) == sizeof( double ) ); //memcpy( &y, x, 8 ); //Debug.Assert( sqlite3IsNaN( y ) ); } #endif #endif return rc; }
/* ** Insert a new FuncDef into a FuncDefHash hash table. */ static void sqlite3FuncDefInsert( FuncDefHash pHash, /* The hash table into which to insert */ FuncDef pDef /* The function definition to insert */ ) { FuncDef pOther; int nName = sqlite3Strlen30( pDef.zName ); u8 c1 = (u8)pDef.zName[0]; int h = ( sqlite3UpperToLower[c1] + nName ) % ArraySize( pHash.a ); pOther = functionSearch( pHash, h, pDef.zName, nName ); if ( pOther != null ) { Debug.Assert( pOther != pDef && pOther.pNext != pDef ); pDef.pNext = pOther.pNext; pOther.pNext = pDef; } else { pDef.pNext = null; pDef.pHash = pHash.a[h]; pHash.a[h] = pDef; } }
/* ** Search a FuncDefHash for a function with the given name. Return ** a pointer to the matching FuncDef if found, or 0 if there is no match. */ static FuncDef functionSearch( FuncDefHash pHash, /* Hash table to search */ int h, /* Hash of the name */ string zFunc, /* Name of function */ int nFunc /* Number of bytes in zFunc */ ) { FuncDef p; for ( p = pHash.a[h]; p != null; p = p.pHash ) { if ( p.zName.Length == nFunc && p.zName.StartsWith( zFunc, StringComparison.InvariantCultureIgnoreCase ) ) { return p; } } return null; }
/* ** Search a FuncDefHash for a function with the given name. Return ** a pointer to the matching FuncDef if found, or 0 if there is no match. */ static FuncDef functionSearch( FuncDefHash pHash, /* Hash table to search */ int h, /* Hash of the name */ string zFunc, /* Name of function */ int nFunc /* Number of bytes in zFunc */ ) { FuncDef p; for ( p = pHash.a[h] ; p != null ; p = p.pHash ) { if ( sqlite3StrNICmp( p.zName, zFunc, nFunc ) == 0 && p.zName.Length == nFunc ) { return p; } } return null; }