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 47 by tony, Mon Jan 9 15:31:51 2017 UTC vs.
Revision 139 by tony, Wed Jan 24 16:16:29 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 GetMask(Bits: integer): byte;
941 +  begin
942 +    case Bits of
943 +      1: Result := $01;
944 +      2: Result := $03;
945 +      3: Result := $07;
946 +    end;
947 +  end;
948 +
949 +  function GetDDLEvent(Phase: TTriggerPhase; ObjectName: string): string;
950 +  begin
951 +    Result := '';
952 +    case Phase of
953 +    tpCreate:
954 +     Result := separator + 'CREATE ' + ObjectName;
955 +    tpAlter:
956 +     Result := separator + 'ALTER ' + ObjectName;
957 +    tpDrop:
958 +     Result := separator + 'Drop ' + ObjectName;
959 +    end;
960 +    if Result <> '' then
961 +      separator := ' OR ';
962 +  end;
963 +
964   begin
965    if TypeID and $2000 <> 0 then
966    {database trigger}
# Line 920 | Line 980 | begin
980      end;
981    end
982    else
983 +  if TypeID and $4000 <> 0 then
984 +  {DDL Trigger}
985 +  begin
986 +    if TypeID and $01 <> 0 then
987 +      Result := 'AFTER '
988 +    else
989 +      Result := 'BEFORE ';
990 +    TypeID := TypeID shr 1;
991 +    separator := '';
992 +    i := 0;
993 +    if TypeID = AllDDLTriggers then
994 +      Result += 'ANY DDL STATEMENT'
995 +    else
996 +      repeat
997 +        if TypeID and GetMask(DDLTriggers[i].Bits) <> 0 then
998 +        begin
999 +          if (DDLTriggers[i].Bits > 0) and (TypeID and $01 <> 0) then
1000 +           Result += GetDDLEvent(DDLTriggers[i].Bit1,DDLTriggers[i].ObjectName);
1001 +
1002 +          if (DDLTriggers[i].Bits > 1) and (TypeID and $02 <> 0) then
1003 +            Result += GetDDLEvent(DDLTriggers[i].Bit2,DDLTriggers[i].ObjectName);
1004 +
1005 +          if (DDLTriggers[i].Bits > 2) and (TypeID and $04 <> 0) then
1006 +            Result += GetDDLEvent(DDLTriggers[i].Bit3,DDLTriggers[i].ObjectName);
1007 +        end;
1008 +        TypeID := TypeID shr DDLTriggers[i].Bits;
1009 +        Inc(i);
1010 +      until TypeID = 0;
1011 +  end
1012 +  else
1013 +  {Normal Trigger}
1014    begin
1015      Inc(TypeID);
1016      if TypeID and $01 <> 0 then
# Line 940 | Line 1031 | begin
1031          Result += 'DELETE';
1032        end;
1033        TypeID := TypeID shr 2;
1034 <    until TypeID = 0;
1035 <  end;
1034 >    until TypeID = 0
1035 >  end
1036   end;
1037  
1038   {          ListAllGrants
# Line 1303 | Line 1394 | begin
1394        SList.Add(Format('CREATE TRIGGER %s%s%s %s POSITION %d',
1395                  [QuoteIdentifier(FDatabase.SQLDialect, TriggerName),
1396                  LineEnding, InActive,
1397 <                GetTriggerType(qryTriggers.FieldByName('RDB$TRIGGER_TYPE').AsInteger),
1397 >                GetTriggerType(qryTriggers.FieldByName('RDB$TRIGGER_TYPE').AsInt64),
1398                  qryTriggers.FieldByName('RDB$TRIGGER_SEQUENCE').AsInteger]));
1399  
1400        if RelationName <> '' then
# Line 2614 | Line 2705 | end;
2705  
2706   procedure TIBExtract.SetDatabase(const Value: TIBDatabase);
2707   begin
2708 <  if FDatabase <> Value then
2708 >  if (csLoading in ComponentState) or (FDatabase <> Value) then
2709    begin
2710      FDatabase := Value;
2711      if (not Assigned(FTransaction)) and (FDatabase <> nil) then
# Line 3241 | Line 3332 | begin
3332        Database := FDatabase;
3333        SQL.Text := TableSQL;
3334        ExecQuery;
3335 +      FMetaData.Add('/* Data Starts */');
3336        while not EOF do
3337        begin
3338          ListData(Trim(FieldByName('RDB$RELATION_NAME').AsString));
3339          Next;
3340        end;
3341 +      FMetaData.Add('/* Data Ends */');
3342      finally
3343        Free;
3344      end;
# Line 3272 | Line 3365 | begin
3365      with TIBInsertStmtsOut.Create(self) do
3366      try
3367        Database := FDatabase;
3368 <      DataOut(Format('Select %s From %s',[FieldList,QuoteIdentifier(FDatabase.SQLDialect, ObjectName)]),
3369 <                Add2MetaData);
3370 <      FMetaData.Add('COMMIT;');
3368 >      if DataOut(Format('Select %s From %s',[FieldList,QuoteIdentifier(FDatabase.SQLDialect, ObjectName)]),
3369 >                Add2MetaData) then
3370 >        FMetaData.Add('COMMIT;');
3371      finally
3372        Free
3373      end;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines