www.pudn.com > sybase_dblib4.zip > Sybgrid.pas


unit sybgrid; 
 
interface 
 
uses 
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, 
  Grids,DsgnIntf,sybase_components,u_cancel_query; 
 
const opt = [goFixedVertLine,goFixedHorzLine,goVertLine,goHorzLine,goRangeSelect,goDrawFocusSelected,goColSizing,goTabs,goThumbTracking]; 
 
type 
  SybObjectname = string[30]; 
 
type 
  Tsybobjectproperty = class(TStringProperty) 
  public 
    procedure GetValues(TheProc: TGetStrProc); override; 
    function getattributes:Tpropertyattributes; override; 
  end; 
 
type 
  Tstringsproperty = class(TPropertyEditor) 
  public 
    function getvalue:string; override; 
    procedure setvalue(const value :string); override; 
    procedure edit;override; 
    function getattributes:Tpropertyattributes; override; 
  end; 
 
type 
  TSybGrid = class; 
  Threadgrid = class(TThread) 
  private 
    { Private declarations } 
    fparent        :tsybgrid; 
    f_cancel_query :Tf_cancel_query; 
  protected 
    constructor create(b:boolean;AOwner:tsybgrid); virtual; 
    procedure Execute; override; 
  end; 
 
  tsybgrid = class(TStringGrid) 
  private 
    { Private declarations } 
    FSql           :ansistring; 
    FDbname        :SybObjectname; 
    FDesignActive  :boolean; 
    FRowsReturned  :boolean; 
    FColumnCount   :integer; 
    FAutoDbProc    :boolean; 
    FDbProc        :integer; 
    FBackground    :boolean; 
    fShowLineNum   :boolean; 
    fShowRowCount  :boolean; 
    sql_buffer     :tstrings; 
    procedure setshowlinenum(Value:boolean); 
    procedure setshowrowcount(Value:boolean); 
    procedure setbackground(Value:boolean); 
    procedure SetDbProc(Value :integer); 
    procedure SetAutoDbProc(Value :boolean); 
    procedure SetSql(Value :ansistring); 
    procedure SetDbName(Value :SybObjectname); 
    procedure SetDesignActive(Value :boolean); 
    procedure SetRowsReturned(Value :boolean); 
    function GetTerminated:boolean; 
    procedure get_sql_commands; 
  protected 
    { Protected declarations } 
     procdict: tstringlist; 
     linenum    :integer; 
     procedure get_dbproc; 
  public 
    { Public declarations } 
    thread         :Threadgrid; 
    Login,Retcode,retcode2,nocols,col:integer; 
    dbprocc:integer; 
    fontsize,numcols      :integer; 
    sql_commands          :tstrings; 
    constructor create(AOwner:TComponent); override; 
    destructor Destroy; override; 
    procedure addsql(Value :ansistring); 
    procedure clearsql; 
    function sqlexec:integer; 
    function heading(index:byte):string; 
    function coltype(index:byte):string; 
    function collength(index:byte):integer; 
    function ischar(index:byte):boolean; 
    function colindex(value:string):smallint; 
  published 
    { Published declarations } 
    procedure LoadSqlFromFile(FileName :string); 
    property Terminated:boolean read GetTerminated; 
    property DbName :SybObjectname read FDbName write setDbname; 
    property Sql :ansistring read FSql write SetSql; 
    property DesignActive:boolean read fdesignactive write setdesignactive stored false; 
    property ShowLineNum:boolean read fshowlinenum write setshowlinenum stored true; 
    property ShowRowCount:boolean read fshowrowcount write setshowrowcount stored true; 
    property RowsReturned:boolean read fRowsReturned write setRowsReturned default false; 
    property AutoDbProc:boolean read FAutoDbProc write SetAutoDbProc default true; 
    property Background:boolean read FBackground write SetBackground default false; 
    property ColumnCount :integer read FColumnCount; 
    property DbProc:integer read FDbproc write SetDbProc default 0; 
  end; 
 
procedure Register; 
 
implementation 
uses sybase32, 
     objectlistdlg, 
     ansistringedit, 
     sybdatabase, 
     sybquery; 
 
