Skip to main content

selene_core/
changeset_variants.rs

1use smallvec::SmallVec;
2
3use crate::{
4    Change, DbString, EdgeId, EdgeTypeDef, EdgeTypeDefV1, GraphId, GraphType, GraphTypeId,
5    IvfIndexConfig, LabelDiff, LabelSet, NodeId, NodeTypeDef, NodeTypeDefV1, NodeTypeRef,
6    PropertyDiff, PropertyMap, RecordTypeDef, RecordTypeId, SchemaChange, SchemaPropertyIndexKind,
7    SchemaVectorIndexKind,
8};
9
10impl Change {
11    /// Factory table with one sample change for each [`Change`] variant.
12    ///
13    /// Tests use this as an append-only ANCHOR so new WAL variants require a
14    /// source-of-truth census update in `selene-core`.
15    pub const ALL: &[fn() -> Self] = &[
16        || Self::NodeCreated {
17            id: NodeId::new(1),
18            labels: LabelSet::new(),
19            properties: PropertyMap::new(),
20        },
21        || Self::NodeUpdated {
22            id: NodeId::new(1),
23            labels_diff: LabelDiff::new([], []).unwrap(),
24            properties_diff: PropertyDiff::new([], []).unwrap(),
25        },
26        || Self::NodeDeleted { id: NodeId::new(1) },
27        || Self::EdgeCreated {
28            id: EdgeId::new(1),
29            label: changeset_variant_string("change.all.edge"),
30            source: NodeId::new(1),
31            target: NodeId::new(2),
32            properties: PropertyMap::new(),
33        },
34        || Self::EdgeUpdated {
35            id: EdgeId::new(1),
36            properties_diff: PropertyDiff::new([], []).unwrap(),
37        },
38        || Self::EdgeDeleted { id: EdgeId::new(1) },
39        || Self::SchemaChanged {
40            graph: GraphId::new(1),
41            change: SchemaChange::GraphDropped {
42                id: GraphId::new(2),
43            },
44        },
45        || Self::NodePropertyRemoved {
46            id: NodeId::new(1),
47            property: changeset_variant_string("change.all.node_property_removed"),
48        },
49        || Self::EdgePropertyRemoved {
50            id: EdgeId::new(1),
51            property: changeset_variant_string("change.all.edge_property_removed"),
52        },
53        || Self::NodeLabelRemoved {
54            id: NodeId::new(1),
55            label: changeset_variant_string("change.all.node_label_removed"),
56        },
57        || Self::NodesOfTypeTruncated {
58            label: changeset_variant_string("change.all.nodes_of_type_truncated"),
59        },
60        || Self::EdgesOfTypeTruncated {
61            label: changeset_variant_string("change.all.edges_of_type_truncated"),
62        },
63        || Self::GraphReset {},
64    ];
65
66    /// Number of known [`Change`] variants in this build.
67    pub const VARIANT_COUNT: usize = Self::ALL.len();
68
69    /// Stable telemetry name for this change variant.
70    #[must_use]
71    pub fn variant_name(&self) -> &'static str {
72        match self {
73            Self::NodeCreated { .. } => "NodeCreated",
74            Self::NodeUpdated { .. } => "NodeUpdated",
75            Self::NodeDeleted { .. } => "NodeDeleted",
76            Self::EdgeCreated { .. } => "EdgeCreated",
77            Self::EdgeUpdated { .. } => "EdgeUpdated",
78            Self::EdgeDeleted { .. } => "EdgeDeleted",
79            Self::SchemaChanged { .. } => "SchemaChanged",
80            Self::NodePropertyRemoved { .. } => "NodePropertyRemoved",
81            Self::EdgePropertyRemoved { .. } => "EdgePropertyRemoved",
82            Self::NodeLabelRemoved { .. } => "NodeLabelRemoved",
83            Self::NodesOfTypeTruncated { .. } => "NodesOfTypeTruncated",
84            Self::EdgesOfTypeTruncated { .. } => "EdgesOfTypeTruncated",
85            Self::GraphReset {} => "GraphReset",
86        }
87    }
88}
89
90impl SchemaChange {
91    /// Factory table with one sample change for each [`SchemaChange`] variant.
92    ///
93    /// Hidden legacy variants are included because their postcard
94    /// discriminants are reserved for WAL compatibility.
95    pub const ALL: &[fn() -> Self] = &[
96        || Self::GraphCreated {
97            id: GraphId::new(1),
98            name: changeset_variant_string("schema.all.graph"),
99            graph_type: Some(changeset_graph_type_id()),
100        },
101        || Self::GraphDropped {
102            id: GraphId::new(1),
103        },
104        || Self::GraphTypeCreated {
105            graph_type: changeset_graph_type(),
106        },
107        || Self::GraphTypeDropped {
108            id: changeset_graph_type_id(),
109        },
110        || Self::NodeTypeAdded {
111            graph_type: changeset_graph_type_id(),
112            label: changeset_variant_string("schema.all.node"),
113            def: NodeTypeDefV1::new(LabelSet::single(changeset_variant_string(
114                "schema.all.node",
115            ))),
116        },
117        || Self::EdgeTypeAdded {
118            graph_type: changeset_graph_type_id(),
119            label: changeset_variant_string("schema.all.edge"),
120            def: EdgeTypeDefV1::new(
121                changeset_variant_string("schema.all.edge"),
122                NodeTypeRef(changeset_variant_string("schema.all.node")),
123                NodeTypeRef(changeset_variant_string("schema.all.node")),
124            ),
125        },
126        || Self::NodeTypeDropped {
127            graph_type: changeset_graph_type_id(),
128            name: changeset_variant_string("schema.all.node"),
129        },
130        || Self::EdgeTypeDropped {
131            graph_type: changeset_graph_type_id(),
132            name: changeset_variant_string("schema.all.edge"),
133        },
134        || Self::RecordTypeAdded {
135            graph_type: changeset_graph_type_id(),
136            def: RecordTypeDef {
137                id: RecordTypeId::new(1),
138                name: changeset_variant_string("schema.all.record"),
139                fields: SmallVec::new(),
140            },
141        },
142        || Self::PropertyIndexCreated {
143            label: changeset_variant_string("schema.all.node"),
144            property: changeset_variant_string("schema.all.property"),
145            kind: SchemaPropertyIndexKind::Bool,
146        },
147        || Self::PropertyIndexDropped {
148            label: changeset_variant_string("schema.all.node"),
149            property: changeset_variant_string("schema.all.property"),
150        },
151        || Self::PropertyIndexCreatedNamed {
152            label: changeset_variant_string("schema.all.node"),
153            property: changeset_variant_string("schema.all.property"),
154            kind: SchemaPropertyIndexKind::Decimal,
155            name: Some(changeset_variant_string("schema.all.index")),
156        },
157        || Self::NodeTypeAddedV2 {
158            graph_type: changeset_graph_type_id(),
159            label: changeset_variant_string("schema.all.node.v2"),
160            def: NodeTypeDef::new(LabelSet::single(changeset_variant_string(
161                "schema.all.node.v2",
162            ))),
163        },
164        || Self::EdgeTypeAddedV2 {
165            graph_type: changeset_graph_type_id(),
166            label: changeset_variant_string("schema.all.edge.v2"),
167            def: EdgeTypeDef::new(
168                changeset_variant_string("schema.all.edge.v2"),
169                NodeTypeRef(changeset_variant_string("schema.all.node")),
170                NodeTypeRef(changeset_variant_string("schema.all.node")),
171            ),
172        },
173        || Self::CompositePropertyIndexCreated {
174            label: changeset_variant_string("schema.all.node"),
175            properties: SmallVec::from_vec(vec![
176                changeset_variant_string("schema.all.property.a"),
177                changeset_variant_string("schema.all.property.b"),
178                changeset_variant_string("schema.all.property.c"),
179                changeset_variant_string("schema.all.property.d"),
180                changeset_variant_string("schema.all.property.e"),
181                changeset_variant_string("schema.all.property.f"),
182                changeset_variant_string("schema.all.property.g"),
183                changeset_variant_string("schema.all.property.h"),
184            ]),
185            kinds: SmallVec::from_vec(vec![
186                SchemaPropertyIndexKind::U64,
187                SchemaPropertyIndexKind::I128,
188                SchemaPropertyIndexKind::U128,
189                SchemaPropertyIndexKind::Decimal,
190                SchemaPropertyIndexKind::ZonedDateTime,
191                SchemaPropertyIndexKind::LocalTime,
192                SchemaPropertyIndexKind::ZonedTime,
193                SchemaPropertyIndexKind::Duration,
194            ]),
195            name: Some(changeset_variant_string("schema.all.composite.index")),
196        },
197        || Self::CompositePropertyIndexDropped {
198            label: changeset_variant_string("schema.all.node"),
199            properties: SmallVec::from_vec(vec![
200                changeset_variant_string("schema.all.property.a"),
201                changeset_variant_string("schema.all.property.b"),
202                changeset_variant_string("schema.all.property.c"),
203                changeset_variant_string("schema.all.property.d"),
204            ]),
205        },
206        || Self::VectorIndexCreated {
207            label: changeset_variant_string("schema.all.node"),
208            property: changeset_variant_string("schema.all.vector"),
209            kind: SchemaVectorIndexKind::IvfCosine,
210            dimension: 128,
211            name: Some(changeset_variant_string("schema.all.vector.index")),
212            hnsw_config: None,
213            ivf_config: Some(IvfIndexConfig::new(256)),
214        },
215        || Self::VectorIndexDropped {
216            label: changeset_variant_string("schema.all.node"),
217            property: changeset_variant_string("schema.all.vector"),
218        },
219        || Self::TextIndexCreated {
220            label: changeset_variant_string("schema.all.node"),
221            property: changeset_variant_string("schema.all.text"),
222            name: Some(changeset_variant_string("schema.all.text.index")),
223        },
224        || Self::TextIndexDropped {
225            label: changeset_variant_string("schema.all.node"),
226            property: changeset_variant_string("schema.all.text"),
227        },
228        || Self::EdgePropertyIndexCreated {
229            label: changeset_variant_string("schema.all.edge"),
230            property: changeset_variant_string("schema.all.edge.property"),
231            kind: SchemaPropertyIndexKind::String,
232            name: Some(changeset_variant_string("schema.all.edge.index")),
233        },
234        || Self::EdgePropertyIndexDropped {
235            label: changeset_variant_string("schema.all.edge"),
236            property: changeset_variant_string("schema.all.edge.property"),
237        },
238    ];
239
240    /// Number of known [`SchemaChange`] variants in this build.
241    pub const VARIANT_COUNT: usize = Self::ALL.len();
242
243    /// Stable telemetry name for this schema-change variant.
244    #[must_use]
245    pub fn variant_name(&self) -> &'static str {
246        match self {
247            Self::GraphCreated { .. } => "GraphCreated",
248            Self::GraphDropped { .. } => "GraphDropped",
249            Self::GraphTypeCreated { .. } => "GraphTypeCreated",
250            Self::GraphTypeDropped { .. } => "GraphTypeDropped",
251            Self::NodeTypeAdded { .. } => "NodeTypeAdded",
252            Self::EdgeTypeAdded { .. } => "EdgeTypeAdded",
253            Self::NodeTypeDropped { .. } => "NodeTypeDropped",
254            Self::EdgeTypeDropped { .. } => "EdgeTypeDropped",
255            Self::RecordTypeAdded { .. } => "RecordTypeAdded",
256            Self::PropertyIndexCreated { .. } => "PropertyIndexCreated",
257            Self::PropertyIndexDropped { .. } => "PropertyIndexDropped",
258            Self::PropertyIndexCreatedNamed { .. } => "PropertyIndexCreatedNamed",
259            Self::NodeTypeAddedV2 { .. } => "NodeTypeAddedV2",
260            Self::EdgeTypeAddedV2 { .. } => "EdgeTypeAddedV2",
261            Self::CompositePropertyIndexCreated { .. } => "CompositePropertyIndexCreated",
262            Self::CompositePropertyIndexDropped { .. } => "CompositePropertyIndexDropped",
263            Self::VectorIndexCreated { .. } => "VectorIndexCreated",
264            Self::VectorIndexDropped { .. } => "VectorIndexDropped",
265            Self::TextIndexCreated { .. } => "TextIndexCreated",
266            Self::TextIndexDropped { .. } => "TextIndexDropped",
267            Self::EdgePropertyIndexCreated { .. } => "EdgePropertyIndexCreated",
268            Self::EdgePropertyIndexDropped { .. } => "EdgePropertyIndexDropped",
269        }
270    }
271}
272
273fn changeset_variant_string(name: &str) -> DbString {
274    crate::db_string(name).expect("Change::ALL fixture strings fit DB string cap")
275}
276
277fn changeset_graph_type_id() -> GraphTypeId {
278    GraphTypeId::new(1).expect("Change::ALL graph type fixture is non-zero")
279}
280
281fn changeset_graph_type() -> GraphType {
282    GraphType::new(
283        changeset_graph_type_id(),
284        changeset_variant_string("schema.all.graph_type"),
285    )
286}