#1 2016-05-02 20:46:06

Sabbiolina
Member
Registered: 2014-05-20
Posts: 120

Bson Problem

Hi.

In a MongoDB collection I have this :

{
    "_id" : "FBB5F6O2ZE2EVJ6AG5JHORWBQA",
    "EmptyArray" : []
}


I do this:

var
ADocs: TVariantDynArray

Coll.FindDocs(ADocs, '', 0, 0, []);

And I get:

[
{  "_id" : "FBB5F6O2ZE2EVJ6AG5JHORWBQA",
    "EmptyArray" : null   <------------------------------------------NULL ?
}
]


So I play with debugger and I make this change:

// used by TBSONElement.ToVariant() method and BSONToDoc() procedure
procedure BSONItemsToDocVariant(Kind: TBSONElementType; BSON: PByte;
  var Doc: TDocVariantData; Option: TBSONDocArrayConversion);
const OPTIONS: array[TBSONDocArrayConversion] of TDocVariantOptions =
    ([],[dvoReturnNullForUnknownProperty],
        [dvoValueCopiedByReference,dvoReturnNullForUnknownProperty]);
var k: TDocVariantKind;
    i,n,cap: integer;
    items: array[0..63] of TBSONElement;
begin // very fast optimized code
  if not (Kind in [betDoc,betArray]) then
    VarCastError;
  if (BSON=nil) {or (BSON^=byte(betEOF))} then // I remove this, a empty array is not null (I think)
    TVarData(Doc).VType := varNull else begin
    if Kind=betDoc then
      k := dvObject else
      k := dvArray;
    Doc.Init(OPTIONS[Option],k);
    cap := 0;
    repeat
      n := 0;
      while items[n].FromNext(BSON) do begin
        inc(n);
        if n=length(items) then
          break;
      end;
      if n=0 then
        break;
      inc(cap,n);
      if cap<512 then
        Doc.Capacity := cap else
        if Doc.Capacity<cap then
          Doc.Capacity := cap+cap shr 3; // faster for huge arrays
      for i := 0 to n-1 do begin
        if Kind=betDoc then
          SetString(Doc.Names[i+Doc.Count],PAnsiChar(items[i].Name),items[i].NameLen);
        items[i].ToVariant(Doc.Values[i+Doc.Count],Option);
      end;
      Doc.SetCount(Doc.Count+n);
    until (BSON=nil) or (BSON^=byte(betEOF));
  end;
end;

I do some tests, and all go well.

Offline

#2 2016-05-03 07:41:30

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

Re: Bson Problem

Indeed.
null is a very confusing notion...

I've ensured BSONItemsToDocVariant() would return [] and {} instead of null.
It would made the function consistent with BSONListToJSON().
See http://synopse.info/fossil/info/a04a39d028

Thanks Sabbiolina for the feedback!

Offline

Board footer

Powered by FluxBB