簡介
Block Diagram Of SQLite |

|
這篇文檔主要描述了SQLite類庫的結構。這篇文檔的內容對于那些想了解和修改SQLite內部結構的人將會非常有用。
右側是一個結構圖,它顯示了SQLite的主要成分及各成分之間是如何相互關聯的。接下來的文本將簡要的介紹每個單一的成分。
這篇文檔描述SQLite第三版,它和 2.8版以及早期的版本基本相似,但在一些細節上是有區別的。
接口程序
SQLite類庫大部分的公共接口程序是由main.c, legacy.c, 和 vdbeapi.c源文件中的功能執行的。但有些程序是分散在其他文件夾的,因為在其他文件夾里他們可以訪問有文件作用域的數據結構。 sqlite3_get_table() 這個程序是在table.c中執行的。 sqlite3_mprintf()在printf.c中執行。 sqlite3_complete()在tokenize.c中執行。 Tcl 接口程序用tclsqlite.c來執行。
為了避免和其它軟件在名字上有沖突,SQLite類庫中所有的外部符號都是以sqlite3為前綴來命名的。這些被用來做外部使用的符號(換句話說,這些符號用來形成SQLite的API)是以sqlite3_.
來命名的。
Tokenizer
當執行一個包含SQL語句的字符串時,接口程序要把這個字符串傳遞給tokenizer。Tokenizer的任務是把原有字符串分成一個個標示符,并把這些標示符傳遞給剖析器。Tokenizer是在C文件夾tokenize.c中用手編譯的。
在這個設計中需要注意的一點是,tokenizer調用parser。熟悉YACC和BISON的人們也許會習慣于用parser調用tokenizer。 The author of SQLite的作者已經嘗試了這兩種方法,并發現用tokenizer調用parser會使程序運行的更順利。YACC使程序更滯后一些。
Parser
The parser是一個部分,它基于文件場景賦予tokens意思。SQLite的parser是由 Lemon LALR(1) parser generator產生的。Lemon和YACC/BISON一樣做同樣的工作,但是它使用不同的輸入語句,這個輸入語句是不易出錯的。 Lemon也產生一個parser,這個parser是可重入的并且是線程安全的。 Lemon 定義了無終端解除程序的概念,所以當遇到語法錯誤的時候,它不會泄露內存。驅動Lemon的原文件在parse.y.
因為lemon是一個在發展機械上不常見的程序,所以lemon的源代碼(只是一個C文件)是在SQLite分布區的"tool"子目錄下的。 lemon的文檔是在分布區的 "doc"子目錄下的。
代碼發生器
在剖析器收集完符號并把之轉換成完全的SQL語句時,它調用代碼產生器來產生虛擬的機器代碼,這些機器代碼將按照SQL語句的要求來工作。在代碼產生器中有許多文件; attach.c, auth.c, build.c, delete.c, expr.c, insert.c, pragma.c, select.c, trigger.c, update.c, vacuum.c and where.c. 正是在這些文件中,最具有重要意義的事情發生了。 expr.c 處理表達式代碼的生成。 where.c 處理SELECT, UPDATE and DELETE語句中WHERE子句的代碼的生成。文件 attach.c, delete.c, insert.c, select.c, trigger.c update.c,和vacuum.c處理SQL語句中具有同樣名字的語句的代碼的生成。(每個文件調用expr.c and where.c中的程序) All other 所有SQL的其它語句的代碼是由build.c生成的。文件auth.c 執行sqlite3_set_authorizer()的功能.
虛擬機器
由代碼生成器產生的程序由虛擬機器來運行。總而言之,虛擬機器主要用來執行一個為操作數據庫而設計的抽象的計算引擎。機器有一個用來存儲中間數據的存儲棧。每個指令包含一個操作代碼和三個額外的操作數。
虛擬機器本身是被包含在一個單獨的文件vdbe.c中的。虛擬機器也有它自己的標題文件:vdbe.h它在虛擬機器和剩下的SQLite類庫之間定義了一個接口程序,vdbeInt.h 它定義了虛擬機器的結構。文件vdbeaux.c包含了虛擬機器所使用的實用程序和一些被其它類庫用來建立VM程序的接口程序模塊。文件vdbeapi.c 包含虛擬機器的外部接口,比如 sqlite3_bind_... 類的函數。單獨的值(字符串,整數,浮動點數值,BLOBS)被存儲在一個叫 "Mem"的內部目標程序里,"Mem"是由vdbemem.c執行的。
SQLite使用C語言程序來來執行SQL函數。即使內置的SQL函數也是用這種方法來執行的。大部分的SQL內置函數(ex: coalesce(), count(),substr(), and so forth)可以在func.c里發現。日期和時間轉換函數在date.c.
B-樹
SQLite數據庫在磁盤里維護,使用源文件btree.c中的B-樹執行。數據庫中的每個表格和目錄使用一個單獨的B-tree。所有的 B-trees 被存儲在同樣的磁盤文件里。文件格式的細節被記錄在btree.c.
開頭的備注里。
B-tree子系統的接口程序被標題文件btree.h所定義。.
頁面高速緩存
B-tree模塊要求信息來源于磁盤上固定規模的程序塊。默認程序塊的大小是1024個字節,但是可以在512和65536個字節間變化。 頁面高速緩存負責讀,寫和高速緩存這些程序塊。頁面高速緩存還提供重新運算和提交抽象命令,它還管理關閉數據庫文件夾。 B-tree驅動器要求頁面高速緩存器中的特別的頁,當它想修改頁或重新運行改變的時候,它會通報頁面高速緩存。為了保證所有的需求被快速,安全和有效的處理,頁面高速緩存處理所有的微小的細節。
運行頁面高速緩存的代碼在專門的C源文件pager.c中。頁面高速緩存的子系統的接口程序被目標文件pager.h所定義。
OS 接口程序
為了在POSIX和Win32 之間提供一些可移植性,SQLite操作系統的接口程序使用一個提取層。 OS提取層的接口程序被定義在os.h. 每個支持的操作系統有它自己的執行文件: Unix使用os_unix.c,windows使用os_win.c。每個具體的操作器具有它自己的標題文件: os_unix.h, os_win.h, etc.
Utilities
內存分配和字符串比較程序位于util.c。剖析器使用的表格符號被hash.c中的無用信息表格維護。源文件utf.c包含UNICODE轉換子程序。SQLite有它自己的執行文件printf() (有一些擴展)在printf.c中,還有它自己隨機數量產生器在random.c.
測試代碼
如果你計算回歸測試腳本,多于一半的SQLite代碼數據庫的代碼將被測試。 在主要代碼文件中有許多assert()語句。另外,源文件test1.c通過test5.c和md5.c 執行只為測試用的擴展名。os_test.c向后的接口程序用來模擬斷電,來驗證頁面調度程序中的系統性事故恢復機制。