#1 2015-10-25 17:52:30

AOG
Member
Registered: 2014-02-24
Posts: 490

Problem with T*ObjArray

Hello,

I do encounter a strange problem, and do not know what to think of it.
System: latest mORMot, Win64, FPC32


I have an email record:

TEmail = type RawUTF8;
TEmailAddress = class(TSynPersistent)
protected
  fEmail: TEmail;
public
  constructor Create(aEmail:string); reintroduce;
published
  property Email: TEmail read fEmail write fEmail;
end;
TEmailAddressObjArray = array of TEmailAddress;

and a person

TName = type RawUTF8;
TSQLPerson = class(TSQLRecord)
private
  fName: TName;
public
  fEmail: TEmailAddressObjArray;
published
  property Name: TName read fName write fName;
  property Email: TEmailAddressObjArray read fEmail write fEmail;
end;

The database is filled with TSQLPerson data (10 records). The data looks good with an external (SQLite3) viewer. Nice JSON arrays in the Email field.

The data is read back:

fConnectionOk:=DataRecord.FillPrepare(RestClient);
if ConnectionOk then
begin
  SQLTable:=DataRecord.FillTable;
  DataRecord.FillRow(SQLTable.RowFromID(4));
  writeln(InttoStr(4)+': '+TSQLPerson(DataRecord).Email[0].Email);
  DataRecord.FillRow(SQLTable.RowFromID(5));
  writeln(InttoStr(5)+': '+TSQLPerson(DataRecord).Email[0].Email);
  DataRecord.FillRow(SQLTable.RowFromID(6));
  writeln(InttoStr(6)+': '+TSQLPerson(DataRecord).Email[0].Email);
  DataRecord.FillRow(SQLTable.RowFromID(5));
  write(InttoStr(5)+': '+TSQLPerson(DataRecord).Email[0].Email);
  DataRecord.FillRow(SQLTable.RowFromID(4));
  writeln(InttoStr(4)+': '+TSQLPerson(DataRecord).Email[0].Email);
end;

The result:
4: dummy4@dummy.com
5: dummy5@dummy.com
6: dummy6@dummy.com
5: dummy6@dummy.com
4: dummy6@dummy.com

As you can see: the last two lines are wrong.
And I do not know why ?!

Offline

#2 2015-10-25 20:53:02

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,236
Website

Re: Problem with T*ObjArray

Problem has nothing to do with T*ObjArray, IMHO...

Offline

#3 2015-10-26 06:48:33

AOG
Member
Registered: 2014-02-24
Posts: 490

Re: Problem with T*ObjArray

I just did the same test with Delphi XE8 for Win32.
Exactly the same result.

Obviously, I do not understand the use of T*ObjArray fully.

The server:
aServer:=TSQLRestServerDB.Create(aModel,'data.db3',False);
aServer.DB.Synchronous := smNormal;
aServer.DB.LockingMode := lmExclusive;
aServer.CreateMissingTables;

The client:
aRestClient := TSQLRestClientDB.Create(aServer AS TSQLRestServerDB);

Result:
4: dummy4@dummy.com
5: dummy5@dummy.com
6: dummy6@dummy.com
5: dummy6@dummy.com
4: dummy6@dummy.com

Offline

#4 2015-10-26 07:46:07

AOG
Member
Registered: 2014-02-24
Posts: 490

Re: Problem with T*ObjArray

For anybody interested: a program based on Sample 2 showing this behavior can be found here:

https://drive.google.com/folderview?id= … sp=sharing

Offline

#5 2015-10-26 12:50:14

warleyalex
Member
From: Sete Lagoas-MG, Brasil
Registered: 2013-01-20
Posts: 250

Re: Problem with T*ObjArray

I think you have to use another approach. This worked as expected for me.

procedure TForm1.Button1Click(Sender: TObject);
begin
  FindButtonClick(StrToInt(Edit1.text),StrToInt(Edit2.text),self);
end;

procedure TForm1.FindButtonClick(myId, aID: integer; Sender: TObject);
var
  Rec: TSQLSampleRecord;
  fConnectionOk:boolean;
  SQLTable:TSQLTable;
  CurrentRow: integer;

