#1 2015-02-24 19:32:23

EMartin
Member
From: Buenos Aires - Argentina
Registered: 2013-01-09
Posts: 337

Cannot create ToDataset with one record

If I want create a dataset with one record, TDocVariantArrayDataSet.Create raise an exception.

Example:

var
  lRespVar: TDocVariantData;
  lRespDS: TSynVirtualDataset;
begin
  lRespVar.InitJSON('{"RESULT":1,"_TVRESULTEXECUTE_":1}',JSON_OPTIONS[true]);
  lRespDS := ToDataset(Nil, lRespVar.Values, [], []); // --> exception here
end

I have detected the problem in TDocVariantArrayDataSet.Create, my workaround is marked with // -->

constructor TDocVariantArrayDataSet.Create(Owner: TComponent;
  const Data: TVariantDynArray; const ColumnNames: array of RawUTF8;
  const ColumnTypes: array of TSQLDBFieldType);
var n,i,j: integer;
    first: PDocVariantData;
begin
  fValues := Data;
  n := Length(ColumnNames);
  if n>0 then begin
    if n<>length(ColumnTypes) then
      raise ESynException.CreateUTF8('%.Create(ColumnNames<>ColumnTypes)',[self]);
    SetLength(fColumns,n);
    for i := 0 to n-1 do begin
      fColumns[i].Name := ColumnNames[i];
      fColumns[i].FieldType := ColumnTypes[i];
    end;
  end else
  if fValues<>nil then begin
    first := DocVariantDataSafe(fValues[0],dvObject);
    SetLength(fColumns,first^.Count);
    for i := 0 to first^.Count-1 do begin
      fColumns[i].Name := first^.Names[i];
      fColumns[i].FieldType := VariantTypeToSQLDBFieldType(first^.Values[i]);
      case fColumns[i].FieldType of
      SynCommons.ftNull:
        fColumns[i].FieldType := SynCommons.ftBlob;
      SynCommons.ftCurrency:
        fColumns[i].FieldType := SynCommons.ftDouble;
      SynCommons.ftInt64:
        for j := 1 to first^.Count-1 do // ensure type coherency of whole column
        begin
          if (j = Length(fValues)) then break; // --> without this workaround raise the exception
          with DocVariantDataSafe(fValues[j],dvObject)^ do
          if (i<Length(Names)) and IdemPropNameU(Names[i],fColumns[i].Name) then
          if VariantTypeToSQLDBFieldType(Values[i]) in [SynCommons.ftDouble,SynCommons.ftCurrency] then begin
            fColumns[i].FieldType := SynCommons.ftDouble;
            break;
          end;
        end;
      end;
    end;
  end;
  inherited Create(Owner);
end;

Maybe there is a better solution.

Thanks in advance.


Esteban

Offline

#2 2015-02-24 22:50:31

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,662
Website

Re: Cannot create ToDataset with one record

This sounds just fine.
See http://synopse.info/fossil/info/ae6c4dd57c

Thanks for the patch!

Offline

Board footer

Powered by FluxBB