blob: 01ef8606174a7050057cb28a53c9912fe23b4ede [file]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//! Table-model (relational) walkthrough: open a [`TableSession`] via the
//! builder, create a database and table, insert a table-model [`Tablet`]
//! (TAG + FIELD columns), query it back with SQL, then clean up.
//!
//! Run against a local IoTDB (e.g. `docker compose up -d`):
//!
//! ```sh
//! cargo run --example table_session
//! ```
use iotdb_client::{ColumnCategory, Result, TSDataType, TableSession, Tablet, Value};
const DB: &str = "rust_example_db";
fn main() -> Result<()> {
env_logger::init();
// The builder opens the session with sql_dialect="table".
let mut session = TableSession::builder()
.node_urls(&["127.0.0.1:6667"])?
.username("root")
.password("root")
.build()?;
println!("table session opened");
// --- DDL: database + table ------------------------------------------
session.execute_non_query(&format!("CREATE DATABASE IF NOT EXISTS {DB}"))?;
session.execute_non_query(&format!("USE {DB}"))?;
println!("current database: {:?}", session.database());
session.execute_non_query(
"CREATE TABLE IF NOT EXISTS sensors (\
region STRING TAG, \
device_id STRING TAG, \
temperature DOUBLE FIELD, \
status BOOLEAN FIELD)",
)?;
println!("table `sensors` created");
// --- Insert a table-model tablet (TAG/FIELD categories) --------------
let mut tablet = Tablet::new_table(
"sensors",
vec![
"region".into(),
"device_id".into(),
"temperature".into(),
"status".into(),
],
vec![
TSDataType::String,
TSDataType::String,
TSDataType::Double,
TSDataType::Boolean,
],
vec![
ColumnCategory::Tag,
ColumnCategory::Tag,
ColumnCategory::Field,
ColumnCategory::Field,
],
)?;
let base_ts = 1_720_000_000_000i64; // epoch milliseconds
for i in 0..8i64 {
tablet.add_row(
base_ts + i * 1_000,
vec![
Some(Value::String(
if i % 2 == 0 { "east" } else { "west" }.into(),
)),
Some(Value::String(format!("dev-{}", i % 3))),
Some(Value::Double(21.0 + i as f64 * 0.25)),
// Some status readings are missing (null cells).
(i % 3 != 0).then_some(Value::Boolean(i % 2 == 0)),
],
)?;
}
session.insert(&tablet)?;
println!("inserted {} rows into `sensors`", tablet.row_count());
// --- Query with SQL ----------------------------------------------------
{
let mut dataset = session.execute_query(
"SELECT time, region, device_id, temperature, status \
FROM sensors ORDER BY time",
)?;
println!("columns: {:?}", dataset.columns());
while let Some(row) = dataset.next_row()? {
println!("{:?}", row.values);
}
} // dataset drop closes the query and releases the session borrow
// --- Cleanup ----------------------------------------------------------
session.execute_non_query(&format!("DROP DATABASE {DB}"))?;
println!("database dropped");
session.close()?;
println!("session closed");
Ok(())
}