• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

HicServices / RDMP / 6658089448

26 Oct 2023 06:10PM UTC coverage: 56.911% (-0.07%) from 56.985%
6658089448

push

github

web-flow
RDMP-15 Use .bak files as Data Loads (#1656)

* basic ui triggers
* working dl

---------

Co-authored-by: James A Sutherland <j@sutherland.pw>

10695 of 20239 branches covered (0.0%)

Branch coverage included in aggregate %.

89 of 89 new or added lines in 6 files covered. (100.0%)

30536 of 52209 relevant lines covered (58.49%)

7341.8 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/Rdmp.Core/DataLoad/Engine/LoadExecution/Components/Runtime/ExecuteSqlBakFileRuntimeTask.cs
1
// Copyright (c) The University of Dundee 2018-2023
2
// This file is part of the Research Data Management Platform (RDMP).
3
// RDMP is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
4
// RDMP is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
5
// You should have received a copy of the GNU General Public License along with RDMP. If not, see <https://www.gnu.org/licenses/>.
6

7
using System;
8
using System.Data;
9
using System.IO;
10
using System.Linq;
11
using Microsoft.Data.SqlClient;
12
using MongoDB.Driver.Core.Servers;
13
using Rdmp.Core.Curation.Data.DataLoad;
14
using Rdmp.Core.DataFlowPipeline;
15
using Rdmp.Core.DataLoad.Engine.Job;
16
using Rdmp.Core.DataLoad.Engine.LoadExecution.Components.Arguments;
17
using Rdmp.Core.DataLoad.Modules.Mutilators;
18
using Rdmp.Core.ReusableLibraryCode.Checks;
19
using Rdmp.Core.ReusableLibraryCode.Progress;
20

21
namespace Rdmp.Core.DataLoad.Engine.LoadExecution.Components.Runtime;
22

23
/// <summary>
24
/// RuntimeTask that executes a single .bak file specified by the user in a ProcessTask with ProcessTaskType SQLBakFile.
25
/// </summary>
26
public class ExecuteSqlBakFileRuntimeTask : RuntimeTask
27
{
28
    public string Filepath;
29
    private readonly IProcessTask _task;
30

31
    private LoadStage _loadStage;
32

33
    public ExecuteSqlBakFileRuntimeTask(IProcessTask task, RuntimeArgumentCollection args) : base(task, args)
×
34
    {
35
        _task = task;
×
36
        Filepath = task.Path;
×
37
    }
×
38

39
    public override ExitCodeType Run(IDataLoadJob job, GracefulCancellationToken cancellationToken)
40
    {
41
        var db = RuntimeArguments.StageSpecificArguments.DbInfo;
×
42
        _loadStage = RuntimeArguments.StageSpecificArguments.LoadStage;
×
43

44
        if (!Exists())
×
45
            throw new Exception($"The sql bak file {Filepath} does not exist");
×
46

47
        string fileOnlyCommand = $"RESTORE FILELISTONLY FROM DISK = '{Filepath}'";
×
48
        using var fileInfo = new DataTable();
×
49
        using var con = (SqlConnection)db.Server.GetConnection();
×
50
        using (var cmd = new SqlCommand(fileOnlyCommand, con))
×
51
          using (var da = new SqlDataAdapter(cmd))
×
52
            da.Fill(fileInfo);
×
53
        DataRow[] primaryFiles = fileInfo.Select("Type = 'D'");
×
54
        DataRow[] logFiles = fileInfo.Select("Type = 'L'");
×
55
        if (primaryFiles.Length != 1 || logFiles.Length != 1)
×
56
        {
57
            //Something has gone wrong
58
            return ExitCodeType.Error;
×
59
        }
60

61

62
        DataRow primaryFile = primaryFiles[0];
×
63
        DataRow logFile = logFiles[0];
×
64
        string primaryFilePhysicalName = primaryFile["PhysicalName"].ToString();
×
65
        string logFilePhysicalName = logFile["PhysicalName"].ToString();
×
66

67
        if (File.Exists(primaryFilePhysicalName) || File.Exists(logFilePhysicalName))
×
68
        {
69
            string timestamp = DateTime.Now.Millisecond.ToString();
×
70
            string primaryFileName = primaryFilePhysicalName.Substring(0, primaryFilePhysicalName.Length - 4);
×
71
            string primaryFileExtention = primaryFilePhysicalName.Substring(primaryFilePhysicalName.Length - 4);
×
72
            primaryFilePhysicalName = $"{primaryFileName}_{timestamp}{primaryFileExtention}";
×
73
            string logFileName = logFilePhysicalName.Substring(0, logFilePhysicalName.Length - 4);
×
74
            string logFileExtention = logFilePhysicalName.Substring(logFilePhysicalName.Length - 4);
×
75
            logFilePhysicalName = $"{logFileName}_{timestamp}{logFileExtention}";
×
76
        }
77

78
        string name = db.ToString();
×
79

80
        string restoreCommand = @$"
×
81
        use master;
×
82
        ALTER DATABASE {name} SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
×
83
        RESTORE DATABASE {name}
×
84
        FROM DISK = '{Filepath}'
×
85
        WITH MOVE '{primaryFile["LogicalName"]}' TO '{primaryFilePhysicalName}',
×
86
        MOVE '{logFile["LogicalName"]}' TO '{logFilePhysicalName}' ,  NOUNLOAD,  REPLACE,  STATS = 5;
×
87
        ALTER DATABASE {name} SET MULTI_USER;
×
88
        ";
×
89

90
        job.OnNotify(this, new NotifyEventArgs(ProgressEventType.Information,
×
91
            $"Executing script {Filepath} ( against {db})"));
×
92

93
        var executer = new ExecuteSqlInDleStage(job, _loadStage);
×
94
        return executer.Execute(restoreCommand, db);
×
95
    }
×
96

97

98
    public override bool Exists() => File.Exists(Filepath);
×
99

100
    public override void Abort(IDataLoadEventListener postLoadEventListener)
101
    {
102
    }
×
103

104
    public override void LoadCompletedSoDispose(ExitCodeType exitCode, IDataLoadEventListener postLoadEventListener)
105
    {
106
    }
×
107

108
    public override void Check(ICheckNotifier notifier)
109
    {
110
        if (string.IsNullOrWhiteSpace(Filepath))
×
111
        {
112
            notifier.OnCheckPerformed(
×
113
                new CheckEventArgs($"ExecuteSqlFileTask {_task} does not have a path specified",
×
114
                    CheckResult.Fail));
×
115
            return;
×
116
        }
117

118
        if (!File.Exists(Filepath))
×
119
            notifier.OnCheckPerformed(
×
120
                new CheckEventArgs(
×
121
                    $"File '{Filepath}' does not exist! (the only time this would be legal is if you have an exe or a freaky plugin that creates this file)",
×
122
                    CheckResult.Warning));
×
123
        else
124
            notifier.OnCheckPerformed(new CheckEventArgs($"Found File '{Filepath}'",
×
125
                CheckResult.Success));
×
126
    }
×
127
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc