📄 sybdataset.pas
字号:
unit SybDataSet;
interface
uses Windows, Db, Classes,
SybBaseQuery,
SybDatabase;
type
PSybData = ^TSybData;
TSybData = record
Name :array[0..29] of char;
Id :array[0..10] of char;
end;
type
// Bookmark information record to support TDataset bookmarks:
PSybBookmarkInfo = ^TSybBookmarkInfo;
TSybBookmarkInfo = record
BookmarkData: Integer;
BookmarkFlag: TBookmarkFlag;
end;
TSybDataSet = class(TDataSet)
private
public
FQuery :TSybBaseQuery;
FTableName: string;
FRecordPos: Integer;
FRecordSize: Integer;
FBufferSize: Integer;
procedure SetTableName(const Value: string);
protected
{ Mandatory overrides }
// Record buffer methods:
function AllocRecordBuffer: PChar; override;
procedure FreeRecordBuffer(var Buffer: PChar); override;
procedure InternalInitRecord(Buffer: PChar); override;
function GetRecord(Buffer: PChar; GetMode: TGetMode;
DoCheck: Boolean): TGetResult; override;
function GetRecordSize: Word; override;
procedure SetFieldData(Field: TField; Buffer: Pointer); override;
// Bookmark methods:
procedure GetBookmarkData(Buffer: PChar; Data: Pointer); override;
function GetBookmarkFlag(Buffer: PChar): TBookmarkFlag; override;
procedure InternalGotoBookmark(Bookmark: Pointer); override;
procedure InternalSetToRecord(Buffer: PChar); override;
procedure SetBookmarkFlag(Buffer: PChar; Value: TBookmarkFlag); override;
procedure SetBookmarkData(Buffer: PChar; Data: Pointer); override;
// Navigational methods:
procedure InternalFirst; override;
procedure InternalLast; override;
// Editing methods:
procedure InternalAddRecord(Buffer: Pointer; Append: Boolean); override;
procedure InternalDelete; override;
procedure InternalPost; override;
// Misc methods:
procedure InternalClose; override;
procedure InternalHandleException; override;
procedure InternalInitFieldDefs; override;
procedure InternalOpen; override;
function IsCursorOpen: Boolean; override;
{ Optional overrides }
function GetRecordCount: Integer; override;
function GetRecNo: Integer; override;
procedure SetRecNo(Value: Integer); override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
function GetFieldData(Field: TField; Buffer: Pointer): Boolean; override;
published
property Active;
property TableName: string read FTableName write SetTableName;
property BufferCount;
property BeforeOpen;
property AfterOpen;
property BeforeClose;
property AfterClose;
property BeforeInsert;
property AfterInsert;
property BeforeEdit;
property AfterEdit;
property BeforePost;
property AfterPost;
property BeforeCancel;
property AfterCancel;
property BeforeDelete;
property AfterDelete;
property BeforeScroll;
property AfterScroll;
property OnDeleteError;
property OnEditError;
end;
procedure Register;
implementation
uses BDE, DBTables, SysUtils, DBConsts, Forms, Controls, Dialogs;
procedure Register;
begin
RegisterComponents('Sybase DBLIB', [TSybDataSet]);
end;
{ TSybDataSet }
function TSybDataSet.AllocRecordBuffer: PChar;
begin
Result := AllocMem(FBufferSize);
end;
constructor TSybDataSet.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FRecordSize := SizeOf(TSybData);
FBufferSize := FRecordSize + SizeOf(TSybBookmarkInfo);
FQuery:=TSybBaseQuery.create(nil);
FQuery.DbName:='db';
end;
destructor TSybDataSet.Destroy;
begin
inherited Destroy;
end;
procedure TSybDataSet.FreeRecordBuffer(var Buffer: PChar);
begin
FreeMem(Buffer);
end;
procedure TSybDataSet.GetBookmarkData(Buffer: PChar; Data: Pointer);
begin
PInteger(Data)^ := PSybBookmarkInfo(Buffer + FRecordSize)^.BookmarkData;
end;
function TSybDataSet.GetBookmarkFlag(Buffer: PChar): TBookmarkFlag;
begin
Result := PSybBookmarkInfo(Buffer + FRecordSize)^.BookmarkFlag;
end;
function TSybDataSet.GetFieldData(Field: TField; Buffer: Pointer): Boolean;
begin
Result := True;
case Field.Index of
0:begin
Move(PSybData(ActiveBuffer)^.Name, Buffer^, Field.DataSize);
end;
1:begin
Move(PSybData(ActiveBuffer)^.Id, Buffer^, Field.DataSize);
end
end;
end;
function TSybDataSet.GetRecNo: Integer;
begin
UpdateCursorPos;
if (FRecordPos = -1) and (RecordCount > 0) then
Result := 1
else
Result := FRecordPos + 1;
end;
function TSybDataSet.GetRecord(Buffer: PChar; GetMode: TGetMode;
DoCheck: Boolean): TGetResult;
var
IndexPos: Integer;
begin
if FQuery.RowsAffected < 1 then
Result := grEOF
else
begin
Result := grOk;
case GetMode of
gmPrior:
if FRecordPos <= 0 then
begin
Result := grBOF;
FRecordPos := -1;
end
else
Dec(FRecordPos);
gmCurrent:
if (FRecordPos < 0) or (FRecordPos >= RecordCount) then
Result := grError;
gmNext:
if FRecordPos >= RecordCount-1 then
Result := grEOF
else
Inc(FRecordPos);
end;
if Result = grOk then
begin
FQuery.GetRow(FRecordPos+1);
strpcopy(PSybData(Buffer)^.Name,FQuery.Column(1));
strpcopy(PSybData(Buffer)^.Id,FQuery.Column(2));
with PSybBookmarkInfo(Buffer + FRecordSize)^ do
begin
BookmarkData := FRecordPos;
BookmarkFlag := bfCurrent;
end;
end
else if (Result = grError) and DoCheck then
DatabaseError('No records');
end;
end;
function TSybDataSet.GetRecordCount: Integer;
begin
Result := FQuery.RowsAffected;
end;
function TSybDataSet.GetRecordSize: Word;
begin
Result := FRecordSize;
end;
procedure TSybDataSet.InternalAddRecord(Buffer: Pointer; Append: Boolean);
begin
//
end;
procedure TSybDataSet.InternalClose;
begin
if DefaultFields then
DestroyFields;
FRecordPos := -1;
end;
procedure TSybDataSet.InternalDelete;
begin
//
end;
procedure TSybDataSet.InternalFirst;
begin
FRecordPos := -1;
end;
procedure TSybDataSet.InternalGotoBookmark(Bookmark: Pointer);
begin
FRecordPos := Integer(Bookmark);
end;
procedure TSybDataSet.InternalHandleException;
begin
// standard implementation for this method:
Application.HandleException(Self);
end;
procedure TSybDataSet.InternalInitFieldDefs;
var i :integer;
begin
// create FieldDefs which map to each field in the data record
FieldDefs.Clear;
// TFieldDef.Create(FieldDefs, FQuery.heading(1), ftString, FQuery.collength(1), False, 1);
// TFieldDef.Create(FieldDefs, FQuery.heading(2), ftString, 11, False, 2);
for i:=1 to FQuery.Numcols do
begin
TFieldDef.Create(FieldDefs, FQuery.heading(i), ftString, FQuery.collength(i), False, i);
end;
end;
procedure TSybDataSet.InternalInitRecord(Buffer: PChar);
begin
FillChar(Buffer^, FBufferSize, 0);
end;
procedure TSybDataSet.InternalLast;
begin
FRecordPos := FQuery.RowsAffected;
end;
procedure TSybDataSet.InternalOpen;
begin
// if not FQuery.Active then
// begin
// MessageBox(GetActiveWindow,'Not connected to database','DB-Library error',mb_ok+mb_iconexclamation);
// exit;
// end;
FQuery.Active:=True;
FQuery.sql:='select name,id from develop..t_cursor';
FQuery.sqlexec;
while FQuery.nextrow = -1 do;
try
FRecordPos := -1; // initial record pos before BOF
BookmarkSize := SizeOf(Integer); // initialize bookmark size for VCL
InternalInitFieldDefs; // initialize FieldDef objects
// Create TField components when no persistent fields have been created
if DefaultFields then
CreateFields;
BindFields(True); // bind FieldDefs to actual data
except
raise;
end;
end;
procedure TSybDataSet.InternalPost;
begin
//
end;
procedure TSybDataSet.InternalSetToRecord(Buffer: PChar);
begin
FRecordPos := PSybBookmarkInfo(Buffer + FRecordSize)^.Bookmarkdata;
end;
function TSybDataSet.IsCursorOpen: Boolean;
begin
Result:=FQuery.Active;
end;
procedure TSybDataSet.SetBookmarkData(Buffer: PChar; Data: Pointer);
begin
PSybBookmarkInfo(Buffer + FRecordSize)^.BookmarkData := PInteger(Data)^;
end;
procedure TSybDataSet.SetBookmarkFlag(Buffer: PChar; Value: TBookmarkFlag);
begin
PSybBookmarkInfo(Buffer + FRecordSize)^.BookmarkFlag := Value;
end;
procedure TSybDataSet.SetFieldData(Field: TField; Buffer: Pointer);
begin
case Field.Index of
0: Move(Buffer^, PSybData(ActiveBuffer)^.Name, Field.Size);
1: Move(Buffer^, PSybData(ActiveBuffer)^.Id, Field.DataSize);
end;
DataEvent(deFieldChange, Longint(Field));
end;
procedure TSybDataSet.SetRecNo(Value: Integer);
begin
if (Value >= 0) and (Value <= FQuery.RowsAffected-1) then
begin
FRecordPos := Value - 1;
Resync([]);
end;
end;
procedure TSybDataSet.SetTableName(const Value: string);
begin
CheckInactive;
FTableName := Value;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -