Избавляемся от костылей!
У меня есть две новости: одна - плохая, другая - хорошая.
1. Метод TIniFile.ReadSectionValues не работает
2. В MVDB есть класс TMemIniFile, который работает с ini-фалом в кодировке UTF-8.
Продолжая идею sparrow о необходимости разовой загрузки формул вычисляемых полей, доделал InlineCalcFields(), костыли отнес в больничку )))
var
DB_CalcFields: TStringList; // список хранимых полей из файла tables.ini
procedure Form1_Button1_OnClick (Sender: TObject; var Cancel: boolean);
var
tmpSQL: string;
begin
tmpSQL :=
'Select '+
' "$checkbox",'+
' "$autoinc",'+
' data, '+
' {test.data_calc} '+ // надо указывать таблицу и вычисляемоте поле
'from '+
' test ';
tmpSQL := InlineCalcFields(tmpSQL);
TdbButton(Sender).dbSQL := tmpSQL;
end;
function InlineCalcFields( ASQL:string ):string;
var
tmpStartPos: integer;
tmpEndPos: integer;
tmpCalcField: string;
tmpFieldSQL: string;
tmpPlaceHolder: string;
begin
try
repeat
tmpStartPos := Pos( '{',ASQL);
if tmpStartPos = 0 then
exit;
tmpEndPos := Pos('}',ASQL);
if tmpEndPos = 0 then
exit;
//
tmpCalcField := copy(ASQL,tmpStartPos+1,tmpEndPos-tmpStartPos-1);
if DB_CalcFields.IndexOfName(tmpCalcField) < 0 then
begin
ShowMessage('Вычисляемое поле '+tmpCalcField+' не найдено!');
exit;
end;
tmpFieldSQL := DB_CalcFields.Values(tmpCalcField);
tmpFieldSQL := ReplaceStr( tmpFieldSQL, '\r' ,'');
tmpFieldSQL := ReplaceStr( tmpFieldSQL, '\n' ,'');
tmpFieldSQL := ReplaceStr( tmpFieldSQL, '^equally^' ,'=');
tmpPlaceHolder := '{'+tmpCalcField+'}';
ASQL := ReplaceStr( ASQL, tmpPlaceHolder ,tmpFieldSQL );
until 1=0;
finally
Result := ASQL;
end;
end;
procedure ReadCalcFields;
// заполняем список вычисляемых полей DB_CalcFields
var
tmpIniFile: TMemIniFile;
tmpList:TStringList;
tmpList2:TStringList;
s: string;
i: integer;
j: integer;
tmpTableName: string;
tmpFieldName: string;
begin
DB_CalcFields := TStringList.Create;
tmpList := TStringList.Create;
tmpList2 := TStringList.Create;
tmpIniFile := TMemIniFile.Create(ExtractFilePath(Application.ExeName)+'tables.ini');
try
tmpIniFile.ReadSections(tmpList);
for i:=0 to tmpList.Count - 1 do
begin
tmpTableName := tmpList.Strings[i];
tmpIniFile.ReadSectionValues( tmpTableName, tmpList2 );
for j := 0 to tmpList2.Count - 1 do
begin
tmpFieldName := tmpList2.Names[j];
if copy(tmpFieldName,1,1) = '%' then
begin
DB_CalcFields.Add( tmpTableName+'.'+copy( tmpList2.Strings[j],2,Length(tmpList2.Strings[j])-1 ) );
end
end;
end;
finally
tmpIniFile.Free;
tmpList.Free;
tmpList2.Free;
end;
end;
begin
ReadCalcFields;
end.