8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-31 13:23:02 +01:00
firebird-mirror/src/msgs/msg.sql
robocop 08a33d50cc Unfortunately several of these are intertwined:
CORE-462 	 New option in addition to -V switch to specify a custom verbose interval
CORE-2540 	 Utilities need a more coherent way to show help and version
CORE-2541 	 Too many hardcoded messages in nbackup
CORE-2542 	 qli and nbackup accept arbitrary input after the first letter of an option
CORE-2543 	 nbackup may hide the real cause of failure
CORE-2545	 Lack of several validations in gbak
CORE-2547 	 Utilities need to honor their minimum number of characters to recognize an option
CORE-2565 	 Many hardcoded messages in Trace Manager
Moving functions that don't depend on preprocessing to iutils.cpp in isql is the only alien change here.
2009-11-05 09:03:41 +00:00

387 lines
11 KiB
SQL

CREATE GENERATOR CHANGE_NUM;
/* Domain definitions */
CREATE DOMAIN D_ACTION AS BLOB SUB_TYPE 0 SEGMENT SIZE 0;
CREATE DOMAIN CHANGE_DATE AS TIMESTAMP;
CREATE DOMAIN CHANGE_NUMBER AS INTEGER;
CREATE DOMAIN CHANGE_WHO AS VARCHAR(32);
CREATE DOMAIN CLASS AS CHAR(10);
CREATE DOMAIN DESCRIPTION AS BLOB SUB_TYPE 0 SEGMENT SIZE 80;
CREATE DOMAIN EXPLANATION AS BLOB SUB_TYPE 0 SEGMENT SIZE 0;
CREATE DOMAIN FACILITY AS CHAR(15);
CREATE DOMAIN FAC_CODE AS SMALLINT;
CREATE DOMAIN D_FILE AS VARCHAR(30);
CREATE DOMAIN FLAGS AS SMALLINT;
CREATE DOMAIN LANGUAGE AS VARCHAR(10);
CREATE DOMAIN LAST_CHANGE AS TIMESTAMP;
CREATE DOMAIN LOCALE AS VARCHAR(20);
CREATE DOMAIN MAX_NUMBER AS SMALLINT;
CREATE DOMAIN MODULE AS VARCHAR(32);
CREATE DOMAIN NUMBER AS SMALLINT;
CREATE DOMAIN OLD_SEQUENCE AS SMALLINT;
CREATE DOMAIN ROUTINE AS VARCHAR(40);
CREATE DOMAIN SEQUENCE AS SMALLINT;
CREATE DOMAIN SEVERITY AS SMALLINT;
CREATE DOMAIN SEVERITY_TEXT AS CHAR(7);
CREATE DOMAIN SQL_CLASS AS CHAR(2);
CREATE DOMAIN SQL_CODE AS SMALLINT;
CREATE DOMAIN SQL_STATE AS CHAR(5);
CREATE DOMAIN SQL_SUBCLASS AS CHAR(3);
CREATE DOMAIN SYMBOL AS VARCHAR(32);
CREATE DOMAIN TEMPLATE AS BLOB SUB_TYPE 0 SEGMENT SIZE 256;
CREATE DOMAIN TEXT AS VARCHAR(118);
CREATE DOMAIN TRANSLATOR AS VARCHAR(32);
CREATE DOMAIN TRANS_DATE AS TIMESTAMP;
CREATE DOMAIN TRANS_NOTES AS BLOB SUB_TYPE 0 SEGMENT SIZE 0;
CREATE DOMAIN D_TYPE AS CHAR(12);
CREATE DOMAIN D_VALUE AS INTEGER;
COMMIT;
/* Tables */
CREATE TABLE FACILITIES (
LAST_CHANGE LAST_CHANGE,
FACILITY FACILITY NOT NULL CONSTRAINT FAC_2 UNIQUE,
FAC_CODE FAC_CODE NOT NULL CONSTRAINT FAC_1 PRIMARY KEY,
MAX_NUMBER MAX_NUMBER
);
CREATE TABLE HISTORY (
CHANGE_NUMBER CHANGE_NUMBER NOT NULL CONSTRAINT HIS_1 PRIMARY KEY,
CHANGE_WHO CHANGE_WHO NOT NULL,
CHANGE_DATE CHANGE_DATE NOT NULL,
FAC_CODE FAC_CODE NOT NULL /*REFERENCES FACILITIES*/,
NUMBER NUMBER NOT NULL,
OLD_TEXT TEXT,
OLD_ACTION D_ACTION,
OLD_EXPLANATION EXPLANATION,
LOCALE LOCALE,
CODE COMPUTED BY (FAC_CODE * 10000 + NUMBER)
);
CREATE TABLE LOCALES (
LOCALE LOCALE NOT NULL CONSTRAINT PRIMARY_LOCALES PRIMARY KEY,
DESCRIPTION DESCRIPTION
);
CREATE TABLE MESSAGES (
SYMBOL SYMBOL CONSTRAINT MSGSYMBOL UNIQUE,
ROUTINE ROUTINE,
MODULE MODULE,
TRANS_NOTES TRANS_NOTES,
FAC_CODE FAC_CODE NOT NULL REFERENCES FACILITIES,
NUMBER NUMBER NOT NULL,
FLAGS FLAGS,
TEXT TEXT NOT NULL,
"ACTION" D_ACTION,
EXPLANATION EXPLANATION,
CODE COMPUTED BY (FAC_CODE * 10000 + NUMBER),
CONSTRAINT MESSAGES_PK PRIMARY KEY (FAC_CODE, NUMBER),
CONSTRAINT CNS UNIQUE (FAC_CODE, NUMBER, SYMBOL)
);
CREATE TABLE SQLSTATES (
SQL_CLASS SQL_CLASS NOT NULL,
SQL_SUBCLASS SQL_SUBCLASS DEFAULT '000' NOT NULL,
SQL_STATE COMPUTED BY (CAST(SQL_CLASS || SQL_SUBCLASS AS SQL_STATE)),
SQL_STATE_TEXT TEXT NOT NULL,
CONSTRAINT SQLSTATES_PK PRIMARY KEY (SQL_CLASS, SQL_SUBCLASS)
);
CREATE TABLE SYMBOLS (
SYMBOL SYMBOL NOT NULL CONSTRAINT SYM2 PRIMARY KEY,
"VALUE" D_VALUE,
CLASS CLASS,
"TYPE" D_TYPE,
SEQUENCE SEQUENCE
);
CREATE TABLE SYSTEM_ERRORS (
SQL_CODE SQL_CODE NOT NULL,
SQL_CLASS SQL_CLASS NOT NULL,
SQL_SUBCLASS SQL_SUBCLASS NOT NULL,
FAC_CODE FAC_CODE NOT NULL REFERENCES FACILITIES,
NUMBER NUMBER NOT NULL,
GDS_SYMBOL SYMBOL NOT NULL CONSTRAINT SYSERR2 UNIQUE,
SEVERITY SEVERITY,
SEVERITY_TEXT SEVERITY_TEXT,
CODE COMPUTED BY (FAC_CODE * 10000 + NUMBER),
SQL_STATE COMPUTED BY (CAST(SQL_CLASS || SQL_SUBCLASS AS SQL_STATE)),
CONSTRAINT SYSTEM_ERRORS_PK PRIMARY KEY (FAC_CODE, NUMBER),
CONSTRAINT SQL_STATE_FK FOREIGN KEY (SQL_CLASS, SQL_SUBCLASS) REFERENCES SQLSTATES (SQL_CLASS, SQL_SUBCLASS),
--CONSTRAINT SYMBOL_FK FOREIGN KEY (GDS_SYMBOL) REFERENCES MESSAGES (SYMBOL)
CONSTRAINT CNS_FK FOREIGN KEY (FAC_CODE, NUMBER, GDS_SYMBOL)
REFERENCES MESSAGES (FAC_CODE, NUMBER, SYMBOL)
);
CREATE TABLE TEMPLATES (
LANGUAGE LANGUAGE,
"FILE" D_FILE,
TEMPLATE TEMPLATE
);
COMMIT;
CREATE TABLE TRANSMSGS (
ENG_TEXT TEXT,
ENG_ACTION D_ACTION,
ENG_EXPLANATION EXPLANATION,
FAC_CODE FAC_CODE NOT NULL, -- REFERENCES FACILITIES, redundant, see FULLCODE_FK
NUMBER NUMBER NOT NULL,
LOCALE LOCALE NOT NULL CONSTRAINT LOCALE_FK REFERENCES LOCALES,
TEXT TEXT NOT NULL,
"ACTION" D_ACTION,
EXPLANATION EXPLANATION,
TRANSLATOR TRANSLATOR,
TRANS_DATE TRANS_DATE,
CODE COMPUTED BY (FAC_CODE * 10000 + NUMBER),
CONSTRAINT TRANSMSGS_PK PRIMARY KEY (LOCALE, FAC_CODE, NUMBER),
CONSTRAINT FULLCODE_FK FOREIGN KEY (FAC_CODE, NUMBER) REFERENCES MESSAGES (FAC_CODE, NUMBER)
);
COMMIT;
/* Index definitions for all user tables */
CREATE INDEX SYM1 ON SYMBOLS(CLASS, "TYPE");
COMMIT;
SET TERM ^ ;
/* Triggers */
CREATE TRIGGER FACILITIES$STORE FOR FACILITIES
ACTIVE BEFORE INSERT POSITION 0 AS
begin
new.last_change = CURRENT_TIMESTAMP;
end^
CREATE TRIGGER FACILITIES$MODIFY FOR FACILITIES
ACTIVE BEFORE UPDATE POSITION 0 AS
begin
new.last_change = CURRENT_TIMESTAMP;
end^
CREATE TRIGGER MESSAGES$MODIFY FOR MESSAGES
ACTIVE AFTER UPDATE POSITION 0 AS
begin
update facilities
set last_change = current_timestamp
where fac_code = new.fac_code;
end^
CREATE TRIGGER MSGS$MODIFY FOR MESSAGES
ACTIVE AFTER UPDATE POSITION 1 AS
begin
if (new.text <> old.text) then
begin
insert into history (change_number, change_date, change_who, fac_code,
number, old_text, old_action, old_explanation, locale)
values (gen_id(change_num, 1), current_timestamp, current_user,
old.fac_code, old.number, old.text, old."ACTION",
old.explanation, 'c_pg');
end
end^
CREATE TRIGGER TRANSMSGS$STORE FOR TRANSMSGS
ACTIVE BEFORE INSERT POSITION 0 AS
begin
if (new.translator is NULL) then
new.translator = current_user;
if (new.trans_date is NULL) then
new.trans_date = current_timestamp;
end^
CREATE TRIGGER TRANSMSGS$MODIFY FOR TRANSMSGS
ACTIVE AFTER UPDATE POSITION 0 AS
begin
if (new.text <> old.text) then
begin
insert into history (change_number, change_date, change_who, fac_code,
number, old_text, old_action, old_explanation, locale)
values (gen_id(change_num, 1), current_timestamp, current_user,
old.fac_code, old.number, old.text, old."ACTION",
old.explanation, old.locale);
end
end^
COMMIT^
SET TERM ; ^
-- Grant permission to the general audience to read these tables.
GRANT SELECT ON FACILITIES TO PUBLIC;
GRANT SELECT ON HISTORY TO PUBLIC;
GRANT SELECT ON LOCALES TO PUBLIC;
GRANT SELECT ON MESSAGES TO PUBLIC;
GRANT SELECT ON SYMBOLS TO PUBLIC;
GRANT SELECT ON SYSTEM_ERRORS TO PUBLIC;
GRANT SELECT ON TEMPLATES TO PUBLIC;
GRANT SELECT ON TRANSMSGS TO PUBLIC;
COMMIT;
/* Notes:
1) Dumping new messages that need translation.
select '(''' || replace(m.text, '''', '''''') ||
''', NULL, NULL, ' || m.fac_code || ', ' || m.number ||
', ''#'', NULL, NULL, ''truser'', ''1000-01-01 00:00:00'')'
from messages m
where not exists (select * from transmsgs t
where t.fac_code = m.fac_code and t.number = m.number)
order by m.fac_code, m.number;
2) Identify messages whose default text in the English main version is different
than in the localized version (it leads to screwed human translation, since the
English version serves as model to translate).
select m.fac_code, m.number, t.locale
from messages m
join transmsgs t
on m.fac_code = t.fac_code and m.number = t.number
where m.text <> t.eng_text
order by m.fac_code, m.number;
3) Identify messages whose number of parameters in the English main version
is different than in the localized versions (it leads old clients to crash).
Starting with the new parameters using @, it's possible to reorder the parameters
in localized version to suit each human language's syntax, but the old messages
before the change have to be maintained in the strict same order, because old
clients use the old printf syntax that's rigid.
select t.fac_code, t.number, t.locale
from transmsgs t
where char_length(t.eng_text) - char_length(replace(t.eng_text, '@', '')) <>
char_length(t.text) - char_length(replace(t.text, '@', ''))
order by t.fac_code, t.number;
4) The following procedure verifies some oddities in translated messages,
regarding the arguments used. Not necessarily errors, because there may be the
need to put params out of order in translated messages when compared to the English
version or to repeat an argument (features that couldn't be done with the
original, printf-based system). The argument for the procedure is the locale. Example:
select * from verifymsg('de_DE');
Claudio Valderrama C., March 2008.
*/
set term ^;
create procedure verifymsg(inloc varchar(5))
returns (reason varchar(20), fac int, num int, loc varchar(5))
as
declare flags int;
declare test1 int;
declare test2 int;
declare test3 int;
declare test4 int;
declare test5 int;
declare iter int;
declare found_loop int;
declare efound int;
declare newpos int;
declare testchar char;
declare len int;
declare a1 int;
declare a2 int;
declare a3 int;
declare a4 int;
declare a5 int;
-- declare fac int;
-- declare num int;
-- declare loc varchar(5);
declare trans_text type of text;
begin
for select m.fac_code, m.number, t.locale, t.text
from messages m
join transmsgs t
on m.fac_code = t.fac_code and m.number = t.number
where t.locale = :inloc
order by m.fac_code, m.number
into :fac, :num, :loc, :trans_text
do begin
a1 = 0;
a2 = 0;
a3 = 0;
a4 = 0;
a5 = 0;
newpos = 0;
flags = 0;
found_loop = 0;
iter = 1;
efound = 0;
len = char_length(trans_text);
while (iter <= len)
do begin
newpos = position('@', trans_text, iter);
if (newpos = 0)
then break;
testchar = substring(trans_text from newpos + 1 for 1);
found_loop = 1;
if (testchar = '1')
then a1 = a1 + 1;
else if (testchar = '2')
then a2 = a2 + 1;
else if (testchar = '3')
then a3 = a3 + 1;
else if (testchar = '4')
then a4 = a4 + 1;
else if (testchar = '5')
then a5 = a5 + 1;
else if (testchar <> '@')
then begin
efound = 1;
reason = 'Found ' || testchar || ' after @';
break;
end
if (testchar <> '@')
then flags = bin_or(flags, bin_shl(1, cast(testchar as int)));
iter = newpos + 2;
end
if (efound = 0)
then if (a1 > 1 or a2 > 1 or a3 > 1 or a4 > 1 or a5 > 1)
then begin
efound = 1;
reason = 'One param has count > 1';
end
else if (found_loop = 1)
then begin
-- efound = 0;
if (bin_and(flags, 2) > 0) -- 2 == bin_shl(1, 1)
then found_loop = 1;
else found_loop = 0;
iter = 2;
while (iter < 6) do
begin
if (bin_and(flags, bin_shl(1, iter)) > 0)
then begin
if (found_loop = 0)
then begin
efound = 1;
reason = '@' || cast(iter as varchar(1)) || ' out of order';
break;
end
-- else found_loop = 1;
end
else found_loop = 0;
iter = iter + 1;
end
end
if (efound = 1)
then suspend;
end
end ^
set term ;^
grant execute on procedure verifymsg to public;
commit;