begin
  Rec := TSQLSampleRecord.Create;
  fConnectionOk:=Rec.FillPrepare(Database);
  try
    SQLTable:=Rec.FillTable;
    CurrentRow := SQLTable.RowFromID(aID);
    Rec.FillRow(CurrentRow);
    QuestionMemo.Lines.Append(InttoStr(myID)+': '+Rec.Email[0].Email);
  finally
    Rec.Free;
  end;
end;

Last edited by warleyalex (2015-10-26 16:01:18)

Offline

#6 2015-11-05 08:35:55

AOG
Member
Registered: 2014-02-24
Posts: 490

Re: Problem with T*ObjArray

@warleyalex
Thanks for your effort.
But your example gets a new table for every request for a new ID.
I need to use the existing table for a new ID.

@ab

1)
Could you comment on this behavior.
(see included example in previous post)
And, when doing something wrong, could you please enlighten me !

2)
While using mORMot, I did encounter a case sensitivity problem.
Would it be possible to do something like this (inside mORMot.pas):

{$ifndef CASE}
  ' TEXT COLLATE NOCASE, ',
  ' TEXT COLLATE SYSTEMNOCASE, ',
{$else}
  ' TEXT, ',
  ' TEXT, ',
{$endif}

3)
Would you mind changing the name of SynDBZEOS.pas into SynDBZeos.pas (lowercase last thee characters).
Otherwise, my app will not compile on Mac.

Thanks.

Offline

#7 2015-11-05 16:41:28

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,236
Website

Re: Problem with T*ObjArray

1) Is SQLTable.RowFromID() working, or is it a problem of SQLTable.RowFromID().

2) You could use  SetCustomCollationForAll() at runtime, when creating the model.
See http://synopse.info/files/html/api-1.18 … C_8CF7118A

3) Done for fossil and git repositories.

Offline

#8 2015-11-10 11:12:48

AOG
Member
Registered: 2014-02-24
Posts: 490

Re: Problem with T*ObjArray

1)
This (still the same simple sample 2 code with email object array):

Rec := TSQLSampleRecord.Create;
fConnectionOk:=Rec.FillPrepare(Database);
SQLTable:=Rec.FillTable;
Rec.FillRow(4);
QuestionMemo.Lines.Append(InttoStr(4)+': '+Rec.Email[0].Email);
Rec.FillRow(5);
QuestionMemo.Lines.Append(InttoStr(5)+': '+Rec.Email[0].Email);
Rec.FillRow(6);
QuestionMemo.Lines.Append(InttoStr(6)+': '+Rec.Email[0].Email);
Rec.FillRow(5);
QuestionMemo.Lines.Append(InttoStr(5)+': '+Rec.Email[0].Email);
Rec.FillRow(4);
QuestionMemo.Lines.Append(InttoStr(4)+': '+Rec.Email[0].Email);

also results into

4: dummy4@dummy.com
5: dummy5@dummy.com
6: dummy6@dummy.com
5: dummy6@dummy.com
4: dummy6@dummy.com

So there is no difference in calling rows directly or via RowFromID.
Still the same behavior !

2) Thanks !
3) Thanks !

Edit 3):
SynDBZeos still has a reference to the Windows unit, that is, AFAIK, not needed.

Last edited by AOG (2015-11-10 11:59:26)

Offline

#9 2015-11-10 18:08:40

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,236
Website

Re: Problem with T*ObjArray

I tried to reproduce the issue.
See http://synopse.info/fossil/info/1d770e9d23a0e2b
No problem reported at this level....

But I identified a potential issue in TSQLPropInfoRTTIDynArray.SetValue when the same JSON input buffer is re-used.
So it should be fixed by http://synopse.info/fossil/info/66d9745378

Offline

#10 2015-11-10 18:36:23

AOG
Member
Registered: 2014-02-24
Posts: 490

Re: Problem with T*ObjArray

Your new mORMot.pas solves all reported problems !
The old mORMot.pas still shows the reported effect !
So, thanks very much !!

Offline

Board footer

Powered by FluxBB