Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ jobs:
run: |
mkdir build
cd build
cmake .. -G "MinGW Makefiles" -DBUILD_TESTING=ON -DBUILD_TESTING_INTEGRATION=ON -DC_WARNINGS_AS_ERRORS=ON -DCPP_WARNINGS_AS_ERRORS=ON -DCMAKE_POLICY_VERSION_MINIMUM=3.5
cmake .. -G "MinGW Makefiles" -DBUILD_TESTING=ON -DBUILD_TESTING_INTEGRATION=ON -DC_WARNINGS_AS_ERRORS=ON -DCPP_WARNINGS_AS_ERRORS=ON
cmake --build . --parallel
- name: Verify Memgraph is running under WSL
Expand Down
13 changes: 10 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

cmake_minimum_required(VERSION 3.8)
cmake_minimum_required(VERSION 3.10)

if(WASM)
execute_process(COMMAND ${CMAKE_SOURCE_DIR}/wasm/install_deps.sh)
Expand Down Expand Up @@ -43,11 +43,18 @@ elseif(UNIX AND NOT APPLE)
message(STATUS "ON LINUX WASM BUILD")
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
message(STATUS "ON LINUX BUILD")
elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" OR
CMAKE_SYSTEM_NAME STREQUAL "NetBSD" OR
CMAKE_SYSTEM_NAME STREQUAL "OpenBSD" OR
CMAKE_SYSTEM_NAME STREQUAL "DragonFly")
message(STATUS "ON BSD BUILD (${CMAKE_SYSTEM_NAME})")
else()
message(FATAL_ERROR "Unsupported operating system. Please create issue or contribute!")
endif()
set(MGCLIENT_ON_LINUX TRUE)
add_definitions(-DMGCLIENT_ON_LINUX)
# Linux and the BSDs (FreeBSD, NetBSD, OpenBSD, DragonFly) share the same
# POSIX socket path in src/linux/, selected by MGCLIENT_ON_POSIX.
set(MGCLIENT_ON_POSIX TRUE)
add_definitions(-DMGCLIENT_ON_POSIX)
set(MGCLIENT_FIND_LIBRARY_PREFIXES "${CMAKE_FIND_LIBRARY_PREFIXES}")
elseif(APPLE)
message(STATUS "ON APPLE BUILD")
Expand Down
53 changes: 53 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,59 @@ cmake -DBUILD_TESTING=ON -DBUILD_TESTING_INTEGRATION=ON ..
ctest
```

## Building and installing on BSD

mgclient builds on FreeBSD, NetBSD, OpenBSD, and DragonFly BSD, which share the
same POSIX socket implementation as Linux.

To build and install mgclient from source you will need:
- CMake version >= 3.8
- OpenSSL version >= 1.0.2
- a C11 compiler (the base system Clang is sufficient)

```
# FreeBSD / DragonFly BSD
pkg install cmake git gcc openssl

# OpenBSD
pkg_add cmake git gcc openssl

# NetBSD
pkgin install cmake git gcc openssl
```

Once everything is in place, configure and build the project from the source
directory:

```
cmake -B build .
cmake --build build
```

This will build two `mgclient` library flavours: a static library (usually
named `libmgclient.a`) and a shared library (usually named `libmgclient.so`).

To install the libraries and corresponding header files run:

```
cmake --install build
```

This will install to system default installation directory. If you want to
change this location, use the `-DCMAKE_INSTALL_PREFIX` option when configuring.

If you want to build and run tests, configure with:

```
cmake -B build -DBUILD_TESTING=ON -DBUILD_TESTING_INTEGRATION=ON .
cmake --build build
ctest --test-dir build
```

NOTE: FreeBSD defaults to Clang with libc++. If you instead configure the build
with GCC (e.g. from `lang/gcc`), point CMake at it explicitly with
`-DCMAKE_C_COMPILER=` / `-DCMAKE_CXX_COMPILER=`.

## Building and installing on Windows

To build and install mgclient from source on Windows you will need:
Expand Down
28 changes: 20 additions & 8 deletions examples/advanced.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,25 @@
#include <cstdlib>
#include <iostream>
#include <numeric>
#include <sstream>
#include <string>

#include "mgclient.hpp"

// Reads the environment variable `value_name`, falling back to `default_value`
// when it is unset. Matches the helper used by the integration tests so the
// examples honor the same MEMGRAPH_HOST / MEMGRAPH_PORT overrides, e.g.
// MEMGRAPH_HOST=<ip> MEMGRAPH_PORT=<port> ./example_advanced_cpp
template <typename T>
T GetEnvOrDefault(const std::string &value_name, const T &default_value) {
const char *char_value = std::getenv(value_name.c_str());
if (!char_value) return default_value;
T value;
std::stringstream env_value_stream(char_value);
env_value_stream >> value;
return value;
}

void ClearDatabaseData(mg::Client *client) {
if (!client->Execute("MATCH (n) DETACH DELETE n;")) {
std::cerr << "Failed to delete all data from the database." << std::endl;
Expand Down Expand Up @@ -46,18 +63,13 @@ std::string MgValueToString(const mg::ConstValue &value) {
return value_str;
}

int main(int argc, char *argv[]) {
if (argc != 3) {
std::cerr << "Usage: " << argv[0] << " [host] [port]\n";
std::exit(1);
}

int main() {
mg::Client::Init();

{
mg::Client::Params params;
params.host = argv[1];
params.port = static_cast<uint16_t>(atoi(argv[2]));
params.host = GetEnvOrDefault<std::string>("MEMGRAPH_HOST", "127.0.0.1");
params.port = GetEnvOrDefault<uint16_t>("MEMGRAPH_PORT", 7687);
auto client = mg::Client::Connect(params);
if (!client) {
std::cerr << "Failed to connect." << std::endl;
Expand Down
28 changes: 23 additions & 5 deletions examples/basic.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,25 @@

#include <mgclient.h>

// Reads the environment variable `name`, falling back to `default_value` when
// it is unset. The C counterpart of the GetEnvOrDefault helper used by the
// integration tests, so the examples honor the same MEMGRAPH_HOST /
// MEMGRAPH_PORT overrides, e.g.
// MEMGRAPH_HOST=<ip> MEMGRAPH_PORT=<port> ./example_basic_c "RETURN 1"
static const char *get_env_or_default(const char *name,
const char *default_value) {
const char *value = getenv(name);
return value ? value : default_value;
}

static int get_env_int_or_default(const char *name, int default_value) {
const char *value = getenv(name);
return value ? atoi(value) : default_value;
}

int main(int argc, char *argv[]) {
if (argc != 4) {
fprintf(stderr, "Usage: %s [host] [port] [query]\n", argv[0]);
if (argc != 2) {
fprintf(stderr, "Usage: %s [query]\n", argv[0]);
exit(1);
}

Expand All @@ -17,8 +33,10 @@ int main(int argc, char *argv[]) {
fprintf(stderr, "failed to allocate session parameters\n");
exit(1);
}
mg_session_params_set_host(params, argv[1]);
mg_session_params_set_port(params, (uint16_t)atoi(argv[2]));
const char *host = get_env_or_default("MEMGRAPH_HOST", "127.0.0.1");
int port = get_env_int_or_default("MEMGRAPH_PORT", 7687);
mg_session_params_set_host(params, host);
mg_session_params_set_port(params, (uint16_t)port);
mg_session_params_set_sslmode(params, MG_SSLMODE_DISABLE);

mg_session *session = NULL;
Expand All @@ -30,7 +48,7 @@ int main(int argc, char *argv[]) {
return 1;
}

if (mg_session_run(session, argv[3], NULL, NULL, NULL, NULL) < 0) {
if (mg_session_run(session, argv[1], NULL, NULL, NULL, NULL) < 0) {
printf("failed to execute query: %s\n", mg_session_error(session));
mg_session_destroy(session);
return 1;
Expand Down
26 changes: 21 additions & 5 deletions examples/basic.cpp
Original file line number Diff line number Diff line change
@@ -1,20 +1,36 @@
#include <cstdlib>
#include <iostream>
#include <sstream>
#include <string>

#include <mgclient.hpp>

// Reads the environment variable `value_name`, falling back to `default_value`
// when it is unset. Matches the helper used by the integration tests so the
// examples honor the same MEMGRAPH_HOST / MEMGRAPH_PORT overrides, e.g.
// MEMGRAPH_HOST=<ip> MEMGRAPH_PORT=<port> ./example_basic_cpp "RETURN 1"
template <typename T>
T GetEnvOrDefault(const std::string &value_name, const T &default_value) {
const char *char_value = std::getenv(value_name.c_str());
if (!char_value) return default_value;
T value;
std::stringstream env_value_stream(char_value);
env_value_stream >> value;
return value;
}

int main(int argc, char *argv[]) {
if (argc != 4) {
std::cerr << "Usage: " << argv[0] << " [host] [port] [query]\n";
if (argc != 2) {
std::cerr << "Usage: " << argv[0] << " [query]\n";
exit(1);
}

mg::Client::Init();

std::cout << "mgclient version: " << mg::Client::Version() << std::endl;
mg::Client::Params params;
params.host = argv[1];
params.port = static_cast<uint16_t>(atoi(argv[2]));
params.host = GetEnvOrDefault<std::string>("MEMGRAPH_HOST", "127.0.0.1");
params.port = GetEnvOrDefault<uint16_t>("MEMGRAPH_PORT", 7687);
params.use_ssl = false;
auto client = mg::Client::Connect(params);

Expand All @@ -23,7 +39,7 @@ int main(int argc, char *argv[]) {
return 1;
}

if (!client->Execute(argv[3])) {
if (!client->Execute(argv[1])) {
std::cerr << "Failed to execute query!";
return 1;
}
Expand Down
2 changes: 1 addition & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ set(mgclient_src_files
mgvalue.c)
if(MGCLIENT_ON_APPLE)
list(APPEND mgclient_src_files apple/mgsocket.c)
elseif(MGCLIENT_ON_LINUX)
elseif(MGCLIENT_ON_POSIX)
list(APPEND mgclient_src_files linux/mgsocket.c)
elseif(MGCLIENT_ON_WINDOWS)
list(APPEND mgclient_src_files windows/mgsocket.c)
Expand Down
5 changes: 5 additions & 0 deletions src/linux/mgcommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@
#ifndef MGCLIENT_LINUX_MGCOMMON_H
#define MGCLIENT_LINUX_MGCOMMON_H

#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \
defined(__DragonFly__)
#include <sys/endian.h>
#else
#include <endian.h>
#endif

#endif
32 changes: 22 additions & 10 deletions src/linux/mgsocket.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,16 +101,28 @@ int mg_socket_options(int sock, mg_session *session) {
int level;
int optname;
int optval;
} socket_options[] = {// disable Nagle algorithm for performance reasons
{SOL_TCP, TCP_NODELAY, 1},
// turn keep-alive on
{SOL_SOCKET, SO_KEEPALIVE, 1},
// wait 20s before sending keep-alive packets
{SOL_TCP, TCP_KEEPIDLE, 20},
// 4 keep-alive packets must fail to close
{SOL_TCP, TCP_KEEPCNT, 4},
// send keep-alive packets every 15s
{SOL_TCP, TCP_KEEPINTVL, 15}};
} socket_options[] = {
// disable Nagle algorithm for performance reasons
{IPPROTO_TCP, TCP_NODELAY, 1},
// turn keep-alive on
{SOL_SOCKET, SO_KEEPALIVE, 1},
// The per-socket keep-alive tuning options below are not portable: OpenBSD,
// for one, only supports SO_KEEPALIVE and tunes the timers system-wide via
// sysctl (net.inet.tcp.keep*). Guard each on its macro so those platforms fall
// back to plain keep-alive instead of failing to build.
#ifdef TCP_KEEPIDLE
// wait 20s before sending keep-alive packets
{IPPROTO_TCP, TCP_KEEPIDLE, 20},
#endif
#ifdef TCP_KEEPCNT
// 4 keep-alive packets must fail to close
{IPPROTO_TCP, TCP_KEEPCNT, 4},
#endif
#ifdef TCP_KEEPINTVL
// send keep-alive packets every 15s
{IPPROTO_TCP, TCP_KEEPINTVL, 15},
#endif
};
const size_t OPTCNT = sizeof(socket_options) / sizeof(socket_options[0]);

for (size_t i = 0; i < OPTCNT; ++i) {
Expand Down
4 changes: 2 additions & 2 deletions src/mgcommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ extern "C" {
#include "apple/mgcommon.h"
#endif // MGCLIENT_ON_APPLE

#ifdef MGCLIENT_ON_LINUX
#ifdef MGCLIENT_ON_POSIX
#include "linux/mgcommon.h"
#endif // MGCLIENT_ON_LINUX
#endif // MGCLIENT_ON_POSIX

#ifdef MGCLIENT_ON_WINDOWS
#include "windows/mgcommon.h"
Expand Down
4 changes: 2 additions & 2 deletions src/mgsocket.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ extern "C" {
#include <unistd.h>
#endif // MGCLIENT_ON_APPLE

#ifdef MGCLIENT_ON_LINUX
#ifdef MGCLIENT_ON_POSIX
#include <arpa/inet.h>
#include <errno.h>
#include <netdb.h>
Expand All @@ -38,7 +38,7 @@ extern "C" {
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#endif // MGCLIENT_ON_LINUX
#endif // MGCLIENT_ON_POSIX

#ifdef MGCLIENT_ON_WINDOWS
#include <Ws2tcpip.h>
Expand Down
4 changes: 2 additions & 2 deletions src/mgtransport.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#ifdef MGCLIENT_ON_LINUX
#ifdef MGCLIENT_ON_POSIX
#ifndef __EMSCRIPTEN__
#include <pthread.h>
#endif
#endif // MGCLIENT_ON_LINUX
#endif // MGCLIENT_ON_POSIX

#include "mgallocator.h"
#include "mgclient.h"
Expand Down
Loading
Loading