procedure Register; 
begin 
  RegisterPropertyEditor(TypeInfo(SybObjectname),tsybgrid,'',Tsybobjectproperty); 
  RegisterPropertyEditor(TypeInfo(AnsiString),tsybgrid,'Sql',TstringsProperty); 
  RegisterComponents('Sybase DBLIB', [tsybgrid]); 
end; 
 
constructor tsybgrid.create(AOwner:TComponent); 
begin 
  inherited create(AOwner); 
  Fdesignactive:=false; 
  Fautodbproc:=true; 
  FBackground:=false; 
  Fdbproc:=0; 
  Fshowlinenum:=true; 
  Fshowrowcount:=true; 
  Defaultrowheight:=20; 
  rowcount:=2; 
  colcount:=2; 
  font.name:='Courier'; 
  font.size:=9; 
  fontsize:=font.size; 
  numcols:=font.size; 
  options:=opt; 
  fixedrows:=1; 
  sql_commands:=tstringlist.create; 
end; 
 
destructor tsybgrid.Destroy; 
begin 
  sql_commands.Free; 
  inherited destroy; 
end; 
 
procedure tsybgrid.SetAutoDbPRoc(Value :boolean); 
begin 
  FAutoDbProc:=value; 
end; 
 
function tsybgrid.GetTerminated:boolean; 
begin 
  if thread <> nil then 
    result:=thread.terminated; 
end; 
 
procedure tsybgrid.SetBackground(Value :boolean); 
begin 
  FBackground:=value; 
end; 
 
procedure tsybgrid.SetShowLineNum(Value :boolean); 
begin 
  FShowLineNum:=value; 
end; 
 
procedure tsybgrid.SetShowRowCount(Value :boolean); 
begin 
  FShowRowCount:=value; 
end; 
 
procedure tsybgrid.SetDbProc(Value :integer); 
begin 
  FDbproc:=Value; 
  Dbprocc:=Value; 
end; 
 
procedure tsybgrid.SetSql(Value :ansistring); 
begin 
  FSql:=Value; 
end; 
 
procedure tsybgrid.Setdesignactive(Value :boolean); 
begin 
  if value then 
  begin 
    get_dbproc; 
    if (length(sql) > 1) then 
    sqlexec; 
  end; 
  Fdesignactive:=Value; 
end; 
 
procedure tsybgrid.SetRowsReturned(Value:boolean); 
begin 
  FRowsReturned:=value; 
end; 
 
procedure tsybgrid.addsql(Value :ansistring); 
begin 
  FSql:=FSql + Value; 
end; 
 
procedure tsybgrid.clearsql; 
begin 
  FSql:=''; 
end; 
 
procedure tsybgrid.SetDbname(Value :SybObjectname); 
begin 
  FDbname:=value; 
  get_dbproc; 
end; 
 
function tsybgrid.sqlexec:integer; 
var value             :string[255]; 
    i,j,nc            :integer; 
    p                 :pchar; 
    rows,first        :integer; 
    sql_count         :integer; 
    max_numcols       :integer; 
    max_rows_return   :integer; 
    col_widths        :array[1..300] of smallint; 
 
