Compare commits

..

20 Commits

Author SHA1 Message Date
Boris Tasevski
c553112b92 MemgraphInstanceRunner -> gqlalchemy.MemgraphInstanceBinary 2022-05-04 14:02:22 +02:00
Boris Tasevski
41635e7306 install scripts updated; MemgraphRunner -> gqlalchemy.MemgraphInstanceRunner 2022-05-04 13:58:03 +02:00
Boris Tasevski
ed4c4e6823 replaced all occurences of wait_for_server for wait_for_port from gqlalchemy 2022-04-28 16:02:51 +02:00
Josip Matak
4abaf27765 Memgraph magic functions (#345)
* Extend mgp_module with include adding functions

* Add return type to the function API

* Change Cypher grammar

* Add Python support for functions

* Implement error handling

* E2e tests for functions

* Write cpp e2e functions

* Create mg.functions() procedure

* Implement case insensitivity for user-defined Magic Functions.
2022-04-21 15:45:31 +02:00
Kostas Kyrimis
ea2806bd57 Implement foreach clause (#351) 2022-04-11 13:55:34 +03:00
Siniša Šušnjar
c8dbaf5979 Small io network socket fixes (#360)
* Modernize AddrInfo

* Modernize Socket
2022-04-08 14:38:13 +02:00
Jure Bajic
17049ada09 Resolve python dependency issues (#372) 2022-04-07 17:56:18 +02:00
Jure Bajic
1b619f51b2 Add docker release action (#356)
* Add docker release action

* Add debian-11 arm script

* Remove test prefix

* Update package_docker script

* Update release script

* Unify architecture extension
2022-04-07 15:23:18 +02:00
János Benjamin Antal
537855a0b2 Fix usages of constexpr (#367)
* Fix usages of constexpr
2022-03-31 13:52:43 +02:00
Jure Bajic
5822b44b15 Fix CentOS 7 release process (#369) 2022-03-31 07:20:53 +02:00
g-despot
bf01c58ed9 Update README.md 2022-03-22 04:50:01 +01:00
g-despot
89a5566f3f Update README.md 2022-03-22 04:49:03 +01:00
g-despot
29452f8774 Update README.md 2022-03-21 16:49:02 +01:00
jbajic
60ad05acff Address review comments 2022-03-14 15:47:41 +01:00
jbajic
4f593c7fca Adapt precommit to run through all files 2022-03-14 15:47:41 +01:00
jbajic
770ea1189a Fix SSL errors 2022-03-14 15:47:41 +01:00
jbajic
695bb343f1 Resolve clang-tidy error 2022-03-14 15:47:41 +01:00
jbajic
12b4ec1589 Add memgraph namespace 2022-03-14 15:47:41 +01:00
Antonio Andelic
b33d2c3940 use boost ssl 2022-03-14 15:47:41 +01:00
Marko Budiselić
477acad1f6 Update CODEOWNERS file (#362) 2022-02-25 13:42:27 +01:00
544 changed files with 13977 additions and 11295 deletions

View File

@@ -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
View 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 .

View File

@@ -1 +1 @@
* @gitbuda @antonio2368 @antaljanosbenjamin @kostasrim @jbajic
* @antaljanosbenjamin @kostasrim

View File

@@ -54,6 +54,18 @@ Memgraph is implemented in C/C++ and leverages an in-memory first architecture
to ensure that youre getting the best possible performance consistently and
without surprises. Its 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

View File

@@ -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
View 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}"

View File

@@ -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

View File

@@ -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

View File

@@ -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
View File

@@ -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"

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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}'"

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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_;
};

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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};

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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"

View File

@@ -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<#)))))

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