ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/public/ibx/trunk/runtime/IBExtract.pas
(Generate patch)

Comparing ibx/trunk/runtime/IBExtract.pas (file contents):
Revision 49 by tony, Thu Feb 2 16:20:12 2017 UTC vs.
Revision 140 by tony, Wed Jan 24 16:31:11 2018 UTC

# Line 31 | Line 31 | Database Triggers (2.1)
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;
# Line 77 | Line 78 | type
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;
# Line 274 | Line 275 | const
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
# Line 436 | Line 468 | const
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;
# Line 446 | Line 478 | var
478    TableType: integer;
479   begin
480    Result := true;
449  ColList := '';
481    IntChar := 0;
482    ValidRelation := false;
483  
# Line 617 | Line 648 | begin
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;
# Line 755 | Line 786 | var
786    qryViews, qryColumns : TIBSQL;
787    RelationName, ColList : String;
788   begin
789 +  ColList := '';
790    qryViews := TIBSQL.Create(FDatabase);
791    qryColumns := TIBSQL.Create(FDatabase);
792    try
# Line 899 | Line 931 | begin
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}
# Line 920 | Line 971 | begin
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
# Line 940 | Line 1019 | begin
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
# Line 1303 | Line 1382 | begin
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
# Line 2614 | Line 2693 | end;
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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines