www.pudn.com > sybase_dblib4.zip > Sybtable.pas
{$H+}
unit sybtable;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Grids,DsgnIntf,sybase_components,sybquery,sybnavigator;
type
SybObjectname = string[30];
sqlstring = array[0..8000] of char;
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
{ tsybtable = class(TWinControl)}
TSybTable = class(TComponent)
private
{ Private declarations }
FSql :ansistring;
FTablename :SybObjectname;
FDbname :SybObjectname;
FDesignActive :boolean;
FMaxCount :integer;
FColumnCount :integer;
FBuffersize :integer;
FRowsReturned :boolean;
FAutoDbProc :boolean;
FUpdateFields :boolean;
FDbProc :integer;
FSprocUpdate :SybObjectname;
FSprocInsert :SybObjectname;
FSprocDelete :SybObjectname;
{ FFields_List :TStrings;}
procedure SetUpdateSProc(Value :SybObjectname);
procedure SetInsertSProc(Value :SybObjectname);
procedure SetDeleteSProc(Value :SybObjectname);
procedure SetAutoDbProc(Value :boolean);
procedure setupdatefields(Value:boolean);
procedure SetDbProc(Value :integer);
procedure SetDbName(Value :SybObjectname);
procedure SetDesignActive(Value :boolean);
procedure SetMaxCount(Value :integer);
procedure SetBuffersize(Value :integer);
procedure SetRowsReturned(Value :boolean);
procedure Settablename(Value :SybObjectname);
procedure Readfieldscount(Reader: TReader);
procedure Writefieldscount(Writer: TWriter);
procedure Writefields(Writer: TWriter);
procedure Readfields(Reader: TReader);
procedure update_fields;
{ procedure SetFields_List(Value:TStrings);}
protected
{ Protected declarations }
first_flag :boolean;
procedure get_dbproc;
procedure get_databasefields;
procedure DefineProperties(Filer: TFiler); override;
procedure setname(const NewName:Tcomponentname); override;
procedure LoadSqlFromFile(FileName :string);
public
fieldscount :smallint;
fields :array[1..255] of SybObjectname;
datafields :array[1..255] of SybObjectname;
datafieldscount :smallint;
SqlCommand :sqlstring;
Login,Retcode,retcode2,nocols,col:integer;
dbprocc:integer;
numcols :integer;
firstrownum,lastrownum,currrownum:longint;
navigator :tsybnavigator;
{ fldslist :tstrings;}
constructor create(AOwner:TComponent); override;
destructor destroy;
function sqlexec:integer;
function nextrow:integer;
function prevrow:integer;
function firstrow:integer;
function lastrow:integer;
function row_exists:boolean;
function column(index:byte):string;
function heading(index:byte):string;
function coltype(index:byte):string;
function collength(index:byte):integer;
function ischar(index:byte):boolean;
procedure addfield(value:SybObjectname);
procedure deletefield(value:SybObjectname);
procedure loaded; override;
function insert_record:integer;
function update_record:integer;
function delete_record:integer;
published
{ Published declarations }
property RowsReturned:boolean read fRowsReturned write setRowsReturned default false;
property DbName :SybObjectname read FDbName write setDbname;
property TableName :SybObjectname read FTableName write settablename;
property DesignActive:boolean read fdesignactive write setdesignactive stored false;
property MaxCount :integer read FMaxCount write SetMaxCount default 0;
property ColumnCount :integer read FColumnCount;
property BufferSize :integer read FBuffersize write SetBuffersize;
property AutoDbProc:boolean read FAutoDbProc write SetAutoDbProc default true;
property DbProc:integer read FDbproc write SetDbProc default 0;
property SProcUpdate :SybObjectname read FSProcUpdate write setUpdateSProc;
property SProcInsert :SybObjectname read FSProcInsert write setInsertSProc;
property SProcDelete :SybObjectname read FSProcDelete write setDeleteSProc;
property UpdateFields:boolean read fupdatefields write setupdatefields default true;
{ property FieldsLst:TStrings read FFields_List write SetFields_List;}
end;
procedure Register;
implementation
uses sybase32,
objectlistdlg,
ansistringedit,
sybdatabase,
sybsproc,
sybcombobox,
sybcheckbox,
sybradiobutton,
sybmemo;
procedure Register;
begin
RegisterPropertyEditor(TypeInfo(SybObjectname),tsybtable,'',Tsybobjectproperty);
RegisterPropertyEditor(TypeInfo(AnsiString),tsybtable,'Sql',TstringsProperty);
RegisterComponents('Sybase DBLIB', [tsybtable]);
end;
procedure tsybtable.DefineProperties(Filer: TFiler);
begin
inherited DefineProperties(Filer);
Filer.DefineProperty('FieldsProp', Readfields, Writefields,fieldscount>0);
Filer.DefineProperty('FieldsCountProp',Readfieldscount,Writefieldscount,true);
end;
procedure tsybtable.LoadSqlFromFile(FileName :string);
begin
fsql:=sybase_components.LoadFromFile(FileName);
end;
procedure tsybtable.SetUpdateSProc(Value :SybObjectname);
begin
FSProcUpdate:=value;
end;
procedure tsybtable.SetInsertSProc(Value :SybObjectname);
begin
FSProcInsert:=value;
end;
procedure tsybtable.SetDeleteSProc(Value :SybObjectname);
begin
FSProcDelete:=value;
end;
procedure TSybtable.Readfields(Reader: TReader);
var i:integer;
begin
Reader.ReadListBegin;
fieldscount:=0;
while not Reader.EndOfList do begin inc(fieldscount); fields[fieldscount]:=Reader.ReadString; end; Reader.ReadListEnd;
end;
procedure TSybtable.Writefields(Writer: TWriter);
var I: Integer;
begin
Writer.WriteListBegin;
for I := 1 to fieldscount do Writer.WriteString(fields[I]);
Writer.WriteListEnd;
end;
procedure tsybtable.Readfieldscount(Reader: TReader);
begin
fieldscount := Reader.ReadInteger;
end;
procedure tsybtable.Writefieldscount(Writer: TWriter);
begin
Writer.WriteInteger(fieldscount);
end;
procedure TSybtable.loaded;
begin
inherited loaded;
{ setfields_list(fldslist);}
end;
{procedure TSybtable.Setfields_List(Value :TStrings);
begin
Ffields_List.assign(Value);
end;}
constructor tsybtable.create(AOwner:TComponent);
begin
inherited create(AOwner);
first_flag:=true;
Fdesignactive:=false;
Fautodbproc:=true;
FBuffersize:=0;
fupdatefields:=true;
Fdbproc:=0;
{ ffields_list:=tstringlist.create;
fldslist:=tstringlist.create;
setfields_list(fldslist);}
if tablelist = nil then
begin
tablelist:=TList.create;
end;
end;
destructor tsybtable.destroy;
begin
tablelist.remove(self);
inherited destroy;
end;
procedure TSybtable.setname(const NewName:Tcomponentname);
begin
inherited setname(NewName);
if tablelist.indexof(self) = -1 then
tablelist.add(self)
else
begin
tablelist.items[tablelist.indexof(self)]:=self;
end;
end;
procedure tsybtable.SetDbProc(Value :integer);
begin
FDbproc:=Value;
Dbprocc:=Value;
end;
procedure Tsybtable.SetAutoDbPRoc(Value :boolean);
begin
FAutoDbProc:=value;
end;
procedure Tsybtable.SetUpdatefields(Value :boolean);
begin
Fupdatefields:=value;
end;
procedure tsybtable.SetRowsReturned(Value:boolean);
begin
FRowsReturned:=value;
end;
procedure tsybtable.Setdesignactive(Value :boolean);
begin
Fdesignactive:=Value;
get_dbproc;
if length(tablename) > 0 then
get_databasefields;
{ setfields_list(fldslist);}
end;
procedure Tsybtable.SetMaxCount(Value :integer);
begin
FMaxCount:=Value;
end;
procedure Tsybtable.SetBuffersize(Value :integer);
var p :pchar;
s :string[20];
begin
FBuffersize:=Value;
s:=inttostr(value);
new(p);
strpcopy(p,s);
if (Value > 0) then
begin
retcode:=dbsetopt(dbproc,DBBUFFER,p,-1);
dispose(p);
end;
end;
procedure tsybtable.SetDbname(Value :SybObjectname);
begin
FDbname:=value;
get_dbproc;
end;
function tsybtable.sqlexec:integer;
var value :string[255];
linenum,i,j,rows :integer;
p :pchar;
begin
if navigatorlist <> nil then
begin
for i:=0 to navigatorlist.count-1 do
begin
if tsybnavigator(navigatorlist[i]).DataSet = name then
begin
navigator:=tsybnavigator(navigatorlist[i]);
break;
end;
end;
end
else
begin
navigator:=tsybnavigator.create(nil);
end;
get_dbproc;
if dbprocc = 0 then
exit;
Fsql:='select * from ' + FTableName;
if (retcode2 <> More_Rows) then
begin
Retcode := Dbcancel(dbProc);
p:=pchar(Fsql);
Retcode:=dbcmd(dbProc,p);
Retcode:=dbsqlexec(dbProc);
Retcode:=dbresults(dbProc);
rows:=dbrows(dbProc);
if rows = fail then
setrowsreturned(false)
else
begin
setrowsreturned(true);
end;
numcols:=dbnumcols(dbProc);
FColumncount:=numcols;
Result:=retcode;
retcode2:=0;
if retcode = Succeed then
begin
firstrownum:=1;
lastrownum:=1;
{ retcode2 := dbnextrow(dbProc);}
end;
end;
end;
procedure Tsybtable.Settablename(Value :SybObjectname);
begin
Ftablename:=value;
get_databasefields;
end;
function Tsybtable.row_exists:boolean;
var res:integer;
begin
result:=false;
res:=nextrow;
if res = -1 then
result:=true;
end;
function Tsybtable.nextrow:integer;
begin
result:=0;
if (retcode = Succeed) then
begin
retcode2 := dbnextrow(dbProc);
Result:=retcode2;
if (fupdatefields) and (retcode2=-1) then
update_fields;
case retcode2 of
-1 :begin
if first_flag then
begin
navigator.btnfirst.enabled:=false;
navigator.btnprior.enabled:=false;
navigator.btnnext.enabled:=true;
navigator.btnlast.enabled:=true;
first_flag:=false;
end
else
begin
navigator.btnfirst.enabled:=true;
navigator.btnprior.enabled:=true;
navigator.btnnext.enabled:=true;
navigator.btnlast.enabled:=true;
end;
end;
-2 :begin
if first_flag then
begin
navigator.btnfirst.enabled:=false;
navigator.btnprior.enabled:=false;
navigator.btnnext.enabled:=false;
navigator.btnlast.enabled:=false;
end;
end;
end;
currrownum:=dbcurrow(dbProc);
if currrownum > lastrownum then
lastrownum:=currrownum;
end
else
result:=No_More_Rows;
end;
function Tsybtable.prevrow:integer;
var value :string[255];
retcode3:integer;
begin
result:=0;
if (retcode = Succeed) then
begin
currrownum:=dbcurrow(dbProc);
if currrownum > 1 then
dec(currrownum);
retcode3 := dbgetrow(dbproc,currrownum);
if fupdatefields then
update_fields;
if currrownum = 1 then
begin
navigator.btnfirst.enabled:=false;
navigator.btnprior.enabled:=false;
navigator.btnnext.enabled:=true;
navigator.btnlast.enabled:=true;
end
else
begin
navigator.btnfirst.enabled:=true;
navigator.btnprior.enabled:=true;
navigator.btnnext.enabled:=true;
navigator.btnlast.enabled:=true;
end;
Result:=retcode3;
end
else
begin
retcode:=No_More_Rows;
result:=No_More_Rows;
end;
end;
function Tsybtable.firstrow:integer;
var value :string[255];
retcode3:integer;
begin
result:=0;
if (retcode = Succeed) then
begin
retcode3 := dbgetrow(dbproc,firstrownum);
Result:=retcode3;
if fupdatefields then
update_fields;
navigator.btnfirst.enabled:=false;
navigator.btnprior.enabled:=false;
navigator.btnnext.enabled:=true;
navigator.btnlast.enabled:=true;
end
else
result:=No_More_Rows;
end;
function Tsybtable.lastrow:integer;
var value :string[255];
retcode3:integer;
begin
result:=0;
if (retcode = Succeed) then
begin
retcode3 := dbgetrow(dbproc,dblastrow(dbProc));
Result:=retcode3;
if fupdatefields then
update_fields;
navigator.btnfirst.enabled:=true;
navigator.btnprior.enabled:=true;
navigator.btnnext.enabled:=false;
navigator.btnlast.enabled:=false;
end
else
result:=No_More_Rows;
end;
function Tsybtable.column(index:byte):string;
begin
result:=strpas(dbvalue(dbproc,index))
end;
function Tsybtable.heading(index:byte):string;
begin
result:=strpas(dbcolname(dbproc,index))
end;
function Tsybtable.coltype(index:byte):string;
begin
result:=strpas(dbprtype(dbcoltype(dbproc,index)))
end;
function Tsybtable.collength(index:byte):integer;
begin
result:=dbcollen(dbproc,index)
end;
function Tsybtable.ischar(index:byte):boolean;
var colltyp :string;
begin
result:=false;
if (coltype(index)='char')
or (coltype(index)='text')
or (coltype(index)='datetime')
or (coltype(index)='smalldatetime') then
begin
result:=true;
exit;
end;
if (coltype(index)='binary')
or (coltype(index)='tinyint')
or (coltype(index)='smallint')
or (coltype(index)='int')
or (coltype(index)='float')
or (coltype(index)='real')
or (coltype(index)='numeric')
or (coltype(index)='decimal')
or (coltype(index)='bit')
or (coltype(index)='money')
or (coltype(index)='smallmoney')
or (coltype(index)='sum')
or (coltype(index)='avg')
or (coltype(index)='count')
or (coltype(index)='min')
or (coltype(index)='max') then
begin
result:=false;
end;
end;
procedure Tsybobjectproperty.GetValues(TheProc: TGetStrProc);
var
Login,Retcode,retcode2,i:integer;
dbname :SybObjectname;
s :string;
tslist:Tsybtable;
SqlCommand :sqlstring;
adatabase :tsybdatabase;
asproc :tsybsproc;
begin
tslist:=Tsybtable(getcomponent(0));
{ if getname='FieldsLst' then
begin
for i:=0 to tslist.ffields_list.count-1 do
theproc(tslist.ffields_list[i]);
end;}
if getname = 'DbName' then
begin
if databaseslist <> nil then
for i:=0 to (sybase_components.databaseslist.count-1) do
begin
adatabase:=databaseslist[i];
theproc(adatabase.name);
end;
end
else
if (getname = 'SProcUpdate')
or (getname = 'SProcInsert')
or (getname = 'SProcDelete') then
begin
if sybase_components.sproclist <> nil then
for i:=0 to (sybase_components.sproclist.count-1) do
begin
asproc:=sproclist[i];
theproc(asproc.name);
end;
end
else
if tslist.dbproc > 40 then
begin
if getname = 'TableName' then
begin
strpcopy(Sqlcommand,'select name from sysobjects where type in ("U","S") order by name');
Retcode := dbcmd(tslist.dbProc,@Sqlcommand);
Retcode := Dbsqlexec(tslist.dbProc);
Retcode := dbresults(tslist.dbProc);
retcode2:=0;
while (retcode <> No_more_results) and (retcode <> Fail) do
begin
if retcode = Succeed then
begin
retcode2 := dbnextrow(tslist.dbProc);
while retcode2 <> No_More_Rows do
Begin
theproc(strpas(dbvalue(tslist.dbproc,1)));
retcode2 := dbnextrow(tslist.dbProc);
end;
end;
Retcode := dbresults(tslist.dbproc);
end;
end;
{ ServList.add(copy(l,2,length(l)-2));}
end
else
showmessage('Not connected to database !');
end;
function Tsybobjectproperty.getattributes:Tpropertyattributes;
begin
Result := [paValueList,paAutoUpdate,paMultiSelect];
end;
procedure tsybtable.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;
procedure tsybtable.addfield(value:SybObjectname);
var i :smallint;
begin
for i:=1 to fieldscount do
begin
if fields[i]=value then
exit;
end;
inc(fieldscount);
fields[fieldscount]:=value;
end;
procedure tsybtable.deletefield(value:SybObjectname);
var i,j :smallint;
newfields:array[1..100] of SybObjectname;
begin
j:=0;
for i:=1 to fieldscount do
begin
if fields[i] <> value then
begin
inc(j);
newfields[j]:=fields[i];
end;
end;
fieldscount:=j;
for i:=1 to fieldscount do
fields[i]:=newfields[i];
end;
procedure tsybtable.get_databasefields;
var tmpquery :tsybquery;
begin
if FDesignActive then
begin
get_dbproc;
tmpquery:=tsybquery.create(nil);
tmpquery.dbname:=dbname;
tmpquery.dbproc:=dbproc;
tmpquery.sql:='select name from syscolumns where id = object_id("' + tablename + '") order by colid';
datafieldscount:=0;
tmpquery.sqlexec;
if (tmpquery.nextrow=-1) or (tmpquery.nextrow=1) then
begin
inc(datafieldscount);
datafields[datafieldscount]:=tmpquery.column(1);
{ fldslist.add(datafields[datafieldscount]);}
while tmpquery.nextrow = -1 do
begin
inc(datafieldscount);
datafields[datafieldscount]:=tmpquery.column(1);
{ fldslist.add(datafields[datafieldscount]);}
end;
end;
tmpquery.free;
end;
end;
function TSybTable.insert_record:integer;
var i :integer;
begin
showmessage(inttostr(sybase_components.fieldslist.count));
for i:=1 to fieldscount do
begin
showmessage(fields[i] + ' = ' + tsybfield(fieldslist.items[i-1]).value);
end;
end;
function TSybTable.update_record:integer;
begin
{}
end;
function TSybTable.delete_record:integer;
begin
{}
end;
procedure TSybTable.update_fields;
var i,j :integer;
field :tsybfield;
begin
for i:=1 to numcols do
begin
if fieldslist <> nil then
begin
for j:=0 to fieldslist.count-1 do
begin
if (lowercase(tcomponent(fieldslist.items[j]).classname)='tsybedit') then
begin
if (tsybfield(fieldslist[j]).dataset = name)
and (tsybfield(fieldslist[j]).datafield = heading(i)) then
tsybfield(fieldslist[j]).value:=column(i);
end
else
if (lowercase(tcomponent(fieldslist.items[j]).classname)='tsybmemo') then
begin
if (tsybmemo(fieldslist[j]).dataset = name)
and (tsybmemo(fieldslist[j]).datafield = heading(i)) then
tsybmemo(fieldslist[j]).value:=column(i);
end
else
if (lowercase(tcomponent(fieldslist.items[j]).classname)='tsybcheckbox') then
begin
if (tsybcheckbox(fieldslist[j]).dataset = name)
and (tsybcheckbox(fieldslist[j]).datafield = heading(i)) then
tsybcheckbox(fieldslist[j]).value:=column(i);
end
else
if (lowercase(tcomponent(fieldslist.items[j]).classname)='tsybradiobutton') then
begin
if (tsybradiobutton(fieldslist[j]).tablename = name)
and (tsybradiobutton(fieldslist[j]).datafield = heading(i)) then
tsybradiobutton(fieldslist[j]).value:=column(i);
end;
end;
end;
end;
end;
end.