开源项目CuteSqlite开发笔记(二):SQLite的架构

在开发CuteSqlite图形客户端的时候,需要用到SQL的语法解释,来对SQL语句进行优化。找了很多的SQL语法解释器,都不是十分满意,只有翻开Sqlite的源码,看看SQLite对SQL语句的解释过程,本文是翻译的官方文档。

 官方介绍架构的文章:https://www.sqlite.org/arch.html

CuteSqlite源码:https://github.com/shinehanx/CuteSqlite.git

SQLite的架构

SQLite的架构图

Introduction 介绍

本文档描述了SQLite库的架构。这里的信息对于那些想要理解或修改SQLite内部工作原理的人很有用。

Overview 概述

SQLite的工作原理是将SQL文本编译成字节码,然后使用虚拟机运行该字节码。

sqlite3_tagre_v2()和相关接口充当将SQL文本转换为字节码的编译器。sqlite3_stmt对象是实现单个SQL语句的单个字节码程序的容器。sqlite3_step()接口将字节码程序传递到虚拟机中,并运行该程序,直到它完成,或形成一行要返回的结果,或遇到致命错误,或被中断。

Interface  接口

C语言接口的大部分内容都可以在源文件main.c、legacy.c和vdbeapi.c中找到,尽管有些例程分散在其他文件中,它们可以访问具有文件范围的数据结构。sqlite3_get_table()例程在table.c中实现。sqlite3_mprintf()例程位于printf.c中。sqlite3_complete()接口位于complete.c中。TCL接口由tclsqlite.c实现。

为了避免名称冲突,SQLite库中的所有外部符号开始都以前缀sqlite3开头。那些供外部使用的符号(换句话说,那些构成SQLite的API的符号)添加下划线,因此开始以sqlite3_开头。扩展API有时会在下划线之前添加扩展名;例如:sqlite3_rbu_或sqlite3_session_。

Tokenizer 分词器

当一个包含SQL语句的字符串要被求值时,它首先被发送到标记器。tokenizer将SQL文本分解为标记,并将这些标记一个接一个地交给解析器。tokenizer在文件tokenize.c中手工编码。

注意,在这个设计中,标记器调用解析器。熟悉YACC和BISON的人可能习惯于用相反的方式来做事情--让解析器调用标记器。不过,让标记器调用解析器会更好,因为它可以是线程安全的,而且运行得更快。

Parser 解析器

解析器根据上下文为标记分配语义。SQLite的解析器使用Lemon解析生成器生成(包含解释SQL语法,并生成C语言代码)。Lemon的工作与YACC/BISON相同,但它使用了不同的输入语法,这更不容易出错。Lemon还生成了一个可重入和线程安全的解析器。Lemon定义了非终结符析构函数(non-terminal destructor)的概念,这样当遇到语法错误时它就不会泄漏内存。驱动Lemon并定义SQLite理解的SQL语言的语法文件位于src/parse.y中。

因为Lemon是一个通常在开发机器上找不到的程序,所以Lemon的完整源代码(只有一个C文件)包含在SQLite发行版的"tool"目录中。(稍后在WINDOWS上使用GCC编译出lemon.exe,并解释src/parse.y成C语言代码)

Code Generator 代码生成器

在解析器将标记组装到解析树中之后,代码生成器运行以分析解析树并生成执行SQL语句的工作的字节码。准备好的语句对象是这个字节码的容器。代码生成器中有许多文件,包括:attach.c、auth.c、build.c、delete.c、expr.c、insert.c、pragma.c、select.c、deliver.c、update.c、vacuum.c、where.c、wherecode.c和whereexpr.c。在这些文件中,大多数严重的魔术发生。expr.c处理表达式的代码生成。where*.c处理SELECT、UPDATE和NULL语句上的WHERE子句的代码生成。文件attach.c、delete.c、insert.c、select.c、update.c和vacuum.c处理具有相同名称的SQL语句的代码生成。(这些文件的每一部分会调用expr.c和where.c中的例程。)所有其他SQL语句都是从build.c中编写的。auth.c文件实现了sqlite3_set_authorizer()的功能。

Bytecode Engine  字节码引擎

由代码生成器创建的字节码程序由虚拟机运行。

虚拟机本身完全包含在单个源文件vdbe.c中。vdbe.h头文件定义了虚拟机与SQLite库的其余部分之间的接口,vdbeInt.h定义了虚拟机本身私有的结构和接口。其他各种vdbe*.c文件是虚拟机的助手。vdbeaux.c文件包含虚拟机使用的实用程序和库的其余部分用来构建VM程序的接口模块。vdbeapi.c文件包含虚拟机的外部接口,例如sqlite3_bind_int()和sqlite3_step()。单个值(字符串、整数、浮点数和BLOB)存储在名为“Mem”的内部对象中,该对象由vdbem.c实现。

SQLite使用C语言例程的回调来实现SQL函数。即使是内置的SQL函数也是这样实现的。大多数内置的SQL函数(例如:abs()、count()、substr()等)都可以在func.c源文件中找到。日期和时间转换函数可以在date.c中找到。有些函数,如coalesce()和typeof(),直接由代码生成器实现为字节码。

B-Tree b树

SQLite数据库使用btree.c源文件中的B树,实现在磁盘上维护。单独的B树用于数据库中的每个表和每个索引。所有的B树都存储在同一个磁盘文件中。文件格式细节是稳定和明确定义的,并保证向前兼容。

B树子系统和SQLite库的其余部分的接口由头文件btree.h定义。

Page Cache 页面高速缓存

B树模块以固定大小的页面从磁盘请求信息。默认的page_size是4096字节,但可以是512到65536字节之间的2的任意幂。页面缓存负责阅读、写入和缓存这些页面。页面缓存还提供回滚和原子提交抽象,并负责数据库文件的锁定。B树驱动程序从页面缓存中请求特定的页面,并在想要修改页面或提交或回滚更改时通知页面缓存。页面缓存处理所有混乱的细节,以确保请求得到快速、安全和有效的处理。

主页面缓存实现在pager.c文件中。WAL模式逻辑在单独的wal.c中。内存缓存是由pcache.c和pcache1.c文件实现的。页面缓存子系统和SQLite其余部分之间的接口由头文件pager.h定义。

主页面缓存实现在pager.c文件中。WAL模式逻辑在单独的wal.c中。内存缓存是由pcache.c和pcache1.c文件实现的。页面缓存子系统和SQLite其余部分之间的接口由头文件pager.h定义。

OS Interface OS接口

为了提供跨操作系统的可移植性,SQLite使用了一个称为VFS的抽象对象。每个VFS都提供了打开、阅读、写入和关闭磁盘上文件的方法,以及其他特定于操作系统的任务,如查找当前时间或获取随机性以初始化内置的伪随机数生成器。SQLite目前为unix(在os_unix.c文件中)和Windows(在os_win.c文件中)提供了VFS。

Utilities 公共的工具函数

内存分配、无大小写字符串比较例程、可移植文本到数字转换例程和其他实用程序位于util.c中。解析器使用的符号表由hash. c中的哈希表维护。utf. c源文件包含Unicode转换子例程。SQLite在printf.c中有自己的printf()私有实现(带有一些扩展),在random.c中有自己的伪随机数生成器(PRNG)。

Test Code 测试代码

源代码树的“src/”文件夹中名称以test开始的文件仅用于测试,不包含在库的标准构建中。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/198400.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Twincat功能块使用经验总结

控制全局变量: //轴控制指令 bi_Power: BOOL; //使能 bi_Reset: BOOL; //复位 bi_Stop: BOOL; //停止 bi_JogForward: BOOL; //正向点动 bi_JogBackwards: BOOL; //反向点动 bi_MoveAdditive: BOOL; //增量位…

Anaconda创建虚拟环境以及Pycharm和Jupyter如何切换虚拟环境

文章目录 Anaconda创建管理虚拟环境0. 进入到终端1. 创建新环境2. 切换环境3. 删除环境4. 查询当前已有的环境 Pycharm切换虚拟环境0. 更换解析器1. 添加虚拟环境(之前默认的是base环境)2. 验证切换虚拟环境 Jupyter Notebook 切换虚拟环境1. 安装ipyker…

基于SSM框架的《超市订单管理系统》Web项目开发(第五天)供应商管理,增删改查

基于SSM框架的《超市订单管理系统》Web项目开发(第五天)供应商管理,增删改查 上一次我们实现了多表关联查询,还有分页显示数据的功能。还完善了用户管理这一模块。 因此今天我们需要完成的是供应商管理模块,这一模块…

BFD多跳检测配置

定义 双向转发检测BFD(Bidirectional Forwarding Detection)是一种全网统一的检测机制,用于快速检测、监控网络中链路或者IP路由的转发连通状况。 目的 为了减小设备故障对业务的影响,提高网络的可靠性,网络设备需要…

抖店的基础框架怎么搭建?新手必看!

我是电商珠珠 我做抖店也已经将近3年了,很多新手会经常问我抖店到底要怎么做这些问题,我呢总结出了一个做抖店的基础框架,想要了解的朋友们仔细往下看。 1、入驻 入驻的时候需要去办理营业执照,营业执照的话可以是个体工也可以…

2-二分-索引二分-在排序数组中查找元素的第一个和最后一个位置

这是索引二分的第二篇算法,力扣链接 这道题其实在另一个专栏写过,借此机会复习一下吧。 给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。 如果数组中不存在目标值 targe…

指针进阶知识超详细讲解(C语言)(中)

前言 苦苦等待,终于迎来了我们的指针讲解第二期,如果有还没有看过上一期的小伙伴,那赶紧点击这个链接学习后再来看这篇博客吧。指针基础知识超详细讲解(C 语言)(上) 如果对学习C语言有兴趣那千万…

超热门好用的免费API接口汇总

通用文字识别OCR:多场景、多语种、高精度的整图文字检测和识别服务,多项指标行业领先,可识别中、英、日、韩、法、德多种语言。二维码识别OCR:对图片中的二维码、条形码进行检测和识别,返回存储的文字内容。身份证识别…

如何在Linux环境搭建本地SVN服务器并结合cpolar实现公网访问

目录 前言 1. Ubuntu安装SVN服务 2. 修改配置文件 2.1 修改svnserve.conf文件 2.2 修改passwd文件 2.3 修改authz文件 3. 启动svn服务 4. 内网穿透 4.1 安装cpolar内网穿透 4.2 创建隧道映射本地端口 5. 测试公网访问 6. 配置固定公网TCP端口地址 6.1 保留一个固定…

GEE:Sobel算子卷积

作者:CSDN _养乐多_ 本文将深入探讨边缘检测中的一个经典算法,即Sobel算子卷积。我们将介绍该算法的基本原理,并演示如何在Google Earth Engine中应用Sobel算子进行图像卷积操作。并以试验区NDVI为例子,研究区真彩色影像、NDVI图…

【GIT】.gitignore 在忽略目录中放开某目录

示例:忽略build下面的所有目录,只放开build/ast2500-default/workspace/recipes-phosphor/ 目录 .gitignore 实现文件代码 # 忽略 build 目录下的所有目录 # 并放开build/ast2500-default/workspace/recipes-phosphor/ build/* !build/ast2500-defaul…

记录 | c++打印变量类型

c打印变量类型: 使用 typeid(变量名).name() int main(){std::cout << "type of ss : " << typeid(ss).name() << std::endl; }

轮询分区的设置

终于可以写MPI了&#xff0c;没想到&#xff0c;刚开始就当头一棒&#xff0c;我按照之前的配置MPI环境&#xff0c;配置完成就报错 好家伙&#xff0c;仔细检查了每一个步骤都没找到问题&#xff0c;上网搜索了一些解决方案&#xff0c;也没有解决。所幸&#xff0c;在配置MPI…

关于前端学习的思考-vertical-align的用法

先摆结论&#xff1a;vertical-align这里的top线&#xff0c;bottom线&#xff0c;middle线&#xff0c;baseline线是由最大宽度和最大高度的行内元素或行内块元素决定的。 按照惯例&#xff0c;先摆三个行内元素。 1、改变第一个盒子&#xff0c;vertical-align&#xff1a;to…

主机装ubuntu双系统,无线网络问题

微星主板开机按del进入bios&#xff0c;setting里设置启动优先级 启动盘制作 350G 三个分区&#xff1a; 1.EFI系统分区&#xff0c;2G&#xff0c;逻辑分区&#xff0c;空间起始位置 2.Ext4&#xff0c;/&#xff0c;根目录&#xff0c;120G&#xff0c;主分区&#xff0c…

Java异常详解大全(2023版)

Java异常详解 异常分类1.Throwable2. Error(错误)3. Exception(异常)3.1 运行时异常 RuntimeException3.2 编译时异常(受检查异常)ClassNotFoundException + IOException4.常见的运行时异常5.异常如何处理Java 的异常处理是通过 5 个关键词来实现的:try、catch、throw、…

Uber Go 语言编码规范

uber-go/guide 的中文翻译 English 文档链接 Uber Go 语言编码规范 Uber 是一家美国硅谷的科技公司&#xff0c;也是 Go 语言的早期 adopter。其开源了很多 golang 项目&#xff0c;诸如被 Gopher 圈熟知的 zap、jaeger 等。2018 年年末 Uber 将内部的 Go 风格规范 开源到 G…

人工智能学习6(贝叶斯实现简单的评论情感分析)

编译工具PyCharm 文章目录 编译工具PyCharm 文本分析与表示实现方式&#xff1a;文本表示方法文本相似度计算LDA主题模型 朴素贝叶斯算法应用&#xff1a;评论情感分析&#xff0c;工具评论分析是好评还是差评获取数据加载停用词内容标准化&#xff08;将每一句话划分成一个个的…

四通道轨-轨运算芯片 D8054,外围应用简便,低功耗2.3mA (典型值)运放供电电流

D8054是一款四通道轨-轨运算放大器&#xff0c;外围应用简便&#xff0c;价格低廉。封装形式为SOP14&#xff0c;TSSOP14&#xff0c; SOP16&#xff0c; TSSOP16。 主要特点&#xff1a; ● 轨-轨输出&#xff0c;输出失调2mV (典型值) ● 高速250MHz&#xff0c;-3dB带…

HNU-电路与电子学-2018期末A卷(含标准解析)

【写在前面】 电路与电子学好像是从2020级开设的课程&#xff0c;故实际上目前只有2020与2021两个年级考过期末考试。 这门课程主要由所谓的“数电”与“模电”组成。而且先学的“模电”后学的“”数电&#xff0c;故期中考试主要以“模电”为主&#xff0c;期末考试主要以“数…