Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@gristlabs/sqlite3",
"description": "Asynchronous, non-blocking SQLite3 bindings",
"version": "4.1.1-grist.4",
"version": "4.1.1-grist.5",
"homepage": "https://github.com/mapbox/node-sqlite3",
"author": {
"name": "MapBox",
Expand Down
25 changes: 25 additions & 0 deletions src/database.cc
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,22 @@ Napi::Value Database::Configure(const Napi::CallbackInfo& info) {
baton->status = info[1].As<Napi::Number>().Int32Value();
db->Schedule(SetBusyTimeout, baton);
}
else if (info[0].StrictEquals( Napi::String::New(env, "limit"))) {
REQUIRE_ARGUMENTS(3);
if (!info[1].IsNumber()) {
Napi::TypeError::New(env, "limit id must be an integer").ThrowAsJavaScriptException();
return env.Null();
}
if (!info[2].IsNumber()) {
Napi::TypeError::New(env, "limit value must be an integer").ThrowAsJavaScriptException();
return env.Null();
}
Napi::Function handle;
int id = info[1].As<Napi::Number>().Int32Value();
int value = info[2].As<Napi::Number>().Int32Value();
Baton* baton = new LimitBaton(db, handle, id, value);
db->Schedule(SetLimit, baton);
}
else {
Napi::TypeError::New(env, (StringConcat(
#if V8_MAJOR_VERSION > 6
Expand Down Expand Up @@ -409,6 +425,15 @@ void Database::SetBusyTimeout(Baton* baton) {
delete baton;
}

void Database::SetLimit(Baton* b) {
std::unique_ptr<LimitBaton> baton(static_cast<LimitBaton*>(b));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, modern C++ (i.e. from 21st century)! Looks good to me, but I don't see it used elsewhere, so wouldn't be surprised if it gets frowned upon upstream in case they are trying to support some old C++ compilers.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, this is actually me matching the latest style upstream, they've started putting this everywhere.


assert(baton->db->open);
assert(baton->db->_handle);

sqlite3_limit(baton->db->_handle, baton->id, baton->value);
}

void Database::RegisterTraceCallback(Baton* baton) {
assert(baton->db->open);
assert(baton->db->_handle);
Expand Down
8 changes: 8 additions & 0 deletions src/database.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,13 @@ class Database : public Napi::ObjectWrap<Database> {
Baton(db_, cb_), filename(filename_) {}
};

struct LimitBaton : Baton {
int id;
int value;
LimitBaton(Database* db_, Napi::Function cb_, int id_, int value_) :
Baton(db_, cb_), id(id_), value(value_) {}
};

typedef void (*Work_Callback)(Baton* baton);

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

static void SetBusyTimeout(Baton* baton);
static void SetLimit(Baton* baton);

static void RegisterTraceCallback(Baton* baton);
static void TraceCallback(void* db, const char* sql);
Expand Down
13 changes: 13 additions & 0 deletions src/node_sqlite3.cc
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,19 @@ Napi::Object RegisterModule(Napi::Env env, Napi::Object exports) {
DEFINE_CONSTANT_INTEGER(exports, SQLITE_FORMAT, FORMAT)
DEFINE_CONSTANT_INTEGER(exports, SQLITE_RANGE, RANGE)
DEFINE_CONSTANT_INTEGER(exports, SQLITE_NOTADB, NOTADB)

DEFINE_CONSTANT_INTEGER(exports, SQLITE_LIMIT_LENGTH, LIMIT_LENGTH)
DEFINE_CONSTANT_INTEGER(exports, SQLITE_LIMIT_SQL_LENGTH, LIMIT_SQL_LENGTH)
DEFINE_CONSTANT_INTEGER(exports, SQLITE_LIMIT_COLUMN, LIMIT_COLUMN)
DEFINE_CONSTANT_INTEGER(exports, SQLITE_LIMIT_EXPR_DEPTH, LIMIT_EXPR_DEPTH)
DEFINE_CONSTANT_INTEGER(exports, SQLITE_LIMIT_COMPOUND_SELECT, LIMIT_COMPOUND_SELECT)
DEFINE_CONSTANT_INTEGER(exports, SQLITE_LIMIT_VDBE_OP, LIMIT_VDBE_OP)
DEFINE_CONSTANT_INTEGER(exports, SQLITE_LIMIT_FUNCTION_ARG, LIMIT_FUNCTION_ARG)
DEFINE_CONSTANT_INTEGER(exports, SQLITE_LIMIT_ATTACHED, LIMIT_ATTACHED)
DEFINE_CONSTANT_INTEGER(exports, SQLITE_LIMIT_LIKE_PATTERN_LENGTH, LIMIT_LIKE_PATTERN_LENGTH)
DEFINE_CONSTANT_INTEGER(exports, SQLITE_LIMIT_VARIABLE_NUMBER, LIMIT_VARIABLE_NUMBER)
DEFINE_CONSTANT_INTEGER(exports, SQLITE_LIMIT_TRIGGER_DEPTH, LIMIT_TRIGGER_DEPTH)
DEFINE_CONSTANT_INTEGER(exports, SQLITE_LIMIT_WORKER_THREADS, LIMIT_WORKER_THREADS)
});

return exports;
Expand Down
28 changes: 28 additions & 0 deletions test/limit.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
var sqlite3 = require('..');

describe('limit', function() {
var db;

before(function(done) {
db = new sqlite3.Database(':memory:', done);
});

it('should support applying limits via configure', function(done) {
db.configure('limit', sqlite3.LIMIT_ATTACHED, 0);
db.exec("ATTACH 'test/support/prepare.db' AS zing", function(err) {
if (!err) {
throw new Error('ATTACH should not succeed');
}
if (err.errno === sqlite3.ERROR &&
err.message === 'SQLITE_ERROR: too many attached databases - max 0') {
db.configure('limit', sqlite3.LIMIT_ATTACHED, 1);
db.exec("ATTACH 'test/support/prepare.db' AS zing", function(err) {
if (err) throw err;
db.close(done);
});
} else {
throw err;
}
});
});
});