勇芳软件工作室.汉化:  SQLite3 API Functions > Database Connection >

sqlite3_open

Previous pageReturn to chapter overviewNext page

描述

 

打开由filename参数指定的SQLite数据库文件。

 

C / C ++语法

 

int sqlite3_open(

const char *filename,   /* Database filename (UTF-8) */

sqlite3 **ppDb          /* OUT: SQLite db handle */

);

 

PB语法

 

FUNCTION sqlite3_open ( _

BYREF szFileName AS ASCIIZ, _

BYREF ppDb AS DWORD _

) AS LONG

 

参数

 

szFileName

 

[in]数据库文件名。

 

ppDb

 

[out]数据库连接句柄。

 

返回值

 

如果成功返回SQLITE_OK,否则返回错误代码。sqlite3_errmsgsqlite3_errmsg16功能可用于在sqlite3_open功能失败后获取错误的英文描述。

 

备注

 

数据库连接句柄通常在* PPDB中返回,即使发生错误。唯一的例外是,如果SQLite无法分配内存来保存sqlite3对象,则NULL将被写入* PPDB而不是指向sqlite3对象的指针。如果成功打开(和/或创建)数据库,则返回SQLITE_OK。否则返回错误代码。

 

当打开时是否发生错误,与数据库连接句柄相关联的资源应该在不再需要时将其传递给sqlite3_close.

 

如果文件名为“:memory:”,则会为该连接创建一个专用的临时内存数据库。当数据库连接关闭时,该内存中的数据库将会消失。SQLite的未来版本可能会使用以“:”字符开头的其他特殊文件名。建议当数据库文件名实际上以“:”字符开头时,您应该使用诸如“./”之类的路径名在文件名前缀,以避免歧义。

 

如果文件名为空字符串,则将创建一个私有的临时磁盘数据库。数据库连接关闭后,该私有数据库将被自动删除。

 

Windows用户注意

 

用于文件名参数sqlite3_open的编码必须是UTF-8,而不是当前定义的任何代码页。包含国际字符的文件名必须在将其传递到sqlite3_open之前转换为UTF-8。

 

C ++实现代码

 

/*

** Open a new database handle.

*/

SQLITE_API int sqlite3_open(

const char *zFilename,

sqlite3 **ppDb

){

return openDatabase(zFilename, ppDb,

                    SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0);

}

 

/*

** This function does the work of opening a database on behalf of

** sqlite3_open() and sqlite3_open16(). The database filename "zFilename"

** is UTF-8 encoded.

*/

static int openDatabase(

const char *zFilename, /* Database filename UTF-8 encoded */

sqlite3 **ppDb,        /* OUT: Returned database handle */

unsigned int flags,    /* Operational flags */

const char *zVfs       /* Name of the VFS to use */

){

sqlite3 *db;                    /* Store allocated handle here */

int rc;                         /* Return code */

int isThreadsafe;               /* True for threadsafe connections */

char *zOpen = 0;                /* Filename argument to pass to BtreeOpen() */

char *zErrMsg = 0;              /* Error message from sqlite3ParseUri() */

 

*ppDb = 0;

#ifndef SQLITE_OMIT_AUTOINIT

rc = sqlite3_initialize();

if( rc ) return rc;

#endif

 

/* Only allow sensible combinations of bits in the flags argument.

** Throw an error if any non-sense combination is used.  If we

** do not block illegal combinations here, it could trigger

** assert() statements in deeper layers.  Sensible combinations

** are:

**

**  1:  SQLITE_OPEN_READONLY

**  2:  SQLITE_OPEN_READWRITE

**  6:  SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE

*/

assert( SQLITE_OPEN_READONLY  == 0x01 );

assert( SQLITE_OPEN_READWRITE == 0x02 );

assert( SQLITE_OPEN_CREATE    == 0x04 );

testcase( (1<<(flags&7))==0x02 ); /* READONLY */

testcase( (1<<(flags&7))==0x04 ); /* READWRITE */

testcase( (1<<(flags&7))==0x40 ); /* READWRITE | CREATE */

if( ((1<<(flags&7)) & 0x46)==0 ) return SQLITE_MISUSE_BKPT;

 

if( sqlite3GlobalConfig.bCoreMutex==0 ){

  isThreadsafe = 0;

}else if( flags & SQLITE_OPEN_NOMUTEX ){

  isThreadsafe = 0;

}else if( flags & SQLITE_OPEN_FULLMUTEX ){

  isThreadsafe = 1;

}else{

  isThreadsafe = sqlite3GlobalConfig.bFullMutex;

}

if( flags & SQLITE_OPEN_PRIVATECACHE ){

  flags &= ~SQLITE_OPEN_SHAREDCACHE;

}else if( sqlite3GlobalConfig.sharedCacheEnabled ){

  flags |= SQLITE_OPEN_SHAREDCACHE;

}

 

/* Remove harmful bits from the flags parameter

**

** The SQLITE_OPEN_NOMUTEX and SQLITE_OPEN_FULLMUTEX flags were

** dealt with in the previous code block.  Besides these, the only

** valid input flags for sqlite3_open_v2() are SQLITE_OPEN_READONLY,

** SQLITE_OPEN_READWRITE, SQLITE_OPEN_CREATE, SQLITE_OPEN_SHAREDCACHE,

** SQLITE_OPEN_PRIVATECACHE, and some reserved bits.  Silently mask

** off all other flags.

*/

flags &=  ~( SQLITE_OPEN_DELETEONCLOSE |

             SQLITE_OPEN_EXCLUSIVE |

             SQLITE_OPEN_MAIN_DB |

             SQLITE_OPEN_TEMP_DB |

             SQLITE_OPEN_TRANSIENT_DB |

             SQLITE_OPEN_MAIN_JOURNAL |

             SQLITE_OPEN_TEMP_JOURNAL |

             SQLITE_OPEN_SUBJOURNAL |

             SQLITE_OPEN_MASTER_JOURNAL |

             SQLITE_OPEN_NOMUTEX |

             SQLITE_OPEN_FULLMUTEX |

             SQLITE_OPEN_WAL

           );

 

/* Allocate the sqlite data structure */

db = sqlite3MallocZero( sizeof(sqlite3) );

if( db==0 ) goto opendb_out;

if( isThreadsafe ){

  db->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE);

  if( db->mutex==0 ){

    sqlite3_free(db);

    db = 0;

    goto opendb_out;

  }

}

sqlite3_mutex_enter(db->mutex);

db->errMask = 0xff;

db->nDb = 2;

db->magic = SQLITE_MAGIC_BUSY;

db->aDb = db->aDbStatic;

 

assert( sizeof(db->aLimit)==sizeof(aHardLimit) );

memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit));

db->autoCommit = 1;

db->nextAutovac = -1;

db->nextPagesize = 0;

db->flags |= SQLITE_ShortColNames | SQLITE_AutoIndex | SQLITE_EnableTrigger

#if SQLITE_DEFAULT_FILE_FORMAT<4

               | SQLITE_LegacyFileFmt

#endif

#ifdef SQLITE_ENABLE_LOAD_EXTENSION

               | SQLITE_LoadExtension

#endif

#if SQLITE_DEFAULT_RECURSIVE_TRIGGERS

               | SQLITE_RecTriggers

#endif

#if defined(SQLITE_DEFAULT_FOREIGN_KEYS) && SQLITE_DEFAULT_FOREIGN_KEYS

               | SQLITE_ForeignKeys

#endif

    ;

sqlite3HashInit(&db->aCollSeq);

#ifndef SQLITE_OMIT_VIRTUALTABLE

sqlite3HashInit(&db->aModule);

#endif

 

/* Add the default collation sequence BINARY. BINARY works for both UTF-8

** and UTF-16, so add a version for each to avoid any unnecessary

** conversions. The only error that can occur here is a malloc() failure.

*/

createCollation(db, "BINARY", SQLITE_UTF8, 0, binCollFunc, 0);

createCollation(db, "BINARY", SQLITE_UTF16BE, 0, binCollFunc, 0);

createCollation(db, "BINARY", SQLITE_UTF16LE, 0, binCollFunc, 0);

createCollation(db, "RTRIM", SQLITE_UTF8, (void*)1, binCollFunc, 0);

if( db->mallocFailed ){

  goto opendb_out;

}

db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 0);

assert( db->pDfltColl!=0 );

 

/* Also add a UTF-8 case-insensitive collation sequence. */

createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0);

 

/* Parse the filename/URI argument. */

db->openFlags = flags;

rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg);

if( rc!=SQLITE_OK ){

  if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;

  sqlite3Error(db, rc, zErrMsg ? "%s" : 0, zErrMsg);

  sqlite3_free(zErrMsg);

  goto opendb_out;

}

 

