VDBE (virtual database engine)是一個運(yùn)行他自己的虛擬機(jī)語言組成的程序的虛擬機(jī)。每條程序都是用來查詢或者操作數(shù)據(jù)庫的。出于這個目的,VDBE的機(jī)器語言被設(shè)計用來進(jìn)行搜索,讀和修改數(shù)據(jù)庫。 每一條VDBE 說明包括一個OPCODE 和3個OPRANDS分別為P1,P2和P3。P1,P2 為整數(shù),P3是一個指向數(shù)據(jù)結(jié)構(gòu)或者字符串的指針,有可能為空。大多數(shù)說明只用到1-2個OPRANDS,只有少數(shù) 說明用到了全部3個OPRANDS。有很多非常重要的說明根本沒有用到任何OPRANDS但是卻能讀取數(shù)據(jù)并且將結(jié)果寫入運(yùn)行時棧當(dāng)中。 一段VDBE代碼從說明0開始運(yùn)行,直到 1。遇到致命錯誤; 2。執(zhí)行了停止說明; 3。整段代碼運(yùn)行完畢,所有打開的數(shù)據(jù)庫都已經(jīng)關(guān)閉,所有內(nèi)存都已經(jīng)釋放,棧為空。 example: 1.建立一個數(shù)據(jù)表,并且插入一個數(shù)據(jù) CREATE TABLE examp(one text,two int); INSERT INTO examp VALUES( 'Hello,World!'99); VDBE將這樣解釋并執(zhí)行這兩條語句 addr opcode p1 p2 p3 ---- ------------ ----- ----- ----------------------------------- 0 Transaction 0 0 1 VerifyCookie 0 81 2 Transaction 1 0 3 Integer 0 0 4 OpenWrite 0 3 examp 5 NewRecno 0 0 6 String 0 0 Hello, World! 7 Integer 99 0 99 8 MakeRecord 2 0 9 PutIntKey 0 1 10 Close 0 0 11 Commit 0 0 12 Halt 0 0 整個操作被分解為12條VDBE說明,前3條和最后2條是系統(tǒng)的標(biāo)準(zhǔn)步驟,所以真正完成我們的工作的是中間7條說明。這段代碼中沒有跳轉(zhuǎn)語句,所有整個代碼段從上到下執(zhí)行一遍。 0 Transaction 0 0 1 VerifyCookie 0 81 2 Transaction 1 0 Transaction 開始一項交互活動。直到 遇到Commit 或者Rollback 時停止。P1參數(shù)是交互開始的數(shù)據(jù)庫文件的索引。0號索引是主文件,1代表這個文件存放的是臨時表。如果P2參數(shù)不為0,則開始一個寫交互。當(dāng)交互開始之 后,對應(yīng)的數(shù)據(jù)庫文件獲得"write lock"狀態(tài)。在這項交互進(jìn)行當(dāng)中其他進(jìn)程將無法讀取這個文件。一項交互必須在任何對數(shù)據(jù)文件的修改動作之前進(jìn)行。如果P2是0這文件將獲得一個 "read lock" VerifyCookie 檢查數(shù)據(jù)庫0號參數(shù)(計劃版本)以確保它=P2,P1是數(shù)據(jù)庫編號,0代表主數(shù)據(jù)庫文件,1代表文件擁有臨時表,其他更大的數(shù)字代表附加數(shù)據(jù)庫。 在建立VerifyCookie之前,必須有一個Transaction已經(jīng)開始,或者已經(jīng)建立了一個read lock. 第2個Transaction語句開始一項交互,應(yīng)用對象是數(shù)據(jù)庫1 (一個臨時數(shù)據(jù)表)。 3 Integer 0 0 4 OpenWrite 0 3 examp Integer 將整數(shù)P1 (0)壓入堆棧。0是下面 OpenWrite 所要用到的數(shù)據(jù)庫的編號,如果P3不為0 ,那么它就是一個代表相同整數(shù)的字符串,執(zhí)行這條語句后,堆棧看起來是這樣 (integer) 0 OpenWrite 創(chuàng)建一個新的讀/寫指針,指向P1(0)也就是數(shù)據(jù)庫中的主文件“examp”,他的根頁(節(jié)點(diǎn))是P2(3),因為數(shù)據(jù)庫文件第一頁是空的,第二頁存放 的是數(shù)據(jù)表的索引。從第3頁開始存放每個數(shù)據(jù)表當(dāng)中的數(shù)據(jù)。P3("examp")是被打開的表的名字,這個參數(shù)是不被使用的,只是使代碼更容易閱讀而 已。這條語句將棧頂元素彈出(0) ,所以之后,堆棧為空。 5 NewRecno 0 0 NewRecno 為指針P1指向的數(shù)據(jù)表創(chuàng)建一個整型的新的紀(jì)錄號。這個紀(jì)錄好并不是一個用在表里的鍵值。新的紀(jì)錄號被壓入堆棧。這個動作之后,堆棧看起來是這樣: (integer) new record key 6 String 0 0 Hello, World! String 將它的P3參數(shù)壓入堆棧,之后,堆棧應(yīng)該是這樣: (string) "Hello World!" (integer) new record key 7 Integer 99 0 99 動作之后,堆棧應(yīng)該是這樣: (integer) 99 (string) "Hello, World!" (integer) new record key 8 MakeRecord 2 0 MakeRecord 將棧頂?shù)腜1個元素取出( 2個),并且將他們轉(zhuǎn)換成二進(jìn)制,然后再把新生成的結(jié)構(gòu)壓回堆棧。之后,堆棧應(yīng)該是這樣: (record) "Hello, World!", 99 (integer) new record key 9 PutIntKey 0 1 PutIntKey 將棧頂?shù)?個元素作為一個entry寫入P1所指的表中,如果表中元素不存在,那么將被創(chuàng)建。如果已經(jīng)存在,則會被覆蓋。數(shù)據(jù)是棧頂元素,鍵是下面的元 素。這條語句當(dāng)中,進(jìn)行2次出棧操作。P2參數(shù)用來判定是否修改表中當(dāng)前rowID,P2=1則rowID 1,并且由 last_insert_rowID()函數(shù)返回,如果rowID=0,則行號不變,仍未當(dāng)前ID.(這就解釋了"表中元素不存在,那么將被創(chuàng)建。如果已 經(jīng)存在,則會被覆蓋").這條語句是文件操作上的insert. 10 Close 0 0 Close 關(guān)閉之前打開的一個文件指針(0)(對應(yīng)于前面的OpenWrite), 如果文件指針當(dāng)前并沒有打開,這條語句不被執(zhí)行。 |
免責(zé)聲明:本站部分文章和圖片均來自用戶投稿和網(wǎng)絡(luò)收集,旨在傳播知識,文章和圖片版權(quán)歸原作者及原出處所有,僅供學(xué)習(xí)與參考,請勿用于商業(yè)用途,如果損害了您的權(quán)利,請聯(lián)系我們及時修正或刪除。謝謝!
始終以前瞻性的眼光聚焦站長、創(chuàng)業(yè)、互聯(lián)網(wǎng)等領(lǐng)域,為您提供最新最全的互聯(lián)網(wǎng)資訊,幫助站長轉(zhuǎn)型升級,為互聯(lián)網(wǎng)創(chuàng)業(yè)者提供更加優(yōu)質(zhì)的創(chuàng)業(yè)信息和品牌營銷服務(wù),與站長一起進(jìn)步!讓互聯(lián)網(wǎng)創(chuàng)業(yè)者不再孤獨(dú)!
掃一掃,關(guān)注站長網(wǎng)微信