reifydb_value/value/container/
temporal_array.rs1use std::{
5 slice,
6 sync::{Arc, LazyLock},
7};
8
9use arrow_array::{
10 Date32Array, IntervalMonthDayNanoArray, PrimitiveArray, Time64NanosecondArray, TimestampNanosecondArray,
11};
12use arrow_buffer::{IntervalMonthDayNano, ScalarBuffer};
13use arrow_schema::{DataType, TimeUnit};
14
15use crate::value::{Value, date::Date, datetime::DateTime, duration::Duration, is::IsTemporal, time::Time};
16
17pub const DATETIME_TIMEZONE: &str = "+00:00";
18
19static TIMEZONE: LazyLock<Arc<str>> = LazyLock::new(|| Arc::from(DATETIME_TIMEZONE));
20
21static DATETIME_DATA_TYPE: LazyLock<DataType> =
22 LazyLock::new(|| DataType::Timestamp(TimeUnit::Nanosecond, Some(datetime_timezone())));
23
24pub fn datetime_timezone() -> Arc<str> {
25 TIMEZONE.clone()
26}
27
28pub fn datetime_data_type() -> DataType {
29 DATETIME_DATA_TYPE.clone()
30}
31
32pub fn dates(array: &Date32Array) -> &[Date] {
33 let values: &[i32] = array.values();
34 unsafe { slice::from_raw_parts(values.as_ptr().cast::<Date>(), values.len()) }
36}
37
38pub fn datetimes(array: &TimestampNanosecondArray) -> &[DateTime] {
39 let values: &[i64] = array.values();
40 unsafe { slice::from_raw_parts(values.as_ptr().cast::<DateTime>(), values.len()) }
42}
43
44pub fn times(array: &Time64NanosecondArray) -> &[Time] {
45 let values: &[i64] = array.values();
46 unsafe { slice::from_raw_parts(values.as_ptr().cast::<Time>(), values.len()) }
48}
49
50pub fn durations(array: &IntervalMonthDayNanoArray) -> &[Duration] {
51 let values: &[IntervalMonthDayNano] = array.values();
52 unsafe { slice::from_raw_parts(values.as_ptr().cast::<Duration>(), values.len()) }
54}
55
56pub fn date_to_native(value: Date) -> i32 {
57 value.to_days_since_epoch()
58}
59
60pub fn datetime_to_native(value: DateTime) -> i64 {
61 value.to_nanos()
62}
63
64pub fn time_to_native(value: Time) -> i64 {
65 value.to_nanos_since_midnight() as i64
66}
67
68pub fn duration_to_native(value: Duration) -> IntervalMonthDayNano {
69 IntervalMonthDayNano::new(value.get_months(), value.get_days(), value.get_nanos())
70}
71
72pub fn date_array(values: impl IntoIterator<Item = Date>) -> Date32Array {
73 let natives: Vec<i32> = values.into_iter().map(date_to_native).collect();
74 PrimitiveArray::new(ScalarBuffer::from(natives), None)
75}
76
77pub fn datetime_array(values: impl IntoIterator<Item = DateTime>) -> TimestampNanosecondArray {
78 let natives: Vec<i64> = values.into_iter().map(datetime_to_native).collect();
79 PrimitiveArray::new(ScalarBuffer::from(natives), None).with_timezone(datetime_timezone())
80}
81
82pub fn time_array(values: impl IntoIterator<Item = Time>) -> Time64NanosecondArray {
83 let natives: Vec<i64> = values.into_iter().map(time_to_native).collect();
84 PrimitiveArray::new(ScalarBuffer::from(natives), None)
85}
86
87pub fn duration_array(values: impl IntoIterator<Item = Duration>) -> IntervalMonthDayNanoArray {
88 let natives: Vec<IntervalMonthDayNano> = values.into_iter().map(duration_to_native).collect();
89 PrimitiveArray::new(ScalarBuffer::from(natives), None)
90}
91
92pub fn get_value<T: IsTemporal + Copy>(values: &[T], index: usize) -> Value {
93 if index < values.len() {
94 values[index].to_value()
95 } else {
96 Value::none()
97 }
98}
99
100pub fn as_string<T: IsTemporal>(values: &[T], index: usize) -> String {
101 if index < values.len() {
102 values[index].to_string()
103 } else {
104 "none".to_string()
105 }
106}