use anyhow::{anyhow, bail, Result};
use chrono::{DateTime, TimeZone, Utc};
use crate::ops::DataType;
pub fn micros_to_datetime(micros: i64) -> Result<DateTime<Utc>> {
let secs = micros.div_euclid(1_000_000);
let nanos = (micros.rem_euclid(1_000_000) as u32) * 1000;
Utc.timestamp_opt(secs, nanos)
.single()
.ok_or_else(|| anyhow!("Invalid timestamp: {} micros", micros))
}
pub const DEFAULT_MAX_MESSAGE_SIZE: u32 = 64 * 1024 * 1024;
pub const SEVERITY_ERROR: u8 = b'E';
pub const SEVERITY_FATAL: u8 = b'F';
pub const TAG_BIG_INT: u8 = 1;
pub const TAG_BOOLEAN: u8 = 2;
pub const TAG_BYTES: u8 = 3;
pub const TAG_DOUBLE: u8 = 4;
pub const TAG_FLOAT: u8 = 5;
pub const TAG_INSTANT: u8 = 6;
pub const TAG_LONG: u8 = 7;
pub const TAG_REF: u8 = 8;
pub const TAG_STRING: u8 = 9;
pub const TAG_UUID: u8 = 10;
pub const TAG_VECTOR: u8 = 11;
pub const TAG_MAP: u8 = 12;
pub const TAG_KEYWORD: u8 = 13;
pub const TAG_UNION: u8 = 127;
pub const TAG_UNKNOWN: u8 = 255;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u16)]
pub enum ErrorCode {
ProtocolVersionMismatch = 1000,
InvalidStartup = 1001,
ParseError = 2000,
QueryError = 2001,
InvalidQuery = 2002,
EmptyQuery = 2003,
TxError = 3000,
TxAborted = 3001,
TxNotIndexed = 3002,
InternalError = 4000,
MessageTooLarge = 4001,
InvalidMessageType = 4002,
QueryCancelled = 4003,
ServerShuttingDown = 4004,
}
impl ErrorCode {
pub fn from_u16(code: u16) -> Result<Self> {
match code {
1000 => Ok(ErrorCode::ProtocolVersionMismatch),
1001 => Ok(ErrorCode::InvalidStartup),
2000 => Ok(ErrorCode::ParseError),
2001 => Ok(ErrorCode::QueryError),
2002 => Ok(ErrorCode::InvalidQuery),
2003 => Ok(ErrorCode::EmptyQuery),
3000 => Ok(ErrorCode::TxError),
3001 => Ok(ErrorCode::TxAborted),
3002 => Ok(ErrorCode::TxNotIndexed),
4000 => Ok(ErrorCode::InternalError),
4001 => Ok(ErrorCode::MessageTooLarge),
4002 => Ok(ErrorCode::InvalidMessageType),
4003 => Ok(ErrorCode::QueryCancelled),
4004 => Ok(ErrorCode::ServerShuttingDown),
_ => bail!("Unknown error code: {}", code),
}
}
pub fn as_u16(self) -> u16 {
self as u16
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct ColumnDescription {
pub name: String,
pub data_type: u8,
pub members: Option<Vec<u8>>,
}
pub fn data_type_tag(dt: &DataType) -> u8 {
match dt {
DataType::BigInt(_) => TAG_BIG_INT,
DataType::Boolean(_) => TAG_BOOLEAN,
DataType::Bytes(_) => TAG_BYTES,
DataType::Double(_) => TAG_DOUBLE,
DataType::Float(_) => TAG_FLOAT,
DataType::Instant(_) => TAG_INSTANT,
DataType::Keyword(_) => TAG_KEYWORD,
DataType::Long(_) => TAG_LONG,
DataType::String(_) => TAG_STRING,
DataType::Uuid(_) => TAG_UUID,
DataType::Vector(_) => TAG_VECTOR,
DataType::Map(_) => TAG_MAP,
}
}