Tecsitel_FactuGES2/Source/Servidor/Utiles/uSchemaUtilsServer.pas

166 lines
4.5 KiB
ObjectPascal
Raw Normal View History

unit uSchemaUtilsServer;
interface
uses
Classes, SysUtils,
uROClientIntf, uROTypes, uROServer, uROServerIntf, uROSessions,
DataAbstract4_Intf, DataAbstractService_Impl,
uDAClasses, uDAInterfaces, uDADataTable;
type
TReplicarDataSet = class
protected
function GenerateNewSQL : String;
public
Service : TDataAbstractService;
Columnas : String;
ColumnasQueSuman : String;
ColumnasQueAVG : String;
SourceDataSetName : String;
function GetNewDataSet : IDADataset;
end;
implementation
{ TReplicaDataSet }
uses
RegExpr,
Dialogs, JclStrings;
function TReplicarDataSet.GenerateNewSQL: String;
var
AColumnList : TStringList;
ASQL: TStringList;
ds : IDADataset;
i : integer;
Separador : String;
bHayAgrupacion : Boolean;
function GetTrueFieldName(AField : string; ConAlias : Boolean = True) : String;
var
ARegExpr : TRegExpr;
begin
Result := AField; // Por si el campo no tuviera alias
ARegExpr := TRegExpr.Create;
try
ARegExpr.ModifierI := True; // case insensitive
ARegExpr.InputString := ds.SQL;
ARegExpr.Expression := '[^ ,]+[ ]+AS[ ]+' + AField; // buscar (xxxx.xxxx AS AField) o (xxxx AS AField)
ARegExpr.Expression := ARegExpr.Expression + '|'; // o
ARegExpr.Expression := ARegExpr.Expression + '[^ ,]+\.' + AField; // buscar xxxx.AField
if ARegExpr.Exec then
Result := ARegExpr.Match[0];
if not ConAlias then
begin
ARegExpr.InputString := Result;
ARegExpr.Expression := '^[^ ,]+'; // Para quedarme con el campo sin alias
if ARegExpr.Exec then
Result := ARegExpr.Match[0]
end;
finally
FreeAndNil(ARegExpr);
end;
end;
begin
AColumnList := TStringList.Create;
ASQL := TStringList.Create;
ds := Service.ServiceSchema.NewDataset(Service.Connection, SourceDataSetName);
bHayAgrupacion := False;
try
AColumnList.CommaText := Columnas;
with ASQL do
begin
Insert(0, 'SELECT DISTINCT');
Insert(1, ''); // Lista de campos
Insert(2, Copy(ds.SQL, Pos('FROM', ds.SQL), Length(ds.SQL)));
Insert(3, ''); // Group by
Separador := '';
for i := 0 to AColumnList.Count - 1 do
begin
if Assigned(ds.FindField(AColumnList[i])) then
begin
if i > 0 then
Separador := ',';
if Pos('#'+AColumnList[i]+'#', ColumnasQueSuman) > 0 then
begin
Strings[1] := Strings[1] + Separador + 'SUM(' + GetTrueFieldName(AColumnList[i], False) + ') AS ' + AColumnList[i];
bHayAgrupacion := True;
end
else if Pos('#'+AColumnList[i]+'#', ColumnasQueAVG) > 0 then
begin
Strings[1] := Strings[1] + Separador + 'AVG(' + GetTrueFieldName(AColumnList[i], False) + ') AS ' + AColumnList[i];
bHayAgrupacion := True;
end
else begin
Strings[1] := Strings[1] + Separador + GetTrueFieldName(AColumnList[i]);
if Length(Strings[3]) = 0 then
Strings[3] := 'GROUP BY '
else begin
if (Strings[3] <> 'GROUP BY ') then
Strings[3] := Strings[3] + Separador;
end;
Strings[3] := Strings[3] + GetTrueFieldName(AColumnList[i], False);
end;
end;
end; // for
if not bHayAgrupacion then
Delete(3);
end;
Result := ASQL.Text;
finally
AColumnList.Free;
ASQL.Free;
end;
end;
function TReplicarDataSet.GetNewDataSet: IDADataset;
var
SQL: String;
ASchemaDataSet: TDADataSet;
AColumnList : TStringList;
i, j : Integer;
begin
SQL := GenerateNewSQL;
Result := Service.Connection.NewDataset(SQL, SourceDataSetName);
ASchemaDataSet := Service.ServiceSchema.Datasets.DatasetByName(SourceDataSetName);
if Assigned(ASchemaDataSet) then
begin
Result.Params.AssignParamCollection(ASchemaDataSet.Params);
Result.Fields.AssignFieldCollection(ASchemaDataSet.Fields);
AColumnList := TStringList.Create;
try
AColumnList.CommaText := Columnas;
j := 0;
i := Result.Fields.Count;
while i > 0 do
begin
if AColumnList.IndexOf(Result.Fields[j].Name) = -1 then
Result.Fields.Delete(j)
else
j := j + 1; // Un campo que dejo
i := i - 1; // Un campo menos por revisar
end;
finally
AColumnList.Free;
end;
end;
Result.Close;
Result.Where.Clear;
end;
end.