/* Open the backend database driver */

rc = sqlite3BtreeOpen(db->pVfs, zOpen, db, &db->aDb[0].pBt, 0,

                      flags | SQLITE_OPEN_MAIN_DB);

if( rc!=SQLITE_OK ){

  if( rc==SQLITE_IOERR_NOMEM ){

    rc = SQLITE_NOMEM;

  }

  sqlite3Error(db, rc, 0);

  goto opendb_out;

}

db->aDb[0].pSchema = sqlite3SchemaGet(db, db->aDb[0].pBt);

db->aDb[1].pSchema = sqlite3SchemaGet(db, 0);

 

 

/* The default safety_level for the main database is 'full'; for the temp

** database it is 'NONE'. This matches the pager layer defaults.

*/

db->aDb[0].zName = "main";

db->aDb[0].safety_level = 3;

db->aDb[1].zName = "temp";

db->aDb[1].safety_level = 1;

 

db->magic = SQLITE_MAGIC_OPEN;

if( db->mallocFailed ){

  goto opendb_out;

}

 

/* Register all built-in functions, but do not attempt to read the

** database schema yet. This is delayed until the first time the database

** is accessed.

*/

sqlite3Error(db, SQLITE_OK, 0);

sqlite3RegisterBuiltinFunctions(db);

 

/* Load automatic extensions - extensions that have been registered

** using the sqlite3_automatic_extension() API.

*/

rc = sqlite3_errcode(db);

if( rc==SQLITE_OK ){

  sqlite3AutoLoadExtensions(db);

  rc = sqlite3_errcode(db);

  if( rc!=SQLITE_OK ){

    goto opendb_out;

  }

}

 

#ifdef SQLITE_ENABLE_FTS1

if( !db->mallocFailed ){

  extern int sqlite3Fts1Init(sqlite3*);

  rc = sqlite3Fts1Init(db);

}

#endif

 

#ifdef SQLITE_ENABLE_FTS2

if( !db->mallocFailed && rc==SQLITE_OK ){

  extern int sqlite3Fts2Init(sqlite3*);

  rc = sqlite3Fts2Init(db);

}

#endif

 

#ifdef SQLITE_ENABLE_FTS3

if( !db->mallocFailed && rc==SQLITE_OK ){

  rc = sqlite3Fts3Init(db);

}

#endif

 

#ifdef SQLITE_ENABLE_ICU

if( !db->mallocFailed && rc==SQLITE_OK ){

  rc = sqlite3IcuInit(db);

}

#endif

 

#ifdef SQLITE_ENABLE_RTREE

if( !db->mallocFailed && rc==SQLITE_OK){

  rc = sqlite3RtreeInit(db);

}

#endif

 

sqlite3Error(db, rc, 0);

 

/* -DSQLITE_DEFAULT_LOCKING_MODE=1 makes EXCLUSIVE the default locking

** mode.  -DSQLITE_DEFAULT_LOCKING_MODE=0 make NORMAL the default locking

** mode.  Doing nothing at all also makes NORMAL the default.

*/

#ifdef SQLITE_DEFAULT_LOCKING_MODE

db->dfltLockMode = SQLITE_DEFAULT_LOCKING_MODE;

sqlite3PagerLockingMode(sqlite3BtreePager(db->aDb[0].pBt),

                        SQLITE_DEFAULT_LOCKING_MODE);

#endif

 

/* Enable the lookaside-malloc subsystem */

setupLookaside(db, 0, sqlite3GlobalConfig.szLookaside,

                      sqlite3GlobalConfig.nLookaside);

 

sqlite3_wal_autocheckpoint(db, SQLITE_DEFAULT_WAL_AUTOCHECKPOINT);

 

opendb_out:

sqlite3_free(zOpen);

if( db ){

  assert( db->mutex!=0 || isThreadsafe==0 || sqlite3GlobalConfig.bFullMutex==0 );

  sqlite3_mutex_leave(db->mutex);

}

rc = sqlite3_errcode(db);

assert( db!=0 || rc==SQLITE_NOMEM );

if( rc==SQLITE_NOMEM ){

  sqlite3_close(db);

  db = 0;

}else if( rc!=SQLITE_OK ){

  db->magic = SQLITE_MAGIC_SICK;

}

*ppDb = db;

return sqlite3ApiExit(0, rc);

}