31 |
|
Global Temporary Tables (2.1) |
32 |
|
Boolean Type (3.0) |
33 |
|
Identity Column Type (3.0) |
34 |
+ |
DDL Triggers (3.0) |
35 |
|
} |
36 |
|
|
37 |
|
unit IBExtract; |
78 |
|
function GetDatabase: TIBDatabase; |
79 |
|
function GetIndexSegments ( indexname : String) : String; |
80 |
|
function GetTransaction: TIBTransaction; |
81 |
< |
function GetTriggerType(TypeID: integer): string; |
81 |
> |
function GetTriggerType(TypeID: Int64): string; |
82 |
|
procedure SetDatabase(const Value: TIBDatabase); |
83 |
|
procedure SetTransaction(const Value: TIBTransaction); |
84 |
|
function PrintValidation(ToValidate : String; flag : Boolean) : String; |
275 |
|
' FDIM.RDB$FIELD_NAME = :FIELDNAME ' + |
276 |
|
'ORDER BY FDIM.RDB$DIMENSION'; |
277 |
|
|
278 |
+ |
type |
279 |
+ |
TTriggerPhase = (tpNone,tpCreate,tpAlter,tpDrop); |
280 |
+ |
|
281 |
+ |
TDDLTriggerMap = record |
282 |
+ |
ObjectName: string; |
283 |
+ |
Bits: integer; |
284 |
+ |
Bit1: TTriggerPhase; |
285 |
+ |
Bit2: TTriggerPhase; |
286 |
+ |
Bit3: TTriggerPhase; |
287 |
+ |
end; |
288 |
+ |
|
289 |
+ |
const |
290 |
+ |
DDLTriggers : array [0..15] of TDDLTriggerMap = ( |
291 |
+ |
(ObjectName: 'TABLE'; Bits: 3; Bit1: tpCreate; Bit2: tpAlter; Bit3: tpDrop), |
292 |
+ |
(ObjectName: 'PROCEDURE'; Bits: 3; Bit1: tpCreate; Bit2: tpAlter; Bit3: tpDrop), |
293 |
+ |
(ObjectName: 'FUNCTION'; Bits: 3; Bit1: tpCreate; Bit2: tpAlter; Bit3: tpDrop), |
294 |
+ |
(ObjectName: 'TRIGGER'; Bits: 3; Bit1: tpCreate; Bit2: tpAlter; Bit3: tpDrop), |
295 |
+ |
(ObjectName: 'Empty slot'; Bits: 3; Bit1: tpNone; Bit2: tpNone; Bit3: tpNone), |
296 |
+ |
(ObjectName: 'EXCEPTION'; Bits: 3; Bit1: tpCreate; Bit2: tpAlter; Bit3: tpDrop), |
297 |
+ |
(ObjectName: 'VIEW'; Bits: 3; Bit1: tpCreate; Bit2: tpAlter; Bit3: tpDrop), |
298 |
+ |
(ObjectName: 'DOMAIN'; Bits: 3; Bit1: tpCreate; Bit2: tpAlter; Bit3: tpDrop), |
299 |
+ |
(ObjectName: 'ROLE'; Bits: 3; Bit1: tpCreate; Bit2: tpAlter; Bit3: tpDrop), |
300 |
+ |
(ObjectName: 'INDEX'; Bits: 3; Bit1: tpCreate; Bit2: tpAlter; Bit3: tpDrop), |
301 |
+ |
(ObjectName: 'SEQUENCE'; Bits: 3; Bit1: tpCreate; Bit2: tpAlter; Bit3: tpDrop), |
302 |
+ |
(ObjectName: 'USER'; Bits: 3; Bit1: tpCreate; Bit2: tpAlter; Bit3: tpDrop), |
303 |
+ |
(ObjectName: 'COLLATION'; Bits: 2; Bit1: tpCreate; Bit2: tpDrop; Bit3: tpNone), |
304 |
+ |
(ObjectName: 'CHARACTER SET'; Bits: 1; Bit1: tpAlter; Bit2: tpNone; Bit3: tpNone), |
305 |
+ |
(ObjectName: 'PACKAGE'; Bits: 3; Bit1: tpCreate; Bit2: tpAlter; Bit3: tpDrop), |
306 |
+ |
(ObjectName: 'PACKAGE BODY'; Bits: 2; Bit1: tpCreate; Bit2: tpDrop; Bit3: tpNone) |
307 |
+ |
); |
308 |
+ |
|
309 |
|
{ TIBExtract } |
310 |
|
|
311 |
|
{ ArrayDimensions |
468 |
|
var |
469 |
|
Collation, CharSetId : integer; |
470 |
|
i : integer; |
471 |
< |
ColList, Column, Constraint : String; |
471 |
> |
Column, Constraint : String; |
472 |
|
SubType : integer; |
473 |
|
IntChar : integer; |
474 |
|
qryTables, qryPrecision, qryConstraints, qryRelConstraints, qryGenerators : TIBSQL; |
478 |
|
TableType: integer; |
479 |
|
begin |
480 |
|
Result := true; |
449 |
– |
ColList := ''; |
481 |
|
IntChar := 0; |
482 |
|
ValidRelation := false; |
483 |
|
|
648 |
|
end; |
649 |
|
|
650 |
|
{Firebird 3 introduces IDENTITY columns. We need to check for them here} |
651 |
< |
if qryTables.HasField('RDB$GENERATOR_NAME') then |
651 |
> |
if qryTables.HasField('RDB$GENERATOR_NAME') and not qryTables.FieldByName('RDB$GENERATOR_NAME').IsNull then |
652 |
|
begin |
653 |
|
qryGenerators.ParamByName('GENERATOR').AsString := qryTables.FieldByName('RDB$GENERATOR_NAME').AsString; |
654 |
|
qryGenerators.ExecQuery; |
786 |
|
qryViews, qryColumns : TIBSQL; |
787 |
|
RelationName, ColList : String; |
788 |
|
begin |
789 |
+ |
ColList := ''; |
790 |
|
qryViews := TIBSQL.Create(FDatabase); |
791 |
|
qryColumns := TIBSQL.Create(FDatabase); |
792 |
|
try |
931 |
|
Result := FTransaction; |
932 |
|
end; |
933 |
|
|
934 |
< |
function TIBExtract.GetTriggerType(TypeID: integer): string; |
934 |
> |
function TIBExtract.GetTriggerType(TypeID: Int64): string; |
935 |
> |
const |
936 |
> |
AllDDLTriggers = $7FFFFFFFFFFFDFFF shr 1; |
937 |
|
var separator: string; |
938 |
+ |
i: integer; |
939 |
+ |
|
940 |
+ |
function GetDDLEvent(Phase: TTriggerPhase; ObjectName: string): string; |
941 |
+ |
begin |
942 |
+ |
Result := ''; |
943 |
+ |
case Phase of |
944 |
+ |
tpCreate: |
945 |
+ |
Result := separator + 'CREATE ' + ObjectName; |
946 |
+ |
tpAlter: |
947 |
+ |
Result := separator + 'ALTER ' + ObjectName; |
948 |
+ |
tpDrop: |
949 |
+ |
Result := separator + 'Drop ' + ObjectName; |
950 |
+ |
end; |
951 |
+ |
if Result <> '' then |
952 |
+ |
separator := ' OR '; |
953 |
+ |
end; |
954 |
+ |
|
955 |
|
begin |
956 |
|
if TypeID and $2000 <> 0 then |
957 |
|
{database trigger} |
971 |
|
end; |
972 |
|
end |
973 |
|
else |
974 |
+ |
if TypeID and $4000 <> 0 then |
975 |
+ |
{DDL Trigger} |
976 |
+ |
begin |
977 |
+ |
if TypeID and $01 <> 0 then |
978 |
+ |
Result := 'AFTER ' |
979 |
+ |
else |
980 |
+ |
Result := 'BEFORE '; |
981 |
+ |
TypeID := TypeID shr 1; |
982 |
+ |
separator := ''; |
983 |
+ |
i := 0; |
984 |
+ |
if TypeID = AllDDLTriggers then |
985 |
+ |
Result += 'ANY DDL STATEMENT' |
986 |
+ |
else |
987 |
+ |
repeat |
988 |
+ |
if (DDLTriggers[i].Bits > 0) and (TypeID and $01 <> 0) then |
989 |
+ |
Result += GetDDLEvent(DDLTriggers[i].Bit1,DDLTriggers[i].ObjectName); |
990 |
+ |
|
991 |
+ |
if (DDLTriggers[i].Bits > 1) and (TypeID and $02 <> 0) then |
992 |
+ |
Result += GetDDLEvent(DDLTriggers[i].Bit2,DDLTriggers[i].ObjectName); |
993 |
+ |
|
994 |
+ |
if (DDLTriggers[i].Bits > 2) and (TypeID and $04 <> 0) then |
995 |
+ |
Result += GetDDLEvent(DDLTriggers[i].Bit3,DDLTriggers[i].ObjectName); |
996 |
+ |
TypeID := TypeID shr DDLTriggers[i].Bits; |
997 |
+ |
Inc(i); |
998 |
+ |
until TypeID = 0; |
999 |
+ |
end |
1000 |
+ |
else |
1001 |
+ |
{Normal Trigger} |
1002 |
|
begin |
1003 |
|
Inc(TypeID); |
1004 |
|
if TypeID and $01 <> 0 then |
1019 |
|
Result += 'DELETE'; |
1020 |
|
end; |
1021 |
|
TypeID := TypeID shr 2; |
1022 |
< |
until TypeID = 0; |
1023 |
< |
end; |
1022 |
> |
until TypeID = 0 |
1023 |
> |
end |
1024 |
|
end; |
1025 |
|
|
1026 |
|
{ ListAllGrants |
1382 |
|
SList.Add(Format('CREATE TRIGGER %s%s%s %s POSITION %d', |
1383 |
|
[QuoteIdentifier(FDatabase.SQLDialect, TriggerName), |
1384 |
|
LineEnding, InActive, |
1385 |
< |
GetTriggerType(qryTriggers.FieldByName('RDB$TRIGGER_TYPE').AsInteger), |
1385 |
> |
GetTriggerType(qryTriggers.FieldByName('RDB$TRIGGER_TYPE').AsInt64), |
1386 |
|
qryTriggers.FieldByName('RDB$TRIGGER_SEQUENCE').AsInteger])); |
1387 |
|
|
1388 |
|
if RelationName <> '' then |
2693 |
|
|
2694 |
|
procedure TIBExtract.SetDatabase(const Value: TIBDatabase); |
2695 |
|
begin |
2696 |
< |
if FDatabase <> Value then |
2696 |
> |
if (csLoading in ComponentState) or (FDatabase <> Value) then |
2697 |
|
begin |
2698 |
|
FDatabase := Value; |
2699 |
|
if (not Assigned(FTransaction)) and (FDatabase <> nil) then |
3320 |
|
Database := FDatabase; |
3321 |
|
SQL.Text := TableSQL; |
3322 |
|
ExecQuery; |
3323 |
+ |
FMetaData.Add('/* Data Starts */'); |
3324 |
|
while not EOF do |
3325 |
|
begin |
3326 |
|
ListData(Trim(FieldByName('RDB$RELATION_NAME').AsString)); |
3327 |
|
Next; |
3328 |
|
end; |
3329 |
+ |
FMetaData.Add('/* Data Ends */'); |
3330 |
|
finally |
3331 |
|
Free; |
3332 |
|
end; |
3353 |
|
with TIBInsertStmtsOut.Create(self) do |
3354 |
|
try |
3355 |
|
Database := FDatabase; |
3356 |
< |
DataOut(Format('Select %s From %s',[FieldList,QuoteIdentifier(FDatabase.SQLDialect, ObjectName)]), |
3357 |
< |
Add2MetaData); |
3358 |
< |
FMetaData.Add('COMMIT;'); |
3356 |
> |
if DataOut(Format('Select %s From %s',[FieldList,QuoteIdentifier(FDatabase.SQLDialect, ObjectName)]), |
3357 |
> |
Add2MetaData) then |
3358 |
> |
FMetaData.Add('COMMIT;'); |
3359 |
|
finally |
3360 |
|
Free |
3361 |
|
end; |