begin 
  get_dbproc; 
  if dbproc = 0 then 
    exit; 
  for i:=1 to 300 do 
    col_widths[i]:=10; 
  get_sql_commands; 
  if FBackground then 
  begin 
    thread:=Threadgrid.create(false,self); 
    exit; 
  end; 
 
  for j:=1 to rowcount do 
    for i:=1 to numcols do 
    begin 
      cells[i,j]:=''; 
    end; 
 
  rowcount:=2; 
  colcount:=2; 
  fixedrows:=1; 
  Retcode := Dbcanquery(dbProc); 
 
  max_numcols:=1; 
  refresh; 
  retcode2:=0; 
  linenum:=1; 
  first:=1; 
  max_rows_return:=fail; 
 
  for sql_count:=0 to sql_commands.count-1 do 
  begin 
    p:=pchar(sql_commands[sql_count]); 
    Retcode:=dbcmd(dbProc,p); 
    Retcode:=dbsqlexec(dbProc); 
    Retcode:=dbresults(dbProc); 
    rows:=dbcmdrow(dbProc); 
    Result:=retcode; 
 
    if rows = fail then 
    begin 
    end 
    else 
    begin 
      max_rows_return:=succeed; 
    end; 
 
    numcols:=dbnumcols(dbProc); 
    if numcols > max_numcols then 
      max_numcols:=numcols; 
    nc:=numcols; 
    FColumncount:=max_numcols; 
    colcount:=max_numcols + 1; 
 
    while (retcode <> No_more_results) and (retcode <> Fail) do 
    begin 
      if retcode = Succeed then 
      begin 
        rows:=dbrows(dbProc); 
        if rows <> fail then 
        begin 
          cells[0,linenum]:=' '; 
          if showlinenum then 
            if linenum > 0 then 
              cells[0,linenum]:=inttostr(linenum); 
          for i:=1 to numcols do 
          begin 
            if (length(strpas(dbcolname(dbProc,i))) * fontsize > colwidths[i]) then 
              colwidths[i]:=length(strpas(dbcolname(dbProc,i))) * fontsize; 
            cells[i,linenum]:=dbcolname(dbProc,i); 
            col_widths[i]:=colwidths[i]; 
          end; 
          rowcount:=rowcount + 1; 
          inc(linenum); 
        end; 
 
        retcode2 := dbnextrow(dbProc); 
 
        while retcode2 <> No_More_Rows do 
        Begin 
          if first = 0 then 
            rowcount:=rowcount + 1 
          else 
            first:=0; 
 
          cells[0,linenum]:=' '; 
          if showlinenum then 
            if linenum > 0 then 
              cells[0,linenum]:=inttostr(linenum); 
          colwidths[0]:=length(cells[0,linenum]) * fontsize + 5; 
 
          if not showlinenum then 
            colwidths[0]:=13; 
 
          for i:=1 to numcols do 
          begin 
            if (length(strpas(dbvalue(dbProc,i))) * fontsize > colwidths[i]) then 
              colwidths[i]:=length(strpas(dbvalue(dbProc,i))) * fontsize; 
            cells[i,linenum]:=dbvalue(dbProc,i); 
            if length(cells[i,linenum])=0 then 
              cells[i,linenum]:=' '; 
            col_widths[i]:=colwidths[i]; 
          end; 
          inc(linenum); 
          retcode2 := dbnextrow(dbProc); 
          result:=retcode2; 
        end; 
      end; 
      Retcode := dbresults(dbproc); 
 
      rows:=dbrows(dbProc); 
      if rows = fail then 
      begin 
      end 
      else 
      begin 
        max_rows_return:=succeed; 
      end; 
 
      numcols:=dbnumcols(dbProc); 
      if numcols > max_numcols then 
        max_numcols:=numcols; 
 
      colcount:=max_numcols + 1; 
 
      for i:=1 to max_numcols do 
      begin 
        if colwidths[i] nil then 
      for i:=0 to (sybase_components.databaseslist.count-1) do 
      begin 
        adatabase:=databaseslist[i]; 
        theproc(adatabase.name); 
      end; 
  end 
end; 
 
function Tsybobjectproperty.getattributes:Tpropertyattributes; 
begin 
  Result := [paValueList,paAutoUpdate,paMultiSelect]; 
end; 
 
procedure tsybgrid.get_dbproc; 
var i         :integer; 
    adatabase :tsybdatabase; 
begin 
  if not autodbproc then 
    exit; 
 
  if databaseslist <> nil then 
    for i:=0 to (sybase_components.databaseslist.count-1) do 
    begin 
      adatabase:=databaseslist[i]; 
      if FDbName = adatabase.name then 
      begin 
        setdbproc(adatabase.dbproc); 
        break; 
      end; 
    end; 
 
end; 
function Tstringsproperty.getvalue:string; 
begin 
  result:=getstrvalue; 
end; 
 
procedure Tstringsproperty.setvalue(const value:string); 
begin 
  setstrvalue(value); 
end; 
 
procedure Tstringsproperty.edit; 
var 
  OKBottomDlg: TOKBottomDlg; 
begin 
  OKBottomDlg:=TOKBottomDlg.create(nil); 
  OKBottomDlg.memo.text:=getstrvalue; 
  OKBottomDlg.showmodal; 
  if OKBottomDlg.modalresult = mrok then 
  begin 
    setstrvalue(OKBottomDlg.memo.text); 
  end; 
