#51 mORMot 1 » Inheritance in JSON Serialization » 2017-03-24 16:06:24

mohsenti
Replies: 4

Hi,

Is it OK that I inherit classes that I use with JSONToObject? I guess yes it is. but a simple problem is here, ObjectToJSONFile saves published properties in reverse order, from child to parent so If Parent has Prop1 and Prop2 and child add Prop3, ObjectToJSONFile save Prop3 and Prop2 and the Prop1.
I checked TTextWriterWriteObjectOption but it seems not has an option for this.

A sample for test:

program project1;

uses
  Classes,
  SysUtils,
  FileUtil,
  SynCommons,
  mORMot;

type
  TParentItem = class;
  TParentItems = array of TParentItem;

  { TItem }

  TItem = class(TSynAutoCreateFields)
  private
    FID: integer;
  published
    property ID: integer read FID write FID;
  end;

  TParentItem = class(TItem)
  private
    FChilds: TParentItems;
  published
    property Childs: TParentItems read FChilds write FChilds;
  end;

  procedure TestIt;
  var
    it: TParentItem;
    s: RawUTF8;
  begin
    TJSONSerializer.RegisterObjArrayForJSON([TypeInfo(TParentItems), TParentItem]);
    s := StringFromFile('test.json');
    it := TParentItem.Create;
    ObjectLoadJSON(it, s);
    ObjectToJSONFile(it, 'output.json');
    it.Free;
  end;

begin
  TestIt;
end.

Input JSON:

{
	"ID": 1,
	"Childs": [{
			"ID": 11,
			"Childs": [{
					"ID": 111,
					"Childs": [{}, {}
					]
				}, {
					"ID": 112,
					"Childs": [{}, {}
					]
				}
			]
		}, {
			"ID": 12,
			"Childs": [{
					"ID": 121,
					"Childs": [{}, {}
					]
				}, {
					"ID": 122,
					"Childs": [{}, {}
					]
				}
			]
		}
	]
}

And output is:

{
	"Childs": 
	[
		{
			"Childs": 
			[
				{
					"Childs": 
					[
						{
							"Childs": [],
							"ID": 0
						},
						{
							"Childs": [],
							"ID": 0
						}
					],
					"ID": 111
				},
				{
					"Childs": 
					[
						{
							"Childs": [],
							"ID": 0
						},
						{
							"Childs": [],
							"ID": 0
						}
					],
					"ID": 112
				}
			],
			"ID": 11
		},
		{
			"Childs": 
			[
				{
					"Childs": 
					[
						{
							"Childs": [],
							"ID": 0
						},
						{
							"Childs": [],
							"ID": 0
						}
					],
					"ID": 121
				},
				{
					"Childs": 
					[
						{
							"Childs": [],
							"ID": 0
						},
						{
							"Childs": [],
							"ID": 0
						}
					],
					"ID": 122
				}
			],
			"ID": 12
		}
	],
	"ID": 1
}

As you can see it will write "Childs" first and then "ID".

Is there a way to make it sort in order or I should make a custom serializer?

#52 mORMot 1 » JSONToObject error/warning log » 2017-03-24 15:57:53

mohsenti
Replies: 2

Hi,

If I add j2oIgnoreUnknownProperty to JSONToObject options it will continue to read the JSON but it whould be nice to have an output from errors or problems. I looked at the code an it will just exit if it faces to any issue, can we have a call back event for error/warning ?
I can implement one if its ok.

#53 mORMot 1 » Prevent making not existence classes in JSON Serialization » 2017-03-24 15:53:47

mohsenti
Replies: 2

Hi,

Is there a way to prevent making classes that their object do not exists in the JSON? In my JSON input sometimes the property that is a class does not exists and JSONToObject make a class for that with empty properties, can I set it to do not make an object and just pass nil to it? or I should make a custom serializer?

Here is a sample file:

{
	"ID": 1,
	"Childs": [{
			"ID": 11,
			"Childs": [{
					"ID": 111,
					"Childs": [{}, {}
					]
				}, {
					"ID": 112,
					"Childs": [{}, {}
					]
				}
			]
		}, {
			"ID": 12,
			"Childs": [{
					"ID": 121,
					"Childs": [{}, {}
					]
				}, {
					"ID": 122,
					"Childs": [{}, {}
					]
				}
			]
		}
	],
	"Options": {
		"Name": "Name1"
	}
}

As you can see this is a tree but only parent has "Options" and if I write serializer like below it will make Options class for every child with empty propertises like the output, can I prevent that or I should make a custom serializer? an option would be nice.

program project1;

uses
  Classes,
  SysUtils,
  FileUtil,
  SynCommons,
  mORMot;

type
  TItem = class;
  TItems = array of TItem;

  { TOptions }

  TOptions = class(TPersistent)
  private
    FName: string;
  published
    property Name: string read FName write FName;
  end;

  { TItem }

  TItem = class(TSynAutoCreateFields)
  private
    FID: integer;
    FChilds: TItems;
    FOptions: TOptions;
  published
    property ID: integer read FID write FID;
    property Childs: TItems read FChilds write FChilds;
    property Options: TOptions read FOptions;
  end;

  procedure TestIt;
  var
    it: TItem;
    s: RawUTF8;
  begin
    TJSONSerializer.RegisterObjArrayForJSON([TypeInfo(TItems), TItem]);
    s := StringFromFile('test.json');
    it := TItem.Create;
    ObjectLoadJSON(it, s);
    ObjectToJSONFile(it, 'output.json');
    it.Free;
  end;

begin
  TestIt;
end. 

And the output will be like:

{
	"ID": 1,
	"Childs": 
	[
		{
			"ID": 11,
			"Childs": 
			[
				{
					"ID": 111,
					"Childs": 
					[
						{
							"ID": 0,
							"Childs": [],
							"Options": {
								"Name": ""
							}
						},
						{
							"ID": 0,
							"Childs": [],
							"Options": {
								"Name": ""
							}
						}
					],
					"Options": {
						"Name": ""
					}
				},
				{
					"ID": 112,
					"Childs": 
					[
						{
							"ID": 0,
							"Childs": [],
							"Options": {
								"Name": ""
							}
						},
						{
							"ID": 0,
							"Childs": [],
							"Options": {
								"Name": ""
							}
						}
					],
					"Options": {
						"Name": ""
					}
				}
			],
			"Options": {
				"Name": ""
			}
		},
		{
			"ID": 12,
			"Childs": 
			[
				{
					"ID": 121,
					"Childs": 
					[
						{
							"ID": 0,
							"Childs": [],
							"Options": {
								"Name": ""
							}
						},
						{
							"ID": 0,
							"Childs": [],
							"Options": {
								"Name": ""
							}
						}
					],
					"Options": {
						"Name": ""
					}
				},
				{
					"ID": 122,
					"Childs": 
					[
						{
							"ID": 0,
							"Childs": [],
							"Options": {
								"Name": ""
							}
						},
						{
							"ID": 0,
							"Childs": [],
							"Options": {
								"Name": ""
							}
						}
					],
					"Options": {
						"Name": ""
					}
				}
			],
			"Options": {
				"Name": ""
			}
		}
	],
	"Options": {
		"Name": "Name1"
	}
}

#54 Re: mORMot 1 » Use JSONToObject for tree structure » 2017-03-24 15:49:02

I will create separate topics for these questions for better order for future.

#55 Re: mORMot 1 » Use JSONToObject for tree structure » 2017-03-24 14:45:36

Hi again,

Is there a way to prevent making classes that their object do not exists in the JSON? In my JSON input sometimes the property that is a class does not exists and JSONToObject make a class for that with empty properties, can I set it to do not make an object and just pass nil to it? or I should make a custom serializer?

#56 Re: mORMot 1 » Use JSONToObject for tree structure » 2017-03-24 11:18:47

Another simple question,

Is it OK that I inherit classes that I use with JSONToObject? I guess yes it is. but a simple problem is here, ObjectToJSONFile saves published properties in reverse order, from child to parent so If Parent has Prop1 and Prop2 and child add Prop3, ObjectToJSONFile save Prop3 and Prop2 and the Prop1.
I checked TTextWriterWriteObjectOption but it seems not has an option for this.
Do you want me to make a sample to make it more clear?

#57 Re: mORMot 1 » Use JSONToObject for tree structure » 2017-03-24 10:33:11

Lazarus now has a Online Package Manager and it works well, you can add it or ask GetMem to add it for easy install. in Lazarus.
http://forum.lazarus.freepascal.org/ind … 297.0.html

#58 Re: mORMot 1 » Use JSONToObject for tree structure » 2017-03-24 10:28:01

