protected virtual void BackupDatabase(DisconnectedMachineEntity machine, Lite <DisconnectedExportEntity> export, Connector newDatabase) { string backupFileName = Path.Combine(DisconnectedLogic.BackupFolder, BackupFileName(machine, export)); FileTools.CreateParentDirectory(backupFileName); DisconnectedTools.BackupDatabase(new DatabaseName(null, newDatabase.DatabaseName()), backupFileName); }
protected virtual int Update(DisconnectedMachineEntity machine, Table table, IDisconnectedStrategy strategy, DatabaseName newDatabaseName) { using (Transaction tr = new Transaction()) { SqlPreCommandSimple command = UpdateTableScript(machine, table, newDatabaseName); int result = Executor.ExecuteNonQuery(command); foreach (var rt in table.TablesMList()) { SqlPreCommandSimple delete = DeleteUpdatedRelationalTableScript(machine, table, rt, newDatabaseName); Executor.ExecuteNonQuery(delete); using (DisableIdentityIfNecessary(rt)) { SqlPreCommandSimple insert = InsertUpdatedRelationalTableScript(machine, table, rt, newDatabaseName); Executor.ExecuteNonQuery(insert); } } return(tr.Commit(result)); } }
protected virtual int Insert(DisconnectedMachineEntity machine, Table table, IDisconnectedStrategy strategy, SqlConnector newDatabase) { DatabaseName newDatabaseName = new DatabaseName(null, newDatabase.DatabaseName()); var count = (int)CountNewItems(table, newDatabaseName).ExecuteScalar(); if (count == 0) { return(0); } using (Transaction tr = new Transaction()) { int result; using (DisableIdentityIfNecessary(table)) { SqlPreCommandSimple sql = InsertTableScript(table, newDatabaseName); result = Executor.ExecuteNonQuery(sql); } foreach (var rt in table.TablesMList()) { using (DisableIdentityIfNecessary(rt)) { SqlPreCommandSimple rsql = InsertRelationalTableScript(table, newDatabaseName, rt); Executor.ExecuteNonQuery(rsql); } } return(tr.Commit(result)); } }
public virtual ImportResult Import(DisconnectedMachineEntity machine, Table table, IDisconnectedStrategy strategy, SqlConnector newDatabase) { int inserts = Insert(machine, table, strategy, newDatabase); return(new ImportResult { Inserted = inserts, Updated = 0 }); }
private void RestoreDatabase(DisconnectedMachineEntity machine, Lite <DisconnectedImportEntity> import) { string backupFileName = Path.Combine(DisconnectedLogic.BackupFolder, BackupFileName(machine, import)); string fileName = DatabaseFileName(machine); string logFileName = DatabaseLogFileName(machine); DisconnectedTools.RestoreDatabase(DatabaseName(machine), backupFileName, fileName, logFileName); }
public override ImportResult Import(DisconnectedMachineEntity machine, Table table, IDisconnectedStrategy strategy, SqlConnector newDatabase) { int update = strategy.Upload == Upload.Subset ? Update(machine, table, strategy, new DatabaseName(null, newDatabase.DatabaseName())) : 0; int inserts = Insert(machine, table, strategy, newDatabase); return(new ImportResult { Inserted = inserts, Updated = update }); }
public virtual Lite <DisconnectedImportEntity> BeginImportDatabase(DisconnectedMachineEntity machine, Stream?file = null) { Lite <DisconnectedImportEntity> import = new DisconnectedImportEntity { Machine = machine.ToLite(), Copies = uploadTables.Select(t => new DisconnectedImportTableEmbedded { Type = t.Type.ToTypeEntity().ToLite(), DisableForeignKeys = t.Strategy.DisableForeignKeys !.Value, }).ToMList()
public override ImportResult Import(DisconnectedMachineEntity machine, Table table, IDisconnectedStrategy strategy, SqlServerConnector newDatabase) { var isPostgres = Schema.Current.Settings.IsPostgres; int update = strategy.Upload == Upload.Subset ? Update(machine, table, strategy, new DatabaseName(null, newDatabase.DatabaseName(), isPostgres)) : 0; int inserts = Insert(machine, table, strategy, newDatabase); return(new ImportResult { Inserted = inserts, Updated = update }); }
protected virtual string CreateDatabase(DisconnectedMachineEntity machine) { DatabaseName databaseName = DatabaseName(machine); DisconnectedTools.DropIfExists(databaseName); string fileName = DatabaseFileName(machine); string logFileName = DatabaseLogFileName(machine); DisconnectedTools.CreateDatabase(databaseName, fileName, logFileName); return(((SqlServerConnector)Connector.Current).ConnectionString.Replace(Connector.Current.DatabaseName(), databaseName.Name)); }
static string ValidateDisconnectedMachine(DisconnectedMachineEntity dm, PropertyInfo pi, bool isMin) { var conflicts = Database.Query <DisconnectedMachineEntity>() .Where(e => e.SeedInterval.Overlaps(dm.SeedInterval) && e != dm) .Select(e => new { e.SeedInterval, Machine = e.ToLite() }) .ToList(); conflicts = conflicts.Where(c => c.SeedInterval.Contains(isMin ? dm.SeedMin : dm.SeedMax) || dm.SeedInterval.Subset(c.SeedInterval) || c.SeedInterval.Subset(dm.SeedInterval)).ToList(); if (conflicts.Any()) { return(DisconnectedMessage._0OverlapsWith1.NiceToString(pi.NiceName(), conflicts.CommaAnd(s => "{0} {1}".FormatWith(s.Machine, s.SeedInterval)))); } return(null); }
protected virtual SqlPreCommandSimple DeleteUpdatedRelationalTableScript(DisconnectedMachineEntity machine, Table table, TableMList rt, DatabaseName newDatabaseName) { ParameterBuilder pb = Connector.Current.ParameterBuilder; var delete = new SqlPreCommandSimple(@"DELETE {0} FROM {0} INNER JOIN {1} as [table] ON {0}.{2} = [table].{3}".FormatWith( rt.Name, table.Name.OnDatabase(newDatabaseName), rt.BackReference.Name.SqlEscape(), table.PrimaryKey.Name.SqlEscape()) + GetUpdateWhere(table), new List <DbParameter> { pb.CreateParameter("@machineId", machine.Id.Object, machine.Id.Object.GetType()) }); return(delete); }
protected virtual SqlPreCommandSimple UpdateTableScript(DisconnectedMachineEntity machine, Table table, DatabaseName newDatabaseName) { ParameterBuilder pb = Connector.Current.ParameterBuilder; var command = new SqlPreCommandSimple(@"UPDATE {0} SET {2} FROM {0} INNER JOIN {1} as [table] ON {0}.{3} = [table].{3}".FormatWith( table.Name, table.Name.OnDatabase(newDatabaseName), table.Columns.Values.Where(c => !c.PrimaryKey).ToString(c => " {0} = [table].{0}".FormatWith(c.Name.SqlEscape()), ",\r\n"), table.PrimaryKey.Name.SqlEscape()) + GetUpdateWhere(table), new List <DbParameter> { pb.CreateParameter("@machineId", machine.Id.Object, machine.Id.Object.GetType()) }); return(command); }
protected virtual SqlPreCommandSimple InsertUpdatedRelationalTableScript(DisconnectedMachineEntity machine, Table table, TableMList rt, DatabaseName newDatabaseName) { ParameterBuilder pb = Connector.Current.ParameterBuilder; var insert = new SqlPreCommandSimple(@"INSERT INTO {0} ({1}) SELECT {2} FROM {3} as [relationalTable] INNER JOIN {4} as [table] ON [relationalTable].{5} = [table].{6}".FormatWith( rt.Name, rt.Columns.Values.ToString(c => c.Name.SqlEscape(), ", "), rt.Columns.Values.ToString(c => "[relationalTable]." + c.Name.SqlEscape(), ", "), rt.Name.OnDatabase(newDatabaseName), table.Name.OnDatabase(newDatabaseName), rt.BackReference.Name.SqlEscape(), table.PrimaryKey.Name.SqlEscape()) + GetUpdateWhere(table), new List <DbParameter> { pb.CreateParameter("@machineId", machine.Id.Object, machine.Id.Object.GetType()) }); return(insert); }
public virtual void Export(Table table, IDisconnectedStrategy strategy, DatabaseName newDatabaseName, DisconnectedMachineEntity machine) { this.CopyTable(table, strategy, newDatabaseName); }
protected virtual string BackupFileName(DisconnectedMachineEntity machine, Lite <DisconnectedExportEntity> export) { return("{0}.{1}.Export.{2}.bak".FormatWith(Connector.Current.DatabaseName(), machine.MachineName.ToString(), export.Id)); }
public virtual string BackupNetworkFileName(DisconnectedMachineEntity machine, Lite <DisconnectedExportEntity> export) { return(Path.Combine(DisconnectedLogic.BackupNetworkFolder, BackupFileName(machine, export))); }
private void DropDatabaseIfExists(DisconnectedMachineEntity machine) { DisconnectedTools.DropIfExists(DatabaseName(machine)); }
protected virtual DatabaseName DatabaseName(DisconnectedMachineEntity machine) { var isPostgres = Schema.Current.Settings.IsPostgres; return(new DatabaseName(null, Connector.Current.DatabaseName() + "_Export_" + DisconnectedTools.CleanMachineName(machine.MachineName), isPostgres)); }
protected virtual string DatabaseLogFileName(DisconnectedMachineEntity machine) { return(Path.Combine(DisconnectedLogic.DatabaseFolder, Connector.Current.DatabaseName() + "_Export_" + DisconnectedTools.CleanMachineName(machine.MachineName) + "_Log.ldf")); }
protected virtual void OnExportingError(DisconnectedMachineEntity machine, Lite <DisconnectedExportEntity> export, Exception exception) { }
protected virtual void OnStartExporting(DisconnectedMachineEntity machine) { }
private string GetImportConnectionString(DisconnectedMachineEntity machine) { return(((SqlConnector)Connector.Current).ConnectionString.Replace(Connector.Current.DatabaseName(), DatabaseName(machine).Name)); }
public static IQueryable <DisconnectedImportEntity> Exports(this DisconnectedMachineEntity m) { return(ExportsExpression.Evaluate(m)); }
protected virtual DatabaseName DatabaseName(DisconnectedMachineEntity machine) { return(new DatabaseName(null, Connector.Current.DatabaseName() + "_Import_" + DisconnectedTools.CleanMachineName(machine.MachineName))); }
public static IQueryable <DisconnectedImportEntity> Exports(this DisconnectedMachineEntity m) => As.Expression(() => Database.Query <DisconnectedImportEntity>().Where(di => di.Machine.Is(m)));
protected virtual string BackupFileName(DisconnectedMachineEntity machine, Lite <DisconnectedImportEntity> import) { return("{0}.{1}.Import.{2}.bak".FormatWith(Connector.Current.DatabaseName(), DisconnectedTools.CleanMachineName(machine.MachineName), import.Id)); }
public override void Export(Table table, IDisconnectedStrategy strategy, DatabaseName newDatabaseName, DisconnectedMachineEntity machine) { this.DeleteTable(table, newDatabaseName); this.CopyTable(table, strategy, newDatabaseName); }
public virtual Lite <DisconnectedExportEntity> BeginExportDatabase(DisconnectedMachineEntity machine) { Lite <DisconnectedExportEntity> export = new DisconnectedExportEntity { Machine = machine.ToLite(), Copies = downloadTables.Select(t => new DisconnectedExportTableEmbedded { Type = t.Type.ToTypeEntity().ToLite() }).ToMList() }.Save().ToLite(); var cancelationSource = new CancellationTokenSource(); var user = UserHolder.Current; var token = cancelationSource.Token; var task = Task.Factory.StartNew(() => { using (UserHolder.UserSession(user)) { OnStartExporting(machine); DisconnectedMachineEntity.Current = machine.ToLite(); try { using (token.MeasureTime(l => export.InDB().UnsafeUpdate().Set(s => s.Lock, s => l).Execute())) { foreach (var tuple in downloadTables) { token.ThrowIfCancellationRequested(); if (tuple.Strategy.Upload == Upload.Subset) { miUnsafeLock.MakeGenericMethod(tuple.Type).Invoke(this, new object[] { machine.ToLite(), tuple.Strategy, export }); } } } string connectionString; using (token.MeasureTime(l => export.InDB().UnsafeUpdate().Set(s => s.CreateDatabase, s => l).Execute())) connectionString = CreateDatabase(machine); var newDatabase = new SqlServerConnector(connectionString, Schema.Current, ((SqlServerConnector)Connector.Current).Version); using (token.MeasureTime(l => export.InDB().UnsafeUpdate().Set(s => s.CreateSchema, s => l).Execute())) using (Connector.Override(newDatabase)) using (ObjectName.OverrideOptions(new ObjectNameOptions { AvoidDatabaseName = true })) { Administrator.TotalGeneration(); } using (token.MeasureTime(l => export.InDB().UnsafeUpdate().Set(s => s.DisableForeignKeys, s => l).Execute())) using (Connector.Override(newDatabase)) using (ObjectName.OverrideOptions(new ObjectNameOptions { AvoidDatabaseName = true })) { foreach (var tuple in downloadTables.Where(t => !t.Type.IsEnumEntity())) { token.ThrowIfCancellationRequested(); DisableForeignKeys(tuple.Table); } } var isPostgres = Schema.Current.Settings.IsPostgres; DatabaseName newDatabaseName = new DatabaseName(null, newDatabase.DatabaseName(), isPostgres); foreach (var tuple in downloadTables) { token.ThrowIfCancellationRequested(); int ms = 0; using (token.MeasureTime(l => ms = l)) { tuple.Strategy.Exporter !.Export(tuple.Table, tuple.Strategy, newDatabaseName, machine); } export.MListElementsLite(_ => _.Copies).Where(c => c.Element.Type.Is(tuple.Type.ToTypeEntity())).UnsafeUpdateMList() .Set(mle => mle.Element.CopyTable, mle => ms) .Execute(); } using (token.MeasureTime(l => export.InDB().UnsafeUpdate().Set(s => s.EnableForeignKeys, s => l).Execute())) foreach (var tuple in downloadTables.Where(t => !t.Type.IsEnumEntity())) { token.ThrowIfCancellationRequested(); EnableForeignKeys(tuple.Table); } using (token.MeasureTime(l => export.InDB().UnsafeUpdate().Set(s => s.ReseedIds, s => l).Execute())) { var tablesToUpload = Schema.Current.Tables.Values.Where(t => DisconnectedLogic.GetStrategy(t.Type).Upload != Upload.None) .SelectMany(t => t.TablesMList().Cast <ITable>().And(t)).Where(t => t.PrimaryKey.Identity).ToList(); var maxIdDictionary = tablesToUpload.ToDictionary(t => t, t => DisconnectedTools.MaxIdInRange(t, machine.SeedMin, machine.SeedMax)); using (Connector.Override(newDatabase)) using (ObjectName.OverrideOptions(new ObjectNameOptions { AvoidDatabaseName = true })) { foreach (var table in tablesToUpload) { token.ThrowIfCancellationRequested(); long?max = maxIdDictionary.GetOrThrow(table); DisconnectedTools.SetNextId(table, (max + 1) ?? machine.SeedMin); } } } CopyExport(export, newDatabase); machine.InDB().UnsafeUpdate().Set(s => s.State, s => DisconnectedMachineState.Disconnected).Execute(); using (SqlServerConnector.Override(newDatabase)) using (ObjectName.OverrideOptions(new ObjectNameOptions { AvoidDatabaseName = true })) machine.InDB().UnsafeUpdate().Set(s => s.State, s => DisconnectedMachineState.Disconnected).Execute(); using (token.MeasureTime(l => export.InDB().UnsafeUpdate().Set(s => s.BackupDatabase, s => l).Execute())) BackupDatabase(machine, export, newDatabase); using (token.MeasureTime(l => export.InDB().UnsafeUpdate().Set(s => s.DropDatabase, s => l).Execute())) DropDatabase(newDatabase); token.ThrowIfCancellationRequested(); export.InDB().UnsafeUpdate() .Set(s => s.State, s => DisconnectedExportState.Completed) .Set(s => s.Total, s => s.CalculateTotal()) .Execute(); } catch (Exception e) { var ex = e.LogException(); export.InDB().UnsafeUpdate() .Set(s => s.Exception, s => ex.ToLite()) .Set(s => s.State, s => DisconnectedExportState.Error) .Execute(); OnExportingError(machine, export, e); } finally { runningExports.Remove(export); DisconnectedMachineEntity.Current = null; OnEndExporting(); } } }); runningExports.Add(export, new RunningExports(task, cancelationSource)); return(export); }
public virtual Lite <DisconnectedImportEntity> BeginImportDatabase(DisconnectedMachineEntity machine, Stream file = null) { Lite <DisconnectedImportEntity> import = new DisconnectedImportEntity { Machine = machine.ToLite(), Copies = uploadTables.Select(t => new DisconnectedImportTableEmbedded { Type = t.Type.ToTypeEntity().ToLite(), DisableForeignKeys = t.Strategy.DisableForeignKeys.Value, }).ToMList() }.Save().ToLite(); if (file != null) { using (FileStream fs = File.OpenWrite(BackupNetworkFileName(machine, import))) { file.CopyTo(fs); file.Close(); } } var threadContext = Statics.ExportThreadContext(); var cancelationSource = new CancellationTokenSource(); var user = UserEntity.Current; var token = cancelationSource.Token; var task = Task.Factory.StartNew(() => { lock (SyncLock) using (UserHolder.UserSession(user)) { OnStartImporting(machine); DisconnectedMachineEntity.Current = machine.ToLite(); try { if (file != null) { using (token.MeasureTime(l => import.InDB().UnsafeUpdate().Set(s => s.RestoreDatabase, s => l).Execute())) { DropDatabaseIfExists(machine); RestoreDatabase(machine, import); } } string connectionString = GetImportConnectionString(machine); var newDatabase = new SqlConnector(connectionString, Schema.Current, DynamicQueryManager.Current, ((SqlConnector)Connector.Current).Version); using (token.MeasureTime(l => import.InDB().UnsafeUpdate().Set(s => s.SynchronizeSchema, s => l).Execute())) using (Connector.Override(newDatabase)) using (ObjectName.OverrideOptions(new ObjectNameOptions { AvoidDatabaseName = true })) using (ExecutionMode.DisableCache()) { var script = Administrator.TotalSynchronizeScript(interactive: false, schemaOnly: true); if (script != null) { string fileName = BackupNetworkFileName(machine, import) + ".sql"; script.Save(fileName); throw new InvalidOperationException("The schema has changed since the last export. A schema sync script has been saved on: {0}".FormatWith(fileName)); } } try { using (token.MeasureTime(l => import.InDB().UnsafeUpdate().Set(s => s.DisableForeignKeys, s => l).Execute())) foreach (var item in uploadTables.Where(u => u.Strategy.DisableForeignKeys.Value)) { DisableForeignKeys(item.Table); } foreach (var tuple in uploadTables) { ImportResult result = null; using (token.MeasureTime(l => { if (result != null) { import.MListElementsLite(_ => _.Copies).Where(mle => mle.Element.Type.RefersTo(tuple.Type.ToTypeEntity())).UnsafeUpdateMList() .Set(mle => mle.Element.CopyTable, mle => l) .Set(mle => mle.Element.DisableForeignKeys, mle => tuple.Strategy.DisableForeignKeys.Value) .Set(mle => mle.Element.InsertedRows, mle => result.Inserted) .Set(mle => mle.Element.UpdatedRows, mle => result.Updated) .Execute(); } })) { result = tuple.Strategy.Importer.Import(machine, tuple.Table, tuple.Strategy, newDatabase); } } using (token.MeasureTime(l => import.InDB().UnsafeUpdate().Set(s => s.Unlock, s => l).Execute())) UnlockTables(machine.ToLite()); } finally { using (token.MeasureTime(l => import.InDB().UnsafeUpdate().Set(s => s.EnableForeignKeys, s => l).Execute())) foreach (var item in uploadTables.Where(u => u.Strategy.DisableForeignKeys.Value)) { EnableForeignKeys(item.Table); } } using (token.MeasureTime(l => import.InDB().UnsafeUpdate().Set(s => s.DropDatabase, s => l).Execute())) DropDatabase(newDatabase); token.ThrowIfCancellationRequested(); import.InDB().UnsafeUpdate() .Set(s => s.State, s => DisconnectedImportState.Completed) .Set(s => s.Total, s => s.CalculateTotal()) .Execute(); machine.InDB().UnsafeUpdate() .Set(m => m.State, m => file == null ? DisconnectedMachineState.Fixed : DisconnectedMachineState.Connected) .Execute(); } catch (Exception e) { var ex = e.LogException(); import.InDB().UnsafeUpdate() .Set(m => m.Exception, m => ex.ToLite()) .Set(m => m.State, m => DisconnectedImportState.Error) .Execute(); machine.InDB().UnsafeUpdate() .Set(m => m.State, m => DisconnectedMachineState.Faulted) .Execute(); OnImportingError(machine, import, e); } finally { runningImports.Remove(import); DisconnectedMachineEntity.Current = null; OnEndImporting(); } } }); runningImports.Add(import, new RunningImports { Task = task, CancelationSource = cancelationSource }); return(import); }