Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Creates a C SDK to interact with the server #2

Merged
merged 36 commits into from
Oct 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
92cd086
First tests building a c SDK. Time to remeber C!
auyer Sep 30, 2023
08b205c
Client, Client builder, url builder
auyer Oct 3, 2023
a6b2817
returning the reponses as *char
auyer Oct 6, 2023
83c6521
compile_flags (for clangd LSP), c11 std
auyer Oct 6, 2023
2420064
clang-tidy, clang-format + reformating with clangd
auyer Oct 6, 2023
1d31526
adds memkv_result structure to handle errors
auyer Oct 7, 2023
33fcb9d
adds Result like return value for error handling
auyer Oct 11, 2023
b925322
adds error handling to the internal string type
auyer Oct 11, 2023
13c4867
documentation on header calls
auyer Oct 11, 2023
9a4ae39
more use cases in the example
auyer Oct 11, 2023
da0b696
adds list/delete with prefix, add delete all
auyer Oct 11, 2023
ad33239
Rename main.c to example.c, set std to 23/2x
auyer Oct 13, 2023
dd48b78
adds note about the SDK in the readme
auyer Oct 13, 2023
0b32080
adds clang-tidy action
auyer Oct 13, 2023
71c3123
update action from v0.12 to v0.14
auyer Oct 13, 2023
c26aba4
use a different action for clang-tidy
auyer Oct 13, 2023
26515c6
add libcurl dep
auyer Oct 13, 2023
13e8cc0
simpler action with reviewdog
auyer Oct 13, 2023
b2e646d
adds workflow_dispatch
auyer Oct 13, 2023
a03e863
set version for action-clang-tidy
auyer Oct 13, 2023
4c296c6
install curl and libcurl in actions
auyer Oct 13, 2023
800295a
changes libcurl-dev to libcurl4-openssl-dev
auyer Oct 13, 2023
d982f9a
apt update before install
auyer Oct 13, 2023
4792456
fixes typo in sudo
auyer Oct 13, 2023
874bea3
add gitkeep int build dir
auyer Oct 13, 2023
06f61ba
fixes directories
auyer Oct 13, 2023
ad28f49
uses in build step working-directory
auyer Oct 13, 2023
d51ff57
adds missing workflow and spacing
auyer Oct 13, 2023
c680c4c
use -B instead os --build
auyer Oct 13, 2023
529dff1
fixes memory leak in string_carrier, apply style fixes
auyer Oct 15, 2023
d4ed0c7
creates memkv_execute_request for code reusability, handle more errors
auyer Oct 17, 2023
6b9c996
fixes allocation of result
auyer Oct 17, 2023
a1725d1
simplify init, fixes reallocation, removes unecessary of result
auyer Oct 17, 2023
c8a97ae
improves init_string, fixes linter warnings, make internal functions …
auyer Oct 17, 2023
d285d85
fixes workdir for clang-tidy
auyer Oct 17, 2023
ef12f64
adds c sdk build to .gitignore
auyer Oct 17, 2023
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
32 changes: 32 additions & 0 deletions .github/workflows/clang-tidy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: clang-tidy-review

on:
pull_request:
paths:
- '**.c'
- '**.h'
workflow_dispatch:

jobs:
clang-tidy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install libcurl
run: sudo apt-get update && sudo apt-get install -y curl libcurl4-openssl-dev

- name: CMake
working-directory: ./sdks/c/
env:
CC: clang
run: cmake -B ./build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON

- name: reviewdog with clang-tidy
uses: arkedge/[email protected]
with:
workdir: ./sdks/c/build/

- name: Build
working-directory: ./sdks/c/
run: cmake -S . -B ./build
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
/target
sdks/c/build
.vscode/settings.json

17 changes: 14 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ What I wanted to create:
- In the Rust programming language
- With a live feed of changes (it felt like a cool demo for my personal site)

I started implementing an http web server using Axum. I did this because I am used to working with http and rest interfaces. I might implement my own connection method, but this will be fine for now.
I started implementing an http web server using Axum. I did this because I am used to working with http and rest interfaces. I might implement my own connection protocol, but this will be fine for now.
Since I was using Axum I also added a `/metrics` endpoint for Prometheus.

