@graphscope-neug/darwin-arm64 0.1.2
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.
- package/CMakeLists.txt +111 -0
- package/README.md +116 -0
- package/build/Release/darwin-arm64/libneug.dylib +0 -0
- package/build/Release/darwin-arm64/neug_node_bind.node +0 -0
- package/lib/async-connection.js +90 -0
- package/lib/binding.js +30 -0
- package/lib/connection.js +127 -0
- package/lib/database.js +310 -0
- package/lib/error-codes.js +208 -0
- package/lib/format.js +131 -0
- package/lib/index.js +66 -0
- package/lib/query-result.js +134 -0
- package/lib/session.js +275 -0
- package/lib/utils.js +46 -0
- package/lib/version.js +53 -0
- package/package.json +41 -0
- package/src/neug_binding.cc +65 -0
- package/src/node_connection.cc +114 -0
- package/src/node_connection.h +55 -0
- package/src/node_database.cc +254 -0
- package/src/node_database.h +60 -0
- package/src/node_query_request.cc +162 -0
- package/src/node_query_request.h +47 -0
- package/src/node_query_result.cc +361 -0
- package/src/node_query_result.h +72 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/** Copyright 2020 Alibaba Group Holding Limited.
|
|
2
|
+
*
|
|
3
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License.
|
|
5
|
+
* You may obtain a copy of the License at
|
|
6
|
+
*
|
|
7
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
*
|
|
9
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
* See the License for the specific language governing permissions and
|
|
13
|
+
* limitations under the License.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
#include "node_connection.h"
|
|
17
|
+
|
|
18
|
+
#include <memory>
|
|
19
|
+
#include <string>
|
|
20
|
+
|
|
21
|
+
#include "neug/execution/common/params_map.h"
|
|
22
|
+
#include "neug/main/neug_db.h"
|
|
23
|
+
#include "neug/utils/exception/exception.h"
|
|
24
|
+
#include "neug/utils/pb_utils.h"
|
|
25
|
+
#include "neug/utils/yaml_utils.h"
|
|
26
|
+
#include "node_query_request.h"
|
|
27
|
+
|
|
28
|
+
#include <rapidjson/document.h>
|
|
29
|
+
|
|
30
|
+
namespace neug {
|
|
31
|
+
|
|
32
|
+
Napi::FunctionReference NodeConnection::constructor;
|
|
33
|
+
|
|
34
|
+
Napi::Object NodeConnection::Init(Napi::Env env, Napi::Object exports) {
|
|
35
|
+
Napi::Function func = DefineClass(
|
|
36
|
+
env, "NodeConnection",
|
|
37
|
+
{
|
|
38
|
+
InstanceMethod("execute", &NodeConnection::Execute),
|
|
39
|
+
InstanceMethod("getSchema", &NodeConnection::GetSchema),
|
|
40
|
+
InstanceMethod("close", &NodeConnection::Close),
|
|
41
|
+
});
|
|
42
|
+
constructor = Napi::Persistent(func);
|
|
43
|
+
constructor.SuppressDestruct();
|
|
44
|
+
exports.Set("NodeConnection", func);
|
|
45
|
+
return exports;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
NodeConnection::NodeConnection(const Napi::CallbackInfo& info)
|
|
49
|
+
: Napi::ObjectWrap<NodeConnection>(info), db_(nullptr), conn_(nullptr) {}
|
|
50
|
+
|
|
51
|
+
void NodeConnection::SetConnection(NeugDB* db,
|
|
52
|
+
std::shared_ptr<Connection> conn) {
|
|
53
|
+
db_ = db;
|
|
54
|
+
conn_ = std::move(conn);
|
|
55
|
+
if (!conn_) {
|
|
56
|
+
THROW_RUNTIME_ERROR("Connection is null");
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
Napi::Object NodeConnection::NewInstance(Napi::Env env, NeugDB& db,
|
|
61
|
+
std::shared_ptr<Connection> conn) {
|
|
62
|
+
Napi::Object obj = constructor.New({});
|
|
63
|
+
NodeConnection* wrapped = Napi::ObjectWrap<NodeConnection>::Unwrap(obj);
|
|
64
|
+
wrapped->SetConnection(&db, std::move(conn));
|
|
65
|
+
return obj;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
Napi::Value NodeConnection::Execute(const Napi::CallbackInfo& info) {
|
|
69
|
+
Napi::Env env = info.Env();
|
|
70
|
+
|
|
71
|
+
if (info.Length() < 1 || !info[0].IsString()) {
|
|
72
|
+
Napi::TypeError::New(env, "Query string required")
|
|
73
|
+
.ThrowAsJavaScriptException();
|
|
74
|
+
return env.Null();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
std::string query_string = info[0].As<Napi::String>().Utf8Value();
|
|
78
|
+
std::string access_mode = "";
|
|
79
|
+
if (info.Length() >= 2 && info[1].IsString()) {
|
|
80
|
+
access_mode = info[1].As<Napi::String>().Utf8Value();
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Parse parameters from JavaScript object
|
|
84
|
+
rapidjson::Document params_json;
|
|
85
|
+
if (info.Length() >= 3 && info[2].IsObject()) {
|
|
86
|
+
Napi::Object params_obj = info[2].As<Napi::Object>();
|
|
87
|
+
Napi::Array keys = params_obj.GetPropertyNames();
|
|
88
|
+
for (uint32_t i = 0; i < keys.Length(); ++i) {
|
|
89
|
+
std::string key = keys.Get(i).As<Napi::String>().Utf8Value();
|
|
90
|
+
Napi::Value value = params_obj.Get(key);
|
|
91
|
+
NodeParameterSerializer::SerializeParameter(params_json, key, value);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
auto query_result = conn_->Query(query_string, access_mode, params_json);
|
|
96
|
+
if (!query_result) {
|
|
97
|
+
return NodeQueryResult::NewInstanceFromStatus(env, query_result.error());
|
|
98
|
+
}
|
|
99
|
+
return NodeQueryResult::NewInstance(env, std::move(query_result.value()));
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
Napi::Value NodeConnection::GetSchema(const Napi::CallbackInfo& info) {
|
|
103
|
+
return Napi::String::New(info.Env(), conn_->GetSchema());
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
Napi::Value NodeConnection::Close(const Napi::CallbackInfo& info) {
|
|
107
|
+
if (conn_) {
|
|
108
|
+
db_->RemoveConnection(conn_);
|
|
109
|
+
conn_.reset();
|
|
110
|
+
}
|
|
111
|
+
return info.Env().Undefined();
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
} // namespace neug
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/** Copyright 2020 Alibaba Group Holding Limited.
|
|
2
|
+
*
|
|
3
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License.
|
|
5
|
+
* You may obtain a copy of the License at
|
|
6
|
+
*
|
|
7
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
*
|
|
9
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
* See the License for the specific language governing permissions and
|
|
13
|
+
* limitations under the License.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
#ifndef TOOLS_NODEJS_BIND_SRC_NODE_CONNECTION_H_
|
|
17
|
+
#define TOOLS_NODEJS_BIND_SRC_NODE_CONNECTION_H_
|
|
18
|
+
|
|
19
|
+
#include <napi.h>
|
|
20
|
+
|
|
21
|
+
#include <memory>
|
|
22
|
+
#include <string>
|
|
23
|
+
|
|
24
|
+
#include "neug/execution/common/types/value.h"
|
|
25
|
+
#include "neug/main/connection.h"
|
|
26
|
+
#include "neug/main/neug_db.h"
|
|
27
|
+
#include "node_query_result.h"
|
|
28
|
+
|
|
29
|
+
namespace neug {
|
|
30
|
+
|
|
31
|
+
class NodeConnection : public Napi::ObjectWrap<NodeConnection> {
|
|
32
|
+
public:
|
|
33
|
+
static Napi::Object Init(Napi::Env env, Napi::Object exports);
|
|
34
|
+
static Napi::Object NewInstance(Napi::Env env, NeugDB& db,
|
|
35
|
+
std::shared_ptr<Connection> conn);
|
|
36
|
+
|
|
37
|
+
NodeConnection(const Napi::CallbackInfo& info);
|
|
38
|
+
~NodeConnection() = default;
|
|
39
|
+
|
|
40
|
+
void SetConnection(NeugDB* db, std::shared_ptr<Connection> conn);
|
|
41
|
+
|
|
42
|
+
private:
|
|
43
|
+
static Napi::FunctionReference constructor;
|
|
44
|
+
|
|
45
|
+
Napi::Value Execute(const Napi::CallbackInfo& info);
|
|
46
|
+
Napi::Value GetSchema(const Napi::CallbackInfo& info);
|
|
47
|
+
Napi::Value Close(const Napi::CallbackInfo& info);
|
|
48
|
+
|
|
49
|
+
NeugDB* db_{nullptr};
|
|
50
|
+
std::shared_ptr<Connection> conn_;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
} // namespace neug
|
|
54
|
+
|
|
55
|
+
#endif // TOOLS_NODEJS_BIND_SRC_NODE_CONNECTION_H_
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
/** Copyright 2020 Alibaba Group Holding Limited.
|
|
2
|
+
*
|
|
3
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License.
|
|
5
|
+
* You may obtain a copy of the License at
|
|
6
|
+
*
|
|
7
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
*
|
|
9
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
* See the License for the specific language governing permissions and
|
|
13
|
+
* limitations under the License.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
#include "node_database.h"
|
|
17
|
+
|
|
18
|
+
#include <string>
|
|
19
|
+
|
|
20
|
+
#include "neug/config.h"
|
|
21
|
+
#include "neug/utils/exception/exception.h"
|
|
22
|
+
|
|
23
|
+
namespace neug {
|
|
24
|
+
|
|
25
|
+
Napi::FunctionReference NodeDatabase::constructor;
|
|
26
|
+
|
|
27
|
+
Napi::Object NodeDatabase::Init(Napi::Env env, Napi::Object exports) {
|
|
28
|
+
Napi::Function func = DefineClass(
|
|
29
|
+
env, "NodeDatabase",
|
|
30
|
+
{
|
|
31
|
+
InstanceMethod("connect", &NodeDatabase::Connect),
|
|
32
|
+
InstanceMethod("close", &NodeDatabase::Close),
|
|
33
|
+
InstanceMethod("serve", &NodeDatabase::Serve),
|
|
34
|
+
InstanceMethod("stopServing", &NodeDatabase::StopServing),
|
|
35
|
+
});
|
|
36
|
+
constructor = Napi::Persistent(func);
|
|
37
|
+
constructor.SuppressDestruct();
|
|
38
|
+
exports.Set("NodeDatabase", func);
|
|
39
|
+
return exports;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
NodeDatabase::NodeDatabase(const Napi::CallbackInfo& info)
|
|
43
|
+
: Napi::ObjectWrap<NodeDatabase>(info) {
|
|
44
|
+
Napi::Env env = info.Env();
|
|
45
|
+
|
|
46
|
+
if (info.Length() < 1 || !info[0].IsObject()) {
|
|
47
|
+
Napi::TypeError::New(env, "Options object required")
|
|
48
|
+
.ThrowAsJavaScriptException();
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
Napi::Object opts = info[0].As<Napi::Object>();
|
|
53
|
+
|
|
54
|
+
// Parse options
|
|
55
|
+
std::string database_path = "";
|
|
56
|
+
if (opts.Has("databasePath") && opts.Get("databasePath").IsString()) {
|
|
57
|
+
database_path = opts.Get("databasePath").As<Napi::String>().Utf8Value();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
int32_t max_thread_num = 0;
|
|
61
|
+
if (opts.Has("maxThreadNum") && opts.Get("maxThreadNum").IsNumber()) {
|
|
62
|
+
max_thread_num = opts.Get("maxThreadNum").As<Napi::Number>().Int32Value();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
std::string mode = "r";
|
|
66
|
+
if (opts.Has("mode") && opts.Get("mode").IsString()) {
|
|
67
|
+
mode = opts.Get("mode").As<Napi::String>().Utf8Value();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
std::string planner = "gopt";
|
|
71
|
+
if (opts.Has("planner") && opts.Get("planner").IsString()) {
|
|
72
|
+
planner = opts.Get("planner").As<Napi::String>().Utf8Value();
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
bool checkpoint_on_close = true;
|
|
76
|
+
if (opts.Has("checkpointOnClose") && opts.Get("checkpointOnClose").IsBoolean()) {
|
|
77
|
+
checkpoint_on_close = opts.Get("checkpointOnClose").As<Napi::Boolean>().Value();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
std::string buffer_strategy = "M_FULL";
|
|
81
|
+
if (opts.Has("bufferStrategy") && opts.Get("bufferStrategy").IsString()) {
|
|
82
|
+
buffer_strategy = opts.Get("bufferStrategy").As<Napi::String>().Utf8Value();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Parse mode
|
|
86
|
+
neug::DBMode mode_;
|
|
87
|
+
if (mode == "read" || mode == "r" || mode == "read-only" ||
|
|
88
|
+
mode == "read_only") {
|
|
89
|
+
mode_ = DBMode::READ_ONLY;
|
|
90
|
+
} else if (mode == "read_write" || mode == "rw" || mode == "w" ||
|
|
91
|
+
mode == "wr" || mode == "write" || mode == "readwrite" ||
|
|
92
|
+
mode == "read-write") {
|
|
93
|
+
mode_ = DBMode::READ_WRITE;
|
|
94
|
+
} else {
|
|
95
|
+
Napi::Error::New(env, "Invalid mode: " + mode)
|
|
96
|
+
.ThrowAsJavaScriptException();
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
db_dir_ = database_path;
|
|
101
|
+
database = std::make_unique<NeugDB>();
|
|
102
|
+
NeugDBConfig config(db_dir_, max_thread_num);
|
|
103
|
+
config.mode = mode_;
|
|
104
|
+
config.planner_kind = planner;
|
|
105
|
+
config.checkpoint_on_close = checkpoint_on_close;
|
|
106
|
+
try {
|
|
107
|
+
config.memory_level = ParseBufferStrategy(buffer_strategy);
|
|
108
|
+
database->Open(config);
|
|
109
|
+
} catch (const neug::exception::Exception& e) {
|
|
110
|
+
Napi::Error::New(env, e.what()).ThrowAsJavaScriptException();
|
|
111
|
+
database.reset();
|
|
112
|
+
return;
|
|
113
|
+
} catch (const std::exception& e) {
|
|
114
|
+
Napi::Error::New(env, e.what()).ThrowAsJavaScriptException();
|
|
115
|
+
database.reset();
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
NodeDatabase::~NodeDatabase() {
|
|
121
|
+
std::lock_guard<std::recursive_mutex> lock(mtx_);
|
|
122
|
+
#ifdef BUILD_HTTP_SERVER
|
|
123
|
+
if (service_) {
|
|
124
|
+
service_->Stop();
|
|
125
|
+
service_.reset();
|
|
126
|
+
}
|
|
127
|
+
#endif
|
|
128
|
+
if (database) {
|
|
129
|
+
database->Close();
|
|
130
|
+
database.reset();
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
Napi::Value NodeDatabase::Connect(const Napi::CallbackInfo& info) {
|
|
135
|
+
Napi::Env env = info.Env();
|
|
136
|
+
if (!database) {
|
|
137
|
+
Napi::Error::New(env, "Database is not initialized.")
|
|
138
|
+
.ThrowAsJavaScriptException();
|
|
139
|
+
return env.Null();
|
|
140
|
+
}
|
|
141
|
+
try {
|
|
142
|
+
auto conn = database->Connect();
|
|
143
|
+
return NodeConnection::NewInstance(env, *database, conn);
|
|
144
|
+
} catch (const neug::exception::Exception& e) {
|
|
145
|
+
Napi::Error::New(env, e.what()).ThrowAsJavaScriptException();
|
|
146
|
+
return env.Null();
|
|
147
|
+
} catch (const std::exception& e) {
|
|
148
|
+
Napi::Error::New(env, e.what()).ThrowAsJavaScriptException();
|
|
149
|
+
return env.Null();
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
Napi::Value NodeDatabase::Close(const Napi::CallbackInfo& info) {
|
|
154
|
+
std::lock_guard<std::recursive_mutex> lock(mtx_);
|
|
155
|
+
#ifdef BUILD_HTTP_SERVER
|
|
156
|
+
if (service_) {
|
|
157
|
+
service_->Stop();
|
|
158
|
+
service_.reset();
|
|
159
|
+
}
|
|
160
|
+
#endif
|
|
161
|
+
if (database) {
|
|
162
|
+
database->Close();
|
|
163
|
+
database.reset();
|
|
164
|
+
}
|
|
165
|
+
return info.Env().Undefined();
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
Napi::Value NodeDatabase::Serve(const Napi::CallbackInfo& info) {
|
|
169
|
+
Napi::Env env = info.Env();
|
|
170
|
+
#ifdef BUILD_HTTP_SERVER
|
|
171
|
+
if (!database) {
|
|
172
|
+
Napi::Error::New(env, "Database is not initialized.")
|
|
173
|
+
.ThrowAsJavaScriptException();
|
|
174
|
+
return env.Null();
|
|
175
|
+
}
|
|
176
|
+
if (service_) {
|
|
177
|
+
Napi::Error::New(env, "Server is already running.")
|
|
178
|
+
.ThrowAsJavaScriptException();
|
|
179
|
+
return env.Null();
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
int port = 10000;
|
|
183
|
+
std::string host = "localhost";
|
|
184
|
+
int32_t num_thread = 0;
|
|
185
|
+
bool blocking = false;
|
|
186
|
+
|
|
187
|
+
if (info.Length() >= 1 && info[0].IsNumber()) {
|
|
188
|
+
port = info[0].As<Napi::Number>().Int32Value();
|
|
189
|
+
}
|
|
190
|
+
if (info.Length() >= 2 && info[1].IsString()) {
|
|
191
|
+
host = info[1].As<Napi::String>().Utf8Value();
|
|
192
|
+
}
|
|
193
|
+
if (info.Length() >= 3 && info[2].IsNumber()) {
|
|
194
|
+
num_thread = info[2].As<Napi::Number>().Int32Value();
|
|
195
|
+
}
|
|
196
|
+
if (info.Length() >= 4 && info[3].IsBoolean()) {
|
|
197
|
+
blocking = info[3].As<Napi::Boolean>().Value();
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
std::lock_guard<std::recursive_mutex> lock(mtx_);
|
|
201
|
+
database->Close();
|
|
202
|
+
database->Open(database->config());
|
|
203
|
+
|
|
204
|
+
neug::ServiceConfig config;
|
|
205
|
+
config.query_port = port;
|
|
206
|
+
config.host_str = host;
|
|
207
|
+
config.shard_num =
|
|
208
|
+
(num_thread == 0) ? std::thread::hardware_concurrency() : num_thread;
|
|
209
|
+
#ifdef __APPLE__
|
|
210
|
+
if (host == "localhost") {
|
|
211
|
+
config.host_str = "127.0.0.1";
|
|
212
|
+
}
|
|
213
|
+
#endif
|
|
214
|
+
|
|
215
|
+
service_ = std::make_unique<neug::NeugDBService>(*database, config);
|
|
216
|
+
if (blocking) {
|
|
217
|
+
service_->run_and_wait_for_exit();
|
|
218
|
+
return Napi::String::New(env, "");
|
|
219
|
+
}
|
|
220
|
+
return Napi::String::New(env, service_->Start());
|
|
221
|
+
#else
|
|
222
|
+
Napi::Error::New(env, "HTTP server is not enabled in this build.")
|
|
223
|
+
.ThrowAsJavaScriptException();
|
|
224
|
+
return env.Null();
|
|
225
|
+
#endif
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
Napi::Value NodeDatabase::StopServing(const Napi::CallbackInfo& info) {
|
|
229
|
+
std::lock_guard<std::recursive_mutex> lock(mtx_);
|
|
230
|
+
#ifdef BUILD_HTTP_SERVER
|
|
231
|
+
if (service_) {
|
|
232
|
+
service_->Stop();
|
|
233
|
+
service_.reset();
|
|
234
|
+
}
|
|
235
|
+
#endif
|
|
236
|
+
return info.Env().Undefined();
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
MemoryLevel NodeDatabase::ParseBufferStrategy(const std::string& level) {
|
|
240
|
+
if (level == "InMemory" || level == "inmemory" || level == "in_memory" ||
|
|
241
|
+
level == "M_FULL") {
|
|
242
|
+
return MemoryLevel::kInMemory;
|
|
243
|
+
} else if (level == "SyncToFile" || level == "synctofile" ||
|
|
244
|
+
level == "sync_to_file" || level == "M_LAZY") {
|
|
245
|
+
return MemoryLevel::kSyncToFile;
|
|
246
|
+
} else if (level == "HugePagePreferred" || level == "hugepagepreferred" ||
|
|
247
|
+
level == "huge_page_preferred" || level == "M_HUGE") {
|
|
248
|
+
return MemoryLevel::kHugePagePreferred;
|
|
249
|
+
} else {
|
|
250
|
+
THROW_INVALID_ARGUMENT_EXCEPTION("Invalid memory level: " + level);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
} // namespace neug
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/** Copyright 2020 Alibaba Group Holding Limited.
|
|
2
|
+
*
|
|
3
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License.
|
|
5
|
+
* You may obtain a copy of the License at
|
|
6
|
+
*
|
|
7
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
*
|
|
9
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
* See the License for the specific language governing permissions and
|
|
13
|
+
* limitations under the License.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
#ifndef TOOLS_NODEJS_BIND_SRC_NODE_DATABASE_H_
|
|
17
|
+
#define TOOLS_NODEJS_BIND_SRC_NODE_DATABASE_H_
|
|
18
|
+
|
|
19
|
+
#include <napi.h>
|
|
20
|
+
|
|
21
|
+
#include <memory>
|
|
22
|
+
#include <mutex>
|
|
23
|
+
#include <string>
|
|
24
|
+
|
|
25
|
+
#include "neug/main/neug_db.h"
|
|
26
|
+
#ifdef BUILD_HTTP_SERVER
|
|
27
|
+
#include "neug/server/neug_db_service.h"
|
|
28
|
+
#endif
|
|
29
|
+
#include "node_connection.h"
|
|
30
|
+
|
|
31
|
+
namespace neug {
|
|
32
|
+
|
|
33
|
+
class NodeDatabase : public Napi::ObjectWrap<NodeDatabase> {
|
|
34
|
+
public:
|
|
35
|
+
static Napi::Object Init(Napi::Env env, Napi::Object exports);
|
|
36
|
+
|
|
37
|
+
NodeDatabase(const Napi::CallbackInfo& info);
|
|
38
|
+
~NodeDatabase();
|
|
39
|
+
|
|
40
|
+
Napi::Value Connect(const Napi::CallbackInfo& info);
|
|
41
|
+
Napi::Value Close(const Napi::CallbackInfo& info);
|
|
42
|
+
Napi::Value Serve(const Napi::CallbackInfo& info);
|
|
43
|
+
Napi::Value StopServing(const Napi::CallbackInfo& info);
|
|
44
|
+
|
|
45
|
+
private:
|
|
46
|
+
static Napi::FunctionReference constructor;
|
|
47
|
+
|
|
48
|
+
MemoryLevel ParseBufferStrategy(const std::string& level);
|
|
49
|
+
|
|
50
|
+
std::recursive_mutex mtx_;
|
|
51
|
+
std::string db_dir_;
|
|
52
|
+
std::unique_ptr<NeugDB> database;
|
|
53
|
+
#ifdef BUILD_HTTP_SERVER
|
|
54
|
+
std::unique_ptr<NeugDBService> service_;
|
|
55
|
+
#endif
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
} // namespace neug
|
|
59
|
+
|
|
60
|
+
#endif // TOOLS_NODEJS_BIND_SRC_NODE_DATABASE_H_
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/** Copyright 2020 Alibaba Group Holding Limited.
|
|
2
|
+
*
|
|
3
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License.
|
|
5
|
+
* You may obtain a copy of the License at
|
|
6
|
+
*
|
|
7
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
*
|
|
9
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
* See the License for the specific language governing permissions and
|
|
13
|
+
* limitations under the License.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
#include "node_query_request.h"
|
|
17
|
+
|
|
18
|
+
#include <sstream>
|
|
19
|
+
#include <string>
|
|
20
|
+
|
|
21
|
+
#include "neug/execution/common/types/value.h"
|
|
22
|
+
#include "neug/main/query_request.h"
|
|
23
|
+
#include "neug/utils/access_mode.h"
|
|
24
|
+
#include "neug/utils/exception/exception.h"
|
|
25
|
+
#include "neug/utils/property/types.h"
|
|
26
|
+
#include "neug/utils/serialization/in_archive.h"
|
|
27
|
+
|
|
28
|
+
#include <rapidjson/document.h>
|
|
29
|
+
#include <rapidjson/stringbuffer.h>
|
|
30
|
+
#include <rapidjson/writer.h>
|
|
31
|
+
|
|
32
|
+
namespace neug {
|
|
33
|
+
|
|
34
|
+
Napi::FunctionReference NodeQueryRequest::constructor;
|
|
35
|
+
|
|
36
|
+
rapidjson::Document napi_value_to_rapidjson_document(
|
|
37
|
+
const Napi::Value& val, rapidjson::Document::AllocatorType& allocator) {
|
|
38
|
+
rapidjson::Document doc(&allocator);
|
|
39
|
+
|
|
40
|
+
if (val.IsNull() || val.IsUndefined()) {
|
|
41
|
+
doc.SetNull();
|
|
42
|
+
} else if (val.IsBoolean()) {
|
|
43
|
+
doc.SetBool(val.As<Napi::Boolean>().Value());
|
|
44
|
+
} else if (val.IsNumber()) {
|
|
45
|
+
Napi::Number num = val.As<Napi::Number>();
|
|
46
|
+
double d = num.DoubleValue();
|
|
47
|
+
// Check if it's an integer
|
|
48
|
+
if (d == static_cast<double>(static_cast<int64_t>(d))) {
|
|
49
|
+
doc.SetInt64(static_cast<int64_t>(d));
|
|
50
|
+
} else {
|
|
51
|
+
doc.SetDouble(d);
|
|
52
|
+
}
|
|
53
|
+
} else if (val.IsString()) {
|
|
54
|
+
std::string s = val.As<Napi::String>().Utf8Value();
|
|
55
|
+
doc.SetString(s.c_str(), s.length(), allocator);
|
|
56
|
+
} else if (val.IsArray()) {
|
|
57
|
+
Napi::Array arr = val.As<Napi::Array>();
|
|
58
|
+
doc.SetArray();
|
|
59
|
+
for (uint32_t i = 0; i < arr.Length(); ++i) {
|
|
60
|
+
rapidjson::Document element_doc =
|
|
61
|
+
napi_value_to_rapidjson_document(arr.Get(i), allocator);
|
|
62
|
+
doc.PushBack(element_doc, allocator);
|
|
63
|
+
}
|
|
64
|
+
} else if (val.IsDate()) {
|
|
65
|
+
// Convert Date to ISO string
|
|
66
|
+
Napi::Object date_obj = val.As<Napi::Object>();
|
|
67
|
+
Napi::Function to_iso =
|
|
68
|
+
date_obj.Get("toISOString").As<Napi::Function>();
|
|
69
|
+
std::string iso_str =
|
|
70
|
+
to_iso.Call(date_obj, {}).As<Napi::String>().Utf8Value();
|
|
71
|
+
doc.SetString(iso_str.c_str(), iso_str.length(), allocator);
|
|
72
|
+
} else if (val.IsObject()) {
|
|
73
|
+
// Serialize plain object as JSON object
|
|
74
|
+
Napi::Object obj = val.As<Napi::Object>();
|
|
75
|
+
Napi::Array keys = obj.GetPropertyNames();
|
|
76
|
+
doc.SetObject();
|
|
77
|
+
for (uint32_t i = 0; i < keys.Length(); ++i) {
|
|
78
|
+
std::string key = keys.Get(i).As<Napi::String>().Utf8Value();
|
|
79
|
+
rapidjson::Document val_doc =
|
|
80
|
+
napi_value_to_rapidjson_document(obj.Get(key), allocator);
|
|
81
|
+
rapidjson::Value json_key;
|
|
82
|
+
json_key.SetString(key.c_str(), key.length(), allocator);
|
|
83
|
+
doc.AddMember(json_key, val_doc, allocator);
|
|
84
|
+
}
|
|
85
|
+
} else {
|
|
86
|
+
throw std::invalid_argument(
|
|
87
|
+
"Unsupported parameter type for serialization.");
|
|
88
|
+
}
|
|
89
|
+
return doc;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
void NodeParameterSerializer::SerializeParameter(rapidjson::Document& doc,
|
|
93
|
+
const std::string& key,
|
|
94
|
+
const Napi::Value& parameter) {
|
|
95
|
+
if (doc.IsNull()) {
|
|
96
|
+
doc.SetObject();
|
|
97
|
+
}
|
|
98
|
+
auto& allocator = doc.GetAllocator();
|
|
99
|
+
rapidjson::Value json_key;
|
|
100
|
+
json_key.SetString(key.c_str(), key.length(), allocator);
|
|
101
|
+
rapidjson::Document json_value =
|
|
102
|
+
napi_value_to_rapidjson_document(parameter, allocator);
|
|
103
|
+
doc.AddMember(json_key, json_value, allocator);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
Napi::Object NodeQueryRequest::Init(Napi::Env env, Napi::Object exports) {
|
|
107
|
+
Napi::Function func = DefineClass(
|
|
108
|
+
env, "NodeQueryRequest",
|
|
109
|
+
{
|
|
110
|
+
StaticMethod("serializeRequest", &NodeQueryRequest::SerializeRequest),
|
|
111
|
+
});
|
|
112
|
+
constructor = Napi::Persistent(func);
|
|
113
|
+
constructor.SuppressDestruct();
|
|
114
|
+
exports.Set("NodeQueryRequest", func);
|
|
115
|
+
return exports;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
NodeQueryRequest::NodeQueryRequest(const Napi::CallbackInfo& info)
|
|
119
|
+
: Napi::ObjectWrap<NodeQueryRequest>(info) {}
|
|
120
|
+
|
|
121
|
+
Napi::Value NodeQueryRequest::SerializeRequest(const Napi::CallbackInfo& info) {
|
|
122
|
+
Napi::Env env = info.Env();
|
|
123
|
+
|
|
124
|
+
if (info.Length() < 1 || !info[0].IsString()) {
|
|
125
|
+
Napi::TypeError::New(env, "Query string required")
|
|
126
|
+
.ThrowAsJavaScriptException();
|
|
127
|
+
return env.Null();
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
std::string query = info[0].As<Napi::String>().Utf8Value();
|
|
131
|
+
std::string access_mode = "update";
|
|
132
|
+
if (info.Length() >= 2 && info[1].IsString()) {
|
|
133
|
+
access_mode = info[1].As<Napi::String>().Utf8Value();
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
rapidjson::Document req_doc(rapidjson::kObjectType);
|
|
137
|
+
auto& allocator = req_doc.GetAllocator();
|
|
138
|
+
req_doc.AddMember("query", rapidjson::Value(query.c_str(), allocator),
|
|
139
|
+
allocator);
|
|
140
|
+
req_doc.AddMember("access_mode",
|
|
141
|
+
rapidjson::Value(access_mode.c_str(), allocator),
|
|
142
|
+
allocator);
|
|
143
|
+
|
|
144
|
+
rapidjson::Document params_doc;
|
|
145
|
+
if (info.Length() >= 3 && info[2].IsObject()) {
|
|
146
|
+
Napi::Object params_obj = info[2].As<Napi::Object>();
|
|
147
|
+
Napi::Array keys = params_obj.GetPropertyNames();
|
|
148
|
+
for (uint32_t i = 0; i < keys.Length(); ++i) {
|
|
149
|
+
std::string key = keys.Get(i).As<Napi::String>().Utf8Value();
|
|
150
|
+
NodeParameterSerializer::SerializeParameter(params_doc, key,
|
|
151
|
+
params_obj.Get(key));
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
req_doc.AddMember("parameters", params_doc, allocator);
|
|
155
|
+
|
|
156
|
+
rapidjson::StringBuffer buffer;
|
|
157
|
+
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
|
|
158
|
+
req_doc.Accept(writer);
|
|
159
|
+
return Napi::String::New(env, buffer.GetString());
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
} // namespace neug
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/** Copyright 2020 Alibaba Group Holding Limited.
|
|
2
|
+
*
|
|
3
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License.
|
|
5
|
+
* You may obtain a copy of the License at
|
|
6
|
+
*
|
|
7
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
*
|
|
9
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
* See the License for the specific language governing permissions and
|
|
13
|
+
* limitations under the License.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
#pragma once
|
|
17
|
+
|
|
18
|
+
#include <napi.h>
|
|
19
|
+
|
|
20
|
+
#include <string>
|
|
21
|
+
|
|
22
|
+
#include <rapidjson/document.h>
|
|
23
|
+
|
|
24
|
+
namespace neug {
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* A helper struct for serializing parameters from NAPI objects to JSON strings.
|
|
28
|
+
*/
|
|
29
|
+
struct NodeParameterSerializer {
|
|
30
|
+
static void SerializeParameter(rapidjson::Document& doc,
|
|
31
|
+
const std::string& key,
|
|
32
|
+
const Napi::Value& parameter);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
class NodeQueryRequest : public Napi::ObjectWrap<NodeQueryRequest> {
|
|
36
|
+
public:
|
|
37
|
+
static Napi::Object Init(Napi::Env env, Napi::Object exports);
|
|
38
|
+
|
|
39
|
+
NodeQueryRequest(const Napi::CallbackInfo& info);
|
|
40
|
+
|
|
41
|
+
private:
|
|
42
|
+
static Napi::FunctionReference constructor;
|
|
43
|
+
|
|
44
|
+
static Napi::Value SerializeRequest(const Napi::CallbackInfo& info);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
} // namespace neug
|