最近做了一个用到嵌入式数据库sqlite的项目,经过三周的努力,终于做完了,记录下流程。
sqlite新版本中添加了一个叫做virtual file system的模块(简称vfs),只要实现了该模块中的要求的功能就可以把sqlite移植到任何系统中,sqlite中预置了windows,linux和OS/2系统的vfs的实现。利用该特性我要做的模块就是通过写一个自己的vfs把sqlite移植到USB Key上,该USB Key类似于SD卡,有自己的文件系统但是没有操作系统。通过使用该USB Key文件系统的各种函数实现vfs,使得SQLite可以操作USB key上的文件。
在sqlite官网上找到了一段编写vfs的步骤,摘录如下:
Checklist For Constructing A New VFS
The preceding paragraphs contain a lot of information. To ease the task of constructing a new VFS for SQLite we offer the following implementation checklist:
- Define an appropriate subclass of the sqlite3_file object.
- Implement the methods required by the sqlite3_io_methods object.
- Create a static and constant sqlite3_io_methods object containing pointers to the methods from the previous step.
- Implement the xOpen method that opens a file and populates an sqlite3_file object, including setting pMethods to point to the sqlite3_io_methods object from the previous step.
- Implement the other methods required by sqlite3_vfs.
- Define a static (but not constant) sqlite3_vfs structure that contains pointers to the xOpen method and the other methods and which contains the appropriate values for iVersion, szOsFile, mxPathname, zName, and pAppData.
- Implement a procedure that calls sqlite3_vfs_register() and passes it a pointer to the sqlite3_vfs structure from the previous step. This procedure is probably the only exported symbol in the source file that implements your VFS.
Within your application, call the procedure implemented in the last step above as part of your initialization process before any database connections are opened.
按照这个步骤编写基本就可以完成vfs,下边记录下自己写代码的时候遇到的问题
1.关于sqlite锁机制的实现
在sqlite在windows平台上调用了API函数lockFile和lockFileEx函数,由于自己的环境中没有类似的函数,所以只能放弃锁机制,在原有加锁和去锁的函数中删去lockFile或者lockFileEx,但是总是返回程序要求的锁,这样不至于导致SQLite因为加不上锁或者去不下去锁而报错。程序完成后经过测试还是支持事务操作的。
2.关键函数
在vfs模块中最重要的几个函数是xOpen,xRead,xWrite,xAccess,xFileControl,xSync,xClose函数,只要按照windows vfs中的函数严格实现了这几个函数就可以成功,其他的函数不太重要,至少我的程序中其他函数未做更改就实现了自己的功能。
3.临时文件
发现SQLite在调用delete语句时会在c盘临时目录中生成一个临时文件,此时文件生成函数xOpen中参数之一的要打开的文件名为空,在xOpen函数中会随即生成一个文件名,查阅了各种资料也没找到为什么会生成该临时文件。由于我的程序中xOpen函数里并未假设要打开的文件名为空,而且有c语言的字符串处理函数对该参数进行操作,导致程序频繁的报异常。
4.sqlite源程序的理解
大概用了一周半的时间对sqlite源程序进行研究,最后还是没研究太透彻,感受最深的就是层层函数调用到最后调用vfs层的函数进行操作以及大量的结构体。真是验证了那句程序=数据结构+算法!
最后把自己收集的感觉比较有用的sqlite教程以及工具传上去,希望会帮助某些朋友