Thanks again.
While I'm testing I faced to a problem, if my class has not all the JSON child it will not load all the childs. As documented I solved it with j2oIgnoreUnknownProperty, but can I add a warning to it so it will load but send me warnings?
I can implement it but I want to know your opinion.

#59 Re: mORMot 1 » Use JSONToObject for tree structure » 2017-03-24 09:59:10

Thanks ab,

Code has bugs indeed, but the error cause was my mORMot, I got it with fpcupdelux and it get the source from deprecated newpascal-ccr repository.
Now I solved it and everything goes well. Thank you very much.
A question out of curiosity: Is this a rule to name items like T*ObjArray, I changed it and everything seems good but because I read your posts in forum, I wanted to ask.

#61 Re: mORMot 1 » Use JSONToObject for tree structure » 2017-03-22 22:19:26

Thanks ab and EMartin.
ab if you talk about something like this:
   

 TJSONSerializer.RegisterClassForJSON([TItem]);   

I done that and call the line before ObjectLoadJSON and because it didnt change the errorm I removed it.


I tested again like this and error still the same:

begin
  s:=ReadFileToString('child.json');
  it:=TItem.Create;
  TJSONSerializer.RegisterClassForJSON([TItem]);
  TJSONSerializer.RegisterObjArrayForJSON([TypeInfo(TItems), TItem]);
  ObjectLoadJSON(it,s);
  it.Free;
end.    

#62 mORMot 1 » Use JSONToObject for tree structure » 2017-03-22 19:35:20

mohsenti
Replies: 14

Hi,

I have a JSON sample like this:

{
	"ID": 1,
	"Childs": [{
			"ID": 11,
			"Childs": [{
					"ID": 111,
					"Childs": [{}, {}
					]
				}, {
					"ID": 112,
					"Childs": [{}, {}
					]
				}
			]
		}, {
			"ID": 12,
			"Childs": [{
					"ID": 121,
					"Childs": [{}, {}
					]
				}, {
					"ID": 122,
					"Childs": [{}, {}
					]
				}
			]
		}
	]
}

And a sample code in last NewPascal code:

program project1;

uses
  Classes,
  SysUtils,
  FileUtil,
  mORMot;

type
  TItem = class;
  TItems = array of TItem;

  { TItem }

  TItem = class(TPersistent)
  private
    FID: integer;
    FItems: TItems;
  published
    property ID: integer read FID write FID;
    property Items: TItems read FItems write FItems;
  end;
var
  it: TItem;
  s: String;

begin
  s:=ReadFileToString('child.json');
  it:=TItem.Create;
  ObjectLoadJSON(it,s);
  it.Free;
end.

but I get a error like this:

Project project1 raised exception class 'ESynException' with message:
TJSONRecordTextDefinition.Create: TSynMapSymbol text definition is not accurate, or the type has not been defined as PACKED record: RTTI size is 5220048 bytes but text definition generated 12 bytes

I know there is a problem with my struture but how can I get JSON tree loaded?

#64 Re: mORMot 1 » Lazarus package » 2016-12-19 15:54:57

Why there is a need for that?
@ab with a package making new projects in Lazarus and mORMot will be easier with no need of adding paths.
Lazarus encourage using packages not adding paths.

#65 Re: mORMot 1 » Lazarus package » 2016-12-14 10:05:46

It is good to have ab opinion.

#66 mORMot 1 » Lazarus package » 2016-12-12 15:23:46

mohsenti
Replies: 12

Hi,

Is there any particular reason not having a Lazarus package?
Now for each project I should add path to units but with Lazarus package just adding a package is enough.

#68 Re: mORMot 1 » Sample REST API with GET request » 2016-11-29 11:26:36

So the code will be like this:

program ProjectServer;

{$APPTYPE CONSOLE}

uses
  SynCommons,
  mORMot,
  SysUtils,
  mORMotHttpServer;

type

  { TServiceServer }

  TServiceServer = class(TSQLRestServerFullMemory)
  published
    procedure Sum(Ctxt: TSQLRestServerURIContext);
  end;


  { TServiceServer }

  procedure TServiceServer.Sum(Ctxt: TSQLRestServerURIContext);
  begin
    Ctxt.Results([Ctxt['a'] + Ctxt['b']]);
  end;

var
  aModel: TSQLModel;
  aRestServ: TSQLHttpServer;
  aRest: TServiceServer;
  aDef: TSQLHttpServerDefinition;
