main.c
来自「sqlite 3.3.8 支持加密的版本」· C语言 代码 · 共 1,336 行 · 第 1/3 页
C
1,336 行
#ifndef SQLITE_OMIT_UTF16
/* 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.
**
** 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_UTF16
int 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;
if( !db || sqlite3MallocFailed() ){
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;
if( sqlite3MallocFailed() ){
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*)
){
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);
}
pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, strlen(zName), 1);
if( pColl ){
pColl->xCmp = xCompare;
pColl->pUser = pCtx;
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
;
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) ||
createCollation(db, "BINARY", SQLITE_UTF16BE, 0, binCollFunc) ||
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?