diff --git a/cpp/mysql/oceanbase/CMakeLists.txt b/cpp/mysql/oceanbase/CMakeLists.txt new file mode 100644 index 00000000..4ee1e219 --- /dev/null +++ b/cpp/mysql/oceanbase/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(mysql_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(mysql_demo main.cpp) + +if(DEFINED ENV{CONDA_PREFIX}) + target_include_directories(mysql_demo PRIVATE $ENV{CONDA_PREFIX}/include) + target_link_directories(mysql_demo PRIVATE $ENV{CONDA_PREFIX}/lib) +endif() + +target_link_libraries(mysql_demo + adbc_driver_manager + Arrow::arrow_shared +) + +target_compile_options(mysql_demo PRIVATE + -Wall + -Werror +) diff --git a/cpp/mysql/oceanbase/Makefile b/cpp/mysql/oceanbase/Makefile new file mode 100644 index 00000000..c7d03051 --- /dev/null +++ b/cpp/mysql/oceanbase/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 + +mysql_demo: main.cpp + $(CXX) $(CXXFLAGS) -o mysql_demo main.cpp $(LIBS) + +clean: + rm -f mysql_demo + +.PHONY: clean diff --git a/cpp/mysql/oceanbase/README.md b/cpp/mysql/oceanbase/README.md new file mode 100644 index 00000000..61109b90 --- /dev/null +++ b/cpp/mysql/oceanbase/README.md @@ -0,0 +1,98 @@ + + +# Connecting C++ and OceanBase Database with ADBC + +## Instructions + +> [!TIP] +> If you already have an OceanBase Database instance running, skip the steps to set up and clean up OceanBase Database. + +### 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 OceanBase Database + +1. [Install Docker](https://docs.docker.com/get-started/get-docker/) + +2. Start an OceanBase Database instance: + + ```sh + docker run -d --rm -p 2881:2881 --name obstandalone -e MODE=MINI -d quay.io/oceanbase/oceanbase-ce + ``` + +### Connect to OceanBase Database + +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 + ./mysql_demo + ``` + + Or using CMake: + ```sh + cmake -B build + cmake --build build + ./build/mysql_demo + ``` + +### Clean up + +1. Clean build artifacts: + + Using Make: + ```sh + make clean + ``` + + Using CMake: + ```sh + rm -rf build + ``` + +2. Stop the Docker container running OceanBase Database: + + ```sh + docker stop obstandalone + ``` diff --git a/cpp/mysql/oceanbase/main.cpp b/cpp/mysql/oceanbase/main.cpp new file mode 100644 index 00000000..20b511d3 --- /dev/null +++ b/cpp/mysql/oceanbase/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:2881)/oceanbase", &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/oceanbase/README.md b/go/mysql/oceanbase/README.md new file mode 100644 index 00000000..dd9c65ba --- /dev/null +++ b/go/mysql/oceanbase/README.md @@ -0,0 +1,66 @@ + + +# Connecting Go and OceanBase Database with ADBC + +## Instructions + +> [!TIP] +> If you already have an OceanBase Database instance running, skip the steps to set up and clean up OceanBase Database. + +### Prerequisites + +1. [Install Go](https://go.dev/doc/install) + +2. [Install dbc](https://docs.columnar.tech/dbc/getting_started/installation/) + +### Set up OceanBase Database + +1. [Install Docker](https://docs.docker.com/get-started/get-docker/) + +2. Start an OceanBase Database instance: + + ```sh + docker run -d --rm -p 2881:2881 --name obstandalone -e MODE=MINI -d quay.io/oceanbase/oceanbase-ce + ``` + +### Connect to OceanBase Database + +1. Install the MySQL ADBC driver: + + ```sh + dbc install mysql + ``` + +2. Customize the Go program `main.go` as needed + - Change the connection arguments in the `NewDatabase()` call + - 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 OceanBase Database: + +```sh +docker stop obstandalone +``` diff --git a/go/mysql/oceanbase/main.go b/go/mysql/oceanbase/main.go new file mode 100644 index 00000000..2850424f --- /dev/null +++ b/go/mysql/oceanbase/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:2881)/oceanbase", + }) + 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/oceanbase/README.md b/java/mysql/oceanbase/README.md new file mode 100644 index 00000000..e762e9d0 --- /dev/null +++ b/java/mysql/oceanbase/README.md @@ -0,0 +1,65 @@ + + +# Connecting Java and OceanBase Database with ADBC + +## Instructions + +> [!TIP] +> If you already have an OceanBase Database instance running, skip the steps to set up and clean up OceanBase Database. + +### Prerequisites + +1. [Install Maven](https://maven.apache.org/install.html) + +2. [Install dbc](https://docs.columnar.tech/dbc/getting_started/installation/) + +### Set up OceanBase Database + +1. [Install Docker](https://docs.docker.com/get-started/get-docker/) + +2. Start an OceanBase Database instance: + + ```sh + docker run -d --rm -p 2881:2881 --name obstandalone -e MODE=MINI -d quay.io/oceanbase/oceanbase-ce + ``` + +### Connect to OceanBase Database + +1. Install the MySQL ADBC driver: + + ```sh + dbc install mysql + ``` + +2. Customize the `main` method in `Example.java` + - Change the connection arguments in the `params.put()` 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 `stmt.setSqlQuery()` + +3. Run the Java program: + + ```sh + mvn compile exec:exec + ``` + +### Clean up + +Stop the Docker container running OceanBase Database: + +```sh +docker stop obstandalone +``` diff --git a/java/mysql/oceanbase/pom.xml b/java/mysql/oceanbase/pom.xml new file mode 100644 index 00000000..967863f8 --- /dev/null +++ b/java/mysql/oceanbase/pom.xml @@ -0,0 +1,136 @@ + + + + 4.0.0 + + tech.columnar + adbc-quickstart-mysql + 1.0-SNAPSHOT + + adbc-quickstart-java-mysql + + + 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/oceanbase/src/main/java/tech/columnar/Example.java b/java/mysql/oceanbase/src/main/java/tech/columnar/Example.java new file mode 100644 index 00000000..6d414ce3 --- /dev/null +++ b/java/mysql/oceanbase/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:2881)/oceanbase"); + + 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/oceanbase/README.md b/python/mysql/oceanbase/README.md new file mode 100644 index 00000000..ed3e9ed3 --- /dev/null +++ b/python/mysql/oceanbase/README.md @@ -0,0 +1,65 @@ + + +# Connecting Python and OceanBase Database with ADBC + +## Instructions + +> [!TIP] +> If you already have an OceanBase Database instance running, skip the steps to set up and clean up OceanBase Database. + +### 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 OceanBase Database + +1. [Install Docker](https://docs.docker.com/get-started/get-docker/) + +2. Start an OceanBase Database instance: + + ```sh + docker run -d --rm -p 2881:2881 --name obstandalone -e MODE=MINI -d quay.io/oceanbase/oceanbase-ce + ``` + +### Connect to OceanBase Database + +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 OceanBase Database: + +```sh +docker stop obstandalone +``` diff --git a/python/mysql/oceanbase/main.py b/python/mysql/oceanbase/main.py new file mode 100644 index 00000000..40041a7a --- /dev/null +++ b/python/mysql/oceanbase/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:2881)/oceanbase"} + ) as connection, + connection.cursor() as cursor, +): + cursor.execute("SELECT version()") + table = cursor.fetch_arrow_table() + +print(table) diff --git a/r/mysql/oceanbase/README.md b/r/mysql/oceanbase/README.md new file mode 100644 index 00000000..cbd26798 --- /dev/null +++ b/r/mysql/oceanbase/README.md @@ -0,0 +1,71 @@ + + +# Connecting R and OceanBase Database with ADBC + +## Instructions + +> [!TIP] +> If you already have an OceanBase Database instance running, skip the steps to set up and clean up OceanBase Database. + +### Prerequisites + +1. [Install R](https://www.r-project.org/) + +2. [Install dbc](https://docs.columnar.tech/dbc/getting_started/installation/) + +3. Install R packages `adbcdrivermanager`, `arrow`, and `tibble`: + + ```r + install.packages(c("adbcdrivermanager", "arrow", "tibble")) + ``` + +### Set up OceanBase Database + +1. [Install Docker](https://docs.docker.com/get-started/get-docker/) + +2. Start an OceanBase Database instance: + + ```sh + docker run -d --rm -p 2881:2881 --name obstandalone -e MODE=MINI -d quay.io/oceanbase/oceanbase-ce + ``` + +### Connect to OceanBase Database + +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 OceanBase Database: + +```sh +docker stop obstandalone +``` diff --git a/r/mysql/oceanbase/main.R b/r/mysql/oceanbase/main.R new file mode 100644 index 00000000..aafe3570 --- /dev/null +++ b/r/mysql/oceanbase/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:2881)/oceanbase" +) + +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/oceanbase/Cargo.toml b/rust/mysql/oceanbase/Cargo.toml new file mode 100644 index 00000000..5ecbd4e4 --- /dev/null +++ b/rust/mysql/oceanbase/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 = "oceanbase" +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/oceanbase/README.md b/rust/mysql/oceanbase/README.md new file mode 100644 index 00000000..9eb2a5a6 --- /dev/null +++ b/rust/mysql/oceanbase/README.md @@ -0,0 +1,65 @@ + + +# Connecting Rust and OceanBase Database with ADBC + +## Instructions + +> [!TIP] +> If you already have an OceanBase Database instance running, skip the steps to set up and clean up OceanBase Database. + +### Prerequisites + +1. [Install Rust](https://www.rust-lang.org/tools/install) + +2. [Install dbc](https://docs.columnar.tech/dbc/getting_started/installation/) + +### Set up OceanBase Database + +1. [Install Docker](https://docs.docker.com/get-started/get-docker/) + +2. Start an OceanBase Database instance: + + ```sh + docker run -d --rm -p 2881:2881 --name obstandalone -e MODE=MINI -d quay.io/oceanbase/oceanbase-ce + ``` + +### Connect to OceanBase Database + +1. Install the MySQL ADBC driver: + + ```sh + dbc install mysql + ``` + +2. Customize `src/main.rs` as needed + - Change the connection arguments in `opts` + - Format `OptionDatabase::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. Run the Rust program: + + ```sh + cargo run + ``` + +### Clean up + +Stop the Docker container running OceanBase Database: + +```sh +docker stop obstandalone +``` diff --git a/rust/mysql/oceanbase/src/main.rs b/rust/mysql/oceanbase/src/main.rs new file mode 100644 index 00000000..f43a14e7 --- /dev/null +++ b/rust/mysql/oceanbase/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:2881)/oceanbase".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"); +}