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

📄 main.c

📁 一个小型的嵌入式数据库
💻 C
📖 第 1 页 / 共 3 页
字号:
    return SQLITE_BUSY;  }  assert( !sqlite3SafetyCheck(db) );  /* FIX ME: db->magic may be set to SQLITE_MAGIC_CLOSED if the database  ** cannot be opened for some reason. So this routine needs to run in  ** that case. But maybe there should be an extra magic value for the  ** "failed to open" state.  */  if( db->magic!=SQLITE_MAGIC_CLOSED && sqlite3SafetyOn(db) ){    /* printf("DID NOT CLOSE\n"); fflush(stdout); */    return SQLITE_ERROR;  }  for(j=0; j<db->nDb; j++){    struct Db *pDb = &db->aDb[j];    if( pDb->pBt ){      sqlite3BtreeClose(pDb->pBt);      pDb->pBt = 0;    }  }  sqlite3ResetInternalSchema(db, 0);  assert( db->nDb<=2 );  assert( db->aDb==db->aDbStatic );  for(i=sqliteHashFirst(&db->aFunc); i; i=sqliteHashNext(i)){    FuncDef *pFunc, *pNext;    for(pFunc = (FuncDef*)sqliteHashData(i); pFunc; pFunc=pNext){      pNext = pFunc->pNext;      sqliteFree(pFunc);    }  }  for(i=sqliteHashFirst(&db->aCollSeq); i; i=sqliteHashNext(i)){    CollSeq *pColl = (CollSeq *)sqliteHashData(i);    sqliteFree(pColl);  }  sqlite3HashClear(&db->aCollSeq);  sqlite3HashClear(&db->aFunc);  sqlite3Error(db, SQLITE_OK, 0); /* Deallocates any cached error strings. */  if( db->pValue ){    sqlite3ValueFree(db->pValue);  }  if( db->pErr ){    sqlite3ValueFree(db->pErr);  }  db->magic = SQLITE_MAGIC_ERROR;  sqliteFree(db);  return SQLITE_OK;}/*** Rollback all database files.*/void sqlite3RollbackAll(sqlite3 *db){  int i;  for(i=0; i<db->nDb; i++){    if( db->aDb[i].pBt ){      sqlite3BtreeRollback(db->aDb[i].pBt);      db->aDb[i].inTrans = 0;    }  }  sqlite3ResetInternalSchema(db, 0);}/*** Return a static string that describes the kind of error specified in the** argument.*/const char *sqlite3ErrStr(int rc){  const char *z;  switch( rc ){    case SQLITE_ROW:    case SQLITE_DONE:    case SQLITE_OK:         z = "not an error";                          break;    case SQLITE_ERROR:      z = "SQL logic error or missing database";   break;    case SQLITE_INTERNAL:   z = "internal SQLite implementation flaw";   break;    case SQLITE_PERM:       z = "access permission denied";              break;    case SQLITE_ABORT:      z = "callback requested query abort";        break;    case SQLITE_BUSY:       z = "database is locked";                    break;    case SQLITE_LOCKED:     z = "database table is locked";              break;    case SQLITE_NOMEM:      z = "out of memory";                         break;    case SQLITE_READONLY:   z = "attempt to write a readonly database";  break;    case SQLITE_INTERRUPT:  z = "interrupted";                           break;    case SQLITE_IOERR:      z = "disk I/O error";                        break;    case SQLITE_CORRUPT:    z = "database disk image is malformed";      break;    case SQLITE_NOTFOUND:   z = "table or record not found";             break;    case SQLITE_FULL:       z = "database is full";                      break;    case SQLITE_CANTOPEN:   z = "unable to open database file";          break;    case SQLITE_PROTOCOL:   z = "database locking protocol failure";     break;    case SQLITE_EMPTY:      z = "table contains no data";                break;    case SQLITE_SCHEMA:     z = "database schema has changed";           break;    case SQLITE_TOOBIG:     z = "too much data for one table row";       break;    case SQLITE_CONSTRAINT: z = "constraint failed";                     break;    case SQLITE_MISMATCH:   z = "datatype mismatch";                     break;    case SQLITE_MISUSE:     z = "library routine called out of sequence";break;    case SQLITE_NOLFS:      z = "kernel lacks large file support";       break;    case SQLITE_AUTH:       z = "authorization denied";                  break;    case SQLITE_FORMAT:     z = "auxiliary database format error";       break;    case SQLITE_RANGE:      z = "bind or column index out of range";     break;    case SQLITE_NOTADB:     z = "file is encrypted or is not a database";break;    default:                z = "unknown error";                         break;  }  return z;}/*** This routine implements a busy callback that sleeps and tries** again until a timeout value is reached.  The timeout value is** an integer number of milliseconds passed in as the first** argument.*/static int sqliteDefaultBusyCallback( void *Timeout,           /* Maximum amount of time to wait */ int count                /* Number of times table has been busy */){#if SQLITE_MIN_SLEEP_MS==1  static const char delays[] =     { 1, 2, 5, 10, 15, 20, 25, 25,  25,  50,  50,  50, 100};  static const short int totals[] =     { 0, 1, 3,  8, 18, 33, 53, 78, 103, 128, 178, 228, 287};# define NDELAY (sizeof(delays)/sizeof(delays[0]))  ptr timeout = (ptr)Timeout;  ptr delay, prior;  if( count <= NDELAY ){    delay = delays[count-1];    prior = totals[count-1];  }else{    delay = delays[NDELAY-1];    prior = totals[NDELAY-1] + delay*(count-NDELAY-1);  }  if( prior + delay > timeout ){    delay = timeout - prior;    if( delay<=0 ) return 0;  }  sqlite3OsSleep(delay);  return 1;#else  int timeout = (int)Timeout;  if( (count+1)*1000 > timeout ){    return 0;  }  sqlite3OsSleep(1000);  return 1;#endif}/*** This routine sets the busy callback for an Sqlite database to the** given callback function with the given argument.*/int sqlite3_busy_handler(  sqlite3 *db,  int (*xBusy)(void*,int),  void *pArg){  if( sqlite3SafetyCheck(db) ){    return SQLITE_MISUSE;  }  db->busyHandler.xFunc = xBusy;  db->busyHandler.pArg = pArg;  return SQLITE_OK;}#ifndef SQLITE_OMIT_PROGRESS_CALLBACK/*** This routine sets the progress callback for an Sqlite database to the** given callback function with the given argument. The progress callback will** be invoked every nOps opcodes.*/void sqlite3_progress_handler(  sqlite3 *db,   int nOps,  int (*xProgress)(void*),   void *pArg){  if( !sqlite3SafetyCheck(db) ){    if( nOps>0 ){      db->xProgress = xProgress;      db->nProgressOps = nOps;      db->pProgressArg = pArg;    }else{      db->xProgress = 0;      db->nProgressOps = 0;      db->pProgressArg = 0;    }  }}#endif/*** This routine installs a default busy handler that waits for the** specified number of milliseconds before returning 0.*/int sqlite3_busy_timeout(sqlite3 *db, int ms){  if( ms>0 ){    sqlite3_busy_handler(db, sqliteDefaultBusyCallback, (void*)(ptr)ms);  }else{    sqlite3_busy_handler(db, 0, 0);  }  return SQLITE_OK;}/*** Cause any pending operation to stop at its earliest opportunity.*/void sqlite3_interrupt(sqlite3 *db){  if( !sqlite3SafetyCheck(db) ){    db->flags |= SQLITE_Interrupt;  }}/*** Windows systems should call this routine to free memory that** is returned in the in the errmsg parameter of sqlite3_open() when** SQLite is a DLL.  For some reason, it does not work to call free()** directly.**** Note that we need to call free() not sqliteFree() here.*/void sqlite3_free(char *p){ free(p); }/*** Create new user functions.*/int sqlite3_create_function(  sqlite3 *db,  const char *zFunctionName,  int nArg,  int enc,  void *pUserData,  void (*xFunc)(sqlite3_context*,int,sqlite3_value **),  void (*xStep)(sqlite3_context*,int,sqlite3_value **),  void (*xFinal)(sqlite3_context*)){  FuncDef *p;  int nName;  if( sqlite3SafetyCheck(db) ){    return SQLITE_MISUSE;  }  if( zFunctionName==0 ||      (xFunc && (xFinal || xStep)) ||       (!xFunc && (xFinal && !xStep)) ||      (!xFunc && (!xFinal && xStep)) ||      (nArg<-1 || nArg>127) ||      (255<(nName = strlen(zFunctionName))) ){    return SQLITE_ERROR;  }  #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 = sqlite3_create_function(db, zFunctionName, nArg, SQLITE_UTF8,         pUserData, xFunc, xStep, xFinal);    if( rc!=SQLITE_OK ) return rc;    rc = sqlite3_create_function(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");      return SQLITE_BUSY;    }else{      sqlite3ExpirePreparedStatements(db);    }  }  p = sqlite3FindFunction(db, zFunctionName, nName, nArg, enc, 1);  if( p==0 ) return SQLITE_NOMEM;  p->xFunc = xFunc;  p->xStep = xStep;  p->xFinalize = xFinal;  p->pUserData = pUserData;  return SQLITE_OK;}#ifndef SQLITE_OMIT_UTF16int sqlite3_create_function16(  sqlite3 *db,  const void *zFunctionName,  int nArg,  int eTextRep,  void *pUserData,  void (*xFunc)(sqlite3_context*,int,sqlite3_value**),  void (*xStep)(sqlite3_context*,int,sqlite3_value**),  void (*xFinal)(sqlite3_context*)){  int rc;  char const *zFunc8;  sqlite3_value *pTmp;  if( sqlite3SafetyCheck(db) ){    return SQLITE_MISUSE;  }  pTmp = sqlite3GetTransientValue(db);  sqlite3ValueSetStr(pTmp, -1, zFunctionName, SQLITE_UTF16NATIVE,SQLITE_STATIC);  zFunc8 = sqlite3ValueText(pTmp, SQLITE_UTF8);  if( !zFunc8 ){    return SQLITE_NOMEM;  }  rc = sqlite3_create_function(db, zFunc8, nArg, eTextRep,       pUserData, xFunc, xStep, xFinal);  return rc;}#endif/*** 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** sqlite3_exec().*/void *sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,const char*), void *pArg){  void *pOld = db->pTraceArg;  db->xTrace = xTrace;  db->pTraceArg = pArg;  return pOld;}/*** EXPERIMENTAL ******* Register a function to be invoked when a transaction comments.** If either 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;}/*** 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 for temporary use only and is deleted as soon as the connection** is closed.**** A temporary database can be either a disk file (that is automatically** deleted when the file is closed) or a set of red-black trees held 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, 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( sqlite3_malloc_failed ){    return sqlite3ErrStr(SQLITE_NOMEM);  }  if( sqlite3SafetyCheck(db) || db->errCode==SQLITE_MISUSE ){    return sqlite3ErrStr(SQLITE_MISUSE);  }  z = 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  };

⌨️ 快捷键说明

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