Small. Fast. Reliable.
Choose any three.

SQLite C 接口

操作系统接口对象
OS Interface Object

typedef struct sqlite3_vfs sqlite3_vfs;
typedef void (*sqlite3_syscall_ptr)(void);
struct sqlite3_vfs {
  int iVersion;            /* 结构体版本号(当前为3)  Structure version number (currently 3) */
  int szOsFile;            /* sqlite3_file的大小  Size of subclassed sqlite3_file */
  int mxPathname;          /* 最大文件路径名长度  Maximum file pathname length */
  sqlite3_vfs *pNext;      /* 下一个注册的VFS  Next registered VFS */
  const char *zName;       /* 虚拟文件系统的名字  Name of this virtual file system */
  void *pAppData;          /* 指向应用程序指定的数据  Pointer to application-specific data */
  int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*,
               int flags, int *pOutFlags);
  int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir);
  int (*xAccess)(sqlite3_vfs*, const char *zName, int flags, int *pResOut);
  int (*xFullPathname)(sqlite3_vfs*, const char *zName, int nOut, char *zOut);
  void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename);
  void (*xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg);
  void (*(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol))(void);
  void (*xDlClose)(sqlite3_vfs*, void*);
  int (*xRandomness)(sqlite3_vfs*, int nByte, char *zOut);
  int (*xSleep)(sqlite3_vfs*, int microseconds);
  int (*xCurrentTime)(sqlite3_vfs*, double*);
  int (*xGetLastError)(sqlite3_vfs*, int, char *);
  /*
  ** The methods above are in version 1 of the sqlite_vfs object
  ** definition.  Those that follow are added in version 2 or later
  */
  int (*xCurrentTimeInt64)(sqlite3_vfs*, sqlite3_int64*);
  /*
  ** The methods above are in versions 1 and 2 of the sqlite_vfs object.
  ** Those below are for version 3 and greater.
  */
  int (*xSetSystemCall)(sqlite3_vfs*, const char *zName, sqlite3_syscall_ptr);
  sqlite3_syscall_ptr (*xGetSystemCall)(sqlite3_vfs*, const char *zName);
  const char *(*xNextSystemCall)(sqlite3_vfs*, const char *zName);
  /*
  ** The methods above are in versions 1 through 3 of the sqlite_vfs object.
  ** New fields may be appended in figure versions.  The iVersion
  ** value will increment whenever this happens. 
  */
};

sqlite3_vfs对象的实例定义了SQLite核心和底层操作系统之间的接口。对象名字中的“vfs”表示“虚拟文件系统(virtual file system)”。详细信息参见VFS 文档
An instance of the sqlite3_vfs object defines the interface between the SQLite core and the underlying operating system. The "vfs" in the name of the object stands for "virtual file system". See the VFS documentation for further information.

iVersion 字段的最初值为1,但是在未来的版本中会变大。当iVersion值增加时,这个对象可能会追加额外的字段。注意,sqlite3_vfs对象的结构在SQLite 3.5.9版到 3.6.0版时发生了变动,但是iVersion 字段没有修改。
The value of the iVersion field is initially 1 but may be larger in future versions of SQLite. Additional fields may be appended to this object when the iVersion value is increased. Note that the structure of the sqlite3_vfs object changes in the transaction between SQLite version 3.5.9 and 3.6.0 and yet the iVersion field was not modified.

szOsFile字段是VFS使用的子类化的sqlite3_file结构体的大小。mxPathname是这个VFS中路径名的最大长度。
The szOsFile field is the size of the subclassed sqlite3_file structure used by this VFS. mxPathname is the maximum length of a pathname in this VFS.

注册的sqlite3_vfs 对象都保存在由pNext指针构成的链表中。sqlite3_vfs_register()sqlite3_vfs_unregister()接口以线程安全的方式来管理这个链表。sqlite3_vfs_find()用于搜索这个链表。应用程序和VFS实现都不会使用这个pNext指针。
Registered sqlite3_vfs objects are kept on a linked list formed by the pNext pointer. The sqlite3_vfs_register() and sqlite3_vfs_unregister() interfaces manage this list in a thread-safe way. The sqlite3_vfs_find() interface searches the list. Neither the application code nor the VFS implementation should use the pNext pointer.

pNext字段是sqlite3_vfs结构体中SQLite唯一会修改的字段。SQLite只有当持有一个特殊的静态互斥锁才能访问或修改这个字段。一旦sqlite3_vfs对象被注册了,应用程序就不能修改这个对象中的任何字段了。
The pNext field is the only field in the sqlite3_vfs structure that SQLite will ever modify. SQLite will only access or modify this field while holding a particular static mutex. The application should never modify anything within the sqlite3_vfs object once the object has been registered.

zName字段保存了这个VFS模块的名字。这个名字在VFS模块中必须是唯一的。
The zName field holds the name of the VFS module. The name must be unique across all VFS modules.

