#1 Re: mORMot 1 » JSON with class and Reserved Word or KeyWord » 2016-02-18 13:04:43

Yeah I already tried it and in delphi 6 it doesn't work.
Delphi 6 is f%%$ing crap but I don't have a choice

So, I tried find and replace on JSON file with 2 600 000 lines and it take 22 seconds
On standard JSON file, I have no difference of time to process it

Just for your information, I don't use delphi StringReplace
I use FastReplace in subtitleworkshop/FastStrings.pas library (https://github.com/dekked/subtitleworkshop)

I just replace this keywork and all it work
unit -> unit_
type -> type_

That's it

#2 Re: mORMot 1 » Unserialize JSON with complex TObjectList structure » 2016-02-17 16:48:20

I think if you set j2oIgnoreUnknownProperty in JSONToObject option will skip item if you don't have it in your class

#3 Re: mORMot 1 » JSON with class and Reserved Word or KeyWord » 2016-02-17 16:41:53

Yeah I know but I use Classes in my unit
My unit contain more than 30 classes and I don't want to rewrite all my code ton convert it into record

The only idea I have is to replace into JSON the reserved keyword and unserialize it like

   JSONString := StringReplace(JSONString, '"Unit" :', '"UnitKW" :', [rfReplaceAll]);
   JSONString := StringReplace(JSONString, '"begin" :', '"beginKW" :', [rfReplaceAll]); //Do for all keyword

When I'll serialize again I replace the reseved keyword again

   JSONString := StringReplace(JSONString, '"UnitKW" :', '"Unit" :', [rfReplaceAll]);
   JSONString := StringReplace(JSONString, '"beginKW" :', '"begin" :', [rfReplaceAll]); //Do for all keyword

But if you have another idea... go for it

Thank

#4 Re: mORMot 1 » JSON with class and Reserved Word or KeyWord » 2016-02-16 18:22:43

Hi,

I don't understant how I can build my object with TDocVariantData
Could you show me an exemple

I always use JSONToObject to unserialize my JSON

Thank you

#5 Re: mORMot 1 » JSON without field name » 2016-02-16 18:08:47

It works
Thank you

This is my code for anyone need it

var
  array : TVariantDynArray;
begin
  array  := JSONToVariantDynArray(JSONRESULT)

#6 mORMot 1 » JSON without field name » 2016-02-16 14:03:36

ioda19
Replies: 2

Hi,

How I can implement class in delphi to serialize/deserialize this JSON file ?

[
	"6b43e778-a0af-429e-8e09-0c664f5016b9",
	"40abc107-d078-41a0-8aa7-0c664f336125",
	"ecf50a16-83d2-4bf6-a099-0c664f1aa447"
]

#7 mORMot 1 » JSON with class and Reserved Word or KeyWord » 2015-11-26 19:13:16

ioda19
Replies: 6

Hi,

I have this JSON

{
  "Product":
  {
    "blablabla":"test",
    "Unit": {
      "Code_0": "UN",
      "Code_1": "UN",
      ....
    }
  }
}

How I can create my class with UNIT keyword in Delphi6 to serialize this JSON
I can't create like this because Delphi return error

TProduct = class(TSynPersistent)
private
  Fblablabla : RAWUTF8 ;
  FUnit : TUnit;
published
  property blablabla: RAWUTF8 read Fblablabla write Fblablabla;
  property Unit : TUnit read FUnit;   <----------  ERROR HERE
end;

Could I map field like AutoMapKeywordFields option into TSQLRecord class ?

#8 Re: mORMot 1 » Unserialize JSON with complex TObjectList structure » 2015-11-23 20:34:49

Maybe I'll need to use array at least of CollectionItem

Could you give me a little exemple to use array in class with my class structure ?

Thank you

#9 mORMot 1 » Sometime is Object, sometime is ItemCollection » 2015-11-23 19:22:39

ioda19
Replies: 0

Hi,

I have a basic object structure declared like this

TProduct = class(TSynAutoCreateFields)
  private
    FID: RawUTF8;
    FNumber: Integer;
  published
    property ID : RawUTF8 read FID write FID;
    property Number : Integer read FNumber write FNumber;
end;

If I call service to GET specified product I receive a JSON like this

{
  "TypeID": "7328059c-51ec-4104-ac9e-1e8af3e32228",
  "Description_0": "Produit AKMN202482",
  "Description_1": "Product AKMN202482",
  "Number": "AKMN202482",
  "ID": "993a1d67-bbe2-4ad0-826c-0be01c51a83f"
}

So this is a basic product class (TSynAutoCreateFields)

If I call service to GET all product list I receive a JSON like this

[
  {
    "TypeID": "7328059c-51ec-4104-ac9e-1e8af3e32228",
    "Description_0": "Produit AKMN202482",
    "Description_1": "Product AKMN202482",
    "Number": "AKMN202482",
    "ID": "993a1d67-bbe2-4ad0-826c-0be01c51a83f"
  },
  {
    "TypeID": "7328059c-51ec-4104-ac9e-1e8af3e32228",
    "Description_0" : "Produit FACR426534",
    "Description_1" : "Product FACR426534",
    "Number": "FACR426534",
    "ID": "ec324edb-4a03-4c31-96f0-0bd7b679320b"
  }
]

This is a Basic product class into CollectionItem (TCollectionItemAutoCreateFields)




I tried this and it work but I wouldn't use interface for each class I need (Product, Customer, Group, etc)

  IProduct = interface(IInterface)
    function GetID : RawUTF8;
    function GetNumber : RawUTF8;
    procedure SetID(Value : RawUTF8);
    procedure SetNumber(value : RawUTF8);

    property ID : RawUTF8 read GetID write SetID;
    property Number : RawUTF8 read GetNumber write SetNumber;
  end;

  TProduct = class(TSynAutoCreateFields, IProduct)
  private
    FID : RawUTF8;
    FNumber : RawUTF8;

    function GetID : RawUTF8;
    function GetNumber : RawUTF8; 
    procedure SetID(Value : RawUTF8);
    procedure SetNumber(value : RawUTF8);
  protected 
    FRefCount: Integer;
    function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
    function _AddRef: Integer; stdcall;
    function _Release: Integer; stdcall;
  published
    property ID : RawUTF8 read GetID write SetID;
    property Number : RawUTF8 read GetNumber write SetNumber;
  end;


  TProducts = class(TCollectionItemAutoCreateFields, IProduct)
  private  
    FID : RawUTF8;
    FNumber : RawUTF8;

    function GetID : RawUTF8;
    function GetNumber : RawUTF8; 
    procedure SetID(Value : RawUTF8);
    procedure SetNumber(value : RawUTF8);
  protected    
    FRefCount: Integer;
    function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
    function _AddRef: Integer; stdcall;
    function _Release: Integer; stdcall;
  published
    property ID : RawUTF8 read GetID write SetID;
    property Number : RawUTF8 read GetNumber write SetNumber;
  end;


How I can implement code to specified what kind of interface I need it without declase Interface and without declare two different classes with same property ?

Thank you

#10 Re: mORMot 1 » Unserialize JSON with complex TObjectList structure » 2015-11-19 15:55:02

Sure

I'll email it today.
Just for your information, I base ma code on "20 - DTO interface based service" exemple

#11 mORMot 1 » Need help (Not for mORMot Framework but maby someone can help me) » 2015-11-18 20:26:45

ioda19
Replies: 1

Hi,

I know this question is not about mORMot Framework but on this forum some programmer are expert and maybe can help me.

I have this structure in C#

public class User
{
  ...
  public ICollection<UserGroup> Groups { get; set; }
  ...
}


public class UserGroup
{
  ...
  public User User { get; set; }
  ...
}

As you can see, User is in UserGroup and UserGroup is in User
In C# you can this


But I need to use same structure in Delphi 6 but I have circular reference between two unit (User and UserGroup)
Someone have a suggestion because I need to serialize and deserialize JSON from C# to Delphi and vice-versa

Thank you

#12 Re: mORMot 1 » Unserialize JSON with complex TObjectList structure » 2015-11-18 20:18:37

I found solution with Collection

This is my code for someone need it

CLASS DEFINITION

type
  TBaseClass = class(TSynAutoCreateFields)
  private
    FID: RawUTF8;
  published
    property ID : RawUTF8 read FID write FID;
end;

type
  TGroup = class(TBaseClass)
  private
    FName: RawUTF8;
  published
    property Name : RawUTF8 read FName write FName;
end;

type
  //CHANGE CLASS TYPE HERE FOR TCollectionItemAutoCreateFields
  TGroups = class(TCollectionItemAutoCreateFields)
  private
    FGroupID: RawUTF8;
    FUserID: RawUTF8;
    FGroup: TGroup;
  published
    property UserID : RawUTF8 read FUserID write FUserID;
    property GroupID : RawUTF8 read FGroupID write FGroupID;
    property Group : TGroup read FGroup;
end;       

//THIS IS NEW CLASS FOR MANAGE COLLECTION AND ACCESS LIKE AN ARRAY
type
  TGroupsCollection = class(TInterfacedCollection)
  private
    function GetCollItem(aIndex: Integer): TGroups;
  protected
    class function GetClass: TCollectionItemClass; override;
  public
    function Add: TGroups;
    property Item[aIndex: Integer]: TGroups read GetCollItem; default;
  end;

type
  TUser = class(TBaseClass)
  private
    FUsername: RawUTF8;
    FFirstName: TNullableUTF8Text;
    FLastName: TNullableUTF8Text;
    FGroups: TGroupsCollection;
    FCanSynchronize: boolean;
  published
    property Username : RawUTF8 read FUsername write FUsername;
    property FirstName : TNullableUTF8Text read FFirstName write FFirstName;
    property LastName : TNullableUTF8Text read FLastName write FLastName;

    property Groups: TGroupsCollection read FGroups;
end;

type
  TCompany = class(TBaseClass)
  private
    FCanSynchronize: boolean;
    FType: Integer;
    FName: RawUTF8;
  published
    property CanSynchronize : boolean read FCanSynchronize write FCanSynchronize;
    property Name : RawUTF8 read FName write FName;
    property Types : Integer read FType write FType;
end;

type
  TSession = class(TBaseClass)
  private
    FUserID: RawUTF8;
    FUser: TUser;
    FCompanyID: RawUTF8;
    FCompany: TCompany;
  published
    property UserID : RawUTF8 read FUserID write FUserID;
    property User : TUser read FUser;
    property CompanyID : RawUTF8 read FCompanyID write FCompanyID;
    property Company : TCompany read FCompany;
end;

type
  TSessions = class(TSynAutoCreateFields)
  private
    FSession: TSession;
    function GetSession: TSession;
  published
    property Session : TSession read FSession;
  end;

CODE FOR CLASS TGroupsCollection

function TGroupsCollection.Add: TGroups;
begin
  result := TGroups(inherited Add);
end;

class function TGroupsCollection.GetClass: TCollectionItemClass;
begin
  result := TGroups;
end;

function TGroupsCollection.GetCollItem(aIndex: Integer): TGroups;
begin
  result := TGroups(GetItem(aIndex));
end;

CREATE JSON FILE

  lSessions := TSessions.Create;

  lSessions.Session.UserID := ('d0d49a49-7cd2-4336-a85e-0bd60584178e');
  lSessions.Session.User.Username := 'admin';

  with lSessions.Session.User.Groups.Add do
  begin
    Group.Name := 'ADMIN';
  end;
  with lSessions.Session.User.Groups.Add do
  begin
    Group.Name := 'INVITE';
  end;

  lSessions.Session.CompanyID := ('a58907b7-8be2-4a14-9a82-0bd60581fad0');
  lSessions.Session.Company.Name := 'Acomba Demo';

  Memo1.Text := ObjectToJSON(lSessions, [woHumanReadable]);

  FreeAndNil(lSessions);

JSON CREATED

{
	"Session": {
		"UserID": "d0d49a49-7cd2-4336-a85e-0bd60584178e",
		"User": {
			"Username": "admin",
			"FirstName": null,
			"LastName": null,
			"Groups": 
			[{
					"UserID": "",
					"GroupID": "",
					"Group": {
						"Name": "ADMIN",
						"ID": ""
					}
				},{
					"UserID": "",
					"GroupID": "",
					"Group": {
						"Name": "INVITE",
						"ID": ""
					}
				}
			],
			"ID": ""
		},
		"CompanyID": "a58907b7-8be2-4a14-9a82-0bd60581fad0",
		"Company": {
			"CanSynchronize": false,
			"Name": "Acomba Demo",
			"Types": 0,
			"ID": ""
		},
		"ID": ""
	}
}

UNSERIALIZE JSON INTO OBJECT

lSessions := TSessions.Create;
JSONToObject(lSessions, @Memo1.Text[1], isValid, nil, [j2oIgnoreUnknownProperty]);
FreeAndNil(lSessions);

Now you can access Groups like this : lSessions.session.user.groups[0].Group.Name or lSessions.session.user.groups.item[0].Group.Name

#13 Re: mORMot 1 » Unserialize JSON with complex TObjectList structure » 2015-11-18 18:13:05

Ok thank you
That was I expected

I'll ready try with TGroupsArray= array of TGroups but not work when deserialize
My array is always empty even I tried TJSONSerializer.RegisterObjArrayForJSON(TypeInfo(TGroupsArray),TGroups);

Can you give me an exemple with array and unserialize ?

Thank

#14 mORMot 1 » Unserialize JSON with complex TObjectList structure » 2015-11-18 14:10:21

ioda19
Replies: 19

Hi,

I search for many hours without found a solution
I have a complex structure of class with TObjectList.
I can serialize JSON from the object but if I unserialize to object, all my TObjectList have no data and isValid result if false
Could you help me

This is my code

CLASS DECLARATION

type
  TBaseClass = class(TSynAutoCreateFields)
  private
    FID: RawUTF8;
  published
    property ID : RawUTF8 read FID write FID;
end;

type
  TGroup = class(TBaseClass)
  private
    FName: RawUTF8;
  published
    property Name : RawUTF8 read FName write FName;
end;

type
  TGroups = class(TSynAutoCreateFields)
  private
    FGroupID: RawUTF8;
    FUserID: RawUTF8;
    FGroup: TGroup;
    function GetGroup: TGroup;
  published
    property UserID : RawUTF8 read FUserID write FUserID;
    property GroupID : RawUTF8 read FGroupID write FGroupID;
    property Group : TGroup read FGroup;
end;

type
  TUser = class(TBaseClass)
  private
    FUsername: RawUTF8;
    FFirstName: TNullableUTF8Text;
    FLastName: TNullableUTF8Text;
    FGroups: TObjectList;
    FCanSynchronize: boolean;
    function GetGroups(Index: Integer): TGroups;
  published
    property Username : RawUTF8 read FUsername write FUsername;
    property FirstName : TNullableUTF8Text read FFirstName write FFirstName;
    property LastName : TNullableUTF8Text read FLastName write FLastName;

    property Groups: TObjectList read FGroups;
end;

type
  TCompany = class(TBaseClass)
  private
    FCanSynchronize: boolean;
    FType: Integer;
    FName: RawUTF8;
  published
    property CanSynchronize : boolean read FCanSynchronize write FCanSynchronize;
    property Name : RawUTF8 read FName write FName;
    property Types : Integer read FType write FType;
end;

type
  TSession = class(TBaseClass)
  private
    FUserID: RawUTF8;
    FUser: TUser;
    FCompanyID: RawUTF8;
    FCompany: TCompany;
    function GetCompany: TCompany;
    function GetUser: TUser;
  published
    property UserID : RawUTF8 read FUserID write FUserID;
    property User : TUser read FUser;
    property CompanyID : RawUTF8 read FCompanyID write FCompanyID;
    property Company : TCompany read FCompany;
end;

type
  TSessions = class(TSynAutoCreateFields)
  private
    FSession: TSession;
    function GetSession: TSession;
  published
    property Session : TSession read FSession;
  end;

GENERATE JSON (WORK)

var
  lSessions : TSessions;
begin
  lSessions := TSessions.Create;

  lSessions.Session.UserID := ('d0d49a49-7cd2-4336-a85e-0bd60584178e');
  lSessions.Session.User.Username := 'admin';
  lSessions.Session.User.Groups.Add(TGroups.Create); //Add one group into JSON
  TGroups(lSessions.Session.User.Groups[0]).UserID := ('d0d49a49-7cd2-4336-a85e-0bd60584178e');
  TGroups(lSessions.Session.User.Groups[0]).Group.Name := 'TEST';

  lSessions.Session.CompanyID := ('a58907b7-8be2-4a14-9a82-0bd60581fad0');
  lSessions.Session.Company.Name := 'Acomba Demo';

  TJSONSerializer.RegisterClassForJSON([TSessions,TUser,TCompany,TGroups,TGroup]);

  Memo1.Text := ObjectToJSON(lSessions, [woHumanReadable, woObjectListWontStoreClassName]); 
  //I must to declare woObjectListWontStoreClassName because the REAL JSON come from another system and doesn't have ClassName field
  //But if I undeclare woObjectListWontStoreClassName deserialization work

  FreeAndNil(lSessions);

JSON RESULT

{
	"Session": {
		"UserID": "d0d49a49-7cd2-4336-a85e-0bd60584178e",
		"User": {
			"Username": "admin",
			"FirstName": null,
			"LastName": null,
			"Groups": 
			[{
					"UserID": "d0d49a49-7cd2-4336-a85e-0bd60584178e",
					"GroupID": "",
					"Group": {
						"Name": "TEST",
						"ID": ""
					}
				}
			],
			"ID": ""
		},
		"CompanyID": "a58907b7-8be2-4a14-9a82-0bd60581fad0",
		"Company": {
			"CanSynchronize": false,
			"Name": "Acomba Demo",
			"Types": 0,
			"ID": ""
		},
		"ID": ""
	}
}

LOAD JSON INTO OBJECT

var
  lSessions : TSessions;
  isValid : boolean;
begin
  lSessions := TSessions.Create;

  TJSONSerializer.RegisterClassForJSON([TSessions,TUser,TCompany,TGroups,TGroup]);

  JSONToObject(lSessions, @Memo1.Text[1], isValid, TSessions);
  FreeAndNil(lSessions);

My question is, could I use TObjectList without ClassName field into JSON ?

Or how I can change my structure with arrays at least TObjectList ?

Thank you

Board footer

Powered by FluxBB