From 4396ca338f8e8f807d8a4c01682b35e6844c6753 Mon Sep 17 00:00:00 2001 From: He Wang Date: Wed, 3 Apr 2024 13:25:04 +0800 Subject: [PATCH] refactor: modify project structure and add github workflow (#25) * modify project structure and add github workflow for java example * modify group name * move yml to workflows dir * fix image name * update java example * update java docs * update golang example * modify example file name * remove assert * update python example * update ci config * remove branch filter * update readme --- .github/workflows/ci.yml | 87 ++++++++++++++++++ .gitpod.yml | 12 --- README-CN.md | 64 +------------ README.md | 62 +------------ examples/driver/golang-go-sql-driver/run.sh | 3 - .../java-mysql-connector-java/README-CN.md | 83 ----------------- .../java-mysql-connector-java/README.md | 83 ----------------- .../driver/java-mysql-connector-java/run.sh | 2 - .../oceanbase/example/MySqlConnectorTest.java | 84 ----------------- examples/driver/java-oceanbase-client/run.sh | 2 - .../example/OceanBaseClientTest.java | 84 ----------------- .../go-sql-driver}/README-CN.md | 4 +- .../go-sql-driver}/README.md | 6 +- .../go-sql-driver/example.go | 51 ++++------ .../go-sql-driver}/go.mod | 0 .../go-sql-driver}/go.sum | 0 ob-example-golang/go-sql-driver/run.sh | 3 + .../mysql-connector-java/README-CN.md | 77 ++++++++++++++++ .../mysql-connector-java/README.md | 77 ++++++++++++++++ .../mysql-connector-java}/pom.xml | 1 - ob-example-java/mysql-connector-java/run.sh | 2 + .../oceanbase/example/MySqlConnectorTest.java | 49 ++++++++++ .../oceanbase-client}/README-CN.md | 20 ++-- .../oceanbase-client}/README.md | 20 ++-- .../oceanbase-client}/pom.xml | 3 +- ob-example-java/oceanbase-client/run.sh | 3 + .../example/InsertAndSelectExample.java | 9 +- .../example/OceanBaseClientTest.java | 50 ++++++++++ .../sveltekit}/.gitignore | 0 .../sveltekit}/README.md | 0 .../sveltekit}/jsconfig.json | 0 .../sveltekit}/package-lock.json | 0 .../sveltekit}/package.json | 0 .../sveltekit}/postcss.config.cjs | 0 .../sveltekit}/src/app.css | 0 .../sveltekit}/src/app.html | 0 .../sveltekit}/src/components/Auth.svelte | 0 .../sveltekit}/src/components/Icons.svelte | 0 .../sveltekit}/src/components/Navbar.svelte | 0 .../sveltekit}/src/components/Todo.svelte | 0 .../sveltekit}/src/components/TodoForm.svelte | 0 .../sveltekit}/src/global.d.ts | 0 .../sveltekit}/src/routes/__layout.svelte | 0 .../sveltekit}/src/routes/api/todos/[id].js | 0 .../sveltekit}/src/routes/api/todos/index.js | 0 .../sveltekit}/src/routes/index.svelte | 0 .../sveltekit}/src/stores/authStore.js | 0 .../sveltekit}/src/stores/todoStore.js | 0 .../sveltekit}/src/styles/tailwind-output.css | 0 .../sveltekit}/src/styles/tailwind.css | 0 .../sveltekit}/static/favicon.png | Bin .../sveltekit}/svelte.config.js | 0 .../sveltekit}/tailwind.config.cjs | 0 .../pymysql}/README-CN.md | 4 +- .../pymysql}/README.md | 4 +- .../pymysql/example.py | 30 +++--- .../pymysql}/requirements.txt | 0 .../pymysql}/run.sh | 2 +- tests/sql/test.sql | 8 -- tools/gitpod/banner.txt | 7 -- tools/gitpod/boot.png | Bin 93679 -> 0 bytes tools/gitpod/init.sh | 15 --- 62 files changed, 431 insertions(+), 580 deletions(-) create mode 100644 .github/workflows/ci.yml delete mode 100644 .gitpod.yml delete mode 100644 examples/driver/golang-go-sql-driver/run.sh delete mode 100644 examples/driver/java-mysql-connector-java/README-CN.md delete mode 100644 examples/driver/java-mysql-connector-java/README.md delete mode 100644 examples/driver/java-mysql-connector-java/run.sh delete mode 100644 examples/driver/java-mysql-connector-java/src/main/java/com/oceanbase/example/MySqlConnectorTest.java delete mode 100644 examples/driver/java-oceanbase-client/run.sh delete mode 100644 examples/driver/java-oceanbase-client/src/main/java/com/oceanbase/example/OceanBaseClientTest.java rename {examples/driver/golang-go-sql-driver => ob-example-golang/go-sql-driver}/README-CN.md (88%) rename {examples/driver/golang-go-sql-driver => ob-example-golang/go-sql-driver}/README.md (88%) rename examples/driver/golang-go-sql-driver/Test.go => ob-example-golang/go-sql-driver/example.go (54%) rename {examples/driver/golang-go-sql-driver => ob-example-golang/go-sql-driver}/go.mod (100%) rename {examples/driver/golang-go-sql-driver => ob-example-golang/go-sql-driver}/go.sum (100%) create mode 100644 ob-example-golang/go-sql-driver/run.sh create mode 100644 ob-example-java/mysql-connector-java/README-CN.md create mode 100644 ob-example-java/mysql-connector-java/README.md rename {examples/driver/java-mysql-connector-java => ob-example-java/mysql-connector-java}/pom.xml (91%) create mode 100644 ob-example-java/mysql-connector-java/run.sh create mode 100644 ob-example-java/mysql-connector-java/src/main/java/com/oceanbase/example/MySqlConnectorTest.java rename {examples/driver/java-oceanbase-client => ob-example-java/oceanbase-client}/README-CN.md (75%) rename {examples/driver/java-oceanbase-client => ob-example-java/oceanbase-client}/README.md (76%) rename {examples/driver/java-oceanbase-client => ob-example-java/oceanbase-client}/pom.xml (88%) create mode 100644 ob-example-java/oceanbase-client/run.sh rename {examples/driver/java-oceanbase-client => ob-example-java/oceanbase-client}/src/main/java/com/oceanbase/example/InsertAndSelectExample.java (81%) create mode 100644 ob-example-java/oceanbase-client/src/main/java/com/oceanbase/example/OceanBaseClientTest.java rename {nodejs-sveltekit => ob-example-javascript/sveltekit}/.gitignore (100%) rename {nodejs-sveltekit => ob-example-javascript/sveltekit}/README.md (100%) rename {nodejs-sveltekit => ob-example-javascript/sveltekit}/jsconfig.json (100%) rename {nodejs-sveltekit => ob-example-javascript/sveltekit}/package-lock.json (100%) rename {nodejs-sveltekit => ob-example-javascript/sveltekit}/package.json (100%) rename {nodejs-sveltekit => ob-example-javascript/sveltekit}/postcss.config.cjs (100%) rename {nodejs-sveltekit => ob-example-javascript/sveltekit}/src/app.css (100%) rename {nodejs-sveltekit => ob-example-javascript/sveltekit}/src/app.html (100%) rename {nodejs-sveltekit => ob-example-javascript/sveltekit}/src/components/Auth.svelte (100%) rename {nodejs-sveltekit => ob-example-javascript/sveltekit}/src/components/Icons.svelte (100%) rename {nodejs-sveltekit => ob-example-javascript/sveltekit}/src/components/Navbar.svelte (100%) rename {nodejs-sveltekit => ob-example-javascript/sveltekit}/src/components/Todo.svelte (100%) rename {nodejs-sveltekit => ob-example-javascript/sveltekit}/src/components/TodoForm.svelte (100%) rename {nodejs-sveltekit => ob-example-javascript/sveltekit}/src/global.d.ts (100%) rename {nodejs-sveltekit => ob-example-javascript/sveltekit}/src/routes/__layout.svelte (100%) rename {nodejs-sveltekit => ob-example-javascript/sveltekit}/src/routes/api/todos/[id].js (100%) rename {nodejs-sveltekit => ob-example-javascript/sveltekit}/src/routes/api/todos/index.js (100%) rename {nodejs-sveltekit => ob-example-javascript/sveltekit}/src/routes/index.svelte (100%) rename {nodejs-sveltekit => ob-example-javascript/sveltekit}/src/stores/authStore.js (100%) rename {nodejs-sveltekit => ob-example-javascript/sveltekit}/src/stores/todoStore.js (100%) rename {nodejs-sveltekit => ob-example-javascript/sveltekit}/src/styles/tailwind-output.css (100%) rename {nodejs-sveltekit => ob-example-javascript/sveltekit}/src/styles/tailwind.css (100%) rename {nodejs-sveltekit => ob-example-javascript/sveltekit}/static/favicon.png (100%) rename {nodejs-sveltekit => ob-example-javascript/sveltekit}/svelte.config.js (100%) rename {nodejs-sveltekit => ob-example-javascript/sveltekit}/tailwind.config.cjs (100%) rename {examples/driver/python3-pymysql => ob-example-python/pymysql}/README-CN.md (87%) rename {examples/driver/python3-pymysql => ob-example-python/pymysql}/README.md (89%) rename examples/driver/python3-pymysql/Test.py => ob-example-python/pymysql/example.py (54%) rename {examples/driver/python3-pymysql => ob-example-python/pymysql}/requirements.txt (100%) rename {examples/driver/python3-pymysql => ob-example-python/pymysql}/run.sh (69%) delete mode 100644 tests/sql/test.sql delete mode 100644 tools/gitpod/banner.txt delete mode 100644 tools/gitpod/boot.png delete mode 100644 tools/gitpod/init.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..567d19d --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,87 @@ +name: CI +on: + push: + paths-ignore: + - 'docs/**' + - '**.md' + - '.*' + pull_request: + paths-ignore: + - 'docs/**' + - '**.md' + - '.*' +concurrency: + group: ${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + golang: + runs-on: ubuntu-latest + strategy: + matrix: + module: [ "go-sql-driver" ] + steps: + - name: Check out repository code + uses: actions/checkout@v4 + - name: Set Go env + uses: actions/setup-go@v4 + with: + go-version: '1.20' + - name: Start docker container + timeout-minutes: 5 + run: | + docker run --name oceanbase-ce --network host -e MODE=slim -e FASTBOOT=true -d oceanbase/oceanbase-ce + eval 'while ! docker logs oceanbase-ce | grep -q "boot success!"; do echo "booting..."; sleep 10; done' + echo "boot success!" + - name: Run example for ${{ matrix.module }} + run: | + cd ob-example-golang/${{ matrix.module }} + sh run.sh + + java: + runs-on: ubuntu-latest + strategy: + matrix: + module: [ "mysql-connector-java", "oceanbase-client" ] + steps: + - name: Check out repository code + uses: actions/checkout@v4 + - name: Set JDK + uses: actions/setup-java@v4 + with: + java-version: '8' + distribution: 'zulu' + cache: 'maven' + - name: Start docker container + timeout-minutes: 5 + run: | + docker run --name oceanbase-ce --network host -e MODE=slim -e FASTBOOT=true -d oceanbase/oceanbase-ce + eval 'while ! docker logs oceanbase-ce | grep -q "boot success!"; do echo "booting..."; sleep 10; done' + echo "boot success!" + - name: Run example for ${{ matrix.module }} + run: | + cd ob-example-java/${{ matrix.module }} + sh run.sh + + python: + runs-on: ubuntu-latest + strategy: + matrix: + module: [ "pymysql" ] + steps: + - name: Check out repository code + uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: "3.9" + - name: Start docker container + timeout-minutes: 5 + run: | + docker run --name oceanbase-ce --network host -e MODE=slim -e FASTBOOT=true -d oceanbase/oceanbase-ce + eval 'while ! docker logs oceanbase-ce | grep -q "boot success!"; do echo "booting..."; sleep 10; done' + echo "boot success!" + - name: Run example for ${{ matrix.module }} + run: | + cd ob-example-python/${{ matrix.module }} + sh run.sh diff --git a/.gitpod.yml b/.gitpod.yml deleted file mode 100644 index 5e18607..0000000 --- a/.gitpod.yml +++ /dev/null @@ -1,12 +0,0 @@ -github: - prebuilds: - master: false - branches: false -tasks: - - name: OB Standalone - init: docker pull oceanbase/oceanbase-ce - command: | - echo "alias sh='/bin/bash'" >> ~/.profile - source ~/.profile - docker run -p 2881:2881 --name obstandalone -e MINI_MODE=1 -d oceanbase/oceanbase-ce - bash /workspace/ob-example/tools/gitpod/init.sh diff --git a/README-CN.md b/README-CN.md index 6eea4b9..5904aa6 100644 --- a/README-CN.md +++ b/README-CN.md @@ -4,71 +4,17 @@ ## 介绍 -本仓库提供了 OceanBase 的示例项目。 它包含以下目录: +本仓库提供了 OceanBase 的示例项目,按照编程语言进行分组,每个分组下面有一个或多个工具的使用示例,示例目录以工具名称命名。 -- [`examples`](examples):该目录包含所有示例项目。 -- [`tests`](tests):该目录包含用于测试的资源。 -- [`tools`](tools):该目录包含脚本和其他工具。 - -### 示例项目 - -示例项目按照如下类型进行分类: - -- [`application`](application): 应用程序框架如网络服务框架。 -- [`connection-pool`](connection-pool): 数据库连接池。 -- [`data-integration`](data-integration): 数据集成框架。 -- [`driver`](driver): 数据库驱动。 -- [`middleware`](middleware): 中间件。 -- [`orm`](orm): ORM(对象关系映射)框架。 - -在这些类型目录下,项目文件夹一般以 `{编程语言}-{组件名称}` 的格式命名。 目前,本仓库包含以下组件的示例: - -#### [数据库驱动](examples/driver) - -- (golang) [go-sql-driver](examples/driver/golang-go-sql-driver) -- (java) [mysql-connector-java](examples/driver/java-mysql-connector-java) -- (java) [oceanbase-client](examples/driver/java-oceanbase-client) -- (python3) [pymysql](examples/driver/python3-pymysql) - -## 快速开始 - -本仓库基于 Gitpod 建立了快速在线体验平台, 点击下面按钮一键体验(建议使用 Chrome 浏览器) - -[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/oceanbase/ob-example) - -需要注意的是,创建 Gitpod 工作区时需要选择大规格,否则可能会因为磁盘空间不足而部署失败。 - -打开新创建的 Gitpod 工作区后,Gitpod 会自动部署一个 OceanBase 本地实例,请耐心等待,直到终端界面显示如下表示部署成功的信息,之后您就可以在工作区使用该 OceanBase 实例了。 - -![Boot Success](tools/gitpod/boot.png) - -### 体验示例项目 - -您可以按下面步骤进行操作,在 Gitpod 上体验示例项目: - -```bash -// 进入目录 -cd xxxx -// 执行示例代码 -sh run.sh -``` - -这里以 python3-pymysql 为例,注意 Gitpod 环境的工作空间默认为 `/workspace/ob-example`: - -```bash -cd /workspace/ob-example/examples/driver/python3-pymysql -sh run.sh -``` +本仓库使用 [oceanbase-ce](https://hub.docker.com/r/oceanbase/oceanbase-ce) 镜像在 GitHub 工作流中启动 OceanBase 数据库实例进行持续集成,用户也可以将所需工具对应的示例代码复制到本地,修改其中的连接信息后进行使用。 ## 贡献 我们欢迎任何人来贡献,感谢所有的[贡献者](https://github.com/oceanbase/ob-example/graphs/contributors)! -在这个仓库中,同类型的示例项目放在同一个目录下,项目目录的命名格式为 `{编程语言}-{组件名称}`。 - -在您提交 Pull Request 前,我们建议您先在 Gitpod 上创建一个 [workspace](https://gitpod.io/workspaces/),以对您的 fork 分支进行测试和验证。 +如果您想增加 OceanBase 的使用示例,请确保将新增的示例代码放置在对应的编程语言目录下,并以工具名称命名该新增模块。 -最终,在新增的目录中,应当至少包含以下几个文件: +在一个示例中,请确保包含以下内容 - 代码文件 - `run.sh` 运行代码的脚本 @@ -76,4 +22,4 @@ sh run.sh ## 参考信息 -关于更多 OceanBase 的细节请参考 [社区官网](https://open.oceanbase.com). +关于更多 OceanBase 的细节请参考 [社区官网](https://open.oceanbase.com)。 diff --git a/README.md b/README.md index e028b94..5f354f4 100644 --- a/README.md +++ b/README.md @@ -4,71 +4,17 @@ English | [简体中文](README-CN.md) ## Introduction -This repository provides the example projects for OceanBase. It contains the following directories: +This repository provides the example projects for OceanBase, which are grouped by programming language. The example directory is named after the component name. -- [`examples`](examples): the directory contains all the example projects. -- [`tests`](tests): the directory contains resources for testing. -- [`tools`](tools): the directory contains scripts and other tools. - -### Examples - -The example projects for OceanBase are classified by type as below: - -- [`application`](examples/application): example projects for application frameworks such as the web service frameworks. -- [`connection-pool`](examples/connection-pool): example projects for connection pool tools. -- [`data-integration`](examples/data-integration): example projects for data integration tools. -- [`driver`](examples/driver): example projects for database drivers. -- [`middleware`](examples/middleware): example projects for middlewares. -- [`orm`](examples/orm): example projects for ORM (Object Relational Mapping) frameworks. - -The project directories under these types are named in format `{programming language}-{component name}`. For now, the repository contains examples for the following components: - -#### [Driver](examples/driver) - -- (golang) [go-sql-driver](examples/driver/golang-go-sql-driver) -- (java) [mysql-connector-java](examples/driver/java-mysql-connector-java) -- (java) [oceanbase-client](examples/driver/java-oceanbase-client) -- (python3) [pymysql](examples/driver/python3-pymysql) - -## Quick Start - -This repo builds an online platform for fast use based on Gitpod, click the following button to have a try. - -[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/oceanbase/ob-example) - -Note that it is necessary to choose a large-class workspace for OceanBase, otherwise the database may fail to deploy due to insufficient disk space. - -Open the newly created workspace, Gitpod will Automatically deploy a standalone OceanBase server. Please wait until the following information about successful deployment appears on the terminal, after that you can try it with our examples. - -![Boot Success](tools/gitpod/boot.png) - -### Try with Example Code - -You can try the example on Gitpod following the steps below: - -```bash -// enter the working directory -cd xxxx -// execute the sample code -sh run.sh -``` - -Here we use python3-pymysql as an example, note that the workspace in Gitpod is set to `/workspace/ob-example`: - -```bash -cd /workspace/ob-example/examples/driver/python3-pymysql -sh run.sh -``` +This repository uses the [oceanbase-ce](https://hub.docker.com/r/oceanbase/oceanbase-ce) image to start the OceanBase database instance in the GitHub workflow for continuous integration. Users can also copy the example code to local environment and use it after changing the connection info. ## Contribution We welcome contributions from anyone, thanks to all [contributors](https://github.com/oceanbase/ob-example/graphs/contributors)! -In this repository, the example projects in the same type are placed in the same directory, and the project directories are named in format `{programming language}-{component name}`. - -Before you submit a Pull Request, we recommend that you first create a [workspace](https://gitpod.io/workspaces) on Gitpod to test and verify your fork branch. +If you want to add a new module, please make sure to place it in the directory of corresponding programming language and name it after the component name. -Finally, in the newly added directory, there should be at least the following files: +In the module, make sure to include the following files: - code files - `run.sh` script to run code diff --git a/examples/driver/golang-go-sql-driver/run.sh b/examples/driver/golang-go-sql-driver/run.sh deleted file mode 100644 index 0e1b5bd..0000000 --- a/examples/driver/golang-go-sql-driver/run.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env bash -cd `dirname $0` -CGO_ENABLED=0 GO111MODULE=on go run Test.go \ No newline at end of file diff --git a/examples/driver/java-mysql-connector-java/README-CN.md b/examples/driver/java-mysql-connector-java/README-CN.md deleted file mode 100644 index fd86274..0000000 --- a/examples/driver/java-mysql-connector-java/README-CN.md +++ /dev/null @@ -1,83 +0,0 @@ -# Java 连接 OceanBase 指南(使用 mysql-connector-java) - -[English](README.md) | 简体中文 - -本文介绍如何通过 MySQL 官方 Java 驱动连接 OceanBase 数据库。 - -## 快速开始 - -在 Maven 中加入 MySQL 驱动 - -```xml - - mysql - mysql-connector-java - 5.1.47 - -``` - -使用 MySQL 驱动时,需要提供相应的 JDBC Url,详细信息请参考 [MySQL文档](https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-reference-jdbc-url-format.html)。 - -以 [MySqlConnectorTest.java](src/main/java/com/oceanbase/example/MySqlConnectorTest.java) 为例 - -```java -public class MySqlConnectorTest { - public static void main(String[] args) { - String workspace = "/workspace/ob-example"; - String sqlFile = "tests/sql/test.sql"; - String tableName = "t_test"; - - Properties properties = new Properties(); - properties.put("user", "root@test"); - properties.put("password", ""); - String jdbcUrl = "jdbc:mysql://127.0.0.1:2881/test"; - - Connection connection; - Statement statement; - try { - connection = DriverManager.getConnection(jdbcUrl, properties); - statement = connection.createStatement(); - System.out.println("Success to connect to OceanBase"); - } catch (SQLException e) { - System.out.println("Failed to connect to OceanBase, exception: " + e.getMessage()); - return; - } - - String selectSql = "SELECT * FROM " + tableName; - System.out.println("Query sql: " + selectSql); - try { - ResultSet rs = statement.executeQuery(selectSql); - ResultSetMetaData metaData = rs.getMetaData(); - System.out.println("Get rows:"); - int count = 0; - while (rs.next()) { - System.out.printf("## row %d: { ", count++); - for (int i = 0; i < metaData.getColumnCount(); i++) { - System.out.print(metaData.getColumnName(i + 1) + ": " + rs.getObject(i + 1) + "; "); - } - System.out.println("}"); - } - } catch (SQLException e) { - System.out.println("Failed to query table " + tableName + ", exception: " + e.getMessage()); - return; - } - - try { - if (statement != null) { - statement.close(); - } - if (connection != null) { - connection.close(); - } - } catch (SQLException e) { - System.out.println("Failed to close statement and connection, exception: " + e.getMessage()); - } - } -} -``` - -在 Gitpod 环境中,可以直接使用 run.sh 运行示例代码。 - -```bash -sh run.sh -``` \ No newline at end of file diff --git a/examples/driver/java-mysql-connector-java/README.md b/examples/driver/java-mysql-connector-java/README.md deleted file mode 100644 index 500885f..0000000 --- a/examples/driver/java-mysql-connector-java/README.md +++ /dev/null @@ -1,83 +0,0 @@ -# Connect OceanBase with Java (mysql-connector-java) - -English | [简体中文](README-CN.md) - -This article describes how to connect to the OceanBase database through `mysql-connector-java`. - -## Quick Start - -Add MySQL JDBC driver to POM. - -```xml - - mysql - mysql-connector-java - 5.1.47 - -``` - -When using the MySQL driver, you need to provide the JDBC Url. Please refer to [MySQL Documentation](https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-reference-jdbc-url-format.html) for details. - -Take [MySqlConnectorTest.java](src/main/java/com/oceanbase/example/MySqlConnectorTest.java) code as an example. - -```java -public class MySqlConnectorTest { - public static void main(String[] args) { - String workspace = "/workspace/ob-example"; - String sqlFile = "tests/sql/test.sql"; - String tableName = "t_test"; - - Properties properties = new Properties(); - properties.put("user", "root@test"); - properties.put("password", ""); - String jdbcUrl = "jdbc:mysql://127.0.0.1:2881/test"; - - Connection connection; - Statement statement; - try { - connection = DriverManager.getConnection(jdbcUrl, properties); - statement = connection.createStatement(); - System.out.println("Success to connect to OceanBase"); - } catch (SQLException e) { - System.out.println("Failed to connect to OceanBase, exception: " + e.getMessage()); - return; - } - - String selectSql = "SELECT * FROM " + tableName; - System.out.println("Query sql: " + selectSql); - try { - ResultSet rs = statement.executeQuery(selectSql); - ResultSetMetaData metaData = rs.getMetaData(); - System.out.println("Get rows:"); - int count = 0; - while (rs.next()) { - System.out.printf("## row %d: { ", count++); - for (int i = 0; i < metaData.getColumnCount(); i++) { - System.out.print(metaData.getColumnName(i + 1) + ": " + rs.getObject(i + 1) + "; "); - } - System.out.println("}"); - } - } catch (SQLException e) { - System.out.println("Failed to query table " + tableName + ", exception: " + e.getMessage()); - return; - } - - try { - if (statement != null) { - statement.close(); - } - if (connection != null) { - connection.close(); - } - } catch (SQLException e) { - System.out.println("Failed to close statement and connection, exception: " + e.getMessage()); - } - } -} -``` - -In the Gitpod environment, you can directly use `run.sh` to run the demo code. - -```bash -sh run.sh -``` \ No newline at end of file diff --git a/examples/driver/java-mysql-connector-java/run.sh b/examples/driver/java-mysql-connector-java/run.sh deleted file mode 100644 index 7d8c29c..0000000 --- a/examples/driver/java-mysql-connector-java/run.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env bash -mvn clean install exec:java -Dexec.cleanupDaemonThreads=false \ No newline at end of file diff --git a/examples/driver/java-mysql-connector-java/src/main/java/com/oceanbase/example/MySqlConnectorTest.java b/examples/driver/java-mysql-connector-java/src/main/java/com/oceanbase/example/MySqlConnectorTest.java deleted file mode 100644 index 615ef3c..0000000 --- a/examples/driver/java-mysql-connector-java/src/main/java/com/oceanbase/example/MySqlConnectorTest.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.oceanbase.example; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.sql.*; -import java.util.Properties; -import java.util.stream.Collectors; - -public class MySqlConnectorTest { - public static void main(String[] args) { - String workspace = "/workspace/ob-example"; - String sqlFile = "tests/sql/test.sql"; - String tableName = "t_test"; - - Properties properties = new Properties(); - properties.put("user", "root@test"); - properties.put("password", ""); - String jdbcUrl = "jdbc:mysql://127.0.0.1:2881/test"; - - Connection connection; - Statement statement; - try { - connection = DriverManager.getConnection(jdbcUrl, properties); - statement = connection.createStatement(); - System.out.println("Success to connect to OceanBase"); - } catch (SQLException e) { - System.out.println("Failed to connect to OceanBase, exception: " + e.getMessage()); - return; - } - - String[] sqlArray; - Path sqlPath = Paths.get(workspace, sqlFile); - try { - sqlArray = Files.readAllLines(sqlPath).stream().map(String::trim).collect(Collectors.joining("\n")) - .split(";"); - } catch (IOException e) { - System.out.println("Failed to load sql file from " + sqlPath + ", exception: " + e.getMessage()); - return; - } - - try { - for (int i = 0; i < sqlArray.length; i++) { - String sql = sqlArray[i]; - System.out.println("Execute sql: " + sql); - statement.execute(sql); - } - } catch (SQLException e) { - System.out.println("Execute sql exception: " + e.getMessage()); - return; - } - - String selectSql = "SELECT * FROM " + tableName; - System.out.println("Query sql: " + selectSql); - try { - ResultSet rs = statement.executeQuery(selectSql); - ResultSetMetaData metaData = rs.getMetaData(); - System.out.println("Get rows:"); - int count = 0; - while (rs.next()) { - System.out.printf("## row %d: { ", count++); - for (int i = 0; i < metaData.getColumnCount(); i++) { - System.out.print(metaData.getColumnName(i + 1) + ": " + rs.getObject(i + 1) + "; "); - } - System.out.println("}"); - } - } catch (SQLException e) { - System.out.println("Failed to query table " + tableName + ", exception: " + e.getMessage()); - return; - } - - try { - if (statement != null) { - statement.close(); - } - if (connection != null) { - connection.close(); - } - } catch (SQLException e) { - System.out.println("Failed to close statement and connection, exception: " + e.getMessage()); - } - } -} diff --git a/examples/driver/java-oceanbase-client/run.sh b/examples/driver/java-oceanbase-client/run.sh deleted file mode 100644 index 7d8c29c..0000000 --- a/examples/driver/java-oceanbase-client/run.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env bash -mvn clean install exec:java -Dexec.cleanupDaemonThreads=false \ No newline at end of file diff --git a/examples/driver/java-oceanbase-client/src/main/java/com/oceanbase/example/OceanBaseClientTest.java b/examples/driver/java-oceanbase-client/src/main/java/com/oceanbase/example/OceanBaseClientTest.java deleted file mode 100644 index cfa8927..0000000 --- a/examples/driver/java-oceanbase-client/src/main/java/com/oceanbase/example/OceanBaseClientTest.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.oceanbase.example; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.sql.*; -import java.util.Properties; -import java.util.stream.Collectors; - -public class OceanBaseClientTest { - public static void main(String[] args) { - String workspace = "/workspace/ob-example"; - String sqlFile = "tests/sql/test.sql"; - String tableName = "t_test"; - - Properties properties = new Properties(); - properties.put("user", "root@test"); - properties.put("password", ""); - String jdbcUrl = "jdbc:oceanbase://127.0.0.1:2881/test"; - - Connection connection; - Statement statement; - try { - connection = DriverManager.getConnection(jdbcUrl, properties); - statement = connection.createStatement(); - System.out.println("Success to connect to OceanBase"); - } catch (SQLException e) { - System.out.println("Failed to connect to OceanBase, exception: " + e.getMessage()); - return; - } - - String[] sqlArray; - Path sqlPath = Paths.get(workspace, sqlFile); - try { - sqlArray = Files.readAllLines(sqlPath).stream().map(String::trim).collect(Collectors.joining("\n")) - .split(";"); - } catch (IOException e) { - System.out.println("Failed to load sql file from " + sqlPath + ", exception: " + e.getMessage()); - return; - } - - try { - for (int i = 0; i < sqlArray.length; i++) { - String sql = sqlArray[i]; - System.out.println("Execute sql: " + sql); - statement.execute(sql); - } - } catch (SQLException e) { - System.out.println("Execute sql exception: " + e.getMessage()); - return; - } - - String selectSql = "SELECT * FROM " + tableName; - System.out.println("Query sql: " + selectSql); - try { - ResultSet rs = statement.executeQuery(selectSql); - ResultSetMetaData metaData = rs.getMetaData(); - System.out.println("Get rows:"); - int count = 0; - while (rs.next()) { - System.out.printf("## row %d: { ", count++); - for (int i = 0; i < metaData.getColumnCount(); i++) { - System.out.print(metaData.getColumnName(i + 1) + ": " + rs.getObject(i + 1) + "; "); - } - System.out.println("}"); - } - } catch (SQLException e) { - System.out.println("Failed to query table " + tableName + ", exception: " + e.getMessage()); - return; - } - - try { - if (statement != null) { - statement.close(); - } - if (connection != null) { - connection.close(); - } - } catch (SQLException e) { - System.out.println("Failed to close statement and connection, exception: " + e.getMessage()); - } - } -} diff --git a/examples/driver/golang-go-sql-driver/README-CN.md b/ob-example-golang/go-sql-driver/README-CN.md similarity index 88% rename from examples/driver/golang-go-sql-driver/README-CN.md rename to ob-example-golang/go-sql-driver/README-CN.md index ad8670c..9a86978 100644 --- a/examples/driver/golang-go-sql-driver/README-CN.md +++ b/ob-example-golang/go-sql-driver/README-CN.md @@ -10,7 +10,7 @@ 您需要使用 dataSourceName 来创建数据库连接,详细信息请参考 [go-sql-driver/mysql 文档](https://github.com/go-sql-driver/mysql#dsn-data-source-name)。 -以 [Test.go](Test.go) 代码为例 +以 [example.go](example.go) 代码为例 ```go var ( @@ -29,7 +29,7 @@ if err != nil { defer db.Close() ``` -在 Gitpod 环境中,可以直接使用 run.sh 运行示例代码。 +修改代码中的连接信息,之后你就可以直接使用 run.sh 运行示例代码。 ```bash sh run.sh diff --git a/examples/driver/golang-go-sql-driver/README.md b/ob-example-golang/go-sql-driver/README.md similarity index 88% rename from examples/driver/golang-go-sql-driver/README.md rename to ob-example-golang/go-sql-driver/README.md index 0655901..e953d99 100644 --- a/examples/driver/golang-go-sql-driver/README.md +++ b/ob-example-golang/go-sql-driver/README.md @@ -10,7 +10,7 @@ For details about `go-sql-driver/mysql`, you can refer to [https://github.com/go You can use `dataSourceName` to create a database connection, please refer to [go-sql-driver/mysql documentation](https://github.com/go-sql-driver/mysql#dsn-data-source-name) for details. -Take [Test.go](Test.go) code as an example. +Take [example.go](example.go) code as an example. ```go var ( @@ -29,7 +29,7 @@ if err != nil { defer db.Close() ``` -In the Gitpod environment, you can directly use `run.sh` to run the demo code. +Modify the connection info in code, and use `run.sh` to run the example code. ```bash sh run.sh @@ -41,4 +41,4 @@ Log in to OceanBase with a root user and run the following command: ```bash alter system set _ob_enable_prepared_statement = true; -``` \ No newline at end of file +``` diff --git a/examples/driver/golang-go-sql-driver/Test.go b/ob-example-golang/go-sql-driver/example.go similarity index 54% rename from examples/driver/golang-go-sql-driver/Test.go rename to ob-example-golang/go-sql-driver/example.go index e0c125c..3f2a635 100644 --- a/examples/driver/golang-go-sql-driver/Test.go +++ b/ob-example-golang/go-sql-driver/example.go @@ -2,13 +2,9 @@ package main import ( "database/sql" - "encoding/json" "fmt" - "log" - "os" - "path/filepath" - _ "github.com/go-sql-driver/mysql" + "log" ) type Entity struct { @@ -16,15 +12,8 @@ type Entity struct { Name string `json:"name"` } -var ( - workspace = "/workspace/ob-example" - sqlFile = "tests/sql/test.sql" - tableName = "t_test" -) - func main() { - // For details about 'dataSourceName', see - // https://github.com/go-sql-driver/mysql#dsn-data-source-name + var ( host = "127.0.0.1" port = 2881 @@ -32,6 +21,9 @@ func main() { username = "root@test" password = "" ) + + // For details about 'dataSourceName', see + // https://github.com/go-sql-driver/mysql#dsn-data-source-name dataSourceName := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s", username, password, host, port, dbName) db, err := sql.Open("mysql", dataSourceName) @@ -40,38 +32,33 @@ func main() { } defer db.Close() - filePath := filepath.Join(workspace, sqlFile) - log.Println("Load sql file from: " + filePath) - - bytes, err := os.ReadFile(filePath) - if err != nil { + if _, err = db.Exec("DROP TABLE IF EXISTS `t_test`"); err != nil { log.Fatal(err) } - - sqlFileContent := string(bytes) - log.Println("Exec sql:\n" + sqlFileContent) - - if _, err = db.Exec(sqlFileContent); err != nil { + if _, err = db.Exec("CREATE TABLE `t_test` (" + + " `id` int(10) NOT NULL AUTO_INCREMENT," + + " `name` varchar(20) DEFAULT NULL," + + " PRIMARY KEY (`id`)" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE = utf8_bin"); err != nil { + log.Fatal(err) + } + if _, err = db.Exec("INSERT INTO `t_test` VALUES (default, 'Hello OceanBase')"); err != nil { log.Fatal(err) } - selectSql := "SELECT * FROM " + tableName - log.Println("Query sql: " + selectSql) - - rows, err := db.Query(selectSql) + rows, err := db.Query("SELECT * FROM `t_test`") if err != nil { log.Fatal(err) } - log.Println("Get rows:") - count := 0 + var result []Entity for rows.Next() { var entity Entity if err = rows.Scan(&entity.ID, &entity.Name); err != nil { log.Fatal(err) } - b, _ := json.Marshal(entity) - log.Printf("## row %d: %s", count, string(b)) - count++ + result = append(result, entity) } + + log.Printf("Query got result: +%v", result) } diff --git a/examples/driver/golang-go-sql-driver/go.mod b/ob-example-golang/go-sql-driver/go.mod similarity index 100% rename from examples/driver/golang-go-sql-driver/go.mod rename to ob-example-golang/go-sql-driver/go.mod diff --git a/examples/driver/golang-go-sql-driver/go.sum b/ob-example-golang/go-sql-driver/go.sum similarity index 100% rename from examples/driver/golang-go-sql-driver/go.sum rename to ob-example-golang/go-sql-driver/go.sum diff --git a/ob-example-golang/go-sql-driver/run.sh b/ob-example-golang/go-sql-driver/run.sh new file mode 100644 index 0000000..1bc0b77 --- /dev/null +++ b/ob-example-golang/go-sql-driver/run.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash +cd `dirname $0` +CGO_ENABLED=0 GO111MODULE=on go run example.go diff --git a/ob-example-java/mysql-connector-java/README-CN.md b/ob-example-java/mysql-connector-java/README-CN.md new file mode 100644 index 0000000..d14cc39 --- /dev/null +++ b/ob-example-java/mysql-connector-java/README-CN.md @@ -0,0 +1,77 @@ +# Java 连接 OceanBase 指南(使用 mysql-connector-java) + +[English](README.md) | 简体中文 + +本文介绍如何通过 MySQL 官方 Java 驱动连接 OceanBase 数据库。 + +## 快速开始 + +在 Maven 中加入 MySQL 驱动 + +```xml + + mysql + mysql-connector-java + 5.1.47 + +``` + +使用 MySQL 驱动时,需要提供相应的 JDBC Url,详细信息请参考 [MySQL文档](https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-reference-jdbc-url-format.html)。 + +以 [MySqlConnectorTest.java](src/main/java/com/oceanbase/example/MySqlConnectorTest.java) 为例 + +```java +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; + +public class MySqlConnectorTest { + + private static final String JDBC_URL = "jdbc:mysql://127.0.0.1:2881/test"; + private static final String USERNAME = "root@test"; + private static final String PASSWORD = ""; + + public static void main(String[] args) { + try (Connection connection = DriverManager.getConnection(JDBC_URL, USERNAME, PASSWORD); + Statement statement = connection.createStatement()) { + statement.execute("DROP TABLE IF EXISTS `t_test`"); + statement.execute("CREATE TABLE `t_test` (" + + " `id` int(10) NOT NULL AUTO_INCREMENT," + + " `name` varchar(20) DEFAULT NULL," + + " PRIMARY KEY (`id`)" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE = utf8_bin"); + statement.execute("INSERT INTO `t_test` VALUES (default, 'Hello OceanBase')"); + + ResultSet rs = statement.executeQuery("SELECT * FROM `t_test`"); + ResultSetMetaData metaData = rs.getMetaData(); + + List result = new ArrayList<>(); + while (rs.next()) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < metaData.getColumnCount(); i++) { + if (i != 0) { + sb.append(","); + } + Object value = rs.getObject(i + 1); + sb.append(value == null ? "null" : value.toString()); + } + result.add(sb.toString()); + } + System.out.println(result); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } +} +``` + +修改代码中的连接信息,之后你就可以直接使用 run.sh 运行示例代码。 + +```bash +sh run.sh +``` diff --git a/ob-example-java/mysql-connector-java/README.md b/ob-example-java/mysql-connector-java/README.md new file mode 100644 index 0000000..6d06466 --- /dev/null +++ b/ob-example-java/mysql-connector-java/README.md @@ -0,0 +1,77 @@ +# Connect OceanBase with Java (mysql-connector-java) + +English | [简体中文](README-CN.md) + +This article describes how to connect to the OceanBase database through `mysql-connector-java`. + +## Quick Start + +Add MySQL JDBC driver to POM. + +```xml + + mysql + mysql-connector-java + 5.1.47 + +``` + +When using the MySQL driver, you need to provide the JDBC Url. Please refer to [MySQL Documentation](https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-reference-jdbc-url-format.html) for details. + +Take [MySqlConnectorTest.java](src/main/java/com/oceanbase/example/MySqlConnectorTest.java) code as an example. + +```java +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; + +public class MySqlConnectorTest { + + private static final String JDBC_URL = "jdbc:mysql://127.0.0.1:2881/test"; + private static final String USERNAME = "root@test"; + private static final String PASSWORD = ""; + + public static void main(String[] args) { + try (Connection connection = DriverManager.getConnection(JDBC_URL, USERNAME, PASSWORD); + Statement statement = connection.createStatement()) { + statement.execute("DROP TABLE IF EXISTS `t_test`"); + statement.execute("CREATE TABLE `t_test` (" + + " `id` int(10) NOT NULL AUTO_INCREMENT," + + " `name` varchar(20) DEFAULT NULL," + + " PRIMARY KEY (`id`)" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE = utf8_bin"); + statement.execute("INSERT INTO `t_test` VALUES (default, 'Hello OceanBase')"); + + ResultSet rs = statement.executeQuery("SELECT * FROM `t_test`"); + ResultSetMetaData metaData = rs.getMetaData(); + + List result = new ArrayList<>(); + while (rs.next()) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < metaData.getColumnCount(); i++) { + if (i != 0) { + sb.append(","); + } + Object value = rs.getObject(i + 1); + sb.append(value == null ? "null" : value.toString()); + } + result.add(sb.toString()); + } + System.out.println(result); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } +} +``` + +Modify the connection info in code, and use `run.sh` to run the example code. + +```bash +sh run.sh +``` diff --git a/examples/driver/java-mysql-connector-java/pom.xml b/ob-example-java/mysql-connector-java/pom.xml similarity index 91% rename from examples/driver/java-mysql-connector-java/pom.xml rename to ob-example-java/mysql-connector-java/pom.xml index 3e95859..df91814 100644 --- a/examples/driver/java-mysql-connector-java/pom.xml +++ b/ob-example-java/mysql-connector-java/pom.xml @@ -14,7 +14,6 @@ UTF-8 1.8 1.8 - com.oceanbase.example.MySqlConnectorTest diff --git a/ob-example-java/mysql-connector-java/run.sh b/ob-example-java/mysql-connector-java/run.sh new file mode 100644 index 0000000..67c9ef4 --- /dev/null +++ b/ob-example-java/mysql-connector-java/run.sh @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +mvn clean install exec:java -Dexec.cleanupDaemonThreads=false -Dexec.mainClass=com.oceanbase.example.MySqlConnectorTest diff --git a/ob-example-java/mysql-connector-java/src/main/java/com/oceanbase/example/MySqlConnectorTest.java b/ob-example-java/mysql-connector-java/src/main/java/com/oceanbase/example/MySqlConnectorTest.java new file mode 100644 index 0000000..b76df99 --- /dev/null +++ b/ob-example-java/mysql-connector-java/src/main/java/com/oceanbase/example/MySqlConnectorTest.java @@ -0,0 +1,49 @@ +package com.oceanbase.example; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; + +public class MySqlConnectorTest { + + private static final String JDBC_URL = "jdbc:mysql://127.0.0.1:2881/test"; + private static final String USERNAME = "root@test"; + private static final String PASSWORD = ""; + + public static void main(String[] args) { + try (Connection connection = DriverManager.getConnection(JDBC_URL, USERNAME, PASSWORD); + Statement statement = connection.createStatement()) { + statement.execute("DROP TABLE IF EXISTS `t_test`"); + statement.execute("CREATE TABLE `t_test` (" + + " `id` int(10) NOT NULL AUTO_INCREMENT," + + " `name` varchar(20) DEFAULT NULL," + + " PRIMARY KEY (`id`)" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE = utf8_bin"); + statement.execute("INSERT INTO `t_test` VALUES (default, 'Hello OceanBase')"); + + ResultSet rs = statement.executeQuery("SELECT * FROM `t_test`"); + ResultSetMetaData metaData = rs.getMetaData(); + + List result = new ArrayList<>(); + while (rs.next()) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < metaData.getColumnCount(); i++) { + if (i != 0) { + sb.append(","); + } + Object value = rs.getObject(i + 1); + sb.append(value == null ? "null" : value.toString()); + } + result.add(sb.toString()); + } + System.out.println(result); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } +} diff --git a/examples/driver/java-oceanbase-client/README-CN.md b/ob-example-java/oceanbase-client/README-CN.md similarity index 75% rename from examples/driver/java-oceanbase-client/README-CN.md rename to ob-example-java/oceanbase-client/README-CN.md index 3de94a5..375f80e 100644 --- a/examples/driver/java-oceanbase-client/README-CN.md +++ b/ob-example-java/oceanbase-client/README-CN.md @@ -14,7 +14,7 @@ com.oceanbase oceanbase-client - 2.4.2 + 2.4.8 ``` @@ -23,15 +23,23 @@ 以 [InsertAndSelectExample.java](src/main/java/com/oceanbase/example/InsertAndSelectExample.java) 为例 ```java +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + public class InsertAndSelectExample { + private static final String JDBC_URL = "jdbc:oceanbase://127.0.0.1:2881/test?characterEncoding=utf-8&useServerPrepStmts=true"; + private static final String USERNAME = "root@test"; + private static final String PASSWORD = ""; + public static void main(String[] args) throws ClassNotFoundException, SQLException { // connect to your database - String url = "jdbc:oceanbase://127.0.0.1:2881/test?characterEncoding=utf-8&useServerPrepStmts=true"; - String user = "root@test"; - String password = ""; Class.forName("com.oceanbase.jdbc.Driver"); - Connection conn = DriverManager.getConnection(url, user, password); + Connection conn = DriverManager.getConnection(JDBC_URL, USERNAME, PASSWORD); // create a table Statement stmt = conn.createStatement(); @@ -66,7 +74,7 @@ public class InsertAndSelectExample { } ``` -在 Gitpod 环境中,可以直接使用 run.sh 运行示例代码。 +修改代码中的连接信息,之后你就可以直接使用 run.sh 运行示例代码。 ```bash sh run.sh diff --git a/examples/driver/java-oceanbase-client/README.md b/ob-example-java/oceanbase-client/README.md similarity index 76% rename from examples/driver/java-oceanbase-client/README.md rename to ob-example-java/oceanbase-client/README.md index e19daa7..15474fb 100644 --- a/examples/driver/java-oceanbase-client/README.md +++ b/ob-example-java/oceanbase-client/README.md @@ -14,7 +14,7 @@ Add OceanBase JDBC driver to POM. com.oceanbase oceanbase-client - 2.4.2 + 2.4.8 ``` @@ -23,15 +23,23 @@ When using the OceanBase driver, you need to provide the JDBC Url. Please refer Take [InsertAndSelectExample.java](src/main/java/com/oceanbase/example/InsertAndSelectExample.java) code as an example. ```java +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + public class InsertAndSelectExample { + private static final String JDBC_URL = "jdbc:oceanbase://127.0.0.1:2881/test?characterEncoding=utf-8&useServerPrepStmts=true"; + private static final String USERNAME = "root@test"; + private static final String PASSWORD = ""; + public static void main(String[] args) throws ClassNotFoundException, SQLException { // connect to your database - String url = "jdbc:oceanbase://127.0.0.1:2881/test?characterEncoding=utf-8&useServerPrepStmts=true"; - String user = "root@test"; - String password = ""; Class.forName("com.oceanbase.jdbc.Driver"); - Connection conn = DriverManager.getConnection(url, user, password); + Connection conn = DriverManager.getConnection(JDBC_URL, USERNAME, PASSWORD); // create a table Statement stmt = conn.createStatement(); @@ -66,7 +74,7 @@ public class InsertAndSelectExample { } ``` -In the Gitpod environment, you can directly use `run.sh` to run the demo code. +Modify the connection info in code, and use `run.sh` to run the example code. ```bash sh run.sh diff --git a/examples/driver/java-oceanbase-client/pom.xml b/ob-example-java/oceanbase-client/pom.xml similarity index 88% rename from examples/driver/java-oceanbase-client/pom.xml rename to ob-example-java/oceanbase-client/pom.xml index b08c8b3..8168a3d 100644 --- a/examples/driver/java-oceanbase-client/pom.xml +++ b/ob-example-java/oceanbase-client/pom.xml @@ -14,14 +14,13 @@ UTF-8 1.8 1.8 - com.oceanbase.example.InsertAndSelectExample com.oceanbase oceanbase-client - 2.4.2 + 2.4.8 diff --git a/ob-example-java/oceanbase-client/run.sh b/ob-example-java/oceanbase-client/run.sh new file mode 100644 index 0000000..d7d5238 --- /dev/null +++ b/ob-example-java/oceanbase-client/run.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash +mvn clean install exec:java -Dexec.cleanupDaemonThreads=false -Dexec.mainClass=com.oceanbase.example.InsertAndSelectExample +mvn clean install exec:java -Dexec.cleanupDaemonThreads=false -Dexec.mainClass=com.oceanbase.example.OceanBaseClientTest diff --git a/examples/driver/java-oceanbase-client/src/main/java/com/oceanbase/example/InsertAndSelectExample.java b/ob-example-java/oceanbase-client/src/main/java/com/oceanbase/example/InsertAndSelectExample.java similarity index 81% rename from examples/driver/java-oceanbase-client/src/main/java/com/oceanbase/example/InsertAndSelectExample.java rename to ob-example-java/oceanbase-client/src/main/java/com/oceanbase/example/InsertAndSelectExample.java index be9a8b0..791641b 100644 --- a/examples/driver/java-oceanbase-client/src/main/java/com/oceanbase/example/InsertAndSelectExample.java +++ b/ob-example-java/oceanbase-client/src/main/java/com/oceanbase/example/InsertAndSelectExample.java @@ -9,13 +9,14 @@ public class InsertAndSelectExample { + private static final String JDBC_URL = "jdbc:oceanbase://127.0.0.1:2881/test?characterEncoding=utf-8&useServerPrepStmts=true"; + private static final String USERNAME = "root@test"; + private static final String PASSWORD = ""; + public static void main(String[] args) throws ClassNotFoundException, SQLException { // connect to your database - String url = "jdbc:oceanbase://127.0.0.1:2881/test?characterEncoding=utf-8&useServerPrepStmts=true"; - String user = "root@test"; - String password = ""; Class.forName("com.oceanbase.jdbc.Driver"); - Connection conn = DriverManager.getConnection(url, user, password); + Connection conn = DriverManager.getConnection(JDBC_URL, USERNAME, PASSWORD); // create a table Statement stmt = conn.createStatement(); diff --git a/ob-example-java/oceanbase-client/src/main/java/com/oceanbase/example/OceanBaseClientTest.java b/ob-example-java/oceanbase-client/src/main/java/com/oceanbase/example/OceanBaseClientTest.java new file mode 100644 index 0000000..c863158 --- /dev/null +++ b/ob-example-java/oceanbase-client/src/main/java/com/oceanbase/example/OceanBaseClientTest.java @@ -0,0 +1,50 @@ +package com.oceanbase.example; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; + +public class OceanBaseClientTest { + + private static final String JDBC_URL = "jdbc:oceanbase://127.0.0.1:2881/test"; + private static final String USERNAME = "root@test"; + private static final String PASSWORD = ""; + + public static void main(String[] args) { + try (Connection connection = DriverManager.getConnection(JDBC_URL, USERNAME, PASSWORD); + Statement statement = connection.createStatement()) { + statement.execute("DROP TABLE IF EXISTS `t_test`"); + statement.execute("CREATE TABLE `t_test` (" + + " `id` int(10) NOT NULL AUTO_INCREMENT," + + " `name` varchar(20) DEFAULT NULL," + + " PRIMARY KEY (`id`)" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE = utf8_bin"); + statement.execute("INSERT INTO `t_test` VALUES (default, 'Hello OceanBase')"); + + ResultSet rs = statement.executeQuery("SELECT * FROM `t_test`"); + ResultSetMetaData metaData = rs.getMetaData(); + + List result = new ArrayList<>(); + while (rs.next()) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < metaData.getColumnCount(); i++) { + if (i != 0) { + sb.append(","); + } + Object value = rs.getObject(i + 1); + sb.append(value == null ? "null" : value.toString()); + } + result.add(sb.toString()); + } + + System.out.println(result); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } +} diff --git a/nodejs-sveltekit/.gitignore b/ob-example-javascript/sveltekit/.gitignore similarity index 100% rename from nodejs-sveltekit/.gitignore rename to ob-example-javascript/sveltekit/.gitignore diff --git a/nodejs-sveltekit/README.md b/ob-example-javascript/sveltekit/README.md similarity index 100% rename from nodejs-sveltekit/README.md rename to ob-example-javascript/sveltekit/README.md diff --git a/nodejs-sveltekit/jsconfig.json b/ob-example-javascript/sveltekit/jsconfig.json similarity index 100% rename from nodejs-sveltekit/jsconfig.json rename to ob-example-javascript/sveltekit/jsconfig.json diff --git a/nodejs-sveltekit/package-lock.json b/ob-example-javascript/sveltekit/package-lock.json similarity index 100% rename from nodejs-sveltekit/package-lock.json rename to ob-example-javascript/sveltekit/package-lock.json diff --git a/nodejs-sveltekit/package.json b/ob-example-javascript/sveltekit/package.json similarity index 100% rename from nodejs-sveltekit/package.json rename to ob-example-javascript/sveltekit/package.json diff --git a/nodejs-sveltekit/postcss.config.cjs b/ob-example-javascript/sveltekit/postcss.config.cjs similarity index 100% rename from nodejs-sveltekit/postcss.config.cjs rename to ob-example-javascript/sveltekit/postcss.config.cjs diff --git a/nodejs-sveltekit/src/app.css b/ob-example-javascript/sveltekit/src/app.css similarity index 100% rename from nodejs-sveltekit/src/app.css rename to ob-example-javascript/sveltekit/src/app.css diff --git a/nodejs-sveltekit/src/app.html b/ob-example-javascript/sveltekit/src/app.html similarity index 100% rename from nodejs-sveltekit/src/app.html rename to ob-example-javascript/sveltekit/src/app.html diff --git a/nodejs-sveltekit/src/components/Auth.svelte b/ob-example-javascript/sveltekit/src/components/Auth.svelte similarity index 100% rename from nodejs-sveltekit/src/components/Auth.svelte rename to ob-example-javascript/sveltekit/src/components/Auth.svelte diff --git a/nodejs-sveltekit/src/components/Icons.svelte b/ob-example-javascript/sveltekit/src/components/Icons.svelte similarity index 100% rename from nodejs-sveltekit/src/components/Icons.svelte rename to ob-example-javascript/sveltekit/src/components/Icons.svelte diff --git a/nodejs-sveltekit/src/components/Navbar.svelte b/ob-example-javascript/sveltekit/src/components/Navbar.svelte similarity index 100% rename from nodejs-sveltekit/src/components/Navbar.svelte rename to ob-example-javascript/sveltekit/src/components/Navbar.svelte diff --git a/nodejs-sveltekit/src/components/Todo.svelte b/ob-example-javascript/sveltekit/src/components/Todo.svelte similarity index 100% rename from nodejs-sveltekit/src/components/Todo.svelte rename to ob-example-javascript/sveltekit/src/components/Todo.svelte diff --git a/nodejs-sveltekit/src/components/TodoForm.svelte b/ob-example-javascript/sveltekit/src/components/TodoForm.svelte similarity index 100% rename from nodejs-sveltekit/src/components/TodoForm.svelte rename to ob-example-javascript/sveltekit/src/components/TodoForm.svelte diff --git a/nodejs-sveltekit/src/global.d.ts b/ob-example-javascript/sveltekit/src/global.d.ts similarity index 100% rename from nodejs-sveltekit/src/global.d.ts rename to ob-example-javascript/sveltekit/src/global.d.ts diff --git a/nodejs-sveltekit/src/routes/__layout.svelte b/ob-example-javascript/sveltekit/src/routes/__layout.svelte similarity index 100% rename from nodejs-sveltekit/src/routes/__layout.svelte rename to ob-example-javascript/sveltekit/src/routes/__layout.svelte diff --git a/nodejs-sveltekit/src/routes/api/todos/[id].js b/ob-example-javascript/sveltekit/src/routes/api/todos/[id].js similarity index 100% rename from nodejs-sveltekit/src/routes/api/todos/[id].js rename to ob-example-javascript/sveltekit/src/routes/api/todos/[id].js diff --git a/nodejs-sveltekit/src/routes/api/todos/index.js b/ob-example-javascript/sveltekit/src/routes/api/todos/index.js similarity index 100% rename from nodejs-sveltekit/src/routes/api/todos/index.js rename to ob-example-javascript/sveltekit/src/routes/api/todos/index.js diff --git a/nodejs-sveltekit/src/routes/index.svelte b/ob-example-javascript/sveltekit/src/routes/index.svelte similarity index 100% rename from nodejs-sveltekit/src/routes/index.svelte rename to ob-example-javascript/sveltekit/src/routes/index.svelte diff --git a/nodejs-sveltekit/src/stores/authStore.js b/ob-example-javascript/sveltekit/src/stores/authStore.js similarity index 100% rename from nodejs-sveltekit/src/stores/authStore.js rename to ob-example-javascript/sveltekit/src/stores/authStore.js diff --git a/nodejs-sveltekit/src/stores/todoStore.js b/ob-example-javascript/sveltekit/src/stores/todoStore.js similarity index 100% rename from nodejs-sveltekit/src/stores/todoStore.js rename to ob-example-javascript/sveltekit/src/stores/todoStore.js diff --git a/nodejs-sveltekit/src/styles/tailwind-output.css b/ob-example-javascript/sveltekit/src/styles/tailwind-output.css similarity index 100% rename from nodejs-sveltekit/src/styles/tailwind-output.css rename to ob-example-javascript/sveltekit/src/styles/tailwind-output.css diff --git a/nodejs-sveltekit/src/styles/tailwind.css b/ob-example-javascript/sveltekit/src/styles/tailwind.css similarity index 100% rename from nodejs-sveltekit/src/styles/tailwind.css rename to ob-example-javascript/sveltekit/src/styles/tailwind.css diff --git a/nodejs-sveltekit/static/favicon.png b/ob-example-javascript/sveltekit/static/favicon.png similarity index 100% rename from nodejs-sveltekit/static/favicon.png rename to ob-example-javascript/sveltekit/static/favicon.png diff --git a/nodejs-sveltekit/svelte.config.js b/ob-example-javascript/sveltekit/svelte.config.js similarity index 100% rename from nodejs-sveltekit/svelte.config.js rename to ob-example-javascript/sveltekit/svelte.config.js diff --git a/nodejs-sveltekit/tailwind.config.cjs b/ob-example-javascript/sveltekit/tailwind.config.cjs similarity index 100% rename from nodejs-sveltekit/tailwind.config.cjs rename to ob-example-javascript/sveltekit/tailwind.config.cjs diff --git a/examples/driver/python3-pymysql/README-CN.md b/ob-example-python/pymysql/README-CN.md similarity index 87% rename from examples/driver/python3-pymysql/README-CN.md rename to ob-example-python/pymysql/README-CN.md index 42f53db..65c0523 100644 --- a/examples/driver/python3-pymysql/README-CN.md +++ b/ob-example-python/pymysql/README-CN.md @@ -10,7 +10,7 @@ 在开始之前,需要先确保 PyMySQL 已安装。PyMySQL 是在 Python 3.x 版本中用于连接 MySQL 服务器的依赖库。有关 PyMySQL 的安装和使用等详细信息,您可参考 [官方文档](https://pypi.org/project/PyMySQL/) 和 [相关 API 参考文档](https://pymysql.readthedocs.io/en/latest/modules/index.html)。 -以 [Test.py](Test.py) 为例。 +以 [example.py](example.py) 为例。 ```python import pymysql @@ -26,7 +26,7 @@ with conn.cursor() as cur: conn.close() ``` -在 Gitpod 环境中,可以直接使用 run.sh 运行示例代码。 +修改代码中的连接信息,之后你就可以直接使用 run.sh 运行示例代码。 ```bash sh run.sh diff --git a/examples/driver/python3-pymysql/README.md b/ob-example-python/pymysql/README.md similarity index 89% rename from examples/driver/python3-pymysql/README.md rename to ob-example-python/pymysql/README.md index 5905d9a..175c923 100644 --- a/examples/driver/python3-pymysql/README.md +++ b/ob-example-python/pymysql/README.md @@ -10,7 +10,7 @@ To prevent environmental problems, it is recommended to use anaconda to set up t Before starting, you need to make sure PyMySQL is installed. PyMySQL is a package used to connect to MySQL server with Python 3.x. For details about the installation and usage of PyMySQL, you can refer to the [Official Documentation](https://pypi.org/project/PyMySQL/) and [API Documentation](https://pymysql.readthedocs.io/en/latest/modules/index.html). -Take [Test.py](Test.py) for example. +Take [example.py](example.py) for example. ```python import pymysql @@ -26,7 +26,7 @@ with conn.cursor() as cur: conn.close() ``` -In the Gitpod environment, you can directly use `run.sh` to run the demo code. +Modify the connection info in code, and use `run.sh` to run the example code. ```bash sh run.sh diff --git a/examples/driver/python3-pymysql/Test.py b/ob-example-python/pymysql/example.py similarity index 54% rename from examples/driver/python3-pymysql/Test.py rename to ob-example-python/pymysql/example.py index d9b81d6..f22231c 100644 --- a/examples/driver/python3-pymysql/Test.py +++ b/ob-example-python/pymysql/example.py @@ -1,37 +1,29 @@ #!/usr/bin/python3 -import os import pymysql -workspace = "/workspace/ob-example" -sql_file = "tests/sql/test.sql" -table_name = "t_test" - - -def load_sql_from_script(filename): - fd = open(filename, 'r') - f = fd.read() - fd.close() - return f.split(';') - - if __name__ == "__main__": conn = pymysql.connect(host="127.0.0.1", port=2881, user="root@test", passwd="", db="test") print("Success to connect to OceanBase with pymysql") + sqls = ['DROP TABLE IF EXISTS `t_test`', + 'CREATE TABLE `t_test` (' + ' `id` int(10) NOT NULL AUTO_INCREMENT, ' + ' `name` varchar(20) DEFAULT NULL, ' + ' PRIMARY KEY (`id`)' + ') ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE = utf8_bin', + 'INSERT INTO `t_test` VALUES (default, "Hello OceanBase")'] + # execute sql script - for sql in load_sql_from_script(os.path.join(workspace, sql_file)): - sql = sql.strip() - if sql == "": - continue - with conn.cursor() as cur: + with conn.cursor() as cur: + for sql in sqls: print("Exec sql: " + sql) cur.execute(sql) # query on test table with conn.cursor() as cur: - sql = 'SELECT * FROM ' + table_name + sql = 'SELECT * FROM `t_test`' print("Query sql: ", sql) cur.execute(sql) ans = cur.fetchall() diff --git a/examples/driver/python3-pymysql/requirements.txt b/ob-example-python/pymysql/requirements.txt similarity index 100% rename from examples/driver/python3-pymysql/requirements.txt rename to ob-example-python/pymysql/requirements.txt diff --git a/examples/driver/python3-pymysql/run.sh b/ob-example-python/pymysql/run.sh similarity index 69% rename from examples/driver/python3-pymysql/run.sh rename to ob-example-python/pymysql/run.sh index abdbf14..2c93cbf 100644 --- a/examples/driver/python3-pymysql/run.sh +++ b/ob-example-python/pymysql/run.sh @@ -1,2 +1,2 @@ python3 -m pip install -r requirements.txt -python3 Test.py +python3 example.py diff --git a/tests/sql/test.sql b/tests/sql/test.sql deleted file mode 100644 index ccf567a..0000000 --- a/tests/sql/test.sql +++ /dev/null @@ -1,8 +0,0 @@ -DROP TABLE IF EXISTS `t_test`; -CREATE TABLE `t_test` ( - `id` int(10) NOT NULL AUTO_INCREMENT, - `name` varchar(20) DEFAULT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE = utf8_bin; - -INSERT INTO `t_test` VALUES (default, 'Hello OceanBase'); \ No newline at end of file diff --git a/tools/gitpod/banner.txt b/tools/gitpod/banner.txt deleted file mode 100644 index 2458381..0000000 --- a/tools/gitpod/banner.txt +++ /dev/null @@ -1,7 +0,0 @@ -\033[32m - ____ ____ - / __ \________ ____ _____ / __ )____ _________ - / / / / ___/ _ \/ __ `/ __ \/ __ / __ `/ ___/ _ \ -/ /_/ / /__/ __/ /_/ / / / / /_/ / /_/ (__ ) __/ -\____/\___/\___/\__,_/_/ /_/_____/\__,_/____/\___/ -\033[0m diff --git a/tools/gitpod/boot.png b/tools/gitpod/boot.png deleted file mode 100644 index 8ca73f2facf5e88711ea0d852bf064b65985eab5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 93679 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

{Srug! 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�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/dev/null 2>/dev/null)) -do - cur_dateTime=`date +"%Y-%m-%d %H:%M:%S"` - echo $cur_dateTime" ob is booting..." - sleep 5s -done - -clear -echo -e "$(< ./tools/gitpod/banner.txt)" - -echo -e "\033[32m\nOceanBase server boot success!\nNow you can use the following commands to connect to the database:\033[0m" -echo -e "\033[32m [1] Connect with user root@sys:\n docker exec -it obstandalone ob-mysql sys\033[0m" -echo -e "\033[32m [2] Connect with user root@test:\n docker exec -it obstandalone ob-mysql root\033[0m" -echo -e "\033[32m [3] Connect with user test@test:\n docker exec -it obstandalone ob-mysql test\033[0m" -