SQLite保证xOpen的zFilename参数只会是NULL或从xFullPathname()加上一个可选的后缀获取的字符串。如果zFilename参数中加入了一个后缀,那么会由一个“-”字符加上不多于11个字符组成。SQLite进一步保证这个字符串在xClose()调用之前都是有效且不会改变的。因为前一句话,所以,如果由于某些原因需要保存文件名的话,sqlite3_file可以安全的存储一个指向文件名的指针。如果xOpen的zFilename参数是一个NULL指针,那么xOpen必须为这个文件创建iGetter独有的临时名字。一旦xFilename参数是NULL,那么也就意味着标志参数包含SQLITE_OPEN_DELETEONCLOSE
SQLite guarantees that the zFilename parameter to xOpen is either a NULL pointer or string obtained from xFullPathname() with an optional suffix added. If a suffix is added to the zFilename parameter, it will consist of a single "-" character followed by no more than 11 alphanumeric and/or "-" characters. SQLite further guarantees that the string will be valid and unchanged until xClose() is called. Because of the previous sentence, the sqlite3_file can safely store a pointer to the filename if it needs to remember the filename for some reason. If the zFilename parameter to xOpen is a NULL pointer then xOpen must invent its own temporary name for the file. Whenever the xFilename parameter is NULL it will also be the case that the flags parameter will include SQLITE_OPEN_DELETEONCLOSE.

xOpen()的标志参数包含sqlite3_open_v2()的标志参数的所有位集合。如果使用sqlite3_open()sqlite3_open16(),那么标志至少包含SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE。如果xOpen()打开一个只读文件,那么*pOutFlags会包含SQLITE_OPEN_READONLY。*pOutFlags中的其它位也可能会设置。
The flags argument to xOpen() includes all bits set in the flags argument to sqlite3_open_v2(). Or if sqlite3_open() or sqlite3_open16() is used, then flags includes at least SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE. If xOpen() opens a file read-only then it sets *pOutFlags to include SQLITE_OPEN_READONLY. Other bits in *pOutFlags may be set.

根据打开的对象不同,SQLite还会在xOpen()调用中加入下列的标志:
SQLite will also add one of the following flags to the xOpen() call, depending on the object being opened:

文件I/O实现可以使用这些标志来改变处理文件的方式。例如,一个应用程序如果不关心崩溃后的恢复和回滚,那么可以使日志文件的打开变为空操作,写入日志也就同样是空操作,其他日志读取操作则都会返回SQLITE_IOERR。或者,实现可能会识别出数据库文件需要在随机顺序中执行页对齐扇区读写,因此相应的设置I/O子系统。
The file I/O implementation can use the object type flags to change the way it deals with files. For example, an application that does not care about crash recovery or rollback might make the open of a journal file a no-op. Writes to this journal would also be no-ops, and any attempt to read the journal would return SQLITE_IOERR. Or the implementation might recognize that a database file will be doing page-aligned sector reads and writes in a random order and set up its I/O subsystem accordingly.

SQLite还可能在xOpen方法中加入下面的标志:
SQLite might also add one of the following flags to the xOpen method:

SQLITE_OPEN_DELETEONCLOSE标志表示这个文件在关闭时会删除。TEMP数据库和它的日志文件、瞬时数据库和子日志都会这是SQLITE_OPEN_DELETEONCLOSE这个标志。
The SQLITE_OPEN_DELETEONCLOSE flag means the file should be deleted when it is closed. The SQLITE_OPEN_DELETEONCLOSE will be set for TEMP databases and their journals, transient databases, and subjournals.

SQLITE_OPEN_EXCLUSIVE标志总是和SQLITE_OPEN_CREATE标志一起联合使用,这两个标志与POSIX open() API的O_EXCL和OCREAT标志类似。当标志SQLITE_OPEN_EXCLUSIVE与SQLITE_OPEN_CREATE成对出现时,表示必须创建一个文件,如果文件已经存在则返回错误。这个表示不是表示文件以排他访问模式打开。
The SQLITE_OPEN_EXCLUSIVE flag is always used in conjunction with the SQLITE_OPEN_CREATE flag, which are both directly analogous to the O_EXCL and O_CREAT flags of the POSIX open() API. The SQLITE_OPEN_EXCLUSIVE flag, when paired with the SQLITE_OPEN_CREATE, is used to indicate that file should always be created, and that it is an error if it already exists. It is not used to indicate the file should be opened for exclusive access.

