Skip to content

Commit f5cbb8a

Browse files
authored
Merge pull request #762 from PHOENIXCONTACT/remove/dump-restore-model
Removed support of dump and restore of data-models
2 parents 337150e + f698e42 commit f5cbb8a

File tree

20 files changed

+11
-406
lines changed

20 files changed

+11
-406
lines changed

docs/migrations/v8_to_v10.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ With MORYX 10, several changes have been made to the data model to improve perfo
3535

3636
- Naming conventions across the data model have been standardized to ensure consistency and clarity. We use pluralised names for DbSet properties and singular names for entity classes. Sample: `public DbSet<ProductEntity> Products { get; set; }` instead of `public DbSet<ProductEntity> ProductEntities { get; set; }`.
3737
- Derived data models are now fully supported. This needs some changes how the model is defined in code first scenarios. Please refer to the [Data Model Tutorial](/docs/tutorials/data-model/CodeFirst.md) for more information.
38+
- Removed support of Dump and Restore operations in the data model. These operations were rarely used and added unnecessary complexity to the data model management. Use your database admin tools to perform backup and restore operations instead.
3839

3940
### Removal of ProductFileEntity
4041

src/Moryx.CommandCenter.Web/src/databases/api/DatabasesRestClient.ts

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import DatabaseConfigModel from "../models/DatabaseConfigModel";
99
import DatabasesResponse from "../models/DatabasesResponse";
1010
import DataModel from "../models/DataModel";
1111
import ExecuteSetupRequest from "./requests/ExecuteSetupRequest";
12-
import RestoreDatabaseRequest from "./requests/RestoreDatabaseRequest";
1312
import DatabaseUpdateSummary from "./responses/DatabaseUpdateSummary";
1413
import TestConnectionResponse from "./responses/TestConnectionResponse";
1514

@@ -45,14 +44,6 @@ export default class DatabasesRestClient extends RestClientBase {
4544
return this.delete<DatabaseConfigModel, InvocationResponse>(DatabasesRestClient.pathTo(targetModel), request, new InvocationResponse());
4645
}
4746

48-
public dumpDatabase(request: DatabaseConfigModel, targetModel: string): Promise<InvocationResponse> {
49-
return this.post<DatabaseConfigModel, InvocationResponse>(DatabasesRestClient.pathTo(targetModel, "/dump"), request, new InvocationResponse());
50-
}
51-
52-
public restoreDatabase(request: RestoreDatabaseRequest, targetModel: string): Promise<InvocationResponse> {
53-
return this.post<RestoreDatabaseRequest, InvocationResponse>(DatabasesRestClient.pathTo(targetModel, "/restore"), request, new InvocationResponse());
54-
}
55-
5647
public applyMigration(targetModel: string, migrationName: string, request: DatabaseConfigModel): Promise<DatabaseUpdateSummary> {
5748
return this.post<DatabaseConfigModel, DatabaseUpdateSummary>(DatabasesRestClient.pathTo(targetModel, `/migrate`), request, new DatabaseUpdateSummary());
5849
}

src/Moryx.CommandCenter.Web/src/databases/api/requests/RestoreDatabaseRequest.ts

Lines changed: 0 additions & 11 deletions
This file was deleted.

src/Moryx.CommandCenter.Web/src/databases/container/DatabaseModel.tsx

Lines changed: 0 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ interface DatabaseModelStateModel {
4646
activeTab: number;
4747
config: DatabaseConfigModel;
4848
targetModel: string;
49-
selectedBackup: string;
5049
testConnectionPending: boolean;
5150
testConnectionResult: TestConnectionResult;
5251
}
@@ -72,7 +71,6 @@ class DatabaseModel extends React.Component<DatabaseModelPropsModel & DatabaseMo
7271
activeTab: 1,
7372
config: this.getConfigValue(),
7473
targetModel: props.DataModel.targetModel,
75-
selectedBackup : (props.DataModel.backups.length !== 0 ? props.DataModel.backups[0].fileName : ""),
7674
testConnectionPending : false,
7775
testConnectionResult : TestConnectionResult.ConfigurationError,
7876
};
@@ -126,10 +124,6 @@ class DatabaseModel extends React.Component<DatabaseModelPropsModel & DatabaseMo
126124
this.setState({ config });
127125
}
128126

