Skip to content

Commit dc6ec98

Browse files
authored
Merge pull request #10 from gristlabs/enable-sqlite3-limit
support sqlite3_limit(id, value) via db.configure('limit', id, value)
2 parents 6ba560a + 0cea98c commit dc6ec98

File tree

5 files changed

+75
-1
lines changed

5 files changed

+75
-1
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@gristlabs/sqlite3",
33
"description": "Asynchronous, non-blocking SQLite3 bindings",
4-
"version": "4.1.1-grist.4",
4+
"version": "4.1.1-grist.5",
55
"homepage": "https://github.com/mapbox/node-sqlite3",
66
"author": {
77
"name": "MapBox",

src/database.cc

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,22 @@ Napi::Value Database::Configure(const Napi::CallbackInfo& info) {
365365
baton->status = info[1].As<Napi::Number>().Int32Value();
366366
db->Schedule(SetBusyTimeout, baton);
367367
}
368+
else if (info[0].StrictEquals( Napi::String::New(env, "limit"))) {
369+
REQUIRE_ARGUMENTS(3);
370+
if (!info[1].IsNumber()) {
371+
Napi::TypeError::New(env, "limit id must be an integer").ThrowAsJavaScriptException();
372+
return env.Null();
373+
}
374+
if (!info[2].IsNumber()) {
375+
Napi::TypeError::New(env, "limit value must be an integer").ThrowAsJavaScriptException();
376+
return env.Null();
377+
}
378+
Napi::Function handle;
379+
int id = info[1].As<Napi::Number>().Int32Value();
380+
int value = info[2].As<Napi::Number>().Int32Value();
381+
Baton* baton = new LimitBaton(db, handle, id, value);
382+
db->Schedule(SetLimit, baton);
383+
}
368384
else {
369385
Napi::TypeError::New(env, (StringConcat(
370386
#if V8_MAJOR_VERSION > 6
@@ -409,6 +425,15 @@ void Database::SetBusyTimeout(Baton* baton) {
409425
delete baton;
410426
}
411427

428+
void Database::SetLimit(Baton* b) {
429+
std::unique_ptr<LimitBaton> baton(static_cast<LimitBaton*>(b));
430+
431+
assert(baton->db->open);
432+
assert(baton->db->_handle);
433+
434+
sqlite3_limit(baton->db->_handle, baton->id, baton->value);
435+
}
436+
412437
void Database::RegisterTraceCallback(Baton* baton) {
413438
assert(baton->db->open);
414439
assert(baton->db->_handle);

src/database.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,13 @@ class Database : public Napi::ObjectWrap<Database> {
7171
Baton(db_, cb_), filename(filename_) {}
7272
};
7373

74+
struct LimitBaton : Baton {
75+
int id;
76+
int value;
77+
LimitBaton(Database* db_, Napi::Function cb_, int id_, int value_) :
78+
Baton(db_, cb_), id(id_), value(value_) {}
79+
};
80+
7481
typedef void (*Work_Callback)(Baton* baton);
7582

7683
struct Call {
@@ -160,6 +167,7 @@ class Database : public Napi::ObjectWrap<Database> {
160167
Napi::Value Interrupt(const Napi::CallbackInfo& info);
161168

162169
static void SetBusyTimeout(Baton* baton);
170+
static void SetLimit(Baton* baton);
163171

164172
static void RegisterTraceCallback(Baton* baton);
165173
static void TraceCallback(void* db, const char* sql);

src/node_sqlite3.cc

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,19 @@ Napi::Object RegisterModule(Napi::Env env, Napi::Object exports) {
6161
DEFINE_CONSTANT_INTEGER(exports, SQLITE_FORMAT, FORMAT)
6262
DEFINE_CONSTANT_INTEGER(exports, SQLITE_RANGE, RANGE)
6363
DEFINE_CONSTANT_INTEGER(exports, SQLITE_NOTADB, NOTADB)
64+
65+
DEFINE_CONSTANT_INTEGER(exports, SQLITE_LIMIT_LENGTH, LIMIT_LENGTH)
66+
DEFINE_CONSTANT_INTEGER(exports, SQLITE_LIMIT_SQL_LENGTH, LIMIT_SQL_LENGTH)
67+
DEFINE_CONSTANT_INTEGER(exports, SQLITE_LIMIT_COLUMN, LIMIT_COLUMN)
68+
DEFINE_CONSTANT_INTEGER(exports, SQLITE_LIMIT_EXPR_DEPTH, LIMIT_EXPR_DEPTH)
69+
DEFINE_CONSTANT_INTEGER(exports, SQLITE_LIMIT_COMPOUND_SELECT, LIMIT_COMPOUND_SELECT)
70+
DEFINE_CONSTANT_INTEGER(exports, SQLITE_LIMIT_VDBE_OP, LIMIT_VDBE_OP)
71+
DEFINE_CONSTANT_INTEGER(exports, SQLITE_LIMIT_FUNCTION_ARG, LIMIT_FUNCTION_ARG)
72+
DEFINE_CONSTANT_INTEGER(exports, SQLITE_LIMIT_ATTACHED, LIMIT_ATTACHED)
73+
DEFINE_CONSTANT_INTEGER(exports, SQLITE_LIMIT_LIKE_PATTERN_LENGTH, LIMIT_LIKE_PATTERN_LENGTH)
74+
DEFINE_CONSTANT_INTEGER(exports, SQLITE_LIMIT_VARIABLE_NUMBER, LIMIT_VARIABLE_NUMBER)
75+
DEFINE_CONSTANT_INTEGER(exports, SQLITE_LIMIT_TRIGGER_DEPTH, LIMIT_TRIGGER_DEPTH)
76+
DEFINE_CONSTANT_INTEGER(exports, SQLITE_LIMIT_WORKER_THREADS, LIMIT_WORKER_THREADS)
6477
});
6578

6679
return exports;

test/limit.test.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
var sqlite3 = require('..');
2+
3+
describe('limit', function() {
4+
var db;
5+
6+
before(function(done) {
7+
db = new sqlite3.Database(':memory:', done);
8+
});
9+
10+
it('should support applying limits via configure', function(done) {
11+
db.configure('limit', sqlite3.LIMIT_ATTACHED, 0);
12+
db.exec("ATTACH 'test/support/prepare.db' AS zing", function(err) {
13+
if (!err) {
14+
throw new Error('ATTACH should not succeed');
15+
}
16+
if (err.errno === sqlite3.ERROR &&
17+
err.message === 'SQLITE_ERROR: too many attached databases - max 0') {
18+
db.configure('limit', sqlite3.LIMIT_ATTACHED, 1);
19+
db.exec("ATTACH 'test/support/prepare.db' AS zing", function(err) {
20+
if (err) throw err;
21+
db.close(done);
22+
});
23+
} else {
24+
throw err;
25+
}
26+
});
27+
});
28+
});

0 commit comments

Comments
 (0)