The "database" part I created with a simple HashMap, and protected it behind a RWMutex.
Expand All @@ -38,5 +38,16 @@ A sample of the WAL received by a WebSocket client:
```

The live demo is available in my personal website: https://rcpassos.me/projects/kv
And the source to that is here:
https://github.com/auyer/auyer.github.io/blob/main/src/lib/services.ts
And the source for that is here:
https://github.com/auyer/auyer.github.io/blob/main/src/lib/services.js

# SDKs
I am also creating SDKs for this project using different languages.
Since the server uses REST with HTTP for the database interface, this is the main part that needs to be implemented in the SDKs.
The Live Feed is implemented using WebSockets, and is a less important feature.


| Feature/SDK | C | Rust
|---------------- |--- |------
| Rest Endpoints | x |
| Live Feed (WS) | |
57 changes: 57 additions & 0 deletions sdks/c/.clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---
Language: Cpp
# BasedOnStyle: Mozilla
AlignAfterOpenBracket: AlwaysBreak
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Right
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Inline
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
BinPackArguments: false
BinPackParameters: false
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Attach
BreakBeforeTernaryOperators: true
BreakStringLiterals: true
ColumnLimit: 120
ContinuationIndentWidth: 4
DerivePointerAlignment: false
IncludeBlocks: Preserve
IndentCaseLabels: true
IndentPPDirectives: AfterHash
IndentWidth: 4
IndentWrappedFunctionNames: true
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 100000
PointerAlignment: Right
ReflowComments: true
SortIncludes: true
SpaceAfterCStyleCast: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
TabWidth: 4
UseTab: Always
...
121 changes: 121 additions & 0 deletions sdks/c/.clang-tidy
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
---
Checks: '
-*,
clang-*,
bugprone-assert-side-effect,
bugprone-bool-pointer-implicit-conversion,
bugprone-incorrect-roundings,
bugprone-integer-division,
bugprone-macro-parentheses,
bugprone-macro-repeated-side-effects,
bugprone-misplaced-widening-cast,
bugprone-multiple-statement-macro,
bugprone-sizeof-expression,
bugprone-suspicious-enum-usage,
bugprone-suspicious-missing-comma,
bugprone-suspicious-semicolon,
bugprone-terminating-continue,
bugprone-too-small-loop-variable,
cppcoreguidelines-avoid-goto,
misc-definitions-in-headers,
misc-misplaced-const,
misc-redundant-expression,
misc-unused-parameters,
readability-braces-around-statements,
readability-const-return-type,
readability-else-after-return,
readability-function-size,
readability-implicit-bool-conversion,
readability-inconsistent-declaration-parameter-name,
readability-isolate-declaration,
readability-magic-numbers,
readability-misplaced-array-index,
readability-named-parameter,
readability-non-const-parameter,
readability-redundant-control-flow,
readability-redundant-declaration,
readability-redundant-preprocessor,
readability-uppercase-literal-suffix,
readability-identifier-naming,
'
WarningsAsErrors: '
bugprone-assert-side-effect,
bugprone-bool-pointer-implicit-conversion,
bugprone-incorrect-roundings,
bugprone-integer-division,
bugprone-macro-parentheses,
bugprone-macro-repeated-side-effects,
bugprone-misplaced-widening-cast,
bugprone-multiple-statement-macro,
bugprone-sizeof-expression,
bugprone-suspicious-enum-usage,
bugprone-suspicious-missing-comma,
bugprone-suspicious-semicolon,
bugprone-terminating-continue,
bugprone-too-small-loop-variable,
cppcoreguidelines-avoid-goto,
misc-definitions-in-headers,
misc-misplaced-const,
misc-redundant-expression,
misc-unused-parameters,
readability-braces-around-statements,
readability-const-return-type,
readability-else-after-return,
readability-function-size,
readability-implicit-bool-conversion,
readability-inconsistent-declaration-parameter-name,
readability-isolate-declaration,
readability-magic-numbers,
readability-misplaced-array-index,
readability-named-parameter,
readability-non-const-parameter,
readability-redundant-control-flow,
readability-redundant-declaration,
readability-redundant-preprocessor,
readability-uppercase-literal-suffix,
# readability-identifier-naming,
'

# From the docs: "Output warnings from headers matching this filter"
# But the goal should be to exclude(!) the headers for which clang-tidy is not called,
# e.g., for naming convention checks. DO NOT USE this field if you don't want to analyze
# header files just because they're included (seems to work).
# HeaderFilterRegex: '$'
# https://github.com/Kitware/CMake/blob/master/.clang-tidy
HeaderFilterRegex: '.*\.(h|hxx|cxx)$'
AnalyzeTemporaryDtors: false
FormatStyle: none
User: martin
CheckOptions:
- { key: bugprone-assert-side-effect.AssertMacros, value: assert }
- { key: bugprone-assert-side-effect.CheckFunctionCalls, value: '0' }
- { key: bugprone-misplaced-widening-cast.CheckImplicitCasts, value: '1' }
- { key: bugprone-sizeof-expression.WarnOnSizeOfConstant, value: '1' }
- { key: bugprone-sizeof-expression.WarnOnSizeOfIntegerExpression, value: '1' }
- { key: bugprone-sizeof-expression.WarnOnSizeOfThis, value: '1' }
- { key: bugprone-sizeof-expression.WarnOnSizeOfCompareToConstant, value: '1' }
- { key: bugprone-suspicious-enum-usage.StrictMode, value: '0' }
- { key: bugprone-suspicious-missing-comma.MaxConcatenatedTokens, value: '5' }
- { key: bugprone-suspicious-missing-comma.RatioThreshold, value: '0.200000' }
- { key: bugprone-suspicious-missing-comma.SizeThreshold, value: '5' }
- { key: misc-definitions-in-headers.HeaderFileExtensions, value: ',h,hh,hpp,hxx' }
- { key: misc-definitions-in-headers.UseHeaderFileExtension, value: '1' }
- { key: readability-braces-around-statements.ShortStatementLines, value: '1' }
- { key: readability-function-size.LineThreshold, value: '500' }
- { key: readability-function-size.StatementThreshold, value: '800' }
- { key: readability-function-size.ParameterThreshold, value: '10' }
- { key: readability-function-size.NestingThreshold, value: '6' }
- { key: readability-function-size.VariableThreshold, value: '15' }
- { key: readability-implicit-bool-conversion.AllowIntegerConditions, value: '0' }
- { key: readability-implicit-bool-conversion.AllowPointerConditions, value: '0' }
- { key: readability-implicit-bool-conversion.AllowPointerConditions, value: '0' }
- { key: readability-inconsistent-declaration-parameter-name.IgnoreMacros, value: '1' }
- { key: readability-inconsistent-declaration-parameter-name.Strict, value: '1' }
- { key: readability-magic-numbers.IgnoredFloatingPointValues, value: '1.0;100.0;' }
- { key: readability-magic-numbers.IgnoredIntegerValues, value: '1;2;3;4;' }
- { key: readability-magic-numbers.IgnorePowersOf2IntegerValues, value: '0' }
- { key: readability-magic-numbers.IgnoreAllFloatingPointValues, value: '0' }
- { key: readability-redundant-declaration.IgnoreMacros, value: '1' }
- { key: readability-redundant-function-ptr-dereference, value: '1' }
- { key: readability-uppercase-literal-suffix.IgnoreMacros, value: '0' }
- { key: readability-uppercase-literal-suffix.IgnoreMacros, value: '0' }
17 changes: 17 additions & 0 deletions sdks/c/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
cmake_minimum_required(VERSION 3.27.6)

project(MemoryKV)

add_executable(${PROJECT_NAME} example.c)

set_property(TARGET ${PROJECT_NAME} PROPERTY C_STANDARD 23)

find_package(PkgConfig REQUIRED)
pkg_check_modules(libcurl REQUIRED IMPORTED_TARGET libcurl>=7.17.0)

add_subdirectory(libMemoryKV)

target_include_directories(${PROJECT_NAME} PUBLIC libMemoryKV/)
target_link_directories(${PROJECT_NAME} PUBLIC libMemoryKV/)

target_link_libraries(${PROJECT_NAME} PUBLIC PkgConfig::libcurl libMemoryKV)
5 changes: 5 additions & 0 deletions sdks/c/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
cmake:
cmake -S . -B build

cmake_make:
cd build && make
Empty file added sdks/c/build/.gitkeep
Empty file.
3 changes: 3 additions & 0 deletions sdks/c/compile_flags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
-I./libMemoryKV
-llibMemoryKV
-std=c2x
95 changes: 95 additions & 0 deletions sdks/c/example.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#include <curl/curl.h>
#include <libMemoryKV.h>
#include <stdio.h>
#include <stdlib.h>

void print_memkv_result(memkv_result *response) {
if (!response) {
fprintf(stderr, "Error: response is NULL\n");

} else if (response->success) {
printf("Success! Result: %s\n", response->result);
} else {
fprintf(stderr, "Error: %s\n", response->error);
}
free(response);
}

int main(void) {
memkv_client *client;

client = memkv_client_new("http://localhost:8080");

memkv_result *response;

char key[] = "c_sdk";
char key2[] = "c_sdk2";
char key3[] = "a_sdk";

fprintf(stdout, "This example will create, and delete in 3 keys: %s, %s and %s\n", key, key2, key3);

// put key
static const char put_body[] = "{"
" \"name\" : \"MemoryKV Example Body\","
" \"content\" : \"json\""
"}";

fprintf(stdout, "\nPut Key '%s'\n", key);
response = memkv_put_key(client, key, put_body);
print_memkv_result(response);

// list key
fprintf(stdout, "\nList Keys\n");
response = memkv_list_keys(client);
print_memkv_result(response);

// get key
fprintf(stdout, "\nGet Key '%s'\n", key);
response = memkv_get_key(client, key);
print_memkv_result(response);

fprintf(stdout, "\nPut Key '%s'\n", key2);
response = memkv_put_key(client, key2, put_body);
print_memkv_result(response);

fprintf(stdout, "\nPut Key '%s'\n", key3);
response = memkv_put_key(client, key3, put_body);
print_memkv_result(response);

fprintf(stdout, "\nPut Key '%s' (again)\n", key3);
response = memkv_put_key(client, key3, put_body);
print_memkv_result(response);

char prefix[] = "c";

fprintf(stdout, "\nList Keys With Prefix '%s'\n", prefix);
response = memkv_list_keys_with_prefix(client, prefix);
print_memkv_result(response);

prefix[0] = 'a';
fprintf(stdout, "\nList Keys With Prefix '%s'\n", prefix);
response = memkv_list_keys_with_prefix(client, prefix);
print_memkv_result(response);

// delete key
prefix[0] = 'c';
fprintf(stdout, "\nMaking a delete Key Request with Prefix '%s'\n", prefix);
response = memkv_delete_keys_with_prefix(client, prefix);
print_memkv_result(response);

// delete all keys
fprintf(stdout, "\nDelete all Keys\n");
response = memkv_delete_all_keys(client);
print_memkv_result(response);

fprintf(stdout, "\nMaking a delete Key '%s'\n", key3);
response = memkv_delete_key(client, key3);
print_memkv_result(response);

// list key
fprintf(stdout, "\nList Keys\n");
response = memkv_list_keys(client);
print_memkv_result(response);

free(client);
}
6 changes: 6 additions & 0 deletions sdks/c/libMemoryKV/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
add_library(libMemoryKV libMemoryKV.c)

find_package(PkgConfig REQUIRED)
pkg_check_modules(libcurl REQUIRED IMPORTED_TARGET libcurl>=7.17.0)

target_link_libraries(${PROJECT_NAME} PUBLIC PkgConfig::libcurl)
Loading
Loading