From 4d5a7123c7e7c5aa64f23f380dd5fe56b1959b1a Mon Sep 17 00:00:00 2001 From: Tim Diekmann Date: Thu, 16 Feb 2023 18:42:32 +0100 Subject: [PATCH 01/19] Remove `GraphElementId` --- apps/hash-graph/lib/graph/src/api/rest.rs | 3 +-- apps/hash-graph/lib/graph/src/shared/identifier.rs | 11 ++--------- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/apps/hash-graph/lib/graph/src/api/rest.rs b/apps/hash-graph/lib/graph/src/api/rest.rs index 3be49c9b03a..06456a5e0e6 100644 --- a/apps/hash-graph/lib/graph/src/api/rest.rs +++ b/apps/hash-graph/lib/graph/src/api/rest.rs @@ -54,7 +54,7 @@ use crate::{ UnresolvedTransactionTimeImage, UnresolvedTransactionTimeKernel, UnresolvedTransactionTimeProjection, }, - EntityVertexId, GraphElementId, GraphElementVertexId, OntologyTypeVertexId, + EntityVertexId, GraphElementVertexId, OntologyTypeVertexId, }, ontology::{ domain_validator::DomainValidator, ExternalOntologyElementMetadata, @@ -186,7 +186,6 @@ async fn serve_static_schema(Path(path): Path) -> Result Date: Thu, 16 Feb 2023 21:47:06 +0100 Subject: [PATCH 02/19] Update `type_system` package --- apps/hash-graph/Cargo.lock | 2 +- apps/hash-graph/bench/Cargo.toml | 2 +- .../bench/representative_read/seed.rs | 4 +- apps/hash-graph/bench/util.rs | 6 +- apps/hash-graph/bin/cli/Cargo.toml | 2 +- apps/hash-graph/lib/graph/Cargo.toml | 2 +- .../lib/graph/src/api/rest/data_type.rs | 11 +-- .../lib/graph/src/api/rest/entity_type.rs | 11 +-- .../lib/graph/src/api/rest/property_type.rs | 11 +-- .../graph/src/ontology/domain_validator.rs | 6 +- .../lib/graph/src/shared/identifier.rs | 10 +-- .../graph/src/shared/identifier/ontology.rs | 19 ++--- .../hash-graph/lib/graph/src/store/fetcher.rs | 8 +- .../lib/graph/src/store/postgres.rs | 16 ++-- .../src/store/postgres/knowledge/entity.rs | 2 +- .../store/postgres/ontology/entity_type.rs | 28 ++++--- .../store/postgres/ontology/property_type.rs | 12 ++- .../store/postgres/query/statement/select.rs | 12 +-- .../lib/graph/src/store/query/filter.rs | 16 ++-- apps/hash-graph/lib/type-fetcher/Cargo.toml | 2 +- apps/hash-graph/tests/integration/Cargo.toml | 2 +- .../tests/integration/postgres/entity.rs | 40 +++++----- .../tests/integration/postgres/lib.rs | 22 ++--- .../tests/integration/postgres/links.rs | 80 +++++++++++-------- 24 files changed, 173 insertions(+), 153 deletions(-) diff --git a/apps/hash-graph/Cargo.lock b/apps/hash-graph/Cargo.lock index 17d186a2af8..7cd18cdc9b3 100644 --- a/apps/hash-graph/Cargo.lock +++ b/apps/hash-graph/Cargo.lock @@ -2701,7 +2701,7 @@ dependencies = [ [[package]] name = "type-system" version = "0.0.0" -source = "git+https://github.com/blockprotocol/blockprotocol?rev=646b7d1#646b7d1c6cc35197ac76872d6c34e8e4185f2f0c" +source = "git+https://github.com/blockprotocol/blockprotocol?rev=ce8df71#ce8df719ca03657f30849140e83843f60ecefa59" dependencies = [ "console_error_panic_hook", "regex", diff --git a/apps/hash-graph/bench/Cargo.toml b/apps/hash-graph/bench/Cargo.toml index 6bba0605326..4fcb834c1d0 100644 --- a/apps/hash-graph/bench/Cargo.toml +++ b/apps/hash-graph/bench/Cargo.toml @@ -21,7 +21,7 @@ serde = { version = "1.0.152", features = ["derive"] } serde_json = "1.0.91" tokio = { version = "1.25.0", features = ["rt-multi-thread", "macros"] } tokio-postgres = { version = "0.7.7", default-features = false } -type-system = { git = "https://github.com/blockprotocol/blockprotocol", rev = "646b7d1" } +type-system = { git = "https://github.com/blockprotocol/blockprotocol", rev = "ce8df71" } uuid = { version = "1.3.0", features = ["v4", "serde"] } [[bench]] diff --git a/apps/hash-graph/bench/representative_read/seed.rs b/apps/hash-graph/bench/representative_read/seed.rs index 0bdf5308e5c..44d4f76ec10 100644 --- a/apps/hash-graph/bench/representative_read/seed.rs +++ b/apps/hash-graph/bench/representative_read/seed.rs @@ -267,8 +267,8 @@ async fn get_samples(account_id: AccountId, store_wrapper: &mut StoreWrapper) -> LIMIT 50 "#, &[ - &entity_type_id.base_uri().as_str(), - &i64::from(entity_type_id.version()), + &entity_type_id.base_uri.as_str(), + &i64::from(entity_type_id.version), ], ) .await diff --git a/apps/hash-graph/bench/util.rs b/apps/hash-graph/bench/util.rs index 9f9a283783a..e0b9aa8c2e7 100644 --- a/apps/hash-graph/bench/util.rs +++ b/apps/hash-graph/bench/util.rs @@ -201,7 +201,7 @@ pub async fn seed( .create_data_type( data_type.clone(), &OntologyElementMetadata::Owned(OwnedOntologyElementMetadata::new( - data_type.id().into(), + data_type.id().clone().into(), ProvenanceMetadata::new(UpdatedById::new(account_id)), OwnedById::new(account_id), )), @@ -232,7 +232,7 @@ pub async fn seed( .create_property_type( property_type.clone(), &OntologyElementMetadata::Owned(OwnedOntologyElementMetadata::new( - property_type.id().into(), + property_type.id().clone().into(), ProvenanceMetadata::new(UpdatedById::new(account_id)), OwnedById::new(account_id), )), @@ -263,7 +263,7 @@ pub async fn seed( .create_entity_type( entity_type.clone(), &OntologyElementMetadata::Owned(OwnedOntologyElementMetadata::new( - entity_type.id().into(), + entity_type.id().clone().into(), ProvenanceMetadata::new(UpdatedById::new(account_id)), OwnedById::new(account_id), )), diff --git a/apps/hash-graph/bin/cli/Cargo.toml b/apps/hash-graph/bin/cli/Cargo.toml index 29942a31bc3..39067f97ddc 100644 --- a/apps/hash-graph/bin/cli/Cargo.toml +++ b/apps/hash-graph/bin/cli/Cargo.toml @@ -24,7 +24,7 @@ tokio = { version = "1.25.0", features = ["rt-multi-thread", "macros"] } tokio-postgres = { version = "0.7.7", default-features = false } tokio-serde = { version = "0.8", features = ["messagepack"], optional = true } tracing = "0.1.37" -type-system = { git = "https://github.com/blockprotocol/blockprotocol", rev = "646b7d1" } +type-system = { git = "https://github.com/blockprotocol/blockprotocol", rev = "ce8df71" } uuid = "1.3.0" # Remove again when the type fetcher is used in the graph diff --git a/apps/hash-graph/lib/graph/Cargo.toml b/apps/hash-graph/lib/graph/Cargo.toml index 5fdc04c379d..f3a78a5aaf8 100644 --- a/apps/hash-graph/lib/graph/Cargo.toml +++ b/apps/hash-graph/lib/graph/Cargo.toml @@ -34,7 +34,7 @@ tonic = "0.8.3" opentelemetry = { version = "0.18.0", features = ["rt-tokio"] } opentelemetry-otlp = "0.11.0" tracing-subscriber = { version = "0.3.16", features = ["env-filter", "json"] } -type-system = { git = "https://github.com/blockprotocol/blockprotocol", rev = "646b7d1" } +type-system = { git = "https://github.com/blockprotocol/blockprotocol", rev = "ce8df71" } uuid = { version = "1.3.0", features = ["v4", "serde"] } utoipa = { version = "3.0.1", features = ["uuid"] } include_dir = "0.7.3" diff --git a/apps/hash-graph/lib/graph/src/api/rest/data_type.rs b/apps/hash-graph/lib/graph/src/api/rest/data_type.rs index 70eeef06f44..b97229e3db0 100644 --- a/apps/hash-graph/lib/graph/src/api/rest/data_type.rs +++ b/apps/hash-graph/lib/graph/src/api/rest/data_type.rs @@ -111,7 +111,7 @@ async fn create_data_type( })?; let metadata = OntologyElementMetadata::Owned(OwnedOntologyElementMetadata::new( - data_type.id().into(), + data_type.id().clone().into(), ProvenanceMetadata::new(actor_id), owned_by_id, )); @@ -204,16 +204,13 @@ async fn update_data_type( ) -> Result, StatusCode> { let Json(UpdateDataTypeRequest { schema, - type_to_update, + mut type_to_update, actor_id, }) = body; - let new_type_id = VersionedUri::new( - type_to_update.base_uri().clone(), - type_to_update.version() + 1, - ); + type_to_update.version += 1; - let data_type = patch_id_and_parse(&new_type_id, schema).map_err(|report| { + let data_type = patch_id_and_parse(&type_to_update, schema).map_err(|report| { tracing::error!(error=?report, "Couldn't patch schema and convert to Data Type"); StatusCode::UNPROCESSABLE_ENTITY // TODO - We should probably return more information to the client diff --git a/apps/hash-graph/lib/graph/src/api/rest/entity_type.rs b/apps/hash-graph/lib/graph/src/api/rest/entity_type.rs index f34d1b18f0a..e5c80ce522b 100644 --- a/apps/hash-graph/lib/graph/src/api/rest/entity_type.rs +++ b/apps/hash-graph/lib/graph/src/api/rest/entity_type.rs @@ -119,7 +119,7 @@ async fn create_entity_type( })?; let metadata = OntologyElementMetadata::Owned(OwnedOntologyElementMetadata::new( - entity_type.id().into(), + entity_type.id().clone().into(), ProvenanceMetadata::new(actor_id), owned_by_id, )); @@ -213,16 +213,13 @@ async fn update_entity_type( ) -> Result, StatusCode> { let Json(UpdateEntityTypeRequest { schema, - type_to_update, + mut type_to_update, actor_id, }) = body; - let new_type_id = VersionedUri::new( - type_to_update.base_uri().clone(), - type_to_update.version() + 1, - ); + type_to_update.version += 1; - let entity_type = patch_id_and_parse(&new_type_id, schema).map_err(|report| { + let entity_type = patch_id_and_parse(&type_to_update, schema).map_err(|report| { tracing::error!(error=?report, "Couldn't convert schema to Entity Type"); // Shame there isn't an UNPROCESSABLE_ENTITY_TYPE code :D StatusCode::UNPROCESSABLE_ENTITY diff --git a/apps/hash-graph/lib/graph/src/api/rest/property_type.rs b/apps/hash-graph/lib/graph/src/api/rest/property_type.rs index c4d2f706c34..1507bffb8e7 100644 --- a/apps/hash-graph/lib/graph/src/api/rest/property_type.rs +++ b/apps/hash-graph/lib/graph/src/api/rest/property_type.rs @@ -116,7 +116,7 @@ async fn create_property_type( })?; let metadata = OntologyElementMetadata::Owned(OwnedOntologyElementMetadata::new( - property_type.id().into(), + property_type.id().clone().into(), ProvenanceMetadata::new(actor_id), owned_by_id, )); @@ -211,16 +211,13 @@ async fn update_property_type( ) -> Result, StatusCode> { let Json(UpdatePropertyTypeRequest { schema, - type_to_update, + mut type_to_update, actor_id, }) = body; - let new_type_id = VersionedUri::new( - type_to_update.base_uri().clone(), - type_to_update.version() + 1, - ); + type_to_update.version += 1; - let property_type = patch_id_and_parse(&new_type_id, schema).map_err(|report| { + let property_type = patch_id_and_parse(&type_to_update, schema).map_err(|report| { tracing::error!(error=?report, "Couldn't patch schema and convert to Property Type"); StatusCode::UNPROCESSABLE_ENTITY // TODO - We should probably return more information to the client diff --git a/apps/hash-graph/lib/graph/src/ontology/domain_validator.rs b/apps/hash-graph/lib/graph/src/ontology/domain_validator.rs index 8e93c8910b9..19ef10ada0d 100644 --- a/apps/hash-graph/lib/graph/src/ontology/domain_validator.rs +++ b/apps/hash-graph/lib/graph/src/ontology/domain_validator.rs @@ -101,7 +101,7 @@ impl DomainValidator { impl ValidateOntologyType for DomainValidator { fn validate(&self, ontology_type: &DataType) -> error_stack::Result<(), DomainValidationError> { - let base_uri = ontology_type.id().base_uri(); + let base_uri = &ontology_type.id().base_uri; if !self.validate_url(base_uri.as_str()) { return Err(DomainValidationError) @@ -134,7 +134,7 @@ impl ValidateOntologyType for DomainValidator { &self, ontology_type: &PropertyType, ) -> error_stack::Result<(), DomainValidationError> { - let base_uri = ontology_type.id().base_uri(); + let base_uri = &ontology_type.id().base_uri; if !self.validate_url(base_uri.as_str()) { return Err(DomainValidationError).into_report().attach_printable( @@ -167,7 +167,7 @@ impl ValidateOntologyType for DomainValidator { &self, ontology_type: &EntityType, ) -> error_stack::Result<(), DomainValidationError> { - let base_uri = ontology_type.id().base_uri(); + let base_uri = &ontology_type.id().base_uri; if !self.validate_url(base_uri.as_str()) { return Err(DomainValidationError) diff --git a/apps/hash-graph/lib/graph/src/shared/identifier.rs b/apps/hash-graph/lib/graph/src/shared/identifier.rs index 2ce86411154..8843887dd96 100644 --- a/apps/hash-graph/lib/graph/src/shared/identifier.rs +++ b/apps/hash-graph/lib/graph/src/shared/identifier.rs @@ -4,7 +4,7 @@ pub mod ontology; pub mod time; use serde::Serialize; -use type_system::uri::BaseUri; +use type_system::uri::{BaseUri, VersionedUri}; use utoipa::ToSchema; use crate::identifier::{ @@ -61,11 +61,11 @@ impl OntologyTypeVertexId { } } -impl From<&VersionedUri> for OntologyTypeVertexId { - fn from(uri: &VersionedUri) -> Self { +impl From for OntologyTypeVertexId { + fn from(uri: VersionedUri) -> Self { Self { - base_id: uri.base_uri().clone(), - version: OntologyTypeVersion::new(uri.version()), + base_id: uri.base_uri, + version: OntologyTypeVersion::new(uri.version), } } } diff --git a/apps/hash-graph/lib/graph/src/shared/identifier/ontology.rs b/apps/hash-graph/lib/graph/src/shared/identifier/ontology.rs index 13c5c64fb44..95cf66add88 100644 --- a/apps/hash-graph/lib/graph/src/shared/identifier/ontology.rs +++ b/apps/hash-graph/lib/graph/src/shared/identifier/ontology.rs @@ -90,20 +90,21 @@ impl Display for OntologyTypeRecordId { } } -// The Type System crate doesn't let us destructure so we need to clone base_uri -impl From<&VersionedUri> for OntologyTypeRecordId { - fn from(versioned_uri: &VersionedUri) -> Self { +impl From for OntologyTypeRecordId { + fn from(versioned_uri: VersionedUri) -> Self { Self { - base_uri: versioned_uri.base_uri().clone(), - version: OntologyTypeVersion::new(versioned_uri.version()), + base_uri: versioned_uri.base_uri, + version: OntologyTypeVersion::new(versioned_uri.version), } } } -impl From<&OntologyTypeRecordId> for VersionedUri { - fn from(record_id: &OntologyTypeRecordId) -> Self { - // We should make it possible to destructure to avoid the clone - Self::new(record_id.base_uri().clone(), record_id.version.inner()) +impl From for VersionedUri { + fn from(record_id: OntologyTypeRecordId) -> Self { + Self { + base_uri: record_id.base_uri, + version: record_id.version.inner(), + } } } diff --git a/apps/hash-graph/lib/graph/src/store/fetcher.rs b/apps/hash-graph/lib/graph/src/store/fetcher.rs index 3159d9b70a5..76114963fc6 100644 --- a/apps/hash-graph/lib/graph/src/store/fetcher.rs +++ b/apps/hash-graph/lib/graph/src/store/fetcher.rs @@ -149,7 +149,7 @@ where OntologyTypeReference::EntityTypeReference(reference) => reference.uri(), }; - if self.domain_validator.validate_url(uri.base_uri().as_str()) { + if self.domain_validator.validate_url(uri.base_uri.as_str()) { // If the domain is valid, we own the data type and it either exists or we cannot // reference it. return Ok(true); @@ -233,7 +233,7 @@ where .await? { let metadata = ExternalOntologyElementMetadata::new( - data_type.id().into(), + data_type.id().clone().into(), provenance_metadata, fetched_ontology_type.fetched_at, ); @@ -255,7 +255,7 @@ where .await? { let metadata = ExternalOntologyElementMetadata::new( - property_type.id().into(), + property_type.id().clone().into(), provenance_metadata, fetched_ontology_type.fetched_at, ); @@ -277,7 +277,7 @@ where .await? { let metadata = ExternalOntologyElementMetadata::new( - entity_type.id().into(), + entity_type.id().clone().into(), provenance_metadata, fetched_ontology_type.fetched_at, ); diff --git a/apps/hash-graph/lib/graph/src/store/postgres.rs b/apps/hash-graph/lib/graph/src/store/postgres.rs index 77a671a9f76..a9bb8818729 100644 --- a/apps/hash-graph/lib/graph/src/store/postgres.rs +++ b/apps/hash-graph/lib/graph/src/store/postgres.rs @@ -283,7 +283,7 @@ where .change_context(InsertionError), _ => report .change_context(InsertionError) - .attach_printable(VersionedUri::from(metadata.record_id())), + .attach_printable(VersionedUri::from(metadata.record_id().clone())), }) } @@ -325,7 +325,7 @@ where .change_context(InsertionError), _ => report .change_context(InsertionError) - .attach_printable(VersionedUri::from(metadata.record_id())), + .attach_printable(VersionedUri::from(metadata.record_id().clone())), }) } @@ -355,8 +355,8 @@ where record_created_by_id := $3 );"#, &[ - &uri.base_uri().as_str(), - &i64::from(uri.version()), + &uri.base_uri.as_str(), + &i64::from(uri.version), &updated_by_id, ], ) @@ -373,7 +373,7 @@ where .change_context(UpdateError), Some(&SqlState::RESTRICT_VIOLATION) => report .change_context(BaseUriDoesNotExist) - .attach_printable(uri.base_uri().clone()) + .attach_printable(uri.base_uri.clone()) .change_context(UpdateError), _ => report .change_context(UpdateError) @@ -439,7 +439,7 @@ where T::Representation: Send, { let uri = database_type.id(); - let record_id = OntologyTypeRecordId::from(uri); + let record_id = OntologyTypeRecordId::from(uri.clone()); let (ontology_id, owned_by_id) = self .update_owned_ontology_id(uri, updated_by_id) @@ -679,7 +679,7 @@ where /// - if the entry referred to by `uri` does not exist. #[tracing::instrument(level = "debug", skip(self))] async fn ontology_id_by_uri(&self, uri: &VersionedUri) -> Result { - let version = i64::from(uri.version()); + let version = i64::from(uri.version); Ok(self .client .as_client() @@ -689,7 +689,7 @@ where FROM ontology_ids WHERE base_uri = $1 AND version = $2; "#, - &[&uri.base_uri().as_str(), &version], + &[&uri.base_uri.as_str(), &version], ) .await .into_report() diff --git a/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity.rs b/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity.rs index a93ee86102c..191010a5a2f 100644 --- a/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity.rs +++ b/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity.rs @@ -100,7 +100,7 @@ impl PostgresStore { if current_resolve_depths.is_of_type.outgoing > 0 { let entity_type_id = - OntologyTypeVertexId::from(entity.metadata().entity_type_id()); + OntologyTypeVertexId::from(entity.metadata().entity_type_id().clone()); subgraph.edges.insert(Edge::KnowledgeGraph { vertex_id: entity_vertex_id, outward_edge: KnowledgeGraphOutwardEdges::ToOntology(OutwardEdge { diff --git a/apps/hash-graph/lib/graph/src/store/postgres/ontology/entity_type.rs b/apps/hash-graph/lib/graph/src/store/postgres/ontology/entity_type.rs index 57e2dcfe8ae..3b43b2a5ae7 100644 --- a/apps/hash-graph/lib/graph/src/store/postgres/ontology/entity_type.rs +++ b/apps/hash-graph/lib/graph/src/store/postgres/ontology/entity_type.rs @@ -112,17 +112,19 @@ impl PostgresStore { if let Some(property_type_ref_uris) = property_type_ref_uris { for property_type_ref_uri in property_type_ref_uris { + let property_type_vertex_id = OntologyTypeVertexId::from(property_type_ref_uri); + subgraph.edges.insert(Edge::Ontology { vertex_id: entity_type_id.clone(), outward_edge: OntologyOutwardEdges::ToOntology(OutwardEdge { kind: OntologyEdgeKind::ConstrainsPropertiesOn, reversed: false, - right_endpoint: OntologyTypeVertexId::from(&property_type_ref_uri), + right_endpoint: property_type_vertex_id.clone(), }), }); self.traverse_property_type( - &OntologyTypeVertexId::from(&property_type_ref_uri), + &property_type_vertex_id, dependency_context, subgraph, GraphResolveDepths { @@ -141,17 +143,20 @@ impl PostgresStore { if let Some(inherits_from_type_ref_uris) = inherits_from_type_ref_uris { for inherits_from_type_ref_uri in inherits_from_type_ref_uris { + let inherits_from_type_vertex_id = + OntologyTypeVertexId::from(inherits_from_type_ref_uri); + subgraph.edges.insert(Edge::Ontology { vertex_id: entity_type_id.clone(), outward_edge: OntologyOutwardEdges::ToOntology(OutwardEdge { kind: OntologyEdgeKind::InheritsFrom, reversed: false, - right_endpoint: OntologyTypeVertexId::from(&inherits_from_type_ref_uri), + right_endpoint: inherits_from_type_vertex_id.clone(), }), }); self.traverse_entity_type( - &OntologyTypeVertexId::from(&inherits_from_type_ref_uri), + &inherits_from_type_vertex_id, dependency_context, subgraph, GraphResolveDepths { @@ -170,17 +175,19 @@ impl PostgresStore { if let Some(link_mappings) = link_mappings { for (link_type_uri, destination_type_uris) in link_mappings { if current_resolve_depths.constrains_links_on.outgoing > 0 { + let link_type_vertex_id = OntologyTypeVertexId::from(link_type_uri); + subgraph.edges.insert(Edge::Ontology { vertex_id: entity_type_id.clone(), outward_edge: OntologyOutwardEdges::ToOntology(OutwardEdge { kind: OntologyEdgeKind::ConstrainsLinksOn, reversed: false, - right_endpoint: OntologyTypeVertexId::from(&link_type_uri), + right_endpoint: link_type_vertex_id.clone(), }), }); self.traverse_entity_type( - &OntologyTypeVertexId::from(&link_type_uri), + &link_type_vertex_id, dependency_context, subgraph, GraphResolveDepths { @@ -201,19 +208,20 @@ impl PostgresStore { > 0 { for destination_type_uri in destination_type_uris { + let destination_type_vertex_id = + OntologyTypeVertexId::from(destination_type_uri); + subgraph.edges.insert(Edge::Ontology { vertex_id: entity_type_id.clone(), outward_edge: OntologyOutwardEdges::ToOntology(OutwardEdge { kind: OntologyEdgeKind::ConstrainsLinkDestinationsOn, reversed: false, - right_endpoint: OntologyTypeVertexId::from( - &destination_type_uri, - ), + right_endpoint: destination_type_vertex_id.clone(), }), }); self.traverse_entity_type( - &OntologyTypeVertexId::from(&destination_type_uri), + &destination_type_vertex_id, dependency_context, subgraph, GraphResolveDepths { diff --git a/apps/hash-graph/lib/graph/src/store/postgres/ontology/property_type.rs b/apps/hash-graph/lib/graph/src/store/postgres/ontology/property_type.rs index 67535989411..c77cbef56af 100644 --- a/apps/hash-graph/lib/graph/src/store/postgres/ontology/property_type.rs +++ b/apps/hash-graph/lib/graph/src/store/postgres/ontology/property_type.rs @@ -88,17 +88,19 @@ impl PostgresStore { if let Some(data_type_ref_uris) = data_type_ref_uris { for data_type_ref in data_type_ref_uris { + let data_type_vertex_id = OntologyTypeVertexId::from(data_type_ref); + subgraph.edges.insert(Edge::Ontology { vertex_id: property_type_id.clone(), outward_edge: OntologyOutwardEdges::ToOntology(OutwardEdge { kind: OntologyEdgeKind::ConstrainsValuesOn, reversed: false, - right_endpoint: OntologyTypeVertexId::from(&data_type_ref), + right_endpoint: data_type_vertex_id.clone(), }), }); self.traverse_data_type( - &OntologyTypeVertexId::from(&data_type_ref), + &data_type_vertex_id, dependency_context, subgraph, GraphResolveDepths { @@ -116,17 +118,19 @@ impl PostgresStore { if let Some(property_type_ref_uris) = property_type_ref_uris { for property_type_ref_uri in property_type_ref_uris { + let property_type_vertex_id = OntologyTypeVertexId::from(property_type_ref_uri); + subgraph.edges.insert(Edge::Ontology { vertex_id: property_type_id.clone(), outward_edge: OntologyOutwardEdges::ToOntology(OutwardEdge { kind: OntologyEdgeKind::ConstrainsPropertiesOn, reversed: false, - right_endpoint: OntologyTypeVertexId::from(&property_type_ref_uri), + right_endpoint: property_type_vertex_id.clone(), }), }); self.traverse_property_type( - &OntologyTypeVertexId::from(&property_type_ref_uri), + &property_type_vertex_id, dependency_context, subgraph, GraphResolveDepths { diff --git a/apps/hash-graph/lib/graph/src/store/postgres/query/statement/select.rs b/apps/hash-graph/lib/graph/src/store/postgres/query/statement/select.rs index dbc026feddf..7dd53015be9 100644 --- a/apps/hash-graph/lib/graph/src/store/postgres/query/statement/select.rs +++ b/apps/hash-graph/lib/graph/src/store/postgres/query/statement/select.rs @@ -775,13 +775,13 @@ mod tests { #[test] fn for_versioned_uri() { - let uri = VersionedUri::new( - BaseUri::new( + let uri = VersionedUri { + base_uri: BaseUri::new( "https://blockprotocol.org/@blockprotocol/types/data-type/text/".to_owned(), ) .expect("invalid base uri"), - 1, - ); + version: 1, + }; let time_projection = UnresolvedTimeProjection::default().resolve(); let mut compiler = @@ -800,8 +800,8 @@ mod tests { WHERE ("ontology_id_with_metadata_0_1_0"."base_uri" = $1) AND ("ontology_id_with_metadata_0_1_0"."version" = $2) "#, &[ - &uri.base_uri().as_str(), - &OntologyTypeVersion::new(uri.version()), + &uri.base_uri.as_str(), + &OntologyTypeVersion::new(uri.version), ], ); } diff --git a/apps/hash-graph/lib/graph/src/store/query/filter.rs b/apps/hash-graph/lib/graph/src/store/query/filter.rs index c6cc33c35ce..e33eac84f7f 100644 --- a/apps/hash-graph/lib/graph/src/store/query/filter.rs +++ b/apps/hash-graph/lib/graph/src/store/query/filter.rs @@ -87,8 +87,8 @@ where #[must_use] pub fn for_versioned_uri(versioned_uri: &'p VersionedUri) -> Self { Self::All(vec![ - Self::for_base_uri(versioned_uri.base_uri()), - Self::for_version(OntologyTypeVersion::new(versioned_uri.version())), + Self::for_base_uri(&versioned_uri.base_uri), + Self::for_version(OntologyTypeVersion::new(versioned_uri.version)), ]) } @@ -440,23 +440,23 @@ mod tests { #[test] fn for_versioned_uri() { - let uri = VersionedUri::new( - BaseUri::new( + let uri = VersionedUri { + base_uri: BaseUri::new( "https://blockprotocol.org/@blockprotocol/types/data-type/text/".to_owned(), ) .expect("invalid base uri"), - 1, - ); + version: 1, + }; let expected = json! {{ "all": [ { "equal": [ { "path": ["baseUri"] }, - { "parameter": uri.base_uri() } + { "parameter": uri.base_uri } ]}, { "equal": [ { "path": ["version"] }, - { "parameter": uri.version() } + { "parameter": uri.version } ]} ] }}; diff --git a/apps/hash-graph/lib/type-fetcher/Cargo.toml b/apps/hash-graph/lib/type-fetcher/Cargo.toml index d571a915528..7af5a95a950 100644 --- a/apps/hash-graph/lib/type-fetcher/Cargo.toml +++ b/apps/hash-graph/lib/type-fetcher/Cargo.toml @@ -7,7 +7,7 @@ description = "RPC service definition to fetch external BP types" [dependencies] error-stack = { version = "0.3.1", features = ["spantrace"] } -type-system = { git = "https://github.com/blockprotocol/blockprotocol", rev = "646b7d1" } +type-system = { git = "https://github.com/blockprotocol/blockprotocol", rev = "ce8df71" } serde = { version = "1.0.152", features = ["derive"] } serde_json = "1.0.91" diff --git a/apps/hash-graph/tests/integration/Cargo.toml b/apps/hash-graph/tests/integration/Cargo.toml index 1fae402d341..7b71ea5577f 100644 --- a/apps/hash-graph/tests/integration/Cargo.toml +++ b/apps/hash-graph/tests/integration/Cargo.toml @@ -16,7 +16,7 @@ serde_json = "1.0.91" time = "0.3.17" tokio = { version = "1.25.0", features = ["rt-multi-thread", "macros"] } tokio-postgres = { version = "0.7.7", default-features = false } -type-system = { git = "https://github.com/blockprotocol/blockprotocol", rev = "646b7d1" } +type-system = { git = "https://github.com/blockprotocol/blockprotocol", rev = "ce8df71" } uuid = { version = "1.3.0", features = ["v4", "serde"] } [[test]] diff --git a/apps/hash-graph/tests/integration/postgres/entity.rs b/apps/hash-graph/tests/integration/postgres/entity.rs index b983a77f3dc..aa7eab3aa97 100644 --- a/apps/hash-graph/tests/integration/postgres/entity.rs +++ b/apps/hash-graph/tests/integration/postgres/entity.rs @@ -22,13 +22,13 @@ async fn insert() { let metadata = api .create_entity( person.clone(), - VersionedUri::new( - BaseUri::new( + VersionedUri { + base_uri: BaseUri::new( "https://blockprotocol.org/@alice/types/entity-type/person/".to_owned(), ) .expect("couldn't construct Base URI"), - 1, - ), + version: 1, + }, None, ) .await @@ -59,13 +59,13 @@ async fn query() { let metadata = api .create_entity( organization.clone(), - VersionedUri::new( - BaseUri::new( + VersionedUri { + base_uri: BaseUri::new( "https://blockprotocol.org/@alice/types/entity-type/organization/".to_owned(), ) .expect("couldn't construct Base URI"), - 1, - ), + version: 1, + }, None, ) .await @@ -98,11 +98,13 @@ async fn update() { let v1_metadata = api .create_entity( page_v1.clone(), - VersionedUri::new( - BaseUri::new("https://blockprotocol.org/@alice/types/entity-type/page/".to_owned()) - .expect("couldn't construct Base URI"), - 1, - ), + VersionedUri { + base_uri: BaseUri::new( + "https://blockprotocol.org/@alice/types/entity-type/page/".to_owned(), + ) + .expect("couldn't construct Base URI"), + version: 1, + }, None, ) .await @@ -112,11 +114,13 @@ async fn update() { .update_entity( v1_metadata.record_id().entity_id(), page_v2.clone(), - VersionedUri::new( - BaseUri::new("https://blockprotocol.org/@alice/types/entity-type/page/".to_owned()) - .expect("couldn't construct Base URI"), - 1, - ), + VersionedUri { + base_uri: BaseUri::new( + "https://blockprotocol.org/@alice/types/entity-type/page/".to_owned(), + ) + .expect("couldn't construct Base URI"), + version: 1, + }, EntityLinkOrder::new(None, None), ) .await diff --git a/apps/hash-graph/tests/integration/postgres/lib.rs b/apps/hash-graph/tests/integration/postgres/lib.rs index a04817b9cb7..09ca41b123f 100644 --- a/apps/hash-graph/tests/integration/postgres/lib.rs +++ b/apps/hash-graph/tests/integration/postgres/lib.rs @@ -123,7 +123,7 @@ impl DatabaseTestWrapper { let data_type = DataType::try_from(data_type_repr).expect("could not parse data type"); let metadata = OntologyElementMetadata::Owned(OwnedOntologyElementMetadata::new( - data_type.id().into(), + data_type.id().clone().into(), ProvenanceMetadata::new(UpdatedById::new(account_id)), OwnedById::new(account_id), )); @@ -139,7 +139,7 @@ impl DatabaseTestWrapper { PropertyType::try_from(property_type_repr).expect("could not parse property type"); let metadata = OntologyElementMetadata::Owned(OwnedOntologyElementMetadata::new( - property_type.id().into(), + property_type.id().clone().into(), ProvenanceMetadata::new(UpdatedById::new(account_id)), OwnedById::new(account_id), )); @@ -155,7 +155,7 @@ impl DatabaseTestWrapper { EntityType::try_from(entity_type_repr).expect("could not parse entity type"); let metadata = OntologyElementMetadata::Owned(OwnedOntologyElementMetadata::new( - entity_type.id().into(), + entity_type.id().clone().into(), ProvenanceMetadata::new(UpdatedById::new(account_id)), OwnedById::new(account_id), )); @@ -188,7 +188,7 @@ impl DatabaseApi<'_> { data_type: DataType, ) -> Result { let metadata = OntologyElementMetadata::Owned(OwnedOntologyElementMetadata::new( - data_type.id().into(), + data_type.id().clone().into(), ProvenanceMetadata::new(UpdatedById::new(self.account_id)), OwnedById::new(self.account_id), )); @@ -215,7 +215,7 @@ impl DatabaseApi<'_> { .await? .vertices .data_types - .remove(&OntologyTypeVertexId::from(uri)) + .remove(&OntologyTypeVertexId::from(uri.clone())) .expect("no data type found")) } @@ -233,7 +233,7 @@ impl DatabaseApi<'_> { property_type: PropertyType, ) -> Result { let metadata = OntologyElementMetadata::Owned(OwnedOntologyElementMetadata::new( - property_type.id().into(), + property_type.id().clone().into(), ProvenanceMetadata::new(UpdatedById::new(self.account_id)), OwnedById::new(self.account_id), )); @@ -262,7 +262,7 @@ impl DatabaseApi<'_> { .await? .vertices .property_types - .remove(&OntologyTypeVertexId::from(uri)) + .remove(&OntologyTypeVertexId::from(uri.clone())) .expect("no property type found")) } @@ -280,7 +280,7 @@ impl DatabaseApi<'_> { entity_type: EntityType, ) -> Result { let metadata = OntologyElementMetadata::Owned(OwnedOntologyElementMetadata::new( - entity_type.id().into(), + entity_type.id().clone().into(), ProvenanceMetadata::new(UpdatedById::new(self.account_id)), OwnedById::new(self.account_id), )); @@ -309,7 +309,7 @@ impl DatabaseApi<'_> { .await? .vertices .entity_types - .remove(&OntologyTypeVertexId::from(uri)) + .remove(&OntologyTypeVertexId::from(uri.clone())) .expect("no entity type found")) } @@ -476,7 +476,7 @@ impl DatabaseApi<'_> { EntityTypeQueryPath::BaseUri, ))), Some(FilterExpression::Parameter(Parameter::Text(Cow::Borrowed( - link_type_id.base_uri().as_str(), + link_type_id.base_uri.as_str(), )))), ), Filter::Equal( @@ -484,7 +484,7 @@ impl DatabaseApi<'_> { EntityTypeQueryPath::Version, ))), Some(FilterExpression::Parameter(Parameter::OntologyTypeVersion( - OntologyTypeVersion::new(link_type_id.version()), + OntologyTypeVersion::new(link_type_id.version), ))), ), ]); diff --git a/apps/hash-graph/tests/integration/postgres/links.rs b/apps/hash-graph/tests/integration/postgres/links.rs index 60ab90b08c9..77d554beef9 100644 --- a/apps/hash-graph/tests/integration/postgres/links.rs +++ b/apps/hash-graph/tests/integration/postgres/links.rs @@ -20,11 +20,13 @@ async fn insert() { .await .expect("could not seed database"); - let person_type_id = VersionedUri::new( - BaseUri::new("https://blockprotocol.org/@alice/types/entity-type/person/".to_owned()) - .expect("couldn't construct Base URI"), - 1, - ); + let person_type_id = VersionedUri { + base_uri: BaseUri::new( + "https://blockprotocol.org/@alice/types/entity-type/person/".to_owned(), + ) + .expect("couldn't construct Base URI"), + version: 1, + }; let alice_metadata = api .create_entity(alice, person_type_id.clone(), None) @@ -36,11 +38,13 @@ async fn insert() { .await .expect("could not create entity"); - let friend_of_type_id = VersionedUri::new( - BaseUri::new("https://blockprotocol.org/@alice/types/entity-type/friend-of/".to_owned()) - .expect("couldn't construct Base URI"), - 1, - ); + let friend_of_type_id = VersionedUri { + base_uri: BaseUri::new( + "https://blockprotocol.org/@alice/types/entity-type/friend-of/".to_owned(), + ) + .expect("couldn't construct Base URI"), + version: 1, + }; api.create_link_entity( friend_of, @@ -85,25 +89,29 @@ async fn get_entity_links() { .await .expect("could not seed database"); - let person_type_id = VersionedUri::new( - BaseUri::new("https://blockprotocol.org/@alice/types/entity-type/person/".to_owned()) - .expect("couldn't construct Base URI"), - 1, - ); + let person_type_id = VersionedUri { + base_uri: BaseUri::new( + "https://blockprotocol.org/@alice/types/entity-type/person/".to_owned(), + ) + .expect("couldn't construct Base URI"), + version: 1, + }; - let friend_link_type_id = VersionedUri::new( - BaseUri::new("https://blockprotocol.org/@alice/types/entity-type/friend-of/".to_owned()) - .expect("couldn't construct Base URI"), - 1, - ); + let friend_link_type_id = VersionedUri { + base_uri: BaseUri::new( + "https://blockprotocol.org/@alice/types/entity-type/friend-of/".to_owned(), + ) + .expect("couldn't construct Base URI"), + version: 1, + }; - let acquaintance_entity_link_type_id = VersionedUri::new( - BaseUri::new( + let acquaintance_entity_link_type_id = VersionedUri { + base_uri: BaseUri::new( "https://blockprotocol.org/@alice/types/entity-type/acquaintance-of/".to_owned(), ) .expect("couldn't construct Base URI"), - 1, - ); + version: 1, + }; let alice_metadata = api .create_entity(alice, person_type_id.clone(), None) @@ -193,17 +201,21 @@ async fn remove_link() { .await .expect("could not seed database"); - let person_type_id = VersionedUri::new( - BaseUri::new("https://blockprotocol.org/@alice/types/entity-type/person/".to_owned()) - .expect("couldn't construct Base URI"), - 1, - ); + let person_type_id = VersionedUri { + base_uri: BaseUri::new( + "https://blockprotocol.org/@alice/types/entity-type/person/".to_owned(), + ) + .expect("couldn't construct Base URI"), + version: 1, + }; - let friend_link_type_id = VersionedUri::new( - BaseUri::new("https://blockprotocol.org/@alice/types/entity-type/friend-of/".to_owned()) - .expect("couldn't construct Base URI"), - 1, - ); + let friend_link_type_id = VersionedUri { + base_uri: BaseUri::new( + "https://blockprotocol.org/@alice/types/entity-type/friend-of/".to_owned(), + ) + .expect("couldn't construct Base URI"), + version: 1, + }; let alice_metadata = api .create_entity(alice, person_type_id.clone(), None) From 75af1f5f10375be0649bb5237f1526864cc21f5f Mon Sep 17 00:00:00 2001 From: Tim Diekmann Date: Thu, 16 Feb 2023 21:53:08 +0100 Subject: [PATCH 03/19] Make fields on `*RecordId` pub --- .../read_scaling/knowledge/complete/entity.rs | 6 +-- .../read_scaling/knowledge/linkless/entity.rs | 2 +- .../bench/representative_read/seed.rs | 4 +- .../lib/graph/src/knowledge/entity.rs | 2 +- apps/hash-graph/lib/graph/src/ontology.rs | 6 +-- .../graph/src/shared/identifier/knowledge.rs | 24 +---------- .../graph/src/shared/identifier/ontology.rs | 24 +---------- .../lib/graph/src/store/postgres.rs | 12 +++--- .../src/store/postgres/knowledge/entity.rs | 25 ++++++++---- .../store/postgres/knowledge/entity/read.rs | 8 ++-- .../graph/src/store/postgres/ontology/read.rs | 2 +- .../tests/integration/postgres/entity.rs | 14 +++---- .../tests/integration/postgres/links.rs | 40 +++++++++---------- 13 files changed, 69 insertions(+), 100 deletions(-) diff --git a/apps/hash-graph/bench/read_scaling/knowledge/complete/entity.rs b/apps/hash-graph/bench/read_scaling/knowledge/complete/entity.rs index 251a9f63484..8067fe856fe 100644 --- a/apps/hash-graph/bench/read_scaling/knowledge/complete/entity.rs +++ b/apps/hash-graph/bench/read_scaling/knowledge/complete/entity.rs @@ -106,8 +106,8 @@ async fn seed_db( None, properties.clone(), Some(LinkData::new( - entity_a_metadata.record_id().entity_id(), - entity_b_metadata.record_id().entity_id(), + entity_a_metadata.record_id().entity_id, + entity_b_metadata.record_id().entity_id, None, None, )), @@ -161,7 +161,7 @@ pub fn bench_get_entity_by_id( |entity_record_id| async move { store .get_entity(&StructuralQuery { - filter: Filter::for_entity_by_entity_id(entity_record_id.entity_id()), + filter: Filter::for_entity_by_entity_id(entity_record_id.entity_id), graph_resolve_depths, time_projection: UnresolvedTimeProjection::DecisionTime(UnresolvedProjection { pinned: UnresolvedKernel::new(None), diff --git a/apps/hash-graph/bench/read_scaling/knowledge/linkless/entity.rs b/apps/hash-graph/bench/read_scaling/knowledge/linkless/entity.rs index 0346822c825..86ad860e99a 100644 --- a/apps/hash-graph/bench/read_scaling/knowledge/linkless/entity.rs +++ b/apps/hash-graph/bench/read_scaling/knowledge/linkless/entity.rs @@ -115,7 +115,7 @@ pub fn bench_get_entity_by_id( |entity_record_id| async move { store .get_entity(&StructuralQuery { - filter: Filter::for_entity_by_entity_id(entity_record_id.entity_id()), + filter: Filter::for_entity_by_entity_id(entity_record_id.entity_id), graph_resolve_depths: GraphResolveDepths::default(), time_projection: UnresolvedTimeProjection::DecisionTime(UnresolvedProjection { pinned: UnresolvedKernel::new(None), diff --git a/apps/hash-graph/bench/representative_read/seed.rs b/apps/hash-graph/bench/representative_read/seed.rs index 44d4f76ec10..dedd65d5e54 100644 --- a/apps/hash-graph/bench/representative_read/seed.rs +++ b/apps/hash-graph/bench/representative_read/seed.rs @@ -181,8 +181,8 @@ async fn seed_db(account_id: AccountId, store_wrapper: &mut StoreWrapper) { None, EntityProperties::empty(), Some(LinkData::new( - left_entity_metadata.record_id().entity_id(), - right_entity_metadata.record_id().entity_id(), + left_entity_metadata.record_id().entity_id, + right_entity_metadata.record_id().entity_id, None, None, )), diff --git a/apps/hash-graph/lib/graph/src/knowledge/entity.rs b/apps/hash-graph/lib/graph/src/knowledge/entity.rs index 3805f242041..1bcf73402d3 100644 --- a/apps/hash-graph/lib/graph/src/knowledge/entity.rs +++ b/apps/hash-graph/lib/graph/src/knowledge/entity.rs @@ -286,7 +286,7 @@ impl Record for Entity { TimeAxis::DecisionTime => self.metadata().version().decision_time.start().cast(), TimeAxis::TransactionTime => self.metadata().version().transaction_time.start().cast(), }; - EntityVertexId::new(self.metadata().record_id().entity_id(), timestamp.into()) + EntityVertexId::new(self.metadata().record_id().entity_id, timestamp.into()) } fn create_filter_for_vertex_id(vertex_id: &Self::VertexId) -> Filter { diff --git a/apps/hash-graph/lib/graph/src/ontology.rs b/apps/hash-graph/lib/graph/src/ontology.rs index ccd1f986638..d656532cbe9 100644 --- a/apps/hash-graph/lib/graph/src/ontology.rs +++ b/apps/hash-graph/lib/graph/src/ontology.rs @@ -292,7 +292,7 @@ impl Record for DataTypeWithMetadata { fn vertex_id(&self, _time_axis: TimeAxis) -> Self::VertexId { let record_id = self.metadata().record_id(); - OntologyTypeVertexId::new(record_id.base_uri().clone(), record_id.version()) + OntologyTypeVertexId::new(record_id.base_uri.clone(), record_id.version) } fn create_filter_for_vertex_id(vertex_id: &Self::VertexId) -> Filter { @@ -333,7 +333,7 @@ impl Record for PropertyTypeWithMetadata { fn vertex_id(&self, _time_axis: TimeAxis) -> Self::VertexId { let record_id = self.metadata().record_id(); - OntologyTypeVertexId::new(record_id.base_uri().clone(), record_id.version()) + OntologyTypeVertexId::new(record_id.base_uri.clone(), record_id.version) } fn create_filter_for_vertex_id(vertex_id: &Self::VertexId) -> Filter { @@ -374,7 +374,7 @@ impl Record for EntityTypeWithMetadata { fn vertex_id(&self, _time_axis: TimeAxis) -> Self::VertexId { let record_id = self.metadata().record_id(); - OntologyTypeVertexId::new(record_id.base_uri().clone(), record_id.version()) + OntologyTypeVertexId::new(record_id.base_uri.clone(), record_id.version) } fn create_filter_for_vertex_id(vertex_id: &Self::VertexId) -> Filter { diff --git a/apps/hash-graph/lib/graph/src/shared/identifier/knowledge.rs b/apps/hash-graph/lib/graph/src/shared/identifier/knowledge.rs index 2925ea7a0e1..88862cf8a52 100644 --- a/apps/hash-graph/lib/graph/src/shared/identifier/knowledge.rs +++ b/apps/hash-graph/lib/graph/src/shared/identifier/knowledge.rs @@ -150,8 +150,8 @@ impl EntityEditionId { #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Serialize, ToSchema)] #[serde(rename_all = "camelCase")] pub struct EntityRecordId { - entity_id: EntityId, - edition_id: EntityEditionId, + pub entity_id: EntityId, + pub edition_id: EntityEditionId, } impl SubgraphIndex for EntityVertexId { @@ -162,23 +162,3 @@ impl SubgraphIndex for EntityVertexId { subgraph.vertices.entities.raw_entry_mut().from_key(self) } } - -impl EntityRecordId { - #[must_use] - pub const fn new(entity_id: EntityId, edition_id: EntityEditionId) -> Self { - Self { - entity_id, - edition_id, - } - } - - #[must_use] - pub const fn entity_id(&self) -> EntityId { - self.entity_id - } - - #[must_use] - pub const fn edition_id(&self) -> EntityEditionId { - self.edition_id - } -} diff --git a/apps/hash-graph/lib/graph/src/shared/identifier/ontology.rs b/apps/hash-graph/lib/graph/src/shared/identifier/ontology.rs index 95cf66add88..0c48a6e1aff 100644 --- a/apps/hash-graph/lib/graph/src/shared/identifier/ontology.rs +++ b/apps/hash-graph/lib/graph/src/shared/identifier/ontology.rs @@ -59,29 +59,9 @@ impl<'a> FromSql<'a> for OntologyTypeVersion { #[serde(rename_all = "camelCase")] pub struct OntologyTypeRecordId { #[schema(value_type = String)] - base_uri: BaseUri, + pub base_uri: BaseUri, #[schema(value_type = u32)] - version: OntologyTypeVersion, -} - -impl OntologyTypeRecordId { - #[must_use] - pub const fn new(base_id: BaseUri, version: OntologyTypeVersion) -> Self { - Self { - base_uri: base_id, - version, - } - } - - #[must_use] - pub const fn base_uri(&self) -> &BaseUri { - &self.base_uri - } - - #[must_use] - pub const fn version(&self) -> OntologyTypeVersion { - self.version - } + pub version: OntologyTypeVersion, } impl Display for OntologyTypeRecordId { diff --git a/apps/hash-graph/lib/graph/src/store/postgres.rs b/apps/hash-graph/lib/graph/src/store/postgres.rs index a9bb8818729..3e4a3749705 100644 --- a/apps/hash-graph/lib/graph/src/store/postgres.rs +++ b/apps/hash-graph/lib/graph/src/store/postgres.rs @@ -267,8 +267,8 @@ where record_created_by_id := $4 );"#, &[ - &metadata.record_id().base_uri().as_str(), - &metadata.record_id().version(), + &metadata.record_id().base_uri.as_str(), + &metadata.record_id().version, &metadata.owned_by_id(), &metadata.provenance_metadata().updated_by_id(), ], @@ -279,7 +279,7 @@ where .map_err(|report| match report.current_context().code() { Some(&SqlState::EXCLUSION_VIOLATION | &SqlState::UNIQUE_VIOLATION) => report .change_context(BaseUriAlreadyExists) - .attach_printable(metadata.record_id().base_uri().clone()) + .attach_printable(metadata.record_id().base_uri.clone()) .change_context(InsertionError), _ => report .change_context(InsertionError) @@ -309,8 +309,8 @@ where record_created_by_id := $4 );"#, &[ - &metadata.record_id().base_uri().as_str(), - &metadata.record_id().version(), + &metadata.record_id().base_uri.as_str(), + &metadata.record_id().version, &metadata.fetched_at(), &metadata.provenance_metadata().updated_by_id(), ], @@ -321,7 +321,7 @@ where .map_err(|report| match report.current_context().code() { Some(&SqlState::EXCLUSION_VIOLATION | &SqlState::UNIQUE_VIOLATION) => report .change_context(BaseUriAlreadyExists) - .attach_printable(metadata.record_id().base_uri().clone()) + .attach_printable(metadata.record_id().base_uri.clone()) .change_context(InsertionError), _ => report .change_context(InsertionError) diff --git a/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity.rs b/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity.rs index 191010a5a2f..9955710051a 100644 --- a/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity.rs +++ b/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity.rs @@ -141,7 +141,7 @@ impl PostgresStore { // outgoing link `Entity` kind: KnowledgeGraphEdgeKind::HasLeftEntity, reversed: true, - right_endpoint: outgoing_link_entity.metadata().record_id().entity_id(), + right_endpoint: outgoing_link_entity.metadata().record_id().entity_id, }), }); @@ -180,7 +180,7 @@ impl PostgresStore { // incoming link `Entity` kind: KnowledgeGraphEdgeKind::HasRightEntity, reversed: true, - right_endpoint: incoming_link_entity.metadata().record_id().entity_id(), + right_endpoint: incoming_link_entity.metadata().record_id().entity_id, }), }); @@ -219,7 +219,7 @@ impl PostgresStore { // outgoing `Link` `Entity` kind: KnowledgeGraphEdgeKind::HasLeftEntity, reversed: false, - right_endpoint: left_entity.metadata().record_id().entity_id(), + right_endpoint: left_entity.metadata().record_id().entity_id, }), }); @@ -258,7 +258,7 @@ impl PostgresStore { // outgoing `Link` `Entity` kind: KnowledgeGraphEdgeKind::HasRightEntity, reversed: false, - right_endpoint: right_entity.metadata().record_id().entity_id(), + right_endpoint: right_entity.metadata().record_id().entity_id, }), }); @@ -370,7 +370,10 @@ impl EntityStore for PostgresStore { .change_context(InsertionError)?; Ok(EntityMetadata::new( - EntityRecordId::new(entity_id, EntityEditionId::new(row.get(0))), + EntityRecordId { + entity_id, + edition_id: EntityEditionId::new(row.get(0)), + }, EntityVersion { decision_time: row.get(1), transaction_time: row.get(2), @@ -458,9 +461,12 @@ impl EntityStore for PostgresStore { .into_iter() .zip(entity_versions) .zip(entity_edition_ids) - .map(|(((entity_id, ..), entity_version), entity_edition_id)| { + .map(|(((entity_id, ..), entity_version), edition_id)| { EntityMetadata::new( - EntityRecordId::new(entity_id, entity_edition_id), + EntityRecordId { + entity_id, + edition_id, + }, entity_version, entity_type_id.clone(), ProvenanceMetadata::new(actor_id), @@ -598,7 +604,10 @@ impl EntityStore for PostgresStore { transaction.commit().await.change_context(UpdateError)?; Ok(EntityMetadata::new( - EntityRecordId::new(entity_id, EntityEditionId::new(row.get(0))), + EntityRecordId { + entity_id, + edition_id: EntityEditionId::new(row.get(0)), + }, EntityVersion { decision_time: row.get(1), transaction_time: row.get(2), diff --git a/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity/read.rs b/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity/read.rs index 56b10cf7b35..49a6c857181 100644 --- a/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity/read.rs +++ b/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity/read.rs @@ -135,10 +135,10 @@ impl crud::Read for PostgresStore { Ok(Entity::new( properties, link_data, - EntityRecordId::new( - EntityId::new(owned_by_id, entity_uuid), - EntityEditionId::new(row.get(edition_id_index)), - ), + EntityRecordId { + entity_id: EntityId::new(owned_by_id, entity_uuid), + edition_id: EntityEditionId::new(row.get(edition_id_index)), + }, EntityVersion { decision_time: row.get(decision_time_index), transaction_time: row.get(transaction_time_index), diff --git a/apps/hash-graph/lib/graph/src/store/postgres/ontology/read.rs b/apps/hash-graph/lib/graph/src/store/postgres/ontology/read.rs index 14ae864791f..0ca51c83c36 100644 --- a/apps/hash-graph/lib/graph/src/store/postgres/ontology/read.rs +++ b/apps/hash-graph/lib/graph/src/store/postgres/ontology/read.rs @@ -113,7 +113,7 @@ where .into_report() .change_context(QueryError)?; - let record_id = OntologyTypeRecordId::new(base_uri, version); + let record_id = OntologyTypeRecordId { base_uri, version }; let provenance = ProvenanceMetadata::new(updated_by_id); Ok(T::new(record, match metadata { diff --git a/apps/hash-graph/tests/integration/postgres/entity.rs b/apps/hash-graph/tests/integration/postgres/entity.rs index aa7eab3aa97..879e142ef06 100644 --- a/apps/hash-graph/tests/integration/postgres/entity.rs +++ b/apps/hash-graph/tests/integration/postgres/entity.rs @@ -35,7 +35,7 @@ async fn insert() { .expect("could not create entity"); let entities = api - .get_entities(metadata.record_id().entity_id()) + .get_entities(metadata.record_id().entity_id) .await .expect("could not get entity"); assert_eq!(entities.len(), 1); @@ -72,7 +72,7 @@ async fn query() { .expect("could not create entity"); let queried_organizations = api - .get_entities(metadata.record_id().entity_id()) + .get_entities(metadata.record_id().entity_id) .await .expect("could not get entity"); assert_eq!(queried_organizations.len(), 1); @@ -112,7 +112,7 @@ async fn update() { let v2_metadata = api .update_entity( - v1_metadata.record_id().entity_id(), + v1_metadata.record_id().entity_id, page_v2.clone(), VersionedUri { base_uri: BaseUri::new( @@ -127,14 +127,14 @@ async fn update() { .expect("could not update entity"); let entities = api - .get_entities(v2_metadata.record_id().entity_id()) + .get_entities(v2_metadata.record_id().entity_id) .await .expect("could not get entity"); assert_eq!(entities.len(), 2); let entity_v2 = api - .get_latest_entity(v2_metadata.record_id().entity_id()) + .get_latest_entity(v2_metadata.record_id().entity_id) .await .expect("could not get entity"); @@ -142,7 +142,7 @@ async fn update() { let entity_v1 = api .get_entity_by_timestamp( - v1_metadata.record_id().entity_id(), + v1_metadata.record_id().entity_id, (*v1_metadata.version().decision_time.start()).into(), ) .await @@ -151,7 +151,7 @@ async fn update() { let entity_v2 = api .get_entity_by_timestamp( - v2_metadata.record_id().entity_id(), + v2_metadata.record_id().entity_id, (*v2_metadata.version().decision_time.start()).into(), ) .await diff --git a/apps/hash-graph/tests/integration/postgres/links.rs b/apps/hash-graph/tests/integration/postgres/links.rs index 77d554beef9..ea1617e7684 100644 --- a/apps/hash-graph/tests/integration/postgres/links.rs +++ b/apps/hash-graph/tests/integration/postgres/links.rs @@ -50,25 +50,25 @@ async fn insert() { friend_of, friend_of_type_id.clone(), None, - alice_metadata.record_id().entity_id(), - bob_metadata.record_id().entity_id(), + alice_metadata.record_id().entity_id, + bob_metadata.record_id().entity_id, ) .await .expect("could not create link"); let link_entity = api - .get_link_entity_target(alice_metadata.record_id().entity_id(), friend_of_type_id) + .get_link_entity_target(alice_metadata.record_id().entity_id, friend_of_type_id) .await .expect("could not fetch entity"); let link_data = link_entity.link_data().expect("entity is not a link"); assert_eq!( link_data.left_entity_id(), - alice_metadata.record_id().entity_id() + alice_metadata.record_id().entity_id ); assert_eq!( link_data.right_entity_id(), - bob_metadata.record_id().entity_id() + bob_metadata.record_id().entity_id ); } @@ -132,8 +132,8 @@ async fn get_entity_links() { EntityProperties::empty(), friend_link_type_id.clone(), None, - alice_metadata.record_id().entity_id(), - bob_metadata.record_id().entity_id(), + alice_metadata.record_id().entity_id, + bob_metadata.record_id().entity_id, ) .await .expect("could not create link"); @@ -142,14 +142,14 @@ async fn get_entity_links() { EntityProperties::empty(), acquaintance_entity_link_type_id.clone(), None, - alice_metadata.record_id().entity_id(), - charles_metadata.record_id().entity_id(), + alice_metadata.record_id().entity_id, + charles_metadata.record_id().entity_id, ) .await .expect("could not create link"); let links_from_source = api - .get_latest_entity_links(alice_metadata.record_id().entity_id()) + .get_latest_entity_links(alice_metadata.record_id().entity_id) .await .expect("could not fetch link"); @@ -172,17 +172,17 @@ async fn get_entity_links() { assert!( link_datas .iter() - .any(|link_data| link_data.left_entity_id() == alice_metadata.record_id().entity_id()) + .any(|link_data| link_data.left_entity_id() == alice_metadata.record_id().entity_id) ); assert!( link_datas .iter() - .any(|link_data| link_data.right_entity_id() == bob_metadata.record_id().entity_id()) + .any(|link_data| link_data.right_entity_id() == bob_metadata.record_id().entity_id) ); assert!( - link_datas.iter().any( - |link_data| link_data.right_entity_id() == charles_metadata.record_id().entity_id() - ) + link_datas + .iter() + .any(|link_data| link_data.right_entity_id() == charles_metadata.record_id().entity_id) ); } @@ -232,21 +232,21 @@ async fn remove_link() { EntityProperties::empty(), friend_link_type_id.clone(), None, - alice_metadata.record_id().entity_id(), - bob_metadata.record_id().entity_id(), + alice_metadata.record_id().entity_id, + bob_metadata.record_id().entity_id, ) .await .expect("could not create link"); assert!( - !api.get_latest_entity_links(alice_metadata.record_id().entity_id()) + !api.get_latest_entity_links(alice_metadata.record_id().entity_id) .await .expect("could not fetch links") .is_empty() ); api.archive_entity( - link_entity_metadata.record_id().entity_id(), + link_entity_metadata.record_id().entity_id, EntityProperties::empty(), friend_link_type_id, EntityLinkOrder::new(None, None), @@ -255,7 +255,7 @@ async fn remove_link() { .expect("could not remove link"); assert!( - api.get_latest_entity_links(alice_metadata.record_id().entity_id()) + api.get_latest_entity_links(alice_metadata.record_id().entity_id) .await .expect("could not fetch links") .is_empty() From c1b948fa99fcd5ee7ed76383df2cd4117d19d63e Mon Sep 17 00:00:00 2001 From: Tim Diekmann Date: Thu, 16 Feb 2023 22:08:49 +0100 Subject: [PATCH 04/19] Make fields on `EntityMetadata` pub --- .../read_scaling/knowledge/complete/entity.rs | 6 +- .../read_scaling/knowledge/linkless/entity.rs | 2 +- .../bench/representative_read/seed.rs | 4 +- .../lib/graph/src/knowledge/entity.rs | 73 ++++--------------- .../graph/src/shared/identifier/knowledge.rs | 6 +- .../src/store/postgres/knowledge/entity.rs | 59 ++++++++------- .../tests/integration/postgres/entity.rs | 18 ++--- .../tests/integration/postgres/links.rs | 47 ++++++------ 8 files changed, 84 insertions(+), 131 deletions(-) diff --git a/apps/hash-graph/bench/read_scaling/knowledge/complete/entity.rs b/apps/hash-graph/bench/read_scaling/knowledge/complete/entity.rs index 8067fe856fe..bc474ad1511 100644 --- a/apps/hash-graph/bench/read_scaling/knowledge/complete/entity.rs +++ b/apps/hash-graph/bench/read_scaling/knowledge/complete/entity.rs @@ -106,8 +106,8 @@ async fn seed_db( None, properties.clone(), Some(LinkData::new( - entity_a_metadata.record_id().entity_id, - entity_b_metadata.record_id().entity_id, + entity_a_metadata.record_id.entity_id, + entity_b_metadata.record_id.entity_id, None, None, )), @@ -154,7 +154,7 @@ pub fn bench_get_entity_by_id( // query entity_metadata_list .iter() - .map(EntityMetadata::record_id) + .map(|metadata| metadata.record_id) .choose(&mut thread_rng()) .expect("could not choose random entity") }, diff --git a/apps/hash-graph/bench/read_scaling/knowledge/linkless/entity.rs b/apps/hash-graph/bench/read_scaling/knowledge/linkless/entity.rs index 86ad860e99a..4a9627529a9 100644 --- a/apps/hash-graph/bench/read_scaling/knowledge/linkless/entity.rs +++ b/apps/hash-graph/bench/read_scaling/knowledge/linkless/entity.rs @@ -108,7 +108,7 @@ pub fn bench_get_entity_by_id( // query entity_metadata_list .iter() - .map(EntityMetadata::record_id) + .map(|metadata| metadata.record_id) .choose(&mut thread_rng()) .expect("could not choose random entity") }, diff --git a/apps/hash-graph/bench/representative_read/seed.rs b/apps/hash-graph/bench/representative_read/seed.rs index dedd65d5e54..3d2e8c77fb0 100644 --- a/apps/hash-graph/bench/representative_read/seed.rs +++ b/apps/hash-graph/bench/representative_read/seed.rs @@ -181,8 +181,8 @@ async fn seed_db(account_id: AccountId, store_wrapper: &mut StoreWrapper) { None, EntityProperties::empty(), Some(LinkData::new( - left_entity_metadata.record_id().entity_id, - right_entity_metadata.record_id().entity_id, + left_entity_metadata.record_id.entity_id, + right_entity_metadata.record_id.entity_id, None, None, )), diff --git a/apps/hash-graph/lib/graph/src/knowledge/entity.rs b/apps/hash-graph/lib/graph/src/knowledge/entity.rs index 1bcf73402d3..da672b18430 100644 --- a/apps/hash-graph/lib/graph/src/knowledge/entity.rs +++ b/apps/hash-graph/lib/graph/src/knowledge/entity.rs @@ -173,57 +173,12 @@ impl LinkData { // TODO: deny_unknown_fields on other structs #[serde(deny_unknown_fields, rename_all = "camelCase")] pub struct EntityMetadata { - record_id: EntityRecordId, - version: EntityVersion, + pub record_id: EntityRecordId, + pub version: EntityVersion, #[schema(value_type = String)] - entity_type_id: VersionedUri, - #[serde(rename = "provenance")] - provenance_metadata: ProvenanceMetadata, - archived: bool, -} - -impl EntityMetadata { - #[must_use] - pub const fn new( - record_id: EntityRecordId, - version: EntityVersion, - entity_type_id: VersionedUri, - provenance_metadata: ProvenanceMetadata, - archived: bool, - ) -> Self { - Self { - record_id, - version, - entity_type_id, - provenance_metadata, - archived, - } - } - - #[must_use] - pub const fn record_id(&self) -> EntityRecordId { - self.record_id - } - - #[must_use] - pub const fn version(&self) -> &EntityVersion { - &self.version - } - - #[must_use] - pub const fn entity_type_id(&self) -> &VersionedUri { - &self.entity_type_id - } - - #[must_use] - pub const fn provenance_metadata(&self) -> ProvenanceMetadata { - self.provenance_metadata - } - - #[must_use] - pub const fn archived(&self) -> bool { - self.archived - } + pub entity_type_id: VersionedUri, + pub provenance: ProvenanceMetadata, + pub archived: bool, } /// A record of an [`Entity`] that has been persisted in the datastore, with its associated @@ -242,22 +197,22 @@ impl Entity { pub const fn new( properties: EntityProperties, link_data: Option, - identifier: EntityRecordId, + record_id: EntityRecordId, version: EntityVersion, entity_type_id: VersionedUri, - provenance_metadata: ProvenanceMetadata, + provenance: ProvenanceMetadata, archived: bool, ) -> Self { Self { properties, link_data, - metadata: EntityMetadata::new( - identifier, + metadata: EntityMetadata { + record_id, version, entity_type_id, - provenance_metadata, + provenance, archived, - ), + }, } } @@ -283,10 +238,10 @@ impl Record for Entity { fn vertex_id(&self, time_axis: TimeAxis) -> Self::VertexId { let timestamp = match time_axis { - TimeAxis::DecisionTime => self.metadata().version().decision_time.start().cast(), - TimeAxis::TransactionTime => self.metadata().version().transaction_time.start().cast(), + TimeAxis::DecisionTime => self.metadata().version.decision_time.start().cast(), + TimeAxis::TransactionTime => self.metadata().version.transaction_time.start().cast(), }; - EntityVertexId::new(self.metadata().record_id().entity_id, timestamp.into()) + EntityVertexId::new(self.metadata().record_id.entity_id, timestamp.into()) } fn create_filter_for_vertex_id(vertex_id: &Self::VertexId) -> Filter { diff --git a/apps/hash-graph/lib/graph/src/shared/identifier/knowledge.rs b/apps/hash-graph/lib/graph/src/shared/identifier/knowledge.rs index 88862cf8a52..ef5fd4ff4f3 100644 --- a/apps/hash-graph/lib/graph/src/shared/identifier/knowledge.rs +++ b/apps/hash-graph/lib/graph/src/shared/identifier/knowledge.rs @@ -4,7 +4,7 @@ use std::{ }; use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer}; -use tokio_postgres::types::ToSql; +use tokio_postgres::types::{FromSql, ToSql}; use utoipa::{openapi, ToSchema}; use uuid::Uuid; @@ -130,7 +130,9 @@ impl EntityVersion { } } -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, ToSql, ToSchema)] +#[derive( + Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, FromSql, ToSql, ToSchema, +)] #[postgres(transparent)] #[repr(transparent)] pub struct EntityEditionId(Uuid); diff --git a/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity.rs b/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity.rs index 9955710051a..3d8f6072e77 100644 --- a/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity.rs +++ b/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity.rs @@ -11,7 +11,7 @@ use uuid::Uuid; use crate::{ identifier::{ - knowledge::{EntityEditionId, EntityId, EntityRecordId, EntityVersion}, + knowledge::{EntityId, EntityRecordId, EntityVersion}, time::{DecisionTime, TimeProjection, Timestamp}, EntityVertexId, OntologyTypeVertexId, }, @@ -61,7 +61,7 @@ impl PostgresStore { let version_interval = entity .metadata() - .version() + .version .projected_time(time_axis); // Intersects the version interval of the entity with the time projection's time @@ -100,7 +100,8 @@ impl PostgresStore { if current_resolve_depths.is_of_type.outgoing > 0 { let entity_type_id = - OntologyTypeVertexId::from(entity.metadata().entity_type_id().clone()); + OntologyTypeVertexId::from(entity.metadata().entity_type_id.clone()); + subgraph.edges.insert(Edge::KnowledgeGraph { vertex_id: entity_vertex_id, outward_edge: KnowledgeGraphOutwardEdges::ToOntology(OutwardEdge { @@ -141,7 +142,7 @@ impl PostgresStore { // outgoing link `Entity` kind: KnowledgeGraphEdgeKind::HasLeftEntity, reversed: true, - right_endpoint: outgoing_link_entity.metadata().record_id().entity_id, + right_endpoint: outgoing_link_entity.metadata().record_id.entity_id, }), }); @@ -180,7 +181,7 @@ impl PostgresStore { // incoming link `Entity` kind: KnowledgeGraphEdgeKind::HasRightEntity, reversed: true, - right_endpoint: incoming_link_entity.metadata().record_id().entity_id, + right_endpoint: incoming_link_entity.metadata().record_id.entity_id, }), }); @@ -219,7 +220,7 @@ impl PostgresStore { // outgoing `Link` `Entity` kind: KnowledgeGraphEdgeKind::HasLeftEntity, reversed: false, - right_endpoint: left_entity.metadata().record_id().entity_id, + right_endpoint: left_entity.metadata().record_id.entity_id, }), }); @@ -258,7 +259,7 @@ impl PostgresStore { // outgoing `Link` `Entity` kind: KnowledgeGraphEdgeKind::HasRightEntity, reversed: false, - right_endpoint: right_entity.metadata().record_id().entity_id, + right_endpoint: right_entity.metadata().record_id.entity_id, }), }); @@ -369,19 +370,19 @@ impl EntityStore for PostgresStore { .into_report() .change_context(InsertionError)?; - Ok(EntityMetadata::new( - EntityRecordId { + Ok(EntityMetadata { + record_id: EntityRecordId { entity_id, - edition_id: EntityEditionId::new(row.get(0)), + edition_id: row.get(0), }, - EntityVersion { + version: EntityVersion { decision_time: row.get(1), transaction_time: row.get(2), }, entity_type_id, - ProvenanceMetadata::new(updated_by_id), + provenance: ProvenanceMetadata::new(updated_by_id), archived, - )) + }) } #[doc(hidden)] @@ -461,17 +462,15 @@ impl EntityStore for PostgresStore { .into_iter() .zip(entity_versions) .zip(entity_edition_ids) - .map(|(((entity_id, ..), entity_version), edition_id)| { - EntityMetadata::new( - EntityRecordId { - entity_id, - edition_id, - }, - entity_version, - entity_type_id.clone(), - ProvenanceMetadata::new(actor_id), - false, - ) + .map(|(((entity_id, ..), version), edition_id)| EntityMetadata { + record_id: EntityRecordId { + entity_id, + edition_id, + }, + version, + entity_type_id: entity_type_id.clone(), + provenance: ProvenanceMetadata::new(actor_id), + archived: false, }) .collect()) } @@ -603,18 +602,18 @@ impl EntityStore for PostgresStore { transaction.commit().await.change_context(UpdateError)?; - Ok(EntityMetadata::new( - EntityRecordId { + Ok(EntityMetadata { + record_id: EntityRecordId { entity_id, - edition_id: EntityEditionId::new(row.get(0)), + edition_id: row.get(0), }, - EntityVersion { + version: EntityVersion { decision_time: row.get(1), transaction_time: row.get(2), }, entity_type_id, - ProvenanceMetadata::new(updated_by_id), + provenance: ProvenanceMetadata::new(updated_by_id), archived, - )) + }) } } diff --git a/apps/hash-graph/tests/integration/postgres/entity.rs b/apps/hash-graph/tests/integration/postgres/entity.rs index 879e142ef06..f9c17b0dd7e 100644 --- a/apps/hash-graph/tests/integration/postgres/entity.rs +++ b/apps/hash-graph/tests/integration/postgres/entity.rs @@ -35,7 +35,7 @@ async fn insert() { .expect("could not create entity"); let entities = api - .get_entities(metadata.record_id().entity_id) + .get_entities(metadata.record_id.entity_id) .await .expect("could not get entity"); assert_eq!(entities.len(), 1); @@ -72,7 +72,7 @@ async fn query() { .expect("could not create entity"); let queried_organizations = api - .get_entities(metadata.record_id().entity_id) + .get_entities(metadata.record_id.entity_id) .await .expect("could not get entity"); assert_eq!(queried_organizations.len(), 1); @@ -112,7 +112,7 @@ async fn update() { let v2_metadata = api .update_entity( - v1_metadata.record_id().entity_id, + v1_metadata.record_id.entity_id, page_v2.clone(), VersionedUri { base_uri: BaseUri::new( @@ -127,14 +127,14 @@ async fn update() { .expect("could not update entity"); let entities = api - .get_entities(v2_metadata.record_id().entity_id) + .get_entities(v2_metadata.record_id.entity_id) .await .expect("could not get entity"); assert_eq!(entities.len(), 2); let entity_v2 = api - .get_latest_entity(v2_metadata.record_id().entity_id) + .get_latest_entity(v2_metadata.record_id.entity_id) .await .expect("could not get entity"); @@ -142,8 +142,8 @@ async fn update() { let entity_v1 = api .get_entity_by_timestamp( - v1_metadata.record_id().entity_id, - (*v1_metadata.version().decision_time.start()).into(), + v1_metadata.record_id.entity_id, + (*v1_metadata.version.decision_time.start()).into(), ) .await .expect("could not get entity"); @@ -151,8 +151,8 @@ async fn update() { let entity_v2 = api .get_entity_by_timestamp( - v2_metadata.record_id().entity_id, - (*v2_metadata.version().decision_time.start()).into(), + v2_metadata.record_id.entity_id, + (*v2_metadata.version.decision_time.start()).into(), ) .await .expect("could not get entity"); diff --git a/apps/hash-graph/tests/integration/postgres/links.rs b/apps/hash-graph/tests/integration/postgres/links.rs index ea1617e7684..0460ba2eb99 100644 --- a/apps/hash-graph/tests/integration/postgres/links.rs +++ b/apps/hash-graph/tests/integration/postgres/links.rs @@ -50,25 +50,25 @@ async fn insert() { friend_of, friend_of_type_id.clone(), None, - alice_metadata.record_id().entity_id, - bob_metadata.record_id().entity_id, + alice_metadata.record_id.entity_id, + bob_metadata.record_id.entity_id, ) .await .expect("could not create link"); let link_entity = api - .get_link_entity_target(alice_metadata.record_id().entity_id, friend_of_type_id) + .get_link_entity_target(alice_metadata.record_id.entity_id, friend_of_type_id) .await .expect("could not fetch entity"); let link_data = link_entity.link_data().expect("entity is not a link"); assert_eq!( link_data.left_entity_id(), - alice_metadata.record_id().entity_id + alice_metadata.record_id.entity_id ); assert_eq!( link_data.right_entity_id(), - bob_metadata.record_id().entity_id + bob_metadata.record_id.entity_id ); } @@ -132,8 +132,8 @@ async fn get_entity_links() { EntityProperties::empty(), friend_link_type_id.clone(), None, - alice_metadata.record_id().entity_id, - bob_metadata.record_id().entity_id, + alice_metadata.record_id.entity_id, + bob_metadata.record_id.entity_id, ) .await .expect("could not create link"); @@ -142,28 +142,25 @@ async fn get_entity_links() { EntityProperties::empty(), acquaintance_entity_link_type_id.clone(), None, - alice_metadata.record_id().entity_id, - charles_metadata.record_id().entity_id, + alice_metadata.record_id.entity_id, + charles_metadata.record_id.entity_id, ) .await .expect("could not create link"); let links_from_source = api - .get_latest_entity_links(alice_metadata.record_id().entity_id) + .get_latest_entity_links(alice_metadata.record_id.entity_id) .await .expect("could not fetch link"); assert!( links_from_source .iter() - .any(|link_entity| link_entity.metadata().entity_type_id() == &friend_link_type_id) - ); - assert!( - links_from_source - .iter() - .any(|link_entity| link_entity.metadata().entity_type_id() - == &acquaintance_entity_link_type_id) + .any(|link_entity| { link_entity.metadata().entity_type_id == friend_link_type_id }) ); + assert!(links_from_source.iter().any(|link_entity| { + link_entity.metadata().entity_type_id == acquaintance_entity_link_type_id + })); let link_datas = links_from_source .iter() @@ -172,17 +169,17 @@ async fn get_entity_links() { assert!( link_datas .iter() - .any(|link_data| link_data.left_entity_id() == alice_metadata.record_id().entity_id) + .any(|link_data| link_data.left_entity_id() == alice_metadata.record_id.entity_id) ); assert!( link_datas .iter() - .any(|link_data| link_data.right_entity_id() == bob_metadata.record_id().entity_id) + .any(|link_data| link_data.right_entity_id() == bob_metadata.record_id.entity_id) ); assert!( link_datas .iter() - .any(|link_data| link_data.right_entity_id() == charles_metadata.record_id().entity_id) + .any(|link_data| link_data.right_entity_id() == charles_metadata.record_id.entity_id) ); } @@ -232,21 +229,21 @@ async fn remove_link() { EntityProperties::empty(), friend_link_type_id.clone(), None, - alice_metadata.record_id().entity_id, - bob_metadata.record_id().entity_id, + alice_metadata.record_id.entity_id, + bob_metadata.record_id.entity_id, ) .await .expect("could not create link"); assert!( - !api.get_latest_entity_links(alice_metadata.record_id().entity_id) + !api.get_latest_entity_links(alice_metadata.record_id.entity_id) .await .expect("could not fetch links") .is_empty() ); api.archive_entity( - link_entity_metadata.record_id().entity_id, + link_entity_metadata.record_id.entity_id, EntityProperties::empty(), friend_link_type_id, EntityLinkOrder::new(None, None), @@ -255,7 +252,7 @@ async fn remove_link() { .expect("could not remove link"); assert!( - api.get_latest_entity_links(alice_metadata.record_id().entity_id) + api.get_latest_entity_links(alice_metadata.record_id.entity_id) .await .expect("could not fetch links") .is_empty() From 22fe8b0abecf4b445fdea99a706fe78595c55548 Mon Sep 17 00:00:00 2001 From: Tim Diekmann Date: Thu, 16 Feb 2023 22:18:46 +0100 Subject: [PATCH 05/19] Flatten `OntologyElementMetadata` --- apps/hash-graph/bench/util.rs | 41 +++---- apps/hash-graph/lib/graph/src/api/rest.rs | 7 +- .../lib/graph/src/api/rest/data_type.rs | 9 +- .../lib/graph/src/api/rest/entity_type.rs | 9 +- .../lib/graph/src/api/rest/property_type.rs | 10 +- apps/hash-graph/lib/graph/src/ontology.rs | 104 +++--------------- .../hash-graph/lib/graph/src/store/fetcher.rs | 49 ++++----- .../lib/graph/src/store/postgres.rs | 68 +++++++----- .../graph/src/store/postgres/ontology/read.rs | 17 ++- .../tests/integration/postgres/lib.rs | 62 +++++------ 10 files changed, 149 insertions(+), 227 deletions(-) diff --git a/apps/hash-graph/bench/util.rs b/apps/hash-graph/bench/util.rs index e0b9aa8c2e7..14c6cf08bc1 100644 --- a/apps/hash-graph/bench/util.rs +++ b/apps/hash-graph/bench/util.rs @@ -2,7 +2,7 @@ use std::mem::ManuallyDrop; use graph::{ identifier::account::AccountId, - ontology::{OntologyElementMetadata, OwnedOntologyElementMetadata}, + ontology::OntologyElementMetadata, provenance::{OwnedById, ProvenanceMetadata, UpdatedById}, store::{ AsClient, BaseUriAlreadyExists, DataTypeStore, DatabaseConnectionInfo, DatabaseType, @@ -198,14 +198,11 @@ pub async fn seed( let data_type = DataType::try_from(data_type_repr).expect("could not parse data type"); match store - .create_data_type( - data_type.clone(), - &OntologyElementMetadata::Owned(OwnedOntologyElementMetadata::new( - data_type.id().clone().into(), - ProvenanceMetadata::new(UpdatedById::new(account_id)), - OwnedById::new(account_id), - )), - ) + .create_data_type(data_type.clone(), &OntologyElementMetadata::Owned { + record_id: data_type.id().clone().into(), + provenance: ProvenanceMetadata::new(UpdatedById::new(account_id)), + owned_by_id: OwnedById::new(account_id), + }) .await { Ok(_) => {} @@ -229,14 +226,11 @@ pub async fn seed( PropertyType::try_from(property_typee_repr).expect("could not parse property type"); match store - .create_property_type( - property_type.clone(), - &OntologyElementMetadata::Owned(OwnedOntologyElementMetadata::new( - property_type.id().clone().into(), - ProvenanceMetadata::new(UpdatedById::new(account_id)), - OwnedById::new(account_id), - )), - ) + .create_property_type(property_type.clone(), &OntologyElementMetadata::Owned { + record_id: property_type.id().clone().into(), + provenance: ProvenanceMetadata::new(UpdatedById::new(account_id)), + owned_by_id: OwnedById::new(account_id), + }) .await { Ok(_) => {} @@ -260,14 +254,11 @@ pub async fn seed( EntityType::try_from(entity_type_repr).expect("could not parse entity type"); match store - .create_entity_type( - entity_type.clone(), - &OntologyElementMetadata::Owned(OwnedOntologyElementMetadata::new( - entity_type.id().clone().into(), - ProvenanceMetadata::new(UpdatedById::new(account_id)), - OwnedById::new(account_id), - )), - ) + .create_entity_type(entity_type.clone(), &OntologyElementMetadata::Owned { + record_id: entity_type.id().clone().into(), + provenance: ProvenanceMetadata::new(UpdatedById::new(account_id)), + owned_by_id: OwnedById::new(account_id), + }) .await { Ok(_) => {} diff --git a/apps/hash-graph/lib/graph/src/api/rest.rs b/apps/hash-graph/lib/graph/src/api/rest.rs index 06456a5e0e6..72d16cd4e88 100644 --- a/apps/hash-graph/lib/graph/src/api/rest.rs +++ b/apps/hash-graph/lib/graph/src/api/rest.rs @@ -56,10 +56,7 @@ use crate::{ }, EntityVertexId, GraphElementVertexId, OntologyTypeVertexId, }, - ontology::{ - domain_validator::DomainValidator, ExternalOntologyElementMetadata, - OntologyElementMetadata, OwnedOntologyElementMetadata, Selector, - }, + ontology::{domain_validator::DomainValidator, OntologyElementMetadata, Selector}, provenance::{OwnedById, ProvenanceMetadata, UpdatedById}, store::{QueryError, StorePool}, subgraph::edges::{ @@ -179,8 +176,6 @@ async fn serve_static_schema(Path(path): Path) -> Result( StatusCode::INTERNAL_SERVER_ERROR })?; - let metadata = OntologyElementMetadata::Owned(OwnedOntologyElementMetadata::new( - data_type.id().clone().into(), - ProvenanceMetadata::new(actor_id), + let metadata = OntologyElementMetadata::Owned { + record_id: data_type.id().clone().into(), + provenance: ProvenanceMetadata::new(actor_id), owned_by_id, - )); + }; store .create_data_type(data_type, &metadata) diff --git a/apps/hash-graph/lib/graph/src/api/rest/entity_type.rs b/apps/hash-graph/lib/graph/src/api/rest/entity_type.rs index e5c80ce522b..bc0e8f3e49d 100644 --- a/apps/hash-graph/lib/graph/src/api/rest/entity_type.rs +++ b/apps/hash-graph/lib/graph/src/api/rest/entity_type.rs @@ -16,7 +16,6 @@ use crate::{ ontology::{ domain_validator::{DomainValidator, ValidateOntologyType}, patch_id_and_parse, EntityTypeQueryToken, EntityTypeWithMetadata, OntologyElementMetadata, - OwnedOntologyElementMetadata, }, provenance::{OwnedById, ProvenanceMetadata, UpdatedById}, store::{ @@ -118,11 +117,11 @@ async fn create_entity_type( StatusCode::INTERNAL_SERVER_ERROR })?; - let metadata = OntologyElementMetadata::Owned(OwnedOntologyElementMetadata::new( - entity_type.id().clone().into(), - ProvenanceMetadata::new(actor_id), + let metadata = OntologyElementMetadata::Owned { + record_id: entity_type.id().clone().into(), + provenance: ProvenanceMetadata::new(actor_id), owned_by_id, - )); + }; store .create_entity_type(entity_type, &metadata) diff --git a/apps/hash-graph/lib/graph/src/api/rest/property_type.rs b/apps/hash-graph/lib/graph/src/api/rest/property_type.rs index 1507bffb8e7..b8c8d156d13 100644 --- a/apps/hash-graph/lib/graph/src/api/rest/property_type.rs +++ b/apps/hash-graph/lib/graph/src/api/rest/property_type.rs @@ -14,7 +14,7 @@ use crate::{ api::rest::{report_to_status_code, utoipa_typedef::subgraph::Subgraph}, ontology::{ domain_validator::{DomainValidator, ValidateOntologyType}, - patch_id_and_parse, OntologyElementMetadata, OwnedOntologyElementMetadata, + patch_id_and_parse, OntologyElementMetadata, PropertyTypeQueryToken, PropertyTypeWithMetadata, }, provenance::{OwnedById, ProvenanceMetadata, UpdatedById}, @@ -115,11 +115,11 @@ async fn create_property_type( StatusCode::INTERNAL_SERVER_ERROR })?; - let metadata = OntologyElementMetadata::Owned(OwnedOntologyElementMetadata::new( - property_type.id().clone().into(), - ProvenanceMetadata::new(actor_id), + let metadata = OntologyElementMetadata::Owned { + record_id: property_type.id().clone().into(), + provenance: ProvenanceMetadata::new(actor_id), owned_by_id, - )); + }; store .create_property_type(property_type, &metadata) diff --git a/apps/hash-graph/lib/graph/src/ontology.rs b/apps/hash-graph/lib/graph/src/ontology.rs index d656532cbe9..e4af0299cea 100644 --- a/apps/hash-graph/lib/graph/src/ontology.rs +++ b/apps/hash-graph/lib/graph/src/ontology.rs @@ -176,106 +176,38 @@ pub trait OntologyTypeWithMetadata: Record { #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, ToSchema)] #[serde(untagged)] pub enum OntologyElementMetadata { - Owned(OwnedOntologyElementMetadata), - External(ExternalOntologyElementMetadata), + #[serde(rename_all = "camelCase")] + #[schema(title = "OwnedOntologyElementMetadata")] + Owned { + record_id: OntologyTypeRecordId, + provenance: ProvenanceMetadata, + owned_by_id: OwnedById, + }, + #[serde(rename_all = "camelCase")] + #[schema(title = "ExternalOntologyElementMetadata")] + External { + record_id: OntologyTypeRecordId, + provenance: ProvenanceMetadata, + #[schema(value_type = String)] + #[serde(with = "time::serde::iso8601")] + fetched_at: OffsetDateTime, + }, } impl OntologyElementMetadata { #[must_use] pub const fn record_id(&self) -> &OntologyTypeRecordId { match self { - Self::Owned(owned) => owned.record_id(), - Self::External(external) => external.record_id(), + Self::Owned { record_id, .. } | Self::External { record_id, .. } => record_id, } } #[must_use] pub const fn provenance_metadata(&self) -> ProvenanceMetadata { match self { - Self::Owned(owned) => owned.provenance_metadata, - Self::External(external) => external.provenance_metadata, - } - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, ToSchema)] -#[serde(rename_all = "camelCase")] -pub struct OwnedOntologyElementMetadata { - record_id: OntologyTypeRecordId, - #[serde(rename = "provenance")] - provenance_metadata: ProvenanceMetadata, - owned_by_id: OwnedById, -} - -impl OwnedOntologyElementMetadata { - #[must_use] - pub const fn new( - record_id: OntologyTypeRecordId, - provenance_metadata: ProvenanceMetadata, - owned_by_id: OwnedById, - ) -> Self { - Self { - record_id, - provenance_metadata, - owned_by_id, - } - } - - #[must_use] - pub const fn record_id(&self) -> &OntologyTypeRecordId { - &self.record_id - } - - #[must_use] - pub const fn provenance_metadata(&self) -> ProvenanceMetadata { - self.provenance_metadata - } - - #[must_use] - pub const fn owned_by_id(&self) -> OwnedById { - self.owned_by_id - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, ToSchema)] -#[serde(rename_all = "camelCase")] -pub struct ExternalOntologyElementMetadata { - record_id: OntologyTypeRecordId, - #[serde(rename = "provenance")] - provenance_metadata: ProvenanceMetadata, - #[schema(value_type = String)] - #[serde(with = "time::serde::iso8601")] - fetched_at: OffsetDateTime, -} - -impl ExternalOntologyElementMetadata { - #[must_use] - pub const fn new( - record_id: OntologyTypeRecordId, - provenance_metadata: ProvenanceMetadata, - fetched_at: OffsetDateTime, - ) -> Self { - Self { - record_id, - provenance_metadata, - fetched_at, + Self::Owned { provenance, .. } | Self::External { provenance, .. } => *provenance, } } - - #[must_use] - pub const fn record_id(&self) -> &OntologyTypeRecordId { - &self.record_id - } - - #[must_use] - pub const fn provenance_metadata(&self) -> ProvenanceMetadata { - self.provenance_metadata - } - - #[must_use] - pub const fn fetched_at(&self) -> OffsetDateTime { - self.fetched_at - } } #[derive(Debug, PartialEq, Eq, Serialize, ToSchema)] diff --git a/apps/hash-graph/lib/graph/src/store/fetcher.rs b/apps/hash-graph/lib/graph/src/store/fetcher.rs index 76114963fc6..f92fe3c9f60 100644 --- a/apps/hash-graph/lib/graph/src/store/fetcher.rs +++ b/apps/hash-graph/lib/graph/src/store/fetcher.rs @@ -26,7 +26,7 @@ use crate::{ knowledge::{Entity, EntityLinkOrder, EntityMetadata, EntityProperties, EntityUuid, LinkData}, ontology::{ domain_validator::DomainValidator, DataTypeWithMetadata, EntityTypeWithMetadata, - ExternalOntologyElementMetadata, OntologyElementMetadata, PropertyTypeWithMetadata, + OntologyElementMetadata, PropertyTypeWithMetadata, }, provenance::{OwnedById, ProvenanceMetadata, UpdatedById}, store::{ @@ -210,7 +210,7 @@ where let mut entity_types = Vec::new(); for (reference, fetched_by) in ontology_type_references { - let provenance_metadata = ProvenanceMetadata::new(fetched_by); + let provenance = ProvenanceMetadata::new(fetched_by); let fetched_ontology_types = fetcher_client .fetch_ontology_type_exhaustive(context::current(), reference.uri().clone()) .await @@ -232,14 +232,13 @@ where )) .await? { - let metadata = ExternalOntologyElementMetadata::new( - data_type.id().clone().into(), - provenance_metadata, - fetched_ontology_type.fetched_at, - ); - - data_types - .push((data_type, OntologyElementMetadata::External(metadata))); + let metadata = OntologyElementMetadata::External { + record_id: data_type.id().clone().into(), + provenance, + fetched_at: fetched_ontology_type.fetched_at, + }; + + data_types.push((data_type, metadata)); } } OntologyType::PropertyType(property_type) => { @@ -254,14 +253,13 @@ where )) .await? { - let metadata = ExternalOntologyElementMetadata::new( - property_type.id().clone().into(), - provenance_metadata, - fetched_ontology_type.fetched_at, - ); - - property_types - .push((property_type, OntologyElementMetadata::External(metadata))); + let metadata = OntologyElementMetadata::External { + record_id: property_type.id().clone().into(), + provenance, + fetched_at: fetched_ontology_type.fetched_at, + }; + + property_types.push((property_type, metadata)); } } OntologyType::EntityType(entity_type) => { @@ -276,14 +274,13 @@ where )) .await? { - let metadata = ExternalOntologyElementMetadata::new( - entity_type.id().clone().into(), - provenance_metadata, - fetched_ontology_type.fetched_at, - ); - - entity_types - .push((entity_type, OntologyElementMetadata::External(metadata))); + let metadata = OntologyElementMetadata::External { + record_id: entity_type.id().clone().into(), + provenance, + fetched_at: fetched_ontology_type.fetched_at, + }; + + entity_types.push((entity_type, metadata)); } } } diff --git a/apps/hash-graph/lib/graph/src/store/postgres.rs b/apps/hash-graph/lib/graph/src/store/postgres.rs index 3e4a3749705..45a3c5f01db 100644 --- a/apps/hash-graph/lib/graph/src/store/postgres.rs +++ b/apps/hash-graph/lib/graph/src/store/postgres.rs @@ -13,6 +13,7 @@ use std::{ use async_trait::async_trait; use error_stack::{IntoReport, Result, ResultExt}; +use time::OffsetDateTime; #[cfg(feature = "__internal_bench")] use tokio_postgres::{binary_copy::BinaryCopyInWriter, types::Type}; use tokio_postgres::{error::SqlState, GenericClient}; @@ -30,9 +31,7 @@ use crate::{ EntityVertexId, OntologyTypeVertexId, }, interval::Interval, - ontology::{ - ExternalOntologyElementMetadata, OntologyElementMetadata, OwnedOntologyElementMetadata, - }, + ontology::OntologyElementMetadata, provenance::{OwnedById, ProvenanceMetadata, UpdatedById}, store::{ error::{VersionedUriAlreadyExists, WrongOntologyVersion}, @@ -253,7 +252,9 @@ where #[tracing::instrument(level = "debug", skip(self))] async fn create_owned_ontology_id( &self, - metadata: &OwnedOntologyElementMetadata, + record_id: &OntologyTypeRecordId, + provenance: ProvenanceMetadata, + owned_by_id: OwnedById, ) -> Result { self.as_client() .query_one( @@ -267,10 +268,10 @@ where record_created_by_id := $4 );"#, &[ - &metadata.record_id().base_uri.as_str(), - &metadata.record_id().version, - &metadata.owned_by_id(), - &metadata.provenance_metadata().updated_by_id(), + &record_id.base_uri.as_str(), + &record_id.version, + &owned_by_id, + &provenance.updated_by_id(), ], ) .await @@ -279,11 +280,11 @@ where .map_err(|report| match report.current_context().code() { Some(&SqlState::EXCLUSION_VIOLATION | &SqlState::UNIQUE_VIOLATION) => report .change_context(BaseUriAlreadyExists) - .attach_printable(metadata.record_id().base_uri.clone()) + .attach_printable(record_id.base_uri.clone()) .change_context(InsertionError), _ => report .change_context(InsertionError) - .attach_printable(VersionedUri::from(metadata.record_id().clone())), + .attach_printable(VersionedUri::from(record_id.clone())), }) } @@ -295,7 +296,9 @@ where #[tracing::instrument(level = "debug", skip(self))] async fn create_external_ontology_id( &self, - metadata: &ExternalOntologyElementMetadata, + record_id: &OntologyTypeRecordId, + provenance: ProvenanceMetadata, + fetched_at: OffsetDateTime, ) -> Result { self.as_client() .query_one( @@ -309,10 +312,10 @@ where record_created_by_id := $4 );"#, &[ - &metadata.record_id().base_uri.as_str(), - &metadata.record_id().version, - &metadata.fetched_at(), - &metadata.provenance_metadata().updated_by_id(), + &record_id.base_uri.as_str(), + &record_id.version, + &fetched_at, + &provenance.updated_by_id(), ], ) .await @@ -321,11 +324,11 @@ where .map_err(|report| match report.current_context().code() { Some(&SqlState::EXCLUSION_VIOLATION | &SqlState::UNIQUE_VIOLATION) => report .change_context(BaseUriAlreadyExists) - .attach_printable(metadata.record_id().base_uri.clone()) + .attach_printable(record_id.base_uri.clone()) .change_context(InsertionError), _ => report .change_context(InsertionError) - .attach_printable(VersionedUri::from(metadata.record_id().clone())), + .attach_printable(VersionedUri::from(record_id.clone())), }) } @@ -405,11 +408,21 @@ where T::Representation: Send, { let ontology_id = match metadata { - OntologyElementMetadata::Owned(metadata) => { - self.create_owned_ontology_id(metadata).await? + OntologyElementMetadata::Owned { + record_id, + provenance, + owned_by_id, + } => { + self.create_owned_ontology_id(record_id, *provenance, *owned_by_id) + .await? } - OntologyElementMetadata::External(metadata) => { - self.create_external_ontology_id(metadata).await? + OntologyElementMetadata::External { + record_id, + provenance, + fetched_at, + } => { + self.create_external_ontology_id(record_id, *provenance, *fetched_at) + .await? } }; @@ -449,14 +462,11 @@ where .await .change_context(UpdateError)?; - Ok(( - ontology_id, - OntologyElementMetadata::Owned(OwnedOntologyElementMetadata::new( - record_id, - ProvenanceMetadata::new(updated_by_id), - owned_by_id, - )), - )) + Ok((ontology_id, OntologyElementMetadata::Owned { + record_id, + provenance: ProvenanceMetadata::new(updated_by_id), + owned_by_id, + })) } /// Inserts an [`OntologyDatabaseType`] identified by [`OntologyId`], and associated with an diff --git a/apps/hash-graph/lib/graph/src/store/postgres/ontology/read.rs b/apps/hash-graph/lib/graph/src/store/postgres/ontology/read.rs index 0ca51c83c36..b9b32d590a0 100644 --- a/apps/hash-graph/lib/graph/src/store/postgres/ontology/read.rs +++ b/apps/hash-graph/lib/graph/src/store/postgres/ontology/read.rs @@ -14,10 +14,7 @@ use crate::{ ontology::{OntologyTypeRecordId, OntologyTypeVersion}, time::TimeProjection, }, - ontology::{ - ExternalOntologyElementMetadata, OntologyElementMetadata, OntologyType, - OntologyTypeWithMetadata, OwnedOntologyElementMetadata, - }, + ontology::{OntologyElementMetadata, OntologyType, OntologyTypeWithMetadata}, provenance::{OwnedById, ProvenanceMetadata, UpdatedById}, store::{ crud::Read, @@ -118,16 +115,18 @@ where Ok(T::new(record, match metadata { AdditionalOntologyMetadata::Owned { owned_by_id } => { - OntologyElementMetadata::Owned(OwnedOntologyElementMetadata::new( + OntologyElementMetadata::Owned { record_id, provenance, owned_by_id, - )) + } } AdditionalOntologyMetadata::External { fetched_at } => { - OntologyElementMetadata::External(ExternalOntologyElementMetadata::new( - record_id, provenance, fetched_at, - )) + OntologyElementMetadata::External { + record_id, + provenance, + fetched_at, + } } })) }) diff --git a/apps/hash-graph/tests/integration/postgres/lib.rs b/apps/hash-graph/tests/integration/postgres/lib.rs index 09ca41b123f..88c1b3abd24 100644 --- a/apps/hash-graph/tests/integration/postgres/lib.rs +++ b/apps/hash-graph/tests/integration/postgres/lib.rs @@ -32,7 +32,7 @@ use graph::{ }, ontology::{ DataTypeWithMetadata, EntityTypeQueryPath, EntityTypeWithMetadata, OntologyElementMetadata, - OwnedOntologyElementMetadata, PropertyTypeWithMetadata, + PropertyTypeWithMetadata, }, provenance::{OwnedById, ProvenanceMetadata, UpdatedById}, store::{ @@ -122,11 +122,11 @@ impl DatabaseTestWrapper { .expect("could not parse data type representation"); let data_type = DataType::try_from(data_type_repr).expect("could not parse data type"); - let metadata = OntologyElementMetadata::Owned(OwnedOntologyElementMetadata::new( - data_type.id().clone().into(), - ProvenanceMetadata::new(UpdatedById::new(account_id)), - OwnedById::new(account_id), - )); + let metadata = OntologyElementMetadata::Owned { + record_id: data_type.id().clone().into(), + provenance: ProvenanceMetadata::new(UpdatedById::new(account_id)), + owned_by_id: OwnedById::new(account_id), + }; (data_type, metadata) }); @@ -138,11 +138,11 @@ impl DatabaseTestWrapper { let property_type = PropertyType::try_from(property_type_repr).expect("could not parse property type"); - let metadata = OntologyElementMetadata::Owned(OwnedOntologyElementMetadata::new( - property_type.id().clone().into(), - ProvenanceMetadata::new(UpdatedById::new(account_id)), - OwnedById::new(account_id), - )); + let metadata = OntologyElementMetadata::Owned { + record_id: property_type.id().clone().into(), + provenance: ProvenanceMetadata::new(UpdatedById::new(account_id)), + owned_by_id: OwnedById::new(account_id), + }; (property_type, metadata) }); @@ -154,11 +154,11 @@ impl DatabaseTestWrapper { let entity_type = EntityType::try_from(entity_type_repr).expect("could not parse entity type"); - let metadata = OntologyElementMetadata::Owned(OwnedOntologyElementMetadata::new( - entity_type.id().clone().into(), - ProvenanceMetadata::new(UpdatedById::new(account_id)), - OwnedById::new(account_id), - )); + let metadata = OntologyElementMetadata::Owned { + record_id: entity_type.id().clone().into(), + provenance: ProvenanceMetadata::new(UpdatedById::new(account_id)), + owned_by_id: OwnedById::new(account_id), + }; (entity_type, metadata) }); @@ -187,11 +187,11 @@ impl DatabaseApi<'_> { &mut self, data_type: DataType, ) -> Result { - let metadata = OntologyElementMetadata::Owned(OwnedOntologyElementMetadata::new( - data_type.id().clone().into(), - ProvenanceMetadata::new(UpdatedById::new(self.account_id)), - OwnedById::new(self.account_id), - )); + let metadata = OntologyElementMetadata::Owned { + record_id: data_type.id().clone().into(), + provenance: ProvenanceMetadata::new(UpdatedById::new(self.account_id)), + owned_by_id: OwnedById::new(self.account_id), + }; self.store.create_data_type(data_type, &metadata).await?; @@ -232,11 +232,11 @@ impl DatabaseApi<'_> { &mut self, property_type: PropertyType, ) -> Result { - let metadata = OntologyElementMetadata::Owned(OwnedOntologyElementMetadata::new( - property_type.id().clone().into(), - ProvenanceMetadata::new(UpdatedById::new(self.account_id)), - OwnedById::new(self.account_id), - )); + let metadata = OntologyElementMetadata::Owned { + record_id: property_type.id().clone().into(), + provenance: ProvenanceMetadata::new(UpdatedById::new(self.account_id)), + owned_by_id: OwnedById::new(self.account_id), + }; self.store .create_property_type(property_type, &metadata) @@ -279,11 +279,11 @@ impl DatabaseApi<'_> { &mut self, entity_type: EntityType, ) -> Result { - let metadata = OntologyElementMetadata::Owned(OwnedOntologyElementMetadata::new( - entity_type.id().clone().into(), - ProvenanceMetadata::new(UpdatedById::new(self.account_id)), - OwnedById::new(self.account_id), - )); + let metadata = OntologyElementMetadata::Owned { + record_id: entity_type.id().clone().into(), + provenance: ProvenanceMetadata::new(UpdatedById::new(self.account_id)), + owned_by_id: OwnedById::new(self.account_id), + }; self.store .create_entity_type(entity_type, &metadata) From 9ef147793a1662eaaf57c0decaca9c891c3281a5 Mon Sep 17 00:00:00 2001 From: Tim Diekmann Date: Thu, 16 Feb 2023 22:23:51 +0100 Subject: [PATCH 06/19] Make fields on `ProvenanceMetadata` pub` pub --- apps/hash-graph/bench/util.rs | 12 +++++++--- .../bin/cli/src/subcommand/server.rs | 8 +++++-- .../lib/graph/src/api/rest/data_type.rs | 4 +++- .../lib/graph/src/api/rest/entity_type.rs | 4 +++- .../lib/graph/src/api/rest/property_type.rs | 8 ++++--- .../lib/graph/src/shared/provenance.rs | 14 +---------- .../hash-graph/lib/graph/src/store/fetcher.rs | 10 ++++---- .../lib/graph/src/store/postgres.rs | 6 ++--- .../src/store/postgres/knowledge/entity.rs | 8 ++++--- .../store/postgres/knowledge/entity/read.rs | 2 +- .../graph/src/store/postgres/ontology/read.rs | 2 +- .../tests/integration/postgres/lib.rs | 24 ++++++++++++++----- 12 files changed, 61 insertions(+), 41 deletions(-) diff --git a/apps/hash-graph/bench/util.rs b/apps/hash-graph/bench/util.rs index 14c6cf08bc1..a31246ee174 100644 --- a/apps/hash-graph/bench/util.rs +++ b/apps/hash-graph/bench/util.rs @@ -200,7 +200,9 @@ pub async fn seed( match store .create_data_type(data_type.clone(), &OntologyElementMetadata::Owned { record_id: data_type.id().clone().into(), - provenance: ProvenanceMetadata::new(UpdatedById::new(account_id)), + provenance: ProvenanceMetadata { + updated_by_id: UpdatedById::new(account_id), + }, owned_by_id: OwnedById::new(account_id), }) .await @@ -228,7 +230,9 @@ pub async fn seed( match store .create_property_type(property_type.clone(), &OntologyElementMetadata::Owned { record_id: property_type.id().clone().into(), - provenance: ProvenanceMetadata::new(UpdatedById::new(account_id)), + provenance: ProvenanceMetadata { + updated_by_id: UpdatedById::new(account_id), + }, owned_by_id: OwnedById::new(account_id), }) .await @@ -256,7 +260,9 @@ pub async fn seed( match store .create_entity_type(entity_type.clone(), &OntologyElementMetadata::Owned { record_id: entity_type.id().clone().into(), - provenance: ProvenanceMetadata::new(UpdatedById::new(account_id)), + provenance: ProvenanceMetadata { + updated_by_id: UpdatedById::new(account_id), + }, owned_by_id: OwnedById::new(account_id), }) .await diff --git a/apps/hash-graph/bin/cli/src/subcommand/server.rs b/apps/hash-graph/bin/cli/src/subcommand/server.rs index ff24a1df95e..f7a64762ca6 100644 --- a/apps/hash-graph/bin/cli/src/subcommand/server.rs +++ b/apps/hash-graph/bin/cli/src/subcommand/server.rs @@ -213,7 +213,9 @@ async fn stop_gap_setup(pool: &PostgresStorePool) -> Result<(), GraphErro let data_type_metadata = OntologyElementMetadata::External(ExternalOntologyElementMetadata::new( data_type.id().into(), - ProvenanceMetadata::new(UpdatedById::new(root_account_id)), + ProvenanceMetadata { + updated_by_id: UpdatedById::new(root_account_id), + }, OffsetDateTime::now_utc(), )); @@ -251,7 +253,9 @@ async fn stop_gap_setup(pool: &PostgresStorePool) -> Result<(), GraphErro let link_entity_type_metadata = OntologyElementMetadata::External(ExternalOntologyElementMetadata::new( link_entity_type.id().into(), - ProvenanceMetadata::new(UpdatedById::new(root_account_id)), + ProvenanceMetadata { + updated_by_id: UpdatedById::new(root_account_id), + }, OffsetDateTime::now_utc(), )); diff --git a/apps/hash-graph/lib/graph/src/api/rest/data_type.rs b/apps/hash-graph/lib/graph/src/api/rest/data_type.rs index cbdb372ff30..d1a1bb1b55b 100644 --- a/apps/hash-graph/lib/graph/src/api/rest/data_type.rs +++ b/apps/hash-graph/lib/graph/src/api/rest/data_type.rs @@ -111,7 +111,9 @@ async fn create_data_type( let metadata = OntologyElementMetadata::Owned { record_id: data_type.id().clone().into(), - provenance: ProvenanceMetadata::new(actor_id), + provenance: ProvenanceMetadata { + updated_by_id: actor_id, + }, owned_by_id, }; diff --git a/apps/hash-graph/lib/graph/src/api/rest/entity_type.rs b/apps/hash-graph/lib/graph/src/api/rest/entity_type.rs index bc0e8f3e49d..b5b9ebee29e 100644 --- a/apps/hash-graph/lib/graph/src/api/rest/entity_type.rs +++ b/apps/hash-graph/lib/graph/src/api/rest/entity_type.rs @@ -119,7 +119,9 @@ async fn create_entity_type( let metadata = OntologyElementMetadata::Owned { record_id: entity_type.id().clone().into(), - provenance: ProvenanceMetadata::new(actor_id), + provenance: ProvenanceMetadata { + updated_by_id: actor_id, + }, owned_by_id, }; diff --git a/apps/hash-graph/lib/graph/src/api/rest/property_type.rs b/apps/hash-graph/lib/graph/src/api/rest/property_type.rs index b8c8d156d13..89aea5ad769 100644 --- a/apps/hash-graph/lib/graph/src/api/rest/property_type.rs +++ b/apps/hash-graph/lib/graph/src/api/rest/property_type.rs @@ -14,8 +14,8 @@ use crate::{ api::rest::{report_to_status_code, utoipa_typedef::subgraph::Subgraph}, ontology::{ domain_validator::{DomainValidator, ValidateOntologyType}, - patch_id_and_parse, OntologyElementMetadata, - PropertyTypeQueryToken, PropertyTypeWithMetadata, + patch_id_and_parse, OntologyElementMetadata, PropertyTypeQueryToken, + PropertyTypeWithMetadata, }, provenance::{OwnedById, ProvenanceMetadata, UpdatedById}, store::{BaseUriAlreadyExists, BaseUriDoesNotExist, PropertyTypeStore, StorePool}, @@ -117,7 +117,9 @@ async fn create_property_type( let metadata = OntologyElementMetadata::Owned { record_id: property_type.id().clone().into(), - provenance: ProvenanceMetadata::new(actor_id), + provenance: ProvenanceMetadata { + updated_by_id: actor_id, + }, owned_by_id, }; diff --git a/apps/hash-graph/lib/graph/src/shared/provenance.rs b/apps/hash-graph/lib/graph/src/shared/provenance.rs index 6985bc46e32..4a1809a87cc 100644 --- a/apps/hash-graph/lib/graph/src/shared/provenance.rs +++ b/apps/hash-graph/lib/graph/src/shared/provenance.rs @@ -53,17 +53,5 @@ define_provenance_id!(UpdatedById); #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, ToSchema)] #[serde(deny_unknown_fields, rename_all = "camelCase")] pub struct ProvenanceMetadata { - updated_by_id: UpdatedById, -} - -impl ProvenanceMetadata { - #[must_use] - pub const fn new(updated_by_id: UpdatedById) -> Self { - Self { updated_by_id } - } - - #[must_use] - pub const fn updated_by_id(&self) -> UpdatedById { - self.updated_by_id - } + pub updated_by_id: UpdatedById, } diff --git a/apps/hash-graph/lib/graph/src/store/fetcher.rs b/apps/hash-graph/lib/graph/src/store/fetcher.rs index f92fe3c9f60..5431d4578a7 100644 --- a/apps/hash-graph/lib/graph/src/store/fetcher.rs +++ b/apps/hash-graph/lib/graph/src/store/fetcher.rs @@ -210,7 +210,9 @@ where let mut entity_types = Vec::new(); for (reference, fetched_by) in ontology_type_references { - let provenance = ProvenanceMetadata::new(fetched_by); + let provenance = ProvenanceMetadata { + updated_by_id: fetched_by, + }; let fetched_ontology_types = fetcher_client .fetch_ontology_type_exhaustive(context::current(), reference.uri().clone()) .await @@ -398,7 +400,7 @@ where self.insert_external_types(data_types.iter().map(|(data_type, metadata)| { ( data_type, - metadata.borrow().provenance_metadata().updated_by_id(), + metadata.borrow().provenance_metadata().updated_by_id, ) })) .await?; @@ -447,7 +449,7 @@ where self.insert_external_types(property_types.iter().map(|(property_type, metadata)| { ( property_type, - metadata.borrow().provenance_metadata().updated_by_id(), + metadata.borrow().provenance_metadata().updated_by_id, ) })) .await?; @@ -498,7 +500,7 @@ where self.insert_external_types(entity_types.iter().map(|(entity_type, metadata)| { ( entity_type, - metadata.borrow().provenance_metadata().updated_by_id(), + metadata.borrow().provenance_metadata().updated_by_id, ) })) .await?; diff --git a/apps/hash-graph/lib/graph/src/store/postgres.rs b/apps/hash-graph/lib/graph/src/store/postgres.rs index 45a3c5f01db..573e9a85479 100644 --- a/apps/hash-graph/lib/graph/src/store/postgres.rs +++ b/apps/hash-graph/lib/graph/src/store/postgres.rs @@ -271,7 +271,7 @@ where &record_id.base_uri.as_str(), &record_id.version, &owned_by_id, - &provenance.updated_by_id(), + &provenance.updated_by_id, ], ) .await @@ -315,7 +315,7 @@ where &record_id.base_uri.as_str(), &record_id.version, &fetched_at, - &provenance.updated_by_id(), + &provenance.updated_by_id, ], ) .await @@ -464,7 +464,7 @@ where Ok((ontology_id, OntologyElementMetadata::Owned { record_id, - provenance: ProvenanceMetadata::new(updated_by_id), + provenance: ProvenanceMetadata { updated_by_id }, owned_by_id, })) } diff --git a/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity.rs b/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity.rs index 3d8f6072e77..9b5391425e4 100644 --- a/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity.rs +++ b/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity.rs @@ -380,7 +380,7 @@ impl EntityStore for PostgresStore { transaction_time: row.get(2), }, entity_type_id, - provenance: ProvenanceMetadata::new(updated_by_id), + provenance: ProvenanceMetadata { updated_by_id }, archived, }) } @@ -469,7 +469,9 @@ impl EntityStore for PostgresStore { }, version, entity_type_id: entity_type_id.clone(), - provenance: ProvenanceMetadata::new(actor_id), + provenance: ProvenanceMetadata { + updated_by_id: actor_id, + }, archived: false, }) .collect()) @@ -612,7 +614,7 @@ impl EntityStore for PostgresStore { transaction_time: row.get(2), }, entity_type_id, - provenance: ProvenanceMetadata::new(updated_by_id), + provenance: ProvenanceMetadata { updated_by_id }, archived, }) } diff --git a/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity/read.rs b/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity/read.rs index 49a6c857181..9916b4e3fc1 100644 --- a/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity/read.rs +++ b/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity/read.rs @@ -144,7 +144,7 @@ impl crud::Read for PostgresStore { transaction_time: row.get(transaction_time_index), }, entity_type_uri, - ProvenanceMetadata::new(updated_by_id), + ProvenanceMetadata { updated_by_id }, // TODO: only the historic table would have an `archived` field. // Consider what we should do about that. row.get(archived_index), diff --git a/apps/hash-graph/lib/graph/src/store/postgres/ontology/read.rs b/apps/hash-graph/lib/graph/src/store/postgres/ontology/read.rs index b9b32d590a0..33f38b0b421 100644 --- a/apps/hash-graph/lib/graph/src/store/postgres/ontology/read.rs +++ b/apps/hash-graph/lib/graph/src/store/postgres/ontology/read.rs @@ -111,7 +111,7 @@ where .change_context(QueryError)?; let record_id = OntologyTypeRecordId { base_uri, version }; - let provenance = ProvenanceMetadata::new(updated_by_id); + let provenance = ProvenanceMetadata { updated_by_id }; Ok(T::new(record, match metadata { AdditionalOntologyMetadata::Owned { owned_by_id } => { diff --git a/apps/hash-graph/tests/integration/postgres/lib.rs b/apps/hash-graph/tests/integration/postgres/lib.rs index 88c1b3abd24..4cfca6a67b8 100644 --- a/apps/hash-graph/tests/integration/postgres/lib.rs +++ b/apps/hash-graph/tests/integration/postgres/lib.rs @@ -124,7 +124,9 @@ impl DatabaseTestWrapper { let metadata = OntologyElementMetadata::Owned { record_id: data_type.id().clone().into(), - provenance: ProvenanceMetadata::new(UpdatedById::new(account_id)), + provenance: ProvenanceMetadata { + updated_by_id: UpdatedById::new(account_id), + }, owned_by_id: OwnedById::new(account_id), }; @@ -140,7 +142,9 @@ impl DatabaseTestWrapper { let metadata = OntologyElementMetadata::Owned { record_id: property_type.id().clone().into(), - provenance: ProvenanceMetadata::new(UpdatedById::new(account_id)), + provenance: ProvenanceMetadata { + updated_by_id: UpdatedById::new(account_id), + }, owned_by_id: OwnedById::new(account_id), }; @@ -156,7 +160,9 @@ impl DatabaseTestWrapper { let metadata = OntologyElementMetadata::Owned { record_id: entity_type.id().clone().into(), - provenance: ProvenanceMetadata::new(UpdatedById::new(account_id)), + provenance: ProvenanceMetadata { + updated_by_id: UpdatedById::new(account_id), + }, owned_by_id: OwnedById::new(account_id), }; @@ -189,7 +195,9 @@ impl DatabaseApi<'_> { ) -> Result { let metadata = OntologyElementMetadata::Owned { record_id: data_type.id().clone().into(), - provenance: ProvenanceMetadata::new(UpdatedById::new(self.account_id)), + provenance: ProvenanceMetadata { + updated_by_id: UpdatedById::new(self.account_id), + }, owned_by_id: OwnedById::new(self.account_id), }; @@ -234,7 +242,9 @@ impl DatabaseApi<'_> { ) -> Result { let metadata = OntologyElementMetadata::Owned { record_id: property_type.id().clone().into(), - provenance: ProvenanceMetadata::new(UpdatedById::new(self.account_id)), + provenance: ProvenanceMetadata { + updated_by_id: UpdatedById::new(self.account_id), + }, owned_by_id: OwnedById::new(self.account_id), }; @@ -281,7 +291,9 @@ impl DatabaseApi<'_> { ) -> Result { let metadata = OntologyElementMetadata::Owned { record_id: entity_type.id().clone().into(), - provenance: ProvenanceMetadata::new(UpdatedById::new(self.account_id)), + provenance: ProvenanceMetadata { + updated_by_id: UpdatedById::new(self.account_id), + }, owned_by_id: OwnedById::new(self.account_id), }; From 4d78aea872fa8b413d21d542ccef01b5ae647fbb Mon Sep 17 00:00:00 2001 From: Tim Diekmann Date: Thu, 16 Feb 2023 22:31:19 +0100 Subject: [PATCH 07/19] Make fields on `EntityId` pub` pub --- .../lib/graph/src/knowledge/entity.rs | 1 + .../graph/src/shared/identifier/knowledge.rs | 24 +----- .../lib/graph/src/shared/provenance.rs | 15 +++- .../lib/graph/src/store/postgres.rs | 26 +++--- .../src/store/postgres/knowledge/entity.rs | 30 +++---- .../store/postgres/knowledge/entity/read.rs | 31 +++---- .../store/postgres/query/statement/select.rs | 60 +++++++------- .../lib/graph/src/store/query/filter.rs | 80 +++++++++---------- .../tests/integration/postgres/lib.rs | 8 +- 9 files changed, 138 insertions(+), 137 deletions(-) diff --git a/apps/hash-graph/lib/graph/src/knowledge/entity.rs b/apps/hash-graph/lib/graph/src/knowledge/entity.rs index da672b18430..5e588908599 100644 --- a/apps/hash-graph/lib/graph/src/knowledge/entity.rs +++ b/apps/hash-graph/lib/graph/src/knowledge/entity.rs @@ -31,6 +31,7 @@ use crate::{ Serialize, Deserialize, ToSchema, + FromSql, ToSql, )] #[postgres(transparent)] diff --git a/apps/hash-graph/lib/graph/src/shared/identifier/knowledge.rs b/apps/hash-graph/lib/graph/src/shared/identifier/knowledge.rs index ef5fd4ff4f3..4a35b83cf96 100644 --- a/apps/hash-graph/lib/graph/src/shared/identifier/knowledge.rs +++ b/apps/hash-graph/lib/graph/src/shared/identifier/knowledge.rs @@ -25,28 +25,8 @@ use crate::{ #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct EntityId { - owned_by_id: OwnedById, - entity_uuid: EntityUuid, -} - -impl EntityId { - #[must_use] - pub const fn new(owned_by_id: OwnedById, entity_uuid: EntityUuid) -> Self { - Self { - owned_by_id, - entity_uuid, - } - } - - #[must_use] - pub const fn owned_by_id(&self) -> OwnedById { - self.owned_by_id - } - - #[must_use] - pub const fn entity_uuid(&self) -> EntityUuid { - self.entity_uuid - } + pub owned_by_id: OwnedById, + pub entity_uuid: EntityUuid, } impl Serialize for EntityId { diff --git a/apps/hash-graph/lib/graph/src/shared/provenance.rs b/apps/hash-graph/lib/graph/src/shared/provenance.rs index 4a1809a87cc..60a9ccd1339 100644 --- a/apps/hash-graph/lib/graph/src/shared/provenance.rs +++ b/apps/hash-graph/lib/graph/src/shared/provenance.rs @@ -1,7 +1,7 @@ use core::fmt; use serde::{Deserialize, Serialize}; -use tokio_postgres::types::ToSql; +use tokio_postgres::types::{FromSql, ToSql}; use utoipa::{openapi, ToSchema}; use uuid::Uuid; @@ -10,7 +10,18 @@ use crate::identifier::account::AccountId; macro_rules! define_provenance_id { ($name:tt) => { #[derive( - Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize, ToSql, + Debug, + Copy, + Clone, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + Serialize, + Deserialize, + FromSql, + ToSql, )] #[postgres(transparent)] #[repr(transparent)] diff --git a/apps/hash-graph/lib/graph/src/store/postgres.rs b/apps/hash-graph/lib/graph/src/store/postgres.rs index 573e9a85479..e02f487b216 100644 --- a/apps/hash-graph/lib/graph/src/store/postgres.rs +++ b/apps/hash-graph/lib/graph/src/store/postgres.rs @@ -785,17 +785,25 @@ impl PostgresStore> { writer .as_mut() .write(&[ - &entity_id.owned_by_id(), - &entity_id.entity_uuid(), - &left_entity_id.as_ref().map(EntityId::owned_by_id), - &left_entity_id.as_ref().map(EntityId::entity_uuid), - &right_entity_id.as_ref().map(EntityId::owned_by_id), - &right_entity_id.as_ref().map(EntityId::entity_uuid), + &entity_id.owned_by_id, + &entity_id.entity_uuid, + &left_entity_id + .as_ref() + .map(|entity_id| entity_id.owned_by_id), + &left_entity_id + .as_ref() + .map(|entity_id| entity_id.entity_uuid), + &right_entity_id + .as_ref() + .map(|entity_id| entity_id.owned_by_id), + &right_entity_id + .as_ref() + .map(|entity_id| entity_id.entity_uuid), ]) .await .into_report() .change_context(InsertionError) - .attach_printable(entity_id.entity_uuid())?; + .attach_printable(entity_id.entity_uuid)?; } writer @@ -967,8 +975,8 @@ impl PostgresStore> { writer .as_mut() .write(&[ - &entity_id.owned_by_id(), - &entity_id.entity_uuid(), + &entity_id.owned_by_id, + &entity_id.entity_uuid, &entity_edition_id, &decision_time, ]) diff --git a/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity.rs b/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity.rs index 9b5391425e4..3627ce0492b 100644 --- a/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity.rs +++ b/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity.rs @@ -303,10 +303,10 @@ impl EntityStore for PostgresStore { properties: EntityProperties, link_data: Option, ) -> Result { - let entity_id = EntityId::new( + let entity_id = EntityId { owned_by_id, - entity_uuid.unwrap_or_else(|| EntityUuid::new(Uuid::new_v4())), - ); + entity_uuid: entity_uuid.unwrap_or_else(|| EntityUuid::new(Uuid::new_v4())), + }; let entity_type_ontology_id = self .ontology_id_by_uri(&entity_type_id) @@ -343,8 +343,8 @@ impl EntityStore for PostgresStore { ); "#, &[ - &entity_id.owned_by_id(), - &entity_id.entity_uuid(), + &entity_id.owned_by_id, + &entity_id.entity_uuid, &decision_time, &updated_by_id, &archived, @@ -352,16 +352,16 @@ impl EntityStore for PostgresStore { &properties, &link_data .as_ref() - .map(|metadata| metadata.left_entity_id().owned_by_id()), + .map(|metadata| metadata.left_entity_id().owned_by_id), &link_data .as_ref() - .map(|metadata| metadata.left_entity_id().entity_uuid()), + .map(|metadata| metadata.left_entity_id().entity_uuid), &link_data .as_ref() - .map(|metadata| metadata.right_entity_id().owned_by_id()), + .map(|metadata| metadata.right_entity_id().owned_by_id), &link_data .as_ref() - .map(|metadata| metadata.right_entity_id().entity_uuid()), + .map(|metadata| metadata.right_entity_id().entity_uuid), &link_data.as_ref().map(LinkData::left_to_right_order), &link_data.as_ref().map(LinkData::right_to_left_order), ], @@ -410,10 +410,10 @@ impl EntityStore for PostgresStore { let mut entity_versions = Vec::with_capacity(entities.size_hint().0); for (owned_by_id, entity_uuid, properties, link_data, decision_time) in entities { entity_ids.push(( - EntityId::new( + EntityId { owned_by_id, - entity_uuid.unwrap_or_else(|| EntityUuid::new(Uuid::new_v4())), - ), + entity_uuid: entity_uuid.unwrap_or_else(|| EntityUuid::new(Uuid::new_v4())), + }, link_data.as_ref().map(LinkData::left_entity_id), link_data.as_ref().map(LinkData::right_entity_id), )); @@ -547,7 +547,7 @@ impl EntityStore for PostgresStore { SELECT EXISTS ( SELECT 1 FROM entity_ids WHERE owned_by_id = $1 AND entity_uuid = $2 );"#, - &[&entity_id.owned_by_id(), &entity_id.entity_uuid()], + &[&entity_id.owned_by_id, &entity_id.entity_uuid], ) .await .into_report() @@ -581,8 +581,8 @@ impl EntityStore for PostgresStore { ); "#, &[ - &entity_id.owned_by_id(), - &entity_id.entity_uuid(), + &entity_id.owned_by_id, + &entity_id.entity_uuid, &decision_time, &updated_by_id, &archived, diff --git a/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity/read.rs b/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity/read.rs index 9916b4e3fc1..de15077dfc6 100644 --- a/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity/read.rs +++ b/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity/read.rs @@ -15,7 +15,7 @@ use crate::{ }, knowledge::{Entity, EntityProperties, EntityQueryPath, EntityUuid, LinkData}, ontology::EntityTypeQueryPath, - provenance::{OwnedById, ProvenanceMetadata, UpdatedById}, + provenance::{OwnedById, ProvenanceMetadata}, store::{ crud, postgres::query::{Distinctness, SelectCompiler}, @@ -109,14 +109,14 @@ impl crud::Read for PostgresStore { Some(right_owned_by_id), Some(right_entity_uuid), ) => Some(LinkData::new( - EntityId::new( - OwnedById::new(left_owned_by_id), - EntityUuid::new(left_entity_uuid), - ), - EntityId::new( - OwnedById::new(right_owned_by_id), - EntityUuid::new(right_entity_uuid), - ), + EntityId { + owned_by_id: OwnedById::new(left_owned_by_id), + entity_uuid: EntityUuid::new(left_entity_uuid), + }, + EntityId { + owned_by_id: OwnedById::new(right_owned_by_id), + entity_uuid: EntityUuid::new(right_entity_uuid), + }, row.get(left_to_right_order_index), row.get(right_to_left_order_index), )), @@ -128,15 +128,14 @@ impl crud::Read for PostgresStore { } }; - let owned_by_id = OwnedById::new(row.get(owned_by_id_index)); - let entity_uuid = EntityUuid::new(row.get(entity_uuid_index)); - let updated_by_id = UpdatedById::new(row.get(updated_by_id_index)); - Ok(Entity::new( properties, link_data, EntityRecordId { - entity_id: EntityId::new(owned_by_id, entity_uuid), + entity_id: EntityId { + owned_by_id: row.get(owned_by_id_index), + entity_uuid: row.get(entity_uuid_index), + }, edition_id: EntityEditionId::new(row.get(edition_id_index)), }, EntityVersion { @@ -144,7 +143,9 @@ impl crud::Read for PostgresStore { transaction_time: row.get(transaction_time_index), }, entity_type_uri, - ProvenanceMetadata { updated_by_id }, + ProvenanceMetadata { + updated_by_id: row.get(updated_by_id_index), + }, // TODO: only the historic table would have an `archived` field. // Consider what we should do about that. row.get(archived_index), diff --git a/apps/hash-graph/lib/graph/src/store/postgres/query/statement/select.rs b/apps/hash-graph/lib/graph/src/store/postgres/query/statement/select.rs index 7dd53015be9..711c939c98b 100644 --- a/apps/hash-graph/lib/graph/src/store/postgres/query/statement/select.rs +++ b/apps/hash-graph/lib/graph/src/store/postgres/query/statement/select.rs @@ -838,10 +838,10 @@ mod tests { #[test] fn for_entity_by_entity_id() { - let entity_id = EntityId::new( - OwnedById::new(AccountId::new(Uuid::new_v4())), - EntityUuid::new(Uuid::new_v4()), - ); + let entity_id = EntityId { + owned_by_id: OwnedById::new(AccountId::new(Uuid::new_v4())), + entity_uuid: EntityUuid::new(Uuid::new_v4()), + }; let time_projection = UnresolvedTimeProjection::default().resolve(); let kernel = time_projection.kernel().cast::(); @@ -863,18 +863,18 @@ mod tests { &[ &kernel, &time_projection.image(), - &entity_id.owned_by_id().as_uuid(), - &entity_id.entity_uuid().as_uuid(), + &entity_id.owned_by_id.as_uuid(), + &entity_id.entity_uuid.as_uuid(), ], ); } #[test] fn for_incoming_link_by_source_entity_id() { - let entity_id = EntityId::new( - OwnedById::new(AccountId::new(Uuid::new_v4())), - EntityUuid::new(Uuid::new_v4()), - ); + let entity_id = EntityId { + owned_by_id: OwnedById::new(AccountId::new(Uuid::new_v4())), + entity_uuid: EntityUuid::new(Uuid::new_v4()), + }; let time_projection = UnresolvedTimeProjection::default().resolve(); let kernel = time_projection.kernel().cast::(); @@ -896,18 +896,18 @@ mod tests { &[ &kernel, &time_projection.image(), - &entity_id.owned_by_id().as_uuid(), - &entity_id.entity_uuid().as_uuid(), + &entity_id.owned_by_id.as_uuid(), + &entity_id.entity_uuid.as_uuid(), ], ); } #[test] fn for_outgoing_link_by_source_entity_id() { - let entity_id = EntityId::new( - OwnedById::new(AccountId::new(Uuid::new_v4())), - EntityUuid::new(Uuid::new_v4()), - ); + let entity_id = EntityId { + owned_by_id: OwnedById::new(AccountId::new(Uuid::new_v4())), + entity_uuid: EntityUuid::new(Uuid::new_v4()), + }; let time_projection = UnresolvedTimeProjection::default().resolve(); let kernel = time_projection.kernel().cast::(); @@ -929,18 +929,18 @@ mod tests { &[ &kernel, &time_projection.image(), - &entity_id.owned_by_id().as_uuid(), - &entity_id.entity_uuid().as_uuid(), + &entity_id.owned_by_id.as_uuid(), + &entity_id.entity_uuid.as_uuid(), ], ); } #[test] fn for_left_entity_by_entity_id() { - let entity_id = EntityId::new( - OwnedById::new(AccountId::new(Uuid::new_v4())), - EntityUuid::new(Uuid::new_v4()), - ); + let entity_id = EntityId { + owned_by_id: OwnedById::new(AccountId::new(Uuid::new_v4())), + entity_uuid: EntityUuid::new(Uuid::new_v4()), + }; let time_projection = UnresolvedTimeProjection::default().resolve(); let kernel = time_projection.kernel().cast::(); @@ -966,18 +966,18 @@ mod tests { &[ &kernel, &time_projection.image(), - &entity_id.owned_by_id().as_uuid(), - &entity_id.entity_uuid().as_uuid(), + &entity_id.owned_by_id.as_uuid(), + &entity_id.entity_uuid.as_uuid(), ], ); } #[test] fn for_right_entity_by_entity_id() { - let entity_id = EntityId::new( - OwnedById::new(AccountId::new(Uuid::new_v4())), - EntityUuid::new(Uuid::new_v4()), - ); + let entity_id = EntityId { + owned_by_id: OwnedById::new(AccountId::new(Uuid::new_v4())), + entity_uuid: EntityUuid::new(Uuid::new_v4()), + }; let time_projection = UnresolvedTimeProjection::default().resolve(); let kernel = time_projection.kernel().cast::(); @@ -1003,8 +1003,8 @@ mod tests { &[ &kernel, &time_projection.image(), - &entity_id.owned_by_id().as_uuid(), - &entity_id.entity_uuid().as_uuid(), + &entity_id.owned_by_id.as_uuid(), + &entity_id.entity_uuid.as_uuid(), ], ); } diff --git a/apps/hash-graph/lib/graph/src/store/query/filter.rs b/apps/hash-graph/lib/graph/src/store/query/filter.rs index e33eac84f7f..a5b1dd359ca 100644 --- a/apps/hash-graph/lib/graph/src/store/query/filter.rs +++ b/apps/hash-graph/lib/graph/src/store/query/filter.rs @@ -111,13 +111,13 @@ impl<'p> Filter<'p, Entity> { Self::Equal( Some(FilterExpression::Path(EntityQueryPath::OwnedById)), Some(FilterExpression::Parameter(Parameter::Uuid( - entity_id.owned_by_id().as_uuid(), + entity_id.owned_by_id.as_uuid(), ))), ), Self::Equal( Some(FilterExpression::Path(EntityQueryPath::Uuid)), Some(FilterExpression::Parameter(Parameter::Uuid( - entity_id.entity_uuid().as_uuid(), + entity_id.entity_uuid.as_uuid(), ))), ), ]) @@ -133,7 +133,7 @@ impl<'p> Filter<'p, Entity> { Box::new(EntityQueryPath::OwnedById), ))), Some(FilterExpression::Parameter(Parameter::Uuid( - entity_id.owned_by_id().as_uuid(), + entity_id.owned_by_id.as_uuid(), ))), ), Self::Equal( @@ -141,7 +141,7 @@ impl<'p> Filter<'p, Entity> { Box::new(EntityQueryPath::Uuid), ))), Some(FilterExpression::Parameter(Parameter::Uuid( - entity_id.entity_uuid().as_uuid(), + entity_id.entity_uuid.as_uuid(), ))), ), ]) @@ -157,7 +157,7 @@ impl<'p> Filter<'p, Entity> { Box::new(EntityQueryPath::OwnedById), ))), Some(FilterExpression::Parameter(Parameter::Uuid( - entity_id.owned_by_id().as_uuid(), + entity_id.owned_by_id.as_uuid(), ))), ), Self::Equal( @@ -165,7 +165,7 @@ impl<'p> Filter<'p, Entity> { Box::new(EntityQueryPath::Uuid), ))), Some(FilterExpression::Parameter(Parameter::Uuid( - entity_id.entity_uuid().as_uuid(), + entity_id.entity_uuid.as_uuid(), ))), ), ]) @@ -181,7 +181,7 @@ impl<'p> Filter<'p, Entity> { Box::new(EntityQueryPath::OwnedById), ))), Some(FilterExpression::Parameter(Parameter::Uuid( - entity_id.owned_by_id().as_uuid(), + entity_id.owned_by_id.as_uuid(), ))), ), Self::Equal( @@ -189,7 +189,7 @@ impl<'p> Filter<'p, Entity> { Box::new(EntityQueryPath::Uuid), ))), Some(FilterExpression::Parameter(Parameter::Uuid( - entity_id.entity_uuid().as_uuid(), + entity_id.entity_uuid.as_uuid(), ))), ), ]) @@ -205,7 +205,7 @@ impl<'p> Filter<'p, Entity> { Box::new(EntityQueryPath::OwnedById), ))), Some(FilterExpression::Parameter(Parameter::Uuid( - entity_id.owned_by_id().as_uuid(), + entity_id.owned_by_id.as_uuid(), ))), ), Self::Equal( @@ -213,7 +213,7 @@ impl<'p> Filter<'p, Entity> { Box::new(EntityQueryPath::Uuid), ))), Some(FilterExpression::Parameter(Parameter::Uuid( - entity_id.entity_uuid().as_uuid(), + entity_id.entity_uuid.as_uuid(), ))), ), ]) @@ -498,20 +498,20 @@ mod tests { #[test] fn for_entity_by_entity_id() { - let entity_id = EntityId::new( - OwnedById::new(AccountId::new(Uuid::new_v4())), - EntityUuid::new(Uuid::new_v4()), - ); + let entity_id = EntityId { + owned_by_id: OwnedById::new(AccountId::new(Uuid::new_v4())), + entity_uuid: EntityUuid::new(Uuid::new_v4()), + }; let expected = json! {{ "all": [ { "equal": [ { "path": ["ownedById"] }, - { "parameter": entity_id.owned_by_id() } + { "parameter": entity_id.owned_by_id } ]}, { "equal": [ { "path": ["uuid"] }, - { "parameter": entity_id.entity_uuid() } + { "parameter": entity_id.entity_uuid } ]} ] }}; @@ -521,20 +521,20 @@ mod tests { #[test] fn for_entity_by_id() { - let entity_id = EntityId::new( - OwnedById::new(AccountId::new(Uuid::new_v4())), - EntityUuid::new(Uuid::new_v4()), - ); + let entity_id = EntityId { + owned_by_id: OwnedById::new(AccountId::new(Uuid::new_v4())), + entity_uuid: EntityUuid::new(Uuid::new_v4()), + }; let expected = json! {{ "all": [ { "equal": [ { "path": ["ownedById"] }, - { "parameter": entity_id.owned_by_id() } + { "parameter": entity_id.owned_by_id } ]}, { "equal": [ { "path": ["uuid"] }, - { "parameter": entity_id.entity_uuid() } + { "parameter": entity_id.entity_uuid } ]} ] }}; @@ -544,20 +544,20 @@ mod tests { #[test] fn for_outgoing_link_by_source_entity_id() { - let entity_id = EntityId::new( - OwnedById::new(AccountId::new(Uuid::new_v4())), - EntityUuid::new(Uuid::new_v4()), - ); + let entity_id = EntityId { + owned_by_id: OwnedById::new(AccountId::new(Uuid::new_v4())), + entity_uuid: EntityUuid::new(Uuid::new_v4()), + }; let expected = json! {{ "all": [ { "equal": [ { "path": ["leftEntity", "ownedById"] }, - { "parameter": entity_id.owned_by_id() } + { "parameter": entity_id.owned_by_id } ]}, { "equal": [ { "path": ["leftEntity", "uuid"] }, - { "parameter": entity_id.entity_uuid() } + { "parameter": entity_id.entity_uuid } ]} ] }}; @@ -570,20 +570,20 @@ mod tests { #[test] fn for_left_entity_by_entity_id() { - let entity_id = EntityId::new( - OwnedById::new(AccountId::new(Uuid::new_v4())), - EntityUuid::new(Uuid::new_v4()), - ); + let entity_id = EntityId { + owned_by_id: OwnedById::new(AccountId::new(Uuid::new_v4())), + entity_uuid: EntityUuid::new(Uuid::new_v4()), + }; let expected = json! {{ "all": [ { "equal": [ { "path": ["outgoingLinks", "ownedById"] }, - { "parameter": entity_id.owned_by_id() } + { "parameter": entity_id.owned_by_id } ]}, { "equal": [ { "path": ["outgoingLinks", "uuid"] }, - { "parameter": entity_id.entity_uuid() } + { "parameter": entity_id.entity_uuid } ]} ] }}; @@ -593,20 +593,20 @@ mod tests { #[test] fn for_right_entity_by_entity_id() { - let entity_id = EntityId::new( - OwnedById::new(AccountId::new(Uuid::new_v4())), - EntityUuid::new(Uuid::new_v4()), - ); + let entity_id = EntityId { + owned_by_id: OwnedById::new(AccountId::new(Uuid::new_v4())), + entity_uuid: EntityUuid::new(Uuid::new_v4()), + }; let expected = json! {{ "all": [ { "equal": [ { "path": ["incomingLinks", "ownedById"] }, - { "parameter": entity_id.owned_by_id() } + { "parameter": entity_id.owned_by_id } ]}, { "equal": [ { "path": ["incomingLinks", "uuid"] }, - { "parameter": entity_id.entity_uuid() } + { "parameter": entity_id.entity_uuid } ]} ] }}; diff --git a/apps/hash-graph/tests/integration/postgres/lib.rs b/apps/hash-graph/tests/integration/postgres/lib.rs index 4cfca6a67b8..fde1915ec6a 100644 --- a/apps/hash-graph/tests/integration/postgres/lib.rs +++ b/apps/hash-graph/tests/integration/postgres/lib.rs @@ -472,7 +472,7 @@ impl DatabaseApi<'_> { Box::new(EntityQueryPath::Uuid), ))), Some(FilterExpression::Parameter(Parameter::Uuid( - source_entity_id.entity_uuid().as_uuid(), + source_entity_id.entity_uuid.as_uuid(), ))), ), Filter::Equal( @@ -480,7 +480,7 @@ impl DatabaseApi<'_> { Box::new(EntityQueryPath::OwnedById), ))), Some(FilterExpression::Parameter(Parameter::Uuid( - source_entity_id.owned_by_id().as_uuid(), + source_entity_id.owned_by_id.as_uuid(), ))), ), Filter::Equal( @@ -540,7 +540,7 @@ impl DatabaseApi<'_> { Box::new(EntityQueryPath::Uuid), ))), Some(FilterExpression::Parameter(Parameter::Uuid( - source_entity_id.entity_uuid().as_uuid(), + source_entity_id.entity_uuid.as_uuid(), ))), ), Filter::Equal( @@ -548,7 +548,7 @@ impl DatabaseApi<'_> { Box::new(EntityQueryPath::OwnedById), ))), Some(FilterExpression::Parameter(Parameter::Uuid( - source_entity_id.owned_by_id().as_uuid(), + source_entity_id.owned_by_id.as_uuid(), ))), ), Filter::Equal( From 4958d8c17871fb9688c0279199c288613f76b9c3 Mon Sep 17 00:00:00 2001 From: Tim Diekmann Date: Thu, 16 Feb 2023 22:37:41 +0100 Subject: [PATCH 08/19] Make fields on `Entity` pub` pub --- .../lib/graph/src/knowledge/entity.rs | 52 +++---------------- .../lib/graph/src/knowledge/entity/query.rs | 4 +- .../src/store/postgres/knowledge/entity.rs | 12 ++--- .../store/postgres/knowledge/entity/read.rs | 40 +++++++------- .../tests/integration/postgres/entity.rs | 10 ++-- .../tests/integration/postgres/links.rs | 8 +-- 6 files changed, 43 insertions(+), 83 deletions(-) diff --git a/apps/hash-graph/lib/graph/src/knowledge/entity.rs b/apps/hash-graph/lib/graph/src/knowledge/entity.rs index 5e588908599..c63be1ae094 100644 --- a/apps/hash-graph/lib/graph/src/knowledge/entity.rs +++ b/apps/hash-graph/lib/graph/src/knowledge/entity.rs @@ -187,50 +187,10 @@ pub struct EntityMetadata { #[derive(Debug, PartialEq, Eq, Serialize, ToSchema)] #[serde(rename_all = "camelCase")] pub struct Entity { - properties: EntityProperties, + pub properties: EntityProperties, #[serde(default, skip_serializing_if = "Option::is_none")] - link_data: Option, - metadata: EntityMetadata, -} - -impl Entity { - #[must_use] - pub const fn new( - properties: EntityProperties, - link_data: Option, - record_id: EntityRecordId, - version: EntityVersion, - entity_type_id: VersionedUri, - provenance: ProvenanceMetadata, - archived: bool, - ) -> Self { - Self { - properties, - link_data, - metadata: EntityMetadata { - record_id, - version, - entity_type_id, - provenance, - archived, - }, - } - } - - #[must_use] - pub const fn properties(&self) -> &EntityProperties { - &self.properties - } - - #[must_use] - pub const fn link_data(&self) -> Option { - self.link_data - } - - #[must_use] - pub const fn metadata(&self) -> &EntityMetadata { - &self.metadata - } + pub link_data: Option, + pub metadata: EntityMetadata, } impl Record for Entity { @@ -239,10 +199,10 @@ impl Record for Entity { fn vertex_id(&self, time_axis: TimeAxis) -> Self::VertexId { let timestamp = match time_axis { - TimeAxis::DecisionTime => self.metadata().version.decision_time.start().cast(), - TimeAxis::TransactionTime => self.metadata().version.transaction_time.start().cast(), + TimeAxis::DecisionTime => self.metadata.version.decision_time.start().cast(), + TimeAxis::TransactionTime => self.metadata.version.transaction_time.start().cast(), }; - EntityVertexId::new(self.metadata().record_id.entity_id, timestamp.into()) + EntityVertexId::new(self.metadata.record_id.entity_id, timestamp.into()) } fn create_filter_for_vertex_id(vertex_id: &Self::VertexId) -> Filter { diff --git a/apps/hash-graph/lib/graph/src/knowledge/entity/query.rs b/apps/hash-graph/lib/graph/src/knowledge/entity/query.rs index cbe0928bf3f..cdbc1912afb 100644 --- a/apps/hash-graph/lib/graph/src/knowledge/entity/query.rs +++ b/apps/hash-graph/lib/graph/src/knowledge/entity/query.rs @@ -223,7 +223,7 @@ pub enum EntityQueryPath<'p> { /// /// [`LinkData::right_to_left_order()`]: crate::knowledge::LinkData::right_to_left_order RightToLeftOrder, - /// Corresponds to [`Entity::properties()`]. + /// Corresponds to [`Entity::properties`]. /// /// Deserializes from `["properties", ...]` where `...` is a path to a property URI of an /// [`Entity`]. @@ -246,7 +246,7 @@ pub enum EntityQueryPath<'p> { /// ``` /// /// [`Entity`]: crate::knowledge::Entity - /// [`Entity::properties()`]: crate::knowledge::Entity::properties + /// [`Entity::properties`]: crate::knowledge::Entity::properties Properties(Option>), } diff --git a/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity.rs b/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity.rs index 3627ce0492b..7a6a4b5c874 100644 --- a/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity.rs +++ b/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity.rs @@ -60,7 +60,7 @@ impl PostgresStore { }; let version_interval = entity - .metadata() + .metadata .version .projected_time(time_axis); @@ -100,7 +100,7 @@ impl PostgresStore { if current_resolve_depths.is_of_type.outgoing > 0 { let entity_type_id = - OntologyTypeVertexId::from(entity.metadata().entity_type_id.clone()); + OntologyTypeVertexId::from(entity.metadata.entity_type_id.clone()); subgraph.edges.insert(Edge::KnowledgeGraph { vertex_id: entity_vertex_id, @@ -142,7 +142,7 @@ impl PostgresStore { // outgoing link `Entity` kind: KnowledgeGraphEdgeKind::HasLeftEntity, reversed: true, - right_endpoint: outgoing_link_entity.metadata().record_id.entity_id, + right_endpoint: outgoing_link_entity.metadata.record_id.entity_id, }), }); @@ -181,7 +181,7 @@ impl PostgresStore { // incoming link `Entity` kind: KnowledgeGraphEdgeKind::HasRightEntity, reversed: true, - right_endpoint: incoming_link_entity.metadata().record_id.entity_id, + right_endpoint: incoming_link_entity.metadata.record_id.entity_id, }), }); @@ -220,7 +220,7 @@ impl PostgresStore { // outgoing `Link` `Entity` kind: KnowledgeGraphEdgeKind::HasLeftEntity, reversed: false, - right_endpoint: left_entity.metadata().record_id.entity_id, + right_endpoint: left_entity.metadata.record_id.entity_id, }), }); @@ -259,7 +259,7 @@ impl PostgresStore { // outgoing `Link` `Entity` kind: KnowledgeGraphEdgeKind::HasRightEntity, reversed: false, - right_endpoint: right_entity.metadata().record_id.entity_id, + right_endpoint: right_entity.metadata.record_id.entity_id, }), }); diff --git a/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity/read.rs b/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity/read.rs index de15077dfc6..fa4fd5cef12 100644 --- a/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity/read.rs +++ b/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity/read.rs @@ -13,7 +13,7 @@ use crate::{ knowledge::{EntityEditionId, EntityId, EntityRecordId, EntityVersion}, time::TimeProjection, }, - knowledge::{Entity, EntityProperties, EntityQueryPath, EntityUuid, LinkData}, + knowledge::{Entity, EntityMetadata, EntityProperties, EntityQueryPath, EntityUuid, LinkData}, ontology::EntityTypeQueryPath, provenance::{OwnedById, ProvenanceMetadata}, store::{ @@ -86,7 +86,7 @@ impl crud::Read for PostgresStore { serde_json::from_value(row.get(properties_index)) .into_report() .change_context(QueryError)?; - let entity_type_uri = VersionedUri::from_str(row.get(type_id_index)) + let entity_type_id = VersionedUri::from_str(row.get(type_id_index)) .into_report() .change_context(QueryError)?; @@ -128,28 +128,28 @@ impl crud::Read for PostgresStore { } }; - Ok(Entity::new( + Ok(Entity { properties, link_data, - EntityRecordId { - entity_id: EntityId { - owned_by_id: row.get(owned_by_id_index), - entity_uuid: row.get(entity_uuid_index), + metadata: EntityMetadata { + record_id: EntityRecordId { + entity_id: EntityId { + owned_by_id: row.get(owned_by_id_index), + entity_uuid: row.get(entity_uuid_index), + }, + edition_id: EntityEditionId::new(row.get(edition_id_index)), }, - edition_id: EntityEditionId::new(row.get(edition_id_index)), - }, - EntityVersion { - decision_time: row.get(decision_time_index), - transaction_time: row.get(transaction_time_index), - }, - entity_type_uri, - ProvenanceMetadata { - updated_by_id: row.get(updated_by_id_index), + version: EntityVersion { + decision_time: row.get(decision_time_index), + transaction_time: row.get(transaction_time_index), + }, + entity_type_id, + provenance: ProvenanceMetadata { + updated_by_id: row.get(updated_by_id_index), + }, + archived: row.get(archived_index), }, - // TODO: only the historic table would have an `archived` field. - // Consider what we should do about that. - row.get(archived_index), - )) + }) }) .try_collect() .await diff --git a/apps/hash-graph/tests/integration/postgres/entity.rs b/apps/hash-graph/tests/integration/postgres/entity.rs index f9c17b0dd7e..16984b5afa3 100644 --- a/apps/hash-graph/tests/integration/postgres/entity.rs +++ b/apps/hash-graph/tests/integration/postgres/entity.rs @@ -40,7 +40,7 @@ async fn insert() { .expect("could not get entity"); assert_eq!(entities.len(), 1); - assert_eq!(entities[0].properties(), &person); + assert_eq!(entities[0].properties, person); } #[tokio::test] @@ -77,7 +77,7 @@ async fn query() { .expect("could not get entity"); assert_eq!(queried_organizations.len(), 1); - assert_eq!(queried_organizations[0].properties(), &organization); + assert_eq!(queried_organizations[0].properties, organization); } #[tokio::test] @@ -138,7 +138,7 @@ async fn update() { .await .expect("could not get entity"); - assert_eq!(entity_v2.properties(), &page_v2); + assert_eq!(entity_v2.properties, page_v2); let entity_v1 = api .get_entity_by_timestamp( @@ -147,7 +147,7 @@ async fn update() { ) .await .expect("could not get entity"); - assert_eq!(entity_v1.properties(), &page_v1); + assert_eq!(entity_v1.properties, page_v1); let entity_v2 = api .get_entity_by_timestamp( @@ -157,5 +157,5 @@ async fn update() { .await .expect("could not get entity"); - assert_eq!(entity_v2.properties(), &page_v2); + assert_eq!(entity_v2.properties, page_v2); } diff --git a/apps/hash-graph/tests/integration/postgres/links.rs b/apps/hash-graph/tests/integration/postgres/links.rs index 0460ba2eb99..3d651193792 100644 --- a/apps/hash-graph/tests/integration/postgres/links.rs +++ b/apps/hash-graph/tests/integration/postgres/links.rs @@ -60,7 +60,7 @@ async fn insert() { .get_link_entity_target(alice_metadata.record_id.entity_id, friend_of_type_id) .await .expect("could not fetch entity"); - let link_data = link_entity.link_data().expect("entity is not a link"); + let link_data = link_entity.link_data.expect("entity is not a link"); assert_eq!( link_data.left_entity_id(), @@ -156,15 +156,15 @@ async fn get_entity_links() { assert!( links_from_source .iter() - .any(|link_entity| { link_entity.metadata().entity_type_id == friend_link_type_id }) + .any(|link_entity| { link_entity.metadata.entity_type_id == friend_link_type_id }) ); assert!(links_from_source.iter().any(|link_entity| { - link_entity.metadata().entity_type_id == acquaintance_entity_link_type_id + link_entity.metadata.entity_type_id == acquaintance_entity_link_type_id })); let link_datas = links_from_source .iter() - .map(|entity| entity.link_data().expect("entity is not a link")) + .map(|entity| entity.link_data.expect("entity is not a link")) .collect::>(); assert!( link_datas From d34f12427dbf9cbc1c28f52a1aa2d5e29a831c63 Mon Sep 17 00:00:00 2001 From: Tim Diekmann Date: Thu, 16 Feb 2023 22:44:44 +0100 Subject: [PATCH 09/19] Make fields on `*VertexId` pub --- .../api/rest/utoipa_typedef/subgraph/edges.rs | 16 +++---- .../rest/utoipa_typedef/subgraph/vertices.rs | 12 +++--- .../lib/graph/src/knowledge/entity.rs | 7 +++- apps/hash-graph/lib/graph/src/ontology.rs | 15 +++++-- .../lib/graph/src/shared/identifier.rs | 42 ++----------------- .../src/store/postgres/knowledge/entity.rs | 8 ++-- .../store/postgres/query/statement/select.rs | 10 ++--- .../lib/graph/src/store/query/filter.rs | 16 +++---- 8 files changed, 52 insertions(+), 74 deletions(-) diff --git a/apps/hash-graph/lib/graph/src/api/rest/utoipa_typedef/subgraph/edges.rs b/apps/hash-graph/lib/graph/src/api/rest/utoipa_typedef/subgraph/edges.rs index ca8e11dc946..046333f7e69 100644 --- a/apps/hash-graph/lib/graph/src/api/rest/utoipa_typedef/subgraph/edges.rs +++ b/apps/hash-graph/lib/graph/src/api/rest/utoipa_typedef/subgraph/edges.rs @@ -72,12 +72,12 @@ impl Edges { HashMap::new(), |mut map, (id, edges)| { let edges = edges.into_iter().collect(); - match map.entry(id.base_id().clone()) { + match map.entry(id.base_id.clone()) { Entry::Occupied(entry) => { - entry.into_mut().insert(id.version(), edges); + entry.into_mut().insert(id.version, edges); } Entry::Vacant(entry) => { - entry.insert(BTreeMap::from([(id.version(), edges)])); + entry.insert(BTreeMap::from([(id.version, edges)])); } } map @@ -117,11 +117,11 @@ impl Edges { let earliest_timestamp = if edge.reversed { vertices.earliest_entity_by_id(&edge.right_endpoint) } else { - vertices.earliest_entity_by_id(&id.base_id()) + vertices.earliest_entity_by_id(&id.base_id) } .expect("entity must exist in subgraph") .vertex_id(time_axis) - .version(); + .version; KnowledgeGraphOutwardEdges::ToKnowledgeGraph(OutwardEdge { kind: edge.kind, @@ -134,16 +134,16 @@ impl Edges { } } }).collect(); - match map.entry(id.base_id()) { + match map.entry(id.base_id) { Entry::Occupied(entry) => { entry.into_mut().insert( - id.version(), + id.version, edges, ); } Entry::Vacant(entry) => { entry.insert(BTreeMap::from([( - id.version(), + id.version, edges, )])); } diff --git a/apps/hash-graph/lib/graph/src/api/rest/utoipa_typedef/subgraph/vertices.rs b/apps/hash-graph/lib/graph/src/api/rest/utoipa_typedef/subgraph/vertices.rs index 36ea83bb9bb..64c36f69736 100644 --- a/apps/hash-graph/lib/graph/src/api/rest/utoipa_typedef/subgraph/vertices.rs +++ b/apps/hash-graph/lib/graph/src/api/rest/utoipa_typedef/subgraph/vertices.rs @@ -66,12 +66,12 @@ impl From for Vertices { ontology: OntologyVertices(data_types.chain(property_types).chain(entity_types).fold( HashMap::new(), |mut map, (id, vertex)| { - match map.entry(id.base_id().clone()) { + match map.entry(id.base_id.clone()) { Entry::Occupied(entry) => { - entry.into_mut().insert(id.version(), vertex); + entry.into_mut().insert(id.version, vertex); } Entry::Vacant(entry) => { - entry.insert(BTreeMap::from([(id.version(), vertex)])); + entry.insert(BTreeMap::from([(id.version, vertex)])); } } map @@ -80,15 +80,15 @@ impl From for Vertices { knowledge_graph: KnowledgeGraphVertices(vertices.entities.into_iter().fold( HashMap::new(), |mut map, (id, vertex)| { - match map.entry(id.base_id()) { + match map.entry(id.base_id) { Entry::Occupied(entry) => { entry .into_mut() - .insert(id.version(), KnowledgeGraphVertex::Entity(vertex)); + .insert(id.version, KnowledgeGraphVertex::Entity(vertex)); } Entry::Vacant(entry) => { entry.insert(BTreeMap::from([( - id.version(), + id.version, KnowledgeGraphVertex::Entity(vertex), )])); } diff --git a/apps/hash-graph/lib/graph/src/knowledge/entity.rs b/apps/hash-graph/lib/graph/src/knowledge/entity.rs index c63be1ae094..df4c14f4da6 100644 --- a/apps/hash-graph/lib/graph/src/knowledge/entity.rs +++ b/apps/hash-graph/lib/graph/src/knowledge/entity.rs @@ -202,11 +202,14 @@ impl Record for Entity { TimeAxis::DecisionTime => self.metadata.version.decision_time.start().cast(), TimeAxis::TransactionTime => self.metadata.version.transaction_time.start().cast(), }; - EntityVertexId::new(self.metadata.record_id.entity_id, timestamp.into()) + EntityVertexId { + base_id: self.metadata.record_id.entity_id, + version: timestamp.into(), + } } fn create_filter_for_vertex_id(vertex_id: &Self::VertexId) -> Filter { - Filter::for_entity_by_entity_id(vertex_id.base_id()) + Filter::for_entity_by_entity_id(vertex_id.base_id) } } diff --git a/apps/hash-graph/lib/graph/src/ontology.rs b/apps/hash-graph/lib/graph/src/ontology.rs index e4af0299cea..8d00bff9446 100644 --- a/apps/hash-graph/lib/graph/src/ontology.rs +++ b/apps/hash-graph/lib/graph/src/ontology.rs @@ -224,7 +224,10 @@ impl Record for DataTypeWithMetadata { fn vertex_id(&self, _time_axis: TimeAxis) -> Self::VertexId { let record_id = self.metadata().record_id(); - OntologyTypeVertexId::new(record_id.base_uri.clone(), record_id.version) + OntologyTypeVertexId { + base_id: record_id.base_uri.clone(), + version: record_id.version, + } } fn create_filter_for_vertex_id(vertex_id: &Self::VertexId) -> Filter { @@ -265,7 +268,10 @@ impl Record for PropertyTypeWithMetadata { fn vertex_id(&self, _time_axis: TimeAxis) -> Self::VertexId { let record_id = self.metadata().record_id(); - OntologyTypeVertexId::new(record_id.base_uri.clone(), record_id.version) + OntologyTypeVertexId { + base_id: record_id.base_uri.clone(), + version: record_id.version, + } } fn create_filter_for_vertex_id(vertex_id: &Self::VertexId) -> Filter { @@ -306,7 +312,10 @@ impl Record for EntityTypeWithMetadata { fn vertex_id(&self, _time_axis: TimeAxis) -> Self::VertexId { let record_id = self.metadata().record_id(); - OntologyTypeVertexId::new(record_id.base_uri.clone(), record_id.version) + OntologyTypeVertexId { + base_id: record_id.base_uri.clone(), + version: record_id.version, + } } fn create_filter_for_vertex_id(vertex_id: &Self::VertexId) -> Filter { diff --git a/apps/hash-graph/lib/graph/src/shared/identifier.rs b/apps/hash-graph/lib/graph/src/shared/identifier.rs index 8843887dd96..057007fe56e 100644 --- a/apps/hash-graph/lib/graph/src/shared/identifier.rs +++ b/apps/hash-graph/lib/graph/src/shared/identifier.rs @@ -16,49 +16,15 @@ use crate::identifier::{ #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Serialize, ToSchema)] #[serde(rename_all = "camelCase")] pub struct EntityVertexId { - base_id: EntityId, - version: Timestamp, -} - -impl EntityVertexId { - #[must_use] - pub const fn new(base_id: EntityId, version: Timestamp) -> Self { - Self { base_id, version } - } - - #[must_use] - pub const fn base_id(&self) -> EntityId { - self.base_id - } - - #[must_use] - pub const fn version(&self) -> Timestamp { - self.version - } + pub base_id: EntityId, + pub version: Timestamp, } #[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, ToSchema)] #[serde(rename_all = "camelCase")] pub struct OntologyTypeVertexId { - base_id: BaseUri, - version: OntologyTypeVersion, -} - -impl OntologyTypeVertexId { - #[must_use] - pub const fn new(base_id: BaseUri, version: OntologyTypeVersion) -> Self { - Self { base_id, version } - } - - #[must_use] - pub const fn base_id(&self) -> &BaseUri { - &self.base_id - } - - #[must_use] - pub const fn version(&self) -> OntologyTypeVersion { - self.version - } + pub base_id: BaseUri, + pub version: OntologyTypeVersion, } impl From for OntologyTypeVertexId { diff --git a/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity.rs b/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity.rs index 7a6a4b5c874..0fb0e948806 100644 --- a/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity.rs +++ b/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity.rs @@ -130,7 +130,7 @@ impl PostgresStore { if current_resolve_depths.has_left_entity.incoming > 0 { for outgoing_link_entity in >::read( self, - &Filter::for_outgoing_link_by_source_entity_id(entity_vertex_id.base_id()), + &Filter::for_outgoing_link_by_source_entity_id(entity_vertex_id.base_id), &intersected_time_projection, ) .await? @@ -169,7 +169,7 @@ impl PostgresStore { if current_resolve_depths.has_right_entity.incoming > 0 { for incoming_link_entity in >::read( self, - &Filter::for_incoming_link_by_source_entity_id(entity_vertex_id.base_id()), + &Filter::for_incoming_link_by_source_entity_id(entity_vertex_id.base_id), &intersected_time_projection, ) .await? @@ -208,7 +208,7 @@ impl PostgresStore { if current_resolve_depths.has_left_entity.outgoing > 0 { for left_entity in >::read( self, - &Filter::for_left_entity_by_entity_id(entity_vertex_id.base_id()), + &Filter::for_left_entity_by_entity_id(entity_vertex_id.base_id), &intersected_time_projection, ) .await? @@ -247,7 +247,7 @@ impl PostgresStore { if current_resolve_depths.has_right_entity.outgoing > 0 { for right_entity in >::read( self, - &Filter::for_right_entity_by_entity_id(entity_vertex_id.base_id()), + &Filter::for_right_entity_by_entity_id(entity_vertex_id.base_id), &intersected_time_projection, ) .await? diff --git a/apps/hash-graph/lib/graph/src/store/postgres/query/statement/select.rs b/apps/hash-graph/lib/graph/src/store/postgres/query/statement/select.rs index 711c939c98b..8a0a60667fb 100644 --- a/apps/hash-graph/lib/graph/src/store/postgres/query/statement/select.rs +++ b/apps/hash-graph/lib/graph/src/store/postgres/query/statement/select.rs @@ -808,13 +808,13 @@ mod tests { #[test] fn for_ontology_type_record_id() { - let uri = OntologyTypeVertexId::new( - BaseUri::new( + let uri = OntologyTypeVertexId { + base_id: BaseUri::new( "https://blockprotocol.org/@blockprotocol/types/data-type/text/".to_owned(), ) .expect("invalid base uri"), - OntologyTypeVersion::new(1), - ); + version: OntologyTypeVersion::new(1), + }; let time_projection = UnresolvedTimeProjection::default().resolve(); let mut compiler = @@ -832,7 +832,7 @@ mod tests { ON "ontology_id_with_metadata_0_1_0"."ontology_id" = "data_types_0_0_0"."ontology_id" WHERE ("ontology_id_with_metadata_0_1_0"."base_uri" = $1) AND ("ontology_id_with_metadata_0_1_0"."version" = $2) "#, - &[&uri.base_id().as_str(), &uri.version()], + &[&uri.base_id.as_str(), &uri.version], ); } diff --git a/apps/hash-graph/lib/graph/src/store/query/filter.rs b/apps/hash-graph/lib/graph/src/store/query/filter.rs index a5b1dd359ca..51ff762b177 100644 --- a/apps/hash-graph/lib/graph/src/store/query/filter.rs +++ b/apps/hash-graph/lib/graph/src/store/query/filter.rs @@ -97,8 +97,8 @@ where #[must_use] pub fn for_ontology_type_vertex_id(ontology_type_vertex_id: &'p OntologyTypeVertexId) -> Self { Self::All(vec![ - Self::for_base_uri(ontology_type_vertex_id.base_id()), - Self::for_version(ontology_type_vertex_id.version()), + Self::for_base_uri(&ontology_type_vertex_id.base_id), + Self::for_version(ontology_type_vertex_id.version), ]) } } @@ -469,23 +469,23 @@ mod tests { #[test] fn for_ontology_type_version_id() { - let uri = OntologyTypeVertexId::new( - BaseUri::new( + let uri = OntologyTypeVertexId { + base_id: BaseUri::new( "https://blockprotocol.org/@blockprotocol/types/data-type/text/".to_owned(), ) .expect("invalid base uri"), - OntologyTypeVersion::new(1), - ); + version: OntologyTypeVersion::new(1), + }; let expected = json! {{ "all": [ { "equal": [ { "path": ["baseUri"] }, - { "parameter": uri.base_id() } + { "parameter": uri.base_id } ]}, { "equal": [ { "path": ["version"] }, - { "parameter": uri.version() } + { "parameter": uri.version } ]} ] }}; From 1afbc99214acfc2ddd60e033c268fffac66bf7fe Mon Sep 17 00:00:00 2001 From: Tim Diekmann Date: Thu, 16 Feb 2023 22:51:05 +0100 Subject: [PATCH 10/19] Make fields on `LinkData` pub --- .../read_scaling/knowledge/complete/entity.rs | 16 ++-- .../bench/representative_read/seed.rs | 16 ++-- .../lib/graph/src/knowledge/entity.rs | 83 ++++--------------- .../src/store/postgres/knowledge/entity.rs | 34 +++++--- .../store/postgres/knowledge/entity/read.rs | 19 +++-- .../tests/integration/postgres/entity.rs | 5 +- .../tests/integration/postgres/lib.rs | 9 +- .../tests/integration/postgres/links.rs | 21 ++--- 8 files changed, 89 insertions(+), 114 deletions(-) diff --git a/apps/hash-graph/bench/read_scaling/knowledge/complete/entity.rs b/apps/hash-graph/bench/read_scaling/knowledge/complete/entity.rs index bc474ad1511..0aeadbe6b3e 100644 --- a/apps/hash-graph/bench/read_scaling/knowledge/complete/entity.rs +++ b/apps/hash-graph/bench/read_scaling/knowledge/complete/entity.rs @@ -10,7 +10,7 @@ use graph::{ UnresolvedTimeProjection, }, }, - knowledge::{EntityMetadata, EntityProperties, LinkData}, + knowledge::{EntityLinkOrder, EntityMetadata, EntityProperties, LinkData}, provenance::{OwnedById, UpdatedById}, store::{query::Filter, AccountStore, EntityStore}, subgraph::{ @@ -105,12 +105,14 @@ async fn seed_db( owned_by_id, None, properties.clone(), - Some(LinkData::new( - entity_a_metadata.record_id.entity_id, - entity_b_metadata.record_id.entity_id, - None, - None, - )), + Some(LinkData { + left_entity_id: entity_a_metadata.record_id.entity_id, + right_entity_id: entity_b_metadata.record_id.entity_id, + order: EntityLinkOrder { + left_to_right: None, + right_to_left: None, + }, + }), None, ) }) diff --git a/apps/hash-graph/bench/representative_read/seed.rs b/apps/hash-graph/bench/representative_read/seed.rs index 3d2e8c77fb0..7a6ff1d1235 100644 --- a/apps/hash-graph/bench/representative_read/seed.rs +++ b/apps/hash-graph/bench/representative_read/seed.rs @@ -6,7 +6,7 @@ use std::{ use graph::{ identifier::account::AccountId, - knowledge::{EntityProperties, EntityUuid, LinkData}, + knowledge::{EntityLinkOrder, EntityProperties, EntityUuid, LinkData}, provenance::{OwnedById, UpdatedById}, store::{AccountStore, AsClient, EntityStore}, }; @@ -180,12 +180,14 @@ async fn seed_db(account_id: AccountId, store_wrapper: &mut StoreWrapper) { OwnedById::new(account_id), None, EntityProperties::empty(), - Some(LinkData::new( - left_entity_metadata.record_id.entity_id, - right_entity_metadata.record_id.entity_id, - None, - None, - )), + Some(LinkData { + left_entity_id: left_entity_metadata.record_id.entity_id, + right_entity_id: right_entity_metadata.record_id.entity_id, + order: EntityLinkOrder { + left_to_right: None, + right_to_left: None, + }, + }), None, ) }), diff --git a/apps/hash-graph/lib/graph/src/knowledge/entity.rs b/apps/hash-graph/lib/graph/src/knowledge/entity.rs index df4c14f4da6..d903966c91d 100644 --- a/apps/hash-graph/lib/graph/src/knowledge/entity.rs +++ b/apps/hash-graph/lib/graph/src/knowledge/entity.rs @@ -92,81 +92,30 @@ impl EntityProperties { } #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, ToSchema)] -#[serde(deny_unknown_fields, rename_all = "camelCase")] +#[serde(deny_unknown_fields)] pub struct EntityLinkOrder { - #[serde(default, skip_serializing_if = "Option::is_none")] - left_to_right_order: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - right_to_left_order: Option, -} - -impl EntityLinkOrder { - #[must_use] - pub const fn new( - left_to_right_order: Option, - right_to_left_order: Option, - ) -> Self { - Self { - left_to_right_order, - right_to_left_order, - } - } - - #[must_use] - pub const fn left_to_right(&self) -> Option { - self.left_to_right_order - } - - #[must_use] - pub const fn right_to_left(&self) -> Option { - self.right_to_left_order - } + #[serde( + default, + skip_serializing_if = "Option::is_none", + rename = "leftToRightOrder" + )] + pub left_to_right: Option, + #[serde( + default, + skip_serializing_if = "Option::is_none", + rename = "rightToLeftOrder" + )] + pub right_to_left: Option, } /// The associated information for 'Link' entities #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, ToSchema)] #[serde(deny_unknown_fields, rename_all = "camelCase")] pub struct LinkData { - left_entity_id: EntityId, - right_entity_id: EntityId, + pub left_entity_id: EntityId, + pub right_entity_id: EntityId, #[serde(flatten)] - order: EntityLinkOrder, -} - -impl LinkData { - #[must_use] - pub const fn new( - left_entity_id: EntityId, - right_entity_id: EntityId, - left_to_right_order: Option, - right_to_left_order: Option, - ) -> Self { - Self { - left_entity_id, - right_entity_id, - order: EntityLinkOrder::new(left_to_right_order, right_to_left_order), - } - } - - #[must_use] - pub const fn left_entity_id(&self) -> EntityId { - self.left_entity_id - } - - #[must_use] - pub const fn right_entity_id(&self) -> EntityId { - self.right_entity_id - } - - #[must_use] - pub const fn left_to_right_order(&self) -> Option { - self.order.left_to_right_order - } - - #[must_use] - pub const fn right_to_left_order(&self) -> Option { - self.order.right_to_left_order - } + pub order: EntityLinkOrder, } /// The metadata of an [`Entity`] record. diff --git a/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity.rs b/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity.rs index 0fb0e948806..2c5db626c06 100644 --- a/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity.rs +++ b/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity.rs @@ -352,18 +352,22 @@ impl EntityStore for PostgresStore { &properties, &link_data .as_ref() - .map(|metadata| metadata.left_entity_id().owned_by_id), + .map(|metadata| metadata.left_entity_id.owned_by_id), &link_data .as_ref() - .map(|metadata| metadata.left_entity_id().entity_uuid), + .map(|metadata| metadata.left_entity_id.entity_uuid), &link_data .as_ref() - .map(|metadata| metadata.right_entity_id().owned_by_id), + .map(|metadata| metadata.right_entity_id.owned_by_id), &link_data .as_ref() - .map(|metadata| metadata.right_entity_id().entity_uuid), - &link_data.as_ref().map(LinkData::left_to_right_order), - &link_data.as_ref().map(LinkData::right_to_left_order), + .map(|metadata| metadata.right_entity_id.entity_uuid), + &link_data + .as_ref() + .map(|link_data| link_data.order.left_to_right), + &link_data + .as_ref() + .map(|link_data| link_data.order.right_to_left), ], ) .await @@ -414,13 +418,19 @@ impl EntityStore for PostgresStore { owned_by_id, entity_uuid: entity_uuid.unwrap_or_else(|| EntityUuid::new(Uuid::new_v4())), }, - link_data.as_ref().map(LinkData::left_entity_id), - link_data.as_ref().map(LinkData::right_entity_id), + link_data.as_ref().map(|link_data| link_data.left_entity_id), + link_data + .as_ref() + .map(|link_data| link_data.right_entity_id), )); entity_editions.push(( properties, - link_data.as_ref().and_then(LinkData::left_to_right_order), - link_data.as_ref().and_then(LinkData::right_to_left_order), + link_data + .as_ref() + .and_then(|link_data| link_data.order.left_to_right), + link_data + .as_ref() + .and_then(|link_data| link_data.order.right_to_left), )); entity_versions.push(decision_time); } @@ -588,8 +598,8 @@ impl EntityStore for PostgresStore { &archived, &entity_type_ontology_id, &properties, - &link_order.left_to_right(), - &link_order.right_to_left(), + &link_order.left_to_right, + &link_order.right_to_left, ], ) .await diff --git a/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity/read.rs b/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity/read.rs index fa4fd5cef12..fd66567699c 100644 --- a/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity/read.rs +++ b/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity/read.rs @@ -13,7 +13,10 @@ use crate::{ knowledge::{EntityEditionId, EntityId, EntityRecordId, EntityVersion}, time::TimeProjection, }, - knowledge::{Entity, EntityMetadata, EntityProperties, EntityQueryPath, EntityUuid, LinkData}, + knowledge::{ + Entity, EntityLinkOrder, EntityMetadata, EntityProperties, EntityQueryPath, EntityUuid, + LinkData, + }, ontology::EntityTypeQueryPath, provenance::{OwnedById, ProvenanceMetadata}, store::{ @@ -108,18 +111,20 @@ impl crud::Read for PostgresStore { Some(left_entity_uuid), Some(right_owned_by_id), Some(right_entity_uuid), - ) => Some(LinkData::new( - EntityId { + ) => Some(LinkData { + left_entity_id: EntityId { owned_by_id: OwnedById::new(left_owned_by_id), entity_uuid: EntityUuid::new(left_entity_uuid), }, - EntityId { + right_entity_id: EntityId { owned_by_id: OwnedById::new(right_owned_by_id), entity_uuid: EntityUuid::new(right_entity_uuid), }, - row.get(left_to_right_order_index), - row.get(right_to_left_order_index), - )), + order: EntityLinkOrder { + left_to_right: row.get(left_to_right_order_index), + right_to_left: row.get(right_to_left_order_index), + }, + }), (None, None, None, None) => None, _ => unreachable!( "It's not possible to have a link entity with the left entityId or \ diff --git a/apps/hash-graph/tests/integration/postgres/entity.rs b/apps/hash-graph/tests/integration/postgres/entity.rs index 16984b5afa3..2d713679a75 100644 --- a/apps/hash-graph/tests/integration/postgres/entity.rs +++ b/apps/hash-graph/tests/integration/postgres/entity.rs @@ -121,7 +121,10 @@ async fn update() { .expect("couldn't construct Base URI"), version: 1, }, - EntityLinkOrder::new(None, None), + EntityLinkOrder { + left_to_right: None, + right_to_left: None, + }, ) .await .expect("could not update entity"); diff --git a/apps/hash-graph/tests/integration/postgres/lib.rs b/apps/hash-graph/tests/integration/postgres/lib.rs index fde1915ec6a..5f751e07195 100644 --- a/apps/hash-graph/tests/integration/postgres/lib.rs +++ b/apps/hash-graph/tests/integration/postgres/lib.rs @@ -456,7 +456,14 @@ impl DatabaseApi<'_> { false, entity_type_id, properties, - Some(LinkData::new(left_entity_id, right_entity_id, None, None)), + Some(LinkData { + left_entity_id, + right_entity_id, + order: EntityLinkOrder { + left_to_right: None, + right_to_left: None, + }, + }), ) .await } diff --git a/apps/hash-graph/tests/integration/postgres/links.rs b/apps/hash-graph/tests/integration/postgres/links.rs index 3d651193792..74fcfd7cdbd 100644 --- a/apps/hash-graph/tests/integration/postgres/links.rs +++ b/apps/hash-graph/tests/integration/postgres/links.rs @@ -62,14 +62,8 @@ async fn insert() { .expect("could not fetch entity"); let link_data = link_entity.link_data.expect("entity is not a link"); - assert_eq!( - link_data.left_entity_id(), - alice_metadata.record_id.entity_id - ); - assert_eq!( - link_data.right_entity_id(), - bob_metadata.record_id.entity_id - ); + assert_eq!(link_data.left_entity_id, alice_metadata.record_id.entity_id); + assert_eq!(link_data.right_entity_id, bob_metadata.record_id.entity_id); } #[tokio::test] @@ -169,17 +163,17 @@ async fn get_entity_links() { assert!( link_datas .iter() - .any(|link_data| link_data.left_entity_id() == alice_metadata.record_id.entity_id) + .any(|link_data| link_data.left_entity_id == alice_metadata.record_id.entity_id) ); assert!( link_datas .iter() - .any(|link_data| link_data.right_entity_id() == bob_metadata.record_id.entity_id) + .any(|link_data| link_data.right_entity_id == bob_metadata.record_id.entity_id) ); assert!( link_datas .iter() - .any(|link_data| link_data.right_entity_id() == charles_metadata.record_id.entity_id) + .any(|link_data| link_data.right_entity_id == charles_metadata.record_id.entity_id) ); } @@ -246,7 +240,10 @@ async fn remove_link() { link_entity_metadata.record_id.entity_id, EntityProperties::empty(), friend_link_type_id, - EntityLinkOrder::new(None, None), + EntityLinkOrder { + left_to_right: None, + right_to_left: None, + }, ) .await .expect("could not remove link"); From 4198b187c3000b82c62644af0252b7b9b328c7cd Mon Sep 17 00:00:00 2001 From: Tim Diekmann Date: Thu, 16 Feb 2023 23:01:50 +0100 Subject: [PATCH 11/19] Regenerate OpenAPI specs --- libs/@local/hash-graph-client/api.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/libs/@local/hash-graph-client/api.ts b/libs/@local/hash-graph-client/api.ts index d6956376125..e0411fe6a9b 100644 --- a/libs/@local/hash-graph-client/api.ts +++ b/libs/@local/hash-graph-client/api.ts @@ -905,12 +905,6 @@ export type Filter = */ export type FilterExpression = ParameterExpression | PathExpression; -/** - * @type GraphElementId - * @export - */ -export type GraphElementId = string; - /** * @type GraphElementVertexId * @export From e670e661fb11f981f19fabe3c2bf9479e4a8aa70 Mon Sep 17 00:00:00 2001 From: Tim Diekmann Date: Thu, 16 Feb 2023 23:42:24 +0100 Subject: [PATCH 12/19] Fix lints --- .../bin/cli/src/subcommand/server.rs | 88 +++++++++---------- .../lib/graph/src/knowledge/entity/query.rs | 8 +- 2 files changed, 47 insertions(+), 49 deletions(-) diff --git a/apps/hash-graph/bin/cli/src/subcommand/server.rs b/apps/hash-graph/bin/cli/src/subcommand/server.rs index f7a64762ca6..914019b6612 100644 --- a/apps/hash-graph/bin/cli/src/subcommand/server.rs +++ b/apps/hash-graph/bin/cli/src/subcommand/server.rs @@ -84,7 +84,7 @@ async fn stop_gap_setup(pool: &PostgresStorePool) -> Result<(), GraphErro use graph::{ identifier::account::AccountId, - ontology::{ExternalOntologyElementMetadata, OntologyElementMetadata}, + ontology::OntologyElementMetadata, provenance::{ProvenanceMetadata, UpdatedById}, store::{AccountStore, BaseUriAlreadyExists, DataTypeStore, EntityTypeStore, StorePool}, }; @@ -98,13 +98,13 @@ async fn stop_gap_setup(pool: &PostgresStorePool) -> Result<(), GraphErro // TODO: how do we make these URIs compliant let text = DataType::new( - VersionedUri::new( - BaseUri::new( + VersionedUri { + base_uri: BaseUri::new( "https://blockprotocol.org/@blockprotocol/types/data-type/text/".to_owned(), ) .expect("failed to construct base URI"), - 1, - ), + version: 1, + }, "Text".to_owned(), Some("An ordered sequence of characters".to_owned()), "string".to_owned(), @@ -112,13 +112,13 @@ async fn stop_gap_setup(pool: &PostgresStorePool) -> Result<(), GraphErro ); let number = DataType::new( - VersionedUri::new( - BaseUri::new( + VersionedUri { + base_uri: BaseUri::new( "https://blockprotocol.org/@blockprotocol/types/data-type/number/".to_owned(), ) .expect("failed to construct base URI"), - 1, - ), + version: 1, + }, "Number".to_owned(), Some("An arithmetical value (in the Real number system)".to_owned()), "number".to_owned(), @@ -126,13 +126,13 @@ async fn stop_gap_setup(pool: &PostgresStorePool) -> Result<(), GraphErro ); let boolean = DataType::new( - VersionedUri::new( - BaseUri::new( + VersionedUri { + base_uri: BaseUri::new( "https://blockprotocol.org/@blockprotocol/types/data-type/boolean/".to_owned(), ) .expect("failed to construct base URI"), - 1, - ), + version: 1, + }, "Boolean".to_owned(), Some("A True or False value".to_owned()), "boolean".to_owned(), @@ -140,13 +140,13 @@ async fn stop_gap_setup(pool: &PostgresStorePool) -> Result<(), GraphErro ); let null = DataType::new( - VersionedUri::new( - BaseUri::new( + VersionedUri { + base_uri: BaseUri::new( "https://blockprotocol.org/@blockprotocol/types/data-type/null/".to_owned(), ) .expect("failed to construct base URI"), - 1, - ), + version: 1, + }, "Null".to_owned(), Some("A placeholder value representing 'nothing'".to_owned()), "null".to_owned(), @@ -154,13 +154,13 @@ async fn stop_gap_setup(pool: &PostgresStorePool) -> Result<(), GraphErro ); let object = DataType::new( - VersionedUri::new( - BaseUri::new( + VersionedUri { + base_uri: BaseUri::new( "https://blockprotocol.org/@blockprotocol/types/data-type/object/".to_owned(), ) .expect("failed to construct base URI"), - 1, - ), + version: 1, + }, "Object".to_owned(), Some("A plain JSON object with no pre-defined structure".to_owned()), "object".to_owned(), @@ -168,13 +168,13 @@ async fn stop_gap_setup(pool: &PostgresStorePool) -> Result<(), GraphErro ); let empty_list = DataType::new( - VersionedUri::new( - BaseUri::new( + VersionedUri { + base_uri: BaseUri::new( "https://blockprotocol.org/@blockprotocol/types/data-type/empty-list/".to_owned(), ) .expect("failed to construct base URI"), - 1, - ), + version: 1, + }, "Empty List".to_owned(), Some("An Empty List".to_owned()), "array".to_owned(), @@ -210,14 +210,13 @@ async fn stop_gap_setup(pool: &PostgresStorePool) -> Result<(), GraphErro for data_type in [text, number, boolean, empty_list, object, null] { let title = data_type.title().to_owned(); - let data_type_metadata = - OntologyElementMetadata::External(ExternalOntologyElementMetadata::new( - data_type.id().into(), - ProvenanceMetadata { - updated_by_id: UpdatedById::new(root_account_id), - }, - OffsetDateTime::now_utc(), - )); + let data_type_metadata = OntologyElementMetadata::External { + record_id: data_type.id().clone().into(), + provenance: ProvenanceMetadata { + updated_by_id: UpdatedById::new(root_account_id), + }, + fetched_at: OffsetDateTime::now_utc(), + }; if let Err(error) = connection .create_data_type(data_type, &data_type_metadata) @@ -234,13 +233,13 @@ async fn stop_gap_setup(pool: &PostgresStorePool) -> Result<(), GraphErro } } let link_entity_type = EntityType::new( - VersionedUri::new( - BaseUri::new( + VersionedUri { + base_uri: BaseUri::new( "https://blockprotocol.org/@blockprotocol/types/entity-type/link/".to_owned(), ) .expect("failed to construct base URI"), - 1, - ), + version: 1, + }, "Link".to_owned(), Some("A link".to_owned()), Object::new(HashMap::default(), Vec::default()).expect("invalid property object"), @@ -250,14 +249,13 @@ async fn stop_gap_setup(pool: &PostgresStorePool) -> Result<(), GraphErro Vec::default(), ); - let link_entity_type_metadata = - OntologyElementMetadata::External(ExternalOntologyElementMetadata::new( - link_entity_type.id().into(), - ProvenanceMetadata { - updated_by_id: UpdatedById::new(root_account_id), - }, - OffsetDateTime::now_utc(), - )); + let link_entity_type_metadata = OntologyElementMetadata::External { + record_id: link_entity_type.id().clone().into(), + provenance: ProvenanceMetadata { + updated_by_id: UpdatedById::new(root_account_id), + }, + fetched_at: OffsetDateTime::now_utc(), + }; let title = link_entity_type.title().to_owned(); diff --git a/apps/hash-graph/lib/graph/src/knowledge/entity/query.rs b/apps/hash-graph/lib/graph/src/knowledge/entity/query.rs index cdbc1912afb..abad29454ed 100644 --- a/apps/hash-graph/lib/graph/src/knowledge/entity/query.rs +++ b/apps/hash-graph/lib/graph/src/knowledge/entity/query.rs @@ -197,7 +197,7 @@ pub enum EntityQueryPath<'p> { /// [`Entity`]: crate::knowledge::Entity /// [`LinkData::right_entity_id()`]: crate::knowledge::LinkData::right_entity_id RightEntity(Box), - /// Corresponds to [`LinkData::left_to_right_order()`]. + /// Corresponds to [`EntityLinkOrder::left_to_right`]. /// /// ```rust /// # use serde::Deserialize; @@ -208,9 +208,9 @@ pub enum EntityQueryPath<'p> { /// # Ok::<(), serde_json::Error>(()) /// ``` /// - /// [`LinkData::left_to_right_order()`]: crate::knowledge::LinkData::left_to_right_order + /// [`EntityLinkOrder::left_to_right`]: crate::knowledge::EntityLinkOrder::left_to_right LeftToRightOrder, - /// Corresponds to [`LinkData::right_to_left_order()`]. + /// Corresponds to [`EntityLinkOrder::right_to_left`]. /// /// ```rust /// # use serde::Deserialize; @@ -221,7 +221,7 @@ pub enum EntityQueryPath<'p> { /// # Ok::<(), serde_json::Error>(()) /// ``` /// - /// [`LinkData::right_to_left_order()`]: crate::knowledge::LinkData::right_to_left_order + /// [`EntityLinkOrder::right_to_left`]: crate::knowledge::EntityLinkOrder::right_to_left RightToLeftOrder, /// Corresponds to [`Entity::properties`]. /// From c0ece85b15167787c55f3de703fc9cea7865c57f Mon Sep 17 00:00:00 2001 From: Tim Diekmann Date: Fri, 17 Feb 2023 00:00:32 +0100 Subject: [PATCH 13/19] Simplify `Read` --- .../lib/graph/src/store/postgres/knowledge/entity/read.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity/read.rs b/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity/read.rs index fd66567699c..cd1ac7e50c4 100644 --- a/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity/read.rs +++ b/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity/read.rs @@ -142,7 +142,7 @@ impl crud::Read for PostgresStore { owned_by_id: row.get(owned_by_id_index), entity_uuid: row.get(entity_uuid_index), }, - edition_id: EntityEditionId::new(row.get(edition_id_index)), + edition_id: row.get(edition_id_index), }, version: EntityVersion { decision_time: row.get(decision_time_index), From 8209c26b814062746878fc30c4e2e52ac4358fc2 Mon Sep 17 00:00:00 2001 From: Tim Diekmann Date: Fri, 17 Feb 2023 00:38:43 +0100 Subject: [PATCH 14/19] Satisfy clippy --- .../lib/graph/src/store/postgres/knowledge/entity/read.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity/read.rs b/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity/read.rs index cd1ac7e50c4..566ceb82350 100644 --- a/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity/read.rs +++ b/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity/read.rs @@ -10,7 +10,7 @@ use uuid::Uuid; use crate::{ identifier::{ account::AccountId, - knowledge::{EntityEditionId, EntityId, EntityRecordId, EntityVersion}, + knowledge::{EntityId, EntityRecordId, EntityVersion}, time::TimeProjection, }, knowledge::{ From 5fa64433672dd6234ccb399c870633d2c2c54e8a Mon Sep 17 00:00:00 2001 From: Tim Diekmann Date: Fri, 17 Feb 2023 11:06:09 +0100 Subject: [PATCH 15/19] Update `type_system` package --- apps/hash-graph/Cargo.lock | 2 +- apps/hash-graph/bench/Cargo.toml | 2 +- apps/hash-graph/bin/cli/Cargo.toml | 2 +- apps/hash-graph/lib/graph/Cargo.toml | 2 +- apps/hash-graph/lib/type-fetcher/Cargo.toml | 2 +- apps/hash-graph/tests/integration/Cargo.toml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/hash-graph/Cargo.lock b/apps/hash-graph/Cargo.lock index 7cd18cdc9b3..b0acfde56af 100644 --- a/apps/hash-graph/Cargo.lock +++ b/apps/hash-graph/Cargo.lock @@ -2701,7 +2701,7 @@ dependencies = [ [[package]] name = "type-system" version = "0.0.0" -source = "git+https://github.com/blockprotocol/blockprotocol?rev=ce8df71#ce8df719ca03657f30849140e83843f60ecefa59" +source = "git+https://github.com/blockprotocol/blockprotocol?rev=adab205#adab205d4724c992b0f4b8efbf21f8942050479b" dependencies = [ "console_error_panic_hook", "regex", diff --git a/apps/hash-graph/bench/Cargo.toml b/apps/hash-graph/bench/Cargo.toml index 4fcb834c1d0..efdcc490033 100644 --- a/apps/hash-graph/bench/Cargo.toml +++ b/apps/hash-graph/bench/Cargo.toml @@ -21,7 +21,7 @@ serde = { version = "1.0.152", features = ["derive"] } serde_json = "1.0.91" tokio = { version = "1.25.0", features = ["rt-multi-thread", "macros"] } tokio-postgres = { version = "0.7.7", default-features = false } -type-system = { git = "https://github.com/blockprotocol/blockprotocol", rev = "ce8df71" } +type-system = { git = "https://github.com/blockprotocol/blockprotocol", rev = "adab205" } uuid = { version = "1.3.0", features = ["v4", "serde"] } [[bench]] diff --git a/apps/hash-graph/bin/cli/Cargo.toml b/apps/hash-graph/bin/cli/Cargo.toml index 39067f97ddc..85d4b5b2d40 100644 --- a/apps/hash-graph/bin/cli/Cargo.toml +++ b/apps/hash-graph/bin/cli/Cargo.toml @@ -24,7 +24,7 @@ tokio = { version = "1.25.0", features = ["rt-multi-thread", "macros"] } tokio-postgres = { version = "0.7.7", default-features = false } tokio-serde = { version = "0.8", features = ["messagepack"], optional = true } tracing = "0.1.37" -type-system = { git = "https://github.com/blockprotocol/blockprotocol", rev = "ce8df71" } +type-system = { git = "https://github.com/blockprotocol/blockprotocol", rev = "adab205" } uuid = "1.3.0" # Remove again when the type fetcher is used in the graph diff --git a/apps/hash-graph/lib/graph/Cargo.toml b/apps/hash-graph/lib/graph/Cargo.toml index f3a78a5aaf8..d30ce42a9f6 100644 --- a/apps/hash-graph/lib/graph/Cargo.toml +++ b/apps/hash-graph/lib/graph/Cargo.toml @@ -34,7 +34,7 @@ tonic = "0.8.3" opentelemetry = { version = "0.18.0", features = ["rt-tokio"] } opentelemetry-otlp = "0.11.0" tracing-subscriber = { version = "0.3.16", features = ["env-filter", "json"] } -type-system = { git = "https://github.com/blockprotocol/blockprotocol", rev = "ce8df71" } +type-system = { git = "https://github.com/blockprotocol/blockprotocol", rev = "adab205" } uuid = { version = "1.3.0", features = ["v4", "serde"] } utoipa = { version = "3.0.1", features = ["uuid"] } include_dir = "0.7.3" diff --git a/apps/hash-graph/lib/type-fetcher/Cargo.toml b/apps/hash-graph/lib/type-fetcher/Cargo.toml index 7af5a95a950..680608e131b 100644 --- a/apps/hash-graph/lib/type-fetcher/Cargo.toml +++ b/apps/hash-graph/lib/type-fetcher/Cargo.toml @@ -7,7 +7,7 @@ description = "RPC service definition to fetch external BP types" [dependencies] error-stack = { version = "0.3.1", features = ["spantrace"] } -type-system = { git = "https://github.com/blockprotocol/blockprotocol", rev = "ce8df71" } +type-system = { git = "https://github.com/blockprotocol/blockprotocol", rev = "adab205" } serde = { version = "1.0.152", features = ["derive"] } serde_json = "1.0.91" diff --git a/apps/hash-graph/tests/integration/Cargo.toml b/apps/hash-graph/tests/integration/Cargo.toml index 7b71ea5577f..2564d49a742 100644 --- a/apps/hash-graph/tests/integration/Cargo.toml +++ b/apps/hash-graph/tests/integration/Cargo.toml @@ -16,7 +16,7 @@ serde_json = "1.0.91" time = "0.3.17" tokio = { version = "1.25.0", features = ["rt-multi-thread", "macros"] } tokio-postgres = { version = "0.7.7", default-features = false } -type-system = { git = "https://github.com/blockprotocol/blockprotocol", rev = "ce8df71" } +type-system = { git = "https://github.com/blockprotocol/blockprotocol", rev = "adab205" } uuid = { version = "1.3.0", features = ["v4", "serde"] } [[test]] From 29db874bc5b2b6c792a64c276eaf107074ebe160 Mon Sep 17 00:00:00 2001 From: Tim Diekmann Date: Fri, 17 Feb 2023 11:54:29 +0100 Subject: [PATCH 16/19] Revert "Make fields on `ProvenanceMetadata` pub` pub" This reverts commit 9ef14779 --- apps/hash-graph/bench/util.rs | 12 +++------- .../bin/cli/src/subcommand/server.rs | 8 ++----- .../lib/graph/src/api/rest/data_type.rs | 4 +--- .../lib/graph/src/api/rest/entity_type.rs | 4 +--- .../lib/graph/src/api/rest/property_type.rs | 8 +++---- .../lib/graph/src/shared/provenance.rs | 17 ++++++++++++- .../hash-graph/lib/graph/src/store/fetcher.rs | 10 ++++---- .../lib/graph/src/store/postgres.rs | 6 ++--- .../src/store/postgres/knowledge/entity.rs | 8 +++---- .../store/postgres/knowledge/entity/read.rs | 8 +++---- .../graph/src/store/postgres/ontology/read.rs | 2 +- .../tests/integration/postgres/lib.rs | 24 +++++-------------- 12 files changed, 47 insertions(+), 64 deletions(-) diff --git a/apps/hash-graph/bench/util.rs b/apps/hash-graph/bench/util.rs index a31246ee174..14c6cf08bc1 100644 --- a/apps/hash-graph/bench/util.rs +++ b/apps/hash-graph/bench/util.rs @@ -200,9 +200,7 @@ pub async fn seed( match store .create_data_type(data_type.clone(), &OntologyElementMetadata::Owned { record_id: data_type.id().clone().into(), - provenance: ProvenanceMetadata { - updated_by_id: UpdatedById::new(account_id), - }, + provenance: ProvenanceMetadata::new(UpdatedById::new(account_id)), owned_by_id: OwnedById::new(account_id), }) .await @@ -230,9 +228,7 @@ pub async fn seed( match store .create_property_type(property_type.clone(), &OntologyElementMetadata::Owned { record_id: property_type.id().clone().into(), - provenance: ProvenanceMetadata { - updated_by_id: UpdatedById::new(account_id), - }, + provenance: ProvenanceMetadata::new(UpdatedById::new(account_id)), owned_by_id: OwnedById::new(account_id), }) .await @@ -260,9 +256,7 @@ pub async fn seed( match store .create_entity_type(entity_type.clone(), &OntologyElementMetadata::Owned { record_id: entity_type.id().clone().into(), - provenance: ProvenanceMetadata { - updated_by_id: UpdatedById::new(account_id), - }, + provenance: ProvenanceMetadata::new(UpdatedById::new(account_id)), owned_by_id: OwnedById::new(account_id), }) .await diff --git a/apps/hash-graph/bin/cli/src/subcommand/server.rs b/apps/hash-graph/bin/cli/src/subcommand/server.rs index 914019b6612..3266d07e725 100644 --- a/apps/hash-graph/bin/cli/src/subcommand/server.rs +++ b/apps/hash-graph/bin/cli/src/subcommand/server.rs @@ -212,9 +212,7 @@ async fn stop_gap_setup(pool: &PostgresStorePool) -> Result<(), GraphErro let data_type_metadata = OntologyElementMetadata::External { record_id: data_type.id().clone().into(), - provenance: ProvenanceMetadata { - updated_by_id: UpdatedById::new(root_account_id), - }, + provenance: ProvenanceMetadata::new(UpdatedById::new(root_account_id)), fetched_at: OffsetDateTime::now_utc(), }; @@ -251,9 +249,7 @@ async fn stop_gap_setup(pool: &PostgresStorePool) -> Result<(), GraphErro let link_entity_type_metadata = OntologyElementMetadata::External { record_id: link_entity_type.id().clone().into(), - provenance: ProvenanceMetadata { - updated_by_id: UpdatedById::new(root_account_id), - }, + provenance: ProvenanceMetadata::new(UpdatedById::new(root_account_id)), fetched_at: OffsetDateTime::now_utc(), }; diff --git a/apps/hash-graph/lib/graph/src/api/rest/data_type.rs b/apps/hash-graph/lib/graph/src/api/rest/data_type.rs index d1a1bb1b55b..cbdb372ff30 100644 --- a/apps/hash-graph/lib/graph/src/api/rest/data_type.rs +++ b/apps/hash-graph/lib/graph/src/api/rest/data_type.rs @@ -111,9 +111,7 @@ async fn create_data_type( let metadata = OntologyElementMetadata::Owned { record_id: data_type.id().clone().into(), - provenance: ProvenanceMetadata { - updated_by_id: actor_id, - }, + provenance: ProvenanceMetadata::new(actor_id), owned_by_id, }; diff --git a/apps/hash-graph/lib/graph/src/api/rest/entity_type.rs b/apps/hash-graph/lib/graph/src/api/rest/entity_type.rs index b5b9ebee29e..bc0e8f3e49d 100644 --- a/apps/hash-graph/lib/graph/src/api/rest/entity_type.rs +++ b/apps/hash-graph/lib/graph/src/api/rest/entity_type.rs @@ -119,9 +119,7 @@ async fn create_entity_type( let metadata = OntologyElementMetadata::Owned { record_id: entity_type.id().clone().into(), - provenance: ProvenanceMetadata { - updated_by_id: actor_id, - }, + provenance: ProvenanceMetadata::new(actor_id), owned_by_id, }; diff --git a/apps/hash-graph/lib/graph/src/api/rest/property_type.rs b/apps/hash-graph/lib/graph/src/api/rest/property_type.rs index 89aea5ad769..b8c8d156d13 100644 --- a/apps/hash-graph/lib/graph/src/api/rest/property_type.rs +++ b/apps/hash-graph/lib/graph/src/api/rest/property_type.rs @@ -14,8 +14,8 @@ use crate::{ api::rest::{report_to_status_code, utoipa_typedef::subgraph::Subgraph}, ontology::{ domain_validator::{DomainValidator, ValidateOntologyType}, - patch_id_and_parse, OntologyElementMetadata, PropertyTypeQueryToken, - PropertyTypeWithMetadata, + patch_id_and_parse, OntologyElementMetadata, + PropertyTypeQueryToken, PropertyTypeWithMetadata, }, provenance::{OwnedById, ProvenanceMetadata, UpdatedById}, store::{BaseUriAlreadyExists, BaseUriDoesNotExist, PropertyTypeStore, StorePool}, @@ -117,9 +117,7 @@ async fn create_property_type( let metadata = OntologyElementMetadata::Owned { record_id: property_type.id().clone().into(), - provenance: ProvenanceMetadata { - updated_by_id: actor_id, - }, + provenance: ProvenanceMetadata::new(actor_id), owned_by_id, }; diff --git a/apps/hash-graph/lib/graph/src/shared/provenance.rs b/apps/hash-graph/lib/graph/src/shared/provenance.rs index 60a9ccd1339..570232c738a 100644 --- a/apps/hash-graph/lib/graph/src/shared/provenance.rs +++ b/apps/hash-graph/lib/graph/src/shared/provenance.rs @@ -61,8 +61,23 @@ macro_rules! define_provenance_id { define_provenance_id!(OwnedById); define_provenance_id!(UpdatedById); +// TODO: Make fields `pub` when `#[feature(mut_restriction)]` is available. +// see https://github.com/rust-lang/rust/issues/105077 +// see https://app.asana.com/0/0/1203977361907407/f #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, ToSchema)] #[serde(deny_unknown_fields, rename_all = "camelCase")] pub struct ProvenanceMetadata { - pub updated_by_id: UpdatedById, + updated_by_id: UpdatedById, +} + +impl ProvenanceMetadata { + #[must_use] + pub const fn new(updated_by_id: UpdatedById) -> Self { + Self { updated_by_id } + } + + #[must_use] + pub const fn updated_by_id(&self) -> UpdatedById { + self.updated_by_id + } } diff --git a/apps/hash-graph/lib/graph/src/store/fetcher.rs b/apps/hash-graph/lib/graph/src/store/fetcher.rs index 5431d4578a7..f92fe3c9f60 100644 --- a/apps/hash-graph/lib/graph/src/store/fetcher.rs +++ b/apps/hash-graph/lib/graph/src/store/fetcher.rs @@ -210,9 +210,7 @@ where let mut entity_types = Vec::new(); for (reference, fetched_by) in ontology_type_references { - let provenance = ProvenanceMetadata { - updated_by_id: fetched_by, - }; + let provenance = ProvenanceMetadata::new(fetched_by); let fetched_ontology_types = fetcher_client .fetch_ontology_type_exhaustive(context::current(), reference.uri().clone()) .await @@ -400,7 +398,7 @@ where self.insert_external_types(data_types.iter().map(|(data_type, metadata)| { ( data_type, - metadata.borrow().provenance_metadata().updated_by_id, + metadata.borrow().provenance_metadata().updated_by_id(), ) })) .await?; @@ -449,7 +447,7 @@ where self.insert_external_types(property_types.iter().map(|(property_type, metadata)| { ( property_type, - metadata.borrow().provenance_metadata().updated_by_id, + metadata.borrow().provenance_metadata().updated_by_id(), ) })) .await?; @@ -500,7 +498,7 @@ where self.insert_external_types(entity_types.iter().map(|(entity_type, metadata)| { ( entity_type, - metadata.borrow().provenance_metadata().updated_by_id, + metadata.borrow().provenance_metadata().updated_by_id(), ) })) .await?; diff --git a/apps/hash-graph/lib/graph/src/store/postgres.rs b/apps/hash-graph/lib/graph/src/store/postgres.rs index e02f487b216..1cbf1de07fe 100644 --- a/apps/hash-graph/lib/graph/src/store/postgres.rs +++ b/apps/hash-graph/lib/graph/src/store/postgres.rs @@ -271,7 +271,7 @@ where &record_id.base_uri.as_str(), &record_id.version, &owned_by_id, - &provenance.updated_by_id, + &provenance.updated_by_id(), ], ) .await @@ -315,7 +315,7 @@ where &record_id.base_uri.as_str(), &record_id.version, &fetched_at, - &provenance.updated_by_id, + &provenance.updated_by_id(), ], ) .await @@ -464,7 +464,7 @@ where Ok((ontology_id, OntologyElementMetadata::Owned { record_id, - provenance: ProvenanceMetadata { updated_by_id }, + provenance: ProvenanceMetadata::new(updated_by_id), owned_by_id, })) } diff --git a/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity.rs b/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity.rs index 2c5db626c06..6c6b76f8cc0 100644 --- a/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity.rs +++ b/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity.rs @@ -384,7 +384,7 @@ impl EntityStore for PostgresStore { transaction_time: row.get(2), }, entity_type_id, - provenance: ProvenanceMetadata { updated_by_id }, + provenance: ProvenanceMetadata::new(updated_by_id), archived, }) } @@ -479,9 +479,7 @@ impl EntityStore for PostgresStore { }, version, entity_type_id: entity_type_id.clone(), - provenance: ProvenanceMetadata { - updated_by_id: actor_id, - }, + provenance: ProvenanceMetadata::new(actor_id), archived: false, }) .collect()) @@ -624,7 +622,7 @@ impl EntityStore for PostgresStore { transaction_time: row.get(2), }, entity_type_id, - provenance: ProvenanceMetadata { updated_by_id }, + provenance: ProvenanceMetadata::new(updated_by_id), archived, }) } diff --git a/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity/read.rs b/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity/read.rs index 566ceb82350..c793a1ec688 100644 --- a/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity/read.rs +++ b/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity/read.rs @@ -18,7 +18,7 @@ use crate::{ LinkData, }, ontology::EntityTypeQueryPath, - provenance::{OwnedById, ProvenanceMetadata}, + provenance::{OwnedById, ProvenanceMetadata, UpdatedById}, store::{ crud, postgres::query::{Distinctness, SelectCompiler}, @@ -133,6 +133,8 @@ impl crud::Read for PostgresStore { } }; + let updated_by_id = UpdatedById::new(row.get(updated_by_id_index)); + Ok(Entity { properties, link_data, @@ -149,9 +151,7 @@ impl crud::Read for PostgresStore { transaction_time: row.get(transaction_time_index), }, entity_type_id, - provenance: ProvenanceMetadata { - updated_by_id: row.get(updated_by_id_index), - }, + provenance: ProvenanceMetadata::new(updated_by_id), archived: row.get(archived_index), }, }) diff --git a/apps/hash-graph/lib/graph/src/store/postgres/ontology/read.rs b/apps/hash-graph/lib/graph/src/store/postgres/ontology/read.rs index 33f38b0b421..b9b32d590a0 100644 --- a/apps/hash-graph/lib/graph/src/store/postgres/ontology/read.rs +++ b/apps/hash-graph/lib/graph/src/store/postgres/ontology/read.rs @@ -111,7 +111,7 @@ where .change_context(QueryError)?; let record_id = OntologyTypeRecordId { base_uri, version }; - let provenance = ProvenanceMetadata { updated_by_id }; + let provenance = ProvenanceMetadata::new(updated_by_id); Ok(T::new(record, match metadata { AdditionalOntologyMetadata::Owned { owned_by_id } => { diff --git a/apps/hash-graph/tests/integration/postgres/lib.rs b/apps/hash-graph/tests/integration/postgres/lib.rs index 5f751e07195..2ba2bdd07b9 100644 --- a/apps/hash-graph/tests/integration/postgres/lib.rs +++ b/apps/hash-graph/tests/integration/postgres/lib.rs @@ -124,9 +124,7 @@ impl DatabaseTestWrapper { let metadata = OntologyElementMetadata::Owned { record_id: data_type.id().clone().into(), - provenance: ProvenanceMetadata { - updated_by_id: UpdatedById::new(account_id), - }, + provenance: ProvenanceMetadata::new(UpdatedById::new(account_id)), owned_by_id: OwnedById::new(account_id), }; @@ -142,9 +140,7 @@ impl DatabaseTestWrapper { let metadata = OntologyElementMetadata::Owned { record_id: property_type.id().clone().into(), - provenance: ProvenanceMetadata { - updated_by_id: UpdatedById::new(account_id), - }, + provenance: ProvenanceMetadata::new(UpdatedById::new(account_id)), owned_by_id: OwnedById::new(account_id), }; @@ -160,9 +156,7 @@ impl DatabaseTestWrapper { let metadata = OntologyElementMetadata::Owned { record_id: entity_type.id().clone().into(), - provenance: ProvenanceMetadata { - updated_by_id: UpdatedById::new(account_id), - }, + provenance: ProvenanceMetadata::new(UpdatedById::new(account_id)), owned_by_id: OwnedById::new(account_id), }; @@ -195,9 +189,7 @@ impl DatabaseApi<'_> { ) -> Result { let metadata = OntologyElementMetadata::Owned { record_id: data_type.id().clone().into(), - provenance: ProvenanceMetadata { - updated_by_id: UpdatedById::new(self.account_id), - }, + provenance: ProvenanceMetadata::new(UpdatedById::new(self.account_id)), owned_by_id: OwnedById::new(self.account_id), }; @@ -242,9 +234,7 @@ impl DatabaseApi<'_> { ) -> Result { let metadata = OntologyElementMetadata::Owned { record_id: property_type.id().clone().into(), - provenance: ProvenanceMetadata { - updated_by_id: UpdatedById::new(self.account_id), - }, + provenance: ProvenanceMetadata::new(UpdatedById::new(self.account_id)), owned_by_id: OwnedById::new(self.account_id), }; @@ -291,9 +281,7 @@ impl DatabaseApi<'_> { ) -> Result { let metadata = OntologyElementMetadata::Owned { record_id: entity_type.id().clone().into(), - provenance: ProvenanceMetadata { - updated_by_id: UpdatedById::new(self.account_id), - }, + provenance: ProvenanceMetadata::new(UpdatedById::new(self.account_id)), owned_by_id: OwnedById::new(self.account_id), }; From 42b77488ff3f3be2b0c740c2803c507b6720af2b Mon Sep 17 00:00:00 2001 From: Tim Diekmann Date: Fri, 17 Feb 2023 11:56:31 +0100 Subject: [PATCH 17/19] Revert "Flatten `OntologyElementMetadata`" This reverts commit 22fe8b0abecf4b445fdea99a706fe78595c55548. --- apps/hash-graph/bench/util.rs | 41 ++++--- apps/hash-graph/lib/graph/src/api/rest.rs | 7 +- .../lib/graph/src/api/rest/data_type.rs | 9 +- .../lib/graph/src/api/rest/entity_type.rs | 9 +- .../lib/graph/src/api/rest/property_type.rs | 10 +- apps/hash-graph/lib/graph/src/ontology.rs | 107 +++++++++++++++--- .../hash-graph/lib/graph/src/store/fetcher.rs | 49 ++++---- .../lib/graph/src/store/postgres.rs | 68 +++++------ .../graph/src/store/postgres/ontology/read.rs | 17 +-- .../tests/integration/postgres/lib.rs | 62 +++++----- 10 files changed, 230 insertions(+), 149 deletions(-) diff --git a/apps/hash-graph/bench/util.rs b/apps/hash-graph/bench/util.rs index 14c6cf08bc1..e0b9aa8c2e7 100644 --- a/apps/hash-graph/bench/util.rs +++ b/apps/hash-graph/bench/util.rs @@ -2,7 +2,7 @@ use std::mem::ManuallyDrop; use graph::{ identifier::account::AccountId, - ontology::OntologyElementMetadata, + ontology::{OntologyElementMetadata, OwnedOntologyElementMetadata}, provenance::{OwnedById, ProvenanceMetadata, UpdatedById}, store::{ AsClient, BaseUriAlreadyExists, DataTypeStore, DatabaseConnectionInfo, DatabaseType, @@ -198,11 +198,14 @@ pub async fn seed( let data_type = DataType::try_from(data_type_repr).expect("could not parse data type"); match store - .create_data_type(data_type.clone(), &OntologyElementMetadata::Owned { - record_id: data_type.id().clone().into(), - provenance: ProvenanceMetadata::new(UpdatedById::new(account_id)), - owned_by_id: OwnedById::new(account_id), - }) + .create_data_type( + data_type.clone(), + &OntologyElementMetadata::Owned(OwnedOntologyElementMetadata::new( + data_type.id().clone().into(), + ProvenanceMetadata::new(UpdatedById::new(account_id)), + OwnedById::new(account_id), + )), + ) .await { Ok(_) => {} @@ -226,11 +229,14 @@ pub async fn seed( PropertyType::try_from(property_typee_repr).expect("could not parse property type"); match store - .create_property_type(property_type.clone(), &OntologyElementMetadata::Owned { - record_id: property_type.id().clone().into(), - provenance: ProvenanceMetadata::new(UpdatedById::new(account_id)), - owned_by_id: OwnedById::new(account_id), - }) + .create_property_type( + property_type.clone(), + &OntologyElementMetadata::Owned(OwnedOntologyElementMetadata::new( + property_type.id().clone().into(), + ProvenanceMetadata::new(UpdatedById::new(account_id)), + OwnedById::new(account_id), + )), + ) .await { Ok(_) => {} @@ -254,11 +260,14 @@ pub async fn seed( EntityType::try_from(entity_type_repr).expect("could not parse entity type"); match store - .create_entity_type(entity_type.clone(), &OntologyElementMetadata::Owned { - record_id: entity_type.id().clone().into(), - provenance: ProvenanceMetadata::new(UpdatedById::new(account_id)), - owned_by_id: OwnedById::new(account_id), - }) + .create_entity_type( + entity_type.clone(), + &OntologyElementMetadata::Owned(OwnedOntologyElementMetadata::new( + entity_type.id().clone().into(), + ProvenanceMetadata::new(UpdatedById::new(account_id)), + OwnedById::new(account_id), + )), + ) .await { Ok(_) => {} diff --git a/apps/hash-graph/lib/graph/src/api/rest.rs b/apps/hash-graph/lib/graph/src/api/rest.rs index 72d16cd4e88..06456a5e0e6 100644 --- a/apps/hash-graph/lib/graph/src/api/rest.rs +++ b/apps/hash-graph/lib/graph/src/api/rest.rs @@ -56,7 +56,10 @@ use crate::{ }, EntityVertexId, GraphElementVertexId, OntologyTypeVertexId, }, - ontology::{domain_validator::DomainValidator, OntologyElementMetadata, Selector}, + ontology::{ + domain_validator::DomainValidator, ExternalOntologyElementMetadata, + OntologyElementMetadata, OwnedOntologyElementMetadata, Selector, + }, provenance::{OwnedById, ProvenanceMetadata, UpdatedById}, store::{QueryError, StorePool}, subgraph::edges::{ @@ -176,6 +179,8 @@ async fn serve_static_schema(Path(path): Path) -> Result( StatusCode::INTERNAL_SERVER_ERROR })?; - let metadata = OntologyElementMetadata::Owned { - record_id: data_type.id().clone().into(), - provenance: ProvenanceMetadata::new(actor_id), + let metadata = OntologyElementMetadata::Owned(OwnedOntologyElementMetadata::new( + data_type.id().clone().into(), + ProvenanceMetadata::new(actor_id), owned_by_id, - }; + )); store .create_data_type(data_type, &metadata) diff --git a/apps/hash-graph/lib/graph/src/api/rest/entity_type.rs b/apps/hash-graph/lib/graph/src/api/rest/entity_type.rs index bc0e8f3e49d..e5c80ce522b 100644 --- a/apps/hash-graph/lib/graph/src/api/rest/entity_type.rs +++ b/apps/hash-graph/lib/graph/src/api/rest/entity_type.rs @@ -16,6 +16,7 @@ use crate::{ ontology::{ domain_validator::{DomainValidator, ValidateOntologyType}, patch_id_and_parse, EntityTypeQueryToken, EntityTypeWithMetadata, OntologyElementMetadata, + OwnedOntologyElementMetadata, }, provenance::{OwnedById, ProvenanceMetadata, UpdatedById}, store::{ @@ -117,11 +118,11 @@ async fn create_entity_type( StatusCode::INTERNAL_SERVER_ERROR })?; - let metadata = OntologyElementMetadata::Owned { - record_id: entity_type.id().clone().into(), - provenance: ProvenanceMetadata::new(actor_id), + let metadata = OntologyElementMetadata::Owned(OwnedOntologyElementMetadata::new( + entity_type.id().clone().into(), + ProvenanceMetadata::new(actor_id), owned_by_id, - }; + )); store .create_entity_type(entity_type, &metadata) diff --git a/apps/hash-graph/lib/graph/src/api/rest/property_type.rs b/apps/hash-graph/lib/graph/src/api/rest/property_type.rs index b8c8d156d13..1507bffb8e7 100644 --- a/apps/hash-graph/lib/graph/src/api/rest/property_type.rs +++ b/apps/hash-graph/lib/graph/src/api/rest/property_type.rs @@ -14,7 +14,7 @@ use crate::{ api::rest::{report_to_status_code, utoipa_typedef::subgraph::Subgraph}, ontology::{ domain_validator::{DomainValidator, ValidateOntologyType}, - patch_id_and_parse, OntologyElementMetadata, + patch_id_and_parse, OntologyElementMetadata, OwnedOntologyElementMetadata, PropertyTypeQueryToken, PropertyTypeWithMetadata, }, provenance::{OwnedById, ProvenanceMetadata, UpdatedById}, @@ -115,11 +115,11 @@ async fn create_property_type( StatusCode::INTERNAL_SERVER_ERROR })?; - let metadata = OntologyElementMetadata::Owned { - record_id: property_type.id().clone().into(), - provenance: ProvenanceMetadata::new(actor_id), + let metadata = OntologyElementMetadata::Owned(OwnedOntologyElementMetadata::new( + property_type.id().clone().into(), + ProvenanceMetadata::new(actor_id), owned_by_id, - }; + )); store .create_property_type(property_type, &metadata) diff --git a/apps/hash-graph/lib/graph/src/ontology.rs b/apps/hash-graph/lib/graph/src/ontology.rs index 8d00bff9446..402ee8af628 100644 --- a/apps/hash-graph/lib/graph/src/ontology.rs +++ b/apps/hash-graph/lib/graph/src/ontology.rs @@ -173,41 +173,112 @@ pub trait OntologyTypeWithMetadata: Record { fn metadata(&self) -> &OntologyElementMetadata; } +// TODO: Flatten when `#[feature(mut_restriction)]` is available. +// see https://github.com/rust-lang/rust/issues/105077 +// see https://app.asana.com/0/0/1203977361907407/f #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, ToSchema)] #[serde(untagged)] pub enum OntologyElementMetadata { - #[serde(rename_all = "camelCase")] - #[schema(title = "OwnedOntologyElementMetadata")] - Owned { - record_id: OntologyTypeRecordId, - provenance: ProvenanceMetadata, - owned_by_id: OwnedById, - }, - #[serde(rename_all = "camelCase")] - #[schema(title = "ExternalOntologyElementMetadata")] - External { - record_id: OntologyTypeRecordId, - provenance: ProvenanceMetadata, - #[schema(value_type = String)] - #[serde(with = "time::serde::iso8601")] - fetched_at: OffsetDateTime, - }, + Owned(OwnedOntologyElementMetadata), + External(ExternalOntologyElementMetadata), } impl OntologyElementMetadata { #[must_use] pub const fn record_id(&self) -> &OntologyTypeRecordId { match self { - Self::Owned { record_id, .. } | Self::External { record_id, .. } => record_id, + Self::Owned(owned) => owned.record_id(), + Self::External(external) => external.record_id(), } } #[must_use] pub const fn provenance_metadata(&self) -> ProvenanceMetadata { match self { - Self::Owned { provenance, .. } | Self::External { provenance, .. } => *provenance, + Self::Owned(owned) => owned.provenance_metadata, + Self::External(external) => external.provenance_metadata, + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, ToSchema)] +#[serde(rename_all = "camelCase")] +pub struct OwnedOntologyElementMetadata { + record_id: OntologyTypeRecordId, + #[serde(rename = "provenance")] + provenance_metadata: ProvenanceMetadata, + owned_by_id: OwnedById, +} + +impl OwnedOntologyElementMetadata { + #[must_use] + pub const fn new( + record_id: OntologyTypeRecordId, + provenance_metadata: ProvenanceMetadata, + owned_by_id: OwnedById, + ) -> Self { + Self { + record_id, + provenance_metadata, + owned_by_id, + } + } + + #[must_use] + pub const fn record_id(&self) -> &OntologyTypeRecordId { + &self.record_id + } + + #[must_use] + pub const fn provenance_metadata(&self) -> ProvenanceMetadata { + self.provenance_metadata + } + + #[must_use] + pub const fn owned_by_id(&self) -> OwnedById { + self.owned_by_id + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, ToSchema)] +#[serde(rename_all = "camelCase")] +pub struct ExternalOntologyElementMetadata { + record_id: OntologyTypeRecordId, + #[serde(rename = "provenance")] + provenance_metadata: ProvenanceMetadata, + #[schema(value_type = String)] + #[serde(with = "time::serde::iso8601")] + fetched_at: OffsetDateTime, +} + +impl ExternalOntologyElementMetadata { + #[must_use] + pub const fn new( + record_id: OntologyTypeRecordId, + provenance_metadata: ProvenanceMetadata, + fetched_at: OffsetDateTime, + ) -> Self { + Self { + record_id, + provenance_metadata, + fetched_at, } } + + #[must_use] + pub const fn record_id(&self) -> &OntologyTypeRecordId { + &self.record_id + } + + #[must_use] + pub const fn provenance_metadata(&self) -> ProvenanceMetadata { + self.provenance_metadata + } + + #[must_use] + pub const fn fetched_at(&self) -> OffsetDateTime { + self.fetched_at + } } #[derive(Debug, PartialEq, Eq, Serialize, ToSchema)] diff --git a/apps/hash-graph/lib/graph/src/store/fetcher.rs b/apps/hash-graph/lib/graph/src/store/fetcher.rs index f92fe3c9f60..76114963fc6 100644 --- a/apps/hash-graph/lib/graph/src/store/fetcher.rs +++ b/apps/hash-graph/lib/graph/src/store/fetcher.rs @@ -26,7 +26,7 @@ use crate::{ knowledge::{Entity, EntityLinkOrder, EntityMetadata, EntityProperties, EntityUuid, LinkData}, ontology::{ domain_validator::DomainValidator, DataTypeWithMetadata, EntityTypeWithMetadata, - OntologyElementMetadata, PropertyTypeWithMetadata, + ExternalOntologyElementMetadata, OntologyElementMetadata, PropertyTypeWithMetadata, }, provenance::{OwnedById, ProvenanceMetadata, UpdatedById}, store::{ @@ -210,7 +210,7 @@ where let mut entity_types = Vec::new(); for (reference, fetched_by) in ontology_type_references { - let provenance = ProvenanceMetadata::new(fetched_by); + let provenance_metadata = ProvenanceMetadata::new(fetched_by); let fetched_ontology_types = fetcher_client .fetch_ontology_type_exhaustive(context::current(), reference.uri().clone()) .await @@ -232,13 +232,14 @@ where )) .await? { - let metadata = OntologyElementMetadata::External { - record_id: data_type.id().clone().into(), - provenance, - fetched_at: fetched_ontology_type.fetched_at, - }; - - data_types.push((data_type, metadata)); + let metadata = ExternalOntologyElementMetadata::new( + data_type.id().clone().into(), + provenance_metadata, + fetched_ontology_type.fetched_at, + ); + + data_types + .push((data_type, OntologyElementMetadata::External(metadata))); } } OntologyType::PropertyType(property_type) => { @@ -253,13 +254,14 @@ where )) .await? { - let metadata = OntologyElementMetadata::External { - record_id: property_type.id().clone().into(), - provenance, - fetched_at: fetched_ontology_type.fetched_at, - }; - - property_types.push((property_type, metadata)); + let metadata = ExternalOntologyElementMetadata::new( + property_type.id().clone().into(), + provenance_metadata, + fetched_ontology_type.fetched_at, + ); + + property_types + .push((property_type, OntologyElementMetadata::External(metadata))); } } OntologyType::EntityType(entity_type) => { @@ -274,13 +276,14 @@ where )) .await? { - let metadata = OntologyElementMetadata::External { - record_id: entity_type.id().clone().into(), - provenance, - fetched_at: fetched_ontology_type.fetched_at, - }; - - entity_types.push((entity_type, metadata)); + let metadata = ExternalOntologyElementMetadata::new( + entity_type.id().clone().into(), + provenance_metadata, + fetched_ontology_type.fetched_at, + ); + + entity_types + .push((entity_type, OntologyElementMetadata::External(metadata))); } } } diff --git a/apps/hash-graph/lib/graph/src/store/postgres.rs b/apps/hash-graph/lib/graph/src/store/postgres.rs index 1cbf1de07fe..e2632090f78 100644 --- a/apps/hash-graph/lib/graph/src/store/postgres.rs +++ b/apps/hash-graph/lib/graph/src/store/postgres.rs @@ -13,7 +13,6 @@ use std::{ use async_trait::async_trait; use error_stack::{IntoReport, Result, ResultExt}; -use time::OffsetDateTime; #[cfg(feature = "__internal_bench")] use tokio_postgres::{binary_copy::BinaryCopyInWriter, types::Type}; use tokio_postgres::{error::SqlState, GenericClient}; @@ -31,7 +30,9 @@ use crate::{ EntityVertexId, OntologyTypeVertexId, }, interval::Interval, - ontology::OntologyElementMetadata, + ontology::{ + ExternalOntologyElementMetadata, OntologyElementMetadata, OwnedOntologyElementMetadata, + }, provenance::{OwnedById, ProvenanceMetadata, UpdatedById}, store::{ error::{VersionedUriAlreadyExists, WrongOntologyVersion}, @@ -252,9 +253,7 @@ where #[tracing::instrument(level = "debug", skip(self))] async fn create_owned_ontology_id( &self, - record_id: &OntologyTypeRecordId, - provenance: ProvenanceMetadata, - owned_by_id: OwnedById, + metadata: &OwnedOntologyElementMetadata, ) -> Result { self.as_client() .query_one( @@ -268,10 +267,10 @@ where record_created_by_id := $4 );"#, &[ - &record_id.base_uri.as_str(), - &record_id.version, - &owned_by_id, - &provenance.updated_by_id(), + &metadata.record_id().base_uri.as_str(), + &metadata.record_id().version, + &metadata.owned_by_id(), + &metadata.provenance_metadata().updated_by_id(), ], ) .await @@ -280,11 +279,11 @@ where .map_err(|report| match report.current_context().code() { Some(&SqlState::EXCLUSION_VIOLATION | &SqlState::UNIQUE_VIOLATION) => report .change_context(BaseUriAlreadyExists) - .attach_printable(record_id.base_uri.clone()) + .attach_printable(metadata.record_id().base_uri.clone()) .change_context(InsertionError), _ => report .change_context(InsertionError) - .attach_printable(VersionedUri::from(record_id.clone())), + .attach_printable(VersionedUri::from(metadata.record_id().clone())), }) } @@ -296,9 +295,7 @@ where #[tracing::instrument(level = "debug", skip(self))] async fn create_external_ontology_id( &self, - record_id: &OntologyTypeRecordId, - provenance: ProvenanceMetadata, - fetched_at: OffsetDateTime, + metadata: &ExternalOntologyElementMetadata, ) -> Result { self.as_client() .query_one( @@ -312,10 +309,10 @@ where record_created_by_id := $4 );"#, &[ - &record_id.base_uri.as_str(), - &record_id.version, - &fetched_at, - &provenance.updated_by_id(), + &metadata.record_id().base_uri.as_str(), + &metadata.record_id().version, + &metadata.fetched_at(), + &metadata.provenance_metadata().updated_by_id(), ], ) .await @@ -324,11 +321,11 @@ where .map_err(|report| match report.current_context().code() { Some(&SqlState::EXCLUSION_VIOLATION | &SqlState::UNIQUE_VIOLATION) => report .change_context(BaseUriAlreadyExists) - .attach_printable(record_id.base_uri.clone()) + .attach_printable(metadata.record_id().base_uri.clone()) .change_context(InsertionError), _ => report .change_context(InsertionError) - .attach_printable(VersionedUri::from(record_id.clone())), + .attach_printable(VersionedUri::from(metadata.record_id().clone())), }) } @@ -408,21 +405,11 @@ where T::Representation: Send, { let ontology_id = match metadata { - OntologyElementMetadata::Owned { - record_id, - provenance, - owned_by_id, - } => { - self.create_owned_ontology_id(record_id, *provenance, *owned_by_id) - .await? + OntologyElementMetadata::Owned(metadata) => { + self.create_owned_ontology_id(metadata).await? } - OntologyElementMetadata::External { - record_id, - provenance, - fetched_at, - } => { - self.create_external_ontology_id(record_id, *provenance, *fetched_at) - .await? + OntologyElementMetadata::External(metadata) => { + self.create_external_ontology_id(metadata).await? } }; @@ -462,11 +449,14 @@ where .await .change_context(UpdateError)?; - Ok((ontology_id, OntologyElementMetadata::Owned { - record_id, - provenance: ProvenanceMetadata::new(updated_by_id), - owned_by_id, - })) + Ok(( + ontology_id, + OntologyElementMetadata::Owned(OwnedOntologyElementMetadata::new( + record_id, + ProvenanceMetadata::new(updated_by_id), + owned_by_id, + )), + )) } /// Inserts an [`OntologyDatabaseType`] identified by [`OntologyId`], and associated with an diff --git a/apps/hash-graph/lib/graph/src/store/postgres/ontology/read.rs b/apps/hash-graph/lib/graph/src/store/postgres/ontology/read.rs index b9b32d590a0..0ca51c83c36 100644 --- a/apps/hash-graph/lib/graph/src/store/postgres/ontology/read.rs +++ b/apps/hash-graph/lib/graph/src/store/postgres/ontology/read.rs @@ -14,7 +14,10 @@ use crate::{ ontology::{OntologyTypeRecordId, OntologyTypeVersion}, time::TimeProjection, }, - ontology::{OntologyElementMetadata, OntologyType, OntologyTypeWithMetadata}, + ontology::{ + ExternalOntologyElementMetadata, OntologyElementMetadata, OntologyType, + OntologyTypeWithMetadata, OwnedOntologyElementMetadata, + }, provenance::{OwnedById, ProvenanceMetadata, UpdatedById}, store::{ crud::Read, @@ -115,18 +118,16 @@ where Ok(T::new(record, match metadata { AdditionalOntologyMetadata::Owned { owned_by_id } => { - OntologyElementMetadata::Owned { + OntologyElementMetadata::Owned(OwnedOntologyElementMetadata::new( record_id, provenance, owned_by_id, - } + )) } AdditionalOntologyMetadata::External { fetched_at } => { - OntologyElementMetadata::External { - record_id, - provenance, - fetched_at, - } + OntologyElementMetadata::External(ExternalOntologyElementMetadata::new( + record_id, provenance, fetched_at, + )) } })) }) diff --git a/apps/hash-graph/tests/integration/postgres/lib.rs b/apps/hash-graph/tests/integration/postgres/lib.rs index 2ba2bdd07b9..506e0766751 100644 --- a/apps/hash-graph/tests/integration/postgres/lib.rs +++ b/apps/hash-graph/tests/integration/postgres/lib.rs @@ -32,7 +32,7 @@ use graph::{ }, ontology::{ DataTypeWithMetadata, EntityTypeQueryPath, EntityTypeWithMetadata, OntologyElementMetadata, - PropertyTypeWithMetadata, + OwnedOntologyElementMetadata, PropertyTypeWithMetadata, }, provenance::{OwnedById, ProvenanceMetadata, UpdatedById}, store::{ @@ -122,11 +122,11 @@ impl DatabaseTestWrapper { .expect("could not parse data type representation"); let data_type = DataType::try_from(data_type_repr).expect("could not parse data type"); - let metadata = OntologyElementMetadata::Owned { - record_id: data_type.id().clone().into(), - provenance: ProvenanceMetadata::new(UpdatedById::new(account_id)), - owned_by_id: OwnedById::new(account_id), - }; + let metadata = OntologyElementMetadata::Owned(OwnedOntologyElementMetadata::new( + data_type.id().clone().into(), + ProvenanceMetadata::new(UpdatedById::new(account_id)), + OwnedById::new(account_id), + )); (data_type, metadata) }); @@ -138,11 +138,11 @@ impl DatabaseTestWrapper { let property_type = PropertyType::try_from(property_type_repr).expect("could not parse property type"); - let metadata = OntologyElementMetadata::Owned { - record_id: property_type.id().clone().into(), - provenance: ProvenanceMetadata::new(UpdatedById::new(account_id)), - owned_by_id: OwnedById::new(account_id), - }; + let metadata = OntologyElementMetadata::Owned(OwnedOntologyElementMetadata::new( + property_type.id().clone().into(), + ProvenanceMetadata::new(UpdatedById::new(account_id)), + OwnedById::new(account_id), + )); (property_type, metadata) }); @@ -154,11 +154,11 @@ impl DatabaseTestWrapper { let entity_type = EntityType::try_from(entity_type_repr).expect("could not parse entity type"); - let metadata = OntologyElementMetadata::Owned { - record_id: entity_type.id().clone().into(), - provenance: ProvenanceMetadata::new(UpdatedById::new(account_id)), - owned_by_id: OwnedById::new(account_id), - }; + let metadata = OntologyElementMetadata::Owned(OwnedOntologyElementMetadata::new( + entity_type.id().clone().into(), + ProvenanceMetadata::new(UpdatedById::new(account_id)), + OwnedById::new(account_id), + )); (entity_type, metadata) }); @@ -187,11 +187,11 @@ impl DatabaseApi<'_> { &mut self, data_type: DataType, ) -> Result { - let metadata = OntologyElementMetadata::Owned { - record_id: data_type.id().clone().into(), - provenance: ProvenanceMetadata::new(UpdatedById::new(self.account_id)), - owned_by_id: OwnedById::new(self.account_id), - }; + let metadata = OntologyElementMetadata::Owned(OwnedOntologyElementMetadata::new( + data_type.id().clone().into(), + ProvenanceMetadata::new(UpdatedById::new(self.account_id)), + OwnedById::new(self.account_id), + )); self.store.create_data_type(data_type, &metadata).await?; @@ -232,11 +232,11 @@ impl DatabaseApi<'_> { &mut self, property_type: PropertyType, ) -> Result { - let metadata = OntologyElementMetadata::Owned { - record_id: property_type.id().clone().into(), - provenance: ProvenanceMetadata::new(UpdatedById::new(self.account_id)), - owned_by_id: OwnedById::new(self.account_id), - }; + let metadata = OntologyElementMetadata::Owned(OwnedOntologyElementMetadata::new( + property_type.id().clone().into(), + ProvenanceMetadata::new(UpdatedById::new(self.account_id)), + OwnedById::new(self.account_id), + )); self.store .create_property_type(property_type, &metadata) @@ -279,11 +279,11 @@ impl DatabaseApi<'_> { &mut self, entity_type: EntityType, ) -> Result { - let metadata = OntologyElementMetadata::Owned { - record_id: entity_type.id().clone().into(), - provenance: ProvenanceMetadata::new(UpdatedById::new(self.account_id)), - owned_by_id: OwnedById::new(self.account_id), - }; + let metadata = OntologyElementMetadata::Owned(OwnedOntologyElementMetadata::new( + entity_type.id().clone().into(), + ProvenanceMetadata::new(UpdatedById::new(self.account_id)), + OwnedById::new(self.account_id), + )); self.store .create_entity_type(entity_type, &metadata) From 167abec91d09d5d8ff0196a0d93daac5b5824881 Mon Sep 17 00:00:00 2001 From: Tim Diekmann Date: Fri, 17 Feb 2023 11:59:27 +0100 Subject: [PATCH 18/19] Revert "Make fields on `EntityMetadata` pub" This reverts commit c1b948fa --- .../read_scaling/knowledge/complete/entity.rs | 6 +- .../read_scaling/knowledge/linkless/entity.rs | 2 +- .../bench/representative_read/seed.rs | 4 +- .../lib/graph/src/knowledge/entity.rs | 64 ++++++++++++++++--- .../src/store/postgres/knowledge/entity.rs | 59 ++++++++--------- .../store/postgres/knowledge/entity/read.rs | 12 ++-- .../tests/integration/postgres/entity.rs | 18 +++--- .../tests/integration/postgres/links.rs | 53 ++++++++------- 8 files changed, 138 insertions(+), 80 deletions(-) diff --git a/apps/hash-graph/bench/read_scaling/knowledge/complete/entity.rs b/apps/hash-graph/bench/read_scaling/knowledge/complete/entity.rs index 0aeadbe6b3e..bd56c59fd4b 100644 --- a/apps/hash-graph/bench/read_scaling/knowledge/complete/entity.rs +++ b/apps/hash-graph/bench/read_scaling/knowledge/complete/entity.rs @@ -106,8 +106,8 @@ async fn seed_db( None, properties.clone(), Some(LinkData { - left_entity_id: entity_a_metadata.record_id.entity_id, - right_entity_id: entity_b_metadata.record_id.entity_id, + left_entity_id: entity_a_metadata.record_id().entity_id, + right_entity_id: entity_b_metadata.record_id().entity_id, order: EntityLinkOrder { left_to_right: None, right_to_left: None, @@ -156,7 +156,7 @@ pub fn bench_get_entity_by_id( // query entity_metadata_list .iter() - .map(|metadata| metadata.record_id) + .map(EntityMetadata::record_id) .choose(&mut thread_rng()) .expect("could not choose random entity") }, diff --git a/apps/hash-graph/bench/read_scaling/knowledge/linkless/entity.rs b/apps/hash-graph/bench/read_scaling/knowledge/linkless/entity.rs index 4a9627529a9..86ad860e99a 100644 --- a/apps/hash-graph/bench/read_scaling/knowledge/linkless/entity.rs +++ b/apps/hash-graph/bench/read_scaling/knowledge/linkless/entity.rs @@ -108,7 +108,7 @@ pub fn bench_get_entity_by_id( // query entity_metadata_list .iter() - .map(|metadata| metadata.record_id) + .map(EntityMetadata::record_id) .choose(&mut thread_rng()) .expect("could not choose random entity") }, diff --git a/apps/hash-graph/bench/representative_read/seed.rs b/apps/hash-graph/bench/representative_read/seed.rs index 7a6ff1d1235..d8bc4060de4 100644 --- a/apps/hash-graph/bench/representative_read/seed.rs +++ b/apps/hash-graph/bench/representative_read/seed.rs @@ -181,8 +181,8 @@ async fn seed_db(account_id: AccountId, store_wrapper: &mut StoreWrapper) { None, EntityProperties::empty(), Some(LinkData { - left_entity_id: left_entity_metadata.record_id.entity_id, - right_entity_id: right_entity_metadata.record_id.entity_id, + left_entity_id: left_entity_metadata.record_id().entity_id, + right_entity_id: right_entity_metadata.record_id().entity_id, order: EntityLinkOrder { left_to_right: None, right_to_left: None, diff --git a/apps/hash-graph/lib/graph/src/knowledge/entity.rs b/apps/hash-graph/lib/graph/src/knowledge/entity.rs index d903966c91d..ef1e5ce0a68 100644 --- a/apps/hash-graph/lib/graph/src/knowledge/entity.rs +++ b/apps/hash-graph/lib/graph/src/knowledge/entity.rs @@ -121,14 +121,62 @@ pub struct LinkData { /// The metadata of an [`Entity`] record. #[derive(Debug, Clone, PartialEq, Eq, Serialize, ToSchema)] // TODO: deny_unknown_fields on other structs +// TODO: Make fields `pub` when `#[feature(mut_restriction)]` is available. +// see https://github.com/rust-lang/rust/issues/105077 +// see https://app.asana.com/0/0/1203977361907407/f #[serde(deny_unknown_fields, rename_all = "camelCase")] pub struct EntityMetadata { - pub record_id: EntityRecordId, - pub version: EntityVersion, + record_id: EntityRecordId, + version: EntityVersion, #[schema(value_type = String)] - pub entity_type_id: VersionedUri, - pub provenance: ProvenanceMetadata, - pub archived: bool, + entity_type_id: VersionedUri, + #[serde(rename = "provenance")] + provenance_metadata: ProvenanceMetadata, + archived: bool, +} + +impl EntityMetadata { + #[must_use] + pub const fn new( + record_id: EntityRecordId, + version: EntityVersion, + entity_type_id: VersionedUri, + provenance_metadata: ProvenanceMetadata, + archived: bool, + ) -> Self { + Self { + record_id, + version, + entity_type_id, + provenance_metadata, + archived, + } + } + + #[must_use] + pub const fn record_id(&self) -> EntityRecordId { + self.record_id + } + + #[must_use] + pub const fn version(&self) -> &EntityVersion { + &self.version + } + + #[must_use] + pub const fn entity_type_id(&self) -> &VersionedUri { + &self.entity_type_id + } + + #[must_use] + pub const fn provenance_metadata(&self) -> ProvenanceMetadata { + self.provenance_metadata + } + + #[must_use] + pub const fn archived(&self) -> bool { + self.archived + } } /// A record of an [`Entity`] that has been persisted in the datastore, with its associated @@ -148,11 +196,11 @@ impl Record for Entity { fn vertex_id(&self, time_axis: TimeAxis) -> Self::VertexId { let timestamp = match time_axis { - TimeAxis::DecisionTime => self.metadata.version.decision_time.start().cast(), - TimeAxis::TransactionTime => self.metadata.version.transaction_time.start().cast(), + TimeAxis::DecisionTime => self.metadata.version().decision_time.start().cast(), + TimeAxis::TransactionTime => self.metadata.version().transaction_time.start().cast(), }; EntityVertexId { - base_id: self.metadata.record_id.entity_id, + base_id: self.metadata.record_id().entity_id, version: timestamp.into(), } } diff --git a/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity.rs b/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity.rs index 6c6b76f8cc0..1f6ae5108ce 100644 --- a/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity.rs +++ b/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity.rs @@ -11,7 +11,7 @@ use uuid::Uuid; use crate::{ identifier::{ - knowledge::{EntityId, EntityRecordId, EntityVersion}, + knowledge::{EntityEditionId, EntityId, EntityRecordId, EntityVersion}, time::{DecisionTime, TimeProjection, Timestamp}, EntityVertexId, OntologyTypeVertexId, }, @@ -61,7 +61,7 @@ impl PostgresStore { let version_interval = entity .metadata - .version + .version() .projected_time(time_axis); // Intersects the version interval of the entity with the time projection's time @@ -100,8 +100,7 @@ impl PostgresStore { if current_resolve_depths.is_of_type.outgoing > 0 { let entity_type_id = - OntologyTypeVertexId::from(entity.metadata.entity_type_id.clone()); - + OntologyTypeVertexId::from(entity.metadata.entity_type_id().clone()); subgraph.edges.insert(Edge::KnowledgeGraph { vertex_id: entity_vertex_id, outward_edge: KnowledgeGraphOutwardEdges::ToOntology(OutwardEdge { @@ -142,7 +141,7 @@ impl PostgresStore { // outgoing link `Entity` kind: KnowledgeGraphEdgeKind::HasLeftEntity, reversed: true, - right_endpoint: outgoing_link_entity.metadata.record_id.entity_id, + right_endpoint: outgoing_link_entity.metadata.record_id().entity_id, }), }); @@ -181,7 +180,7 @@ impl PostgresStore { // incoming link `Entity` kind: KnowledgeGraphEdgeKind::HasRightEntity, reversed: true, - right_endpoint: incoming_link_entity.metadata.record_id.entity_id, + right_endpoint: incoming_link_entity.metadata.record_id().entity_id, }), }); @@ -220,7 +219,7 @@ impl PostgresStore { // outgoing `Link` `Entity` kind: KnowledgeGraphEdgeKind::HasLeftEntity, reversed: false, - right_endpoint: left_entity.metadata.record_id.entity_id, + right_endpoint: left_entity.metadata.record_id().entity_id, }), }); @@ -259,7 +258,7 @@ impl PostgresStore { // outgoing `Link` `Entity` kind: KnowledgeGraphEdgeKind::HasRightEntity, reversed: false, - right_endpoint: right_entity.metadata.record_id.entity_id, + right_endpoint: right_entity.metadata.record_id().entity_id, }), }); @@ -374,19 +373,19 @@ impl EntityStore for PostgresStore { .into_report() .change_context(InsertionError)?; - Ok(EntityMetadata { - record_id: EntityRecordId { + Ok(EntityMetadata::new( + EntityRecordId { entity_id, - edition_id: row.get(0), + edition_id: EntityEditionId::new(row.get(0)), }, - version: EntityVersion { + EntityVersion { decision_time: row.get(1), transaction_time: row.get(2), }, entity_type_id, - provenance: ProvenanceMetadata::new(updated_by_id), + ProvenanceMetadata::new(updated_by_id), archived, - }) + )) } #[doc(hidden)] @@ -472,15 +471,17 @@ impl EntityStore for PostgresStore { .into_iter() .zip(entity_versions) .zip(entity_edition_ids) - .map(|(((entity_id, ..), version), edition_id)| EntityMetadata { - record_id: EntityRecordId { - entity_id, - edition_id, - }, - version, - entity_type_id: entity_type_id.clone(), - provenance: ProvenanceMetadata::new(actor_id), - archived: false, + .map(|(((entity_id, ..), entity_version), edition_id)| { + EntityMetadata::new( + EntityRecordId { + entity_id, + edition_id, + }, + entity_version, + entity_type_id.clone(), + ProvenanceMetadata::new(actor_id), + false, + ) }) .collect()) } @@ -612,18 +613,18 @@ impl EntityStore for PostgresStore { transaction.commit().await.change_context(UpdateError)?; - Ok(EntityMetadata { - record_id: EntityRecordId { + Ok(EntityMetadata::new( + EntityRecordId { entity_id, - edition_id: row.get(0), + edition_id: EntityEditionId::new(row.get(0)), }, - version: EntityVersion { + EntityVersion { decision_time: row.get(1), transaction_time: row.get(2), }, entity_type_id, - provenance: ProvenanceMetadata::new(updated_by_id), + ProvenanceMetadata::new(updated_by_id), archived, - }) + )) } } diff --git a/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity/read.rs b/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity/read.rs index c793a1ec688..a7f4b0eda49 100644 --- a/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity/read.rs +++ b/apps/hash-graph/lib/graph/src/store/postgres/knowledge/entity/read.rs @@ -138,22 +138,22 @@ impl crud::Read for PostgresStore { Ok(Entity { properties, link_data, - metadata: EntityMetadata { - record_id: EntityRecordId { + metadata: EntityMetadata::new( + EntityRecordId { entity_id: EntityId { owned_by_id: row.get(owned_by_id_index), entity_uuid: row.get(entity_uuid_index), }, edition_id: row.get(edition_id_index), }, - version: EntityVersion { + EntityVersion { decision_time: row.get(decision_time_index), transaction_time: row.get(transaction_time_index), }, entity_type_id, - provenance: ProvenanceMetadata::new(updated_by_id), - archived: row.get(archived_index), - }, + ProvenanceMetadata::new(updated_by_id), + row.get(archived_index), + ), }) }) .try_collect() diff --git a/apps/hash-graph/tests/integration/postgres/entity.rs b/apps/hash-graph/tests/integration/postgres/entity.rs index 2d713679a75..5195974a686 100644 --- a/apps/hash-graph/tests/integration/postgres/entity.rs +++ b/apps/hash-graph/tests/integration/postgres/entity.rs @@ -35,7 +35,7 @@ async fn insert() { .expect("could not create entity"); let entities = api - .get_entities(metadata.record_id.entity_id) + .get_entities(metadata.record_id().entity_id) .await .expect("could not get entity"); assert_eq!(entities.len(), 1); @@ -72,7 +72,7 @@ async fn query() { .expect("could not create entity"); let queried_organizations = api - .get_entities(metadata.record_id.entity_id) + .get_entities(metadata.record_id().entity_id) .await .expect("could not get entity"); assert_eq!(queried_organizations.len(), 1); @@ -112,7 +112,7 @@ async fn update() { let v2_metadata = api .update_entity( - v1_metadata.record_id.entity_id, + v1_metadata.record_id().entity_id, page_v2.clone(), VersionedUri { base_uri: BaseUri::new( @@ -130,14 +130,14 @@ async fn update() { .expect("could not update entity"); let entities = api - .get_entities(v2_metadata.record_id.entity_id) + .get_entities(v2_metadata.record_id().entity_id) .await .expect("could not get entity"); assert_eq!(entities.len(), 2); let entity_v2 = api - .get_latest_entity(v2_metadata.record_id.entity_id) + .get_latest_entity(v2_metadata.record_id().entity_id) .await .expect("could not get entity"); @@ -145,8 +145,8 @@ async fn update() { let entity_v1 = api .get_entity_by_timestamp( - v1_metadata.record_id.entity_id, - (*v1_metadata.version.decision_time.start()).into(), + v1_metadata.record_id().entity_id, + (*v1_metadata.version().decision_time.start()).into(), ) .await .expect("could not get entity"); @@ -154,8 +154,8 @@ async fn update() { let entity_v2 = api .get_entity_by_timestamp( - v2_metadata.record_id.entity_id, - (*v2_metadata.version.decision_time.start()).into(), + v2_metadata.record_id().entity_id, + (*v2_metadata.version().decision_time.start()).into(), ) .await .expect("could not get entity"); diff --git a/apps/hash-graph/tests/integration/postgres/links.rs b/apps/hash-graph/tests/integration/postgres/links.rs index 74fcfd7cdbd..b6b4a47294b 100644 --- a/apps/hash-graph/tests/integration/postgres/links.rs +++ b/apps/hash-graph/tests/integration/postgres/links.rs @@ -50,20 +50,26 @@ async fn insert() { friend_of, friend_of_type_id.clone(), None, - alice_metadata.record_id.entity_id, - bob_metadata.record_id.entity_id, + alice_metadata.record_id().entity_id, + bob_metadata.record_id().entity_id, ) .await .expect("could not create link"); let link_entity = api - .get_link_entity_target(alice_metadata.record_id.entity_id, friend_of_type_id) + .get_link_entity_target(alice_metadata.record_id().entity_id, friend_of_type_id) .await .expect("could not fetch entity"); let link_data = link_entity.link_data.expect("entity is not a link"); - assert_eq!(link_data.left_entity_id, alice_metadata.record_id.entity_id); - assert_eq!(link_data.right_entity_id, bob_metadata.record_id.entity_id); + assert_eq!( + link_data.left_entity_id, + alice_metadata.record_id().entity_id + ); + assert_eq!( + link_data.right_entity_id, + bob_metadata.record_id().entity_id + ); } #[tokio::test] @@ -126,8 +132,8 @@ async fn get_entity_links() { EntityProperties::empty(), friend_link_type_id.clone(), None, - alice_metadata.record_id.entity_id, - bob_metadata.record_id.entity_id, + alice_metadata.record_id().entity_id, + bob_metadata.record_id().entity_id, ) .await .expect("could not create link"); @@ -136,25 +142,28 @@ async fn get_entity_links() { EntityProperties::empty(), acquaintance_entity_link_type_id.clone(), None, - alice_metadata.record_id.entity_id, - charles_metadata.record_id.entity_id, + alice_metadata.record_id().entity_id, + charles_metadata.record_id().entity_id, ) .await .expect("could not create link"); let links_from_source = api - .get_latest_entity_links(alice_metadata.record_id.entity_id) + .get_latest_entity_links(alice_metadata.record_id().entity_id) .await .expect("could not fetch link"); assert!( links_from_source .iter() - .any(|link_entity| { link_entity.metadata.entity_type_id == friend_link_type_id }) + .any(|link_entity| link_entity.metadata.entity_type_id() == &friend_link_type_id) + ); + assert!( + links_from_source + .iter() + .any(|link_entity| link_entity.metadata.entity_type_id() + == &acquaintance_entity_link_type_id) ); - assert!(links_from_source.iter().any(|link_entity| { - link_entity.metadata.entity_type_id == acquaintance_entity_link_type_id - })); let link_datas = links_from_source .iter() @@ -163,17 +172,17 @@ async fn get_entity_links() { assert!( link_datas .iter() - .any(|link_data| link_data.left_entity_id == alice_metadata.record_id.entity_id) + .any(|link_data| link_data.left_entity_id == alice_metadata.record_id().entity_id) ); assert!( link_datas .iter() - .any(|link_data| link_data.right_entity_id == bob_metadata.record_id.entity_id) + .any(|link_data| link_data.right_entity_id == bob_metadata.record_id().entity_id) ); assert!( link_datas .iter() - .any(|link_data| link_data.right_entity_id == charles_metadata.record_id.entity_id) + .any(|link_data| link_data.right_entity_id == charles_metadata.record_id().entity_id) ); } @@ -223,21 +232,21 @@ async fn remove_link() { EntityProperties::empty(), friend_link_type_id.clone(), None, - alice_metadata.record_id.entity_id, - bob_metadata.record_id.entity_id, + alice_metadata.record_id().entity_id, + bob_metadata.record_id().entity_id, ) .await .expect("could not create link"); assert!( - !api.get_latest_entity_links(alice_metadata.record_id.entity_id) + !api.get_latest_entity_links(alice_metadata.record_id().entity_id) .await .expect("could not fetch links") .is_empty() ); api.archive_entity( - link_entity_metadata.record_id.entity_id, + link_entity_metadata.record_id().entity_id, EntityProperties::empty(), friend_link_type_id, EntityLinkOrder { @@ -249,7 +258,7 @@ async fn remove_link() { .expect("could not remove link"); assert!( - api.get_latest_entity_links(alice_metadata.record_id.entity_id) + api.get_latest_entity_links(alice_metadata.record_id().entity_id) .await .expect("could not fetch links") .is_empty() From 4105509d327bea3d3f2a8a40e01f03b5f028db3a Mon Sep 17 00:00:00 2001 From: Tim Diekmann Date: Fri, 17 Feb 2023 13:10:17 +0100 Subject: [PATCH 19/19] Fix default-feature branch --- .../bin/cli/src/subcommand/server.rs | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/apps/hash-graph/bin/cli/src/subcommand/server.rs b/apps/hash-graph/bin/cli/src/subcommand/server.rs index 3266d07e725..6f6d009f7bd 100644 --- a/apps/hash-graph/bin/cli/src/subcommand/server.rs +++ b/apps/hash-graph/bin/cli/src/subcommand/server.rs @@ -84,7 +84,7 @@ async fn stop_gap_setup(pool: &PostgresStorePool) -> Result<(), GraphErro use graph::{ identifier::account::AccountId, - ontology::OntologyElementMetadata, + ontology::{ExternalOntologyElementMetadata, OntologyElementMetadata}, provenance::{ProvenanceMetadata, UpdatedById}, store::{AccountStore, BaseUriAlreadyExists, DataTypeStore, EntityTypeStore, StorePool}, }; @@ -210,11 +210,12 @@ async fn stop_gap_setup(pool: &PostgresStorePool) -> Result<(), GraphErro for data_type in [text, number, boolean, empty_list, object, null] { let title = data_type.title().to_owned(); - let data_type_metadata = OntologyElementMetadata::External { - record_id: data_type.id().clone().into(), - provenance: ProvenanceMetadata::new(UpdatedById::new(root_account_id)), - fetched_at: OffsetDateTime::now_utc(), - }; + let data_type_metadata = + OntologyElementMetadata::External(ExternalOntologyElementMetadata::new( + data_type.id().clone().into(), + ProvenanceMetadata::new(UpdatedById::new(root_account_id)), + OffsetDateTime::now_utc(), + )); if let Err(error) = connection .create_data_type(data_type, &data_type_metadata) @@ -247,11 +248,12 @@ async fn stop_gap_setup(pool: &PostgresStorePool) -> Result<(), GraphErro Vec::default(), ); - let link_entity_type_metadata = OntologyElementMetadata::External { - record_id: link_entity_type.id().clone().into(), - provenance: ProvenanceMetadata::new(UpdatedById::new(root_account_id)), - fetched_at: OffsetDateTime::now_utc(), - }; + let link_entity_type_metadata = + OntologyElementMetadata::External(ExternalOntologyElementMetadata::new( + link_entity_type.id().clone().into(), + ProvenanceMetadata::new(UpdatedById::new(root_account_id)), + OffsetDateTime::now_utc(), + )); let title = link_entity_type.title().to_owned();