class Database : public Napi::ObjectWrap { public: explicit Database(const Napi::CallbackInfo& info); ~Database(); // Whenever this is used, addon->dbs.erase() must be invoked beforehand. void CloseHandles(); // Used to support ordered containers. class CompareDatabase { public: inline bool operator() (Database const * const a, Database const * const b) const { return a < b; } }; class CompareStatement { public: inline bool operator() (Statement const * const a, Statement const * const b) const { return Statement::Compare(a, b); } }; class CompareBackup { public: inline bool operator() (Backup const * const a, Backup const * const b) const { return Backup::Compare(a, b); } }; // Proper error handling logic for when an sqlite3 operation fails. void ThrowDatabaseError(Napi::Env env); static void ThrowSqliteError(Napi::Env env, Addon* addon, sqlite3* db_handle); static void ThrowSqliteError(Napi::Env env, Addon* addon, const char* message, int code); // Allows Statements to log their executed SQL. bool Log(Napi::Env env, sqlite3_stmt* handle); // Allow Statements to manage themselves when created and garbage collected. inline void AddStatement(Statement* stmt) { stmts.insert(stmts.end(), stmt); } inline void RemoveStatement(Statement* stmt) { stmts.erase(stmt); } // Allow Backups to manage themselves when created and garbage collected. inline void AddBackup(Backup* backup) { backups.insert(backups.end(), backup); } inline void RemoveBackup(Backup* backup) { backups.erase(backup); } // A view for Statements to see and modify Database state. // The order of these fields must exactly match their actual order. struct State { const bool open; bool busy; const bool safe_ints; const bool unsafe_mode; bool was_js_error; const bool has_logger; unsigned short iterators; Addon* const addon; }; inline State* GetState() { return reinterpret_cast(&open); } inline sqlite3* GetHandle() { return db_handle; } inline Addon* GetAddon() { return addon; } // Identifies objects that are backed by this class (see IsInstanceOf). static const napi_type_tag TYPE_TAG; static INIT(Init); private: NODE_METHOD(JS_new); static NODE_METHOD(JS_prepare); static NODE_METHOD(JS_exec); static NODE_METHOD(JS_backup); static NODE_METHOD(JS_serialize); static NODE_METHOD(JS_function); static NODE_METHOD(JS_aggregate); static NODE_METHOD(JS_table); static NODE_METHOD(JS_loadExtension); static NODE_METHOD(JS_close); static NODE_METHOD(JS_defaultSafeIntegers); static NODE_METHOD(JS_unsafeMode); static NODE_GETTER(JS_open); static NODE_GETTER(JS_inTransaction); static bool Deserialize(Napi::Env env, Napi::Object buffer, Addon* addon, sqlite3* db_handle, bool readonly); static void FreeSerialization(Napi::Env env, char* data); static const int MAX_BUFFER_SIZE; static const int MAX_STRING_SIZE; sqlite3* db_handle; bool open; bool busy; bool safe_ints; bool unsafe_mode; bool was_js_error; bool has_logger; unsigned short iterators; Addon* const addon; Napi::Reference logger; std::set stmts; std::set backups; };