Looks like JavaScript, feels like Ruby, and it is a script language fitting in C programmers.
This project is maintained by Kray-G
SQLite database file is useful because it uses just one file and that file is portable and independent from a platform.
SQLite object is provided as a core library, but in fact Database object which wraps a SQLite object and has more useful interfaces is recommended.
Generating by new SQLite(filename[, timeout]) and it connects to the database.
var db = new SQLite("sample.db", 30000);
Basically SQLite object has three methods of exec, prepare, transaction as a basic method.
By the way, Database object described later has more useful methods.
Use a exec method when it is not the case of using SELECT, otherwise use a prepare method to create a SQL object.
db.exec("CREATE TABLE IF NOT EXISTS mytable "
"("
"id INTEGER PRIMARY KEY AUTOINCREMENT, "
"name TEXT NOT NULL"
")"
);
The SQL object returned by a prepare method has a bind, exec, query, and next method.
All methods will return the object itself after operations.
And a next method is available after calling a query method.
The result of next method is a row object, and its shape is like an example below.
{
"columnName": [ "col1", "col2", "col3" ],
"value": [ val1, val2, val3 ]
}
For example, you can use it like below.
var c, r = db.prepare("SELECT * FROM mytable WHERE (id > ? AND id < ?) OR id = ?")
.bind(2)
.bind(8, 10) // bind() can be separated.
.query(); // do binding & ready to next().
while (c = r.next()) {
var cols = c.columnName;
var vals = c.value;
System.println("Record[%d]" % vals[0]);
for (var i = 0, len = cols.length(); i < len; ++i) {
System.println(" %-8s = %s" % cols[i] % vals[i]);
}
}
A query method is available only when it is SELECT.
Bound values are always reset after executing SQL command when using exec.
A transaction method provides a lock mechanism for whole command sequence.
For example, you can use it like below when inserting multiple values at one operation without interrupted.
It will be faster than doing it without transaction.
var ins = db.prepare("INSERT INTO mytable (name) VALUES (?)");
db.transaction(&{
for (var i = 0; i < 20; ++i) {
ins.bind("name(%{i})").exec();
}
});
The class Database is a wrapper class of SQLite described above.
It has methods as follows.
transaction … Does a transaction.createTable … Creates a table.dropTable … Removes a table.insert … Inserts data.delete … Removes data.query … Returns a cursor object to fetch data.queryAll … Fetch all data.You can instantiate a Database object by new operator.
var db = new Database(dbfile[, options]);
The options when instantiating it are as follows.
force … When it is true, the file will be created if the file does not exist. When it is false, an exception will be raised. It is false by default.timeout … Specify a timeout of database operations in milliseconds. It is 10 seconds by default.Here is an example below.
var db = new Database("dbfile.db", { force: true });
Moreover, you can pass multiple database names as an array, it means to use ATTACH DATABASE.
The matster database is the first item of an array and the rest items will be attached to the master.
And then, the stem of filename, which is abc for abc.db, is automatically used as an alias.
You can specify the name of main for the master database, and you can specify the stem of filename as alias for other databases.
You can use transaction with more useful, but normally it is used almost same as a method of SQLite object.
db.transaction(&{
...
});
When operations in the transaction is successfully done, it will commit automatically. Otherwise, for example when an exception occurs, it will try to rollback
And a transaction method of Database class has a mode as a first argument.
The mode should be specified by a string as follows.
'EXCLUSIVE' … Starts transaction with BEGIN EXCLUSIVE mode.'IMMEDIATE' … Starts transaction with BEGIN IMMEDIATE mode.It will be BEGIN DEFERRED when it is not specified or any other strings.
db.transaction('EXCLUSIVE', &{
...
});
createTable will receive a table name and a schema.
A schema should be just a string or an array.
If it is an array, it will be just joined by , and wrapped by ( and ).
db.createTable("mytable", [
"id INTEGER PRIMARY KEY AUTOINCREMENT",
"name TEXT NOT NULL"
]);
By the way, a table will be created always with IF NOT EXISTS.
dropTable will receive only a name of a table.
db.dropTable("mytable");
By the way, it will always do with IF EXISTS.
Note
You will see RuntimeException of database is locked when a statement is remaining.
You have to do dropTable in the condition that no references to a statement is remaining.
insert will receive parameters as follows.
| パラメータ | 内容 |
|---|---|
into |
Mandatory, a table name. |
replace |
true or false, false when omitted. |
column |
Mandatory, a column name string, or an array of column names. |
bind |
Mandatory, bound values for each column as an array, and it is needed the same number of items as the number of column. |
Normally, insert in transaction is faster than it without transaction.
db.transaction(&{
for (var i = 0; i < 20; ++i) {
db.insert({
into: "mytable",
column: ["name"],
bind: ["name(%{i})"],
});
}
});
delete will use from, where, and bind. All parameters are mandatory.
db.delete({
from: "mytable",
where: "id = ?",
bind: [4]
});
This method query will return a DatabaseCursor object to fetch data mathed by a condition.
The initial state of a DatabaseCursor object is the condition of nothing fetched.
The parameters for query() is as follows.
| パラメータ | 内容 |
|---|---|
distinct |
true or false, false when omitted. |
select |
* when omitted, or a column name string or an array of column names. |
from |
Mandatory, a table name. |
innerJoin |
INNER JOIN clause (innerJoin and outerJoin can not be specified at the same time) |
outerJoin |
OUTER JOIN clause. |
on |
Available only when specifying innerJoin or outerJoin |
where |
WHERE clause, a string, or an array. It will join by AND when it is an array. |
bind |
An array of bound values against WHERE clause. The number of items is the same number of ?. |
groupby |
GROUP BY clause. |
having |
HAVING clause. |
orderby |
ORDER BY clause. (orderby, orderbyAsc, and orderbyDesc can not be specified at the same time) |
orderbyAsc |
It is same as orderby. |
orderbyDesc |
ORDER BY clause with DESC. |
limit |
LIMIT clause. |
offset |
OFFSET clause. |
Here is an example below.
var c = db.query({
select: "*",
from: "mytable",
where: "(id > ? AND id < ?) OR id = ?",
bind: [2, 8, 10]
});
The c above is a DatabaseCursor object, and it has a next(), columns(), and values() method.
A columns() returns an array of column names and values() returns an array of values.
Using a DatabaseCursor object, all data can be acquired by fetching until returning null.
while (c.next()) {
var cols = c.columns();
var vals = c.values();
System.println("Record[%d]" % vals[0]);
for (var i = 0, len = cols.length(); i < len; ++i) {
System.println(" %-8s = %s" % cols[i] % vals[i]);
}
}
You can use a queryAll method with two different way of usage.
That is the way of using a callback, or not using a callback.
If not using a callback, you can get all data at once, but it will use a lot of memory.
Therefore you can use a callback to fetch data one by one.
When you want to get data at once, you do not write a callback like an example below.
var res = db.queryAll({
select: "*",
from: "mytable",
where: "(id > ? AND id < ?) OR id = ?",
bind: [2, 8, 10]
});
Data structure will be the following.
{
"columns": ["id", "name"],
"values": [
[3, "name(2)"],
[5, "name(4)"],
[6, "name(5)"],
[7, "name(6)"],
[10, "name(9)"]
]
}
You can write a callback as a second argument like an example below.
db.queryAll({
select: "*",
from: "mytable",
where: "(id > ? AND id < ?) OR id = ?",
bind: [2, 8, 10]
}, &(c, i) => {
System.println("%2d => " % i, c.toJsonString());
});
The result is below. Each row object will be returned.
In this case, note that it is NOT a DatabaseCursor object.
0 => {"columns":["id","name"],"values":[3,"name(2)"]}
1 => {"columns":["id","name"],"values":[5,"name(4)"]}
2 => {"columns":["id","name"],"values":[6,"name(5)"]}
3 => {"columns":["id","name"],"values":[7,"name(6)"]}
4 => {"columns":["id","name"],"values":[10,"name(9)"]}
If you want to stop iteration, return false like the following.
db.queryAll({
select: "*",
from: "mytable",
where: "(id > ? AND id < ?) OR id = ?",
bind: [2, 8, 10]
}, &(c, i) => {
System.println("%2d => " % i, c.toJsonString());
return false if (i == 2);
});
Here is the result.
0 => {"columns":["id","name"],"values":[3,"name(2)"]}
1 => {"columns":["id","name"],"values":[5,"name(4)"]}
2 => {"columns":["id","name"],"values":[6,"name(5)"]}
var db = new SQLite("database.db", 3000);
db.exec("DROP TABLE IF EXISTS mytable");
db.exec("CREATE TABLE IF NOT EXISTS mytable "
"("
"id INTEGER PRIMARY KEY AUTOINCREMENT, "
"name TEXT NOT NULL"
")"
);
System.println(File.exists("database.db"));
1
var db = new SQLite("database.db", 3000);
var ins = db.prepare("INSERT INTO mytable (name) VALUES (?)");
db.transaction(&{
for (var i = 0; i < 20; ++i) {
ins.bind("name(%{i})").exec();
}
});
var c, r = db.prepare("SELECT * FROM mytable WHERE (id > ? AND id < ?) OR id = ?")
.bind(2)
.bind(8, 10)
.query();
while (c = r.next()) {
var cols = c.columnName;
var vals = c.value;
System.println("Record[%d]" % vals[0]);
for (var i = 0, len = cols.length(); i < len; ++i) {
System.println(" %-8s = %s" % cols[i] % vals[i]);
}
}
Record[3]
id = 3
name = name(2)
Record[4]
id = 4
name = name(3)
Record[5]
id = 5
name = name(4)
Record[6]
id = 6
name = name(5)
Record[7]
id = 7
name = name(6)
Record[10]
id = 10
name = name(9)
var db = new Database("dbfile.db", { force: true, timeout: 3000 });
db.dropTable("mytable");
db.createTable("mytable", [
"id INTEGER PRIMARY KEY AUTOINCREMENT",
"name TEXT NOT NULL"
]);
var c = db.query({
select: "name",
from: "sqlite_master",
where: "type='table' AND name <> 'sqlite_sequence'",
});
while (c.next()) {
var cols = c.columns();
var vals = c.values();
System.println("Record[%d]" % vals[0]);
for (var i = 0, len = cols.length(); i < len; ++i) {
System.println(" %-8s = %s" % cols[i] % vals[i]);
}
}
Record[mytable]
name = mytable
var db = new Database("dbfile.db", { force: true, timeout: 3000 });
db.transaction(&{
for (var i = 0; i < 20; ++i) {
db.insert({
into: "mytable",
column: ["name"],
bind: ["name(%{i})"],
});
}
});
var c = db.query({
select: "*",
from: "mytable",
where: "(id > ? AND id < ?) OR id = ?",
bind: [2, 8, 10]
});
while (c.next()) {
var cols = c.columns();
var vals = c.values();
System.println("Record[%d]" % vals[0]);
for (var i = 0, len = cols.length(); i < len; ++i) {
System.println(" %-8s = %s" % cols[i] % vals[i]);
}
}
Record[3]
id = 3
name = name(2)
Record[4]
id = 4
name = name(3)
Record[5]
id = 5
name = name(4)
Record[6]
id = 6
name = name(5)
Record[7]
id = 7
name = name(6)
Record[10]
id = 10
name = name(9)
var db = new Database("dbfile.db", { force: true, timeout: 3000 });
db.delete({
from: "mytable",
where: "id = ?",
bind: [4]
});
var res = db.queryAll({
select: "*",
from: "mytable",
where: "(id > ? AND id < ?) OR id = ?",
bind: [2, 8, 10]
});
System.println(res.toJsonString(true));
{
"columns": ["id", "name"],
"values": [[3, "name(2)"], [5, "name(4)"], [6, "name(5)"], [7, "name(6)"], [10, "name(9)"]]
}
var db = new Database("dbfile.db", { force: true, timeout: 3000 });
db.queryAll({
select: "*",
from: "mytable",
where: "(id > ? AND id < ?) OR id = ?",
bind: [2, 8, 10]
}, &(c, i) => {
System.println("*%2d => " % i, c.toJsonString());
});
* 0 => {"columns":["id","name"],"values":[3,"name(2)"]}
* 1 => {"columns":["id","name"],"values":[5,"name(4)"]}
* 2 => {"columns":["id","name"],"values":[6,"name(5)"]}
* 3 => {"columns":["id","name"],"values":[7,"name(6)"]}
* 4 => {"columns":["id","name"],"values":[10,"name(9)"]}
var db = new Database("dbfile.db", { force: true, timeout: 3000 });
db.queryAll({
select: "*",
from: "mytable",
where: "(id > ? AND id < ?) OR id = ?",
bind: [2, 8, 10]
}, &(c, i) => {
System.println("*%2d => " % i, c.toJsonString());
return false if (i == 2);
});
* 0 => {"columns":["id","name"],"values":[3,"name(2)"]}
* 1 => {"columns":["id","name"],"values":[5,"name(4)"]}
* 2 => {"columns":["id","name"],"values":[6,"name(5)"]}