/* ** 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; if( db->init.busy ) return SQLITE_OK; assert( (db->flags & SQLITE_Initialized)==0 ); rc = SQLITE_OK; db->init.busy = 1; 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 ){ sqliteResetInternalSchema(db, i); } } db->init.busy = 0; if( rc==SQLITE_OK ){ db->flags |= SQLITE_Initialized; sqliteCommitInternalChanges(db); } /* 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 fail the init. */ if( rc==SQLITE_OK && db->file_format<3 ){ char *zErr = 0; InitData initData; int meta[SQLITE_N_BTREE_META]; db->magic = SQLITE_MAGIC_OPEN; 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, (char*)0); } sqlite_freemem(zErr); } if( rc!=SQLITE_OK ){ db->flags &= ~SQLITE_Initialized; } return rc; }
/* ** Attempt to read the database schema and initialize internal ** data structures for a single database file. The index of the ** database file is given by iDb. iDb==0 is used for the main ** database. iDb==1 should never be used. iDb>=2 is used for ** auxiliary databases. Return one of the SQLITE_ error codes to ** indicate success or failure. */ static int sqliteInitOne(sqlite *db, int iDb, char **pzErrMsg){ int rc; BtCursor *curMain; int size; Table *pTab; char const *azArg[6]; char zDbNum[30]; int meta[SQLITE_N_BTREE_META]; InitData initData; char const *zMasterSchema; char const *zMasterName; char *zSql = 0; /* ** The master database table has a structure like this */ static char master_schema[] = "CREATE TABLE sqlite_master(\n" " type text,\n" " name text,\n" " tbl_name text,\n" " rootpage integer,\n" " sql text\n" ")" ; static char temp_master_schema[] = "CREATE TEMP TABLE sqlite_temp_master(\n" " type text,\n" " name text,\n" " tbl_name text,\n" " rootpage integer,\n" " sql text\n" ")" ; assert( iDb>=0 && iDb<db->nDb ); /* zMasterSchema and zInitScript are set to point at the master schema ** and initialisation script appropriate for the database being ** initialised. zMasterName is the name of the master table. */ if( iDb==1 ){ zMasterSchema = temp_master_schema; zMasterName = TEMP_MASTER_NAME; }else{ zMasterSchema = master_schema; zMasterName = MASTER_NAME; } /* Construct the schema table. */ sqliteSafetyOff(db); azArg[0] = "table"; azArg[1] = zMasterName; azArg[2] = "2"; azArg[3] = zMasterSchema; sprintf(zDbNum, "%d", iDb); azArg[4] = zDbNum; azArg[5] = 0; initData.db = db; initData.pzErrMsg = pzErrMsg; sqliteInitCallback(&initData, 5, (char **)azArg, 0); pTab = sqliteFindTable(db, zMasterName, db->aDb[iDb].zName); if( pTab ){ pTab->readOnly = 1; }else{ return SQLITE_NOMEM; } sqliteSafetyOn(db); /* Create a cursor to hold the database open */ if( db->aDb[iDb].pBt==0 ) return SQLITE_OK; rc = sqliteBtreeCursor(db->aDb[iDb].pBt, 2, 0, &curMain); if( rc ){ sqliteSetString(pzErrMsg, sqlite_error_string(rc), (char*)0); return rc; } /* Get the database meta information */ rc = sqliteBtreeGetMeta(db->aDb[iDb].pBt, meta); if( rc ){ sqliteSetString(pzErrMsg, sqlite_error_string(rc), (char*)0); sqliteBtreeCloseCursor(curMain); return rc; } db->aDb[iDb].schema_cookie = meta[1]; if( iDb==0 ){ db->next_cookie = meta[1]; db->file_format = meta[2]; size = meta[3]; if( size==0 ){ size = MAX_PAGES; } db->cache_size = size; db->safety_level = meta[4]; if( meta[6]>0 && meta[6]<=2 && db->temp_store==0 ){ db->temp_store = meta[6]; } if( db->safety_level==0 ) db->safety_level = 2; /* ** file_format==1 Version 2.1.0. ** file_format==2 Version 2.2.0. Add support for INTEGER PRIMARY KEY. ** file_format==3 Version 2.6.0. Fix empty-string index bug. ** file_format==4 Version 2.7.0. Add support for separate numeric and ** text datatypes. */ if( db->file_format==0 ){ /* This happens if the database was initially empty */ db->file_format = 4; }else if( db->file_format>4 ){ sqliteBtreeCloseCursor(curMain); sqliteSetString(pzErrMsg, "unsupported file format", (char*)0); return SQLITE_ERROR; } }else if( iDb!=1 && (db->file_format!=meta[2] || db->file_format<4) ){ assert( db->file_format>=4 ); if( meta[2]==0 ){ sqliteSetString(pzErrMsg, "cannot attach empty database: ", db->aDb[iDb].zName, (char*)0); }else{ sqliteSetString(pzErrMsg, "incompatible file format in auxiliary " "database: ", db->aDb[iDb].zName, (char*)0); } sqliteBtreeClose(db->aDb[iDb].pBt); db->aDb[iDb].pBt = 0; return SQLITE_FORMAT; } sqliteBtreeSetCacheSize(db->aDb[iDb].pBt, db->cache_size); sqliteBtreeSetSafetyLevel(db->aDb[iDb].pBt, meta[4]==0 ? 2 : meta[4]); /* Read the schema information out of the schema tables */ assert( db->init.busy ); sqliteSafetyOff(db); /* The following SQL will read the schema from the master tables. ** The first version works with SQLite file formats 2 or greater. ** The second version is for format 1 files. ** ** Beginning with file format 2, the rowid for new table entries ** (including entries in sqlite_master) is an increasing integer. ** So for file format 2 and later, we can play back sqlite_master ** and all the CREATE statements will appear in the right order. ** But with file format 1, table entries were random and so we ** have to make sure the CREATE TABLEs occur before their corresponding ** CREATE INDEXs. (We don't have to deal with CREATE VIEW or ** CREATE TRIGGER in file format 1 because those constructs did ** not exist then.) */ if( db->file_format>=2 ){ sqliteSetString(&zSql, "SELECT type, name, rootpage, sql, ", zDbNum, " FROM \"", db->aDb[iDb].zName, "\".", zMasterName, (char*)0); }else{ sqliteSetString(&zSql, "SELECT type, name, rootpage, sql, ", zDbNum, " FROM \"", db->aDb[iDb].zName, "\".", zMasterName, " WHERE type IN ('table', 'index')" " ORDER BY CASE type WHEN 'table' THEN 0 ELSE 1 END", (char*)0); } rc = sqlite_exec(db, zSql, sqliteInitCallback, &initData, 0); sqliteFree(zSql); sqliteSafetyOn(db); sqliteBtreeCloseCursor(curMain); if( sqlite_malloc_failed ){ sqliteSetString(pzErrMsg, "out of memory", (char*)0); rc = SQLITE_NOMEM; sqliteResetInternalSchema(db, 0); } if( rc==SQLITE_OK ){ DbSetProperty(db, iDb, DB_SchemaLoaded); }else{ sqliteResetInternalSchema(db, iDb); } return rc; }