anymore1113 / superobject

Automatically exported from code.google.com/p/superobject
0 stars 0 forks source link

better interaction with variants #62

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
Hi, I'd like to be able to write sentences like:

  Js.V['element'] := Table1['value']

or 

  Table1['something'] := Js.V['element']

where Null (Variant) gets mapped to null (json), and in general the value type 
is inferred from the TVarType for variants and DataType for SOs. This eases a 
lot interaction with databases because code like this:

if not VarIsNull(Table1['something']) then
  Js.I['element'] := Table1['something']
else
  Js.O['element'] := nil;

becomes a single liner as shown above.

I have a prototype working implementation of this feature for an older SO 
version. I can try to forward port it and post it here if you're interested. 

The implementation is simple: wherever there's an I/S/D/C/A... property a new V 
property (for variant!) is added. The accessors look like these:

function TSuperObject.GetV(const path: SOString): Variant;
var
  obj: ISuperObject;
begin
  obj := GetO(path);
  if obj <> nil then
  begin
    case obj.DataType of
      stNull:     Result := Null;
      stBoolean:  Result := obj.AsBoolean;
      stDouble:   Result := obj.AsDouble;
      stCurrency: Result := obj.AsCurrency;
      stInt:      Result := obj.AsInteger;
      stObject:   Result := obj;
      stArray:    Result := obj;
      stString:   Result := obj.AsString;
{$IFDEF SUPER_METHOD}
      stMethod:   Result := obj;
{$ENDIF}
    end;
  end
  else
    Result := Null;
end;

procedure TSuperObject.PutV(const path: SOString; Value: Variant);
begin
  with TVarData(Value) do
  case VType of
    varNull:     PutO(path, nil);
    varEmpty:    PutO(path, nil);
    varSmallInt: PutI(path, VSmallInt);
    varInteger:  PutI(path, VInteger);
    varSingle:   PutD(path, VSingle);
    varDouble:   PutD(path, VDouble);
    varCurrency: PutC(path, VCurrency);
    varDate:     PutI(path, DelphiToJavaDateTime(vDate));
    varOleStr:   PutS(path, SOString(VOleStr));
    varBoolean:  PutB(path, VBoolean);
    varShortInt: PutI(path, VShortInt);
    varByte:     PutI(path, VByte);
    varWord:     PutI(path, VWord);
    varLongWord: PutI(path, VLongWord);
    varInt64:    PutI(path, VInt64);
    varString:   PutS(path, SOString(AnsiString(VString)));
{$if declared(varUString)}
  {$IFDEF FPC}
    varUString:  PutS(path, SOString(UnicodeString(VString)));
  {$ELSE}
    varUString:  PutS(path, SOString(string(VUString)));
  {$ENDIF}
{$ifend}
  else
    raise Exception.CreateFmt('Unsuported variant data type: %d', [VType]);
  end;
end;

Original issue reported on code.google.com by mca...@notnull.com.ar on 9 Jan 2015 at 12:56