end; 
 
function Tstringsproperty.getattributes:Tpropertyattributes; 
begin 
  result:=[padialog]; 
end; 
 
constructor Threadgrid.create(b:boolean;AOwner:tsybgrid); 
begin 
   fparent:=AOwner; 
   inherited create(b); 
   fparent:=AOwner; 
 
{   f_cancel_query:=Tf_cancel_query.create(fparent); 
   f_cancel_query.show; 
   f_cancel_query.close; 
   f_cancel_query.free;} 
end; 
 
procedure Threadgrid.Execute; 
var value             :string[255]; 
    i,j,nc    :integer; 
    p                 :pchar; 
    rows,first        :integer; 
    RetCode,retcode2  :integer; 
    max_rows_return   :integer; 
    max_numcols       :integer; 
    sql_count         :integer; 
    col_widths        :array[1..300] of smallint; 
 
begin 
 
  freeonterminate:=true; 
  for j:=1 to fparent.rowcount do 
    for i:=1 to fparent.numcols do 
    begin 
      if terminated then 
      begin 
        fparent.thread.destroy; 
        exit; 
      end; 
      fparent.cells[i,j]:=''; 
    end; 
  fparent.rowcount:=2; 
  fparent.fixedrows:=1; 
  fparent.colcount:=2; 
  for i:=1 to 300 do 
    col_widths[i]:=10; 
  if terminated then 
  begin 
    fparent.thread.destroy; 
    exit; 
  end; 
  Retcode := Dbcanquery(fparent.dbProc); 
  max_numcols:=1; 
 
  if terminated then 
  begin 
    fparent.thread.destroy; 
    exit; 
  end; 
 
  fparent.linenum:=1;  {XX} 
  first:=1; 
  for sql_count:=0 to fparent.sql_commands.count-1 do 
  begin 
 
  p:=pchar(fparent.sql_commands[sql_count]); 
 
  if terminated then 
  begin 
    fparent.thread.destroy; 
    exit; 
  end; 
  Retcode:=dbcmd(fparent.dbProc,p); 
  if terminated then 
  begin 
    destroy; 
    fparent.thread.destroy; 
    exit; 
  end; 
  Retcode:=dbsqlexec(fparent.dbProc); 
  if terminated then 
  begin 
    fparent.thread.destroy; 
    exit; 
  end; 
  Retcode:=dbresults(fparent.dbProc); 
  if terminated then 
  begin 
    fparent.thread.destroy; 
    exit; 
  end; 
 
  rows:=dbrows(fparent.dbProc); 
  if terminated then 
  begin 
    fparent.thread.destroy; 
    exit; 
  end; 
  if rows = fail then 
  begin 
  end 
  else 
  begin 
    max_rows_return:=succeed; 
  end; 
   
  if terminated then 
  begin 
    fparent.thread.destroy; 
    exit; 
  end; 
 
