#![cfg(all(feature = "wal2json", feature = "pg-walstream", feature = "maxwell"))]
extern crate alloc;
use alloc::string::String;
use alloc::vec::Vec;
use bytes::Bytes;
use sqlite_diff_rs::maxwell::{Maxwell, MaxwellColumn};
use sqlite_diff_rs::pg_walstream::{ColumnValue, PgWalstream, PgWalstreamColumn};
use sqlite_diff_rs::wal2json::{Wal2Json, Wal2JsonColumn};
use sqlite_diff_rs::{
DecodeError, MySqlBinaryDecoder, PgByteaBinaryDecoder, PgByteaTextModeDecoder, TypeMap, Value,
WireAdapter,
};
#[test]
fn pg_bytea_binary_decoder_pass_through_binary() {
let cv = ColumnValue::binary_bytes(Bytes::from_static(&[0xDE, 0xAD, 0xBE, 0xEF]));
let got: Value<String, Vec<u8>> = PgWalstreamColumn {
column_name: "b",
oid: 17,
type_modifier: -1,
data: &cv,
}
.decoded_by(&PgByteaBinaryDecoder)
.unwrap();
assert_eq!(got, Value::Blob(alloc::vec![0xDE, 0xAD, 0xBE, 0xEF]));
}
#[test]
fn pg_bytea_binary_decoder_hex_escape_text_mode() {
let cv = ColumnValue::text("\\xdeadbeef");
let got: Value<String, Vec<u8>> = PgWalstreamColumn {
column_name: "b",
oid: 17,
type_modifier: -1,
data: &cv,
}
.decoded_by(&PgByteaBinaryDecoder)
.unwrap();
assert_eq!(got, Value::Blob(alloc::vec![0xDE, 0xAD, 0xBE, 0xEF]));
}
#[test]
fn pg_bytea_binary_decoder_null() {
let cv = ColumnValue::Null;
let got: Value<String, Vec<u8>> = PgWalstreamColumn {
column_name: "b",
oid: 17,
type_modifier: -1,
data: &cv,
}
.decoded_by(&PgByteaBinaryDecoder)
.unwrap();
assert_eq!(got, Value::Null);
}
#[test]
fn pg_bytea_binary_decoder_rejects_malformed_hex() {
let cv = ColumnValue::text("\\xzz");
let result: Result<Value<String, Vec<u8>>, _> = PgWalstreamColumn {
column_name: "b",
oid: 17,
type_modifier: -1,
data: &cv,
}
.decoded_by(&PgByteaBinaryDecoder);
assert!(matches!(
result.unwrap_err(),
DecodeError::InvalidHexEscape { .. }
));
}
#[test]
fn pg_bytea_text_mode_decoder_wal2json_hex() {
let s = serde_json::Value::String("\\xcafef00d".into());
let got: Value<String, Vec<u8>> = Wal2JsonColumn {
column_name: "b",
pg_type_name: "bytea",
value: &s,
}
.decoded_by(&PgByteaTextModeDecoder)
.unwrap();
assert_eq!(got, Value::Blob(alloc::vec![0xCA, 0xFE, 0xF0, 0x0D]));
}
#[test]
fn pg_bytea_text_mode_decoder_wal2json_null() {
let s = serde_json::Value::Null;
let got: Value<String, Vec<u8>> = Wal2JsonColumn {
column_name: "b",
pg_type_name: "bytea",
value: &s,
}
.decoded_by(&PgByteaTextModeDecoder)
.unwrap();
assert_eq!(got, Value::Null);
}
#[test]
fn mysql_binary_decoder_maxwell_base64() {
let s = serde_json::Value::String("3q2+7w==".into());
let got: Value<String, Vec<u8>> = MaxwellColumn {
column_name: "b",
mysql_type: Some("blob"),
value: &s,
}
.decoded_by(&MySqlBinaryDecoder)
.unwrap();
assert_eq!(got, Value::Blob(alloc::vec![0xDE, 0xAD, 0xBE, 0xEF]));
}
#[test]
fn mysql_binary_decoder_maxwell_empty_string() {
let s = serde_json::Value::String(String::new());
let got: Value<String, Vec<u8>> = MaxwellColumn {
column_name: "b",
mysql_type: Some("blob"),
value: &s,
}
.decoded_by(&MySqlBinaryDecoder)
.unwrap();
assert_eq!(got, Value::Blob(Vec::new()));
}
#[test]
fn mysql_binary_decoder_maxwell_null() {
let s = serde_json::Value::Null;
let got: Value<String, Vec<u8>> = MaxwellColumn {
column_name: "b",
mysql_type: Some("blob"),
value: &s,
}
.decoded_by(&MySqlBinaryDecoder)
.unwrap();
assert_eq!(got, Value::Null);
}
#[test]
fn type_map_defaults_route_byte_types() {
let pg: TypeMap<PgWalstream, String, Vec<u8>> = TypeMap::defaults();
let w2j: TypeMap<Wal2Json, String, Vec<u8>> = TypeMap::defaults();
let mx: TypeMap<Maxwell, String, Vec<u8>> = TypeMap::defaults();
let cv_bin = ColumnValue::binary_bytes(Bytes::from_static(&[0x01, 0x02, 0x03]));
let got = pg
.decode(PgWalstreamColumn {
column_name: "b",
oid: 17,
type_modifier: -1,
data: &cv_bin,
})
.unwrap();
assert_eq!(got, Value::Blob(alloc::vec![0x01, 0x02, 0x03]));
let cv_txt = ColumnValue::text("\\x010203");
let got = pg
.decode(PgWalstreamColumn {
column_name: "b",
oid: 17,
type_modifier: -1,
data: &cv_txt,
})
.unwrap();
assert_eq!(got, Value::Blob(alloc::vec![0x01, 0x02, 0x03]));
let s = serde_json::Value::String("\\x010203".into());
let got = w2j
.decode(Wal2JsonColumn {
column_name: "b",
pg_type_name: "bytea",
value: &s,
})
.unwrap();
assert_eq!(got, Value::Blob(alloc::vec![0x01, 0x02, 0x03]));
let s = serde_json::Value::String("AQID".into()); let got = mx
.decode(MaxwellColumn {
column_name: "b",
mysql_type: Some("blob"),
value: &s,
})
.unwrap();
assert_eq!(got, Value::Blob(alloc::vec![0x01, 0x02, 0x03]));
}