You are not logged in.
Pages: 1
Hello everyone. I found an error. An example is below
program pAppend;
{$APPTYPE CONSOLE}
uses
SysUtils, dialogs
,mormot.core.os
;
var i:integer;
begin
for I := 0 to 10 do
AppendToFile(inttostr(i),'test.log');
//only the last digit will be written to the "test.log" file
{
in mormot.core.os
Line 7148 FileSeek64(0, soFromEnd) // append
need to insert a file's handle "h" to a function
FileSeek64(h, 0, soFromEnd)
}
ShowMessage('ok');
end.
Another unsolved problem is the incorrect operation of the _ObjArrayClear function
I also get access violation
https://gist.github.com/delphiapp/33c66 … e87c51c4cf
because line 5822 file mormot.core.rtti is
RawObjectsClear(pointer(V), PDALen(PAnsiChar(V^) - _DALEN)^ + _DAOFF); in this function
must be
RawObjectsClear(V^, PDALen(PAnsiChar(V^) - _DALEN)^ + _DAOFF);
I used Delphi 2006 Compiler and Stable Lazarus 2.2.4 Win32. In mORMot2 I got Access Violation from adress $00000000 when the programm is started
I have added compilation capability in Lazarus
I have a problem with TRestHttpServer too
This is my test code (mORMot1 is Ok, mORMot2 is fail)
https://gist.github.com/delphiapp/95640 … 858068f326
The line where is a problem - 884 mormot.rest.http.server;
log.Log(sllHttp, '% initialized for %', [fHttpServer, fDBServerNames], self);
One interesting feature turned out. When using the [jpoClearValues] parameter, the FinalizeAndClearPublishedProperties function is called and if the property is of type T*Objarray, the _ObjArrayClear function is called. This function not only frees the memory of array elements, but also deletes the array itself via _DynArrayClear.
But when we use the AutoDestroyFields function, if the property is of type T*ObjArray, then only the RawObjectsClear function is called. The array itself is not deleted
Good morning.
The probable cause of the error is an incorrect value of the first parameter of the RawObjectsClear function in the _ObjArrayClear procedure (line 5743, mormot.core.rtti)
there is -
RawObjectsClear(pointer(V), PDALen(PAnsiChar(V^) - _DALEN)^ + _DAOFF);
must be-
RawObjectsClear(V^, PDALen(PAnsiChar(V^) - _DALEN)^ + _DAOFF);
Please bear my foolishness. Why then is the T*ObjArray type property with the [jpoClearValues] parameter not released
You're right. In mormot 1, any previous instances of objects were forcibly released when json was loaded, but in mormot 2, it is now necessary to set the [jpoClearValues] parameter in the JsonFileToObject function. Thanks a lot.
Good morning. I have updated the example. See: https://gist.github.com/delphiapp/b2558 … 2cab5a6cc1
Since the class inherits from TSynAutoCreateFields, as I understand it, there is no need to prescribe a constructor and a destructor.
Thank you very much, Thomas, for wanting to help
Thanks a lot for your advices, but none of them helped. The error still exists.
Hello @ab. I got an error when reloading serialized data in Mormot2. When reloading data, an error appears when clearing T*ObjArray. File mormot.core.base, line 6996.
In version 1(switch the define) it's all right. You can reproduce the error through the source code.
Hello.
I am adding mORMot2 support to my project.
I met a pitfall. I attach an example of a project with an error. The variant with the error is controlled via a define "Test".
In mORMot1 I had a line code, which compile well in mORMot2, but doesn't work without a property ORM
ClientDB.OneFieldValue(TSQLRecordNames,'ID','Name=?',[],[StringToUTF8('Name3')]);
and a line
ClientDB.ExecuteJson([TSQLRecordNames],'SELECT * FROM Names')));
works equally well with and without a property ORM
Thanks for the quick response.
I don't want to define. Simply, the IDE just did it (added custom options) automatically without my knowledge
Hello.
I have found a problem when compiling an empty project mORMot 1.18 in Lazarus IDE 32 bit, on Windows 64bit, intel core. May be it is not an error, but "As designed". But it took me quite a while to find the cause of the error. And I would like others to be able to avoid such a situation.
It turned out by chance when I converted the empty Delphi project with unit SynCommons to Lazarus and selected(checked) the compatibility with Delphi7.
The IDE automatically added these parameters to "Custom Options: -dBorland -dVer150 -dDelphi7 -dCompiler6_Up -dPUREPASCAL". The last attribute "-dPUREPASCAL" in these parameters leads to compilation errors
Build project the unit SynCommons I get 2 errors.
First of all, in a inplementation of function crc32cfast I see many errors like this:
SynCommons.pas(25067,17) Error: Unknown identifier "R8"
AFAIK R8 and R9 and so on, these are 64-bit registers, but I have IDE 32 bit.
And second, functions StrCompSSE42 and StrLenSSE42 is active in a declaration, but disable(gray colour, for a reason "defines") in an inplementation and consequently i see errors:
SynCommons.pas(2324,10) Error: Forward declaration not solved "StrCompSSE42(Pointer;Pointer):LongInt;" and
SynCommons.pas(2331,10) Error: Forward declaration not solved "StrLenSSE42(Pointer):LongInt;"
Is it necessary to describe this situation to users?
Good afternoon. Please, tell me about how I can save a variant as a json object, but not as a json Array? By default mORMot1 save the variant as an object, and mORMot2 as an array.
ok, sorry
Good morning.
I wanted to do a trick, to persist data of record(structure) throught a variant published field. I use pre unicode version Delphi.
Well. I run my code with mormot1(switch the VER2 directive) and it work very well(all fields are serialized), but with mormot2, I get an error.
Here is my code ready for compile and json file "SaveAll.json"
Yes, it is. Everything works perfectly in Delphi and Lazarus
Ok. I will be use
GetSetNameValue(TypeInfo(TSetMyEnum), pEnum, endofobject);
instead TypeInfo(TSetMyEnumPart), where TSetMyEnum = set of TMyEnum;
And all passes.
Thanks for the clarification. But when I ran your a new test, I get an error. I am using BDS 2006.
Good day. I found the following problem when working with sets. Change a directive VER2 and see result.
program Project;
{$APPTYPE CONSOLE}
{$DEFINE VER2}
uses
SysUtils
{$IFnDEF VER2}
,SynCommons
{$ELSE}
,mormot.core.base, mormot.core.json
{$ENDIF}
;
type
TMyEnum = (enOne, enTwo, enThree, enFour, enFive);
TMyEnumPart =enTwo..enFour;
TSetMyEnumPart = set of TMyEnumPart;
var pEnum:PUTF8Char; s:RawUTF8;endofobject:Char;
begin
s:='["enTwo"]';
pEnum := PUTF8Char(s);
GetSetNameValue(TypeInfo(TSetMyEnumPart), pEnum, endofobject);
if pEnum <> nil then
Writeln('Error')
else
Writeln('Success');
readln;
end.
Thank you. It works very well;
Hello everyone. I want to serialize some records to a file. These records are inside object. When I writing code, as sample:
recapparat:=GetParamApparatUstr;
AddString('ParamApparat:');
AddRecordJSON(recapparat,TypeInfo(TApparatDataUstr));
Add(',');
....
I got:
{
ParamApparat:{
TrToka: [0,1,2,3,4,5,6,7],
TrTkOtb: [3],
TrNapr: [8,9,10,11,12,13,14],
Vhody: [16,16,16],
Rele: [16,16,16]
}
}
How I can get this(to indent all fields of records?):
{
ParamApparat:{
TrToka: [0,1,2,3,4,5,6,7],
TrTkOtb: [3],
TrNapr: [8,9,10,11,12,13,14],
Vhody: [16,16,16],
Rele: [16,16,16]
}
}
Thank you.
I noticed different behavior when saving a dynamic array of strings and a dynamic array of records. Should it be? I use pre-unicode version Delphi - BDS2006. When I compiled in Delphi XE4, it's all values the same
Here is the code.
program pStrangeSave;
{$APPTYPE CONSOLE}
uses
SysUtils,SynCommons,mORMot;
type
TListKanalov = array of string;
const
__Rec = 'name string';
type
TRec = packed record
name:string;
end;
TListRecKanalov = array of TRec;
var
Kanals : TListKanalov; RecKanals : TListRecKanalov;
da,daRec:TDynArray; i:Integer; s: RawUTF8;
const
ArrStr : array [0..2] of string = ('фаза1','фаза2','фаза3');//cirillic name
begin
TJSONSerializer.RegisterCustomJSONSerializerFromText(TypeInfo(TRec),__Rec);
SetLength(Kanals,3);
for i := 0 to 2 do
Kanals[i]:=ArrStr[i];
da.Init(TypeInfo(TListKanalov),Kanals);
SetLength(RecKanals,3);
for i := 0 to 2 do
RecKanals[i].name:=ArrStr[i];
daRec.Init(TypeInfo(TListRecKanalov),RecKanals);
with TTextWriter.CreateOwnedStream() do begin
AddDynArrayJSON(da); AddCR; AddDynArrayJSON(daRec); SetText(s);
end;
FileFromString(s,'strange.txt');
end.
I had the same problem. I used newpascal to compile and it's all become ok. You need unit - fpcsrc\rtl\objpas\typinfo.pp.
Check your json at least one online validator. https://jsonformatter.org/ https://codebeautify.org/jsonvalidator https://jsonlint.com/ You can see, that your data is not correct.
thank you very much, now it works very well
thank you, but have to
[
{
"ID": 1,
"IDZakaza": 1,
"IDTipoisp": 1,
"SerNomer": "",
"Otchety_nastrk": "{\"Href\":\"\",\"Report\":\"\",\"Result\":\"\",\"DateTest\":\"\"}",
"Otchety_termo0": "{\"Href\":\"\",\"Report\":\"<html></html>\",\"Result\":\"Success\",\"DateTest\":\"29.09.2015 10:35:52\"}",
"Otchety_termo8": "{\"Href\":\"\",\"Report\":\"\",\"Result\":\"\",\"DateTest\":\"\"}",
"Otchety_termo16": "{\"Href\":\"\",\"Report\":\"\",\"Result\":\"\",\"DateTest\":\"\"}",
"Otchety_termo24": "{\"Href\":\"\",\"Report\":\"\",\"Result\":\"\",\"DateTest\":\"\"}",
"Otchety_termo36": "{\"Href\":\"\",\"Report\":\"\",\"Result\":\"\",\"DateTest\":\"\"}",
"Otchety_termo48": "{\"Href\":\"\",\"Report\":\"\",\"Result\":\"\",\"DateTest\":\"\"}",
"Otchety_termo72": "{\"Href\":\"\",\"Report\":\"\",\"Result\":\"\",\"DateTest\":\"\"}",
"Otchety_Koeff": "{\"Href\":\"\",\"Report\":\"\",\"Result\":\"\",\"DateTest\":\"\"}",
"Otchety_HtmKoeff": "{\"Href\":\"\",\"Report\":\"\",\"Result\":\"\",\"DateTest\":\"\"}",
"Otchety_Test": "{\"Href\":\"\",\"Report\":\"\",\"Result\":\"\",\"DateTest\":\"\"}"
}
]
I have code from 7 july 2015
I know, the application compiles and runs. And what about the content of the file "pserver.db.json". Is it ok?
what is most interesting is that the file is valid, but it is wrong
Anybody help, compile this code and look to the file "pserver.db.json", it is wrong, how i writed above
program pServer;
{$APPTYPE CONSOLE}
uses
SysUtils,
StrUtils,
SynCommons,
mORMot,
SynSQlite3Static,
mORMotSQLite3,
Classes,
Forms;
var Model:TSQLModel;
Database:TSQLRest;
iId_BD:TID;
{------------------------------------------------------------------------------
Model
------------------------------------------------------------------------------}
type
TDateTermoprAll = (NoTest, Nastrk, Termo0, Termo8, Termo16, Termo24, Termo36, Termo48, Termo72, KoeffDSP, KoeffHTML, Test);
TDateTermopr = Nastrk..Test;
const
// Data name Blob field in DB
strDateTermopr : array[TDateTermopr] of ShortString = ('Otchety_nastrk', 'Otchety_termo0', 'Otchety_termo8',
'Otchety_termo16','Otchety_termo24','Otchety_termo36',
'Otchety_termo48','Otchety_termo72','Otchety_Koeff','Otchety_HtmKoeff','Otchety_Test');
type
/// here we declare the class containing the data
// - it just has to inherits from TSQLRecord, and the published
// properties will be used for the ORM (and all SQL creation)
// - the beginning of the class name must be 'TSQL' for proper table naming
// in client/server environnment
TDataReport = class(TPersistent)
private
fHref : RawUTF8;
fReport : RawUTF8;
fResult : RawUTF8;
fDateTest : RawUTF8;
public
procedure Clear;
published
property Href : RawUTF8 read fHref write fHref;
property Report : RawUTF8 read fReport write fReport;
property Result : RawUTF8 read fResult write fResult;
property DateTest : RawUTF8 read fDateTest write fDateTest;
end;
TSQLRecordZakaz = class(TSQLRecord)
private
fNomerZakaza : RawUTF8;
fZakazchik : RawUTF8;
fVypolnen : Boolean;
FTimeVypoln : TDateTime;
published
property NomerZakaza : RawUTF8 read fNomerZakaza write fNomerZakaza;
property Zakazchik : RawUTF8 read fZakazchik write fZakazchik;
property Vypolnen : Boolean read fVypolnen write fVypolnen;
property TimeVypoln : TDateTime read FTimeVypoln write FTimeVypoln;
end;
TSQLRecordTip = class(TSQLRecord)
private
fNameTipoisp : RawUTF8;
published
property NameTipoisp : RawUTF8 read fNameTipoisp write fNameTipoisp;
end;
TSQLRecordDevice = class(TSQLRecord)
private
fIDZakaza : TSQLRecordZakaz;
fIDTipoisp : TSQLRecordTip;
fSerNomer : RawUTF8;
fOtchety_nastrk : TDataReport;
fOtchety_termo0 : TDataReport;
fOtchety_termo8 : TDataReport;
fOtchety_termo16 : TDataReport;
fOtchety_termo24 : TDataReport;
fOtchety_termo36 : TDataReport;
fOtchety_termo48 : TDataReport;
fOtchety_termo72 : TDataReport;
fOtchety_Koeff : TDataReport;
fOtchety_HtmKoeff : TDataReport;
fOtchety_Test : TDataReport;
public
constructor Create; override;
destructor Destroy; override;
published
property IDZakaza : TSQLRecordZakaz read fIDZakaza write fIDZakaza;
property IDTipoisp : TSQLRecordTip read fIDTipoisp write fIDTipoisp;
property SerNomer : RawUTF8 read fSerNomer write fSerNomer;
property Otchety_nastrk : TDataReport read fOtchety_nastrk write fOtchety_nastrk;
property Otchety_termo0 : TDataReport read fOtchety_termo0 write fOtchety_termo0;
property Otchety_termo8 : TDataReport read fOtchety_termo8 write fOtchety_termo8;
property Otchety_termo16 : TDataReport read fOtchety_termo16 write fOtchety_termo16;
property Otchety_termo24 : TDataReport read fOtchety_termo24 write fOtchety_termo24;
property Otchety_termo36 : TDataReport read fOtchety_termo36 write fOtchety_termo36;
property Otchety_termo48 : TDataReport read fOtchety_termo48 write fOtchety_termo48;
property Otchety_termo72 : TDataReport read fOtchety_termo72 write fOtchety_termo72;
property Otchety_Koeff : TDataReport read fOtchety_Koeff write fOtchety_Koeff;
property Otchety_HtmKoeff : TDataReport read fOtchety_HtmKoeff write fOtchety_HtmKoeff;
property Otchety_Test : TDataReport read fOtchety_Test write fOtchety_Test;
end;
{ TSQLRecordDevice }
constructor TSQLRecordDevice.Create;
begin
inherited;
fOtchety_nastrk:=TDataReport.Create;
fOtchety_termo0:=TDataReport.Create;
fOtchety_termo8:=TDataReport.Create;
fOtchety_termo16:=TDataReport.Create;
fOtchety_termo24:=TDataReport.Create;
fOtchety_termo36:=TDataReport.Create;
fOtchety_termo48:=TDataReport.Create;
fOtchety_termo72:=TDataReport.Create;
fOtchety_Koeff:=TDataReport.Create;
fOtchety_HtmKoeff:=TDataReport.Create;
fOtchety_Test:=TDataReport.Create;
end;
destructor TSQLRecordDevice.Destroy;
begin
fOtchety_nastrk.Free;
fOtchety_termo0.Free;
fOtchety_termo8.Free;
fOtchety_termo16.Free;
fOtchety_termo24.Free;
fOtchety_termo36.Free;
fOtchety_termo48.Free;
fOtchety_termo72.Free;
fOtchety_Koeff.Free;
fOtchety_HtmKoeff.Free;
fOtchety_Test.Free;
inherited;
end;
{ TDataOtchet }
procedure TDataReport.Clear;
begin
fHref:='';
fReport:='';
fResult:='';
fDateTest:='';
end;
{------------------------------------------------------------------------------
Create Record
------------------------------------------------------------------------------}
procedure CreateRecordDB(sNomerZakaza,stipoisp:RawUTF8;var iId_BD:TID);
var
RecordOrder: TSQLRecordZakaz;RecordTip: TSQLRecordTip; RecordDevice: TSQLRecordDevice;
iId_Order,iId_Tip: integer;
s:RawUTF8;
begin
s:=Database.OneFieldValue(Model['Zakaz'],'ID',Format('NOMERZAKAZA=''%s''',[sNomerZakaza]));
if not TryStrToInt(s,iId_Order) then
begin
RecordOrder:=TSQLRecordZakaz.Create;
try
RecordOrder.NomerZakaza:=sNomerZakaza;
RecordOrder.Vypolnen:=False;
iId_Order := Database.Add(RecordOrder,true);
finally
RecordOrder.Free;
end;
end else
begin
RecordOrder:=TSQLRecordZakaz.Create(DataBase,iId_Order);
RecordOrder.Vypolnen:=False;
DataBase.Update(RecordOrder);
end;
s:=Database.OneFieldValue(Model['Tip'],'ID',Format('NAMETIPOISP=''%s''',[stipoisp]));
if not TryStrToInt(s,iId_Tip) then
begin
RecordTip:=TSQLRecordTip.Create;
try
RecordTip.NameTipoisp:=stipoisp;
iId_Tip := Database.Add(RecordTip,true);
finally
RecordTip.Free;
end;
end;
RecordDevice:=TSQLRecordDevice.Create;
try
RecordDevice.IDZakaza:=TSQLRecordZakaz(iId_Order);
RecordDevice.IDTipoisp:=TSQLRecordTip(iId_Tip);
iId_BD := Database.Add(RecordDevice,true);
finally
RecordDevice.Free;
end;
end;
{------------------------------------------------------------------------------
Update Record
------------------------------------------------------------------------------}
procedure LoadProtocolToDB(iId_BD:TID;aHTMLString: RawUTF8; isProverkaSuccess: Boolean; dt: TDateTermoprAll);
var
rec:TSQLRecordDevice;
procedure AssignToOtchet(ADataReport:TDataReport);
begin
ADataReport.Href:='';// StringToUTF8(dt.sHref);
ADataReport.Report:=aHTMLString;
ADataReport.Result:=ifthen(isProverkaSuccess,'Success','Errors');
ADataReport.DateTest:=DateTimeToStr(Now);
end;
begin
if (iId_BD=0) or (aHTMLString='') then Exit;
rec:=TSQLRecordDevice.Create(Database,iId_BD);
try
case dt of
Nastrk: AssignToOtchet(Rec.Otchety_nastrk);
Termo0: AssignToOtchet(Rec.Otchety_termo0);
Termo8: AssignToOtchet(Rec.Otchety_termo8);
Termo16: AssignToOtchet(Rec.Otchety_termo16);
Termo24: AssignToOtchet(Rec.Otchety_termo24);
Termo36: AssignToOtchet(Rec.Otchety_termo36);
Termo48: AssignToOtchet(Rec.Otchety_termo48);
Termo72: AssignToOtchet(Rec.Otchety_termo72);
Test: AssignToOtchet(Rec.Otchety_Test);
KoeffDSP: AssignToOtchet(Rec.Otchety_Koeff);
KoeffHTML: AssignToOtchet(Rec.Otchety_HtmKoeff);
end;
Database.Update(rec);
finally
Rec.free;
end;
end;
function CreateSampleModel: TSQLModel;
begin
result := TSQLModel.Create([TSQLRecordZakaz,TSQLRecordTip,TSQLRecordDevice]);
end;
begin
Model := CreateSampleModel;
try
Database := TSQLRestServerDB.Create(Model, ChangeFileExt(Application.ExeName,'.db'));
if not Assigned(Database) then raise Exception.Create('Error connect or create db');
try
TSQLRestServerDB(Database).CreateMissingTables(0);
TSQLRestServerDB(Database).NoAJAXJSON:=False;
CreateRecordDB('123','BE',iId_BD);
LoadProtocolToDB(iId_BD,'<html></html>',true,Termo0);
FileFromString(JSONReformat(Database.ExecuteJson([TSQLRecordDevice],'select * from Device')),'pServer.db.json');
write('Press [Enter] to close the server.');
Readln;
finally
Database.Free;
end;
finally
Model.Free;
end;
end.
Today tried to compile my example with Delphi XE2 and the same bad result
I took source from http://synopse.info/files/mORMotNightlyBuild.zip yesterday. I had to take in GitHub.
Today mORMotNightlyBuild.zip have been changed for actual version. I could to compile it.
But it doesn't help.
I saw in debug when execute inside function GetJSONValues(W: TJSONSerializer) adding colnames "Otchety_nastrk" immediately added rest colnames: Otchety_termo0... Otchety_Test. Is it ok?.
winXP, Delphi 2006
i can not compile
appear error : too many actual parameters in row Call.OutBody := rec.GetJSONValues(true,true,soSelect,nil,true);
before update all worked ok
I writed new data to field "Otchety_termo0" and when I did update database, data writed
But now, when I write field "Otchety_termo0" and update database then I see that data writed to other fields record and moreover its broken
for example: "Otchety_termo8":"{\"Href\":\"\",\"Report\":\"\",\"Result\":\"\",\"DateTest\":\"\"}cess\",\"DateTest\":\"14.09.2015 14:21:06\"}",
Hi all
After last update, I detected strange behavior on UPDATE operation
I write data to one field with name "Otchety_termo0", but in result, I see data in many fields of database.
{
"IDZakaza":1,
"IDTipoisp":1,
"SerNomer":"",
"Otchety_nastrk":"{\"Href\":\"\",\"Report\":\"\",\"Result\":\"\",\"DateTest\":\"\"}",
"Otchety_termo0":"{\"Href\":\"\",\"Report\":\"<html></html>\",\"Result\":\"Success\",\"DateTest\":\"14.09.2015 14:21:06\"}",
"Otchety_termo8":"{\"Href\":\"\",\"Report\":\"\",\"Result\":\"\",\"DateTest\":\"\"}cess\",\"DateTest\":\"14.09.2015 14:21:06\"}",
"Otchety_termo16":"{\"Href\":\"\",\"Report\":\"\",\"Result\":\"\",\"DateTest\":\"\"}cess\",\"DateTest\":\"14.09.2015 14:21:06\"}",
"Otchety_termo24":"{\"Href\":\"\",\"Report\":\"\",\"Result\":\"\",\"DateTest\":\"\"}cess\",\"DateTest\":\"14.09.2015 14:21:06\"}",
"Otchety_termo36":"{\"Href\":\"\",\"Report\":\"\",\"Result\":\"\",\"DateTest\":\"\"}cess\",\"DateTest\":\"14.09.2015 14:21:06\"}",
"Otchety_termo48":"{\"Href\":\"\",\"Report\":\"\",\"Result\":\"\",\"DateTest\":\"\"}cess\",\"DateTest\":\"14.09.2015 14:21:06\"}",
"Otchety_termo72":"{\"Href\":\"\",\"Report\":\"\",\"Result\":\"\",\"DateTest\":\"\"}cess\",\"DateTest\":\"14.09.2015 14:21:06\"}",
"Otchety_Koeff":"{\"Href\":\"\",\"Report\":\"\",\"Result\":\"\",\"DateTest\":\"\"}cess\",\"DateTest\":\"14.09.2015 14:21:06\"}",
"Otchety_HtmKoeff":"{\"Href\":\"\",\"Report\":\"\",\"Result\":\"\",\"DateTest\":\"\"}cess\",\"DateTest\":\"14.09.2015 14:21:06\"}",
"Otchety_Test":"{\"Href\":\"\",\"Report\":\"\",\"Result\":\"\",\"DateTest\":\"\"}cess\",\"DateTest\":\"14.09.2015 14:21:06\"}"
}
This is my TEST code model, server and client for repeat situation
MODEL
unit uModel;
interface
uses
Classes, SynCommons, mORMot, mORMotHttpServer;
type
TDateTermoprAll = (NoTest, Nastrk, Termo0, Termo8, Termo16, Termo24, Termo36, Termo48, Termo72, KoeffDSP, KoeffHTML, Test);
TDateTermopr = Nastrk..Test;
const
// Data name Blob field in DB
strDateTermopr : array[TDateTermopr] of ShortString = ('Otchety_nastrk', 'Otchety_termo0', 'Otchety_termo8',
'Otchety_termo16','Otchety_termo24','Otchety_termo36',
'Otchety_termo48','Otchety_termo72','Otchety_Koeff','Otchety_HtmKoeff','Otchety_Test');
type
/// here we declare the class containing the data
// - it just has to inherits from TSQLRecord, and the published
// properties will be used for the ORM (and all SQL creation)
// - the beginning of the class name must be 'TSQL' for proper table naming
// in client/server environnment
TDataReport = class(TPersistent)
private
fHref : RawUTF8;
fReport : RawUTF8;
fResult : RawUTF8;
fDateTest : RawUTF8;
public
procedure Clear;
published
property Href : RawUTF8 read fHref write fHref;
property Report : RawUTF8 read fReport write fReport;
property Result : RawUTF8 read fResult write fResult;
property DateTest : RawUTF8 read fDateTest write fDateTest;
end;
TSQLRecordZakaz = class(TSQLRecord)
private
fNomerZakaza : RawUTF8;
fZakazchik : RawUTF8;
fVypolnen : Boolean;
FTimeVypoln : TDateTime;
published
property NomerZakaza : RawUTF8 read fNomerZakaza write fNomerZakaza;
property Zakazchik : RawUTF8 read fZakazchik write fZakazchik;
property Vypolnen : Boolean read fVypolnen write fVypolnen;
property TimeVypoln : TDateTime read FTimeVypoln write FTimeVypoln;
end;
TSQLRecordTip = class(TSQLRecord)
private
fNameTipoisp : RawUTF8;
published
property NameTipoisp : RawUTF8 read fNameTipoisp write fNameTipoisp;
end;
TSQLRecordDevice = class(TSQLRecord)
private
fIDZakaza : TSQLRecordZakaz;
fIDTipoisp : TSQLRecordTip;
fSerNomer : RawUTF8;
fOtchety_nastrk : TDataReport;
fOtchety_termo0 : TDataReport;
fOtchety_termo8 : TDataReport;
fOtchety_termo16 : TDataReport;
fOtchety_termo24 : TDataReport;
fOtchety_termo36 : TDataReport;
fOtchety_termo48 : TDataReport;
fOtchety_termo72 : TDataReport;
fOtchety_Koeff : TDataReport;
fOtchety_HtmKoeff : TDataReport;
fOtchety_Test : TDataReport;
public
constructor Create; override;
destructor Destroy; override;
published
property IDZakaza : TSQLRecordZakaz read fIDZakaza write fIDZakaza;
property IDTipoisp : TSQLRecordTip read fIDTipoisp write fIDTipoisp;
property SerNomer : RawUTF8 read fSerNomer write fSerNomer;
property Otchety_nastrk : TDataReport read fOtchety_nastrk write fOtchety_nastrk;
property Otchety_termo0 : TDataReport read fOtchety_termo0 write fOtchety_termo0;
property Otchety_termo8 : TDataReport read fOtchety_termo8 write fOtchety_termo8;
property Otchety_termo16 : TDataReport read fOtchety_termo16 write fOtchety_termo16;
property Otchety_termo24 : TDataReport read fOtchety_termo24 write fOtchety_termo24;
property Otchety_termo36 : TDataReport read fOtchety_termo36 write fOtchety_termo36;
property Otchety_termo48 : TDataReport read fOtchety_termo48 write fOtchety_termo48;
property Otchety_termo72 : TDataReport read fOtchety_termo72 write fOtchety_termo72;
property Otchety_Koeff : TDataReport read fOtchety_Koeff write fOtchety_Koeff;
property Otchety_HtmKoeff : TDataReport read fOtchety_HtmKoeff write fOtchety_HtmKoeff;
property Otchety_Test : TDataReport read fOtchety_Test write fOtchety_Test;
end;
/// an easy way to create a database model for client and server
function CreateSampleModel: TSQLModel;
var Model:TSQLModel;
Database:TSQLRest;
Server: TSQLHttpServer;
implementation
function CreateSampleModel: TSQLModel;
begin
result := TSQLModel.Create([TSQLRecordZakaz,TSQLRecordTip,TSQLRecordDevice]);
end;
{ TSQLRecordDevice }
constructor TSQLRecordDevice.Create;
begin
inherited;
fOtchety_nastrk:=TDataReport.Create;
fOtchety_termo0:=TDataReport.Create;
fOtchety_termo8:=TDataReport.Create;
fOtchety_termo16:=TDataReport.Create;
fOtchety_termo24:=TDataReport.Create;
fOtchety_termo36:=TDataReport.Create;
fOtchety_termo48:=TDataReport.Create;
fOtchety_termo72:=TDataReport.Create;
fOtchety_Koeff:=TDataReport.Create;
fOtchety_HtmKoeff:=TDataReport.Create;
fOtchety_Test:=TDataReport.Create;
end;
destructor TSQLRecordDevice.Destroy;
begin
fOtchety_nastrk.Free;
fOtchety_termo0.Free;
fOtchety_termo8.Free;
fOtchety_termo16.Free;
fOtchety_termo24.Free;
fOtchety_termo36.Free;
fOtchety_termo48.Free;
fOtchety_termo72.Free;
fOtchety_Koeff.Free;
fOtchety_HtmKoeff.Free;
fOtchety_Test.Free;
inherited;
end;
{ TDataOtchet }
procedure TDataReport.Clear;
begin
fHref:='';
fReport:='';
fResult:='';
fDateTest:='';
end;
end.
SERVER
program pServer;
{$APPTYPE CONSOLE}
uses
SysUtils,
mORMot,
SynSQlite3,
DB,
SynDBVCL,
SynDBSQLite3,
SynDB,
SynSQlite3Static,
mORMotSQLite3,
mORMotHttpServer,
Classes,
Forms,
uModel in 'uModel.pas';
begin
Model := CreateSampleModel;
try
Database := TSQLRestServerDB.Create(Model, ChangeFileExt(Application.ExeName,'.db'));
if not Assigned(Database) then raise Exception.Create('Error connect or create db');
try
TSQLRestServerDB(Database).CreateMissingTables(0);
TSQLRestServerDB(Database).NoAJAXJSON:=False;
Server := TSQLHttpServer.Create('777',[TSQLRestServerDB(Database)],'+',{useHttpSocket}useHttpApiRegisteringURI,32,secNone,'report');
Server.AccessControlAllowOrigin := '*'; // allow cross-site AJAX queries
write('Press [Enter] to close the server.');
Readln;
finally
Database.Free;
end;
finally
Model.Free;
end;
end.
CLIENT
program pClient;
{$APPTYPE CONSOLE}
uses
SysUtils,
StrUtils,
SynCommons,
mORMot,
mORMotSQLite3,
mORMotHttpClient,
uModel;
procedure CreateRecordDB(sNomerZakaza,stipoisp:string;var iId_BD:TID);
var
RecordOrder: TSQLRecordZakaz;RecordTip: TSQLRecordTip; RecordDevice: TSQLRecordDevice;
iId_Order,iId_Tip: integer;
s:string;
begin
s:=Database.OneFieldValue(Model['Zakaz'],'ID',Format('NOMERZAKAZA=''%s''',[StringToUTF8(sNomerZakaza)]));
if not TryStrToInt(s,iId_Order) then
begin
RecordOrder:=TSQLRecordZakaz.Create;
try
RecordOrder.NomerZakaza:=StringToUTF8(sNomerZakaza);
RecordOrder.Vypolnen:=False;
iId_Order := Database.Add(RecordOrder,true);
finally
RecordOrder.Free;
end;
end else
begin
RecordOrder:=TSQLRecordZakaz.Create(DataBase,iId_Order);
RecordOrder.Vypolnen:=False;
DataBase.Update(RecordOrder);
end;
s:=Database.OneFieldValue(Model['Tip'],'ID',Format('NAMETIPOISP=''%s''',[StringToUTF8(stipoisp)]));
if not TryStrToInt(s,iId_Tip) then
begin
RecordTip:=TSQLRecordTip.Create;
try
RecordTip.NameTipoisp:=StringToUTF8(stipoisp);
iId_Tip := Database.Add(RecordTip,true);
finally
RecordTip.Free;
end;
end;
RecordDevice:=TSQLRecordDevice.Create;
try
RecordDevice.IDZakaza:=TSQLRecordZakaz(iId_Order);
RecordDevice.IDTipoisp:=TSQLRecordTip(iId_Tip);
iId_BD := Database.Add(RecordDevice,true);
finally
RecordDevice.Free;
end;
end;
procedure LoadProtocolToDB(iId_BD:TID;aHTMLString: string; isProverkaSuccess: Boolean; dt: TDateTermoprAll);
var
rec:TSQLRecordDevice;
procedure AssignToOtchet(ADataReport:TDataReport);
begin
ADataReport.Href:='';// StringToUTF8(dt.sHref);
ADataReport.Report:=aHTMLString;
ADataReport.Result:=ifthen(isProverkaSuccess,'Success','Errors');
ADataReport.DateTest:=DateTimeToStr(Now);
end;
begin
if (iId_BD=0) or (aHTMLString='') then Exit;
rec:=TSQLRecordDevice.Create(Database,iId_BD);
try
case dt of
Nastrk: AssignToOtchet(Rec.Otchety_nastrk);
Termo0: AssignToOtchet(Rec.Otchety_termo0);
Termo8: AssignToOtchet(Rec.Otchety_termo8);
Termo16: AssignToOtchet(Rec.Otchety_termo16);
Termo24: AssignToOtchet(Rec.Otchety_termo24);
Termo36: AssignToOtchet(Rec.Otchety_termo36);
Termo48: AssignToOtchet(Rec.Otchety_termo48);
Termo72: AssignToOtchet(Rec.Otchety_termo72);
Test: AssignToOtchet(Rec.Otchety_Test);
KoeffDSP: AssignToOtchet(Rec.Otchety_Koeff);
KoeffHTML: AssignToOtchet(Rec.Otchety_HtmKoeff);
end;
Database.Update(rec);
finally
Rec.free;
end;
end;
var iId_BD:TID;
begin
Model := CreateSampleModel;
try
Database := TSQLHttpClient.Create('localhost', '777',Model);
try
write('Press [Enter] to close the client.');
CreateRecordDB('123','BE',iId_BD);
LoadProtocolToDB(iId_BD,'<html></html>',true,Termo0);
Readln;
finally
Database.Free;
end;
finally
Model.Free;
end;
end.
i used TSynPersistent and now its all works, though ealier i used TComponent as parent class, but it didn't work.
Thank you.
It did not solve the problem. Then problem is that function Item := ClassInstanceCreate(ItemClass) doesn't call "create" method TLine object and therefore all of its properties equals nil.
I have registred classes in initialization section
TJSONSerializer.RegisterClassForJSON([TLine, TDevice]);
this is my file
{
"ClassName":"TConfig",
"ListLines":
[{
"ClassName":"TLine",
"NameLine": "MyLine",
"ComPort": "COM1",
"IniFile": "",
"ListDevices":
[{
"ClassName":"TDevice",
"Name": "MyDevice",
"Speed": "9600",
"Adress": 1
}
]
}
]
}
there is field "classname", but it did not help.
The option "woStoreClassName" adds only property "TConfig" to the root object. Other options were earlier.
I tried save instance of object with ObjectToJSON. And it's really ok. But a want to load my file, i get message "not valid". In debug i found, when parser read nested TObjectList = TDevice, it can not detect its.
Try this code.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, SynCommons, mORMot, Contnrs, StdCtrls;
type
TSpeed = (s9600,s38400);
TLine = class;
TConfig = class;
TDevice = class(TPersistent)
strict private
fParentLine : TLine;
fName : string;
fSpeed : TSpeed;
fAdress : Integer;
public
constructor Create(ALine:TLine;AName:string;Adress:Integer);
property ParentLine : TLine read fParentLine write fParentLine;
published
property Name : string read fName write fName;
property Speed : TSpeed read fSpeed write fSpeed;
property Adress : Integer read fAdress write fAdress;
end;
TLine = class(TPersistent)
strict private
fParentConfig : TConfig;
fListDevices : TObjectList;
fName : string;
fComPort : string;
fIniFile : string;
public
constructor Create(AConfig:TConfig;ANameLine,AComPort:string);
destructor Destroy; override;
function AddDevice(AName:string):TDevice;
property ParentConfig : TConfig read fParentConfig write fParentConfig;
published
property NameLine : string read fName write fName;
property ComPort : string read fComPort write fComPort;
property IniFile : string read fIniFile write fIniFile;
property ListDevices : TObjectList read fListDevices write fListDevices;
end;
TConfig = class(TPersistent)
private
fListLines : TObjectList;
public
constructor Create;
destructor Destroy; override;
function AddLine(AName,AComPort:string):TLine;
procedure SaveConfig(AFileName:string);
procedure LoadConfig(AFileName:string);
published
property ListLines : TObjectList read fListLines write fListLines;
end;
TForm1 = class(TForm)
btnSave: TButton;
btnLoad: TButton;
btnCreate: TButton;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure btnCreateClick(Sender: TObject);
procedure btnLoadClick(Sender: TObject);
procedure btnSaveClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
Config:TConfig;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TLine }
function TLine.AddDevice(AName: string): TDevice;
begin
Result:=TDevice.Create(Self, AName, 1);
fListDevices.Add(Result);
end;
constructor TLine.Create(AConfig:TConfig;ANameLine,AComPort:string);
begin
fParentConfig:=AConfig;
fName:=ANameLine;
fComPort:=AComPort;
fListDevices:=TObjectList.Create;
end;
destructor TLine.Destroy;
begin
fListDevices.Free;
inherited;
end;
{ TConfig }
function TConfig.AddLine(AName,AComPort: string):TLine;
begin
Result:=TLine.Create(Self,AName,AComPort);
fListLines.Add(Result);
end;
constructor TConfig.Create;
begin
inherited;
fListLines:=TObjectList.Create;
end;
destructor TConfig.Destroy;
begin
fListLines.Free;
inherited;
end;
procedure TConfig.LoadConfig(AFileName: string);
var s:RawUTF8;
isValid: Boolean;
begin
s:=StringToUTF8(StringFromFile(AFileName));
JSONToObject(Self,@s[1],isValid);
if not isValid then ShowMessage('not valid');
end;
procedure TConfig.SaveConfig(AFileName: string);
var
s: string;
begin
s:=UTF8ToString(ObjectToJSON(Self,[woDontStoreDefault,woHumanReadable]));
FileFromString(s,AFileName);
end;
procedure TForm1.btnCreateClick(Sender: TObject);
var Line:TLine; Dev:TDevice;
begin
Line:=Config.AddLine('MyLine','COM1');
Line.AddDevice('MyDevice');
end;
procedure TForm1.btnLoadClick(Sender: TObject);
begin
Config.LoadConfig('test.cnfg');
end;
procedure TForm1.btnSaveClick(Sender: TObject);
begin
Config.SaveConfig('test.cnfg');
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Config:=TConfig.Create;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
Config.Free;
end;
{ TDevice }
constructor TDevice.Create(ALine: TLine; AName: string;Adress:Integer);
begin
fParentLine:=ALine;
fName:=AName;
fAdress:=Adress;
end;
initialization
TJSONSerializer.RegisterClassForJSON([TLine, TDevice]);
finalization
Code from SynCommons.pas
procedure TimeToIso8601PChar(P: PUTF8Char; Expanded: boolean; H,M,S: cardinal;
FirstChar: AnsiChar = 'T'); overload;
// we use Thhmmss format //---------------------> but not THH:MM:SS.SSS
begin
P^ := FirstChar;
inc(P);
pWord(P)^ := TwoDigitLookupW[h];
inc(P,2);
if Expanded then begin
P^ := ':';
inc(P);
end;
pWord(P)^ := TwoDigitLookupW[M];
inc(P,2);
if Expanded then begin
P^ := ':';
inc(P);
end;
pWord(P)^ := TwoDigitLookupW[s];
// -------------->here no code with milliseconds
end;
//-------------->here convert date - it's ok
procedure DateToIso8601PChar(Date: TDateTime; P: PUTF8Char; Expanded: boolean); overload;
// we use YYYYMMDD date format
var Y,M,D: word;
begin
DecodeDate(Date,Y,M,D);
DateToIso8601PChar(P,Expanded,Y,M,D);
end;
/// convert a date into 'YYYY-MM-DD' date format
function DateToIso8601Text(Date: TDateTime): RawUTF8;
begin
SetLength(Result,10);
DateToIso8601PChar(Date,pointer(Result),True);
end;
procedure TimeToIso8601PChar(Time: TDateTime; P: PUTF8Char; Expanded: boolean;
FirstChar: AnsiChar = 'T'); overload;
// we use Thhmmss format
var H,M,S,MS: word;
begin
DecodeTime(Time,H,M,S,MS); //-------------->here we have MS, but don't use it after
TimeToIso8601PChar(P,Expanded,H,M,S,FirstChar);
end;
function DateTimeToIso8601(D: TDateTime; Expanded: boolean;
FirstChar: AnsiChar='T'): RawUTF8;
// we use YYYYMMDDThhmmss format
var tmp: array[0..31] of AnsiChar;
begin
if Expanded then begin //-------------->here Expanded version TDatetime
DateToIso8601PChar(D,tmp,true);
TimeToIso8601PChar(D,@tmp[10],true,FirstChar);
SetString(result,PAnsiChar(@tmp),19);
end else begin
DateToIso8601PChar(D,tmp,false);
TimeToIso8601PChar(D,@tmp[8],false,FirstChar);
SetString(result,PAnsiChar(@tmp),15);
end;
end;
How I can store milliseconds TDateTime in any kind datetime property?
thank you for quick answer
Good day. I use the following code.
TSQLRecordOtchet = class(TSQLRecord)
private
fOtchety_nastrk : Variant;
public
constructor Create; override;
published
property Otchety_nastrk : Variant read fOtchety_nastrk write fOtchety_nastrk;
constructor TSQLRecordOtchet.Create;
begin
inherited;
fOtchety_nastrk:=TDocVariant.New;
end;
and when I created a record with
rec:=TSQLRecordOtchet.Create, then I get rec.Otchety_nastrk = 'null', but
when I created a record already with
rec:=TSQLRecordOtchet.Create(DataBase,ID), then I get rec.Otchety_nastrk = null, i.e. without quotes.
And if I want assign rec.Otchety_nastrk.Href:='http://...' I get exception "Invalid variant type 1 invoke"
In then first case, after create rec.Otchety_nastrk.Href:='http://...' it's ok. {Href:'http://...'}
Pages: 1