use reifydb_value::value::{diff_type::DiffType, frame::frame::Frame};
use crate::{ChangeKind, FrameChange};
pub(crate) fn frames_to_changes(frames: Vec<Frame>) -> Vec<FrameChange> {
frames.into_iter()
.map(|frame| FrameChange {
kind: read_op_kind(&frame),
frame,
})
.collect()
}
pub(crate) fn read_op_kind(frame: &Frame) -> ChangeKind {
match frame.op {
Some(DiffType::Update) => ChangeKind::Update,
Some(DiffType::Remove) => ChangeKind::Remove,
_ => ChangeKind::Insert,
}
}
#[cfg(test)]
mod tests {
use reifydb_value::value::{
Value,
container::number::NumberContainer,
frame::{column::FrameColumn, data::FrameColumnData, frame::Frame},
};
use super::*;
fn frame_with_op(op: DiffType, id: i32) -> Frame {
Frame::new(vec![FrameColumn {
name: "id".to_string(),
data: FrameColumnData::Int4(NumberContainer::from_vec(vec![id])),
}])
.with_op(op)
}
#[test]
fn derives_op_per_frame_and_keeps_every_user_column() {
let changes = frames_to_changes(vec![
frame_with_op(DiffType::Insert, 10),
frame_with_op(DiffType::Update, 11),
frame_with_op(DiffType::Remove, 12),
]);
assert_eq!(changes.len(), 3);
assert_eq!(changes[0].kind, ChangeKind::Insert);
assert_eq!(changes[1].kind, ChangeKind::Update);
assert_eq!(changes[2].kind, ChangeKind::Remove);
for (change, expected_id) in changes.iter().zip([10, 11, 12]) {
assert_eq!(
change.frame.columns.len(),
1,
"the op must ride the frame, so it must not add a column"
);
let id = change.frame.columns.iter().find(|c| c.name == "id").expect("id column preserved");
assert_eq!(id.data.get_value(0), Value::Int4(expected_id));
}
}
#[test]
fn frame_without_op_defaults_to_insert() {
let changes = frames_to_changes(vec![Frame::new(vec![FrameColumn {
name: "id".to_string(),
data: FrameColumnData::Int4(NumberContainer::from_vec(vec![1])),
}])]);
assert_eq!(changes[0].kind, ChangeKind::Insert);
}
}