diff --git a/cpp/mysql/greptimedb/CMakeLists.txt b/cpp/mysql/greptimedb/CMakeLists.txt new file mode 100644 index 00000000..e720fb65 --- /dev/null +++ b/cpp/mysql/greptimedb/CMakeLists.txt @@ -0,0 +1,43 @@ +# Copyright 2026 Columnar Technologies Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +cmake_minimum_required(VERSION 3.15) +project(greptimedb_demo CXX) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +# Use conda environment paths +if(DEFINED ENV{CONDA_PREFIX}) + list(APPEND CMAKE_PREFIX_PATH "$ENV{CONDA_PREFIX}") +endif() + +find_package(Arrow REQUIRED) + +add_executable(greptimedb_demo main.cpp) + +if(DEFINED ENV{CONDA_PREFIX}) + target_include_directories(greptimedb_demo PRIVATE $ENV{CONDA_PREFIX}/include) + target_link_directories(greptimedb_demo PRIVATE $ENV{CONDA_PREFIX}/lib) +endif() + +target_link_libraries(greptimedb_demo + adbc_driver_manager + Arrow::arrow_shared +) + +target_compile_options(greptimedb_demo PRIVATE + -Wall + -Werror +) diff --git a/cpp/mysql/greptimedb/Makefile b/cpp/mysql/greptimedb/Makefile new file mode 100644 index 00000000..4fd9397c --- /dev/null +++ b/cpp/mysql/greptimedb/Makefile @@ -0,0 +1,24 @@ +# Copyright 2026 Columnar Technologies Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +CXXFLAGS = -std=c++17 -Wall -Werror -I$(CONDA_PREFIX)/include +LIBS = -L$(CONDA_PREFIX)/lib -ladbc_driver_manager -larrow -Wl,-rpath,$(CONDA_PREFIX)/lib + +greptimedb_demo: main.cpp + $(CXX) $(CXXFLAGS) -o greptimedb_demo main.cpp $(LIBS) + +clean: + rm -f greptimedb_demo + +.PHONY: clean diff --git a/cpp/mysql/greptimedb/README.md b/cpp/mysql/greptimedb/README.md new file mode 100644 index 00000000..fdc5b68b --- /dev/null +++ b/cpp/mysql/greptimedb/README.md @@ -0,0 +1,98 @@ + + +# Connecting C++ and GreptimeDB with ADBC + +## Instructions + +> [!TIP] +> If you already have a GreptimeDB instance running, skip the steps to set up and clean up GreptimeDB. + +### Prerequisites + +1. [Install dbc](https://docs.columnar.tech/dbc/getting_started/installation/) + +2. [Install miniforge](https://github.com/conda-forge/miniforge) + +3. Create and activate a new environment with the required C++ libraries: + + ```sh + mamba create -n adbc-cpp -c conda-forge cmake compilers libadbc-driver-manager libarrow + + # Initialize mamba in your shell if not already done + eval "$(mamba shell hook --shell zsh)" + mamba activate adbc-cpp + ``` + + (`cmake` is only needed if you use CMake to build the C++ program below.) + +### Set up GreptimeDB + +1. [Install Docker](https://docs.docker.com/get-started/get-docker/) + +2. Start a GreptimeDB instance: + + ```sh + docker run -d --rm --name greptime -p 4002:4002 greptime/greptimedb:v1.0.0-beta.4 standalone start --mysql-addr 0.0.0.0:4002 + ``` + +### Connect to GreptimeDB + +1. Install the MySQL ADBC driver: + + ```sh + dbc install --level user mysql + ``` + +2. Customize the C++ program `main.cpp` as needed + - Change the connection arguments in the `AdbcDatabaseSetOption()` calls + - Format `uri` according to the [DSN (Data Source Name) format used by Go-MySQL-Driver](https://pkg.go.dev/github.com/go-sql-driver/mysql#section-readme), or keep it as is + - If you changed which database you're connecting to, also change the SQL SELECT statement in `AdbcStatementSetSqlQuery()` + +3. Build and run the C++ program: + + Using Make: + ```sh + make + ./greptimedb_demo + ``` + + Or using CMake: + ```sh + cmake -B build + cmake --build build + ./build/greptimedb_demo + ``` + +### Clean up + +1. Clean build artifacts: + + Using Make: + ```sh + make clean + ``` + + Using CMake: + ```sh + rm -rf build + ``` + +2. Stop the Docker container running GreptimeDB: + + ```sh + docker stop greptime + ``` diff --git a/cpp/mysql/greptimedb/main.cpp b/cpp/mysql/greptimedb/main.cpp new file mode 100644 index 00000000..a26c38a0 --- /dev/null +++ b/cpp/mysql/greptimedb/main.cpp @@ -0,0 +1,108 @@ +// Copyright 2026 Columnar Technologies Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// For EXIT_SUCCESS +#include +// For strerror +#include +#include + +#include +#include +#include +#include + +// Error-checking helper for ADBC calls. +// Assumes that there is an AdbcError named `error` in scope. +#define CHECK_ADBC(EXPR) \ + if (AdbcStatusCode status = (EXPR); status != ADBC_STATUS_OK) { \ + if (error.message != nullptr) { \ + std::cerr << error.message << std::endl; \ + } \ + return EXIT_FAILURE; \ + } + +// Error-checking helper for ArrowArrayStream. +#define CHECK_STREAM(STREAM, EXPR) \ + if (int status = (EXPR); status != 0) { \ + std::cerr << "(" << std::strerror(status) << "): "; \ + const char *message = (STREAM).get_last_error(&(STREAM)); \ + if (message != nullptr) { \ + std::cerr << message << std::endl; \ + } else { \ + std::cerr << "(no error message)" << std::endl; \ + } \ + return EXIT_FAILURE; \ + } + +int main() { + AdbcError error = {}; + + AdbcDatabase database = {}; + CHECK_ADBC(AdbcDatabaseNew(&database, &error)); + + CHECK_ADBC(AdbcDatabaseSetOption(&database, "driver", "mysql", &error)); + CHECK_ADBC(AdbcDatabaseSetOption(&database, "uri", + "root:@tcp(localhost:4002)/public", &error)); + CHECK_ADBC(AdbcDriverManagerDatabaseSetLoadFlags( + &database, ADBC_LOAD_FLAG_DEFAULT, &error)); + CHECK_ADBC(AdbcDatabaseInit(&database, &error)); + + AdbcConnection connection = {}; + CHECK_ADBC(AdbcConnectionNew(&connection, &error)); + CHECK_ADBC(AdbcConnectionInit(&connection, &database, &error)); + + AdbcStatement statement = {}; + CHECK_ADBC(AdbcStatementNew(&connection, &statement, &error)); + + struct ArrowArrayStream stream = {}; + int64_t rows_affected = -1; + + CHECK_ADBC( + AdbcStatementSetSqlQuery(&statement, "SELECT version()", &error)); + CHECK_ADBC( + AdbcStatementExecuteQuery(&statement, &stream, &rows_affected, &error)); + + // Import stream as record batch reader + auto maybe_reader = arrow::ImportRecordBatchReader(&stream); + if (!maybe_reader.ok()) { + std::cerr << "Failed to import record batch reader: " + << maybe_reader.status().message() << std::endl; + return 1; + } + + auto reader = maybe_reader.ValueOrDie(); + + while (true) { + auto maybe_batch = reader->Next(); + if (!maybe_batch.ok()) { + std::cerr << "Error reading batch: " << maybe_batch.status().message() + << std::endl; + return 1; + } + + auto batch = maybe_batch.ValueOrDie(); + if (!batch) { + break; + } + + std::cout << batch->ToString() << std::endl; + } + + CHECK_ADBC(AdbcStatementRelease(&statement, &error)); + CHECK_ADBC(AdbcConnectionRelease(&connection, &error)); + CHECK_ADBC(AdbcDatabaseRelease(&database, &error)); + + return EXIT_SUCCESS; +} diff --git a/go/mysql/greptimedb/README.md b/go/mysql/greptimedb/README.md new file mode 100644 index 00000000..852db4e2 --- /dev/null +++ b/go/mysql/greptimedb/README.md @@ -0,0 +1,66 @@ + + +# Connecting Go and GreptimeDB with ADBC + +## Instructions + +> [!TIP] +> If you already have a GreptimeDB instance running, skip the steps to set up and clean up GreptimeDB. + +### Prerequisites + +1. [Install Go](https://go.dev/doc/install) + +2. [Install dbc](https://docs.columnar.tech/dbc/getting_started/installation/) + +### Set up GreptimeDB + +1. [Install Docker](https://docs.docker.com/get-started/get-docker/) + +2. Start a GreptimeDB instance: + + ```sh + docker run -d --rm --name greptime -p 4002:4002 greptime/greptimedb:v1.0.0-beta.4 standalone start --mysql-addr 0.0.0.0:4002 + ``` + +### Connect to GreptimeDB + +1. Install the MySQL ADBC driver: + + ```sh + dbc install mysql + ``` + +2. Customize the Go program `main.go` as needed + - Change the connection arguments in `drv.NewDatabase()` + - Format `uri` according to the [DSN (Data Source Name) format used by Go-MySQL-Driver](https://pkg.go.dev/github.com/go-sql-driver/mysql#section-readme), or keep it as is + - If you changed which database you're connecting to, also change the SQL SELECT statement in `stmt.SetSqlQuery()` + +3. Run the Go program: + + ```sh + go mod tidy + go run main.go + ``` + +### Clean up + +Stop the Docker container running GreptimeDB: + +```sh +docker stop greptime +``` diff --git a/go/mysql/greptimedb/main.go b/go/mysql/greptimedb/main.go new file mode 100644 index 00000000..f95dae8e --- /dev/null +++ b/go/mysql/greptimedb/main.go @@ -0,0 +1,69 @@ +// Copyright 2026 Columnar Technologies Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package main + +import ( + "context" + "fmt" + "log" + + "github.com/apache/arrow-adbc/go/adbc/drivermgr" +) + +func main() { + var drv drivermgr.Driver + + db, err := drv.NewDatabase(map[string]string{ + "driver": "mysql", + "uri": "root:@tcp(localhost:4002)/public", + }) + if err != nil { + log.Fatal(err) + } + defer db.Close() + + conn, err := db.Open(context.Background()) + if err != nil { + log.Fatal(err) + } + defer conn.Close() + + stmt, err := conn.NewStatement() + if err != nil { + log.Fatal(err) + } + defer stmt.Close() + + err = stmt.SetSqlQuery("SELECT version()") + if err != nil { + log.Fatal(err) + } + + stream, _, err := stmt.ExecuteQuery(context.Background()) + if err != nil { + log.Fatal(err) + } + defer stream.Release() + + // Read all record batches from the stream + for stream.Next() { + batch := stream.RecordBatch() + fmt.Println(batch) + } + + if err := stream.Err(); err != nil { + log.Fatal(err) + } +} diff --git a/java/mysql/greptimedb/README.md b/java/mysql/greptimedb/README.md new file mode 100644 index 00000000..42c51267 --- /dev/null +++ b/java/mysql/greptimedb/README.md @@ -0,0 +1,67 @@ + + +# Connecting Java and GreptimeDB with ADBC + +## Instructions + +> [!TIP] +> If you already have a GreptimeDB instance running, skip the steps to set up and clean up GreptimeDB. + +### Prerequisites + +1. [Install Java](https://www.java.com/en/download/help/download_options.html) + +2. [Install Maven](https://maven.apache.org/install.html) + +3. [Install dbc](https://docs.columnar.tech/dbc/getting_started/installation/) + +### Set up GreptimeDB + +1. [Install Docker](https://docs.docker.com/get-started/get-docker/) + +2. Start a GreptimeDB instance: + + ```sh + docker run -d --rm --name greptime -p 4002:4002 greptime/greptimedb:v1.0.0-beta.4 standalone start --mysql-addr 0.0.0.0:4002 + ``` + +### Connect to GreptimeDB + +1. Install the MySQL ADBC driver: + + ```sh + dbc install mysql + ``` + +2. Customize the Java program `src/main/java/tech/columnar/Example.java` as needed + - Change the connection arguments in the `params` map + - Format `uri` according to the [DSN (Data Source Name) format used by Go-MySQL-Driver](https://pkg.go.dev/github.com/go-sql-driver/mysql#section-readme), or keep it as is + - If you changed which database you're connecting to, also change the SQL SELECT statement in `stmt.setSqlQuery()` + +3. Compile and run the Java program: + + ```sh + mvn clean compile exec:exec + ``` + +### Clean up + +Stop the Docker container running GreptimeDB: + +```sh +docker stop greptime +``` diff --git a/java/mysql/greptimedb/pom.xml b/java/mysql/greptimedb/pom.xml new file mode 100644 index 00000000..798dc76d --- /dev/null +++ b/java/mysql/greptimedb/pom.xml @@ -0,0 +1,136 @@ + + + + 4.0.0 + + tech.columnar + adbc-quickstart-greptimedb + 1.0-SNAPSHOT + + adbc-quickstart-java-greptimedb + + + UTF-8 + 17 + tech.columnar.Example + 18.3.0 + 0.21.0 + + + + + + org.apache.arrow + arrow-bom + ${arrow.version} + pom + import + + + + + + + org.apache.arrow + arrow-memory-core + + + org.apache.arrow + arrow-memory-netty + + + org.apache.arrow + arrow-vector + + + + org.apache.arrow.adbc + adbc-core + ${adbc.version} + + + org.apache.arrow.adbc + adbc-driver-manager + ${adbc.version} + + + org.apache.arrow.adbc + adbc-driver-jni + ${adbc.version} + + + + + + + + maven-clean-plugin + 3.4.0 + + + maven-resources-plugin + 3.3.1 + + + maven-compiler-plugin + 3.13.0 + + + maven-surefire-plugin + 3.3.0 + + + maven-jar-plugin + 3.4.2 + + + maven-install-plugin + 3.1.2 + + + maven-deploy-plugin + 3.1.2 + + + maven-site-plugin + 3.12.1 + + + maven-project-info-reports-plugin + 3.6.1 + + + + + + org.codehaus.mojo + exec-maven-plugin + 3.5.1 + + java + + --add-opens=java.base/java.nio=org.apache.arrow.memory.core,ALL-UNNAMED + -classpath + + tech.columnar.Example + + + + + + diff --git a/java/mysql/greptimedb/src/main/java/tech/columnar/Example.java b/java/mysql/greptimedb/src/main/java/tech/columnar/Example.java new file mode 100644 index 00000000..ab58164f --- /dev/null +++ b/java/mysql/greptimedb/src/main/java/tech/columnar/Example.java @@ -0,0 +1,52 @@ +/* + * Copyright 2026 Columnar Technologies Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package tech.columnar; + +import java.util.HashMap; +import java.util.Map; +import org.apache.arrow.adbc.core.AdbcConnection; +import org.apache.arrow.adbc.core.AdbcDatabase; +import org.apache.arrow.adbc.core.AdbcStatement; +import org.apache.arrow.adbc.driver.jni.JniDriver; +import org.apache.arrow.adbc.drivermanager.AdbcDriverManager; +import org.apache.arrow.memory.BufferAllocator; +import org.apache.arrow.memory.RootAllocator; +import org.apache.arrow.vector.ipc.ArrowReader; + +public class Example { + private static final String DRIVER_FACTORY = "org.apache.arrow.adbc.driver.jni.JniDriverFactory"; + + public static void main(String[] args) throws Exception { + Map params = new HashMap<>(); + JniDriver.PARAM_DRIVER.set(params, "mysql"); + params.put("uri", "root:@tcp(localhost:4002)/public"); + + try (BufferAllocator allocator = new RootAllocator(); + AdbcDatabase db = + AdbcDriverManager.getInstance().connect(DRIVER_FACTORY, allocator, params); + AdbcConnection conn = db.connect(); + AdbcStatement stmt = conn.createStatement()) { + stmt.setSqlQuery("SELECT version()"); + try (AdbcStatement.QueryResult result = stmt.executeQuery()) { + ArrowReader reader = result.getReader(); + while (reader.loadNextBatch()) { + System.out.println(reader.getVectorSchemaRoot().contentToTSVString()); + } + } + } + } +} diff --git a/python/mysql/greptimedb/README.md b/python/mysql/greptimedb/README.md new file mode 100644 index 00000000..8f9fce2b --- /dev/null +++ b/python/mysql/greptimedb/README.md @@ -0,0 +1,65 @@ + + +# Connecting Python and GreptimeDB with ADBC + +## Instructions + +> [!TIP] +> If you already have a GreptimeDB instance running, skip the steps to set up and clean up GreptimeDB. + +### Prerequisites + +1. [Install uv](https://docs.astral.sh/uv/getting-started/installation/) + +2. [Install dbc](https://docs.columnar.tech/dbc/getting_started/installation/) + +### Set up GreptimeDB + +1. [Install Docker](https://docs.docker.com/get-started/get-docker/) + +2. Start a GreptimeDB instance: + + ```sh + docker run -d --rm --name greptime -p 4002:4002 greptime/greptimedb:v1.0.0-beta.4 standalone start --mysql-addr 0.0.0.0:4002 + ``` + +### Connect to GreptimeDB + +1. Install the MySQL ADBC driver: + + ```sh + dbc install mysql + ``` + +2. Customize the Python script `main.py` as needed + - Change the connection arguments in `db_kwargs` + - Format `uri` according to the [DSN (Data Source Name) format used by Go-MySQL-Driver](https://pkg.go.dev/github.com/go-sql-driver/mysql#section-readme), or keep it as is + - If you changed which database you're connecting to, also change the SQL SELECT statement in `cursor.execute()` + +3. Run the Python script: + + ```sh + uv run main.py + ``` + +### Clean up + +Stop the Docker container running GreptimeDB: + +```sh +docker stop greptime +``` diff --git a/python/mysql/greptimedb/main.py b/python/mysql/greptimedb/main.py new file mode 100644 index 00000000..5f10e92d --- /dev/null +++ b/python/mysql/greptimedb/main.py @@ -0,0 +1,31 @@ +# Copyright 2026 Columnar Technologies Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# /// script +# requires-python = ">=3.10" +# dependencies = ["adbc-driver-manager>=1.9.0", "pyarrow>=20.0.0"] +# /// + +from adbc_driver_manager import dbapi + +with ( + dbapi.connect( + driver="mysql", db_kwargs={"uri": "root:@tcp(localhost:4002)/public"} + ) as connection, + connection.cursor() as cursor, +): + cursor.execute("SELECT version()") + table = cursor.fetch_arrow_table() + +print(table) diff --git a/r/mysql/greptimedb/README.md b/r/mysql/greptimedb/README.md new file mode 100644 index 00000000..6beafc31 --- /dev/null +++ b/r/mysql/greptimedb/README.md @@ -0,0 +1,71 @@ + + +# Connecting R and GreptimeDB with ADBC + +## Instructions + +> [!TIP] +> If you already have a GreptimeDB instance running, skip the steps to set up and clean up GreptimeDB. + +### Prerequisites + +1. [Install R](https://www.r-project.org/) + +2. [Install dbc](https://docs.columnar.tech/dbc/getting_started/installation/) + +3. Install the R packages `arrow`, `adbcdrivermanager`, and `tibble`: + + ```r + install.packages(c("arrow", "adbcdrivermanager", "tibble")) + ``` + +### Set up GreptimeDB + +1. [Install Docker](https://docs.docker.com/get-started/get-docker/) + +2. Start a GreptimeDB instance: + + ```sh + docker run -d --rm --name greptime -p 4002:4002 greptime/greptimedb:v1.0.0-beta.4 standalone start --mysql-addr 0.0.0.0:4002 + ``` + +### Connect to GreptimeDB + +1. Install the MySQL ADBC driver: + + ```sh + dbc install mysql + ``` + +2. Customize the R script `main.R` as needed + - Change the connection arguments in `adbc_database_init()` + - Format `uri` according to the [DSN (Data Source Name) format used by Go-MySQL-Driver](https://pkg.go.dev/github.com/go-sql-driver/mysql#section-readme), or keep it as is + - If you changed which database you're connecting to, also change the SQL SELECT statement in `read_adbc()` + +3. Run the R script: + + ```sh + Rscript main.R + ``` + +### Clean up + +Stop the Docker container running GreptimeDB: + +```sh +docker stop greptime +``` diff --git a/r/mysql/greptimedb/main.R b/r/mysql/greptimedb/main.R new file mode 100644 index 00000000..ffd97220 --- /dev/null +++ b/r/mysql/greptimedb/main.R @@ -0,0 +1,30 @@ +# Copyright 2026 Columnar Technologies Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +library(adbcdrivermanager) + +drv <- adbc_driver("mysql") + +db <- adbc_database_init( + drv, + uri = "root:@tcp(localhost:4002)/public" +) + +con <- adbc_connection_init(db) + +con |> + read_adbc("SELECT version()") |> + tibble::as_tibble() # or: +# arrow::as_arrow_table() # to keep result in Arrow format +# arrow::as_record_batch_reader() # for larger results diff --git a/rust/mysql/greptimedb/Cargo.toml b/rust/mysql/greptimedb/Cargo.toml new file mode 100644 index 00000000..c0c68db8 --- /dev/null +++ b/rust/mysql/greptimedb/Cargo.toml @@ -0,0 +1,24 @@ +# Copyright 2026 Columnar Technologies Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +[package] +name = "greptimedb" +version = "0.1.0" +edition = "2024" + +[dependencies] +adbc_core = "0.21.0" +adbc_driver_manager = "0.21.0" +arrow = { version = "57.0.0", features = ["prettyprint"] } +arrow-array = "57.0.0" diff --git a/rust/mysql/greptimedb/README.md b/rust/mysql/greptimedb/README.md new file mode 100644 index 00000000..526fabf9 --- /dev/null +++ b/rust/mysql/greptimedb/README.md @@ -0,0 +1,65 @@ + + +# Connecting Rust and GreptimeDB with ADBC + +## Instructions + +> [!TIP] +> If you already have a GreptimeDB instance running, skip the steps to set up and clean up GreptimeDB. + +### Prerequisites + +1. [Install Rust](https://www.rust-lang.org/tools/install) + +2. [Install dbc](https://docs.columnar.tech/dbc/getting_started/installation/) + +### Set up GreptimeDB + +1. [Install Docker](https://docs.docker.com/get-started/get-docker/) + +2. Start a GreptimeDB instance: + + ```sh + docker run -d --rm --name greptime -p 4002:4002 greptime/greptimedb:v1.0.0-beta.4 standalone start --mysql-addr 0.0.0.0:4002 + ``` + +### Connect to GreptimeDB + +1. Install the MySQL ADBC driver: + + ```sh + dbc install mysql + ``` + +2. Customize the Rust program `src/main.rs` as needed + - Change the connection arguments in `opts` + - Format the URI according to the [DSN (Data Source Name) format used by Go-MySQL-Driver](https://pkg.go.dev/github.com/go-sql-driver/mysql#section-readme), or keep it as is + - If you changed which database you're connecting to, also change the SQL SELECT statement in `statement.set_sql_query()` + +3. Compile and run the Rust program: + + ```sh + cargo run + ``` + +### Clean up + +Stop the Docker container running GreptimeDB: + +```sh +docker stop greptime +``` diff --git a/rust/mysql/greptimedb/src/main.rs b/rust/mysql/greptimedb/src/main.rs new file mode 100644 index 00000000..10f6dbba --- /dev/null +++ b/rust/mysql/greptimedb/src/main.rs @@ -0,0 +1,47 @@ +// Copyright 2026 Columnar Technologies Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use adbc_core::options::{AdbcVersion, OptionDatabase}; +use adbc_core::{Connection, Database, Driver, LOAD_FLAG_DEFAULT, Statement}; +use adbc_driver_manager::ManagedDriver; +use arrow::util::pretty; +use arrow_array::RecordBatch; + +fn main() { + let mut driver = ManagedDriver::load_from_name( + "mysql", + None, + AdbcVersion::default(), + LOAD_FLAG_DEFAULT, + None, + ) + .expect("Failed to load driver"); + + let opts = [( + OptionDatabase::Uri, + "root:@tcp(localhost:4002)/public".into(), + )]; + let db = driver + .new_database_with_opts(opts) + .expect("Failed to create database handle"); + + let mut conn = db.new_connection().expect("Failed to create connection"); + + let mut statement: adbc_driver_manager::ManagedStatement = conn.new_statement().unwrap(); + statement.set_sql_query("SELECT version()").unwrap(); + let reader = statement.execute().unwrap(); + let batches: Vec = reader.collect::>().unwrap(); + + pretty::print_batches(&batches).expect("Failed to print batches"); +}