public static IEnumerable <IEnumerable <T> > ExecuteQuery <T, T1, T2>(this IStatementRunner ext, Func <qu.IQueryBuilder, string> query, Func <T, T1, T2, T> map, params object[] param) where T : class where T1 : class where T2 : class { return(ext.ExecuteQuery <T, T1, T2>(query(new qu.QueryBuilder()), map, param)); }
public static T AddOrUpdateNode <T>(this IStatementRunner ext, T entity, Expression <Func <T, object> > propMatch = null) where T : class { ext = ext ?? throw new ArgumentNullException(nameof(ext)); entity = entity ?? throw new ArgumentNullException(nameof(entity)); IEnumerable <string> keyOn = propMatch?.ToPropertyNameCollection() ?? new string[0]; if (keyOn.Count() > 0) { foreach (string name in keyOn) { PropertyInfo pinfo = typeof(T).GetProperty(name); if (ObjectExtensions.Configuration.Get(pinfo, entity) == pinfo.PropertyType.GetDefault()) { throw new ArgumentException($"Every selection matching property must be set. '{name}' has its default type value."); } } } Symbol s = new Symbol(); Node n = new Node(s, typeof(T), entity.SelectProperties(keyOn)); n.Parametrize(prefix: "value."); return(ext.ExecuteQuery <T>( $"MERGE {n} " + $"ON CREATE SET {s}+=$value,{s}.{nameof(IOgmEntity.EntityId)}=id({s}) " + $"ON MATCH SET {s}+=$value,{s}.{nameof(IOgmEntity.EntityId)}=id({s}) " + $"RETURN {s}", new { value = entity.SelectMatchingTypesProperties(p => p.IsPrimitive() || p.IsOfGenericType(typeof(IEnumerable <>), t => t.Type.IsPrimitive())) }).FirstOrDefault()); }
public override IEnumerable <IOgmConnection> UpdateRels(IStatementRunner runner, IEnumerable <Tuple <IOgmConnection, IEnumerable <string> > > entities) { runner = runner ?? throw new ArgumentNullException(nameof(runner)); entities = entities ?? throw new ArgumentNullException(nameof(entities)); entities = entities.Where(p => p?.Item1?.EntityId != null); if (entities.Count() == 0) { return(null); } IGraphManagedStatementRunner mgr = (runner as IGraphManagedStatementRunner) ?? throw new ArgumentException("The statement must be decorated.", nameof(runner)); using (ManagerAccess.Manager.ScopeOMnG()) { Symbol row = new Symbol(); Symbol m = new Symbol(); StringBuilder sb = new StringBuilder(); sb.Append($"UNWIND $batch AS {row} "); sb.Append($"MATCH ()-[{m} {{{nameof(IOgmEntity.EntityId)}:{row}.{nameof(IOgmEntity.EntityId)}}}]->()"); sb.Append($"SET {m}+={row}.{nameof(RelEntity.Properties)} "); sb.Append($"RETURN {m}"); return(runner.ExecuteQuery <IOgmEntity>(sb.ToString(), new { batch = entities.Select(p => new RelEntity(p.Item1, -1, -1, excludePorperties: p.Item2).ToPropDictionary()).ToList() }).ToList().Select(p => p as IOgmConnection)); } }
public override IEnumerable <IOgmConnection> CreateRels(IStatementRunner runner, IEnumerable <Tuple <IOgmConnection, IEnumerable <string> > > entities) { runner = runner ?? throw new ArgumentNullException(nameof(runner)); entities = entities ?? throw new ArgumentNullException(nameof(entities)); entities = entities.Where(p => p?.Item1 != null); if (entities.Count() == 0) { return(null); } IGraphManagedStatementRunner mgr = (runner as IGraphManagedStatementRunner) ?? throw new ArgumentException("The statement must be decorated.", nameof(runner)); using (ManagerAccess.Manager.ScopeOMnG()) { Symbol row = new Symbol(); Symbol m = new Symbol(); Symbol s = new Symbol(); Symbol d = new Symbol(); StringBuilder sb = new StringBuilder(); sb.Append($"UNWIND $batch AS {row} "); sb.Append($"MATCH ({s} {{{nameof(IOgmEntity.EntityId)}:{row}.{nameof(RelEntity.SourceId)}}})"); sb.Append($"MATCH ({d} {{{nameof(IOgmEntity.EntityId)}:{row}.{nameof(RelEntity.DestinationId)}}})"); sb.Append($"CALL apoc.create.relationship({s}, {row}.{nameof(RelEntity.Label)}, {row}.{nameof(RelEntity.Properties)}, {d}) yield rel AS {m} "); sb.Append($"SET {m}.{nameof(IOgmEntity.EntityId)}=id({m}) "); sb.Append($"RETURN {m}"); return(runner.ExecuteQuery <IOgmEntity>(sb.ToString(), new { batch = entities.Select(p => new RelEntity(p.Item1, p.Item1.Source.EntityId.Value, p.Item1.Destination.EntityId.Value, false, excludePorperties: p.Item2).ToPropDictionary()).ToList() }).ToList().Select(p => p as IOgmConnection)); } }
public override IEnumerable <IOgmEntity> CreateNodes(IStatementRunner runner, IEnumerable <Tuple <IOgmEntity, IEnumerable <string> > > entities) { runner = runner ?? throw new ArgumentNullException(nameof(runner)); entities = entities ?? throw new ArgumentNullException(nameof(entities)); entities = entities.Where(p => p != null); if (entities.Count() == 0) { return(null); } IGraphManagedStatementRunner mgr = (runner as IGraphManagedStatementRunner) ?? throw new ArgumentException("The statement must be decorated.", nameof(runner)); using (ManagerAccess.Manager.ScopeOMnG()) { Symbol row = new Symbol(); Symbol m = new Symbol(); StringBuilder sb = new StringBuilder(); sb.Append($"UNWIND $batch AS {row} "); sb.Append($"CALL apoc.create.node({row}.{nameof(NodeEntity.Labels)}, {row}.{nameof(NodeEntity.Properties)}) yield node AS {m} "); sb.Append($"SET {m}.{nameof(IOgmEntity.EntityId)}=id({m}) "); sb.Append($"RETURN {m}"); return(runner.ExecuteQuery <IOgmEntity>(sb.ToString(), new { batch = entities.Select(p => new NodeEntity(p.Item1, false, excludePorperties: p.Item2).ToPropDictionary()).ToList() }).ToList()); } }
public static IQueryable <T> GetQueryableNodeSet <T>(this IStatementRunner ext) where T : class { ext = ext ?? throw new ArgumentNullException(nameof(ext)); Symbol s = new Symbol(); Node n = new Node(s, typeof(T)); return(ext.ExecuteQuery <T>( $"MATCH {n.BuildForQuery()} " + $"RETURN {s}")); }
public override IEnumerable <IOgmConnection> CreateRels(IStatementRunner runner, IEnumerable <Tuple <IOgmConnection, IEnumerable <string> > > entities) { runner = runner ?? throw new ArgumentNullException(nameof(runner)); entities = entities ?? throw new ArgumentNullException(nameof(entities)); entities = entities.Where(p => p?.Item1 != null); if (entities.Count() == 0) { return(null); } IGraphManagedStatementRunner mgr = (runner as IGraphManagedStatementRunner) ?? throw new ArgumentException("The statement must be decorated.", nameof(runner)); List <IGrouping <Type, Tuple <int, Type, RelEntity> > > sets = entities .Select((p, i) => new Tuple <int, Type, RelEntity>( i, p.Item1.GetType(), new RelEntity(p.Item1, p.Item1.Source.EntityId.Value, p.Item1.Destination.EntityId.Value, false, p.Item2))) .GroupBy(p => p.Item2).ToList(); List <Tuple <int, IOgmEntity> > results = new List <Tuple <int, IOgmEntity> >(); using (ManagerAccess.Manager.ScopeOMnG()) { foreach (var set in sets) { List <Tuple <int, Type, RelEntity> > items = set.ToList(); Symbol row = new Symbol(); Symbol m = new Symbol(); Symbol s = new Symbol(); Symbol d = new Symbol(); StringBuilder sb = new StringBuilder(); sb.Append($"UNWIND $batch AS {row} "); sb.Append($"MATCH ({s} {{{nameof(IOgmEntity.EntityId)}:{row}.{nameof(RelEntity.SourceId)}}}) "); sb.Append($"MATCH ({d} {{{nameof(IOgmEntity.EntityId)}:{row}.{nameof(RelEntity.DestinationId)}}}) "); sb.Append($"CREATE ({s})-{new Rel(m, set.Key)}->({d}) "); sb.Append($"SET {m}+={row}.{nameof(RelEntity.Properties)},{m}.{nameof(IOgmEntity.EntityId)}=id({m}) "); sb.Append($"RETURN {m}"); results.AddRange(runner .ExecuteQuery <IOgmEntity>(sb.ToString(), new { batch = items.Select(p => p.Item3.ToPropDictionary()).ToList() }) .ToList() .Select((p, i) => new Tuple <int, IOgmEntity>(items[i].Item1, p))); } return(results.OrderBy(p => p.Item1).Select(p => p.Item2 as IOgmConnection).ToList()); } }
public static IEnumerable <IEnumerable <T> > ExecuteQuery <T, T1>(this IStatementRunner ext, string query, Func <T, T1, T> map, params object[] param) where T : class where T1 : class { if (param == null || param.Length == 0) { yield break; } foreach (object item in param) { yield return(ext.ExecuteQuery <T, T1>(query, map, item)); } }
public static IEnumerable <IEnumerable <T> > ExecuteQuery <T>(this IStatementRunner ext, string query, params object[] param) where T : class { ext = ext ?? throw new ArgumentNullException(nameof(ext)); query = query ?? throw new ArgumentNullException(nameof(query)); if (param == null || param.Length == 0) { yield break; } foreach (object item in param) { yield return(ext.ExecuteQuery <T>(query, item)); } }
public static IQueryable <T> ExecuteQuery <T>(this IStatementRunner ext, Func <qu.IQueryBuilder, string> query, object param = null) where T : class { return(ext.ExecuteQuery <T>(query(new qu.QueryBuilder()), param)); }
public override IEnumerable <IOgmConnection> MergeConnections(IStatementRunner runner, IEnumerable <Tuple <IOgmConnection, IEnumerable <string> > > entities) { runner = runner ?? throw new ArgumentNullException(nameof(runner)); entities = entities ?? throw new ArgumentNullException(nameof(entities)); entities = entities.Where(p => p?.Item1 != null); if (entities.Count() == 0) { return(null); } IGraphManagedStatementRunner mgr = (runner as IGraphManagedStatementRunner) ?? throw new ArgumentException("The statement must be decorated.", nameof(runner)); using (ManagerAccess.Manager.ScopeOMnG()) { long version = DateTimeOffset.Now.ToUnixTimeMilliseconds(); List <IGrouping <string, Tuple <int, ConnectionEntity> > > sets = entities .Select((p, i) => new Tuple <int, ConnectionEntity>(i, new ConnectionEntity(p.Item1, p.Item1.Source.EntityId.Value, p.Item1.Destination.EntityId.Value, version, excludePorperties: p.Item2))) .GroupBy(p => p.Item2.Label).ToList(); Symbol row = new Symbol(); Symbol s = new Symbol(); Symbol d = new Symbol(); Symbol r = new Symbol(); List <Tuple <int, IOgmEntity> > results = new List <Tuple <int, IOgmEntity> >(); foreach (var set in sets) { List <Tuple <int, ConnectionEntity> > items = set.ToList(); StringBuilder sb = new StringBuilder(); sb.Append($"UNWIND $batch AS {row} "); sb.Append($"MATCH ({s} {{{nameof(IOgmEntity.EntityId)}:{row}.{nameof(RelEntity.SourceId)}}}) "); sb.Append($"MATCH ({d} {{{nameof(IOgmEntity.EntityId)}:{row}.{nameof(RelEntity.DestinationId)}}}) "); sb.Append($"MERGE ({s})-"); sb.Append($"[{r}:`{set.Key}` {{" + $"{nameof(OgmConnection.SourcePropertyName)}:{row}.{nameof(RelEntity.Properties)}.{nameof(OgmConnection.SourcePropertyName)}," + $"{nameof(OgmConnection.DestinationPropertyName)}:{row}.{nameof(RelEntity.Properties)}.{nameof(OgmConnection.DestinationPropertyName)}," + $"{nameof(OgmConnection.Order)}:{row}.{nameof(RelEntity.Properties)}.{nameof(OgmConnection.Order)}" + $"}}]"); sb.Append($"->({d}) "); sb.Append($"ON CREATE SET {r}+={row}.{nameof(RelEntity.Properties)},{r}.{nameof(IOgmEntity.EntityId)}=id({r}) "); sb.Append($"ON MATCH SET {r}+={row}.{nameof(RelEntity.Properties)},{r}.{nameof(IOgmEntity.EntityId)}=id({r}) "); sb.Append($"RETURN {r}"); object batch = new { batch = set.Select(p => p.Item2.ToPropDictionary()).ToList() }; results.AddRange(runner .ExecuteQuery <IOgmEntity>(sb.ToString(), batch).ToList() .Select((p, i) => new Tuple <int, IOgmEntity>(items[i].Item1, p))); sb.Clear(); sb.Append($"UNWIND $batch AS {row} "); sb.Append($"MATCH ({s} {{{nameof(IOgmEntity.EntityId)}:{row}.{nameof(RelEntity.SourceId)}}}) "); sb.Append($"MATCH ({d} {{{nameof(IOgmEntity.EntityId)}:{row}.{nameof(RelEntity.DestinationId)}}}) "); sb.Append($"MATCH ({s})-"); sb.Append($"[{r}:`{set.Key}` {{" + $"{nameof(OgmConnection.SourcePropertyName)}:{row}.{nameof(RelEntity.Properties)}.{nameof(OgmConnection.SourcePropertyName)}," + $"{nameof(OgmConnection.DestinationPropertyName)}:{row}.{nameof(RelEntity.Properties)}.{nameof(OgmConnection.DestinationPropertyName)}," + $"{nameof(OgmConnection.Order)}:{row}.{nameof(RelEntity.Properties)}.{nameof(OgmConnection.Order)}" + $"}}]"); sb.Append($"->({d}) "); sb.Append($"WHERE EXISTS({r}.{nameof(OgmConnection.Version)}) AND {r}.{nameof(OgmConnection.Version)}<>{row}.{nameof(RelEntity.Properties)}.{nameof(OgmConnection.Version)} "); sb.Append($"DELETE {r}"); runner.Execute(sb.ToString(), batch); } return(results.OrderBy(p => p.Item1).Select(p => p.Item2 as IOgmConnection).ToList()); } }