Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Archive #1271

Merged
merged 14 commits into from
Sep 22, 2023
164 changes: 141 additions & 23 deletions raphtory-graphql/src/model/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,26 @@ use crate::{
};
use async_graphql::Context;
use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine};
use chrono::{NaiveDateTime, Utc};
use dynamic_graphql::{
App, Mutation, MutationFields, MutationRoot, ResolvedObject, ResolvedObjectFields, Result,
Upload,
};
use itertools::Itertools;
use raphtory::{
core::Prop,
db::api::view::internal::{CoreGraphOps, IntoDynamic, MaterializedGraph},
prelude::{Graph, GraphViewOps, PropertyAdditionOps},
core::{ArcStr, Prop},
db::api::view::internal::{CoreGraphOps, DynamicGraph, IntoDynamic, MaterializedGraph},
prelude::{Graph, GraphViewOps, PropertyAdditionOps, VertexViewOps},
search::IndexedGraph,
};
use std::{
collections::HashMap,
error::Error,
fmt::{Display, Formatter},
fs,
io::BufReader,
ops::Deref,
time::UNIX_EPOCH,
};
use uuid::Uuid;

Expand Down Expand Up @@ -143,6 +146,59 @@ impl Mut {
keys
}

async fn rename_graph<'a>(
ctx: &Context<'a>,
parent_graph_name: String,
graph_name: String,
new_graph_name: String,
) -> Result<bool> {
if new_graph_name.ne(&graph_name) && parent_graph_name.ne(&graph_name) {
let mut data = ctx.data_unchecked::<Data>().graphs.write();

let subgraph = data.get(&graph_name).ok_or("Graph not found")?;
let path = subgraph
.constant_prop(&"path".to_string())
.ok_or("Path is missing")?
.to_string();

let parent_graph = data.get(&parent_graph_name).ok_or("Graph not found")?;
let new_subgraph = parent_graph
.subgraph(subgraph.vertices().iter().map(|v| v.name()).collect_vec())
.materialize()?;

let static_props_without_name: Vec<(ArcStr, Prop)> = subgraph
.properties()
.into_iter()
.filter(|(a, b)| a != "name")
.collect_vec();

new_subgraph.add_constant_properties(static_props_without_name)?;
new_subgraph.add_constant_properties([(
"name".to_string(),
Prop::Str(new_graph_name.clone().into()),
)])?;

let dt = Utc::now();
let timestamp: i64 = dt.timestamp();
new_subgraph.add_constant_properties([(
"lastUpdated".to_string(),
Prop::I64(timestamp * 1000),
)])?;

new_subgraph.save_to_file(path)?;

let gi: IndexedGraph<Graph> = new_subgraph
.into_events()
.ok_or("Graph with deletions not supported")?
.into();

data.insert(new_graph_name.clone(), gi.clone());
data.remove(&graph_name);
}

Ok(true)
}

async fn save_graph<'a>(
ctx: &Context<'a>,
parent_graph_name: String,
Expand All @@ -156,7 +212,7 @@ impl Mut {
let subgraph = data.get(&graph_name).ok_or("Graph not found")?;
let mut path = subgraph
.constant_prop(&"path".to_string())
.expect("Path is missing")
.ok_or("Path is missing")?
.to_string();

if new_graph_name.ne(&graph_name) {
Expand All @@ -181,27 +237,49 @@ impl Mut {
}

let parent_graph = data.get(&parent_graph_name).ok_or("Graph not found")?;
let new_subgraph = parent_graph
.subgraph(graph_nodes)
.materialize()
.expect("Failed to materialize graph");
let static_props_without_name = subgraph
.properties()
.into_iter()
.filter(|(a, _)| a != "name");
new_subgraph
.add_constant_properties(static_props_without_name)
.expect("Failed to add static properties");
new_subgraph
.add_constant_properties([("name".to_string(), Prop::str(new_graph_name.clone()))])
.expect("Failed to add static property");
new_subgraph
.add_constant_properties([("uiProps".to_string(), Prop::str(props))])
.expect("Failed to add static property");

let new_subgraph = parent_graph.subgraph(graph_nodes).materialize()?;

new_subgraph.add_constant_properties([(
"name".to_string(),
Prop::Str(new_graph_name.clone().into()),
)])?;

// parent_graph_name == graph_name, means its a graph created from UI
if parent_graph_name.ne(&graph_name) {
// graph_name == new_graph_name, means its a "save" and not "save as" action
if graph_name.ne(&new_graph_name) {
let static_props: Vec<(ArcStr, Prop)> = subgraph
.properties()
.into_iter()
.filter(|(a, b)| a != "name" && a != "creationTime" && a != "uiProps")
.collect_vec();
new_subgraph.add_constant_properties(static_props)?;
} else {
let static_props: Vec<(ArcStr, Prop)> = subgraph
.properties()
.into_iter()
.filter(|(a, b)| a != "name" && a != "lastUpdated" && a != "uiProps")
.collect_vec();
new_subgraph.add_constant_properties(static_props)?;
}
}

let dt = Utc::now();
let timestamp: i64 = dt.timestamp();

if parent_graph_name.eq(&graph_name) || graph_name.ne(&new_graph_name) {
new_subgraph.add_constant_properties([(
"creationTime".to_string(),
Prop::I64(timestamp * 1000),
)])?;
}

new_subgraph
.save_to_file(path)
.expect("Failed to save graph");
.add_constant_properties([("lastUpdated".to_string(), Prop::I64(timestamp * 1000))])?;
new_subgraph.add_constant_properties([("uiProps".to_string(), Prop::Str(props.into()))])?;

new_subgraph.save_to_file(path)?;

let gi: IndexedGraph<Graph> = new_subgraph
.into_events()
Expand Down Expand Up @@ -259,6 +337,46 @@ impl Mut {
);
Ok(name)
}

async fn archive_graph<'a>(
ctx: &Context<'a>,
graph_name: String,
parent_graph_name: String,
is_archive: u8,
) -> Result<bool> {
let mut data = ctx.data_unchecked::<Data>().graphs.write();

let subgraph = data.get(&graph_name).ok_or("Graph not found")?;

let path = subgraph
.constant_prop(&"path".to_string())
.ok_or("Path is missing")?
.to_string();

let parent_graph = data.get(&parent_graph_name).ok_or("Graph not found")?;
let new_subgraph = parent_graph
.subgraph(subgraph.vertices().iter().map(|v| v.name()).collect_vec())
.materialize()?;

let static_props_without_isactive: Vec<(ArcStr, Prop)> = subgraph
.properties()
.into_iter()
.filter(|(a, b)| a != "isArchive")
.collect_vec();
new_subgraph.add_constant_properties(static_props_without_isactive)?;
new_subgraph
.add_constant_properties([("isArchive".to_string(), Prop::U8(is_archive.clone()))])?;
new_subgraph.save_to_file(path)?;

let gi: IndexedGraph<Graph> = new_subgraph
.into_events()
.ok_or("Graph with deletions not supported")?
.into();

data.insert(graph_name, gi.clone());

Ok(true)
}
}

#[derive(App)]
Expand Down