Skip to content

Commit 7cd6b4c

Browse files
committed
tests
1 parent 7513fba commit 7cd6b4c

File tree

6 files changed

+101
-15
lines changed

6 files changed

+101
-15
lines changed

README.md

+7
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
# chdb-rust <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/d/d5/Rust_programming_language_black_logo.svg/1024px-Rust_programming_language_black_logo.svg.png" height=20 />
66
Experimental [chDB](https://github.com/chdb-io/chdb) FFI bindings for Rust
7+
78
### Status
89

910
- Experimental, unstable, subject to changes
@@ -14,3 +15,9 @@ Experimental [chDB](https://github.com/chdb-io/chdb) FFI bindings for Rust
1415
./update_libchdb.sh
1516
RUST_BACKTRACE=full cargo build --verbose
1617
```
18+
19+
### Run tests
20+
`cargo test`
21+
22+
### Examples
23+
See `tests` directory.

src/arg.rs

-7
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,15 @@ use std::borrow::Cow;
22
use std::ffi::CString;
33

44
use crate::error::Error;
5-
use crate::format::InputFormat;
65
use crate::format::OutputFormat;
76
use crate::log_level::LogLevel;
87

98
#[derive(Debug)]
109
pub enum Arg<'a> {
1110
/// --config-file=<value>
1211
ConfigFilePath(Cow<'a, str>),
13-
/// --database=<value>
14-
Database(Cow<'a, str>),
1512
/// --log-level=<value>
1613
LogLevel(LogLevel),
17-
/// --input-format=<value>
18-
InputFormat(InputFormat),
1914
/// --output-format=<value>
2015
OutputFormat(OutputFormat),
2116
/// --multiquery
@@ -39,9 +34,7 @@ impl<'a> Arg<'a> {
3934
pub(crate) fn to_cstring(&self) -> Result<CString, Error> {
4035
Ok(match self {
4136
Self::ConfigFilePath(v) => CString::new(format!("--config-file={}", v)),
42-
Self::Database(v) => CString::new(format!("--database={}", v)),
4337
Self::LogLevel(v) => CString::new(format!("--log-level={}", v.as_str())),
44-
Self::InputFormat(v) => CString::new(format!("--input-format={}", v.as_str())),
4538
Self::OutputFormat(v) => CString::new(format!("--output-format={}", v.as_str())),
4639
Self::MultiQuery => CString::new("-n"),
4740
Self::Custom(k, v) => match v {

src/format.rs

+2
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ pub enum OutputFormat {
131131
RawBLOB,
132132
MsgPack,
133133
Markdown,
134+
Vertical,
134135
}
135136

136137
impl InputFormat {
@@ -274,6 +275,7 @@ impl OutputFormat {
274275
Self::RawBLOB => "RawBLOB",
275276
Self::MsgPack => "MsgPack",
276277
Self::Markdown => "Markdown",
278+
Self::Vertical => "Vertical",
277279
}
278280
}
279281
}

src/query_result.rs

+11-8
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
use core::slice;
2+
use std::borrow::Cow;
3+
use std::ffi::CStr;
24
use std::time::Duration;
35

46
use crate::bindings;
@@ -13,6 +15,10 @@ impl QueryResult {
1315
.map_err(|e| Error::NonUtf8Sequence(e.to_string()))
1416
}
1517

18+
pub fn data_utf8_lossy<'a>(&'a self) -> Cow<'a, str> {
19+
String::from_utf8_lossy(self.data_ref())
20+
}
21+
1622
pub fn data_utf8_unchecked(&self) -> String {
1723
unsafe { String::from_utf8_unchecked(self.data_ref().to_vec()) }
1824
}
@@ -38,18 +44,15 @@ impl QueryResult {
3844
}
3945

4046
pub(crate) fn check_error(self) -> Result<Self, Error> {
41-
let buf = unsafe { (*self.0).error_message };
47+
let err_ptr = unsafe { (*self.0).error_message };
4248

43-
if buf.is_null() {
49+
if err_ptr.is_null() {
4450
return Ok(self);
4551
}
4652

47-
let len = unsafe { (*self.0).len };
48-
let bytes: &[u8] = unsafe { slice::from_raw_parts(buf as *const u8, len) };
49-
50-
Err(Error::QueryError(
51-
String::from_utf8_lossy(bytes).to_string(),
52-
))
53+
Err(Error::QueryError(unsafe {
54+
CStr::from_ptr(err_ptr).to_string_lossy().to_string()
55+
}))
5356
}
5457
}
5558

tests/examples.rs

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
use chdb_rust::arg::Arg;
2+
use chdb_rust::execute;
3+
use chdb_rust::format::InputFormat;
4+
use chdb_rust::format::OutputFormat;
5+
use chdb_rust::log_level::LogLevel;
6+
use chdb_rust::session::SessionBuilder;
7+
8+
#[test]
9+
fn stateful() {
10+
//
11+
// Create session.
12+
//
13+
14+
let session = SessionBuilder::new()
15+
.with_data_path("/tmp/chdb")
16+
.with_arg(Arg::LogLevel(LogLevel::Debug))
17+
.with_arg(Arg::Custom("priority".into(), Some("1".into())))
18+
.with_auto_cleanup(true)
19+
.build()
20+
.unwrap();
21+
22+
//
23+
// Create database.
24+
//
25+
26+
session
27+
.execute("CREATE DATABASE demo; USE demo", Some(&[Arg::MultiQuery]))
28+
.unwrap();
29+
30+
//
31+
// Create table.
32+
//
33+
34+
session
35+
.execute(
36+
"CREATE TABLE logs (id UInt64, msg String) ENGINE = MergeTree ORDER BY id",
37+
None,
38+
)
39+
.unwrap();
40+
41+
//
42+
// Insert into table.
43+
//
44+
45+
session
46+
.execute("INSERT INTO logs (id, msg) VALUES (1, 'test')", None)
47+
.unwrap();
48+
49+
//
50+
// Select from table.
51+
//
52+
53+
let result = session
54+
.execute(
55+
"SELECT * FROM logs",
56+
Some(&[Arg::OutputFormat(OutputFormat::JSONEachRow)]),
57+
)
58+
.unwrap()
59+
.unwrap();
60+
61+
assert_eq!(result.data_utf8_lossy(), "{\"id\":1,\"msg\":\"test\"}\n");
62+
}
63+
64+
#[test]
65+
fn stateless() {
66+
let query = format!(
67+
"SELECT * FROM file('tests/logs.csv', {})",
68+
InputFormat::CSV.as_str()
69+
);
70+
71+
let result = execute(
72+
&query,
73+
Some(&[Arg::OutputFormat(OutputFormat::JSONEachRow)]),
74+
)
75+
.unwrap()
76+
.unwrap();
77+
78+
assert_eq!(result.data_utf8_lossy(), "{\"id\":1,\"msg\":\"test\"}\n");
79+
}

tests/logs.csv

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
id,msg
2+
1,test

0 commit comments

Comments
 (0)