📄 jvqmemorydataset.pas
字号:
Result := Data <> nil
else
Result := Data[0] <> #0;
Inc(Data);
if Field.DataType in [ftString, ftFixedChar, ftWideString, ftGuid] then
Result := Result and (StrLen(Data) > 0);
if Result and (Buffer <> nil) then
if Field.DataType = ftVariant then
begin
VarData := PVariant(Data)^;
PVariant(Buffer)^ := VarData;
end
else
Move(Data^, Buffer^, CalcFieldLen(Field.DataType, Field.Size));
end;
end
else
if State in [dsBrowse, dsEdit, dsInsert, dsCalcFields] then
begin
Inc(RecBuf, FRecordSize + Field.Offset);
Result := RecBuf[0] <> #0;
if Result and (Buffer <> nil) then
Move(RecBuf[1], Buffer^, Field.DataSize);
end;
end;
procedure TJvMemoryData.SetFieldData(Field: TField; Buffer: Pointer);
var
RecBuf, Data: PChar;
VarData: Variant;
begin
if not (State in dsWriteModes) then
Error(SNotEditing);
GetActiveRecBuf(RecBuf);
with Field do
begin
if FieldNo > 0 then
begin
if State in [dsCalcFields, dsFilter] then
Error(SNotEditing);
if ReadOnly and not (State in [dsSetKey, dsFilter]) then
ErrorFmt(SFieldReadOnly, [DisplayName]);
Validate(Buffer);
if FieldKind <> fkInternalCalc then
begin
Data := FindFieldData(RecBuf, Field);
if Data <> nil then
begin
if DataType = ftVariant then
begin
if Buffer <> nil then
VarData := PVariant(Buffer)^
else
VarData := EmptyParam;
Data[0] := Char(Ord((Buffer <> nil) and not
(VarIsNull(VarData) or VarIsEmpty(VarData))));
if Data[0] <> #0 then
begin
Inc(Data);
PVariant(Data)^ := VarData;
end
else
FillChar(Data^, CalcFieldLen(DataType, Size), 0);
end
else
begin
Data[0] := Char(Ord(Buffer <> nil));
Inc(Data);
if Buffer <> nil then
Move(Buffer^, Data^, CalcFieldLen(DataType, Size))
else
FillChar(Data^, CalcFieldLen(DataType, Size), 0);
end;
end;
end;
end
else {fkCalculated, fkLookup}
begin
Inc(RecBuf, FRecordSize + Offset);
RecBuf[0] := Char(Ord(Buffer <> nil));
if RecBuf[0] <> #0 then
Move(Buffer^, RecBuf[1], DataSize);
end;
if not (State in [dsCalcFields, dsFilter, dsNewValue]) then
DataEvent(deFieldChange, Longint(Field));
end;
end;
procedure TJvMemoryData.SetFiltered(Value: Boolean);
begin
if Active then
begin
CheckBrowseMode;
if Filtered <> Value then
inherited SetFiltered(Value);
First;
end
else
inherited SetFiltered(Value);
end;
procedure TJvMemoryData.SetOnFilterRecord(const Value: TFilterRecordEvent);
begin
if Active then
begin
CheckBrowseMode;
inherited SetOnFilterRecord(Value);
if Filtered then
First;
end
else
inherited SetOnFilterRecord(Value);
end;
function TJvMemoryData.RecordFilter: Boolean;
var
SaveState: TDataSetState;
begin
Result := True;
if Assigned(OnFilterRecord) then
begin
if (FRecordPos >= 0) and (FRecordPos < RecordCount) then
begin
SaveState := SetTempState(dsFilter);
try
RecordToBuffer(Records[FRecordPos], TempBuffer);
OnFilterRecord(Self, Result);
except
Application.HandleException(Self);
end;
RestoreState(SaveState);
end
else
Result := False;
end;
end;
function TJvMemoryData.GetBlobData(Field: TField; Buffer: PChar): TMemBlobData;
begin
Result := PMemBlobArray(Buffer + FBlobOfs)[Field.Offset];
end;
procedure TJvMemoryData.SetBlobData(Field: TField; Buffer: PChar;
Value: TMemBlobData);
begin
if Buffer = ActiveBuffer then
begin
if State = dsFilter then
Error(SNotEditing);
PMemBlobArray(Buffer + FBlobOfs)[Field.Offset] := Value;
end;
end;
procedure TJvMemoryData.CloseBlob(Field: TField);
begin
if (FRecordPos >= 0) and (FRecordPos < FRecords.Count) and (State = dsEdit) then
PMemBlobArray(ActiveBuffer + FBlobOfs)[Field.Offset] :=
PMemBlobArray(Records[FRecordPos].FBlobs)[Field.Offset]
else
PMemBlobArray(ActiveBuffer + FBlobOfs)[Field.Offset] := '';
end;
function TJvMemoryData.CreateBlobStream(Field: TField; Mode: TBlobStreamMode): TStream;
begin
Result := TJvMemBlobStream.Create(Field as TBlobField, Mode);
end;
function TJvMemoryData.BookmarkValid(Bookmark: TBookmark): Boolean;
begin
Result := (Bookmark <> nil) and FActive and (TBookmarkData(Bookmark^) > Low(Integer)) and
(TBookmarkData(Bookmark^) <= FLastID);
end;
function TJvMemoryData.CompareBookmarks(Bookmark1, Bookmark2: TBookmark): Integer;
begin
if (Bookmark1 = nil) and (Bookmark2 = nil) then
Result := 0
else
if (Bookmark1 <> nil) and (Bookmark2 = nil) then
Result := 1
else
if (Bookmark1 = nil) and (Bookmark2 <> nil) then
Result := -1
else
if TBookmarkData(Bookmark1^) > TBookmarkData(Bookmark2^) then
Result := 1
else
if TBookmarkData(Bookmark1^) < TBookmarkData(Bookmark2^) then
Result := -1
else
Result := 0;
end;
procedure TJvMemoryData.GetBookmarkData(Buffer: PChar; Data: Pointer);
begin
Move(PMemBookmarkInfo(Buffer + FBookmarkOfs)^.BookmarkData, Data^,
SizeOf(TBookmarkData));
end;
procedure TJvMemoryData.SetBookmarkData(Buffer: PChar; Data: Pointer);
begin
Move(Data^, PMemBookmarkInfo(Buffer + FBookmarkOfs)^.BookmarkData,
SizeOf(TBookmarkData));
end;
function TJvMemoryData.GetBookmarkFlag(Buffer: PChar): TBookmarkFlag;
begin
Result := PMemBookmarkInfo(Buffer + FBookmarkOfs)^.BookmarkFlag;
end;
procedure TJvMemoryData.SetBookmarkFlag(Buffer: PChar; Value: TBookmarkFlag);
begin
PMemBookmarkInfo(Buffer + FBookmarkOfs)^.BookmarkFlag := Value;
end;
procedure TJvMemoryData.InternalGotoBookmark(Bookmark: TBookmark);
var
Rec: TJvMemoryRecord;
SavePos: Integer;
Accept: Boolean;
begin
Rec := FindRecordID(TBookmarkData(Bookmark^));
if Rec <> nil then
begin
Accept := True;
SavePos := FRecordPos;
try
FRecordPos := Rec.Index;
if Filtered then
Accept := RecordFilter;
finally
if not Accept then
FRecordPos := SavePos;
end;
end;
end;
procedure TJvMemoryData.InternalSetToRecord(Buffer: PChar);
begin
InternalGotoBookmark(@PMemBookmarkInfo(Buffer + FBookmarkOfs)^.BookmarkData);
end;
procedure TJvMemoryData.InternalFirst;
begin
FRecordPos := -1;
end;
procedure TJvMemoryData.InternalLast;
begin
FRecordPos := FRecords.Count;
end;
procedure TJvMemoryData.DataConvert(Field: TField; Source, Dest: Pointer; ToNative: Boolean);
begin
if Field.DataType = ftWideString then
begin
if ToNative then
begin
Word(Dest^) := Length(PWideString(Source)^) * 2;
Move(PWideChar(Source^)^, (PWideChar(Dest) + 1)^, Word(Dest^));
end
else
SetString(WideString(Dest^), PWideChar(PChar(Source) + 2), Word(Source^) div 2);
end
else
inherited DataConvert(Field, Source, Dest, ToNative);
end;
procedure TJvMemoryData.AssignMemoryRecord(Rec: TJvMemoryRecord; Buffer: PChar);
var
I: Integer;
begin
Move(Buffer^, Rec.Data^, FRecordSize);
for I := 0 to BlobFieldCount - 1 do
PMemBlobArray(Rec.FBlobs)[I] := PMemBlobArray(Buffer + FBlobOfs)[I];
end;
procedure TJvMemoryData.SetMemoryRecordData(Buffer: PChar; Pos: Integer);
var
Rec: TJvMemoryRecord;
begin
if State = dsFilter then
Error(SNotEditing);
Rec := Records[Pos];
AssignMemoryRecord(Rec, Buffer);
end;
procedure TJvMemoryData.SetAutoIncFields(Buffer: PChar);
var
I, Count: Integer;
Data: PChar;
begin
Count := 0;
for I := 0 to FieldCount - 1 do
if (Fields[I].FieldKind in fkStoredFields) and
(Fields[I].DataType = ftAutoInc) then
begin
Data := FindFieldData(Buffer, Fields[I]);
if Data <> nil then
begin
Data[0] := Char(Ord(True));
Inc(Data);
Move(FAutoInc, Data^, SizeOf(Longint));
Inc(Count);
end;
end;
if Count > 0 then
Inc(FAutoInc);
end;
procedure TJvMemoryData.InternalAddRecord(Buffer: Pointer; Append: Boolean);
var
RecPos: Integer;
Rec: TJvMemoryRecord;
begin
if Append then
begin
Rec := AddRecord;
FRecordPos := FRecords.Count - 1;
end
else
begin
if FRecordPos = -1 then
RecPos := 0
else
RecPos := FRecordPos;
Rec := InsertRecord(RecPos);
FRecordPos := RecPos;
end;
SetAutoIncFields(Buffer);
SetMemoryRecordData(Buffer, Rec.Index);
end;
procedure TJvMemoryData.InternalDelete;
var
Accept: Boolean;
//---- Added by CFZ ---------------
Status: TRecordStatus;
PFValues: TPVariant;
//---------------------------------
begin
//---------------------- Added by CFZ ---------------------------------
// Disable warnings
Status := rsOriginal;
PFValues := nil;
if FApplyMode <> amNone then
begin
Status := TRecordStatus(FieldByName(FStatusName).AsInteger);
if Status <> rsInserted then
begin
if FApplyMode = amAppend then
begin
Cancel;
Exit;
end
else
begin
New(PFValues);
PFValues^ := GetValues;
end;
end;
end;
//----------------------------------------------------------------------
Records[FRecordPos].Free;
if FRecordPos >= FRecords.Count then
Dec(FRecordPos);
Accept := True;
repeat
if Filtered then
Accept := RecordFilter;
if not Accept then
Dec(FRecordPos);
until Accept or (FRecordPos < 0);
if FRecords.Count = 0 then
FLastID := Low(Integer);
//---------------------- Added by CFZ 2004/03/03 ----------------------
if FApplyMode <> amNone then
begin
if Status = rsInserted then
Dec(FRowsChanged)
else
FDeletedValues.Add(PFValues);
if Status = rsOriginal then
Inc(FRowsChanged);
end;
//----------------------------------------------------------------------
end;
procedure TJvMemoryData.InternalPost;
var
RecPos: Integer;
//------ Added by CFZ -----------------
Index: Integer;
Status: TRecordStatus;
NewChange: Boolean;
//-------------------------------------
begin
//------------------------ Added by CFZ -----------------------------------
NewChange := False;
if (FApplyMode <> amNone) and not IsLoading then
begin
Status := TRecordStatus(FieldByName(FStatusName).AsInteger);
(* If (State = dsEdit) And (Status In [rsInserted,rsUpdated]) Then NewChange := False; *)
if (State = dsEdit) and (Status = rsOriginal) then
begin
if FApplyMode = amAppend then
begin
Cancel;
Exit;
end
else
begin
NewChange := True;
FieldByName(FStatusName).AsInteger := Integer(rsUpdated);
end;
end;
if State = dsInsert then
begin
if IsDeleted(Index) then
begin
FDeletedValues.Delete(Index);
if FApplyMode = amAppend then
FieldByName(FStatusName).AsInteger := Integer(rsInserted)
else
FieldByName(FStatusName).AsInteger := Integer(rsUpdated);
end
else
begin
NewChange := True;
FieldByName(FStatusName).AsInteger := Integer(rsInserted);
end;
end;
end;
//---------------------------------------------------------------------------
if State = dsEdit then
SetMemoryRecordData(ActiveBuffer, FRecordPos)
else
begin
if State in [dsInsert] then
SetAutoIncFields(ActiveBuffer);
if FRecordPos >= FRecords.Count then
begin
SetMemoryRecordData(ActiveBuffer, AddRecord.Index);
FRecordPos := FRecords.Count - 1;
end
else
begin
if FRecordPos = -1 then
RecPos := 0
else
RecPos := FRecordPos;
SetMemoryRecordData(ActiveBuffer, InsertRecord(RecPos).Index);
FRecordPos := RecPos;
end;
end;
//------------------------ Added by CFZ -----------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -