Skip to content

Commit

Permalink
refactor(sys): impl taos_connect, taos_errno and taos_errstr funcs
Browse files Browse the repository at this point in the history
  • Loading branch information
qevolg committed Dec 26, 2024
1 parent 030fc6a commit 9d1b912
Show file tree
Hide file tree
Showing 3 changed files with 203 additions and 14 deletions.
82 changes: 82 additions & 0 deletions taos-ws-sys/src/native/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
use std::cell::RefCell;
use std::ffi::{c_char, c_int, CStr};

use taos_error::Error;

use super::TAOS_RES;

#[no_mangle]
pub extern "C" fn taos_errno(res: *mut TAOS_RES) -> c_int {
if res.is_null() {
return errno();
}
todo!()
}

#[no_mangle]
pub extern "C" fn taos_errstr(res: *mut TAOS_RES) -> *const c_char {
if res.is_null() {
if errno() == 0 {
return EMPTY.as_ptr();
}
return errstr();
}
todo!()
}

const EMPTY: &CStr = c"";
const MAX_ERRSTR_LEN: usize = 4096;

thread_local! {
static ERRNO: RefCell<i32> = const { RefCell::new(0) };
static ERRSTR: RefCell<[u8; MAX_ERRSTR_LEN]> = const { RefCell::new([0; MAX_ERRSTR_LEN]) };
}

pub fn set_err_and_get_code(err: Error) -> i32 {
ERRNO.with(|errno| {
let code: u32 = err.code().into();
*errno.borrow_mut() = (code | 0x80000000) as i32;
});

ERRSTR.with(|errstr| {
let bytes = err.message().into_bytes();
let len = bytes.len().min(MAX_ERRSTR_LEN - 1);
let mut errstr = errstr.borrow_mut();
errstr[..len].copy_from_slice(&bytes[..len]);
errstr[len] = 0;
});

errno()
}

pub fn errno() -> i32 {
ERRNO.with(|errno| *errno.borrow())
}

pub fn errstr() -> *const c_char {
ERRSTR.with(|errstr| errstr.borrow().as_ptr() as _)
}

#[cfg(test)]
mod tests {
use std::ffi::CStr;
use std::ptr::null_mut;

use taos_error::Error;

use super::*;

#[test]
fn test_set_err_and_get_code() {
let err = Error::new(1, "test error");
let code = set_err_and_get_code(err);
assert_eq!(code as u32, 0x80000001);

let code = taos_errno(null_mut());
assert_eq!(code as u32, 0x80000001);

let errstr_ptr = taos_errstr(null_mut());
let errstr = unsafe { CStr::from_ptr(errstr_ptr) };
assert_eq!(errstr, c"Internal error: `test error`"); // todo
}
}
125 changes: 111 additions & 14 deletions taos-ws-sys/src/native/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
#![allow(unused_variables)]

use std::ffi::{c_char, c_int, c_void};
use std::ffi::{c_char, c_int, c_void, CStr};
use std::ptr::null_mut;

use error::set_err_and_get_code;
use taos_error::{Code, Error};
use taos_query::TBuilder;
use taos_ws::{Taos, TaosBuilder};

mod error;
pub mod query;
pub mod sml;
pub mod stmt;
Expand All @@ -13,6 +20,8 @@ pub type TAOS = c_void;
#[allow(non_camel_case_types)]
pub type TAOS_RES = c_void;

type Result<T> = std::result::Result<T, Error>;

