mirror of
https://github.com/perstarkse/minne.git
synced 2026-04-23 09:18:36 +02:00
upsert relationship and creation
This commit is contained in:
@@ -130,6 +130,19 @@ impl SurrealDbClient {
|
|||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Operation to upsert an object in SurrealDB, replacing any existing record
|
||||||
|
/// with the same ID. Useful for idempotent ingestion flows.
|
||||||
|
pub async fn upsert_item<T>(&self, item: T) -> Result<Option<T>, Error>
|
||||||
|
where
|
||||||
|
T: StoredObject + Send + Sync + 'static,
|
||||||
|
{
|
||||||
|
let id = item.get_id().to_string();
|
||||||
|
self.client
|
||||||
|
.upsert((T::table_name(), id))
|
||||||
|
.content(item)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
/// Operation to retrieve all objects from a certain table, requires the struct to implement StoredObject
|
/// Operation to retrieve all objects from a certain table, requires the struct to implement StoredObject
|
||||||
///
|
///
|
||||||
/// # Returns
|
/// # Returns
|
||||||
@@ -268,6 +281,56 @@ mod tests {
|
|||||||
assert!(fetch_post.is_none());
|
assert!(fetch_post.is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn upsert_item_overwrites_existing_records() {
|
||||||
|
let namespace = "test_ns";
|
||||||
|
let database = &Uuid::new_v4().to_string();
|
||||||
|
let db = SurrealDbClient::memory(namespace, database)
|
||||||
|
.await
|
||||||
|
.expect("Failed to start in-memory surrealdb");
|
||||||
|
|
||||||
|
db.apply_migrations()
|
||||||
|
.await
|
||||||
|
.expect("Failed to initialize schema");
|
||||||
|
|
||||||
|
let mut dummy = Dummy {
|
||||||
|
id: "abc".to_string(),
|
||||||
|
name: "first".to_string(),
|
||||||
|
created_at: Utc::now(),
|
||||||
|
updated_at: Utc::now(),
|
||||||
|
};
|
||||||
|
|
||||||
|
db.store_item(dummy.clone())
|
||||||
|
.await
|
||||||
|
.expect("Failed to store initial record");
|
||||||
|
|
||||||
|
dummy.name = "updated".to_string();
|
||||||
|
let upserted = db
|
||||||
|
.upsert_item(dummy.clone())
|
||||||
|
.await
|
||||||
|
.expect("Failed to upsert record");
|
||||||
|
assert!(upserted.is_some());
|
||||||
|
|
||||||
|
let fetched: Option<Dummy> = db.get_item(&dummy.id).await.expect("fetch after upsert");
|
||||||
|
assert_eq!(fetched.unwrap().name, "updated");
|
||||||
|
|
||||||
|
let new_record = Dummy {
|
||||||
|
id: "def".to_string(),
|
||||||
|
name: "brand-new".to_string(),
|
||||||
|
created_at: Utc::now(),
|
||||||
|
updated_at: Utc::now(),
|
||||||
|
};
|
||||||
|
db.upsert_item(new_record.clone())
|
||||||
|
.await
|
||||||
|
.expect("Failed to upsert new record");
|
||||||
|
|
||||||
|
let fetched_new: Option<Dummy> = db
|
||||||
|
.get_item(&new_record.id)
|
||||||
|
.await
|
||||||
|
.expect("fetch inserted via upsert");
|
||||||
|
assert_eq!(fetched_new, Some(new_record));
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_applying_migrations() {
|
async fn test_applying_migrations() {
|
||||||
let namespace = "test_ns";
|
let namespace = "test_ns";
|
||||||
|
|||||||
@@ -41,17 +41,18 @@ impl KnowledgeRelationship {
|
|||||||
}
|
}
|
||||||
pub async fn store_relationship(&self, db_client: &SurrealDbClient) -> Result<(), AppError> {
|
pub async fn store_relationship(&self, db_client: &SurrealDbClient) -> Result<(), AppError> {
|
||||||
let query = format!(
|
let query = format!(
|
||||||
r#"RELATE knowledge_entity:`{}`->relates_to:`{}`->knowledge_entity:`{}`
|
r#"DELETE relates_to:`{rel_id}`;
|
||||||
|
RELATE knowledge_entity:`{in_id}`->relates_to:`{rel_id}`->knowledge_entity:`{out_id}`
|
||||||
SET
|
SET
|
||||||
metadata.user_id = '{}',
|
metadata.user_id = '{user_id}',
|
||||||
metadata.source_id = '{}',
|
metadata.source_id = '{source_id}',
|
||||||
metadata.relationship_type = '{}'"#,
|
metadata.relationship_type = '{relationship_type}'"#,
|
||||||
self.in_,
|
rel_id = self.id,
|
||||||
self.id,
|
in_id = self.in_,
|
||||||
self.out,
|
out_id = self.out,
|
||||||
self.metadata.user_id,
|
user_id = self.metadata.user_id.as_str(),
|
||||||
self.metadata.source_id,
|
source_id = self.metadata.source_id.as_str(),
|
||||||
self.metadata.relationship_type
|
relationship_type = self.metadata.relationship_type.as_str()
|
||||||
);
|
);
|
||||||
|
|
||||||
db_client.query(query).await?;
|
db_client.query(query).await?;
|
||||||
|
|||||||
Reference in New Issue
Block a user