Hello, all.
Ok, I ask Dmitry Starodubov to create a patch for FB3.0 and publish it
for review.
Nikolay
Patch against FB HEAD in attach.
Dmitry
Index: lang_helpers/gds_codes.ftn
===================================================================
--- lang_helpers/gds_codes.ftn (revision 58043)
+++ lang_helpers/gds_codes.ftn (working copy)
@@ -2392,6 +2392,8 @@
PARAMETER (GDS__nbackup_switchd_parameter = 337117255)
INTEGER*4 GDS__nbackup_user_stop
PARAMETER (GDS__nbackup_user_stop = 337117257)
+ INTEGER*4 GDS__nbackup_lostrec_guid_db
+ PARAMETER (GDS__nbackup_lostrec_guid_db = 337117258)
INTEGER*4 GDS__trace_conflict_acts
PARAMETER (GDS__trace_conflict_acts = 337182750)
INTEGER*4 GDS__trace_act_notfound
Index: lang_helpers/gds_codes.pas
===================================================================
--- lang_helpers/gds_codes.pas (revision 58043)
+++ lang_helpers/gds_codes.pas (working copy)
@@ -1203,6 +1203,7 @@
gds_nbackup_lostguid_l0bk = 337117251;
gds_nbackup_switchd_parameter = 337117255;
gds_nbackup_user_stop = 337117257;
+ gds_nbackup_lostrec_guid_db = 337117258;
gds_trace_conflict_acts = 337182750;
gds_trace_act_notfound = 337182751;
gds_trace_switch_once = 337182752;
Index: src/common/classes/ClumpletReader.cpp
===================================================================
--- src/common/classes/ClumpletReader.cpp (revision 58043)
+++ src/common/classes/ClumpletReader.cpp (working copy)
@@ -432,6 +432,7 @@
case isc_spb_nbk_file:
case isc_spb_nbk_direct:
case isc_spb_dbname:
+ case isc_spb_nbk_guid:
return StringSpb;
case isc_spb_nbk_level:
case isc_spb_options:
Index: src/include/consts_pub.h
===================================================================
--- src/include/consts_pub.h (revision 58043)
+++ src/include/consts_pub.h (working copy)
@@ -530,7 +530,9 @@
#define isc_spb_nbk_level 5
#define isc_spb_nbk_file 6
#define isc_spb_nbk_direct 7
+#define isc_spb_nbk_guid 8
#define isc_spb_nbk_no_triggers 0x01
+#define isc_spb_nbk_inplace 0x02
/***************************************
* Parameters for isc_action_svc_trace *
Index: src/include/gen/codetext.h
===================================================================
--- src/include/gen/codetext.h (revision 58043)
+++ src/include/gen/codetext.h (working copy)
@@ -1192,6 +1192,7 @@
{"nbackup_lostguid_l0bk", 337117251},
{"nbackup_switchd_parameter", 337117255},
{"nbackup_user_stop", 337117257},
+ {"nbackup_lostrec_guid_db", 337117258},
{"trace_conflict_acts", 337182750},
{"trace_act_notfound", 337182751},
{"trace_switch_once", 337182752},
Index: src/include/gen/iberror.h
===================================================================
--- src/include/gen/iberror.h (revision 58043)
+++ src/include/gen/iberror.h (working copy)
@@ -1226,6 +1226,7 @@
const ISC_STATUS isc_nbackup_lostguid_l0bk = 337117251L;
const ISC_STATUS isc_nbackup_switchd_parameter = 337117255L;
const ISC_STATUS isc_nbackup_user_stop = 337117257L;
+const ISC_STATUS isc_nbackup_lostrec_guid_db = 337117258L;
const ISC_STATUS isc_trace_conflict_acts = 337182750L;
const ISC_STATUS isc_trace_act_notfound = 337182751L;
const ISC_STATUS isc_trace_switch_once = 337182752L;
@@ -1237,7 +1238,7 @@
const ISC_STATUS isc_trace_switch_param_miss = 337182758L;
const ISC_STATUS isc_trace_param_act_notcompat = 337182759L;
const ISC_STATUS isc_trace_mandatory_switch_miss = 337182760L;
-const ISC_STATUS isc_err_max = 1181;
+const ISC_STATUS isc_err_max = 1182;
#else /* c definitions */
@@ -2433,6 +2434,7 @@
#define isc_nbackup_lostguid_l0bk 337117251L
#define isc_nbackup_switchd_parameter 337117255L
#define isc_nbackup_user_stop 337117257L
+#define isc_nbackup_lostrec_guid_db 337117258L
#define isc_trace_conflict_acts 337182750L
#define isc_trace_act_notfound 337182751L
#define isc_trace_switch_once 337182752L
@@ -2444,7 +2446,7 @@
#define isc_trace_switch_param_miss 337182758L
#define isc_trace_param_act_notcompat 337182759L
#define isc_trace_mandatory_switch_miss 337182760L
-#define isc_err_max 1181
+#define isc_err_max 1182
#endif
Index: src/include/gen/msgs.h
===================================================================
--- src/include/gen/msgs.h (revision 58043)
+++ src/include/gen/msgs.h (working copy)
@@ -1195,6 +1195,7 @@
{337117251, "Cannot get backup guid clumplet from L0 backup"},
/* nbackup_lostguid_l0bk */
{337117255, "Wrong parameter @1 for switch -D, need ON or OFF"},
/* nbackup_switchd_parameter */
{337117257, "Terminated due to user request"}, /*
nbackup_user_stop */
+ {337117258, "Cannot find record for database \"@1\" backup GUID @2 in
the backup history"}, /* nbackup_lostrec_guid_db */
{337182750, "conflicting actions \"@1\" and \"@2\" found"},
/* trace_conflict_acts */
{337182751, "action switch not found"}, /* trace_act_notfound */
{337182752, "switch \"@1\" must be set only once"}, /*
trace_switch_once */
Index: src/include/gen/sql_code.h
===================================================================
--- src/include/gen/sql_code.h (revision 58043)
+++ src/include/gen/sql_code.h (working copy)
@@ -1191,6 +1191,7 @@
{337117251, -901}, /* 67 nbackup_lostguid_l0bk */
{337117255, -901}, /* 71 nbackup_switchd_parameter */
{337117257, -901}, /* 73 nbackup_user_stop */
+ {337117258, -901}, /* 74 nbackup_lostrec_guid_db */
{337182750, -901}, /* 30 trace_conflict_acts */
{337182751, -901}, /* 31 trace_act_notfound */
{337182752, -901}, /* 32 trace_switch_once */
Index: src/include/gen/sql_state.h
===================================================================
--- src/include/gen/sql_state.h (revision 58043)
+++ src/include/gen/sql_state.h (working copy)
@@ -1191,6 +1191,7 @@
{337117251, "00000"}, // 67 nbackup_lostguid_l0bk
{337117255, "00000"}, // 71 nbackup_switchd_parameter
{337117257, "08006"}, // 73 nbackup_user_stop
+ {337117258, "00000"}, // 74 nbackup_lostrec_guid_db
{337182750, "00000"}, // 30 trace_conflict_acts
{337182751, "00000"}, // 31 trace_act_notfound
{337182752, "00000"}, // 32 trace_switch_once
Index: src/jrd/svc.cpp
===================================================================
--- src/jrd/svc.cpp (revision 58043)
+++ src/jrd/svc.cpp (working copy)
@@ -2571,6 +2571,7 @@
string nbk_database, nbk_file;
int nbk_level = -1;
+ string nbk_guid;
bool found = false;
@@ -2593,13 +2594,23 @@
break;
case isc_spb_nbk_level:
- if (nbk_level >= 0)
+ if (nbk_level >= 0 || nbk_guid.hasData())
{
- (Arg::Gds(isc_unexp_spb_form) <<
Arg::Str("only one isc_spb_nbk_level")).raise();
+ (Arg::Gds(isc_unexp_spb_form) <<
+ Arg::Str("only one
isc_spb_nbk_level or isc_spb_nbk_guid")).raise();
}
nbk_level = spb.getInt();
break;
+ case isc_spb_nbk_guid:
+ if (nbk_level >= 0 || nbk_guid.hasData())
+ {
+ (Arg::Gds(isc_unexp_spb_form) <<
+ Arg::Str("only one
isc_spb_nbk_level or isc_spb_nbk_guid")).raise();
+ }
+ get_action_svc_string(spb, nbk_guid);
+ break;
+
case isc_spb_nbk_file:
if (nbk_file.hasData() && svc_action !=
isc_action_svc_nrest)
{
@@ -2987,13 +2998,19 @@
}
if (svc_action == isc_action_svc_nbak)
{
- if (nbk_level < 0)
+ if (nbk_level < 0 && nbk_guid.isEmpty())
{
- (Arg::Gds(isc_missing_required_spb) <<
Arg::Str("isc_spb_nbk_level")).raise();
+ (Arg::Gds(isc_missing_required_spb) <<
+ Arg::Str("isc_spb_nbk_level or
isc_spb_nbk_guid")).raise();
}
- string temp;
- temp.printf("%d ", nbk_level);
- switches += temp;
+ if (nbk_level >= 0)
+ {
+ string temp;
+ temp.printf("%d ", nbk_level);
+ switches += temp;
+ }
+ else
+ switches += nbk_guid;
}
switches += nbk_database;
switches += nbk_file;
Index: src/msgs/facilities2.sql
===================================================================
--- src/msgs/facilities2.sql (revision 58043)
+++ src/msgs/facilities2.sql (working copy)
@@ -18,7 +18,7 @@
('2012-05-25 19:59:42', 'GSTAT', 21, 56)
('2009-12-18 19:33:34', 'FBSVCMGR', 22, 57)
('2009-07-18 12:12:12', 'UTL', 23, 2)
-('2011-05-25 16:17:34', 'NBACKUP', 24, 74)
+('2011-05-25 16:17:34', 'NBACKUP', 24, 77)
('2009-07-20 07:55:48', 'FBTRACEMGR', 25, 41)
stop
Index: src/msgs/messages2.sql
===================================================================
--- src/msgs/messages2.sql (revision 58043)
+++ src/msgs/messages2.sql (working copy)
@@ -3153,7 +3153,7 @@
(NULL, 'usage', 'nbackup.cpp', NULL, 24, 8, NULL, ' -L(OCK) <database>
Lock database for filesystem copy', NULL, NULL)
(NULL, 'usage', 'nbackup.cpp', NULL, 24, 9, NULL, ' -UN(LOCK) <database>
Unlock previously locked database', NULL, NULL)
(NULL, 'usage', 'nbackup.cpp', NULL, 24, 10, NULL, ' -F(IXUP) <database>
Fixup database after filesystem copy', NULL, NULL)
-(NULL, 'usage', 'nbackup.cpp', NULL, 24, 11, NULL, ' -B(ACKUP) <level> <db>
[<file>] Create incremental backup', NULL, NULL)
+(NULL, 'usage', 'nbackup.cpp', NULL, 24, 11, NULL, ' -B(ACKUP) <level>|<GUID>
<db> [<file>] Create incremental backup', NULL, NULL)
(NULL, 'usage', 'nbackup.cpp', NULL, 24, 12, NULL, ' -R(ESTORE) <db> [<file0>
[<file1>...]] Restore incremental backup', NULL, NULL)
(NULL, 'usage', 'nbackup.cpp', NULL, 24, 13, NULL, ' -U(SER) <user>
User name', NULL, NULL)
(NULL, 'usage', 'nbackup.cpp', NULL, 24, 14, NULL, ' -P(ASSWORD) <password>
Password', NULL, NULL)
@@ -3216,6 +3216,9 @@
('nbackup_switchd_parameter', 'main', 'nbackup.cpp', NULL, 24, 71, NULL,
'Wrong parameter @1 for switch -D, need ON or OFF', NULL, NULL)
(NULL, 'usage', 'nbackup.cpp', NULL, 24, 72, NULL, 'special options are:',
NULL, NULL)
('nbackup_user_stop', 'checkCtrlC()', 'nbackup.cpp', NULL, 24, 73, NULL,
'Terminated due to user request', NULL, NULL)
+('nbackup_lostrec_guid_db', 'NBackup::backup_database', 'nbackup.cpp', NULL,
24, 74, NULL, 'Cannot find record for database "@1" backup GUID @2 in the
backup history', NULL, NULL)
+(NULL, 'usage', 'nbackup.cpp', NULL, 24, 75, NULL, ' -I
Restore incremental backup(s) to existing database', NULL, NULL)
+(NULL, 'usage', 'nbackup.cpp', NULL, 24, 76, NULL, ' -I option could corrupt
the database that has changed since previous restore', NULL, NULL)
-- FBTRACEMGR
-- All messages use the new format.
(NULL, 'usage', 'TraceCmdLine.cpp', NULL, 25, 1, NULL, 'Firebird Trace Manager
version @1', NULL, NULL)
Index: src/msgs/system_errors2.sql
===================================================================
--- src/msgs/system_errors2.sql (revision 58043)
+++ src/msgs/system_errors2.sql (working copy)
@@ -1190,6 +1190,7 @@
(-901, '00', '000', 24, 67, 'nbackup_lostguid_l0bk', NULL, NULL)
(-901, '00', '000', 24, 71, 'nbackup_switchd_parameter', NULL, NULL)
(-901, '08', '006', 24, 73, 'nbackup_user_stop', NULL, NULL)
+(-901, '00', '000', 24, 74, 'nbackup_lostrec_guid_db', NULL, NULL)
-- FBTRACEMGR
(-901, '00', '000', 25, 30, 'trace_conflict_acts', NULL, NULL)
(-901, '00', '000', 25, 31, 'trace_act_notfound', NULL, NULL)
Index: src/utilities/fbsvcmgr/fbsvcmgr.cpp
===================================================================
--- src/utilities/fbsvcmgr/fbsvcmgr.cpp (revision 58043)
+++ src/utilities/fbsvcmgr/fbsvcmgr.cpp (working copy)
@@ -456,6 +456,7 @@
{"dbname", putStringArgument, 0, isc_spb_dbname, 0},
{"nbk_file", putStringArgument, 0, isc_spb_nbk_file, 0},
{"nbk_level", putNumericArgument, 0, isc_spb_nbk_level, 0},
+ {"nbk_guid", putStringArgument, 0, isc_spb_nbk_guid, 0},
{"nbk_no_triggers", putOption, 0, isc_spb_nbk_no_triggers, 0},
{"nbk_direct", putStringArgument, 0, isc_spb_nbk_direct, 0},
{0, 0, 0, 0, 0}
@@ -465,6 +466,7 @@
{
{"dbname", putStringArgument, 0, isc_spb_dbname, 0},
{"nbk_file", putStringArgument, 0, isc_spb_nbk_file, 0},
+ {"nbk_inplace", putOption, 0, isc_spb_nbk_inplace, 0},
{0, 0, 0, 0, 0}
};
Index: src/utilities/nbackup/nbackup.cpp
===================================================================
--- src/utilities/nbackup/nbackup.cpp (revision 58043)
+++ src/utilities/nbackup/nbackup.cpp (working copy)
@@ -135,7 +135,7 @@
}
const int mainUsage[] = { 2, 3, 4, 5, 6, 0 };
- const int notes[] = { 19, 20, 21, 22, 26, 27, 28, 0 };
+ const int notes[] = { 19, 20, 21, 22, 26, 27, 28, 76, 0 };
const Switches::in_sw_tab_t* const base =
nbackup_action_in_sw_table;
for (int i = 0; mainUsage[i]; ++i)
@@ -293,11 +293,11 @@
typedef ObjectsArray<PathName> BackupFiles;
// External calls must clean up resources after themselves
- void fixup_database();
+ void fixup_database(bool set_readonly = false);
void lock_database(bool get_size);
void unlock_database();
- void backup_database(int level, const PathName& fname);
- void restore_database(const BackupFiles& files);
+ void backup_database(int level, Guid& guid, const PathName& fname);
+ void restore_database(const BackupFiles& files, bool inc_rest = false);
bool printed()
{
@@ -337,7 +337,7 @@
void detach_database();
// Create/open database and backup
- void open_database_write();
+ void open_database_write(bool exclusive = false);
void open_database_scan();
void create_database();
void close_database();
@@ -407,16 +407,19 @@
Arg::OsError());
}
-void NBackup::open_database_write()
+void NBackup::open_database_write(bool exclusive)
{
#ifdef WIN_NT
+ const DWORD shareFlags = exclusive ? FILE_SHARE_READ :
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
dbase = CreateFile(dbname.c_str(), GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ shareFlags, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
NULL);
if (dbase != INVALID_HANDLE_VALUE)
return;
#else
- dbase = open(dbname.c_str(), O_RDWR | O_LARGEFILE);
+ const int flags = exclusive ? O_EXCL | O_RDWR | O_LARGEFILE :
+ O_RDWR | O_LARGEFILE;
+ dbase = open(dbname.c_str(), flags);
if (dbase >= 0)
return;
#endif
@@ -570,7 +573,7 @@
#endif
}
-void NBackup::fixup_database()
+void NBackup::fixup_database(bool set_readonly)
{
open_database_write();
Ods::header_page header;
@@ -584,6 +587,8 @@
Arg::Num(Jrd::nbak_state_stalled));
}
header.hdr_flags = (header.hdr_flags & ~Ods::hdr_backup_mask) |
Jrd::nbak_state_normal;
+ if (set_readonly)
+ header.hdr_flags |= Ods::hdr_read_only;
seek_file(dbase, 0);
write_file(dbase, &header, sizeof(header));
close_database();
@@ -771,13 +776,14 @@
detach_database();
}
-void NBackup::backup_database(int level, const PathName& fname)
+void NBackup::backup_database(int level, Guid& guid, const PathName& fname)
{
bool database_locked = false;
// We set this flag when backup file is in inconsistent state
bool delete_backup = false;
ULONG prev_scn = 0;
char prev_guid[GUID_BUFF_SIZE] = "";
+ char str_guid[GUID_BUFF_SIZE] = "";
Ods::pag* page_buff = NULL;
attach_database();
ULONG page_writes = 0, page_reads = 0;
@@ -804,6 +810,9 @@
// Look for SCN and GUID of previous-level backup in history
table
if (level)
{
+ if (level < 0)
+ GuidToString(str_guid, &guid);
+
if (isc_start_transaction(status, &trans, 1, &newdb, 0,
NULL))
pr_error(status, "start transaction");
char out_sqlda_data[XSQLDA_LENGTH(2)];
@@ -815,10 +824,18 @@
if (isc_dsql_allocate_statement(status, &newdb, &stmt))
pr_error(status, "allocate statement");
char str[200];
- sprintf(str, "select rdb$guid, rdb$scn from
rdb$backup_history "
- "where rdb$backup_id = "
- "(select max(rdb$backup_id) from
rdb$backup_history "
- "where rdb$backup_level = %d)", level - 1);
+ if (level > 0)
+ {
+ sprintf(str, "select rdb$guid, rdb$scn from
rdb$backup_history "
+ "where rdb$backup_id = "
+ "(select max(rdb$backup_id) from
rdb$backup_history "
+ "where rdb$backup_level = %d)",
level - 1);
+ }
+ else
+ {
+ sprintf(str, "select first 1 rdb$guid, rdb$scn
from rdb$backup_history "
+ "where rdb$guid = '%s'", str_guid);
+ }
if (isc_dsql_prepare(status, &trans, &stmt, 0, str, 1,
NULL))
pr_error(status, "prepare history query");
if (isc_dsql_describe(status, &stmt, 1, out_sqlda))
@@ -834,8 +851,12 @@
switch (isc_dsql_fetch(status, &stmt, 1, out_sqlda))
{
case 100: // No more records available
-
status_exception::raise(Arg::Gds(isc_nbackup_lostrec_db) << database.c_str() <<
-
Arg::Num(level - 1));
+ if (level > 0)
+
status_exception::raise(Arg::Gds(isc_nbackup_lostrec_db) << database.c_str() <<
+
Arg::Num(level - 1));
+ else
+
status_exception::raise(Arg::Gds(isc_nbackup_lostrec_guid_db) <<
database.c_str() <<
+
Arg::Str(str_guid));
case 0:
if (guid_null || scn_null)
status_exception::raise(Arg::Gds(isc_nbackup_lostguid_db));
@@ -862,9 +883,18 @@
// Let's generate nice new filename
PathName begin, fil;
PathUtils::splitLastComponent(begin, fil, database);
- bakname.printf("%s-%d-%04d%02d%02d-%02d%02d.nbk",
fil.c_str(), level,
- today.tm_year + 1900, today.tm_mon + 1,
today.tm_mday,
- today.tm_hour, today.tm_min);
+ if (level >= 0)
+ {
+
bakname.printf("%s-%d-%04d%02d%02d-%02d%02d.nbk", fil.c_str(), level,
+ today.tm_year + 1900, today.tm_mon + 1,
today.tm_mday,
+ today.tm_hour, today.tm_min);
+ }
+ else
+ {
+
bakname.printf("%s-%s-%04d%02d%02d-%02d%02d.nbk", fil.c_str(), str_guid,
+ today.tm_year + 1900, today.tm_mon + 1,
today.tm_mday,
+ today.tm_hour, today.tm_min);
+ }
if (!uSvc->isService())
printf("%s", bakname.c_str()); // Print out
generated filename for script processing
}
@@ -953,7 +983,7 @@
inc_header bh;
memcpy(bh.signature, backup_signature,
sizeof(backup_signature));
bh.version = 1;
- bh.level = level;
+ bh.level = level > 0 ? level : 0;
bh.backup_guid = backup_guid;
StringToGuid(&bh.prev_guid, prev_guid);
bh.page_size = header->hdr_page_size;
@@ -1110,8 +1140,17 @@
if (isc_dsql_describe_bind(status, &stmt, 1, in_sqlda))
pr_error(status, "bind history insert");
short null_flag = 0;
- in_sqlda->sqlvar[0].sqldata = (char*) &level;
- in_sqlda->sqlvar[0].sqlind = &null_flag;
+ if (level >= 0)
+ {
+ in_sqlda->sqlvar[0].sqldata = (char*) &level;
+ in_sqlda->sqlvar[0].sqlind = &null_flag;
+ }
+ else
+ {
+ short null_ind = -1;
+ in_sqlda->sqlvar[0].sqldata = NULL;
+ in_sqlda->sqlvar[0].sqlind = &null_ind;
+ }
char temp[GUID_BUFF_SIZE];
GuidToString(temp, &backup_guid);
in_sqlda->sqlvar[1].sqldata = temp;
@@ -1170,14 +1209,17 @@
elapsed, page_reads, page_writes);
}
-void NBackup::restore_database(const BackupFiles& files)
+void NBackup::restore_database(const BackupFiles& files, bool inc_rest)
{
// We set this flag when database file is in inconsistent state
bool delete_database = false;
const int filecount = files.getCount();
#ifndef WIN_NT
- create_database();
- delete_database = true;
+ if (!inc_rest)
+ {
+ create_database();
+ delete_database = true;
+ }
#endif
UCHAR *page_buffer = NULL;
try {
@@ -1232,16 +1274,19 @@
}
else
{
- if (curLevel >= filecount)
+ if (curLevel >= filecount + (inc_rest ? 1 : 0))
{
close_database();
- fixup_database();
+ fixup_database(inc_rest);
delete[] page_buffer;
return;
}
- bakname = files[curLevel];
+ if (!inc_rest || curLevel)
+ bakname = files[curLevel - (inc_rest ?
1 : 0)];
#ifdef WIN_NT
if (curLevel)
+#else
+ if (!inc_rest || curLevel)
#endif
open_backup_scan();
}
@@ -1258,7 +1303,7 @@
status_exception::raise(Arg::Gds(isc_nbackup_unsupvers_incbk) <<
Arg::Num(bakheader.version) << bakname.c_str());
}
- if (bakheader.level != curLevel)
+ if (bakheader.level && bakheader.level !=
curLevel)
{
status_exception::raise(Arg::Gds(isc_nbackup_invlevel_incbk) <<
Arg::Num(bakheader.level) <<
bakname.c_str() << Arg::Num(curLevel));
@@ -1267,7 +1312,8 @@
if (memcmp(&bakheader.prev_guid, &prev_guid,
sizeof(Guid)) != 0)
status_exception::raise(Arg::Gds(isc_nbackup_wrong_orderbk) << bakname.c_str());
- delete_database = true;
+ if (!inc_rest)
+ delete_database = true;
prev_guid = bakheader.backup_guid;
while (true)
{
@@ -1288,28 +1334,34 @@
}
else
{
+ if (!inc_rest)
+ {
#ifdef WIN_NT
- if (!CopyFile(bakname.c_str(), dbname.c_str(),
TRUE))
- {
-
status_exception::raise(Arg::Gds(isc_nbackup_err_copy) <<
- dbname.c_str() <<
bakname.c_str() << Arg::OsError());
- }
- checkCtrlC(uSvc);
- delete_database = true; // database is possibly
broken
- open_database_write();
+ if (!CopyFile(bakname.c_str(),
dbname.c_str(), TRUE))
+ {
+
status_exception::raise(Arg::Gds(isc_nbackup_err_copy) <<
+ dbname.c_str() <<
bakname.c_str() << Arg::OsError());
+ }
+ checkCtrlC(uSvc);
+ delete_database = true; // database is
possibly broken
+ open_database_write();
#else
- // Use relatively small buffer to make use of
prefetch and lazy flush
- char buffer[65536];
- while (true)
- {
- const size_t bytesRead =
read_file(backup, buffer, sizeof(buffer));
- if (bytesRead == 0)
- break;
- write_file(dbase, buffer, bytesRead);
- checkCtrlC(uSvc);
+ // Use relatively small buffer to make
use of prefetch and lazy flush
+ char buffer[65536];
+ while (true)
+ {
+ const size_t bytesRead =
read_file(backup, buffer, sizeof(buffer));
+ if (bytesRead == 0)
+ break;
+ write_file(dbase, buffer,
bytesRead);
+ checkCtrlC(uSvc);
+ }
+ seek_file(dbase, 0);
+#endif
}
- seek_file(dbase, 0);
-#endif
+ else
+ open_database_write(true);
+
// Read database header
Ods::header_page header;
if (read_file(dbase, &header, sizeof(header))
!= sizeof(header))
@@ -1417,8 +1469,9 @@
false;
#endif
NBackup::BackupFiles backup_files;
- int level;
- bool print_size = false, version = false;
+ int level = -1;
+ Guid guid;
+ bool print_size = false, version = false, inc_rest = false;
string trustedUser;
bool trustedRole = false;
string onOff;
@@ -1548,7 +1601,10 @@
if (++itr >= argc)
missingParameterForSwitch(uSvc, argv[itr - 1]);
- level = atoi(argv[itr]);
+ if (argv[itr][0] == '{')
+ StringToGuid(&guid, argv[itr]);
+ else
+ level = atoi(argv[itr]);
if (++itr >= argc)
missingParameterForSwitch(uSvc, argv[itr - 2]);
@@ -1593,6 +1649,10 @@
version = true;
break;
+ case IN_SW_NBK_INPLACE:
+ inc_rest = true;
+ break;
+
default:
usage(uSvc, isc_nbackup_unknown_switch, argv[itr]);
break;
@@ -1636,11 +1696,11 @@
break;
case nbBackup:
- nbk.backup_database(level, filename);
+ nbk.backup_database(level, guid, filename);
break;
case nbRestore:
- nbk.restore_database(backup_files);
+ nbk.restore_database(backup_files, inc_rest);
break;
}
}
Index: src/utilities/nbackup/nbkswi.h
===================================================================
--- src/utilities/nbackup/nbkswi.h (revision 58043)
+++ src/utilities/nbackup/nbkswi.h (working copy)
@@ -48,12 +48,14 @@
const int IN_SW_NBK_TRUSTED_ROLE = 13;
const int IN_SW_NBK_HELP = 14;
const int IN_SW_NBK_DIRECT = 15;
+const int IN_SW_NBK_INPLACE = 16;
static const struct Switches::in_sw_tab_t nbackup_in_sw_table [] =
{
{IN_SW_NBK_NODBTRIG, isc_spb_nbk_no_triggers, "T",
0, 0, 0, false, 0, 1, NULL},
{IN_SW_NBK_DIRECT, isc_spb_nbk_direct,
"DIRECT", 0, 0, 0, false, 0, 1, NULL},
+ {IN_SW_NBK_INPLACE, isc_spb_nbk_inplace, "I",
0, 0, 0, false, 0, 1, NULL},
{IN_SW_NBK_0, 0,
NULL, 0, 0, 0, false, 0, 0, NULL} // End
of List
};
@@ -68,6 +70,7 @@
{IN_SW_NBK_BACKUP, isc_action_svc_nbak, "BACKUP",
0, 0, 0, false, 11, 1, NULL, nboExclusive},
{IN_SW_NBK_RESTORE, isc_action_svc_nrest, "RESTORE",
0, 0, 0, false, 12, 1, NULL, nboExclusive},
{IN_SW_NBK_DIRECT, 0,
"DIRECT", 0, 0, 0, false, 70, 1, NULL,
nboSpecial},
+ {IN_SW_NBK_INPLACE, 0,
"I", 0, 0, 0, false, 75, 1, NULL,
nboSpecial},
{IN_SW_NBK_SIZE, 0,
"SIZE", 0, 0, 0, false, 17, 1, NULL,
nboSpecial},
{IN_SW_NBK_NODBTRIG, 0,
"T", 0, 0, 0, false, 0, 1, NULL,
nboGeneral},
{IN_SW_NBK_NODBTRIG, 0,
"NODBTRIGGERS", 0, 0, 0, false, 16, 3, NULL, nboGeneral},
------------------------------------------------------------------------------
Learn Graph Databases - Download FREE O'Reilly Book
"Graph Databases" is the definitive new guide to graph databases and
their applications. This 200-page book is written by three acclaimed
leaders in the field. The early access version is available now.
Download your free book today! http://p.sf.net/sfu/neotech_d2d_may
Firebird-Devel mailing list, web interface at
https://lists.sourceforge.net/lists/listinfo/firebird-devel