Example #1
0
        Dictionary <Lite <RoleEntity>, RoleAllowedCache> NewCache()
        {
            using (AuthLogic.Disable())
                using (new EntityCache(EntityCacheType.ForceNewSealed))
                {
                    List <Lite <RoleEntity> > roles = AuthLogic.RolesInOrder().ToList();

                    var rules = Database.Query <RuleTypeEntity>().ToList();

                    var errors = GraphExplorer.FullIntegrityCheck(GraphExplorer.FromRoots(rules));
                    if (errors != null)
                    {
                        throw new IntegrityCheckException(errors);
                    }

                    Dictionary <Lite <RoleEntity>, Dictionary <Type, TypeAllowedAndConditions> > realRules =
                        rules.AgGroupToDictionary(ru => ru.Role, gr => gr
                                                  .SelectCatch(ru => KeyValuePair.Create(TypeLogic.EntityToType.GetOrThrow(ru.Resource), ru.ToTypeAllowedAndConditions()))
                                                  .ToDictionaryEx());

                    Dictionary <Lite <RoleEntity>, RoleAllowedCache> newRules = new Dictionary <Lite <RoleEntity>, RoleAllowedCache>();
                    foreach (var role in roles)
                    {
                        var related = AuthLogic.RelatedTo(role);

                        newRules.Add(role, new RoleAllowedCache(role, merger, related.Select(r => newRules.GetOrThrow(r)).ToList(), realRules.TryGetC(role)));
                    }

                    return(newRules);
                }
        }
Example #2
0
    static void Validate <T>(IEnumerable <T> entities) where T : Entity
    {
#if DEBUG
        var errors = new List <IntegrityCheckWithEntity>();
        foreach (var e in entities)
        {
            var ic = e.FullIntegrityCheck();

            if (ic != null)
            {
                var withEntites = ic.WithEntities(GraphExplorer.FromRoots(entities));
                errors.AddRange(withEntites);
            }
        }
        if (errors.Count > 0)
        {
            throw new IntegrityCheckException(errors);
        }
#else
        var errors = new Dictionary <Guid, IntegrityCheck>();
        foreach (var e in entities)
        {
            var ic = e.FullIntegrityCheck();

            if (ic != null)
            {
                errors.AddRange(ic);
            }
        }
        if (errors.Count > 0)
        {
            throw new IntegrityCheckException(errors);
        }
#endif
    }
Example #3
0
        private void AssertRetrieved <T>(List <T> list) where T : Modifiable
        {
            var graph = GraphExplorer.FromRoots(list);

            var problematic = graph.Where(a =>
                                          a.IsGraphModified &&
                                          a is Entity && (((Entity)a).IdOrNull == null || ((Entity)a).IsNew));

            if (problematic.Any())
            {
                Assert.True(false, "Some non-retrived elements: {0}".FormatWith(problematic.ToString(", ")));
            }
        }
Example #4
0
        public void SaveManyMList()
        {
            using (var tr = new Transaction())
                using (OperationLogic.AllowSave <LabelEntity>())
                    using (OperationLogic.AllowSave <CountryEntity>())
                        using (OperationLogic.AllowSave <AlbumEntity>())
                            using (OperationLogic.AllowSave <ArtistEntity>())
                            {
                                var prev = Database.MListQuery((AlbumEntity a) => a.Songs).Count();

                                var authors =
                                    Database.Query <BandEntity>().Take(6).ToList().Concat <IAuthorEntity>(
                                        Database.Query <ArtistEntity>().Take(8).ToList()).ToList();

                                var label = new LabelEntity {
                                    Name = "Four Music", Country = new CountryEntity {
                                        Name = "Germany"
                                    }, Node = MusicLoader.NextLabelNode()
                                };

                                List <AlbumEntity> albums = 0.To(16).Select(i => new AlbumEntity()
                                {
                                    Name   = "System Greatest hits {0}".FormatWith(i),
                                    Author = i < authors.Count ? authors[i] : new ArtistEntity {
                                        Name = ".Net Framework"
                                    },
                                    Year  = 2001,
                                    Songs = { new SongEmbedded {
                                                  Name = "Compilation {0}".FormatWith(i)
                                              } },
                                    State = AlbumState.Saved,
                                    Label = label,
                                }).ToList();

                                albums.SaveList();

                                Assert.All(GraphExplorer.FromRoots(albums), a => Assert.False(a.IsGraphModified));

                                Assert.Equal(prev + 16, Database.MListQuery((AlbumEntity a) => a.Songs).Count());

                                albums.ForEach(a => a.Name += "Updated");

                                albums.SaveList();

                                albums.ForEach(a => a.Songs.ForEach(s => s.Name = "Updated"));

                                albums.SaveList();

                                //tr.Commit();
                            }
        }
Example #5
0
        static void Validate <T>(IEnumerable <T> entities) where T : Entity
        {
            foreach (var e in entities)
            {
                var ic = e.FullIntegrityCheck();

                if (ic != null)
                {
#if DEBUG
                    throw new IntegrityCheckException(ic.WithEntities(GraphExplorer.FromRoots(entities)));
#else
                    throw new IntegrityCheckException(ic);
#endif
                }
            }
        }
Example #6
0
        public void RetrieveSealed()
        {
            using (Transaction tr = new Transaction())
                using (new EntityCache(EntityCacheType.ForceNewSealed))
                {
                    var albums = Database.Query <AlbumEntity>().ToList();

                    Assert2.AssertAll(GraphExplorer.FromRoots(albums), a => a.Modified == ModifiedState.Sealed);

                    Assert2.Throws <InvalidOperationException>("sealed", () => albums.First().Name = "New name");


                    var notes = Database.Query <NoteWithDateEntity>().ToList();
                    Assert2.AssertAll(GraphExplorer.FromRoots(notes), a => a.Modified == ModifiedState.Sealed);

                    //tr.Commit();
                }
        }
Example #7
0
        /// <param name="keySelector">Unique key to retrieve ids</param>
        /// <param name="isNewPredicate">Optional filter to query only the recently inseted entities</param>
        public static int BulkInsertQueryIds <T, K>(this IEnumerable <T> entities,
                                                    Expression <Func <T, K> > keySelector,
                                                    Expression <Func <T, bool> >?isNewPredicate = null,
                                                    SqlBulkCopyOptions copyOptions = SqlBulkCopyOptions.Default,
                                                    bool preSaving     = true,
                                                    bool validateFirst = true,
                                                    int?timeout        = null,
                                                    string?message     = null)
            where T : Entity
            where K : notnull
        {
            using (HeavyProfiler.Log(nameof(BulkInsertQueryIds), () => typeof(T).TypeName()))
                using (Transaction tr = new Transaction())
                {
                    var t = Schema.Current.Table(typeof(T));

                    var list = entities.ToList();

                    if (isNewPredicate == null)
                    {
                        isNewPredicate = GetFilterAutomatic <T>(t);
                    }

                    var rowNum = BulkInsertTable <T>(list, copyOptions, preSaving, validateFirst, false, timeout, message);

                    var dictionary = Database.Query <T>().Where(isNewPredicate).Select(a => KeyValuePair.Create(keySelector.Evaluate(a), a.Id)).ToDictionaryEx();

                    var getKeyFunc = keySelector.Compile();

                    list.ForEach(e =>
                    {
                        e.SetId(dictionary.GetOrThrow(getKeyFunc(e)));
                        e.SetIsNew(false);
                    });

                    BulkInsertMLists(list, copyOptions, timeout, message);

                    GraphExplorer.CleanModifications(GraphExplorer.FromRoots(list));

                    return(tr.Commit(rowNum));
                }
        }
Example #8
0
        public void SaveManyMList()
        {
            using (Transaction tr = new Transaction())
                using (OperationLogic.AllowSave <AlbumEntity>())
                    using (OperationLogic.AllowSave <ArtistEntity>())
                    {
                        var prev = Database.MListQuery((AlbumEntity a) => a.Songs).Count();

                        var authors =
                            Database.Query <BandEntity>().Take(6).ToList().Concat <IAuthorEntity>(
                                Database.Query <ArtistEntity>().Take(8).ToList()).ToList();

                        List <AlbumEntity> albums = 0.To(16).Select(i => new AlbumEntity()
                        {
                            Name   = "System Greatest hits {0}".FormatWith(i),
                            Author = i < authors.Count ? authors[i] : new ArtistEntity {
                                Name = ".Net Framework"
                            },
                            Year  = 2001,
                            Songs = { new SongEntity {
                                          Name = "Compilation {0}".FormatWith(i)
                                      } },
                            State = AlbumState.Saved
                        }).ToList();

                        albums.SaveList();

                        Assert2.AssertAll(GraphExplorer.FromRoots(albums), a => !a.IsGraphModified);

                        Assert.AreEqual(prev + 16, Database.MListQuery((AlbumEntity a) => a.Songs).Count());

                        albums.ForEach(a => a.Name += "Updated");

                        albums.SaveList();

                        albums.ForEach(a => a.Songs.ForEach(s => s.Name = "Updated"));

                        albums.SaveList();

                        //tr.Commit();
                    }
        }
Example #9
0
        public static int BulkInsertTable <T>(IEnumerable <T> entities,
                                              SqlBulkCopyOptions copyOptions = SqlBulkCopyOptions.Default,
                                              bool preSaving       = true,
                                              bool validateFirst   = true,
                                              bool disableIdentity = false,
                                              int?timeout          = null,
                                              string?message       = null)
            where T : Entity
        {
            using (HeavyProfiler.Log(nameof(BulkInsertTable), () => typeof(T).TypeName()))
            {
                if (message != null)
                {
                    return(SafeConsole.WaitRows(message == "auto" ? $"BulkInsering {entities.Count()} {typeof(T).TypeName()}" : message,
                                                () => BulkInsertTable(entities, copyOptions, preSaving, validateFirst, disableIdentity, timeout, message: null)));
                }

                if (disableIdentity)
                {
                    copyOptions |= SqlBulkCopyOptions.KeepIdentity;
                }

                if (copyOptions.HasFlag(SqlBulkCopyOptions.UseInternalTransaction))
                {
                    throw new InvalidOperationException("BulkInsertDisableIdentity not compatible with UseInternalTransaction");
                }

                var list = entities.ToList();

                if (preSaving)
                {
                    Saver.PreSaving(() => GraphExplorer.FromRoots(list));
                }

                if (validateFirst)
                {
                    Validate <T>(list);
                }

                var  t = Schema.Current.Table <T>();
                bool disableIdentityBehaviour = copyOptions.HasFlag(SqlBulkCopyOptions.KeepIdentity);

                DataTable dt      = new DataTable();
                var       columns = t.Columns.Values.Where(c => !(c is SystemVersionedInfo.SqlServerPeriodColumn) && (disableIdentityBehaviour || !c.IdentityBehaviour)).ToList();
                foreach (var c in columns)
                {
                    dt.Columns.Add(new DataColumn(c.Name, ConvertType(c.Type)));
                }

                using (disableIdentityBehaviour ? Administrator.DisableIdentity(t, behaviourOnly: true) : null)
                {
                    foreach (var e in list)
                    {
                        if (!e.IsNew)
                        {
                            throw new InvalidOperationException("Entites should be new");
                        }
                        t.SetToStrField(e);
                        dt.Rows.Add(t.BulkInsertDataRow(e));
                    }
                }

                using (Transaction tr = new Transaction())
                {
                    Schema.Current.OnPreBulkInsert(typeof(T), inMListTable: false);

                    Executor.BulkCopy(dt, columns, t.Name, copyOptions, timeout);

                    foreach (var item in list)
                    {
                        item.SetNotModified();
                    }

                    return(tr.Commit(list.Count));
                }
            }
        }
Example #10
0
        public static void Save(Entity[] entities)
        {
            if (entities == null || entities.Any(e => e == null))
            {
                throw new ArgumentNullException("entity");
            }

            using (var log = HeavyProfiler.LogNoStackTrace("PreSaving"))
            {
                Schema schema = Schema.Current;
                DirectedGraph <Modifiable> modifiables = PreSaving(() => GraphExplorer.FromRoots(entities));

                HashSet <Entity> wasNew          = modifiables.OfType <Entity>().Where(a => a.IsNew).ToHashSet(ReferenceEqualityComparer <Entity> .Default);
                HashSet <Entity> wasSelfModified = modifiables.OfType <Entity>().Where(a => a.Modified == ModifiedState.SelfModified).ToHashSet(ReferenceEqualityComparer <Entity> .Default);

                log.Switch("Integrity");

                var error = GraphExplorer.FullIntegrityCheck(modifiables);
                if (error != null)
                {
#if DEBUG
                    throw new IntegrityCheckException(error.WithEntities(modifiables));
#else
                    throw new IntegrityCheckException(error);
#endif
                }

                log.Switch("Graph");

                GraphExplorer.PropagateModifications(modifiables.Inverse());

                //colapsa modifiables (collections and embeddeds) keeping indentifiables only
                DirectedGraph <Entity> identifiables = GraphExplorer.ColapseIdentifiables(modifiables);

                foreach (var node in identifiables)
                {
                    schema.OnSaving(node);
                }

                //Remove all the edges that doesn't mean a dependency
                identifiables.RemoveEdges(identifiables.Edges.Where(e => !e.To.IsNew).ToList());

                //Remove all the nodes that are not modified
                List <Entity> notModified = identifiables.Where(node => !node.IsGraphModified).ToList();

                notModified.ForEach(node => identifiables.RemoveFullNode(node, None));

                log.Switch("SaveGroups");

                SaveGraph(schema, identifiables);

                foreach (var node in identifiables)
                {
                    schema.OnSaved(node, new SavedEventArgs
                    {
                        IsRoot          = entities.Contains(node),
                        WasNew          = wasNew.Contains(node),
                        WasSelfModified = wasSelfModified.Contains(node),
                    });
                }

                EntityCache.Add(identifiables);
                EntityCache.Add(notModified);

                GraphExplorer.CleanModifications(modifiables);
            }
        }
Example #11
0
        public static int BulkInsertTable <T>(IEnumerable <T> entities,
                                              SqlBulkCopyOptions copyOptions = SqlBulkCopyOptions.Default,
                                              bool preSaving       = false,
                                              bool validateFirst   = false,
                                              bool disableIdentity = false,
                                              int?timeout          = null,
                                              string message       = null)
            where T : Entity
        {
            if (message != null)
            {
                return(SafeConsole.WaitRows(message == "auto" ? $"BulkInsering {entities.Count()} {typeof(T).TypeName()}" : message,
                                            () => BulkInsertTable(entities, copyOptions, preSaving, validateFirst, disableIdentity, timeout, message: null)));
            }

            if (disableIdentity)
            {
                copyOptions |= SqlBulkCopyOptions.KeepIdentity;
            }

            if (copyOptions.HasFlag(SqlBulkCopyOptions.UseInternalTransaction))
            {
                throw new InvalidOperationException("BulkInsertDisableIdentity not compatible with UseInternalTransaction");
            }

            var list = entities.ToList();

            if (preSaving)
            {
                Schema schema = Schema.Current;
                GraphExplorer.PreSaving(() => GraphExplorer.FromRoots(list), (Modifiable m, ref bool graphModified) =>
                {
                    if (m is ModifiableEntity me)
                    {
                        me.SetTemporalErrors(null);
                    }

                    m.PreSaving(ref graphModified);

                    if (m is Entity ident)
                    {
                        schema.OnPreSaving(ident, ref graphModified);
                    }
                });
            }

            if (validateFirst)
            {
                Validate <T>(list);
            }

            var  t = Schema.Current.Table <T>();
            bool disableIdentityBehaviour = copyOptions.HasFlag(SqlBulkCopyOptions.KeepIdentity);
            bool oldIdentityBehaviour     = t.IdentityBehaviour;

            DataTable dt = new DataTable();

            foreach (var c in disableIdentityBehaviour ? t.Columns.Values : t.Columns.Values.Where(c => !c.IdentityBehaviour))
            {
                dt.Columns.Add(new DataColumn(c.Name, c.Type.UnNullify()));
            }

            if (disableIdentityBehaviour)
            {
                t.IdentityBehaviour = false;
            }
            foreach (var e in entities)
            {
                if (!e.IsNew)
                {
                    throw new InvalidOperationException("Entites should be new");
                }
                t.SetToStrField(e);
                dt.Rows.Add(t.BulkInsertDataRow(e));
            }
            if (disableIdentityBehaviour)
            {
                t.IdentityBehaviour = oldIdentityBehaviour;
            }

            using (Transaction tr = new Transaction())
            {
                Schema.Current.OnPreBulkInsert(typeof(T), inMListTable: false);

                Executor.BulkCopy(dt, t.Name, copyOptions, timeout);

                foreach (var item in list)
                {
                    item.SetNotModified();
                }

                return(tr.Commit(list.Count));
            }
        }