Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: move arrow convert function into file #241

Merged
merged 1 commit into from
May 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions rust/quary-databases/src/database_arrow_helper.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
use chrono::{DateTime, Utc};
use duckdb::arrow::array::{array, Array};
use std::sync::Arc;

pub(crate) fn convert_array_to_vec_string(
array: &[Arc<dyn Array>],
) -> Result<Vec<Vec<String>>, String> {
let num_rows = array[0].len();
let num_columns = array.len();
let mut rows = Vec::with_capacity(num_rows);
for _ in 0..num_rows {
let row = vec!["".to_string(); num_columns];
rows.push(row);
}

for (i, row) in rows.iter_mut().enumerate() {
for (j, value) in row.iter_mut().enumerate() {
let array = &array[j];
if let Some(string_array) = array.as_any().downcast_ref::<array::StringArray>() {
*value = string_array.value(i).to_string();
} else if let Some(int32_array) = array.as_any().downcast_ref::<array::Int32Array>() {
*value = int32_array.value(i).to_string();
} else if let Some(int64_array) = array.as_any().downcast_ref::<array::Int64Array>() {
*value = int64_array.value(i).to_string();
} else if let Some(float32_array) = array.as_any().downcast_ref::<array::Float32Array>()
{
*value = float32_array.value(i).to_string();
} else if let Some(float64_array) = array.as_any().downcast_ref::<array::Float64Array>()
{
*value = float64_array.value(i).to_string();
} else if let Some(boolean_array) = array.as_any().downcast_ref::<array::BooleanArray>()
{
*value = boolean_array.value(i).to_string();
} else if let Some(date_array) = array.as_any().downcast_ref::<array::Date64Array>() {
*value = date_array.value(i).to_string();
} else if let Some(date_array) = array.as_any().downcast_ref::<array::Date32Array>() {
*value = date_array.value(i).to_string();
} else if let Some(timestamp_array) = array
.as_any()
.downcast_ref::<array::TimestampMicrosecondArray>()
{
if timestamp_array.is_null(i) {
*value = "NULL".to_string();
} else {
let timestamp_micros = timestamp_array.value(i);
let datetime_utc = DateTime::<Utc>::from_timestamp(
timestamp_micros / 1_000_000,
(timestamp_micros % 1_000_000) as u32 * 1_000,
)
.ok_or("error converting timestamp to datetime")?;
*value = datetime_utc.format("%Y-%m-%d %H:%M:%S%.6f %Z").to_string();
}
} else {
let array_type = array.data_type();
return Err(format!("Unsupported array type: {:?}", array_type));
}
}
}

// Example for a specific array type, e.g., StringArray
Ok(rows)
}
63 changes: 2 additions & 61 deletions rust/quary-databases/src/databases_duckdb.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use chrono::{DateTime, Utc};
use duckdb::arrow::array::{array, Array};
use crate::database_arrow_helper::convert_array_to_vec_string;
use duckdb::arrow::array::Array;

Check warning on line 2 in rust/quary-databases/src/databases_duckdb.rs

View workflow job for this annotation

GitHub Actions / Rust Test

unused import: `duckdb::arrow::array::Array`
use duckdb::arrow::record_batch::RecordBatch;
use duckdb::{params, Connection};
use quary_core::database_duckdb::DatabaseQueryGeneratorDuckDB;
Expand Down Expand Up @@ -219,65 +219,6 @@
}
}

