⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vdbeapi.c

📁 最新的sqlite3.6.2源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*** 2004 May 26**** 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.******************************************************************************* This file contains code use to implement APIs that are part of the** VDBE.**** $Id: vdbeapi.c,v 1.140 2008/08/21 12:19:44 danielk1977 Exp $*/#include "sqliteInt.h"#include "vdbeInt.h"#if 0 && defined(SQLITE_ENABLE_MEMORY_MANAGEMENT)/*** The following structure contains pointers to the end points of a** doubly-linked list of all compiled SQL statements that may be holding** buffers eligible for release when the sqlite3_release_memory() interface is** invoked. Access to this list is protected by the SQLITE_MUTEX_STATIC_LRU2** mutex.**** Statements are added to the end of this list when sqlite3_reset() is** called. They are removed either when sqlite3_step() or sqlite3_finalize()** is called. When statements are added to this list, the associated ** register array (p->aMem[1..p->nMem]) may contain dynamic buffers that** can be freed using sqlite3VdbeReleaseMemory().**** When statements are added or removed from this list, the mutex** associated with the Vdbe being added or removed (Vdbe.db->mutex) is** already held. The LRU2 mutex is then obtained, blocking if necessary,** the linked-list pointers manipulated and the LRU2 mutex relinquished.*/struct StatementLruList {  Vdbe *pFirst;  Vdbe *pLast;};static struct StatementLruList sqlite3LruStatements;/*** Check that the list looks to be internally consistent. This is used** as part of an assert() statement as follows:****   assert( stmtLruCheck() );*/#ifndef NDEBUGstatic int stmtLruCheck(){  Vdbe *p;  for(p=sqlite3LruStatements.pFirst; p; p=p->pLruNext){    assert(p->pLruNext || p==sqlite3LruStatements.pLast);    assert(!p->pLruNext || p->pLruNext->pLruPrev==p);    assert(p->pLruPrev || p==sqlite3LruStatements.pFirst);    assert(!p->pLruPrev || p->pLruPrev->pLruNext==p);  }  return 1;}#endif/*** Add vdbe p to the end of the statement lru list. It is assumed that** p is not already part of the list when this is called. The lru list** is protected by the SQLITE_MUTEX_STATIC_LRU mutex.*/static void stmtLruAdd(Vdbe *p){  sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU2));  if( p->pLruPrev || p->pLruNext || sqlite3LruStatements.pFirst==p ){    sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU2));    return;  }  assert( stmtLruCheck() );  if( !sqlite3LruStatements.pFirst ){    assert( !sqlite3LruStatements.pLast );    sqlite3LruStatements.pFirst = p;    sqlite3LruStatements.pLast = p;  }else{    assert( !sqlite3LruStatements.pLast->pLruNext );    p->pLruPrev = sqlite3LruStatements.pLast;    sqlite3LruStatements.pLast->pLruNext = p;    sqlite3LruStatements.pLast = p;  }  assert( stmtLruCheck() );  sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU2));}/*** Assuming the SQLITE_MUTEX_STATIC_LRU2 mutext is already held, remove** statement p from the least-recently-used statement list. If the ** statement is not currently part of the list, this call is a no-op.*/static void stmtLruRemoveNomutex(Vdbe *p){  if( p->pLruPrev || p->pLruNext || p==sqlite3LruStatements.pFirst ){    assert( stmtLruCheck() );    if( p->pLruNext ){      p->pLruNext->pLruPrev = p->pLruPrev;    }else{      sqlite3LruStatements.pLast = p->pLruPrev;    }    if( p->pLruPrev ){      p->pLruPrev->pLruNext = p->pLruNext;    }else{      sqlite3LruStatements.pFirst = p->pLruNext;    }    p->pLruNext = 0;    p->pLruPrev = 0;    assert( stmtLruCheck() );  }}/*** Assuming the SQLITE_MUTEX_STATIC_LRU2 mutext is not held, remove** statement p from the least-recently-used statement list. If the ** statement is not currently part of the list, this call is a no-op.*/static void stmtLruRemove(Vdbe *p){  sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU2));  stmtLruRemoveNomutex(p);  sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU2));}/*** Try to release n bytes of memory by freeing buffers associated ** with the memory registers of currently unused vdbes.*/int sqlite3VdbeReleaseMemory(int n){  Vdbe *p;  Vdbe *pNext;  int nFree = 0;  sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU2));  for(p=sqlite3LruStatements.pFirst; p && nFree<n; p=pNext){    pNext = p->pLruNext;    /* For each statement handle in the lru list, attempt to obtain the    ** associated database mutex. If it cannot be obtained, continue    ** to the next statement handle. It is not possible to block on    ** the database mutex - that could cause deadlock.    */    if( SQLITE_OK==sqlite3_mutex_try(p->db->mutex) ){      nFree += sqlite3VdbeReleaseBuffers(p);      stmtLruRemoveNomutex(p);      sqlite3_mutex_leave(p->db->mutex);    }  }  sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU2));  return nFree;}/*** Call sqlite3Reprepare() on the statement. Remove it from the** lru list before doing so, as Reprepare() will free all the** memory register buffers anyway.*/int vdbeReprepare(Vdbe *p){  stmtLruRemove(p);  return sqlite3Reprepare(p);}#else       /* !SQLITE_ENABLE_MEMORY_MANAGEMENT */  #define stmtLruRemove(x)  #define stmtLruAdd(x)  #define vdbeReprepare(x) sqlite3Reprepare(x)#endif/*** Return TRUE (non-zero) of the statement supplied as an argument needs** to be recompiled.  A statement needs to be recompiled whenever the** execution environment changes in a way that would alter the program** that sqlite3_prepare() generates.  For example, if new functions or** collating sequences are registered or if an authorizer function is** added or changed.*/int sqlite3_expired(sqlite3_stmt *pStmt){  Vdbe *p = (Vdbe*)pStmt;  return p==0 || p->expired;}/*** The following routine destroys a virtual machine that is created by** the sqlite3_compile() routine. The integer returned is an SQLITE_** success/failure code that describes the result of executing the virtual** machine.**** This routine sets the error code and string returned by** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16().*/int sqlite3_finalize(sqlite3_stmt *pStmt){  int rc;  if( pStmt==0 ){    rc = SQLITE_OK;  }else{    Vdbe *v = (Vdbe*)pStmt;#ifndef SQLITE_MUTEX_NOOP    sqlite3_mutex *mutex = v->db->mutex;#endif    sqlite3_mutex_enter(mutex);    stmtLruRemove(v);    rc = sqlite3VdbeFinalize(v);    sqlite3_mutex_leave(mutex);  }  return rc;}/*** Terminate the current execution of an SQL statement and reset it** back to its starting state so that it can be reused. A success code from** the prior execution is returned.**** This routine sets the error code and string returned by** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16().*/int sqlite3_reset(sqlite3_stmt *pStmt){  int rc;  if( pStmt==0 ){    rc = SQLITE_OK;  }else{    Vdbe *v = (Vdbe*)pStmt;    sqlite3_mutex_enter(v->db->mutex);    rc = sqlite3VdbeReset(v);    stmtLruAdd(v);    sqlite3VdbeMakeReady(v, -1, 0, 0, 0);    assert( (rc & (v->db->errMask))==rc );    sqlite3_mutex_leave(v->db->mutex);  }  return rc;}/*** Set all the parameters in the compiled SQL statement to NULL.*/int sqlite3_clear_bindings(sqlite3_stmt *pStmt){  int i;  int rc = SQLITE_OK;  Vdbe *p = (Vdbe*)pStmt;#ifndef SQLITE_MUTEX_NOOP  sqlite3_mutex *mutex = ((Vdbe*)pStmt)->db->mutex;#endif  sqlite3_mutex_enter(mutex);  for(i=0; i<p->nVar; i++){    sqlite3VdbeMemRelease(&p->aVar[i]);    p->aVar[i].flags = MEM_Null;  }  sqlite3_mutex_leave(mutex);  return rc;}/**************************** sqlite3_value_  ********************************* The following routines extract information from a Mem or sqlite3_value** structure.*/const void *sqlite3_value_blob(sqlite3_value *pVal){  Mem *p = (Mem*)pVal;  if( p->flags & (MEM_Blob|MEM_Str) ){    sqlite3VdbeMemExpandBlob(p);    p->flags &= ~MEM_Str;    p->flags |= MEM_Blob;    return p->z;  }else{    return sqlite3_value_text(pVal);  }}int sqlite3_value_bytes(sqlite3_value *pVal){  return sqlite3ValueBytes(pVal, SQLITE_UTF8);}int sqlite3_value_bytes16(sqlite3_value *pVal){  return sqlite3ValueBytes(pVal, SQLITE_UTF16NATIVE);}double sqlite3_value_double(sqlite3_value *pVal){  return sqlite3VdbeRealValue((Mem*)pVal);}int sqlite3_value_int(sqlite3_value *pVal){  return sqlite3VdbeIntValue((Mem*)pVal);}sqlite_int64 sqlite3_value_int64(sqlite3_value *pVal){  return sqlite3VdbeIntValue((Mem*)pVal);}const unsigned char *sqlite3_value_text(sqlite3_value *pVal){  return (const unsigned char *)sqlite3ValueText(pVal, SQLITE_UTF8);}#ifndef SQLITE_OMIT_UTF16const void *sqlite3_value_text16(sqlite3_value* pVal){  return sqlite3ValueText(pVal, SQLITE_UTF16NATIVE);}const void *sqlite3_value_text16be(sqlite3_value *pVal){  return sqlite3ValueText(pVal, SQLITE_UTF16BE);}const void *sqlite3_value_text16le(sqlite3_value *pVal){  return sqlite3ValueText(pVal, SQLITE_UTF16LE);}#endif /* SQLITE_OMIT_UTF16 */int sqlite3_value_type(sqlite3_value* pVal){  return pVal->type;}/**************************** sqlite3_result_  ********************************* The following routines are used by user-defined functions to specify** the function result.*/void sqlite3_result_blob(  sqlite3_context *pCtx,   const void *z,   int n,   void (*xDel)(void *)){  assert( n>=0 );  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );  sqlite3VdbeMemSetStr(&pCtx->s, z, n, 0, xDel);}void sqlite3_result_double(sqlite3_context *pCtx, double rVal){  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );  sqlite3VdbeMemSetDouble(&pCtx->s, rVal);}void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );  pCtx->isError = SQLITE_ERROR;  sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF8, SQLITE_TRANSIENT);}#ifndef SQLITE_OMIT_UTF16void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );  pCtx->isError = SQLITE_ERROR;  sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT);}#endifvoid sqlite3_result_int(sqlite3_context *pCtx, int iVal){  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );  sqlite3VdbeMemSetInt64(&pCtx->s, (i64)iVal);}void sqlite3_result_int64(sqlite3_context *pCtx, i64 iVal){  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );  sqlite3VdbeMemSetInt64(&pCtx->s, iVal);}void sqlite3_result_null(sqlite3_context *pCtx){  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );  sqlite3VdbeMemSetNull(&pCtx->s);}void sqlite3_result_text(  sqlite3_context *pCtx,   const char *z,   int n,  void (*xDel)(void *)){  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );  sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF8, xDel);}#ifndef SQLITE_OMIT_UTF16void sqlite3_result_text16(  sqlite3_context *pCtx,   const void *z,   int n,   void (*xDel)(void *)){  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );  sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16NATIVE, xDel);}void sqlite3_result_text16be(  sqlite3_context *pCtx,   const void *z,   int n,   void (*xDel)(void *)){  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );  sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16BE, xDel);}void sqlite3_result_text16le(  sqlite3_context *pCtx,   const void *z,   int n,   void (*xDel)(void *)){  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );  sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16LE, xDel);}#endif /* SQLITE_OMIT_UTF16 */void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );  sqlite3VdbeMemCopy(&pCtx->s, pValue);}void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );  sqlite3VdbeMemSetZeroBlob(&pCtx->s, n);}void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){  pCtx->isError = errCode;}/* Force an SQLITE_TOOBIG error. */void sqlite3_result_error_toobig(sqlite3_context *pCtx){  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );  pCtx->isError = SQLITE_TOOBIG;  sqlite3VdbeMemSetStr(&pCtx->s, "string or blob too big", -1,                        SQLITE_UTF8, SQLITE_STATIC);}/* An SQLITE_NOMEM error. */void sqlite3_result_error_nomem(sqlite3_context *pCtx){  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );  sqlite3VdbeMemSetNull(&pCtx->s);  pCtx->isError = SQLITE_NOMEM;  pCtx->s.db->mallocFailed = 1;}/*** Execute the statement pStmt, either until a row of data is ready, the** statement is completely executed or an error occurs.**** This routine implements the bulk of the logic behind the sqlite_step()** API.  The only thing omitted is the automatic recompile if a ** schema change has occurred.  That detail is handled by the** outer sqlite3_step() wrapper procedure.*/static int sqlite3Step(Vdbe *p){  sqlite3 *db;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -