Skip to content

Commit 00578b0

Browse files
authored
Add async worker capabilities (#29)
1 parent e6db78f commit 00578b0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+8535
-1397
lines changed

.eslintignore

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1 @@
1-
.git/
2-
build/
3-
node_modules/
1+
example/typescript/*.js

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@ jobs:
2424
uses: actions/cache@v1
2525
with:
2626
path: ~/memgraph
27-
key: cache-memgraph-v1.6.1-docker-image
27+
key: cache-memgraph-v2.0.1-docker-image
2828
- name: Download Memgraph Docker image
2929
if: steps.cache-memgraph-docker.outputs.cache-hit != 'true'
3030
run: |
3131
mkdir ~/memgraph
32-
curl -L https://memgraph.com/download/memgraph/v1.6.1/docker/memgraph-1.6.1-community-docker.tar.gz > ~/memgraph/memgraph-docker.tar.gz
32+
curl -L https://memgraph.com/download/memgraph/v2.0.1/docker/memgraph-2.0.1-docker.tar.gz > ~/memgraph/memgraph-docker.tar.gz
3333
- name: Load Memgraph Docker image
3434
run: |
3535
docker load -i ~/memgraph/memgraph-docker.tar.gz

.npmignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
node_modules
2+
build/*
3+
!build/Release/nodemgclient.node
4+
.cache
5+
.github

CMakeLists.txt

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,10 @@ endif()
4343
ExternalProject_Add(mgclient-proj
4444
PREFIX mgclient
4545
GIT_REPOSITORY https://github.com/memgraph/mgclient.git
46-
GIT_TAG 63ffb016f2338e56ba7c5171d5f4938b6cec50f6
46+
GIT_TAG v1.3.0
4747
CMAKE_ARGS "-DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>"
4848
"-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}"
49+
"-DBUILD_CPP_BINDINGS=ON"
4950
INSTALL_DIR "${PROJECT_BINARY_DIR}/mgclient")
5051
ExternalProject_Get_Property(mgclient-proj install_dir)
5152
set(MGCLIENT_ROOT ${install_dir})
@@ -68,18 +69,21 @@ message(STATUS "MGCLIENT_LIBRARY: ${MGCLIENT_LIBRARY}")
6869

6970
# Define the addon.
7071
include_directories(${CMAKE_JS_INC})
71-
set(SOURCE_FILES src/addon.cpp src/connection.cpp src/glue.cpp
72-
src/record.cpp src/cursor.cpp)
72+
set(SOURCE_FILES src/addon.cpp
73+
src/client.cpp
74+
src/glue.cpp)
7375
add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES} ${CMAKE_JS_SRC})
7476
add_dependencies(${PROJECT_NAME} ${MGCLIENT_LIBRARY})
7577
set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "" SUFFIX ".node")
7678
target_link_libraries(${PROJECT_NAME} PRIVATE
7779
${CMAKE_JS_LIB} ${MGCLIENT_LIBRARY}
7880
project_warnings project_options)
79-
# TODO(gitbuda): hpp wrappers don't work yet because of exceptions.
80-
# Exceptions are disabled in this project. Decide and adjust.
8181
target_include_directories(${PROJECT_NAME} PRIVATE ${MGCLIENT_INCLUDE_DIRS})
82-
target_compile_options(${PROJECT_NAME} PRIVATE "-fno-exceptions")
82+
target_compile_options(${PROJECT_NAME} PRIVATE "")
83+
# C++ mgclient throws, which means this project has to enable exceptions. If at
84+
# any time we decide to disable exceptions with the combination of NAPI_THROW +
85+
# std::nullopt in case of an error, the code should work as is.
86+
add_definitions(-DNAPI_CPP_EXCEPTIONS)
8387

8488
# Include N-API wrappers.
8589
execute_process(COMMAND node -p "require('node-addon-api').include"
@@ -88,10 +92,3 @@ execute_process(COMMAND node -p "require('node-addon-api').include"
8892
string(REPLACE "\n" "" NODE_ADDON_API_DIR ${NODE_ADDON_API_DIR})
8993
string(REPLACE "\"" "" NODE_ADDON_API_DIR ${NODE_ADDON_API_DIR})
9094
target_include_directories(${PROJECT_NAME} SYSTEM PRIVATE "${NODE_ADDON_API_DIR}")
91-
92-
# Added because of BigInt support.
93-
add_definitions(-DNAPI_EXPERIMENTAL)
94-
# Cpp exceptions are disabled because the addon has to work with C primitives.
95-
# Any throw increases a chance for a memory leak because there is no room for
96-
# proper cleanup.
97-
add_definitions(-DNAPI_DISABLE_CPP_EXCEPTIONS)

README.md

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,14 @@
88

99
## Installation
1010

11-
`nodemgclient` is a wrapper around the
12-
[mgclient](https://github.com/memgraph/mgclient).
11+
### Build from Source on Linux
1312

14-
### Build from Source
15-
16-
To install `nodemgclient` from sources you will need (only Linux is tested at
17-
the moment):
13+
To install `nodemgclient` from sources you will need (only Linux is tested at
14+
the moment):
1815

1916
* OpenSSL >= 1.0.2
2017
* A CMake >= 3.10
21-
* A Clang compiler supporting C11 standard
22-
* A Clang compiler supporting C++17 standard
18+
* A Clang compiler supporting C11 and C++17 standard
2319
* Node.js >= 12
2420

2521
First install the prerequisites:
@@ -30,7 +26,7 @@ First install the prerequisites:
3026
sudo apt install -y npm nodejs cmake make gcc g++ clang libssl-dev
3127
```
3228

33-
* On CentOS:
29+
* On RedHat/CentOS:
3430

3531
```bash
3632
sudo yum install -y npm nodejs cmake3 make gcc gcc-c++ clang openssl-devel
@@ -43,12 +39,40 @@ npm ci
4339
npm run build:release
4440
```
4541

46-
To run tests, [Docker](https://docs.docker.com/engine/install) is required.
42+
To test ([Docker](https://docs.docker.com/engine/install) is required) run:
4743

48-
## Windows
44+
```bash
45+
npm run test
46+
```
47+
### Build from Source on Windows
4948

5049
NOTE: Not yet possible under MinGW.
5150

5251
If installing OpenSSL package from
5352
https://slproweb.com/products/Win32OpenSSL.html, make sure to use the full one
54-
because of the header files.
53+
because of the header files.
54+
55+
## Implementation and Interface Notes
56+
57+
### Temporal Types
58+
59+
Suitable JS type to store Memgrpah temporal types don't exist. In particular,
60+
it's impossible to convert `mg_duration` and `mg_local_time` to the `Date`
61+
type. Since [the temporal
62+
specification](https://github.com/tc39/proposal-temporal) is not yet widely
63+
supported, the decision was to expose plain JS objects (dict) with the exact
64+
fields `mgclient` is providing (for more details, please take a look under
65+
`mgclient`
66+
[header](https://github.com/memgraph/mgclient/blob/master/include/mgclient.h)
67+
and [source](https://github.com/memgraph/mgclient/blob/master/src/mgclient.c)
68+
files). In addition, when possible (`mg_date` and `mg_local_date_time`), are
69+
converted into objects which have `date` property,
70+
which in fact, is the JS `Date` representation of these types. Keep in mind the
71+
loss of precision because JS `Date` time fields can only store up to
72+
milliseconds precision. However, Memgraph supports microsecond precision for
73+
the local time and therefore any use of the `date` property (JS `Date` object)
74+
can potentially cause loss of information.
75+
76+
Module exposes `create` functions, e.g. `createMgDate`, which simplify creation
77+
of temporal object interpretable by Memgraph. For more details take a look
78+
under the API docs under [index.js](./index.js) file.

cmake/CompilerWarnings.cmake

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@ function(set_project_warnings project_name)
1616
-Woverloaded-virtual # warn if you overload (not override) a virtual
1717
# function
1818
-Wpedantic # warn if non-standard C++ is used
19-
-Wconversion # warn on type conversions that may lose data
20-
-Wsign-conversion # warn on sign conversions
19+
# TODO(gitbuda): Fix mgclient cpp issue and put back the conversion warnings.
20+
# -Wconversion # warn on type conversions that may lose data
21+
# -Wsign-conversion # warn on sign conversions
2122
-Wnull-dereference # warn if a null dereference is detected
2223
-Wdouble-promotion # warn if float is implicit promoted to double
2324
-Wformat=2 # warn on security issues around functions that format output

example/async_connection.js

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// Copyright (c) 2016-2021 Memgraph Ltd. [https://memgraph.com]
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+
// TODO(gitbuda): Make tests out of this async example.
16+
17+
const memgraph = require('..');
18+
19+
(async () => {
20+
try {
21+
const client = memgraph.Client();
22+
client
23+
.Connect({ host: 'localhost' })
24+
.then(async (connection) => {
25+
console.log('Connected!');
26+
connection
27+
.Execute('MATCH (n) WHERE n.name = $name RETURN n, n.name;', {
28+
name: 'TEST',
29+
})
30+
.then(async (_) => {
31+
try {
32+
try {
33+
await connection.Execute('MATCH (n) RETURN n;');
34+
} catch (e) {
35+
console.log('The second MATCH should fail: ' + e);
36+
}
37+
let data = await connection.FetchAll();
38+
console.log(data);
39+
data = await connection.FetchOne();
40+
console.log(data);
41+
data = await connection.FetchOne();
42+
console.log(data);
43+
} catch (e) {
44+
console.log(e);
45+
}
46+
})
47+
.catch((e) => {
48+
console.log(e);
49+
});
50+
})
51+
.catch((e) => {
52+
console.log(e);
53+
});
54+
console.log('Connecting...');
55+
await new Promise((resolve) => setTimeout(resolve, 1000));
56+
57+
const txConn = await memgraph
58+
.Client()
59+
.Connect({ host: 'localhost', port: 7687 });
60+
await txConn.Begin();
61+
await txConn.Execute('CREATE (), ();');
62+
await txConn.FetchAll();
63+
await txConn.Execute('CREATE (), ();');
64+
const txConnData = await txConn.FetchAll();
65+
console.log(txConnData);
66+
await txConn.Commit();
67+
} catch (e) {
68+
console.log(e);
69+
}
70+
})();

example/count_nodes_edges.js

Lines changed: 0 additions & 47 deletions
This file was deleted.

example/create_node_edge.js

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,21 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
const memgraph = require('../lib');
15+
const memgraph = require('..');
1616
const query = require('../test/queries');
1717

18-
const connection = memgraph.Connect({ host: 'localhost', port: 7687 });
19-
2018
(async () => {
2119
try {
22-
await connection.ExecuteAndFetchRecords(query.DELETE_ALL);
23-
await connection.ExecuteAndFetchRecords(query.CREATE_RICH_NODE);
24-
await connection.ExecuteAndFetchRecords(query.CREATE_RICH_EDGE);
20+
const connection = await memgraph.Connect({
21+
host: 'localhost',
22+
port: 7687,
23+
});
24+
await connection.ExecuteAndFetchAll(query.DELETE_ALL);
25+
await connection.ExecuteAndFetchAll(query.CREATE_RICH_NODE);
26+
await connection.ExecuteAndFetchAll(query.CREATE_RICH_EDGE);
2527

26-
console.log(await connection.ExecuteAndFetchRecords(query.NODES));
27-
console.log(await connection.ExecuteAndFetchRecords(query.EDGES));
28+
console.log(await connection.ExecuteAndFetchAll(query.NODES));
29+
console.log(await connection.ExecuteAndFetchAll(query.EDGES));
2830
} catch (e) {
2931
console.log(e);
3032
}

example/create_path.js

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,18 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
const memgraph = require('../lib');
15+
const memgraph = require('..');
1616
const query = require('../test/queries');
1717

18-
const connection = memgraph.Connect({ host: 'localhost', port: 7687 });
19-
2018
(async () => {
2119
try {
22-
await connection.ExecuteAndFetchRecords(query.DELETE_ALL);
23-
await connection.ExecuteAndFetchRecords(query.CREATE_PATH);
24-
const paths = await connection.ExecuteAndFetchRecords(query.MATCH_PATHS);
20+
const connection = await memgraph.Connect({
21+
host: 'localhost',
22+
port: 7687,
23+
});
24+
await connection.ExecuteAndFetchAll(query.DELETE_ALL);
25+
await connection.ExecuteAndFetchAll(query.CREATE_PATH);
26+
const paths = await connection.ExecuteAndFetchAll(query.MATCH_PATHS);
2527
console.log(paths);
2628
} catch (e) {
2729
console.log(e);

0 commit comments

Comments
 (0)