📄 jvqmemorydataset.pas
字号:
{******************************************************************************}
{* WARNING: JEDI VCL To CLX Converter generated unit. *}
{* Manual modifications will be lost on next release. *}
{******************************************************************************}
{-----------------------------------------------------------------------------
The contents of this file are subject to the Mozilla Public License
Version 1.1 (the "License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/MPL-1.1.html
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
the specific language governing rights and limitations under the License.
The Original Code is: JvMemDS.PAS, released on 2002-07-04.
The Initial Developers of the Original Code are: Fedor Koshevnikov, Igor Pavluk and Serge Korolev
Copyright (c) 1997, 1998 Fedor Koshevnikov, Igor Pavluk and Serge Korolev
Copyright (c) 2001,2002 SGB Software
All Rights Reserved.
You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
located at http://jvcl.sourceforge.net
Known Issues:
//********************** Added by Claudio F. Zwitkovits (CFZ) **************************
Property DataSet <== Attach any bi-directional DataSet (TTable,TQuery,etc)
Property DataSetClosed <== True/False If After Load Structure and/or Records, Close the attached DataSet
Property KeyFieldNames <== String with the names of the fields from the primary key / Index key
Property ApplyMode <== The mode do Apply the changes in original DataSet
amNone = Not Apply
amAppend = Allow ONLY insert records, and edit/delete this records inserted
amMerge = Allow ALL (Insert,Edit,Delete) records
Property ExactApply <== If True, the RowsAffected (Applied) EQUAL FRowsChanged
If False, Apply Tolerance
Property LoadStructure <== If True, is NOT needed define the fields in design time
the JvMemoryData load the fields from the original dataset
Property LoadRecords <== TRUE/FALSE Auto-load records from the original dataset.
Property SaveLoadState <== Return if loading or saving from/to other dataset.
Events BeforeApply, AfterApply <== in the calling to the ApplyChanges public method.
BeforeApplyRecord, AfterApplyRecord <== in the calling to the SaveChanges internal methods.
Methods (Public) ApplyChanges and CancelChanges <== Save / Discard the changes into
the original DataSet.
Methods (Public) IsLoading <== True/False. If the JvMemData is loading data from external dataset
(LoadFromDataSet or CopyFromDataSet)
Methods (Public) IsSaving <== True/False If the JvMemData is saving data to external dataset
(SaveToDataSet or ApplyChanges)
Methods (Public) IsInserted, IsUpdated, IsOriginal, IsDeleted
return the status from the current record
Methods (Public) GetValues <== Obtain the values from list of Fields or Key Fields
IMPORTANT : This component, add a hidden field, in the last position ( in FieldDefs
And Fields Lists ) and save the STATUS of the current record
(rsOriginal, rsInserted, rsUpdated), in the hidden field.
Likewise, have a private List (FDeletedValues) with the primary key values
from the Deleted records (rsDeleted).
Implementation : 2004/03/03
Revisions : 1st = 2004/09/19
2nd = 2004/10/19
3th = 2004/10/25
Comments and Bugs : cfzwit att yahoo dott com dott ar
-----------------------------------------------------------------------------}
// $Id: JvQMemoryDataset.pas,v 1.11 2005/02/06 14:06:14 asnepvangers Exp $
unit JvQMemoryDataset;
{$I jvcl.inc}
interface
uses
SysUtils, Classes, DB,
{$IFDEF HAS_UNIT_VARIANTS}
Variants,
{$ENDIF HAS_UNIT_VARIANTS}
JvQDBUtils;
type
//----------------- Added by CFZ -----------------------------
TPVariant = ^Variant;
TApplyMode = (amNone, amAppend, amMerge);
TRecordStatus = (rsOriginal, rsUpdated, rsInserted, rsDeleted);
TApplyRecordEvent = procedure(DataSet: TDataSet; RecStatus: TRecordStatus; FoundApply: Boolean) of object;
//------------------------------------------------------------
TMemBlobData = string;
TMemBlobArray = array [0..0] of TMemBlobData;
PMemBlobArray = ^TMemBlobArray;
TJvMemoryRecord = class;
TLoadMode = (lmCopy, lmAppend);
TSaveLoadState = (slsNone, slsLoading, slsSaving);
TCompareRecords = function(Item1, Item2: TJvMemoryRecord): Integer of object;
TJvMemoryData = class(TDataSet)
private
FSaveLoadState: TSaveLoadState;
FRecordPos: Integer;
FRecordSize: Integer;
FBookmarkOfs: Integer;
FBlobOfs: Integer;
FRecBufSize: Integer;
FOffsets: PWordArray;
FLastID: Integer;
FAutoInc: Longint;
FActive: Boolean;
FRecords: TList;
FIndexList: TList;
FCaseInsensitiveSort: Boolean;
FDescendingSort: Boolean;
FAutoIncField: TField;
FSrcAutoIncField: TField;
//-------------- Added by CFZ ----------------------------
FDataSet: TDataSet;
FDataSetClosed: Boolean;
FLoadStructure: Boolean;
FLoadRecords: Boolean;
FKeyFieldNames: string;
FApplyMode: TApplyMode;
FExactApply: Boolean;
FAutoIncAsInteger: Boolean;
FRowsOriginal: Integer;
FRowsChanged: Integer;
FRowsAffected: Integer;
FDeletedValues: TList;
FStatusName: string;
FBeforeApply: TDataSetNotifyEvent;
FAfterApply: TDataSetNotifyEvent;
FBeforeApplyRecord: TApplyRecordEvent;
FAfterApplyRecord: TApplyRecordEvent;
//--------------------------------------------------------
function AddRecord: TJvMemoryRecord;
function InsertRecord(Index: Integer): TJvMemoryRecord;
function FindRecordID(ID: Integer): TJvMemoryRecord;
procedure CreateIndexList(const FieldNames: string);
procedure FreeIndexList;
procedure QuickSort(L, R: Integer; Compare: TCompareRecords);
procedure Sort;
function CalcRecordSize: Integer;
function GetMemoryRecord(Index: Integer): TJvMemoryRecord;
function GetCapacity: Integer;
function RecordFilter: Boolean;
procedure SetCapacity(Value: Integer);
procedure ClearRecords;
procedure InitBufferPointers(GetProps: Boolean);
procedure FixReadOnlyFields(MakeReadOnly: Boolean);
//----------------- Added by CFZ -----------------------------
procedure SetDataSet(ADataSet: TDataSet);
procedure SetDataSetClosed(Value: Boolean);
procedure SetLoadStructure(Value: Boolean);
procedure SetLoadRecords(Value: Boolean);
procedure SetApplyMode(Value: TApplyMode);
procedure SetExactApply(Value: Boolean);
procedure CheckStructure(UseAutoIncAsInteger: Boolean = False);
procedure AddStatusField;
procedure HideStatusField;
function CopyFromDataSet: Integer;
procedure ClearChanges;
procedure DoBeforeApply;
procedure DoAfterApply;
procedure DoBeforeApplyRecord(ADataSet: TDataSet; RS: TRecordStatus; Found: Boolean);
procedure DoAfterApplyRecord(ADataSet: TDataSet; RS: TRecordStatus; Apply: Boolean);
//------------------------------------------------------------
protected
function FindFieldData(Buffer: Pointer; Field: TField): Pointer;
function CompareFields(Data1, Data2: Pointer; FieldType: TFieldType;
CaseInsensitive: Boolean): Integer; virtual;
procedure DataConvert(Field: TField; Source, Dest: Pointer; ToNative: Boolean); override;
procedure AssignMemoryRecord(Rec: TJvMemoryRecord; Buffer: PChar);
function GetActiveRecBuf(var RecBuf: PChar): Boolean; virtual;
procedure InitFieldDefsFromFields;
procedure RecordToBuffer(Rec: TJvMemoryRecord; Buffer: PChar);
procedure SetMemoryRecordData(Buffer: PChar; Pos: Integer); virtual;
procedure SetAutoIncFields(Buffer: PChar); virtual;
function CompareRecords(Item1, Item2: TJvMemoryRecord): Integer; virtual;
function GetBlobData(Field: TField; Buffer: PChar): TMemBlobData;
procedure SetBlobData(Field: TField; Buffer: PChar; Value: TMemBlobData);
function AllocRecordBuffer: PChar; override;
procedure FreeRecordBuffer(var Buffer: PChar); override;
procedure InternalInitRecord(Buffer: PChar); override;
procedure ClearCalcFields(Buffer: PChar); override;
function GetRecord(Buffer: PChar; GetMode: TGetMode;
DoCheck: Boolean): TGetResult; override;
function GetRecordSize: Word; override;
procedure SetFiltered(Value: Boolean); override;
procedure SetOnFilterRecord(const Value: TFilterRecordEvent); override;
procedure SetFieldData(Field: TField; Buffer: Pointer); override;
procedure CloseBlob(Field: TField); override;
procedure GetBookmarkData(Buffer: PChar; Data: Pointer); override;
function GetBookmarkFlag(Buffer: PChar): TBookmarkFlag; override;
procedure InternalGotoBookmark(Bookmark: TBookmark); override;
procedure InternalSetToRecord(Buffer: PChar); override;
procedure SetBookmarkFlag(Buffer: PChar; Value: TBookmarkFlag); override;
procedure SetBookmarkData(Buffer: PChar; Data: Pointer); override;
function GetIsIndexField(Field: TField): Boolean; override;
procedure InternalFirst; override;
procedure InternalLast; override;
procedure InitRecord(Buffer: PChar); override;
procedure InternalAddRecord(Buffer: Pointer; Append: Boolean); override;
procedure InternalDelete; override;
procedure InternalPost; override;
procedure InternalClose; override;
procedure InternalHandleException; override;
procedure InternalInitFieldDefs; override;
procedure InternalOpen; override;
procedure OpenCursor(InfoQuery: Boolean); override;
function IsCursorOpen: Boolean; override;
function GetRecordCount: Integer; override;
function GetRecNo: Integer; override;
procedure SetRecNo(Value: Integer); override;
property Records[Index: Integer]: TJvMemoryRecord read GetMemoryRecord;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
function BookmarkValid(Bookmark: TBookmark): Boolean; override;
function CompareBookmarks(Bookmark1, Bookmark2: TBookmark): Integer; override;
function CreateBlobStream(Field: TField; Mode: TBlobStreamMode): TStream; override;
function GetFieldData(Field: TField; Buffer: Pointer): Boolean; override;
function GetCurrentRecord(Buffer: PChar): Boolean; override;
function IsSequenced: Boolean; override;
function Locate(const KeyFields: string; const KeyValues: Variant;
Options: TLocateOptions): Boolean; override;
procedure SortOnFields(const FieldNames: string;
CaseInsensitive: Boolean = True; Descending: Boolean = False);
procedure EmptyTable;
procedure CopyStructure(Source: TDataSet; UseAutoIncAsInteger: Boolean = False);
function LoadFromDataSet(Source: TDataSet; RecordCount: Integer;
Mode: TLoadMode; DisableAllControls: Boolean = True): Integer;
function SaveToDataSet(Dest: TDataSet; RecordCount: Integer; DisableAllControls: Boolean = True): Integer;
property SaveLoadState: TSaveLoadState read FSaveLoadState;
//-------------------- Added by CFZ ---------------------------------
procedure Open; reintroduce;
function GetValues(FldNames: string = ''): Variant;
function FindDeleted(KeyValues: Variant): Integer;
function IsDeleted(out Index: Integer): Boolean;
function IsInserted: Boolean;
function IsUpdated: Boolean;
function IsOriginal: Boolean;
procedure CancelChanges;
function ApplyChanges: Boolean;
function IsLoading: Boolean;
function IsSaving: Boolean;
property RowsOriginal: Integer read FRowsOriginal;
property RowsChanged: Integer read FRowsChanged;
property RowsAffected: Integer read FRowsAffected;
//-------------------------------------------------------------------
published
property Capacity: Integer read GetCapacity write SetCapacity default 0;
property Active;
property AutoCalcFields;
property Filtered;
property FieldDefs;
property ObjectView default False;
//------------------- Added by CFZ ---------- ----------------------
property DataSet: TDataSet read FDataSet write SetDataSet;
property DataSetClosed: Boolean read FDataSetClosed write SetDataSetClosed default True;
property KeyFieldNames: string read FKeyFieldNames write FKeyFieldNames;
property LoadStructure: Boolean read FLoadStructure write SetLoadStructure default False;
property LoadRecords: Boolean read FLoadRecords write SetLoadRecords default False;
property ApplyMode: TApplyMode read FApplyMode write SetApplyMode default amNone;
property ExactApply: Boolean read FExactApply write SetExactApply default False;
property AutoIncAsInteger: Boolean read FAutoIncAsInteger write FAutoIncAsInteger default False;
//------------------------------------------------------------------
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 OnCalcFields;
property OnDeleteError;
property OnEditError;
property OnFilterRecord;
property OnNewRecord;
property OnPostError;
//------------------- Added by CFZ ---------------------------------
property BeforeApply: TDataSetNotifyEvent read FBeforeApply write FBeforeApply;
property AfterApply: TDataSetNotifyEvent read FAfterApply write FAfterApply;
property BeforeApplyRecord: TApplyRecordEvent read FBeforeApplyRecord write FBeforeApplyRecord;
property AfterApplyRecord: TApplyRecordEvent read FAfterApplyRecord write FAfterApplyRecord;
//------------------------------------------------------------------
end;
TJvMemBlobStream = class(TStream)
private
FField: TBlobField;
FDataSet: TJvMemoryData;
FBuffer: PChar;
FMode: TBlobStreamMode;
FOpened: Boolean;
FModified: Boolean;
FPosition: Longint;
FCached: Boolean;
function GetBlobSize: Longint;
function GetBlobFromRecord(Field: TField): TMemBlobData;
public
constructor Create(Field: TBlobField; Mode: TBlobStreamMode);
destructor Destroy; override;
function Read(var Buffer; Count: Longint): Longint; override;
function Write(const Buffer; Count: Longint): Longint; override;
function Seek(Offset: Longint; Origin: Word): Longint; override;
procedure Truncate;
end;
TJvMemoryRecord = class(TPersistent)
private
FMemoryData: TJvMemoryData;
FID: Integer;
FData: Pointer;
FBlobs: Pointer;
function GetIndex: Integer;
procedure SetMemoryData(Value: TJvMemoryData; UpdateParent: Boolean);
protected
procedure SetIndex(Value: Integer); virtual;
public
constructor Create(MemoryData: TJvMemoryData); virtual;
constructor CreateEx(MemoryData: TJvMemoryData; UpdateParent: Boolean); virtual;
destructor Destroy; override;
property MemoryData: TJvMemoryData read FMemoryData;
property ID: Integer read FID write FID;
property Index: Integer read GetIndex write SetIndex;
property Data: Pointer read FData;
end;
implementation
uses
{$IFDEF UNITVERSIONING}
JclUnitVersioning,
{$ENDIF UNITVERSIONING}
QForms, QDialogs, DbConsts, Math,
JvQResources;
const
ftBlobTypes = [ftBlob, ftMemo, ftGraphic, ftFmtMemo, ftParadoxOle,
ftDBaseOle, ftTypedBinary, ftOraBlob, ftOraClob];
ftSupported = [ftString, ftSmallint, ftInteger, ftWord, ftBoolean, ftFloat,
ftCurrency, ftDate, ftTime, ftDateTime, ftAutoInc, ftBCD, ftBytes,
ftVarBytes, ftADT, ftFixedChar, ftWideString,
ftLargeint, ftVariant, ftGuid] +
ftBlobTypes;
fkStoredFields = [fkData];
GuidSize = 38;
//-------- Added by CFZ --------------------
STATUSNAME = 'C67F70Z90'; (* Magic *)
//------------------------------------------
{ Utility routines }
function CalcFieldLen(FieldType: TFieldType; Size: Word): Word;
begin
if not (FieldType in ftSupported) then
Result := 0
else
if FieldType in ftBlobTypes then
Result := SizeOf(Longint)
else
begin
Result := Size;
case FieldType of
ftString:
Inc(Result);
ftSmallint:
Result := SizeOf(Smallint);
ftInteger:
Result := SizeOf(Longint);
ftWord:
Result := SizeOf(Word);
ftBoolean:
Result := SizeOf(WordBool);
ftFloat:
Result := SizeOf(Double);
ftCurrency:
Result := SizeOf(Double);
ftBCD:
Result := 34;
ftDate, ftTime:
Result := SizeOf(Longint);
ftDateTime:
Result := SizeOf(TDateTime);
ftBytes:
Result := Size;
ftVarBytes:
Result := Size + 2;
ftAutoInc:
Result := SizeOf(Longint);
ftADT:
Result := 0;
ftFixedChar:
Inc(Result);
ftWideString:
Result := (Result + 1) * 2;
ftLargeint:
Result := SizeOf(Int64);
ftVariant:
Result := SizeOf(Variant);
ftGuid:
Result := GuidSize + 1;
end;
end;
end;
procedure CalcDataSize(FieldDef: TFieldDef; var DataSize: Integer);
var
I: Integer;
begin
with FieldDef do
begin
if DataType in ftSupported - ftBlobTypes then
Inc(DataSize, CalcFieldLen(DataType, Size) + 1);
for I := 0 to ChildDefs.Count - 1 do
CalcDataSize(ChildDefs[I], DataSize);
end;
end;
procedure Error(const Msg: string);
begin
DatabaseError(Msg);
end;
procedure ErrorFmt(const Msg: string; const Args: array of const);
begin
DatabaseErrorFmt(Msg, Args);
end;
type
TBookmarkData = Integer;
PMemBookmarkInfo = ^TMemBookmarkInfo;
TMemBookmarkInfo = record
BookmarkData: TBookmarkData;
BookmarkFlag: TBookmarkFlag;
end;
//=== { TJvMemoryRecord } ====================================================
constructor TJvMemoryRecord.Create(MemoryData: TJvMemoryData);
begin
CreateEx(MemoryData, True);
end;
constructor TJvMemoryRecord.CreateEx(MemoryData: TJvMemoryData;
UpdateParent: Boolean);
begin
inherited Create;
SetMemoryData(MemoryData, UpdateParent);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -