Jump to content
ron

Savetostring issue in TW3Dataset

Recommended Posts

As i mention in this topic (couldn't delete it)
http://forums.smartmobilestudio.com/index.php?/topic/4259-dataset-savetostring/
 

unit Form1;

interface

uses 
  SmartCL.System, SmartCL.Graphics, SmartCL.Components, SmartCL.Forms, 
  SmartCL.Fonts, SmartCL.Borders, SmartCL.Application, System.Dataset;

type
  TForm1 = class(TW3Form)
  mDataset :TW3Dataset;
  Procedure TestDataset;
  private
    {$I 'Form1:intf'}
  protected
    procedure InitializeForm; override;
    procedure InitializeObject; override;
    procedure Resize; override;
  end;

implementation

{ TForm1 }

Procedure TForm1.TestDataset;
var
  mDataset: TW3Dataset;
  x:Integer;
  mId: Integer;
begin
  mDataset:=TW3Dataset.Create;
  try
    mDataset.FieldDefs.add('id',ftAutoInc);
    mDataset.FieldDefs.add('key',ftGUID);
    mDataset.FieldDefs.add('name',ftString);
    mDataset.createDataset;

    for x:=1 to 50 do
    Begin
      mDataset.Append;
      mId:=mDataset.Fields.FieldByName('id').asInteger;
      mDataset.Fields.FieldByName('name').asString:='Data field #' + IntToStr(mId);
      mDataset.post;
    end;

    showmessage(mDataset.saveToString);

  finally
    mDataset.free;
  end;
end;


procedure TForm1.InitializeForm;
begin
  inherited;
  // this is a good place to initialize components
end;

procedure TForm1.InitializeObject;
begin
  inherited;
  {$I 'Form1:impl'}
  TestDataset;
end;
 
procedure TForm1.Resize;
begin
  inherited;
end;
 
initialization
  Forms.RegisterForm({$I %FILE%}, TForm1);
end.

the alertbox displayed;
{"dhCount":50,"dhFieldDefs":"%7B%22ddMagic%22:3401235116,%22ddDefs%22:%5B%7B%22fdName%22:%22id%22,%22fdDatatype%22:6%7D,%7B%22fdName%22:%22key%22,%22fdDatatype%22:7%7D,%7B%22fdName%22:%22name%22,%22fdDatatype%22:4%7D%5D%7D","dhMagic":51966}
 
 
 
The recordfields doesn't get saved in Savetostring..
 
 
Ron

Share this post


Link to post
Share on other sites

The issue is in the following code in the unit: System.DataSet

Function TW3Dataset.SaveToString:String;
var
  mHead:  TW3DatasetHeader;
Begin
  if FActive then
  Begin
    try
      (* Setup the header *)
      mHead.dhMagic:=$CAFE;
      mHead.dhCount:=getRecCount;

      (* Serialize and store field-defs *)
      mHead.dhFieldDefs:=EncodeURI(FDefs.SaveToString);

      (* Serialize and store dataset records *)
      asm
        (@mHead).dhData = JSON.stringify((@self).FCache);
      end;

      (* Now serialize and return text representation of data structure *)
      asm
        @result = JSON.stringify(@mHead);
      end;

    except
      on e: exception do
      raise EW3Dataset.CreateFmt(CNT_ERR_DATASET_FailedStore,[e.message]);
    end;

  end;
end;

Replace

asm
  (@mHead).dhData = JSON.stringify((@self).FCache);
end;

with

asm
  (@mHead).dhData = JSON.stringify(@FCache);
end;

And it will work!

 

Reason:

(@self).FCache becomes in javascript (self).FCache$1.

Share this post


Link to post
Share on other sites

Same thing with the LoadFromString Procedure..

Procedure TW3Dataset.LoadFromString(Const aText:String);
var
  mHead:  TW3DatasetHeader;
Begin
  (* If the dataset is active, close it down *)
  if FActive then
  Close;

  (* Check source string *)
  if aText.Length>0 then
  Begin
    (* Attempt to de-serialize JSON data *)
    try
      asm
        @mHead = JSON.parse(@aText);
      end;
    except
      on e: exception do
      Raise EW3Dataset.CreateFmt(CNT_ERR_DATASET_FailedLoad,[e.message]);
    end;

    (* Verify header *)
    if mHead.dhMagic=$CAFE then
    Begin
      (* Load DEFS if any *)
      if mHead.dhFieldDefs.Length>0 then
      FDefs.LoadFromString(DecodeURI(mHead.dhFieldDefs));

      (* Any actual rows? ok, try to load them *)
      if mHead.dhCount>0 then
      Begin
        try
          asm
            (@self).FCache = JSON.parse((@mHead).dhData);
          end;
        except
          on e: exception do
          Raise EW3Dataset.CreateFmt(CNT_ERR_DATASET_FailedLoad,[e.message]);
        end;
      end;
    end else
    Raise EW3Dataset.Create(CNT_ERR_DATASET_LoadInvalidSignature);
  end else
  Raise EW3Dataset.Create(CNT_ERR_DATASET_LoadInvalidSource);
end;

replace

    asm
      (@self).FCache = JSON.parse((@mHead).dhData);
    end;

with

    asm
      @FCache = JSON.parse((@mHead).dhData);
    end;

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×