Skip to content

Commit 2f2a301

Browse files
committed
Initial commit, very early version of the implementation.
1 parent ff4729c commit 2f2a301

17 files changed

+4030
-0
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,5 @@
2222
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
2323
hs_err_pid*
2424
replay_pid*
25+
/cmake-build-debug/
26+
*.lst

CMakeLists.txt

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
cmake_minimum_required(VERSION 3.10)
2+
project(chdb_java)
3+
4+
set(CMAKE_CXX_STANDARD 17)
5+
set(CMAKE_CXX_STANDARD_REQUIRED True)
6+
7+
# Set the path to the shared library and header files
8+
set(LIBRARY_PATH "${CMAKE_SOURCE_DIR}/")
9+
set(HEADER_PATH "${CMAKE_SOURCE_DIR}/src")
10+
11+
# Find the shared library
12+
find_library(CHDB_LIB NAMES chdb PATHS ${LIBRARY_PATH})
13+
14+
# Include the header files
15+
include_directories(${HEADER_PATH})
16+
17+
# Add the source files
18+
set(SOURCE_FILES src/jni/chdb_jni.cpp)
19+
20+
# Add the shared library
21+
add_library(chdbjni SHARED ${SOURCE_FILES})
22+
23+
set_target_properties(chdbjni PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${LIBRARY_PATH})
24+
25+
# Link the shared library
26+
target_link_libraries(chdbjni ${CHDB_LIB})

build_mac.sh

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/bin/bash
2+
3+
# Set relative paths
4+
SOURCE_DIR=$(dirname "$0")
5+
BUILD_DIR="$SOURCE_DIR/cmake-build-debug"
6+
7+
# Run cmake to configure the project
8+
/opt/homebrew/bin/cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_MAKE_PROGRAM=/opt/homebrew/bin/ninja -G Ninja -S "$SOURCE_DIR" -B "$BUILD_DIR"
9+
10+
# Build the project
11+
/opt/homebrew/bin/cmake --build "$BUILD_DIR" --target chdbjni -j 12

