use crate::{DataTransfer, StructureMigration, create_connection, DatabaseType, FieldMapping};
use std::ffi::CStr;
use std::os::raw::{c_char, c_int};
use std::sync::Arc;
#[repr(C)]
pub struct SqlToolHandle {
inner: *mut Arc<()>,
}
#[repr(C)]
pub struct DatabaseConnectionHandle {
inner: *mut Arc<()>,
}
#[repr(C)]
pub struct DataTransferHandle {
inner: *mut Arc<()>,
}
#[repr(C)]
pub struct StructureMigrationHandle {
inner: *mut Arc<()>,
}
#[unsafe(no_mangle)]
pub extern "C" fn sqltool_init() -> c_int {
let _ = env_logger::try_init();
0
}
#[unsafe(no_mangle)]
pub extern "C" fn sqltool_create_connection(
db_type: c_int, connection_string: *const c_char,
) -> *mut DatabaseConnectionHandle {
let db_type_enum = match db_type {
0 => DatabaseType::MySQL,
1 => DatabaseType::PostgreSQL,
2 => DatabaseType::SQLite,
3 => DatabaseType::Redis,
_ => return std::ptr::null_mut(),
};
let conn_str = unsafe {
CStr::from_ptr(connection_string)
.to_str()
.unwrap_or("")
};
let conn = match tokio::runtime::Runtime::new() {
Ok(runtime) => runtime.block_on(create_connection(db_type_enum, conn_str)),
Err(_) => return std::ptr::null_mut(),
};
match conn {
Ok(_) => {
let handle = Box::new(DatabaseConnectionHandle {
inner: Box::into_raw(Box::new(Arc::new(()))),
});
Box::into_raw(handle)
}
Err(_) => std::ptr::null_mut(),
}
}
#[unsafe(no_mangle)]
pub extern "C" fn sqltool_create_data_transfer(
source_conn: *mut DatabaseConnectionHandle,
target_conn: *mut DatabaseConnectionHandle,
) -> *mut DataTransferHandle {
if source_conn.is_null() || target_conn.is_null() {
return std::ptr::null_mut();
}
let _transfer = DataTransfer::new(
todo!(),
todo!(),
);
let handle = Box::new(DataTransferHandle {
inner: Box::into_raw(Box::new(Arc::new(()))),
});
Box::into_raw(handle)
}
#[unsafe(no_mangle)]
pub extern "C" fn sqltool_transfer_data(
transfer: *mut DataTransferHandle,
mappings: *const *const FieldMapping,
mapping_count: c_int,
) -> c_int {
if transfer.is_null() {
return -1;
}
let mut mappings_vec = vec![];
for i in 0..mapping_count {
let mapping_ptr = unsafe { *mappings.offset(i as isize) };
if !mapping_ptr.is_null() {
let mapping = unsafe { (*mapping_ptr).clone() };
mappings_vec.push(mapping);
}
}
todo!()
}
#[unsafe(no_mangle)]
pub extern "C" fn sqltool_create_structure_migration(
source_conn: *mut DatabaseConnectionHandle,
target_conn: *mut DatabaseConnectionHandle,
) -> *mut StructureMigrationHandle {
if source_conn.is_null() || target_conn.is_null() {
return std::ptr::null_mut();
}
let _migration = StructureMigration::new(
todo!(),
todo!(),
);
let handle = Box::new(StructureMigrationHandle {
inner: Box::into_raw(Box::new(Arc::new(()))),
});
Box::into_raw(handle)
}
#[unsafe(no_mangle)]
pub extern "C" fn sqltool_migrate_structure(
migration: *mut StructureMigrationHandle,
source_table: *const c_char,
target_table: *const c_char,
) -> c_int {
if migration.is_null() {
return -1;
}
let _source_table_str = unsafe {
CStr::from_ptr(source_table)
.to_str()
.unwrap_or("")
};
let _target_table_str = unsafe {
CStr::from_ptr(target_table)
.to_str()
.unwrap_or("")
};
todo!()
}
#[unsafe(no_mangle)]
pub extern "C" fn sqltool_free_connection(conn: *mut DatabaseConnectionHandle) {
if !conn.is_null() {
unsafe {
let conn_box = Box::from_raw(conn);
if !conn_box.inner.is_null() {
let _ = Box::from_raw(conn_box.inner);
}
}
}
}
#[unsafe(no_mangle)]
pub extern "C" fn sqltool_free_data_transfer(transfer: *mut DataTransferHandle) {
if !transfer.is_null() {
unsafe {
let transfer_box = Box::from_raw(transfer);
if !transfer_box.inner.is_null() {
let _ = Box::from_raw(transfer_box.inner);
}
}
}
}
#[unsafe(no_mangle)]
pub extern "C" fn sqltool_free_structure_migration(migration: *mut StructureMigrationHandle) {
if !migration.is_null() {
unsafe {
let migration_box = Box::from_raw(migration);
if !migration_box.inner.is_null() {
let _ = Box::from_raw(migration_box.inner);
}
}
}
}