use std::{
ops::{Deref, DerefMut},
ptr,
};
use crate::ffi::{duckdb_data_chunk, duckdb_destroy_data_chunk};
use super::result::DuckResult;
use crate::{error::Result, ffi};
pub struct DataChunk(
pub(crate) duckdb_data_chunk,
pub(crate) u64, );
impl DataChunk {
#[inline]
pub fn new(data_chunk: ffi::duckdb_data_chunk) -> Result<DataChunk> {
if data_chunk.is_null() {
return Err(crate::error::Error::DuckDBFailure(
ffi::Error::new(ffi::DuckDBError),
Some("data chunk is null".to_owned()),
));
}
Ok(DataChunk(data_chunk, 0))
}
#[inline]
pub fn from_result(result: &DuckResult) -> Option<Result<DataChunk>> {
let data_chunk = unsafe { ffi::duckdb_fetch_chunk(**result) };
if data_chunk.is_null() {
return None;
}
let res = DataChunk::new(data_chunk);
Some(res)
}
#[allow(unused)]
#[inline]
pub fn current_row(&self) -> u64 {
self.1
}
#[inline]
pub fn row_count(&self) -> u64 {
unsafe { ffi::duckdb_data_chunk_get_size(self.0) }
}
#[inline]
pub fn next_row(&mut self) -> Option<u64> {
if self.row_count() < 1 {
return None;
}
if self.1 >= self.row_count() {
self.1 = 0;
unsafe { duckdb_destroy_data_chunk(&mut (self.0)) };
self.0 = ptr::null_mut();
return None;
}
self.1 += 1;
Some(self.1 - 1)
}
}
impl Deref for DataChunk {
type Target = duckdb_data_chunk;
#[inline]
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for DataChunk {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl Drop for DataChunk {
fn drop(&mut self) {
if !self.0.is_null() {
unsafe { duckdb_destroy_data_chunk(&mut (self.0)) };
}
}
}