129-
public onSelectBackup(e: React.ChangeEvent<HTMLInputElement>): void {
130-
this.setState({ selectedBackup: e.target.value });
131-
}
132-
133127
private createEntriesInput(): React.JSX.Element[] {
134128
return Object.keys(this.state.config.entries)?.map((element) => {
135129
return (
@@ -240,32 +234,6 @@ class DatabaseModel extends React.Component<DatabaseModelPropsModel & DatabaseMo
240234
}).catch((d) => this.props.onShowWaitDialog(false));
241235
}
242236

243-
public onExecuteDump(): void {
244-
this.props.onShowWaitDialog(true);
245-
246-
this.props.RestClient.dumpDatabase(this.createConfigModel(), this.props.DataModel.targetModel).then((data) => {
247-
this.props.onShowWaitDialog(false);
248-
if (data.success) {
249-
toast.success("Database dump started successfully. Please refer to the log to get information about the progress.", { autoClose: 5000 });
250-
} else {
251-
toast.error("Dump start failed: " + data.errorMessage, { autoClose: 5000 });
252-
}
253-
}).catch((d) => this.props.onShowWaitDialog(false));
254-
}
255-
256-
public onExecuteRestore(): void {
257-
this.props.onShowWaitDialog(true);
258-
259-
this.props.RestClient.restoreDatabase({ Config: this.createConfigModel(), BackupFileName: this.props.DataModel.targetModel }, this.state.targetModel).then((data) => {
260-
this.props.onShowWaitDialog(false);
261-
if (data.success) {
262-
toast.success("Database restore started successfully. Please refer to the log to get information about the progress.", { autoClose: 5000 });
263-
} else {
264-
toast.error("Restore start failed: " + data.errorMessage, { autoClose: 5000 });
265-
}
266-
}).catch((d) => this.props.onShowWaitDialog(false));
267-
}
268-
269237
public onApplyMigration(migration: string): void {
270238
this.props.onShowWaitDialog(true);
271239

@@ -380,40 +348,6 @@ class DatabaseModel extends React.Component<DatabaseModelPropsModel & DatabaseMo
380348
<Button color="primary" variant="outlined" onClick={() => this.onSave()}>Save</Button>
381349
</GridLegacy>
382350
</DatabaseSection>
383-
<DatabaseSection title="Backup &amp; Restore">
384-
<GridLegacy item={true} md={12}>
385-
<Stack>
386-
<TextField
387-
label="Backup"
388-
size="small"
389-
margin="dense"
390-
disabled={this.props.DataModel.backups.length === 0 }
391-
variant="outlined"
392-
select={true}
393-
onChange={(e: React.ChangeEvent<HTMLInputElement>) => this.onSelectBackup(e)}>
394-
{
395-
this.props.DataModel.backups.map((backup, idx) => {
396-
return (<MenuItem key={idx} value={backup.fileName}>{backup.fileName + " (Size: " + kbToString(backup.size * 1024) + ", Created on: " + moment(backup.creationDate).format("YYYY-MM-DD HH:mm:ss") + ")"}</MenuItem>);
397-
})
398-
}
399-
</TextField>
400-
</Stack>
401-
</GridLegacy>
402-
<GridLegacy item={true} md={12}>
403-
<ButtonGroup>
404-
<Button color="primary"
405-
disabled={this.state.testConnectionResult !== TestConnectionResult.Success && this.state.testConnectionResult !== TestConnectionResult.PendingMigrations}
406-
onClick={this.onExecuteDump.bind(this)}>
407-
Create a backup
408-
</Button>
409-
<Button color="primary"
410-
disabled={this.state.selectedBackup === "" || (this.state.testConnectionResult !== TestConnectionResult.Success && this.state.testConnectionResult !== TestConnectionResult.PendingMigrations)}
411-
onClick={this.onExecuteRestore.bind(this)}>
412-
Restore selected backup
413-
</Button>
414-
</ButtonGroup>
415-
</GridLegacy>
416-
</DatabaseSection>
417351
<DatabaseSection title="Database">
418352
<GridLegacy item={true} md={12}>
419353
<ButtonGroup>

src/Moryx.CommandCenter.Web/src/databases/models/BackupModel.ts

Lines changed: 0 additions & 10 deletions
This file was deleted.

src/Moryx.CommandCenter.Web/src/databases/models/DataModel.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
* Copyright (c) 2020, Phoenix Contact GmbH & Co. KG
33
* Licensed under the Apache License, Version 2.0
44
*/
5-
import BackupModel from "./BackupModel";
65
import DatabaseConfigModel from "./DatabaseConfigModel";
76
import DatabaseConfigOptionModel from "./DatabaseConfigOptionModel";
87
import DbMigrationsModel from "./DbMigrationsModel";
@@ -12,7 +11,6 @@ export default class DataModel {
1211
public targetModel: string;
1312
public config: DatabaseConfigModel;
1413
public setups: SetupModel[];
15-
public backups: BackupModel[];
1614
public availableMigrations: DbMigrationsModel[];
1715
public appliedMigrations: DbMigrationsModel[];
1816
public possibleConfigurators: DatabaseConfigOptionModel[];

src/Moryx.Model.PostgreSQL/NpgsqlModelConfigurator.cs

Lines changed: 0 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -54,30 +54,6 @@ public override async Task DeleteDatabase(IDatabaseConfig config)
5454
await connection.CloseAsync();
5555
}
5656

57-
/// <inheritdoc />
58-
public override Task DumpDatabase(IDatabaseConfig config, string targetPath)
59-
{
60-
var connectionString = CreateConnectionStringBuilder(config);
61-
62-
var dumpName = $"{DateTime.Now:dd-MM-yyyy-hh-mm-ss}_{connectionString.Database}.backup";
63-
var fileName = Path.Combine(targetPath, dumpName);
64-
65-
Logger.Log(LogLevel.Debug, "Starting to dump database with pg_dump to: {0}", fileName);
66-
67-
// Create process
68-
var arguments = $"-U {connectionString.Username} --format=c --file={fileName} " +
69-
$"-h {connectionString.Host} -p {connectionString.Port} {connectionString.Database}";
70-
71-
var process = CreateBackgroundPgProcess("pg_dump.exe", arguments, connectionString.Password);
72-
73-
// Configure the process using the StartInfo properties.
74-
process.Start();
75-
process.BeginOutputReadLine();
76-
process.BeginErrorReadLine();
77-
78-
return Task.CompletedTask;
79-
}
80-
8157
private static NpgsqlConnectionStringBuilder CreateConnectionStringBuilder(IDatabaseConfig config, bool includeModel = true)
8258
{
8359
var builder = new NpgsqlConnectionStringBuilder(config.ConnectionSettings.ConnectionString);
@@ -125,26 +101,6 @@ public override Task<TestConnectionResult> TestConnection(IDatabaseConfig config
125101
return base.TestConnection(CreateTestDatabaseConfig(config));
126102
}
127103

128-
/// <inheritdoc />
129-
public override Task RestoreDatabase(IDatabaseConfig config, string filePath)
130-
{
131-
Logger.Log(LogLevel.Debug, "Starting to restore database with pg_restore from: {0}", filePath);
132-
var connectionString = CreateConnectionStringBuilder(config);
133-
134-
// Create process
135-
var arguments = $"-U {connectionString.Username} --format=c --single-transaction --clean " +
136-
$"-h {connectionString.Host} -p {connectionString.Port} -d {connectionString.Database} {filePath}";
137-
138-
var process = CreateBackgroundPgProcess("pg_restore.exe", arguments, connectionString.Password);
139-
140-
// Configure the process using the StartInfo properties.
141-
process.Start();
142-
process.BeginOutputReadLine();
143-
process.BeginErrorReadLine();
144-
145-
return Task.CompletedTask;
146-
}
147-
148104
/// <inheritdoc />
149105
public override DbContextOptions BuildDbContextOptions(IDatabaseConfig config)
150106
{
@@ -162,54 +118,6 @@ private static string BuildConnectionString(IDatabaseConfig config, bool include
162118
return builder.ToString();
163119
}
164120

165-
private Process CreateBackgroundPgProcess(string fileName, string arguments, string pgPassword)
166-
{
167-
var process = new Process { EnableRaisingEvents = true };
168-
process.Exited += OnProcessCompleted;
169-
170-
var startInfo = process.StartInfo;
171-
startInfo.UseShellExecute = false;
172-
startInfo.RedirectStandardOutput = true;
173-
startInfo.RedirectStandardError = true;
174-
process.StartInfo.EnvironmentVariables["PGPASSWORD"] = pgPassword;
175-
176-
startInfo.FileName = fileName;
177-
startInfo.Arguments = arguments;
178-
179-
process.OutputDataReceived += OnProcessOutputDataReceived;
180-
process.ErrorDataReceived += OnProcessOutputDataReceived;
181-
182-
return process;
183-
}
184-
185-
private void OnProcessCompleted(object sender, EventArgs eventArgs)
186-
{
187-
var process = (Process)sender;
188-
process.Exited -= OnProcessCompleted;
189-
190-
process.CancelOutputRead();
191-
process.CancelErrorRead();
192-
process.OutputDataReceived -= OnProcessOutputDataReceived;
193-
process.ErrorDataReceived -= OnProcessOutputDataReceived;
194-
195-
if (process.ExitCode != 0)
196-
{
197-
Logger.Log(LogLevel.Error, "Error while running process {0}, ExitCode: {1}!",
198-
process.Id, process.ExitCode);
199-
}
200-
else
201-
{
202-
Logger.Log(LogLevel.Debug, "Process {0} exited successfully!",
203-
process.Id);
204-
}
205-
}
206-
207-
private void OnProcessOutputDataReceived(object sender, DataReceivedEventArgs args)
208-
{
209-
var process = (Process)sender;
210-
Logger.Log(LogLevel.Debug, "Process: {0}: {1}", process.Id, args.Data);
211-
}
212-
213121
/// <inheritdoc />
214122
protected override DbContext CreateMigrationContext(IDatabaseConfig config)
215123
{

src/Moryx.Model.SqlServer/SqlServerModelConfigurator.cs

Lines changed: 0 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -53,28 +53,6 @@ public override async Task DeleteDatabase(IDatabaseConfig config)
5353
await command.ExecuteNonQueryAsync();
5454
}
5555

56-
/// <inheritdoc />
57-
public override async Task DumpDatabase(IDatabaseConfig config, string targetPath)
58-
{
59-
if (!IsValidBackupFilePath(targetPath))
60-
throw new ArgumentException("Invalid backup file path.");
61-
62-
var connectionString = CreateConnectionStringBuilder(config);
63-
64-
var dumpName = $"{DateTime.Now:dd-MM-yyyy-hh-mm-ss}_{connectionString.InitialCatalog}.bak";
65-
var fileName = Path.Combine(targetPath, dumpName);
66-
67-
await using var connection = new SqlConnection(BuildConnectionString(config, false));
68-
await using var command =
69-
CreateCommand($"BACKUP DATABASE [{connectionString.InitialCatalog}] TO DISK = N'{fileName}' WITH INIT",
70-
connection);
71-
72-
Logger.Log(LogLevel.Debug, "Starting to dump database with 'BACKUP DATABASE' to: {fileName}", fileName);
73-
74-
await connection.OpenAsync();
75-
await command.ExecuteNonQueryAsync();
76-
}
77-
7856
private static SqlConnectionStringBuilder CreateConnectionStringBuilder(IDatabaseConfig config, bool includeModel = true)
7957
{
8058
var builder = new SqlConnectionStringBuilder(config.ConnectionSettings.ConnectionString)
@@ -85,24 +63,6 @@ private static SqlConnectionStringBuilder CreateConnectionStringBuilder(IDatabas
8563
return builder;
8664
}
8765

88-
/// <inheritdoc />
89-
public override async Task RestoreDatabase(IDatabaseConfig config, string filePath)
90-
{
91-
if (!IsValidBackupFilePath(filePath))
92-
throw new ArgumentException("Invalid backup file path.");
93-
94-
var connectionString = CreateConnectionStringBuilder(config);
95-
96-
await using var connection = new SqlConnection(BuildConnectionString(config, false));
97-
await using var command = CreateCommand($"RESTORE DATABASE [{connectionString.InitialCatalog}] FROM DISK = N'{filePath}' WITH REPLACE",
98-
connection);
99-
100-
Logger.Log(LogLevel.Debug, "Starting to restore database with 'RESTORE DATABASE' from: {filePath}", filePath);
101-
102-
await connection.OpenAsync();
103-
await command.ExecuteNonQueryAsync();
104-
}
105-
10666
/// <inheritdoc />
10767
public override DbContextOptions BuildDbContextOptions(IDatabaseConfig config)
10868
{
@@ -145,11 +105,4 @@ private static bool IsValidDatabaseName(string dbName)
145105
// Only allow letters, numbers, and underscores
146106
return Regex.IsMatch(dbName, @"^[A-Za-z0-9_]+$");
147107
}
148-
149-
private static bool IsValidBackupFilePath(string filePath)
150-
{
151-
// Disallow dangerous characters
152-
var invalidStrings = new[] { ";", "'", "\"", "--" };
153-
return invalidStrings.All(s => !filePath.Contains(s));
154-
}
155108
}

src/Moryx.Model.Sqlite/SqliteModelConfigurator.cs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -45,18 +45,6 @@ public override Task DeleteDatabase(IDatabaseConfig config)
4545
return Task.CompletedTask;
4646
}
4747

48-
/// <inheritdoc />
49-
public override Task DumpDatabase(IDatabaseConfig config, string targetPath)
50-
{
51-
throw new NotSupportedException();
52-
}
53-
54-
/// <inheritdoc />
55-
public override Task RestoreDatabase(IDatabaseConfig config, string filePath)
56-
{
57-
throw new NotSupportedException();
58-
}
59-
6048
/// <inheritdoc />
6149
public override DbContextOptions BuildDbContextOptions(IDatabaseConfig config)
6250
{

src/Moryx.Model/Configuration/ModelConfiguratorBase.cs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -230,12 +230,6 @@ public async Task<IReadOnlyList<string>> AppliedMigrations(DbContext context)
230230
/// <inheritdoc />
231231
public abstract Task DeleteDatabase(IDatabaseConfig config);
232232

233-
/// <inheritdoc />
234-
public abstract Task DumpDatabase(IDatabaseConfig config, string targetPath);
235-
236-
/// <inheritdoc />
237-
public abstract Task RestoreDatabase(IDatabaseConfig config, string filePath);
238-
239233
/// <summary>
240234
/// Generally tests the connection to the database
241235
/// </summary>

0 commit comments

Comments
 (0)