Skip to content

Commit 2d6f258

Browse files
committed
Fixup support in Services API (#886)
1 parent 4c46be6 commit 2d6f258

File tree

3 files changed

+133
-22
lines changed

3 files changed

+133
-22
lines changed

src/FirebirdSql.Data.FirebirdClient.Tests/FbServicesTests.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,40 @@ public async Task Validation2Test()
393393
await validationSvc.ExecuteAsync();
394394
}
395395

396+
[Test]
397+
public async Task NFixupTest()
398+
{
399+
if (!EnsureServerVersion(new Version(4, 0, 0, 0)))
400+
return;
401+
402+
var deltaFile = Path.GetTempFileName();
403+
Connection.Open();
404+
try
405+
{
406+
await using (var cmd = Connection.CreateCommand())
407+
{
408+
cmd.CommandText = $"alter database add difference file '{deltaFile}'";
409+
await cmd.ExecuteNonQueryAsync();
410+
cmd.CommandText = "alter database begin backup";
411+
await cmd.ExecuteNonQueryAsync();
412+
}
413+
}
414+
finally
415+
{
416+
Connection.Close();
417+
}
418+
File.Delete(deltaFile);
419+
420+
Assert.ThrowsAsync<FbException>(() => Connection.OpenAsync());
421+
422+
var fixup = new FbNFixup();
423+
fixup.ConnectionString = BuildServicesConnectionString(ServerType, Compression, WireCrypt, true);
424+
fixup.ServiceOutput += ServiceOutput;
425+
await fixup.ExecuteAsync();
426+
427+
Assert.DoesNotThrowAsync(() => Connection.OpenAsync());
428+
}
429+
396430
static void ServiceOutput(object sender, ServiceOutputEventArgs e)
397431
{
398432
var dummy = e.Message;

src/FirebirdSql.Data.FirebirdClient/Common/IscCodes.cs

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -397,30 +397,31 @@ internal static class IscCodes
397397

398398
#region Services Actions
399399

400-
public const int isc_action_svc_backup = 1; /* Starts database backup process on the server */
401-
public const int isc_action_svc_restore = 2; /* Starts database restore process on the server */
402-
public const int isc_action_svc_repair = 3; /* Starts database repair process on the server */
403-
public const int isc_action_svc_add_user = 4; /* Adds a new user to the security database */
404-
public const int isc_action_svc_delete_user = 5; /* Deletes a user record from the security database */
405-
public const int isc_action_svc_modify_user = 6; /* Modifies a user record in the security database */
406-
public const int isc_action_svc_display_user = 7; /* Displays a user record from the security database */
407-
public const int isc_action_svc_properties = 8; /* Sets database properties */
408-
public const int isc_action_svc_add_license = 9; /* Adds a license to the license file */
409-
public const int isc_action_svc_remove_license = 10; /* Removes a license from the license file */
410-
public const int isc_action_svc_db_stats = 11; /* Retrieves database statistics */
411-
public const int isc_action_svc_get_ib_log = 12; /* Retrieves the InterBase log file from the server */
412-
public const int isc_action_svc_get_fb_log = 12; /* Retrieves the Firebird log file from the server */
413-
public const int isc_action_svc_nbak = 20; /* Incremental nbackup */
400+
public const int isc_action_svc_backup = 1; /* Starts database backup process on the server */
401+
public const int isc_action_svc_restore = 2; /* Starts database restore process on the server */
402+
public const int isc_action_svc_repair = 3; /* Starts database repair process on the server */
403+
public const int isc_action_svc_add_user = 4; /* Adds a new user to the security database */
404+
public const int isc_action_svc_delete_user = 5; /* Deletes a user record from the security database */
405+
public const int isc_action_svc_modify_user = 6; /* Modifies a user record in the security database */
406+
public const int isc_action_svc_display_user = 7; /* Displays a user record from the security database */
407+
public const int isc_action_svc_properties = 8; /* Sets database properties */
408+
public const int isc_action_svc_add_license = 9; /* Adds a license to the license file */
409+
public const int isc_action_svc_remove_license = 10; /* Removes a license from the license file */
410+
public const int isc_action_svc_db_stats = 11; /* Retrieves database statistics */
411+
public const int isc_action_svc_get_ib_log = 12; /* Retrieves the InterBase log file from the server */
412+
public const int isc_action_svc_get_fb_log = 12; /* Retrieves the Firebird log file from the server */
413+
public const int isc_action_svc_nbak = 20; /* Incremental nbackup */
414414
public const int isc_action_svc_nrest = 21; /* Incremental database restore */
415-
public const int isc_action_svc_trace_start = 22; // Start trace session
416-
public const int isc_action_svc_trace_stop = 23; // Stop trace session
415+
public const int isc_action_svc_trace_start = 22; // Start trace session
416+
public const int isc_action_svc_trace_stop = 23; // Stop trace session
417417
public const int isc_action_svc_trace_suspend = 24; // Suspend trace session
418-
public const int isc_action_svc_trace_resume = 25; // Resume trace session
419-
public const int isc_action_svc_trace_list = 26; // List existing sessions
420-
public const int isc_action_svc_set_mapping = 27; // Set auto admins mapping in security database
421-
public const int isc_action_svc_drop_mapping = 28; // Drop auto admins mapping in security database
422-
public const int isc_action_svc_display_user_adm = 29; // Displays user(s) from security database with admin info
423-
public const int isc_action_svc_validate = 30; // Starts database online validation
418+
public const int isc_action_svc_trace_resume = 25; // Resume trace session
419+
public const int isc_action_svc_trace_list = 26; // List existing sessions
420+
public const int isc_action_svc_set_mapping = 27; // Set auto admins mapping in security database
421+
public const int isc_action_svc_drop_mapping = 28; // Drop auto admins mapping in security database
422+
public const int isc_action_svc_display_user_adm = 29; // Displays user(s) from security database with admin info
423+
public const int isc_action_svc_validate = 30; // Starts database online validation
424+
public const int isc_action_svc_nfix = 31; // Fixup database after file system copy
424425

425426
#endregion
426427

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*
2+
* The contents of this file are subject to the Initial
3+
* Developer's Public License Version 1.0 (the "License");
4+
* you may not use this file except in compliance with the
5+
* License. You may obtain a copy of the License at
6+
* https://github.com/FirebirdSQL/NETProvider/raw/master/license.txt.
7+
*
8+
* Software distributed under the License is distributed on
9+
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
10+
* express or implied. See the License for the specific
11+
* language governing rights and limitations under the License.
12+
*
13+
* All Rights Reserved.
14+
*/
15+
16+
//$Authors = Jiri Cincura (jiri@cincura.net)
17+
18+
using System;
19+
using System.Threading;
20+
using System.Threading.Tasks;
21+
using FirebirdSql.Data.Common;
22+
using FirebirdSql.Data.FirebirdClient;
23+
24+
namespace FirebirdSql.Data.Services;
25+
26+
public sealed class FbNFixup : FbService
27+
{
28+
public FbNFixup(string connectionString = null)
29+
: base(connectionString)
30+
{ }
31+
32+
public void Execute()
33+
{
34+
EnsureDatabase();
35+
36+
try
37+
{
38+
Open();
39+
var startSpb = new ServiceParameterBuffer2(Service.ParameterBufferEncoding);
40+
startSpb.Append(IscCodes.isc_action_svc_nfix);
41+
startSpb.Append2(IscCodes.isc_spb_dbname, Database);
42+
StartTask(startSpb);
43+
ProcessServiceOutput(new ServiceParameterBuffer2(Service.ParameterBufferEncoding));
44+
}
45+
catch (Exception ex)
46+
{
47+
throw FbException.Create(ex);
48+
}
49+
finally
50+
{
51+
Close();
52+
}
53+
}
54+
public async Task ExecuteAsync(CancellationToken cancellationToken = default)
55+
{
56+
EnsureDatabase();
57+
58+
try
59+
{
60+
await OpenAsync(cancellationToken).ConfigureAwait(false);
61+
var startSpb = new ServiceParameterBuffer2(Service.ParameterBufferEncoding);
62+
startSpb.Append(IscCodes.isc_action_svc_nfix);
63+
startSpb.Append2(IscCodes.isc_spb_dbname, Database);
64+
await StartTaskAsync(startSpb, cancellationToken).ConfigureAwait(false);
65+
await ProcessServiceOutputAsync(new ServiceParameterBuffer2(Service.ParameterBufferEncoding), cancellationToken).ConfigureAwait(false);
66+
}
67+
catch (Exception ex)
68+
{
69+
throw FbException.Create(ex);
70+
}
71+
finally
72+
{
73+
await CloseAsync(cancellationToken).ConfigureAwait(false);
74+
}
75+
}
76+
}

0 commit comments

Comments
 (0)