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), 如果文件指针当前并没有打开,这条语句不被执行。 |
免责声明:本站部分文章和图片均来自用户投稿和网络收集,旨在传播知识,文章和图片版权归原作者及原出处所有,仅供学习与参考,请勿用于商业用途,如果损害了您的权利,请联系我们及时修正或删除。谢谢!
始终以前瞻性的眼光聚焦站长、创业、互联网等领域,为您提供最新最全的互联网资讯,帮助站长转型升级,为互联网创业者提供更加优质的创业信息和品牌营销服务,与站长一起进步!让互联网创业者不再孤独!
扫一扫,关注站长网微信