begin
  aModel := TSQLModel.Create([]);
  try
    aDef := TSQLHttpServerDefinition.Create;
    aDef.Https := False;
    aDef.BindPort := '888';
    aDef.EnableCORS := True;
    aDef.WebSocketPassword := '';
    aRest := TServiceServer.Create(aModel);
    aRestServ := TSQLHttpServer.Create(aRest, aDef);
    with aRest do
      try
        Write('Press [Enter] to close the server.');
        readln;
      finally
        Free;
      end;
  finally
    aRestServ.Free;
    aDef.Free;
    aModel.Free;
  end;
end.

Right?

Now some question to understand better how should I work:
1- Should I use this sample server on real server or I should make it work with Apache for example? Also for HTTPS?
2-Should I use it as this server or somehow make it a cgi? how?
3-Where can I read about make a simple authentication like a simple for example API key?
I tried to read the examples and doc but they are so easy or so complicated and I want to know "How to run a very simple API in my server with mORMot in real project". What are the steps?

#69 mORMot 1 » Sample REST API with GET request » 2016-11-28 06:48:04

mohsenti
Replies: 13

Hi,

How can I make sample 06 with REST API server so I can get access with simple browser GET request like:

http://localhost:1234/API/sum?a=2&b=3

(Custom port and root is API)
I want that to make a simple API but use it in browser.

#70 Re: mORMot 1 » Simple Interface based server with database ! » 2015-04-12 05:36:28

edwinsn wrote:

Do you mean something like:

myNode := TSQLNote.Create;
myNode.Title := 'no title';
aServer.Add(myNote);

?

Yes but can't access aServer in TServiceNote

function TServiceNote.addNote(Title, Body: RawUTF8): Boolean;
begin
  // can't access aServer here
end;

#71 Re: mORMot 1 » Simple Interface based server with database ! » 2015-04-11 09:39:40

I don't know continuation and how to work with DB in interface based system.

#72 mORMot 1 » Simple Interface based server with database ! » 2015-04-11 07:09:13

mohsenti
Replies: 8

Hi all;

I develop mormot server based on document and demos but I can't insert data to table with interface system;

thanks;

// interfaces.pas

unit Interfaces;

interface
uses SynCommons;
type
  INote = interface(IInvokable)
  ['{4C284438-8107-4237-9932-F844472A0369}']
    function addNote(Title,Body:RawUtf8):Boolean;
  end;

implementation

uses mORMot;

initialization
  TInterfaceFactory.RegisterInterfaces([TypeInfo(INote)]);
end.

// models.pas

unit Models;

interface

uses mOrmot,SynCommons;

type
  TSQLNote=class(TSQLRecord)
  private
    fTitle,fBody:RawUTF8;
  public
    function check:Boolean;
  published
    property Title:RawUTF8 read fTitle write fTitle;
    property Body:RawUTF8 read fBody write fBody;
  end;

  function CreateModel:TSQLModel;

implementation

  function CreateModel:TSQLModel;
  begin
    Result:=TSQLModel.Create([TSQLNote]);
  end;

{ TSQLNote }

function TSQLNote.check: Boolean;
begin
  Result:=True;
end;

end.

// main.pas

unit Main;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs,mORMot,mORMotHttpServer,MormotSQLite3,SynCommons,Interfaces,SynSQLite3Static;

type

  TServiceNote=class(TInterfacedObject,INote)
  public
    function addNote(Title: RawUTF8; Body: RawUTF8): Boolean;
  end;

  TForm2 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
  public
    aModel: TSQLModel;
    aServer: TSQLRestServer;
    aHTTPServer: TSQLHttpServer;
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

uses Models;

procedure TForm2.FormCreate(Sender: TObject);
begin
  aModel:=CreateModel;
  aServer:=TSQLRESTServerDB.Create(aModel,'Database.db');
  aServer.ServiceDefine(TServiceNote,[INote],sicShared);
  aHTTPServer:=TSQLHttpServer.Create('8096',aServer,'+',useHttpApiRegisteringURI);
end;

procedure TForm2.FormDestroy(Sender: TObject);
begin
  aModel.Free; aServer.Free;  aHTTPServer.Free;
end;

{ TServiceDemo }

function TServiceNote.addNote(Title, Body: RawUTF8): Boolean;
begin

end;

end.

Board footer

Powered by FluxBB