@graphscope-neug/osx-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.
@@ -0,0 +1,65 @@
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 <napi.h>
17
+
18
+ #include <iostream>
19
+ #include <string>
20
+
21
+ #include <glog/logging.h>
22
+
23
+ #include "neug/utils/exception/exception.h"
24
+ #include "node_connection.h"
25
+ #include "node_database.h"
26
+ #include "node_query_request.h"
27
+ #include "node_query_result.h"
28
+
29
+ namespace neug {
30
+
31
+ void SetupLogging() {
32
+ google::InitGoogleLogging("neug");
33
+ const char* debug = std::getenv("DEBUG");
34
+
35
+ if (debug) {
36
+ std::string mode = debug;
37
+ if (mode == "1" || mode == "true" || mode == "ON") {
38
+ FLAGS_minloglevel = 0; // 0 for verbose
39
+ FLAGS_logtostderr = true; // Log to stderr
40
+ } else {
41
+ std::cerr << "Invalid DEBUG value: " << mode
42
+ << ". Expected '1', 'true', or 'ON'." << std::endl;
43
+ FLAGS_minloglevel = 2; // 2 for error
44
+ FLAGS_logtostderr = false; // Log to file instead of stderr
45
+ }
46
+ } else {
47
+ FLAGS_minloglevel = 2; // 2 for error
48
+ FLAGS_logtostderr = false; // Log to file instead of stderr
49
+ }
50
+ }
51
+
52
+ } // namespace neug
53
+
54
+ static Napi::Object InitAll(Napi::Env env, Napi::Object exports) {
55
+ neug::NodeDatabase::Init(env, exports);
56
+ neug::NodeConnection::Init(env, exports);
57
+ neug::NodeQueryResult::Init(env, exports);
58
+ neug::NodeQueryRequest::Init(env, exports);
59
+
60
+ neug::SetupLogging();
61
+
62
+ return exports;
63
+ }
64
+
65
+ NODE_API_MODULE(neug_node_bind, InitAll)
@@ -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,265 @@
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 <unistd.h>
19
+
20
+ #include <string>
21
+
22
+ #include "neug/config.h"
23
+ #include "neug/utils/exception/exception.h"
24
+
25
+ namespace neug {
26
+
27
+ Napi::FunctionReference NodeDatabase::constructor;
28
+
29
+ Napi::Object NodeDatabase::Init(Napi::Env env, Napi::Object exports) {
30
+ Napi::Function func = DefineClass(
31
+ env, "NodeDatabase",
32
+ {
33
+ InstanceMethod("connect", &NodeDatabase::Connect),
34
+ InstanceMethod("close", &NodeDatabase::Close),
35
+ InstanceMethod("serve", &NodeDatabase::Serve),
36
+ InstanceMethod("stopServing", &NodeDatabase::StopServing),
37
+ StaticMethod("cpuCount", &NodeDatabase::GetCpuCount),
38
+ });
39
+ constructor = Napi::Persistent(func);
40
+ constructor.SuppressDestruct();
41
+ exports.Set("NodeDatabase", func);
42
+ return exports;
43
+ }
44
+
45
+ NodeDatabase::NodeDatabase(const Napi::CallbackInfo& info)
46
+ : Napi::ObjectWrap<NodeDatabase>(info) {
47
+ Napi::Env env = info.Env();
48
+
49
+ if (info.Length() < 1 || !info[0].IsObject()) {
50
+ Napi::TypeError::New(env, "Options object required")
51
+ .ThrowAsJavaScriptException();
52
+ return;
53
+ }
54
+
55
+ Napi::Object opts = info[0].As<Napi::Object>();
56
+
57
+ // Parse options
58
+ std::string database_path = "";
59
+ if (opts.Has("databasePath") && opts.Get("databasePath").IsString()) {
60
+ database_path = opts.Get("databasePath").As<Napi::String>().Utf8Value();
61
+ }
62
+
63
+ int32_t max_thread_num = 0;
64
+ if (opts.Has("maxThreadNum") && opts.Get("maxThreadNum").IsNumber()) {
65
+ max_thread_num = opts.Get("maxThreadNum").As<Napi::Number>().Int32Value();
66
+ }
67
+
68
+ std::string mode = "r";
69
+ if (opts.Has("mode") && opts.Get("mode").IsString()) {
70
+ mode = opts.Get("mode").As<Napi::String>().Utf8Value();
71
+ }
72
+
73
+ std::string planner = "gopt";
74
+ if (opts.Has("planner") && opts.Get("planner").IsString()) {
75
+ planner = opts.Get("planner").As<Napi::String>().Utf8Value();
76
+ }
77
+
78
+ bool checkpoint_on_close = true;
79
+ if (opts.Has("checkpointOnClose") && opts.Get("checkpointOnClose").IsBoolean()) {
80
+ checkpoint_on_close = opts.Get("checkpointOnClose").As<Napi::Boolean>().Value();
81
+ }
82
+
83
+ std::string buffer_strategy = "M_FULL";
84
+ if (opts.Has("bufferStrategy") && opts.Get("bufferStrategy").IsString()) {
85
+ buffer_strategy = opts.Get("bufferStrategy").As<Napi::String>().Utf8Value();
86
+ }
87
+
88
+ // Parse mode
89
+ neug::DBMode mode_;
90
+ if (mode == "read" || mode == "r" || mode == "read-only" ||
91
+ mode == "read_only") {
92
+ mode_ = DBMode::READ_ONLY;
93
+ } else if (mode == "read_write" || mode == "rw" || mode == "w" ||
94
+ mode == "wr" || mode == "write" || mode == "readwrite" ||
95
+ mode == "read-write") {
96
+ mode_ = DBMode::READ_WRITE;
97
+ } else {
98
+ Napi::Error::New(env, "Invalid mode: " + mode)
99
+ .ThrowAsJavaScriptException();
100
+ return;
101
+ }
102
+
103
+ db_dir_ = database_path;
104
+ database = std::make_unique<NeugDB>();
105
+ NeugDBConfig config(db_dir_, max_thread_num);
106
+ config.mode = mode_;
107
+ config.planner_kind = planner;
108
+ config.checkpoint_on_close = checkpoint_on_close;
109
+ try {
110
+ config.memory_level = ParseBufferStrategy(buffer_strategy);
111
+ database->Open(config);
112
+ } catch (const neug::exception::Exception& e) {
113
+ Napi::Error::New(env, e.what()).ThrowAsJavaScriptException();
114
+ database.reset();
115
+ return;
116
+ } catch (const std::exception& e) {
117
+ Napi::Error::New(env, e.what()).ThrowAsJavaScriptException();
118
+ database.reset();
119
+ return;
120
+ }
121
+ }
122
+
123
+ NodeDatabase::~NodeDatabase() {
124
+ std::lock_guard<std::recursive_mutex> lock(mtx_);
125
+ #ifdef BUILD_HTTP_SERVER
126
+ if (service_) {
127
+ service_->Stop();
128
+ service_.reset();
129
+ }
130
+ #endif
131
+ if (database) {
132
+ database->Close();
133
+ database.reset();
134
+ }
135
+ }
136
+
137
+ Napi::Value NodeDatabase::Connect(const Napi::CallbackInfo& info) {
138
+ Napi::Env env = info.Env();
139
+ if (!database) {
140
+ Napi::Error::New(env, "Database is not initialized.")
141
+ .ThrowAsJavaScriptException();
142
+ return env.Null();
143
+ }
144
+ try {
145
+ auto conn = database->Connect();
146
+ return NodeConnection::NewInstance(env, *database, conn);
147
+ } catch (const neug::exception::Exception& e) {
148
+ Napi::Error::New(env, e.what()).ThrowAsJavaScriptException();
149
+ return env.Null();
150
+ } catch (const std::exception& e) {
151
+ Napi::Error::New(env, e.what()).ThrowAsJavaScriptException();
152
+ return env.Null();
153
+ }
154
+ }
155
+
156
+ Napi::Value NodeDatabase::Close(const Napi::CallbackInfo& info) {
157
+ std::lock_guard<std::recursive_mutex> lock(mtx_);
158
+ #ifdef BUILD_HTTP_SERVER
159
+ if (service_) {
160
+ service_->Stop();
161
+ service_.reset();
162
+ }
163
+ #endif
164
+ if (database) {
165
+ database->Close();
166
+ database.reset();
167
+ }
168
+ return info.Env().Undefined();
169
+ }
170
+
171
+ Napi::Value NodeDatabase::Serve(const Napi::CallbackInfo& info) {
172
+ Napi::Env env = info.Env();
173
+ #ifdef BUILD_HTTP_SERVER
174
+ if (!database) {
175
+ Napi::Error::New(env, "Database is not initialized.")
176
+ .ThrowAsJavaScriptException();
177
+ return env.Null();
178
+ }
179
+ if (service_) {
180
+ Napi::Error::New(env, "Server is already running.")
181
+ .ThrowAsJavaScriptException();
182
+ return env.Null();
183
+ }
184
+
185
+ int port = 10000;
186
+ std::string host = "localhost";
187
+ int32_t num_thread = 0;
188
+ bool blocking = false;
189
+
190
+ if (info.Length() >= 1 && info[0].IsNumber()) {
191
+ port = info[0].As<Napi::Number>().Int32Value();
192
+ }
193
+ if (info.Length() >= 2 && info[1].IsString()) {
194
+ host = info[1].As<Napi::String>().Utf8Value();
195
+ }
196
+ if (info.Length() >= 3 && info[2].IsNumber()) {
197
+ num_thread = info[2].As<Napi::Number>().Int32Value();
198
+ }
199
+ if (info.Length() >= 4 && info[3].IsBoolean()) {
200
+ blocking = info[3].As<Napi::Boolean>().Value();
201
+ }
202
+
203
+ std::lock_guard<std::recursive_mutex> lock(mtx_);
204
+ database->Close();
205
+ database->Open(database->config());
206
+
207
+ neug::ServiceConfig config;
208
+ config.query_port = port;
209
+ config.host_str = host;
210
+ config.shard_num =
211
+ (num_thread == 0) ? std::thread::hardware_concurrency() : num_thread;
212
+ #ifdef __APPLE__
213
+ if (host == "localhost") {
214
+ config.host_str = "127.0.0.1";
215
+ }
216
+ #endif
217
+
218
+ service_ = std::make_unique<neug::NeugDBService>(*database, config);
219
+ if (blocking) {
220
+ service_->run_and_wait_for_exit();
221
+ return Napi::String::New(env, "");
222
+ }
223
+ return Napi::String::New(env, service_->Start());
224
+ #else
225
+ Napi::Error::New(env, "HTTP server is not enabled in this build.")
226
+ .ThrowAsJavaScriptException();
227
+ return env.Null();
228
+ #endif
229
+ }
230
+
231
+ Napi::Value NodeDatabase::StopServing(const Napi::CallbackInfo& info) {
232
+ std::lock_guard<std::recursive_mutex> lock(mtx_);
233
+ #ifdef BUILD_HTTP_SERVER
234
+ if (service_) {
235
+ service_->Stop();
236
+ service_.reset();
237
+ }
238
+ #endif
239
+ return info.Env().Undefined();
240
+ }
241
+
242
+ Napi::Value NodeDatabase::GetCpuCount(const Napi::CallbackInfo& info) {
243
+ long n = sysconf(_SC_NPROCESSORS_ONLN);
244
+ if (n < 1) {
245
+ n = 1;
246
+ }
247
+ return Napi::Number::New(info.Env(), static_cast<int32_t>(n));
248
+ }
249
+
250
+ MemoryLevel NodeDatabase::ParseBufferStrategy(const std::string& level) {
251
+ if (level == "InMemory" || level == "inmemory" || level == "in_memory" ||
252
+ level == "M_FULL") {
253
+ return MemoryLevel::kInMemory;
254
+ } else if (level == "SyncToFile" || level == "synctofile" ||
255
+ level == "sync_to_file" || level == "M_LAZY") {
256
+ return MemoryLevel::kSyncToFile;
257
+ } else if (level == "HugePagePreferred" || level == "hugepagepreferred" ||
258
+ level == "huge_page_preferred" || level == "M_HUGE") {
259
+ return MemoryLevel::kHugePagePreferred;
260
+ } else {
261
+ THROW_INVALID_ARGUMENT_EXCEPTION("Invalid memory level: " + level);
262
+ }
263
+ }
264
+
265
+ } // namespace neug
@@ -0,0 +1,61 @@
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
+ static Napi::Value GetCpuCount(const Napi::CallbackInfo& info);
37
+
38
+ NodeDatabase(const Napi::CallbackInfo& info);
39
+ ~NodeDatabase();
40
+
41
+ Napi::Value Connect(const Napi::CallbackInfo& info);
42
+ Napi::Value Close(const Napi::CallbackInfo& info);
43
+ Napi::Value Serve(const Napi::CallbackInfo& info);
44
+ Napi::Value StopServing(const Napi::CallbackInfo& info);
45
+
46
+ private:
47
+ static Napi::FunctionReference constructor;
48
+
49
+ MemoryLevel ParseBufferStrategy(const std::string& level);
50
+
51
+ std::recursive_mutex mtx_;
52
+ std::string db_dir_;
53
+ std::unique_ptr<NeugDB> database;
54
+ #ifdef BUILD_HTTP_SERVER
55
+ std::unique_ptr<NeugDBService> service_;
56
+ #endif
57
+ };
58
+
59
+ } // namespace neug
60
+
61
+ #endif // TOOLS_NODEJS_BIND_SRC_NODE_DATABASE_H_