{  Result:=retcode;} 
 
  fparent.numcols:=dbnumcols(fparent.dbProc); 
  if fparent.numcols> max_numcols then 
    max_numcols:=fparent.numcols; 
 
  nc:=fparent.numcols; 
  fparent.FColumncount:=max_numcols; 
  if terminated then 
  begin 
    fparent.thread.destroy; 
    exit; 
  end; 
 
  fparent.colcount:=max_numcols + 1; 
 
  if terminated then 
  begin 
    fparent.thread.destroy; 
    exit; 
  end; 
 
  while (retcode <> No_more_results) and (retcode <> Fail) do 
  begin 
    if terminated then 
    begin 
      fparent.thread.destroy; 
      exit; 
    end; 
    if retcode = Succeed then 
    begin 
      if terminated then 
      begin 
        fparent.thread.destroy; 
        exit; 
      end; 
 
      rows:=dbrows(fparent.dbProc); 
      if rows <> fail then 
      begin 
        fparent.cells[0,fparent.linenum]:=' '; 
        if fparent.showlinenum then 
          if fparent.linenum > 0 then 
            fparent.cells[0,fparent.linenum]:=inttostr(fparent.linenum); 
        for i:=1 to fparent.numcols do 
        begin 
          if terminated then 
          begin 
            fparent.thread.destroy; 
            exit; 
          end; 
          fparent.cells[i,fparent.linenum]:=dbcolname(fparent.dbProc,i); 
          if (length(strpas(dbcolname(fparent.dbProc,i))) * fparent.fontsize > fparent.colwidths[i]) then 
            fparent.colwidths[i]:=length(strpas(dbcolname(fparent.dbProc,i))) * fparent.fontsize; 
          col_widths[i]:=fparent.colwidths[i]; 
        end; 
        fparent.rowcount:=fparent.rowcount + 1; 
        inc(fparent.linenum); 
      end; 
 
      retcode2 := dbnextrow(fparent.dbProc); 
      while retcode2 <> No_More_Rows do 
      Begin 
        if terminated then 
        begin 
          fparent.thread.destroy; 
          exit; 
        end; 
 
        if first = 0 then 
          fparent.rowcount:=fparent.rowcount + 1 
        else 
          first:=0; 
 
        fparent.cells[0,fparent.linenum]:=' '; 
        if fparent.showlinenum then 
          if fparent.linenum > 0 then 
            fparent.cells[0,fparent.linenum]:=inttostr(fparent.linenum); 
        fparent.colwidths[0]:=length(fparent.cells[0,fparent.linenum]) * fparent.fontsize + 5; 
        if not fparent.showlinenum then 
          fparent.colwidths[0]:=13; 
        for i:=1 to fparent.numcols do 
        begin 
          if terminated then 
          begin 
            fparent.thread.destroy; 
            exit; 
          end; 
          if (length(strpas(dbvalue(fparent.dbProc,i))) * fparent.fontsize > fparent.colwidths[i]) then 
            fparent.colwidths[i]:=length(strpas(dbvalue(fparent.dbProc,i))) * fparent.fontsize; 
          fparent.cells[i,fparent.linenum]:=dbvalue(fparent.dbProc,i); 
          if length(fparent.cells[i,fparent.linenum])=0 then 
            fparent.cells[i,fparent.linenum]:=' '; 
          col_widths[i]:=fparent.colwidths[i]; 
        end; 
        if terminated then 
        begin 
          fparent.thread.destroy; 
          exit; 
        end; 
        inc(fparent.linenum); 
        retcode2 := dbnextrow(fparent.dbProc); 
{        result:=retcode2;} 
      end; 
    end; 
    if terminated then 
    begin 
      fparent.thread.destroy; 
      exit; 
    end; 
    Retcode := dbresults(fparent.dbproc); 
    fparent.numcols:=dbnumcols(fparent.dbProc); 
    if fparent.numcols > max_numcols then 
      max_numcols:=fparent.numcols; 
    fparent.colcount:=max_numcols + 1; 
 
    for i:=1 to max_numcols do 
    begin 
      if fparent.colwidths[i] length(sql_comm) then 
      begin 
        l:=copy(sql_comm,lastfound,length(sql_comm)-lastfound+1); 
        if length(trim(l))>0 then 
        begin 
          sql_commands.add(l); 
          if ShowRowCount then 
          begin 
            sql_commands.add('select "(" + convert(varchar(10),@@rowcount) + " rows affected)"'); 
          end; 
        end; 
      end; 
      if sql_commands.Count=1 then 
         sql_commands.add('select "(" + convert(varchar(10),@@rowcount) + " rows affected)"'); 
      exit; 
    end; 
    if iFoundPosit > 0 then 
    begin 
      ifCurrentpos:=iFoundPosit+char_indx+1; 
      char_indx:=ifCurrentpos-1; 
      l:=copy(sql_comm,lastfound,ifCurrentpos-lastfound-length(sFindText)); 
      sql_commands.add(l); 
      if ShowRowCount then 
      begin 
        sql_commands.add('select "(" + convert(varchar(10),@@rowcount) + " rows affected)"'); 
      end; 
      l:=''; 
      lastfound:=ifCurrentpos + length(sFindText)-1; 
      inc(go_count); 
    end; 
  end; 
  if sql_commands.Count=1 then 
     sql_commands.add('select "(" + convert(varchar(10),@@rowcount) + " rows affected)"'); 
end; 
 
end.