作者:SQLite 开发团队
译者:宋彤彤
责编:屠敏
原文链接:https://github.com/sqlite/sqlite
SQLite是遵守ACID的关系数据库管理系统,它包含在一个相对小的C程序库中。与许多其它数据库管理系统不同,SQLite不是一个客户端/服务器结构的数据库引擎,而是被集成在用户程序中。SQLite是D. Richard Hipp创建的开源项目。
SQLite遵守ACID,实现了大多数SQL标准。它使用动态的、弱类型的SQL语法。它作为嵌入式数据库,是应用程序,如网页浏览器,在本地/客户端存储数据的常见选择。它可能是最广泛部署的数据库引擎,因为它正在被一些流行的浏览器、操作系统、嵌入式系统所使用。同时,它有许多程序设计语言的语言绑定。
该存储库包含SQLite数据库引擎的完整源代码,还包括一些测试脚本。 但是许多其他测试脚本和大部分文档都是单独管理的。
版本控制
SQLite源代码使用Fossil进行管理,Fossil是一个分布式版本控制系统,专为支持SQLite开发而设计和编写。Fossil存储库包含urtext。
如果你在GitHub或其他一些Git存储库或服务上阅读这篇文章,那么你看到的就是一面镜子。Git镜像中签入和其他项目的名称与这些对象的官方名称不同。签入的官方名称可在授权镜像的签入注释的页脚中找到。官方签入名称也可以在树根目录的文件中看到。在沟通SQLite签入时,始终使用官方名称,而不是Git名称。
如果您从辅助源中提取了SQLite源代码,并想验证其完整性,则在下面的验证代码真实性部分中提供了有关如何执行此操作的提示。
获取代码
如果您不想使用Fossil,可以下载压缩包或ZIP存档或SQLite存档,如下所示:
最新的主干签入为压缩包、ZIP存档或SQLite存档。
最新版本为Tarball、ZIP-archive或SQLite-archive。
对于其他签入,对于其他签入,用适当的分支名称、标签或散列前缀代替上一个项目符号的 URL 中的“release”。亦或是浏览时间线来找到所需的签到,单击其信息页面链接,然后单击信息页面上的“压缩包”或“ZIP存档”链接。
如果您确实想使用Fossil查看源代码树,请先安装Fossil 2.0版或更高版本。Fossil是一个独立的程序。要安装,只需下载或构建单个可执行文件,然后将该文件放在$PATH上的某个地方。然后运行如下命令:
mkdir -p ~/sqlite ~/Fossils
cd ~/sqlite
fossil clone https://www.sqlite.org/src ~/Fossils/sqlite.fossil
fossil open ~/Fossils/sqlite.fossil
使用上述步骤设置存储库后,您始终可以使用以下命令更新到最新版本:
fossil update trunk;
# latest trunk check-in
fossil update release ;
# latest official release
或者键入"fossil ui"以获取基于Web的用户界面。
为类Unix系统编译
首先创建一个目录,在其中放置生成产品,建议(但不是必需)生成目录与源目录分开。Cd进入构建目录,然后从构建目录运行在源代码树根目录下找到的配置脚本。然后运行"make"。
例如:
tar xzf sqlite.tar.gz;
#Unpack the source tree into "sqlite"
mkdir bld;
#Build will occur in a sibling directory
cd bld;
#Change to the build directory
../sqlite/configure;
#Run the configure script
make;
#Run the makefile.
make sqlite3.c;
#Build the "amalgamation" source file
make test;
#Run some tests (requires Tcl)
有关其他目标,请参阅生成文件。
配置脚本使用autoconf 2.61和libtool。如果配置脚本不适合您,则在源代码树的顶部目录中有一个名为"Makefile.linux-gcc"的通用生成文件,您可以复制和编辑该文件以满足您的需要。通用生成文件上的注释显示了需要哪些更改。
将MSVC用于Windows系统
在Windows上,所有适用的生成产品都可以使用MSVC进行编译。首先打开与所需编译器版本关联的命令提示符窗口(例如"VS2013的开发人员命令提示符")。接下来,将NMAKE与提供的"Makefile.msc"结合使用,来构建一个受支持的目标。
例如,从名为"sqlite"的源子树的父目录中:
mkdir bld
cd bld
nmake /f ..\sqlite\Makefile.msc TOP=..\sqlite
nmake /f ..\sqlite\Makefile.msc sqlite3.c TOP=..\sqlite
nmake /f ..\sqlite\Makefile.msc sqlite3.dll TOP=..\sqlite
nmake /f ..\sqlite\Makefile.msc sqlite3.exe TOP=..\sqlite
nmake /f ..\sqlite\Makefile.msc test TOP=..\sqlite
可以通过NMAKE命令行设置多个生成选项。例如,要为WinRT构建,只需将 “FOR_WINRT=1”参数添加到上面的 “sqlite3.dll”命令行中即可。调试到SQLite代码时,建议将“DEBUG=1”参数添加到上述命令行之一。
SQLite不需要Tcl运行,但makefile(包括MSVC的文件)需要安装Tcl。SQLite包含大量生成的代码,Tcl用于执行大部分代码生成。
源代码之旅
大多数核心源文件都位于src/子目录中。src/文件夹还包含用于构建“testfixture”测试工具的文件。“testfixture”使用的源文件的名称都以“test”开头。src/ 还包含“shell.c”文件,它是“sqlite3.exe”命令行shell的主程序和“tclsqlite.c”文件,它实现了SQLite的Tcl绑定。(历史注释:SQLite最初是Tcl扩展,后来才作为一个独立的库逃到野外。
测试脚本和程序位于测试/子目录中。附加测试代码可以在其他源存储库中找到。请参阅如何测试SQLite以获取更多信息。
ext/子目录包含扩展的代码。全文搜索引擎位于ext/fts3中。R-树引擎位于ext/rtree中。ext/misc子目录包含许多较小的单文件扩展名,如REGEXP运算符。
该工具/子目录包含各种脚本和程序,用于构建生成的源代码文件或用于测试或生成附件程序,例如“sqlite3_analyzer(.exe)”。
生成的源代码文件
SQLite使用的几个C语言源文件是从其他源生成的,而不是由程序员手动键入的。本节将总结这些自动生成的文件。要创建所有自动生成的文件,只需运行“制作target_source”。“target_source”make target将创建一个子目录“tsrc/”,并用构建SQLite所需的所有源文件填充它,包括手动编辑的文件和自动生成的文件。
SQLite接口由sqlite3.h头文件定义,该文件由src/sqlite.h.in、./manifest.uuid和./VERSION生成,tool/mksqlite3h.tcl上的Tcl脚本执行转换。manifest.uuid文件包含特定签入的SHA3散列,并用于生成SQLITE_SOURCE_ID宏。VERSION文件包含当前的SQLite版本号。sqlite3.h头文件实际上只是src/sqlite.h.in的副本,源代码ID和版本号插入在正确的位置。请注意,sqlite3.h文件中的注释文本用于生成大部分SQLite API文档。用于生成该文档的Tcl脚本位于单独的源存储库中。
SQL语言解析器是parse.c它是从src/parse.y文件中的语法生成的。将 “parse.y”转换为 “parse.c”由lemon LALR(1)解析器生成器完成,lemon的源代码位于tool/lemon.c。Lemon使用工具/lempar.c文件作为生成其解析器的模板,还会生成parse.h头文件,同时生成parse.c。
opcodes.h头文件包含宏,这些宏定义与“VDBE”虚拟机中的操作码的数字相对应。opcodes.h文件由扫描 src/vdbe.c源文件生成。位于./mkopcodeh.tcl的Tcl脚本执行此扫描并生成 opcodes.h。然后,第二个Tcl脚本./mkopcodec.tcl扫描opcodes.h以生成opcodes.c源文件,其中包含从操作码编号到操作码名称的反向映射,用于EXPLAIN输出。
关键字hash.h头文件包含散列表的定义,该散列表将SQL语言关键字(例如:“CREATE”,“SELECT”,“INDEX”等)映射到解析器.c解析器使用的数字代码中。关键字hash.h文件由工具mkkeywordhash.c的C语言程序生成。
pragma.h头文件包含用于解析和实现PRAGMA语句的各种定义。标头由脚本工具/mkpragmatab.tcl生成。如果要添加新的PRAGMA,请编辑tool/mkpragmatab.tcl文件以插入解析器为新PRAGMA所需的信息,然后运行脚本以重新生成pragma.h头文件。
合并
所有单独的C源代码和头文件(手动编辑和自动生成)都可以组合成一个大的源文件sqlite3.c称为“合并”,合并是在大型应用程序中使用SQLite的推荐方式。将所有单独的源代码文件组合到一个大的源代码文件中,使C编译器能够执行更多的跨过程分析并生成更好的代码。SQLite从合并编译时比从单个源文件编译时快约5%。
合并是从工具/mksqlite3c.tcl Tcl脚本生成的。首先,必须将所有单独的源文件收集到tsrc/ 子目录中(使用等效“make target_source”),然后运行tool/mksqlite3c.tcl脚本,以正确的顺序将它们全部复制在一起,同时解析内部的“#include”引用。
合并源文件的长度超过200K行。某些符号调试器(最明显的是MSVC)无法处理长度超过64K行的文件。为了解决这个问题,可以在合并上运行一个单独的Tcl脚本tool/split-sqlite3c.tcl,将其分解成一个名为sqlite3-all.c的小C文件,该文件#include大约七个名为sqlite3-1.c,sqlite3-2.c,…,sqlite3-7.c。通过这种方式,所有源代码都包含在单个翻译单元中,以便编译器可以进行额外的跨过程优化,但单个源文件的长度不会超过32K行。
如何全部融合在一起
SQLite采用模块化设计。有关详细信息,请参阅体系结构说明。中有用的其他文档(帮助了解SQLite的工作原理)包括文件格式说明、运行预准备语句的虚拟机、事务工作原理的说明以及查询计划程序的概述。
多年来,我们一直在努力优化SQLite,无论是小尺寸还是高性能。优化往往会导致复杂的代码。因此,当前的SQLite实现中存在很多复杂性。它不会是世界上最容易破解的图书馆。
密钥文件:
- sqlite.h.in ——此文件定义SQLite库的公共接口。读者需要熟悉此界面,然后才能尝试了解库的内部工作原理。
- sqliteInt.h ——此头文件定义了SQLite内部使用的许多数据对象。除了“sqliteInt.h”之外,一些子系统还有自己的头文件。
- parse.y ——此文件描述了SQLite用于解析SQL语句的LALR(1)语法,以及在解析过程中每个步骤中执行的操作。
- vdbe.c ——此文件实现了运行预准备语句的虚拟机。有各种帮助程序文件的名称以“vdbe”开头。VDBE可以访问定义内部数据对象的vdbeInt.h头文件。SQLite的其余部分通过vdbe.h定义的接口与VDBE进行交互。
- where.c ——此文件(连同其由“where*.c”命名的帮助程序文件)分析WHERE子句并生成虚拟机代码以有效地运行查询。此文件有时称为“查询优化器”。它有自己的私有头文件,其中Int.h,定义内部使用的数据对象。
- btree.c ——此文件包含SQLite使用的B树存储引擎的实现。系统其余部分的接口由"btree.h"定义。“btreeInt.h”头定义了btree内部使用的对象.c而不是发布到系统的其余部分。
- pager.c ——此文件包含“pager”实现,即实现事务的模块。“pager.h”头文件定义了pager.c和系统其余部分之间的接口。
- os_unix.c和os_win.c ——这两个文件使用运行时可插拔VFS接口实现SQLite和基础操作系统之间的接口。
- shell.c.in ——此文件不是核心SQLite库的一部分。当与sqlite3.a链接时,该文件会生成“sqlite3.exe”命令行shell。作为构建过程的一部分,“shell.c.in”文件将转换为“shell.c”。
- tclsqlite.c ——此文件实现SQLite的Tcl绑定。它不是核心SQLite库的一部分。但是,由于此存储库中的大多数测试都是用Tcl编写的,因此Tcl语言绑定非常重要。
- test.c* ——src/文件夹中以“test”开头的文件将用于构建“testfixture.exe”程序。testfixture.exe程序是一个增强的Tcl shell。testfixture.exe程序在test/文件夹中运行脚本来验证核心SQLite代码。测试修复程序(以及一些其他测试程序)是在您键入“进行测试”时构建并运行的。
- ext/misc/json1.c——此文件实现内置于SQLite中的各种JSON函数。
【开源资讯|开源数据库 SQLite 发布 3.37.0 版本】验证代码真实性
源代码树根目录下的文件包含存储库中每个源文件的SHA3-256散列值(对于较新的文件)或 SHA1散列值(对于较旧的文件)。文件本身的SHA3-256散列值是您拥有的源代码树版本的官方名称。该文件应包含该文件的SHA3-256散列值。如果上述所有散列值比较都是正确的,那么您可以确信您的源树是真实的,而不是掺杂的。
推荐阅读
- Java|Java基础——数组
- 人工智能|干货!人体姿态估计与运动预测
- java简介|Java是什么(Java能用来干什么?)
- Java|规范的打印日志
- Linux|109 个实用 shell 脚本
- 程序员|【高级Java架构师系统学习】毕业一年萌新的Java大厂面经,最新整理
- Spring注解驱动第十讲--@Autowired使用
- SqlServer|sql server的UPDLOCK、HOLDLOCK试验
- jvm|【JVM】JVM08(java内存模型解析[JMM])
- 技术|为参加2021年蓝桥杯Java软件开发大学B组细心整理常见基础知识、搜索和常用算法解析例题(持续更新...)