Commit dd3ef522 by Jim Schlight Committed by Mohamed Akram

Fix compilation

parent fc09ced9
......@@ -12,7 +12,6 @@
#include <uv.h>
using namespace Napi;
using namespace Napi;
namespace node_sqlite3 {
......@@ -98,7 +97,6 @@ public:
static Napi::FunctionReference constructor;
static Napi::Object Init(Napi::Env env, Napi::Object exports);
static Napi::Value New(const Napi::CallbackInfo& info);
struct Baton {
uv_work_t request;
......@@ -150,21 +148,23 @@ public:
Baton* baton;
};
Backup(Database* db_) : Napi::ObjectWrap<Backup>(),
db(db_),
_handle(NULL),
_otherDb(NULL),
_destDb(NULL),
inited(false),
locked(true),
completed(false),
failed(false),
remaining(-1),
pageCount(-1),
finished(false) {
void init(Database* db_) {
db = db_;
_handle = NULL;
_otherDb = NULL;
_destDb = NULL;
inited = false;
locked = true;
completed = false;
failed = false;
remaining = -1;
pageCount = -1;
finished = false;
db->Ref();
}
Backup(const Napi::CallbackInfo& info);
~Backup() {
if (!finished) {
FinishAll();
......@@ -216,7 +216,7 @@ protected:
bool finished;
std::queue<Call*> queue;
Napi::Persistent<Array> retryErrors;
Napi::Reference<Array> retryErrors;
};
}
......
......@@ -29,7 +29,7 @@ public:
Napi::HandleScope scope(env);
if (!val.IsObject()) return false;
Napi::Object obj = val.As<Napi::Object>();
return Napi::New(env, constructor)->HasInstance(obj);
return obj.InstanceOf(constructor.Value());
}
struct Baton {
......@@ -43,7 +43,9 @@ public:
db(db_), status(SQLITE_OK) {
db->Ref();
request.data = this;
callback.Reset(cb_);
if (!cb_.IsUndefined() && cb_.IsFunction()) {
callback.Reset(cb_, 1);
}
}
virtual ~Baton() {
db->Unref();
......@@ -102,19 +104,20 @@ public:
friend class Statement;
friend class Backup;
protected:
Database() : Napi::ObjectWrap<Database>(),
_handle(NULL),
open(false),
closing(false),
locked(false),
pending(0),
serialize(false),
debug_trace(NULL),
debug_profile(NULL),
update_event(NULL) {
void init() {
_handle = NULL;
open = false;
closing = false;
locked = false;
pending = 0;
serialize = false;
debug_trace = NULL;
debug_profile = NULL;
update_event = NULL;
}
Database(const Napi::CallbackInfo& info);
~Database() {
RemoveCallbacks();
sqlite3_close(_handle);
......@@ -122,7 +125,7 @@ protected:
open = false;
}
static Napi::Value New(const Napi::CallbackInfo& info);
protected:
static void Work_BeginOpen(Baton* baton);
static void Work_Open(uv_work_t* req);
static void Work_AfterOpen(uv_work_t* req);
......@@ -132,30 +135,30 @@ protected:
void Schedule(Work_Callback callback, Baton* baton, bool exclusive = false);
void Process();
static Napi::Value Exec(const Napi::CallbackInfo& info);
Napi::Value Exec(const Napi::CallbackInfo& info);
static void Work_BeginExec(Baton* baton);
static void Work_Exec(uv_work_t* req);
static void Work_AfterExec(uv_work_t* req);
static Napi::Value Wait(const Napi::CallbackInfo& info);
Napi::Value Wait(const Napi::CallbackInfo& info);
static void Work_Wait(Baton* baton);
static Napi::Value Close(const Napi::CallbackInfo& info);
Napi::Value Close(const Napi::CallbackInfo& info);
static void Work_BeginClose(Baton* baton);
static void Work_Close(uv_work_t* req);
static void Work_AfterClose(uv_work_t* req);
static Napi::Value LoadExtension(const Napi::CallbackInfo& info);
Napi::Value LoadExtension(const Napi::CallbackInfo& info);
static void Work_BeginLoadExtension(Baton* baton);
static void Work_LoadExtension(uv_work_t* req);
static void Work_AfterLoadExtension(uv_work_t* req);
static Napi::Value Serialize(const Napi::CallbackInfo& info);
static Napi::Value Parallelize(const Napi::CallbackInfo& info);
Napi::Value Serialize(const Napi::CallbackInfo& info);
Napi::Value Parallelize(const Napi::CallbackInfo& info);
static Napi::Value Configure(const Napi::CallbackInfo& info);
Napi::Value Configure(const Napi::CallbackInfo& info);
static Napi::Value Interrupt(const Napi::CallbackInfo& info);
Napi::Value Interrupt(const Napi::CallbackInfo& info);
static void SetBusyTimeout(Baton* baton);
......
......@@ -3,35 +3,49 @@
const char* sqlite_code_string(int code);
const char* sqlite_authorizer_string(int type);
#include <vector>
// TODO: better way to work around StringConcat?
#include <napi.h>
inline Napi::String StringConcat(Napi::Value str1, Napi::Value str2) {
return Napi::String::New(str1.Env(), str1.As<Napi::String>().Utf8Value() +
str2.As<Napi::String>().Utf8Value() );
}
// A Napi substitute IsInt32()
inline bool OtherIsInt(Napi::Number source) {
double orig_val = source.DoubleValue();
double int_val = (double)source.Int32Value();
if (orig_val == int_val) {
return true;
} else {
return false;
}
}
#define REQUIRE_ARGUMENTS(n) \
if (info.Length() < (n)) { \
Napi::TypeError::New(env, "Expected " #n "arguments").ThrowAsJavaScriptException(); \
return env.Null(); \
}
#define REQUIRE_ARGUMENT_EXTERNAL(i, var) \
if (info.Length() <= (i) || !info[i].IsExternal()) { \
if (info.Length() <= (i) || !info[i].IsExternal()) { \
Napi::TypeError::New(env, "Argument " #i " invalid").ThrowAsJavaScriptException(); \
return env.Null(); \
} \
Napi::External var = info[i].As<Napi::External>();
#define REQUIRE_ARGUMENT_FUNCTION(i, var) \
if (info.Length() <= (i) || !info[i].IsFunction()) { \
if (info.Length() <= (i) || !info[i].IsFunction()) { \
Napi::TypeError::New(env, "Argument " #i " must be a function").ThrowAsJavaScriptException(); \
return env.Null(); \
} \
Napi::Function var = info[i].As<Napi::Function>();
#define REQUIRE_ARGUMENT_STRING(i, var) \
if (info.Length() <= (i) || !info[i].IsString()) { \
if (info.Length() <= (i) || !info[i].IsString()) { \
Napi::TypeError::New(env, "Argument " #i " must be a string").ThrowAsJavaScriptException(); \
return env.Null(); \
} \
std::string var = info[i].As<Napi::String>();
......@@ -43,13 +57,12 @@ const char* sqlite_authorizer_string(int type);
int var(info[i].As<Napi::Number>().Int32Value());
#define OPTIONAL_ARGUMENT_FUNCTION(i, var) \
Napi::Function var; \
if (info.Length() > i && !info[i].IsUndefined()) { \
if (!info[i].IsFunction()) { \
Napi::Function var; \
if (info.Length() > i && !info[i].IsUndefined()) { \
if (!info[i].IsFunction()) { \
Napi::TypeError::New(env, "Argument " #i " must be a function").ThrowAsJavaScriptException(); \
return env.Null(); \
} \
var = info[i].As<Napi::Function>(); \
var = info[i].As<Napi::Function>(); \
}
......@@ -59,67 +72,57 @@ const char* sqlite_authorizer_string(int type);
var = (default); \
} \
else if (info[i].IsNumber()) { \
var = info[i].As<Napi::Number>().Int32Value(); \
if (OtherIsInt(info[i].As<Number>())) { \
var = info[i].As<Napi::Number>().Int32Value(); \
} \
} \
else { \
Napi::TypeError::New(env, "Argument " #i " must be an integer").ThrowAsJavaScriptException(); \
return env.Null(); \
}
#define DEFINE_CONSTANT_INTEGER(target, constant, name) \
target->DefineProperty( \
Napi::New(env, #name), \
Napi::Number::New(env, constant), \
static_cast<napi_property_attributes>(napi_enumerable | napi_configurable) \
);
Napi::PropertyDescriptor::Value(#name, Napi::Number::New(env, constant), \
static_cast<napi_property_attributes>(napi_enumerable | napi_configurable)),
#define DEFINE_CONSTANT_STRING(target, constant, name) \
target->DefineProperty( \
Napi::New(env, #name), \
Napi::New(env, constant), \
static_cast<napi_property_attributes>(napi_enumerable | napi_configurable) \
);
#define NODE_SET_GETTER(target, name, function) \
Napi::SetAccessor((target)->InstanceTemplate(), \
Napi::New(env, name), (function));
#define NODE_SET_SETTER(target, name, getter, setter) \
Napi::SetAccessor((target)->InstanceTemplate(), \
Napi::New(env, name), getter, setter);
#define GET_STRING(source, name, property) \
std::string name = (source).Get(\
Napi::New(env, prop.As<Napi::String>()));
#define GET_INTEGER(source, name, prop) \
int name = Napi::To<int>((source).Get(\
Napi::New(env, property)));
Napi::PropertyDescriptor::Value(#name, Napi::String::New(env, constant), \
static_cast<napi_property_attributes>(napi_enumerable | napi_configurable)),
#define EXCEPTION(msg, errno, name) \
Napi::Value name = Exception::Error(Napi::New(env, \
std::string(sqlite_code_string(errno)) + \
std::string(": ") + std::string(msg) \
)); \
Napi::Object name ##_obj = name.As<Napi::Object>(); \
(name ##_obj).Set(Napi::String::New(env, "errno"), Napi::New(env, errno));\
(name ##_obj).Set(Napi::String::New(env, "code"), \
Napi::New(env, sqlite_code_string(errno)));
Napi::Value name = Napi::Error::New(env, \
StringConcat( \
StringConcat( \
Napi::String::New(env, sqlite_code_string(errno)), \
Napi::String::New(env, ": ") \
), \
(msg) \
).Utf8Value() \
).Value(); \
Napi::Object name ##_obj = name.As<Napi::Object>(); \
(name ##_obj).Set( Napi::String::New(env, "errno"), Napi::Number::New(env, errno)); \
(name ##_obj).Set( Napi::String::New(env, "code"), \
Napi::String::New(env, sqlite_code_string(errno)));
#define EMIT_EVENT(obj, argc, argv) \
TRY_CATCH_CALL((obj), \
(obj).Get(\
Napi::String::New(env, "emit")).As<Napi::Function>(),\
(obj).Get("emit").As<Napi::Function>(),\
argc, argv \
);
// The Mac OS compiler complains when argv is NULL unless we
// first assign it to a locally defined variable.
#define TRY_CATCH_CALL(context, callback, argc, argv) \
(callback).MakeCallback((context), (argc), (argv))
Napi::Value* passed_argv = argv;\
std::vector<napi_value> args;\
if ((argc != 0) && (passed_argv != NULL)) {\
args.assign(passed_argv, passed_argv + argc);\
}\
(callback).MakeCallback(Napi::Value(context), args);
#define WORK_DEFINITION(name) \
static Napi::Value name(const Napi::CallbackInfo& info); \
Napi::Value name(const Napi::CallbackInfo& info); \
static void Work_Begin##name(Baton* baton); \
static void Work_##name(uv_work_t* req); \
static void Work_After##name(uv_work_t* req);
......
......@@ -16,50 +16,54 @@ namespace {
Napi::Object RegisterModule(Napi::Env env, Napi::Object exports) {
Napi::HandleScope scope(env);
Database::Init(env, target, module);
Statement::Init(env, target, module);
Backup::Init(env, target, module);
Database::Init(env, exports);
Statement::Init(env, exports);
Backup::Init(env, exports);
DEFINE_CONSTANT_INTEGER(target, SQLITE_OPEN_READONLY, OPEN_READONLY);
DEFINE_CONSTANT_INTEGER(target, SQLITE_OPEN_READWRITE, OPEN_READWRITE);
DEFINE_CONSTANT_INTEGER(target, SQLITE_OPEN_CREATE, OPEN_CREATE);
DEFINE_CONSTANT_INTEGER(target, SQLITE_OPEN_FULLMUTEX, OPEN_FULLMUTEX);
DEFINE_CONSTANT_INTEGER(target, SQLITE_OPEN_URI, OPEN_URI);
DEFINE_CONSTANT_INTEGER(target, SQLITE_OPEN_SHAREDCACHE, OPEN_SHAREDCACHE);
DEFINE_CONSTANT_INTEGER(target, SQLITE_OPEN_PRIVATECACHE, OPEN_PRIVATECACHE);
DEFINE_CONSTANT_STRING(target, SQLITE_VERSION, VERSION);
exports.DefineProperties({
DEFINE_CONSTANT_INTEGER(exports, SQLITE_OPEN_READONLY, OPEN_READONLY)
DEFINE_CONSTANT_INTEGER(exports, SQLITE_OPEN_READWRITE, OPEN_READWRITE)
DEFINE_CONSTANT_INTEGER(exports, SQLITE_OPEN_CREATE, OPEN_CREATE)
DEFINE_CONSTANT_INTEGER(exports, SQLITE_OPEN_FULLMUTEX, OPEN_FULLMUTEX)
DEFINE_CONSTANT_INTEGER(exports, SQLITE_OPEN_URI, OPEN_URI)
DEFINE_CONSTANT_INTEGER(exports, SQLITE_OPEN_SHAREDCACHE, OPEN_SHAREDCACHE)
DEFINE_CONSTANT_INTEGER(exports, SQLITE_OPEN_PRIVATECACHE, OPEN_PRIVATECACHE)
DEFINE_CONSTANT_STRING(exports, SQLITE_VERSION, VERSION)
#ifdef SQLITE_SOURCE_ID
DEFINE_CONSTANT_STRING(target, SQLITE_SOURCE_ID, SOURCE_ID);
DEFINE_CONSTANT_STRING(exports, SQLITE_SOURCE_ID, SOURCE_ID)
#endif
DEFINE_CONSTANT_INTEGER(target, SQLITE_VERSION_NUMBER, VERSION_NUMBER);
DEFINE_CONSTANT_INTEGER(exports, SQLITE_VERSION_NUMBER, VERSION_NUMBER)
DEFINE_CONSTANT_INTEGER(target, SQLITE_OK, OK);
DEFINE_CONSTANT_INTEGER(target, SQLITE_ERROR, ERROR);
DEFINE_CONSTANT_INTEGER(target, SQLITE_INTERNAL, INTERNAL);
DEFINE_CONSTANT_INTEGER(target, SQLITE_PERM, PERM);
DEFINE_CONSTANT_INTEGER(target, SQLITE_ABORT, ABORT);
DEFINE_CONSTANT_INTEGER(target, SQLITE_BUSY, BUSY);
DEFINE_CONSTANT_INTEGER(target, SQLITE_LOCKED, LOCKED);
DEFINE_CONSTANT_INTEGER(target, SQLITE_NOMEM, NOMEM);
DEFINE_CONSTANT_INTEGER(target, SQLITE_READONLY, READONLY);
DEFINE_CONSTANT_INTEGER(target, SQLITE_INTERRUPT, INTERRUPT);
DEFINE_CONSTANT_INTEGER(target, SQLITE_IOERR, IOERR);
DEFINE_CONSTANT_INTEGER(target, SQLITE_CORRUPT, CORRUPT);
DEFINE_CONSTANT_INTEGER(target, SQLITE_NOTFOUND, NOTFOUND);
DEFINE_CONSTANT_INTEGER(target, SQLITE_FULL, FULL);
DEFINE_CONSTANT_INTEGER(target, SQLITE_CANTOPEN, CANTOPEN);
DEFINE_CONSTANT_INTEGER(target, SQLITE_PROTOCOL, PROTOCOL);
DEFINE_CONSTANT_INTEGER(target, SQLITE_EMPTY, EMPTY);
DEFINE_CONSTANT_INTEGER(target, SQLITE_SCHEMA, SCHEMA);
DEFINE_CONSTANT_INTEGER(target, SQLITE_TOOBIG, TOOBIG);
DEFINE_CONSTANT_INTEGER(target, SQLITE_CONSTRAINT, CONSTRAINT);
DEFINE_CONSTANT_INTEGER(target, SQLITE_MISMATCH, MISMATCH);
DEFINE_CONSTANT_INTEGER(target, SQLITE_MISUSE, MISUSE);
DEFINE_CONSTANT_INTEGER(target, SQLITE_NOLFS, NOLFS);
DEFINE_CONSTANT_INTEGER(target, SQLITE_AUTH, AUTH);
DEFINE_CONSTANT_INTEGER(target, SQLITE_FORMAT, FORMAT);
DEFINE_CONSTANT_INTEGER(target, SQLITE_RANGE, RANGE);
DEFINE_CONSTANT_INTEGER(target, SQLITE_NOTADB, NOTADB);
DEFINE_CONSTANT_INTEGER(exports, SQLITE_OK, OK)
DEFINE_CONSTANT_INTEGER(exports, SQLITE_ERROR, ERROR)
DEFINE_CONSTANT_INTEGER(exports, SQLITE_INTERNAL, INTERNAL)
DEFINE_CONSTANT_INTEGER(exports, SQLITE_PERM, PERM)
DEFINE_CONSTANT_INTEGER(exports, SQLITE_ABORT, ABORT)
DEFINE_CONSTANT_INTEGER(exports, SQLITE_BUSY, BUSY)
DEFINE_CONSTANT_INTEGER(exports, SQLITE_LOCKED, LOCKED)
DEFINE_CONSTANT_INTEGER(exports, SQLITE_NOMEM, NOMEM)
DEFINE_CONSTANT_INTEGER(exports, SQLITE_READONLY, READONLY)
DEFINE_CONSTANT_INTEGER(exports, SQLITE_INTERRUPT, INTERRUPT)
DEFINE_CONSTANT_INTEGER(exports, SQLITE_IOERR, IOERR)
DEFINE_CONSTANT_INTEGER(exports, SQLITE_CORRUPT, CORRUPT)
DEFINE_CONSTANT_INTEGER(exports, SQLITE_NOTFOUND, NOTFOUND)
DEFINE_CONSTANT_INTEGER(exports, SQLITE_FULL, FULL)
DEFINE_CONSTANT_INTEGER(exports, SQLITE_CANTOPEN, CANTOPEN)
DEFINE_CONSTANT_INTEGER(exports, SQLITE_PROTOCOL, PROTOCOL)
DEFINE_CONSTANT_INTEGER(exports, SQLITE_EMPTY, EMPTY)
DEFINE_CONSTANT_INTEGER(exports, SQLITE_SCHEMA, SCHEMA)
DEFINE_CONSTANT_INTEGER(exports, SQLITE_TOOBIG, TOOBIG)
DEFINE_CONSTANT_INTEGER(exports, SQLITE_CONSTRAINT, CONSTRAINT)
DEFINE_CONSTANT_INTEGER(exports, SQLITE_MISMATCH, MISMATCH)
DEFINE_CONSTANT_INTEGER(exports, SQLITE_MISUSE, MISUSE)
DEFINE_CONSTANT_INTEGER(exports, SQLITE_NOLFS, NOLFS)
DEFINE_CONSTANT_INTEGER(exports, SQLITE_AUTH, AUTH)
DEFINE_CONSTANT_INTEGER(exports, SQLITE_FORMAT, FORMAT)
DEFINE_CONSTANT_INTEGER(exports, SQLITE_RANGE, RANGE)
DEFINE_CONSTANT_INTEGER(exports, SQLITE_NOTADB, NOTADB)
});
return exports;
}
}
......
......@@ -16,7 +16,6 @@
#include <uv.h>
using namespace Napi;
using namespace Napi;
namespace node_sqlite3 {
......@@ -144,7 +143,7 @@ public:
if (!db->IsOpen() && db->IsLocked()) {
// The database handle was closed before the statement could be
// prepared.
stmt->Finalize();
stmt->Finalize_();
}
}
};
......@@ -186,18 +185,20 @@ public:
}
};
Statement(Database* db_) : Napi::ObjectWrap<Statement>(),
db(db_),
_handle(NULL),
status(SQLITE_OK),
prepared(false),
locked(true),
finalized(false) {
void init(Database* db_) {
db = db_;
_handle = NULL;
status = SQLITE_OK;
prepared = false;
locked = true;
finalized = false;
db->Ref();
}
Statement(const Napi::CallbackInfo& info);
~Statement() {
if (!finalized) Finalize();
if (!finalized) Finalize_();
}
WORK_DEFINITION(Bind);
......@@ -207,7 +208,7 @@ public:
WORK_DEFINITION(Each);
WORK_DEFINITION(Reset);
static Napi::Value Finalize(const Napi::CallbackInfo& info);
Napi::Value Finalize_(const Napi::CallbackInfo& info);
protected:
static void Work_BeginPrepare(Database::Baton* baton);
......@@ -217,15 +218,15 @@ protected:
static void AsyncEach(uv_async_t* handle, int status);
static void CloseCallback(uv_handle_t* handle);
static void Finalize(Baton* baton);
void Finalize();
static void Finalize_(Baton* baton);
void Finalize_();
template <class T> inline Values::Field* BindParameter(const Napi::Value source, T pos);
template <class T> T* Bind(const Napi::CallbackInfo& info, int start = 0, int end = -1);
bool Bind(const Parameters &parameters);
static void GetRow(Row* row, sqlite3_stmt* stmt);
static Napi::Object RowToJS(Row* row);
static Napi::Value RowToJS(Napi::Env env, Row* row);
void Schedule(Work_Callback callback, Baton* baton);
void Process();
void CleanQueue();
......
......@@ -10,11 +10,11 @@ describe('error handling', function() {
it('throw when calling Database() without new', function() {
assert.throws(function() {
sqlite3.Database(':memory:');
}, (/Use the new operator to create new Database objects/));
}, (/Class constructors cannot be invoked without 'new'/));
assert.throws(function() {
sqlite3.Statement();
}, (/Use the new operator to create new Statement objects/));
}, (/Class constructors cannot be invoked without 'new'/));
});
it('should error when calling Database#get on a missing table', function(done) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment