Write a RecordBatch to the underlying writer
(&mut self, batch: &RecordBatch)
| 239 | |
| 240 | /// Write a RecordBatch to the underlying writer |
| 241 | pub fn write(&mut self, batch: &RecordBatch) -> Result<(), ArrowError> { |
| 242 | let num_columns = batch.num_columns(); |
| 243 | if self.beginning { |
| 244 | if self.has_headers { |
| 245 | let mut headers: Vec<String> = Vec::with_capacity(num_columns); |
| 246 | batch |
| 247 | .schema() |
| 248 | .fields() |
| 249 | .iter() |
| 250 | .for_each(|field| headers.push(field.name().to_string())); |
| 251 | self.writer |
| 252 | .write_record(&headers[..]) |
| 253 | .map_err(map_csv_error)?; |
| 254 | } |
| 255 | self.beginning = false; |
| 256 | } |
| 257 | |
| 258 | let options = FormatOptions::default() |
| 259 | .with_null(self.null_value.as_deref().unwrap_or(DEFAULT_NULL_VALUE)) |
| 260 | .with_date_format(self.date_format.as_deref()) |
| 261 | .with_datetime_format(self.datetime_format.as_deref()) |
| 262 | .with_timestamp_format(self.timestamp_format.as_deref()) |
| 263 | .with_timestamp_tz_format(self.timestamp_tz_format.as_deref()) |
| 264 | .with_time_format(self.time_format.as_deref()); |
| 265 | |
| 266 | let converters = batch |
| 267 | .columns() |
| 268 | .iter() |
| 269 | .map(|a| { |
| 270 | if a.data_type().is_nested() { |
| 271 | Err(ArrowError::CsvError(format!( |
| 272 | "Nested type {} is not supported in CSV", |
| 273 | a.data_type() |
| 274 | ))) |
| 275 | } else { |
| 276 | ArrayFormatter::try_new(a.as_ref(), &options) |
| 277 | } |
| 278 | }) |
| 279 | .collect::<Result<Vec<_>, ArrowError>>()?; |
| 280 | |
| 281 | let mut buffer = String::with_capacity(1024); |
| 282 | let mut byte_record = ByteRecord::with_capacity(1024, converters.len()); |
| 283 | |
| 284 | for row_idx in 0..batch.num_rows() { |
| 285 | byte_record.clear(); |
| 286 | for (col_idx, converter) in converters.iter().enumerate() { |
| 287 | buffer.clear(); |
| 288 | converter.value(row_idx).write(&mut buffer).map_err(|e| { |
| 289 | ArrowError::CsvError(format!( |
| 290 | "Error processing row {}, col {}: {e}", |
| 291 | row_idx + 1, |
| 292 | col_idx + 1 |
| 293 | )) |
| 294 | })?; |
| 295 | |
| 296 | let field_bytes = |
| 297 | self.get_trimmed_field_bytes(&buffer, batch.column(col_idx).data_type()); |
| 298 | byte_record.push_field(field_bytes); |