@homeofthings/sqlite3 0.0.1-alpha0 → 6.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,244 @@
1
+ #ifndef NODE_SQLITE3_SRC_STATEMENT_H
2
+ #define NODE_SQLITE3_SRC_STATEMENT_H
3
+
4
+ #include <cstdlib>
5
+ #include <cstring>
6
+ #include <string>
7
+ #include <queue>
8
+ #include <vector>
9
+ #include <sqlite3.h>
10
+ #include <napi.h>
11
+ #include <uv.h>
12
+
13
+ #include "database.h"
14
+ #include "threading.h"
15
+
16
+ using namespace Napi;
17
+
18
+ namespace node_sqlite3 {
19
+
20
+ namespace Values {
21
+ struct Field {
22
+ inline Field(unsigned short _index, unsigned short _type = SQLITE_NULL) :
23
+ type(_type), index(_index) {}
24
+ inline Field(const char* _name, unsigned short _type = SQLITE_NULL) :
25
+ type(_type), index(0), name(_name) {}
26
+
27
+ unsigned short type;
28
+ unsigned short index;
29
+ std::string name;
30
+
31
+ virtual ~Field() = default;
32
+ };
33
+
34
+ struct Integer : Field {
35
+ template <class T> inline Integer(T _name, int64_t val) :
36
+ Field(_name, SQLITE_INTEGER), value(val) {}
37
+ int64_t value;
38
+ virtual ~Integer() override = default;
39
+ };
40
+
41
+ struct Float : Field {
42
+ template <class T> inline Float(T _name, double val) :
43
+ Field(_name, SQLITE_FLOAT), value(val) {}
44
+ double value;
45
+ virtual ~Float() override = default;
46
+ };
47
+
48
+ struct Text : Field {
49
+ template <class T> inline Text(T _name, size_t len, const char* val) :
50
+ Field(_name, SQLITE_TEXT), value(val, len) {}
51
+ std::string value;
52
+ virtual ~Text() override = default;
53
+ };
54
+
55
+ struct Blob : Field {
56
+ template <class T> inline Blob(T _name, size_t len, const void* val) :
57
+ Field(_name, SQLITE_BLOB), length(len) {
58
+ value = new char[len];
59
+ assert(value != nullptr);
60
+ memcpy(value, val, len);
61
+ }
62
+ inline virtual ~Blob() override {
63
+ delete[] value;
64
+ }
65
+ int length;
66
+ char* value;
67
+ };
68
+
69
+ typedef Field Null;
70
+ }
71
+
72
+ typedef std::vector<std::unique_ptr<Values::Field> > Row;
73
+ typedef std::vector<std::unique_ptr<Row> > Rows;
74
+ typedef Row Parameters;
75
+
76
+
77
+
78
+ class Statement : public Napi::ObjectWrap<Statement> {
79
+ public:
80
+ static Napi::Object Init(Napi::Env env, Napi::Object exports);
81
+ static Napi::Value New(const Napi::CallbackInfo& info);
82
+
83
+ struct Baton {
84
+ napi_async_work request = NULL;
85
+ Statement* stmt;
86
+ Napi::FunctionReference callback;
87
+ Parameters parameters;
88
+
89
+ Baton(Statement* stmt_, Napi::Function cb_) : stmt(stmt_) {
90
+ stmt->Ref();
91
+ callback.Reset(cb_, 1);
92
+ }
93
+ virtual ~Baton() {
94
+ parameters.clear();
95
+ if (request) napi_delete_async_work(stmt->Env(), request);
96
+ stmt->Unref();
97
+ callback.Reset();
98
+ }
99
+ };
100
+
101
+ struct RowBaton : Baton {
102
+ RowBaton(Statement* stmt_, Napi::Function cb_) :
103
+ Baton(stmt_, cb_) {}
104
+ Row row;
105
+ virtual ~RowBaton() override = default;
106
+ };
107
+
108
+ struct RunBaton : Baton {
109
+ RunBaton(Statement* stmt_, Napi::Function cb_) :
110
+ Baton(stmt_, cb_), inserted_id(0), changes(0) {}
111
+ sqlite3_int64 inserted_id;
112
+ int changes;
113
+ virtual ~RunBaton() override = default;
114
+ };
115
+
116
+ struct RowsBaton : Baton {
117
+ RowsBaton(Statement* stmt_, Napi::Function cb_) :
118
+ Baton(stmt_, cb_) {}
119
+ Rows rows;
120
+ virtual ~RowsBaton() override = default;
121
+ };
122
+
123
+ struct Async;
124
+
125
+ struct EachBaton : Baton {
126
+ Napi::FunctionReference completed;
127
+ Async* async; // Isn't deleted when the baton is deleted.
128
+
129
+ EachBaton(Statement* stmt_, Napi::Function cb_) :
130
+ Baton(stmt_, cb_) {}
131
+ virtual ~EachBaton() override {
132
+ completed.Reset();
133
+ }
134
+ };
135
+
136
+ struct PrepareBaton : Database::Baton {
137
+ Statement* stmt;
138
+ std::string sql;
139
+ PrepareBaton(Database* db_, Napi::Function cb_, Statement* stmt_) :
140
+ Baton(db_, cb_), stmt(stmt_) {
141
+ stmt->Ref();
142
+ }
143
+ virtual ~PrepareBaton() override {
144
+ stmt->Unref();
145
+ if (!db->IsOpen() && db->IsLocked()) {
146
+ // The database handle was closed before the statement could be
147
+ // prepared.
148
+ stmt->Finalize_();
149
+ }
150
+ }
151
+ };
152
+
153
+ typedef void (*Work_Callback)(Baton* baton);
154
+
155
+ struct Call {
156
+ Call(Work_Callback cb_, Baton* baton_) : callback(cb_), baton(baton_) {};
157
+ Work_Callback callback;
158
+ Baton* baton;
159
+ };
160
+
161
+ struct Async {
162
+ uv_async_t watcher;
163
+ Statement* stmt;
164
+ Rows data;
165
+ NODE_SQLITE3_MUTEX_t;
166
+ bool completed;
167
+ int retrieved;
168
+
169
+ // Store the callbacks here because we don't have
170
+ // access to the baton in the async callback.
171
+ Napi::FunctionReference item_cb;
172
+ Napi::FunctionReference completed_cb;
173
+
174
+ Async(Statement* st, uv_async_cb async_cb) :
175
+ stmt(st), completed(false), retrieved(0) {
176
+ watcher.data = this;
177
+ NODE_SQLITE3_MUTEX_INIT
178
+ stmt->Ref();
179
+ uv_loop_t *loop;
180
+ napi_get_uv_event_loop(stmt->Env(), &loop);
181
+ uv_async_init(loop, &watcher, async_cb);
182
+ }
183
+
184
+ ~Async() {
185
+ stmt->Unref();
186
+ item_cb.Reset();
187
+ completed_cb.Reset();
188
+ NODE_SQLITE3_MUTEX_DESTROY
189
+ }
190
+ };
191
+
192
+ Statement(const Napi::CallbackInfo& info);
193
+
194
+ ~Statement() {
195
+ if (!finalized) Finalize_();
196
+ }
197
+
198
+ WORK_DEFINITION(Bind)
199
+ WORK_DEFINITION(Get)
200
+ WORK_DEFINITION(Run)
201
+ WORK_DEFINITION(All)
202
+ WORK_DEFINITION(Each)
203
+ WORK_DEFINITION(Reset)
204
+
205
+ Napi::Value Finalize_(const Napi::CallbackInfo& info);
206
+
207
+ protected:
208
+ static void Work_BeginPrepare(Database::Baton* baton);
209
+ static void Work_Prepare(napi_env env, void* data);
210
+ static void Work_AfterPrepare(napi_env env, napi_status status, void* data);
211
+
212
+ static void AsyncEach(uv_async_t* handle);
213
+ static void CloseCallback(uv_handle_t* handle);
214
+
215
+ static void Finalize_(Baton* baton);
216
+ void Finalize_();
217
+
218
+ template <class T> inline std::unique_ptr<Values::Field> BindParameter(const Napi::Value source, T pos);
219
+ template <class T> T* Bind(const Napi::CallbackInfo& info, int start = 0, int end = -1);
220
+ bool Bind(const Parameters &parameters);
221
+
222
+ static void GetRow(Row* row, sqlite3_stmt* stmt);
223
+ static Napi::Value RowToJS(Napi::Env env, Row* row);
224
+ void Schedule(Work_Callback callback, Baton* baton);
225
+ void Process();
226
+ void CleanQueue();
227
+ template <class T> static void Error(T* baton);
228
+
229
+ protected:
230
+ Database* db;
231
+
232
+ sqlite3_stmt* _handle = NULL;
233
+ int status = SQLITE_OK;
234
+ bool prepared = false;
235
+ bool locked = true;
236
+ bool finalized = false;
237
+
238
+ std::queue<Call*> queue;
239
+ std::string message;
240
+ };
241
+
242
+ }
243
+
244
+ #endif
@@ -0,0 +1,10 @@
1
+ #ifndef NODE_SQLITE3_SRC_THREADING_H
2
+ #define NODE_SQLITE3_SRC_THREADING_H
3
+
4
+ #define NODE_SQLITE3_MUTEX_t uv_mutex_t mutex;
5
+ #define NODE_SQLITE3_MUTEX_INIT uv_mutex_init(&mutex);
6
+ #define NODE_SQLITE3_MUTEX_LOCK(m) uv_mutex_lock(m);
7
+ #define NODE_SQLITE3_MUTEX_UNLOCK(m) uv_mutex_unlock(m);
8
+ #define NODE_SQLITE3_MUTEX_DESTROY uv_mutex_destroy(&mutex);
9
+
10
+ #endif // NODE_SQLITE3_SRC_THREADING_H
package/index.js DELETED
@@ -1 +0,0 @@
1
- module.exports = require('./lib/sqlite3');