📄 memtableeh.pas
字号:
{$ENDIF}
begin
UpdateCursorPos;
if FRecordsView.ViewRecord[FRecordPos].OldData <> nil then
begin
Result := TempBuffer;
RecordToBuffer(FRecordsView.ViewRecord[FRecordPos], dvvOldValueEh, Result, FRecordPos);
end else
Result := nil;
end;
var
{$IFDEF EH_LIB_12}
Buffer: TRecordBuffer;
{$ELSE}
Buffer: {$IFDEF CIL}TRecordBuffer{$ELSE}PChar{$ENDIF};
{$ENDIF}
begin
if FInstantReadMode and not IsForWrite then
RecBuf := BufferToRecBuf(InstantBuffer)
else
case State of
dsBrowse:
if IsEmpty
then RecBuf := nil
else RecBuf := BufferToRecBuf(ActiveBuffer);
dsOldValue:
begin
Buffer := GetOldValuesBuffer;
if Buffer <> nil then
begin
RecBuf := BufferToRecBuf(Buffer);
if RecBuf = nil then
RecBuf := BufferToRecBuf(ActiveBuffer)
end else
RecBuf := nil;
end;
dsEdit, dsInsert, dsNewValue: RecBuf := BufferToRecBuf(ActiveBuffer);
dsCalcFields: RecBuf := BufferToRecBuf(CalcBuffer);
dsFilter: RecBuf := BufferToRecBuf(TempBuffer);
else RecBuf := nil;
end;
Result := RecBuf <> nil;
end;
{ Field Data }
function TCustomMemTableEh.GetFieldData(Field: TField;
Buffer: {$IFDEF CIL}TRecordBuffer{$ELSE}Pointer{$ENDIF}; NativeFormat: Boolean): Boolean;
var
// PVarValue: PVariant;
RecBuf: TRecBuf;
// FieldBufNo: Integer;
{$IFDEF CIL}
procedure VarToBuffer(var Value: Variant);
var
B: TBytes;
Len: Integer;
TimeStamp: TTimeStamp;
D: Double;
begin
case Field.DataType of
ftWideString:
begin
B := WideBytesOf(Value.ToString);
Len := Length(B);
if Len > Field.Size * 2 then
begin
SetLength(B, Field.Size * 2);
Len := Field.Size * 2;
end;
SetLength(B, Len + 2);
B[Len - 1] := 0;
B[Len] := 0; // add null terminator
Marshal.Copy(B, 0, Buffer, Len + 2);
end;
ftString, ftGuid:
begin
B := BytesOf(Value.ToString);
Len := Length(B);
if Len > Field.Size then
begin
SetLength(B, Field.Size);
Len := Field.Size;
end;
SetLength(B, Len + 1);
B[Len] := 0; // add null terminator
Marshal.Copy(B, 0, Buffer, Len + 1);
end;
ftFixedChar:
begin
B := BytesOf(System.String.Create(CharArray(Value)));
Len := Length(B);
if Len > Field.Size then
begin
SetLength(B, Field.Size);
Len := Field.Size;
end;
SetLength(B, Len + 1);
B[Len] := 0; // add null terminator
Marshal.Copy(B, 0, Buffer, Len + 1);
end;
ftSmallint, ftWord:
Marshal.WriteInt16(Buffer, SmallInt(Value));
ftAutoInc, ftInteger:
Marshal.WriteInt32(Buffer, Integer(Value));
ftLargeInt:
Marshal.WriteInt64(Buffer, Int64(Value));
ftBoolean:
if Boolean(Value) then
Marshal.WriteInt16(Buffer, 1)
else
Marshal.WriteInt16(Buffer, 0);
ftFloat, ftCurrency:
Marshal.WriteInt64(Buffer, BitConverter.DoubleToInt64Bits(Value));
ftBCD:
if NativeFormat then
Marshal.Copy(TBcd.ToBytes(Value), 0, Buffer, SizeOfTBCD)
else
Marshal.WriteInt64(Buffer, System.Decimal.ToOACurrency(System.Decimal(Value)));
ftDate, ftTime, ftDateTime:
if NativeFormat then
begin
TimeStamp := DateTimeToTimeStamp(TDateTime(Value));
case Field.DataType of
ftDate:
Marshal.WriteInt32(Buffer, TimeStamp.Date);
ftTime:
Marshal.WriteInt32(Buffer, TimeStamp.Time);
ftDateTime:
begin
D := TimeStampToMSecs(TimeStamp);
Marshal.WriteInt64(Buffer, BitConverter.DoubleToInt64Bits(D));
end;
end;
end
else
Marshal.WriteInt64(Buffer, BitConverter.DoubleToInt64Bits(Double(Value)));
ftBytes:
Marshal.Copy(TBytes(TObject(Value)), 0, Buffer,
Length(TBytes(TObject(Value))));
ftVarBytes:
begin
Len := Length(TBytes(TObject(Value)));
if NativeFormat then
begin
Marshal.WriteInt16(Buffer, Len);
Marshal.Copy(TBytes(TObject(Value)), 0, IntPtr(Integer(Buffer.ToInt32 + 2)), Len);
end else
Marshal.Copy(TBytes(TObject(Value)), 0, Buffer, Len);
end;
ftTimeStamp:
Marshal.StructureToPtr(TObject(Value), Buffer, False);
ftFMTBCD:
Marshal.Copy(TBcd.ToBytes(Value), 0, Buffer, SizeOfTBCD);
else
DatabaseErrorFmt('SUsupportedFieldType', [FieldTypeNames[Field.DataType], Field.DisplayName]);
end;
end;
{$ELSE}
procedure VarToBuffer(var Value: Variant);
begin
case Field.DataType of
ftGuid, ftFixedChar, ftString:
begin
PAnsiChar(Buffer)[Field.Size] := #0;
StrLCopy(PAnsiChar(Buffer), PAnsiChar(VarToAnsiStr(Value)), Field.Size);
end;
ftWideString:
{$IFDEF EH_LIB_10}
WStrCopy(PWideChar(Buffer), PWideChar(VarToWideStr(Value)));
{$ELSE}
WideString(Buffer^) := Value;
{$ENDIF}
ftSmallint:
SmallInt(Buffer^) := Value;
ftWord:
Word(Buffer^) := Value;
ftAutoInc, ftInteger:
Integer(Buffer^) := Value;
ftFloat, ftCurrency:
Double(Buffer^) := Value;
ftBCD:
if NativeFormat
then DataConvert(Field, @Value, Buffer, True)
else Currency(Buffer^) := Value;
ftBoolean:
WordBool(Buffer^) := Value;
ftDate, ftTime, ftDateTime:
if NativeFormat
then DataConvert(Field, @TVarData(Value).VDate, Buffer, True)
else TDateTime(Buffer^) := Value;
ftBytes, ftVarBytes:
if NativeFormat
then DataConvert(Field, @Value, Buffer, True)
else Variant(Buffer^) := Value;
ftInterface: IUnknown(Buffer^) := Value;
ftIDispatch: IDispatch(Buffer^) := Value;
{$IFDEF EH_LIB_6}
ftLargeInt: LargeInt(Buffer^) := Value;
ftTimeStamp:
if NativeFormat
then DataConvert(Field, @Value, Buffer, True)
else TSQLTimeStamp(Buffer^) := VarToSQLTimeStamp(Value);
ftFMTBcd:
if NativeFormat
then DataConvert(Field, @Value, Buffer, True)
else TBcd(Buffer^) := VarToBcd(Value);
{$ENDIF}
ftBlob..ftTypedBinary, ftVariant: Variant(Buffer^) := Value;
{$IFDEF EH_LIB_10}
ftWideMemo: Variant(Buffer^) := Value;
{$ENDIF}
else
DatabaseErrorFmt('SUsupportedFieldType', [FieldTypeNames[Field.DataType],
Field.DisplayName]);
end;
end;
{$ENDIF}
var
OutValue: Variant;
begin
Result := GetActiveRecBuf(RecBuf);
if not Result then Exit;
// if Field.FieldNo > 0
// then FieldBufNo := Field.Index //???Field.FieldNo - 1
// else FieldBufNo := {Field.Offset}FCalcFieldIndexes[Field.Index] + DataFieldsCount;
if Field.FieldKind = fkAggregate then
OutValue := GetAggregateValue(Field)
else
begin
// FieldBufNo := Field.Index;
// OutValue := RecBuf.Values[FieldBufNo];
OutValue := RecBuf.Value[Field];
if Assigned(FOnGetFieldValue) then
FOnGetFieldValue(Self, Field, OutValue);
end;
if VarIsNull(OutValue) then
Result := False
else if Buffer <> nil then
VarToBuffer(OutValue);
end;
function TCustomMemTableEh.GetFieldData(Field: TField; Buffer: {$IFDEF CIL}TRecordBuffer{$ELSE}Pointer{$ENDIF}): Boolean;
begin
Result := GetFieldData(Field, Buffer, True);
end;
function TCustomMemTableEh.GetFieldData(FieldNo: Integer; Buffer: {$IFDEF CIL}TRecordBuffer{$ELSE}Pointer{$ENDIF}): Boolean;
begin
Result := GetFieldData(FieldByNumber(FieldNo), Buffer);
end;
function TCustomMemTableEh.GetFieldDataAsObject(Field: TField; var Value: TObject): Boolean;
var
RecBuf: TRecBuf;
// FieldBufNo: Integer;
OutValue: Variant;
begin
Value := nil;
Result := GetActiveRecBuf(RecBuf);
if not Result then Exit;
// FieldBufNo := Field.Index;
// OutValue := RecBuf.Values[FieldBufNo];
OutValue := RecBuf.Value[Field];
if Assigned(FOnGetFieldValue) then
FOnGetFieldValue(Self, Field, OutValue);
if VarIsNull(OutValue)
then Result := False
else Value := VariantToRefObject(OutValue);
end;
procedure TCustomMemTableEh.SetFieldData(Field: TField;
Buffer: {$IFDEF CIL}TValueBuffer{$ELSE}Pointer{$ENDIF}; NativeFormat: Boolean);
var
RecBuf: TRecBuf;
// FieldBufNo: Integer;
v: Variant;
{$IFDEF CIL}
procedure BufferToVar(var Data: Variant);
var
B: TBytes;
Len: Smallint;
begin
case Field.DataType of
ftWideString:
Data := Variant(Marshal.PtrToStringUni(Buffer));
ftString, ftGuid, ftFixedChar:
Data := Variant(Marshal.PtrToStringAnsi(Buffer));
ftSmallint, ftWord:
Data := Variant(Marshal.ReadInt16(Buffer));
ftAutoInc, ftInteger:
Data := Variant(Marshal.ReadInt32(Buffer));
ftLargeInt:
Data := Variant(Marshal.ReadInt64(Buffer));
ftBoolean:
if Marshal.ReadInt16(Buffer) <> 0 then
Data := Variant(True)
else
Data := Variant(False);
ftFloat, ftCurrency:
Data := Variant(BitConverter.Int64BitsToDouble(Marshal.ReadInt64(Buffer)));
ftBCD:
if NativeFormat then
begin
SetLength(B, SizeOfTBCD);
Marshal.Copy(Buffer, B, 0, SizeOfTBCD);
Data := Variant(TBcd.FromBytes(B));
end
else
Data := System.Decimal.FromOACurrency(Marshal.ReadInt64(Buffer));
ftDate, ftTime, ftDateTime:
if NativeFormat then
begin
case Field.DataType of
ftDate:
Data := System.DateTime.Create(0).AddDays(Marshal.ReadInt32(Buffer));
ftTime:
Data := System.DateTime.Create(0).AddMilliseconds(
Marshal.ReadInt32(Buffer));
ftDateTime:
Data := System.DateTime.Create(0).AddMilliseconds(
BitConverter.Int64BitsToDouble(Marshal.ReadInt64(Buffer)));
end;
end
else // data is TDateTime
Data := System.DateTime.FromOADate(BitConverter.Int64BitsToDouble(
Marshal.ReadInt64(Buffer)));
ftBytes:
begin
SetLength(B, Field.Size);
Marshal.Copy(Buffer, B, 0, Field.Size);
Data := Variant(B);
end;
ftTimeStamp:
Data := Variant(Marshal.PtrToStructure(Buffer, TypeOf(TSQLTimeStamp)));
ftFMTBCD:
begin
SetLength(B, SizeOfTBCD);
Marshal.Copy(Buffer, B, 0, SizeOfTBCD);
Data := Variant(TBcd.FromBytes(B));
end;
ftVarBytes:
if NativeFormat then
begin
Len := Marshal.ReadInt16(Buffer);
SetLength(B, Len);
Marshal.Copy(IntPtr(Integer(Buffer.ToInt32 + 2)), B, 0, Len);
Data := Variant(B);
end else
begin
{note, we cant support VarBytes if not length prefixed}
DatabaseErrorFmt('SUsupportedFieldType', [FieldTypeNames[ftVarBytes],
Field.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -