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
160 changes: 150 additions & 10 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},
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,63 @@ 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
.static_prop(&"path".to_string())
.expect("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()
.expect("Failed to materialize graph");

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

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");

let dt = Utc::now();
let timestamp: i64 = dt.timestamp();
new_subgraph
.add_constant_properties([("lastUpdated".to_string(), Prop::I64(timestamp * 1000))])
.expect("Failed to add static properties");

new_subgraph
.save_to_file(path)
.expect("Failed to save graph");

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 Down Expand Up @@ -185,17 +245,51 @@ impl Mut {
.subgraph(graph_nodes)
.materialize()
.expect("Failed to materialize graph");
let static_props_without_name: Vec<(String, Prop)> = subgraph
.properties()
.into_iter()
.filter(|(a, b)| a != "name")
.collect_vec();
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");

// 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<(String, Prop)> = subgraph
.properties()
.into_iter()
.filter(|(a, b)| a != "name" && a != "creationTime" && a != "uiProps")
.collect_vec();
new_subgraph
.add_constant_properties(static_props)
.expect("Failed to add static properties");
} else {
let static_props: Vec<(String, Prop)> = subgraph
.properties()
.into_iter()
.filter(|(a, b)| a != "name" && a != "lastUpdated" && a != "uiProps")
.collect_vec();
new_subgraph
.add_constant_properties(static_props)
.expect("Failed to add static properties");
}
}

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),
)])
.expect("Failed to add static properties");
}

new_subgraph
.add_constant_properties([("lastUpdated".to_string(), Prop::I64(timestamp * 1000))])
.expect("Failed to add static properties");

new_subgraph
.add_constant_properties([("uiProps".to_string(), Prop::Str(props))])
.expect("Failed to add static property");
Expand Down Expand Up @@ -260,6 +354,52 @@ 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
.static_prop(&"path".to_string())
.expect("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()
.expect("Failed to materialize graph");

let static_props_without_isactive: Vec<(String, Prop)> = subgraph
.properties()
.into_iter()
.filter(|(a, b)| a != "isArchive")
.collect_vec();
new_subgraph
.add_constant_properties(static_props_without_isactive)
.expect("Failed to add static properties");
new_subgraph
.add_constant_properties([("isArchive".to_string(), Prop::U8(is_archive.clone()))])
.expect("Failed to add static property");
new_subgraph
.save_to_file(path)
.expect("Failed to save graph");

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