pub(crate) fn convert_array_to_vec_string(
array: &[Arc<dyn Array>],
) -> Result<Vec<Vec<String>>, String> {
let num_rows = array[0].len();
let num_columns = array.len();
let mut rows = Vec::with_capacity(num_rows);
for _ in 0..num_rows {
let row = vec!["".to_string(); num_columns];
rows.push(row);
}

for (i, row) in rows.iter_mut().enumerate() {
for (j, value) in row.iter_mut().enumerate() {
let array = &array[j];
if let Some(string_array) = array.as_any().downcast_ref::<array::StringArray>() {
*value = string_array.value(i).to_string();
} else if let Some(int32_array) = array.as_any().downcast_ref::<array::Int32Array>() {
*value = int32_array.value(i).to_string();
} else if let Some(int64_array) = array.as_any().downcast_ref::<array::Int64Array>() {
*value = int64_array.value(i).to_string();
} else if let Some(float32_array) = array.as_any().downcast_ref::<array::Float32Array>()
{
*value = float32_array.value(i).to_string();
} else if let Some(float64_array) = array.as_any().downcast_ref::<array::Float64Array>()
{
*value = float64_array.value(i).to_string();
} else if let Some(boolean_array) = array.as_any().downcast_ref::<array::BooleanArray>()
{
*value = boolean_array.value(i).to_string();
} else if let Some(date_array) = array.as_any().downcast_ref::<array::Date64Array>() {
*value = date_array.value(i).to_string();
} else if let Some(date_array) = array.as_any().downcast_ref::<array::Date32Array>() {
*value = date_array.value(i).to_string();
} else if let Some(timestamp_array) = array
.as_any()
.downcast_ref::<array::TimestampMicrosecondArray>()
{
if timestamp_array.is_null(i) {
*value = "NULL".to_string();
} else {
let timestamp_micros = timestamp_array.value(i);
let datetime_utc = DateTime::<Utc>::from_timestamp(
timestamp_micros / 1_000_000,
(timestamp_micros % 1_000_000) as u32 * 1_000,
)
.ok_or("error converting timestamp to datetime")?;
*value = datetime_utc.format("%Y-%m-%d %H:%M:%S%.6f %Z").to_string();
}
} else {
let array_type = array.data_type();
return Err(format!("Unsupported array type: {:?}", array_type));
}
}
}

// Example for a specific array type, e.g., StringArray
Ok(rows)
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down Expand Up @@ -900,7 +841,7 @@
NaiveDateTime::parse_from_str(datetime_str, "%Y-%m-%d %H:%M:%S").unwrap();

// Convert NaiveDateTime to DateTime<Utc>
let datetime_utc = DateTime::<Utc>::from_utc(naive_datetime, Utc);

Check warning on line 844 in rust/quary-databases/src/databases_duckdb.rs

View workflow job for this annotation

GitHub Actions / Rust Test

use of deprecated associated function `chrono::DateTime::<Tz>::from_utc`: Use TimeZone::from_utc_datetime() or DateTime::from_naive_utc_and_offset instead

// Convert DateTime<Utc> to SystemTime
let system_time = SystemTime::from(datetime_utc);
Expand Down Expand Up @@ -1023,7 +964,7 @@
NaiveDateTime::parse_from_str(datetime_str_updated, "%Y-%m-%d %H:%M:%S").unwrap();

// Convert NaiveDateTime to DateTime<Utc>
let datetime_utc_updated = DateTime::<Utc>::from_utc(naive_datetime_updated, Utc);

Check warning on line 967 in rust/quary-databases/src/databases_duckdb.rs

View workflow job for this annotation

GitHub Actions / Rust Test

use of deprecated associated function `chrono::DateTime::<Tz>::from_utc`: Use TimeZone::from_utc_datetime() or DateTime::from_naive_utc_and_offset instead

// Convert DateTime<Utc> to SystemTime
let system_time_updated = SystemTime::from(datetime_utc_updated);
Expand Down Expand Up @@ -1132,7 +1073,7 @@
NaiveDateTime::parse_from_str(datetime_str, "%Y-%m-%d %H:%M:%S").unwrap();

// Convert NaiveDateTime to DateTime<Utc>
let datetime_utc = DateTime::<Utc>::from_utc(naive_datetime, Utc);

Check warning on line 1076 in rust/quary-databases/src/databases_duckdb.rs

View workflow job for this annotation

GitHub Actions / Rust Test

use of deprecated associated function `chrono::DateTime::<Tz>::from_utc`: Use TimeZone::from_utc_datetime() or DateTime::from_naive_utc_and_offset instead

// Convert DateTime<Utc> to SystemTime
let system_time = SystemTime::from(datetime_utc);
Expand Down Expand Up @@ -1256,7 +1197,7 @@
NaiveDateTime::parse_from_str(datetime_str_updated, "%Y-%m-%d %H:%M:%S").unwrap();

// Convert NaiveDateTime to DateTime<Utc>
let datetime_utc_updated = DateTime::<Utc>::from_utc(naive_datetime_updated, Utc);

Check warning on line 1200 in rust/quary-databases/src/databases_duckdb.rs

View workflow job for this annotation

GitHub Actions / Rust Test

use of deprecated associated function `chrono::DateTime::<Tz>::from_utc`: Use TimeZone::from_utc_datetime() or DateTime::from_naive_utc_and_offset instead

// Convert DateTime<Utc> to SystemTime
let system_time_updated = SystemTime::from(datetime_utc_updated);
Expand Down
2 changes: 1 addition & 1 deletion rust/quary-databases/src/databases_snowflake.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::databases_duckdb::convert_array_to_vec_string;
use crate::database_arrow_helper::convert_array_to_vec_string;
use async_trait::async_trait;
use quary_core::database_snowflake::{
validate_snowfalke_account_identifier, DatabaseQueryGeneratorSnowflake,
Expand Down
1 change: 1 addition & 0 deletions rust/quary-databases/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
mod database_arrow_helper;
mod databases_bigquery;
pub mod databases_connection;
pub mod databases_duckdb;
Expand Down
Loading