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 = "crate::serde_map")]
228 roles: BTreeMap<RoleId, RoleDefinition>,
229 role_names: BTreeMap<String, RoleId>,
231 #[serde(with = "crate::serde_map")]
233 labels: BTreeMap<LabelId, LabelDefinition>,
234 label_names: BTreeMap<String, LabelId>,
236 #[serde(with = "crate::serde_map")]
238 relation_types: BTreeMap<RelationTypeId, RelationTypeDefinition>,
239 relation_type_names: BTreeMap<String, RelationTypeId>,
241 #[serde(with = "crate::serde_map")]
243 property_keys: BTreeMap<PropertyKeyId, PropertyKeyDefinition>,
244 property_key_names: BTreeMap<String, PropertyKeyId>,
246 #[serde(with = "crate::serde_map")]
248 projections: BTreeMap<ProjectionId, ProjectionEntry>,
249 projection_names: BTreeMap<String, ProjectionId>,
251 #[serde(with = "crate::serde_map")]
253 indexes: BTreeMap<IndexId, IndexEntry>,
254 index_names: BTreeMap<String, IndexId>,
256}
257
258impl Catalog {
259 #[must_use]
265 pub(crate) const fn empty() -> Self {
266 Self {
267 roles: BTreeMap::new(),
268 role_names: BTreeMap::new(),
269 labels: BTreeMap::new(),
270 label_names: BTreeMap::new(),
271 relation_types: BTreeMap::new(),
272 relation_type_names: BTreeMap::new(),
273 property_keys: BTreeMap::new(),
274 property_key_names: BTreeMap::new(),
275 projections: BTreeMap::new(),
276 projection_names: BTreeMap::new(),
277 indexes: BTreeMap::new(),
278 index_names: BTreeMap::new(),
279 }
280 }
281
282 #[must_use]
288 pub fn role(&self, id: RoleId) -> Option<&RoleDefinition> {
289 self.roles.get(&id)
290 }
291
292 #[must_use]
298 pub fn label(&self, id: LabelId) -> Option<&LabelDefinition> {
299 self.labels.get(&id)
300 }
301
302 #[must_use]
308 pub fn relation_type(&self, id: RelationTypeId) -> Option<&RelationTypeDefinition> {
309 self.relation_types.get(&id)
310 }
311
312 #[must_use]
318 pub fn property_key(&self, id: PropertyKeyId) -> Option<&PropertyKeyDefinition> {
319 self.property_keys.get(&id)
320 }
321
322 #[must_use]
328 pub fn projection(&self, id: ProjectionId) -> Option<&ProjectionEntry> {
329 self.projections.get(&id)
330 }
331
332 #[must_use]
338 pub fn index(&self, id: IndexId) -> Option<&IndexEntry> {
339 self.indexes.get(&id)
340 }
341
342 #[must_use]
348 pub fn role_id(&self, name: &str) -> Option<RoleId> {
349 self.role_names.get(name).copied()
350 }
351
352 #[must_use]
358 pub fn label_id(&self, name: &str) -> Option<LabelId> {
359 self.label_names.get(name).copied()
360 }
361
362 #[must_use]
368 pub fn relation_type_id(&self, name: &str) -> Option<RelationTypeId> {
369 self.relation_type_names.get(name).copied()
370 }
371
372 #[must_use]
378 pub fn property_key_id(&self, name: &str) -> Option<PropertyKeyId> {
379 self.property_key_names.get(name).copied()
380 }
381
382 #[must_use]
388 pub fn projection_id(&self, name: &str) -> Option<ProjectionId> {
389 self.projection_names.get(name).copied()
390 }
391
392 #[must_use]
398 pub fn index_id(&self, name: &str) -> Option<IndexId> {
399 self.index_names.get(name).copied()
400 }
401
402 pub fn roles(&self) -> impl Iterator<Item = &RoleDefinition> {
408 self.roles.values()
409 }
410
411 pub fn labels(&self) -> impl Iterator<Item = &LabelDefinition> {
417 self.labels.values()
418 }
419
420 pub fn relation_types(&self) -> impl Iterator<Item = &RelationTypeDefinition> {
426 self.relation_types.values()
427 }
428
429 pub fn property_keys(&self) -> impl Iterator<Item = &PropertyKeyDefinition> {
435 self.property_keys.values()
436 }
437
438 pub fn projections(&self) -> impl Iterator<Item = &ProjectionEntry> {
444 self.projections.values()
445 }
446
447 pub fn indexes(&self) -> impl Iterator<Item = &IndexEntry> {
453 self.indexes.values()
454 }
455
456 pub(crate) fn insert_role(&mut self, id: RoleId, name: String) -> Result<(), DbError> {
458 insert_named(&mut self.role_names, &name, id)?;
459 self.roles.insert(id, RoleDefinition { id, name });
460 Ok(())
461 }
462
463 pub(crate) fn insert_label(&mut self, id: LabelId, name: String) -> Result<(), DbError> {
465 insert_named(&mut self.label_names, &name, id)?;
466 self.labels.insert(id, LabelDefinition { id, name });
467 Ok(())
468 }
469
470 pub(crate) fn insert_relation_type(
472 &mut self,
473 id: RelationTypeId,
474 name: String,
475 ) -> Result<(), DbError> {
476 insert_named(&mut self.relation_type_names, &name, id)?;
477 self.relation_types
478 .insert(id, RelationTypeDefinition { id, name });
479 Ok(())
480 }
481
482 pub(crate) fn insert_property_key(
484 &mut self,
485 definition: PropertyKeyDefinition,
486 ) -> Result<(), DbError> {
487 insert_named(
488 &mut self.property_key_names,
489 &definition.name,
490 definition.id,
491 )?;
492 self.property_keys.insert(definition.id, definition);
493 Ok(())
494 }
495
496 pub(crate) fn insert_projection(
498 &mut self,
499 id: ProjectionId,
500 definition: ProjectionDefinition,
501 ) -> Result<(), DbError> {
502 insert_named(&mut self.projection_names, definition.name(), id)?;
503 self.projections
504 .insert(id, ProjectionEntry { id, definition });
505 Ok(())
506 }
507
508 pub(crate) fn insert_index(
510 &mut self,
511 id: IndexId,
512 name: String,
513 definition: IndexDefinition,
514 ) -> Result<(), DbError> {
515 insert_named(&mut self.index_names, &name, id)?;
516 self.indexes.insert(
517 id,
518 IndexEntry {
519 id,
520 name,
521 definition,
522 },
523 );
524 Ok(())
525 }
526}
527
528fn insert_named<Id: Copy>(
530 names: &mut BTreeMap<String, Id>,
531 name: &str,
532 id: Id,
533) -> Result<(), DbError> {
534 if names.contains_key(name) {
535 return Err(DbError::DuplicateCatalogName);
536 }
537 names.insert(name.to_owned(), id);
538 Ok(())
539}