diff --git a/builds/posix/Makefile.in.client.util b/builds/posix/Makefile.in.client.util index cd3eba128e..f35337df3a 100644 --- a/builds/posix/Makefile.in.client.util +++ b/builds/posix/Makefile.in.client.util @@ -46,9 +46,9 @@ LOCKPRINT_Sources = $(addprefix lock/, $(LOCKPRINT_Files)) $(LOCKPRINT_Other_Sou LOCKPRINT_Objects = $(addprefix $(OBJ)/, $(addsuffix .o, $(basename $(LOCKPRINT_Sources)))) -NBACKUP_Other_Sources = jrd/db_alias.cpp \ +NBACKUP_Other_Sources = jrd/db_alias.cpp common/UtilSvc.cpp \ common/config/config.cpp common/config/config_file.cpp $(OS_SPECIFIC_Sources) -NBACKUP_Files= nbackup.cpp +NBACKUP_Files= nbackup.cpp nbackup/nbkMain.cpp NBACKUP_Sources = $(addprefix utilities/, $(NBACKUP_Files)) $(NBACKUP_Other_Sources) NBACKUP_Objects = $(addprefix $(OBJ)/, $(addsuffix .o, $(basename $(NBACKUP_Sources)))) $(CLUMPLETS_Objects) diff --git a/builds/posix/Makefile.in.embed.util b/builds/posix/Makefile.in.embed.util index 9670d4c251..293bd87b2d 100644 --- a/builds/posix/Makefile.in.embed.util +++ b/builds/posix/Makefile.in.embed.util @@ -48,10 +48,10 @@ LOCKPRINT_Sources = $(addprefix lock/, $(LOCKPRINT_Files)) $(LOCKPRINT_Other_Sou LOCKPRINT_Objects = $(addprefix $(OBJ)/, $(addsuffix .o, $(basename $(LOCKPRINT_Sources)))) -NBACKUP_Other_Sources = jrd/db_alias.cpp \ +NBACKUP_Other_Sources = jrd/db_alias.cpp common/UtilSvc.cpp \ common/config/config.cpp common/config/config_file.cpp $(OS_SPECIFIC_Sources) -NBACKUP_Files= nbackup.cpp +NBACKUP_Files= nbackup.cpp nbackup/nbkMain.cpp NBACKUP_Sources = $(addprefix utilities/, $(NBACKUP_Files)) $(NBACKUP_Other_Sources) NBACKUP_Objects = $(addprefix $(OBJ)/, $(addsuffix .o, $(basename $(NBACKUP_Sources)))) diff --git a/builds/posix/make.shared.variables b/builds/posix/make.shared.variables index e145ecdeef..c92c9857c5 100644 --- a/builds/posix/make.shared.variables +++ b/builds/posix/make.shared.variables @@ -140,12 +140,19 @@ ALICE_Objects = $(addprefix $(OBJ)/, $(addsuffix .o, $(basename $(ALICE_Sources) #________________________________________________________________________ # -# alice +# burp BURP_Files=burp.cpp backup.epp restore.epp mvol.cpp misc.cpp canonical.cpp BURP_Sources = $(addprefix burp/, $(BURP_Files)) BURP_Objects = $(addprefix $(OBJ)/, $(addsuffix .o, $(basename $(BURP_Sources)))) +#________________________________________________________________________ +# +# nbackup + +NBACKUP_SERVER_Files= nbackup.cpp +NBACKUP_SERVER_Sources = $(addprefix utilities/, $(NBACKUP_SERVER_Files)) +NBACKUP_SERVER_Objects = $(addprefix $(OBJ)/, $(addsuffix .o, $(basename $(NBACKUP_SERVER_Sources)))) #________________________________________________________________________ # @@ -306,6 +313,7 @@ LIBFBEMBED_Objects =$(OS_SPECIFIC_Objects) \ $(FBCONFIG_Objects) \ $(BURP_Objects) \ $(ALICE_Objects) \ + $(NBACKUP_SERVER_Objects) \ $(UTIL_Objects) # Objects differences for server (super) and embedded (classic) libraries diff --git a/configure.in b/configure.in index f46bc23798..99d5e31bec 100644 --- a/configure.in +++ b/configure.in @@ -939,6 +939,7 @@ mkdir -p temp/boot/utilities/gstat mkdir -p temp/boot/utilities/guard mkdir -p temp/boot/utilities/ibmgr mkdir -p temp/boot/utilities/install +mkdir -p temp/boot/utilities/nbackup mkdir -p temp/boot/utilities/rebuild mkdir -p temp/boot/vulcan @@ -976,6 +977,7 @@ mkdir -p temp/std/utilities/gstat mkdir -p temp/std/utilities/guard mkdir -p temp/std/utilities/ibmgr mkdir -p temp/std/utilities/install +mkdir -p temp/std/utilities/nbackup mkdir -p temp/std/utilities/rebuild mkdir -p temp/std/vulcan @@ -1013,6 +1015,7 @@ mkdir -p temp/superclient/utilities/gstat mkdir -p temp/superclient/utilities/guard mkdir -p temp/superclient/utilities/ibmgr mkdir -p temp/superclient/utilities/install +mkdir -p temp/superclient/utilities/nbackup mkdir -p temp/superclient/utilities/rebuild mkdir -p temp/superclient/vulcan @@ -1050,6 +1053,7 @@ mkdir -p temp/superserver/utilities/gstat mkdir -p temp/superserver/utilities/guard mkdir -p temp/superserver/utilities/ibmgr mkdir -p temp/superserver/utilities/install +mkdir -p temp/superserver/utilities/nbackup mkdir -p temp/superserver/utilities/rebuild mkdir -p temp/superserver/vulcan diff --git a/lang_helpers/gds_codes.ftn b/lang_helpers/gds_codes.ftn index 9d32d9be72..b0d038878c 100644 --- a/lang_helpers/gds_codes.ftn +++ b/lang_helpers/gds_codes.ftn @@ -1350,6 +1350,8 @@ C -- PARAMETER (GDS__sysf_binuuid_mustbe_str = 335544968) INTEGER*4 GDS__sysf_binuuid_wrongsize PARAMETER (GDS__sysf_binuuid_wrongsize = 335544969) + INTEGER*4 GDS__missing_required_spb + PARAMETER (GDS__missing_required_spb = 335544970) INTEGER*4 GDS__gfix_db_name PARAMETER (GDS__gfix_db_name = 335740929) INTEGER*4 GDS__gfix_invalid_sw diff --git a/lang_helpers/gds_codes.pas b/lang_helpers/gds_codes.pas index a258e4cf69..e586e1934d 100644 --- a/lang_helpers/gds_codes.pas +++ b/lang_helpers/gds_codes.pas @@ -682,6 +682,7 @@ const gds_sysf_argmustbe_nonneg = 335544967; gds_sysf_binuuid_mustbe_str = 335544968; gds_sysf_binuuid_wrongsize = 335544969; + gds_missing_required_spb = 335544970; gds_gfix_db_name = 335740929; gds_gfix_invalid_sw = 335740930; gds_gfix_incmp_sw = 335740932; diff --git a/src/common/classes/ClumpletReader.cpp b/src/common/classes/ClumpletReader.cpp index d3102c9a6e..7d4df789af 100644 --- a/src/common/classes/ClumpletReader.cpp +++ b/src/common/classes/ClumpletReader.cpp @@ -309,6 +309,19 @@ ClumpletReader::ClumpletType ClumpletReader::getClumpletType(UCHAR tag) const case isc_action_svc_get_ib_log: invalid_structure("unknown parameter for getting log"); break; + case isc_action_svc_nbak: + case isc_action_svc_nrest: + switch (tag) + { + case isc_spb_nbk_file: + case isc_spb_dbname: + return StringSpb; + case isc_spb_nbk_level: + case isc_spb_options: + return IntSpb; + } + invalid_structure("unknown parameter for nbackup"); + break; } invalid_structure("wrong spb state"); break; diff --git a/src/include/consts_pub.h b/src/include/consts_pub.h index 7f23a5af7b..13638f8766 100644 --- a/src/include/consts_pub.h +++ b/src/include/consts_pub.h @@ -281,6 +281,8 @@ #define isc_action_svc_db_stats 11 /* Retrieves database statistics */ #define isc_action_svc_get_ib_log 12 /* Retrieves the InterBase log file from the server */ #define isc_action_svc_get_fb_log 12 /* Retrieves the Firebird log file from the server */ +#define isc_action_svc_nbak 20 /* Incremental nbackup */ +#define isc_action_svc_nrest 21 /* Incremental database restore */ /***************************** * Service information items * @@ -478,6 +480,13 @@ /* Not available in Firebird 1.5 */ +/*************************************** + * Parameters for isc_action_svc_nbak * + ***************************************/ + +#define isc_spb_nbk_level 5 +#define isc_spb_nbk_file 6 +#define isc_spb_nbk_no_triggers 0x01 /**********************************************/ /* Dynamic Data Definition Language operators */ diff --git a/src/include/gen/codetext.h b/src/include/gen/codetext.h index 7ce6a89a39..50d2521556 100644 --- a/src/include/gen/codetext.h +++ b/src/include/gen/codetext.h @@ -671,6 +671,7 @@ static const struct { {"sysf_argmustbe_nonneg", 335544967}, {"sysf_binuuid_mustbe_str", 335544968}, {"sysf_binuuid_wrongsize", 335544969}, + {"missing_required_spb", 335544970}, {"gfix_db_name", 335740929}, {"gfix_invalid_sw", 335740930}, {"gfix_incmp_sw", 335740932}, diff --git a/src/include/gen/iberror.h b/src/include/gen/iberror.h index eee9a45911..ff73d0238c 100644 --- a/src/include/gen/iberror.h +++ b/src/include/gen/iberror.h @@ -705,6 +705,7 @@ const ISC_STATUS isc_sysf_invalid_scale = 335544966L; const ISC_STATUS isc_sysf_argmustbe_nonneg = 335544967L; const ISC_STATUS isc_sysf_binuuid_mustbe_str = 335544968L; const ISC_STATUS isc_sysf_binuuid_wrongsize = 335544969L; +const ISC_STATUS isc_missing_required_spb = 335544970L; const ISC_STATUS isc_gfix_db_name = 335740929L; const ISC_STATUS isc_gfix_invalid_sw = 335740930L; const ISC_STATUS isc_gfix_incmp_sw = 335740932L; @@ -995,7 +996,7 @@ const ISC_STATUS isc_fbsvcmgr_query_err = 336986117L; const ISC_STATUS isc_fbsvcmgr_switch_unknown = 336986118L; const ISC_STATUS isc_fbsvcmgr_bad_sm = 336986159L; const ISC_STATUS isc_utl_trusted_switch = 337051649L; -const ISC_STATUS isc_err_max = 939; +const ISC_STATUS isc_err_max = 940; #else /* c definitions */ @@ -1670,6 +1671,7 @@ const ISC_STATUS isc_err_max = 939; #define isc_sysf_argmustbe_nonneg 335544967L #define isc_sysf_binuuid_mustbe_str 335544968L #define isc_sysf_binuuid_wrongsize 335544969L +#define isc_missing_required_spb 335544970L #define isc_gfix_db_name 335740929L #define isc_gfix_invalid_sw 335740930L #define isc_gfix_incmp_sw 335740932L @@ -1960,7 +1962,7 @@ const ISC_STATUS isc_err_max = 939; #define isc_fbsvcmgr_switch_unknown 336986118L #define isc_fbsvcmgr_bad_sm 336986159L #define isc_utl_trusted_switch 337051649L -#define isc_err_max 939 +#define isc_err_max 940 #endif diff --git a/src/include/gen/msgs.h b/src/include/gen/msgs.h index 2e6f90dc17..2fdc858100 100644 --- a/src/include/gen/msgs.h +++ b/src/include/gen/msgs.h @@ -674,295 +674,296 @@ Data source : @4"}, /* 606, eds_statement */ {335544967, "Argument for @1 must be zero or positive"}, /* 647, sysf_argmustbe_nonneg */ {335544968, "Binary UUID argument for @1 must be of string type"}, /* 648, sysf_binuuid_mustbe_str */ {335544969, "Binary UUID argument for @2 must use @1 bytes"}, /* 649, sysf_binuuid_wrongsize */ - {335740929, "data base file name (@1) already given"}, /* 650, gfix_db_name */ - {335740930, "invalid switch @1"}, /* 651, gfix_invalid_sw */ - {335740932, "incompatible switch combination"}, /* 652, gfix_incmp_sw */ - {335740933, "replay log pathname required"}, /* 653, gfix_replay_req */ - {335740934, "number of page buffers for cache required"}, /* 654, gfix_pgbuf_req */ - {335740935, "numeric value required"}, /* 655, gfix_val_req */ - {335740936, "positive numeric value required"}, /* 656, gfix_pval_req */ - {335740937, "number of transactions per sweep required"}, /* 657, gfix_trn_req */ - {335740940, "\"full\" or \"reserve\" required"}, /* 658, gfix_full_req */ - {335740941, "user name required"}, /* 659, gfix_usrname_req */ - {335740942, "password required"}, /* 660, gfix_pass_req */ - {335740943, "subsystem name"}, /* 661, gfix_subs_name */ - {335740944, "\"wal\" required"}, /* 662, gfix_wal_req */ - {335740945, "number of seconds required"}, /* 663, gfix_sec_req */ - {335740946, "numeric value between 0 and 32767 inclusive required"}, /* 664, gfix_nval_req */ - {335740947, "must specify type of shutdown"}, /* 665, gfix_type_shut */ - {335740948, "please retry, specifying an option"}, /* 666, gfix_retry */ - {335740951, "please retry, giving a database name"}, /* 667, gfix_retry_db */ - {335740991, "internal block exceeds maximum size"}, /* 668, gfix_exceed_max */ - {335740992, "corrupt pool"}, /* 669, gfix_corrupt_pool */ - {335740993, "virtual memory exhausted"}, /* 670, gfix_mem_exhausted */ - {335740994, "bad pool id"}, /* 671, gfix_bad_pool */ - {335740995, "Transaction state @1 not in valid range."}, /* 672, gfix_trn_not_valid */ - {335741012, "unexpected end of input"}, /* 673, gfix_unexp_eoi */ - {335741018, "failed to reconnect to a transaction in database @1"}, /* 674, gfix_recon_fail */ - {335741036, "Transaction description item unknown"}, /* 675, gfix_trn_unknown */ - {335741038, "\"read_only\" or \"read_write\" required"}, /* 676, gfix_mode_req */ - {335741039, " -sql_dialect set database dialect n"}, /* 677, gfix_opt_SQL_dialect */ - {335741042, "positive or zero numeric value required"}, /* 678, gfix_pzval_req */ - {336003074, "Cannot SELECT RDB$DB_KEY from a stored procedure."}, /* 679, dsql_dbkey_from_non_table */ - {336003075, "Precision 10 to 18 changed from DOUBLE PRECISION in SQL dialect 1 to 64-bit scaled integer in SQL dialect 3"}, /* 680, dsql_transitional_numeric */ - {336003076, "Use of @1 expression that returns different results in dialect 1 and dialect 3"}, /* 681, dsql_dialect_warning_expr */ - {336003077, "Database SQL dialect @1 does not support reference to @2 datatype"}, /* 682, sql_db_dialect_dtype_unsupport */ - {336003079, "DB dialect @1 and client dialect @2 conflict with respect to numeric precision @3."}, /* 683, isc_sql_dialect_conflict_num */ - {336003080, "WARNING: Numeric literal @1 is interpreted as a floating-point"}, /* 684, dsql_warning_number_ambiguous */ - {336003081, "value in SQL dialect 1, but as an exact numeric value in SQL dialect 3."}, /* 685, dsql_warning_number_ambiguous1 */ - {336003082, "WARNING: NUMERIC and DECIMAL fields with precision 10 or greater are stored"}, /* 686, dsql_warn_precision_ambiguous */ - {336003083, "as approximate floating-point values in SQL dialect 1, but as 64-bit"}, /* 687, dsql_warn_precision_ambiguous1 */ - {336003084, "integers in SQL dialect 3."}, /* 688, dsql_warn_precision_ambiguous2 */ - {336003085, "Ambiguous field name between @1 and @2"}, /* 689, dsql_ambiguous_field_name */ - {336003086, "External function should have return position between 1 and @1"}, /* 690, dsql_udf_return_pos_err */ - {336003087, "Label @1 @2 in the current scope"}, /* 691, dsql_invalid_label */ - {336003088, "Datatypes @1are not comparable in expression @2"}, /* 692, dsql_datatypes_not_comparable */ - {336003089, "Empty cursor name is not allowed"}, /* 693, dsql_cursor_invalid */ - {336003090, "Statement already has a cursor @1 assigned"}, /* 694, dsql_cursor_redefined */ - {336003091, "Cursor @1 is not found in the current context"}, /* 695, dsql_cursor_not_found */ - {336003092, "Cursor @1 already exists in the current context"}, /* 696, dsql_cursor_exists */ - {336003093, "Relation @1 is ambiguous in cursor @2"}, /* 697, dsql_cursor_rel_ambiguous */ - {336003094, "Relation @1 is not found in cursor @2"}, /* 698, dsql_cursor_rel_not_found */ - {336003095, "Cursor is not open"}, /* 699, dsql_cursor_not_open */ - {336003096, "Data type @1 is not supported for EXTERNAL TABLES. Relation '@2', field '@3'"}, /* 700, dsql_type_not_supp_ext_tab */ - {336003097, "Feature not supported on ODS version older than @1.@2"}, /* 701, dsql_feature_not_supported_ods */ - {336003098, "Primary key required on table @1"}, /* 702, primary_key_required */ - {336003099, "UPDATE OR INSERT field list does not match primary key of table @1"}, /* 703, upd_ins_doesnt_match_pk */ - {336003100, "UPDATE OR INSERT field list does not match MATCHING clause"}, /* 704, upd_ins_doesnt_match_matching */ - {336003101, "UPDATE OR INSERT without MATCHING could not be used with views based on more than one table"}, /* 705, upd_ins_with_complex_view */ - {336003102, "Incompatible trigger type"}, /* 706, dsql_incompatible_trigger_type */ - {336003103, "Database trigger type can't be changed"}, /* 707, dsql_db_trigger_type_cant_change */ - {336068740, "Table @1 already exists"}, /* 708, dyn_dup_table */ - {336068784, "column @1 does not exist in table/view @2"}, /* 709, dyn_column_does_not_exist */ - {336068796, "SQL role @1 does not exist"}, /* 710, dyn_role_does_not_exist */ - {336068797, "user @1 has no grant admin option on SQL role @2"}, /* 711, dyn_no_grant_admin_opt */ - {336068798, "user @1 is not a member of SQL role @2"}, /* 712, dyn_user_not_role_member */ - {336068799, "@1 is not the owner of SQL role @2"}, /* 713, dyn_delete_role_failed */ - {336068800, "@1 is a SQL role and not a user"}, /* 714, dyn_grant_role_to_user */ - {336068801, "user name @1 could not be used for SQL role"}, /* 715, dyn_inv_sql_role_name */ - {336068802, "SQL role @1 already exists"}, /* 716, dyn_dup_sql_role */ - {336068803, "keyword @1 can not be used as a SQL role name"}, /* 717, dyn_kywd_spec_for_role */ - {336068804, "SQL roles are not supported in on older versions of the database. A backup and restore of the database is required."}, /* 718, dyn_roles_not_supported */ - {336068812, "Cannot rename domain @1 to @2. A domain with that name already exists."}, /* 719, dyn_domain_name_exists */ - {336068813, "Cannot rename column @1 to @2. A column with that name already exists in table @3."}, /* 720, dyn_field_name_exists */ - {336068814, "Column @1 from table @2 is referenced in @3"}, /* 721, dyn_dependency_exists */ - {336068815, "Cannot change datatype for column @1. Changing datatype is not supported for BLOB or ARRAY columns."}, /* 722, dyn_dtype_invalid */ - {336068816, "New size specified for column @1 must be at least @2 characters."}, /* 723, dyn_char_fld_too_small */ - {336068817, "Cannot change datatype for @1. Conversion from base type @2 to @3 is not supported."}, /* 724, dyn_invalid_dtype_conversion */ - {336068818, "Cannot change datatype for column @1 from a character type to a non-character type."}, /* 725, dyn_dtype_conv_invalid */ - {336068820, "Zero length identifiers are not allowed"}, /* 726, dyn_zero_len_id */ - {336068829, "Maximum number of collations per character set exceeded"}, /* 727, max_coll_per_charset */ - {336068830, "Invalid collation attributes"}, /* 728, invalid_coll_attr */ - {336068840, "@1 cannot reference @2"}, /* 729, dyn_wrong_gtt_scope */ - {336068852, "New scale specified for column @1 must be at most @2."}, /* 730, dyn_scale_too_big */ - {336068853, "New precision specified for column @1 must be at least @2."}, /* 731, dyn_precision_too_small */ - {336068855, "Warning: @1 on @2 is not granted to @3."}, /* 732, dyn_miss_priv_warning */ - {336068856, "Feature '@1' is not supported in ODS @2.@3"}, /* 733, dyn_ods_not_supp_feature */ - {336068857, "Cannot add or remove COMPUTED from column @1"}, /* 734, dyn_cannot_addrem_computed */ - {336068858, "Password should not be empty string"}, /* 735, dyn_no_empty_pw */ - {336068859, "Index @1 already exists"}, /* 736, dyn_dup_index */ - {336330753, "found unknown switch"}, /* 737, gbak_unknown_switch */ - {336330754, "page size parameter missing"}, /* 738, gbak_page_size_missing */ - {336330755, "Page size specified (@1) greater than limit (16384 bytes)"}, /* 739, gbak_page_size_toobig */ - {336330756, "redirect location for output is not specified"}, /* 740, gbak_redir_ouput_missing */ - {336330757, "conflicting switches for backup/restore"}, /* 741, gbak_switches_conflict */ - {336330758, "device type @1 not known"}, /* 742, gbak_unknown_device */ - {336330759, "protection is not there yet"}, /* 743, gbak_no_protection */ - {336330760, "page size is allowed only on restore or create"}, /* 744, gbak_page_size_not_allowed */ - {336330761, "multiple sources or destinations specified"}, /* 745, gbak_multi_source_dest */ - {336330762, "requires both input and output filenames"}, /* 746, gbak_filename_missing */ - {336330763, "input and output have the same name. Disallowed."}, /* 747, gbak_dup_inout_names */ - {336330764, "expected page size, encountered \"@1\""}, /* 748, gbak_inv_page_size */ - {336330765, "REPLACE specified, but the first file @1 is a database"}, /* 749, gbak_db_specified */ - {336330766, "database @1 already exists. To replace it, use the -REP switch"}, /* 750, gbak_db_exists */ - {336330767, "device type not specified"}, /* 751, gbak_unk_device */ - {336330772, "gds_$blob_info failed"}, /* 752, gbak_blob_info_failed */ - {336330773, "do not understand BLOB INFO item @1"}, /* 753, gbak_unk_blob_item */ - {336330774, "gds_$get_segment failed"}, /* 754, gbak_get_seg_failed */ - {336330775, "gds_$close_blob failed"}, /* 755, gbak_close_blob_failed */ - {336330776, "gds_$open_blob failed"}, /* 756, gbak_open_blob_failed */ - {336330777, "Failed in put_blr_gen_id"}, /* 757, gbak_put_blr_gen_id_failed */ - {336330778, "data type @1 not understood"}, /* 758, gbak_unk_type */ - {336330779, "gds_$compile_request failed"}, /* 759, gbak_comp_req_failed */ - {336330780, "gds_$start_request failed"}, /* 760, gbak_start_req_failed */ - {336330781, "gds_$receive failed"}, /* 761, gbak_rec_failed */ - {336330782, "gds_$release_request failed"}, /* 762, gbak_rel_req_failed */ - {336330783, "gds_$database_info failed"}, /* 763, gbak_db_info_failed */ - {336330784, "Expected database description record"}, /* 764, gbak_no_db_desc */ - {336330785, "failed to create database @1"}, /* 765, gbak_db_create_failed */ - {336330786, "RESTORE: decompression length error"}, /* 766, gbak_decomp_len_error */ - {336330787, "cannot find table @1"}, /* 767, gbak_tbl_missing */ - {336330788, "Cannot find column for BLOB"}, /* 768, gbak_blob_col_missing */ - {336330789, "gds_$create_blob failed"}, /* 769, gbak_create_blob_failed */ - {336330790, "gds_$put_segment failed"}, /* 770, gbak_put_seg_failed */ - {336330791, "expected record length"}, /* 771, gbak_rec_len_exp */ - {336330792, "wrong length record, expected @1 encountered @2"}, /* 772, gbak_inv_rec_len */ - {336330793, "expected data attribute"}, /* 773, gbak_exp_data_type */ - {336330794, "Failed in store_blr_gen_id"}, /* 774, gbak_gen_id_failed */ - {336330795, "do not recognize record type @1"}, /* 775, gbak_unk_rec_type */ - {336330796, "Expected backup version 1..8. Found @1"}, /* 776, gbak_inv_bkup_ver */ - {336330797, "expected backup description record"}, /* 777, gbak_missing_bkup_desc */ - {336330798, "string truncated"}, /* 778, gbak_string_trunc */ - {336330799, "warning -- record could not be restored"}, /* 779, gbak_cant_rest_record */ - {336330800, "gds_$send failed"}, /* 780, gbak_send_failed */ - {336330801, "no table name for data"}, /* 781, gbak_no_tbl_name */ - {336330802, "unexpected end of file on backup file"}, /* 782, gbak_unexp_eof */ - {336330803, "database format @1 is too old to restore to"}, /* 783, gbak_db_format_too_old */ - {336330804, "array dimension for column @1 is invalid"}, /* 784, gbak_inv_array_dim */ - {336330807, "Expected XDR record length"}, /* 785, gbak_xdr_len_expected */ - {336330817, "cannot open backup file @1"}, /* 786, gbak_open_bkup_error */ - {336330818, "cannot open status and error output file @1"}, /* 787, gbak_open_error */ - {336330934, "blocking factor parameter missing"}, /* 788, gbak_missing_block_fac */ - {336330935, "expected blocking factor, encountered \"@1\""}, /* 789, gbak_inv_block_fac */ - {336330936, "a blocking factor may not be used in conjunction with device CT"}, /* 790, gbak_block_fac_specified */ - {336330940, "user name parameter missing"}, /* 791, gbak_missing_username */ - {336330941, "password parameter missing"}, /* 792, gbak_missing_password */ - {336330952, " missing parameter for the number of bytes to be skipped"}, /* 793, gbak_missing_skipped_bytes */ - {336330953, "expected number of bytes to be skipped, encountered \"@1\""}, /* 794, gbak_inv_skipped_bytes */ - {336330965, "character set"}, /* 795, gbak_err_restore_charset */ - {336330967, "collation"}, /* 796, gbak_err_restore_collation */ - {336330972, "Unexpected I/O error while reading from backup file"}, /* 797, gbak_read_error */ - {336330973, "Unexpected I/O error while writing to backup file"}, /* 798, gbak_write_error */ - {336330985, "could not drop database @1 (database might be in use)"}, /* 799, gbak_db_in_use */ - {336330990, "System memory exhausted"}, /* 800, gbak_sysmemex */ - {336331002, "SQL role"}, /* 801, gbak_restore_role_failed */ - {336331005, "SQL role parameter missing"}, /* 802, gbak_role_op_missing */ - {336331010, "page buffers parameter missing"}, /* 803, gbak_page_buffers_missing */ - {336331011, "expected page buffers, encountered \"@1\""}, /* 804, gbak_page_buffers_wrong_param */ - {336331012, "page buffers is allowed only on restore or create"}, /* 805, gbak_page_buffers_restore */ - {336331014, "size specification either missing or incorrect for file @1"}, /* 806, gbak_inv_size */ - {336331015, "file @1 out of sequence"}, /* 807, gbak_file_outof_sequence */ - {336331016, "can't join -- one of the files missing"}, /* 808, gbak_join_file_missing */ - {336331017, " standard input is not supported when using join operation"}, /* 809, gbak_stdin_not_supptd */ - {336331018, "standard output is not supported when using split operation"}, /* 810, gbak_stdout_not_supptd */ - {336331019, "backup file @1 might be corrupt"}, /* 811, gbak_bkup_corrupt */ - {336331020, "database file specification missing"}, /* 812, gbak_unk_db_file_spec */ - {336331021, "can't write a header record to file @1"}, /* 813, gbak_hdr_write_failed */ - {336331022, "free disk space exhausted"}, /* 814, gbak_disk_space_ex */ - {336331023, "file size given (@1) is less than minimum allowed (@2)"}, /* 815, gbak_size_lt_min */ - {336331025, "service name parameter missing"}, /* 816, gbak_svc_name_missing */ - {336331026, "Cannot restore over current database, must be SYSDBA or owner of the existing database."}, /* 817, gbak_not_ownr */ - {336331031, "\"read_only\" or \"read_write\" required"}, /* 818, gbak_mode_req */ - {336331033, "just data ignore all constraints etc."}, /* 819, gbak_just_data */ - {336331034, "restoring data only ignoring foreign key, unique, not null & other constraints"}, /* 820, gbak_data_only */ - {336397205, "ODS versions before ODS@1 are not supported"}, /* 821, dsql_too_old_ods */ - {336397206, "Table @1 does not exist"}, /* 822, dsql_table_not_found */ - {336397207, "View @1 does not exist"}, /* 823, dsql_view_not_found */ - {336397208, "At line @1, column @2"}, /* 824, dsql_line_col_error */ - {336397209, "At unknown line and column"}, /* 825, dsql_unknown_pos */ - {336397210, "Column @1 cannot be repeated in @2 statement"}, /* 826, dsql_no_dup_name */ - {336397211, "Too many values (more than @1) in member list to match against"}, /* 827, dsql_too_many_values */ - {336397212, "Array and BLOB data types not allowed in computed field"}, /* 828, dsql_no_array_computed */ - {336397213, "Implicit domain name @1 not allowed in user created domain"}, /* 829, dsql_implicit_domain_name */ - {336397214, "scalar operator used on field @1 which is not an array"}, /* 830, dsql_only_can_subscript_array */ - {336397215, "cannot sort on more than 255 items"}, /* 831, dsql_max_sort_items */ - {336397216, "cannot group on more than 255 items"}, /* 832, dsql_max_group_items */ - {336397217, "Cannot include the same field (@1.@2) twice in the ORDER BY clause with conflicting sorting options"}, /* 833, dsql_conflicting_sort_field */ - {336397218, "column list from derived table @1 has more columns than the number of items in its SELECT statement"}, /* 834, dsql_derived_table_more_columns */ - {336397219, "column list from derived table @1 has less columns than the number of items in its SELECT statement"}, /* 835, dsql_derived_table_less_columns */ - {336397220, "no column name specified for column number @1 in derived table @2"}, /* 836, dsql_derived_field_unnamed */ - {336397221, "column @1 was specified multiple times for derived table @2"}, /* 837, dsql_derived_field_dup_name */ - {336397222, "Internal dsql error: alias type expected by pass1_expand_select_node"}, /* 838, dsql_derived_alias_select */ - {336397223, "Internal dsql error: alias type expected by pass1_field"}, /* 839, dsql_derived_alias_field */ - {336397224, "Internal dsql error: column position out of range in pass1_union_auto_cast"}, /* 840, dsql_auto_field_bad_pos */ - {336397225, "Recursive CTE member (@1) can refer itself only in FROM clause"}, /* 841, dsql_cte_wrong_reference */ - {336397226, "CTE '@1' has cyclic dependencies"}, /* 842, dsql_cte_cycle */ - {336397227, "Recursive member of CTE can't be member of an outer join"}, /* 843, dsql_cte_outer_join */ - {336397228, "Recursive member of CTE can't reference itself more than once"}, /* 844, dsql_cte_mult_references */ - {336397229, "Recursive CTE (@1) must be an UNION"}, /* 845, dsql_cte_not_a_union */ - {336397230, "CTE '@1' defined non-recursive member after recursive"}, /* 846, dsql_cte_nonrecurs_after_recurs */ - {336397231, "Recursive member of CTE '@1' has @2 clause"}, /* 847, dsql_cte_wrong_clause */ - {336397232, "Recursive members of CTE (@1) must be linked with another members via UNION ALL"}, /* 848, dsql_cte_union_all */ - {336397233, "Non-recursive member is missing in CTE '@1'"}, /* 849, dsql_cte_miss_nonrecursive */ - {336397234, "WITH clause can't be nested"}, /* 850, dsql_cte_nested_with */ - {336397235, "column @1 appears more than once in USING clause"}, /* 851, dsql_col_more_than_once_using */ - {336397236, "feature is not supported in dialect @1"}, /* 852, dsql_unsupp_feature_dialect */ - {336397237, "CTE \"@1\" is not used in query"}, /* 853, dsql_cte_not_used */ - {336397238, "column @1 appears more than once in ALTER VIEW"}, /* 854, dsql_col_more_than_once_view */ - {336397239, "@1 is not supported inside IN AUTONOMOUS TRANSACTION block"}, /* 855, dsql_unsupported_in_auto_trans */ - {336397240, "Unknown node type @1 in dsql/GEN_expr"}, /* 856, dsql_eval_unknode */ - {336397241, "Argument for @1 in dialect 1 must be string or numeric"}, /* 857, dsql_agg_wrongarg */ - {336397242, "Argument for @1 in dialect 3 must be numeric"}, /* 858, dsql_agg2_wrongarg */ - {336397243, "Strings cannot be added to or subtracted from DATE or TIME types"}, /* 859, dsql_nodateortime_pm_string */ - {336397244, "Invalid data type for subtraction involving DATE, TIME or TIMESTAMP types"}, /* 860, dsql_invalid_datetime_subtract */ - {336397245, "Adding two DATE values or two TIME values is not allowed"}, /* 861, dsql_invalid_dateortime_add */ - {336397246, "DATE value cannot be subtracted from the provided data type"}, /* 862, dsql_invalid_type_minus_date */ - {336397247, "Strings cannot be added or subtracted in dialect 3"}, /* 863, dsql_nostring_addsub_dial3 */ - {336397248, "Invalid data type for addition or subtraction in dialect 3"}, /* 864, dsql_invalid_type_addsub_dial3 */ - {336397249, "Invalid data type for multiplication in dialect 1"}, /* 865, dsql_invalid_type_multip_dial1 */ - {336397250, "Strings cannot be multiplied in dialect 3"}, /* 866, dsql_nostring_multip_dial3 */ - {336397251, "Invalid data type for multiplication in dialect 3"}, /* 867, dsql_invalid_type_multip_dial3 */ - {336397252, "Division in dialect 1 must be between numeric data types"}, /* 868, dsql_mustuse_numeric_div_dial1 */ - {336397253, "Strings cannot be divided in dialect 3"}, /* 869, dsql_nostring_div_dial3 */ - {336397254, "Invalid data type for division in dialect 3"}, /* 870, dsql_invalid_type_div_dial3 */ - {336397255, "Strings cannot be negated (applied the minus operator) in dialect 3"}, /* 871, dsql_nostring_neg_dial3 */ - {336397256, "Invalid data type for negation (minus operator)"}, /* 872, dsql_invalid_type_neg */ - {336723983, "unable to open database"}, /* 873, gsec_cant_open_db */ - {336723984, "error in switch specifications"}, /* 874, gsec_switches_error */ - {336723985, "no operation specified"}, /* 875, gsec_no_op_spec */ - {336723986, "no user name specified"}, /* 876, gsec_no_usr_name */ - {336723987, "add record error"}, /* 877, gsec_err_add */ - {336723988, "modify record error"}, /* 878, gsec_err_modify */ - {336723989, "find/modify record error"}, /* 879, gsec_err_find_mod */ - {336723990, "record not found for user: @1"}, /* 880, gsec_err_rec_not_found */ - {336723991, "delete record error"}, /* 881, gsec_err_delete */ - {336723992, "find/delete record error"}, /* 882, gsec_err_find_del */ - {336723996, "find/display record error"}, /* 883, gsec_err_find_disp */ - {336723997, "invalid parameter, no switch defined"}, /* 884, gsec_inv_param */ - {336723998, "operation already specified"}, /* 885, gsec_op_specified */ - {336723999, "password already specified"}, /* 886, gsec_pw_specified */ - {336724000, "uid already specified"}, /* 887, gsec_uid_specified */ - {336724001, "gid already specified"}, /* 888, gsec_gid_specified */ - {336724002, "project already specified"}, /* 889, gsec_proj_specified */ - {336724003, "organization already specified"}, /* 890, gsec_org_specified */ - {336724004, "first name already specified"}, /* 891, gsec_fname_specified */ - {336724005, "middle name already specified"}, /* 892, gsec_mname_specified */ - {336724006, "last name already specified"}, /* 893, gsec_lname_specified */ - {336724008, "invalid switch specified"}, /* 894, gsec_inv_switch */ - {336724009, "ambiguous switch specified"}, /* 895, gsec_amb_switch */ - {336724010, "no operation specified for parameters"}, /* 896, gsec_no_op_specified */ - {336724011, "no parameters allowed for this operation"}, /* 897, gsec_params_not_allowed */ - {336724012, "incompatible switches specified"}, /* 898, gsec_incompat_switch */ - {336724044, "Invalid user name (maximum 31 bytes allowed)"}, /* 899, gsec_inv_username */ - {336724045, "Warning - maximum 8 significant bytes of password used"}, /* 900, gsec_inv_pw_length */ - {336724046, "database already specified"}, /* 901, gsec_db_specified */ - {336724047, "database administrator name already specified"}, /* 902, gsec_db_admin_specified */ - {336724048, "database administrator password already specified"}, /* 903, gsec_db_admin_pw_specified */ - {336724049, "SQL role name already specified"}, /* 904, gsec_sql_role_specified */ - {336789504, "The license file does not exist or could not be opened for read"}, /* 905, license_no_file */ - {336789523, "operation already specified"}, /* 906, license_op_specified */ - {336789524, "no operation specified"}, /* 907, license_op_missing */ - {336789525, "invalid switch"}, /* 908, license_inv_switch */ - {336789526, "invalid switch combination"}, /* 909, license_inv_switch_combo */ - {336789527, "illegal operation/switch combination"}, /* 910, license_inv_op_combo */ - {336789528, "ambiguous switch"}, /* 911, license_amb_switch */ - {336789529, "invalid parameter, no switch specified"}, /* 912, license_inv_parameter */ - {336789530, "switch does not take any parameter"}, /* 913, license_param_specified */ - {336789531, "switch requires a parameter"}, /* 914, license_param_req */ - {336789532, "syntax error in command line"}, /* 915, license_syntx_error */ - {336789534, "The certificate was not added. A duplicate ID exists in the license file."}, /* 916, license_dup_id */ - {336789535, "The certificate was not added. Invalid certificate ID / Key combination."}, /* 917, license_inv_id_key */ - {336789536, "The certificate was not removed. The key does not exist or corresponds to a temporary evaluation license."}, /* 918, license_err_remove */ - {336789537, "An error occurred updating the license file. Operation cancelled."}, /* 919, license_err_update */ - {336789538, "The certificate could not be validated based on the information given. Please recheck the ID and key information."}, /* 920, license_err_convert */ - {336789539, "Operation failed. An unknown error occurred."}, /* 921, license_err_unk */ - {336789540, "Add license operation failed, KEY: @1 ID: @2"}, /* 922, license_svc_err_add */ - {336789541, "Remove license operation failed, KEY: @1"}, /* 923, license_svc_err_remove */ - {336789563, "The evaluation license has already been used on this server. You need to purchase a non-evaluation license."}, /* 924, license_eval_exists */ - {336920577, "found unknown switch"}, /* 925, gstat_unknown_switch */ - {336920578, "please retry, giving a database name"}, /* 926, gstat_retry */ - {336920579, "Wrong ODS version, expected @1, encountered @2"}, /* 927, gstat_wrong_ods */ - {336920580, "Unexpected end of database file."}, /* 928, gstat_unexpected_eof */ - {336920605, "Can't open database file @1"}, /* 929, gstat_open_err */ - {336920606, "Can't read a database page"}, /* 930, gstat_read_err */ - {336920607, "System memory exhausted"}, /* 931, gstat_sysmemex */ - {336986113, "Wrong value for access mode"}, /* 932, fbsvcmgr_bad_am */ - {336986114, "Wrong value for write mode"}, /* 933, fbsvcmgr_bad_wm */ - {336986115, "Wrong value for reserve space"}, /* 934, fbsvcmgr_bad_rs */ - {336986116, "Unknown tag (@1) in info_svr_db_info block after isc_svc_query()"}, /* 935, fbsvcmgr_info_err */ - {336986117, "Unknown tag (@1) in isc_svc_query() results"}, /* 936, fbsvcmgr_query_err */ - {336986118, "Unknown switch \"@1\""}, /* 937, fbsvcmgr_switch_unknown */ - {336986159, "Wrong value for shutdown mode"}, /* 938, fbsvcmgr_bad_sm */ - {337051649, "Switches trusted_svc and trusted_role are not supported from command line"}, /* 939, utl_trusted_switch */ + {335544970, "Missing required item @1 in service parameter block"}, /* 650, missing_required_spb */ + {335740929, "data base file name (@1) already given"}, /* 651, gfix_db_name */ + {335740930, "invalid switch @1"}, /* 652, gfix_invalid_sw */ + {335740932, "incompatible switch combination"}, /* 653, gfix_incmp_sw */ + {335740933, "replay log pathname required"}, /* 654, gfix_replay_req */ + {335740934, "number of page buffers for cache required"}, /* 655, gfix_pgbuf_req */ + {335740935, "numeric value required"}, /* 656, gfix_val_req */ + {335740936, "positive numeric value required"}, /* 657, gfix_pval_req */ + {335740937, "number of transactions per sweep required"}, /* 658, gfix_trn_req */ + {335740940, "\"full\" or \"reserve\" required"}, /* 659, gfix_full_req */ + {335740941, "user name required"}, /* 660, gfix_usrname_req */ + {335740942, "password required"}, /* 661, gfix_pass_req */ + {335740943, "subsystem name"}, /* 662, gfix_subs_name */ + {335740944, "\"wal\" required"}, /* 663, gfix_wal_req */ + {335740945, "number of seconds required"}, /* 664, gfix_sec_req */ + {335740946, "numeric value between 0 and 32767 inclusive required"}, /* 665, gfix_nval_req */ + {335740947, "must specify type of shutdown"}, /* 666, gfix_type_shut */ + {335740948, "please retry, specifying an option"}, /* 667, gfix_retry */ + {335740951, "please retry, giving a database name"}, /* 668, gfix_retry_db */ + {335740991, "internal block exceeds maximum size"}, /* 669, gfix_exceed_max */ + {335740992, "corrupt pool"}, /* 670, gfix_corrupt_pool */ + {335740993, "virtual memory exhausted"}, /* 671, gfix_mem_exhausted */ + {335740994, "bad pool id"}, /* 672, gfix_bad_pool */ + {335740995, "Transaction state @1 not in valid range."}, /* 673, gfix_trn_not_valid */ + {335741012, "unexpected end of input"}, /* 674, gfix_unexp_eoi */ + {335741018, "failed to reconnect to a transaction in database @1"}, /* 675, gfix_recon_fail */ + {335741036, "Transaction description item unknown"}, /* 676, gfix_trn_unknown */ + {335741038, "\"read_only\" or \"read_write\" required"}, /* 677, gfix_mode_req */ + {335741039, " -sql_dialect set database dialect n"}, /* 678, gfix_opt_SQL_dialect */ + {335741042, "positive or zero numeric value required"}, /* 679, gfix_pzval_req */ + {336003074, "Cannot SELECT RDB$DB_KEY from a stored procedure."}, /* 680, dsql_dbkey_from_non_table */ + {336003075, "Precision 10 to 18 changed from DOUBLE PRECISION in SQL dialect 1 to 64-bit scaled integer in SQL dialect 3"}, /* 681, dsql_transitional_numeric */ + {336003076, "Use of @1 expression that returns different results in dialect 1 and dialect 3"}, /* 682, dsql_dialect_warning_expr */ + {336003077, "Database SQL dialect @1 does not support reference to @2 datatype"}, /* 683, sql_db_dialect_dtype_unsupport */ + {336003079, "DB dialect @1 and client dialect @2 conflict with respect to numeric precision @3."}, /* 684, isc_sql_dialect_conflict_num */ + {336003080, "WARNING: Numeric literal @1 is interpreted as a floating-point"}, /* 685, dsql_warning_number_ambiguous */ + {336003081, "value in SQL dialect 1, but as an exact numeric value in SQL dialect 3."}, /* 686, dsql_warning_number_ambiguous1 */ + {336003082, "WARNING: NUMERIC and DECIMAL fields with precision 10 or greater are stored"}, /* 687, dsql_warn_precision_ambiguous */ + {336003083, "as approximate floating-point values in SQL dialect 1, but as 64-bit"}, /* 688, dsql_warn_precision_ambiguous1 */ + {336003084, "integers in SQL dialect 3."}, /* 689, dsql_warn_precision_ambiguous2 */ + {336003085, "Ambiguous field name between @1 and @2"}, /* 690, dsql_ambiguous_field_name */ + {336003086, "External function should have return position between 1 and @1"}, /* 691, dsql_udf_return_pos_err */ + {336003087, "Label @1 @2 in the current scope"}, /* 692, dsql_invalid_label */ + {336003088, "Datatypes @1are not comparable in expression @2"}, /* 693, dsql_datatypes_not_comparable */ + {336003089, "Empty cursor name is not allowed"}, /* 694, dsql_cursor_invalid */ + {336003090, "Statement already has a cursor @1 assigned"}, /* 695, dsql_cursor_redefined */ + {336003091, "Cursor @1 is not found in the current context"}, /* 696, dsql_cursor_not_found */ + {336003092, "Cursor @1 already exists in the current context"}, /* 697, dsql_cursor_exists */ + {336003093, "Relation @1 is ambiguous in cursor @2"}, /* 698, dsql_cursor_rel_ambiguous */ + {336003094, "Relation @1 is not found in cursor @2"}, /* 699, dsql_cursor_rel_not_found */ + {336003095, "Cursor is not open"}, /* 700, dsql_cursor_not_open */ + {336003096, "Data type @1 is not supported for EXTERNAL TABLES. Relation '@2', field '@3'"}, /* 701, dsql_type_not_supp_ext_tab */ + {336003097, "Feature not supported on ODS version older than @1.@2"}, /* 702, dsql_feature_not_supported_ods */ + {336003098, "Primary key required on table @1"}, /* 703, primary_key_required */ + {336003099, "UPDATE OR INSERT field list does not match primary key of table @1"}, /* 704, upd_ins_doesnt_match_pk */ + {336003100, "UPDATE OR INSERT field list does not match MATCHING clause"}, /* 705, upd_ins_doesnt_match_matching */ + {336003101, "UPDATE OR INSERT without MATCHING could not be used with views based on more than one table"}, /* 706, upd_ins_with_complex_view */ + {336003102, "Incompatible trigger type"}, /* 707, dsql_incompatible_trigger_type */ + {336003103, "Database trigger type can't be changed"}, /* 708, dsql_db_trigger_type_cant_change */ + {336068740, "Table @1 already exists"}, /* 709, dyn_dup_table */ + {336068784, "column @1 does not exist in table/view @2"}, /* 710, dyn_column_does_not_exist */ + {336068796, "SQL role @1 does not exist"}, /* 711, dyn_role_does_not_exist */ + {336068797, "user @1 has no grant admin option on SQL role @2"}, /* 712, dyn_no_grant_admin_opt */ + {336068798, "user @1 is not a member of SQL role @2"}, /* 713, dyn_user_not_role_member */ + {336068799, "@1 is not the owner of SQL role @2"}, /* 714, dyn_delete_role_failed */ + {336068800, "@1 is a SQL role and not a user"}, /* 715, dyn_grant_role_to_user */ + {336068801, "user name @1 could not be used for SQL role"}, /* 716, dyn_inv_sql_role_name */ + {336068802, "SQL role @1 already exists"}, /* 717, dyn_dup_sql_role */ + {336068803, "keyword @1 can not be used as a SQL role name"}, /* 718, dyn_kywd_spec_for_role */ + {336068804, "SQL roles are not supported in on older versions of the database. A backup and restore of the database is required."}, /* 719, dyn_roles_not_supported */ + {336068812, "Cannot rename domain @1 to @2. A domain with that name already exists."}, /* 720, dyn_domain_name_exists */ + {336068813, "Cannot rename column @1 to @2. A column with that name already exists in table @3."}, /* 721, dyn_field_name_exists */ + {336068814, "Column @1 from table @2 is referenced in @3"}, /* 722, dyn_dependency_exists */ + {336068815, "Cannot change datatype for column @1. Changing datatype is not supported for BLOB or ARRAY columns."}, /* 723, dyn_dtype_invalid */ + {336068816, "New size specified for column @1 must be at least @2 characters."}, /* 724, dyn_char_fld_too_small */ + {336068817, "Cannot change datatype for @1. Conversion from base type @2 to @3 is not supported."}, /* 725, dyn_invalid_dtype_conversion */ + {336068818, "Cannot change datatype for column @1 from a character type to a non-character type."}, /* 726, dyn_dtype_conv_invalid */ + {336068820, "Zero length identifiers are not allowed"}, /* 727, dyn_zero_len_id */ + {336068829, "Maximum number of collations per character set exceeded"}, /* 728, max_coll_per_charset */ + {336068830, "Invalid collation attributes"}, /* 729, invalid_coll_attr */ + {336068840, "@1 cannot reference @2"}, /* 730, dyn_wrong_gtt_scope */ + {336068852, "New scale specified for column @1 must be at most @2."}, /* 731, dyn_scale_too_big */ + {336068853, "New precision specified for column @1 must be at least @2."}, /* 732, dyn_precision_too_small */ + {336068855, "Warning: @1 on @2 is not granted to @3."}, /* 733, dyn_miss_priv_warning */ + {336068856, "Feature '@1' is not supported in ODS @2.@3"}, /* 734, dyn_ods_not_supp_feature */ + {336068857, "Cannot add or remove COMPUTED from column @1"}, /* 735, dyn_cannot_addrem_computed */ + {336068858, "Password should not be empty string"}, /* 736, dyn_no_empty_pw */ + {336068859, "Index @1 already exists"}, /* 737, dyn_dup_index */ + {336330753, "found unknown switch"}, /* 738, gbak_unknown_switch */ + {336330754, "page size parameter missing"}, /* 739, gbak_page_size_missing */ + {336330755, "Page size specified (@1) greater than limit (16384 bytes)"}, /* 740, gbak_page_size_toobig */ + {336330756, "redirect location for output is not specified"}, /* 741, gbak_redir_ouput_missing */ + {336330757, "conflicting switches for backup/restore"}, /* 742, gbak_switches_conflict */ + {336330758, "device type @1 not known"}, /* 743, gbak_unknown_device */ + {336330759, "protection is not there yet"}, /* 744, gbak_no_protection */ + {336330760, "page size is allowed only on restore or create"}, /* 745, gbak_page_size_not_allowed */ + {336330761, "multiple sources or destinations specified"}, /* 746, gbak_multi_source_dest */ + {336330762, "requires both input and output filenames"}, /* 747, gbak_filename_missing */ + {336330763, "input and output have the same name. Disallowed."}, /* 748, gbak_dup_inout_names */ + {336330764, "expected page size, encountered \"@1\""}, /* 749, gbak_inv_page_size */ + {336330765, "REPLACE specified, but the first file @1 is a database"}, /* 750, gbak_db_specified */ + {336330766, "database @1 already exists. To replace it, use the -REP switch"}, /* 751, gbak_db_exists */ + {336330767, "device type not specified"}, /* 752, gbak_unk_device */ + {336330772, "gds_$blob_info failed"}, /* 753, gbak_blob_info_failed */ + {336330773, "do not understand BLOB INFO item @1"}, /* 754, gbak_unk_blob_item */ + {336330774, "gds_$get_segment failed"}, /* 755, gbak_get_seg_failed */ + {336330775, "gds_$close_blob failed"}, /* 756, gbak_close_blob_failed */ + {336330776, "gds_$open_blob failed"}, /* 757, gbak_open_blob_failed */ + {336330777, "Failed in put_blr_gen_id"}, /* 758, gbak_put_blr_gen_id_failed */ + {336330778, "data type @1 not understood"}, /* 759, gbak_unk_type */ + {336330779, "gds_$compile_request failed"}, /* 760, gbak_comp_req_failed */ + {336330780, "gds_$start_request failed"}, /* 761, gbak_start_req_failed */ + {336330781, "gds_$receive failed"}, /* 762, gbak_rec_failed */ + {336330782, "gds_$release_request failed"}, /* 763, gbak_rel_req_failed */ + {336330783, "gds_$database_info failed"}, /* 764, gbak_db_info_failed */ + {336330784, "Expected database description record"}, /* 765, gbak_no_db_desc */ + {336330785, "failed to create database @1"}, /* 766, gbak_db_create_failed */ + {336330786, "RESTORE: decompression length error"}, /* 767, gbak_decomp_len_error */ + {336330787, "cannot find table @1"}, /* 768, gbak_tbl_missing */ + {336330788, "Cannot find column for BLOB"}, /* 769, gbak_blob_col_missing */ + {336330789, "gds_$create_blob failed"}, /* 770, gbak_create_blob_failed */ + {336330790, "gds_$put_segment failed"}, /* 771, gbak_put_seg_failed */ + {336330791, "expected record length"}, /* 772, gbak_rec_len_exp */ + {336330792, "wrong length record, expected @1 encountered @2"}, /* 773, gbak_inv_rec_len */ + {336330793, "expected data attribute"}, /* 774, gbak_exp_data_type */ + {336330794, "Failed in store_blr_gen_id"}, /* 775, gbak_gen_id_failed */ + {336330795, "do not recognize record type @1"}, /* 776, gbak_unk_rec_type */ + {336330796, "Expected backup version 1..8. Found @1"}, /* 777, gbak_inv_bkup_ver */ + {336330797, "expected backup description record"}, /* 778, gbak_missing_bkup_desc */ + {336330798, "string truncated"}, /* 779, gbak_string_trunc */ + {336330799, "warning -- record could not be restored"}, /* 780, gbak_cant_rest_record */ + {336330800, "gds_$send failed"}, /* 781, gbak_send_failed */ + {336330801, "no table name for data"}, /* 782, gbak_no_tbl_name */ + {336330802, "unexpected end of file on backup file"}, /* 783, gbak_unexp_eof */ + {336330803, "database format @1 is too old to restore to"}, /* 784, gbak_db_format_too_old */ + {336330804, "array dimension for column @1 is invalid"}, /* 785, gbak_inv_array_dim */ + {336330807, "Expected XDR record length"}, /* 786, gbak_xdr_len_expected */ + {336330817, "cannot open backup file @1"}, /* 787, gbak_open_bkup_error */ + {336330818, "cannot open status and error output file @1"}, /* 788, gbak_open_error */ + {336330934, "blocking factor parameter missing"}, /* 789, gbak_missing_block_fac */ + {336330935, "expected blocking factor, encountered \"@1\""}, /* 790, gbak_inv_block_fac */ + {336330936, "a blocking factor may not be used in conjunction with device CT"}, /* 791, gbak_block_fac_specified */ + {336330940, "user name parameter missing"}, /* 792, gbak_missing_username */ + {336330941, "password parameter missing"}, /* 793, gbak_missing_password */ + {336330952, " missing parameter for the number of bytes to be skipped"}, /* 794, gbak_missing_skipped_bytes */ + {336330953, "expected number of bytes to be skipped, encountered \"@1\""}, /* 795, gbak_inv_skipped_bytes */ + {336330965, "character set"}, /* 796, gbak_err_restore_charset */ + {336330967, "collation"}, /* 797, gbak_err_restore_collation */ + {336330972, "Unexpected I/O error while reading from backup file"}, /* 798, gbak_read_error */ + {336330973, "Unexpected I/O error while writing to backup file"}, /* 799, gbak_write_error */ + {336330985, "could not drop database @1 (database might be in use)"}, /* 800, gbak_db_in_use */ + {336330990, "System memory exhausted"}, /* 801, gbak_sysmemex */ + {336331002, "SQL role"}, /* 802, gbak_restore_role_failed */ + {336331005, "SQL role parameter missing"}, /* 803, gbak_role_op_missing */ + {336331010, "page buffers parameter missing"}, /* 804, gbak_page_buffers_missing */ + {336331011, "expected page buffers, encountered \"@1\""}, /* 805, gbak_page_buffers_wrong_param */ + {336331012, "page buffers is allowed only on restore or create"}, /* 806, gbak_page_buffers_restore */ + {336331014, "size specification either missing or incorrect for file @1"}, /* 807, gbak_inv_size */ + {336331015, "file @1 out of sequence"}, /* 808, gbak_file_outof_sequence */ + {336331016, "can't join -- one of the files missing"}, /* 809, gbak_join_file_missing */ + {336331017, " standard input is not supported when using join operation"}, /* 810, gbak_stdin_not_supptd */ + {336331018, "standard output is not supported when using split operation"}, /* 811, gbak_stdout_not_supptd */ + {336331019, "backup file @1 might be corrupt"}, /* 812, gbak_bkup_corrupt */ + {336331020, "database file specification missing"}, /* 813, gbak_unk_db_file_spec */ + {336331021, "can't write a header record to file @1"}, /* 814, gbak_hdr_write_failed */ + {336331022, "free disk space exhausted"}, /* 815, gbak_disk_space_ex */ + {336331023, "file size given (@1) is less than minimum allowed (@2)"}, /* 816, gbak_size_lt_min */ + {336331025, "service name parameter missing"}, /* 817, gbak_svc_name_missing */ + {336331026, "Cannot restore over current database, must be SYSDBA or owner of the existing database."}, /* 818, gbak_not_ownr */ + {336331031, "\"read_only\" or \"read_write\" required"}, /* 819, gbak_mode_req */ + {336331033, "just data ignore all constraints etc."}, /* 820, gbak_just_data */ + {336331034, "restoring data only ignoring foreign key, unique, not null & other constraints"}, /* 821, gbak_data_only */ + {336397205, "ODS versions before ODS@1 are not supported"}, /* 822, dsql_too_old_ods */ + {336397206, "Table @1 does not exist"}, /* 823, dsql_table_not_found */ + {336397207, "View @1 does not exist"}, /* 824, dsql_view_not_found */ + {336397208, "At line @1, column @2"}, /* 825, dsql_line_col_error */ + {336397209, "At unknown line and column"}, /* 826, dsql_unknown_pos */ + {336397210, "Column @1 cannot be repeated in @2 statement"}, /* 827, dsql_no_dup_name */ + {336397211, "Too many values (more than @1) in member list to match against"}, /* 828, dsql_too_many_values */ + {336397212, "Array and BLOB data types not allowed in computed field"}, /* 829, dsql_no_array_computed */ + {336397213, "Implicit domain name @1 not allowed in user created domain"}, /* 830, dsql_implicit_domain_name */ + {336397214, "scalar operator used on field @1 which is not an array"}, /* 831, dsql_only_can_subscript_array */ + {336397215, "cannot sort on more than 255 items"}, /* 832, dsql_max_sort_items */ + {336397216, "cannot group on more than 255 items"}, /* 833, dsql_max_group_items */ + {336397217, "Cannot include the same field (@1.@2) twice in the ORDER BY clause with conflicting sorting options"}, /* 834, dsql_conflicting_sort_field */ + {336397218, "column list from derived table @1 has more columns than the number of items in its SELECT statement"}, /* 835, dsql_derived_table_more_columns */ + {336397219, "column list from derived table @1 has less columns than the number of items in its SELECT statement"}, /* 836, dsql_derived_table_less_columns */ + {336397220, "no column name specified for column number @1 in derived table @2"}, /* 837, dsql_derived_field_unnamed */ + {336397221, "column @1 was specified multiple times for derived table @2"}, /* 838, dsql_derived_field_dup_name */ + {336397222, "Internal dsql error: alias type expected by pass1_expand_select_node"}, /* 839, dsql_derived_alias_select */ + {336397223, "Internal dsql error: alias type expected by pass1_field"}, /* 840, dsql_derived_alias_field */ + {336397224, "Internal dsql error: column position out of range in pass1_union_auto_cast"}, /* 841, dsql_auto_field_bad_pos */ + {336397225, "Recursive CTE member (@1) can refer itself only in FROM clause"}, /* 842, dsql_cte_wrong_reference */ + {336397226, "CTE '@1' has cyclic dependencies"}, /* 843, dsql_cte_cycle */ + {336397227, "Recursive member of CTE can't be member of an outer join"}, /* 844, dsql_cte_outer_join */ + {336397228, "Recursive member of CTE can't reference itself more than once"}, /* 845, dsql_cte_mult_references */ + {336397229, "Recursive CTE (@1) must be an UNION"}, /* 846, dsql_cte_not_a_union */ + {336397230, "CTE '@1' defined non-recursive member after recursive"}, /* 847, dsql_cte_nonrecurs_after_recurs */ + {336397231, "Recursive member of CTE '@1' has @2 clause"}, /* 848, dsql_cte_wrong_clause */ + {336397232, "Recursive members of CTE (@1) must be linked with another members via UNION ALL"}, /* 849, dsql_cte_union_all */ + {336397233, "Non-recursive member is missing in CTE '@1'"}, /* 850, dsql_cte_miss_nonrecursive */ + {336397234, "WITH clause can't be nested"}, /* 851, dsql_cte_nested_with */ + {336397235, "column @1 appears more than once in USING clause"}, /* 852, dsql_col_more_than_once_using */ + {336397236, "feature is not supported in dialect @1"}, /* 853, dsql_unsupp_feature_dialect */ + {336397237, "CTE \"@1\" is not used in query"}, /* 854, dsql_cte_not_used */ + {336397238, "column @1 appears more than once in ALTER VIEW"}, /* 855, dsql_col_more_than_once_view */ + {336397239, "@1 is not supported inside IN AUTONOMOUS TRANSACTION block"}, /* 856, dsql_unsupported_in_auto_trans */ + {336397240, "Unknown node type @1 in dsql/GEN_expr"}, /* 857, dsql_eval_unknode */ + {336397241, "Argument for @1 in dialect 1 must be string or numeric"}, /* 858, dsql_agg_wrongarg */ + {336397242, "Argument for @1 in dialect 3 must be numeric"}, /* 859, dsql_agg2_wrongarg */ + {336397243, "Strings cannot be added to or subtracted from DATE or TIME types"}, /* 860, dsql_nodateortime_pm_string */ + {336397244, "Invalid data type for subtraction involving DATE, TIME or TIMESTAMP types"}, /* 861, dsql_invalid_datetime_subtract */ + {336397245, "Adding two DATE values or two TIME values is not allowed"}, /* 862, dsql_invalid_dateortime_add */ + {336397246, "DATE value cannot be subtracted from the provided data type"}, /* 863, dsql_invalid_type_minus_date */ + {336397247, "Strings cannot be added or subtracted in dialect 3"}, /* 864, dsql_nostring_addsub_dial3 */ + {336397248, "Invalid data type for addition or subtraction in dialect 3"}, /* 865, dsql_invalid_type_addsub_dial3 */ + {336397249, "Invalid data type for multiplication in dialect 1"}, /* 866, dsql_invalid_type_multip_dial1 */ + {336397250, "Strings cannot be multiplied in dialect 3"}, /* 867, dsql_nostring_multip_dial3 */ + {336397251, "Invalid data type for multiplication in dialect 3"}, /* 868, dsql_invalid_type_multip_dial3 */ + {336397252, "Division in dialect 1 must be between numeric data types"}, /* 869, dsql_mustuse_numeric_div_dial1 */ + {336397253, "Strings cannot be divided in dialect 3"}, /* 870, dsql_nostring_div_dial3 */ + {336397254, "Invalid data type for division in dialect 3"}, /* 871, dsql_invalid_type_div_dial3 */ + {336397255, "Strings cannot be negated (applied the minus operator) in dialect 3"}, /* 872, dsql_nostring_neg_dial3 */ + {336397256, "Invalid data type for negation (minus operator)"}, /* 873, dsql_invalid_type_neg */ + {336723983, "unable to open database"}, /* 874, gsec_cant_open_db */ + {336723984, "error in switch specifications"}, /* 875, gsec_switches_error */ + {336723985, "no operation specified"}, /* 876, gsec_no_op_spec */ + {336723986, "no user name specified"}, /* 877, gsec_no_usr_name */ + {336723987, "add record error"}, /* 878, gsec_err_add */ + {336723988, "modify record error"}, /* 879, gsec_err_modify */ + {336723989, "find/modify record error"}, /* 880, gsec_err_find_mod */ + {336723990, "record not found for user: @1"}, /* 881, gsec_err_rec_not_found */ + {336723991, "delete record error"}, /* 882, gsec_err_delete */ + {336723992, "find/delete record error"}, /* 883, gsec_err_find_del */ + {336723996, "find/display record error"}, /* 884, gsec_err_find_disp */ + {336723997, "invalid parameter, no switch defined"}, /* 885, gsec_inv_param */ + {336723998, "operation already specified"}, /* 886, gsec_op_specified */ + {336723999, "password already specified"}, /* 887, gsec_pw_specified */ + {336724000, "uid already specified"}, /* 888, gsec_uid_specified */ + {336724001, "gid already specified"}, /* 889, gsec_gid_specified */ + {336724002, "project already specified"}, /* 890, gsec_proj_specified */ + {336724003, "organization already specified"}, /* 891, gsec_org_specified */ + {336724004, "first name already specified"}, /* 892, gsec_fname_specified */ + {336724005, "middle name already specified"}, /* 893, gsec_mname_specified */ + {336724006, "last name already specified"}, /* 894, gsec_lname_specified */ + {336724008, "invalid switch specified"}, /* 895, gsec_inv_switch */ + {336724009, "ambiguous switch specified"}, /* 896, gsec_amb_switch */ + {336724010, "no operation specified for parameters"}, /* 897, gsec_no_op_specified */ + {336724011, "no parameters allowed for this operation"}, /* 898, gsec_params_not_allowed */ + {336724012, "incompatible switches specified"}, /* 899, gsec_incompat_switch */ + {336724044, "Invalid user name (maximum 31 bytes allowed)"}, /* 900, gsec_inv_username */ + {336724045, "Warning - maximum 8 significant bytes of password used"}, /* 901, gsec_inv_pw_length */ + {336724046, "database already specified"}, /* 902, gsec_db_specified */ + {336724047, "database administrator name already specified"}, /* 903, gsec_db_admin_specified */ + {336724048, "database administrator password already specified"}, /* 904, gsec_db_admin_pw_specified */ + {336724049, "SQL role name already specified"}, /* 905, gsec_sql_role_specified */ + {336789504, "The license file does not exist or could not be opened for read"}, /* 906, license_no_file */ + {336789523, "operation already specified"}, /* 907, license_op_specified */ + {336789524, "no operation specified"}, /* 908, license_op_missing */ + {336789525, "invalid switch"}, /* 909, license_inv_switch */ + {336789526, "invalid switch combination"}, /* 910, license_inv_switch_combo */ + {336789527, "illegal operation/switch combination"}, /* 911, license_inv_op_combo */ + {336789528, "ambiguous switch"}, /* 912, license_amb_switch */ + {336789529, "invalid parameter, no switch specified"}, /* 913, license_inv_parameter */ + {336789530, "switch does not take any parameter"}, /* 914, license_param_specified */ + {336789531, "switch requires a parameter"}, /* 915, license_param_req */ + {336789532, "syntax error in command line"}, /* 916, license_syntx_error */ + {336789534, "The certificate was not added. A duplicate ID exists in the license file."}, /* 917, license_dup_id */ + {336789535, "The certificate was not added. Invalid certificate ID / Key combination."}, /* 918, license_inv_id_key */ + {336789536, "The certificate was not removed. The key does not exist or corresponds to a temporary evaluation license."}, /* 919, license_err_remove */ + {336789537, "An error occurred updating the license file. Operation cancelled."}, /* 920, license_err_update */ + {336789538, "The certificate could not be validated based on the information given. Please recheck the ID and key information."}, /* 921, license_err_convert */ + {336789539, "Operation failed. An unknown error occurred."}, /* 922, license_err_unk */ + {336789540, "Add license operation failed, KEY: @1 ID: @2"}, /* 923, license_svc_err_add */ + {336789541, "Remove license operation failed, KEY: @1"}, /* 924, license_svc_err_remove */ + {336789563, "The evaluation license has already been used on this server. You need to purchase a non-evaluation license."}, /* 925, license_eval_exists */ + {336920577, "found unknown switch"}, /* 926, gstat_unknown_switch */ + {336920578, "please retry, giving a database name"}, /* 927, gstat_retry */ + {336920579, "Wrong ODS version, expected @1, encountered @2"}, /* 928, gstat_wrong_ods */ + {336920580, "Unexpected end of database file."}, /* 929, gstat_unexpected_eof */ + {336920605, "Can't open database file @1"}, /* 930, gstat_open_err */ + {336920606, "Can't read a database page"}, /* 931, gstat_read_err */ + {336920607, "System memory exhausted"}, /* 932, gstat_sysmemex */ + {336986113, "Wrong value for access mode"}, /* 933, fbsvcmgr_bad_am */ + {336986114, "Wrong value for write mode"}, /* 934, fbsvcmgr_bad_wm */ + {336986115, "Wrong value for reserve space"}, /* 935, fbsvcmgr_bad_rs */ + {336986116, "Unknown tag (@1) in info_svr_db_info block after isc_svc_query()"}, /* 936, fbsvcmgr_info_err */ + {336986117, "Unknown tag (@1) in isc_svc_query() results"}, /* 937, fbsvcmgr_query_err */ + {336986118, "Unknown switch \"@1\""}, /* 938, fbsvcmgr_switch_unknown */ + {336986159, "Wrong value for shutdown mode"}, /* 939, fbsvcmgr_bad_sm */ + {337051649, "Switches trusted_svc and trusted_role are not supported from command line"}, /* 940, utl_trusted_switch */ {0, NULL} }; diff --git a/src/include/gen/sql_code.h b/src/include/gen/sql_code.h index de481def93..1ada7f6631 100644 --- a/src/include/gen/sql_code.h +++ b/src/include/gen/sql_code.h @@ -670,6 +670,7 @@ static const struct { {335544967, -833}, /* 647 sysf_argmustbe_nonneg */ {335544968, -833}, /* 648 sysf_binuuid_mustbe_str */ {335544969, -833}, /* 649 sysf_binuuid_wrongsize */ + {335544970, -902}, /* 650 missing_required_spb */ {335740929, -901}, /* 1 gfix_db_name */ {335740930, -901}, /* 2 gfix_invalid_sw */ {335740932, -901}, /* 4 gfix_incmp_sw */ diff --git a/src/include/gen/sql_state.h b/src/include/gen/sql_state.h index 3e0036621b..e9ba156a77 100644 --- a/src/include/gen/sql_state.h +++ b/src/include/gen/sql_state.h @@ -670,6 +670,7 @@ static const struct { {335544967, "42000"}, // 647 sysf_argmustbe_nonneg {335544968, "42000"}, // 648 sysf_binuuid_mustbe_str {335544969, "42000"}, // 649 sysf_binuuid_wrongsize + {335544970, "HY000"}, // 650 missing_required_spb {335740929, "00000"}, // 1 gfix_db_name {335740930, "00000"}, // 2 gfix_invalid_sw {335740932, "00000"}, // 4 gfix_incmp_sw diff --git a/src/msgs/facilities2.sql b/src/msgs/facilities2.sql index 387d4be147..7bed372109 100644 --- a/src/msgs/facilities2.sql +++ b/src/msgs/facilities2.sql @@ -1,7 +1,7 @@ /* MAX_NUMBER is the next number to be used, always one more than the highest message number. */ set bulk_insert INSERT INTO FACILITIES (LAST_CHANGE, FACILITY, FAC_CODE, MAX_NUMBER) VALUES (?, ?, ?, ?); -- -('2008-11-07 10:55:00', 'JRD', 0, 650) +('2008-11-20 20:01:41', 'JRD', 0, 651) ('2005-09-02 00:55:59', 'QLI', 1, 513) ('1996-11-07 13:38:37', 'GDEF', 2, 345) ('2007-04-07 13:11:00', 'GFIX', 3, 116) diff --git a/src/msgs/messages2.sql b/src/msgs/messages2.sql index 865439f923..2d1ddccbbb 100644 --- a/src/msgs/messages2.sql +++ b/src/msgs/messages2.sql @@ -754,6 +754,7 @@ Data source : @4', NULL, NULL) ('sysf_argmustbe_nonneg', 'evlSqrt', 'evl.cpp', NULL, 0, 647, NULL, 'Argument for @1 must be zero or positive', NULL, NULL) ('sysf_binuuid_mustbe_str', 'evlUuidToChar', 'evl.cpp', NULL, 0, 648, NULL, 'Binary UUID argument for @1 must be of string type', NULL, NULL) ('sysf_binuuid_wrongsize', 'evlUuidToChar', 'evl.cpp', NULL, 0, 649, NULL, 'Binary UUID argument for @2 must use @1 bytes', NULL, NULL) +('missing_required_spb', 'process_switches', 'svc.cpp', NULL, 0, 650, NULL, 'Missing required item @1 in service parameter block', NULL, NULL) --('', '', 'evl.cpp', NULL, 0, , NULL, '', NULL, NULL) -- End of extras for isc_expression_eval_err -- QLI diff --git a/src/msgs/system_errors2.sql b/src/msgs/system_errors2.sql index 240387ede8..ae311c1290 100644 --- a/src/msgs/system_errors2.sql +++ b/src/msgs/system_errors2.sql @@ -651,6 +651,7 @@ set bulk_insert INSERT INTO SYSTEM_ERRORS (SQL_CODE, SQL_CLASS, SQL_SUBCLASS, FA (-833, '42', '000', 0, 647, 'sysf_argmustbe_nonneg', NULL, NULL) (-833, '42', '000', 0, 648, 'sysf_binuuid_mustbe_str', NULL, NULL) (-833, '42', '000', 0, 649, 'sysf_binuuid_wrongsize', NULL, NULL) +(-902, 'HY', '000', 0, 650, 'missing_required_spb', NULL, NULL) -- End of expression_eval_err subcodes -- GFIX (-901, '00', '000', 3, 1, 'gfix_db_name', NULL, NULL) diff --git a/src/utilities/fbsvcmgr.cpp b/src/utilities/fbsvcmgr.cpp index ff4edbc5cb..791e2bfd47 100644 --- a/src/utilities/fbsvcmgr.cpp +++ b/src/utilities/fbsvcmgr.cpp @@ -349,6 +349,20 @@ const Switches addmodOptions[] = { {0, 0, 0, 0, 0} }; +const Switches nbackOptions[] = { + {"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_no_triggers", putOption, 0, isc_spb_nbk_no_triggers, 0}, + {0, 0, 0, 0, 0} +}; + +const Switches nrestOptions[] = { + {"dbname", putStringArgument, 0, isc_spb_dbname, 0}, + {"nbk_file", putStringArgument, 0, isc_spb_nbk_file, 0}, + {0, 0, 0, 0, 0} +}; + const Switches actionSwitch[] = { {"action_backup", putSingleTag, backupOptions, isc_action_svc_backup, isc_info_svc_line}, {"action_restore", putSingleTag, restoreOptions, isc_action_svc_restore, isc_info_svc_line}, @@ -360,6 +374,8 @@ const Switches actionSwitch[] = { {"action_add_user", putSingleTag, addmodOptions, isc_action_svc_add_user, 0}, {"action_delete_user", putSingleTag, dispdelOptions, isc_action_svc_delete_user, 0}, {"action_modify_user", putSingleTag, addmodOptions, isc_action_svc_modify_user, 0}, + {"action_nbak", putSingleTag, nbackOptions, isc_action_svc_nbak, 0}, + {"action_nrest", putSingleTag, nrestOptions, isc_action_svc_nrest, 0}, {0, 0, 0, 0, 0} }; diff --git a/src/utilities/nbackup.cpp b/src/utilities/nbackup.cpp index fb4b2ec7ad..e192e652f5 100644 --- a/src/utilities/nbackup.cpp +++ b/src/utilities/nbackup.cpp @@ -28,12 +28,13 @@ */ -// firebird.h must go first because otherwise we'll not get 64-bit IO #include "firebird.h" + #include #include #include #include + #include "../jrd/common.h" #include "../jrd/db_alias.h" #include "../jrd/ods.h" @@ -45,6 +46,7 @@ #include "../common/utils_proto.h" #include "../common/classes/array.h" #include "../common/classes/ClumpletWriter.h" +#include "../utilities/nbackup/nbk_proto.h" #ifdef HAVE_UNISTD_H #include @@ -62,17 +64,26 @@ #define O_LARGEFILE 0 #endif -const int EXIT_OK = 0; -const int EXIT_ERROR = 1; - // How much we align memory when reading database header. // Sector alignment of memory is necessary to use unbuffered IO on Windows. // Actually, sectors may be bigger than 1K, but let's be consistent with // JRD regarding the matter for the moment. const size_t SECTOR_ALIGNMENT = MIN_PAGE_SIZE; -void usage() +using namespace Firebird; + +void usage(UtilSvc* uSvc, const char* message, ...) { + string msg; + va_list params; + va_start(params, message); + msg.vprintf(message, params); + va_end(params); + + if (uSvc->isService()) + (Arg::Gds(isc_random) << msg).raise(); + + fprintf(stderr, "ERROR: %s.\n\n", msg.c_str()); fprintf(stderr, "Physical Backup Manager Copyright (C) 2004 Firebird development team\n" " Original idea is of Sean Leyne \n" @@ -94,15 +105,29 @@ void usage() " incremental backups of multi-file databases are not supported yet\n" " \"stdout\" may be used as a value of for -B option\n" ); - exit(EXIT_ERROR); + exit(FINI_ERROR); } -void missing_parameter_for_switch(const char* sw) { - fprintf(stderr, "ERROR: Missing parameter for switch %s.\n\n", sw); - usage(); +void missing_parameter_for_switch(UtilSvc* uSvc, const char* sw) +{ + usage(uSvc, "Missing parameter for switch %s", sw); } -class b_error : public Firebird::LongJump +void singleAction(UtilSvc* uSvc) +{ + usage(uSvc, "Only one of -L, -N, -F, -B or -R should be specified"); +} + +namespace +{ + const int MSG_LEN = 1024; + const size_t NBACKUP_FAILURE_SPACE = MSG_LEN * 4; + typedef Firebird::CircularStringsBuffer NbkStringsBuffer; + GlobalPtr nbkStringsBuffer; + GlobalPtr nbkBufMutex; +} + +class b_error : public LongJump { public: explicit b_error(const char* message) @@ -111,10 +136,9 @@ public: strncpy(txt, message, len); txt[len] = 0; } - enum {MSG_LEN = 1024}; virtual ~b_error() throw() {} virtual const char* what() const throw() { return txt; } - static void raise(const char* message, ...) + static void raise(UtilSvc* uSvc, const char* message, ...) { char temp[MSG_LEN]; va_list params; @@ -122,9 +146,26 @@ public: VSNPRINTF(temp, sizeof(temp), message, params); temp[sizeof(temp) - 1] = 0; va_end(params); - fprintf(stderr, "Failure: %s\n", temp); + + if (!uSvc->isService()) + fprintf(stderr, "Failure: %s\n", temp); + throw b_error(temp); } + virtual ISC_STATUS stuff_exception(ISC_STATUS* const status_vector, StringsBuffer* sb = NULL) const throw() + { + if (! sb) + { + sb = &nbkStringsBuffer; + } + + (Arg::Gds(isc_random) << txt).copyTo(status_vector); + + MutexLockGuard guard(nbkBufMutex); + sb->makePermanentVector(status_vector, status_vector); + + return status_vector[1]; + } private: char txt[MSG_LEN]; }; @@ -155,53 +196,50 @@ struct inc_header ULONG prev_scn; // SCN of previous level backup }; -class nbackup +class NBackup { public: - nbackup(const char* _database, const char* _username, const char* _password, bool _run_db_triggers) + NBackup(UtilSvc* _uSvc, const PathName& _database, const string& _username, + const string& _password, bool _run_db_triggers, const string& _trustedUser, + bool _trustedRole) + : uSvc(_uSvc), newdb(0), trans(0), database(_database), + username(_username), password(_password), trustedUser(_trustedUser), + run_db_triggers(_run_db_triggers), trustedRole(_trustedRole), + dbase(0), backup(0), db_size_pages(0) { - if (_username) - username = _username; - - if (_password) - password = _password; - - database = _database; - run_db_triggers = _run_db_triggers; - - dbase = 0; - backup = 0; - db_size_pages = 0; - newdb = 0; - trans = 0; // Recognition of local prefix allows to work with // database using TCP/IP loopback while reading file locally. // This makes NBACKUP compatible with Windows CS with XNET disabled - if (strncmp(_database, local_prefix, sizeof(local_prefix) - 1) == 0) { - _database += sizeof(local_prefix) - 1; - } - if (!ResolveDatabaseAlias(_database, dbname)) - dbname = _database; + PathName db(_database); + if (strncmp(db.c_str(), local_prefix, sizeof(local_prefix) - 1) == 0) + db = db.substr(sizeof(local_prefix) - 1); + + if (!ResolveDatabaseAlias(db, dbname)) + dbname = db; } + + typedef ObjectsArray BackupFiles; + // External calls must clean up resources after themselves void fixup_database(); void lock_database(bool get_size); void unlock_database(); - void backup_database(int level, const char* fname); - void restore_database(int filecount, const char* const* files); + void backup_database(int level, const PathName& fname); + void restore_database(const BackupFiles& files); private: + UtilSvc* uSvc; + ISC_STATUS_ARRAY status; // status vector isc_db_handle newdb; // database handle isc_tr_handle trans; // transaction handle - Firebird::PathName database; - Firebird::string username; - Firebird::string password; - bool run_db_triggers; + PathName database; + string username, password, trustedUser; + bool run_db_triggers, trustedRole; - Firebird::PathName dbname; // Database file name - Firebird::PathName bakname; + PathName dbname; // Database file name + PathName bakname; FILE_HANDLE dbase; FILE_HANDLE backup; ULONG db_size_pages; // In pages @@ -211,7 +249,7 @@ private: void write_file(FILE_HANDLE &file, void *buffer, size_t bufsize); void seek_file(FILE_HANDLE &file, SINT64 pos); - static void pr_error(const ISC_STATUS* status, const char* operation); + void pr_error(const ISC_STATUS* status, const char* operation); void internal_lock_database(); void get_database_size(); @@ -230,12 +268,12 @@ private: void close_backup(); }; -size_t nbackup::read_file(FILE_HANDLE &file, void *buffer, size_t bufsize) +size_t NBackup::read_file(FILE_HANDLE &file, void *buffer, size_t bufsize) { #ifdef WIN_NT DWORD bytesDone; if (!ReadFile(file, buffer, bufsize, &bytesDone, NULL)) - b_error::raise("IO error (%d) reading file: %s", + b_error::raise(uSvc, "IO error (%d) reading file: %s", GetLastError(), &file == &dbase ? dbname.c_str() : &file == &backup ? bakname.c_str() : "unknown"); @@ -243,7 +281,7 @@ size_t nbackup::read_file(FILE_HANDLE &file, void *buffer, size_t bufsize) #else const ssize_t res = read(file, buffer, bufsize); if (res < 0) - b_error::raise("IO error (%d) reading file: %s", + b_error::raise(uSvc, "IO error (%d) reading file: %s", errno, &file == &dbase ? dbname.c_str() : &file == &backup ? bakname.c_str() : "unknown"); @@ -251,28 +289,28 @@ size_t nbackup::read_file(FILE_HANDLE &file, void *buffer, size_t bufsize) #endif } -void nbackup::write_file(FILE_HANDLE &file, void *buffer, size_t bufsize) +void NBackup::write_file(FILE_HANDLE &file, void *buffer, size_t bufsize) { #ifdef WIN_NT DWORD bytesDone; if (!WriteFile(file, buffer, bufsize, &bytesDone, NULL) || bytesDone != bufsize) { - b_error::raise("IO error (%d) writing file: %s", + b_error::raise(uSvc, "IO error (%d) writing file: %s", GetLastError(), &file == &dbase ? dbname.c_str() : &file == &backup ? bakname.c_str() : "unknown"); } #else if (write(file, buffer, bufsize) != (ssize_t)bufsize) - b_error::raise("IO error (%d) writing file: %s", + b_error::raise(uSvc, "IO error (%d) writing file: %s", errno, &file == &dbase ? dbname.c_str() : &file == &backup ? bakname.c_str() : "unknown"); #endif } -void nbackup::seek_file(FILE_HANDLE &file, SINT64 pos) +void NBackup::seek_file(FILE_HANDLE &file, SINT64 pos) { #ifdef WIN_NT LARGE_INTEGER offset; @@ -282,36 +320,36 @@ void nbackup::seek_file(FILE_HANDLE &file, SINT64 pos) FILE_BEGIN) == INVALID_SET_FILE_POINTER && (error = GetLastError()) != NO_ERROR) { - b_error::raise("IO error (%d) seeking file: %s", + b_error::raise(uSvc, "IO error (%d) seeking file: %s", error, &file == &dbase ? dbname.c_str() : &file == &backup ? bakname.c_str() : "unknown"); } #else if (lseek(file, pos, SEEK_SET) == (off_t) - 1) - b_error::raise("IO error (%d) seeking file: %s", + b_error::raise(uSvc, "IO error (%d) seeking file: %s", errno, &file == &dbase ? dbname.c_str() : &file == &backup ? bakname.c_str() : "unknown"); #endif } -void nbackup::open_database_write() +void NBackup::open_database_write() { #ifdef WIN_NT 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); if (dbase == INVALID_HANDLE_VALUE) - b_error::raise("Error (%d) opening database file: %s", GetLastError(), dbname.c_str()); + b_error::raise(uSvc, "Error (%d) opening database file: %s", GetLastError(), dbname.c_str()); #else dbase = open(dbname.c_str(), O_RDWR | O_LARGEFILE); if (dbase < 0) - b_error::raise("Error (%d) opening database file: %s", errno, dbname.c_str()); + b_error::raise(uSvc, "Error (%d) opening database file: %s", errno, dbname.c_str()); #endif } -void nbackup::open_database_scan() +void NBackup::open_database_scan() { #ifdef WIN_NT // On Windows we use unbuffered IO to work around bug in Windows Server 2003 @@ -326,29 +364,29 @@ void nbackup::open_database_scan() FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN | FILE_FLAG_NO_BUFFERING, NULL); if (dbase == INVALID_HANDLE_VALUE) - b_error::raise("Error (%d) opening database file: %s", GetLastError(), dbname.c_str()); + b_error::raise(uSvc, "Error (%d) opening database file: %s", GetLastError(), dbname.c_str()); #else dbase = open(dbname.c_str(), O_RDONLY | O_LARGEFILE); if (dbase < 0) - b_error::raise("Error (%d) opening database file: %s", errno, dbname.c_str()); + b_error::raise(uSvc, "Error (%d) opening database file: %s", errno, dbname.c_str()); #endif } -void nbackup::create_database() +void NBackup::create_database() { #ifdef WIN_NT dbase = CreateFile(dbname.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_DELETE, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); if (dbase == INVALID_HANDLE_VALUE) - b_error::raise("Error (%d) creating database file: %s", GetLastError(), dbname.c_str()); + b_error::raise(uSvc, "Error (%d) creating database file: %s", GetLastError(), dbname.c_str()); #else dbase = open(dbname.c_str(), O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE, 0660); if (dbase < 0) - b_error::raise("Error (%d) creating database file: %s", errno, dbname.c_str()); + b_error::raise(uSvc, "Error (%d) creating database file: %s", errno, dbname.c_str()); #endif } -void nbackup::close_database() +void NBackup::close_database() { #ifdef WIN_NT CloseHandle(dbase); @@ -357,21 +395,21 @@ void nbackup::close_database() #endif } -void nbackup::open_backup_scan() +void NBackup::open_backup_scan() { #ifdef WIN_NT backup = CreateFile(bakname.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); if (backup == INVALID_HANDLE_VALUE) - b_error::raise("Error (%d) opening backup file: %s", GetLastError(), bakname.c_str()); + b_error::raise(uSvc, "Error (%d) opening backup file: %s", GetLastError(), bakname.c_str()); #else backup = open(bakname.c_str(), O_RDONLY | O_LARGEFILE); if (backup < 0) - b_error::raise("Error (%d) opening backup file: %s", errno, bakname.c_str()); + b_error::raise(uSvc, "Error (%d) opening backup file: %s", errno, bakname.c_str()); #endif } -void nbackup::create_backup() +void NBackup::create_backup() { #ifdef WIN_NT if (bakname == "stdout") { @@ -382,7 +420,7 @@ void nbackup::create_backup() NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); } if (backup == INVALID_HANDLE_VALUE) - b_error::raise("Error (%d) creating backup file: %s", GetLastError(), bakname.c_str()); + b_error::raise(uSvc, "Error (%d) creating backup file: %s", GetLastError(), bakname.c_str()); #else if (bakname == "stdout") { backup = 1; // Posix file handle for stdout @@ -390,12 +428,12 @@ void nbackup::create_backup() else { backup = open(bakname.c_str(), O_WRONLY | O_CREAT | O_EXCL | O_LARGEFILE, 0660); if (backup < 0) - b_error::raise("Error (%d) creating backup file: %s", errno, bakname.c_str()); + b_error::raise(uSvc, "Error (%d) creating backup file: %s", errno, bakname.c_str()); } #endif } -void nbackup::close_backup() +void NBackup::close_backup() { if (bakname == "stdout") return; @@ -406,15 +444,15 @@ void nbackup::close_backup() #endif } -void nbackup::fixup_database() +void NBackup::fixup_database() { open_database_write(); Ods::header_page header; if (read_file(dbase, &header, sizeof(header)) != sizeof(header)) - b_error::raise("Unexpected end of database file", errno); + b_error::raise(uSvc, "Unexpected end of database file", errno); const int backup_state = header.hdr_flags & Ods::hdr_backup_mask; if (backup_state != Jrd::nbak_state_stalled) - b_error::raise("Database is not in state (%d) to be safely fixed up", backup_state); + b_error::raise(uSvc, "Database is not in state (%d) to be safely fixed up", backup_state); header.hdr_flags = (header.hdr_flags & ~Ods::hdr_backup_mask) | Jrd::nbak_state_normal; seek_file(dbase, 0); write_file(dbase, &header, sizeof(header)); @@ -425,8 +463,11 @@ void nbackup::fixup_database() * Print the status, the SQLCODE, and exit. * Also, indicate which operation the error occured on. */ -void nbackup::pr_error (const ISC_STATUS* status, const char* operation) +void NBackup::pr_error (const ISC_STATUS* status, const char* operation) { + if (uSvc->isService()) + status_exception::raise(status); + printf("[\n"); printf("PROBLEM ON \"%s\".\n", operation); @@ -436,24 +477,34 @@ void nbackup::pr_error (const ISC_STATUS* status, const char* operation) printf("]\n"); - b_error::raise("Database error"); + b_error::raise(uSvc, "Database error"); } -void nbackup::attach_database() +void NBackup::attach_database() { if (username.length() > 255 || password.length() > 255) - b_error::raise("Username or password is too long"); + b_error::raise(uSvc, "Username or password is too long"); - Firebird::ClumpletWriter dpb(Firebird::ClumpletReader::Tagged, MAX_DPB_SIZE, isc_dpb_version1); + ClumpletWriter dpb(ClumpletReader::Tagged, MAX_DPB_SIZE, isc_dpb_version1); - if (!username.isEmpty()) { + if (username.hasData()) { dpb.insertString(isc_dpb_user_name, username); } - if (!password.isEmpty()) { + if (password.hasData()) { dpb.insertString(isc_dpb_password, password); } + if (trustedUser.hasData()) { + uSvc->checkService(); + dpb.insertString(isc_dpb_trusted_auth, trustedUser); + } + + if (trustedRole) { + uSvc->checkService(); + dpb.insertString(isc_dpb_trusted_role, ADMIN_ROLE, strlen(ADMIN_ROLE)); + } + if (!run_db_triggers) dpb.insertByte(isc_dpb_no_db_triggers, 1); @@ -464,7 +515,7 @@ void nbackup::attach_database() } } -void nbackup::detach_database() +void NBackup::detach_database() { if (trans) { if (isc_rollback_transaction(status, &trans)) @@ -474,7 +525,7 @@ void nbackup::detach_database() pr_error(status, "detach database"); } -void nbackup::internal_lock_database() +void NBackup::internal_lock_database() { if (isc_start_transaction(status, &trans, 1, &newdb, 0, NULL)) pr_error(status, "start transaction"); @@ -485,7 +536,7 @@ void nbackup::internal_lock_database() pr_error(status, "begin backup: commit"); } -void nbackup::get_database_size() +void NBackup::get_database_size() { db_size_pages = 0; char fs[] = {isc_info_db_file_size}; @@ -501,7 +552,7 @@ void nbackup::get_database_size() } } -void nbackup::internal_unlock_database() +void NBackup::internal_unlock_database() { if (isc_start_transaction(status, &trans, 1, &newdb, 0, NULL)) pr_error(status, "start transaction"); @@ -512,7 +563,7 @@ void nbackup::internal_unlock_database() pr_error(status, "end backup: commit"); } -void nbackup::lock_database(bool get_size) +void NBackup::lock_database(bool get_size) { attach_database(); db_size_pages = 0; @@ -521,31 +572,31 @@ void nbackup::lock_database(bool get_size) if (get_size) { get_database_size(); - if (db_size_pages) + if (db_size_pages && (!uSvc->isService())) printf("%d\n", db_size_pages); } } - catch (const Firebird::Exception&) { + catch (const Exception&) { detach_database(); throw; } detach_database(); } -void nbackup::unlock_database() +void NBackup::unlock_database() { attach_database(); try { internal_unlock_database(); } - catch (const Firebird::Exception&) { + catch (const Exception&) { detach_database(); throw; } detach_database(); } -void nbackup::backup_database(int level, const char* fname) +void NBackup::backup_database(int level, const PathName& fname) { bool database_locked = false; // We set this flag when backup file is in inconsistent state @@ -587,11 +638,11 @@ void nbackup::backup_database(int level, const char* fname) switch (isc_dsql_fetch(status, &stmt, 1, out_sqlda)) { case 100: // No more records available - b_error::raise("Cannot find record for database \"%s\" backup level %d " + b_error::raise(uSvc, "Cannot find record for database \"%s\" backup level %d " "in the backup history", database.c_str(), level - 1); case 0: if (guid_null || scn_null) - b_error::raise("Internal error. History query returned null SCN or GUID"); + b_error::raise(uSvc, "Internal error. History query returned null SCN or GUID"); prev_guid[sizeof(prev_guid) - 1] = 0; break; default: @@ -611,19 +662,17 @@ void nbackup::backup_database(int level, const char* fname) time_t _time = time(NULL); const struct tm *today = localtime(&_time); - if (fname) + if (fname.hasData()) bakname = fname; else { // Let's generate nice new filename - Firebird::PathName begin, fil; + PathName begin, fil; PathUtils::splitLastComponent(begin, fil, database); - char temp[MAXPATHLEN]; - SNPRINTF(temp, sizeof(temp), "%s-%d-%04d%02d%02d-%02d%02d.nbk", fil.c_str(), level, + 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); - temp[sizeof(temp) - 1] = 0; - bakname = temp; - printf("%s", bakname.c_str()); // Print out generated filename for script processing + if (!uSvc->isService()) + printf("%s", bakname.c_str()); // Print out generated filename for script processing } // Level 0 backup is a full reconstructed database image that can be @@ -651,14 +700,14 @@ void nbackup::backup_database(int level, const char* fname) reinterpret_cast( FB_ALIGN((IPTR) unaligned_header_buffer, SECTOR_ALIGNMENT)); if (read_file(dbase, header, SECTOR_ALIGNMENT/*sizeof(*header)*/) != SECTOR_ALIGNMENT/*sizeof(*header)*/) - b_error::raise("Unexpected end of file when reading header of database file"); + b_error::raise(uSvc, "Unexpected end of file when reading header of database file"); if ((header->hdr_flags & Ods::hdr_backup_mask) != Jrd::nbak_state_stalled) { - b_error::raise("Internal error. Database file is not locked. Flags are %d", + b_error::raise(uSvc, "Internal error. Database file is not locked. Flags are %d", header->hdr_flags); } - Firebird::Array unaligned_page_buffer; + Array unaligned_page_buffer; page_buff = reinterpret_cast( FB_ALIGN( (IPTR) unaligned_page_buffer.getBuffer( @@ -671,7 +720,7 @@ void nbackup::backup_database(int level, const char* fname) seek_file(dbase, 0); if (read_file(dbase, page_buff, header->hdr_page_size) != header->hdr_page_size) - b_error::raise("Unexpected end of file when reading header of database file (stage 2)"); + b_error::raise(uSvc, "Unexpected end of file when reading header of database file (stage 2)"); --db_size; FB_GUID backup_guid; @@ -693,7 +742,7 @@ void nbackup::backup_database(int level, const char* fname) } if (!guid_found) - b_error::raise("Internal error. Cannot get backup guid clumplet"); + b_error::raise(uSvc, "Internal error. Cannot get backup guid clumplet"); // Write data to backup file ULONG backup_scn = header->hdr_header.pag_scn - 1; @@ -726,7 +775,7 @@ void nbackup::backup_database(int level, const char* fname) while (true) { if (curPage && page_buff->pag_scn > backup_scn) - b_error::raise("Internal error. Database page %d had been changed during backup" + b_error::raise(uSvc, "Internal error. Database page %d had been changed during backup" " (page SCN=%d, backup SCN=%d)", curPage, page_buff->pag_scn, backup_scn); if (level) { @@ -746,7 +795,7 @@ void nbackup::backup_database(int level, const char* fname) if (bytesDone == 0) break; if (bytesDone != header->hdr_page_size) - b_error::raise("Database file size is not a multiply of page size"); + b_error::raise(uSvc, "Database file size is not a multiply of page size"); curPage++; if (isODS11_x && curPage == lastPage) @@ -819,7 +868,7 @@ void nbackup::backup_database(int level, const char* fname) pr_error(status, "commit history insert"); } - catch (const Firebird::Exception&) { + catch (const Exception&) { if (delete_backup) remove(bakname.c_str()); if (trans) { @@ -842,10 +891,11 @@ void nbackup::backup_database(int level, const char* fname) detach_database(); } -void nbackup::restore_database(int filecount, const char* const* files) +void NBackup::restore_database(const BackupFiles& files) { // We set this flag when database file is in inconsistent state bool delete_database = false; + int filecount = files.getCount(); #ifndef WIN_NT create_database(); delete_database = true; @@ -857,22 +907,28 @@ void nbackup::restore_database(int filecount, const char* const* files) while (true) { if (!filecount) { while (true) { - printf("Enter name of the backup file of level %d " - "(\".\" - do not restore further): \n", curLevel); - char temp[256]; - scanf("%255s", temp); - bakname = temp; + if (uSvc->isService()) + bakname = "."; + else + { + printf("Enter name of the backup file of level %d " + "(\".\" - do not restore further): \n", curLevel); + char temp[256]; + scanf("%255s", temp); + bakname = temp; + } if (bakname == ".") { close_database(); if (!curLevel) { remove(dbname.c_str()); - b_error::raise("Level 0 backup is not restored"); + b_error::raise(uSvc, "Level 0 backup is not restored"); } fixup_database(); delete[] page_buffer; return; } + // Never reach this posint when run as service try { #ifdef WIN_NT if (curLevel) @@ -880,7 +936,7 @@ void nbackup::restore_database(int filecount, const char* const* files) open_backup_scan(); break; } - catch (const Firebird::Exception& e) { + catch (const Exception& e) { printf("%s\n", e.what()); } } @@ -902,18 +958,18 @@ void nbackup::restore_database(int filecount, const char* const* files) if (curLevel) { inc_header bakheader; if (read_file(backup, &bakheader, sizeof(bakheader)) != sizeof(bakheader)) - b_error::raise("Unexpected end of file when reading header of backup file: %s", bakname.c_str()); + b_error::raise(uSvc, "Unexpected end of file when reading header of backup file: %s", bakname.c_str()); if (memcmp(bakheader.signature, backup_signature, sizeof(backup_signature)) != 0) - b_error::raise("Invalid incremental backup file: %s", bakname.c_str()); + b_error::raise(uSvc, "Invalid incremental backup file: %s", bakname.c_str()); if (bakheader.version != 1) - b_error::raise("Unsupported version %d of incremental backup file: %s", bakheader.version, bakname.c_str()); + b_error::raise(uSvc, "Unsupported version %d of incremental backup file: %s", bakheader.version, bakname.c_str()); if (bakheader.level != curLevel) - b_error::raise("Invalid level %d of incremental backup file: %s, expected %d", + b_error::raise(uSvc, "Invalid level %d of incremental backup file: %s, expected %d", bakheader.level, bakname.c_str(), curLevel); // We may also add SCN check, but GUID check covers this case too if (memcmp(&bakheader.prev_guid, &prev_guid, sizeof(FB_GUID)) != 0) { - b_error::raise( + b_error::raise(uSvc, "Wrong order of backup files or " "invalid incremental backup file detected, file: %s", bakname.c_str()); } @@ -927,7 +983,7 @@ void nbackup::restore_database(int filecount, const char* const* files) if (bytesDone != sizeof(pageNum) || read_file(backup, page_buffer, bakheader.page_size) != bakheader.page_size) { - b_error::raise("Unexpected end of backup file: %s", bakname.c_str()); + b_error::raise(uSvc, "Unexpected end of backup file: %s", bakname.c_str()); } seek_file(dbase, ((SINT64)pageNum)*bakheader.page_size); write_file(dbase, page_buffer, bakheader.page_size); @@ -937,7 +993,7 @@ void nbackup::restore_database(int filecount, const char* const* files) else { #ifdef WIN_NT if (!CopyFile(bakname.c_str(), dbname.c_str(), TRUE)) { - b_error::raise("Error (%d) creating database file: %s via copying from: %s", + b_error::raise(uSvc, "Error (%d) creating database file: %s via copying from: %s", GetLastError(), dbname.c_str(), bakname.c_str()); } delete_database = true; // database is possibly broken @@ -956,13 +1012,13 @@ void nbackup::restore_database(int filecount, const char* const* files) // Read database header Ods::header_page header; if (read_file(dbase, &header, sizeof(header)) != sizeof(header)) - b_error::raise("Unexpected end of file when reading restored database header"); + b_error::raise(uSvc, "Unexpected end of file when reading restored database header"); page_buffer = FB_NEW(*getDefaultMemoryPool()) UCHAR[header.hdr_page_size]; seek_file(dbase, 0); if (read_file(dbase, page_buffer, header.hdr_page_size) != header.hdr_page_size) - b_error::raise("Unexpected end of file when reading header of restored database file (stage 2)"); + b_error::raise(uSvc, "Unexpected end of file when reading header of restored database file (stage 2)"); bool guid_found = false; const UCHAR* p = reinterpret_cast(page_buffer)->hdr_data; @@ -981,7 +1037,7 @@ void nbackup::restore_database(int filecount, const char* const* files) break; } if (!guid_found) - b_error::raise("Cannot get backup guid clumplet from L0 backup"); + b_error::raise(uSvc, "Cannot get backup guid clumplet from L0 backup"); // We are likely to have normal database here delete_database = false; } @@ -992,7 +1048,7 @@ void nbackup::restore_database(int filecount, const char* const* files) curLevel++; } } - catch (const Firebird::Exception&) { + catch (const Exception&) { delete[] page_buffer; if (delete_database) remove(dbname.c_str()); @@ -1000,166 +1056,196 @@ void nbackup::restore_database(int filecount, const char* const* files) } } +THREAD_ENTRY_DECLARE NBACKUP_main(THREAD_ENTRY_PARAM arg) +{ + UtilSvc* uSvc = (UtilSvc*) arg; + int exit_code = FB_SUCCESS; + + try { + nbackup(uSvc); + } + catch (const Exception& e) + { + e.stuff_exception(uSvc->getStatus()); + exit_code = FB_FAILURE; + } + + uSvc->started(); + uSvc->finish(); + return (THREAD_ENTRY_RETURN)(IPTR) exit_code; +} + enum NbOperation {nbNone, nbLock, nbUnlock, nbFixup, nbBackup, nbRestore}; -int main( int argc, char *argv[] ) +void nbackup(UtilSvc* uSvc) { + UtilSvc::ArgvType& argv = uSvc->argv; + const int argc = uSvc->argv.getCount(); + #if defined DEV_BUILD && !defined WIN_NT - fprintf(stderr, "Using %d-bit UNIX IO\n", sizeof(off_t) * 8); + if (!uSvc->isService()) + fprintf(stderr, "Using %d-bit UNIX IO\n", sizeof(off_t) * 8); #endif - // Do not constify. GCC 3.4.0 chokes on minus below in this case - char **end = argv + argc; NbOperation op = nbNone; - const char *username = NULL, *password = NULL, *database = NULL, - *filename = NULL; + string username, password; + PathName database, filename; bool run_db_triggers = true; - const char* const* backup_files = NULL; + NBackup::BackupFiles backup_files; int level; int filecount; bool print_size = false; + string trustedUser; + bool trustedRole; - try { - // Read global command line parameters - for (char** argp = argv + 1; argp < end; argp++) { - // We must recognize all parameters here - if (**argp != '-') { - fprintf(stderr, "ERROR: Unrecognized parameter %s.\n\n", *argp); - usage(); + // Read global command line parameters + for (int itr = 1; itr < argc; ++itr) { + // We must recognize all parameters here + if (argv[itr][0] != '-') { + usage(uSvc, "Unrecognized parameter %s", argv[itr]); + } + + if (uSvc->isService()) + { + PathName sw = &argv[itr][1]; + if (sw == TRUSTED_USER_SWITCH) + { + if (++itr >= argc) + missing_parameter_for_switch(uSvc, argv[itr - 1]); + trustedUser = argv[itr]; + continue; } - - switch (UPPER((*argp)[1])) { - case 'U': - if (++argp >= end) - missing_parameter_for_switch(argp[-1]); - - username = *argp; - break; - - case 'P': - if (++argp >= end) - missing_parameter_for_switch(argp[-1]); - - password = fb_utils::get_passwd(*argp); - break; - - case 'T': - run_db_triggers = false; - break; - - case 'F': - if (op != nbNone) - usage(); - - if (++argp >= end) - missing_parameter_for_switch(argp[-1]); - - database = *argp; - op = nbFixup; - break; - - case 'L': - if (op != nbNone) - usage(); - - if (++argp >= end) - missing_parameter_for_switch(argp[-1]); - - database = *argp; - op = nbLock; - break; - - case 'N': - if (op != nbNone) - usage(); - - if (++argp >= end) - missing_parameter_for_switch(argp[-1]); - - database = *argp; - op = nbUnlock; - break; - - case 'B': { - if (op != nbNone) - usage(); - - if (++argp >= end) - missing_parameter_for_switch(argp[-1]); - - level = atoi(*argp); - - if (++argp >= end) - missing_parameter_for_switch(argp[-1]); - - database = *argp; - - if (argp + 1 < end) - filename = *(++argp); - - op = nbBackup; - break; - } - - case 'R': - if (op != nbNone) - usage(); - - if (++argp >= end) - missing_parameter_for_switch(argp[-1]); - - database = *argp; - filecount = end - argp - 1; - backup_files = argp + 1; - argp += filecount; - - op = nbRestore; - break; - - case 'S': - print_size = true; - break; - - default: - fprintf(stderr, "ERROR: Unknown switch %s.\n\n", *argp); - usage(); - break; + if (sw == TRUSTED_ROLE_SWITCH) + { + trustedRole = true; + continue; } } - if (print_size && (op != nbLock)) - usage(); + switch (UPPER(argv[itr][1])) { + case 'U': + if (++itr >= argc) + missing_parameter_for_switch(uSvc, argv[itr - 1]); - switch (op) { - case nbNone: - usage(); - break; + username = argv[itr]; + break; - case nbLock: - nbackup(database, username, password, run_db_triggers).lock_database(print_size); - break; + case 'P': + if (++itr >= argc) + missing_parameter_for_switch(uSvc, argv[itr - 1]); - case nbUnlock: - nbackup(database, username, password, run_db_triggers).unlock_database(); - break; + password = argv[itr]; + uSvc->hidePasswd(argv, itr); + break; - case nbFixup: - nbackup(database, username, password, run_db_triggers).fixup_database(); - break; + case 'T': + run_db_triggers = false; + break; - case nbBackup: - nbackup(database, username, password, run_db_triggers).backup_database(level, filename); - break; + case 'F': + if (op != nbNone) + singleAction(uSvc); - case nbRestore: - nbackup(database, username, password, run_db_triggers).restore_database(filecount, backup_files); - break; + if (++itr >= argc) + missing_parameter_for_switch(uSvc, argv[itr - 1]); + + database = argv[itr]; + op = nbFixup; + break; + + case 'L': + if (op != nbNone) + singleAction(uSvc); + + if (++itr >= argc) + missing_parameter_for_switch(uSvc, argv[itr - 1]); + + database = argv[itr]; + op = nbLock; + break; + + case 'N': + if (op != nbNone) + singleAction(uSvc); + + if (++itr >= argc) + missing_parameter_for_switch(uSvc, argv[itr - 1]); + + database = argv[itr]; + op = nbUnlock; + break; + + case 'B': + if (op != nbNone) + singleAction(uSvc); + + if (++itr >= argc) + missing_parameter_for_switch(uSvc, argv[itr - 1]); + + level = atoi(argv[itr]); + + if (++itr >= argc) + missing_parameter_for_switch(uSvc, argv[itr - 2]); + + database = argv[itr]; + + if (itr + 1 < argc) + filename = argv[++itr]; + + op = nbBackup; + break; + + case 'R': + if (op != nbNone) + singleAction(uSvc); + + if (++itr >= argc) + missing_parameter_for_switch(uSvc, argv[itr - 1]); + + database = argv[itr]; + while (++itr < argc) + backup_files.push(argv[itr]); + + op = nbRestore; + break; + + case 'S': + print_size = true; + break; + + default: + usage(uSvc, "Unknown switch %s", argv[itr]); + break; } } - catch (const Firebird::Exception&) { - // It must have been printed out. No need to repeat the task - return EXIT_ERROR; - } - return EXIT_OK; + if (print_size && (op != nbLock)) + usage(uSvc, "Switch -S can be used only with -L"); + + NBackup nbk(uSvc, database, username, password, run_db_triggers, trustedUser, trustedRole); + switch (op) { + case nbNone: + usage(uSvc, "None of -L, -N, -F, -B or -R specified"); + break; + + case nbLock: + nbk.lock_database(print_size); + break; + + case nbUnlock: + nbk.unlock_database(); + break; + + case nbFixup: + nbk.fixup_database(); + break; + + case nbBackup: + nbk.backup_database(level, filename); + break; + + case nbRestore: + nbk.restore_database(backup_files); + break; + } }