Skip to content

Commit c3f2918

Browse files
authored
Merge pull request #6 from questdb/corrosion
Rewrite of the core logic in Rust. Float serialisation issues fixed.
2 parents b052a13 + 3213003 commit c3f2918

File tree

113 files changed

+5776
-1910
lines changed

Some content is hidden

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

113 files changed

+5776
-1910
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
target
2+
Cargo.lock
13
build
24
.vs
35
.vscode

BUILD.md

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,26 @@ This page describes how to build this project.
55
Also make sure to read the page on
66
[integrating this library into your project](DEPENDENCY.md).
77

8-
## Pre-requisites
8+
## Pre-requisites and dependencies
99

10-
* A modern C11/C++17 compiler.
10+
* Rust 1.61 or newer (get it from [https://rustup.rs/](https://rustup.rs/))
11+
* A modern C11 or C++17 compiler.
1112
* CMake 3.15 or newer.
1213

14+
The library statically links all its dependencies.
15+
16+
```
17+
$ ls build/libquestdb_client.*
18+
build/libquestdb_client.a build/libquestdb_client.so
19+
$ ldd build/libquestdb_client.so
20+
linux-vdso.so.1 (0x00007ffddd344000)
21+
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fe61d252000)
22+
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fe61d22f000)
23+
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fe61d229000)
24+
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe61d037000)
25+
/lib64/ld-linux-x86-64.so.2 (0x00007fe61d2ee000)
26+
```
27+
1328
## Build steps
1429

1530
### Linux / MacOS
@@ -37,20 +52,9 @@ Visual Studio Code should also work well provided you have the "C/C++",
3752

3853
## Build outputs
3954

40-
The build will generate libraries compiled to `./build`
55+
The build will generate both static and dynamic libraries compiled to `./build`
4156
(or your otherwise selected CMake build directory).
4257

43-
You will find one dynamic library and depending on
44-
the operating system either one or two static libraries.
45-
46-
On platforms that support compiling with position independent code (Linux, Mac)
47-
we ship both a static library with `-fPIC` enabled and one with the option
48-
disabled. Use the former if you intend to link the static library into a dynamic
49-
library and use the latter if you intend to link it into an executable.
50-
If you intend to create your own language binding (e.g. for Python), then you
51-
probably want to use the `-fPIC` static library.
52-
On Windows there is just one static library you may use for all purposes.
53-
5458
## Running tests
5559

5660
### Unit Tests
@@ -87,3 +91,20 @@ Delete the `./build` directory.
8791
```bash
8892
$ rm -fR build # or your otherwise selected CMake build directory.
8993
```
94+
95+
## Building Rust Code
96+
97+
You may find that you need to build the Rust code directly.
98+
99+
From the root:
100+
101+
```
102+
cargo build --release --features ffi
103+
```
104+
105+
Note that this will build binaries in `./target` rather than `./build`.
106+
107+
This will also refresh the `line_sender.h` header file.
108+
109+
Call this command if you want to integrate the library within your project and
110+
you use a build system other than CMake.

CMakeLists.txt

Lines changed: 45 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,30 @@ set(CMAKE_CXX_STANDARD 17)
1616
set(CMAKE_CXX_STANDARD_REQUIRED ON)
1717
set(CMAKE_CXX_EXTENSIONS OFF)
1818

19-
set(LIB_SOURCES
20-
src/aborting_malloc.c
21-
src/line_sender.c
22-
src/mem_writer.c
23-
src/utf8.c)
19+
option(
20+
BUILD_SHARED_LIBS
21+
"Build shared library dependencies instead of static."
22+
OFF)
23+
24+
# Build static and dynamic lib written in Rust by invoking `cargo`.
25+
# Imports `questdb_client` target.
26+
add_subdirectory(corrosion)
27+
corrosion_import_crate(
28+
MANIFEST_PATH Cargo.toml
29+
FEATURES ffi
30+
LINK_AS C)
31+
target_include_directories(
32+
questdb_client INTERFACE
33+
${CMAKE_CURRENT_SOURCE_DIR}/include)
34+
if(WIN32)
35+
set_target_properties(
36+
questdb_client-shared
37+
PROPERTIES
38+
DEFINE_SYMBOL "LINESENDER_DYN_LIB")
39+
target_link_libraries(
40+
questdb_client-shared
41+
INTERFACE wsock32 ws2_32)
42+
endif(WIN32)
2443

2544
function(set_compile_flags TARGET_NAME)
2645
if(MSVC)
@@ -43,86 +62,42 @@ function(set_compile_flags TARGET_NAME)
4362
endif()
4463
endfunction()
4564

46-
# Shared Library
47-
add_library(
48-
c_questdb_client SHARED
49-
${LIB_SOURCES})
50-
target_include_directories(
51-
c_questdb_client
52-
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
53-
set_compile_flags(c_questdb_client)
54-
target_compile_definitions(
55-
c_questdb_client
56-
PUBLIC
57-
LINESENDER_DYN_LIB)
58-
if(WIN32)
59-
set_target_properties(
60-
c_questdb_client
61-
PROPERTIES
62-
DEFINE_SYMBOL "LINESENDER_EXPORTS")
63-
target_link_libraries(c_questdb_client wsock32 ws2_32)
64-
endif(WIN32)
65-
if(UNIX)
66-
target_compile_options(
67-
c_questdb_client PRIVATE
68-
-fvisibility=hidden)
69-
endif(UNIX)
70-
71-
# Static Library
72-
add_library(
73-
c_questdb_client_static STATIC
74-
${LIB_SOURCES})
75-
target_include_directories(
76-
c_questdb_client_static
77-
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
78-
set_compile_flags(c_questdb_client_static)
79-
if(WIN32)
80-
target_link_libraries(c_questdb_client_static wsock32 ws2_32)
81-
endif(WIN32)
82-
83-
# Static Library w/ -fPIC
84-
if(UNIX)
85-
add_library(
86-
c_questdb_client_static_pic STATIC
87-
${LIB_SOURCES})
88-
set_property(
89-
TARGET c_questdb_client_static_pic
90-
PROPERTY POSITION_INDEPENDENT_CODE ON)
91-
target_include_directories(
92-
c_questdb_client_static_pic
93-
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
94-
set_compile_flags(c_questdb_client_static_pic)
95-
endif(UNIX)
96-
9765
# Examples
9866
add_executable(
9967
line_sender_c_example
10068
examples/line_sender_c_example.c)
10169
target_link_libraries(
10270
line_sender_c_example
103-
c_questdb_client_static) # example depending on static lib.
71+
questdb_client)
10472
add_executable(
10573
line_sender_cpp_example
10674
examples/line_sender_cpp_example.cpp)
10775
target_link_libraries(
10876
line_sender_cpp_example
109-
c_questdb_client) # example depending on dynamic lib.
77+
questdb_client)
11078

111-
# Unit test binary.
112-
add_executable(
79+
# Unit test binaries.
80+
function(compile_test TARGET_NAME)
81+
list(POP_FRONT ARGV) # compile_test
82+
add_executable(
83+
${TARGET_NAME}
84+
${ARGV})
85+
target_link_libraries(
86+
${TARGET_NAME}
87+
questdb_client)
88+
target_include_directories(
89+
${TARGET_NAME}
90+
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
91+
set_compile_flags(${TARGET_NAME})
92+
add_test(
93+
NAME ${TARGET_NAME}
94+
COMMAND ${TARGET_NAME})
95+
endfunction()
96+
97+
compile_test(
11398
test_line_sender
11499
test/mock_server.cpp
115100
test/test_line_sender.cpp)
116-
target_link_libraries(
117-
test_line_sender
118-
c_questdb_client_static)
119-
target_include_directories(
120-
test_line_sender
121-
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
122-
set_compile_flags(test_line_sender)
123-
add_test(
124-
NAME test_line_sender
125-
COMMAND test_line_sender)
126101

127102
# System testing Python3 script.
128103
# This will download the latest QuestDB instance from Github,

Cargo.toml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
[package]
2+
name = "rs-questdb-client"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[lib]
7+
name = "questdb_client"
8+
crate-type = ["cdylib", "staticlib"]
9+
10+
[dependencies]
11+
libc = "0.2"
12+
socket2 = "0.4.4"
13+
dns-lookup = "1.0.8"
14+
15+
[target.'cfg(windows)'.dependencies]
16+
winapi = "0.3.9"
17+
18+
[build-dependencies]
19+
cbindgen = { version = "0.24.2", optional = true, default-features = false }
20+
21+
[features]
22+
# Build C buildings, but don't generate the header file.
23+
ffi = []
24+
25+
# Auto-generate the header. This is for dev-debugging-diffing only.
26+
# A hand-crafted header is easier on the eyes.
27+
gen_h = ["ffi", "cbindgen"]

DEPENDENCY.md

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -83,31 +83,25 @@ set(CMAKE_CXX_STANDARD 17)
8383
set(CMAKE_CXX_STANDARD_REQUIRED ON)
8484
set(CMAKE_CXX_EXTENSIONS OFF)
8585
86-
find_package(Git REQUIRED)
8786
include(FetchContent)
8887
8988
FetchContent_Declare(
9089
c_questdb_client_proj
9190
GIT_REPOSITORY https://github.com/questdb/c-questdb-client.git
9291
GIT_TAG CHOSEN_RELEASE_TAG) # CHANGE ME!
9392
94-
FetchContent_GetProperties(c_questdb_client_proj)
95-
if(NOT c_questdb_client_proj_POPULATED)
96-
FetchContent_Populate(c_questdb_client_proj)
97-
add_subdirectory(
98-
${c_questdb_client_proj_SOURCE_DIR}
99-
${c_questdb_client_proj_BINARY_DIR}
100-
EXCLUDE_FROM_ALL)
101-
endif()
93+
FetchContent_MakeAvailable(c_questdb_client)
10294
10395
add_executable(
10496
main
10597
main.cpp)
10698
target_link_libraries(
10799
main
108-
c_questdb_client_static)
100+
questdb_client)
109101
```
110102

103+
*Note:* By default, the library will be linked statically. Call `cmake .. -DBUILD_SHARED_LIBS=ON` to depend on the dynamic library.
104+
111105
## Option 2: CMake add_subdirectory & Git source code grafting
112106

113107
If you're using both CMake and git in your project, then you can graft this
@@ -231,7 +225,7 @@ add_executable(
231225
main.cpp)
232226
target_link_libraries(
233227
main
234-
c_questdb_client_static)
228+
questdb_client)
235229
```
236230

237231
## Option 3: Other build systems
@@ -251,6 +245,8 @@ If you use a build system other than CMake, the following tips should help you:
251245
to mark `__declspec(dllexport)`:
252246
This define should *not* be present when *using* the library.
253247

248+
*Note:* By default, the library will be linked statically. Call `cmake .. -DBUILD_SHARED_LIBS=ON` to depend on the dynamic library.
249+
254250
## Package Managers
255251

256252
If you are using a particular package manager (e.g. Conan or vcpkg), contact us

DEV_NOTES.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Developer notes
2+
3+
## CMake Integration
4+
We temporarily use a forked version of https://github.com/corrosion-rs/corrosion
5+
to enable linking the Rust crate as C rather than C++.
6+
7+
The "corrosion" directory has been added as:
8+
9+
```
10+
git subtree add --prefix corrosion https://github.com/amunra/corrosion master --squash
11+
```
12+
13+
and is being maintained as:
14+
15+
```
16+
git subtree add --prefix corrosion https://github.com/amunra/corrosion master --squash
17+
```
18+
19+
Until our outstanding pull request with the upstream project is resolved.
20+
See: https://github.com/corrosion-rs/corrosion/pull/188.
21+
22+
23+
## Building without CMake
24+
For development, you may also call `cargo build` directly.
25+
By default, this will not build the `C` FFI layer.
26+
27+
For that, call `cargo build --features ffi`.
28+
29+
If you are editing the C functions and what to see the resulting generated
30+
header file, call `cargo build --features cbindgen`.
31+
32+
Note that to reduce compile time we don't use cbindgen in the header we ship.

README.md

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,12 @@ This library makes it easy to insert data into [QuestDB](https://questdb.io/).
66
This client library implements the [InfluxDB Line Protocol](
77
https://questdb.io/docs/reference/api/ilp/overview/) (ILP) over TCP.
88

9-
* Implementation is in C11, with no dependency on the C++ standard library
10-
for simpler inclusion into your projects.
11-
* The C++ API is a header-only wrapper written in C++17.
9+
* Implementation is in Rust, with no additional
10+
[run-time or link-time dependencies](BUILD.md#pre-requisites-and-dependencies)
11+
on the C++ standard library or other libraries.
12+
* We ship both a static and a dynamic library.
13+
* The library exposes both a C and a C++17 API.
14+
* The C++ API is a header-only wrapper over the C API.
1215

1316
## Protocol
1417

@@ -21,7 +24,7 @@ Inserting data into QuestDB can be done via one of three protocols.
2124
| [PostgreSQL](https://questdb.io/docs/reference/api/postgres/) | Transaction-level | Good |
2225

2326
This library mitigates the lack of confirmation and error reporting by
24-
validating data ahead of time, before any data is sent to the database instance.
27+
validating data ahead of time before any data is sent to the database instance.
2528

2629
For example, the client library will report that a supplied string isn't encoded
2730
in UTF-8. Some issues unfortunately can't be caught by the library and require
@@ -35,8 +38,8 @@ To understand the protocol in more depth, consult the
3538

3639
## Using this Library
3740

38-
Start with the [build instructions](BUILD.md), then read guide for including
39-
this library as a [dependency to your project](DEPENDENCY.md).
41+
Start with the [build instructions](BUILD.md), then read the guide for including
42+
this library as a [dependency from your project](DEPENDENCY.md).
4043

4144
Once you've all set up, you can take a look at our examples:
4245

@@ -77,7 +80,7 @@ See a [complete example in C++](examples/line_sender_cpp_example.cpp).
7780
The API is sequentially coupled, meaning that methods need to be called in a
7881
specific order.
7982
80-
For each row you need to specify a table name and at least one symbol or
83+
For each row, you need to specify a table name and at least one symbol or
8184
column. Symbols must be specified before columns.
8285
Once you're done with a row you must add a timestamp calling `at` or `at_now`.
8386
@@ -101,7 +104,7 @@ a failure.
101104
You may then call `line_sender_error_msg(err)` and
102105
`line_sender_error_get_code(err)` to extract error details.
103106
104-
Once handled, the error object *must* be disposed by calling
107+
Once handled, the error object *must* be disposed of by calling
105108
`line_sender_error_free(err)`.
106109
107110
On error you must also call `line_sender_close(sender)`.

0 commit comments

Comments
 (0)