📄 main.c
字号:
db->file_format>=2 ? init_script : older_init_script, pzErrMsg); }else{ char *zSql = 0; sqliteSetString(&zSql, "SELECT type, name, rootpage, sql, ", zDbNum, " FROM \"", db->aDb[iDb].zName, "\".sqlite_master", 0); sqliteRunParser(&sParse, zSql, pzErrMsg); sqliteFree(zSql); } sqliteBtreeCloseCursor(curMain); if( sqlite_malloc_failed ){ sqliteSetString(pzErrMsg, "out of memory", 0); sParse.rc = SQLITE_NOMEM; sqliteResetInternalSchema(db, 0); } if( sParse.rc==SQLITE_OK ){ DbSetProperty(db, iDb, DB_SchemaLoaded); if( iDb==0 ){ DbSetProperty(db, 1, DB_SchemaLoaded); } }else{ sqliteResetInternalSchema(db, iDb); } return sParse.rc;}/*** Initialize all database files - the main database file, the file** used to store temporary tables, and any additional database files** created using ATTACH statements. Return a success code. If an** error occurs, write an error message into *pzErrMsg.**** After the database is initialized, the SQLITE_Initialized** bit is set in the flags field of the sqlite structure. An** attempt is made to initialize the database as soon as it** is opened. If that fails (perhaps because another process** has the sqlite_master table locked) than another attempt** is made the first time the database is accessed.*/int sqliteInit(sqlite *db, char **pzErrMsg){ int i, rc; assert( (db->flags & SQLITE_Initialized)==0 ); rc = SQLITE_OK; for(i=0; rc==SQLITE_OK && i<db->nDb; i++){ if( DbHasProperty(db, i, DB_SchemaLoaded) ) continue; assert( i!=1 ); /* Should have been initialized together with 0 */ rc = sqliteInitOne(db, i, pzErrMsg); } if( rc==SQLITE_OK ){ db->flags |= SQLITE_Initialized; sqliteCommitInternalChanges(db); }else{ db->flags &= ~SQLITE_Initialized; } return rc;}/*** The version of the library*/const char rcsid[] = "@(#) \044Id: SQLite version " SQLITE_VERSION " $";const char sqlite_version[] = SQLITE_VERSION;/*** Does the library expect data to be encoded as UTF-8 or iso8859? The** following global constant always lets us know.*/#ifdef SQLITE_UTF8const char sqlite_encoding[] = "UTF-8";#elseconst char sqlite_encoding[] = "iso8859";#endif/*** Open a new SQLite database. Construct an "sqlite" structure to define** the state of this database and return a pointer to that structure.**** An attempt is made to initialize the in-memory data structures that** hold the database schema. But if this fails (because the schema file** is locked) then that step is deferred until the first call to** sqlite_exec().*/sqlite *sqlite_open(const char *zFilename, int mode, char **pzErrMsg){ sqlite *db; int rc, i; /* Allocate the sqlite data structure */ db = sqliteMalloc( sizeof(sqlite) ); if( pzErrMsg ) *pzErrMsg = 0; if( db==0 ) goto no_mem_on_open; db->onError = OE_Default; db->priorNewRowid = 0; db->magic = SQLITE_MAGIC_BUSY; db->nDb = 2; db->aDb = db->aDbStatic; sqliteHashInit(&db->aFunc, SQLITE_HASH_STRING, 1); for(i=0; i<db->nDb; i++){ sqliteHashInit(&db->aDb[i].tblHash, SQLITE_HASH_STRING, 0); sqliteHashInit(&db->aDb[i].idxHash, SQLITE_HASH_STRING, 0); sqliteHashInit(&db->aDb[i].trigHash, SQLITE_HASH_STRING, 0); sqliteHashInit(&db->aDb[i].aFKey, SQLITE_HASH_STRING, 1); } /* Open the backend database driver */ if( zFilename[0]==':' && strcmp(zFilename,":memory:")==0 ){ db->temp_store = 2; } rc = sqliteBtreeFactory(db, zFilename, 0, MAX_PAGES, &db->aDb[0].pBt); if( rc!=SQLITE_OK ){ switch( rc ){ default: { sqliteSetString(pzErrMsg, "unable to open database: ", zFilename, 0); } } sqliteFree(db); sqliteStrRealloc(pzErrMsg); return 0; } db->aDb[0].zName = "main"; db->aDb[1].zName = "temp"; /* Attempt to read the schema */ sqliteRegisterBuiltinFunctions(db); rc = sqliteInit(db, pzErrMsg); db->magic = SQLITE_MAGIC_OPEN; if( sqlite_malloc_failed ){ sqlite_close(db); goto no_mem_on_open; }else if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){ sqlite_close(db); sqliteStrRealloc(pzErrMsg); return 0; }else if( pzErrMsg ){ sqliteFree(*pzErrMsg); *pzErrMsg = 0; } /* If the database is in formats 1 or 2, then upgrade it to ** version 3. This will reconstruct all indices. If the ** upgrade fails for any reason (ex: out of disk space, database ** is read only, interrupt received, etc.) then refuse to open. */ if( rc==SQLITE_OK && db->file_format<3 ){ char *zErr = 0; InitData initData; int meta[SQLITE_N_BTREE_META]; initData.db = db; initData.pzErrMsg = &zErr; db->file_format = 3; rc = sqlite_exec(db, "BEGIN; SELECT name FROM sqlite_master WHERE type='table';", upgrade_3_callback, &initData, &zErr); if( rc==SQLITE_OK ){ sqliteBtreeGetMeta(db->aDb[0].pBt, meta); meta[2] = 4; sqliteBtreeUpdateMeta(db->aDb[0].pBt, meta); sqlite_exec(db, "COMMIT", 0, 0, 0); } if( rc!=SQLITE_OK ){ sqliteSetString(pzErrMsg, "unable to upgrade database to the version 2.6 format", zErr ? ": " : 0, zErr, 0); sqlite_freemem(zErr); sqliteStrRealloc(pzErrMsg); sqlite_close(db); return 0; } sqlite_freemem(zErr); } /* Return a pointer to the newly opened database structure */ return db;no_mem_on_open: sqliteSetString(pzErrMsg, "out of memory", 0); sqliteStrRealloc(pzErrMsg); return 0;}/*** Return the ROWID of the most recent insert*/int sqlite_last_insert_rowid(sqlite *db){ return db->lastRowid;}/*** Return the number of changes in the most recent call to sqlite_exec().*/int sqlite_changes(sqlite *db){ return db->nChange;}/*** Close an existing SQLite database*/void sqlite_close(sqlite *db){ HashElem *i; int j; db->want_to_close = 1; if( sqliteSafetyCheck(db) || sqliteSafetyOn(db) ){ /* printf("DID NOT CLOSE\n"); fflush(stdout); */ return; } db->magic = SQLITE_MAGIC_CLOSED; for(j=0; j<db->nDb; j++){ if( db->aDb[j].pBt ){ sqliteBtreeClose(db->aDb[j].pBt); db->aDb[j].pBt = 0; } if( j>=2 ){ sqliteFree(db->aDb[j].zName); db->aDb[j].zName = 0; } } sqliteResetInternalSchema(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); } } sqliteHashClear(&db->aFunc); sqliteFree(db);}/*** Rollback all database files.*/void sqliteRollbackAll(sqlite *db){ int i; for(i=0; i<db->nDb; i++){ if( db->aDb[i].pBt ){ sqliteBtreeRollback(db->aDb[i].pBt); db->aDb[i].inTrans = 0; } } sqliteRollbackInternalChanges(db);}/*** This routine does the work of either sqlite_exec() or sqlite_compile().** It works like sqlite_exec() if pVm==NULL and it works like sqlite_compile()** otherwise.*/static int sqliteMain( sqlite *db, /* The database on which the SQL executes */ const char *zSql, /* The SQL to be executed */ sqlite_callback xCallback, /* Invoke this callback routine */ void *pArg, /* First argument to xCallback() */ const char **pzTail, /* OUT: Next statement after the first */ sqlite_vm **ppVm, /* OUT: The virtual machine */ char **pzErrMsg /* OUT: Write error messages here */){ Parse sParse; if( pzErrMsg ) *pzErrMsg = 0; if( sqliteSafetyOn(db) ) goto exec_misuse; if( (db->flags & SQLITE_Initialized)==0 ){ int rc, cnt = 1; while( (rc = sqliteInit(db, pzErrMsg))==SQLITE_BUSY && db->xBusyCallback && db->xBusyCallback(db->pBusyArg, "", cnt++)!=0 ){} if( rc!=SQLITE_OK ){ sqliteStrRealloc(pzErrMsg); sqliteSafetyOff(db); return rc; } if( pzErrMsg ){ sqliteFree(*pzErrMsg); *pzErrMsg = 0; } } if( db->file_format<3 ){ sqliteSafetyOff(db); sqliteSetString(pzErrMsg, "obsolete database file format", 0); return SQLITE_ERROR; } if( db->pVdbe==0 ){ db->nChange = 0; } memset(&sParse, 0, sizeof(sParse)); sParse.db = db; sParse.xCallback = xCallback; sParse.pArg = pArg; sParse.useCallback = ppVm==0; if( db->xTrace ) db->xTrace(db->pTraceArg, zSql); sqliteRunParser(&sParse, zSql, pzErrMsg); if( sqlite_malloc_failed ){ sqliteSetString(pzErrMsg, "out of memory", 0); sParse.rc = SQLITE_NOMEM; sqliteRollbackAll(db); sqliteResetInternalSchema(db, 0); db->flags &= ~SQLITE_InTrans; } if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK; if( sParse.rc!=SQLITE_OK && pzErrMsg && *pzErrMsg==0 ){ sqliteSetString(pzErrMsg, sqlite_error_string(sParse.rc), 0); } sqliteStrRealloc(pzErrMsg); if( sParse.rc==SQLITE_SCHEMA ){ sqliteResetInternalSchema(db, 0); } if( sParse.useCallback==0 ){ assert( ppVm ); *ppVm = (sqlite_vm*)sParse.pVdbe; if( pzTail ) *pzTail = sParse.zTail; } if( sqliteSafetyOff(db) ) goto exec_misuse; return sParse.rc;exec_misuse: if( pzErrMsg ){ *pzErrMsg = 0; sqliteSetString(pzErrMsg, sqlite_error_string(SQLITE_MISUSE), 0); sqliteStrRealloc(pzErrMsg); } return SQLITE_MISUSE;}/*** Execute SQL code. Return one of the SQLITE_ success/failure** codes. Also write an error message into memory obtained from** malloc() and make *pzErrMsg point to that message.**** If the SQL is a query, then for each row in the query result** the xCallback() function is called. pArg becomes the first** argument to xCallback(). If xCallback=NULL then no callback** is invoked, even for queries.*/int sqlite_exec( sqlite *db, /* The database on which the SQL executes */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -