原文链接: Documentation
node-sqlite3
内置序函数串行调用,以及操作队列的管理。从而保证即使数据库对象未完全打开,也可以调用该对象上的函数。Database#close()
函数在关闭数据库之前,会先等待所有数据库操作已完成。
API
Main
new sqlite3.Database(filename, [mode], [callback])
返回Database
对象并自动打开数据库。node-sqlite3
没有提供可以单独执行打开数据库的方法。
filename
: 数据库文件路径;:memory:
创建存储在内存的匿名数据库,空字符串创建基于硬盘的匿名数据库。匿名数据库无法持久化数据,当关闭数据库时会丢失数据。mode
: 可选的,有效值为:sqlite3.OPEN_READONLY
、sqlite3.OPEN_READWRITE
、sqlite3.OPEN_CREATE
,可进行与操作。默认为OPEN_READWRITE | OPEN_CREATE
。callback
: 可选的,签名为function([err])
。数据库打开失败或成功的回调函数,如果打开成功,则err参数为null
。
如果未提供callback
参数,则发生错误时,会抛出错误对象并触发当前实例的error
事件。
无论是否提供了callback
参数,当数据库打开成功时,都会触发open
事件(不抛出参数)。
sqlite3.verbose()
返回Database
对象并自动打开数据库,类似sqlite3.Database
。
但是会设置执行模式为verbose
模式,从而会打印更详细的堆栈跟踪信息。没有办法重置该模式。
debug
Database
Database#close([callback])
关闭数据库。
callback
: 可选的。签名为function([err])
。当数据库关闭成功或发生错误时触发。如果关闭成功则err为null
。
如果发生错误,且未提供callback
参数,则触发Database
的error
事件,抛出错误对象。
如果关闭成功,无论是否提供callback
参数,都会触发close
事件(不抛出参数)。
Database#configure(option, value)
设置相关配置。有效参数对象:{ trace, profile, busyTimeout }
。
详细查看: Tracing & profiling、busy timeout。
Database#run(sql, [param, …], [callback])
返回Database
对象,可以方便进行链式调用。
根据指定的参数执行SQL,完成后调用callback
回调。该方法不会检索SQL执行结果。
sql
: 要执行的SQL语句。
如果执行出错,且传入callback
参数,则调用callback
并传入错误对象。
如果未提供callback
参数,则触发底层Statement
对象的error
事件。param,...
: 可选的。如果sql
中存在占位符,则会在sql
执行前绑定参数。param
格式有三种: 依次作为参数传入、作为数组、作为对象。
如果要callback
作为第三个参数传入,则需要传入空数组作为第二个参数。
db.run(sql, (err) => {});
db.run(sql, null, (err) => {});
参数的三种格式:
// Directly in the function arguments.
db.run("UPDATE tbl SET name = ? WHERE id = ?", "bar", 2);
// As an array.
db.run("UPDATE tbl SET name = ? WHERE id = ?", [ "bar", 2 ]);
// As an object with named parameters.
db.run("UPDATE tbl SET name = $name WHERE id = $id", {
$id: 2,
$name: "bar"
});
命名参数可以使用如下前缀::name
,@name
和$name
。建议使用$name
格式,应为在javascript中$
可以不用转义直接作为变量名。
-callback
: (err:Error | Null) => void, sql执行完成后触发的回调。如果执行成功,则第一个参数null
,如果在sql准备阶段、执行阶段、执行完成后任意阶段发生错误,则触发回调并传入错误对象。callback
的this值为对应的statement对象,需注意statement对象只能执行一次,在第一次执行后会自动标志为完成,后续再尝试执行则会报错。
如果执行成功,则this
对象包含两个属性:{lastID,changes}
。
如果sql为INSERT
,则lastID
则代表最后插入的rowid。如果sql为UPDATE
或DELETE
语句,则changes
代表所影响的行数。其他情况下,这两个属性提供的值并不准确,应避免使用。
只有.run()
方法提供了这两个属性,其他查询方法无法获取这两个值,例如.all()
或.get()
等。
Database#get(sql, [param, …], [callback])
执行sql,完成后调用callback
回调。返回数据库对象,方便进行链式调用。
该方法类似.run()
,存在以下区别:
callback
的函数签名为:function(err,row)
。row
为对象,代表sql执行结果的第一行的值。如果执行结果为空,则row
为undefined
。row
的属性名为对应的列名。且仅支持使用列明访问,不能使用索引进行访问。
Database#all(sql, [param, …], [callback])
返回数据库对象。类似.run()
方法,存在以下区别:callback
的签名为function(err,rows)
,rows
为数组类型,如果查询结果为空,则为空数组。数组中的每一项代表一行数据,类似.get()
函数。
该方法会一次性取回所有数据并保存在数组中。如果查询数据量过大,应当使用Database#each
检索所有数据或使用Database#prepare
和Statement#get
检索预先无法预估数量的数据。
Database#each(sql, [param, …], [callback], [complete])
执行sql,返回数据库对象。
callback
签名为function(err,callback)
,该回调会对应每行记录执行一次,执行顺序和返回的查询结果顺序一致。如果查询结果为空,则不会触发callback
回调。
complete
签名为function(err,count)
,该回调会在对应每行callback
执行完成后调用。count
参数为查询结果的行数。
如果仅传入一个函数,则视为callback
回调,如果传入两个函数,则第一个视为callback
,第二个视为complete
。
目前没有提供可以中断执行该函数的方法。
如果能够确定只会返回有限行数的结果,则使用.all()
一次放回所有结果更方便。
Database#exec(sql, [callback])
执行传入的所有sql语句。如果出现错误,则后续未执行的sql则不会执行(如果要确保一致性则建议把sql包在事务中)。
callback
函数签名为function(err)
,如果未提供callback
参数,则发生错误时会触发数据库对象的error
事件。
Note: 该方法只执行到第一个空字节的语句。且不支持注释。
Database#prepare(sql, [param, …], [callback])
准备sql语句。该方法返回Statement
对象。
准备成功后,触发callback
回调,签名为function(err)
。
Statement
Control Flow
node-sqlite3
提供两个方法控制语句的执行流。默认为并行执行模式。但是Database#close
除外,该方法总是等待所有查询完成之后再执行,并且在关闭过程中不会再执行其他任何查询。
Database#serialize([callback])
设置执行模式为串行。
即同一时间最多只能执行一条语句。其他语句在队列中等待,直到前面的语句执行完成。
如果传入callback
参数,则callback
会立即执行,在该函数内,所有sql语句执行为串行模式。该函数返回后(即该函数作用域外),执行模式仍为原来的模式。Database#serialize()
可以嵌套调用:
// 并行模式
db.serialize(function() {
// 串行模式
db.serialize(function() {
// 串行模式
});
// 串行模式
});
// 并行模式
注意:如果查询语句不是直接在.serialize()
的callback
参数中,则可能不是串行模式:
db.serialize(function() {
// 以下两个查询为串行执行。
db.run("CREATE TABLE foo (num)");
db.run("INSERT INTO foo VALUES (?)", 1, function() {
// 以下两个查询为并行执行。
// 因此第二个查询语句有可能发生错误,因为执行时该表还不存在
db.run("CREATE TABLE bar (num)");
db.run("INSERT INTO bar VALUES (?)", 1);
});
});
如果未传入callback
参数,则此时执行模式会直接转换为串行模式,直到再次调用Database#parallelize
。
Database#parallelize([callback])
设置执行模式为并行模式。
类似Database#serialize()
,但是执行模式为并行:
db.serialize(function() {
// 串行模式
db.parallelize(function() {
// 并行模式
});
// 串行模式
});
Debugging
通过线程池编写的异步函数非常不幸的会丢失堆栈跟踪信息,从而导致调试会非常痛苦,因为只是通过错误对象,并不能判断是哪里导致的错误。为了缓解这种问题,node-sqlite3
提供了verbose
模式来捕获堆栈跟踪信息。通过调用sqlite3.verbose()
开启verbose
模式,或直接在require的时候就使用var sqlite3 = require('sqlite3').verbose()
。
当你在数据库对象的函数的回调中抛出错误时,node-sqlite3
会从原始调用中追加堆栈跟踪信息:
Error: SQLITE_RANGE: bind or column index out of range
--> in Database#run('CREATE TABLE foo (a, b)', 3, [Function])
at Object.<anonymous> (demo.js:5:4)
at Module._compile (module.js:374:26)
at Object..js (module.js:380:10)
at Module.load (module.js:306:31)
at Function._load (module.js:272:10)
at Array.<anonymous> (module.js:393:10)
at EventEmitter._tickCallback (node.js:108:26)
注意: 不应当在生产环境使用verbose
模式,因为收集堆栈跟踪信息的性能损耗很大。
Verbose
模式目前不会在语句对象(Statement
)和数据库对象(Database
)抛出的错误对象上添加堆栈跟踪信息。
Database#on('trace', [callback])
执行查询时触发该事件,callback
的签名为: function(sql)
Database#on('profile', [callback])
在查询语句执行结束后触发的事件,callback
的签名为:function(sql,milliseconds)
Extensions
Database#loadExtension(path, [callback])
加载SQLite扩展。
path
: SQLite扩展的文件路径。callback
: 扩展加载完成后触发回调。
Caching
node-sqlite3
内置了数据库对象缓存,以避免多次打开同一个数据库。要使用缓存特性,只需使用new sqlite3.cached.Database()
替代new sqlite3.Database()
。