Compare commits
20 Commits
T0818-MG-f
...
T0074-Repl
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c553112b92 | ||
|
|
41635e7306 | ||
|
|
ed4c4e6823 | ||
|
|
4abaf27765 | ||
|
|
ea2806bd57 | ||
|
|
c8dbaf5979 | ||
|
|
17049ada09 | ||
|
|
1b619f51b2 | ||
|
|
537855a0b2 | ||
|
|
5822b44b15 | ||
|
|
bf01c58ed9 | ||
|
|
89a5566f3f | ||
|
|
29452f8774 | ||
|
|
60ad05acff | ||
|
|
4f593c7fca | ||
|
|
770ea1189a | ||
|
|
695bb343f1 | ||
|
|
12b4ec1589 | ||
|
|
b33d2c3940 | ||
|
|
477acad1f6 |
@@ -16,6 +16,7 @@ tmpdir=$(mktemp -d repo-XXXXXXXX)
|
||||
trap "rm -rf $tmpdir" EXIT INT
|
||||
|
||||
modified_files=$(git diff --cached --name-only --diff-filter=AM $against | sed -nE "/.*\.(cpp|cc|cxx|c|h|hpp)$/p")
|
||||
FAIL=0
|
||||
for file in $modified_files; do
|
||||
echo "Checking $file..."
|
||||
|
||||
@@ -25,19 +26,20 @@ for file in $modified_files; do
|
||||
|
||||
echo "Running clang-format..."
|
||||
$project_folder/tools/git-clang-format $tmpdir/$file
|
||||
code=$?
|
||||
CODE=$?
|
||||
|
||||
if [ $code -ne 0 ]; then
|
||||
if [ $CODE -ne 0 ]; then
|
||||
break
|
||||
fi
|
||||
|
||||
# Do not break header checker
|
||||
echo "Running header checker..."
|
||||
$project_folder/tools/header-checker.py $tmpdir/$file $file --amend-year
|
||||
code=$?
|
||||
|
||||
if [ $code -ne 0 ]; then
|
||||
break
|
||||
CODE=$?
|
||||
if [ $CODE -ne 0 ]; then
|
||||
FAIL=1
|
||||
fi
|
||||
|
||||
done;
|
||||
|
||||
return $code
|
||||
return ${FAIL}
|
||||
|
||||
49
.github/workflows/release_docker.yaml
vendored
Normal file
49
.github/workflows/release_docker.yaml
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
name: Publish Docker images
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: "Memgraph binary version to publish on Dockerhub."
|
||||
required: true
|
||||
|
||||
jobs:
|
||||
docker_publish:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
DOCKER_ORGANIZATION_NAME: memgraph
|
||||
DOCKER_REPOSITORY_NAME: memgraph
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
id: buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
|
||||
- name: Log in to Docker Hub
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Download memgraph binary
|
||||
run: |
|
||||
cd release/docker
|
||||
curl -L https://download.memgraph.com/memgraph/v${{ github.event.inputs.version }}/debian-11/memgraph_${{ github.event.inputs.version }}-1_amd64.deb > memgraph-amd64.deb
|
||||
curl -L https://download.memgraph.com/memgraph/v${{ github.event.inputs.version }}/debian-11-aarch64/memgraph_${{ github.event.inputs.version }}-1_arm64.deb > memgraph-arm64.deb
|
||||
|
||||
- name: Build & push docker images
|
||||
run: |
|
||||
cd release/docker
|
||||
docker buildx build \
|
||||
--build-arg BINARY_NAME="memgraph-" \
|
||||
--build-arg EXTENSION="deb" \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--tag $DOCKER_ORGANIZATION_NAME/$DOCKER_REPOSITORY_NAME:${{ github.event.inputs.version }} \
|
||||
--tag $DOCKER_ORGANIZATION_NAME/$DOCKER_REPOSITORY_NAME:latest \
|
||||
--file memgraph_deb.dockerfile \
|
||||
--push .
|
||||
@@ -1 +1 @@
|
||||
* @gitbuda @antonio2368 @antaljanosbenjamin @kostasrim @jbajic
|
||||
* @antaljanosbenjamin @kostasrim
|
||||
|
||||
12
README.md
12
README.md
@@ -54,6 +54,18 @@ Memgraph is implemented in C/C++ and leverages an in-memory first architecture
|
||||
to ensure that you’re getting the best possible performance consistently and
|
||||
without surprises. It’s also ACID-compliant and highly available.
|
||||
|
||||
## :video_game: Memgraph Playground
|
||||
|
||||
You don't need to install anything to try out Memgraph. Check out
|
||||
our **[Memgraph Playground](https://playground.memgraph.com/)** sandboxes in
|
||||
your browser.
|
||||
|
||||
<p align="left">
|
||||
<a href="https://playground.memgraph.com/">
|
||||
<img width="450px" alt="Memgraph Playground" src="https://download.memgraph.com/asset/github/memgraph/memgraph-playground.png">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
## :floppy_disk: Download & Install
|
||||
|
||||
### Windows
|
||||
|
||||
@@ -106,7 +106,7 @@ install() {
|
||||
https://repo.ius.io/ius-release-el7.rpm
|
||||
yum update -y
|
||||
yum install -y wget python3 python3-pip
|
||||
yum install -y git224
|
||||
yum install -y git
|
||||
for pkg in $1; do
|
||||
if [ "$pkg" == libipt ]; then
|
||||
if ! yum list installed libipt >/dev/null 2>/dev/null; then
|
||||
|
||||
104
environment/os/debian-11-arm.sh
Executable file
104
environment/os/debian-11-arm.sh
Executable file
@@ -0,0 +1,104 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -Eeuo pipefail
|
||||
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
source "$DIR/../util.sh"
|
||||
|
||||
TOOLCHAIN_BUILD_DEPS=(
|
||||
coreutils gcc g++ build-essential make # generic build tools
|
||||
wget # used for archive download
|
||||
gnupg # used for archive signature verification
|
||||
tar gzip bzip2 xz-utils unzip # used for archive unpacking
|
||||
zlib1g-dev # zlib library used for all builds
|
||||
libexpat1-dev liblzma-dev python3-dev texinfo # for gdb
|
||||
libcurl4-openssl-dev # for cmake
|
||||
libreadline-dev # for cmake and llvm
|
||||
libffi-dev libxml2-dev # for llvm
|
||||
libedit-dev libpcre3-dev automake bison # for swig
|
||||
curl # snappy
|
||||
file # for libunwind
|
||||
libssl-dev # for libevent
|
||||
libgmp-dev
|
||||
gperf # for proxygen
|
||||
git # for fbthrift
|
||||
)
|
||||
|
||||
TOOLCHAIN_RUN_DEPS=(
|
||||
make # generic build tools
|
||||
tar gzip bzip2 xz-utils # used for archive unpacking
|
||||
zlib1g # zlib library used for all builds
|
||||
libexpat1 liblzma5 python3 # for gdb
|
||||
libcurl4 # for cmake
|
||||
file # for CPack
|
||||
libreadline8 # for cmake and llvm
|
||||
libffi7 libxml2 # for llvm
|
||||
libssl-dev # for libevent
|
||||
)
|
||||
|
||||
MEMGRAPH_BUILD_DEPS=(
|
||||
git # source code control
|
||||
make pkg-config # build system
|
||||
curl wget # for downloading libs
|
||||
uuid-dev default-jre-headless # required by antlr
|
||||
libreadline-dev # for memgraph console
|
||||
libpython3-dev python3-dev # for query modules
|
||||
libssl-dev
|
||||
libseccomp-dev
|
||||
netcat # tests are using nc to wait for memgraph
|
||||
python3 virtualenv python3-virtualenv python3-pip # for qa, macro_benchmark and stress tests
|
||||
python3-yaml # for the configuration generator
|
||||
libcurl4-openssl-dev # mg-requests
|
||||
sbcl # for custom Lisp C++ preprocessing
|
||||
doxygen graphviz # source documentation generators
|
||||
mono-runtime mono-mcs zip unzip default-jdk-headless # for driver tests
|
||||
golang nodejs npm
|
||||
autoconf # for jemalloc code generation
|
||||
libtool # for protobuf code generation
|
||||
)
|
||||
|
||||
list() {
|
||||
echo "$1"
|
||||
}
|
||||
|
||||
check() {
|
||||
check_all_dpkg "$1"
|
||||
}
|
||||
|
||||
install() {
|
||||
cat >/etc/apt/sources.list <<EOF
|
||||
deb http://deb.debian.org/debian bullseye main
|
||||
deb-src http://deb.debian.org/debian bullseye main
|
||||
|
||||
deb http://deb.debian.org/debian-security/ bullseye-security main
|
||||
deb-src http://deb.debian.org/debian-security/ bullseye-security main
|
||||
|
||||
deb http://deb.debian.org/debian bullseye-updates main
|
||||
deb-src http://deb.debian.org/debian bullseye-updates main
|
||||
EOF
|
||||
cd "$DIR"
|
||||
apt update
|
||||
# If GitHub Actions runner is installed, append LANG to the environment.
|
||||
# Python related tests doesn't work the LANG export.
|
||||
if [ -d "/home/gh/actions-runner" ]; then
|
||||
echo "LANG=en_US.utf8" >> /home/gh/actions-runner/.env
|
||||
else
|
||||
echo "NOTE: export LANG=en_US.utf8"
|
||||
fi
|
||||
apt install -y wget
|
||||
for pkg in $1; do
|
||||
if [ "$pkg" == dotnet-sdk-3.1 ]; then
|
||||
if ! dpkg -s "$pkg" 2>/dev/null >/dev/null; then
|
||||
wget -nv https://packages.microsoft.com/config/debian/10/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
|
||||
dpkg -i packages-microsoft-prod.deb
|
||||
apt-get update
|
||||
apt-get install -y apt-transport-https dotnet-sdk-3.1
|
||||
fi
|
||||
continue
|
||||
fi
|
||||
apt install -y "$pkg"
|
||||
done
|
||||
}
|
||||
|
||||
deps=$2"[*]"
|
||||
"$1" "${!deps}"
|
||||
@@ -5,6 +5,10 @@ operating_system() {
|
||||
sort | cut -d '=' -f 2- | sed 's/"//g' | paste -s -d '-'
|
||||
}
|
||||
|
||||
architecture() {
|
||||
uname -m
|
||||
}
|
||||
|
||||
check_all_yum() {
|
||||
local missing=""
|
||||
for pkg in $1; do
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -549,6 +549,8 @@ enum mgp_error mgp_path_equal(struct mgp_path *p1, struct mgp_path *p2, int *res
|
||||
struct mgp_result;
|
||||
/// Represents a record of resulting field values.
|
||||
struct mgp_result_record;
|
||||
/// Represents a return type for magic functions
|
||||
struct mgp_func_result;
|
||||
|
||||
/// Set the error as the result of the procedure.
|
||||
/// Return MGP_ERROR_UNABLE_TO_ALLOCATE ff there's no memory for copying the error message.
|
||||
@@ -1290,6 +1292,9 @@ struct mgp_module;
|
||||
/// Describes a procedure of a query module.
|
||||
struct mgp_proc;
|
||||
|
||||
/// Describes a Memgraph magic function.
|
||||
struct mgp_func;
|
||||
|
||||
/// Entry-point for a query module read procedure, invoked through openCypher.
|
||||
///
|
||||
/// Passed in arguments will not live longer than the callback's execution.
|
||||
@@ -1502,6 +1507,84 @@ typedef void (*mgp_trans_cb)(struct mgp_messages *, struct mgp_graph *, struct m
|
||||
enum mgp_error mgp_module_add_transformation(struct mgp_module *module, const char *name, mgp_trans_cb cb);
|
||||
/// @}
|
||||
|
||||
/// @name Memgraph Magic Functions API
|
||||
///
|
||||
/// API for creating the Memgraph magic functions. It is used to create external-source stateless methods which can
|
||||
/// be called by using openCypher query language. These methods should not modify the original graph and should use only
|
||||
/// the values provided as arguments to the method.
|
||||
///
|
||||
///@{
|
||||
|
||||
/// Add a required argument to a function.
|
||||
///
|
||||
/// The order of the added arguments corresponds to the signature of the openCypher function.
|
||||
/// Note, that required arguments are followed by optional arguments.
|
||||
///
|
||||
/// The `name` must be a valid identifier, following the same rules as the
|
||||
/// function `name` in mgp_module_add_function.
|
||||
///
|
||||
/// Passed in `type` describes what kind of values can be used as the argument.
|
||||
///
|
||||
/// Return MGP_ERROR_UNABLE_TO_ALLOCATE if unable to allocate memory for an argument.
|
||||
/// Return MGP_ERROR_INVALID_ARGUMENT if `name` is not a valid argument name.
|
||||
/// Return MGP_ERROR_LOGIC_ERROR if the function already has any optional argument.
|
||||
enum mgp_error mgp_func_add_arg(struct mgp_func *func, const char *name, struct mgp_type *type);
|
||||
|
||||
/// Add an optional argument with a default value to a function.
|
||||
///
|
||||
/// The order of the added arguments corresponds to the signature of the openCypher function.
|
||||
/// Note, that required arguments are followed by optional arguments.
|
||||
///
|
||||
/// The `name` must be a valid identifier, following the same rules as the
|
||||
/// function `name` in mgp_module_add_function.
|
||||
///
|
||||
/// Passed in `type` describes what kind of values can be used as the argument.
|
||||
///
|
||||
/// `default_value` is copied and set as the default value for the argument.
|
||||
/// Don't forget to call mgp_value_destroy when you are done using
|
||||
/// `default_value`. When the function is called, if this argument is not
|
||||
/// provided, `default_value` will be used instead. `default_value` must not be
|
||||
/// a graph element (node, relationship, path) and it must satisfy the given
|
||||
/// `type`.
|
||||
///
|
||||
/// Return MGP_ERROR_UNABLE_TO_ALLOCATE if unable to allocate memory for an argument.
|
||||
/// Return MGP_ERROR_INVALID_ARGUMENT if `name` is not a valid argument name.
|
||||
/// Return MGP_ERROR_VALUE_CONVERSION if `default_value` is a graph element (vertex, edge or path).
|
||||
/// Return MGP_ERROR_LOGIC_ERROR if `default_value` does not satisfy `type`.
|
||||
enum mgp_error mgp_func_add_opt_arg(struct mgp_func *func, const char *name, struct mgp_type *type,
|
||||
struct mgp_value *default_value);
|
||||
|
||||
/// Entry-point for a custom Memgraph awesome function.
|
||||
///
|
||||
/// Passed in arguments will not live longer than the callback's execution.
|
||||
/// Therefore, you must not store them globally or use the passed in mgp_memory
|
||||
/// to allocate global resources.
|
||||
typedef void (*mgp_func_cb)(struct mgp_list *, struct mgp_func_context *, struct mgp_func_result *,
|
||||
struct mgp_memory *);
|
||||
|
||||
/// Register a Memgraph magic function
|
||||
///
|
||||
/// The `name` must be a sequence of digits, underscores, lowercase and
|
||||
/// uppercase Latin letters. The name must begin with a non-digit character.
|
||||
/// Note that Unicode characters are not allowed.
|
||||
///
|
||||
/// Return MGP_ERROR_UNABLE_TO_ALLOCATE if unable to allocate memory for mgp_func.
|
||||
/// Return MGP_ERROR_INVALID_ARGUMENT if `name` is not a valid function name.
|
||||
/// RETURN MGP_ERROR_LOGIC_ERROR if a function with the same name was already registered.
|
||||
enum mgp_error mgp_module_add_function(struct mgp_module *module, const char *name, mgp_func_cb cb,
|
||||
struct mgp_func **result);
|
||||
|
||||
/// Set an error message as an output to the Magic function
|
||||
/// Return MGP_ERROR_UNABLE_TO_ALLOCATE if there's no memory for copying the error message.
|
||||
enum mgp_error mgp_func_result_set_error_msg(struct mgp_func_result *result, const char *error_msg,
|
||||
struct mgp_memory *memory);
|
||||
|
||||
/// Set an output value for the Magic function
|
||||
/// Return MGP_ERROR_UNABLE_TO_ALLOCATE if unable to allocate memory to copy the mgp_value to mgp_func_result.
|
||||
enum mgp_error mgp_func_result_set_value(struct mgp_func_result *result, struct mgp_value *value,
|
||||
struct mgp_memory *memory);
|
||||
/// @}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
247
include/mgp.py
247
include/mgp.py
@@ -40,6 +40,7 @@ class InvalidContextError(Exception):
|
||||
"""
|
||||
Signals using a graph element instance outside of the registered procedure.
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
@@ -47,6 +48,7 @@ class UnknownError(_mgp.UnknownError):
|
||||
"""
|
||||
Signals unspecified failure.
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
@@ -54,6 +56,7 @@ class UnableToAllocateError(_mgp.UnableToAllocateError):
|
||||
"""
|
||||
Signals failed memory allocation.
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
@@ -61,6 +64,7 @@ class InsufficientBufferError(_mgp.InsufficientBufferError):
|
||||
"""
|
||||
Signals that some buffer is not big enough.
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
@@ -69,6 +73,7 @@ class OutOfRangeError(_mgp.OutOfRangeError):
|
||||
Signals that an index-like parameter has a value that is outside its
|
||||
possible values.
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
@@ -77,6 +82,7 @@ class LogicErrorError(_mgp.LogicErrorError):
|
||||
Signals faulty logic within the program such as violating logical
|
||||
preconditions or class invariants and may be preventable.
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
@@ -84,6 +90,7 @@ class DeletedObjectError(_mgp.DeletedObjectError):
|
||||
"""
|
||||
Signals accessing an already deleted object.
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
@@ -91,6 +98,7 @@ class InvalidArgumentError(_mgp.InvalidArgumentError):
|
||||
"""
|
||||
Signals that some of the arguments have invalid values.
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
@@ -98,6 +106,7 @@ class KeyAlreadyExistsError(_mgp.KeyAlreadyExistsError):
|
||||
"""
|
||||
Signals that a key already exists in a container-like object.
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
@@ -105,6 +114,7 @@ class ImmutableObjectError(_mgp.ImmutableObjectError):
|
||||
"""
|
||||
Signals modification of an immutable object.
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
@@ -112,6 +122,7 @@ class ValueConversionError(_mgp.ValueConversionError):
|
||||
"""
|
||||
Signals that the conversion failed between python and cypher values.
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
@@ -120,12 +131,14 @@ class SerializationError(_mgp.SerializationError):
|
||||
Signals serialization error caused by concurrent modifications from
|
||||
different transactions.
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class Label:
|
||||
"""Label of a Vertex."""
|
||||
__slots__ = ('_name',)
|
||||
|
||||
__slots__ = ("_name",)
|
||||
|
||||
def __init__(self, name: str):
|
||||
self._name = name
|
||||
@@ -145,19 +158,22 @@ class Label:
|
||||
# Named property value of a Vertex or an Edge.
|
||||
# It would be better to use typing.NamedTuple with typed fields, but that is
|
||||
# not available in Python 3.5.
|
||||
Property = namedtuple('Property', ('name', 'value'))
|
||||
Property = namedtuple("Property", ("name", "value"))
|
||||
|
||||
|
||||
class Properties:
|
||||
"""
|
||||
A collection of properties either on a Vertex or an Edge.
|
||||
"""
|
||||
__slots__ = ('_vertex_or_edge', '_len',)
|
||||
|
||||
__slots__ = (
|
||||
"_vertex_or_edge",
|
||||
"_len",
|
||||
)
|
||||
|
||||
def __init__(self, vertex_or_edge):
|
||||
if not isinstance(vertex_or_edge, (_mgp.Vertex, _mgp.Edge)):
|
||||
raise TypeError("Expected '_mgp.Vertex' or '_mgp.Edge', \
|
||||
got {}".format(type(vertex_or_edge)))
|
||||
raise TypeError("Expected '_mgp.Vertex' or '_mgp.Edge', got {}".format(type(vertex_or_edge)))
|
||||
self._len = None
|
||||
self._vertex_or_edge = vertex_or_edge
|
||||
|
||||
@@ -330,7 +346,8 @@ class Properties:
|
||||
|
||||
class EdgeType:
|
||||
"""Type of an Edge."""
|
||||
__slots__ = ('_name',)
|
||||
|
||||
__slots__ = ("_name",)
|
||||
|
||||
def __init__(self, name):
|
||||
self._name = name
|
||||
@@ -348,7 +365,7 @@ class EdgeType:
|
||||
|
||||
|
||||
if sys.version_info >= (3, 5, 2):
|
||||
EdgeId = typing.NewType('EdgeId', int)
|
||||
EdgeId = typing.NewType("EdgeId", int)
|
||||
else:
|
||||
EdgeId = int
|
||||
|
||||
@@ -360,12 +377,12 @@ class Edge:
|
||||
a query. You should not globally store an instance of an Edge. Using an
|
||||
invalid Edge instance will raise InvalidContextError.
|
||||
"""
|
||||
__slots__ = ('_edge',)
|
||||
|
||||
__slots__ = ("_edge",)
|
||||
|
||||
def __init__(self, edge):
|
||||
if not isinstance(edge, _mgp.Edge):
|
||||
raise TypeError(
|
||||
"Expected '_mgp.Edge', got '{}'".format(type(edge)))
|
||||
raise TypeError("Expected '_mgp.Edge', got '{}'".format(type(edge)))
|
||||
self._edge = edge
|
||||
|
||||
def __deepcopy__(self, memo):
|
||||
@@ -408,7 +425,7 @@ class Edge:
|
||||
return EdgeType(self._edge.get_type_name())
|
||||
|
||||
@property
|
||||
def from_vertex(self) -> 'Vertex':
|
||||
def from_vertex(self) -> "Vertex":
|
||||
"""
|
||||
Get the source vertex.
|
||||
|
||||
@@ -419,7 +436,7 @@ class Edge:
|
||||
return Vertex(self._edge.from_vertex())
|
||||
|
||||
@property
|
||||
def to_vertex(self) -> 'Vertex':
|
||||
def to_vertex(self) -> "Vertex":
|
||||
"""
|
||||
Get the destination vertex.
|
||||
|
||||
@@ -453,7 +470,7 @@ class Edge:
|
||||
|
||||
|
||||
if sys.version_info >= (3, 5, 2):
|
||||
VertexId = typing.NewType('VertexId', int)
|
||||
VertexId = typing.NewType("VertexId", int)
|
||||
else:
|
||||
VertexId = int
|
||||
|
||||
@@ -465,12 +482,12 @@ class Vertex:
|
||||
in a query. You should not globally store an instance of a Vertex. Using an
|
||||
invalid Vertex instance will raise InvalidContextError.
|
||||
"""
|
||||
__slots__ = ('_vertex',)
|
||||
|
||||
__slots__ = ("_vertex",)
|
||||
|
||||
def __init__(self, vertex):
|
||||
if not isinstance(vertex, _mgp.Vertex):
|
||||
raise TypeError(
|
||||
"Expected '_mgp.Vertex', got '{}'".format(type(vertex)))
|
||||
raise TypeError("Expected '_mgp.Vertex', got '{}'".format(type(vertex)))
|
||||
self._vertex = vertex
|
||||
|
||||
def __deepcopy__(self, memo):
|
||||
@@ -513,8 +530,7 @@ class Vertex:
|
||||
"""
|
||||
if not self.is_valid():
|
||||
raise InvalidContextError()
|
||||
return tuple(Label(self._vertex.label_at(i))
|
||||
for i in range(self._vertex.labels_count()))
|
||||
return tuple(Label(self._vertex.label_at(i)) for i in range(self._vertex.labels_count()))
|
||||
|
||||
def add_label(self, label: str) -> None:
|
||||
"""
|
||||
@@ -615,7 +631,8 @@ class Vertex:
|
||||
|
||||
class Path:
|
||||
"""Path containing Vertex and Edge instances."""
|
||||
__slots__ = ('_path', '_vertices', '_edges')
|
||||
|
||||
__slots__ = ("_path", "_vertices", "_edges")
|
||||
|
||||
def __init__(self, starting_vertex_or_path: typing.Union[_mgp.Path, Vertex]):
|
||||
"""Initialize with a starting Vertex.
|
||||
@@ -636,8 +653,7 @@ class Path:
|
||||
raise InvalidContextError()
|
||||
self._path = _mgp.Path.make_with_start(vertex)
|
||||
else:
|
||||
raise TypeError("Expected '_mgp.Vertex' or '_mgp.Path', got '{}'"
|
||||
.format(type(starting_vertex_or_path)))
|
||||
raise TypeError("Expected '_mgp.Vertex' or '_mgp.Path', got '{}'".format(type(starting_vertex_or_path)))
|
||||
|
||||
def __copy__(self):
|
||||
if not self.is_valid():
|
||||
@@ -678,8 +694,7 @@ class Path:
|
||||
extension.
|
||||
"""
|
||||
if not isinstance(edge, Edge):
|
||||
raise TypeError(
|
||||
"Expected '_mgp.Edge', got '{}'".format(type(edge)))
|
||||
raise TypeError("Expected '_mgp.Edge', got '{}'".format(type(edge)))
|
||||
if not self.is_valid() or not edge.is_valid():
|
||||
raise InvalidContextError()
|
||||
self._path.expand(edge._edge)
|
||||
@@ -698,8 +713,7 @@ class Path:
|
||||
raise InvalidContextError()
|
||||
if self._vertices is None:
|
||||
num_vertices = self._path.size() + 1
|
||||
self._vertices = tuple(Vertex(self._path.vertex_at(i))
|
||||
for i in range(num_vertices))
|
||||
self._vertices = tuple(Vertex(self._path.vertex_at(i)) for i in range(num_vertices))
|
||||
return self._vertices
|
||||
|
||||
@property
|
||||
@@ -713,14 +727,14 @@ class Path:
|
||||
raise InvalidContextError()
|
||||
if self._edges is None:
|
||||
num_edges = self._path.size()
|
||||
self._edges = tuple(Edge(self._path.edge_at(i))
|
||||
for i in range(num_edges))
|
||||
self._edges = tuple(Edge(self._path.edge_at(i)) for i in range(num_edges))
|
||||
return self._edges
|
||||
|
||||
|
||||
class Record:
|
||||
"""Represents a record of resulting field values."""
|
||||
__slots__ = ('fields',)
|
||||
|
||||
__slots__ = ("fields",)
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
"""Initialize with name=value fields in kwargs."""
|
||||
@@ -729,12 +743,12 @@ class Record:
|
||||
|
||||
class Vertices:
|
||||
"""Iterable over vertices in a graph."""
|
||||
__slots__ = ('_graph', '_len')
|
||||
|
||||
__slots__ = ("_graph", "_len")
|
||||
|
||||
def __init__(self, graph):
|
||||
if not isinstance(graph, _mgp.Graph):
|
||||
raise TypeError(
|
||||
"Expected '_mgp.Graph', got '{}'".format(type(graph)))
|
||||
raise TypeError("Expected '_mgp.Graph', got '{}'".format(type(graph)))
|
||||
self._graph = graph
|
||||
self._len = None
|
||||
|
||||
@@ -791,12 +805,12 @@ class Vertices:
|
||||
|
||||
class Graph:
|
||||
"""State of the graph database in current ProcCtx."""
|
||||
__slots__ = ('_graph',)
|
||||
|
||||
__slots__ = ("_graph",)
|
||||
|
||||
def __init__(self, graph):
|
||||
if not isinstance(graph, _mgp.Graph):
|
||||
raise TypeError(
|
||||
"Expected '_mgp.Graph', got '{}'".format(type(graph)))
|
||||
raise TypeError("Expected '_mgp.Graph', got '{}'".format(type(graph)))
|
||||
self._graph = graph
|
||||
|
||||
def __deepcopy__(self, memo):
|
||||
@@ -885,8 +899,7 @@ class Graph:
|
||||
raise InvalidContextError()
|
||||
self._graph.detach_delete_vertex(vertex._vertex)
|
||||
|
||||
def create_edge(self, from_vertex: Vertex, to_vertex: Vertex,
|
||||
edge_type: EdgeType) -> None:
|
||||
def create_edge(self, from_vertex: Vertex, to_vertex: Vertex, edge_type: EdgeType) -> None:
|
||||
"""
|
||||
Create an edge.
|
||||
|
||||
@@ -899,8 +912,7 @@ class Graph:
|
||||
"""
|
||||
if not self.is_valid():
|
||||
raise InvalidContextError()
|
||||
return Edge(self._graph.create_edge(from_vertex._vertex,
|
||||
to_vertex._vertex, edge_type.name))
|
||||
return Edge(self._graph.create_edge(from_vertex._vertex, to_vertex._vertex, edge_type.name))
|
||||
|
||||
def delete_edge(self, edge: Edge) -> None:
|
||||
"""
|
||||
@@ -918,6 +930,7 @@ class Graph:
|
||||
|
||||
class AbortError(Exception):
|
||||
"""Signals that the procedure was asked to abort its execution."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
@@ -927,12 +940,12 @@ class ProcCtx:
|
||||
Access to a ProcCtx is only valid during a single execution of a procedure
|
||||
in a query. You should not globally store a ProcCtx instance.
|
||||
"""
|
||||
__slots__ = ('_graph',)
|
||||
|
||||
__slots__ = ("_graph",)
|
||||
|
||||
def __init__(self, graph):
|
||||
if not isinstance(graph, _mgp.Graph):
|
||||
raise TypeError(
|
||||
"Expected '_mgp.Graph', got '{}'".format(type(graph)))
|
||||
raise TypeError("Expected '_mgp.Graph', got '{}'".format(type(graph)))
|
||||
self._graph = Graph(graph)
|
||||
|
||||
def is_valid(self) -> bool:
|
||||
@@ -969,8 +982,7 @@ LocalDateTime = datetime.datetime
|
||||
|
||||
Duration = datetime.timedelta
|
||||
|
||||
Any = typing.Union[bool, str, Number, Map, Path,
|
||||
list, Date, LocalTime, LocalDateTime, Duration]
|
||||
Any = typing.Union[bool, str, Number, Map, Path, list, Date, LocalTime, LocalDateTime, Duration]
|
||||
|
||||
List = typing.List
|
||||
|
||||
@@ -1003,7 +1015,7 @@ def _typing_to_cypher_type(type_):
|
||||
Date: _mgp.type_date(),
|
||||
LocalTime: _mgp.type_local_time(),
|
||||
LocalDateTime: _mgp.type_local_date_time(),
|
||||
Duration: _mgp.type_duration()
|
||||
Duration: _mgp.type_duration(),
|
||||
}
|
||||
try:
|
||||
return simple_types[type_]
|
||||
@@ -1021,14 +1033,14 @@ def _typing_to_cypher_type(type_):
|
||||
if type(None) in type_args:
|
||||
types = tuple(t for t in type_args if t is not type(None)) # noqa E721
|
||||
if len(types) == 1:
|
||||
type_arg, = types
|
||||
(type_arg,) = types
|
||||
else:
|
||||
# We cannot do typing.Union[*types], so do the equivalent
|
||||
# with __getitem__ which does not even need arg unpacking.
|
||||
type_arg = typing.Union.__getitem__(types)
|
||||
return _mgp.type_nullable(_typing_to_cypher_type(type_arg))
|
||||
elif complex_type == list:
|
||||
type_arg, = type_args
|
||||
(type_arg,) = type_args
|
||||
return _mgp.type_list(_typing_to_cypher_type(type_arg))
|
||||
raise UnsupportedTypingError(type_)
|
||||
else:
|
||||
@@ -1038,13 +1050,17 @@ def _typing_to_cypher_type(type_):
|
||||
# printed the same way. `typing.List[type]` is printed as such, while
|
||||
# `typing.Optional[type]` is printed as 'typing.Union[type, NoneType]'
|
||||
def parse_type_args(type_as_str):
|
||||
return tuple(map(str.strip,
|
||||
type_as_str[type_as_str.index('[') + 1: -1].split(',')))
|
||||
return tuple(
|
||||
map(
|
||||
str.strip,
|
||||
type_as_str[type_as_str.index("[") + 1 : -1].split(","),
|
||||
)
|
||||
)
|
||||
|
||||
def fully_qualified_name(cls):
|
||||
if cls.__module__ is None or cls.__module__ == 'builtins':
|
||||
if cls.__module__ is None or cls.__module__ == "builtins":
|
||||
return cls.__name__
|
||||
return cls.__module__ + '.' + cls.__name__
|
||||
return cls.__module__ + "." + cls.__name__
|
||||
|
||||
def get_simple_type(type_as_str):
|
||||
for simple_type, cypher_type in simple_types.items():
|
||||
@@ -1060,28 +1076,26 @@ def _typing_to_cypher_type(type_):
|
||||
pass
|
||||
|
||||
def parse_typing(type_as_str):
|
||||
if type_as_str.startswith('typing.Union'):
|
||||
if type_as_str.startswith("typing.Union"):
|
||||
type_args_as_str = parse_type_args(type_as_str)
|
||||
none_type_as_str = type(None).__name__
|
||||
if none_type_as_str in type_args_as_str:
|
||||
types = tuple(
|
||||
t for t in type_args_as_str if t != none_type_as_str)
|
||||
types = tuple(t for t in type_args_as_str if t != none_type_as_str)
|
||||
if len(types) == 1:
|
||||
type_arg_as_str, = types
|
||||
(type_arg_as_str,) = types
|
||||
else:
|
||||
type_arg_as_str = 'typing.Union[' + \
|
||||
', '.join(types) + ']'
|
||||
type_arg_as_str = "typing.Union[" + ", ".join(types) + "]"
|
||||
simple_type = get_simple_type(type_arg_as_str)
|
||||
if simple_type is not None:
|
||||
return _mgp.type_nullable(simple_type)
|
||||
return _mgp.type_nullable(parse_typing(type_arg_as_str))
|
||||
elif type_as_str.startswith('typing.List'):
|
||||
elif type_as_str.startswith("typing.List"):
|
||||
type_arg_as_str = parse_type_args(type_as_str)
|
||||
|
||||
if len(type_arg_as_str) > 1:
|
||||
# Nested object could be a type consisting of a list of types (e.g. mgp.Map)
|
||||
# so we need to join the parts.
|
||||
type_arg_as_str = ', '.join(type_arg_as_str)
|
||||
type_arg_as_str = ", ".join(type_arg_as_str)
|
||||
else:
|
||||
type_arg_as_str = type_arg_as_str[0]
|
||||
|
||||
@@ -1096,9 +1110,11 @@ def _typing_to_cypher_type(type_):
|
||||
|
||||
# Procedure registration
|
||||
|
||||
|
||||
class Deprecated:
|
||||
"""Annotate a resulting Record's field as deprecated."""
|
||||
__slots__ = ('field_type',)
|
||||
|
||||
__slots__ = ("field_type",)
|
||||
|
||||
def __init__(self, type_):
|
||||
self.field_type = type_
|
||||
@@ -1106,8 +1122,7 @@ class Deprecated:
|
||||
|
||||
def raise_if_does_not_meet_requirements(func: typing.Callable[..., Record]):
|
||||
if not callable(func):
|
||||
raise TypeError("Expected a callable object, got an instance of '{}'"
|
||||
.format(type(func)))
|
||||
raise TypeError("Expected a callable object, got an instance of '{}'".format(type(func)))
|
||||
if inspect.iscoroutinefunction(func):
|
||||
raise TypeError("Callable must not be 'async def' function")
|
||||
if sys.version_info >= (3, 6):
|
||||
@@ -1117,24 +1132,25 @@ def raise_if_does_not_meet_requirements(func: typing.Callable[..., Record]):
|
||||
raise NotImplementedError("Generator functions are not supported")
|
||||
|
||||
|
||||
def _register_proc(func: typing.Callable[..., Record],
|
||||
is_write: bool):
|
||||
def _register_proc(func: typing.Callable[..., Record], is_write: bool):
|
||||
raise_if_does_not_meet_requirements(func)
|
||||
register_func = (
|
||||
_mgp.Module.add_write_procedure if is_write
|
||||
else _mgp.Module.add_read_procedure)
|
||||
register_func = _mgp.Module.add_write_procedure if is_write else _mgp.Module.add_read_procedure
|
||||
sig = inspect.signature(func)
|
||||
params = tuple(sig.parameters.values())
|
||||
if params and params[0].annotation is ProcCtx:
|
||||
|
||||
@wraps(func)
|
||||
def wrapper(graph, args):
|
||||
return func(ProcCtx(graph), *args)
|
||||
|
||||
params = params[1:]
|
||||
mgp_proc = register_func(_mgp._MODULE, wrapper)
|
||||
else:
|
||||
|
||||
@wraps(func)
|
||||
def wrapper(graph, args):
|
||||
return func(*args)
|
||||
|
||||
mgp_proc = register_func(_mgp._MODULE, wrapper)
|
||||
for param in params:
|
||||
name = param.name
|
||||
@@ -1149,8 +1165,7 @@ def _register_proc(func: typing.Callable[..., Record],
|
||||
if sig.return_annotation is not sig.empty:
|
||||
record = sig.return_annotation
|
||||
if not isinstance(record, Record):
|
||||
raise TypeError("Expected '{}' to return 'mgp.Record', got '{}'"
|
||||
.format(func.__name__, type(record)))
|
||||
raise TypeError("Expected '{}' to return 'mgp.Record', got '{}'".format(func.__name__, type(record)))
|
||||
for name, type_ in record.fields.items():
|
||||
if isinstance(type_, Deprecated):
|
||||
cypher_type = _typing_to_cypher_type(type_.field_type)
|
||||
@@ -1257,20 +1272,22 @@ class InvalidMessageError(Exception):
|
||||
"""
|
||||
Signals using a message instance outside of the registered transformation.
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
SOURCE_TYPE_KAFKA = _mgp.SOURCE_TYPE_KAFKA
|
||||
SOURCE_TYPE_PULSAR = _mgp.SOURCE_TYPE_PULSAR
|
||||
|
||||
|
||||
class Message:
|
||||
"""Represents a message from a stream."""
|
||||
__slots__ = ('_message',)
|
||||
|
||||
__slots__ = ("_message",)
|
||||
|
||||
def __init__(self, message):
|
||||
if not isinstance(message, _mgp.Message):
|
||||
raise TypeError(
|
||||
"Expected '_mgp.Message', got '{}'".format(type(message)))
|
||||
raise TypeError("Expected '_mgp.Message', got '{}'".format(type(message)))
|
||||
self._message = message
|
||||
|
||||
def __deepcopy__(self, memo):
|
||||
@@ -1353,17 +1370,18 @@ class Message:
|
||||
|
||||
class InvalidMessagesError(Exception):
|
||||
"""Signals using a messages instance outside of the registered transformation."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class Messages:
|
||||
"""Represents a list of messages from a stream."""
|
||||
__slots__ = ('_messages',)
|
||||
|
||||
__slots__ = ("_messages",)
|
||||
|
||||
def __init__(self, messages):
|
||||
if not isinstance(messages, _mgp.Messages):
|
||||
raise TypeError(
|
||||
"Expected '_mgp.Messages', got '{}'".format(type(messages)))
|
||||
raise TypeError("Expected '_mgp.Messages', got '{}'".format(type(messages)))
|
||||
self._messages = messages
|
||||
|
||||
def __deepcopy__(self, memo):
|
||||
@@ -1395,12 +1413,12 @@ class TransCtx:
|
||||
Access to a TransCtx is only valid during a single execution of a transformation.
|
||||
You should not globally store a TransCtx instance.
|
||||
"""
|
||||
__slots__ = ('_graph')
|
||||
|
||||
__slots__ = "_graph"
|
||||
|
||||
def __init__(self, graph):
|
||||
if not isinstance(graph, _mgp.Graph):
|
||||
raise TypeError(
|
||||
"Expected '_mgp.Graph', got '{}'".format(type(graph)))
|
||||
raise TypeError("Expected '_mgp.Graph', got '{}'".format(type(graph)))
|
||||
self._graph = Graph(graph)
|
||||
|
||||
def is_valid(self) -> bool:
|
||||
@@ -1420,21 +1438,76 @@ def transformation(func: typing.Callable[..., Record]):
|
||||
params = tuple(sig.parameters.values())
|
||||
if not params or not params[0].annotation is Messages:
|
||||
if not len(params) == 2 or not params[1].annotation is Messages:
|
||||
raise NotImplementedError(
|
||||
"Valid signatures for transformations are (TransCtx, Messages) or (Messages)")
|
||||
raise NotImplementedError("Valid signatures for transformations are (TransCtx, Messages) or (Messages)")
|
||||
if params[0].annotation is TransCtx:
|
||||
|
||||
@wraps(func)
|
||||
def wrapper(graph, messages):
|
||||
return func(TransCtx(graph), messages)
|
||||
|
||||
_mgp._MODULE.add_transformation(wrapper)
|
||||
else:
|
||||
|
||||
@wraps(func)
|
||||
def wrapper(graph, messages):
|
||||
return func(messages)
|
||||
|
||||
_mgp._MODULE.add_transformation(wrapper)
|
||||
return func
|
||||
|
||||
|
||||
class FuncCtx:
|
||||
"""Context of a function being executed.
|
||||
|
||||
Access to a FuncCtx is only valid during a single execution of a transformation.
|
||||
You should not globally store a FuncCtx instance.
|
||||
"""
|
||||
|
||||
__slots__ = "_graph"
|
||||
|
||||
def __init__(self, graph):
|
||||
if not isinstance(graph, _mgp.Graph):
|
||||
raise TypeError("Expected '_mgp.Graph', got '{}'".format(type(graph)))
|
||||
self._graph = Graph(graph)
|
||||
|
||||
def is_valid(self) -> bool:
|
||||
return self._graph.is_valid()
|
||||
|
||||
|
||||
def function(func: typing.Callable):
|
||||
raise_if_does_not_meet_requirements(func)
|
||||
register_func = _mgp.Module.add_function
|
||||
sig = inspect.signature(func)
|
||||
params = tuple(sig.parameters.values())
|
||||
if params and params[0].annotation is FuncCtx:
|
||||
|
||||
@wraps(func)
|
||||
def wrapper(graph, args):
|
||||
return func(FuncCtx(graph), *args)
|
||||
|
||||
params = params[1:]
|
||||
mgp_func = register_func(_mgp._MODULE, wrapper)
|
||||
else:
|
||||
|
||||
@wraps(func)
|
||||
def wrapper(graph, args):
|
||||
return func(*args)
|
||||
|
||||
mgp_func = register_func(_mgp._MODULE, wrapper)
|
||||
|
||||
for param in params:
|
||||
name = param.name
|
||||
type_ = param.annotation
|
||||
if type_ is param.empty:
|
||||
type_ = object
|
||||
cypher_type = _typing_to_cypher_type(type_)
|
||||
if param.default is param.empty:
|
||||
mgp_func.add_arg(name, cypher_type)
|
||||
else:
|
||||
mgp_func.add_opt_arg(name, cypher_type, param.default)
|
||||
return func
|
||||
|
||||
|
||||
def _wrap_exceptions():
|
||||
def wrap_function(func):
|
||||
@wraps(func)
|
||||
@@ -1463,6 +1536,7 @@ def _wrap_exceptions():
|
||||
raise ValueConversionError(e)
|
||||
except _mgp.SerializationError as e:
|
||||
raise SerializationError(e)
|
||||
|
||||
return wrapped_func
|
||||
|
||||
def wrap_prop_func(func):
|
||||
@@ -1473,11 +1547,16 @@ def _wrap_exceptions():
|
||||
if inspect.isfunction(obj):
|
||||
setattr(cls, name, wrap_function(obj))
|
||||
elif isinstance(obj, property):
|
||||
setattr(cls, name, property(
|
||||
wrap_prop_func(obj.fget),
|
||||
wrap_prop_func(obj.fset),
|
||||
wrap_prop_func(obj.fdel),
|
||||
obj.__doc__))
|
||||
setattr(
|
||||
cls,
|
||||
name,
|
||||
property(
|
||||
wrap_prop_func(obj.fget),
|
||||
wrap_prop_func(obj.fset),
|
||||
wrap_prop_func(obj.fdel),
|
||||
obj.__doc__,
|
||||
),
|
||||
)
|
||||
|
||||
def defined_in_this_module(obj: object):
|
||||
return getattr(obj, "__module__", "") == __name__
|
||||
|
||||
28
init
28
init
@@ -65,8 +65,14 @@ else
|
||||
fi
|
||||
|
||||
DISTRO=$(operating_system)
|
||||
echo "ALL BUILD PACKAGES: $($DIR/environment/os/$DISTRO.sh list MEMGRAPH_BUILD_DEPS)"
|
||||
$DIR/environment/os/$DISTRO.sh check MEMGRAPH_BUILD_DEPS
|
||||
ARCHITECTURE=$(architecture)
|
||||
if [ "${ARCHITECTURE}" = "arm64" ]; then
|
||||
OS_SCRIPT=$DIR/environment/os/$DISTRO-arm.sh
|
||||
else
|
||||
OS_SCRIPT=$DIR/environment/os/$DISTRO.sh
|
||||
fi
|
||||
echo "ALL BUILD PACKAGES: $($OS_SCRIPT list MEMGRAPH_BUILD_DEPS)"
|
||||
$OS_SCRIPT check MEMGRAPH_BUILD_DEPS
|
||||
echo "All packages are in-place..."
|
||||
|
||||
# create a default build directory
|
||||
@@ -105,22 +111,10 @@ if [[ "$setup_libs" == "true" ]]; then
|
||||
cd ..
|
||||
fi
|
||||
|
||||
# setup gql_behave dependencies
|
||||
setup_virtualenv tests/gql_behave
|
||||
|
||||
# setup stress dependencies
|
||||
setup_virtualenv tests/stress
|
||||
|
||||
# setup integration/ldap dependencies
|
||||
setup_virtualenv tests/integration/ldap
|
||||
|
||||
# Setup tests dependencies.
|
||||
# cd tests
|
||||
# ./setup.sh
|
||||
# cd ..
|
||||
# TODO(gitbuda): Remove setup_virtualenv, replace it with tests/ve3. Take care
|
||||
# of the build order because tests/setup.py builds pymgclient which depends on
|
||||
# mgclient which is build after this script by calling make.
|
||||
cd tests
|
||||
./setup.sh
|
||||
cd ..
|
||||
|
||||
echo "Done installing dependencies for Memgraph"
|
||||
|
||||
|
||||
@@ -122,6 +122,7 @@ declare -A primary_urls=(
|
||||
["protobuf"]="http://$local_cache_host/git/protobuf.git"
|
||||
["pulsar"]="http://$local_cache_host/git/pulsar.git"
|
||||
["librdtsc"]="http://$local_cache_host/git/librdtsc.git"
|
||||
["gqlalchemy"]="http://$local_cache_host/git/gqlalchemy.git"
|
||||
)
|
||||
|
||||
# The goal of secondary urls is to have links to the "source of truth" of
|
||||
@@ -147,6 +148,7 @@ declare -A secondary_urls=(
|
||||
["protobuf"]="https://github.com/protocolbuffers/protobuf.git"
|
||||
["pulsar"]="https://github.com/apache/pulsar.git"
|
||||
["librdtsc"]="https://github.com/gabrieleara/librdtsc.git"
|
||||
["gqlalchemy"]="http://github.com/memgraph/gqlalchemy.git"
|
||||
)
|
||||
|
||||
# antlr
|
||||
@@ -199,7 +201,7 @@ git apply ../rocksdb.patch
|
||||
popd
|
||||
|
||||
# mgclient
|
||||
mgclient_tag="96e95c6845463cbe88948392be58d26da0d5ffd3" # (2022-02-08)
|
||||
mgclient_tag="v1.3.0" # (2022-02-08)
|
||||
repo_clone_try_double "${primary_urls[mgclient]}" "${secondary_urls[mgclient]}" "mgclient" "$mgclient_tag"
|
||||
sed -i 's/\${CMAKE_INSTALL_LIBDIR}/lib/' mgclient/src/CMakeLists.txt
|
||||
|
||||
@@ -238,3 +240,10 @@ repo_clone_try_double "${primary_urls[librdtsc]}" "${secondary_urls[librdtsc]}"
|
||||
pushd librdtsc
|
||||
git apply ../librdtsc.patch
|
||||
popd
|
||||
|
||||
#gqlalchemy
|
||||
gqlalchemy_tag="v1.2.0"
|
||||
repo_clone_try_double "${primary_urls[gqlalchemy]}" "${secondary_urls[gqlalchemy]}" "gqlalchemy" "$gqlalchemy_tag" true
|
||||
pushd gqlalchemy
|
||||
git apply ../gqlalchemy.patch
|
||||
popd
|
||||
|
||||
@@ -10,6 +10,14 @@ set(CPACK_PACKAGE_VENDOR "Memgraph Ltd.")
|
||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY
|
||||
"High performance, in-memory, transactional graph database")
|
||||
|
||||
# Setting arhitecture extension for deb packages
|
||||
set(MG_ARCH_EXTENSION_DEB "all")
|
||||
if (${MG_ARCH} STREQUAL "x86_64")
|
||||
set(MG_ARCH_EXTENSION_DEB "amd64")
|
||||
elseif (${MG_ARCH} STREQUAL "ARM64")
|
||||
set(MG_ARCH_EXTENSION_DEB "arm64")
|
||||
endif()
|
||||
|
||||
# DEB specific
|
||||
# Instead of using "name <email>" format, we use "email (name)" to prevent
|
||||
# errors due to full stop, '.' at the end of "Ltd". (See: RFC 822)
|
||||
@@ -17,7 +25,7 @@ set(CPACK_DEBIAN_PACKAGE_MAINTAINER "tech@memgraph.com (Memgraph Ltd.)")
|
||||
set(CPACK_DEBIAN_PACKAGE_SECTION non-free/database)
|
||||
set(CPACK_DEBIAN_PACKAGE_HOMEPAGE https://memgraph.com)
|
||||
set(CPACK_DEBIAN_PACKAGE_VERSION "${MEMGRAPH_VERSION_DEB}")
|
||||
set(CPACK_DEBIAN_FILE_NAME "memgraph_${MEMGRAPH_VERSION_DEB}_amd64.deb")
|
||||
set(CPACK_DEBIAN_FILE_NAME "memgraph_${MEMGRAPH_VERSION_DEB}_${MG_ARCH_EXTENSION_DEB}.deb")
|
||||
set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/debian/conffiles;"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/debian/copyright;"
|
||||
@@ -35,19 +43,18 @@ set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "${CPACK_PACKAGE_DESCRIPTION_SUMMARY}
|
||||
# We also depend on `python3` because we embed it in Memgraph.
|
||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "openssl (>= 1.1.0), python3 (>= 3.5.0)")
|
||||
|
||||
# RPM specific
|
||||
|
||||
set(MG_ARCH_EXTENSION "noarch")
|
||||
|
||||
# Setting arhitecture extension for rpm packages
|
||||
set(MG_ARCH_EXTENSION_RPM "noarch")
|
||||
if (${MG_ARCH} STREQUAL "x86_64")
|
||||
set(MG_ARCH_EXTENSION "x86_64")
|
||||
set(MG_ARCH_EXTENSION_RPM "x86_64")
|
||||
elseif (${MG_ARCH} STREQUAL "ARM64")
|
||||
set(MG_ARCH_EXTENSION "aarch64")
|
||||
set(MG_ARCH_EXTENSION_RPM "aarch64")
|
||||
endif()
|
||||
|
||||
# RPM specific
|
||||
set(CPACK_RPM_PACKAGE_URL https://memgraph.com)
|
||||
set(CPACK_RPM_PACKAGE_VERSION "${MEMGRAPH_VERSION_RPM}")
|
||||
set(CPACK_RPM_FILE_NAME "memgraph-${MEMGRAPH_VERSION_RPM}-1.${MG_ARCH_EXTENSION}.rpm")
|
||||
set(CPACK_RPM_FILE_NAME "memgraph-${MEMGRAPH_VERSION_RPM}-1.${MG_ARCH_EXTENSION_RPM}.rpm")
|
||||
set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION
|
||||
/var /var/lib /var/log /etc/logrotate.d
|
||||
/lib /lib/systemd /lib/systemd/system /lib/systemd/system/memgraph.service)
|
||||
|
||||
@@ -1,19 +1,21 @@
|
||||
FROM debian:bullseye
|
||||
# NOTE: If you change the base distro update release/package as well.
|
||||
|
||||
ARG release
|
||||
ARG BINARY_NAME
|
||||
ARG EXTENSION
|
||||
ARG TARGETARCH
|
||||
|
||||
RUN apt-get update && apt-get install -y \
|
||||
openssl libcurl4 libssl1.1 libseccomp2 python3 libpython3.9 python3-pip \
|
||||
--no-install-recommends \
|
||||
openssl libcurl4 libssl1.1 libseccomp2 python3 libpython3.9 python3-pip \
|
||||
--no-install-recommends \
|
||||
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||
|
||||
RUN pip3 install networkx==2.4 numpy==1.21.4 scipy==1.7.3
|
||||
|
||||
COPY ${release} /
|
||||
COPY "${BINARY_NAME}${TARGETARCH}.${EXTENSION}" /
|
||||
|
||||
# Install memgraph package
|
||||
RUN dpkg -i ${release}
|
||||
RUN dpkg -i "${BINARY_NAME}${TARGETARCH}.deb"
|
||||
|
||||
# Memgraph listens for Bolt Protocol on this port by default.
|
||||
EXPOSE 7687
|
||||
|
||||
@@ -55,7 +55,10 @@ image_name="memgraph:${version}"
|
||||
image_package_name="memgraph-${version}-docker.tar.gz"
|
||||
|
||||
# Build docker image.
|
||||
docker build -t ${image_name} ${tag_latest} -f ${dockerfile_path} --build-arg release=${package_name}.${extension} .
|
||||
docker build -t ${image_name} ${tag_latest} -f ${dockerfile_path} \
|
||||
--build-arg BINARY_NAME=${package_name} \
|
||||
--build-arg EXTENSION=${extension} \
|
||||
--build-arg TARGETARCH="" .
|
||||
docker save ${image_name} ${latest_image} | gzip > ${image_package_name}
|
||||
rm "${package_name}.${extension}"
|
||||
echo "Built Docker image at '${working_dir}/${image_package_name}'"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Licensed as a Memgraph Enterprise file under the Memgraph Enterprise
|
||||
// License (the "License"); by using this file, you agree to be bound by the terms of the License, and you may not use
|
||||
@@ -18,7 +18,7 @@
|
||||
#include "utils/logging.hpp"
|
||||
#include "utils/string.hpp"
|
||||
|
||||
namespace audit {
|
||||
namespace memgraph::audit {
|
||||
|
||||
// Helper function that converts a `storage::PropertyValue` to `nlohmann::json`.
|
||||
inline nlohmann::json PropertyValueToJson(const storage::PropertyValue &pv) {
|
||||
@@ -143,4 +143,4 @@ void Log::Flush() {
|
||||
log_.Sync();
|
||||
}
|
||||
|
||||
} // namespace audit
|
||||
} // namespace memgraph::audit
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Licensed as a Memgraph Enterprise file under the Memgraph Enterprise
|
||||
// License (the "License"); by using this file, you agree to be bound by the terms of the License, and you may not use
|
||||
@@ -17,7 +17,7 @@
|
||||
#include "utils/file.hpp"
|
||||
#include "utils/scheduler.hpp"
|
||||
|
||||
namespace audit {
|
||||
namespace memgraph::audit {
|
||||
|
||||
const uint64_t kBufferSizeDefault = 100000;
|
||||
const uint64_t kBufferFlushIntervalMillisDefault = 200;
|
||||
@@ -71,4 +71,4 @@ class Log {
|
||||
std::mutex lock_;
|
||||
};
|
||||
|
||||
} // namespace audit
|
||||
} // namespace memgraph::audit
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Licensed as a Memgraph Enterprise file under the Memgraph Enterprise
|
||||
// License (the "License"); by using this file, you agree to be bound by the terms of the License, and you may not use
|
||||
@@ -42,8 +42,7 @@ DEFINE_VALIDATED_int32(auth_module_timeout_ms, 10000,
|
||||
"response from the auth module.",
|
||||
FLAG_IN_RANGE(100, 1800000));
|
||||
|
||||
namespace auth {
|
||||
|
||||
namespace memgraph::auth {
|
||||
const std::string kUserPrefix = "user:";
|
||||
const std::string kRolePrefix = "role:";
|
||||
const std::string kLinkPrefix = "link:";
|
||||
@@ -316,4 +315,4 @@ std::vector<auth::User> Auth::AllUsersForRole(const std::string &rolename_orig)
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace auth
|
||||
} // namespace memgraph::auth
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Licensed as a Memgraph Enterprise file under the Memgraph Enterprise
|
||||
// License (the "License"); by using this file, you agree to be bound by the terms of the License, and you may not use
|
||||
@@ -18,8 +18,7 @@
|
||||
#include "kvstore/kvstore.hpp"
|
||||
#include "utils/settings.hpp"
|
||||
|
||||
namespace auth {
|
||||
|
||||
namespace memgraph::auth {
|
||||
/**
|
||||
* This class serves as the main Authentication/Authorization storage.
|
||||
* It provides functions for managing Users, Roles and Permissions.
|
||||
@@ -163,4 +162,4 @@ class Auth final {
|
||||
kvstore::KVStore storage_;
|
||||
auth::Module module_;
|
||||
};
|
||||
} // namespace auth
|
||||
} // namespace memgraph::auth
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Licensed as a Memgraph Enterprise file under the Memgraph Enterprise
|
||||
// License (the "License"); by using this file, you agree to be bound by the terms of the License, and you may not use
|
||||
@@ -12,8 +12,7 @@
|
||||
|
||||
#include "auth/exceptions.hpp"
|
||||
|
||||
namespace auth {
|
||||
|
||||
namespace memgraph::auth {
|
||||
const std::string EncryptPassword(const std::string &password) {
|
||||
char salt[BCRYPT_HASHSIZE];
|
||||
char hash[BCRYPT_HASHSIZE];
|
||||
@@ -40,4 +39,4 @@ bool VerifyPassword(const std::string &password, const std::string &hash) {
|
||||
return ret == 0;
|
||||
}
|
||||
|
||||
} // namespace auth
|
||||
} // namespace memgraph::auth
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Licensed as a Memgraph Enterprise file under the Memgraph Enterprise
|
||||
// License (the "License"); by using this file, you agree to be bound by the terms of the License, and you may not use
|
||||
@@ -10,12 +10,11 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace auth {
|
||||
|
||||
namespace memgraph::auth {
|
||||
/// @throw AuthException if unable to encrypt the password.
|
||||
const std::string EncryptPassword(const std::string &password);
|
||||
|
||||
/// @throw AuthException if unable to verify the password.
|
||||
bool VerifyPassword(const std::string &password, const std::string &hash);
|
||||
|
||||
} // namespace auth
|
||||
} // namespace memgraph::auth
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -13,8 +13,7 @@
|
||||
|
||||
#include "utils/exceptions.hpp"
|
||||
|
||||
namespace auth {
|
||||
|
||||
namespace memgraph::auth {
|
||||
/**
|
||||
* This exception class is thrown for all exceptions that can occur when dealing
|
||||
* with the Auth library.
|
||||
@@ -23,4 +22,4 @@ class AuthException : public utils::BasicException {
|
||||
public:
|
||||
using utils::BasicException::BasicException;
|
||||
};
|
||||
} // namespace auth
|
||||
} // namespace memgraph::auth
|
||||
|
||||
@@ -22,14 +22,13 @@
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
|
||||
DEFINE_bool(auth_password_permit_null, true, "Set to false to disable null passwords.");
|
||||
|
||||
constexpr std::string_view default_password_regex = ".+";
|
||||
inline constexpr std::string_view default_password_regex = ".+";
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
|
||||
DEFINE_string(auth_password_strength_regex, default_password_regex.data(),
|
||||
"The regular expression that should be used to match the entire "
|
||||
"entered password to ensure its strength.");
|
||||
|
||||
namespace auth {
|
||||
|
||||
namespace memgraph::auth {
|
||||
namespace {
|
||||
// Constant list of all available permissions.
|
||||
const std::vector<Permission> kPermissionsAll = {
|
||||
@@ -303,4 +302,4 @@ bool operator==(const User &first, const User &second) {
|
||||
return first.username_ == second.username_ && first.password_hash_ == second.password_hash_ &&
|
||||
first.permissions_ == second.permissions_ && first.role_ == second.role_;
|
||||
}
|
||||
} // namespace auth
|
||||
} // namespace memgraph::auth
|
||||
|
||||
@@ -13,8 +13,7 @@
|
||||
|
||||
#include <json/json.hpp>
|
||||
|
||||
namespace auth {
|
||||
|
||||
namespace memgraph::auth {
|
||||
// These permissions must have values that are applicable for usage in a
|
||||
// bitmask.
|
||||
// clang-format off
|
||||
@@ -154,4 +153,4 @@ class User final {
|
||||
};
|
||||
|
||||
bool operator==(const User &first, const User &second);
|
||||
} // namespace auth
|
||||
} // namespace memgraph::auth
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Licensed as a Memgraph Enterprise file under the Memgraph Enterprise
|
||||
// License (the "License"); by using this file, you agree to be bound by the terms of the License, and you may not use
|
||||
@@ -153,7 +153,7 @@ int Target(void *arg) {
|
||||
// process and something really bad could happen.
|
||||
|
||||
// Get a pointer to the passed arguments.
|
||||
auto *ta = reinterpret_cast<auth::TargetArguments *>(arg);
|
||||
auto *ta = reinterpret_cast<memgraph::auth::TargetArguments *>(arg);
|
||||
|
||||
// Redirect `stdin` to `/dev/null`.
|
||||
int fd = open("/dev/null", O_RDONLY | O_CLOEXEC);
|
||||
@@ -312,8 +312,7 @@ nlohmann::json GetData(int fd, int timeout_millisec) {
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace auth {
|
||||
|
||||
namespace memgraph::auth {
|
||||
Module::Module(const std::filesystem::path &module_executable_path) {
|
||||
if (!module_executable_path.empty()) {
|
||||
module_executable_path_ = std::filesystem::absolute(module_executable_path);
|
||||
@@ -447,4 +446,4 @@ void Module::Shutdown() {
|
||||
|
||||
Module::~Module() { Shutdown(); }
|
||||
|
||||
} // namespace auth
|
||||
} // namespace memgraph::auth
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Licensed as a Memgraph Enterprise file under the Memgraph Enterprise
|
||||
// License (the "License"); by using this file, you agree to be bound by the terms of the License, and you may not use
|
||||
@@ -16,8 +16,7 @@
|
||||
|
||||
#include <json/json.hpp>
|
||||
|
||||
namespace auth {
|
||||
|
||||
namespace memgraph::auth {
|
||||
struct TargetArguments {
|
||||
std::filesystem::path module_executable_path;
|
||||
int pipe_to_module{-1};
|
||||
@@ -70,4 +69,4 @@ class Module final {
|
||||
int pipe_from_module_[2] = {-1, -1};
|
||||
};
|
||||
|
||||
} // namespace auth
|
||||
} // namespace memgraph::auth
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -21,7 +21,7 @@
|
||||
#include "utils/exceptions.hpp"
|
||||
#include "utils/logging.hpp"
|
||||
|
||||
namespace communication::bolt {
|
||||
namespace memgraph::communication::bolt {
|
||||
|
||||
/// This exception is thrown whenever an error occurs during query execution
|
||||
/// that isn't fatal (eg. mistyped query or some transient error occurred).
|
||||
@@ -315,4 +315,4 @@ class Client final {
|
||||
ChunkedEncoderBuffer<communication::ClientOutputStream> encoder_buffer_{output_stream_};
|
||||
ClientEncoder<ChunkedEncoderBuffer<communication::ClientOutputStream>> encoder_{encoder_buffer_};
|
||||
};
|
||||
} // namespace communication::bolt
|
||||
} // namespace memgraph::communication::bolt
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -13,10 +13,10 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace communication::bolt {
|
||||
namespace memgraph::communication::bolt {
|
||||
|
||||
static constexpr uint8_t kPreamble[4] = {0x60, 0x60, 0xB0, 0x17};
|
||||
static constexpr uint8_t kProtocol[4] = {0x00, 0x00, 0x00, 0x01};
|
||||
inline constexpr uint8_t kPreamble[4] = {0x60, 0x60, 0xB0, 0x17};
|
||||
inline constexpr uint8_t kProtocol[4] = {0x00, 0x00, 0x00, 0x01};
|
||||
|
||||
enum class Signature : uint8_t {
|
||||
Noop = 0x00,
|
||||
@@ -95,9 +95,9 @@ enum class Marker : uint8_t {
|
||||
Struct16 = 0xDD,
|
||||
};
|
||||
|
||||
static constexpr uint8_t MarkerString = 0, MarkerList = 1, MarkerMap = 2;
|
||||
static constexpr Marker MarkerTiny[3] = {Marker::TinyString, Marker::TinyList, Marker::TinyMap};
|
||||
static constexpr Marker Marker8[3] = {Marker::String8, Marker::List8, Marker::Map8};
|
||||
static constexpr Marker Marker16[3] = {Marker::String16, Marker::List16, Marker::Map16};
|
||||
static constexpr Marker Marker32[3] = {Marker::String32, Marker::List32, Marker::Map32};
|
||||
} // namespace communication::bolt
|
||||
inline constexpr uint8_t MarkerString = 0, MarkerList = 1, MarkerMap = 2;
|
||||
inline constexpr Marker MarkerTiny[3] = {Marker::TinyString, Marker::TinyList, Marker::TinyMap};
|
||||
inline constexpr Marker Marker8[3] = {Marker::String8, Marker::List8, Marker::Map8};
|
||||
inline constexpr Marker Marker16[3] = {Marker::String16, Marker::List16, Marker::Map16};
|
||||
inline constexpr Marker Marker32[3] = {Marker::String32, Marker::List32, Marker::Map32};
|
||||
} // namespace memgraph::communication::bolt
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -14,22 +14,22 @@
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
namespace communication::bolt {
|
||||
namespace memgraph::communication::bolt {
|
||||
|
||||
/**
|
||||
* Sizes related to the chunk defined in Bolt protocol.
|
||||
*/
|
||||
static constexpr size_t kChunkHeaderSize = 2;
|
||||
static constexpr size_t kChunkMaxDataSize = 65535;
|
||||
static constexpr size_t kChunkWholeSize = kChunkHeaderSize + kChunkMaxDataSize;
|
||||
inline constexpr size_t kChunkHeaderSize = 2;
|
||||
inline constexpr size_t kChunkMaxDataSize = 65535;
|
||||
inline constexpr size_t kChunkWholeSize = kChunkHeaderSize + kChunkMaxDataSize;
|
||||
|
||||
/**
|
||||
* Handshake size defined in the Bolt protocol.
|
||||
*/
|
||||
static constexpr size_t kHandshakeSize = 20;
|
||||
inline constexpr size_t kHandshakeSize = 20;
|
||||
|
||||
static constexpr uint16_t kSupportedVersions[] = {0x0100, 0x0400, 0x0401, 0x0403};
|
||||
inline constexpr uint16_t kSupportedVersions[] = {0x0100, 0x0400, 0x0401, 0x0403};
|
||||
|
||||
static constexpr int kPullAll = -1;
|
||||
static constexpr int kPullLast = -1;
|
||||
} // namespace communication::bolt
|
||||
inline constexpr int kPullAll = -1;
|
||||
inline constexpr int kPullLast = -1;
|
||||
} // namespace memgraph::communication::bolt
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
#include "communication/bolt/v1/constants.hpp"
|
||||
|
||||
namespace communication::bolt {
|
||||
namespace memgraph::communication::bolt {
|
||||
|
||||
/**
|
||||
* This class is used as the return value of the GetChunk function of the
|
||||
@@ -136,4 +136,4 @@ class ChunkedDecoderBuffer {
|
||||
std::vector<uint8_t> data_;
|
||||
size_t pos_{0};
|
||||
};
|
||||
} // namespace communication::bolt
|
||||
} // namespace memgraph::communication::bolt
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -22,7 +22,7 @@
|
||||
#include "utils/logging.hpp"
|
||||
#include "utils/temporal.hpp"
|
||||
|
||||
namespace communication::bolt {
|
||||
namespace memgraph::communication::bolt {
|
||||
|
||||
/**
|
||||
* Bolt Decoder.
|
||||
@@ -591,4 +591,4 @@ class Decoder {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
} // namespace communication::bolt
|
||||
} // namespace memgraph::communication::bolt
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -22,7 +22,7 @@ static_assert(std::is_same_v<std::uint8_t, char> || std::is_same_v<std::uint8_t,
|
||||
"communication::bolt::Encoder requires uint8_t to be "
|
||||
"implemented as char or unsigned char.");
|
||||
|
||||
namespace communication::bolt {
|
||||
namespace memgraph::communication::bolt {
|
||||
|
||||
/**
|
||||
* Bolt BaseEncoder. Has public interfaces for writing Bolt encoded data.
|
||||
@@ -273,4 +273,4 @@ class BaseEncoder {
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace communication::bolt
|
||||
} // namespace memgraph::communication::bolt
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
#include "communication/bolt/v1/constants.hpp"
|
||||
|
||||
namespace communication::bolt {
|
||||
namespace memgraph::communication::bolt {
|
||||
|
||||
/**
|
||||
* @brief ChunkedEncoderBuffer
|
||||
@@ -123,4 +123,4 @@ class ChunkedEncoderBuffer {
|
||||
// Amount of data in chunk array.
|
||||
size_t have_{0};
|
||||
};
|
||||
} // namespace communication::bolt
|
||||
} // namespace memgraph::communication::bolt
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -14,7 +14,7 @@
|
||||
#include "communication/bolt/v1/codes.hpp"
|
||||
#include "communication/bolt/v1/encoder/base_encoder.hpp"
|
||||
|
||||
namespace communication::bolt {
|
||||
namespace memgraph::communication::bolt {
|
||||
|
||||
/**
|
||||
* Bolt Client Encoder.
|
||||
@@ -169,4 +169,4 @@ class ClientEncoder : private BaseEncoder<Buffer> {
|
||||
return buffer_.Flush();
|
||||
}
|
||||
};
|
||||
} // namespace communication::bolt
|
||||
} // namespace memgraph::communication::bolt
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -14,7 +14,7 @@
|
||||
#include "communication/bolt/v1/codes.hpp"
|
||||
#include "communication/bolt/v1/encoder/base_encoder.hpp"
|
||||
|
||||
namespace communication::bolt {
|
||||
namespace memgraph::communication::bolt {
|
||||
|
||||
/**
|
||||
* Bolt Encoder.
|
||||
@@ -158,4 +158,4 @@ class Encoder : private BaseEncoder<Buffer> {
|
||||
return buffer_.Flush();
|
||||
}
|
||||
};
|
||||
} // namespace communication::bolt
|
||||
} // namespace memgraph::communication::bolt
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
#include "utils/exceptions.hpp"
|
||||
|
||||
namespace communication::bolt {
|
||||
namespace memgraph::communication::bolt {
|
||||
|
||||
/**
|
||||
* Used to indicate something is wrong with the client but the transaction is
|
||||
@@ -83,4 +83,4 @@ class VerboseError : public utils::BasicException {
|
||||
std::string code_;
|
||||
};
|
||||
|
||||
} // namespace communication::bolt
|
||||
} // namespace memgraph::communication::bolt
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -27,7 +27,7 @@
|
||||
#include "utils/exceptions.hpp"
|
||||
#include "utils/logging.hpp"
|
||||
|
||||
namespace communication::bolt {
|
||||
namespace memgraph::communication::bolt {
|
||||
|
||||
/**
|
||||
* Bolt Session Exception
|
||||
@@ -195,4 +195,4 @@ class Session {
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace communication::bolt
|
||||
} // namespace memgraph::communication::bolt
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace communication::bolt {
|
||||
namespace memgraph::communication::bolt {
|
||||
|
||||
/**
|
||||
* This class represents states in execution of the Bolt protocol.
|
||||
@@ -55,4 +55,4 @@ enum class State : uint8_t {
|
||||
*/
|
||||
Close
|
||||
};
|
||||
} // namespace communication::bolt
|
||||
} // namespace memgraph::communication::bolt
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -20,7 +20,7 @@
|
||||
#include "utils/likely.hpp"
|
||||
#include "utils/logging.hpp"
|
||||
|
||||
namespace communication::bolt {
|
||||
namespace memgraph::communication::bolt {
|
||||
|
||||
/**
|
||||
* Error state run function
|
||||
@@ -95,4 +95,4 @@ State StateErrorRun(TSession &session, State state) {
|
||||
return state;
|
||||
}
|
||||
}
|
||||
} // namespace communication::bolt
|
||||
} // namespace memgraph::communication::bolt
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -26,7 +26,7 @@
|
||||
#include "utils/logging.hpp"
|
||||
#include "utils/message.hpp"
|
||||
|
||||
namespace communication::bolt {
|
||||
namespace memgraph::communication::bolt {
|
||||
|
||||
template <typename TSession>
|
||||
State RunHandlerV1(Signature signature, TSession &session, State state, Marker marker) {
|
||||
@@ -118,4 +118,4 @@ State StateExecutingRun(TSession &session, State state) {
|
||||
return State::Close;
|
||||
}
|
||||
}
|
||||
} // namespace communication::bolt
|
||||
} // namespace memgraph::communication::bolt
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -24,7 +24,7 @@
|
||||
#include "utils/logging.hpp"
|
||||
#include "utils/message.hpp"
|
||||
|
||||
namespace communication::bolt {
|
||||
namespace memgraph::communication::bolt {
|
||||
// TODO: Revise these error messages
|
||||
inline std::pair<std::string, std::string> ExceptionToErrorMessage(const std::exception &e) {
|
||||
if (const auto *verbose = dynamic_cast<const VerboseError *>(&e)) {
|
||||
@@ -415,4 +415,4 @@ State HandleRoute(TSession &session) {
|
||||
}
|
||||
return State::Error;
|
||||
}
|
||||
} // namespace communication::bolt
|
||||
} // namespace memgraph::communication::bolt
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -22,7 +22,7 @@
|
||||
#include "utils/likely.hpp"
|
||||
#include "utils/logging.hpp"
|
||||
|
||||
namespace communication::bolt {
|
||||
namespace memgraph::communication::bolt {
|
||||
|
||||
inline bool CopyProtocolInformationIfSupported(uint16_t version, uint8_t *protocol) {
|
||||
const auto *supported_version = std::find(std::begin(kSupportedVersions), std::end(kSupportedVersions), version);
|
||||
@@ -110,4 +110,4 @@ State StateHandshakeRun(TSession &session) {
|
||||
|
||||
return State::Init;
|
||||
}
|
||||
} // namespace communication::bolt
|
||||
} // namespace memgraph::communication::bolt
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -21,7 +21,7 @@
|
||||
#include "utils/likely.hpp"
|
||||
#include "utils/logging.hpp"
|
||||
|
||||
namespace communication::bolt {
|
||||
namespace memgraph::communication::bolt {
|
||||
|
||||
namespace details {
|
||||
template <typename TSession>
|
||||
@@ -212,4 +212,4 @@ State StateInitRun(TSession &session) {
|
||||
spdlog::trace("Unsupported bolt version:{}.{})!", session.version_.major, session.version_.minor);
|
||||
return State::Close;
|
||||
}
|
||||
} // namespace communication::bolt
|
||||
} // namespace memgraph::communication::bolt
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -14,7 +14,7 @@
|
||||
#include "utils/algorithm.hpp"
|
||||
#include "utils/string.hpp"
|
||||
|
||||
namespace communication::bolt {
|
||||
namespace memgraph::communication::bolt {
|
||||
|
||||
#define DEF_GETTER_BY_VAL(type, value_type, field) \
|
||||
value_type &Value::Value##type() { \
|
||||
@@ -461,4 +461,4 @@ std::ostream &operator<<(std::ostream &os, const Value::Type type) {
|
||||
return os << "duration";
|
||||
}
|
||||
}
|
||||
} // namespace communication::bolt
|
||||
} // namespace memgraph::communication::bolt
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -20,7 +20,7 @@
|
||||
#include "utils/exceptions.hpp"
|
||||
#include "utils/temporal.hpp"
|
||||
|
||||
namespace communication::bolt {
|
||||
namespace memgraph::communication::bolt {
|
||||
|
||||
/** Forward declaration of Value class. */
|
||||
class Value;
|
||||
@@ -282,4 +282,4 @@ std::ostream &operator<<(std::ostream &os, const UnboundedEdge &edge);
|
||||
std::ostream &operator<<(std::ostream &os, const Path &path);
|
||||
std::ostream &operator<<(std::ostream &os, const Value &value);
|
||||
std::ostream &operator<<(std::ostream &os, const Value::Type type);
|
||||
} // namespace communication::bolt
|
||||
} // namespace memgraph::communication::bolt
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
#include "utils/logging.hpp"
|
||||
|
||||
namespace communication {
|
||||
namespace memgraph::communication {
|
||||
|
||||
Buffer::Buffer() : data_(kBufferInitialSize, 0), read_end_(this), write_end_(this) {}
|
||||
|
||||
@@ -77,4 +77,4 @@ void Buffer::Resize(size_t len) {
|
||||
|
||||
void Buffer::Clear() { have_ = 0; }
|
||||
|
||||
} // namespace communication
|
||||
} // namespace memgraph::communication
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
#include "io/network/stream_buffer.hpp"
|
||||
|
||||
namespace communication {
|
||||
namespace memgraph::communication {
|
||||
|
||||
/**
|
||||
* @brief Buffer
|
||||
@@ -171,4 +171,4 @@ class Buffer final {
|
||||
ReadEnd read_end_;
|
||||
WriteEnd write_end_;
|
||||
};
|
||||
} // namespace communication
|
||||
} // namespace memgraph::communication
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -14,7 +14,7 @@
|
||||
#include "communication/helpers.hpp"
|
||||
#include "utils/logging.hpp"
|
||||
|
||||
namespace communication {
|
||||
namespace memgraph::communication {
|
||||
|
||||
Client::Client(ClientContext *context) : context_(context) {}
|
||||
|
||||
@@ -239,4 +239,4 @@ bool ClientOutputStream::Write(const uint8_t *data, size_t len, bool have_more)
|
||||
}
|
||||
bool ClientOutputStream::Write(const std::string &str, bool have_more) { return client_.Write(str, have_more); }
|
||||
|
||||
} // namespace communication
|
||||
} // namespace memgraph::communication
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -21,14 +21,14 @@
|
||||
#include "io/network/endpoint.hpp"
|
||||
#include "io/network/socket.hpp"
|
||||
|
||||
namespace communication {
|
||||
namespace memgraph::communication {
|
||||
|
||||
/**
|
||||
* This class implements a generic network Client.
|
||||
* It uses blocking sockets and provides an API that can be used to receive/send
|
||||
* data over the network connection.
|
||||
*
|
||||
* NOTE: If you use this client you **must** create `communication::SSLInit`
|
||||
* NOTE: If you use this client you **must** create `memgraph::communication::SSLInit`
|
||||
* from the `main` function before using the client!
|
||||
*/
|
||||
class Client final {
|
||||
@@ -167,4 +167,4 @@ class ClientOutputStream final {
|
||||
Client &client_;
|
||||
};
|
||||
|
||||
} // namespace communication
|
||||
} // namespace memgraph::communication
|
||||
|
||||
@@ -10,10 +10,13 @@
|
||||
// licenses/APL.txt.
|
||||
|
||||
#include "communication/context.hpp"
|
||||
#include <boost/asio/ssl/context.hpp>
|
||||
#include <boost/asio/ssl/verify_mode.hpp>
|
||||
#include <boost/system/detail/error_code.hpp>
|
||||
|
||||
#include "utils/logging.hpp"
|
||||
|
||||
namespace communication {
|
||||
namespace memgraph::communication {
|
||||
|
||||
ClientContext::ClientContext(bool use_ssl) : use_ssl_(use_ssl), ctx_(nullptr) {
|
||||
if (use_ssl_) {
|
||||
@@ -74,42 +77,31 @@ SSL_CTX *ClientContext::context() { return ctx_; }
|
||||
bool ClientContext::use_ssl() { return use_ssl_; }
|
||||
|
||||
ServerContext::ServerContext(const std::string &key_file, const std::string &cert_file, const std::string &ca_file,
|
||||
bool verify_peer)
|
||||
:
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
ctx_(SSL_CTX_new(SSLv23_server_method()))
|
||||
#else
|
||||
ctx_(SSL_CTX_new(TLS_server_method()))
|
||||
#endif
|
||||
{
|
||||
// TODO (mferencevic): add support for encrypted private keys
|
||||
// TODO (mferencevic): add certificate revocation list (CRL)
|
||||
MG_ASSERT(SSL_CTX_use_certificate_file(ctx_, cert_file.c_str(), SSL_FILETYPE_PEM) == 1,
|
||||
"Couldn't load server certificate from file: {}", cert_file);
|
||||
MG_ASSERT(SSL_CTX_use_PrivateKey_file(ctx_, key_file.c_str(), SSL_FILETYPE_PEM) == 1,
|
||||
"Couldn't load server private key from file: {}", key_file);
|
||||
bool verify_peer) {
|
||||
ctx_.emplace(boost::asio::ssl::context::tls_server);
|
||||
ctx_->set_default_verify_paths();
|
||||
// TODO: add support for encrypted private keys
|
||||
// TODO: add certificate revocation list (CRL)
|
||||
boost::system::error_code ec;
|
||||
ctx_->use_certificate_chain_file(cert_file, ec);
|
||||
MG_ASSERT(!ec, "Couldn't load server certificate from file: {}", cert_file);
|
||||
ctx_->use_private_key_file(key_file, boost::asio::ssl::context::pem, ec);
|
||||
MG_ASSERT(!ec, "Couldn't load server private key from file: {}", key_file);
|
||||
|
||||
// Disable legacy SSL support. Other options can be seen here:
|
||||
// https://www.openssl.org/docs/man1.0.2/ssl/SSL_CTX_set_options.html
|
||||
SSL_CTX_set_options(ctx_, SSL_OP_NO_SSLv3);
|
||||
ctx_->set_options(SSL_OP_NO_SSLv3, ec);
|
||||
MG_ASSERT(!ec, "Setting options to SSL context failed!");
|
||||
|
||||
if (ca_file != "") {
|
||||
if (!ca_file.empty()) {
|
||||
// Load the certificate authority file.
|
||||
MG_ASSERT(SSL_CTX_load_verify_locations(ctx_, ca_file.c_str(), nullptr) == 1,
|
||||
"Couldn't load certificate authority from file: {}", ca_file);
|
||||
boost::system::error_code ec;
|
||||
ctx_->load_verify_file(ca_file, ec);
|
||||
MG_ASSERT(!ec, "Couldn't load certificate authority from file: {}", ca_file);
|
||||
|
||||
if (verify_peer) {
|
||||
// Add the CA to list of accepted CAs that is sent to the client.
|
||||
STACK_OF(X509_NAME) *ca_names = SSL_load_client_CA_file(ca_file.c_str());
|
||||
MG_ASSERT(ca_names != nullptr, "Couldn't load certificate authority from file: {}", ca_file);
|
||||
// `ca_names` doesn' need to be free'd because we pass it to
|
||||
// `SSL_CTX_set_client_CA_list`:
|
||||
// https://mta.openssl.org/pipermail/openssl-users/2015-May/001363.html
|
||||
SSL_CTX_set_client_CA_list(ctx_, ca_names);
|
||||
|
||||
// Enable verification of the client certificate.
|
||||
// NOLINTNEXTLINE(hicpp-signed-bitwise)
|
||||
SSL_CTX_set_verify(ctx_, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
|
||||
ctx_->set_verify_mode(boost::asio::ssl::verify_peer | boost::asio::ssl::verify_fail_if_no_peer_cert, ec);
|
||||
MG_ASSERT(!ec, "Setting SSL verification mode failed!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -119,36 +111,27 @@ ServerContext::ServerContext(ServerContext &&other) noexcept { std::swap(ctx_, o
|
||||
ServerContext &ServerContext::operator=(ServerContext &&other) noexcept {
|
||||
if (this == &other) return *this;
|
||||
|
||||
// destroy my objects
|
||||
if (ctx_) {
|
||||
SSL_CTX_free(ctx_);
|
||||
}
|
||||
|
||||
// move other objects to self
|
||||
ctx_ = other.ctx_;
|
||||
ctx_ = std::move(other.ctx_);
|
||||
|
||||
// reset other objects
|
||||
other.ctx_ = nullptr;
|
||||
other.ctx_.reset();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
ServerContext::~ServerContext() {
|
||||
if (ctx_) {
|
||||
SSL_CTX_free(ctx_);
|
||||
}
|
||||
}
|
||||
ServerContext::~ServerContext() {}
|
||||
|
||||
SSL_CTX *ServerContext::context() {
|
||||
MG_ASSERT(ctx_);
|
||||
return ctx_;
|
||||
return ctx_->native_handle();
|
||||
}
|
||||
SSL_CTX *ServerContext::context_clone() {
|
||||
|
||||
boost::asio::ssl::context &ServerContext::context_clone() {
|
||||
MG_ASSERT(ctx_);
|
||||
SSL_CTX_up_ref(ctx_);
|
||||
return ctx_;
|
||||
return *ctx_;
|
||||
}
|
||||
|
||||
bool ServerContext::use_ssl() const { return ctx_ != nullptr; }
|
||||
bool ServerContext::use_ssl() const { return ctx_.has_value(); }
|
||||
|
||||
} // namespace communication
|
||||
} // namespace memgraph::communication
|
||||
|
||||
@@ -11,11 +11,13 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
#include <boost/asio/ssl/context.hpp>
|
||||
|
||||
namespace communication {
|
||||
namespace memgraph::communication {
|
||||
|
||||
/**
|
||||
* This class represents a context that should be used with network clients. One
|
||||
@@ -94,12 +96,12 @@ class ServerContext final {
|
||||
~ServerContext();
|
||||
|
||||
SSL_CTX *context();
|
||||
SSL_CTX *context_clone();
|
||||
boost::asio::ssl::context &context_clone();
|
||||
|
||||
bool use_ssl() const;
|
||||
|
||||
private:
|
||||
SSL_CTX *ctx_{nullptr};
|
||||
std::optional<boost::asio::ssl::context> ctx_;
|
||||
};
|
||||
|
||||
} // namespace communication
|
||||
} // namespace memgraph::communication
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
#include "utils/exceptions.hpp"
|
||||
|
||||
namespace communication {
|
||||
namespace memgraph::communication {
|
||||
|
||||
/**
|
||||
* This exception is thrown to indicate to the communication stack that the
|
||||
@@ -22,4 +22,4 @@ namespace communication {
|
||||
class SessionClosedException : public utils::BasicException {
|
||||
using utils::BasicException::BasicException;
|
||||
};
|
||||
} // namespace communication
|
||||
} // namespace memgraph::communication
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
#include "communication/helpers.hpp"
|
||||
|
||||
namespace communication {
|
||||
namespace memgraph::communication {
|
||||
|
||||
const std::string SslGetLastError() {
|
||||
char buff[2048];
|
||||
@@ -21,4 +21,4 @@ const std::string SslGetLastError() {
|
||||
ERR_error_string_n(err, buff, sizeof(buff));
|
||||
return std::string(buff);
|
||||
}
|
||||
} // namespace communication
|
||||
} // namespace memgraph::communication
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -13,11 +13,11 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace communication {
|
||||
namespace memgraph::communication {
|
||||
|
||||
/**
|
||||
* This function reads and returns a string describing the last OpenSSL error.
|
||||
*/
|
||||
const std::string SslGetLastError();
|
||||
|
||||
} // namespace communication
|
||||
} // namespace memgraph::communication
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -20,7 +20,7 @@
|
||||
#include "utils/signals.hpp"
|
||||
#include "utils/spin_lock.hpp"
|
||||
|
||||
namespace communication {
|
||||
namespace memgraph::communication {
|
||||
|
||||
namespace {
|
||||
// OpenSSL before 1.1 did not have a out-of-the-box multithreading support
|
||||
@@ -72,4 +72,4 @@ SSLInit::SSLInit() {
|
||||
}
|
||||
|
||||
SSLInit::~SSLInit() { Cleanup(); }
|
||||
} // namespace communication
|
||||
} // namespace memgraph::communication
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace communication {
|
||||
namespace memgraph::communication {
|
||||
|
||||
/**
|
||||
* Create this object in each `main` file that uses the Communication stack. It
|
||||
@@ -36,4 +36,4 @@ struct SSLInit {
|
||||
~SSLInit();
|
||||
};
|
||||
|
||||
} // namespace communication
|
||||
} // namespace memgraph::communication
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -28,7 +28,7 @@
|
||||
#include "utils/spin_lock.hpp"
|
||||
#include "utils/thread.hpp"
|
||||
|
||||
namespace communication {
|
||||
namespace memgraph::communication {
|
||||
|
||||
/**
|
||||
* This class listens to events on an epoll object and processes them.
|
||||
@@ -273,4 +273,4 @@ class Listener final {
|
||||
const std::string service_name_;
|
||||
const size_t workers_count_;
|
||||
};
|
||||
} // namespace communication
|
||||
} // namespace memgraph::communication
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -29,7 +29,7 @@
|
||||
*/
|
||||
class ResultStreamFaker {
|
||||
public:
|
||||
explicit ResultStreamFaker(storage::Storage *store) : store_(store) {}
|
||||
explicit ResultStreamFaker(memgraph::storage::Storage *store) : store_(store) {}
|
||||
|
||||
ResultStreamFaker(const ResultStreamFaker &) = delete;
|
||||
ResultStreamFaker &operator=(const ResultStreamFaker &) = delete;
|
||||
@@ -38,25 +38,25 @@ class ResultStreamFaker {
|
||||
|
||||
void Header(const std::vector<std::string> &fields) { header_ = fields; }
|
||||
|
||||
void Result(const std::vector<communication::bolt::Value> &values) { results_.push_back(values); }
|
||||
void Result(const std::vector<memgraph::communication::bolt::Value> &values) { results_.push_back(values); }
|
||||
|
||||
void Result(const std::vector<query::TypedValue> &values) {
|
||||
std::vector<communication::bolt::Value> bvalues;
|
||||
void Result(const std::vector<memgraph::query::TypedValue> &values) {
|
||||
std::vector<memgraph::communication::bolt::Value> bvalues;
|
||||
bvalues.reserve(values.size());
|
||||
for (const auto &value : values) {
|
||||
auto maybe_value = glue::ToBoltValue(value, *store_, storage::View::NEW);
|
||||
auto maybe_value = memgraph::glue::ToBoltValue(value, *store_, memgraph::storage::View::NEW);
|
||||
MG_ASSERT(maybe_value.HasValue());
|
||||
bvalues.push_back(std::move(*maybe_value));
|
||||
}
|
||||
results_.push_back(std::move(bvalues));
|
||||
}
|
||||
|
||||
void Summary(const std::map<std::string, communication::bolt::Value> &summary) { summary_ = summary; }
|
||||
void Summary(const std::map<std::string, memgraph::communication::bolt::Value> &summary) { summary_ = summary; }
|
||||
|
||||
void Summary(const std::map<std::string, query::TypedValue> &summary) {
|
||||
std::map<std::string, communication::bolt::Value> bsummary;
|
||||
void Summary(const std::map<std::string, memgraph::query::TypedValue> &summary) {
|
||||
std::map<std::string, memgraph::communication::bolt::Value> bsummary;
|
||||
for (const auto &item : summary) {
|
||||
auto maybe_value = glue::ToBoltValue(item.second, *store_, storage::View::NEW);
|
||||
auto maybe_value = memgraph::glue::ToBoltValue(item.second, *store_, memgraph::storage::View::NEW);
|
||||
MG_ASSERT(maybe_value.HasValue());
|
||||
bsummary.insert({item.first, std::move(*maybe_value)});
|
||||
}
|
||||
@@ -119,17 +119,17 @@ class ResultStreamFaker {
|
||||
|
||||
// output the summary
|
||||
os << "Query summary: {";
|
||||
utils::PrintIterable(os, results.GetSummary(), ", ",
|
||||
[&](auto &stream, const auto &kv) { stream << kv.first << ": " << kv.second; });
|
||||
memgraph::utils::PrintIterable(os, results.GetSummary(), ", ",
|
||||
[&](auto &stream, const auto &kv) { stream << kv.first << ": " << kv.second; });
|
||||
os << "}" << std::endl;
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
private:
|
||||
storage::Storage *store_;
|
||||
memgraph::storage::Storage *store_;
|
||||
// the data that the record stream can accept
|
||||
std::vector<std::string> header_;
|
||||
std::vector<std::vector<communication::bolt::Value>> results_;
|
||||
std::map<std::string, communication::bolt::Value> summary_;
|
||||
std::vector<std::vector<memgraph::communication::bolt::Value>> results_;
|
||||
std::map<std::string, memgraph::communication::bolt::Value> summary_;
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -27,7 +27,7 @@
|
||||
#include "utils/message.hpp"
|
||||
#include "utils/thread.hpp"
|
||||
|
||||
namespace communication {
|
||||
namespace memgraph::communication {
|
||||
|
||||
/**
|
||||
* Communication server.
|
||||
@@ -37,10 +37,10 @@ namespace communication {
|
||||
* that has `num_workers` threads. It is started automatically on constructor,
|
||||
* and stopped at destructor.
|
||||
*
|
||||
* Current Server achitecture:
|
||||
* Current Server architecture:
|
||||
* incoming connection -> server -> listener -> session
|
||||
*
|
||||
* NOTE: If you use this server you **must** create `communication::SSLInit`
|
||||
* NOTE: If you use this server you **must** create communication::SSLInit`
|
||||
* from the `main` function before using the server!
|
||||
*
|
||||
* @tparam TSession the server can handle different Sessions, each session
|
||||
@@ -161,4 +161,4 @@ class Server final {
|
||||
const std::string service_name_;
|
||||
};
|
||||
|
||||
} // namespace communication
|
||||
} // namespace memgraph::communication
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -33,7 +33,7 @@
|
||||
#include "utils/on_scope_exit.hpp"
|
||||
#include "utils/spin_lock.hpp"
|
||||
|
||||
namespace communication {
|
||||
namespace memgraph::communication {
|
||||
|
||||
/**
|
||||
* This is used to provide input to user sessions. All sessions used with the
|
||||
@@ -327,4 +327,4 @@ class Session final {
|
||||
SSL *ssl_{nullptr};
|
||||
BIO *bio_{nullptr};
|
||||
}; // namespace communication
|
||||
} // namespace communication
|
||||
} // namespace memgraph::communication
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace communication::websocket {
|
||||
namespace memgraph::communication::websocket {
|
||||
|
||||
bool SafeAuth::Authenticate(const std::string &username, const std::string &password) const {
|
||||
return auth_->Lock()->Authenticate(username, password).has_value();
|
||||
@@ -27,4 +27,4 @@ bool SafeAuth::HasUserPermission(const std::string &username, const auth::Permis
|
||||
}
|
||||
|
||||
bool SafeAuth::HasAnyUsers() const { return auth_->ReadLock()->HasUsers(); }
|
||||
} // namespace communication::websocket
|
||||
} // namespace memgraph::communication::websocket
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#include "utils/spin_lock.hpp"
|
||||
#include "utils/synchronized.hpp"
|
||||
|
||||
namespace communication::websocket {
|
||||
namespace memgraph::communication::websocket {
|
||||
|
||||
class AuthenticationInterface {
|
||||
public:
|
||||
@@ -41,4 +41,4 @@ class SafeAuth : public AuthenticationInterface {
|
||||
private:
|
||||
utils::Synchronized<auth::Auth, utils::WritePrioritizedRWLock> *auth_;
|
||||
};
|
||||
} // namespace communication::websocket
|
||||
} // namespace memgraph::communication::websocket
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#include "communication/websocket/listener.hpp"
|
||||
|
||||
namespace communication::websocket {
|
||||
namespace memgraph::communication::websocket {
|
||||
namespace {
|
||||
void LogError(boost::beast::error_code ec, const std::string_view what) {
|
||||
spdlog::warn("Websocket listener failed on {}: {}", what, ec.message());
|
||||
@@ -87,4 +87,4 @@ void Listener::OnAccept(boost::beast::error_code ec, tcp::socket socket) {
|
||||
|
||||
DoAccept();
|
||||
}
|
||||
} // namespace communication::websocket
|
||||
} // namespace memgraph::communication::websocket
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#include "utils/spin_lock.hpp"
|
||||
#include "utils/synchronized.hpp"
|
||||
|
||||
namespace communication::websocket {
|
||||
namespace memgraph::communication::websocket {
|
||||
class Listener : public std::enable_shared_from_this<Listener> {
|
||||
using tcp = boost::asio::ip::tcp;
|
||||
|
||||
@@ -54,4 +54,4 @@ class Listener : public std::enable_shared_from_this<Listener> {
|
||||
utils::Synchronized<std::list<std::shared_ptr<Session>>, utils::SpinLock> sessions_;
|
||||
AuthenticationInterface &auth_;
|
||||
};
|
||||
} // namespace communication::websocket
|
||||
} // namespace memgraph::communication::websocket
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
#include <spdlog/pattern_formatter.h>
|
||||
|
||||
namespace communication::websocket {
|
||||
namespace memgraph::communication::websocket {
|
||||
|
||||
Server::~Server() {
|
||||
MG_ASSERT(!background_thread_ || (ioc_.stopped() && !background_thread_->joinable()),
|
||||
@@ -44,10 +44,10 @@ class QuoteEscapeFormatter : public spdlog::custom_flag_formatter {
|
||||
void format(const spdlog::details::log_msg &msg, const std::tm & /*time*/, spdlog::memory_buf_t &dest) override {
|
||||
for (const auto c : msg.payload) {
|
||||
if (c == '"') {
|
||||
constexpr std::string_view escaped_quote = "\\\"";
|
||||
static constexpr std::string_view escaped_quote = "\\\"";
|
||||
dest.append(escaped_quote.data(), escaped_quote.data() + escaped_quote.size());
|
||||
} else if (c == '\n') {
|
||||
constexpr std::string_view escaped_newline = "\\n";
|
||||
static constexpr std::string_view escaped_newline = "\\n";
|
||||
dest.append(escaped_newline.data(), escaped_newline.data() + escaped_newline.size());
|
||||
} else {
|
||||
dest.push_back(c);
|
||||
@@ -81,4 +81,4 @@ std::shared_ptr<Server::LoggingSink> Server::GetLoggingSink() {
|
||||
return sink;
|
||||
}
|
||||
|
||||
} // namespace communication::websocket
|
||||
} // namespace memgraph::communication::websocket
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#include "communication/websocket/listener.hpp"
|
||||
#include "io/network/endpoint.hpp"
|
||||
|
||||
namespace communication::websocket {
|
||||
namespace memgraph::communication::websocket {
|
||||
|
||||
class Server final {
|
||||
using tcp = boost::asio::ip::tcp;
|
||||
@@ -65,4 +65,4 @@ class Server final {
|
||||
std::shared_ptr<Listener> listener_;
|
||||
std::optional<std::thread> background_thread_;
|
||||
};
|
||||
} // namespace communication::websocket
|
||||
} // namespace memgraph::communication::websocket
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include "communication/websocket/auth.hpp"
|
||||
#include "utils/logging.hpp"
|
||||
|
||||
namespace communication::websocket {
|
||||
namespace memgraph::communication::websocket {
|
||||
namespace {
|
||||
void LogError(const boost::beast::error_code ec, const std::string_view what) {
|
||||
spdlog::warn("Websocket session failed on {}: {}", what, ec.message());
|
||||
@@ -232,4 +232,4 @@ void Session::DoShutdown() {
|
||||
ws_);
|
||||
}
|
||||
|
||||
} // namespace communication::websocket
|
||||
} // namespace memgraph::communication::websocket
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#include "utils/synchronized.hpp"
|
||||
#include "utils/variant_helpers.hpp"
|
||||
|
||||
namespace communication::websocket {
|
||||
namespace memgraph::communication::websocket {
|
||||
class Session : public std::enable_shared_from_this<Session> {
|
||||
using tcp = boost::asio::ip::tcp;
|
||||
|
||||
@@ -78,7 +78,7 @@ class Session : public std::enable_shared_from_this<Session> {
|
||||
|
||||
std::variant<PlainWebSocket, SSLWebSocket> CreateWebSocket(tcp::socket &&socket, ServerContext &context);
|
||||
|
||||
std::optional<boost::asio::ssl::context> ssl_context_;
|
||||
std::optional<std::reference_wrapper<boost::asio::ssl::context>> ssl_context_;
|
||||
std::variant<PlainWebSocket, SSLWebSocket> ws_;
|
||||
boost::beast::flat_buffer buffer_;
|
||||
std::deque<std::shared_ptr<std::string>> messages_;
|
||||
@@ -88,4 +88,4 @@ class Session : public std::enable_shared_from_this<Session> {
|
||||
bool close_{false};
|
||||
AuthenticationInterface &auth_;
|
||||
};
|
||||
} // namespace communication::websocket
|
||||
} // namespace memgraph::communication::websocket
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -49,7 +49,7 @@ class RingBuffer {
|
||||
void emplace(TArgs &&...args) {
|
||||
while (true) {
|
||||
{
|
||||
std::lock_guard<utils::SpinLock> guard(lock_);
|
||||
std::lock_guard<memgraph::utils::SpinLock> guard(lock_);
|
||||
if (size_ < capacity_) {
|
||||
buffer_[write_pos_++] = TElement(std::forward<TArgs>(args)...);
|
||||
write_pos_ %= capacity_;
|
||||
@@ -70,7 +70,7 @@ class RingBuffer {
|
||||
* empty, nullopt is returned.
|
||||
*/
|
||||
std::optional<TElement> pop() {
|
||||
std::lock_guard<utils::SpinLock> guard(lock_);
|
||||
std::lock_guard<memgraph::utils::SpinLock> guard(lock_);
|
||||
if (size_ == 0) return std::nullopt;
|
||||
size_--;
|
||||
std::optional<TElement> result(std::move(buffer_[read_pos_++]));
|
||||
@@ -80,7 +80,7 @@ class RingBuffer {
|
||||
|
||||
/** Removes all elements from the buffer. */
|
||||
void clear() {
|
||||
std::lock_guard<utils::SpinLock> guard(lock_);
|
||||
std::lock_guard<memgraph::utils::SpinLock> guard(lock_);
|
||||
read_pos_ = 0;
|
||||
write_pos_ = 0;
|
||||
size_ = 0;
|
||||
@@ -89,7 +89,7 @@ class RingBuffer {
|
||||
private:
|
||||
int capacity_;
|
||||
std::unique_ptr<TElement[]> buffer_;
|
||||
utils::SpinLock lock_;
|
||||
memgraph::utils::SpinLock lock_;
|
||||
int read_pos_{0};
|
||||
int write_pos_{0};
|
||||
int size_{0};
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#include "glue/auth.hpp"
|
||||
|
||||
namespace glue {
|
||||
namespace memgraph::glue {
|
||||
|
||||
auth::Permission PrivilegeToPermission(query::AuthQuery::Privilege privilege) {
|
||||
switch (privilege) {
|
||||
@@ -59,4 +59,4 @@ auth::Permission PrivilegeToPermission(query::AuthQuery::Privilege privilege) {
|
||||
return auth::Permission::WEBSOCKET;
|
||||
}
|
||||
}
|
||||
} // namespace glue
|
||||
} // namespace memgraph::glue
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -12,7 +12,7 @@
|
||||
#include "auth/models.hpp"
|
||||
#include "query/frontend/ast/ast.hpp"
|
||||
|
||||
namespace glue {
|
||||
namespace memgraph::glue {
|
||||
|
||||
/**
|
||||
* This function converts query::AuthQuery::Privilege to its corresponding
|
||||
@@ -20,4 +20,4 @@ namespace glue {
|
||||
*/
|
||||
auth::Permission PrivilegeToPermission(query::AuthQuery::Privilege privilege);
|
||||
|
||||
} // namespace glue
|
||||
} // namespace memgraph::glue
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -20,14 +20,14 @@
|
||||
#include "storage/v2/vertex_accessor.hpp"
|
||||
#include "utils/temporal.hpp"
|
||||
|
||||
using communication::bolt::Value;
|
||||
using memgraph::communication::bolt::Value;
|
||||
|
||||
namespace glue {
|
||||
namespace memgraph::glue {
|
||||
|
||||
query::TypedValue ToTypedValue(const Value &value) {
|
||||
switch (value.type()) {
|
||||
case Value::Type::Null:
|
||||
return query::TypedValue();
|
||||
return {};
|
||||
case Value::Type::Bool:
|
||||
return query::TypedValue(value.ValueBool());
|
||||
case Value::Type::Int:
|
||||
@@ -271,4 +271,4 @@ Value ToBoltValue(const storage::PropertyValue &value) {
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace glue
|
||||
} // namespace memgraph::glue
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -18,13 +18,13 @@
|
||||
#include "storage/v2/result.hpp"
|
||||
#include "storage/v2/view.hpp"
|
||||
|
||||
namespace storage {
|
||||
namespace memgraph::storage {
|
||||
class EdgeAccessor;
|
||||
class Storage;
|
||||
class VertexAccessor;
|
||||
} // namespace storage
|
||||
} // namespace memgraph::storage
|
||||
|
||||
namespace glue {
|
||||
namespace memgraph::glue {
|
||||
|
||||
/// @param storage::VertexAccessor for converting to
|
||||
/// communication::bolt::Vertex.
|
||||
@@ -65,4 +65,4 @@ communication::bolt::Value ToBoltValue(const storage::PropertyValue &value);
|
||||
|
||||
storage::PropertyValue ToPropertyValue(const communication::bolt::Value &value);
|
||||
|
||||
} // namespace glue
|
||||
} // namespace memgraph::glue
|
||||
|
||||
@@ -14,10 +14,12 @@
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
|
||||
namespace integrations {
|
||||
constexpr int64_t kDefaultCheckBatchLimit{1};
|
||||
constexpr std::chrono::milliseconds kDefaultCheckTimeout{30000};
|
||||
constexpr std::chrono::milliseconds kMinimumInterval{1};
|
||||
constexpr int64_t kMinimumSize{1};
|
||||
namespace memgraph::integrations {
|
||||
|
||||
inline constexpr int64_t kDefaultCheckBatchLimit{1};
|
||||
inline constexpr std::chrono::milliseconds kDefaultCheckTimeout{30000};
|
||||
inline constexpr std::chrono::milliseconds kMinimumInterval{1};
|
||||
inline constexpr int64_t kMinimumSize{1};
|
||||
const std::string kReducted{"<REDUCTED>"};
|
||||
} // namespace integrations
|
||||
|
||||
} // namespace memgraph::integrations
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#include "utils/on_scope_exit.hpp"
|
||||
#include "utils/thread.hpp"
|
||||
|
||||
namespace integrations::kafka {
|
||||
namespace memgraph::integrations::kafka {
|
||||
|
||||
namespace {
|
||||
utils::BasicResult<std::string, std::vector<Message>> GetBatch(RdKafka::KafkaConsumer &consumer,
|
||||
@@ -185,8 +185,10 @@ Consumer::Consumer(ConsumerInfo info, ConsumerFunction consumer_function)
|
||||
std::inserter(topic_names_from_metadata, topic_names_from_metadata.begin()),
|
||||
[](const auto topic_metadata) { return topic_metadata->topic(); });
|
||||
|
||||
constexpr size_t max_topic_name_length = 249;
|
||||
constexpr auto is_valid_topic_name = [](const auto c) { return std::isalnum(c) || c == '.' || c == '_' || c == '-'; };
|
||||
static constexpr size_t max_topic_name_length = 249;
|
||||
static constexpr auto is_valid_topic_name = [](const auto c) {
|
||||
return std::isalnum(c) || c == '.' || c == '_' || c == '-';
|
||||
};
|
||||
|
||||
for (const auto &topic_name : info_.topics) {
|
||||
if (topic_name.size() > max_topic_name_length ||
|
||||
@@ -351,7 +353,7 @@ void Consumer::StartConsuming() {
|
||||
}
|
||||
|
||||
thread_ = std::thread([this] {
|
||||
constexpr auto kMaxThreadNameSize = utils::GetMaxThreadNameSize();
|
||||
static constexpr auto kMaxThreadNameSize = utils::GetMaxThreadNameSize();
|
||||
const auto full_thread_name = "Cons#" + info_.consumer_name;
|
||||
|
||||
utils::ThreadSetName(full_thread_name.substr(0, kMaxThreadNameSize));
|
||||
@@ -448,4 +450,4 @@ void Consumer::ConsumerRebalanceCb::rebalance_cb(RdKafka::KafkaConsumer *consume
|
||||
}
|
||||
}
|
||||
void Consumer::ConsumerRebalanceCb::set_offset(int64_t offset) { offset_ = offset; }
|
||||
} // namespace integrations::kafka
|
||||
} // namespace memgraph::integrations::kafka
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include <librdkafka/rdkafkacpp.h>
|
||||
#include "utils/result.hpp"
|
||||
|
||||
namespace integrations::kafka {
|
||||
namespace memgraph::integrations::kafka {
|
||||
|
||||
/// Wraps the message returned from librdkafka.
|
||||
///
|
||||
@@ -183,4 +183,4 @@ class Consumer final : public RdKafka::EventCb {
|
||||
std::thread thread_;
|
||||
ConsumerRebalanceCb cb_;
|
||||
};
|
||||
} // namespace integrations::kafka
|
||||
} // namespace memgraph::integrations::kafka
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
#include "utils/exceptions.hpp"
|
||||
|
||||
namespace integrations::kafka {
|
||||
namespace memgraph::integrations::kafka {
|
||||
class KafkaStreamException : public utils::BasicException {
|
||||
using utils::BasicException::BasicException;
|
||||
};
|
||||
@@ -64,4 +64,4 @@ class TopicNotFoundException : public KafkaStreamException {
|
||||
TopicNotFoundException(const std::string_view consumer_name, const std::string_view topic_name)
|
||||
: KafkaStreamException("Kafka consumer {} cannot find topic {}", consumer_name, topic_name) {}
|
||||
};
|
||||
} // namespace integrations::kafka
|
||||
} // namespace memgraph::integrations::kafka
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -26,7 +26,7 @@
|
||||
#include "utils/result.hpp"
|
||||
#include "utils/thread.hpp"
|
||||
|
||||
namespace integrations::pulsar {
|
||||
namespace memgraph::integrations::pulsar {
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -231,7 +231,7 @@ void Consumer::StartConsuming() {
|
||||
is_running_.store(true);
|
||||
|
||||
thread_ = std::thread([this] {
|
||||
constexpr auto kMaxThreadNameSize = utils::GetMaxThreadNameSize();
|
||||
static constexpr auto kMaxThreadNameSize = utils::GetMaxThreadNameSize();
|
||||
const auto full_thread_name = "Cons#" + info_.consumer_name;
|
||||
|
||||
utils::ThreadSetName(full_thread_name.substr(0, kMaxThreadNameSize));
|
||||
@@ -284,4 +284,4 @@ void Consumer::StopConsuming() {
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace integrations::pulsar
|
||||
} // namespace memgraph::integrations::pulsar
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
#include <pulsar/Client.h>
|
||||
|
||||
namespace integrations::pulsar {
|
||||
namespace memgraph::integrations::pulsar {
|
||||
|
||||
namespace pulsar_client = ::pulsar;
|
||||
|
||||
@@ -79,4 +79,4 @@ class Consumer final {
|
||||
pulsar_client::MessageId last_message_id_{pulsar_client::MessageId::earliest()};
|
||||
std::thread thread_;
|
||||
};
|
||||
} // namespace integrations::pulsar
|
||||
} // namespace memgraph::integrations::pulsar
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
#include "utils/exceptions.hpp"
|
||||
|
||||
namespace integrations::pulsar {
|
||||
namespace memgraph::integrations::pulsar {
|
||||
class PulsarStreamException : public utils::BasicException {
|
||||
using utils::BasicException::BasicException;
|
||||
};
|
||||
@@ -55,4 +55,4 @@ class TopicNotFoundException : public PulsarStreamException {
|
||||
TopicNotFoundException(const std::string &consumer_name, const std::string &topic_name)
|
||||
: PulsarStreamException("Pulsar consumer {} cannot find topic {}", consumer_name, topic_name) {}
|
||||
};
|
||||
} // namespace integrations::pulsar
|
||||
} // namespace memgraph::integrations::pulsar
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -9,34 +9,52 @@
|
||||
// by the Apache License, Version 2.0, included in the file
|
||||
// licenses/APL.txt.
|
||||
|
||||
#include <netdb.h>
|
||||
#include <cstring>
|
||||
|
||||
#include "io/network/addrinfo.hpp"
|
||||
|
||||
#include <concepts>
|
||||
#include <iterator>
|
||||
|
||||
#include "io/network/network_error.hpp"
|
||||
|
||||
namespace io::network {
|
||||
namespace memgraph::io::network {
|
||||
|
||||
AddrInfo::AddrInfo(struct addrinfo *info) : info(info) {}
|
||||
static_assert(std::forward_iterator<AddrInfo::Iterator> && std::equality_comparable<AddrInfo::Iterator>);
|
||||
|
||||
AddrInfo::~AddrInfo() { freeaddrinfo(info); }
|
||||
|
||||
AddrInfo AddrInfo::Get(const char *addr, const char *port) {
|
||||
struct addrinfo hints;
|
||||
memset(&hints, 0, sizeof(struct addrinfo));
|
||||
|
||||
hints.ai_family = AF_UNSPEC; // IPv4 and IPv6
|
||||
hints.ai_socktype = SOCK_STREAM; // TCP socket
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
|
||||
struct addrinfo *result;
|
||||
auto status = getaddrinfo(addr, port, &hints, &result);
|
||||
AddrInfo::AddrInfo(const Endpoint &endpoint) : AddrInfo(endpoint.address, endpoint.port) {}
|
||||
|
||||
AddrInfo::AddrInfo(const std::string &addr, uint16_t port) : info_{nullptr, nullptr} {
|
||||
addrinfo hints{
|
||||
.ai_flags = AI_PASSIVE,
|
||||
.ai_family = AF_UNSPEC, // IPv4 and IPv6
|
||||
.ai_socktype = SOCK_STREAM // TCP socket
|
||||
};
|
||||
addrinfo *info = nullptr;
|
||||
auto status = getaddrinfo(addr.c_str(), std::to_string(port).c_str(), &hints, &info);
|
||||
if (status != 0) throw NetworkError(gai_strerror(status));
|
||||
|
||||
return AddrInfo(result);
|
||||
info_ = std::unique_ptr<addrinfo, decltype(&freeaddrinfo)>(info, &freeaddrinfo);
|
||||
}
|
||||
|
||||
AddrInfo::operator struct addrinfo *() { return info; }
|
||||
} // namespace io::network
|
||||
AddrInfo::Iterator::Iterator(addrinfo *p) noexcept : ptr_(p) {}
|
||||
|
||||
AddrInfo::Iterator::reference AddrInfo::Iterator::operator*() const noexcept { return *ptr_; }
|
||||
|
||||
AddrInfo::Iterator::pointer AddrInfo::Iterator::operator->() const noexcept { return ptr_; }
|
||||
|
||||
// NOLINTNEXTLINE(cert-dcl21-cpp)
|
||||
AddrInfo::Iterator AddrInfo::Iterator::operator++(int) noexcept {
|
||||
auto it = *this;
|
||||
++(*this);
|
||||
return it;
|
||||
}
|
||||
AddrInfo::Iterator &AddrInfo::Iterator::operator++() noexcept {
|
||||
ptr_ = ptr_->ai_next;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const AddrInfo::Iterator &lhs, const AddrInfo::Iterator &rhs) noexcept { return lhs.ptr_ == rhs.ptr_; };
|
||||
|
||||
bool operator!=(const AddrInfo::Iterator &lhs, const AddrInfo::Iterator &rhs) noexcept { return !(lhs == rhs); };
|
||||
|
||||
void swap(AddrInfo::Iterator &lhs, AddrInfo::Iterator &rhs) noexcept { std::swap(lhs.ptr_, rhs.ptr_); };
|
||||
|
||||
} // namespace memgraph::io::network
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -11,23 +11,53 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace io::network {
|
||||
#include <netdb.h>
|
||||
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "io/network/endpoint.hpp"
|
||||
|
||||
namespace memgraph::io::network {
|
||||
|
||||
/**
|
||||
* Wrapper class for getaddrinfo.
|
||||
* see: man 3 getaddrinfo
|
||||
*/
|
||||
class AddrInfo {
|
||||
explicit AddrInfo(struct addrinfo *info);
|
||||
|
||||
public:
|
||||
~AddrInfo();
|
||||
struct Iterator {
|
||||
using iterator_category = std::forward_iterator_tag;
|
||||
using value_type = addrinfo;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using pointer = addrinfo *;
|
||||
using reference = addrinfo &;
|
||||
|
||||
static AddrInfo Get(const char *addr, const char *port);
|
||||
Iterator() = default;
|
||||
Iterator(const Iterator &) = default;
|
||||
explicit Iterator(addrinfo *p) noexcept;
|
||||
Iterator &operator=(const Iterator &) = default;
|
||||
reference operator*() const noexcept;
|
||||
pointer operator->() const noexcept;
|
||||
Iterator operator++(int) noexcept;
|
||||
Iterator &operator++() noexcept;
|
||||
|
||||
operator struct addrinfo *();
|
||||
friend bool operator==(const Iterator &lhs, const Iterator &rhs) noexcept;
|
||||
friend bool operator!=(const Iterator &lhs, const Iterator &rhs) noexcept;
|
||||
friend void swap(Iterator &lhs, Iterator &rhs) noexcept;
|
||||
|
||||
private:
|
||||
addrinfo *ptr_{nullptr};
|
||||
};
|
||||
|
||||
AddrInfo(const std::string &addr, uint16_t port);
|
||||
explicit AddrInfo(const Endpoint &endpoint);
|
||||
|
||||
auto begin() const noexcept { return Iterator(info_.get()); }
|
||||
auto end() const noexcept { return Iterator{nullptr}; }
|
||||
|
||||
private:
|
||||
struct addrinfo *info;
|
||||
std::unique_ptr<addrinfo, void (*)(addrinfo *)> info_;
|
||||
};
|
||||
} // namespace io::network
|
||||
} // namespace memgraph::io::network
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -21,7 +21,7 @@
|
||||
#include "utils/message.hpp"
|
||||
#include "utils/string.hpp"
|
||||
|
||||
namespace io::network {
|
||||
namespace memgraph::io::network {
|
||||
|
||||
Endpoint::IpFamily Endpoint::GetIpFamily(const std::string &ip_address) {
|
||||
in_addr addr4;
|
||||
@@ -110,4 +110,4 @@ std::ostream &operator<<(std::ostream &os, const Endpoint &endpoint) {
|
||||
return os << endpoint.address << ":" << endpoint.port;
|
||||
}
|
||||
|
||||
} // namespace io::network
|
||||
} // namespace memgraph::io::network
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -17,7 +17,7 @@
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
namespace io::network {
|
||||
namespace memgraph::io::network {
|
||||
|
||||
/**
|
||||
* This class represents a network endpoint that is used in Socket.
|
||||
@@ -55,4 +55,4 @@ struct Endpoint {
|
||||
static IpFamily GetIpFamily(const std::string &ip_address);
|
||||
};
|
||||
|
||||
} // namespace io::network
|
||||
} // namespace memgraph::io::network
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -21,7 +21,7 @@
|
||||
#include "utils/likely.hpp"
|
||||
#include "utils/logging.hpp"
|
||||
|
||||
namespace io::network {
|
||||
namespace memgraph::io::network {
|
||||
|
||||
/**
|
||||
* Wrapper class for epoll.
|
||||
@@ -104,4 +104,4 @@ class Epoll {
|
||||
private:
|
||||
const int epoll_fd_;
|
||||
};
|
||||
} // namespace io::network
|
||||
} // namespace memgraph::io::network
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -13,10 +13,10 @@
|
||||
|
||||
#include "utils/exceptions.hpp"
|
||||
|
||||
namespace io::network {
|
||||
namespace memgraph::io::network {
|
||||
|
||||
class NetworkError : public utils::StacktraceException {
|
||||
public:
|
||||
using utils::StacktraceException::StacktraceException;
|
||||
};
|
||||
} // namespace io::network
|
||||
} // namespace memgraph::io::network
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -14,18 +14,18 @@
|
||||
#include "io/network/endpoint.hpp"
|
||||
#include "slk/serialization.hpp"
|
||||
|
||||
namespace slk {
|
||||
namespace memgraph::slk {
|
||||
|
||||
inline void Save(const io::network::Endpoint &endpoint, slk::Builder *builder) {
|
||||
slk::Save(endpoint.address_, builder);
|
||||
slk::Save(endpoint.port_, builder);
|
||||
slk::Save(endpoint.family_, builder);
|
||||
inline void Save(const io::network::Endpoint &endpoint, Builder *builder) {
|
||||
Save(endpoint.address_, builder);
|
||||
Save(endpoint.port_, builder);
|
||||
Save(endpoint.family_, builder);
|
||||
}
|
||||
|
||||
inline void Load(io::network::Endpoint *endpoint, slk::Reader *reader) {
|
||||
slk::Load(&endpoint->address_, reader);
|
||||
slk::Load(&endpoint->port_, reader);
|
||||
slk::Load(&endpoint->family_, reader);
|
||||
inline void Load(io::network::Endpoint *endpoint, Reader *reader) {
|
||||
Load(&endpoint->address_, reader);
|
||||
Load(&endpoint->port_, reader);
|
||||
Load(&endpoint->family_, reader);
|
||||
}
|
||||
|
||||
} // namespace slk
|
||||
} // namespace memgraph::slk
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -9,39 +9,25 @@
|
||||
// by the Apache License, Version 2.0, included in the file
|
||||
// licenses/APL.txt.
|
||||
|
||||
#include "io/network/socket.hpp"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <poll.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "io/network/addrinfo.hpp"
|
||||
#include "io/network/socket.hpp"
|
||||
#include "utils/likely.hpp"
|
||||
#include "utils/logging.hpp"
|
||||
|
||||
namespace io::network {
|
||||
namespace memgraph::io::network {
|
||||
|
||||
Socket::Socket(Socket &&other) {
|
||||
socket_ = other.socket_;
|
||||
endpoint_ = std::move(other.endpoint_);
|
||||
Socket::Socket(Socket &&other) noexcept : socket_(other.socket_), endpoint_(std::move(other.endpoint_)) {
|
||||
other.socket_ = -1;
|
||||
}
|
||||
|
||||
Socket &Socket::operator=(Socket &&other) {
|
||||
Socket &Socket::operator=(Socket &&other) noexcept {
|
||||
if (this != &other) {
|
||||
if (socket_ != -1) close(socket_);
|
||||
socket_ = other.socket_;
|
||||
endpoint_ = std::move(other.endpoint_);
|
||||
other.socket_ = -1;
|
||||
@@ -49,9 +35,8 @@ Socket &Socket::operator=(Socket &&other) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
Socket::~Socket() {
|
||||
if (socket_ == -1) return;
|
||||
close(socket_);
|
||||
Socket::~Socket() noexcept {
|
||||
if (socket_ != -1) close(socket_);
|
||||
}
|
||||
|
||||
void Socket::Close() {
|
||||
@@ -70,33 +55,27 @@ bool Socket::IsOpen() const { return socket_ != -1; }
|
||||
bool Socket::Connect(const Endpoint &endpoint) {
|
||||
if (socket_ != -1) return false;
|
||||
|
||||
auto info = AddrInfo::Get(endpoint.address.c_str(), std::to_string(endpoint.port).c_str());
|
||||
|
||||
for (struct addrinfo *it = info; it != nullptr; it = it->ai_next) {
|
||||
int sfd = socket(it->ai_family, it->ai_socktype, it->ai_protocol);
|
||||
for (const auto &it : AddrInfo{endpoint}) {
|
||||
int sfd = socket(it.ai_family, it.ai_socktype, it.ai_protocol);
|
||||
if (sfd == -1) continue;
|
||||
if (connect(sfd, it->ai_addr, it->ai_addrlen) == 0) {
|
||||
if (connect(sfd, it.ai_addr, it.ai_addrlen) == 0) {
|
||||
socket_ = sfd;
|
||||
endpoint_ = endpoint;
|
||||
break;
|
||||
} else {
|
||||
// If the connect failed close the file descriptor to prevent file
|
||||
// descriptors being leaked
|
||||
close(sfd);
|
||||
}
|
||||
// If the connect failed close the file descriptor to prevent file
|
||||
// descriptors being leaked
|
||||
close(sfd);
|
||||
}
|
||||
|
||||
if (socket_ == -1) return false;
|
||||
return true;
|
||||
return !(socket_ == -1);
|
||||
}
|
||||
|
||||
bool Socket::Bind(const Endpoint &endpoint) {
|
||||
if (socket_ != -1) return false;
|
||||
|
||||
auto info = AddrInfo::Get(endpoint.address.c_str(), std::to_string(endpoint.port).c_str());
|
||||
|
||||
for (struct addrinfo *it = info; it != nullptr; it = it->ai_next) {
|
||||
int sfd = socket(it->ai_family, it->ai_socktype, it->ai_protocol);
|
||||
for (const auto &it : AddrInfo{endpoint}) {
|
||||
int sfd = socket(it.ai_family, it.ai_socktype, it.ai_protocol);
|
||||
if (sfd == -1) continue;
|
||||
|
||||
int on = 1;
|
||||
@@ -107,14 +86,13 @@ bool Socket::Bind(const Endpoint &endpoint) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bind(sfd, it->ai_addr, it->ai_addrlen) == 0) {
|
||||
if (bind(sfd, it.ai_addr, it.ai_addrlen) == 0) {
|
||||
socket_ = sfd;
|
||||
break;
|
||||
} else {
|
||||
// If the bind failed close the file descriptor to prevent file
|
||||
// descriptors being leaked
|
||||
close(sfd);
|
||||
}
|
||||
// If the bind failed close the file descriptor to prevent file
|
||||
// descriptors being leaked
|
||||
close(sfd);
|
||||
}
|
||||
|
||||
if (socket_ == -1) return false;
|
||||
@@ -122,7 +100,7 @@ bool Socket::Bind(const Endpoint &endpoint) {
|
||||
// detect bound port, used when the server binds to a random port
|
||||
struct sockaddr_in6 portdata;
|
||||
socklen_t portdatalen = sizeof(portdata);
|
||||
if (getsockname(socket_, (struct sockaddr *)&portdata, &portdatalen) < 0) {
|
||||
if (getsockname(socket_, reinterpret_cast<sockaddr *>(&portdata), &portdatalen) < 0) {
|
||||
// If the getsockname failed close the file descriptor to prevent file
|
||||
// descriptors being leaked
|
||||
close(socket_);
|
||||
@@ -136,36 +114,35 @@ bool Socket::Bind(const Endpoint &endpoint) {
|
||||
}
|
||||
|
||||
void Socket::SetNonBlocking() {
|
||||
int flags = fcntl(socket_, F_GETFL, 0);
|
||||
const unsigned flags = fcntl(socket_, F_GETFL);
|
||||
constexpr unsigned o_nonblock = O_NONBLOCK;
|
||||
MG_ASSERT(flags != -1, "Can't get socket mode");
|
||||
flags |= O_NONBLOCK;
|
||||
MG_ASSERT(fcntl(socket_, F_SETFL, flags) != -1, "Can't set socket nonblocking");
|
||||
MG_ASSERT(fcntl(socket_, F_SETFL, flags | o_nonblock) != -1, "Can't set socket nonblocking");
|
||||
}
|
||||
|
||||
void Socket::SetKeepAlive() {
|
||||
int optval = 1;
|
||||
socklen_t optlen = sizeof(optval);
|
||||
|
||||
MG_ASSERT(!setsockopt(socket_, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen), "Can't set socket keep alive");
|
||||
MG_ASSERT(!setsockopt(socket_, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval)), "Can't set socket keep alive");
|
||||
|
||||
optval = 20; // wait 20s before sending keep-alive packets
|
||||
MG_ASSERT(!setsockopt(socket_, SOL_TCP, TCP_KEEPIDLE, (void *)&optval, optlen), "Can't set socket keep alive");
|
||||
MG_ASSERT(!setsockopt(socket_, SOL_TCP, TCP_KEEPIDLE, (void *)&optval, sizeof(optval)),
|
||||
"Can't set socket keep alive");
|
||||
|
||||
optval = 4; // 4 keep-alive packets must fail to close
|
||||
MG_ASSERT(!setsockopt(socket_, SOL_TCP, TCP_KEEPCNT, (void *)&optval, optlen), "Can't set socket keep alive");
|
||||
MG_ASSERT(!setsockopt(socket_, SOL_TCP, TCP_KEEPCNT, (void *)&optval, sizeof(optval)), "Can't set socket keep alive");
|
||||
|
||||
optval = 15; // send keep-alive packets every 15s
|
||||
MG_ASSERT(!setsockopt(socket_, SOL_TCP, TCP_KEEPINTVL, (void *)&optval, optlen), "Can't set socket keep alive");
|
||||
MG_ASSERT(!setsockopt(socket_, SOL_TCP, TCP_KEEPINTVL, (void *)&optval, sizeof(optval)),
|
||||
"Can't set socket keep alive");
|
||||
}
|
||||
|
||||
void Socket::SetNoDelay() {
|
||||
int optval = 1;
|
||||
socklen_t optlen = sizeof(optval);
|
||||
|
||||
MG_ASSERT(!setsockopt(socket_, SOL_TCP, TCP_NODELAY, (void *)&optval, optlen), "Can't set socket no delay");
|
||||
MG_ASSERT(!setsockopt(socket_, SOL_TCP, TCP_NODELAY, (void *)&optval, sizeof(optval)), "Can't set socket no delay");
|
||||
}
|
||||
|
||||
void Socket::SetTimeout(long sec, long usec) {
|
||||
// NOLINTNEXTLINE(readability-make-member-function-const)
|
||||
void Socket::SetTimeout(int64_t sec, int64_t usec) {
|
||||
struct timeval tv;
|
||||
tv.tv_sec = sec;
|
||||
tv.tv_usec = usec;
|
||||
@@ -176,7 +153,7 @@ void Socket::SetTimeout(long sec, long usec) {
|
||||
}
|
||||
|
||||
int Socket::ErrorStatus() const {
|
||||
int optval;
|
||||
int optval = 0;
|
||||
socklen_t optlen = sizeof(optval);
|
||||
auto status = getsockopt(socket_, SOL_SOCKET, SO_ERROR, &optval, &optlen);
|
||||
MG_ASSERT(!status, "getsockopt failed");
|
||||
@@ -189,21 +166,22 @@ std::optional<Socket> Socket::Accept() {
|
||||
sockaddr_storage addr;
|
||||
socklen_t addr_size = sizeof addr;
|
||||
char addr_decoded[INET6_ADDRSTRLEN];
|
||||
void *addr_src;
|
||||
unsigned short port;
|
||||
|
||||
int sfd = accept(socket_, (struct sockaddr *)&addr, &addr_size);
|
||||
int sfd = accept(socket_, reinterpret_cast<sockaddr *>(&addr), &addr_size);
|
||||
if (UNLIKELY(sfd == -1)) return std::nullopt;
|
||||
|
||||
void *addr_src = nullptr;
|
||||
uint16_t port = 0;
|
||||
|
||||
if (addr.ss_family == AF_INET) {
|
||||
addr_src = (void *)&(((sockaddr_in *)&addr)->sin_addr);
|
||||
port = ntohs(((sockaddr_in *)&addr)->sin_port);
|
||||
addr_src = &reinterpret_cast<sockaddr_in &>(addr).sin_addr;
|
||||
port = ntohs(reinterpret_cast<sockaddr_in &>(addr).sin_port);
|
||||
} else {
|
||||
addr_src = (void *)&(((sockaddr_in6 *)&addr)->sin6_addr);
|
||||
port = ntohs(((sockaddr_in6 *)&addr)->sin6_port);
|
||||
addr_src = &reinterpret_cast<sockaddr_in6 &>(addr).sin6_addr;
|
||||
port = ntohs(reinterpret_cast<sockaddr_in6 &>(addr).sin6_port);
|
||||
}
|
||||
|
||||
inet_ntop(addr.ss_family, addr_src, addr_decoded, INET6_ADDRSTRLEN);
|
||||
inet_ntop(addr.ss_family, addr_src, addr_decoded, sizeof(addr_decoded));
|
||||
|
||||
Endpoint endpoint(addr_decoded, port);
|
||||
|
||||
@@ -213,9 +191,11 @@ std::optional<Socket> Socket::Accept() {
|
||||
bool Socket::Write(const uint8_t *data, size_t len, bool have_more) {
|
||||
// MSG_NOSIGNAL is here to disable raising a SIGPIPE signal when a
|
||||
// connection dies mid-write, the socket will only return an EPIPE error.
|
||||
int flags = MSG_NOSIGNAL | (have_more ? MSG_MORE : 0);
|
||||
constexpr unsigned msg_nosignal = MSG_NOSIGNAL;
|
||||
constexpr unsigned msg_more = MSG_MORE;
|
||||
const unsigned flags = msg_nosignal | (have_more ? msg_more : 0);
|
||||
while (len > 0) {
|
||||
auto written = send(socket_, data, len, flags);
|
||||
auto written = send(socket_, data, len, static_cast<int>(flags));
|
||||
if (written == -1) {
|
||||
if (errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR) {
|
||||
// Terminal error, return failure.
|
||||
@@ -253,7 +233,8 @@ bool Socket::WaitForReadyRead() {
|
||||
// event occurs.
|
||||
int ret = poll(&p, 1, -1);
|
||||
if (ret < 1) return false;
|
||||
return p.revents & POLLIN;
|
||||
constexpr unsigned pollin = POLLIN;
|
||||
return static_cast<unsigned>(p.revents) & pollin;
|
||||
}
|
||||
|
||||
bool Socket::WaitForReadyWrite() {
|
||||
@@ -265,7 +246,8 @@ bool Socket::WaitForReadyWrite() {
|
||||
// event occurs.
|
||||
int ret = poll(&p, 1, -1);
|
||||
if (ret < 1) return false;
|
||||
return p.revents & POLLOUT;
|
||||
constexpr unsigned pollout = POLLOUT;
|
||||
return static_cast<unsigned>(p.revents) & pollout;
|
||||
}
|
||||
|
||||
} // namespace io::network
|
||||
} // namespace memgraph::io::network
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
#include "io/network/endpoint.hpp"
|
||||
|
||||
namespace io::network {
|
||||
namespace memgraph::io::network {
|
||||
|
||||
/**
|
||||
* This class creates a network socket.
|
||||
@@ -27,12 +27,12 @@ namespace io::network {
|
||||
*/
|
||||
class Socket {
|
||||
public:
|
||||
Socket() = default;
|
||||
Socket() noexcept = default;
|
||||
Socket(const Socket &) = delete;
|
||||
Socket &operator=(const Socket &) = delete;
|
||||
Socket(Socket &&);
|
||||
Socket &operator=(Socket &&);
|
||||
~Socket();
|
||||
Socket(Socket &&) noexcept;
|
||||
Socket &operator=(Socket &&) noexcept;
|
||||
~Socket() noexcept;
|
||||
|
||||
/**
|
||||
* Closes the socket if it is open.
|
||||
@@ -118,7 +118,7 @@ class Socket {
|
||||
* @param sec timeout seconds value
|
||||
* @param usec timeout microseconds value
|
||||
*/
|
||||
void SetTimeout(long sec, long usec);
|
||||
void SetTimeout(int64_t sec, int64_t usec);
|
||||
|
||||
/**
|
||||
* Checks if there are any errors on a socket. Returns 0 if there are none.
|
||||
@@ -206,4 +206,4 @@ class Socket {
|
||||
int socket_ = -1;
|
||||
Endpoint endpoint_;
|
||||
};
|
||||
} // namespace io::network
|
||||
} // namespace memgraph::io::network
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace io::network {
|
||||
namespace memgraph::io::network {
|
||||
|
||||
/**
|
||||
* StreamBuffer
|
||||
@@ -25,4 +25,4 @@ struct StreamBuffer {
|
||||
uint8_t *data;
|
||||
size_t len;
|
||||
};
|
||||
} // namespace io::network
|
||||
} // namespace memgraph::io::network
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
#include "utils/logging.hpp"
|
||||
|
||||
namespace io::network {
|
||||
namespace memgraph::io::network {
|
||||
|
||||
/// Resolves hostname to ip, if already an ip, just returns it
|
||||
std::string ResolveHostname(std::string hostname) {
|
||||
@@ -68,4 +68,4 @@ bool CanEstablishConnection(const io::network::Endpoint &endpoint) {
|
||||
return client.Connect(endpoint);
|
||||
}
|
||||
|
||||
}; // namespace io::network
|
||||
}; // namespace memgraph::io::network
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#include "io/network/endpoint.hpp"
|
||||
|
||||
namespace io::network {
|
||||
namespace memgraph::io::network {
|
||||
|
||||
/// Resolves hostname to ip, if already an ip, just returns it
|
||||
std::string ResolveHostname(std::string hostname);
|
||||
@@ -27,4 +27,4 @@ std::optional<std::string> GetHostname();
|
||||
// Try to establish a connection to a remote host
|
||||
bool CanEstablishConnection(const Endpoint &endpoint);
|
||||
|
||||
} // namespace io::network
|
||||
} // namespace memgraph::io::network
|
||||
|
||||
@@ -5,7 +5,3 @@ find_package(ZLIB REQUIRED)
|
||||
# STATIC library used to store key-value pairs
|
||||
add_library(mg-kvstore STATIC kvstore.cpp)
|
||||
target_link_libraries(mg-kvstore stdc++fs mg-utils rocksdb BZip2::BZip2 ZLIB::ZLIB gflags)
|
||||
|
||||
# STATIC library for dummy key-value storage
|
||||
# add_library(mg-kvstore-dummy STATIC kvstore_dummy.cpp)
|
||||
# target_link_libraries(mg-kvstore-dummy mg-utils)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -15,7 +15,7 @@
|
||||
#include "kvstore/kvstore.hpp"
|
||||
#include "utils/file.hpp"
|
||||
|
||||
namespace kvstore {
|
||||
namespace memgraph::kvstore {
|
||||
|
||||
struct KVStore::impl {
|
||||
std::filesystem::path storage;
|
||||
@@ -169,4 +169,4 @@ bool KVStore::CompactRange(const std::string &begin_prefix, const std::string &e
|
||||
return s.ok();
|
||||
}
|
||||
|
||||
} // namespace kvstore
|
||||
} // namespace memgraph::kvstore
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
#include "utils/exceptions.hpp"
|
||||
|
||||
namespace kvstore {
|
||||
namespace memgraph::kvstore {
|
||||
|
||||
class KVStoreError : public utils::BasicException {
|
||||
public:
|
||||
@@ -206,4 +206,4 @@ class KVStore final {
|
||||
std::unique_ptr<impl> pimpl_;
|
||||
};
|
||||
|
||||
} // namespace kvstore
|
||||
} // namespace memgraph::kvstore
|
||||
|
||||
@@ -1,111 +0,0 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
// License, and you may not use this file except in compliance with the Business Source License.
|
||||
//
|
||||
// As of the Change Date specified in that file, in accordance with
|
||||
// the Business Source License, use of this software will be governed
|
||||
// by the Apache License, Version 2.0, included in the file
|
||||
// licenses/APL.txt.
|
||||
|
||||
#include "kvstore/kvstore.hpp"
|
||||
|
||||
#include "utils/file.hpp"
|
||||
#include "utils/logging.hpp"
|
||||
|
||||
namespace kvstore {
|
||||
|
||||
struct KVStore::impl {};
|
||||
|
||||
KVStore::KVStore(std::filesystem::path storage) {}
|
||||
|
||||
KVStore::~KVStore() {}
|
||||
|
||||
bool KVStore::Put(const std::string &key, const std::string &value) {
|
||||
LOG_FATAL("Unsupported operation (KVStore::Put) -- this is a dummy kvstore");
|
||||
}
|
||||
|
||||
bool KVStore::PutMultiple(const std::map<std::string, std::string> &items) {
|
||||
LOG_FATAL(
|
||||
"Unsupported operation (KVStore::PutMultiple) -- this is a "
|
||||
"dummy kvstore");
|
||||
}
|
||||
|
||||
std::optional<std::string> KVStore::Get(const std::string &key) const noexcept {
|
||||
LOG_FATAL("Unsupported operation (KVStore::Get) -- this is a dummy kvstore");
|
||||
}
|
||||
|
||||
bool KVStore::Delete(const std::string &key) {
|
||||
LOG_FATAL("Unsupported operation (KVStore::Delete) -- this is a dummy kvstore");
|
||||
}
|
||||
|
||||
bool KVStore::DeleteMultiple(const std::vector<std::string> &keys) {
|
||||
LOG_FATAL(
|
||||
"Unsupported operation (KVStore::DeleteMultiple) -- this is "
|
||||
"a dummy kvstore");
|
||||
}
|
||||
|
||||
bool KVStore::DeletePrefix(const std::string &prefix) {
|
||||
LOG_FATAL(
|
||||
"Unsupported operation (KVStore::DeletePrefix) -- this is a "
|
||||
"dummy kvstore");
|
||||
}
|
||||
|
||||
bool KVStore::PutAndDeleteMultiple(const std::map<std::string, std::string> &items,
|
||||
const std::vector<std::string> &keys) {
|
||||
LOG_FATAL(
|
||||
"Unsupported operation (KVStore::PutAndDeleteMultiple) -- this is a "
|
||||
"dummy kvstore");
|
||||
}
|
||||
|
||||
// iterator
|
||||
|
||||
struct KVStore::iterator::impl {};
|
||||
|
||||
KVStore::iterator::iterator(const KVStore *kvstore, const std::string &prefix, bool at_end) : pimpl_(new impl()) {}
|
||||
|
||||
KVStore::iterator::iterator(KVStore::iterator &&other) { pimpl_ = std::move(other.pimpl_); }
|
||||
|
||||
KVStore::iterator::~iterator() {}
|
||||
|
||||
KVStore::iterator &KVStore::iterator::operator=(KVStore::iterator &&other) {
|
||||
pimpl_ = std::move(other.pimpl_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
KVStore::iterator &KVStore::iterator::operator++() {
|
||||
LOG_FATAL(
|
||||
"Unsupported operation (&KVStore::iterator::operator++) -- "
|
||||
"this is a dummy kvstore");
|
||||
}
|
||||
|
||||
bool KVStore::iterator::operator==(const iterator &other) const { return true; }
|
||||
|
||||
bool KVStore::iterator::operator!=(const iterator &other) const { return false; }
|
||||
|
||||
KVStore::iterator::reference KVStore::iterator::operator*() {
|
||||
LOG_FATAL(
|
||||
"Unsupported operation (KVStore::iterator::operator*)-- this "
|
||||
"is a dummy kvstore");
|
||||
}
|
||||
|
||||
KVStore::iterator::pointer KVStore::iterator::operator->() {
|
||||
LOG_FATAL(
|
||||
"Unsupported operation (KVStore::iterator::operator->) -- "
|
||||
"this is a dummy kvstore");
|
||||
}
|
||||
|
||||
void KVStore::iterator::SetInvalid() {}
|
||||
|
||||
bool KVStore::iterator::IsValid() { return false; }
|
||||
|
||||
size_t KVStore::Size(const std::string &prefix) { return 0; }
|
||||
|
||||
bool KVStore::CompactRange(const std::string &begin_prefix, const std::string &end_prefix) {
|
||||
LOG_FATAL(
|
||||
"Unsupported operation (KVStore::Compact) -- this is a "
|
||||
"dummy kvstore");
|
||||
}
|
||||
|
||||
} // namespace kvstore
|
||||
@@ -83,7 +83,7 @@ NIL, returns a string."
|
||||
(when (> (length super-classes) 1)
|
||||
(error "Unable to generate TypeInfo for class '~A' due to multiple inheritance!"
|
||||
(cpp-type-name cpp-class)))
|
||||
(format s "const utils::TypeInfo ~A::kType{0x~XULL, \"~A\", ~A};~%"
|
||||
(format s "const memgraph::utils::TypeInfo ~A::kType{0x~XULL, \"~A\", ~A};~%"
|
||||
(if *generating-cpp-impl-p*
|
||||
(cpp-type-name cpp-class)
|
||||
;; Use full type declaration if class definition
|
||||
@@ -344,7 +344,7 @@ LCP-FILE, HPP-FILE, CPP-FILE and SLK-SERIALIZE-P are as in PROCESS-LCP."
|
||||
(write-line "// SLK serialization declarations" out)
|
||||
(write-line "#include \"slk/serialization.hpp\"" out)
|
||||
(with-namespaced-output (out open-namespace)
|
||||
(open-namespace '("slk"))
|
||||
(open-namespace '("memgraph::slk"))
|
||||
(dolist (type-for-slk types-for-slk)
|
||||
(ctypecase type-for-slk
|
||||
(cpp-class
|
||||
@@ -383,7 +383,7 @@ LCP-FILE, HPP-FILE, CPP-FILE and SLK-SERIALIZE-P are as in PROCESS-LCP."
|
||||
(remove-if (complement #'cpp-enum-serializep) *cpp-enums*)))))
|
||||
(write-line "// Autogenerated SLK serialization code" out)
|
||||
(with-namespaced-output (out open-namespace)
|
||||
(open-namespace '("slk"))
|
||||
(open-namespace '("memgraph::slk"))
|
||||
(dolist (cpp-type types-for-slk)
|
||||
(ctypecase cpp-type
|
||||
(cpp-class
|
||||
|
||||
@@ -58,7 +58,7 @@ generation expects the declarations and definitions to be in `slk` namespace."
|
||||
(let ((self-arg (list (lcp::ensure-namestring-for-variable 'self)
|
||||
(lcp::cpp-type-wrap cpp-class '("const" "&"))))
|
||||
(builder-arg (list (lcp::ensure-namestring-for-variable 'builder)
|
||||
(lcp::ensure-cpp-type "slk::Builder *"))))
|
||||
(lcp::ensure-cpp-type "memgraph::slk::Builder *"))))
|
||||
(lcp::cpp-function-declaration
|
||||
"Save" :args (list* self-arg builder-arg (save-extra-args cpp-class))
|
||||
:type-params (lcp::cpp-type-type-params cpp-class))))
|
||||
@@ -78,7 +78,7 @@ namespace."
|
||||
(let ((self-arg (list (lcp::ensure-namestring-for-variable 'self)
|
||||
(lcp::cpp-type-wrap cpp-class '("std::unique_ptr" "*"))))
|
||||
(reader-arg (list (lcp::ensure-namestring-for-variable 'reader)
|
||||
(lcp::ensure-cpp-type "slk::Reader *"))))
|
||||
(lcp::ensure-cpp-type "memgraph::slk::Reader *"))))
|
||||
(lcp::cpp-function-declaration
|
||||
"ConstructAndLoad"
|
||||
:args (list* self-arg reader-arg (load-extra-args cpp-class))
|
||||
@@ -97,7 +97,7 @@ generation expects the declarations and definitions to be in `slk` namespace."
|
||||
(let ((self-arg (list (lcp::ensure-namestring-for-variable 'self)
|
||||
(lcp::cpp-type-wrap cpp-class '("*"))))
|
||||
(reader-arg (list (lcp::ensure-namestring-for-variable 'reader)
|
||||
(lcp::ensure-cpp-type "slk::Reader *"))))
|
||||
(lcp::ensure-cpp-type "memgraph::slk::Reader *"))))
|
||||
(lcp::cpp-function-declaration
|
||||
"Load" :args (list* self-arg reader-arg (load-extra-args cpp-class))
|
||||
:type-params (lcp::cpp-type-type-params cpp-class))))
|
||||
@@ -125,7 +125,7 @@ serializable member has no public access."
|
||||
(lcp::cpp-type-name cpp-class)))
|
||||
;; TODO: Extra args for cpp-class members
|
||||
(t
|
||||
(format s "slk::Save(self.~A, builder);~%" member-name)))))))
|
||||
(format s "memgraph::slk::Save(self.~A, builder);~%" member-name)))))))
|
||||
|
||||
(defun members-for-load (cpp-class)
|
||||
(remove-if (lambda (m)
|
||||
@@ -155,7 +155,7 @@ serializable member has no public access."
|
||||
(lcp::cpp-type-name cpp-class)))
|
||||
;; TODO: Extra args for cpp-class members
|
||||
(t
|
||||
(format s "slk::Load(&self->~A, reader);~%" member-name)))))))
|
||||
(format s "memgraph::slk::Load(&self->~A, reader);~%" member-name)))))))
|
||||
|
||||
(defun save-parents-recursively (cpp-class)
|
||||
"Generate code for saving members of all parents, recursively. Raise
|
||||
@@ -220,7 +220,7 @@ CPP-CLASS. Raise `SLK-ERROR' if a derived class has template parameters."
|
||||
(derived-var (lcp::cpp-name-for-variable (lcp::cpp-type-name subclass)))
|
||||
(extra-args (mapcar #'first (save-extra-args cpp-class))))
|
||||
(format s "if (const auto *~A_derived = utils::Downcast<const ~A>(&self)) {
|
||||
return slk::Save(*~A_derived, builder~{, ~A~}); }~%"
|
||||
return memgraph::slk::Save(*~A_derived, builder~{, ~A~}); }~%"
|
||||
derived-var derived-class derived-var extra-args))))))
|
||||
|
||||
(defun save-function-code-for-class (cpp-class)
|
||||
@@ -239,14 +239,14 @@ constructs, mostly related to templates."
|
||||
(lcp::cpp-type-name cpp-class))
|
||||
(progn
|
||||
;; We aren't abstract, so save our data.
|
||||
(format s "slk::Save(~A::kType.id, builder);~%"
|
||||
(format s "memgraph::slk::Save(~A::kType.id, builder);~%"
|
||||
(lcp::cpp-type-decl cpp-class))
|
||||
(write-string (save-parents-recursively cpp-class) s)
|
||||
(write-string (save-members cpp-class) s))))
|
||||
(t
|
||||
(when (cpp-class-super-classes-for-slk cpp-class)
|
||||
;; Write type ID for the (final) derived classes.
|
||||
(format s "slk::Save(~A::kType.id, builder);~%"
|
||||
(format s "memgraph::slk::Save(~A::kType.id, builder);~%"
|
||||
(lcp::cpp-type-decl cpp-class)))
|
||||
(write-string (save-parents-recursively cpp-class) s)
|
||||
(write-string (save-members cpp-class) s)))))
|
||||
@@ -268,7 +268,7 @@ constructs, mostly related to templates."
|
||||
(append concrete-classes (concrete-subclasses-rec subclass)))))))
|
||||
(with-output-to-string (s)
|
||||
(write-line "uint64_t type_id;" s)
|
||||
(write-line "slk::Load(&type_id, reader);" s)
|
||||
(write-line "memgraph::slk::Load(&type_id, reader);" s)
|
||||
(let ((concrete-classes (concrete-subclasses-rec cpp-class)))
|
||||
(unless (lcp::cpp-class-abstractp cpp-class)
|
||||
(push cpp-class concrete-classes))
|
||||
@@ -279,9 +279,9 @@ constructs, mostly related to templates."
|
||||
(lcp::with-cpp-block-output
|
||||
(s :name (format nil "if (~A::kType.id == type_id)" type-decl))
|
||||
(format s "auto ~A_instance = std::make_unique<~A>();~%" var-name type-decl)
|
||||
(format s "slk::Load(~A_instance.get(), reader~{, ~A~});~%" var-name extra-args)
|
||||
(format s "memgraph::slk::Load(~A_instance.get(), reader~{, ~A~});~%" var-name extra-args)
|
||||
(format s "*self = std::move(~A_instance); return;~%" var-name))))
|
||||
(write-line "throw slk::SlkDecodeException(\"Trying to load unknown derived type!\");" s)))))
|
||||
(write-line "throw memgraph::slk::SlkDecodeException(\"Trying to load unknown derived type!\");" s)))))
|
||||
|
||||
(defun load-function-code-for-class (cpp-class)
|
||||
"Generate code for serializing CPP-CLASS. Raise `SLK-ERROR' on unsupported C++
|
||||
@@ -296,7 +296,7 @@ constructs, mostly related to templates."
|
||||
;; derived ones.
|
||||
(when (lcp::cpp-class-direct-subclasses cpp-class)
|
||||
(format s "if (self->GetTypeInfo() != ~A::kType)~%" (lcp::cpp-type-decl cpp-class))
|
||||
(write-line "throw slk::SlkDecodeException(\"Trying to load incorrect derived type!\");" s))
|
||||
(write-line "throw memgraph::slk::SlkDecodeException(\"Trying to load incorrect derived type!\");" s))
|
||||
(write-string (load-parents-recursively cpp-class) s)
|
||||
(write-string (load-members cpp-class) s)))
|
||||
|
||||
@@ -341,7 +341,7 @@ generation expects the declarations and definitions to be in `slk` namespace."
|
||||
(let ((self-arg (list (lcp::ensure-namestring-for-variable 'self)
|
||||
(lcp::cpp-type-wrap cpp-enum '("const" "&"))))
|
||||
(builder-arg (list (lcp::ensure-namestring-for-variable 'builder)
|
||||
(lcp::ensure-cpp-type "slk::Builder *"))))
|
||||
(lcp::ensure-cpp-type "memgraph::slk::Builder *"))))
|
||||
(lcp::cpp-function-declaration "Save" :args (list self-arg builder-arg))))
|
||||
|
||||
(defun save-function-code-for-enum (cpp-enum)
|
||||
@@ -354,7 +354,7 @@ generation expects the declarations and definitions to be in `slk` namespace."
|
||||
(lcp::cpp-type-decl cpp-enum)
|
||||
enum-value
|
||||
enum-ix)))
|
||||
(write-line "slk::Save(enum_value, builder);" s)))
|
||||
(write-line "memgraph::slk::Save(enum_value, builder);" s)))
|
||||
|
||||
(defun save-function-definition-for-enum (cpp-enum)
|
||||
"Generate SLK save function. Note that the code generation expects the
|
||||
@@ -372,13 +372,13 @@ generation expects the declarations and definitions to be in `slk` namespace."
|
||||
(let ((self-arg (list (lcp::ensure-namestring-for-variable 'self)
|
||||
(lcp::cpp-type-wrap cpp-enum '("*"))))
|
||||
(reader-arg (list (lcp::ensure-namestring-for-variable 'reader)
|
||||
(lcp::ensure-cpp-type "slk::Reader *"))))
|
||||
(lcp::ensure-cpp-type "memgraph::slk::Reader *"))))
|
||||
(lcp::cpp-function-declaration "Load" :args (list self-arg reader-arg))))
|
||||
|
||||
(defun load-function-code-for-enum (cpp-enum)
|
||||
(with-output-to-string (s)
|
||||
(write-line "uint8_t enum_value;" s)
|
||||
(write-line "slk::Load(&enum_value, reader);" s)
|
||||
(write-line "memgraph::slk::Load(&enum_value, reader);" s)
|
||||
(lcp::with-cpp-block-output (s :name "switch (enum_value)")
|
||||
(loop :for enum-value :in (lcp::cpp-enum-values cpp-enum)
|
||||
:and enum-ix :from 0 :do
|
||||
@@ -386,7 +386,7 @@ generation expects the declarations and definitions to be in `slk` namespace."
|
||||
enum-ix
|
||||
(lcp::cpp-type-decl cpp-enum)
|
||||
enum-value))
|
||||
(write-line "default: throw slk::SlkDecodeException(\"Trying to load unknown enum value!\");" s))))
|
||||
(write-line "default: throw memgraph::slk::SlkDecodeException(\"Trying to load unknown enum value!\");" s))))
|
||||
|
||||
(defun load-function-definition-for-enum (cpp-enum)
|
||||
"Generate SLK save function. Note that the code generation expects the
|
||||
|
||||
@@ -197,25 +197,25 @@ CPP-TYPE-DECL."
|
||||
(let ((test-struct (lcp:define-struct test-struct ()
|
||||
())))
|
||||
(is-generated (lcp.slk:save-function-declaration-for-class test-struct)
|
||||
"void Save(const TestStruct &self, slk::Builder *builder)")
|
||||
"void Save(const TestStruct &self, memgraph::slk::Builder *builder)")
|
||||
(is-generated (lcp.slk:load-function-declaration-for-class test-struct)
|
||||
"void Load(TestStruct *self, slk::Reader *reader)"))
|
||||
"void Load(TestStruct *self, memgraph::slk::Reader *reader)"))
|
||||
(undefine-cpp-types)
|
||||
(let ((derived (lcp:define-class derived (base)
|
||||
())))
|
||||
(is-generated (lcp.slk:save-function-declaration-for-class derived)
|
||||
"void Save(const Derived &self, slk::Builder *builder)")
|
||||
"void Save(const Derived &self, memgraph::slk::Builder *builder)")
|
||||
(is-generated (lcp.slk:load-function-declaration-for-class derived)
|
||||
"void Load(Derived *self, slk::Reader *reader)"))
|
||||
"void Load(Derived *self, memgraph::slk::Reader *reader)"))
|
||||
(undefine-cpp-types)
|
||||
(let ((test-struct (lcp:define-struct test-struct ()
|
||||
()
|
||||
(:serialize (:slk :save-args '((extra-arg "SaveArgType"))
|
||||
:load-args '((extra-arg "LoadArgType")))))))
|
||||
(is-generated (lcp.slk:save-function-declaration-for-class test-struct)
|
||||
"void Save(const TestStruct &self, slk::Builder *builder, SaveArgType extra_arg)")
|
||||
"void Save(const TestStruct &self, memgraph::slk::Builder *builder, SaveArgType extra_arg)")
|
||||
(is-generated (lcp.slk:load-function-declaration-for-class test-struct)
|
||||
"void Load(TestStruct *self, slk::Reader *reader, LoadArgType extra_arg)"))
|
||||
"void Load(TestStruct *self, memgraph::slk::Reader *reader, LoadArgType extra_arg)"))
|
||||
(undefine-cpp-types)
|
||||
(let ((base-class (lcp:define-struct base ()
|
||||
()
|
||||
@@ -225,18 +225,18 @@ CPP-TYPE-DECL."
|
||||
())))
|
||||
(declare (ignore base-class))
|
||||
(is-generated (lcp.slk:save-function-declaration-for-class derived-class)
|
||||
"void Save(const Derived &self, slk::Builder *builder, SaveArgType extra_arg)")
|
||||
"void Save(const Derived &self, memgraph::slk::Builder *builder, SaveArgType extra_arg)")
|
||||
(is-generated (lcp.slk:load-function-declaration-for-class derived-class)
|
||||
"void Load(Derived *self, slk::Reader *reader, LoadArgType extra_arg)")
|
||||
"void Load(Derived *self, memgraph::slk::Reader *reader, LoadArgType extra_arg)")
|
||||
(is-generated (lcp.slk:construct-and-load-function-declaration-for-class derived-class)
|
||||
"void ConstructAndLoad(std::unique_ptr<Derived> *self, slk::Reader *reader, LoadArgType extra_arg)"))
|
||||
"void ConstructAndLoad(std::unique_ptr<Derived> *self, memgraph::slk::Reader *reader, LoadArgType extra_arg)"))
|
||||
(undefine-cpp-types)
|
||||
(let ((my-enum (lcp:define-enum my-enum
|
||||
(first-value second-value))))
|
||||
(is-generated (lcp.slk:save-function-declaration-for-enum my-enum)
|
||||
"void Save(const MyEnum &self, slk::Builder *builder)")
|
||||
"void Save(const MyEnum &self, memgraph::slk::Builder *builder)")
|
||||
(is-generated (lcp.slk:load-function-declaration-for-enum my-enum)
|
||||
"void Load(MyEnum *self, slk::Reader *reader)"))
|
||||
"void Load(MyEnum *self, memgraph::slk::Reader *reader)"))
|
||||
(undefine-cpp-types)
|
||||
;; Unsupported multiple inheritance
|
||||
(is-error (lcp.slk:save-function-declaration-for-class
|
||||
@@ -249,7 +249,7 @@ CPP-TYPE-DECL."
|
||||
(lcp:define-class derived (fst-base snd-base)
|
||||
()
|
||||
(:serialize (:slk :ignore-other-base-classes t))))
|
||||
"void Save(const Derived &self, slk::Builder *builder)")
|
||||
"void Save(const Derived &self, memgraph::slk::Builder *builder)")
|
||||
(undefine-cpp-types)
|
||||
;; Unsupported class templates
|
||||
(is-error (lcp.slk:save-function-declaration-for-class
|
||||
@@ -268,22 +268,22 @@ CPP-TYPE-DECL."
|
||||
(let ((my-enum (lcp:define-enum my-enum
|
||||
(first-value second-value))))
|
||||
(is-generated (lcp.slk:save-function-definition-for-enum my-enum)
|
||||
"void Save(const MyEnum &self, slk::Builder *builder) {
|
||||
"void Save(const MyEnum &self, memgraph::slk::Builder *builder) {
|
||||
uint8_t enum_value;
|
||||
switch (self) {
|
||||
case MyEnum::FIRST_VALUE: enum_value = 0; break;
|
||||
case MyEnum::SECOND_VALUE: enum_value = 1; break;
|
||||
}
|
||||
slk::Save(enum_value, builder);
|
||||
memgraph::slk::Save(enum_value, builder);
|
||||
}")
|
||||
(is-generated (lcp.slk:load-function-definition-for-enum my-enum)
|
||||
"void Load(MyEnum *self, slk::Reader *reader) {
|
||||
"void Load(MyEnum *self, memgraph::slk::Reader *reader) {
|
||||
uint8_t enum_value;
|
||||
slk::Load(&enum_value, reader);
|
||||
memgraph::slk::Load(&enum_value, reader);
|
||||
switch (enum_value) {
|
||||
case static_cast<uint8_t>(0): *self = MyEnum::FIRST_VALUE; break;
|
||||
case static_cast<uint8_t>(1): *self = MyEnum::SECOND_VALUE; break;
|
||||
default: throw slk::SlkDecodeException(\"Trying to load unknown enum value!\");
|
||||
default: throw memgraph::slk::SlkDecodeException(\"Trying to load unknown enum value!\");
|
||||
}
|
||||
}")))
|
||||
|
||||
@@ -293,22 +293,22 @@ CPP-TYPE-DECL."
|
||||
((int-member :int64_t)
|
||||
(vec-member "std::vector<SomeType>")))))
|
||||
(is-generated (lcp.slk:save-function-definition-for-class test-struct)
|
||||
"void Save(const TestStruct &self, slk::Builder *builder) {
|
||||
slk::Save(self.int_member, builder);
|
||||
slk::Save(self.vec_member, builder);
|
||||
"void Save(const TestStruct &self, memgraph::slk::Builder *builder) {
|
||||
memgraph::slk::Save(self.int_member, builder);
|
||||
memgraph::slk::Save(self.vec_member, builder);
|
||||
}")
|
||||
(is-generated (lcp.slk:load-function-definition-for-class test-struct)
|
||||
"void Load (TestStruct *self, slk::Reader *reader) {
|
||||
slk::Load(&self->int_member, reader);
|
||||
slk::Load(&self->vec_member, reader);
|
||||
"void Load (TestStruct *self, memgraph::slk::Reader *reader) {
|
||||
memgraph::slk::Load(&self->int_member, reader);
|
||||
memgraph::slk::Load(&self->vec_member, reader);
|
||||
}"))
|
||||
(undefine-cpp-types)
|
||||
(let ((test-struct (lcp:define-struct test-struct ()
|
||||
((skip-member :int64_t :dont-save t)))))
|
||||
(is-generated (lcp.slk:save-function-definition-for-class test-struct)
|
||||
"void Save(const TestStruct &self, slk::Builder *builder) {}")
|
||||
"void Save(const TestStruct &self, memgraph::slk::Builder *builder) {}")
|
||||
(is-generated (lcp.slk:load-function-definition-for-class test-struct)
|
||||
"void Load(TestStruct *self, slk::Reader *reader) {}"))
|
||||
"void Load(TestStruct *self, memgraph::slk::Reader *reader) {}"))
|
||||
(undefine-cpp-types)
|
||||
(let ((test-struct
|
||||
(lcp:define-struct test-struct ()
|
||||
@@ -320,11 +320,11 @@ CPP-TYPE-DECL."
|
||||
(check-type member-name string)
|
||||
(format nil "self->~A.CustomLoad(reader);" member-name)))))))
|
||||
(is-generated (lcp.slk:save-function-definition-for-class test-struct)
|
||||
"void Save(const TestStruct &self, slk::Builder *builder) {
|
||||
"void Save(const TestStruct &self, memgraph::slk::Builder *builder) {
|
||||
{ self.custom_member.CustomSave(builder); }
|
||||
}")
|
||||
(is-generated (lcp.slk:load-function-definition-for-class test-struct)
|
||||
"void Load(TestStruct *self, slk::Reader *reader) {
|
||||
"void Load(TestStruct *self, memgraph::slk::Reader *reader) {
|
||||
{ self->custom_member.CustomLoad(reader); }
|
||||
}"))
|
||||
(undefine-cpp-types)
|
||||
@@ -360,10 +360,10 @@ CPP-TYPE-DECL."
|
||||
:slk-load #'custom-load)))))
|
||||
(dolist (ptr-class (list raw-ptr-class shared-ptr-class unique-ptr-class))
|
||||
(is-generated (lcp.slk:save-function-definition-for-class ptr-class)
|
||||
(format nil "void Save(const ~A &self, slk::Builder *builder) { { CustomSave(); } }"
|
||||
(format nil "void Save(const ~A &self, memgraph::slk::Builder *builder) { { CustomSave(); } }"
|
||||
(lcp::cpp-type-decl ptr-class)))
|
||||
(is-generated (lcp.slk:load-function-definition-for-class ptr-class)
|
||||
(format nil "void Load(~A *self, slk::Reader *reader) { { CustomLoad(); } }"
|
||||
(format nil "void Load(~A *self, memgraph::slk::Reader *reader) { { CustomLoad(); } }"
|
||||
(lcp::cpp-type-decl ptr-class)))))))
|
||||
|
||||
(subtest "class inheritance serialization"
|
||||
@@ -378,61 +378,61 @@ CPP-TYPE-DECL."
|
||||
;; We will test single inheritance and ignored multiple inheritance, both
|
||||
;; should generate the same code that follows.
|
||||
(let ((base-save-code
|
||||
"void Save(const Base &self, slk::Builder *builder) {
|
||||
"void Save(const Base &self, memgraph::slk::Builder *builder) {
|
||||
if (const auto *derived_derived = utils::Downcast<const Derived>(&self)) {
|
||||
return slk::Save(*derived_derived, builder);
|
||||
return memgraph::slk::Save(*derived_derived, builder);
|
||||
}
|
||||
slk::Save(Base::kType.id, builder);
|
||||
slk::Save(self.base_member, builder);
|
||||
memgraph::slk::Save(Base::kType.id, builder);
|
||||
memgraph::slk::Save(self.base_member, builder);
|
||||
}")
|
||||
(base-construct-code
|
||||
"void ConstructAndLoad(std::unique_ptr<Base> *self, slk::Reader *reader) {
|
||||
"void ConstructAndLoad(std::unique_ptr<Base> *self, memgraph::slk::Reader *reader) {
|
||||
uint64_t type_id;
|
||||
slk::Load(&type_id, reader);
|
||||
memgraph::slk::Load(&type_id, reader);
|
||||
if (Base::kType.id == type_id) {
|
||||
auto base_instance = std::make_unique<Base>();
|
||||
slk::Load(base_instance.get(), reader);
|
||||
memgraph::slk::Load(base_instance.get(), reader);
|
||||
*self = std::move(base_instance);
|
||||
return;
|
||||
}
|
||||
if (Derived::kType.id == type_id) {
|
||||
auto derived_instance = std::make_unique<Derived>();
|
||||
slk::Load(derived_instance.get(), reader);
|
||||
memgraph::slk::Load(derived_instance.get(), reader);
|
||||
*self = std::move(derived_instance);
|
||||
return;
|
||||
}
|
||||
throw slk::SlkDecodeException(\"Trying to load unknown derived type!\");
|
||||
throw memgraph::slk::SlkDecodeException(\"Trying to load unknown derived type!\");
|
||||
}")
|
||||
(base-load-code
|
||||
"void Load(Base *self, slk::Reader *reader) {
|
||||
"void Load(Base *self, memgraph::slk::Reader *reader) {
|
||||
if (self->GetTypeInfo() != Base::kType)
|
||||
throw slk::SlkDecodeException(\"Trying to load incorrect derived type!\");
|
||||
slk::Load(&self->base_member, reader);
|
||||
throw memgraph::slk::SlkDecodeException(\"Trying to load incorrect derived type!\");
|
||||
memgraph::slk::Load(&self->base_member, reader);
|
||||
}")
|
||||
(derived-save-code
|
||||
"void Save(const Derived &self, slk::Builder *builder) {
|
||||
slk::Save(Derived::kType.id, builder);
|
||||
"void Save(const Derived &self, memgraph::slk::Builder *builder) {
|
||||
memgraph::slk::Save(Derived::kType.id, builder);
|
||||
// Save parent Base
|
||||
{ slk::Save(self.base_member, builder); }
|
||||
slk::Save(self.derived_member, builder);
|
||||
{ memgraph::slk::Save(self.base_member, builder); }
|
||||
memgraph::slk::Save(self.derived_member, builder);
|
||||
}")
|
||||
(derived-construct-code
|
||||
"void ConstructAndLoad(std::unique_ptr<Derived> *self, slk::Reader *reader) {
|
||||
"void ConstructAndLoad(std::unique_ptr<Derived> *self, memgraph::slk::Reader *reader) {
|
||||
uint64_t type_id;
|
||||
slk::Load(&type_id, reader);
|
||||
memgraph::slk::Load(&type_id, reader);
|
||||
if (Derived::kType.id == type_id) {
|
||||
auto derived_instance = std::make_unique<Derived>();
|
||||
slk::Load(derived_instance.get(), reader);
|
||||
memgraph::slk::Load(derived_instance.get(), reader);
|
||||
*self = std::move(derived_instance);
|
||||
return;
|
||||
}
|
||||
throw slk::SlkDecodeException(\"Trying to load unknown derived type!\");
|
||||
throw memgraph::slk::SlkDecodeException(\"Trying to load unknown derived type!\");
|
||||
}")
|
||||
(derived-load-code
|
||||
"void Load(Derived *self, slk::Reader *reader) {
|
||||
"void Load(Derived *self, memgraph::slk::Reader *reader) {
|
||||
// Load parent Base
|
||||
{ slk::Load(&self->base_member, reader); }
|
||||
slk::Load(&self->derived_member, reader);
|
||||
{ memgraph::slk::Load(&self->base_member, reader); }
|
||||
memgraph::slk::Load(&self->derived_member, reader);
|
||||
}"))
|
||||
;; Single inheritance
|
||||
(let ((base-class (lcp:define-struct base ()
|
||||
@@ -478,48 +478,48 @@ CPP-TYPE-DECL."
|
||||
(derived-class (lcp:define-struct derived (abstract-base)
|
||||
((derived-member :int64_t)))))
|
||||
(is-generated (lcp.slk:save-function-definition-for-class abstract-base-class)
|
||||
"void Save(const AbstractBase &self, slk::Builder *builder) {
|
||||
"void Save(const AbstractBase &self, memgraph::slk::Builder *builder) {
|
||||
if (const auto *derived_derived = utils::Downcast<const Derived>(&self)) {
|
||||
return slk::Save(*derived_derived, builder);
|
||||
return memgraph::slk::Save(*derived_derived, builder);
|
||||
}
|
||||
LOG(FATAL) << \"`AbstractBase` is marked as an abstract class!\";
|
||||
}")
|
||||
(is-generated (lcp.slk:construct-and-load-function-definition-for-class abstract-base-class)
|
||||
"void ConstructAndLoad(std::unique_ptr<AbstractBase> *self, slk::Reader *reader) {
|
||||
"void ConstructAndLoad(std::unique_ptr<AbstractBase> *self, memgraph::slk::Reader *reader) {
|
||||
uint64_t type_id;
|
||||
slk::Load(&type_id, reader);
|
||||
memgraph::slk::Load(&type_id, reader);
|
||||
if (Derived::kType.id == type_id) {
|
||||
auto derived_instance = std::make_unique<Derived>();
|
||||
slk::Load(derived_instance.get(), reader);
|
||||
memgraph::slk::Load(derived_instance.get(), reader);
|
||||
*self = std::move(derived_instance);
|
||||
return;
|
||||
}
|
||||
throw slk::SlkDecodeException(\"Trying to load unknown derived type!\");
|
||||
throw memgraph::slk::SlkDecodeException(\"Trying to load unknown derived type!\");
|
||||
}")
|
||||
(is-generated (lcp.slk:save-function-definition-for-class derived-class)
|
||||
"void Save(const Derived &self, slk::Builder *builder) {
|
||||
slk::Save(Derived::kType.id, builder);
|
||||
"void Save(const Derived &self, memgraph::slk::Builder *builder) {
|
||||
memgraph::slk::Save(Derived::kType.id, builder);
|
||||
// Save parent AbstractBase
|
||||
{ slk::Save(self.base_member, builder); }
|
||||
slk::Save(self.derived_member, builder);
|
||||
{ memgraph::slk::Save(self.base_member, builder); }
|
||||
memgraph::slk::Save(self.derived_member, builder);
|
||||
}")
|
||||
(is-generated (lcp.slk:construct-and-load-function-definition-for-class derived-class)
|
||||
"void ConstructAndLoad(std::unique_ptr<Derived> *self, slk::Reader *reader) {
|
||||
"void ConstructAndLoad(std::unique_ptr<Derived> *self, memgraph::slk::Reader *reader) {
|
||||
uint64_t type_id;
|
||||
slk::Load(&type_id, reader);
|
||||
memgraph::slk::Load(&type_id, reader);
|
||||
if (Derived::kType.id == type_id) {
|
||||
auto derived_instance = std::make_unique<Derived>();
|
||||
slk::Load(derived_instance.get(), reader);
|
||||
memgraph::slk::Load(derived_instance.get(), reader);
|
||||
*self = std::move(derived_instance);
|
||||
return;
|
||||
}
|
||||
throw slk::SlkDecodeException(\"Trying to load unknown derived type!\");
|
||||
throw memgraph::slk::SlkDecodeException(\"Trying to load unknown derived type!\");
|
||||
}")
|
||||
(is-generated (lcp.slk:load-function-definition-for-class derived-class)
|
||||
"void Load(Derived *self, slk::Reader *reader) {
|
||||
"void Load(Derived *self, memgraph::slk::Reader *reader) {
|
||||
// Load parent AbstractBase
|
||||
{ slk::Load(&self->base_member, reader); }
|
||||
slk::Load(&self->derived_member, reader);
|
||||
{ memgraph::slk::Load(&self->base_member, reader); }
|
||||
memgraph::slk::Load(&self->derived_member, reader);
|
||||
}"))
|
||||
(undefine-cpp-types)
|
||||
(let ((base-class-template (lcp:define-struct (base t-param) ()
|
||||
@@ -552,9 +552,9 @@ CPP-TYPE-DECL."
|
||||
((member :bool))
|
||||
(:serialize (:slk :base t)))))
|
||||
(is-generated (lcp.slk:save-function-definition-for-class class)
|
||||
"void Save(const Derived &self, slk::Builder *builder) { slk::Save(self.member, builder); }")
|
||||
"void Save(const Derived &self, memgraph::slk::Builder *builder) { memgraph::slk::Save(self.member, builder); }")
|
||||
(is-generated (lcp.slk:load-function-definition-for-class class)
|
||||
"void Load(Derived *self, slk::Reader *reader) { slk::Load(&self->member, reader); }"))
|
||||
"void Load(Derived *self, memgraph::slk::Reader *reader) { memgraph::slk::Load(&self->member, reader); }"))
|
||||
|
||||
(undefine-cpp-types)
|
||||
(let ((base-class (lcp:define-struct base ()
|
||||
@@ -566,23 +566,23 @@ CPP-TYPE-DECL."
|
||||
())))
|
||||
(declare (ignore derived-class))
|
||||
(is-generated (lcp.slk:save-function-definition-for-class base-class)
|
||||
"void Save(const Base &self, slk::Builder *builder, SaveArg extra_arg) {
|
||||
"void Save(const Base &self, memgraph::slk::Builder *builder, SaveArg extra_arg) {
|
||||
if (const auto *derived_derived = utils::Downcast<const Derived>(&self)) {
|
||||
return slk::Save(*derived_derived, builder, extra_arg);
|
||||
return memgraph::slk::Save(*derived_derived, builder, extra_arg);
|
||||
}
|
||||
LOG(FATAL) << \"`Base` is marked as an abstract class!\";
|
||||
}")
|
||||
(is-generated (lcp.slk:construct-and-load-function-definition-for-class base-class)
|
||||
"void ConstructAndLoad(std::unique_ptr<Base> *self, slk::Reader *reader, LoadArg extra_arg) {
|
||||
"void ConstructAndLoad(std::unique_ptr<Base> *self, memgraph::slk::Reader *reader, LoadArg extra_arg) {
|
||||
uint64_t type_id;
|
||||
slk::Load(&type_id, reader);
|
||||
memgraph::slk::Load(&type_id, reader);
|
||||
if (Derived::kType.id == type_id) {
|
||||
auto derived_instance = std::make_unique<Derived>();
|
||||
slk::Load(derived_instance.get(), reader, extra_arg);
|
||||
memgraph::slk::Load(derived_instance.get(), reader, extra_arg);
|
||||
*self = std::move(derived_instance);
|
||||
return;
|
||||
}
|
||||
throw slk::SlkDecodeException(\"Trying to load unknown derived type!\");
|
||||
throw memgraph::slk::SlkDecodeException(\"Trying to load unknown derived type!\");
|
||||
}")))
|
||||
|
||||
(subtest "non-public members"
|
||||
|
||||
@@ -1416,26 +1416,26 @@ structure named by the string NAME."
|
||||
(unless (lcp.slk::save-extra-args class)
|
||||
(push ,(progn
|
||||
#>cpp
|
||||
static void Save(const ${name} &self, slk::Builder *builder);
|
||||
static void Save(const ${name} &self, memgraph::slk::Builder *builder);
|
||||
cpp<#)
|
||||
(cpp-class-public class))
|
||||
(in-impl
|
||||
,(progn
|
||||
#>cpp
|
||||
void ${name}::Save(const ${name} &self, slk::Builder *builder) {
|
||||
slk::Save(self, builder);
|
||||
void ${name}::Save(const ${name} &self, memgraph::slk::Builder *builder) {
|
||||
memgraph::slk::Save(self, builder);
|
||||
}
|
||||
cpp<#)))
|
||||
(unless (lcp.slk::load-extra-args class)
|
||||
(push ,(progn #>cpp
|
||||
static void Load(${name} *self, slk::Reader *reader);
|
||||
static void Load(${name} *self, memgraph::slk::Reader *reader);
|
||||
cpp<#)
|
||||
(cpp-class-public class))
|
||||
(in-impl
|
||||
,(progn
|
||||
#>cpp
|
||||
void ${name}::Load(${name} *self, slk::Reader *reader) {
|
||||
slk::Load(self, reader);
|
||||
void ${name}::Load(${name} *self, memgraph::slk::Reader *reader) {
|
||||
memgraph::slk::Load(self, reader);
|
||||
}
|
||||
cpp<#)))))
|
||||
|
||||
|
||||
501
src/memgraph.cpp
501
src/memgraph.cpp
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user