#[repr(C)]
#[allow(non_camel_case_types)]
pub enum TSDB_OPTION {
Expand Down Expand Up @@ -61,17 +70,77 @@ pub extern "C" fn taos_connect(
db: *const c_char,
port: u16,
) -> *mut TAOS {
todo!()
match connect(ip, user, pass, db, port) {
Ok(taos) => Box::into_raw(Box::new(taos)) as _,
Err(err) => {
set_err_and_get_code(err);
null_mut()
}
}
}

#[no_mangle]
pub extern "C" fn taos_connect_dsn(
dsn: *const c_char,
fn connect(
ip: *const c_char,
user: *const c_char,
pass: *const c_char,
db: *const c_char,
) -> *mut TAOS {
todo!()
mut port: u16,
) -> Result<Taos> {
const DEFAULT_IP: &str = "localhost";
const DEFAULT_PORT: u16 = 6041;
const DEFAULT_USER: &str = "root";
const DEFAULT_PASS: &str = "taosdata";
const DEFAULT_DB: &str = "";

let ip = if ip.is_null() {
DEFAULT_IP
} else {
let ip = unsafe { CStr::from_ptr(ip) };
match ip.to_str() {
Ok(ip) => ip,
Err(_) => return Err(Error::new(Code::INVALID_PARA, "Invalid ip")),
}
};

let user = if user.is_null() {
DEFAULT_USER
} else {
let user = unsafe { CStr::from_ptr(user) };
match user.to_str() {
Ok(user) => user,
Err(_) => return Err(Error::new(Code::INVALID_PARA, "Invalid user")),
}
};

let pass = if pass.is_null() {
DEFAULT_PASS
} else {
let pass = unsafe { CStr::from_ptr(pass) };
match pass.to_str() {
Ok(pass) => pass,
Err(_) => return Err(Error::new(Code::INVALID_PARA, "Invalid pass")),
}
};

let db = if db.is_null() {
DEFAULT_DB
} else {
let db = unsafe { CStr::from_ptr(db) };
match db.to_str() {
Ok(db) => db,
Err(_) => return Err(Error::new(Code::INVALID_PARA, "Invalid db")),
}
};

if port == 0 {
port = DEFAULT_PORT;
}

let dsn = format!("ws://{user}:{pass}@{ip}:{port}/{db}");
let builder = TaosBuilder::from_dsn(dsn)?;
let mut taos = builder.build()?;
builder.ping(&mut taos)?;
Ok(taos)
}

#[no_mangle]
Expand All @@ -84,12 +153,40 @@ pub extern "C" fn taos_data_type(r#type: c_int) -> *const c_char {
todo!()
}

#[no_mangle]
pub extern "C" fn taos_errstr(res: *mut TAOS_RES) -> *const c_char {
todo!()
}
#[cfg(test)]
mod tests {
use std::ffi::CString;
use std::ptr::null;

#[no_mangle]
pub extern "C" fn taos_errno(res: *mut TAOS_RES) -> c_int {
todo!()
use super::*;

#[test]
fn test_taos_connect() {
let taos = taos_connect(
c"localhost".as_ptr(),
c"root".as_ptr(),
c"taosdata".as_ptr(),
null(),
6041,
);
assert!(!taos.is_null());

let taos = taos_connect(null(), null(), null(), null(), 0);
assert!(!taos.is_null());

let invalid_utf8 = CString::new([0xff, 0xfe, 0xfd]).unwrap();
let invalid_utf8_ptr = invalid_utf8.as_ptr();

let taos = taos_connect(invalid_utf8_ptr, null(), null(), null(), 0);
assert!(taos.is_null());

let taos = taos_connect(null(), invalid_utf8_ptr, null(), null(), 0);
assert!(taos.is_null());

let taos = taos_connect(null(), null(), invalid_utf8_ptr, null(), 0);
assert!(taos.is_null());

let taos = taos_connect(null(), null(), null(), invalid_utf8_ptr, 0);
assert!(taos.is_null());
}
}
10 changes: 10 additions & 0 deletions taos-ws-sys/src/native/stub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,16 @@ pub extern "C" fn taos_connect_auth(
todo!("taos_connect_auth");
}

#[no_mangle]
pub extern "C" fn taos_connect_dsn(
dsn: *const c_char,
user: *const c_char,
pass: *const c_char,
db: *const c_char,
) -> *mut TAOS {
todo!("taos_connect_dsn");
}

#[no_mangle]
pub extern "C" fn taos_connect_dsn_auth(
dsn: *const c_char,
Expand Down

0 comments on commit 9d1b912

Please sign in to comment.