33.29 数据库

Emacs 可编译为内置支持访问 SQLite 数据库的版本。本节介绍从 Lisp 程序访问 SQLite 数据库的可用功能。

Function: sqlite-available-p

若当前 Emacs 会话中启用了内置 SQLite 支持, 该函数返回非 nil 值。

当 SQLite 支持可用时,可使用以下函数。

Function: sqlite-open &optional file

该函数将 file 作为 SQLite 数据库文件打开。如果 file 不存在,将创建一个新数据库并存储到该文件中。 若省略 file 或其值为 nil,则创建一个新的内存数据库。

返回值是一个 数据库对象(database object),可作为下文所述大多数后续函数的参数。

Function: sqlitep object

object 是 SQLite 数据库对象,该谓词函数返回 非 nil 值。sqlite-open 函数返回的数据库对象满足此谓词条件。

Function: sqlite-close db

关闭数据库 db。通常无需显式调用此 函数—当 Emacs 关闭或数据库对象被垃圾回收时,数据库将自动关闭。

Function: sqlite-execute db statement &optional values

执行 SQL 语句 statement。例如:

(sqlite-execute db "insert into foo values ('bar', 2)")

若提供可选参数 values,其值应为执行语句时要绑定的值构成的列表或向量。 例如:

(sqlite-execute db "insert into foo values (?, ?)" '("bar" 2))

此写法与上例效果完全相同,但效率更高且更安全(因为不涉及任何字符串解析或插值操作)。

sqlite-execute 通常返回受影响的行数。 例如,‘insert’ 语句通常返回 ‘1’,而 ‘update’ 语句可能返回 0 或更大的数值。 但当使用 SQL 语句如 ‘insert into … returning … 等时,将返回 ‘returning … 子句指定的值。

SQLite 中的字符串默认以 utf-8 编码存储, 查询文本列时会使用该字符集解码字符串。 查询二进制大对象(blob)列将返回未经任何解码的原始数据(即返回包含数据库中存储字节的单字节字符串)。 但向 blob 列插入二进制数据时需要注意,因为 sqlite-execute 默认将所有字符串都解释为 utf-8 编码。

例如,若单字节字符串 gif 中包含 GIF 格式数据, 需对其进行特殊标记以告知 sqlite-execute

(put-text-property 0 1 'coding-system 'binary gif)
(sqlite-execute db "insert into foo values (?, ?)" (list gif 2))
Function: sqlite-execute-batch db statements

执行 SQL 语句集 statementsstatements 是一个 包含 0 个或多个 SQL 语句的字符串。当 Lisp 程序需要一次性执行多条数据定义语言(DDL)语句时, 此命令非常有用。

Function: sqlite-select db query &optional values return-type

db 中查询数据并返回结果。例如:

(sqlite-select db "select * from foo where key = 2")
  ⇒ (("bar" 2))

sqlite-execute 类似,可选择性传入将在执行查询前绑定的值构成的列表或向量:

(sqlite-select db "select * from foo where key = ?" [2])
  ⇒ (("bar" 2))

此方式通常比上例中的方法更高效、更安全。

默认情况下,该函数返回匹配行的列表,其中每行是列值构成的列表。 若 return-typefull,则返回值的第一个元素为列名(字符串列表)。

return-typeset,该函数将返回一个 语句对象(statement object)。可通过 sqlite-nextsqlite-columnssqlite-more-p 函数查看该对象。如果结果集较小,直接返回数据通常更便捷;但如果结果集较大(或无需使用结果集中的所有数据), 使用 set 方式将分配更少的内存,因此内存效率更高。

Function: sqlite-next statement

该函数返回结果集 statement 中的下一行数据, statement 通常是 sqlite-select 返回的对象。

(sqlite-next stmt)
    ⇒ ("bar" 2)
Function: sqlite-columns statement

该函数返回结果集 statement 的列名, statement 通常是 sqlite-select 返回的对象。

(sqlite-columns stmt)
    ⇒ ("name" "issue")
Function: sqlite-more-p statement

该谓词函数用于判断结果集 statement 中是否还有更多待提取的数据, statement 通常是 sqlite-select 返回的对象。

Function: sqlite-finalize statement

若不再使用 statement,调用此函数可释放 statement 占用的资源。 通常无需手动调用—当 statement 对象被 垃圾回收时,Emacs 会自动释放其资源。

Function: sqlite-transaction db

db 中启动一个事务。处于事务中时,数据库的其他读取者 将无法访问事务提交(通过 sqlite-commit)前的结果。

Function: sqlite-commit db

结束 db 中的事务并将数据写入文件。

Function: sqlite-rollback db

结束 db 中的事务并丢弃该事务做出的所有修改。

Macro: with-sqlite-transaction db body…

类似 progn(see 顺序执行),但在持有事务的情况下执行 body, 若 body 正常执行完毕则提交事务。若 body 触发错误, 或事务提交失败,则回滚 bodydb 做出的所有修改。 若 body 正常完成且提交成功,该宏返回 body 的执行结果。

Function: sqlite-pragma db pragma

db 中执行编译指示 pragma编译指示(pragma) 通常是影响整个数据库的命令, 而非针对特定表。例如,要让 SQLite 自动回收不再需要的数据,可执行:

(sqlite-pragma db "auto_vacuum = FULL")

该函数执行成功时返回非 nil 值,编译指示执行失败时返回 nil。 许多编译指示仅能在数据库全新且为空时执行。

Function: sqlite-load-extension db module

将指定的扩展模块 module 加载到数据库 db 中。 扩展模块通常是共享库文件;在 GNU 和 Unix 系统上, 这类文件的扩展名是 .so

Function: sqlite-version

返回表示当前使用的 SQLite 库版本的字符串。

若要列出 SQLite 文件的内容,可使用 sqlite-mode-open-file 命令。该命令会弹出一个使用 sqlite-mode 的缓冲区, 允许你查看(并修改)SQLite 数据库的内容。