1use std::collections::{BTreeMap, BTreeSet};
4
5use serde::{Deserialize, Serialize};
6
7use crate::{
8 DbError, IndexId, LabelId, ProjectionId, PropertyKeyId, RelationTypeId, RoleId,
9 value::PropertyType,
10};
11
12#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
18pub struct RoleDefinition {
19 pub id: RoleId,
21 pub name: String,
23}
24
25#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
31pub struct LabelDefinition {
32 pub id: LabelId,
34 pub name: String,
36}
37
38#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
44pub struct RelationTypeDefinition {
45 pub id: RelationTypeId,
47 pub name: String,
49}
50
51#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
57pub enum PropertyFamily {
58 Element,
60 Relation,
62 Incidence,
64}
65
66#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
72pub struct PropertyKeyDefinition {
73 pub id: PropertyKeyId,
75 pub name: String,
77 pub family: PropertyFamily,
79 pub value_type: PropertyType,
81}
82
83#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
92pub struct GraphProjectionDefinition {
93 pub name: String,
95 pub relation_types: BTreeSet<RelationTypeId>,
97 pub source_role: RoleId,
99 pub target_role: RoleId,
101}
102
103#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
113pub struct HypergraphProjectionDefinition {
114 pub name: String,
116 pub relation_types: BTreeSet<RelationTypeId>,
118 pub source_roles: BTreeSet<RoleId>,
120 pub target_roles: BTreeSet<RoleId>,
122}
123
124#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
130pub enum ProjectionDefinition {
131 Graph(GraphProjectionDefinition),
133 Hypergraph(HypergraphProjectionDefinition),
135}
136
137impl ProjectionDefinition {
138 #[must_use]
144 pub fn name(&self) -> &str {
145 match self {
146 Self::Graph(definition) => &definition.name,
147 Self::Hypergraph(definition) => &definition.name,
148 }
149 }
150}
151
152#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
158pub enum IndexDefinition {
159 Label {
161 label: LabelId,
163 },
164 RelationType {
166 relation_type: RelationTypeId,
168 },
169 PropertyEquality {
171 key: PropertyKeyId,
173 },
174 PropertyRange {
176 key: PropertyKeyId,
178 },
179 CompositeEquality {
181 keys: Vec<PropertyKeyId>,
183 },
184 Projection {
186 projection: ProjectionId,
188 },
189}
190
191#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
197pub struct IndexEntry {
198 pub id: IndexId,
200 pub name: String,
202 pub definition: IndexDefinition,
204}
205
206#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
212pub struct ProjectionEntry {
213 pub id: ProjectionId,
215 pub definition: ProjectionDefinition,
217}
218
219#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
225pub struct Catalog {
226 #[serde(with = "serde_btree_map_vec")]
228 roles: BTreeMap<RoleId, RoleDefinition>,
229 role_names: BTreeMap<String, RoleId>,
231 #[serde(with = "serde_btree_map_vec")]
233 labels: BTreeMap<LabelId, LabelDefinition>,
234 label_names: BTreeMap<String, LabelId>,
236 #[serde(with = "serde_btree_map_vec")]
238 relation_types: BTreeMap<RelationTypeId, RelationTypeDefinition>,
239 relation_type_names: BTreeMap<String, RelationTypeId>,
241 #[serde(with = "serde_btree_map_vec")]
243 property_keys: BTreeMap<PropertyKeyId, PropertyKeyDefinition>,
244 property_key_names: BTreeMap<String, PropertyKeyId>,
246 #[serde(with = "serde_btree_map_vec")]
248 projections: BTreeMap<ProjectionId, ProjectionEntry>,
249 projection_names: BTreeMap<String, ProjectionId>,
251 #[serde(with = "serde_btree_map_vec")]
253 indexes: BTreeMap<IndexId, IndexEntry>,
254 index_names: BTreeMap<String, IndexId>,
256}
257
258mod serde_btree_map_vec {
260 pub(super) fn serialize<S, K, V>(
262 map: &std::collections::BTreeMap<K, V>,
263 serializer: S,
264 ) -> Result<S::Ok, S::Error>
265 where
266 S: serde::Serializer,
267 K: serde::Serialize,
268 V: serde::Serialize,
269 {
270 serde::Serialize::serialize(&map.iter().collect::<Vec<_>>(), serializer)
271 }
272
273 pub(super) fn deserialize<'de, D, K, V>(
275 deserializer: D,
276 ) -> Result<std::collections::BTreeMap<K, V>, D::Error>
277 where
278 D: serde::Deserializer<'de>,
279 K: Ord + serde::de::DeserializeOwned,
280 V: serde::de::DeserializeOwned,
281 {
282 <Vec<(K, V)> as serde::Deserialize>::deserialize(deserializer)
283 .map(|entries| entries.into_iter().collect())
284 }
285}
286
287impl Catalog {
288 #[must_use]
294 pub(crate) const fn empty() -> Self {
295 Self {
296 roles: BTreeMap::new(),
297 role_names: BTreeMap::new(),
298 labels: BTreeMap::new(),
299 label_names: BTreeMap::new(),
300 relation_types: BTreeMap::new(),
301 relation_type_names: BTreeMap::new(),
302 property_keys: BTreeMap::new(),
303 property_key_names: BTreeMap::new(),
304 projections: BTreeMap::new(),
305 projection_names: BTreeMap::new(),
306 indexes: BTreeMap::new(),
307 index_names: BTreeMap::new(),
308 }
309 }
310
311 #[must_use]
317 pub fn role(&self, id: RoleId) -> Option<&RoleDefinition> {
318 self.roles.get(&id)
319 }
320
321 #[must_use]
327 pub fn label(&self, id: LabelId) -> Option<&LabelDefinition> {
328 self.labels.get(&id)
329 }
330
331 #[must_use]
337 pub fn relation_type(&self, id: RelationTypeId) -> Option<&RelationTypeDefinition> {
338 self.relation_types.get(&id)
339 }
340
341 #[must_use]
347 pub fn property_key(&self, id: PropertyKeyId) -> Option<&PropertyKeyDefinition> {
348 self.property_keys.get(&id)
349 }
350
351 #[must_use]
357 pub fn projection(&self, id: ProjectionId) -> Option<&ProjectionEntry> {
358 self.projections.get(&id)
359 }
360
361 #[must_use]
367 pub fn index(&self, id: IndexId) -> Option<&IndexEntry> {
368 self.indexes.get(&id)
369 }
370
371 #[must_use]
377 pub fn role_id(&self, name: &str) -> Option<RoleId> {
378 self.role_names.get(name).copied()
379 }
380
381 #[must_use]
387 pub fn label_id(&self, name: &str) -> Option<LabelId> {
388 self.label_names.get(name).copied()
389 }
390
391 #[must_use]
397 pub fn relation_type_id(&self, name: &str) -> Option<RelationTypeId> {
398 self.relation_type_names.get(name).copied()
399 }
400
401 #[must_use]
407 pub fn property_key_id(&self, name: &str) -> Option<PropertyKeyId> {
408 self.property_key_names.get(name).copied()
409 }
410
411 #[must_use]
417 pub fn projection_id(&self, name: &str) -> Option<ProjectionId> {
418 self.projection_names.get(name).copied()
419 }
420
421 #[must_use]
427 pub fn index_id(&self, name: &str) -> Option<IndexId> {
428 self.index_names.get(name).copied()
429 }
430
431 pub fn roles(&self) -> impl Iterator<Item = &RoleDefinition> {
437 self.roles.values()
438 }
439
440 pub fn labels(&self) -> impl Iterator<Item = &LabelDefinition> {
446 self.labels.values()
447 }
448
449 pub fn relation_types(&self) -> impl Iterator<Item = &RelationTypeDefinition> {
455 self.relation_types.values()
456 }
457
458 pub fn property_keys(&self) -> impl Iterator<Item = &PropertyKeyDefinition> {
464 self.property_keys.values()
465 }
466
467 pub fn projections(&self) -> impl Iterator<Item = &ProjectionEntry> {
473 self.projections.values()
474 }
475
476 pub fn indexes(&self) -> impl Iterator<Item = &IndexEntry> {
482 self.indexes.values()
483 }
484
485 pub(crate) fn insert_role(&mut self, id: RoleId, name: String) -> Result<(), DbError> {
487 insert_named(&mut self.role_names, &name, id)?;
488 self.roles.insert(id, RoleDefinition { id, name });
489 Ok(())
490 }
491
492 pub(crate) fn insert_label(&mut self, id: LabelId, name: String) -> Result<(), DbError> {
494 insert_named(&mut self.label_names, &name, id)?;
495 self.labels.insert(id, LabelDefinition { id, name });
496 Ok(())
497 }
498
499 pub(crate) fn insert_relation_type(
501 &mut self,
502 id: RelationTypeId,
503 name: String,
504 ) -> Result<(), DbError> {
505 insert_named(&mut self.relation_type_names, &name, id)?;
506 self.relation_types
507 .insert(id, RelationTypeDefinition { id, name });
508 Ok(())
509 }
510
511 pub(crate) fn insert_property_key(
513 &mut self,
514 definition: PropertyKeyDefinition,
515 ) -> Result<(), DbError> {
516 insert_named(
517 &mut self.property_key_names,
518 &definition.name,
519 definition.id,
520 )?;
521 self.property_keys.insert(definition.id, definition);
522 Ok(())
523 }
524
525 pub(crate) fn insert_projection(
527 &mut self,
528 id: ProjectionId,
529 definition: ProjectionDefinition,
530 ) -> Result<(), DbError> {
531 insert_named(&mut self.projection_names, definition.name(), id)?;
532 self.projections
533 .insert(id, ProjectionEntry { id, definition });
534 Ok(())
535 }
536
537 pub(crate) fn insert_index(
539 &mut self,
540 id: IndexId,
541 name: String,
542 definition: IndexDefinition,
543 ) -> Result<(), DbError> {
544 insert_named(&mut self.index_names, &name, id)?;
545 self.indexes.insert(
546 id,
547 IndexEntry {
548 id,
549 name,
550 definition,
551 },
552 );
553 Ok(())
554 }
555}
556
557fn insert_named<Id: Copy>(
559 names: &mut BTreeMap<String, Id>,
560 name: &str,
561 id: Id,
562) -> Result<(), DbError> {
563 if names.contains_key(name) {
564 return Err(DbError::DuplicateCatalogName);
565 }
566 names.insert(name.to_owned(), id);
567 Ok(())
568}