diff --git a/docs/en/developer/00-drivers/00-golang.md b/docs/en/developer/00-drivers/00-golang.md index 750dee579a..dfff130b70 100644 --- a/docs/en/developer/00-drivers/00-golang.md +++ b/docs/en/developer/00-drivers/00-golang.md @@ -1,309 +1,100 @@ --- -title: Golang +title: Go --- -import StepsWrap from '@site/src/components/StepsWrap'; -import StepContent from '@site/src/components/Steps/step-content'; +# Go Driver for Databend -Databend offers a driver (databend-go) written in Golang, which facilitates the development of applications using the Golang programming language and establishes connectivity with Databend. +The official Go driver providing a standard `database/sql` interface for seamless integration with existing Go applications. -For installation instructions, examples, and the source code, see the GitHub [databend-go](https://github.com/databendlabs/databend-go) repo. +## Installation -## Data Type Mappings - -This table illustrates the correspondence between Databend data types and their corresponding Go equivalents: - -| Databend | Go | -| ------------------ | --------------- | -| TINYINT | int8 | -| SMALLINT | int16 | -| INT | int32 | -| BIGINT | int64 | -| TINYINT UNSIGNED | uint8 | -| SMALLINT UNSIGNED | uint16 | -| INT UNSIGNED | uint32 | -| BIGINT UNSIGNED | uint64 | -| Float32 | float32 | -| Float64 | float64 | -| Bitmap | string | -| Decimal | decimal.Decimal | -| String | string | -| Date | time.Time | -| DateTime | time.Time | -| Array(T) | string | -| Tuple(T1, T2, ...) | string | -| Variant | string | - -## Databend Go Driver Behavior Summary - -The Databend Go Driver is compatible with the ["database/sql"](https://pkg.go.dev/database/sql) interface specification. Below are some common basic behaviors, along with the key functions involved and the principles behind them. - -| Basic Behavior | Key Functions Involved | Principle | -| --------------------------- | -------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Creating a connection | `DB.Open` | Establish a connection to Databend using the DSN string and the `DB.Open` method.

The DSN string format is `https://user:password@host/database?=`. | -| Executing statements | `DB.Exec` | The `DB.Exec` method executes SQL statements using the `v1/query` interface for creating, deleting tables and inserting data. | -| Bulk insertion | `DB.Begin`, `Tx.Prepare`, `Stmt.Exec`, `Tx.Commit` | Bulk insert/replace data (`INSERT INTO` and `REPLACE INTO`) are processed through transactions.

Use `Stmt.Exec` to add as much data as possible to a prepared statement object; data will be appended to a file.

Executing `Tx.Commit()` will finally upload the data to the built-in Stage and perform the insert/replace operation, using [Stage Attachment](/developer/apis/http#stage-attachment). | -| Querying single row | `DB.QueryRow`, `Row.Scan` | Use the `DB.QueryRow` method to query a single row of data and return a `*sql.Row`, then call `Row.Scan` to map the column data to variables. | -| Iterating over rows | `DB.Query`, `Rows.Next`, `Rows.Scan` | Use the `DB.Query` method to query multiple rows of data and return a `*sql.Rows` structure, iterate over rows using the `Rows.Next` method, and map the data to variables using `Rows.Scan`. | -| Uploading to internal Stage | `APIClient.UploadToStage` | Upload data to Stage. By default, use `PRESIGN UPLOAD` to get a URL, or if PRESIGN is disabled, use the `v1/upload_to_stage` API. | - -## Tutorial-1: Integrating with Databend using Golang - -Before you start, make sure you have successfully installed a local Databend. For detailed instructions, see [Local and Docker Deployments](/guides/deploy/deploy/non-production/deploying-local). - -### Step 1. Prepare a SQL User Account - -To connect your program to Databend and execute SQL operations, you must provide a SQL user account with appropriate privileges in your code. Create one in Databend if needed, and ensure that the SQL user has only the necessary privileges for security. - -This tutorial uses a SQL user named 'user1' with password 'abc123' as an example. As the program will write data into Databend, the user needs ALL privileges. For how to manage SQL users and their privileges, see [User & Role](/sql/sql-commands/ddl/user/). - -```sql -CREATE USER user1 IDENTIFIED BY 'abc123'; -GRANT ALL on *.* TO user1; +```bash +go get github.com/databendlabs/databend-go ``` -### Step 2. Write a Golang Program +**Connection String**: See [Drivers Overview](./index.md#connection-string-dsn) for DSN format and connection examples. -In this step, you'll create a simple Golang program that communicates with Databend. The program will involve tasks such as creating a table, inserting data, and executing data queries. +--- - +## Key Features - +- ✅ **Standard Interface**: Full `database/sql` compatibility +- ✅ **Connection Pooling**: Built-in connection management +- ✅ **Bulk Operations**: Efficient batch inserts via transactions +- ✅ **Type Safety**: Comprehensive Go type mappings -### Copy and paste the following code to the file main.go +## Data Type Mappings -:::note +| Databend | Go | Notes | +|----------|----|---------| +| **Integers** | | | +| `TINYINT` | `int8` | | +| `SMALLINT` | `int16` | | +| `INT` | `int32` | | +| `BIGINT` | `int64` | | +| `TINYINT UNSIGNED` | `uint8` | | +| `SMALLINT UNSIGNED` | `uint16` | | +| `INT UNSIGNED` | `uint32` | | +| `BIGINT UNSIGNED` | `uint64` | | +| **Floating Point** | | | +| `FLOAT` | `float32` | | +| `DOUBLE` | `float64` | | +| **Other Types** | | | +| `DECIMAL` | `decimal.Decimal` | Requires decimal package | +| `STRING` | `string` | | +| `DATE` | `time.Time` | | +| `TIMESTAMP` | `time.Time` | | +| `ARRAY(T)` | `string` | JSON encoded | +| `TUPLE(...)` | `string` | JSON encoded | +| `VARIANT` | `string` | JSON encoded | +| `BITMAP` | `string` | Base64 encoded | -- The code below connects to a local Databend with a SQL user named 'user1' and password 'abc123' as an example. Feel free to use your own values while maintaining the same format. -- The value of `hostname` in the code below must align with your HTTP handler settings for Databend query service. - ::: +--- -```go title='main.go' -package main +## Basic Usage +```go import ( - "database/sql" - "fmt" - "log" - - _ "github.com/databendcloud/databend-go" -) + "database/sql" + "fmt" + "log" -const ( - username = "user1" - password = "abc123" - hostname = "127.0.0.1:8000" + _ "github.com/databendlabs/databend-go" ) -type Book struct { - Title string - Author string - Date string +// Connect to Databend +db, err := sql.Open("databend", "") +if err != nil { + log.Fatal(err) } +defer db.Close() -func dsn() string { - return fmt.Sprintf("databend://%s:%s@%s?sslmode=disable", username, password, hostname) +// DDL: Create table +_, err = db.Exec("CREATE TABLE users (id INT, name STRING)") +if err != nil { + log.Fatal(err) } -func main() { - db, err := sql.Open("databend", dsn()) - - if err != nil { - log.Fatal(err) - } - defer db.Close() - - err = db.Ping() - if err != nil { - log.Fatal(err) - } - log.Println("Connected") - - // Create db if do not exist - dbSql := "CREATE DATABASE IF NOT EXISTS book_db" - _, err = db.Exec(dbSql) - if err != nil { - log.Fatal(err) - } - log.Println("Create database book_db success") - - // Use book_db database - _, err = db.Exec("USE book_db") - if err != nil { - log.Fatal(err) - } - - // Create table. - sql := "create table if not exists books(title VARCHAR, author VARCHAR, date VARCHAR)" - _, err = db.Exec(sql) - if err != nil { - log.Fatal(err) - } - log.Println("Create table: books") - - // Insert 1 row. - _, err = db.Exec("INSERT INTO books VALUES(?, ?, ?)", "mybook", "author", "2022") - if err != nil { - log.Fatal(err) - } - log.Println("Insert 1 row") - - // Select. - res, err := db.Query("SELECT * FROM books") - if err != nil { - log.Fatal(err) - } - - for res.Next() { - var book Book - err := res.Scan(&book.Title, &book.Author, &book.Date) - if err != nil { - log.Fatal(err) - } - - log.Printf("Select:%v", book) - } - db.Exec("drop table books") - db.Exec("drop database book_db") +// Write: Insert data +_, err = db.Exec("INSERT INTO users VALUES (?, ?)", 1, "Alice") +if err != nil { + log.Fatal(err) } -``` - - - - - -### Install dependencies. - -```shell -go mod init databend-golang -``` - -```text title='go.mod' -module databend-golang -go 1.20 - -require github.com/databendcloud/databend-go v0.3.10 - -require ( - github.com/BurntSushi/toml v1.2.1 // indirect - github.com/avast/retry-go v3.0.0+incompatible // indirect - github.com/google/uuid v1.3.0 // indirect - github.com/pkg/errors v0.9.1 // indirect - github.com/sirupsen/logrus v1.9.0 // indirect - golang.org/x/sys v0.5.0 // indirect -) -``` - - - - - -### Run the program. - -```shell -go run main.go -``` - -```text title='Outputs' -2023/02/24 23:57:31 Connected -2023/02/24 23:57:31 Create database book_db success -2023/02/24 23:57:31 Create table: books -2023/02/24 23:57:31 Insert 1 row -2023/02/24 23:57:31 Select:{mybook author 2022} -``` - - - - - -## Tutorial-2: Integrating with Databend Cloud using Golang - -Before you start, make sure you have successfully created a warehouse and obtained the connection information. For how -to do that, see [Connecting to a Warehouse](/guides/cloud/using-databend-cloud/warehouses#connecting). - -### Step 1. Create a Go Module - -```shell -$ mkdir sample -$ cd sample -$ go mod init cloud.databend.com/sample -``` - -### Step 2. Install Dependencies - -```go -$ go get github.com/databendcloud/databend-go -``` - -### Step 3. Connect with databend-go - -Create a file named `main.go` with the following code: - -```go -package main - -import ( - "database/sql" - "fmt" - - _ "github.com/databendcloud/databend-go" -) - -func main() { - dsn := "databend://{USER}:{PASSWORD}@${HOST}:443/{DATABASE}?&warehouse={WAREHOUSE_NAME}"; - conn, err := sql.Open("databend", dsn) - if err != nil { - fmt.Println(err) - } - conn.Exec(`DROP TABLE IF EXISTS data`) - createTable := `CREATE TABLE IF NOT EXISTS data ( - i64 Int64, - u64 UInt64, - f64 Float64, - s String, - s2 String, - a16 Array(Int16), - a8 Array(UInt8), - d Date, - t DateTime)` - _, err = conn.Exec(createTable) - if err != nil { - fmt.Println(err) - } - scope, err := conn.Begin() - batch, err := scope.Prepare(fmt.Sprintf("INSERT INTO %s VALUES", "data")) - if err != nil { - fmt.Println(err) - } - for i := 0; i < 10; i++ { - _, err = batch.Exec( - "1234", - "2345", - "3.1415", - "test", - "test2", - "[4, 5, 6]", - "[1, 2, 3]", - "2021-01-01", - "2021-01-01 00:00:00", - ) - } - err = scope.Commit() - if err != nil { - fmt.Println(err) - } +// Query: Select data +var id int +var name string +err = db.QueryRow("SELECT id, name FROM users WHERE id = ?", 1).Scan(&id, &name) +if err != nil { + log.Fatal(err) } + +fmt.Printf("User: %d, %s\n", id, name) ``` -:::tip -Replace `{USER}, {PASSWORD}, {HOST}, {WAREHOUSE_NAME} and {DATABASE}` in the code with your connection information. For how to -obtain the connection information, -see [Connecting to a Warehouse](/guides/cloud/using-databend-cloud/warehouses#connecting). -::: +## Resources -### Step 4. Run main.go +- **GitHub Repository**: [databend-go](https://github.com/databendlabs/databend-go) +- **Go Package**: [pkg.go.dev](https://pkg.go.dev/github.com/datafuselabs/databend-go) +- **Examples**: [GitHub Examples](https://github.com/databendlabs/databend-go/tree/main/examples) -```shell -$ go run main.go -``` diff --git a/docs/en/developer/00-drivers/01-python.md b/docs/en/developer/00-drivers/01-python.md index eddd720262..b9a8c9aa43 100644 --- a/docs/en/developer/00-drivers/01-python.md +++ b/docs/en/developer/00-drivers/01-python.md @@ -2,53 +2,126 @@ title: Python --- -Databend offers the following Python packages enabling you to develop Python applications that interact with Databend: +# Python Driver for Databend -- [databend-driver (**Recommended**)](https://pypi.org/project/databend-driver/): A Python driver for Databend, providing both synchronous and asynchronous interfaces to interact with Databend, execute SQL queries, and handle data operations. -- [databend-sqlalchemy](https://github.com/databendcloud/databend-sqlalchemy): Provides a SQL toolkit and [Object-Relational Mapping](https://en.wikipedia.org/wiki/Object%E2%80%93relational_mapping) to interface with the Databend database. [SQLAlchemy](https://www.sqlalchemy.org/) is a popular SQL toolkit and ORM for Python, and databend-SQLAlchemy is a dialect for SQLAlchemy that allows you to use SQLAlchemy to interact with Databend. +Connect to Databend using Python with our official drivers supporting both synchronous and asynchronous operations. -Both packages require Python version 3.7 or higher. To check your Python version, run `python --version` in your command prompt. To install the latest `databend-driver` or `databend-sqlalchemy` package: +## Quick Start -```bash -# install databend-driver -pip install databend-driver +Choose your preferred approach: -# install databend-sqlalchemy -pip install databend-sqlalchemy +| Package | Best For | Installation | +|---------|----------|-------------| +| **databend-driver** | Direct database operations, async/await | `pip install databend-driver` | +| **databend-sqlalchemy** | ORM integration, existing SQLAlchemy apps | `pip install databend-sqlalchemy` | + +**Connection String**: See [Drivers Overview](./index.md#connection-string-dsn) for DSN format and examples. + +--- + +## databend-driver (Recommended) + +### Features +- ✅ **Native Performance**: Direct connection to Databend +- ✅ **Async/Sync Support**: Choose your programming style +- ✅ **PEP 249 Compatible**: Standard Python DB API +- ✅ **Type Safety**: Full Python type mapping + +### Synchronous Usage + +```python +from databend_driver import BlockingDatabendClient + +# Connect and execute +client = BlockingDatabendClient('') +cursor = client.cursor() + +# DDL: Create table +cursor.execute("CREATE TABLE users (id INT, name STRING)") + +# Write: Insert data +cursor.execute("INSERT INTO users VALUES (?, ?)", (1, 'Alice')) + +# Query: Read data +cursor.execute("SELECT * FROM users") +for row in cursor.fetchall(): + print(row.values()) + +cursor.close() +``` + +### Asynchronous Usage + +```python +import asyncio +from databend_driver import AsyncDatabendClient + +async def main(): + client = AsyncDatabendClient('') + conn = await client.get_conn() + + # DDL: Create table + await conn.exec("CREATE TABLE users (id INT, name STRING)") + + # Write: Insert data + await conn.exec("INSERT INTO users VALUES (?, ?)", (1, 'Alice')) + + # Query: Read data + rows = await conn.query_iter("SELECT * FROM users") + async for row in rows: + print(row.values()) + + await conn.close() + +asyncio.run(main()) +``` + +--- + +## databend-sqlalchemy + +For SQLAlchemy ORM integration: + +```python +from sqlalchemy import create_engine, text + +engine = create_engine('') +with engine.connect() as conn: + result = conn.execute(text("SELECT 1")) + print(result.fetchall()) ``` +--- + ## Data Type Mappings -This table illustrates the correspondence between Databend general data types and their corresponding Python equivalents: - -| Databend | Python | -| --------- | ----------------- | -| BOOLEAN | bool | -| TINYINT | int | -| SMALLINT | int | -| INT | int | -| BIGINT | int | -| FLOAT | float | -| DOUBLE | float | -| DECIMAL | decimal.Decimal | -| DATE | datetime.date | -| TIMESTAMP | datetime.datetime | -| VARCHAR | str | -| BINARY | bytes | - -This table illustrates the correspondence between Databend semi-structured data types and their corresponding Python equivalents: - -| Databend | Python | -| -------- | ------ | -| ARRAY | list | -| TUPLE | tuple | -| MAP | dict | -| VARIANT | str | -| BITMAP | str | -| GEOMETRY | str | - -## Tutorials - -- [Integrating with Databend Cloud using databend-driver](/tutorials/programming/python/integrating-with-databend-cloud-using-databend-driver) -- [Integrating with Databend Cloud using databend-sqlalchemy](/tutorials/programming/python/integrating-with-databend-cloud-using-databend-sqlalchemy) -- [Integrating with Self-Hosted Databend](/tutorials/programming/python/integrating-with-self-hosted-databend) \ No newline at end of file +| Databend | Python | Notes | +|----------|--------|-------| +| **Numeric Types** | | | +| `BOOLEAN` | `bool` | | +| `TINYINT` | `int` | | +| `SMALLINT` | `int` | | +| `INT` | `int` | | +| `BIGINT` | `int` | | +| `FLOAT` | `float` | | +| `DOUBLE` | `float` | | +| `DECIMAL` | `decimal.Decimal` | Precision preserved | +| **Date/Time** | | | +| `DATE` | `datetime.date` | | +| `TIMESTAMP` | `datetime.datetime` | | +| `INTERVAL` | `datetime.timedelta` | | +| **Text/Binary** | | | +| `VARCHAR` | `str` | UTF-8 encoded | +| `BINARY` | `bytes` | | +| **Complex Types** | | | +| `ARRAY` | `list` | Nested structures supported | +| `TUPLE` | `tuple` | | +| `MAP` | `dict` | | +| `VARIANT` | `str` | JSON-encoded | +| `BITMAP` | `str` | Base64-encoded | +| `GEOMETRY` | `str` | WKT format | + +## Resources + +- **PyPI**: [databend-driver](https://pypi.org/project/databend-driver/) • [databend-sqlalchemy](https://pypi.org/project/databend-sqlalchemy/) +- **GitHub**: [databend-driver](https://github.com/databendlabs/databend-py) • [databend-sqlalchemy](https://github.com/databendlabs/databend-sqlalchemy) \ No newline at end of file diff --git a/docs/en/developer/00-drivers/02-nodejs.md b/docs/en/developer/00-drivers/02-nodejs.md index eb2178eefa..a0a9c4760b 100644 --- a/docs/en/developer/00-drivers/02-nodejs.md +++ b/docs/en/developer/00-drivers/02-nodejs.md @@ -2,243 +2,84 @@ title: Node.js --- -import StepsWrap from '@site/src/components/StepsWrap'; -import StepContent from '@site/src/components/Steps/step-content'; +# Node.js Driver for Databend -Databend enables you to develop Node.js programs that interact with Databend using Databend Driver Node.js Binding. This driver provides an interface for connecting to Databend and performing operations such as executing SQL queries and retrieving results. With the Databend driver, you can take advantage of the powerful distributed computing capabilities of Databend and build scalable data processing applications. Visit https://www.npmjs.com/package/databend-driver for more information about the driver. +The official Node.js driver providing TypeScript support and Promise-based API for modern JavaScript applications. -To install the Databend driver for Node.js: +## Installation -```shell -npm install --save databend-driver -``` - -:::note -Before installing the driver, make sure to fulfill the following prerequisites: - -- Node.js must already be installed on the environment where you want to install the driver. -- Ensure that you can run the `node` and `npm` commands. -- Depending on your environment, you may require sudo privileges to install the driver. - ::: - -## Data Type Mappings - -This table illustrates the correspondence between Databend general data types and their corresponding Node.js equivalents: - -| Databend | Node.js | -| --------- | ------- | -| BOOLEAN | Boolean | -| TINYINT | Number | -| SMALLINT | Number | -| INT | Number | -| BIGINT | Number | -| FLOAT | Number | -| DOUBLE | Number | -| DECIMAL | String | -| DATE | Date | -| TIMESTAMP | Date | -| VARCHAR | String | -| BINARY | Buffer | - -This table illustrates the correspondence between Databend semi-structured data types and their corresponding Node.js equivalents: - -| Databend | Node.js | -| -------- | ------- | -| ARRAY | Array | -| TUPLE | Array | -| MAP | Object | -| VARIANT | String | -| BITMAP | String | -| GEOMETRY | String | - -## Databend Node.js Driver Behavior Summary - -The Node.js driver offers similar functionalities as a binding of the Rust Driver, with identically named functions having the same logic and capabilities. - -The table below summarizes the main behaviors and functions of the Node.js Driver and their purposes: - -| Function Name | Description | -| ---------------- | ---------------------------------------------------------------------------------------------------------------------------- | -| `info` | Returns the client's connection information. | -| `version` | Returns the result of executing the `SELECT VERSION()` statement. | -| `exec` | Executes an SQL statement and returns the number of rows affected. | -| `query_iter` | Executes an SQL query and returns an iterator for processing results row by row. | -| `query_iter_ext` | Executes an SQL query and returns an iterator that includes statistical information about the results. | -| `query_row` | Executes an SQL query and returns a single row result. | -| `stream_load` | Uploads data to a built-in Stage and executes insert/replace with [stage attachment](/developer/apis/http#stage-attachment). | - -## Tutorial-1: Integrating with Databend using Node.js - -Before you start, make sure you have successfully installed a local Databend. For detailed instructions, see [Local and Docker Deployments](/guides/deploy/deploy/non-production/deploying-local). - -### Step 1. Prepare a SQL User Account - -To connect your program to Databend and execute SQL operations, you must provide a SQL user account with appropriate privileges in your code. Create one in Databend if needed, and ensure that the SQL user has only the necessary privileges for security. - -This tutorial uses a SQL user named 'user1' with password 'abc123' as an example. As the program will write data into Databend, the user needs ALL privileges. For how to manage SQL users and their privileges, see [User & Role](/sql/sql-commands/ddl/user/). - -```sql -CREATE USER user1 IDENTIFIED BY 'abc123'; -GRANT ALL on *.* TO user1; -``` - -### Step 2. Write a Node.js Program - - - - - -### Copy and paste the following code to a file named databend.js: - -```js title='databend.js' -const { Client } = require("databend-driver"); - -// Connecting to a local Databend with a SQL user named 'user1' and password 'abc123' as an example. -// Feel free to use your own values while maintaining the same format. -const dsn = process.env.DATABEND_DSN ? process.env.DATABEND_DSN : "databend://user1:abc123@localhost:8000/default?sslmode=disable"; - -async function create_conn() { - this.client = new Client(dsn); - this.conn = await this.client.getConn(); - console.log("Connected to Databend Server!"); -} - -async function select_books() { - var sql = "CREATE DATABASE IF NOT EXISTS book_db"; - await this.conn.exec(sql); - console.log("Database created"); - - var sql = "USE book_db"; - await this.conn.exec(sql); - console.log("Database used"); - - var sql = "CREATE TABLE IF NOT EXISTS books(title VARCHAR, author VARCHAR, date VARCHAR)"; - await this.conn.exec(sql); - console.log("Table created"); - - var sql = "INSERT INTO books VALUES('Readings in Database Systems', 'Michael Stonebraker', '2004')"; - await this.conn.exec(sql); - console.log("1 record inserted"); - - var sql = "SELECT * FROM books"; - const rows = await this.conn.queryIter(sql); - const ret = []; - let row = await rows.next(); - while (row) { - ret.push(row.values()); - row = await rows.next(); - } - console.log(ret); -} - -create_conn().then(conn => { - select_books(); -}); -``` - - - - - -### Run node databend.js - -```text -Connected to Databend Server! -Database created -Database used -Table created -1 record inserted -[ [ 'Readings in Database Systems', 'Michael Stonebraker', '2004' ] ] +```bash +npm install databend-driver ``` - - - - -## Tutorial-2: Integrating with Databend Cloud using Node.js +**Connection String**: See [Drivers Overview](./index.md#connection-string-dsn) for DSN format and connection examples. -Before you start, make sure you have successfully created a warehouse and obtained the connection information. For how -to do that, see [Connecting to a Warehouse](/guides/cloud/using-databend-cloud/warehouses#connecting). - -### Step 1. Create a Node.js Package - -```shell -$ mkdir databend-sample -$ cd databend-sample -$ npm init -y -``` - -### Step 2. Add Dependencies +--- -Install the Databend driver for Node.js: +## Key Features -```bash -$ npm install --save databend-driver -``` +- ✅ **TypeScript Support**: Full TypeScript definitions included +- ✅ **Promise-based API**: Modern async/await support +- ✅ **Streaming Results**: Efficient handling of large result sets +- ✅ **Connection Pooling**: Built-in connection management -Add a new NPM script to `package.json` : +## Data Type Mappings -```diff - "scripts": { -+ "run-example": "node index.js", - "test": "echo \"Error: no test specified\" && exit 1" - }, -``` +| Databend | Node.js | Notes | +|----------|---------|-------| +| **Basic Types** | | | +| `BOOLEAN` | `boolean` | | +| `TINYINT` | `number` | | +| `SMALLINT` | `number` | | +| `INT` | `number` | | +| `BIGINT` | `number` | | +| `FLOAT` | `number` | | +| `DOUBLE` | `number` | | +| `DECIMAL` | `string` | Precision preserved | +| `STRING` | `string` | | +| **Date/Time** | | | +| `DATE` | `Date` | | +| `TIMESTAMP` | `Date` | | +| **Complex Types** | | | +| `ARRAY(T)` | `Array` | | +| `TUPLE(...)` | `Array` | | +| `MAP(K,V)` | `Object` | | +| `VARIANT` | `string` | JSON encoded | +| `BINARY` | `Buffer` | | +| `BITMAP` | `string` | Base64 encoded | -### Step 3. Connect with databend-driver +--- -Create a file named `index.js` with the following code: +## Basic Usage ```javascript -const { Client } = require("databend-driver"); - -const dsn = process.env.DATABEND_DSN ? process.env.DATABEND_DSN : "databend://{USER}:{PASSWORD}@${HOST}:443/{DATABASE}?&warehouse={WAREHOUSE_NAME}"; - -async function create_conn() { - this.client = new Client(dsn); - this.conn = await this.client.getConn(); - console.log("Connected to Databend Server!"); -} - -async function select_data() { - let sql_table_create = `CREATE TABLE IF NOT EXISTS data ( - i64 Int64, - u64 UInt64, - f64 Float64, - s String, - s2 String, - d Date, - t DateTime)`; - - await this.conn.exec(sql_table_create); - - let sql_insert = "INSERT INTO data VALUES ('1234', '2345', '3.1415', 'test', 'test2', '2021-01-01', '2021-01-01 00:00:00');"; - await this.conn.exec(sql_insert); - - let sql_select = "SELECT * FROM data"; - const rows = await this.conn.queryIter(sql_select); - const ret = []; - let row = await rows.next(); - while (row) { - ret.push(row.values()); - row = await rows.next(); - } - console.log(ret); +const { Client } = require('databend-driver'); + +// Connect to Databend +const client = new Client(''); +const conn = await client.getConn(); + +// DDL: Create table +await conn.exec(`CREATE TABLE users ( + id INT, + name STRING, + email STRING +)`); + +// Write: Insert data +await conn.exec("INSERT INTO users VALUES (?, ?, ?)", [1, "Alice", "alice@example.com"]); + +// Query: Select data +const rows = await conn.queryIter("SELECT id, name, email FROM users WHERE id = ?", [1]); +for await (const row of rows) { + console.log(row.values()); } -create_conn().then(conn => { - select_data(); -}); +conn.close(); ``` -:::tip -Replace `{USER}, {PASSWORD}, {HOST}, {WAREHOUSE_NAME} and {DATABASE}` in the code with your connection information. For how to -obtain the connection information, -see [Connecting to a Warehouse](/guides/cloud/using-databend-cloud/warehouses#connecting). -::: - -### Step 4. Run sample with NPM +## Resources -```shell -$ npm run run-example -``` +- **NPM Package**: [databend-driver](https://www.npmjs.com/package/databend-driver) +- **GitHub Repository**: [databend-js](https://github.com/databendlabs/databend-js) +- **TypeScript Definitions**: Included in package diff --git a/docs/en/developer/00-drivers/03-jdbc.md b/docs/en/developer/00-drivers/03-jdbc.md index 9f9754c4ed..0cd14e669f 100644 --- a/docs/en/developer/00-drivers/03-jdbc.md +++ b/docs/en/developer/00-drivers/03-jdbc.md @@ -1,26 +1,14 @@ --- -title: Java +title: Java (JDBC) --- -You can connect to and interact with Databend from various client tools and applications through a native interface designed for Java programming language, the [Databend JDBC driver](https://github.com/databendcloud/databend-jdbc). +# Java JDBC Driver for Databend -## Installing Databend JDBC Driver +The official JDBC driver providing standard JDBC 4.0 compatibility for seamless integration with Java applications. -This topic outlines the steps to download and install the Databend JDBC driver for use in Java-based projects. The driver requires Java LTS (Long-Term Support) versions 1.8 or higher. If your client machine does not have the minimum required version of Java, install [Oracle Java](http://www.java.com/en/download/manual.jsp) or [OpenJDK](http://openjdk.java.net). +## Installation -To download the Databend JDBC driver: - -1. Go to the Maven Central Repository at https://repo1.maven.org/maven2/com/databend/databend-jdbc/ -2. Click on the directory of the latest version. -3. Download the jar file, for example, _databend-jdbc-0.1.1.jar_. - -To verify the version of Databend JDBC driver, for example, _databend-jdbc-0.1.1.jar_, run the following command in the terminal: - -```bash -java -jar databend-jdbc-0.3.7.jar --version -``` - -The Databend JDBC driver is provided as a JAR file and can be integrated directly into your Java-based projects. Alternatively, you can declare a Maven dependency in your project's pom.xml file, like so: +### Maven ```xml @@ -30,342 +18,91 @@ The Databend JDBC driver is provided as a JAR file and can be integrated directl ``` -:::tip DID YOU KNOW? -You can also connect to Databend from DBeaver through the Databend JDBC driver. For more information, see [Connecting to Databend with JDBC](/guides/sql-clients/jdbc). -::: - -## Data Type Mappings - -This table illustrates the correspondence between Databend data types and their corresponding Java equivalents: - -| Databend | Java | -| --------- | ---------- | -| TINYINT | Byte | -| SMALLINT | Short | -| INT | Integer | -| BIGINT | Long | -| UInt8 | Short | -| UInt16 | Integer | -| UInt32 | Long | -| UInt64 | BigInteger | -| Float32 | Float | -| Float64 | Double | -| String | String | -| Date | String | -| TIMESTAMP | String | -| Bitmap | byte[] | -| Array | String | -| Decimal | BigDecimal | -| Tuple | String | -| Map | String | -| VARIANT | String | - -## Databend JDBC Driver Behavior Summary - -Databend's JDBC Driver generally follows the JDBC specifications. Below is a list of some common basic behaviors, their associated key functions, and the principles behind them. +### Gradle -| Basic Behavior | Key Functions | Principle | -| ---------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Establishing a Connection | `DriverManager.getConnection`, `Properties.setProperty` | `getConnection` establishes a connection with Databend using the provided connection string.

The `Properties` object is used to construct connection parameters, such as `user` and `password`, which can also be specified within the connection string. | -| Executing Queries | `Statement.createStatement()`, `Statement.execute()` | `Statement.execute()` performs queries using the `v1/query` interface. | -| Batch Inserting | `Connection.prepareStatement()`, `PrepareStatement.setInt()`, `PrepareStatement.setString()`, `PrepareStatement.addBatch()`, `PrepareStatement.executeBatch()`, etc. | Databend supports batch insertions and replacements (`INSERT INTO` and `REPLACE INTO`) using `PrepareStatement` objects.

The `PrepareStatement.setXXX()` methods are used for binding values to the parameters of the statement.

`PrepareStatement.addBatch()` adds as much data as possible to the batch for the created statement object.

`PrepareStatement.executeBatch()` uploads data to the built-in Stage and executes insert/replace operations, utilizing [Stage Attachment](/developer/apis/http#stage-attachment). | -| Uploading Files to an Internal Stage | `Connection.uploadStream` | Data will be uploaded to a Stage. By default, the `PRESIGN UPLOAD` is used to obtain a URL, or if PRESIGN is disabled, the `v1/upload_to_stage` API is used. | -| Downloading Files from an Internal Stage | `Connection.downloadStream` | Data will be downloaded from a Stage using the `PRESIGN DOWNLOAD` to obtain a URL. | +```gradle +implementation 'com.databend:databend-jdbc:0.3.7' +``` -## Configuring Connection String +**Connection String**: See [Drivers Overview](./index.md#connection-string-dsn) for DSN format and connection examples. -Once the driver is installed and integrated into your project , you can use it to connect to Databend using the following JDBC connection string format: +--- -```java -jdbc:databend://:@/? -``` +## Key Features -The `connection_params` refers to a series of one or more parameters in the format of `param=value`. Each parameter should be separated by the ampersand character (&), and there should be no spaces anywhere in the connection string. These parameters can be set either in the connection string or in a Properties object passed to the DriverManager.getConnection() method. For example: +- ✅ **JDBC 4.0 Compatible**: Standard JDBC interface support +- ✅ **Connection Pooling**: Built-in connection management +- ✅ **Prepared Statements**: Efficient parameterized queries +- ✅ **Batch Operations**: Bulk insert and update supportations -```java -Properties props = new Properties(); -props.put("parameter1", parameter1Value); -props.put("parameter2", parameter2Value); -Connection con = DriverManager.getConnection("jdbc:databend://user:pass@host/database", props); -``` +## Data Type Mappings -For the available connection parameters and their descriptions, see https://github.com/databendcloud/databend-jdbc/blob/main/docs/Connection.md#connection-parameters +| Databend | Java | Notes | +|----------|------|---------| +| **Integers** | | | +| `TINYINT` | `Byte` | | +| `SMALLINT` | `Short` | | +| `INT` | `Integer` | | +| `BIGINT` | `Long` | | +| `TINYINT UNSIGNED` | `Short` | | +| `SMALLINT UNSIGNED` | `Integer` | | +| `INT UNSIGNED` | `Long` | | +| `BIGINT UNSIGNED` | `BigInteger` | | +| **Floating Point** | | | +| `FLOAT` | `Float` | | +| `DOUBLE` | `Double` | | +| `DECIMAL` | `BigDecimal` | Precision preserved | +| **Other Types** | | | +| `BOOLEAN` | `Boolean` | | +| `STRING` | `String` | | +| `DATE` | `Date` | | +| `TIMESTAMP` | `Timestamp` | | +| `ARRAY(T)` | `String` | JSON encoded | +| `TUPLE(...)` | `String` | JSON encoded | +| `MAP(K,V)` | `String` | JSON encoded | +| `VARIANT` | `String` | JSON encoded | +| `BITMAP` | `String` | Base64 encoded | -## Examples +--- -### Example: Creating a Database and Table +## Basic Usage ```java -package com.example; - import java.sql.*; -import java.util.Properties; - -public class Main { - // Connecting to a local Databend with a SQL user named 'user1' and password 'abc123' as an example. - // Feel free to use your own values while maintaining the same format. - static final String DB_URL = "jdbc:databend://127.0.0.1:8000"; - - public static void main(String[] args) throws Exception { - Properties properties = new Properties(); - properties.setProperty("user", "user1"); - properties.setProperty("password", "abc123"); - properties.setProperty("SSL", "false"); - Connection conn = DriverManager.getConnection(DB_URL, properties); - - Statement stmt = conn.createStatement(); - String create_sql = "CREATE DATABASE IF NOT EXISTS book_db"; - stmt.execute(create_sql); - - String use_sql = "USE book_db"; - stmt.execute(use_sql); - - String ct_sql = "CREATE TABLE IF NOT EXISTS books(title VARCHAR, author VARCHAR, date VARCHAR)"; - stmt.execute(ct_sql); - stmt.close(); - conn.close(); - System.exit(0); - } +// Connect to Databend +Connection conn = DriverManager.getConnection(""); + +// DDL: Create table +Statement stmt = conn.createStatement(); +stmt.execute("CREATE TABLE users (id INT, name STRING, email STRING)"); + +// Write: Insert data +PreparedStatement pstmt = conn.prepareStatement("INSERT INTO users VALUES (?, ?, ?)"); +pstmt.setInt(1, 1); +pstmt.setString(2, "Alice"); +pstmt.setString(3, "alice@example.com"); +pstmt.executeUpdate(); + +// Query: Select data +ResultSet rs = stmt.executeQuery("SELECT id, name, email FROM users WHERE id = 1"); +while (rs.next()) { + System.out.println("User: " + rs.getInt("id") + ", " + + rs.getString("name") + ", " + + rs.getString("email")); } -``` - -### Example: Copy into or merge into table - -```java - public void copyInto(String tableName, List files) throws Exception { - String filesStr = "'" + String.join("','", files) + "'"; - String copyIntoSql = String.format("copy into %s from @~ files=(%s) file_format=(type=NDJSON) purge=true;", tableName, filesStr); - Connection connection = createConnection(); - try (Statement statement = connection.createStatement()) { - Instant copyIntoStart = Instant.now(); - statement.execute(copyIntoSql); - ResultSet r = statement.getResultSet(); - while (r.next()) { - } - Instant copyIntoEnd = Instant.now(); - System.out.println("Copied files into: " + files.size() + " , time elapsed: " + (copyIntoEnd.toEpochMilli() - copyIntoStart.toEpochMilli()) + "ms"); - } catch (Exception e) { - e.printStackTrace(); - } finally { - connection.close(); - } - } -// For merge into just replace the copyIntoSql. -``` - -:::tip - -1. Because the SQL commands such as SELECT, COPY INTO, and MERGE INTO return a ResultSet object, it is necessary to call rs.next() before accessing the data. Failure to do so may result in the query being canceled. If you don't intend to retrieve the results, you can iterate over the ResultSet using a while loop (while (r.next()){}) to avoid this issue. -2. For other SQL commands such as CREATE TABLE or DROP TABLE, which are non-query type SQL, you can call statement.execute() directly. - ::: - -### Example: Batch Inserting -In your Java application code, you can insert multiple rows in a single batch by binding parameters in an INSERT statement and calling addBatch() and executeBatch(). - -As an example, the following code inserts two rows into a table that contains an INT column and a VARCHAR column. The example binds values to the parameters in the INSERT statement and calls addBatch() and executeBatch() to perform a batch insert. - -```java -Connection connection = DriverManager.getConnection(url, prop); - -PreparedStatement pstmt = connection.prepareStatement("INSERT INTO t(c1, c2) VALUES(?, ?)"); -pstmt.setInt(1, 101); -pstmt.setString(2, "test1"); -pstmt.addBatch(); - -pstmt.setInt(1, 102); -pstmt.setString(2, "test2"); -pstmt.addBatch(); - -int[] count = pstmt.executeBatch(); // After execution, count[0]=1, count[1]=1 -... +// Close connections +rs.close(); +stmt.close(); pstmt.close(); +conn.close(); ``` -### Example: Batch Update -You can update multiple rows in a single batch binding parameters in an REPLACE INTO statement and calling addBatch() and executeBatch(). - -As an example, the following code update the rows which have conflict values in field `a`. The example binds values to the parameters in the REPLACE INTO statement and calls addBatch() and executeBatch() to perform a batch update according to the key field. -```java -Connection c = Utils.createConnection(); -c.setAutoCommit(false); -PreparedStatement ps1 = c.prepareStatement("insert into test_prepare_statement values"); -ps1.setInt(1, 1); -ps1.setInt(2, 2); -ps1.addBatch(); -ps1.executeBatch(); - -PreparedStatement ps = c.prepareStatement("replace into test_prepare_statement on(a) values"); -ps.setInt(1, 1); -ps.setString(2, "a"); -ps.addBatch(); -ps.setInt(1, 3); -ps.setString(2, "b"); -ps.addBatch(); -System.out.println("execute batch replace into"); -int[] ans = ps.executeBatch(); -... -``` +## Resources -:::tip -Databend does not support `executeBatch()` in UPDATE statement. If you want to do batch update, please use REPLACE INTO. -::: +- **Maven Central**: [databend-jdbc](https://repo1.maven.org/maven2/com/databend/databend-jdbc/) +- **GitHub Repository**: [databend-jdbc](https://github.com/databendcloud/databend-jdbc) +- **JDBC Documentation**: [Oracle JDBC Guide](https://docs.oracle.com/javase/tutorial/jdbc/) -### Example: Uploading Files to an Internal Stage -```java - /** - * Upload inputStream to the databend internal stage, the data would be uploaded as one file with no split. - * Caller should close the input stream after the upload is done. - * - * @param stageName the stage which receive uploaded file - * @param destPrefix the prefix of the file name in the stage - * @param inputStream the input stream of the file - * @param destFileName the destination file name in the stage - * @param fileSize the file size in the stage - * @param compressData whether to compress the data - * @throws SQLException failed to upload input stream - */ - public void uploadStream(String stageName, String destPrefix, InputStream inputStream, String destFileName, long fileSize, boolean compressData) throws SQLException; -``` - -Uploading CSV File to Databend: - -```java - File f = new File("test.csv"); - try (InputStream fileInputStream = Files.newInputStream(f.toPath())) { - Logger.getLogger(OkHttpClient.class.getName()).setLevel(Level.ALL); - Connection connection = createConnection(); - String stageName = "test_stage"; - DatabendConnection databendConnection = connection.unwrap(DatabendConnection.class); - PresignContext.createStageIfNotExists(databendConnection, stageName); - databendConnection.uploadStream(stageName, "jdbc/test/", fileInputStream, "test.csv", f.length(), false); - } catch (Exception e) { - throw new RuntimeException(e); - } finally { - f.delete(); - } -``` - -### Example: Downloading Files from an Internal Stage - -```java - /** - * Download a file from the databend internal stage, the data would be downloaded as one file with no split. - * - * @param stageName the stage which contains the file - * @param sourceFileName the file name in the stage - * @param decompress whether to decompress the data - * @return the input stream of the file - * @throws SQLException - */ - public InputStream downloadStream(String stageName, String sourceFileName, boolean decompress) throws SQLException; -``` - -Downloading CSV File from Databend: - -```Java - File f = new File("test.csv"); - try (InputStream fileInputStream = Files.newInputStream(f.toPath())) { - Logger.getLogger(OkHttpClient.class.getName()).setLevel(Level.ALL); - Connection connection = createConnection(true); - String stageName = "test_stage"; - DatabendConnection databendConnection = connection.unwrap(DatabendConnection.class); - PresignContext.createStageIfNotExists(databendConnection, stageName); - databendConnection.uploadStream(stageName, "jdbc/test/", fileInputStream, "test.csv", f.length(), false); - InputStream downloaded = databendConnection.downloadStream(stageName, "jdbc/test/test.csv", false); - byte[] arr = streamToByteArray(downloaded); - System.out.println(arr); - } catch (Exception e) { - throw new RuntimeException(e); - } finally { - f.delete(); - } -``` - -### Example: Integrating with Databend Cloud - -Before you start, make sure you have successfully created a warehouse and obtained the connection information. For how to do that, see [Connecting to a Warehouse](/guides/cloud/using-databend-cloud/warehouses#connecting). - -#### Step 1. Add Dependencies with Maven - -```xml - - com.databend - databend-jdbc - 0.2.8 - -``` - -#### Step 2. Connect with databend-jdbc - -Create a file named `sample.java` with the following code: - -```java -package databend_cloud; - -import java.sql.*; -import java.util.Properties; - -public class sample { - public static void main(String[] args) throws Exception { - - String url = "jdbc:databend://{WAREHOUSE_HOST}:443/{DATABASE}"; - Properties properties = new Properties(); - properties.setProperty("user", "{USER}"); - properties.setProperty("password", "{PASSWORD}"); - properties.setProperty("SSL", "true"); - Connection connection = DriverManager.getConnection(url, properties); - - // Execute - connection.createStatement().execute("CREATE TABLE IF NOT EXISTS sample_test(id TINYINT, obj VARIANT, d TIMESTAMP, s String, arr ARRAY(INT64)) Engine = Fuse"); - - // SELECT - Statement statement = connection.createStatement(); - statement.execute("SELECT number from numbers(200000) order by number"); - ResultSet r = statement.getResultSet(); - r.next(); - for (int i = 1; i < 1000; i++) { - r.next(); - System.out.println(r.getInt(1)); - } - - // INSERT INTO Using executeBatch() - connection.setAutoCommit(false); - PreparedStatement ps = connection.prepareStatement("insert into sample_test values"); - ps.setInt(1, 1); - ps.setString(2, "{\"a\": 1,\"b\": 2}"); - ps.setTimestamp(3, Timestamp.valueOf("1983-07-12 21:30:55.888")); - ps.setString(4, "hello world, 你好"); - ps.setString(5, "[1,2,3,4,5]"); - ps.addBatch(); - int[] ans = ps.executeBatch(); - Statement s = connection.createStatement(); - - System.out.println("execute select on table"); - statement.execute("SELECT * from sample_test"); - ResultSet r2 = statement.getResultSet(); - - while (r2.next()) { - System.out.println(r2.getInt(1)); - System.out.println(r2.getString(2)); - System.out.println(r2.getTimestamp(3).toString()); - System.out.println(r2.getString(4)); - System.out.println(r2.getString(5)); - } - connection.close(); - } -} -``` - -:::tip -Replace `{USER}, {PASSWORD}, {WAREHOUSE_HOST}, and {DATABASE}` in the code with your connection information. For how to obtain the connection information, see [Connecting to a Warehouse](/guides/cloud/using-databend-cloud/warehouses#connecting). -::: - -#### Step 3. Run sample with Maven - -```shell -$ mvn compile -$ mvn exec:java -D exec.mainClass="databend_cloud.sample" -``` diff --git a/docs/en/developer/00-drivers/04-rust.md b/docs/en/developer/00-drivers/04-rust.md index 7f1f9f0d93..1e325eee65 100644 --- a/docs/en/developer/00-drivers/04-rust.md +++ b/docs/en/developer/00-drivers/04-rust.md @@ -2,258 +2,106 @@ title: Rust --- -import StepsWrap from '@site/src/components/StepsWrap'; -import StepContent from '@site/src/components/Steps/step-content'; +# Rust Driver for Databend -Databend offers a driver ([crates.io - databend-driver](https://crates.io/crates/databend-driver)) written in Rust, which facilitates the development of applications using the Rust programming language and establishes connectivity with Databend. Please note that the driver currently does not support handling arrays. +The official Rust driver providing native connectivity with async/await support and comprehensive type safety for Rust applications. -For installation instructions, examples, and the source code, see [GitHub - databend-driver](https://github.com/databendlabs/BendSQL/tree/main/driver). +## Installation -## Data Type Mappings - -This table illustrates the correspondence between Databend general data types and their corresponding Rust equivalents: - -| Databend | Rust | -| --------- | --------------------- | -| BOOLEAN | bool | -| TINYINT | i8,u8 | -| SMALLINT | i16,u16 | -| INT | i32,u32 | -| BIGINT | i64,u64 | -| FLOAT | f32 | -| DOUBLE | f64 | -| DECIMAL | String | -| DATE | chrono::NaiveDate | -| TIMESTAMP | chrono::NaiveDateTime | -| VARCHAR | String | -| BINARY | `Vec` | - -This table illustrates the correspondence between Databend semi-structured data types and their corresponding Rust equivalents: - -| Databend | Rust | -| ----------- | --------------- | -| ARRAY[T] | `Vec ` | -| TUPLE[T, U] | (T, U) | -| MAP[K, V] | `HashMap` | -| VARIANT | String | -| BITMAP | String | -| GEOMETRY | String | - -## Databend Rust Driver Behavior Summary - -The table below summarizes the main behaviors and functions of the Rust Driver and their purposes: - -| Function Name | Description | -| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | -| `info` | Returns the client's connection information. | -| `version` | Returns the result of executing the `SELECT VERSION()` statement. | -| `exec` | Executes an SQL statement and returns the number of rows affected. | -| `query_iter` | Executes an SQL query and returns an iterator for processing results row by row. | -| `query_iter_ext` | Executes an SQL query and returns an iterator that includes statistical information about the results. | -| `query_row` | Executes an SQL query and returns a single row result. | -| `get_presigned_url` | Generates a `PRESIGN` statement based on operation and Stage parameters, returning the HTTP method, headers, and URL. | -| `upload_to_stage` | Uploads data to a Stage. Uses `PRESIGN UPLOAD` by default for URL, or the `v1/upload_to_stage` API if PRESIGN is disabled. | -| `load_data` | Uploads data to a built-in Stage (`upload_to_stage`) and executes insert/replace with [stage attachment](/developer/apis/http#stage-attachment). | -| `load_file` | Reuses the `load_data` logic to upload a file and insert data. | -| `stream_load` | Reads data as a Vec, converts it to CSV, then calls the `load_data` method. | - -## Tutorial-1: Integrating with Databend using Rust - -Before you start, make sure you have successfully installed a local Databend. For detailed instructions, see [Local and Docker Deployments](/guides/deploy/deploy/non-production/deploying-local). - -### Step 1. Prepare a SQL User Account - -To connect your program to Databend and execute SQL operations, you must provide a SQL user account with appropriate privileges in your code. Create one in Databend if needed, and ensure that the SQL user has only the necessary privileges for security. - -This tutorial uses a SQL user named 'user1' with password 'abc123' as an example. As the program will write data into Databend, the user needs ALL privileges. For how to manage SQL users and their privileges, see [User & Role](/sql/sql-commands/ddl/user/). - -```sql -CREATE USER user1 IDENTIFIED BY 'abc123'; -GRANT ALL on *.* TO user1; -``` - -### Step 2. Write a Rust Program - -In this step, you'll create a simple Rust program that communicates with Databend. The program will involve tasks such as creating a table, inserting data, and executing data queries. - - - - - -### Create a new project - -```shell -cargo new databend-demo --bin -``` - -```toml title='Cargo.toml' -[package] -name = "databend-demo" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +Add the driver to your `Cargo.toml`: +```toml [dependencies] databend-driver = "0.7" tokio = { version = "1", features = ["full"] } -tokio-stream = "0.1.12" -``` - - - - - -### Copy and paste the following code to the file main.rs - -:::note -The value of `hostname` in the code below must align with your HTTP handler settings for Databend query service. -::: - -```rust title='main.rs' -use databend_driver::Client; -use tokio_stream::StreamExt; - -#[tokio::main] -async fn main() { - // Connecting to a local Databend with a SQL user named 'user1' and password 'abc123' as an example. - // Feel free to use your own values while maintaining the same format. - let dsn = "databend://user1:abc123@localhost:8000/default?sslmode=disable"; - let client = Client::new(dsn.to_string()); - let conn = client.get_conn().await.unwrap(); - - let sql_db_create = "CREATE DATABASE IF NOT EXISTS book_db;"; - conn.exec(sql_db_create).await.unwrap(); - - let sql_table_create = "CREATE TABLE book_db.books ( - title VARCHAR, - author VARCHAR, - date VARCHAR -);"; - - conn.exec(sql_table_create).await.unwrap(); - let sql_insert = "INSERT INTO book_db.books VALUES ('mybook', 'author', '2022');"; - conn.exec(sql_insert).await.unwrap(); - - let mut rows = conn.query_iter("SELECT * FROM book_db.books;").await.unwrap(); - while let Some(row) = rows.next().await { - let (title, author, date): (String, String, String) = row.unwrap().try_into().unwrap(); - println!("{} {} {}", title, author, date); - } - - let sql_table_drop = "DROP TABLE book_db.books;"; - conn.exec(sql_table_drop).await.unwrap(); - - let sql_db_drop = "DROP DATABASE book_db;"; - conn.exec(sql_db_drop).await.unwrap(); -} ``` - - - - -### Run the program. - -```shell -cargo run -``` - -```text title='Outputs' -mybook author 2022 -``` - - - - - -## Tutorial-2: Integrating with Databend Cloud using Rust +**Connection String**: See [Drivers Overview](./index.md#connection-string-dsn) for DSN format and connection examples. -Before you start, make sure you have successfully created a warehouse and obtained the connection information. For how -to do that, see [Connecting to a Warehouse](/guides/cloud/using-databend-cloud/warehouses#connecting). - -### Step 1. Create a Rust Crate - -```shell -$ cargo new databend-sample --bin -``` +--- -### Step 2. Add Dependencies +## Key Features -Edit the file named `Cargo.toml` with the following code: +- ✅ **Async/Await Support**: Built for modern Rust async programming +- ✅ **Type Safety**: Strong type mapping with Rust's type system +- ✅ **Connection Pooling**: Efficient connection management +- ✅ **Stage Operations**: Upload/download data to/from Databend stages +- ✅ **Streaming Results**: Process large result sets efficiently -```toml -[package] -name = "databend-sample" -version = "0.1.0" -edition = "2021" +## Data Type Mappings -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +### Basic Types +| Databend | Rust | Notes | +| --------- | --------------------- | ------------------------ | +| BOOLEAN | bool | | +| TINYINT | i8, u8 | | +| SMALLINT | i16, u16 | | +| INT | i32, u32 | | +| BIGINT | i64, u64 | | +| FLOAT | f32 | | +| DOUBLE | f64 | | +| DECIMAL | String | Precision preserved | +| VARCHAR | String | UTF-8 encoded | +| BINARY | `Vec` | | + +### Date/Time Types +| Databend | Rust | Notes | +| --------- | --------------------- | ------------------------ | +| DATE | chrono::NaiveDate | Requires chrono crate | +| TIMESTAMP | chrono::NaiveDateTime | Requires chrono crate | + +### Complex Types +| Databend | Rust | Notes | +| ----------- | --------------- | ------------------------ | +| ARRAY[T] | `Vec` | Nested arrays supported | +| TUPLE[T, U] | (T, U) | Multiple element tuples | +| MAP[K, V] | `HashMap` | Key-value mappings | +| VARIANT | String | JSON-encoded | +| BITMAP | String | Base64-encoded | +| GEOMETRY | String | WKT format | -[dependencies] -chrono = "0.4" -databend-driver = "0.6" -tokio = { version = "1", features = ["full"] } -tokio-stream = "0.1" -``` +--- -### Step 3. Connect with databend-driver +## Basic Usage -Edit the file named `main.rs` with the following code: +Here's a simple example demonstrating DDL, write, and query operations: ```rust use databend_driver::Client; use tokio_stream::StreamExt; #[tokio::main] -async fn main() { - let dsn = "databend://{USER}:{PASSWORD}@${HOST}:443/{DATABASE}?&warehouse={WAREHOUSE_NAME}"; - let client = Client::new(dsn.to_string()); - let conn = client.get_conn().await.unwrap(); - - let sql_table_dorp = "DROP TABLE IF EXISTS data;"; - conn.exec(sql_table_drop).await.unwrap(); - - let sql_table_create = "CREATE TABLE IF NOT EXISTS data ( - i64 Int64, - u64 UInt64, - f64 Float64, - s String, - s2 String, - d Date, - t DateTime)"; - - conn.exec(sql_table_create).await.unwrap(); - let sql_insert = "INSERT INTO data VALUES ('1234', '2345', '3.1415', 'test', 'test2', '2021-01-01', '2021-01-01 00:00:00');"; - conn.exec(sql_insert).await.unwrap(); - - let mut rows = conn.query_iter("SELECT * FROM data;").await.unwrap(); +async fn main() -> Result<(), Box> { + // Connect to Databend + let client = Client::new("".to_string()); + let conn = client.get_conn().await?; + + // DDL: Create table + conn.exec("CREATE TABLE IF NOT EXISTS users (id INT, name VARCHAR, created_at TIMESTAMP)") + .await?; + + // Write: Insert data + conn.exec("INSERT INTO users VALUES (1, 'Alice', '2023-12-01 10:00:00')") + .await?; + conn.exec("INSERT INTO users VALUES (2, 'Bob', '2023-12-01 11:00:00')") + .await?; + + // Query: Select data + let mut rows = conn.query_iter("SELECT id, name, created_at FROM users ORDER BY id") + .await?; + while let Some(row) = rows.next().await { - let (col1, col2, col3, col4, col5, col6, col7): ( - i64, - u64, - f64, - String, - String, - chrono::NaiveDate, - chrono::NaiveDateTime, - ) = row.unwrap().try_into().unwrap(); - println!( - "{} {} {} {} {} {} {}", - col1, col2, col3, col4, col5, col6, col7 - ); + let (id, name, created_at): (i32, String, chrono::NaiveDateTime) = + row?.try_into()?; + println!("User {}: {} (created: {})", id, name, created_at); } + + Ok(()) } ``` -:::tip -Replace `{USER}, {PASSWORD}, {WAREHOUSE_HOST}, and {DATABASE}` in the code with your connection information. For how to -obtain the connection information, -see [Connecting to a Warehouse](/guides/cloud/using-databend-cloud/warehouses#connecting). -::: +## Resources -### Step 4. Run sample with Cargo - -```shell -$ cargo run -``` +- **Crates.io**: [databend-driver](https://crates.io/crates/databend-driver) +- **GitHub Repository**: [BendSQL/driver](https://github.com/databendlabs/BendSQL/tree/main/driver) +- **Rust Documentation**: [docs.rs/databend-driver](https://docs.rs/databend-driver) diff --git a/docs/en/developer/00-drivers/index.md b/docs/en/developer/00-drivers/index.md new file mode 100644 index 0000000000..322587b82a --- /dev/null +++ b/docs/en/developer/00-drivers/index.md @@ -0,0 +1,38 @@ +--- +title: Drivers +--- + +Databend provides official drivers for multiple programming languages, enabling you to connect and interact with Databend from your applications. + +## Quick Start + +1. **Choose your language** - Select from Python, Go, Node.js, Java, or Rust +2. **Get your connection string** - Use the DSN format below +3. **Install and connect** - Follow the driver-specific documentation + +## Connection String (DSN) + +All Databend drivers use the same DSN (Data Source Name) format: + +``` +databend://user[:password]@host[:port]/[database][?sslmode=disable][&arg1=value1] +``` + +### Examples + +| Deployment | Connection String | +|------------|-------------------| +| **Self-hosted** | `databend://user:pass@localhost:8000/database?sslmode=disable` | +| **Databend Cloud** | `databend://cloudapp:pass@host:443/database?warehouse=wh` | + +> **Databend Cloud users**: [Get your connection info →](/guides/cloud/using-databend-cloud/warehouses#obtaining-connection-information) + +## Available Drivers + +| Language | Package | Key Features | +|----------|---------|-------------| +| **[Python](./python)** | `databend-driver`
`databend-sqlalchemy` | • Sync/async support
• SQLAlchemy dialect
• PEP 249 compatible | +| **[Go](./golang)** | `databend-go` | • database/sql interface
• Connection pooling
• Bulk operations | +| **[Node.js](./nodejs)** | `databend-driver` | • TypeScript support
• Promise-based API
• Streaming results | +| **[Java](./jdbc)** | `databend-jdbc` | • JDBC 4.0 compatible
• Connection pooling
• Prepared statements | +| **[Rust](./rust)** | `databend-driver` | • Async/await support
• Type-safe queries
• Zero-copy deserialization | diff --git a/docs/en/developer/index.md b/docs/en/developer/index.md index d2eb202512..e97b746a42 100644 --- a/docs/en/developer/index.md +++ b/docs/en/developer/index.md @@ -3,22 +3,35 @@ title: Developer Resources sidebar_position: -2 --- +# Developer Resources + +Build applications with Databend using our official drivers, APIs, and development tools. + ## Drivers -Learn to use programming languages such as Go, Python, Node.js, Java, and Rust to develop applications that interact with Databend. Drivers described in the table below can be used to access Databend or Databend Cloud from these applications, enabling communication with Databend from the supported languages. +Connect to Databend using native drivers for popular programming languages. All drivers support both Databend self-hosted and Databend Cloud deployments. -| Language | Drivers | Native? | Description | -| -------- | ------------------------------------------------------------------------------------------------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| Go | [ databend-go ](https://github.com/databendlabs/databend-go) | Yes | Connect to and interact with Databend or Databend Cloud through a native interface designed for Go programming language. [Click here](00-drivers/00-golang.md) for more information about the driver installation, tutorials, and code samples. | -| Python | [databend-driver](https://pypi.org/project/databend-driver/) & [ databend-sqlalchemy ](https://github.com/databendcloud/databend-py) | Yes | Connect to and interact with Databend or Databend Cloud through a native interface developed for Python programming language. [Click here](00-drivers/01-python.md) for more information about the driver installation, tutorials, and code samples. | -| Node.js | [databend-driver](https://www.npmjs.com/package/databend-driver) | Yes | Connect to and interact with Databend or Databend Cloud using the Databend Driver Node.js Binding. [Click here](00-drivers/02-nodejs.md) for more information about the driver installation, tutorials, and code samples. | -| Java | [databend-jdbc](https://github.com/databendcloud/databend-jdbc) | Yes | Connect to and interact with Databend or Databend Cloud from various client tools and applications through a native interface designed for Java programming language. [Click here](00-drivers/03-jdbc.md) for more information about the driver installation, tutorials, and code samples. | -| Rust | [databend-driver](https://github.com/databendlabs/BendSQL/tree/main/driver) | Yes | Connect to and interact with Databend or Databend Cloud through a native interface developed for Rust programming language. [Click here](00-drivers/04-rust.md) for more information about the driver installation, tutorials, and code samples. | +| Language | Package | Key Features | Documentation | +|----------|---------|-------------|---------------| +| **Go** | [databend-go](https://github.com/databendlabs/databend-go) | Standard database/sql interface, connection pooling | [View Guide](00-drivers/00-golang.md) | +| **Python** | [databend-driver](https://pypi.org/project/databend-driver/) | Sync/async support, SQLAlchemy dialect available | [View Guide](00-drivers/01-python.md) | +| **Node.js** | [databend-driver](https://www.npmjs.com/package/databend-driver) | TypeScript support, Promise-based API | [View Guide](00-drivers/02-nodejs.md) | +| **Java** | [databend-jdbc](https://github.com/databendcloud/databend-jdbc) | JDBC 4.0 compatible, prepared statements | [View Guide](00-drivers/03-jdbc.md) | +| **Rust** | [databend-driver](https://github.com/databendlabs/BendSQL/tree/main/driver) | Async/await support, type-safe queries | [View Guide](00-drivers/04-rust.md) | ## APIs -Databend offers a variety of powerful APIs, allowing you to seamlessly interact with the system, integrate with external databases, enable real-time data ingestion, and simplify file uploads. Feel free to utilize these APIs when developing in supported languages to leverage the full potential of Databend. +Databend provides REST APIs for direct integration and custom applications. + +| API | Description | Use Cases | +|-----|-------------|----------| +| [HTTP API](10-apis/http.md) | RESTful interface for SQL execution and data operations | Custom integrations, direct SQL execution | + +## Development Tools + +- **[BendSQL CLI](/tutorials/connect/connect-to-databendcloud-bendsql)** - Command-line interface for Databend +- **[Databend Cloud Console](/guides/cloud/using-databend-cloud/worksheet)** - Web-based management interface + +## Additional Resources -| API | Description | -| ------------------------------- | ------------------------------------------------------- | -| [HTTP Handler](10-apis/http.md) | Allows interaction with Databend through HTTP requests. | +- **[Community](https://github.com/databendlabs/databend)** - Get help and share knowledge