Skip to main content

nodedb_types/sync/wire/
columnar.rs

1// SPDX-License-Identifier: Apache-2.0
2
3//! Columnar insert sync messages (client → server / server → client).
4//!
5//! `ColumnarInsertMsg` carries a batch of typed row values from a Lite
6//! client to Origin. Each row is a MessagePack-serialized `Vec<Value>` in
7//! schema column order, matching the collection's `ColumnarSchema`.
8//!
9//! Wire layout mirrors `TimeseriesPushMsg`: typed payload + schema hint +
10//! a monotonic `batch_id` for dedup / ACK correlation.
11
12use serde::{Deserialize, Serialize};
13
14use crate::sync::wire::ack_status::AckStatus;
15
16/// Columnar batch insert (client → server, 0xA0).
17///
18/// Carries one or more rows for a columnar collection. Each entry in
19/// `rows` is a MessagePack-serialized `Vec<nodedb_types::value::Value>`
20/// with entries in schema column order.
21///
22/// `schema_bytes` is a MessagePack-serialized `ColumnarSchema`. Origin uses
23/// it to create the collection if it does not yet exist (definition-sync
24/// guarantees it will already exist in most cases, but the schema hint
25/// lets Origin validate column count and types rather than guessing).
26#[derive(
27    Debug, Clone, Serialize, Deserialize, zerompk::ToMessagePack, zerompk::FromMessagePack,
28)]
29pub struct ColumnarInsertMsg {
30    /// Lite instance ID (for routing and dedup).
31    pub lite_id: String,
32    /// Target collection name.
33    pub collection: String,
34    /// Batch of rows. Each element is MessagePack `Vec<Value>` (schema column order).
35    pub rows: Vec<Vec<u8>>,
36    /// Monotonic batch ID (Lite-assigned, per-collection). Used for ACK correlation.
37    pub batch_id: u64,
38    /// MessagePack-serialized `ColumnarSchema`. May be empty for collections
39    /// that were already synced via definition-sync.
40    #[serde(default)]
41    pub schema_bytes: Vec<u8>,
42    /// Stable identity of the originating producer. 0 for legacy clients.
43    #[serde(default)]
44    pub producer_id: u64,
45    /// Monotonic epoch counter incremented on every producer restart.
46    #[serde(default)]
47    pub epoch: u64,
48    /// Per-stream monotonic sequence number within the epoch.
49    #[serde(default)]
50    pub seq: u64,
51}
52
53/// Columnar insert acknowledgment (server → client, 0xA1).
54#[derive(
55    Debug, Clone, Serialize, Deserialize, zerompk::ToMessagePack, zerompk::FromMessagePack,
56)]
57pub struct ColumnarInsertAckMsg {
58    /// Collection acknowledged.
59    pub collection: String,
60    /// Batch ID from the originating `ColumnarInsertMsg`.
61    pub batch_id: u64,
62    /// Number of rows successfully inserted.
63    pub accepted: u64,
64    /// Number of rows rejected (schema mismatch, constraint violation, etc.).
65    pub rejected: u64,
66    /// Optional rejection detail for the first rejected row.
67    #[serde(default)]
68    pub reject_reason: Option<String>,
69    /// Highest sequence number from this producer that has been durably applied.
70    #[serde(default)]
71    pub applied_seq: u64,
72    /// Idempotency outcome of the acknowledged message.
73    #[serde(default)]
74    pub status: AckStatus,
75}