📄 main.c
字号:
/*** 2001 September 15**** The author disclaims copyright to this source code. In place of** a legal notice, here is a blessing:**** May you do good and not evil.** May you find forgiveness for yourself and forgive others.** May you share freely, never taking more than you give.***************************************************************************** Main file for the SQLite library. The routines in this file** implement the programmer interface to the library. Routines in** other files are for internal use by SQLite and should not be** accessed by users of the library.**** $Id: main.c,v 1.494 2008/08/27 19:01:58 danielk1977 Exp $*/#include "sqliteInt.h"#include <ctype.h>#ifdef SQLITE_ENABLE_FTS3# include "fts3.h"#endif#ifdef SQLITE_ENABLE_RTREE# include "rtree.h"#endif/*** The version of the library*/const char sqlite3_version[] = SQLITE_VERSION;const char *sqlite3_libversion(void){ return sqlite3_version; }int sqlite3_libversion_number(void){ return SQLITE_VERSION_NUMBER; }int sqlite3_threadsafe(void){ return SQLITE_THREADSAFE; }#if !defined(SQLITE_OMIT_TRACE) && defined(SQLITE_ENABLE_IOTRACE)/*** If the following function pointer is not NULL and if** SQLITE_ENABLE_IOTRACE is enabled, then messages describing** I/O active are written using this function. These messages** are intended for debugging activity only.*/void (*sqlite3IoTrace)(const char*, ...) = 0;#endif/*** If the following global variable points to a string which is the** name of a directory, then that directory will be used to store** temporary files.**** See also the "PRAGMA temp_store_directory" SQL command.*/char *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.*/int sqlite3_initialize(void){ static int inProgress = 0; /* Prevent recursion */ sqlite3_mutex *pMaster; /* The main static mutex */ int rc; /* Result code */ /* 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( sqlite3Config.isInit ) 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 ) 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); if( !sqlite3Config.isMallocInit ){ rc = sqlite3MallocInit(); } if( rc==SQLITE_OK ){ sqlite3Config.isMallocInit = 1; if( !sqlite3Config.pInitMutex ){ sqlite3Config.pInitMutex = sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE); if( sqlite3Config.bCoreMutex && !sqlite3Config.pInitMutex ){ rc = SQLITE_NOMEM; } } sqlite3Config.nRefInitMutex++; } sqlite3_mutex_leave(pMaster); /* If unable to initialize the malloc subsystem, then return early. ** There is little hope of getting SQLite to run if the malloc ** subsystem cannot be initialized. */ 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. */ sqlite3_mutex_enter(sqlite3Config.pInitMutex); if( sqlite3Config.isInit==0 && inProgress==0 ){ inProgress = 1; memset(&sqlite3GlobalFunctions, 0, sizeof(sqlite3GlobalFunctions)); sqlite3RegisterGlobalFunctions(); rc = sqlite3_os_init(); if( rc==SQLITE_OK ){ rc = sqlite3PcacheInitialize(); sqlite3PCacheBufferSetup(sqlite3Config.pPage, sqlite3Config.szPage, sqlite3Config.nPage); } inProgress = 0; sqlite3Config.isInit = (rc==SQLITE_OK ? 1 : 0); } sqlite3_mutex_leave(sqlite3Config.pInitMutex); /* Go back under the static mutex and clean up the recursive ** mutex to prevent a resource leak. */ sqlite3_mutex_enter(pMaster); sqlite3Config.nRefInitMutex--; if( sqlite3Config.nRefInitMutex<=0 ){ assert( sqlite3Config.nRefInitMutex==0 ); sqlite3_mutex_free(sqlite3Config.pInitMutex); sqlite3Config.pInitMutex = 0; } 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. */#ifndef NDEBUG /* This section of code's only "output" is via assert() statements. */ if ( rc==SQLITE_OK ){ u64 x = (((u64)1)<<63)-1; double y; assert(sizeof(x)==8); assert(sizeof(x)==sizeof(y)); memcpy(&y, &x, 8); assert( sqlite3IsNaN(y) ); }#endif return rc;}/*** Undo the effects of sqlite3_initialize(). Must not be called while** there are outstanding database connections or memory allocations or** while any part of SQLite is otherwise in use in any thread. This** routine is not threadsafe. Not by a long shot.*/int sqlite3_shutdown(void){ sqlite3Config.isMallocInit = 0; sqlite3PcacheShutdown(); if( sqlite3Config.isInit ){ sqlite3_os_end(); } if( sqlite3Config.m.xShutdown ){ sqlite3MallocEnd(); } if( sqlite3Config.mutex.xMutexEnd ){ sqlite3MutexEnd(); } sqlite3Config.isInit = 0; return SQLITE_OK;}/*** This API allows applications to modify the global configuration of** the SQLite library at run-time.**** This routine should only be called when there are no outstanding** database connections or memory allocations. This routine is not** threadsafe. Failure to heed these warnings can lead to unpredictable** behavior.*/int sqlite3_config(int op, ...){ va_list ap; int rc = SQLITE_OK; /* sqlite3_config() shall return SQLITE_MISUSE if it is invoked while ** the SQLite library is in use. */ if( sqlite3Config.isInit ) return SQLITE_MISUSE; va_start(ap, op); switch( op ){ case SQLITE_CONFIG_SINGLETHREAD: { /* Disable all mutexing */ sqlite3Config.bCoreMutex = 0; sqlite3Config.bFullMutex = 0; break; } case SQLITE_CONFIG_MULTITHREAD: { /* Disable mutexing of database connections */ /* Enable mutexing of core data structures */ sqlite3Config.bCoreMutex = 1; sqlite3Config.bFullMutex = 0; break; } case SQLITE_CONFIG_SERIALIZED: { /* Enable all mutexing */ sqlite3Config.bCoreMutex = 1; sqlite3Config.bFullMutex = 1; break; } case SQLITE_CONFIG_MALLOC: { /* Specify an alternative malloc implementation */ sqlite3Config.m = *va_arg(ap, sqlite3_mem_methods*); break; } case SQLITE_CONFIG_GETMALLOC: { /* Retrieve the current malloc() implementation */ if( sqlite3Config.m.xMalloc==0 ) sqlite3MemSetDefault(); *va_arg(ap, sqlite3_mem_methods*) = sqlite3Config.m; break; } case SQLITE_CONFIG_MUTEX: { /* Specify an alternative mutex implementation */ sqlite3Config.mutex = *va_arg(ap, sqlite3_mutex_methods*); break; } case SQLITE_CONFIG_GETMUTEX: { /* Retrieve the current mutex implementation */ *va_arg(ap, sqlite3_mutex_methods*) = sqlite3Config.mutex; break; } case SQLITE_CONFIG_MEMSTATUS: { /* Enable or disable the malloc status collection */ sqlite3Config.bMemstat = va_arg(ap, int); break; } case SQLITE_CONFIG_SCRATCH: { /* Designate a buffer for scratch memory space */ sqlite3Config.pScratch = va_arg(ap, void*); sqlite3Config.szScratch = va_arg(ap, int); sqlite3Config.nScratch = va_arg(ap, int); break; } case SQLITE_CONFIG_PAGECACHE: { /* Designate a buffer for scratch memory space */ sqlite3Config.pPage = va_arg(ap, void*); sqlite3Config.szPage = va_arg(ap, int); sqlite3Config.nPage = va_arg(ap, int); break; }#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5) case SQLITE_CONFIG_HEAP: { /* Designate a buffer for heap memory space */ sqlite3Config.pHeap = va_arg(ap, void*); sqlite3Config.nHeap = va_arg(ap, int); sqlite3Config.mnReq = va_arg(ap, int); if( sqlite3Config.pHeap==0 ){ /* If the heap pointer is NULL, then restore the malloc implementation ** back to NULL pointers too. This will cause the malloc to go ** back to its default implementation when sqlite3_initialize() is ** run. */ memset(&sqlite3Config.m, 0, sizeof(sqlite3Config.m)); }else{ /* The heap pointer is not NULL, then install one of the ** mem5.c/mem3.c methods. If neither ENABLE_MEMSYS3 nor ** ENABLE_MEMSYS5 is defined, return an error. ** the default case and return an error. */#ifdef SQLITE_ENABLE_MEMSYS3 sqlite3Config.m = *sqlite3MemGetMemsys3();#endif#ifdef SQLITE_ENABLE_MEMSYS5 sqlite3Config.m = *sqlite3MemGetMemsys5();#endif } break; }#endif#if defined(SQLITE_ENABLE_MEMSYS6) case SQLITE_CONFIG_CHUNKALLOC: { sqlite3Config.nSmall = va_arg(ap, int); sqlite3Config.m = *sqlite3MemGetMemsys6(); break; }#endif case SQLITE_CONFIG_LOOKASIDE: { sqlite3Config.szLookaside = va_arg(ap, int); sqlite3Config.nLookaside = va_arg(ap, int); break; } default: { rc = SQLITE_ERROR; break; } } va_end(ap); return rc;}/*** Set up the lookaside buffers for a database connection.** Return SQLITE_OK on success. ** If lookaside is already active, return SQLITE_BUSY.**** The sz parameter is the number of bytes in each lookaside slot.** The cnt parameter is the number of slots. If pStart is NULL the** space for the lookaside memory is obtained from sqlite3_malloc().** If pStart is not NULL then it is sz*cnt bytes of memory to use for** the lookaside memory.*/static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){ void *pStart; if( db->lookaside.nOut ){ return SQLITE_BUSY; } if( sz<0 ) sz = 0; if( cnt<0 ) cnt = 0; if( pBuf==0 ){ sz = (sz + 7)&~7; sqlite3BeginBenignMalloc(); pStart = sqlite3Malloc( sz*cnt ); sqlite3EndBenignMalloc(); }else{ sz = sz&~7; pStart = pBuf; } if( db->lookaside.bMalloced ){ sqlite3_free(db->lookaside.pStart); } db->lookaside.pStart = pStart; db->lookaside.pFree = 0; db->lookaside.sz = sz; db->lookaside.bMalloced = pBuf==0; if( pStart ){ int i; LookasideSlot *p; p = (LookasideSlot*)pStart; for(i=cnt-1; i>=0; i--){ p->pNext = db->lookaside.pFree; db->lookaside.pFree = p; p = (LookasideSlot*)&((u8*)p)[sz]; } db->lookaside.pEnd = p; db->lookaside.bEnabled = 1; }else{ db->lookaside.pEnd = 0; db->lookaside.bEnabled = 0; } return SQLITE_OK;}/*** Configuration settings for an individual database connection*/int sqlite3_db_config(sqlite3 *db, int op, ...){ va_list ap; int rc; va_start(ap, op); switch( op ){ case SQLITE_DBCONFIG_LOOKASIDE: { void *pBuf = va_arg(ap, void*); int sz = va_arg(ap, int); int cnt = va_arg(ap, int); rc = setupLookaside(db, pBuf, sz, cnt); break; } default: { rc = SQLITE_ERROR; break; } } va_end(ap); return rc;}/*** Routine needed to support the testcase() macro.*/#ifdef SQLITE_COVERAGE_TESTvoid sqlite3Coverage(int x){ static int dummy = 0; dummy += x;}#endif/*** Return true if the buffer z[0..n-1] contains all spaces.*/static int allSpaces(const char *z, int n){ while( n>0 && z[n-1]==' ' ){ n--; } return n==0;}/*** This is the default collating function named "BINARY" which is always** available.**** If the padFlag argument is not NULL then space padding at the end** of strings is ignored. This implements the RTRIM collation.*/static int binCollFunc( void *padFlag, int nKey1, const void *pKey1, int nKey2, const void *pKey2){ int rc, n; n = nKey1<nKey2 ? nKey1 : nKey2; rc = memcmp(pKey1, pKey2, n); if( rc==0 ){ if( padFlag && allSpaces(((char*)pKey1)+n, nKey1-n) && allSpaces(((char*)pKey2)+n, nKey2-n) ){ /* Leave rc unchanged at 0 */ }else{ rc = nKey1 - nKey2; } } return rc;}/*** Another built-in collating sequence: NOCASE. **** This collating sequence is intended to be used for "case independant** comparison". SQLite's knowledge of upper and lower case equivalents** extends only to the 26 characters used in the English language.**** At the moment there is only a UTF-8 implementation.*/static int nocaseCollatingFunc( void *NotUsed, int nKey1, const void *pKey1, int nKey2, const void *pKey2){ int r = sqlite3StrNICmp( (const char *)pKey1, (const char *)pKey2, (nKey1<nKey2)?nKey1:nKey2); if( 0==r ){ r = nKey1-nKey2; } return r;}/*** Return the ROWID of the most recent insert*/sqlite_int64 sqlite3_last_insert_rowid(sqlite3 *db){ return db->lastRowid;}/*** Return the number of changes in the most recent call to sqlite3_exec().*/int sqlite3_changes(sqlite3 *db){ return db->nChange;}/*** Return the number of changes since the database handle was opened.*/int sqlite3_total_changes(sqlite3 *db){ return db->nTotalChange;}/*** Close an existing SQLite database
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -