Sqlite3源碼學習(5)OS的接口VFS
之前講了那么多的環境搭建,現在終于可以學習源碼了。官方有一篇講解VFS的文檔,對理解sqlite3的VFS有很大的幫助:
http://www.sqlite.org/vfs.html
1.VFS簡介
VFS也就是所謂的虛擬文件系統,因為sqlite3運行在不同的平臺上會有不同的文件系統,VFS就是對不同的文件系統做一個統一的接口。
先來看一下一張圖:
這張圖展示了sqlite3的軟件層次結構,主要分為前端和后端,OS層位于最底層,是和系統的磁盤文件存儲直接打交道,在OS層里封裝了VFS。
Sqlit3的VFS體現了跨平臺的特性,雖然不同文件系統的實現是不一樣的,但是接口都是相同的。
2.VFS的組成
VFS最基本的對象是sqlite3_vfs結構體:
typedef struct sqlite3_vfs sqlite3_vfs;
typedef void (*sqlite3_syscall_ptr)(void);
struct sqlite3_vfs {
int iVersion; /* Structure version number (currently 3) */
int szOsFile; /* Size of subclassed sqlite3_file */
int mxPathname; /* Maximum file pathname length */
sqlite3_vfs *pNext; /* 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 future versions. The iVersion
** value will increment whenever this happens.
*/
};
結構體里定義了一系列函數指針,幾個關鍵的地方是:
int szOsFile: file結構體的大小,繼承自sqlite3_file,分配空間時要用
sqlite3_vfs *pNext;:指向下一個vfs節點的指針
const char * zName:vfs的名字
void *pAppData:這個指針指向一個存儲了各種文件io操作方法的結構體地址,如win下是
typedef struct winVfsAppData winVfsAppData;
struct winVfsAppData {
const sqlite3_io_methods *pMethod; /* The file I/O methods to use. */
void *pAppData; /* The extra pAppData, if any. */
BOOL bNoLock; /* Non-zero if locking is disabled. */
};
static winVfsAppData winAppData = {
&winIoMethod, /* pMethod */
0, /* pAppData */
0 /* bNoLock */
};
要實現一個VFS實體,就是實現sqlite3_vfs和sqlite3_io_methods結構體里的一系列方法,即函數指針的實體函數的實現,sqlite3_file結構體作為一個文件句柄的傳入參數,在open時會將sqlite3_file指針強制轉為特定的file指針,該file結構體從sqlite3_file繼承,感覺有點像C++,sqlite3_file相當于一個基類,在不同VFS下有不同的派生類。
3.VFS的類型
在win下的vfs有win32、win32-longpath、win32-none和win32-longpath-none,默認使用的是win32 vfs;在類unix系統下的vfs有unix、unix-dotfil、unix-excl、unix-none等,默認使用的是unix vfs。sqlite3內核在初始化時調用sqlite3_os_init()函數來注冊vfs,sqlite3_os_init()在不同系統下有不同的實現。
除了上面這些在test文件里還實現了一些其他的vfs如
test_demovfs.c:最簡單的vfs,可以學習vfs的基本實現
test_onefile.c:用于嵌入式設備的vfs
test_quota.c:實現了一個名為quota的vfs、功能暫時不清楚,具體見官方文檔
test_multiplex.c:這個vfs好像是用來處理大文件,具體見官方文檔
test_journal.c:這個vfs主要測試回滾日志的存儲
test_vfs.c:這個文件主要實現文件系統出錯的模擬
4.VFS的注冊和使用
如果vfs沒有在sqlite3_os_init()里注冊,那么就要使用sqlite3_vfs_register函數來注冊,其實現如下:
int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
MUTEX_LOGIC(sqlite3_mutex *mutex;)
#ifndef SQLITE_OMIT_AUTOINIT
int rc = sqlite3_initialize();
if( rc ) return rc;
#endif
#ifdef SQLITE_ENABLE_API_ARMOR
if( pVfs==0 ) return SQLITE_MISUSE_BKPT;
#endif
MUTEX_LOGIC( mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
sqlite3_mutex_enter(mutex);
vfsUnlink(pVfs);
if( makeDflt || vfsList==0 ){
pVfs->pNext = vfsList;
vfsList = pVfs;
}else{
pVfs->pNext = vfsList->pNext;
vfsList->pNext = pVfs;
}
assert(vfsList);
sqlite3_mutex_leave(mutex);
return SQLITE_OK;
}
這個函數的傳入參數為要注冊的vfs地址pVfs和makeDflt,將pVfsv存儲到鏈表中,vfsList為頭節點,如果makeDflt不為0,那么pVfs作為頭節點,否則pVfs指向頭節點的下一個節點,這里添加節點時需要加鎖,防止多線程時被重入。
注冊后就可以通過調用sqlite3_open_v2()來替換vfs,下面以demo vfs為示例
sqlite3_vfs_register(sqlite3_demovfs(), 1);//注冊
int rc = sqlite3_open_v2("demo.db", &db, SQLITE_OPEN_READWRITE, "demo");//使用demo vfs替換默認的vfs
在tcl下的使用時,先運行上篇講的tcl擴展程序,輸入以下命令register_demovfs #注冊demo vfs
sqlite3 db example1.db -vfs demo #打開example1.db數據庫,并選擇demo vfs替換默認的vfs。
db eval {CREATE TABLE t1(a TEXT, b INTEGER)} #新建表
db eval {
INSERT INTO t1 VALUES('one',1);
INSERT INTO t1 VALUES('two',2);
INSERT INTO t1 VALUES(NULL,3);
} #插入行
puts [db eval {SELECT * FROM t1}] #顯示表的所有行,最后輸出結果:
one 1 two 2 {} 3
關于sqlite3中tcl的使用參考以下文檔
http://nut.sourceforge.net/drh.html
http://www.sqlite.org/tclsqlite.html
智能推薦
sqlite3的簡單用法
sqlite3的簡單用法 安裝sqlite3 基本用法 打開數據庫 sqlite3 test.db 查看表 .tables 可以使用圖形化工具navicat來創建的查看數據庫 sqlite3 C/C++接口 Example 編譯 需要在編譯選項上加入-lsqlite3 如果使用的編輯器,比如codeblocks,按如下位置配置 出現fatal error: sqlite3.h: No such f...
SQLite3的安裝與使用
SQLite3的安裝與使用 SQLite下載 我是64位機,下載下面的兩個解壓就好 然后解壓配置環境變量Path H:\java\SQLlite\sqlite-tools-win32-x86-3310100 我的安裝目錄是在這里,所以Path配置地址就是這個 測試使用 在dos界面中輸入sqlite3查看 輸入sqlite3,顯示下面內容說明成功 創建數據庫 生成DB文件 創建表 新增數據 Nav...
Sqlite3的安裝及應用
SQLite,是一款輕型的數據庫,是遵守ACID的關系型數據庫管理系統,它包含在一個相對小的C庫中。SQLite是D.Richard Hipp用C語言編寫的開源嵌入式數據庫引擎,它支持大多數的SQL92標準。它的設計目標是嵌入式的,而且目前已經在很多嵌入式產品中使用了它,它占用資源非常的低,在嵌入式設備中,可能只需要幾百K的內存就夠了。它能夠...
Django sqlite3的實際應用
db.html(模板) models.py views.py#向數據庫member里進行增刪改查操作 urls.py#訪問網址 setting.py#數據庫配置 出現編碼問題 名前、年目、メール、時間、地點從數據庫獲取。 命令操作 遇到問題 models.py增加字段后,需要重新生成數據表時,刪除migrations目錄,以及數據庫里有關的數據表, 重新執行命令生成。(有時執行命令報錯,參照刪除即...
猜你喜歡
freemarker + ItextRender 根據模板生成PDF文件
1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...
電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!
Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...
requests實現全自動PPT模板
http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...
Linux C系統編程-線程互斥鎖(四)
互斥鎖 互斥鎖也是屬于線程之間處理同步互斥方式,有上鎖/解鎖兩種狀態。 互斥鎖函數接口 1)初始化互斥鎖 pthread_mutex_init() man 3 pthread_mutex_init (找不到的情況下首先 sudo apt-get install glibc-doc sudo apt-get install manpages-posix-dev) 動態初始化 int pthread_...