DBD-SQLite2
view release on metacpan or search on metacpan
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;
}
/*
** 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) || i==1 ) continue;
rc = sqliteInitOne(db, i, pzErrMsg);
if( rc ){
sqliteResetInternalSchema(db, i);
}
}
/* Once all the other databases have been initialised, load the schema
** for the TEMP database. This is loaded last, as the TEMP database
** schema may contain references to objects in other databases.
*/
if( rc==SQLITE_OK && db->nDb>1 && !DbHasProperty(db, 1, DB_SchemaLoaded) ){
rc = sqliteInitOne(db, 1, pzErrMsg);
if( rc ){
sqliteResetInternalSchema(db, 1);
}
}
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;
}
/*
** 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_UTF8
const char sqlite_encoding[] = "UTF-8";
#else
const 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;
/* db->flags |= SQLITE_ShortColNames; */
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, (char*)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;
}
/* Return a pointer to the newly opened database structure */
exec_misuse:
if( pzErrMsg ){
*pzErrMsg = 0;
sqliteSetString(pzErrMsg, sqlite_error_string(SQLITE_MISUSE), (char*)0);
sqliteStrRealloc(pzErrMsg);
}
return SQLITE_MISUSE;
}
/*
** The following routine destroys a virtual machine that is created by
** the sqlite_compile() routine.
**
** The integer returned is an SQLITE_ success/failure code that describes
** the result of executing the virtual machine. An error message is
** written into memory obtained from malloc and *pzErrMsg is made to
** point to that error if pzErrMsg is not NULL. The calling routine
** should use sqlite_freemem() to delete the message when it has finished
** with it.
*/
int sqlite_finalize(
sqlite_vm *pVm, /* The virtual machine to be destroyed */
char **pzErrMsg /* OUT: Write error messages here */
){
int rc = sqliteVdbeFinalize((Vdbe*)pVm, pzErrMsg);
sqliteStrRealloc(pzErrMsg);
return rc;
}
/*
** Terminate the current execution of a virtual machine then
** reset the virtual machine back to its starting state so that it
** can be reused. Any error message resulting from the prior execution
** is written into *pzErrMsg. A success code from the prior execution
** is returned.
*/
int sqlite_reset(
sqlite_vm *pVm, /* The virtual machine to be destroyed */
char **pzErrMsg /* OUT: Write error messages here */
){
int rc = sqliteVdbeReset((Vdbe*)pVm, pzErrMsg);
sqliteVdbeMakeReady((Vdbe*)pVm, -1, 0);
sqliteStrRealloc(pzErrMsg);
return rc;
}
/*
** Return a static string that describes the kind of error specified in the
** argument.
*/
const char *sqlite_error_string(int rc){
const char *z;
switch( rc ){
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 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 */
const char *NotUsed, /* The name of the table that is busy */
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]))
int timeout = (int)(long)Timeout;
int 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;
}
sqliteOsSleep(delay);
return 1;
#else
int timeout = (int)(long)Timeout;
( run in 1.380 second using v1.01-cache-2.11-cpan-e1769b4cff6 )