📄 absrelationalalgebra.pas
字号:
property FieldCount;
property RecordCount;
property ResultDataset;
property Eof;
end;
// table expression
TABSAOSQLTopRowCount = class (TABSAO)
protected
procedure InternalFirst; override;
procedure InternalNext; override;
function InternalGetEof: Boolean; override;
function InternalGetRecordCount: Integer; override;
public
constructor Create(
Child: TABSAO
);
// sets Top row count
procedure SetTopRowCount(FirstRowNo, TopRowCount: Integer); override;
public
property IsMaterialized;
property FieldCount;
property RecordCount;
property ResultDataset;
property Eof;
end;
procedure ConvertIndexFieldNamesToLists(
FieldNames, DescFields, CaseInsFields: String;
FieldList, AscDescList, CaseInsList: TStringList
);
procedure ConvertListsToIndexFieldNames(
var FieldNames: String;
var DescNames: String;
var CaseInsNames: String;
FieldList, AscDescList, CaseInsList: TStringList
);
implementation
uses ABSMain,ABSExpressions;
////////////////////////////////////////////////////////////////////////////////
//
// TABSFields
//
////////////////////////////////////////////////////////////////////////////////
//------------------------------------------------------------------------------
// creates
//------------------------------------------------------------------------------
constructor TABSFields.Create;
begin
ItemCount := 0;
end;// Create
//------------------------------------------------------------------------------
// add item to the end
//------------------------------------------------------------------------------
procedure TABSFields.Append(var Item: TABSSelectListItem);
begin
Inc(ItemCount);
SetLength(Items, ItemCount);
Items[ItemCount-1] := Item;
end;// Append
////////////////////////////////////////////////////////////////////////////////
//
// TABSAO
//
////////////////////////////////////////////////////////////////////////////////
//------------------------------------------------------------------------------
// create
//------------------------------------------------------------------------------
procedure TABSAO.InternalCreate(
LeftAO: TABSAO = nil;
RightAO: TABSAO = nil;
TableName: String = '';
TableAlias: String = ''
);
begin
FResultDataset := TABSTable.Create(nil);
if (LeftAO <> nil) then
if (LeftAO.ResultDataset <> nil) then
if (TABSTable(LeftAO.ResultDataset).SessionName <> '') then
TABSTable(FResultDataset).SessionName := TABSTable(LeftAO.ResultDataset).SessionName;
if (RightAO <> nil) then
if (RightAO.ResultDataset <> nil) then
if (TABSTable(RightAO.ResultDataset).SessionName <> '') then
TABSTable(FResultDataset).SessionName := TABSTable(RightAO.ResultDataset).SessionName;
FIsRootAO := False;
FIsAOTable := False;
FIsAOGroupBy := False;
FHasSetResultFields := False;
FTableName := TableName;
FTableAlias := TableAlias;
FLeftAO := LeftAO;
FRightAO := RightAO;
FResultFieldsOrder := TABSIntegerArray.Create(0,1,100);
FIsMaterialized := True;
FFieldCount := 0;
FLeftAONull := False;
FRightAONull := False;
FDistinctApplied := False;
FDistinctFields := '';
FFilterExpr := nil;
FTopRowCount := -1;
FFirstRowNo := -1;
FExpressionsExists := False;
FResultIndexFieldsList := nil;
FResultIndexAscDescFieldsList := nil;
FResultIndexCaseInsFieldsList := nil;
FResultTableName := '';
FResultDatabaseName := '';
FResultInMemory := False;
FResultImmediate := False;
FIsLocked := False;
if (FLeftAO <> nil) then
FDisableTempFiles := FLeftAO.FDisableTempFiles
else
FDisableTempFiles := False;
if (FRightAO <> nil) then
FDisableTempFiles := FDisableTempFiles or FRightAO.FDisableTempFiles;
FValue := TABSVariant.Create;
end; // InternalCreate
//------------------------------------------------------------------------------
// go to first record
//------------------------------------------------------------------------------
procedure TABSAO.InternalFirst;
begin
;
end; // First
//------------------------------------------------------------------------------
// go to next record
//------------------------------------------------------------------------------
procedure TABSAO.InternalNext;
begin
;
end; // Next
//------------------------------------------------------------------------------
// return true if cursor points to the last record
//------------------------------------------------------------------------------
function TABSAO.InternalGetEof: Boolean;
begin
Result := False;
end; // InternalGetEof
//------------------------------------------------------------------------------
// return number of records
//------------------------------------------------------------------------------
function TABSAO.InternalGetRecordCount: Integer;
begin
Result := 0;
if (FIsMaterialized) then
Result := FResultDataset.RecordCount;
end; // InternalGetRecordCount
//------------------------------------------------------------------------------
// go to first record
//------------------------------------------------------------------------------
procedure TABSAO.First;
begin
if (FIsMaterialized) then
FResultDataset.First
else
InternalFirst;
end; // First
//------------------------------------------------------------------------------
// go to next record
//------------------------------------------------------------------------------
procedure TABSAO.Next;
begin
if (FIsMaterialized) then
FResultDataset.Next
else
InternalNext;
end; // Next
//------------------------------------------------------------------------------
// return true if cursor points to the last record
//------------------------------------------------------------------------------
function TABSAO.GetEof: Boolean;
begin
if (FIsMaterialized) then
Result := FResultDataset.Eof
else
Result := InternalGetEof;
end; // GetEof
//------------------------------------------------------------------------------
// return number of records
//------------------------------------------------------------------------------
function TABSAO.GetRecordCount: Integer;
begin
if (FIsMaterialized) then
Result := FResultDataset.RecordCount
else
Result := InternalGetRecordCount;
end; // GetRecordCount
//------------------------------------------------------------------------------
// sets names to FieldLinks list and renames duplicate names
//------------------------------------------------------------------------------
procedure TABSAO.SetFieldNames;
var i,j,k: Integer;
name,s: String;
bOk: Boolean;
begin
for i := 0 to FFieldCount-1 do
begin
FFieldLinks[i].FieldName := GetFieldName(i);
// renaming fields without name (calculated, expressions...)
if (FFieldLinks[i].FieldName = '') then
FFieldLinks[i].FieldName := GetTemporaryName(ABSExpressionFieldName);
end;
// try to remove duplicates by renaming hidden fields only
for i := 0 to FFieldCount-1 do
begin
k := 1;
if not (FFieldLinks[i].IsHidden) then Continue;
name := FFieldLinks[i].FieldName;
repeat
s := AnsiUpperCase(name);
bOk := true;
for j := 0 to i-1 do
if (s = AnsiUpperCase(FFieldLinks[j].FieldName)) then
begin
bOk := false;
break;
end;
if (bOk) then
Break;
if (k = 1) then
name := name +'_' + IntToStr(k)
else
name := name + IntToStr(k);
inc(k);
until bOk;
FFieldLinks[i].FieldName := name;
end;
// remove all duplicates
for i := 1 to FFieldCount-1 do
begin
k := 1;
name := FFieldLinks[i].FieldName;
repeat
s := AnsiUpperCase(name);
bOk := true;
for j := 0 to i-1 do
if (s = AnsiUpperCase(FFieldLinks[j].FieldName)) then
begin
bOk := false;
break;
end;
if (bOk) then
Break;
if (k = 1) then
name := name +'_' + IntToStr(k)
else
name := name + IntToStr(k);
inc(k);
until bOk;
FFieldLinks[i].FieldName := name;
end;
end;
//------------------------------------------------------------------------------
// create table
//------------------------------------------------------------------------------
function TABSAO.CreateIndexForMaterialize(BeforeCreateTable: Boolean): String;
var IndexDef: TIndexDef;
FieldNames, DescNames, CaseInsNames: String;
begin
ConvertListsToIndexFieldNames(FieldNames,DescNames,CaseInsNames,
FResultIndexFieldsList,FResultIndexAscDescFieldsList,
FResultIndexCaseInsFieldsList);
Result := GetTemporaryName(ABSTemporaryIndexName);
if (BeforeCreateTable) then
begin
IndexDef := TABSTable(FResultDataset).IndexDefs.AddIndexDef;
IndexDef.Name := Result;
IndexDef.Fields := FieldNames;
IndexDef.DescFields := DescNames;
IndexDef.CaseInsFields := CaseInsNames;
end
else
begin
TABSTable(FResultDataset).AddIndex(Result,FieldNames,[],DescNames,CaseInsNames);
end;
end; // CreateIndexForMaterialize
//------------------------------------------------------------------------------
// create table
//------------------------------------------------------------------------------
procedure TABSAO.CreateTableForMaterialize(
FieldList: TStringList;
AliasList: TStringList
);
var i,j: Integer;
FieldDef: TABSAdvFieldDef;
(*DuplicateCount: Integer;*)
Name: string;
procedure CreateIndexForDistinct;
var
IndexDef: TIndexDef;
begin
IndexDef := TABSTable(FResultDataset).IndexDefs.AddIndexDef;
IndexDef.Name := GetTemporaryName(ABSTemporaryIndexName);
IndexDef.Fields := FDistinctFields;
IndexDef.DescFields := '';
IndexDef.CaseInsFields := '';
IndexDef.Options := [ixUnique];
end;
begin
// prepare field defs
TABSTable(FResultDataset).FieldDefs.Clear;
TABSTable(FResultDataset).IndexDefs.Clear;
TABSTable(FResultDataset).AdvFieldDefs.Clear;
TABSTable(FResultDataset).AdvIndexDefs.Clear;
// result table is a table with applied projection (output fields list)
if (FResultFieldsOrder.ItemCount <= 0) then
begin
// no projection
// not result table
for i := 0 to FFieldCount-1 do
begin
// field names will be 'Field'+n
if (FFieldLinks[i].IsHidden) then continue;
(*DuplicateCount := 0;*)
Name := FFieldLinks[i].FieldName;
(*// 5.05 rename duplicate fields
if TABSTFFieldLinks[i].FieldNameable(FResultDataset).AdvFieldDefs.Find(FFieldLinks[i].FieldName) <> nil then
repeat
Name := FFieldLinks[i].FieldName + '_' + IntToStr(DuplicateCount + 1);
Inc(DuplicateCount);
until TABSTable(FResultDataset).AdvFieldDefs.Find(Name) = nil;*)
FieldDef := TABSTable(FResultDataset).AdvFieldDefs.AddFieldDef;
FieldDef.Name := Name;
FieldList.Add(Name);
AliasList.Add('');
if (IsAutoincFieldType(FFieldLinks[i].FieldType)) then
FieldDef.DataType := BaseFieldTypeToAdvancedFieldType(AdvancedFieldTypeToBaseFieldType(FFieldLinks[i].FieldType))
else
FieldDef.DataType := FFieldLinks[i].FieldType;
FieldDef.Size := FFieldLinks[i].FieldSize;
FieldDef.BLOBCompressionAlgorithm :=
TCompressionAlgorithm(FFieldLinks[i].BLOBCompressionAlgorithm);
FieldDef.BLOBCompressionMode := FFieldLinks[i].BLOBCompressionMode;
FieldDef.BLOBBlockSize := FFieldLinks[i].BLOBBlockSize;
end; // not result table
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -