public static void BuildModel(LyniconSystem sys) { //if (!Collator.Instance.RepositoryBuilt) // throw new Exception("In CoreDb.OnModelCreating because there was a use of CoreDb before repository was built"); Debug.WriteLine("Building SummaryDb"); var requiredBaseTypes = ContentTypeHierarchy.AllContentTypes .Select(ct => Collator.Instance.ContainerType(ct)) .Select(crt => sys.Extender.ExtensionTypes().Contains(crt) ? sys.Extender.Base(crt) : crt) .Distinct() .Where(crt => Repository.Instance.Registered(crt).DataSourceFactory is CoreDataSourceFactory) .ToList(); var builder = new ModelBuilder(SqlServerConventionSetBuilder.Build()); sys.Extender.BaseTypes.Do(t => builder.Ignore(t)); foreach (var sumsType in sys.Extender.BaseTypes.Where(bt => requiredBaseTypes.Contains(bt))) { builder.Entity(sys.Extender.Summarised(sumsType)).ToTable(LinqX.GetTableName(sumsType)); } SummaryModel = builder.Model; }
/// <summary> /// Delete a container from the data source /// </summary> /// <param name="o">The container to delete</param> /// <param name="bypassChecks">Whether to bypass any checks made to stop deletion by a front end user</param> public void Delete(object o, bool bypassChecks) { using (var dataSource = DataSourceFactory.Create(false)) { var idProp = LinqX.GetIdProp(o.GetType(), this.IdName); object noId = ReflectionX.GetDefault(idProp.PropertyType); var eventData = new RepositoryEventData(o, bypassChecks); var eventResult = EventHub.Instance.ProcessEvent("Repository.Set.Delete", this, eventData); var itemDel = ((RepositoryEventData)eventResult.Data).Container; bool wasHandled = ((RepositoryEventData)eventResult.Data).WasHandled; if (itemDel != null) { if (eventResult.EventName.EndsWith("Add")) { DoAdd(dataSource, itemDel, idProp, wasHandled); } else if (eventResult.EventName.EndsWith("Update") && !wasHandled) { dataSource.Update(itemDel); } else if (!wasHandled) { dataSource.Delete(itemDel); } if (!wasHandled) { dataSource.SaveChanges(); } } var savedEventData = new RepositoryEventData(o, bypassChecks); EventHub.Instance.ProcessEvent(eventResult.EventName.Replace("Set", "Saved"), this, savedEventData); } }
protected static void BuildModel() { //if (!Collator.Instance.RepositoryBuilt) // throw new Exception("In CoreDb.OnModelCreating because there was a use of CoreDb before repository was built"); Debug.WriteLine("Building CoreDb"); var requiredTypes = ContentTypeHierarchy.AllContentTypes .Select(ct => Collator.Instance.ContainerType(ct)) .Distinct() .Where(crt => Repository.Instance.Registered(crt).DataSourceFactory is CoreDataSourceFactory) .ToList(); var builder = new ModelBuilder(SqlServerConventionSetBuilder.Build()); // temp, breaks separability of Lynicon systems var sys = LyniconSystem.Instance; foreach (Type baseType in sys.Extender.BaseTypes.Where(t => requiredTypes.Contains(sys.Extender[t]))) { builder.Entity(sys.Extender[baseType]).ToTable(LinqX.GetTableName(baseType)); } CoreModel = builder.Model; }
/// <inheritdoc/> public override TTarget GetSummary <TTarget>(object item) { Type itemType = item.GetType().UnextendedType(); var propertyMap = GetPropertyMap(itemType); var summTypeAttr = itemType.GetCustomAttribute <SummaryTypeAttribute>(); Type summType = typeof(Summary); if (summTypeAttr != null) { summType = summTypeAttr.SummaryType; } TTarget summ = Activator.CreateInstance(summType) as TTarget; if (summ == null) { return(null); } //throw new Exception("GetSummary on object with SummaryAttribute indicating class " + summType.FullName + " not assignable to " + typeof(TTarget).FullName); propertyMap.Do(kvp => summType.GetProperty(kvp.Key).SetValue(summ, itemType.GetProperty(kvp.Value).GetValue(item))); var summary = summ as Summary; summary.Type = itemType; summary.Url = ContentMap.Instance.GetUrl(item); summary.Version = System.Versions.GetVersion(item); summary.UniqueId = LinqX.GetIdProp(item.GetType(), null).GetValue(item); return(summ); }
private object GetKeyForCreate(Type oType, object o) { var keyInfo = LinqX.GetIdProp(o.GetType(), null); if (keyInfo.GetCustomAttribute <DatabaseGeneratedAttribute>()?.DatabaseGeneratedOption == DatabaseGeneratedOption.Identity) { keyInfo.SetValue(o, Data.ContainsKey(oType) ? Data[oType].Count + 1 : 1); } return(keyInfo.GetValue(o)); }
/// <summary> /// Get fields needed to create a summary type from a record type /// </summary> /// <typeparam name="T">the record type</typeparam> /// <param name="contentType">the content type</param> /// <param name="summaryType">the summary type</param> /// <returns>list of fields needed to create summary type</returns> public virtual List <string> GetFieldsForSummary(Type contentType, Type summaryType) { //List<string> summaryProps = summaryType.GetProperties().Select(pi => pi.Name).ToList(); var propertyMap = contentType.GetProperties() .Select(pi => new { pi.Name, SummaryAttribute = pi.GetCustomAttribute <SummaryAttribute>(), AddressingAttribute = pi.GetCustomAttribute <AddressComponentAttribute>() }) .Where(pia => (pia.SummaryAttribute != null) || // && summaryProps.Contains(pia.SummaryAttribute.SummaryProperty) pia.AddressingAttribute != null) .Select(pia => pia.Name) .ToList(); propertyMap.Add(LinqX.GetIdProp(contentType, this.IdName).Name); return(propertyMap); }
protected override void OnModelCreating(ModelBuilder builder) { var requiredTypes = ContentTypeHierarchy.AllContentTypes .Select(ct => Collator.Instance.ContainerType(ct)) .Distinct() .Where(crt => Repository.Instance.Registered(crt).DataSourceFactory is CoreDataSourceFactory) .ToList(); var sys = LyniconSystem.Instance; foreach (Type baseType in sys.Extender.BaseTypes.Where(t => requiredTypes.Contains(sys.Extender[t]))) { builder.Entity(sys.Extender[baseType]).ToTable(LinqX.GetTableName(baseType)); } base.OnModelCreating(builder); }
/// <summary> /// Delete a container from the data source /// </summary> /// <param name="o">The container to delete</param> /// <param name="bypassChecks">Whether to bypass any checks made to stop deletion by a front end user</param> public void Delete(object o, bool bypassChecks) { var db = GetDb(); try { var idProp = LinqX.GetIdProp(o.GetType(), this.IdName); object noId = ReflectionX.GetDefault(idProp.PropertyType); var eventData = new RepositoryEventData(o, bypassChecks); var eventResult = EventHub.Instance.ProcessEvent("Repository.Set.Delete", this, eventData); var itemDel = ((RepositoryEventData)eventResult.Data).Container; bool wasHandled = ((RepositoryEventData)eventResult.Data).WasHandled; if (itemDel != null) { if (eventResult.EventName.EndsWith("Add")) { DoAdd(db, itemDel, idProp, wasHandled); } else if (eventResult.EventName.EndsWith("Update") && !wasHandled) { db.Entry(itemDel).State = EntityState.Modified; } else if (!wasHandled) { db.Entry(itemDel).State = EntityState.Deleted; } if (!wasHandled) { db.SaveChanges(); } } var savedEventData = new RepositoryEventData(o, bypassChecks); EventHub.Instance.ProcessEvent(eventResult.EventName.Replace("Set", "Saved"), this, savedEventData); } finally { EndCallDb(db); } }
protected override void OnModelCreating(ModelBuilder builder) { Debug.WriteLine("Building SummaryDb"); var sys = LyniconSystem.Instance; var requiredBaseTypes = ContentTypeHierarchy.AllContentTypes .Select(ct => Collator.Instance.ContainerType(ct)) .Select(crt => sys.Extender.ExtensionTypes().Contains(crt) ? sys.Extender.Base(crt) : crt) .Distinct() .Where(crt => Repository.Instance.Registered(crt).DataSourceFactory is CoreDataSourceFactory) .ToList(); sys.Extender.BaseTypes.Do(t => builder.Ignore(t)); foreach (var sumsType in sys.Extender.BaseTypes.Where(bt => requiredBaseTypes.Contains(bt))) { builder.Entity(sys.Extender.Summarised(sumsType)).ToTable(LinqX.GetTableName(sumsType)); } }
/// <summary> /// Get containers of a specific type by addresses /// </summary> /// <typeparam name="T">The type of containers to get</typeparam> /// <param name="targetType">type of contained items these will produce, can be a summary type</param> /// <param name="addresses">list of addresses to fetch (ignored if don't have the container type specified)</param> /// <returns>containers at addresses</returns> public IEnumerable <T> Get <T>(Type targetType, IEnumerable <Address> addresses) where T : class { if (!addresses.Any()) { yield break; } var contentType = addresses.First().Type; var paths = addresses.Where( a => typeof(T).IsAssignableFrom(System.Collator.ContainerType(a.Type)) && a.Type == contentType) .Select(a => a.GetAsContentPath()).ToList(); var pathPiInfo = typeof(T).GetProperties() .Select(pi => new { pi, a = pi.GetCustomAttribute <AddressComponentAttribute>() }) .FirstOrDefault(pii => pii.a != null && pii.a.UsePath); var pathSel = LinqX.GetFieldSelector <T>(pathPiInfo.pi.Name); var repo = Registered(typeof(T)); foreach (var res in repo.Get <T>(targetType, new Type[] { contentType }, iq => iq.WhereIn(pathSel, paths))) { yield return(res); } }
/// <summary> /// Delete a container from the data source /// </summary> /// <param name="o">The container to delete</param> /// <param name="bypassChecks">Whether to bypass any checks made to stop deletion by a front end user</param> public virtual void Delete(object o, bool bypassChecks) { using (var dataSource = DataSourceFactory.Create(false)) { var idProp = LinqX.GetIdProp(o.GetType(), this.IdName); Dictionary <string, object> options = new Dictionary <string, object> { { "bypassChecks", bypassChecks } }; var eventData = new RepositoryEventData(o, options); var eventResult = System.Events.ProcessEvent("Repository.Set.Delete", this, eventData); var itemDel = ((RepositoryEventData)eventResult.Data).Container; bool wasHandled = ((RepositoryEventData)eventResult.Data).WasHandled; if (itemDel != null) { if (eventResult.EventName.EndsWith("Add")) { DoAdd(dataSource, itemDel, idProp, wasHandled); } else if (eventResult.EventName.EndsWith("Update") && !wasHandled) { dataSource.Update(itemDel); } else if (!wasHandled) { dataSource.Delete(itemDel); } if (!wasHandled) { dataSource.SaveChanges(); } } var savedEventData = new RepositoryEventData(o, options); System.Events.ProcessEvent(eventResult.EventName.Replace("Set", "Saved"), this, savedEventData); } }
/// <summary> /// Set (create or update) a list of containers to the data source /// </summary> /// <param name="items">The list of containers</param> /// <param name="setOptions">Options for setting</param> /// <returns>List of flags for whether the corresponding by position item was created (rather than updated)</returns> public virtual List <bool> Set(List <object> items, Dictionary <string, object> setOptions) { var db = GetDb(); var createds = new List <bool>(); bool?create = setOptions.Get <bool?>("create"); bool bypassChecks = setOptions.Get <bool>("bypassChecks", false); bool anyUnhandled = false; try { var savedItems = new List <Tuple <object, bool> >(); foreach (object item in items) { var idProp = LinqX.GetIdProp(item.GetType(), this.IdName); bool isAdd; if (create == null) { object noId = ReflectionX.GetDefault(idProp.PropertyType); isAdd = idProp.GetValue(item).Equals(noId); } else { isAdd = create.Value; } var eventData = new RepositoryEventData(item, bypassChecks); var eventResult = EventHub.Instance.ProcessEvent("Repository.Set." + (isAdd ? "Add" : "Update"), this, eventData); var itemSave = ((RepositoryEventData)eventResult.Data).Container; bool wasHandled = ((RepositoryEventData)eventResult.Data).WasHandled; if (!wasHandled) { anyUnhandled = true; } isAdd = eventResult.EventName.EndsWith("Add"); if (isAdd) { DoAdd(db, itemSave, idProp, wasHandled); } else if (!wasHandled) { db.Entry(itemSave).State = EntityState.Modified; } savedItems.Add(Tuple.Create(itemSave, isAdd)); createds.Add(isAdd); } if (savedItems.Count > 0 && anyUnhandled) { db.SaveChanges(); } foreach (var savedItem in savedItems) { var eventData = new RepositoryEventData(savedItem.Item1, bypassChecks); EventHub.Instance.ProcessEvent("Repository.Saved." + (savedItem.Item2 ? "Add" : "Update"), this, eventData); } return(createds); } finally { EndCallDb(db); } }
/// <summary> /// Get a query to find items by unique id /// </summary> /// <typeparam name="T">Type of the content items to get</typeparam> /// <param name="ids">The list of ids of items to get</param> /// <returns>A query body</returns> public Func <IQueryable, IQueryable> GetIdsQuery <T>(IEnumerable <object> ids) where T : class { return((Func <IQueryable, IQueryable>)(iq => iq.AsFacade <T>().WhereIn <T>(LinqX.GetIdSelector <T>(), ids))); }
/// <summary> /// Get the PropertyInfo of the id for a given type /// </summary> /// <param name="t">The type</param> /// <returns>The PropertyInfo for the id</returns> public PropertyInfo GetIdProperty(Type t) { return(LinqX.GetIdProp(t, this.IdName)); }
private object GetKey(object o) { return(LinqX.GetIdProp(o.GetType(), null).GetValue(o)); }
/// <inheritdoc/> public override PropertyInfo GetIdProperty(Type t) { return(LinqX.GetIdProp(t, null)); }
/// <summary> /// Get a query body which converts the address into a query which should return the item from that address /// when used as an argument to a Repository method. /// </summary> /// <typeparam name="T">Container type query is applied to, which the address addresses</typeparam> /// <param name="coll">The collator of the data system in which the query body will run</param> /// <returns>The query body</returns> public Func <IQueryable <T>, IQueryable <T> > GetAsQueryBody <T>(Collator coll) { Func <IQueryable <T>, IQueryable <T> > queryBody = null; if (this.ContainsKey("_id")) { var idProp = coll.GetIdProperty(typeof(T)); return(iq => iq.Where(LinqX.GetPropertyTest <T>(idProp.Name, this["_id"]))); } Dictionary <string, string> keyProps = typeof(T).GetProperties() .Select(pi => new { pi, attr = pi.GetCustomAttribute <AddressComponentAttribute>() }) .Where(pii => pii.attr != null) .ToDictionary(pii => pii.attr.UsePath ? "{Path}" : (pii.attr.RouteKey ?? ("_" + pii.pi.Name)), pii => pii.pi.Name); if (keyProps.ContainsKey("{Path}")) { queryBody = iq => iq.Where(LinqX.GetPropertyTest <T>(keyProps["{Path}"], GetAsContentPath())); } else { foreach (string key in keyProps.Keys) { string propName = keyProps[key]; object matchVal; if (this.ContainsKey(key)) { matchVal = this[key]; } else { // this address doesn't have a value for this address component property so use a default value Type keyType = typeof(T).GetProperty(propName).PropertyType; if (keyType.IsValueType()) { matchVal = Activator.CreateInstance(keyType); } else { matchVal = null; } } if (queryBody == null) { queryBody = iq => iq.Where(LinqX.GetPropertyTest <T>(propName, matchVal)); } else { var innerQueryBody = queryBody; queryBody = iq => innerQueryBody(iq).Where(LinqX.GetPropertyTest <T>(propName, matchVal)); } } if (queryBody == null) { queryBody = iq => iq; } } return(queryBody); }