@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.
@@ -0,0 +1,361 @@
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_result.h"
17
+
18
+ #include <cstdint>
19
+ #include <memory>
20
+ #include <vector>
21
+
22
+ #include "neug/storages/graph/schema.h"
23
+ #include "neug/utils/bolt_utils.h"
24
+ #include "neug/utils/exception/exception.h"
25
+ #include "neug/utils/property/types.h"
26
+
27
+ namespace neug {
28
+
29
+ Napi::FunctionReference NodeQueryResult::constructor;
30
+
31
+ Napi::Object NodeQueryResult::Init(Napi::Env env, Napi::Object exports) {
32
+ Napi::Function func = DefineClass(
33
+ env, "NodeQueryResult",
34
+ {
35
+ InstanceMethod("hasNext", &NodeQueryResult::HasNext),
36
+ InstanceMethod("getNext", &NodeQueryResult::GetNext),
37
+ InstanceMethod("getAt", &NodeQueryResult::GetAt),
38
+ InstanceMethod("length", &NodeQueryResult::Length),
39
+ InstanceMethod("columnNames", &NodeQueryResult::ColumnNames),
40
+ InstanceMethod("statusCode", &NodeQueryResult::StatusCode),
41
+ InstanceMethod("statusMessage", &NodeQueryResult::StatusMessage),
42
+ InstanceMethod("getBoltResponse", &NodeQueryResult::GetBoltResponse),
43
+ InstanceMethod("close", &NodeQueryResult::Close),
44
+ StaticMethod("fromString", &NodeQueryResult::FromString),
45
+ });
46
+ constructor = Napi::Persistent(func);
47
+ constructor.SuppressDestruct();
48
+ exports.Set("NodeQueryResult", func);
49
+ return exports;
50
+ }
51
+
52
+ NodeQueryResult::NodeQueryResult(const Napi::CallbackInfo& info)
53
+ : Napi::ObjectWrap<NodeQueryResult>(info),
54
+ status_(Status::OK()),
55
+ query_result_() {}
56
+
57
+ NodeQueryResult::~NodeQueryResult() {}
58
+
59
+ Napi::Object NodeQueryResult::NewInstance(Napi::Env env, QueryResult&& result) {
60
+ Napi::Object obj = constructor.New({});
61
+ NodeQueryResult* wrapped = Napi::ObjectWrap<NodeQueryResult>::Unwrap(obj);
62
+ wrapped->status_ = Status::OK();
63
+ // QueryResult has no move assignment operator, use Swap instead
64
+ QueryResult tmp(std::move(result));
65
+ wrapped->query_result_.Swap(tmp);
66
+ wrapped->index_ = 0;
67
+ return obj;
68
+ }
69
+
70
+ Napi::Object NodeQueryResult::NewInstanceFromStatus(Napi::Env env,
71
+ const Status& status) {
72
+ Napi::Object obj = constructor.New({});
73
+ NodeQueryResult* wrapped = Napi::ObjectWrap<NodeQueryResult>::Unwrap(obj);
74
+ wrapped->status_ = status;
75
+ wrapped->index_ = 0;
76
+ return obj;
77
+ }
78
+
79
+ Napi::Object NodeQueryResult::NewInstanceFromString(Napi::Env env,
80
+ std::string&& result_str) {
81
+ Napi::Object obj = constructor.New({});
82
+ NodeQueryResult* wrapped = Napi::ObjectWrap<NodeQueryResult>::Unwrap(obj);
83
+ wrapped->status_ = Status::OK();
84
+ wrapped->query_result_.Swap(QueryResult::From(std::move(result_str)));
85
+ wrapped->index_ = 0;
86
+ return obj;
87
+ }
88
+
89
+ bool NodeQueryResult::hasNext() { return index_ < query_result_.length(); }
90
+
91
+ int32_t NodeQueryResult::length() const { return query_result_.length(); }
92
+
93
+ std::vector<std::string> NodeQueryResult::column_names() const {
94
+ const auto& schema = query_result_.result_schema();
95
+ std::vector<std::string> names(schema.name_size());
96
+ for (int i = 0; i < schema.name_size(); ++i) {
97
+ names[i] = schema.name(i);
98
+ }
99
+ return names;
100
+ }
101
+
102
+ int32_t NodeQueryResult::status_code() const { return status_.error_code(); }
103
+
104
+ const std::string& NodeQueryResult::status_message() const {
105
+ return status_.error_message();
106
+ }
107
+
108
+ namespace {
109
+
110
+ inline bool is_valid(const std::string& map, size_t i) {
111
+ return map.empty() || (static_cast<uint8_t>(map[i >> 3]) >> (i & 7)) & 1;
112
+ }
113
+
114
+ Napi::Value ParseJsonToJsObject(Napi::Env env, const std::string& json_str) {
115
+ Napi::Object global = env.Global();
116
+ Napi::Object json_obj = global.Get("JSON").As<Napi::Object>();
117
+ Napi::Function parse_fn = json_obj.Get("parse").As<Napi::Function>();
118
+ return parse_fn.Call(json_obj, {Napi::String::New(env, json_str)});
119
+ }
120
+
121
+ Napi::Value FetchValueFromColumn(Napi::Env env, const neug::Array& column,
122
+ size_t index) {
123
+ if (column.has_bool_array()) {
124
+ const auto& col = column.bool_array();
125
+ if (is_valid(col.validity(), index)) {
126
+ return Napi::Boolean::New(env, col.values(index));
127
+ } else {
128
+ return env.Null();
129
+ }
130
+ } else if (column.has_int32_array()) {
131
+ const auto& col = column.int32_array();
132
+ if (is_valid(col.validity(), index)) {
133
+ return Napi::Number::New(env, col.values(index));
134
+ } else {
135
+ return env.Null();
136
+ }
137
+ } else if (column.has_uint32_array()) {
138
+ const auto& col = column.uint32_array();
139
+ if (is_valid(col.validity(), index)) {
140
+ return Napi::Number::New(env, col.values(index));
141
+ } else {
142
+ return env.Null();
143
+ }
144
+ } else if (column.has_int64_array()) {
145
+ const auto& col = column.int64_array();
146
+ if (is_valid(col.validity(), index)) {
147
+ return Napi::Number::New(env, static_cast<double>(col.values(index)));
148
+ } else {
149
+ return env.Null();
150
+ }
151
+ } else if (column.has_uint64_array()) {
152
+ const auto& col = column.uint64_array();
153
+ if (is_valid(col.validity(), index)) {
154
+ return Napi::Number::New(env, static_cast<double>(col.values(index)));
155
+ } else {
156
+ return env.Null();
157
+ }
158
+ } else if (column.has_float_array()) {
159
+ const auto& col = column.float_array();
160
+ if (is_valid(col.validity(), index)) {
161
+ return Napi::Number::New(env, col.values(index));
162
+ } else {
163
+ return env.Null();
164
+ }
165
+ } else if (column.has_double_array()) {
166
+ const auto& col = column.double_array();
167
+ if (is_valid(col.validity(), index)) {
168
+ return Napi::Number::New(env, col.values(index));
169
+ } else {
170
+ return env.Null();
171
+ }
172
+ } else if (column.has_string_array()) {
173
+ const auto& col = column.string_array();
174
+ if (is_valid(col.validity(), index)) {
175
+ return Napi::String::New(env, col.values(index));
176
+ } else {
177
+ return env.Null();
178
+ }
179
+ } else if (column.has_date_array()) {
180
+ const auto& col = column.date_array();
181
+ if (is_valid(col.validity(), index)) {
182
+ Date day;
183
+ day.from_timestamp(col.values(index));
184
+ // Return ISO date string (YYYY-MM-DD with leading zeros)
185
+ return Napi::String::New(env, day.to_string());
186
+ } else {
187
+ return env.Null();
188
+ }
189
+ } else if (column.has_timestamp_array()) {
190
+ const auto& col = column.timestamp_array();
191
+ if (is_valid(col.validity(), index)) {
192
+ int64_t ms = col.values(index);
193
+ // Return as JS Date object
194
+ Napi::Object global = env.Global();
195
+ Napi::Function date_ctor = global.Get("Date").As<Napi::Function>();
196
+ return date_ctor.New({Napi::Number::New(env, static_cast<double>(ms))});
197
+ } else {
198
+ return env.Null();
199
+ }
200
+ } else if (column.has_interval_array()) {
201
+ const auto& col = column.interval_array();
202
+ if (is_valid(col.validity(), index)) {
203
+ return Napi::String::New(env, col.values(index));
204
+ } else {
205
+ return env.Null();
206
+ }
207
+ } else if (column.has_list_array()) {
208
+ const auto& col = column.list_array();
209
+ if (is_valid(col.validity(), index)) {
210
+ uint32_t list_size = col.offsets(index + 1) - col.offsets(index);
211
+ size_t offset = col.offsets(index);
212
+ Napi::Array arr = Napi::Array::New(env, list_size);
213
+ for (uint32_t i = 0; i < list_size; ++i) {
214
+ arr.Set(i,
215
+ FetchValueFromColumn(env, col.elements(), offset + i));
216
+ }
217
+ return arr;
218
+ } else {
219
+ return env.Null();
220
+ }
221
+ } else if (column.has_struct_array()) {
222
+ const auto& col = column.struct_array();
223
+ if (is_valid(col.validity(), index)) {
224
+ Napi::Array arr = Napi::Array::New(env, col.fields_size());
225
+ for (int i = 0; i < col.fields_size(); ++i) {
226
+ arr.Set(i, FetchValueFromColumn(env, col.fields(i), index));
227
+ }
228
+ return arr;
229
+ } else {
230
+ return env.Null();
231
+ }
232
+ } else if (column.has_vertex_array()) {
233
+ const auto& col = column.vertex_array();
234
+ if (is_valid(col.validity(), index)) {
235
+ return ParseJsonToJsObject(env, col.values(index));
236
+ } else {
237
+ return env.Null();
238
+ }
239
+ } else if (column.has_edge_array()) {
240
+ const auto& col = column.edge_array();
241
+ if (is_valid(col.validity(), index)) {
242
+ return ParseJsonToJsObject(env, col.values(index));
243
+ } else {
244
+ return env.Null();
245
+ }
246
+ } else if (column.has_path_array()) {
247
+ const auto& col = column.path_array();
248
+ if (is_valid(col.validity(), index)) {
249
+ return ParseJsonToJsObject(env, col.values(index));
250
+ } else {
251
+ return env.Null();
252
+ }
253
+ } else {
254
+ return env.Null();
255
+ }
256
+ }
257
+
258
+ } // namespace
259
+
260
+ Napi::Value NodeQueryResult::HasNext(const Napi::CallbackInfo& info) {
261
+ return Napi::Boolean::New(info.Env(), hasNext());
262
+ }
263
+
264
+ Napi::Value NodeQueryResult::GetNext(const Napi::CallbackInfo& info) {
265
+ Napi::Env env = info.Env();
266
+ if (!hasNext()) {
267
+ Napi::Error::New(env, "No more results").ThrowAsJavaScriptException();
268
+ return env.Null();
269
+ }
270
+ const auto& response = query_result_.response();
271
+ int num_columns = response.arrays_size();
272
+ Napi::Array arr = Napi::Array::New(env, num_columns);
273
+ for (int i = 0; i < num_columns; ++i) {
274
+ arr.Set(i, FetchValueFromColumn(env, response.arrays(i), index_));
275
+ }
276
+ ++index_;
277
+ return arr;
278
+ }
279
+
280
+ Napi::Value NodeQueryResult::GetAt(const Napi::CallbackInfo& info) {
281
+ Napi::Env env = info.Env();
282
+ if (info.Length() < 1) {
283
+ Napi::TypeError::New(env, "Index argument required")
284
+ .ThrowAsJavaScriptException();
285
+ return env.Null();
286
+ }
287
+ int32_t idx = info[0].As<Napi::Number>().Int32Value();
288
+ int32_t total = query_result_.length();
289
+ if (idx < 0) {
290
+ idx += total;
291
+ }
292
+ if (idx < 0 || idx >= total) {
293
+ Napi::RangeError::New(env, "Index out of range")
294
+ .ThrowAsJavaScriptException();
295
+ return env.Null();
296
+ }
297
+ const auto& response = query_result_.response();
298
+ int num_columns = response.arrays_size();
299
+ Napi::Array arr = Napi::Array::New(env, num_columns);
300
+ for (int i = 0; i < num_columns; ++i) {
301
+ arr.Set(i, FetchValueFromColumn(env, response.arrays(i), idx));
302
+ }
303
+ return arr;
304
+ }
305
+
306
+ Napi::Value NodeQueryResult::Length(const Napi::CallbackInfo& info) {
307
+ return Napi::Number::New(info.Env(), length());
308
+ }
309
+
310
+ Napi::Value NodeQueryResult::ColumnNames(const Napi::CallbackInfo& info) {
311
+ Napi::Env env = info.Env();
312
+ auto names = column_names();
313
+ Napi::Array arr = Napi::Array::New(env, names.size());
314
+ for (size_t i = 0; i < names.size(); ++i) {
315
+ arr.Set(i, Napi::String::New(env, names[i]));
316
+ }
317
+ return arr;
318
+ }
319
+
320
+ Napi::Value NodeQueryResult::StatusCode(const Napi::CallbackInfo& info) {
321
+ return Napi::Number::New(info.Env(), status_code());
322
+ }
323
+
324
+ Napi::Value NodeQueryResult::StatusMessage(const Napi::CallbackInfo& info) {
325
+ return Napi::String::New(info.Env(), status_message());
326
+ }
327
+
328
+ Napi::Value NodeQueryResult::GetBoltResponse(const Napi::CallbackInfo& info) {
329
+ auto names = column_names();
330
+ return Napi::String::New(info.Env(),
331
+ results_to_bolt_response(query_result_.response(),
332
+ names));
333
+ }
334
+
335
+ Napi::Value NodeQueryResult::Close(const Napi::CallbackInfo& info) {
336
+ // No-op, provided for compatibility
337
+ return info.Env().Undefined();
338
+ }
339
+
340
+ Napi::Value NodeQueryResult::FromString(const Napi::CallbackInfo& info) {
341
+ Napi::Env env = info.Env();
342
+ if (info.Length() < 1) {
343
+ Napi::TypeError::New(env, "String or Buffer argument required")
344
+ .ThrowAsJavaScriptException();
345
+ return env.Null();
346
+ }
347
+ std::string result_str;
348
+ if (info[0].IsBuffer()) {
349
+ auto buf = info[0].As<Napi::Buffer<char>>();
350
+ result_str.assign(buf.Data(), buf.Length());
351
+ } else if (info[0].IsString()) {
352
+ result_str = info[0].As<Napi::String>().Utf8Value();
353
+ } else {
354
+ Napi::TypeError::New(env, "String or Buffer argument required")
355
+ .ThrowAsJavaScriptException();
356
+ return env.Null();
357
+ }
358
+ return NewInstanceFromString(env, std::move(result_str));
359
+ }
360
+
361
+ } // namespace neug
@@ -0,0 +1,72 @@
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_QUERY_RESULT_H_
17
+ #define TOOLS_NODEJS_BIND_SRC_NODE_QUERY_RESULT_H_
18
+
19
+ #include <napi.h>
20
+
21
+ #include <memory>
22
+ #include <string>
23
+ #include <vector>
24
+
25
+ #include "neug/main/query_result.h"
26
+ #include "neug/storages/graph/schema.h"
27
+ #include "neug/utils/result.h"
28
+
29
+ namespace neug {
30
+
31
+ class NodeQueryResult : public Napi::ObjectWrap<NodeQueryResult> {
32
+ public:
33
+ static Napi::Object Init(Napi::Env env, Napi::Object exports);
34
+ static Napi::Object NewInstance(Napi::Env env, QueryResult&& result);
35
+ static Napi::Object NewInstanceFromStatus(Napi::Env env,
36
+ const Status& status);
37
+ static Napi::Object NewInstanceFromString(Napi::Env env,
38
+ std::string&& result_str);
39
+
40
+ NodeQueryResult(const Napi::CallbackInfo& info);
41
+ ~NodeQueryResult();
42
+
43
+ bool hasNext();
44
+ int32_t length() const;
45
+ std::vector<std::string> column_names() const;
46
+ int32_t status_code() const;
47
+ const std::string& status_message() const;
48
+
49
+ QueryResult& query_result() { return query_result_; }
50
+
51
+ private:
52
+ static Napi::FunctionReference constructor;
53
+
54
+ Napi::Value HasNext(const Napi::CallbackInfo& info);
55
+ Napi::Value GetNext(const Napi::CallbackInfo& info);
56
+ Napi::Value GetAt(const Napi::CallbackInfo& info);
57
+ Napi::Value Length(const Napi::CallbackInfo& info);
58
+ Napi::Value ColumnNames(const Napi::CallbackInfo& info);
59
+ Napi::Value StatusCode(const Napi::CallbackInfo& info);
60
+ Napi::Value StatusMessage(const Napi::CallbackInfo& info);
61
+ Napi::Value GetBoltResponse(const Napi::CallbackInfo& info);
62
+ Napi::Value Close(const Napi::CallbackInfo& info);
63
+ static Napi::Value FromString(const Napi::CallbackInfo& info);
64
+
65
+ size_t index_{0};
66
+ Status status_;
67
+ QueryResult query_result_;
68
+ };
69
+
70
+ } // namespace neug
71
+
72
+ #endif // TOOLS_NODEJS_BIND_SRC_NODE_QUERY_RESULT_H_