📄 myldblocalengine.pas
字号:
begin
{$IFDEF DEBUG_TRACE_DATASET}
aaWriteToLog('TMYLDBLocalCursor.CloseTable start');
{$ENDIF}
FDatabaseData := TMYLDBLocalSession(Session).DatabaseData;
FDatabaseData.Lock;
try
if (FTableData <> nil) then
begin
FTableData.CloseTable(Self);
if (IsDesignMode) and (FInMemory or FTemporary) then
FTableData.DeleteTable(Self, True)
else
begin
if (FTableData is TMYLDBDiskTableData) then
TMYLDBDiskTableData(FTableData).FreeIfNoCursorsConnected;
end;
FTableData := nil;
end;
if (RecordBitmap <> nil) then
TMYLDBRecordBitmap(RecordBitmap).Free;
RecordBitmap := nil;
if (FilterExpression <> nil) then
TMYLDBExpression(FilterExpression).Free;
FilterExpression := nil;
if (FFieldDefs <> nil) then
FFieldDefs.Free;
FFieldDefs := nil;
if (not FSettingProjection) then
begin
if (FVisibleFieldDefs <> nil) then
FVisibleFieldDefs.Free;
FVisibleFieldDefs := nil;
end;
if (FIndexDefs <> nil) then
FIndexDefs.Free;
FIndexDefs := nil;
ClearBLOBStreams(False);
if (FBLOBStreams <> nil) then
FBLOBStreams.Free;
FBLOBStreams := nil;
// Constraints
if (FConstraintDefs <> nil) then
FConstraintDefs.Free;
FConstraintDefs := nil;
finally
FDatabaseData.Unlock;
end;
{$IFDEF DEBUG_TRACE_DATASET}
aaWriteToLog('TMYLDBLocalCursor.CloseTable finish');
{$ENDIF}
end; // CloseTable
//------------------------------------------------------------------------------
// lock table
//------------------------------------------------------------------------------
procedure TMYLDBLocalCursor.LockTableData;
begin
if (FTableData = nil) then
raise EMYLDBException.Create(10260,ErrorLNilPointer);
FTableData.Lock;
end; // LockTableData
//------------------------------------------------------------------------------
// unlock table
//------------------------------------------------------------------------------
procedure TMYLDBLocalCursor.UnlockTableData;
begin
if (FTableData = nil) then
raise EMYLDBException.Create(10261,ErrorLNilPointer);
FTableData.Unlock;
end; // UnlockTableData
//------------------------------------------------------------------------------
// LockTable
//------------------------------------------------------------------------------
function TMYLDBLocalCursor.LockTable(LockType: TMYLDBLockType;
TryCount, Delay: Integer;
AllowXIRWAfterSIRW: Boolean = True): Boolean;
begin
if (FTableData = nil) then
raise EMYLDBException.Create(20221, ErrorANilPointer);
if (FTableData is TMYLDBDiskTableData) then
Result := TMYLDBDiskTableData(FTableData).LockTable(Session.SessionID, LockType, TryCount, Delay, AllowXIRWAfterSIRW)
else
Result := True;
end;// LockTable
//------------------------------------------------------------------------------
// UnlockTable
//------------------------------------------------------------------------------
function TMYLDBLocalCursor.UnlockTable(LockType: TMYLDBLockType; IgnoreIfNoLock: Boolean=False): Boolean;
begin
if (FTableData = nil) then
raise EMYLDBException.Create(20222, ErrorANilPointer);
if (FTableData is TMYLDBDiskTableData) then
Result := TMYLDBDiskTableData(FTableData).UnlockTable(Session.SessionID, LockType, IgnoreIfNoLock)
else
Result := True;
end;// UnlockTable
//------------------------------------------------------------------------------
// initialize record buffer
//------------------------------------------------------------------------------
procedure TMYLDBLocalCursor.InternalInitRecord(RecordBuffer: TMYLDBRecordBuffer; InsertMode: Boolean);
var x,y: Integer;
begin
// set null flags for all fields
y := FFieldDefs.Count;
x := y div 8;
if (y mod 8 > 0) then
Inc(x);
FillChar(RecordBuffer^,x,$FF);
FillChar((RecordBuffer+x)^,FFieldDefs.GetMemoryRecordBufferSize-x,$00);
// set Default Values...
if ((not FTemporary) and (InsertMode)) then
FTableData.FieldManager.ApplyDefaultValuesToRecordBuffer(Session, RecordBuffer);
end; // InternalInitRecord
//------------------------------------------------------------------------------
// Rename Field by Field Index in FieldDefs
//------------------------------------------------------------------------------
procedure TMYLDBLocalCursor.RenameField(FieldName, NewFieldName: String);
begin
FTableData.RenameField(FieldName, NewFieldName);
end;//RenameField
//------------------------------------------------------------------------------
// CopyFieldValue
//------------------------------------------------------------------------------
procedure TMYLDBLocalCursor.CopyFieldValue(SrcFieldNo: Integer;
DirectAccess: Boolean;
DestFieldNo: Integer;
DestCursor: TMYLDBCursor);
var
SrcBuffer, DestBuffer: PChar;
SrcOffset, DestOffset: Integer;
SrcDataSize, DestDataSize: Integer;
SrcFieldType, DestFieldType: TMYLDBBaseFieldType;
IsNull: Boolean;
ActualFieldDefs: TMYLDBFieldDefs;
Value: TMYLDBVariant;
BlobDescriptor: TMYLDBPartialTemporaryBLOBDescriptor;
pBlobData: PChar;
begin
if (DirectAccess) then
ActualFieldDefs := FieldDefs
else
ActualFieldDefs := VisibleFieldDefs;
if (SrcFieldNo >= ActualFieldDefs.Count) then
raise EMYLDBException.Create(10501, ErrorLInvalidFieldNumber,
[SrcFieldNo,ActualFieldDefs.Count]);
if (DestFieldNo >= DestCursor.VisibleFieldDefs.Count) then
raise EMYLDBException.Create(10502, ErrorLInvalidFieldNumber,
[DestFieldNo,DestCursor.VisibleFieldDefs.Count]);
// 5.01 bug-fix
if (ActualFieldDefs = VisibleFieldDefs) then
IsNull := CheckNullFlag(ActualFieldDefs[SrcFieldNo].FieldNoReference, CurrentRecordBuffer)
else
IsNull := CheckNullFlag(SrcFieldNo, CurrentRecordBuffer);
if (not IsNull) then
begin
SrcOffset := ActualFieldDefs[SrcFieldNo].MemoryOffset;
SrcBuffer := PChar(CurrentRecordBuffer + SrcOffset);
SrcDataSize := ActualFieldDefs[SrcFieldNo].MemoryDataSize;
SrcFieldType := ActualFieldDefs[SrcFieldNo].BaseFieldType;
DestOffset := DestCursor.VisibleFieldDefs[DestFieldNo].MemoryOffset;
DestBuffer := PChar(DestCursor.CurrentRecordBuffer + DestOffset);
DestDataSize := DestCursor.VisibleFieldDefs[DestFieldNo].MemoryDataSize;
DestFieldType := DestCursor.VisibleFieldDefs[DestFieldNo].BaseFieldType;
if (SrcFieldType = DestFieldType) and (not IsBLOBFieldType(SrcFieldType)) and
(SrcDataSize = DestDataSize) then
begin
SetNullFlag(False,DestCursor.VisibleFieldDefs[DestFieldNo].FieldNoReference,DestCursor.CurrentRecordBuffer);
Move(SrcBuffer^, DestBuffer^, SrcDataSize);
end
else
if (not IsBLOBFieldType(SrcFieldType)) then
begin
Value := TMYLDBVariant.Create;
try
GetFieldValue(Value, SrcFieldNo, DirectAccess);
DestCursor.SetFieldValue(Value, DestFieldNo, False);
finally
Value.Free;
end;
end
else
begin
// 5.12 fix blobs union bug
if not DirectAccess then
SrcFieldNo := ActualFieldDefs[SrcFieldNo].FieldNoReference;
TableData.GetDirectBlobData(Self,SrcFieldNo,CurrentRecordBuffer,
BlobDescriptor, pBlobData);
TMYLDBLocalCursor(DestCursor).TableData.SetDirectBlobData(DestCursor,DestFieldNo,DestCursor.CurrentRecordBuffer,
BlobDescriptor, pBlobData);
TableData.FreeDirectBlobData(Self,SrcFieldNo,CurrentRecordBuffer,
BlobDescriptor, pBlobData);
end;
end
else
SetNullFlag(True,DestCursor.VisibleFieldDefs[DestFieldNo].FieldNoReference,DestCursor.CurrentRecordBuffer);
end;// CopyFieldValue
//------------------------------------------------------------------------------
// GetIndexDefs
//------------------------------------------------------------------------------
function TMYLDBLocalCursor.GetIndexDefs: TMYLDBIndexDefs;
begin
if (FIndexDefs <> nil) then
FIndexDefs.Assign(FTableData.IndexManager.IndexDefs);
Result := inherited GetIndexDefs;
end;// GetIndexDefs
//------------------------------------------------------------------------------
// add index
//------------------------------------------------------------------------------
procedure TMYLDBLocalCursor.AddIndex(IndexDef: TMYLDBIndexDef);
begin
if (FIndexDefs.GetIndexDefByName(IndexDef.Name) <> nil) then
raise EMYLDBException.Create(20022, ErrorAIndexAlreadyExists, [IndexDef.Name]);
FTableData.AddIndex(IndexDef, Self);
FIndexDefs.Assign(FTableData.IndexManager.IndexDefs);
//if (not FTemporary) then
FConstraintDefs.Assign(FTableData.ConstraintManager.ConstraintDefs);
end;// AddIndex
//------------------------------------------------------------------------------
// DeleteIndex
//------------------------------------------------------------------------------
procedure TMYLDBLocalCursor.DeleteIndex(Name: String);
begin
if (FIndexDefs.GetIndexDefByName(Name) = nil) then
raise EMYLDBException.Create(20021, ErrorACannotDeleteIndex, [Name]);
// Delete Index
FTableData.DeleteIndex(FIndexDefs.GetIndexDefByName(Name).ObjectID, Self);
FIndexDefs.Assign(FTableData.IndexManager.IndexDefs);
//if (not FTemporary) then
FConstraintDefs.Assign(FTableData.ConstraintManager.ConstraintDefs);
end;// DeleteIndex
//------------------------------------------------------------------------------
// DeleteAllIndexes
//------------------------------------------------------------------------------
procedure TMYLDBLocalCursor.DeleteAllIndexes;
begin
FTableData.DeleteAllIndexes(Self);
FIndexDefs.Assign(FTableData.IndexManager.IndexDefs);
//if (not FTemporary) then
FConstraintDefs.Assign(FTableData.ConstraintManager.ConstraintDefs);
end;// DeleteAllIndexes
//------------------------------------------------------------------------------
// return index name
//------------------------------------------------------------------------------
function TMYLDBLocalCursor.FindOrCreateIndex(FieldNamesList, AscDescList, CaseSensitivityList: TStringList; var IsCreated: Boolean): String;
var
i: Integer;
begin
// replace pseudonames
for i:=0 to FieldNamesList.Count-1 do
if (FFieldDefs.GetFieldDefByName(FieldNamesList[i]) = nil) and
(FVisibleFieldDefs.GetFieldDefByName(FieldNamesList[i]) <> nil) then
FieldNamesList[i] := FFieldDefs.Items[FVisibleFieldDefs.GetFieldDefByName(FieldNamesList[i]).FieldNoReference].Name;
Result := FTableData.FindOrCreateIndex(Self, FieldNamesList, AscDescList, CaseSensitivityList, IsCreated);
FIndexDefs.Assign(FTableData.IndexManager.IndexDefs);
end; // FindOrCreateIndex
//------------------------------------------------------------------------------
// IndexExists
//------------------------------------------------------------------------------
function TMYLDBLocalCursor.IndexExists(FieldNamesList, AscDescList, CaseSensitivityList: TStringList): Boolean;
var
i: Integer;
begin
// replace pseudonames
for i:=0 to FieldNamesList.Count-1 do
if (FFieldDefs.GetFieldDefByName(FieldNamesList[i]) = nil) and
(FVisibleFieldDefs.GetFieldDefByName(FieldNamesList[i]) <> nil) then
FieldNamesList[i] := FFieldDefs.Items[FVisibleFieldDefs.GetFieldDefByName(FieldNamesList[i]).FieldNoReference].Name;
Result := FTableData.IndexExists(Self, FieldNamesList, AscDescList, CaseSensitivityList);
end;// IndexExists
//------------------------------------------------------------------------------
// FreeRecordBuffer
//------------------------------------------------------------------------------
procedure TMYLDBLocalCursor.FreeRecordBuffer(var Buffer: TMYLDBRecordBuffer);
begin
if (FTableData <> nil) then
FTableData.ClearBlobsCacheInRecordBuffer(Buffer);
MemoryManager.FreeAndNillMem(Buffer);
end;// FreeRecordBuffer
//------------------------------------------------------------------------------
// get record
//------------------------------------------------------------------------------
function TMYLDBLocalCursor.GetRecordBuffer(
GetRecordMode: TMYLDBGetRecordMode
): TMYLDBGetRecordResult;
begin
FTableData.Lock;
try
Result := FTableData.GetRecordBuffer(Self,GetRecordMode);
finally
FTableData.Unlock;
end;
end; // GetRecordBuffer
//------------------------------------------------------------------------------
// returns record count
//------------------------------------------------------------------------------
function TMYLDBLocalCursor.GetRecordCount: TMYLDBRecordNo;
begin
Result := FTableData.GetRecordCount(Self);
end; // GetRecordCount
//------------------------------------------------------------------------------
// go to record
//------------------------------------------------------------------------------
procedure TMYLDBLocalCursor.SetRecNo(Value: Int64);
begin
FTableData.SetRecNo(Self,Value);
end; // SetRecNo
//------------------------------------------------------------------------------
// return current record number
//------------------------------------------------------------------------------
function TMYLDBLocalCursor.GetRecNo: Int64;
begin
Result := FTableData.GetRecNo(Self);
end; // GetRecNo
//------------------------------------------------------------------------------
// go to first record (before first record to BOF)
//------------------------------------------------------------------------------
procedure TMYLDBLocalCursor.InternalFirst;
begin
FirstPosition := True;
LastPosition := False;
end; // InternalFirst
//------------------------------------------------------------------------------
// go to last record (after last record to EOF)
//------------------------------------------------------------------------------
procedure TMYLDBLocalCursor.InternalLast;
begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -