private long?GetLastOffset() { using var context = dbContextCreator.Create(); var entityTypeName = context.Model.FindEntityType(typeof(TEntity))?.GetTableName(); Expression <Func <SqlEventLogEntry, bool> > filter = e => e.EntityType == entityTypeName && e.TransactionId < PostgresFunctions.SnapshotMinimalTransactionId(PostgresFunctions.CurrentTransactionIdsSnapshot()); if (!context.Set <SqlEventLogEntry>().Any(filter)) { return(null); } return(context.Set <SqlEventLogEntry>().Where(filter).Max(e => e.Offset)); }
private Expression <Func <SqlEventLogEntry, bool> > BuildEventsSearchCriterion(long?fromOffsetExclusive) { Expression <Func <SqlEventLogEntry, bool> > searchCriterion; if (fromOffsetExclusive.HasValue) { searchCriterion = e => e.Offset > fromOffsetExclusive.Value && e.EntityType == entityTypeName && e.TransactionId < PostgresFunctions.SnapshotMinimalTransactionId(PostgresFunctions.CurrentTransactionIdsSnapshot()); } else { searchCriterion = e => e.EntityType == entityTypeName && e.TransactionId < PostgresFunctions.SnapshotMinimalTransactionId(PostgresFunctions.CurrentTransactionIdsSnapshot()); } return(searchCriterion); }
SqlPreCommand?SyncViews(Replacements replacements) { var isPostgres = Schema.Current.Settings.IsPostgres; var oldView = Schema.Current.DatabaseNames().SelectMany(db => { if (isPostgres) { if (db != null) { throw new InvalidOperationException("Multi-database not supported in postgress"); } return((from p in Database.View <PgClass>() where p.relkind == RelKind.View let ns = p.Namespace() where !ns.IsInternal() let definition = PostgresFunctions.pg_get_viewdef(p.oid) select KeyValuePair.Create(new ObjectName(new SchemaName(db, ns.nspname, isPostgres), p.relname, isPostgres), definition)).ToList()); } else { using (Administrator.OverrideDatabaseInSysViews(db)) { return((from v in Database.View <SysViews>() join s in Database.View <SysSchemas>() on v.schema_id equals s.schema_id join m in Database.View <SysSqlModules>() on v.object_id equals m.object_id select KeyValuePair.Create(new ObjectName(new SchemaName(db, s.name, isPostgres), v.name, isPostgres), m.definition)).ToList()); } } }).ToDictionary(); using (replacements.WithReplacedDatabaseName()) return(Synchronizer.SynchronizeScript(Spacing.Double, Views, oldView, createNew: (name, newView) => newView.CreateView(), removeOld: null, mergeBoth: (name, newDef, oldDef) => Clean(newDef.CreateView().Sql) == Clean(oldDef) ? null : newDef.AlterView() )); }
SqlPreCommand?SyncProcedures(Replacements replacements) { var isPostgres = Schema.Current.Settings.IsPostgres; var oldProcedures = Schema.Current.DatabaseNames().SelectMany(db => { if (isPostgres) { if (db != null) { throw new InvalidOperationException("Multi-database not supported in postgress"); } return((from v in Database.View <PgProc>() let ns = v.Namespace() where !ns.IsInternal() let definition = PostgresFunctions.pg_get_viewdef(v.oid) select KeyValuePair.Create(new ObjectName(new SchemaName(db, ns.nspname, isPostgres), v.proname, isPostgres), definition)).ToList()); } else { using (Administrator.OverrideDatabaseInSysViews(db)) { return((from p in Database.View <SysObjects>() join s in Database.View <SysSchemas>() on p.schema_id equals s.schema_id where p.type == "P" || p.type == "IF" || p.type == "FN" join m in Database.View <SysSqlModules>() on p.object_id equals m.object_id select KeyValuePair.Create(new ObjectName(new SchemaName(db, s.name, isPostgres), p.name, isPostgres), m.definition)).ToList()); } } }).ToDictionary(); return(Synchronizer.SynchronizeScript( Spacing.Double, StoreProcedures, oldProcedures, createNew: (name, newProc) => newProc.CreateSql(), removeOld: null, mergeBoth: (name, newProc, oldProc) => Clean(newProc.CreateSql().Sql) == Clean(oldProc) ? null : newProc.AlterSql() )); }
public static Dictionary <string, DiffTable> GetDatabaseDescription(List <DatabaseName?> databases) { List <DiffTable> allTables = new List <DiffTable>(); var isPostgres = Schema.Current.Settings.IsPostgres; foreach (var db in databases) { SafeConsole.WriteColor(ConsoleColor.Cyan, '.'); using (Administrator.OverrideDatabaseInSysViews(db)) { var databaseName = db == null?Connector.Current.DatabaseName() : db.Name; //var sysDb = Database.View<SysDatabases>().Single(a => a.name == databaseName); var con = Connector.Current; var tables = (from ns in Database.View <PgNamespace>() where !ns.IsInternal() from t in ns.Tables() select new DiffTable { Name = new ObjectName(new SchemaName(db, ns.nspname, isPostgres), t.relname, isPostgres), TemporalType = t.Triggers().Any(t => t.Proc() !.proname == "versioning") ? Signum.Engine.SysTableTemporalType.SystemVersionTemporalTable : SysTableTemporalType.None, //Period = !con.SupportsTemporalTables ? null : //(from p in t.Periods() // join sc in t.Columns() on p.start_column_id equals sc.column_id // join ec in t.Columns() on p.end_column_id equals ec.column_id // select new DiffPeriod // { // StartColumnName = sc.name, // EndColumnName = ec.name, // }).SingleOrDefaultEx(), TemporalTableName = t.Triggers() .Where(t => t.Proc() !.proname == "versioning") .Select(t => ParseVersionFunctionParam(t.tgargs)) .SingleOrDefaultEx(), //TemporalTableName = !con.SupportsTemporalTables || t.history_table_id == null ? null : // Database.View<SysTables>() // .Where(ht => ht.object_id == t.history_table_id) // .Select(ht => new ObjectName(new SchemaName(db, ht.Schema().name, isPostgres), ht.name, isPostgres)) // .SingleOrDefault(), PrimaryKeyName = (from c in t.Constraints() where c.contype == ConstraintType.PrimaryKey select c.conname == null ? null : new ObjectName(new SchemaName(db, c.Namespace() !.nspname, isPostgres), c.conname, isPostgres)) .SingleOrDefaultEx(), Columns = (from c in t.Attributes() let def = c.Default() select new DiffColumn { Name = c.attname, DbType = new AbstractDbType(ToNpgsqlDbType(c.Type() !.typname)), UserTypeName = null, Nullable = !c.attnotnull, Collation = null, Length = PostgresFunctions._pg_char_max_length(c.atttypid, c.atttypmod) ?? -1, Precision = c.atttypid == 1700 /*numeric*/ ? ((c.atttypmod - 4) >> 16) & 65535 : 0, Scale = c.atttypid == 1700 /*numeric*/ ? (c.atttypmod - 4) & 65535 : 0, Identity = c.attidentity == 'a', GeneratedAlwaysType = GeneratedAlwaysType.None, DefaultConstraint = def == null ? null : new DiffDefaultConstraint { Definition = pg_get_expr(def.adbin, def.adrelid), }, PrimaryKey = t.Indices().Any(i => i.indisprimary && i.indkey.Contains(c.attnum)), }).ToDictionaryEx(a => a.Name, "columns"),
public static Dictionary <string, DiffTable> GetDatabaseDescription(List <DatabaseName?> databases) { List <DiffTable> allTables = new List <DiffTable>(); var isPostgres = Schema.Current.Settings.IsPostgres; foreach (var db in databases) { SafeConsole.WriteColor(ConsoleColor.Cyan, '.'); using (Administrator.OverrideDatabaseInSysViews(db)) { var databaseName = db == null?Connector.Current.DatabaseName() : db.Name; //var sysDb = Database.View<SysDatabases>().Single(a => a.name == databaseName); var con = Connector.Current; var tables = (from s in Database.View <PgNamespace>() where !systemSchemas.Contains(s.nspname) from t in s.Tables() select new DiffTable { Name = new ObjectName(new SchemaName(db, s.nspname, isPostgres), t.relname, isPostgres), TemporalType = t.Triggers().Any(t => t.Proc().proname == "versioning") ? Signum.Engine.SysTableTemporalType.SystemVersionTemporalTable : SysTableTemporalType.None, //Period = !con.SupportsTemporalTables ? null : //(from p in t.Periods() // join sc in t.Columns() on p.start_column_id equals sc.column_id // join ec in t.Columns() on p.end_column_id equals ec.column_id // select new DiffPeriod // { // StartColumnName = sc.name, // EndColumnName = ec.name, // }).SingleOrDefaultEx(), TemporalTableName = t.Triggers() .Where(t => t.Proc().proname == "versioning") .Select(t => ParseVersionFunctionParam(t.tgargs)) .SingleOrDefaultEx(), //TemporalTableName = !con.SupportsTemporalTables || t.history_table_id == null ? null : // Database.View<SysTables>() // .Where(ht => ht.object_id == t.history_table_id) // .Select(ht => new ObjectName(new SchemaName(db, ht.Schema().name, isPostgres), ht.name, isPostgres)) // .SingleOrDefault(), PrimaryKeyName = (from c in t.Constraints() where c.contype == ConstraintType.PrimaryKey select c.conname == null ? null : new ObjectName(new SchemaName(db, c.Namespace().nspname, isPostgres), c.conname, isPostgres)) .SingleOrDefaultEx(), Columns = (from c in t.Attributes() let def = c.Default() select new DiffColumn { Name = c.attname, DbType = new AbstractDbType(ToNpgsqlDbType(c.Type().typname)), UserTypeName = null, Nullable = !c.attnotnull, Collation = null, Length = PostgresFunctions._pg_char_max_length(c.atttypid, c.atttypmod) ?? -1, Precision = c.atttypid == 1700 /*numeric*/ ? ((c.atttypmod - 4) >> 16) & 65535 : 0, Scale = c.atttypid == 1700 /*numeric*/ ? (c.atttypmod - 4) & 65535 : 0, Identity = c.attidentity == 'a', GeneratedAlwaysType = GeneratedAlwaysType.None, DefaultConstraint = def == null ? null : new DiffDefaultConstraint { Definition = pg_get_expr(def.adbin, def.adrelid), }, PrimaryKey = t.Indices().Any(i => i.indisprimary && i.indkey.Contains(c.attnum)), }).ToDictionaryEx(a => a.Name, "columns"), MultiForeignKeys = (from fk in t.Constraints() where fk.contype == ConstraintType.ForeignKey select new DiffForeignKey { Name = new ObjectName(new SchemaName(db, fk.Namespace().nspname, isPostgres), fk.conname, isPostgres), IsDisabled = false, TargetTable = new ObjectName(new SchemaName(db, fk.TargetTable().Namespace().nspname, isPostgres), fk.TargetTable().relname, isPostgres), Columns = PostgresFunctions.generate_subscripts(fk.conkey, 1).Select(i => new DiffForeignKeyColumn { Parent = t.Attributes().Single(c => c.attnum == fk.conkey[i]).attname, Referenced = fk.TargetTable().Attributes().Single(c => c.attnum == fk.confkey[i]).attname, }).ToList(), }).ToList(), SimpleIndices = (from ix in t.Indices() select new DiffIndex { IsUnique = ix.indisunique, IsPrimary = ix.indisprimary, IndexName = ix.Class().relname, FilterDefinition = PostgresFunctions.pg_get_expr(ix.indpred !, ix.indrelid), Type = DiffIndexType.NonClustered, Columns = (from i in PostgresFunctions.generate_subscripts(ix.indkey, 1) let at = t.Attributes().Single(a => a.attnum == ix.indkey[i]) orderby i select new DiffIndexColumn { ColumnName = at.attname, IsIncluded = i >= ix.indnkeyatts }).ToList() }).ToList(),
private void ConfigureEventLog(ModelBuilder modelBuilder) { modelBuilder.HasPostgresExtension("uuid-ossp"); modelBuilder.HasDbFunction(() => PostgresFunctions.CurrentTransactionIdsSnapshot()); modelBuilder.HasDbFunction(() => PostgresFunctions.SnapshotMinimalTransactionId(default));