You are not logged in.
Pages: 1
I found a solution.
You need to create an instance of TDTOLevel1 in TDTOLevel2 class:
TDTOLevel2.Create constructor (Collection: TCollection);
begin
inherited;
Flevel1_inherited: TDTOLevel1.Create(nil);
end;
Hello!
I'm having trouble to convert Json for object using the JsonToObject function.
I have the following structure of DTOs:
TDTOBasePersistent = class(TPersistentWithCustomCreate)
private
Fbase_per: RawUtf8;
published
property base_per: RawUtf8 read Fbase_per write Fbase_per;
end;
TDTOBaseCollectionItem = class(TCollectionItem)
private
Fbase_coll: RawUtf8;
published
property base_coll: RawUtf8 read Fbase_coll write Fbase_coll;
end;
TDTOLevel1 = class(TDTOBasePersistent)
private
Flevel1: RawUtf8;
published
property level1: RawUtf8 read Flevel1 write Flevel1;
end;
TDTOLevel2 = class(TDTOBaseCollectionItem)
private
Flevel2: RawUtf8;
Flevel1_inherited: TDTOLevel1;
published
property level2: RawUtf8 read Flevel2 write Flevel2;
property level1_inherited: TDTOLevel1 read Flevel1_inherited write Flevel1_inherited;
end;
TDTOMyList = class(TCollection)
private
function Add: TDTOLevel2;
public
function GetItem(Index: Integer): TDTOLevel2;
property Item[Index: Integer]: TDTOLevel2 read GetItem;
end;
Note, I have a collection (TDTOMyList) of TDTOLevel2.
TDTOLevel2 an inheritance of TDTOBaseCollectionItem and has an attribute (level1_inherited) which is a TDTOLevel1 object.
TDTOLevel1 has inherited of TDTOBasePersistent.
When I serializo my object in JSON everything goes perfectly:
var
oLevel2: TDTOLevel2;
oLevel1: TDTOLevel1;
begin
oList := TDTOMyList.Create(TDTOLevel2);
try
// Create level 1
oLevel1 := TDTOLevel1.Create;
oLevel1.level1 := 'Level 1';
oLevel1.base_per := 'Base Per';
// Add DTO Level 2 in List
oLevel2 := oList.Add;
oLevel2.level2 := '1- Level 2';
oLevel2.Fbase_coll := '1- Base Coll';
oLevel2.level1_inherited := oLevel1;
oLevel2 := oList.Add;
oLevel2.level2 := '2- Level 2';
oLevel2.Fbase_coll := '2- Base Coll';
oLevel2.level1_inherited := oLevel1;
Memo1.Lines.Add(ObjectToJSON(oList));
finally
FreeAndNil(oList);
end;
But when I try to turn this JSON Object I have problems:
var
isValid: Boolean;
sJson: RawByteString;
begin
sJson := Memo1.Lines.Text;
oList := TDTOMyList.Create(TDTOLevel2);
try
JSONToObject(oList, @sJson[1], isValid);
if (not(isValid)) then
raise Exception.Create('Error into JSONToObject');
ShowMessage('JSON is valid');
finally
FreeAndNil(oList);
end;
I'm debug the unit mormot.pas (function JSONToObject) and realized that the problem occurs when you try to convert the JSON for the object "level1_inherited".
This is my string JSON:
[
{
"level2":"1- Level 2",
"level1_inherited":{
"level1":"Level 1",
"base_per":"Base Per"
},
"base_coll":"1- Base Coll"
},
{
"level2":"2- Level 2",
"level1_inherited":{
"level1":"Level 1",
"base_per":"Base Per"
},
"base_coll":"2- Base Coll"
}
]
Can you help me with this problem?
Client mORMot consuming rest server Java? It's possible?
How do requests from mORMot client to server java ? (using Rest)
Help me start with an example?
Yes, everything you said makes sense now .....
I tested using a query modified and log has been updated
oClientSrv.DB.Execute ('delete from t where 1 = 1');
OP: 18 -> Insert zDb: main zTBL: t iRowID: 1 --> insert first line
OP: 18 -> Insert zDb: main zTBL: t iRowID: 2 --> insert second line
OP: 23 -> Update zDb: main zTBL: t iRowID: 1 --> update first line with ID=1 set to 3
OP: 23 -> Update zDb: main zTBL: t iRowID: 2 --> update second line with ID=2 set to 3
OP: 9 -> Delete zDb: main zTBL: t iRowID: 1 --> delete first line
OP: 9 -> Delete zDb: main zTBL: t iRowID: 2 --> delete second line
Thanks...
Hi ab!
I've been researching a bit on the sqlite3.update_hook but I do not understand it.
I have the following code:
begin
sqlite3.update_hook(oServer.DB.DB, Test, nil);
oClientSrv.DB.Execute('begin transaction');
try
oClientSrv.DB.Execute('create table t(a)');
//Log: line 1
oClientSrv.DB.Execute('insert into t values(1)');
//Log: line 2
oClientSrv.DB.Execute('insert into t values(2)');
//Log: line 3
oClientSrv.DB.Execute('update t set a = 3');
//Log: line 4
oClientSrv.DB.Execute('delete from t');
oClientSrv.DB.Execute('drop table t');
finally
oClientSrv.DB.Execute('rollback');
end;
end;
That's my hook:
procedure Test(pUpdateArg: Pointer; op: Integer; const zDb, zTbl: PUTF8Char; iRowID: Int64); {$IFNDEF SQLITE3_FASTCALL}cdecl; {$ENDIF}
var
Operation: String;
begin
case op of
sqlite_insert:
Operation := ' Insert';
sqlite_delete:
Operation := ' Delete';
sqlite_update:
Operation := ' Update';
end;
ShowMessage('OP: ' + IntToStr(op) + ' -> ' + Operation + ' zDb: ' + zDb + ' zTBL: ' + zTbl + ' iRowID: ' + IntToStr(iRowID));
end;
Running my example I have this result:
OP: 18 -> Insert zDb: main zTBL: t iRowID: 1
OP: 18 -> Insert zDb: main zTBL: t iRowID: 2
OP: 23 -> Update zDb: main zTBL: t iRowID: 1
OP: 23 -> Update zDb: main zTBL: t iRowID: 2
But I expected something like:
OP: 18 -> Insert zDb: main zTBL: t iRowID: 1
OP: 18 -> Insert zDb: main zTBL: t iRowID: 2
OP: 23 -> Update zDb: main zTBL: t iRowID: 1
OP: 23 -> Update zDb: main zTBL: t iRowID: 2
OP: 9 -> Delete zDb: main zTBL: t iRowID: ?? (two lines for deleting)
Is there something wrong?
How can I capture the pUpdateArg parameter that is a pointer?
Thanks!
Hi ab!
Do you have any idea how (and when) do this? I saw that SQLite has some features of trace http://www.sqlite.org/c3ref/profile.html
Can we use it?
I'm thinking of using TSQLLog to log the queries executed in the database and have something like an incremental backup of the changes in the base, since SQLite does not provide incremental backup tools.
Use something like for capturing
TSQLLog.Family.Level := [sllSQL];
And with the generated log file using regular expressions, leaving only SQL statements:
SELECT name FROM sqlite_master WHERE type = 'table' AND name NOT LIKE '% sqlite_';
INSERT INTO History (TableName, ExportStatus, CreatedAt, LastChange) VALUES (: ('Items'),: (0):,: (135,163,611,293),: (135,163,611,293) :);
select max (CreatedAt) the CreatedAt from History where TableName = 'Items' and Status = 0;
.....
That would be insurance or I'm too stupid? What better way to get a SQLite incremental backup?
You can create another level of log that displays only SQL statements (Delete, Insert and Updates)?
I have more problems, now with TSQLRestServerDB.BackupGZ(), we executed four backups:
- Database with 1,05 GB -> Generate Backup file with 106 MB - Is OK
- Database with 2,77 GB -> Generate Backup file with 273 MB - Is OK
- Database with 3,95 GB -> Generate Backup file with 388 MB - Is OK
- Database with 5,13 GB -> Generate Backup file with 502 MB - Is OK
Now the restoration using TSQLRestServerDB.RestoreGZ():
- Backup file with 106 MB -> Generate database file with 1,05 GB - Is OK
- Backup file with 273 MB -> NOT GENERATE DATABASE (not restored)
- Backup file with 388 MB -> NOT GENERATE DATABASE (not restored)
- Backup file with 502 MB -> NOT GENERATE DATABASE (not restored)
If I'm debugging the application I get the following notification:
EAssertionFailed with message ‘Assertion failure (d:\mORMot\lib\SynZip.pas, line 1122)’
If I run the demo application (execute .exe) the exception is not presented (reported), but the backup is not restored.
Do you have any suggestions?
Thanks!
Hi!
I'm testing the backup and restore available in TSQLRestServerDB class and am having some problems, I wonder if I'm using the correct form!
Problem: My support is not restored, this code causes the restoration is canceled:
if (Self=nil) or (DB=nil) or not IdemPChar(pointer(ContentToRestore),'SQLITE FORMAT 3') then
exit; // invalid restore contente
In unit mORMotSQLite3
I use this code to execute the backup:
procedure TForm2.Button6Click(Sender: TObject);
var
sBackupName: String;
oFileBackup: TStream;
begin
sBackupName := '.\database\'+FormatDateTime('yyyymmddHHmmsszzz', Now)+'_' + ExtractFileName(oServer.DB.FileName) + '.bkp';
oFileBackup := TFileStream.Create(sBackupName, fmCreate);
if (oServer.Backup(oFileBackup)) then
Memo1.Lines.Add('Backup: ' + oServer.DB.FileName + ' -> ' + sBackupName);
oFileBackup.Free;
end;
And this is the code that execute the restore:
procedure TForm2.Button9Click(Sender: TObject);
begin
// EdtBackup contains the path to the backup file
if (oServer.Restore(EdtBackup.Text)) then
Memo1.Lines.Add('Restore: ' + EdtBackup.Text + ' -> ' + oServer.DB.FileName);
end;
What am I doing wrong?
My database has 110MB...
Thanks...
Pages: 1