parquet 0.0.5 → 0.2.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Cargo.lock +50 -0
- data/README.md +92 -2
- data/ext/parquet/Cargo.toml +1 -0
- data/ext/parquet/src/lib.rs +5 -3
- data/ext/parquet/src/{reader.rs → reader/mod.rs} +5 -2
- data/ext/parquet/src/types/core_types.rs +73 -0
- data/ext/parquet/src/types/mod.rs +30 -0
- data/ext/parquet/src/types/parquet_value.rs +458 -0
- data/ext/parquet/src/types/record_types.rs +204 -0
- data/ext/parquet/src/types/timestamp.rs +85 -0
- data/ext/parquet/src/types/type_conversion.rs +753 -0
- data/ext/parquet/src/types/writer_types.rs +270 -0
- data/ext/parquet/src/writer/mod.rs +403 -0
- data/lib/parquet/version.rb +1 -1
- data/lib/parquet.rbi +33 -2
- metadata +13 -6
- data/ext/parquet/src/types.rs +0 -763
- /data/ext/parquet/src/{parquet_column_reader.rs → reader/parquet_column_reader.rs} +0 -0
- /data/ext/parquet/src/{parquet_row_reader.rs → reader/parquet_row_reader.rs} +0 -0
@@ -0,0 +1,85 @@
|
|
1
|
+
use super::*;
|
2
|
+
|
3
|
+
pub fn parse_zoned_timestamp(value: &ParquetValue) -> jiff::Timestamp {
|
4
|
+
let (ts, tz) = match value {
|
5
|
+
ParquetValue::TimestampSecond(ts, tz) => (jiff::Timestamp::from_second(*ts).unwrap(), tz),
|
6
|
+
ParquetValue::TimestampMillis(ts, tz) => {
|
7
|
+
(jiff::Timestamp::from_millisecond(*ts).unwrap(), tz)
|
8
|
+
}
|
9
|
+
ParquetValue::TimestampMicros(ts, tz) => {
|
10
|
+
(jiff::Timestamp::from_microsecond(*ts).unwrap(), tz)
|
11
|
+
}
|
12
|
+
ParquetValue::TimestampNanos(ts, tz) => {
|
13
|
+
(jiff::Timestamp::from_nanosecond(*ts as i128).unwrap(), tz)
|
14
|
+
}
|
15
|
+
_ => panic!("Invalid timestamp value"),
|
16
|
+
};
|
17
|
+
|
18
|
+
// If timezone is provided, convert to zoned timestamp
|
19
|
+
if let Some(tz) = tz {
|
20
|
+
// Handle fixed offset timezones like "+09:00" first
|
21
|
+
if tz.starts_with('+') || tz.starts_with('-') {
|
22
|
+
// Parse the offset string into hours and minutes
|
23
|
+
let (hours, minutes) = if tz.len() >= 5 && tz.contains(':') {
|
24
|
+
// Format: "+09:00" or "-09:00"
|
25
|
+
let h = tz[1..3].parse::<i32>().unwrap_or(0);
|
26
|
+
let m = tz[4..6].parse::<i32>().unwrap_or(0);
|
27
|
+
(h, m)
|
28
|
+
} else if tz.len() >= 3 {
|
29
|
+
// Format: "+09" or "-09"
|
30
|
+
let h = tz[1..3].parse::<i32>().unwrap_or(0);
|
31
|
+
(h, 0)
|
32
|
+
} else {
|
33
|
+
(0, 0)
|
34
|
+
};
|
35
|
+
|
36
|
+
// Apply sign
|
37
|
+
let total_minutes = if tz.starts_with('-') {
|
38
|
+
-(hours * 60 + minutes)
|
39
|
+
} else {
|
40
|
+
hours * 60 + minutes
|
41
|
+
};
|
42
|
+
|
43
|
+
// Create fixed timezone
|
44
|
+
let tz = jiff::tz::TimeZone::fixed(jiff::tz::offset((total_minutes / 60) as i8));
|
45
|
+
ts.to_zoned(tz).timestamp()
|
46
|
+
} else {
|
47
|
+
// Try IANA timezone
|
48
|
+
match ts.intz(&tz) {
|
49
|
+
Ok(zoned) => zoned.timestamp(),
|
50
|
+
Err(_) => ts, // Fall back to UTC if timezone is invalid
|
51
|
+
}
|
52
|
+
}
|
53
|
+
} else {
|
54
|
+
// No timezone provided - treat as UTC
|
55
|
+
ts
|
56
|
+
}
|
57
|
+
}
|
58
|
+
|
59
|
+
// Macro for handling timestamp conversions
|
60
|
+
#[macro_export]
|
61
|
+
macro_rules! impl_timestamp_conversion {
|
62
|
+
($value:expr, $unit:ident, $handle:expr) => {{
|
63
|
+
match $value {
|
64
|
+
ParquetValue::$unit(ts, tz) => {
|
65
|
+
let ts = parse_zoned_timestamp(&ParquetValue::$unit(ts, tz));
|
66
|
+
let time_class = $handle.class_time();
|
67
|
+
time_class
|
68
|
+
.funcall::<_, _, Value>("parse", (ts.to_string(),))
|
69
|
+
.unwrap()
|
70
|
+
.into_value_with($handle)
|
71
|
+
}
|
72
|
+
_ => panic!("Invalid timestamp type"),
|
73
|
+
}
|
74
|
+
}};
|
75
|
+
}
|
76
|
+
|
77
|
+
// Macro for handling date conversions
|
78
|
+
#[macro_export]
|
79
|
+
macro_rules! impl_date_conversion {
|
80
|
+
($value:expr, $handle:expr) => {{
|
81
|
+
let ts = jiff::Timestamp::from_second(($value as i64) * 86400).unwrap();
|
82
|
+
let formatted = ts.strftime("%Y-%m-%d").to_string();
|
83
|
+
formatted.into_value_with($handle)
|
84
|
+
}};
|
85
|
+
}
|