SQLite至少会分配szOsFile 字节的内存用来存储xOpen中第三个参数传入的sqlite3_file结构体。xOpen函数不需要为这个结构体分配内存,只需要填写这个结构体即可。注意,xOpen函数必须将sqlite3_file.pMethods设置为一个有效的sqlite3_io_methods对象,或者NULL。即使打开失败,xOpen也必须做这件事。不论xOpen调用是否失败,SQLite都期望在xOpen返回之后,sqlite3_file.pMethods是有效的。
At least szOsFile bytes of memory are allocated by SQLite to hold the sqlite3_file structure passed as the third argument to xOpen. The xOpen method does not have to allocate the structure; it should just fill it in. Note that the xOpen method must set the sqlite3_file.pMethods to either a valid sqlite3_io_methods object or to NULL. xOpen must do this even if the open fails. SQLite expects that the sqlite3_file.pMethods element will be valid after xOpen returns regardless of the success or failure of the xOpen call.

xAccess()的标志参数可以用SQLITE_ACCESS_EXISTS来测试一个文件是否存在,也可以用SQLITE_ACCESS_READWRITE标志来测试这个文件是否是可读可写的,还可以用SQLITE_ACCESS_READ标志来测试,这个文件是否是可读的。文件可以是一个目录。
The flags argument to xAccess() may be SQLITE_ACCESS_EXISTS to test for the existence of a file, or SQLITE_ACCESS_READWRITE to test whether a file is readable and writable, or SQLITE_ACCESS_READ to test whether a file is at least readable. The file can be a directory.

SQLite会为xFullPathname的输出缓冲分配至少mxPathname+1个字节。输出缓冲的精确长度也会作为参数传入。如果输出缓冲不够大,则会返回一个SQLITE_CANTOPEN。由于这会被SQLite当做一个致命错误来处理,所以VFS实现应当尽量为mxPathname设置提供一个足够大的值。
SQLite will always allocate at least mxPathname+1 bytes for the output buffer xFullPathname. The exact size of the output buffer is also passed as a parameter to both methods. If the output buffer is not large enough, SQLITE_CANTOPEN should be returned. Since this is handled as a fatal error by SQLite, vfs implementations should endeavor to prevent this by setting mxPathname to a sufficiently large value.

xRandomness()、xSleep()、xCurrentTime()和xCurrentTimeInt64()接口严格来说并不是文件系统的一部分,但是为了完整性还是包含在了VFS结构体中。 xRandomness()会返回nByte个高质量的随机字节到zOut中。返回值是获取的随机字符的实际个数。xSleep()函数会使调用线程睡眠至少给出的毫秒数。xCurrentTime()函数返回当前日期的Julian Day Number浮点数。xCurrentTimeInt64() 函数返回一个Julian Day Number乘以86400000(一天24小时的毫秒数)的整数值。如果xCurrentTimeInt64()函数可用(iVersion大于等于2,并且函数指针不是NULL),SQLite就会使用这个函数来获取当前的日期和时间,如果xCurrentTimeInt64()函数不可用,就会回退为使用xCurrentTime()函数。
The xRandomness(), xSleep(), xCurrentTime(), and xCurrentTimeInt64() interfaces are not strictly a part of the filesystem, but they are included in the VFS structure for completeness. The xRandomness() function attempts to return nBytes bytes of good-quality randomness into zOut. The return value is the actual number of bytes of randomness obtained. The xSleep() method causes the calling thread to sleep for at least the number of microseconds given. The xCurrentTime() method returns a Julian Day Number for the current date and time as a floating point value. The xCurrentTimeInt64() method returns, as an integer, the Julian Day Number multiplied by 86400000 (the number of milliseconds in a 24-hour day). SQLite will use the xCurrentTimeInt64() method to get the current date and time if that method is available (if iVersion is 2 or greater and the function pointer is not NULL) and will fall back to xCurrentTime() if xCurrentTimeInt64() is unavailable.

xSetSystemCall()、xGetSystemCall()和xNestSystemCall()接口不是给SQLite内核使用的。一些VFS提供这些可选的接口以便测试VFS代码。测试程序可以通过使用自己控制的函数覆盖系统调用来实现模拟一些很难甚至不可能发生的错误。在每个不同的VFS中或者同一个VFS的不同版本中,可以覆盖的系统调用集合都是不同的。使用这些接口的应用程序必须准备好面对这其中的某些甚至全部都为NULL,或者在下一个发行版中它们的行为发生变化。如果VFS的iVersion小于3,应用程序就不能访问这些方法了。
The xSetSystemCall(), xGetSystemCall(), and xNestSystemCall() interfaces are not used by the SQLite core. These optional interfaces are provided by some VFSes to facilitate testing of the VFS code. By overriding system calls with functions under its control, a test program can simulate faults and error conditions that would otherwise be difficult or impossible to induce. The set of system calls that can be overridden varies from one VFS to another, and from one version of the same VFS to the next. Applications that use these interfaces must be prepared for any or all of these interfaces to be NULL or for their behavior to change from one release to the next. Applications must not attempt to access any of these methods if the iVersion of the VFS is less than 3.

另行参见ObjectsConstantsFunctions的列表。
See also lists of Objects, Constants, and Functions.