📄 main.c
字号:
** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the ** SQLITE_UTF16NATIVE macro. SQLITE_UTF16 is not used internally. ** ** If SQLITE_ANY is specified, add three versions of the function ** to the hash table. */ if( enc==SQLITE_UTF16 ){ enc = SQLITE_UTF16NATIVE; }else if( enc==SQLITE_ANY ){ int rc; rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF8, pUserData, xFunc, xStep, xFinal); if( rc!=SQLITE_OK ) return rc; rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF16LE, pUserData, xFunc, xStep, xFinal); if( rc!=SQLITE_OK ) return rc; enc = SQLITE_UTF16BE; }#else enc = SQLITE_UTF8;#endif /* Check if an existing function is being overridden or deleted. If so, ** and there are active VMs, then return SQLITE_BUSY. If a function ** is being overridden/deleted but there are no active VMs, allow the ** operation to continue but invalidate all precompiled statements. */ p = sqlite3FindFunction(db, zFunctionName, nName, nArg, enc, 0); if( p && p->iPrefEnc==enc && p->nArg==nArg ){ if( db->activeVdbeCnt ){ sqlite3Error(db, SQLITE_BUSY, "Unable to delete/modify user-function due to active statements"); assert( !sqlite3MallocFailed() ); return SQLITE_BUSY; }else{ sqlite3ExpirePreparedStatements(db); } } p = sqlite3FindFunction(db, zFunctionName, nName, nArg, enc, 1); if( p ){ p->flags = 0; p->xFunc = xFunc; p->xStep = xStep; p->xFinalize = xFinal; p->pUserData = pUserData; p->nArg = nArg; } return SQLITE_OK;}/*** Create new user functions.*/int sqlite3_create_function( sqlite3 *db, const char *zFunctionName, int nArg, int enc, void *p, void (*xFunc)(sqlite3_context*,int,sqlite3_value **), void (*xStep)(sqlite3_context*,int,sqlite3_value **), void (*xFinal)(sqlite3_context*)){ int rc; assert( !sqlite3MallocFailed() ); rc = sqlite3CreateFunc(db, zFunctionName, nArg, enc, p, xFunc, xStep, xFinal); return sqlite3ApiExit(db, rc);}#ifndef SQLITE_OMIT_UTF16int sqlite3_create_function16( sqlite3 *db, const void *zFunctionName, int nArg, int eTextRep, void *p, void (*xFunc)(sqlite3_context*,int,sqlite3_value**), void (*xStep)(sqlite3_context*,int,sqlite3_value**), void (*xFinal)(sqlite3_context*)){ int rc; char *zFunc8; assert( !sqlite3MallocFailed() ); zFunc8 = sqlite3Utf16to8(zFunctionName, -1); rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xFunc, xStep, xFinal); sqliteFree(zFunc8); return sqlite3ApiExit(db, rc);}#endif/*** Declare that a function has been overloaded by a virtual table.**** If the function already exists as a regular global function, then** this routine is a no-op. If the function does not exist, then create** a new one that always throws a run-time error. **** When virtual tables intend to provide an overloaded function, they** should call this routine to make sure the global function exists.** A global function must exist in order for name resolution to work** properly.*/int sqlite3_overload_function( sqlite3 *db, const char *zName, int nArg){ int nName = strlen(zName); if( sqlite3FindFunction(db, zName, nName, nArg, SQLITE_UTF8, 0)==0 ){ sqlite3CreateFunc(db, zName, nArg, SQLITE_UTF8, 0, sqlite3InvalidFunction, 0, 0); } return sqlite3ApiExit(db, SQLITE_OK);}#ifndef SQLITE_OMIT_TRACE/*** Register a trace function. The pArg from the previously registered trace** is returned. **** A NULL trace function means that no tracing is executes. A non-NULL** trace is a pointer to a function that is invoked at the start of each** SQL statement.*/void *sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,const char*), void *pArg){ void *pOld = db->pTraceArg; db->xTrace = xTrace; db->pTraceArg = pArg; return pOld;}/*** Register a profile function. The pArg from the previously registered ** profile function is returned. **** A NULL profile function means that no profiling is executes. A non-NULL** profile is a pointer to a function that is invoked at the conclusion of** each SQL statement that is run.*/void *sqlite3_profile( sqlite3 *db, void (*xProfile)(void*,const char*,sqlite_uint64), void *pArg){ void *pOld = db->pProfileArg; db->xProfile = xProfile; db->pProfileArg = pArg; return pOld;}#endif /* SQLITE_OMIT_TRACE *//*** EXPERIMENTAL ******* Register a function to be invoked when a transaction comments.** If the invoked function returns non-zero, then the commit becomes a** rollback.*/void *sqlite3_commit_hook( sqlite3 *db, /* Attach the hook to this database */ int (*xCallback)(void*), /* Function to invoke on each commit */ void *pArg /* Argument to the function */){ void *pOld = db->pCommitArg; db->xCommitCallback = xCallback; db->pCommitArg = pArg; return pOld;}/*** Register a callback to be invoked each time a row is updated,** inserted or deleted using this database connection.*/void *sqlite3_update_hook( sqlite3 *db, /* Attach the hook to this database */ void (*xCallback)(void*,int,char const *,char const *,sqlite_int64), void *pArg /* Argument to the function */){ void *pRet = db->pUpdateArg; db->xUpdateCallback = xCallback; db->pUpdateArg = pArg; return pRet;}/*** Register a callback to be invoked each time a transaction is rolled** back by this database connection.*/void *sqlite3_rollback_hook( sqlite3 *db, /* Attach the hook to this database */ void (*xCallback)(void*), /* Callback function */ void *pArg /* Argument to the function */){ void *pRet = db->pRollbackArg; db->xRollbackCallback = xCallback; db->pRollbackArg = pArg; return pRet;}/*** This routine is called to create a connection to a database BTree** driver. If zFilename is the name of a file, then that file is** opened and used. If zFilename is the magic name ":memory:" then** the database is stored in memory (and is thus forgotten as soon as** the connection is closed.) If zFilename is NULL then the database** is a "virtual" database for transient use only and is deleted as** soon as the connection is closed.**** A virtual database can be either a disk file (that is automatically** deleted when the file is closed) or it an be held entirely in memory,** depending on the values of the TEMP_STORE compile-time macro and the** db->temp_store variable, according to the following chart:**** TEMP_STORE db->temp_store Location of temporary database** ---------- -------------- ------------------------------** 0 any file** 1 1 file** 1 2 memory** 1 0 file** 2 1 file** 2 2 memory** 2 0 memory** 3 any memory*/int sqlite3BtreeFactory( const sqlite3 *db, /* Main database when opening aux otherwise 0 */ const char *zFilename, /* Name of the file containing the BTree database */ int omitJournal, /* if TRUE then do not journal this file */ int nCache, /* How many pages in the page cache */ Btree **ppBtree /* Pointer to new Btree object written here */){ int btree_flags = 0; int rc; assert( ppBtree != 0); if( omitJournal ){ btree_flags |= BTREE_OMIT_JOURNAL; } if( db->flags & SQLITE_NoReadlock ){ btree_flags |= BTREE_NO_READLOCK; } if( zFilename==0 ){#if TEMP_STORE==0 /* Do nothing */#endif#ifndef SQLITE_OMIT_MEMORYDB#if TEMP_STORE==1 if( db->temp_store==2 ) zFilename = ":memory:";#endif#if TEMP_STORE==2 if( db->temp_store!=1 ) zFilename = ":memory:";#endif#if TEMP_STORE==3 zFilename = ":memory:";#endif#endif /* SQLITE_OMIT_MEMORYDB */ } rc = sqlite3BtreeOpen(zFilename, (sqlite3 *)db, ppBtree, btree_flags); if( rc==SQLITE_OK ){ sqlite3BtreeSetBusyHandler(*ppBtree, (void*)&db->busyHandler); sqlite3BtreeSetCacheSize(*ppBtree, nCache); } return rc;}/*** Return UTF-8 encoded English language explanation of the most recent** error.*/const char *sqlite3_errmsg(sqlite3 *db){ const char *z; assert( !sqlite3MallocFailed() ); if( !db ){ return sqlite3ErrStr(SQLITE_NOMEM); } if( sqlite3SafetyCheck(db) || db->errCode==SQLITE_MISUSE ){ return sqlite3ErrStr(SQLITE_MISUSE); } z = (char*)sqlite3_value_text(db->pErr); if( z==0 ){ z = sqlite3ErrStr(db->errCode); } return z;}#ifndef SQLITE_OMIT_UTF16/*** Return UTF-16 encoded English language explanation of the most recent** error.*/const void *sqlite3_errmsg16(sqlite3 *db){ /* Because all the characters in the string are in the unicode ** range 0x00-0xFF, if we pad the big-endian string with a ** zero byte, we can obtain the little-endian string with ** &big_endian[1]. */ static const char outOfMemBe[] = { 0, 'o', 0, 'u', 0, 't', 0, ' ', 0, 'o', 0, 'f', 0, ' ', 0, 'm', 0, 'e', 0, 'm', 0, 'o', 0, 'r', 0, 'y', 0, 0, 0 }; static const char misuseBe [] = { 0, 'l', 0, 'i', 0, 'b', 0, 'r', 0, 'a', 0, 'r', 0, 'y', 0, ' ', 0, 'r', 0, 'o', 0, 'u', 0, 't', 0, 'i', 0, 'n', 0, 'e', 0, ' ', 0, 'c', 0, 'a', 0, 'l', 0, 'l', 0, 'e', 0, 'd', 0, ' ', 0, 'o', 0, 'u', 0, 't', 0, ' ', 0, 'o', 0, 'f', 0, ' ', 0, 's', 0, 'e', 0, 'q', 0, 'u', 0, 'e', 0, 'n', 0, 'c', 0, 'e', 0, 0, 0 }; const void *z; assert( !sqlite3MallocFailed() ); if( !db ){ return (void *)(&outOfMemBe[SQLITE_UTF16NATIVE==SQLITE_UTF16LE?1:0]); } if( sqlite3SafetyCheck(db) || db->errCode==SQLITE_MISUSE ){ return (void *)(&misuseBe[SQLITE_UTF16NATIVE==SQLITE_UTF16LE?1:0]); } z = sqlite3_value_text16(db->pErr); if( z==0 ){ sqlite3ValueSetStr(db->pErr, -1, sqlite3ErrStr(db->errCode), SQLITE_UTF8, SQLITE_STATIC); z = sqlite3_value_text16(db->pErr); } sqlite3ApiExit(0, 0); return z;}#endif /* SQLITE_OMIT_UTF16 *//*** Return the most recent error code generated by an SQLite routine. If NULL is** passed to this function, we assume a malloc() failed during sqlite3_open().*/int sqlite3_errcode(sqlite3 *db){ if( !db || sqlite3MallocFailed() ){ return SQLITE_NOMEM; } if( sqlite3SafetyCheck(db) ){ return SQLITE_MISUSE; } return db->errCode & db->errMask;}/*** Create a new collating function for database "db". The name is zName** and the encoding is enc.*/static int createCollation( sqlite3* db, const char *zName, int enc, void* pCtx, int(*xCompare)(void*,int,const void*,int,const void*), void(*xDel)(void*)){ CollSeq *pColl; int enc2; if( sqlite3SafetyCheck(db) ){ return SQLITE_MISUSE; } /* If SQLITE_UTF16 is specified as the encoding type, transform this ** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the ** SQLITE_UTF16NATIVE macro. SQLITE_UTF16 is not used internally. */ enc2 = enc & ~SQLITE_UTF16_ALIGNED; if( enc2==SQLITE_UTF16 ){ enc2 = SQLITE_UTF16NATIVE; } if( (enc2&~3)!=0 ){ sqlite3Error(db, SQLITE_ERROR, "unknown encoding"); return SQLITE_ERROR; } /* Check if this call is removing or replacing an existing collation ** sequence. If so, and there are active VMs, return busy. If there ** are no active VMs, invalidate any pre-compiled statements. */ pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, strlen(zName), 0); if( pColl && pColl->xCmp ){ if( db->activeVdbeCnt ){ sqlite3Error(db, SQLITE_BUSY, "Unable to delete/modify collation sequence due to active statements"); return SQLITE_BUSY; } sqlite3ExpirePreparedStatements(db); /* If collation sequence pColl was created directly by a call to ** sqlite3_create_collation, and not generated by synthCollSeq(), ** then any copies made by synthCollSeq() need to be invalidated. ** Also, collation destructor - CollSeq.xDel() - function may need ** to be called. */ if( (pColl->enc & ~SQLITE_UTF16_ALIGNED)==enc2 ){ CollSeq *aColl = sqlite3HashFind(&db->aCollSeq, zName, strlen(zName)); int j; for(j=0; j<3; j++){ CollSeq *p = &aColl[j]; if( p->enc==pColl->enc ){ if( p->xDel ){ p->xDel(p->pUser); } p->xCmp = 0; } } } } pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, strlen(zName), 1); if( pColl ){ pColl->xCmp = xCompare; pColl->pUser = pCtx; pColl->xDel = xDel; pColl->enc = enc2 | (enc & SQLITE_UTF16_ALIGNED); } sqlite3Error(db, SQLITE_OK, 0); return SQLITE_OK;}/*** This routine does the work of opening a database on behalf of** sqlite3_open() and sqlite3_open16(). The database filename "zFilename" ** is UTF-8 encoded.*/static int openDatabase( const char *zFilename, /* Database filename UTF-8 encoded */ sqlite3 **ppDb /* OUT: Returned database handle */){ sqlite3 *db; int rc; CollSeq *pColl; assert( !sqlite3MallocFailed() ); /* Allocate the sqlite data structure */ db = sqliteMalloc( sizeof(sqlite3) ); if( db==0 ) goto opendb_out; db->errMask = 0xff; db->priorNewRowid = 0; db->magic = SQLITE_MAGIC_BUSY; db->nDb = 2; db->aDb = db->aDbStatic; db->autoCommit = 1; db->flags |= SQLITE_ShortColNames#if SQLITE_DEFAULT_FILE_FORMAT<4 | SQLITE_LegacyFileFmt#endif#ifdef SQLITE_ENABLE_LOAD_EXTENSION | SQLITE_LoadExtension#endif ; sqlite3HashInit(&db->aFunc, SQLITE_HASH_STRING, 0); sqlite3HashInit(&db->aCollSeq, SQLITE_HASH_STRING, 0);#ifndef SQLITE_OMIT_VIRTUALTABLE sqlite3HashInit(&db->aModule, SQLITE_HASH_STRING, 0);#endif /* Add the default collation sequence BINARY. BINARY works for both UTF-8 ** and UTF-16, so add a version for each to avoid any unnecessary ** conversions. The only error that can occur here is a malloc() failure. */ if( createCollation(db, "BINARY", SQLITE_UTF8, 0, binCollFunc, 0) || createCollation(db, "BINARY", SQLITE_UTF16BE, 0, binCollFunc, 0) || createCollation(db, "BINARY", SQLITE_UTF16LE, 0, binCollFunc, 0) || (db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 6, 0))==0 ){ assert( sqlite3MallocFailed() ); db->magic = SQLITE_MAGIC_CLOSED; goto opendb_out; } /* Also add a UTF-8 case-insensitive collation sequence. */ createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -