unit TableInfoF;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, IBEIntfEx, ComCtrls, ExtCtrls, OleCtrls, ActnList;

type

  TTableInfoForm = class(TForm)
    Panel1: TPanel;
    Label1: TLabel;
    cbDatabases: TComboBox;
    Panel2: TPanel;
    Splitter1: TSplitter;
    Pages: TPageControl;
    lbTables: TListBox;
    tsFields: TTabSheet;
    tsPK: TTabSheet;
    tsFK: TTabSheet;
    ColumnsTL: TListView;
    PKLV: TListView;
    FKLV: TListView;
    tsChecks: TTabSheet;
    tsUniques: TTabSheet;
    CheckLV: TListView;
    UnqLV: TListView;
    tsTriggers: TTabSheet;
    TriggersLV: TListView;
    Splitter2: TSplitter;
    tsIndices: TTabSheet;
    IndexLV: TListView;
    Panel3: TPanel;
    pTriggers: TPanel;
    m: TMemo;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure cbDatabasesChange(Sender: TObject);
    procedure lbTablesClick(Sender: TObject);
    procedure PagesChange(Sender: TObject);
    procedure TriggersLVChange(Sender: TObject; Item: TListItem; Change: TItemChange);
  private
    procedure Init;
    procedure RefreshInfo;
    procedure RefreshColumnsInfo;
    procedure RefreshPKInfo;
    procedure RefreshFKInfo;
    procedure RefreshChecksInfo;
    procedure RefreshUniquesInfo;
    procedure RefreshTriggersInfo;
    procedure RefreshIndicesInfo;
  public
    Intf : TIBEInterfaceEx;
  end;

procedure ShowTableInfo(Intf : TIBEInterfaceEx);

implementation

procedure ShowTableInfo(Intf : TIBEInterfaceEx);
var
  Frm : TTableInfoForm;
begin
  Application.Handle := TApplication(Intf.MainApplication).Handle;
  Frm := TTableInfoForm.Create(TApplication(Intf.MainApplication));
  Frm.Intf := Intf;
  Frm.Init;
  Frm.Show;
end;

{$R *.DFM}

{ TTableInfoForm }

procedure TTableInfoForm.Init;
var
  iCount, i : integer;
  DB : hDB;
  DBInfo : PibeiDatabaseInfo;
begin
  iCount := Intf.DBCount;
  for i := 0 to pred(iCount) do
  begin
    DB := Intf.GetDBByIndex(i);
    DBInfo := Intf.GetDBInfo(DB);
    try
      cbDatabases.Items.AddObject(DBInfo.Alias,TObject(DB));
    finally
      Intf.FreeDBInfo(DBInfo);
    end;
  end;
end;

procedure TTableInfoForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree;
end;

procedure TTableInfoForm.cbDatabasesChange(Sender: TObject);
var
  DB : hDB;
  i, iCount, Res : integer;
  OL : hDBOL;
  ObjInfo : PibeiDatabaseObjectInfo;
begin
  lbTables.Items.Clear;
  DB := cbDatabases.Items.Objects[cbDatabases.ItemIndex];
  if Assigned(DB) then
  begin
    if Intf.IsDBActive(DB) = 0 then
    begin
      Res := MessageDlg('Database isn''t active. Connect to the database?',mtConfirmation, [mbYes, mbNo], 0);
      if Res = mrYes then
        Intf.OpenDB(DB);
      if Intf.IsDBActive(DB) = 0 then
        Exit;
    end;

    OL := Intf.CreateDBObjectsList(DB,idoTable,0);
    try
      iCount := Intf.GetListCount(OL);
      for i := 0 to pred(iCount) do
      begin
        ObjInfo := Intf.GetDBObjectInfo(OL,i);
        lbTables.Items.Add(ObjInfo.Name);
      end;
    finally
      Intf.FreeDBObjectsList(OL);
    end;
  end;
end;

procedure TTableInfoForm.lbTablesClick(Sender: TObject);
begin
  RefreshInfo;
end;

procedure TTableInfoForm.RefreshInfo;
begin
  if lbTables.ItemIndex < 0 then
    Exit;
  Screen.Cursor := crSQLWait;
  try
    if Pages.ActivePage = tsFields then
      RefreshColumnsInfo
    else if Pages.ActivePage = tsPK then
      RefreshPKInfo
    else if Pages.ActivePage = tsFK then
      RefreshFKInfo
    else if Pages.ActivePage = tsChecks then
      RefreshChecksInfo
    else if Pages.ActivePage = tsUniques then
      RefreshUniquesInfo
    else if Pages.ActivePage = tsTriggers then
      RefreshTriggersInfo
    else if Pages.ActivePage = tsIndices then
      RefreshIndicesInfo;
  finally
    Screen.Cursor := crDefault;
  end;
end;

procedure TTableInfoForm.RefreshColumnsInfo;
var
  FI : PibeiFieldInfo;
  FL : hTFL;
  DB : hDB;
  i, iCount : integer;
  li : TListItem;
begin
  ColumnsTL.Items.BeginUpdate;
  try
    ColumnsTL.Items.Clear;

    DB := cbDatabases.Items.Objects[cbDatabases.ItemIndex];
    FL := Intf.CreateTableFieldsList(DB, PChar(Trim(lbTables.Items[lbTables.ItemIndex])));
    try
      iCount := Intf.GetListCount(FL);
      for i := 0 to pred(iCount) do
      begin
        FI := Intf.GetTableFieldInfo(FL,i);
        li := ColumnsTL.Items.Add;
        li.Caption := FI.FieldName;
        li.SubItems.Add(FI.FieldDomain);
        li.SubItems.Add(FI.FieldTypeAsString);
        if FI.NotNull then
          li.SubItems.Add('No')
        else
          li.SubItems.Add('Yes');
        li.SubItems.Add(FI.Description);
      end;
    finally
      Intf.FreeTableFieldsList(FL);
    end;
  finally
    ColumnsTL.Items.EndUpdate;
  end;
end;

procedure TTableInfoForm.PagesChange(Sender: TObject);
begin
  RefreshInfo;
end;

procedure TTableInfoForm.RefreshPKInfo;
var
  CI : PibeiConstraintInfo;
  CL : hTCL;
  DB : hDB;
  i, iCount : integer;
  li : TListItem;
begin
  PKLV.Items.BeginUpdate;
  try
    PKLV.Items.Clear;

    DB := cbDatabases.Items.Objects[cbDatabases.ItemIndex];
    CL := Intf.CreateConstraintsList(DB, PChar(Trim(lbTables.Items[lbTables.ItemIndex])),ictPrimaryKey);
    try
      iCount := Intf.GetListCount(CL);
      for i := 0 to pred(iCount) do
      begin
        CI := Intf.GetConstraintInfo(CL,i);
        li := PKLV.Items.Add;
        li.Caption := CI.ConstraintName;
        li.SubItems.Add(CI.OnField);
      end;
    finally
      Intf.FreeConstraintsList(CL);
    end;
  finally
    PKLV.Items.EndUpdate;
  end;
end;


procedure TTableInfoForm.RefreshFKInfo;
var
  CI : PibeiConstraintInfo;
  CL : hTCL;
  DB : hDB;
  i, iCount : integer;
  li : TListItem;
begin
  FKLV.Items.BeginUpdate;
  try
    FKLV.Items.Clear;

    DB := cbDatabases.Items.Objects[cbDatabases.ItemIndex];
    CL := Intf.CreateConstraintsList(DB, PChar(Trim(lbTables.Items[lbTables.ItemIndex])),ictForeignKey);
    try
      iCount := Intf.GetListCount(CL);
      for i := 0 to pred(iCount) do
      begin
        CI := Intf.GetConstraintInfo(CL,i);
        li := FKLV.Items.Add;
        li.Caption := CI.ConstraintName;
        li.SubItems.Add(CI.OnField);
        li.SubItems.Add(CI.ForeignTable);
        li.SubItems.Add(CI.ForeignField);
        li.SubItems.Add(CI.UpdateRuleAsString);
        li.SubItems.Add(CI.DeleteRuleAsString);
      end;
    finally
      Intf.FreeConstraintsList(CL);
    end;
  finally
    FKLV.Items.EndUpdate;
  end;
end;


procedure TTableInfoForm.RefreshChecksInfo;
var
  CI : PibeiConstraintInfo;
  CL : hTCL;
  DB : hDB;
  i, iCount : integer;
  li : TListItem;
begin
  CheckLV.Items.BeginUpdate;
  try
    CheckLV.Items.Clear;

    DB := cbDatabases.Items.Objects[cbDatabases.ItemIndex];
    CL := Intf.CreateConstraintsList(DB, PChar(Trim(lbTables.Items[lbTables.ItemIndex])),ictCheck);
    try
      iCount := Intf.GetListCount(CL);
      for i := 0 to pred(iCount) do
      begin
        CI := Intf.GetConstraintInfo(CL,i);
        li := CheckLV.Items.Add;
        li.Caption := CI.ConstraintName;
        li.SubItems.Add(CI.CheckSource);
      end;
    finally
      Intf.FreeConstraintsList(CL);
    end;
  finally
    CheckLV.Items.EndUpdate;
  end;
end;


procedure TTableInfoForm.RefreshUniquesInfo;
var
  CI : PibeiConstraintInfo;
  CL : hTCL;
  DB : hDB;
  i, iCount : integer;
  li : TListItem;
begin
  UnqLV.Items.BeginUpdate;
  try
    UnqLV.Items.Clear;

    DB := cbDatabases.Items.Objects[cbDatabases.ItemIndex];
    CL := Intf.CreateConstraintsList(DB, PChar(Trim(lbTables.Items[lbTables.ItemIndex])),ictUnique);
    try
      iCount := Intf.GetListCount(CL);
      for i := 0 to pred(iCount) do
      begin
        CI := Intf.GetConstraintInfo(CL,i);
        li := UnqLV.Items.Add;
        li.Caption := CI.ConstraintName;
        li.SubItems.Add(CI.OnField);
      end;
    finally
      Intf.FreeConstraintsList(CL);
    end;
  finally
    UnqLV.Items.EndUpdate;
  end;
end;

procedure TTableInfoForm.RefreshTriggersInfo;
var
  TI : PibeiTriggerInfo;
  TL : hTrgL;
  DB : hDB;
  i, iCount : integer;
  li : TListItem;
begin
  TriggersLV.Items.BeginUpdate;
  TriggersLV.OnChange := nil;
  try
    TriggersLV.Items.Clear;

    DB := cbDatabases.Items.Objects[cbDatabases.ItemIndex];
    TL := Intf.CreateTriggersList(DB, PChar(Trim(lbTables.Items[lbTables.ItemIndex])), 1);
    try
      iCount := Intf.GetListCount(TL);
      for i := 0 to pred(iCount) do
      begin
        TI := Intf.GetTriggerInfo(TL,i);
        li := TriggersLV.Items.Add;
        li.Caption := TI.TriggerName;
        li.SubItems.Add(TI.TriggerTypeAsString);
        li.SubItems.Add(IntToStr(TI.Position));
        if Boolean(TI.Active) then
          li.SubItems.Add('Yes')
        else
          li.SubItems.Add('No');
        li.SubItems.Add(TI.Description);
        li.SubItems.Add(TI.DDL);
      end;
    finally
      Intf.FreeTriggersList(TL);
    end;
  finally
    TriggersLV.Items.EndUpdate;
    TriggersLV.OnChange := TriggersLVChange;
  end;
end;


procedure TTableInfoForm.TriggersLVChange(Sender: TObject; Item: TListItem; Change: TItemChange);
begin
  m.Text := Item.SubItems[4];
end;

procedure TTableInfoForm.RefreshIndicesInfo;
var
  II : PibeiIndexInfo;
  IL : hIndL;
  DB : hDB;
  i, iCount : integer;
  li : TListItem;
begin
  IndexLV.Items.BeginUpdate;
  try
    IndexLV.Items.Clear;

    DB := cbDatabases.Items.Objects[cbDatabases.ItemIndex];
    IL := Intf.CreateIndicesList(DB, PChar(Trim(lbTables.Items[lbTables.ItemIndex])));
    try
      iCount := Intf.GetListCount(IL);
      for i := 0 to pred(iCount) do
      begin
        II := Intf.GetIndexInfo(IL,i);
        li := IndexLV.Items.Add;
        li.Caption := II.IndexName;
        li.SubItems.Add(II.Fields);
        if Boolean(II.Active) then
          li.SubItems.Add('Yes')
        else
          li.SubItems.Add('No');

        if Boolean(II.Descending) then
          li.SubItems.Add('DESC')
        else
          li.SubItems.Add('ASC');

        if Boolean(II.Unique) then
          li.SubItems.Add('Yes')
        else
          li.SubItems.Add('No');

        li.SubItems.Add(FloatToStr(II.Statistics));
      end;
    finally
      Intf.FreeIndicesList(IL);
    end;
  finally
    IndexLV.Items.EndUpdate;
  end;
end;


end.
