static SqlPreCommand?Schema_Synchronizing(Replacements replacements) { bool any = Database.Query <TypeHelpEntity>().Any() || Database.Query <QueryHelpEntity>().Any() || Database.Query <NamespaceHelpEntity>().Any() || Database.Query <AppendixHelpEntity>().Any(); if (!(any && replacements.Interactive && SafeConsole.Ask("Synchronize Help content?"))) { return(null); } SyncData data = new SyncData( namespaces: AllTypes().Select(a => a.Namespace !).ToHashSet(), appendices: Database.Query <AppendixHelpEntity>().Select(a => a.UniqueName).ToHashSet() ); var ns = SynchronizeNamespace(replacements, data); var appendix = SynchronizeAppendix(replacements, data); var types = SynchronizeTypes(replacements, data); var queries = SynchronizeQueries(replacements, data); return(SqlPreCommand.Combine(Spacing.Double, ns, appendix, types, queries)); }
public static void ExecuteLeaves(this SqlPreCommand preCommand, CommandType commandType = CommandType.Text) { foreach (var simple in preCommand.Leaves()) { simple.ExecuteNonQuery(commandType); } }
public SqlPreCommand DeleteSqlSync <T>(T entity, Expression <Func <T, bool> >?where, string?comment = null) where T : Entity { if (typeof(T) != Type && where != null) { throw new InvalidOperationException("Invalid table"); } var declaration = where != null?DeclarePrimaryKeyVariable(entity, where) : null; var variableOrId = entity.Id.VariableName ?? entity.Id.Object; var isPostgres = Schema.Current.Settings.IsPostgres; var pre = OnPreDeleteSqlSync(entity); var collections = (from tml in this.TablesMList() select new SqlPreCommandSimple("DELETE FROM {0} WHERE {1} = {2}; --{3}" .FormatWith(tml.Name, tml.BackReference.Name.SqlEscape(isPostgres), variableOrId, comment ?? entity.ToString()))).Combine(Spacing.Simple); var main = new SqlPreCommandSimple("DELETE FROM {0} WHERE {1} = {2}; --{3}" .FormatWith(Name, this.PrimaryKey.Name.SqlEscape(isPostgres), variableOrId, comment ?? entity.ToString())); if (isPostgres && declaration != null) { return(PostgresDoBlock(entity.Id.VariableName !, declaration, SqlPreCommand.Combine(Spacing.Simple, pre, collections, main) !)); } return(SqlPreCommand.Combine(Spacing.Simple, declaration, pre, collections, main) !); }
public static SqlPreCommand?SnapshotIsolation() { var connector = Connector.Current; if (!connector.AllowsSetSnapshotIsolation) { return(null); } var list = connector.Schema.DatabaseNames().Select(a => a?.Name).ToList(); if (list.Contains(null)) { list.Remove(null); list.Add(connector.DatabaseName()); } var sqlBuilder = connector.SqlBuilder; var cmd = list.NotNull() .Select(dbn => new DatabaseName(null, dbn, connector.Schema.Settings.IsPostgres)) .Where(db => !SnapshotIsolationEnabled(db)) .Select(db => SqlPreCommand.Combine(Spacing.Simple, sqlBuilder.SetSingleUser(db), sqlBuilder.SetSnapshotIsolation(db, true), sqlBuilder.MakeSnapshotIsolationDefault(db, true), sqlBuilder.SetMultiUser(db)) ).Combine(Spacing.Double); return(cmd); }
public static SqlPreCommand?CreateTablesScript() { var sqlBuilder = Connector.Current.SqlBuilder; Schema s = Schema.Current; List <ITable> tables = s.GetDatabaseTables().Where(t => !s.IsExternalDatabase(t.Name.Schema.Database)).ToList(); SqlPreCommand?createTables = tables.Select(t => sqlBuilder.CreateTableSql(t)).Combine(Spacing.Double)?.PlainSqlCommand(); SqlPreCommand?foreignKeys = tables.Select(sqlBuilder.AlterTableForeignKeys).Combine(Spacing.Double)?.PlainSqlCommand(); SqlPreCommand?indices = tables.Select(t => { var allIndexes = t.GeneratAllIndexes().Where(a => !(a is PrimaryKeyIndex));; var mainIndices = allIndexes.Select(ix => sqlBuilder.CreateIndex(ix, checkUnique: null)).Combine(Spacing.Simple); var historyIndices = t.SystemVersioned == null ? null : allIndexes.Where(a => a.GetType() == typeof(TableIndex)).Select(mix => sqlBuilder.CreateIndexBasic(mix, forHistoryTable: true)).Combine(Spacing.Simple); return(SqlPreCommand.Combine(Spacing.Double, mainIndices, historyIndices)); }).NotNull().Combine(Spacing.Double)?.PlainSqlCommand(); return(SqlPreCommand.Combine(Spacing.Triple, createTables, foreignKeys, indices)); }
internal SqlPreCommand Schema_Generating() { SqlPreCommand views = GenerateViews(); SqlPreCommand procedures = GenerateProcedures(); return(SqlPreCommand.Combine(Spacing.Triple, views, procedures)); }
public SqlPreCommand SynchronizationScript(bool interactive = true, bool schemaOnly = false, string replaceDatabaseName = null) { OnBeforeDatabaseAccess(); if (Synchronizing == null) { return(null); } using (CultureInfoUtils.ChangeBothCultures(ForceCultureInfo)) using (ExecutionMode.Global()) { Replacements replacements = new Replacements() { Interactive = interactive, ReplaceDatabaseName = replaceDatabaseName, SchemaOnly = schemaOnly }; SqlPreCommand command = Synchronizing .GetInvocationListTyped() .Select(e => { try { return(e(replacements)); } catch (Exception ex) { return(new SqlPreCommandSimple("-- Exception on {0}.{1}\r\n{2}".FormatWith(e.Method.DeclaringType.Name, e.Method.Name, ex.Message.Indent(2, '-')))); } }) .Combine(Spacing.Triple); return(command); } }
internal SqlPreCommand Schema_Synchronizing(Replacements replacements) { SqlPreCommand views = SyncViews(replacements); SqlPreCommand procedures = SyncProcedures(replacements); return(SqlPreCommand.Combine(Spacing.Triple, views, procedures)); }
static SqlPreCommand AuthCache_PreDeleteSqlSync(Entity arg) { TypeEntity type = (TypeEntity)arg; var ce = Administrator.UnsafeDeletePreCommand((DisconnectedExportEntity de) => de.Copies, Database.MListQuery((DisconnectedExportEntity de) => de.Copies).Where(mle => mle.Element.Type.RefersTo(type))); var ci = Administrator.UnsafeDeletePreCommand((DisconnectedImportEntity di) => di.Copies, Database.MListQuery((DisconnectedImportEntity di) => di.Copies).Where(mle => mle.Element.Type.RefersTo(type))); return(SqlPreCommand.Combine(Spacing.Simple, ce, ci)); }
public SqlPreCommand DeleteSqlSync(Entity ident, string comment = null) { var pre = OnPreDeleteSqlSync(ident); var collections = (from tml in this.TablesMList() select new SqlPreCommandSimple("DELETE {0} WHERE {1} = {2} --{3}" .FormatWith(tml.Name, tml.BackReference.Name.SqlEscape(), ident.Id, comment ?? ident.ToString()))).Combine(Spacing.Simple); var main = new SqlPreCommandSimple("DELETE {0} WHERE {1} = {2} --{3}" .FormatWith(Name, this.PrimaryKey.Name.SqlEscape(), ident.Id, comment ?? ident.ToString())); return(SqlPreCommand.Combine(Spacing.Simple, pre, collections, main)); }
public SqlPreCommand SynchronizationScript(bool interactive = true, bool schemaOnly = false, string replaceDatabaseName = null) { OnBeforeDatabaseAccess(); if (Synchronizing == null) { return(null); } using (CultureInfoUtils.ChangeBothCultures(ForceCultureInfo)) using (ExecutionMode.Global()) { Replacements replacements = new Replacements() { Interactive = interactive, ReplaceDatabaseName = replaceDatabaseName, SchemaOnly = schemaOnly }; SqlPreCommand command = Synchronizing .GetInvocationListTyped() .Select(e => { try { SafeConsole.WriteColor(ConsoleColor.White, e.Method.DeclaringType.TypeName()); Console.Write("."); SafeConsole.WriteColor(ConsoleColor.DarkGray, e.Method.MethodName()); Console.Write("..."); var result = e(replacements); if (result == null) { SafeConsole.WriteLineColor(ConsoleColor.Green, "OK"); } else { SafeConsole.WriteLineColor(ConsoleColor.Yellow, "Changes"); } return(result); } catch (Exception ex) { SafeConsole.WriteLineColor(ConsoleColor.Red, "Error"); return(new SqlPreCommandSimple("-- Exception on {0}.{1}\r\n{2}".FormatWith(e.Method.DeclaringType.Name, e.Method.Name, ex.Message.Indent(2, '-')))); } }) .Combine(Spacing.Triple); return(command); } }
public static SqlPreCommand RemoveAllScript(DatabaseName?databaseName) { var schemas = SqlBuilder.SystemSchemas.ToString(a => "'" + a + "'", ", "); return(SqlPreCommand.Combine(Spacing.Double, new SqlPreCommandSimple(Use(databaseName, RemoveAllProceduresScript)), new SqlPreCommandSimple(Use(databaseName, RemoveAllViewsScript).FormatWith(schemas)), new SqlPreCommandSimple(Use(databaseName, RemoveAllConstraintsScript)), Connector.Current.SupportsTemporalTables ? new SqlPreCommandSimple(Use(databaseName, StopSystemVersioning)) : null, new SqlPreCommandSimple(Use(databaseName, RemoveAllTablesScript)), new SqlPreCommandSimple(Use(databaseName, RemoveAllSchemasScript.FormatWith(schemas))) ) !); }
public static SqlPreCommand?RemoveDuplicatedIndices() { var isPostgres = Schema.Current.Settings.IsPostgres; var sqlBuilder = Connector.Current.SqlBuilder; var plainData = (from s in Database.View <SysSchemas>() from t in s.Tables() from ix in t.Indices() from ic in ix.IndexColumns() from c in t.Columns() where ic.column_id == c.column_id select new { table = new ObjectName(new SchemaName(null, s.name, isPostgres), t.name, isPostgres), index = ix.name, ix.is_unique, column = c.name, ic.is_descending_key, ic.is_included_column, ic.index_column_id }).ToList(); var tables = plainData.AgGroupToDictionary(a => a.table, gr => gr.AgGroupToDictionary(a => new { a.index, a.is_unique }, gr2 => gr2.OrderBy(a => a.index_column_id) .Select(a => a.column + (a.is_included_column ? "(K)" : "(I)") + (a.is_descending_key ? "(D)" : "(A)")) .ToString("|"))); var result = tables.SelectMany(t => t.Value.GroupBy(a => a.Value, a => a.Key) .Where(gr => gr.Count() > 1) .Select(gr => { var best = gr.OrderByDescending(a => a.is_unique).ThenByDescending(a => a.index !/*CSBUG*/.StartsWith("IX")).ThenByDescending(a => a.index).First(); return(gr.Where(g => g != best) .Select(g => sqlBuilder.DropIndex(t.Key !, g.index !)) .PreAnd(new SqlPreCommandSimple("-- DUPLICATIONS OF {0}".FormatWith(best.index))).Combine(Spacing.Simple)); }) ).Combine(Spacing.Double); if (result == null) { return(null); } return(SqlPreCommand.Combine(Spacing.Double, new SqlPreCommandSimple("use {0}".FormatWith(Connector.Current.DatabaseName())), result)); }
static SqlPreCommand Schema_Synchronize_Tokens(Replacements replacements) { if (AvoidSynchronize) { return(null); } StringDistance sd = new StringDistance(); var emailTemplates = Database.Query <WordTemplateEntity>().ToList(); SqlPreCommand cmd = emailTemplates.Select(uq => SynchronizeWordTemplate(replacements, uq, sd)).Combine(Spacing.Double); return(cmd); }
static SqlPreCommand Schema_Synchronizing(Replacements replacements) { if (!replacements.Interactive) { return(null); } var list = Database.Query <UserQueryEntity>().ToList(); var table = Schema.Current.Table(typeof(UserQueryEntity)); SqlPreCommand cmd = list.Select(uq => ProcessUserQuery(replacements, table, uq)).Combine(Spacing.Double); return(cmd); }
static void Synchronize() { Console.WriteLine("Check and Modify the synchronization script before"); Console.WriteLine("executing it in SQL Server Management Studio: "); Console.WriteLine(); SqlPreCommand command = Administrator.TotalSynchronizeScript(); if (command == null) { SafeConsole.WriteLineColor(ConsoleColor.Green, "Already synchronized!"); return; } command.OpenSqlFileRetry(); }
static SqlPreCommand?Schema_Synchronizing_DefaultTemplates(Replacements replacements) { if (AvoidSynchronizeDefaultTemplates) { return(null); } var table = Schema.Current.Table(typeof(EmailTemplateEntity)); var emailModels = Database.Query <EmailModelEntity>().Where(se => !se.EmailTemplates().Any()).ToList(); string cis = Database.Query <CultureInfoEntity>().Select(a => a.Name).ToString(", ").Etc(60); if (!emailModels.Any()) { return(null); } if (!replacements.Interactive || !SafeConsole.Ask("{0}\r\n have no EmailTemplates. Create in {1}?".FormatWith(emailModels.ToString("\r\n"), cis.DefaultText("No CultureInfos registered!")))) { return(null); } using (replacements.WithReplacedDatabaseName()) { var cmd = emailModels.Select(se => { try { return(table.InsertSqlSync(EmailModelLogic.CreateDefaultTemplate(se), includeCollections: true)); } catch (Exception e) { return(new SqlPreCommandSimple("Exception on SystemEmail {0}: {1}".FormatWith(se, e.Message))); } }).Combine(Spacing.Double); if (cmd != null) { return(SqlPreCommand.Combine(Spacing.Double, new SqlPreCommandSimple("DECLARE @parentId INT"), cmd)); } return(cmd); } }
public string CleanCommandText() { try { SqlPreCommand eager = EagerProjections?.Select(cp => cp.Command).Combine(Spacing.Double); SqlPreCommand lazy = LazyChildProjections?.Select(cp => cp.Command).Combine(Spacing.Double); return(SqlPreCommandConcat.Combine(Spacing.Double, eager == null ? null : new SqlPreCommandSimple("--------- Eager Client Joins ----------------"), eager, eager == null && lazy == null ? null : new SqlPreCommandSimple("--------- MAIN QUERY ------------------------"), MainCommand, lazy == null ? null : new SqlPreCommandSimple("--------- Lazy Client Joins (if needed) -----"), lazy).PlainSql()); } catch { return(MainCommand.Sql); } }
public static void OpenSqlFileRetry(this SqlPreCommand command) { SafeConsole.WriteLineColor(ConsoleColor.Yellow, "There are changes!"); var fileName = "Sync {0:dd-MM-yyyy HH_mm_ss}.sql".FormatWith(DateTime.Now); Save(command, fileName); SafeConsole.WriteLineColor(ConsoleColor.DarkYellow, command.PlainSql()); Console.WriteLine("Script saved in: " + Path.Combine(Directory.GetCurrentDirectory(), fileName)); Console.WriteLine("Check the synchronization script before running it!"); var answer = SafeConsole.AskRetry("Open or run?", "open", "run", "exit"); if (answer == "open") { Thread.Sleep(1000); Open(fileName); if (SafeConsole.Ask("run now?")) ExecuteRetry(fileName); } else if (answer == "run") { ExecuteRetry(fileName); } }
public static void SynchronizeRoles(XDocument doc) { Table table = Schema.Current.Table(typeof(RoleEntity)); TableMList relationalTable = table.TablesMList().Single(); Dictionary <string, XElement> rolesXml = doc.Root.Element("Roles").Elements("Role").ToDictionary(x => x.Attribute("Name").Value); { Dictionary <string, RoleEntity> rolesDic = Database.Query <RoleEntity>().ToDictionary(a => a.ToString()); Replacements replacements = new Replacements(); replacements.AskForReplacements(rolesDic.Keys.ToHashSet(), rolesXml.Keys.ToHashSet(), "Roles"); rolesDic = replacements.ApplyReplacementsToOld(rolesDic, "Roles"); Console.WriteLine("Part 1: Syncronize roles without relationships"); var roleInsertsDeletes = Synchronizer.SynchronizeScript(Spacing.Double, rolesXml, rolesDic, createNew: (name, xelement) => table.InsertSqlSync(new RoleEntity { Name = name }, includeCollections: false), removeOld: (name, role) => SqlPreCommand.Combine(Spacing.Simple, new SqlPreCommandSimple("DELETE {0} WHERE {1} = {2} --{3}" .FormatWith(relationalTable.Name, ((IColumn)relationalTable.Field).Name.SqlEscape(), role.Id, role.Name)), table.DeleteSqlSync(role)), mergeBoth: (name, xElement, role) => { var oldName = role.Name; role.Name = name; role.MergeStrategy = xElement.Attribute("MergeStrategy")?.Let(t => t.Value.ToEnum <MergeStrategy>()) ?? MergeStrategy.Union; return(table.UpdateSqlSync(role, includeCollections: false, comment: oldName)); }); if (roleInsertsDeletes != null) { SqlPreCommand.Combine(Spacing.Triple, new SqlPreCommandSimple("-- BEGIN ROLE SYNC SCRIPT"), new SqlPreCommandSimple("use {0}".FormatWith(Connector.Current.DatabaseName())), roleInsertsDeletes, new SqlPreCommandSimple("-- END ROLE SYNC SCRIPT")).OpenSqlFileRetry(); Console.WriteLine("Press [Enter] when executed..."); Console.ReadLine(); } else { SafeConsole.WriteLineColor(ConsoleColor.Green, "Already syncronized"); } } { Console.WriteLine("Part 2: Syncronize roles relationships"); Dictionary <string, RoleEntity> rolesDic = Database.Query <RoleEntity>().ToDictionary(a => a.ToString()); var roleRelationships = Synchronizer.SynchronizeScript(Spacing.Double, rolesXml, rolesDic, createNew: (name, xelement) => { throw new InvalidOperationException("No new roles should be at this stage. Did you execute the script?"); }, removeOld: (name, role) => { throw new InvalidOperationException("No old roles should be at this stage. Did you execute the script?"); }, mergeBoth: (name, xElement, role) => { var should = xElement.Attribute("Contains").Value.Split(new [] { ',' }, StringSplitOptions.RemoveEmptyEntries); var current = role.Roles.Select(a => a.ToString()); if (should.OrderBy().SequenceEqual(current.OrderBy())) { return(null); } role.Roles = should.Select(rs => rolesDic.GetOrThrow(rs).ToLite()).ToMList(); return(table.UpdateSqlSync(role)); }); if (roleRelationships != null) { SqlPreCommand.Combine(Spacing.Triple, new SqlPreCommandSimple("-- BEGIN ROLE SYNC SCRIPT"), new SqlPreCommandSimple("use {0}".FormatWith(Connector.Current.DatabaseName())), roleRelationships, new SqlPreCommandSimple("-- END ROLE SYNC SCRIPT")).OpenSqlFileRetry(); Console.WriteLine("Press [Enter] when executed..."); Console.ReadLine(); } else { SafeConsole.WriteLineColor(ConsoleColor.Green, "Already syncronized"); } } }
public static void Save(this SqlPreCommand command, string fileName) { string content = command.PlainSql(); File.WriteAllText(fileName, content, Encoding.Unicode); }
public static SqlPreCommand?ImportRulesScript(XDocument doc, bool interactive) { Replacements replacements = new Replacements { Interactive = interactive }; Dictionary <string, Lite <RoleEntity> > rolesDic = roles.Value.ToDictionary(a => a.ToString()); Dictionary <string, XElement> rolesXml = doc.Root.Element("Roles").Elements("Role").ToDictionary(x => x.Attribute("Name").Value); replacements.AskForReplacements(rolesXml.Keys.ToHashSet(), rolesDic.Keys.ToHashSet(), "Roles"); rolesDic = replacements.ApplyReplacementsToNew(rolesDic, "Roles"); try { var xmlOnly = rolesXml.Keys.Except(rolesDic.Keys).ToList(); if (xmlOnly.Any()) { throw new InvalidOperationException("roles {0} not found on the database".FormatWith(xmlOnly.ToString(", "))); } foreach (var kvp in rolesXml) { var r = rolesDic[kvp.Key]; var current = GetMergeStrategy(r); var should = kvp.Value.Attribute("MergeStrategy")?.Let(t => t.Value.ToEnum <MergeStrategy>()) ?? MergeStrategy.Union; if (current != should) { throw new InvalidOperationException("Merge strategy of {0} is {1} in the database but is {2} in the file".FormatWith(r, current, should)); } EnumerableExtensions.JoinStrict( roles.Value.RelatedTo(r), kvp.Value.Attribute("Contains").Value.Split(new [] { ',' }, StringSplitOptions.RemoveEmptyEntries), sr => sr.ToString(), s => rolesDic[s].ToString(), (sr, s) => 0, "subRoles of {0}".FormatWith(r)); } } catch (InvalidOperationException ex) { throw new InvalidRoleGraphException("The role graph does not match:\r\n" + ex.Message); } var dbOnlyWarnings = rolesDic.Keys.Except(rolesXml.Keys).Select(n => new SqlPreCommandSimple("-- Alien role {0} not configured!!".FormatWith(n)) ).Combine(Spacing.Simple); SqlPreCommand?result = ImportFromXml.GetInvocationListTyped() .Select(inv => inv(doc.Root, rolesDic, replacements)).Combine(Spacing.Triple); if (replacements.Values.Any(a => a.Any())) { SafeConsole.WriteLineColor(ConsoleColor.Red, "There are renames! Remember to export after executing the script"); } if (result == null && dbOnlyWarnings == null) { return(null); } return(SqlPreCommand.Combine(Spacing.Triple, new SqlPreCommandSimple("-- BEGIN AUTH SYNC SCRIPT"), new SqlPreCommandSimple("use {0}".FormatWith(Connector.Current.DatabaseName())), dbOnlyWarnings, result, new SqlPreCommandSimple("-- END AUTH SYNC SCRIPT"))); }
public static SqlPreCommand? Combine(this IEnumerable<SqlPreCommand?> preCommands, Spacing spacing) { return SqlPreCommand.Combine(spacing, preCommands.ToArray()); }
public static SqlPreCommand PlainSqlCommand(this SqlPreCommand command) { return command.PlainSql().SplitNoEmpty("GO\r\n") .Select(s => new SqlPreCommandSimple(s)) .Combine(Spacing.Simple)!; }
private SqlPreCommandSimple PostgresDoBlock(string variableName, SqlPreCommandSimple declaration, SqlPreCommand block) { return(new SqlPreCommandSimple(@$ "DO $$ DECLARE {declaration.PlainSql().Indent(4)} BEGIN IF {variableName} IS NULL THEN RAISE EXCEPTION 'Not found'; END IF; {block.PlainSql().Indent(4)} END $$;")); }
public static void Start(SchemaBuilder sb, DynamicQueryManager dqm) { if (sb.NotDefined(MethodInfo.GetCurrentMethod())) { GetDashboard = GetDashboardDefault; PermissionAuthLogic.RegisterPermissions(DashboardPermission.ViewDashboard); UserAssetsImporter.RegisterName <DashboardEntity>("Dashboard"); UserAssetsImporter.PartNames.AddRange(new Dictionary <string, Type> { { "UserChartPart", typeof(UserChartPartEntity) }, { "UserQueryPart", typeof(UserQueryPartEntity) }, { "LinkListPart", typeof(LinkListPartEntity) }, { "ValueUserQueryListPart", typeof(ValueUserQueryListPartEntity) }, }); sb.Include <DashboardEntity>() .WithQuery(dqm, () => cp => new { Entity = cp, cp.Id, cp.DisplayName, cp.EntityType, cp.Owner, cp.DashboardPriority, }); sb.Include <LinkListPartEntity>() .WithQuery(dqm, () => cp => new { Entity = cp, ToStr = cp.ToString(), Links = cp.Links.Count }); sb.Include <ValueUserQueryListPartEntity>() .WithQuery(dqm, () => cp => new { Entity = cp, ToStr = cp.ToString(), Links = cp.UserQueries.Count }); if (sb.Settings.ImplementedBy((DashboardEntity cp) => cp.Parts.First().Content, typeof(UserQueryPartEntity))) { sb.Schema.EntityEvents <UserQueryEntity>().PreUnsafeDelete += query => { Database.MListQuery((DashboardEntity cp) => cp.Parts).Where(mle => query.Contains(((UserQueryPartEntity)mle.Element.Content).UserQuery)).UnsafeDeleteMList(); Database.Query <UserQueryPartEntity>().Where(uqp => query.Contains(uqp.UserQuery)).UnsafeDelete(); }; sb.Schema.Table <UserQueryEntity>().PreDeleteSqlSync += arg => { var uq = (UserQueryEntity)arg; var parts = Administrator.UnsafeDeletePreCommand((DashboardEntity cp) => cp.Parts, Database.MListQuery((DashboardEntity cp) => cp.Parts) .Where(mle => ((UserQueryPartEntity)mle.Element.Content).UserQuery == uq)); var parts2 = Administrator.UnsafeDeletePreCommand(Database.Query <UserQueryPartEntity>() .Where(mle => mle.UserQuery == uq)); return(SqlPreCommand.Combine(Spacing.Simple, parts, parts2)); }; } if (sb.Settings.ImplementedBy((DashboardEntity cp) => cp.Parts.First().Content, typeof(UserChartPartEntity))) { sb.Schema.EntityEvents <UserChartEntity>().PreUnsafeDelete += query => { Database.MListQuery((DashboardEntity cp) => cp.Parts).Where(mle => query.Contains(((UserChartPartEntity)mle.Element.Content).UserChart)).UnsafeDeleteMList(); Database.Query <UserChartPartEntity>().Where(uqp => query.Contains(uqp.UserChart)).UnsafeDelete(); }; sb.Schema.Table <UserChartEntity>().PreDeleteSqlSync += arg => { var uc = (UserChartEntity)arg; var parts = Administrator.UnsafeDeletePreCommand((DashboardEntity cp) => cp.Parts, Database.MListQuery((DashboardEntity cp) => cp.Parts) .Where(mle => ((UserChartPartEntity)mle.Element.Content).UserChart == uc)); var parts2 = Administrator.UnsafeDeletePreCommand(Database.Query <UserChartPartEntity>() .Where(mle => mle.UserChart == uc)); return(SqlPreCommand.Combine(Spacing.Simple, parts, parts2)); }; } DashboardGraph.Register(); Dashboards = sb.GlobalLazy(() => Database.Query <DashboardEntity>().ToDictionary(a => a.ToLite()), new InvalidateWith(typeof(DashboardEntity))); DashboardsByType = sb.GlobalLazy(() => Dashboards.Value.Values.Where(a => a.EntityType != null) .GroupToDictionary(a => TypeLogic.IdToType.GetOrThrow(a.EntityType.Id), a => a.ToLite()), new InvalidateWith(typeof(DashboardEntity))); } }
public static void Start(SchemaBuilder sb) { if (sb.NotDefined(MethodInfo.GetCurrentMethod())) { PermissionAuthLogic.RegisterPermissions(DashboardPermission.ViewDashboard); UserAssetsImporter.Register <DashboardEntity>("Dashboard", DashboardOperation.Save); UserAssetsImporter.PartNames.AddRange(new Dictionary <string, Type> { { "UserChartPart", typeof(UserChartPartEntity) }, { "CombinedUserChartPart", typeof(CombinedUserChartPartEntity) }, { "UserQueryPart", typeof(UserQueryPartEntity) }, { "LinkListPart", typeof(LinkListPartEntity) }, { "ValueUserQueryListPart", typeof(ValueUserQueryListPartEntity) }, { "UserTreePart", typeof(UserTreePartEntity) }, }); sb.Include <DashboardEntity>() .WithQuery(() => cp => new { Entity = cp, cp.Id, cp.DisplayName, cp.EntityType, cp.Owner, cp.DashboardPriority, }); if (sb.Settings.ImplementedBy((DashboardEntity cp) => cp.Parts.First().Content, typeof(UserQueryPartEntity))) { sb.Schema.EntityEvents <UserQueryEntity>().PreUnsafeDelete += query => { Database.MListQuery((DashboardEntity cp) => cp.Parts).Where(mle => query.Contains(((UserQueryPartEntity)mle.Element.Content).UserQuery)).UnsafeDeleteMList(); Database.Query <UserQueryPartEntity>().Where(uqp => query.Contains(uqp.UserQuery)).UnsafeDelete(); return(null); }; sb.Schema.Table <UserQueryEntity>().PreDeleteSqlSync += arg => { var uq = (UserQueryEntity)arg; var parts = Administrator.UnsafeDeletePreCommandMList((DashboardEntity cp) => cp.Parts, Database.MListQuery((DashboardEntity cp) => cp.Parts) .Where(mle => ((UserQueryPartEntity)mle.Element.Content).UserQuery == uq)); var parts2 = Administrator.UnsafeDeletePreCommand(Database.Query <UserQueryPartEntity>() .Where(mle => mle.UserQuery == uq)); return(SqlPreCommand.Combine(Spacing.Simple, parts, parts2)); }; } if (sb.Settings.ImplementedBy((DashboardEntity cp) => cp.Parts.First().Content, typeof(UserChartPartEntity))) { sb.Schema.EntityEvents <UserChartEntity>().PreUnsafeDelete += query => { Database.MListQuery((DashboardEntity cp) => cp.Parts).Where(mle => query.Contains(((UserChartPartEntity)mle.Element.Content).UserChart)).UnsafeDeleteMList(); Database.Query <UserChartPartEntity>().Where(uqp => query.Contains(uqp.UserChart)).UnsafeDelete(); Database.MListQuery((DashboardEntity cp) => cp.Parts).Where(mle => ((CombinedUserChartPartEntity)mle.Element.Content).UserCharts.Any(uc => query.Contains(uc))).UnsafeDeleteMList(); Database.Query <CombinedUserChartPartEntity>().Where(cuqp => cuqp.UserCharts.Any(uc => query.Contains(uc))).UnsafeDelete(); return(null); }; sb.Schema.Table <UserChartEntity>().PreDeleteSqlSync += arg => { var uc = (UserChartEntity)arg; var mlistElems = Administrator.UnsafeDeletePreCommandMList((DashboardEntity cp) => cp.Parts, Database.MListQuery((DashboardEntity cp) => cp.Parts) .Where(mle => ((UserChartPartEntity)mle.Element.Content).UserChart == uc)); var parts = Administrator.UnsafeDeletePreCommand(Database.Query <UserChartPartEntity>() .Where(mle => mle.UserChart == uc)); var mlistElems2 = Administrator.UnsafeDeletePreCommandMList((DashboardEntity cp) => cp.Parts, Database.MListQuery((DashboardEntity cp) => cp.Parts) .Where(mle => ((CombinedUserChartPartEntity)mle.Element.Content).UserCharts.Contains(uc))); var parts2 = Administrator.UnsafeDeletePreCommand(Database.Query <CombinedUserChartPartEntity>() .Where(mle => mle.UserCharts.Contains(uc))); return(SqlPreCommand.Combine(Spacing.Simple, mlistElems, parts, mlistElems2, parts2)); }; } DashboardGraph.Register(); Dashboards = sb.GlobalLazy(() => Database.Query <DashboardEntity>().ToDictionary(a => a.ToLite()), new InvalidateWith(typeof(DashboardEntity))); DashboardsByType = sb.GlobalLazy(() => Dashboards.Value.Values.Where(a => a.EntityType != null) .SelectCatch(d => KeyValuePair.Create(TypeLogic.IdToType.GetOrThrow(d.EntityType !.Id), d.ToLite())) .GroupToDictionary(), new InvalidateWith(typeof(DashboardEntity))); } }
internal SqlPreCommand ImportXml(XElement element, Dictionary <string, Lite <RoleEntity> > roles, Replacements replacements) { var current = Database.RetrieveAll <RuleTypeEntity>().GroupToDictionary(a => a.Role); var xRoles = (element.Element("Types")?.Elements("Role")).EmptyIfNull(); var should = xRoles.ToDictionary(x => roles[x.Attribute("Name").Value]); Table table = Schema.Current.Table(typeof(RuleTypeEntity)); replacements.AskForReplacements( xRoles.SelectMany(x => x.Elements("Type")).Select(x => x.Attribute("Resource").Value).ToHashSet(), TypeLogic.NameToType.Where(a => !a.Value.IsEnumEntity()).Select(a => a.Key).ToHashSet(), typeReplacementKey); replacements.AskForReplacements( xRoles.SelectMany(x => x.Elements("Type")).SelectMany(t => t.Elements("Condition")).Select(x => x.Attribute("Name").Value).ToHashSet(), SymbolLogic <TypeConditionSymbol> .AllUniqueKeys(), typeConditionReplacementKey); Func <string, TypeEntity> getResource = s => { Type type = TypeLogic.NameToType.TryGetC(replacements.Apply(typeReplacementKey, s)); if (type == null) { return(null); } return(TypeLogic.TypeToEntity[type]); }; return(Synchronizer.SynchronizeScript(Spacing.Double, should, current, createNew: (role, x) => { var dic = (from xr in x.Elements("Type") let t = getResource(xr.Attribute("Resource").Value) where t != null select KVP.Create(t, new { Allowed = xr.Attribute("Allowed").Value.ToEnum <TypeAllowed>(), Condition = Conditions(xr, replacements) })).ToDictionaryEx("Type rules for {0}".FormatWith(role)); SqlPreCommand restSql = dic.Select(kvp => table.InsertSqlSync(new RuleTypeEntity { Resource = kvp.Key, Role = role, Allowed = kvp.Value.Allowed, Conditions = kvp.Value.Condition }, comment: Comment(role, kvp.Key, kvp.Value.Allowed))).Combine(Spacing.Simple)?.Do(p => p.GoBefore = true); return restSql; }, removeOld: (role, list) => list.Select(rt => table.DeleteSqlSync(rt)).Combine(Spacing.Simple)?.Do(p => p.GoBefore = true), mergeBoth: (role, x, list) => { var dic = (from xr in x.Elements("Type") let t = getResource(xr.Attribute("Resource").Value) where t != null && !t.ToType().IsEnumEntity() select KVP.Create(t, xr)).ToDictionaryEx("Type rules for {0}".FormatWith(role)); SqlPreCommand restSql = Synchronizer.SynchronizeScript( Spacing.Simple, dic, list.Where(a => a.Resource != null).ToDictionary(a => a.Resource), createNew: (r, xr) => { var a = xr.Attribute("Allowed").Value.ToEnum <TypeAllowed>(); var conditions = Conditions(xr, replacements); return table.InsertSqlSync(new RuleTypeEntity { Resource = r, Role = role, Allowed = a, Conditions = conditions }, comment: Comment(role, r, a)); }, removeOld: (r, rt) => table.DeleteSqlSync(rt, Comment(role, r, rt.Allowed)), mergeBoth: (r, xr, pr) => { var oldA = pr.Allowed; pr.Allowed = xr.Attribute("Allowed").Value.ToEnum <TypeAllowed>(); var conditions = Conditions(xr, replacements); if (!pr.Conditions.SequenceEqual(conditions)) { pr.Conditions = conditions; } return table.UpdateSqlSync(pr, comment: Comment(role, r, oldA, pr.Allowed)); })?.Do(p => p.GoBefore = true); return restSql; })); }