17站长网

17站长网 首页 数据库 SQLite教程 查看内容

Sqlite虚拟机VDBE原理

2023-3-21 15:29| 查看: 1356 |来源: 互联网

VDBE (virtual database engine)是一个运行他自己的虚拟机语言组成的程序的虚拟机。每条程序都是用来查询或者操作数据库的。出于这个目的,VDBE的机器语言被设计 ...

VDBE (virtual database engine)是一个运行他自己的虚拟机语言组成的程序的虚拟机。每条程序都是用来查询或者操作数据库的。出于这个目的,VDBE的机器语言被设计用来进行搜索,读和修改数据库。

每一条VDBE 说明包括一个OPCODE 和3个OPRANDS分别为P1,P2和P3。P1,P2 为整数,P3是一个指向数据结构或者字符串的指针,有可能为空。大多数说明只用到1-2个OPRANDS,只有少数 说明用到了全部3个OPRANDS。有很多非常重要的说明根本没有用到任何OPRANDS但是却能读取数据并且将结果写入运行时栈当中。

一段VDBE代码从说明0开始运行,直到

1。遇到致命错误;

2。执行了停止说明;

3。整段代码运行完毕,所有打开的数据库都已经关闭,所有内存都已经释放,栈为空。

example:

1.建立一个数据表,并且插入一个数据

CREATE TABLE examp(one text,two int);

INSERT INTO examp VALUES( 'Hello,World!'99);

VDBE将这样解释并执行这两条语句

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条是系统的标准步骤,所以真正完成我们的工作的是中间7条说明。这段代码中没有跳转语句,所有整个代码段从上到下执行一遍。

0 Transaction 0 0

1 VerifyCookie 0 81

2 Transaction 1 0

Transaction 开始一项交互活动。直到 遇到Commit 或者Rollback 时停止。P1参数是交互开始的数据库文件的索引。0号索引是主文件,1代表这个文件存放的是临时表。如果P2参数不为0,则开始一个写交互。当交互开始之 后,对应的数据库文件获得"write lock"状态。在这项交互进行当中其他进程将无法读取这个文件。一项交互必须在任何对数据文件的修改动作之前进行。如果P2是0这文件将获得一个 "read lock"

VerifyCookie 检查数据库0号参数(计划版本)以确保它=P2,P1是数据库编号,0代表主数据库文件,1代表文件拥有临时表,其他更大的数字代表附加数据库。

在建立VerifyCookie之前,必须有一个Transaction已经开始,或者已经建立了一个read lock.

第2个Transaction语句开始一项交互,应用对象是数据库1 (一个临时数据表)。

3 Integer 0 0

4 OpenWrite 0 3 examp

Integer 将整数P1 (0)压入堆栈。0是下面 OpenWrite 所要用到的数据库的编号,如果P3不为0 ,那么它就是一个代表相同整数的字符串,执行这条语句后,堆栈看起来是这样

(integer) 0

OpenWrite 创建一个新的读/写指针,指向P1(0)也就是数据库中的主文件“examp”,他的根页(节点)是P2(3),因为数据库文件第一页是空的,第二页存放 的是数据表的索引。从第3页开始存放每个数据表当中的数据。P3("examp")是被打开的表的名字,这个参数是不被使用的,只是使代码更容易阅读而 已。这条语句将栈顶元素弹出(0) ,所以之后,堆栈为空。

5 NewRecno 0 0

NewRecno 为指针P1指向的数据表创建一个整型的新的纪录号。这个纪录好并不是一个用在表里的键值。新的纪录号被压入堆栈。这个动作之后,堆栈看起来是这样:

(integer) new record key

6 String 0 0 Hello, World!

String 将它的P3参数压入堆栈,之后,堆栈应该是这样:

(string) "Hello World!"

(integer) new record key

7 Integer 99 0 99

动作之后,堆栈应该是这样:

(integer) 99

(string) "Hello, World!"

(integer) new record key

8 MakeRecord 2 0

MakeRecord 将栈顶的P1个元素取出( 2个),并且将他们转换成二进制,然后再把新生成的结构压回堆栈。之后,堆栈应该是这样:

(record) "Hello, World!", 99

(integer) new record key

9 PutIntKey 0 1

PutIntKey 将栈顶的2个元素作为一个entry写入P1所指的表中,如果表中元素不存在,那么将被创建。如果已经存在,则会被覆盖。数据是栈顶元素,键是下面的元 素。这条语句当中,进行2次出栈操作。P2参数用来判定是否修改表中当前rowID,P2=1则rowID 1,并且由 last_insert_rowID()函数返回,如果rowID=0,则行号不变,仍未当前ID.(这就解释了"表中元素不存在,那么将被创建。如果已 经存在,则会被覆盖").这条语句是文件操作上的insert.

10 Close 0 0

Close 关闭之前打开的一个文件指针(0)(对应于前面的OpenWrite), 如果文件指针当前并没有打开,这条语句不被执行。

本文最后更新于 2023-3-21 15:29,某些文章具有时效性,若有错误或已失效,请在网站留言或联系站长:17tui@17tui.com
·END·
站长网微信号:w17tui,关注站长、创业、关注互联网人 - 互联网创业者营销服务中心

免责声明:本站部分文章和图片均来自用户投稿和网络收集,旨在传播知识,文章和图片版权归原作者及原出处所有,仅供学习与参考,请勿用于商业用途,如果损害了您的权利,请联系我们及时修正或删除。谢谢!

17站长网微信二维码

始终以前瞻性的眼光聚焦站长、创业、互联网等领域,为您提供最新最全的互联网资讯,帮助站长转型升级,为互联网创业者提供更加优质的创业信息和品牌营销服务,与站长一起进步!让互联网创业者不再孤独!

扫一扫,关注站长网微信

大家都在看

热门排行

最近更新

返回顶部