oxgraph_postgres/artifact/
metadata.rs1use oxgraph_snapshot::{PlanError, Snapshot, SnapshotBuilder, SnapshotError};
4use zerocopy::{
5 FromBytes, Immutable, IntoBytes, KnownLayout,
6 byteorder::{LE, U32, U64},
7};
8
9pub const SNAPSHOT_KIND_PG_CATALOG: u32 = 0x0200;
11
12pub const SNAPSHOT_KIND_PG_INBOUND_OFFSETS_U32: u32 = 0x0201;
20
21pub const SNAPSHOT_KIND_PG_INBOUND_TARGETS_U32: u32 = 0x0202;
23
24pub const SNAPSHOT_KIND_PG_METADATA: u32 = 0x0203;
26
27#[derive(Clone, Copy, Debug, PartialEq, Eq, FromBytes, Immutable, IntoBytes, KnownLayout)]
29#[repr(C)]
30pub struct PostgresMetadata {
31 pub version: U32<LE>,
33 pub flags: U32<LE>,
35 pub built_at_unix: U64<LE>,
37 pub node_count: U32<LE>,
39 pub edge_count: U32<LE>,
41}
42
43impl PostgresMetadata {
44 pub const VERSION: u32 = 1;
46
47 pub const FLAG_READ_ONLY: u32 = 1;
49
50 pub const FLAG_HAS_REVERSE_INDEX: u32 = 2;
52
53 #[must_use]
55 pub const fn new(
56 node_count: u32,
57 edge_count: u32,
58 built_at_unix: u64,
59 read_only: bool,
60 ) -> Self {
61 let mut flags = 0_u32;
62 if read_only {
63 flags |= Self::FLAG_READ_ONLY;
64 }
65 Self {
66 version: U32::new(Self::VERSION),
67 flags: U32::new(flags),
68 built_at_unix: U64::new(built_at_unix),
69 node_count: U32::new(node_count),
70 edge_count: U32::new(edge_count),
71 }
72 }
73
74 #[must_use]
76 pub const fn with_reverse_index(mut self) -> Self {
77 self.flags = U32::new(self.flags.get() | Self::FLAG_HAS_REVERSE_INDEX);
78 self
79 }
80
81 #[must_use]
83 pub const fn is_read_only(self) -> bool {
84 self.flags.get() & Self::FLAG_READ_ONLY != 0
85 }
86
87 #[must_use]
89 pub const fn has_reverse_index(self) -> bool {
90 self.flags.get() & Self::FLAG_HAS_REVERSE_INDEX != 0
91 }
92}
93
94#[derive(Debug, Clone, PartialEq, Eq)]
96pub enum PostgresSectionError {
97 Snapshot(SnapshotError),
99 MissingSection,
101 Malformed(alloc::string::String),
103}
104
105pub(super) fn read_postgres_metadata(
115 snapshot: &Snapshot<'_>,
116) -> Result<PostgresMetadata, PostgresSectionError> {
117 let section = snapshot
118 .section(SNAPSHOT_KIND_PG_METADATA)
119 .ok_or(PostgresSectionError::MissingSection)?;
120 PostgresMetadata::ref_from_bytes(section.bytes())
121 .map_err(|error| {
122 PostgresSectionError::Malformed(alloc::format!("postgres metadata layout: {error}"))
123 })
124 .copied()
125}
126
127pub(super) fn write_postgres_metadata_section(
137 builder: &mut SnapshotBuilder,
138 metadata: &PostgresMetadata,
139) -> Result<(), PlanError> {
140 builder.add_section_typed(
141 SNAPSHOT_KIND_PG_METADATA,
142 PostgresMetadata::VERSION,
143 core::slice::from_ref(metadata),
144 )?;
145 Ok(())
146}