pom.xml

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<groupId>org.chdb</groupId>
8+
<artifactId>chdb-java</artifactId>
9+
<version>1.0-SNAPSHOT</version>
10+
11+
<properties>
12+
<maven.compiler.source>22</maven.compiler.source>
13+
<maven.compiler.target>22</maven.compiler.target>
14+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
15+
</properties>
16+
17+
<dependencies>
18+
19+
<!-- JUnit 5 dependency -->
20+
<dependency>
21+
<groupId>org.junit.jupiter</groupId>
22+
<artifactId>junit-jupiter-engine</artifactId>
23+
<version>5.8.1</version>
24+
<scope>test</scope>
25+
</dependency>
26+
</dependencies>
27+
28+
<build>
29+
<plugins>
30+
<!-- Other plugins -->
31+
32+
<!-- Surefire plugin to run JUnit 5 tests -->
33+
<plugin>
34+
<groupId>org.apache.maven.plugins</groupId>
35+
<artifactId>maven-surefire-plugin</artifactId>
36+
<version>2.22.2</version>
37+
<configuration>
38+
<includes>
39+
<include>**/*Test.java</include>
40+
</includes>
41+
</configuration>
42+
</plugin>
43+
</plugins>
44+
</build>
45+
46+
</project>
47+

src/jni/chdb.h

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#pragma once
2+
3+
#ifdef __cplusplus
4+
# include <cstddef>
5+
# include <cstdint>
6+
extern "C" {
7+
#else
8+
# include <stddef.h>
9+
# include <stdint.h>
10+
#endif
11+
12+
#define CHDB_EXPORT __attribute__((visibility("default")))
13+
struct local_result
14+
{
15+
char * buf;
16+
size_t len;
17+
void * _vec; // std::vector<char> *, for freeing
18+
double elapsed;
19+
uint64_t rows_read;
20+
uint64_t bytes_read;
21+
};
22+
23+
#ifdef __cplusplus
24+
struct local_result_v2
25+
{
26+
char * buf = nullptr;
27+
size_t len = 0;
28+
void * _vec = nullptr; // std::vector<char> *, for freeing
29+
double elapsed = 0.0;
30+
uint64_t rows_read = 0;
31+
uint64_t bytes_read = 0;
32+
char * error_message = nullptr;
33+
};
34+
#else
35+
struct local_result_v2
36+
{
37+
char * buf;
38+
size_t len;
39+
void * _vec; // std::vector<char> *, for freeing
40+
double elapsed;
41+
uint64_t rows_read;
42+
uint64_t bytes_read;
43+
char * error_message;
44+
};
45+
#endif
46+
47+
CHDB_EXPORT struct local_result * query_stable(int argc, char ** argv);
48+
CHDB_EXPORT void free_result(struct local_result * result);
49+
50+
CHDB_EXPORT struct local_result_v2 * query_stable_v2(int argc, char ** argv);
51+
CHDB_EXPORT void free_result_v2(struct local_result_v2 * result);
52+
53+
#ifdef __cplusplus
54+
}
55+
#endif

src/jni/chdb_jni.cpp

+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
#include "chdb_jni.h"
2+
#include "chdb.h"
3+
#include <string>
4+
#include <vector>
5+
#include <iostream>
6+
7+
local_result_v2 * queryToBuffer(
8+
const std::string & queryStr,
9+
const std::string & output_format = "CSV",
10+
const std::string & path = {},
11+
const std::string & udfPath = {})
12+
{
13+
std::vector<std::string> argv = {"clickhouse", "--multiquery"};
14+
15+
if (output_format == "Debug" || output_format == "debug")
16+
{
17+
argv.push_back("--verbose");
18+
argv.push_back("--log-level=trace");
19+
argv.push_back("--output-format=CSV");
20+
}
21+
else
22+
{
23+
argv.push_back("--output-format=" + output_format);
24+
}
25+
26+
if (!path.empty())
27+
{
28+
argv.push_back("--path=" + path);
29+
}
30+
31+
argv.push_back("--query=" + queryStr);
32+
33+
if (!udfPath.empty())
34+
{
35+
argv.push_back("--");
36+
argv.push_back("--user_scripts_path=" + udfPath);
37+
argv.push_back("--user_defined_executable_functions_config=" + udfPath + "/*.xml");
38+
}
39+
40+
std::vector<char *> argv_char;
41+
for (auto & arg : argv)
42+
{
43+
argv_char.push_back(&arg[0]);
44+
}
45+
argv_char.push_back(nullptr);
46+
47+
return query_stable_v2(static_cast<int>(argv_char.size() - 1), argv_char.data());
48+
}
49+
50+
51+
JNIEXPORT jobject JNICALL Java_org_chdb_jdbc_ChdbJniUtil_executeQuery(JNIEnv *env, jclass clazz, jstring query) {
52+
// 1. Convert Java String to C++ string
53+
54+
std::cout << "call func: ChdbJniUtil_executeQuery!" << std::endl;
55+
56+
const char *queryStr = env->GetStringUTFChars(query, nullptr);
57+
if (queryStr == nullptr) {
58+
std::cerr << "Error: Failed to convert Java string to C++ string" << std::endl;
59+
return nullptr;
60+
}
61+
62+
// 2. Call the native query function
63+
local_result_v2 *result = queryToBuffer(queryStr);
64+
65+
// 3. Release the Java string resources
66+
env->ReleaseStringUTFChars(query, queryStr);
67+
68+
// 4. Check if the result is null (indicates an error)
69+
if (result == nullptr) {
70+
std::cerr << "Error: result is null" << std::endl;
71+
return nullptr;
72+
}
73+
74+
// 5. Find the Java class and its constructor
75+
jclass resultClass = env->FindClass("org/chdb/jdbc/LocalResultV2");
76+
if (resultClass == nullptr) {
77+
std::cerr << "Error: resultClass is null" << std::endl;
78+
free_result_v2(result); // Ensure to free the result even on error
79+
return nullptr;
80+
}
81+
82+
jmethodID constructor = env->GetMethodID(resultClass, "<init>", "(Ljava/nio/ByteBuffer;JJDLjava/lang/String;)V");
83+
if (constructor == nullptr) {
84+
std::cerr << "Error: constructor is null" << std::endl;
85+
free_result_v2(result); // Ensure to free the result even on error
86+
return nullptr;
87+
}
88+
89+
// 6. Create a direct ByteBuffer for the result buffer
90+
jobject buffer = env->NewDirectByteBuffer(result->buf, result->len);
91+
if (buffer == nullptr) {
92+
std::cerr << "Error: Failed to create ByteBuffer" << std::endl;
93+
free_result_v2(result);
94+
return nullptr;
95+
}
96+
97+
// 7. Create the Java String for the error message, if present
98+
jstring errorMessage = result->error_message ? env->NewStringUTF(result->error_message) : nullptr;
99+
100+
// 8. Create a new Java object to hold the result
101+
jobject resultObj = env->NewObject(resultClass, constructor, buffer, result->rows_read, result->bytes_read, result->elapsed, errorMessage);
102+
if (resultObj == nullptr) {
103+
std::cerr << "Error: Failed to create result object" << std::endl;
104+
free_result_v2(result);
105+
return nullptr;
106+
}
107+
108+
// 9. Free the native result structure
109+
free_result_v2(result);
110+
111+
// 10. Return the Java object
112+
return resultObj;
113+
}

src/jni/chdb_jni.h

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#pragma once
2+
3+
#include "jni.h"
4+
#include "chdb.h"
5+
6+
#ifdef __cplusplus
7+
extern "C" {
8+
#endif
9+
10+
JNIEXPORT jobject JNICALL Java_org_chdb_jdbc_ChdbJniUtil_executeQuery(JNIEnv *, jclass, jstring);
11+
//JNIEXPORT jstring JNICALL Java_org_chdb_jdbc_ChdbJniUtil_executeQuery(JNIEnv *, jclass, jstring);
12+
13+
#ifdef __cplusplus
14+
}
15+
#endif

0 commit comments

Comments
 (0)