You are not logged in.
Thank you for your time !
Now, it seems to me that TSynLog.Enter; and ILog := TSynLog.Enter; gives line number, but ILog := TSynLog.Enter(self,'FormCreate'); does not. Could you help to comment ... ![]()
Thank you for your knowledgeable comments on TSQLLog and TSynLog !
About the line number, please see my previous post with correct information ... ![]()
Oh ! Thank you very much for your help !
It seems that using TSQLLog from mORMot.pas instead of TSynLog from SynCommons.pas gives line number !
I wonder is this by design ? Is TSynLog not to be used if one wants line numbers ?
Sorry for the misinformation !
TSynLog.Enter; gives the line number.
procedure TForm1.FormCreate(Sender: TObject);
var
ILog: ISynLog;
begin
with TSynLog.Family do
begin
Level := LOG_VERBOSE;
end;
TSynLog.Enter;ILog := TSynLog.Enter(self,'FormCreate'); does not give the line number.
procedure TForm1.FormCreate(Sender: TObject);
var
ILog: ISynLog;
begin
with TSynLog.Family do
begin
Level := LOG_VERBOSE;
end;
ILog := TSynLog.Enter(self,'FormCreate');I wonder if this is by design ?
Furthermore, could you help to comment about TSQLLog and TSynLog (for example, best practices) ? ![]()
Currently there is only procedure type AnyAnsiToUTF8.
Could you also add function type AnyAnsiToUTF8 besides the procedure type ?
The reason is to make it easier to transform AnsiString into RawUTF8 in unicode Delphi. ![]()
Thank you for your help! Enable "stack frames" under "Compiler" for D7 does not help. Furthermore, "Stack frames" under "Compiler" for DXE is already enabled.
Could you help to comment ?
Source code
unit Unit1;
interface
uses
SynCommons,
Windows, Messages, SysUtils, Variants, Classes, Graphics,
Controls, Forms, Dialogs;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var
ILog: ISynLog;
sl: TStringList;
begin
with TSynLog.Family do
begin
Level := LOG_VERBOSE;
PerThreadLog := ptIdentifiedInOnFile;
RotateFileCount := 5;
RotateFileSizeKB := 20*1024; // rotate by 20 MB logs
end;
ILog := TSynLog.Enter(self,'FormCreate');
// 1
// sl.Add(''); // <--- GPF
end;
end.Problem description
Without the "GPF" line, the log is as below. Note the line number for FormCreate is not shown. On Page 105 of latest SAD 1.18, the line number for TestLog is shown.
20140512 14502252 + TForm1(00762674).FormCreate
20140512 14502252 - 00.000.001With the "GPF" line, the log is as below. Note the line number for where the exception occurs is not shown.
20140512 15083546 + TForm1(00762674).FormCreate
20140512 15083546 EXCOS EAccessViolation (C0000005) at stack trace API 0002D204 SynCommons.SynRtlUnwind (30796) 00002F6C System.@HandleAnyException (9574) 00058EFF Forms.TCustomForm.DoCreate (2648) 00058BDF Forms.TCustomForm.AfterConstruction (2576) 0006029C Forms.TApplication.CreateForm (6947) 00061D00 VCL (13)
20140512 15083546 - 00.000.165Settings for Delphi 7 and Delphi XE.
D7 Compiler 
D7 Linker 
DXE Compiler 
DXE Linker 
Two IDEs are used Delphi 7 (CrossKylix) and Delphi XE. (Non-visual code is using D7 syntax but edited with DXE.) ![]()
Thank you for your comments very much !
CrossKylix is a good idea: (1) CrossKylix is convenient (2) From the FPC mail list archives, it seems that CrossKylix gives better performance and compatibility while FPC gives more targets. (3) That Delphi 7 is one of your favorite IDEs probably means the Linux/CrossKylix part will be in good sync with the Delphi part.
FPC may become useful when CrossKylix fails mainstream Linux distributions. CodeTyphon, bare Lazarus or even CrossFPC are all good choices.
That will be my pleasure! Furthermore, once the linux (Kylix/FPC) version is ready, the FPC gurus (for example, Graeme Geldenhuys who contributes to tiOPF and fpGUI, which might share equally good concepts with your great framework) may also start to use it and like it. Involvements from these experts should be be helpful and important.
The HTTP/IOCP part is really beyond me.
Nonetheless, could you help to comment specifically about what one could do to help to make SynCommons compilable under Linux ? Thus the goodies inside the SynCommons (TSynLog and/or TMemoryMapText) can be used under Linux...
Thanks for your comments. I have been reading your SAD document but have no clue.
Do you mean it is possible to model this "classroom-class" relationship using sharding ?
If you think this is an improper question for you, please just say so . ![]()
Sorry for this newbie question !
The sharding facilitated by mORMot sounds very interesting ! I want to learn this practice with a "Classroom - class" relationship:
"Classroom" :
(1) "Classroom" instances, which will be available for a certain period (e.g., half a day), will be announced.
(2) Each "Classroom" can accommodate one "Class" at a given time.
(3) Once "Classroom" is free from a previous "Class", it may accommodate another "Class".
"Class"
(1) "Class" instances, which will need to be taught at a given time, will be announced.
(2) Each "Class" will be taught in one "Classroom" at a given time.
With multiple-table-paradigm, a new "Assignment" table can help to model this relationship.Right now I don't have any idea how to model this relationship using sharding. Could you help to give me some suggestions ?
If it is not possible to use sharding, could you help to comment how to identify whether sharding fits a relationship in practice ?
Many thanks for your time and comments !
Great work ! ![]()
Indeed much cleaner design !
Thank you for your helpful comments very much ! This should work !
Thank you for your comment !
If the internal-mode SQLite is used (i.e. TSQLRestServerDB), can RollBack affect all three (Source, Dest, Pivot) tables ? ![]()
Furthermore, could you help to comment whether these three are equivalent when all three tables are being updated ? TransactionBegin (TSQLSource), TransactionBegin (TSQLDest), TransactionBegin (TSQLDestPivot) ? ![]()
Thank you for your comments ! I wonder which table to pass into TransactionBegin when multiple tables (Source,Dest,Pivot) are to be updated ? Will the RollBack affect all the tables ?
For example, MySql seems not able to rollback a multiple-table transaction http://stackoverflow.com/questions/3094398, while MSSql seems capable http://social.msdn.microsoft.com/Forums … ransactsql .
If the number of the records gets larger (than 1000), it seems useful to move the records that are three days old from one table into another table (as an archive). Could you help to comment whether it is possible to implement this situation with one TSQLRecord descendant, instead of one TSQLRecordActive and one TSQLRecordNonActive with identical properties ? ![]()
(PS: Maybe it is not possible because ORM applies strict relation between class and table, as seen from this link http://stackoverflow.com/questions/8018597/)
Such a nice work !!
For the HTTP mORMot architecture, the server can handle multiple clients (via http.sys or the other pure-pascal implementation) simultaneously (as seen at the client side) .
For the stand-alone mORMot architecture, can one server and multiple clients (one client per thread) coexist ? The reason to ask is that this might be thought as "producer-consumer" situation.
For example, if I create one TSQLRestServerDB, and use this existing TSQLRestServerDB to create multiple TSQLRestClientDB instances (one client per thread):
Can the server handle the underlying ORM thread-safely ?
How does the server achieve the ORM thread-safety ? Through a queue, or via spawned threads (e.g., TSQLRestClientDB spawns threads to deal with each request of TSQLRestClientDB, when the request of customized service-method takes quite a long time to complete ) ?
Are there special things to pay attention to, for example, in the URI or customized service-methods in the TSQLRestServerDB, to ensure thread-safety for this situation ?
Very nice blog ! (Didn't see that in SAD v1.18
)
Thank you for your helpful comments !
Could you also help to comment on the pros and cons to use "SQLite and sharding" instead of "MongoDB" ? ![]()
Really nice work ! Could you elaborate on ACIDity or the best practices in your test against MongoDB ?
For example, this SO post says MongoDB is only ACID when writing a single record into a single table. http://stackoverflow.com/questions/7149890
For another example, the MongoDB FAQ says the "records/documents" do not need to have the same schema. Is this still so when used with mORMot ? http://docs.mongodb.org/manual/faq/fundamentals/
Could you help to comment the questions above ? i.e. (1) why the sample app above runs faster within IDE than standalone ? (2) what to pass into TransactionBegin when multiple tables are to be updated ?
Thank you very much for your time ! ![]()
Thank you very much for your helpful comments !
Page 174 in the SAD doc v1.18 describes TRestClient.RTreeMatch. However, could you create test case or use case about it ?
In SynSelfTests.pas, there is a test of TSQLRecordRTree, which only involves RTree index, but not TRestClient.RTreeMatch, which involves both data and RTree index.
For example, it is not clear why the TSQLRecordMapData has a BlobField containing the textual representation of the coordinates exposed by TSQLRecordMapBox. Are these two types explicitly defined ? Or TSQLRecordMapData somehow includes a TSQLRecordMapBox. Many Thanks!... ![]()
Thank you for your time and efforts ! A linux version of mORMot framework should benefit many people !
Thank you very much for your help ! SDD v1.17 section 1.9 describes design about ORM.
There seems to be SAD v1.18 around. Is there corresponding SDD v1.18 to read and learn ? ![]()
Take http://synopse.info/forum/viewtopic.php?id=336 for example.
Using IE/Chrome, the printed forum post looks not very well. There is too much space in the printed version.
Could you help to comment how to print forum post better ?
Thank you for your efforts very much ! That is indeed a great news ! ![]()
It probably needs mentioning that http.sys is in "kernel land" but lighhtpd is in "user land" . Does this have a consequence ?
(Note, this comment is from google/internet...)
Thank you for your helpful comments !
Thank you for your time, efforts and knowledgeable comments !
Sorry that I know nothing about this topic... Please check this SO post about IOCP under Linux (In short, epoll seems to be used under Linux instead of IOCP)
http://stackoverflow.com/questions/2794535
Could you help to comment another two questions:
1. It seems when running within IDE, the time consumed is much less than that when running standalone. Could you help to comment ?
For example: running within IDE gives,
- Test TSQL record many: 6,113 assertions passed 138.87ms
Total failed: 0 / 6,113 - My test TSQL record many PASSED 139.14ms
running standalone gives,
- Test TSQL record many: 5,813 assertions passed 479.87ms
Total failed: 0 / 5,813 - My test TSQL record many PASSED 481.13ms
2. There are two occurrences of "TransactionBegin" in "uTestTSQLRecordMany.pas". In the source code comments of "TransactionBegin", it is written "the aTable parameter is not used yet". Is this description correct ? I mean, there are descriptions in the doc v1.18 saying "Locking of the database at the record level (page 157)" and "at sqlite 3 engine leve, there is some kind of giant lock (page 249)".
If not, which aTable should one pass ? For example, in the first occurrence of "TransactionBegin" (line 89), TSQLSource is passed even though three tables are being effected. Is this procedure correct ?
3.
The source code corrected from my mistakes is pasted below for your convenience:
The console program source code is
program Learn2_TSQLRecordMany;
{$APPTYPE CONSOLE}
uses
SysUtils,
SynSQLite3Static,
uTestTSQLRecordMany in 'uTestTSQLRecordMany.pas';
{$R *.res}
begin
with TMyTestSuit.Create do
try
// ToConsole := @Output; // so we will see something on screen
Run;
readln;
finally
Free;
end;
end.The test unit source code is
unit uTestTSQLRecordMany;
interface
uses
SysUtils,
SynCommons,
mORMot,
mORMotSQLite3;
type
TMyTestTSQLRecordMany = class(TSynTestCase)
private
fDatabase: TSQLRest;
fModel: TSQLModel;
published
procedure TestTSQLRecordMany;
end;
TMyTestSuit = class(TSynTests)
published
procedure RegMyTestSuit;
end;
type
TSQLSource = class;
TSQLDest = class;
TSQLDestPivot = class(TSQLRecordMany)
private
fSource: TSQLSource;
fDest: TSQLDest;
fTime: TDateTime;
published
property Source: TSQLSource read fSource;
property Dest: TSQLDest read fDest;
property AssociationTime: TDateTime read fTime write fTime;
end;
TSQLSource = class(TSQLRecordSigned)
private
fDestList: TSQLDestPivot;
published
property SignatureTime;
property Signature;
property DestList: TSQLDestPivot read fDestList;
end;
TSQLDest = class(TSQLRecordSigned)
published
property SignatureTime;
property Signature;
end;
implementation
// !!! Modified !!!
//procedure InternalTestMany(Test: TSynTestCase; aClient: TSQLRestClient);
procedure InternalTestMany(Test: TSynTestCase; aClient: TSQLRest);
var MS: TSQLSource;
MD, MD2: TSQLDest;
i: integer;
sID, dID: array[1..100] of Integer;
res: TIntegerDynArray;
procedure CheckOK;
begin
if Test.CheckFailed(MS.FillTable<>nil) then
exit;
Test.Check(MS.FillTable.RowCount>=length(sId));
while MS.FillOne do begin
Test.Check(MS.DestList.Source.fID=MS.fID);
Test.Check(MS.DestList.Dest.SignatureTime<>0);
MS.ClearProperties;
MS.DestList.Source.ClearProperties;
MS.DestList.Dest.ClearProperties;
end;
MS.FillClose;
end;
begin
MS := TSQLSource.Create;
MD := TSQLDest.Create;
with Test do
try
MD.fSignatureTime := TimeLogNow;
MS.fSignatureTime := MD.fSignatureTime;
Check(MS.DestList<>nil);
Check(MS.DestList.InheritsFrom(TSQLRecordMany));
// !!! Modified !!!
// Check(aClient.TransactionBegin(TSQLSource)); // faster process
Check(aClient.TransactionBegin(TSQLSource, CONST_AUTHENTICATION_NOT_USED)); // faster process
for i := 1 to high(dID) do begin
MD.fSignature := FormatUTF8('% %',[aClient.ClassName,i]);
dID[i] := aClient.Add(MD,true);
Check(dID[i]>0);
end;
for i := 1 to high(sID) do begin
MS.fSignature := FormatUTF8('% %',[aClient.ClassName,i]);
sID[i] := aClient.Add(MS,True);
Check(sID[i]>0);
MS.DestList.AssociationTime := i;
Check(MS.DestList.ManyAdd(aClient,sID[i],dID[i])); // associate both lists
Check(not MS.DestList.ManyAdd(aClient,sID[i],dID[i],true)); // no dup
end;
// !!! Modified !!!
// aClient.Commit;
aClient.Commit(CONST_AUTHENTICATION_NOT_USED);
for i := 1 to high(dID) do begin
Check(MS.DestList.SourceGet(aClient,dID[i],res));
if not CheckFailed(length(res)=1) then
Check(res[0]=sID[i]);
Check(MS.DestList.ManySelect(aClient,sID[i],dID[i]));
Check(MS.DestList.AssociationTime=i);
end;
for i := 1 to high(sID) do begin
Check(MS.DestList.DestGet(aClient,sID[i],res));
if CheckFailed(length(res)=1) then
continue; // avoid GPF
Check(res[0]=dID[i]);
Check(MS.DestList.FillMany(aClient,sID[i])=1);
Check(MS.DestList.FillOne);
Check(Integer(MS.DestList.Source)=sID[i]);
Check(Integer(MS.DestList.Dest)=dID[i]);
Check(MS.DestList.AssociationTime=i);
Check(not MS.DestList.FillOne);
Check(MS.DestList.DestGetJoined(aClient,'',sID[i],res));
if not CheckFailed(length(res)=1) then
Check(res[0]=dID[i]);
// !!! Modified !!!
// Check(MS.DestList.DestGetJoined(aClient,'ADest.SignatureTime=:(0):',sID[i],res));
Check(MS.DestList.DestGetJoined(aClient,'Dest.SignatureTime=:(0):',sID[i],res));
Check(length(res)=0);
Check(MS.DestList.DestGetJoined(aClient,
// !!! Modified !!!
// FormatUTF8('ADest.SignatureTime=?',[],[MD.SignatureTime]),sID[i],res));
FormatUTF8('Dest.SignatureTime=?',[],[MD.SignatureTime]),sID[i],res));
// 'ADest.SignatureTime=:('+Int64ToUTF8(MD.SignatureTime)+'):',sID[i],res));
if CheckFailed(length(res)=1) then
continue; // avoid GPF
Check(res[0]=dID[i]);
MD2 := MS.DestList.DestGetJoined(aClient,
// !!! Modified !!!
// FormatUTF8('ADest.SignatureTime=?',[],[MD.SignatureTime]),sID[i]) as TSQLDest;
FormatUTF8('Dest.SignatureTime=?',[],[MD.SignatureTime]),sID[i]) as TSQLDest;
// 'ADest.SignatureTime=:('+Int64ToUTF8(MD.SignatureTime)+'):',sID[i]) as TSQLDest;
if CheckFailed(MD2<>nil) then
continue;
try
Check(MD2.FillOne);
Check(MD2.ID=dID[i]);
Check(MD2.Signature=FormatUTF8('% %',[aClient.ClassName,i]));
finally
MD2.Free;
end;
end;
Check(MS.FillPrepareMany(aClient,nil,[],[]));
CheckOK;
Check(MS.FillPrepareMany(aClient,'DestList.Dest.SignatureTime<>?',[],[0]));
CheckOK;
Check(MS.FillPrepareMany(aClient,
'DestList.Dest.SignatureTime<>% and RowID>=? and DestList.AssociationTime<>0 '+
'and SignatureTime=DestList.Dest.SignatureTime '+
'and DestList.Dest.Signature<>"DestList.AssociationTime"',[0],[sID[1]]));
if CheckFailed(MS.FillTable<>nil) then
exit;
Check(MS.FillTable.RowCount=length(sID));
for i := 1 to high(sID) do begin
MS.SignatureTime := 0;
MS.DestList.Dest.SignatureTime := 0;
if CheckFailed(MS.FillOne) then
break;
Check(MS.fID=sID[i]);
Check(MS.SignatureTime=MD.fSignatureTime);
Check(MS.DestList.AssociationTime=i);
Check(MS.DestList.Dest.fID=dID[i]);
Check(MS.DestList.Dest.SignatureTime=MD.fSignatureTime);
Check(MS.DestList.Dest.Signature=FormatUTF8('% %',[aClient.ClassName,i]));
end;
MS.FillClose;
// !!! Modified !!!
// Check(aClient.TransactionBegin(TSQLDestPivot)); // faster process
Check(aClient.TransactionBegin(TSQLDestPivot, CONST_AUTHENTICATION_NOT_USED)); // faster process
for i := 1 to high(sID) shr 2 do
Check(MS.DestList.ManyDelete(aClient,sID[i*4],dID[i*4]));
// !!! Modified !!!
// aClient.Commit;
aClient.Commit(CONST_AUTHENTICATION_NOT_USED);
for i := 1 to high(sID) do
if i and 3<>0 then begin
Check(MS.DestList.ManySelect(aClient,sID[i],dID[i]));
Check(MS.DestList.AssociationTime=i);
end else
Check(not MS.DestList.ManySelect(aClient,sID[i],dID[i]));
finally
MD.Free;
MS.Free;
end;
end;
{ TMyTestTSQLRecordMany }
procedure TMyTestTSQLRecordMany.TestTSQLRecordMany;
begin
fModel := TSQLModel.Create([TSQLSource, TSQLDest, TSQLDestPivot]);;
fDatabase := TSQLRestServerDB.Create(fModel, ChangeFileExt(paramstr(0),'.db3'));
TSQLRestServerDB(fDatabase).CreateMissingTables(0);
InternalTestMany(Self, fDatabase);
end;
{ TMyTestSuit }
procedure TMyTestSuit.RegMyTestSuit;
begin
AddCase([TMyTestTSQLRecordMany]);
end;
end.Sorry ! My fault ! ![]()
"TSQLADest" is typed by me as "TSQLDest" in the Delphi type declarations.
Thus, when DestGetJoined is called, the parameter string needs to be changed in accordance. ![]()
That is to say, "ADest.SignatureTime" -> "Dest.SignatureTime"...
There is an ESQLite3Exception complaining "no such column: XXX". However, when the sqlite database file is opened with SqliteMaestro, the column is there. Could you help to comment ?
The console program source code is
program Learn2_TSQLRecordMany;
uses
SysUtils,
SynSQLite3Static,
uTestTSQLRecordMany in 'uTestTSQLRecordMany.pas';
{$R *.res}
begin
with TMyTestSuit.Create do
try
// ToConsole := @Output; // so we will see something on screen
Run;
readln;
finally
Free;
end;
end.The test unit source code is
unit uTestTSQLRecordMany;
interface
uses
SysUtils,
SynCommons,
mORMot,
mORMotSQLite3;
type
TMyTestTSQLRecordMany = class(TSynTestCase)
private
fDatabase: TSQLRest;
fModel: TSQLModel;
published
procedure TestTSQLRecordMany;
end;
TMyTestSuit = class(TSynTests)
published
procedure RegMyTestSuit;
end;
type
TSQLSource = class;
TSQLDest = class;
TSQLDestPivot = class(TSQLRecordMany)
private
fSource: TSQLSource;
fDest: TSQLDest;
fTime: TDateTime;
published
property Source: TSQLSource read fSource;
property Dest: TSQLDest read fDest;
property AssociationTime: TDateTime read fTime write fTime;
end;
TSQLSource = class(TSQLRecordSigned)
private
fDestList: TSQLDestPivot;
published
property SignatureTime;
property Signature;
property DestList: TSQLDestPivot read fDestList;
end;
TSQLDest = class(TSQLRecordSigned)
published
property SignatureTime;
property Signature;
end;
implementation
// !!! Modified !!!
//procedure InternalTestMany(Test: TSynTestCase; aClient: TSQLRestClient);
procedure InternalTestMany(Test: TSynTestCase; aClient: TSQLRest);
var MS: TSQLSource;
MD, MD2: TSQLDest;
i: integer;
sID, dID: array[1..100] of Integer;
res: TIntegerDynArray;
procedure CheckOK;
begin
if Test.CheckFailed(MS.FillTable<>nil) then
exit;
Test.Check(MS.FillTable.RowCount>=length(sId));
while MS.FillOne do begin
Test.Check(MS.DestList.Source.fID=MS.fID);
Test.Check(MS.DestList.Dest.SignatureTime<>0);
MS.ClearProperties;
MS.DestList.Source.ClearProperties;
MS.DestList.Dest.ClearProperties;
end;
MS.FillClose;
end;
begin
MS := TSQLSource.Create;
MD := TSQLDest.Create;
with Test do
try
MD.fSignatureTime := TimeLogNow;
MS.fSignatureTime := MD.fSignatureTime;
Check(MS.DestList<>nil);
Check(MS.DestList.InheritsFrom(TSQLRecordMany));
// !!! Modified !!!
// Check(aClient.TransactionBegin(TSQLSource)); // faster process
Check(aClient.TransactionBegin(TSQLSource, CONST_AUTHENTICATION_NOT_USED)); // faster process
for i := 1 to high(dID) do begin
MD.fSignature := FormatUTF8('% %',[aClient.ClassName,i]);
dID[i] := aClient.Add(MD,true);
Check(dID[i]>0);
end;
for i := 1 to high(sID) do begin
MS.fSignature := FormatUTF8('% %',[aClient.ClassName,i]);
sID[i] := aClient.Add(MS,True);
Check(sID[i]>0);
MS.DestList.AssociationTime := i;
Check(MS.DestList.ManyAdd(aClient,sID[i],dID[i])); // associate both lists
Check(not MS.DestList.ManyAdd(aClient,sID[i],dID[i],true)); // no dup
end;
// !!! Modified !!!
// aClient.Commit;
aClient.Commit(CONST_AUTHENTICATION_NOT_USED);
for i := 1 to high(dID) do begin
Check(MS.DestList.SourceGet(aClient,dID[i],res));
if not CheckFailed(length(res)=1) then
Check(res[0]=sID[i]);
Check(MS.DestList.ManySelect(aClient,sID[i],dID[i]));
Check(MS.DestList.AssociationTime=i);
end;
for i := 1 to high(sID) do begin
Check(MS.DestList.DestGet(aClient,sID[i],res));
if CheckFailed(length(res)=1) then
continue; // avoid GPF
Check(res[0]=dID[i]);
Check(MS.DestList.FillMany(aClient,sID[i])=1);
Check(MS.DestList.FillOne);
Check(Integer(MS.DestList.Source)=sID[i]);
Check(Integer(MS.DestList.Dest)=dID[i]);
Check(MS.DestList.AssociationTime=i);
Check(not MS.DestList.FillOne);
Check(MS.DestList.DestGetJoined(aClient,'',sID[i],res));
if not CheckFailed(length(res)=1) then
Check(res[0]=dID[i]);
Check(MS.DestList.DestGetJoined(aClient,'ADest.SignatureTime=:(0):',sID[i],res));
Check(length(res)=0);
Check(MS.DestList.DestGetJoined(aClient,
FormatUTF8('ADest.SignatureTime=?',[],[MD.SignatureTime]),sID[i],res));
// 'ADest.SignatureTime=:('+Int64ToUTF8(MD.SignatureTime)+'):',sID[i],res));
if CheckFailed(length(res)=1) then
continue; // avoid GPF
Check(res[0]=dID[i]);
MD2 := MS.DestList.DestGetJoined(aClient,
FormatUTF8('ADest.SignatureTime=?',[],[MD.SignatureTime]),sID[i]) as TSQLDest;
// 'ADest.SignatureTime=:('+Int64ToUTF8(MD.SignatureTime)+'):',sID[i]) as TSQLDest;
if CheckFailed(MD2<>nil) then
continue;
try
Check(MD2.FillOne);
Check(MD2.ID=dID[i]);
Check(MD2.Signature=FormatUTF8('% %',[aClient.ClassName,i]));
finally
MD2.Free;
end;
end;
Check(MS.FillPrepareMany(aClient,nil,[],[]));
CheckOK;
Check(MS.FillPrepareMany(aClient,'DestList.Dest.SignatureTime<>?',[],[0]));
CheckOK;
Check(MS.FillPrepareMany(aClient,
'DestList.Dest.SignatureTime<>% and RowID>=? and DestList.AssociationTime<>0 '+
'and SignatureTime=DestList.Dest.SignatureTime '+
'and DestList.Dest.Signature<>"DestList.AssociationTime"',[0],[sID[1]]));
if CheckFailed(MS.FillTable<>nil) then
exit;
Check(MS.FillTable.RowCount=length(sID));
for i := 1 to high(sID) do begin
MS.SignatureTime := 0;
MS.DestList.Dest.SignatureTime := 0;
if CheckFailed(MS.FillOne) then
break;
Check(MS.fID=sID[i]);
Check(MS.SignatureTime=MD.fSignatureTime);
Check(MS.DestList.AssociationTime=i);
Check(MS.DestList.Dest.fID=dID[i]);
Check(MS.DestList.Dest.SignatureTime=MD.fSignatureTime);
Check(MS.DestList.Dest.Signature=FormatUTF8('% %',[aClient.ClassName,i]));
end;
MS.FillClose;
// !!! Modified !!!
// Check(aClient.TransactionBegin(TSQLDestPivot)); // faster process
Check(aClient.TransactionBegin(TSQLDestPivot, CONST_AUTHENTICATION_NOT_USED)); // faster process
for i := 1 to high(sID) shr 2 do
Check(MS.DestList.ManyDelete(aClient,sID[i*4],dID[i*4]));
// !!! Modified !!!
// aClient.Commit;
aClient.Commit(CONST_AUTHENTICATION_NOT_USED);
for i := 1 to high(sID) do
if i and 3<>0 then begin
Check(MS.DestList.ManySelect(aClient,sID[i],dID[i]));
Check(MS.DestList.AssociationTime=i);
end else
Check(not MS.DestList.ManySelect(aClient,sID[i],dID[i]));
finally
MD.Free;
MS.Free;
end;
end;
{ TMyTestTSQLRecordMany }
procedure TMyTestTSQLRecordMany.TestTSQLRecordMany;
begin
fModel := TSQLModel.Create([TSQLSource, TSQLDest, TSQLDestPivot]);;
fDatabase := TSQLRestServerDB.Create(fModel, ChangeFileExt(paramstr(0),'.db3'));
TSQLRestServerDB(fDatabase).CreateMissingTables(0);
InternalTestMany(Self, fDatabase);
end;
{ TMyTestSuit }
procedure TMyTestSuit.RegMyTestSuit;
begin
AddCase([TMyTestTSQLRecordMany]);
end;
end.The exception is
First chance exception at $75A2C41F. Exception class ESQLite3Exception with message 'no such column: ADest.SignatureTime'. Process Learn2_TSQLRecordMany.exe (11172)The stack-trace is
:75a2c41f KERNELBASE.RaiseException + 0x58
SynSQLite3.sqlite3_check(7583624,1)
SynSQLite3.TSQLRequest.Prepare(7583624,'SELECT Dest.RowID FROM Dest,DestPivot WHERE DestPivot.Source=? AND DestPivot.Dest=Dest.RowID AND ADest.SignatureTime=?')
SynSQLite3.TSQLStatementCached.Prepare('SELECT Dest.RowID FROM Dest,DestPivot WHERE DestPivot.Source=? AND DestPivot.Dest=Dest.RowID AND ADest.SignatureTime=?')
mORMotSQLite3.TSQLRestServerDB.GetAndPrepareStatement('SELECT Dest.RowID FROM Dest,DestPivot WHERE DestPivot.Source=:(1): AND DestPivot.Dest=Dest.RowID AND ADest.SignatureTime=:(0):')
mORMotSQLite3.TSQLRestServerDB.EngineList('SELECT Dest.RowID FROM Dest,DestPivot WHERE DestPivot.Source=:(1): AND DestPivot.Dest=Dest.RowID AND ADest.SignatureTime=:(0):',False,nil)
mORMot.TSQLRestServer.ExecuteList((...),'SELECT Dest.RowID FROM Dest,DestPivot WHERE DestPivot.Source=:(1): AND DestPivot.Dest=Dest.RowID AND ADest.SignatureTime=:(0):')
mORMot.TSQLRecordMany.DestGetJoinedTable($6E3660,'ADest.SignatureTime=:(0):',1,jkDestID,'')
mORMot.TSQLRecordMany.DestGetJoined($6E3660,'ADest.SignatureTime=:(0):',1,())
uTestTSQLRecordMany.InternalTestMany($7836D0,$6E3660)
uTestTSQLRecordMany.TMyTestTSQLRecordMany.TestTSQLRecordMany
SynCommons.TSynTests.Run
Learn2_TSQLRecordMany.Learn2_TSQLRecordMany
:753433aa kernel32.BaseThreadInitThunk + 0x12
:778b9ef2 ntdll.RtlInitializeExceptionChain + 0x63
:778b9ec5 ntdll.RtlInitializeExceptionChain + 0x36It should be noted that even though there is no occurrence of TSynLog, the app will give a log file when compiled with Delphi 7, but no log file when compiled with Delphi XE6.
On Page 393 of the doc v1.18, there is a "ToConsole := @Output". In your first post above, there is a "ToConsole: ^Text;".
However, this "ToConsole" seems to be removed in the NightlyBuild. Could you help to comment the reason to remove this and what is the replacement ?
Yes, because of the great comments in this SO post. http://stackoverflow.com/questions/3387501/
Oh! When your great framework turns cross-platform, will it be with Kylix or FPC ?
Oh! How do your server apps utilize mORMot with crosskylix ? Or your server apps only utilize your enhanced RTL ?
TSynLog is a very good log framework! TMemoryMapText provides a very fast file-reading capability!
Both of them are contained in SynCommons.pas, I am therefore wondering if they can be used under Linux OS ? If so, how should one consume them ? (For example, a "Kylix" DEF can be seen in SynCommons.pas. However, when Delphi7/CrossKylix is used to compile a application using TSynLog, the process stops when compiling SynLz.)
Could you help to comment:
(1) the reason not to test against Delphi XE?
(2) whether it is possible for your forum to differentiate the posts (read/unread, new/old/edited)?
![]()
Fantastic ! ![]()
(Can you also test against Delphi XE ?)
"Sounds more like a problem of your system code page - some tests are working only with a Windows 1252 code page..."
Does this mean that even every NightlyBuild passes your tests ? ![]()
With the nightly build, TestSQL3.dpr will fail some tests. Not sure whether it is related...
Delphi XE debug
Synopse mORMot Framework Automated tests
------------------------------------------
1. Synopse libraries
1.1. Low level common:
- System copy record: 22 assertions passed 186us
- TRawUTF8List: 70,005 assertions passed 116.96ms
- TDynArray: 1,027,702 assertions passed 263.56ms
- TDynArrayHashed: 1,200,629 assertions passed 192.50ms
- TObjectListHashed: 999,874 assertions passed 739.55ms
- TObjectDynArrayWrapper: 167,501 assertions passed 30.29ms
- Fast string compare: 7 assertions passed 222us
- IdemPropName: 30 assertions passed 222us
- Url encoding: 105 assertions passed 1.64ms
- GUID: 9,005 assertions passed 3.67ms
- IsMatch: 599 assertions passed 309us
- Soundex: 35 assertions passed 157us
- Numerical conversions: 1,066,591 assertions passed 405.69ms
- Curr 64: 20,053 assertions passed 1.77ms
- CamelCase: 11 assertions passed 163us
- Bits: 4,774 assertions passed 233us
- Ini files: 7,004 assertions passed 31.25ms
- UTF8: 79,111 assertions passed 2.06s
- Iso 8601 date and time: 32,007 assertions passed 6.32ms
- Url decoding: 1,100 assertions passed 705us
- Mime types: 20 assertions passed 137us
! - TSynTable: 197 / 875 FAILED 8.13ms
- TSynCache: 404 assertions passed 876us
- TSynFilter: 1,005 assertions passed 4.10ms
- TSynValidate: 677 assertions passed 869us
- TSynLogFile: 42 assertions passed 1.13ms
Total failed: 197 / 4,689,188 - Low level common FAILED 3.88s
1.2. Low level types:
- RTTI: 52 assertions passed 738us
- Url encoding: 200 assertions passed 2.50ms
- Encode decode JSON: 262,010 assertions passed 187.32ms
- Mustache renderer: 137 assertions passed 2.86ms
! - TDocVariant: 2 / 71,661 FAILED 202.18ms
! - BSON: 8 / 20,000,184 FAILED 357.10ms
Total failed: 10 / 20,334,244 - Low level types FAILED 755.57ms
1.3. Big table:
- TSynBigTable: 19,187 assertions passed 82.12ms
- TSynBigTableString: 16,076 assertions passed 36.31ms
- TSynBigTableMetaData: 384,060 assertions passed 2.06s
- TSynBigTableRecord: 452,185 assertions passed 5.11s
Total failed: 0 / 871,508 - Big table PASSED 7.29s
1.4. Synopse PDF:
! - TPdfDocument: 1 / 2 FAILED 4.52ms
- TPdfDocumentGDI: 5 assertions passed 258.18ms
Total failed: 1 / 7 - Synopse PDF FAILED 263.89ms
1.5. Cryptographic routines:
- Adler32: 1 assertion passed 748us
- MD5: 1 assertion passed 682us
- SHA1: 5 assertions passed 205us
- SHA256: 5 assertions passed 1.10ms
- AES256: 16,815 assertions passed 1.14s
- RC4: 1 assertion passed 1.01ms
- Base64: 11,994 assertions passed 220.97ms
- CompressShaAes: 1,683 assertions passed 5.39ms
Total failed: 0 / 30,505 - Cryptographic routines PASSED 1.37s
1.6. Compression:
- In memory compression: 12 assertions passed 437.91ms
- GZIP format: 19 assertions passed 825.20ms
- ZIP format: 36 assertions passed 1.48s
- SynLZO: 3,006 assertions passed 156.37ms
- SynLZ: 29,018 assertions passed 1.14s
Total failed: 0 / 32,091 - Compression PASSED 4.04s
2. mORMot
2.1. File based:
- Database direct access: 10,138 assertions passed 326.92ms
- Virtual table direct access: 12 assertions passed 2.60ms
- TSQLTableJSON: 111,074 assertions passed 167.87ms
- TSQLRestClientDB: 605,151 assertions passed 3.78s
- Regexp function: 6,016 assertions passed 38.60ms
Total failed: 0 / 732,391 - File based PASSED 4.32s
2.2. File based memory map:
- Database direct access: 10,136 assertions passed 340.42ms
- Virtual table direct access: 12 assertions passed 3.09ms
- TSQLTableJSON: 111,074 assertions passed 161.65ms
- TSQLRestClientDB: 605,150 assertions passed 3.62s
- Regexp function: 6,016 assertions passed 35.65ms
Total failed: 0 / 732,388 - File based memory map PASSED 4.17s
2.3. File based WAL:
- Database direct access: 10,138 assertions passed 353.74ms
- Virtual table direct access: 12 assertions passed 1.60ms
- TSQLTableJSON: 111,074 assertions passed 165.78ms
- TSQLRestClientDB: 605,151 assertions passed 3.55s
- Regexp function: 6,016 assertions passed 33.82ms
Total failed: 0 / 732,391 - File based WAL PASSED 4.11s
2.4. Memory based:
- Database direct access: 10,136 assertions passed 328.75ms
- Virtual table direct access: 12 assertions passed 2.35ms
- TSQLTableJSON: 111,074 assertions passed 158.81ms
- TSQLRestClientDB: 673,447 assertions passed 4.15s
- Regexp function: 6,016 assertions passed 35.30ms
- RTree: 140,000 assertions passed 1.43s
Total failed: 0 / 940,685 - Memory based PASSED 6.11s
2.5. Basic classes:
! - TSQLRecord: 11 / 65 FAILED 3.03ms
- TSQLRecordSigned: 200 assertions passed 5.65ms
- TSQLModel: 3 assertions passed 6.75ms
Total failed: 11 / 268 - Basic classes FAILED 17.89ms
2.6. Client server access:
- TSQLHttpServer: 2 assertions passed 5.29ms
using HTTP API 2.0
- TSQLHttpClient: 3 assertions passed 33.82ms
- HTTP client keep alive: 3,087 assertions passed 520.89ms
4818 B, first 6.76ms, done 481.97ms i.e. 2074/s, aver. 481us, 9.7 MB/s
- HTTP client multi connect: 3,087 assertions passed 449.58ms
4818 B, first 586us, done 427.30ms i.e. 2340/s, aver. 427us, 10.9 MB/s
- HTTP client encrypted: 3,087 assertions passed 597.42ms
4818 B, first 758us, done 567.31ms i.e. 1762/s, aver. 567us, 8.2 MB/s
- Named pipe access: 3,089 assertions passed 594.54ms
4818 B, first 256.45ms, done 122.51ms i.e. 8162/s, aver. 122us, 38.1 MB/s
- Local window messages: 3,088 assertions passed 130.93ms
4818 B, first 374us, done 105.94ms i.e. 9438/s, aver. 105us, 44.1 MB/s
- Direct in process access: 3,056 assertions passed 60.95ms
4818 B, first 57us, done 53.45ms i.e. 18709/s, aver. 53us, 87.4 MB/s
- HTTP several DB servers: 9,604 assertions passed 1.34s
4818 B, first 722us, done 398.60ms i.e. 2508/s, aver. 398us, 11.7 MB/s
4818 B, first 744us, done 387.63ms i.e. 2579/s, aver. 387us, 12.0 MB/s
4818 B, first 703us, done 398.46ms i.e. 2509/s, aver. 398us, 11.7 MB/s
Total failed: 0 / 28,103 - Client server access PASSED 3.74s
2.7. Service oriented architecture:
- Weak interfaces: 56 assertions passed 165us
- Service initialization: 200 assertions passed 3.00ms
- Direct call: 577,083 assertions passed 41.30ms
- Server side: 577,102 assertions passed 48.43ms
- Client side REST: 577,107 assertions passed 668.60ms
- Client side REST result as object: 577,101 assertions passed 720.64ms
- Client side REST locked: 577,104 assertions passed 652.80ms
- Client side REST synchronized: 577,104 assertions passed 1.26s
- Client side REST background thread: 577,104 assertions passed 1.23s
- Client side REST weak authentication: 577,101 assertions passed 666.66ms
- Client side REST custom record layout: 577,101 assertions passed 751.06ms
- Client side JSONRPC: 577,101 assertions passed 922.35ms
- Test over HTTP: 9,524 assertions passed 828.74ms
- Security: 135 assertions passed 1.61ms
- Mocks and stubs: 30,031 assertions passed 66.32ms
Total failed: 0 / 5,810,954 - Service oriented architecture PASSED 7.87s
2.8. External database:
- External records: 2 assertions passed 10.84ms
- Auto adapt SQL: 448 assertions passed 39.38ms
- Crypted database: 253,275 assertions passed 333.95ms
- External via REST: 168,343 assertions passed 1.37s
- External via virtual table: 168,343 assertions passed 3.16s
- JET database: 7,007 assertions passed 1.12s
Total failed: 0 / 597,418 - External database PASSED 6.04s
2.9. Multi thread process:
- Create thread pool: 1 assertion passed 3.41ms
- TSQLRestServerDB: 4,822 assertions passed 116.61ms
1=28508/s 2=25263/s 5=18317/s 10=20180/s 30=20247/s 50=20784/s
- TSQLRestClientDB: 4,822 assertions passed 146.12ms
1=19158/s 2=21143/s 5=10299/s 10=20214/s 30=17799/s 50=21637/s
- TSQLRestClientURINamedPipe: 2,412 assertions passed 1.64s
1=1054/s 2=1243/s 5=542/s
- TSQLRestClientURIMessage: 3,222 assertions passed 264.77ms
1=4928/s 2=10105/s 5=6160/s 10=5515/s
- TSQLHttpClientWinHTTP_HTTPAPI: 4,810 assertions passed 554.67ms
1=2302/s 2=4772/s 5=5210/s 10=5817/s 30=6940/s 50=5390/s
- TSQLHttpClientWinSock_WinSock: 4,820 assertions passed 345.59ms
1=8622/s 2=8358/s 5=8031/s 10=6735/s 30=8323/s 50=5070/s
- Locked: 4,822 assertions passed 152.36ms
1=26056/s 2=16786/s 5=23688/s 10=21265/s 30=14971/s 50=9021/s
- Unlocked: 4,822 assertions passed 174.67ms
1=16175/s 2=17604/s 5=28783/s 10=16806/s 30=12199/s 50=8118/s
- Background thread: 4,821 assertions passed 462.48ms
1=11321/s 2=21219/s 5=16081/s 10=12104/s 30=6351/s 50=1452/s
- Main thread: 4,822 assertions passed 264.48ms
1=9261/s 2=8375/s 5=8714/s 10=11824/s 30=14462/s 50=6866/s
Total failed: 0 / 44,196 - Multi thread process PASSED 4.14s
Synopse framework used: 1.18
SQlite3 engine used: 3.8.4.3
Generated with: Delphi XE compiler
Time elapsed for all tests: 58.20s
Tests performed at 2014/4/29 9:55:03
Total assertions failed for all test suits: 219 / 35,576,337
! Some tests FAILED: please correct the code.Delphi XE6 release
Synopse mORMot Framework Automated tests
------------------------------------------
1. Synopse libraries
1.1. Low level common:
- System copy record: 22 assertions passed 241us
- TRawUTF8List: 70,005 assertions passed 116.29ms
- TDynArray: 1,027,702 assertions passed 205.29ms
- TDynArrayHashed: 1,200,629 assertions passed 167.71ms
- TObjectListHashed: 999,907 assertions passed 549.59ms
- TObjectDynArrayWrapper: 167,501 assertions passed 33.37ms
- Fast string compare: 7 assertions passed 294us
- IdemPropName: 30 assertions passed 234us
- Url encoding: 105 assertions passed 1.03ms
- GUID: 9,005 assertions passed 7.03ms
- IsMatch: 599 assertions passed 269us
- Soundex: 35 assertions passed 143us
- Numerical conversions: 1,063,059 assertions passed 510.88ms
- Curr 64: 20,053 assertions passed 1.40ms
- CamelCase: 11 assertions passed 110us
- Bits: 4,774 assertions passed 133us
- Ini files: 7,004 assertions passed 34.16ms
- UTF8: 79,111 assertions passed 1.25s
- Iso 8601 date and time: 32,007 assertions passed 5.17ms
- Url decoding: 1,100 assertions passed 784us
- Mime types: 20 assertions passed 207us
! - TSynTable: 200 / 875 FAILED 9.09ms
- TSynCache: 404 assertions passed 877us
- TSynFilter: 1,005 assertions passed 9.35ms
- TSynValidate: 677 assertions passed 997us
- TSynLogFile: 42 assertions passed 754us
Total failed: 200 / 4,685,689 - Low level common FAILED 2.91s
1.2. Low level types:
- RTTI: 52 assertions passed 3.86ms
- Url encoding: 200 assertions passed 783us
- Encode decode JSON: 262,010 assertions passed 136.71ms
- Mustache renderer: 137 assertions passed 2.07ms
- TDocVariant: 71,661 assertions passed 216.75ms
! - BSON: 8 / 20,000,184 FAILED 223.39ms
Total failed: 8 / 20,334,244 - Low level types FAILED 587.45ms
1.3. Big table:
- TSynBigTable: 19,216 assertions passed 67.58ms
- TSynBigTableString: 16,177 assertions passed 22.47ms
- TSynBigTableMetaData: 384,060 assertions passed 1.06s
- TSynBigTableRecord: 452,185 assertions passed 2.50s
Total failed: 0 / 871,638 - Big table PASSED 3.66s
1.4. Synopse PDF:
! - TPdfDocument: 1 / 2 FAILED 4.71ms
- TPdfDocumentGDI: 5 assertions passed 141.06ms
Total failed: 1 / 7 - Synopse PDF FAILED 146.75ms
1.5. Cryptographic routines:
- Adler32: 1 assertion passed 648us
- MD5: 1 assertion passed 104us
- SHA1: 5 assertions passed 114us
- SHA256: 5 assertions passed 648us
- AES256: 16,815 assertions passed 1.08s
- RC4: 1 assertion passed 1.13ms
- Base64: 11,994 assertions passed 156.61ms
- CompressShaAes: 1,683 assertions passed 4.41ms
Total failed: 0 / 30,505 - Cryptographic routines PASSED 1.25s
1.6. Compression:
- In memory compression: 12 assertions passed 464.13ms
- GZIP format: 19 assertions passed 956.83ms
- ZIP format: 36 assertions passed 1.69s
- SynLZO: 3,006 assertions passed 137.41ms
- SynLZ: 29,018 assertions passed 861.38ms
Total failed: 0 / 32,091 - Compression PASSED 4.12s
2. mORMot
2.1. File based:
- Database direct access: 10,138 assertions passed 313.02ms
- Virtual table direct access: 12 assertions passed 2.53ms
- TSQLTableJSON: 111,074 assertions passed 110.57ms
- TSQLRestClientDB: 605,151 assertions passed 3.26s
- Regexp function: 6,016 assertions passed 40.57ms
Total failed: 0 / 732,391 - File based PASSED 3.73s
2.2. File based memory map:
- Database direct access: 10,136 assertions passed 335.15ms
- Virtual table direct access: 12 assertions passed 1.87ms
- TSQLTableJSON: 111,074 assertions passed 109.27ms
- TSQLRestClientDB: 605,150 assertions passed 3.14s
- Regexp function: 6,016 assertions passed 33.67ms
Total failed: 0 / 732,388 - File based memory map PASSED 3.63s
2.3. File based WAL:
- Database direct access: 10,138 assertions passed 354.29ms
- Virtual table direct access: 12 assertions passed 1.68ms
- TSQLTableJSON: 111,074 assertions passed 109.03ms
- TSQLRestClientDB: 605,151 assertions passed 3.27s
- Regexp function: 6,016 assertions passed 32.96ms
Total failed: 0 / 732,391 - File based WAL PASSED 3.77s
2.4. Memory based:
- Database direct access: 10,136 assertions passed 303.13ms
- Virtual table direct access: 12 assertions passed 1.30ms
- TSQLTableJSON: 111,074 assertions passed 100.84ms
- TSQLRestClientDB: 673,447 assertions passed 3.96s
- Regexp function: 6,016 assertions passed 55.47ms
- RTree: 140,000 assertions passed 1.30s
Total failed: 0 / 940,685 - Memory based PASSED 5.73s
2.5. Basic classes:
- TSQLRecord: 65 assertions passed 1.10ms
- TSQLRecordSigned: 200 assertions passed 5.07ms
- TSQLModel: 3 assertions passed 17.55ms
Total failed: 0 / 268 - Basic classes PASSED 26.07ms
2.6. Client server access:
- TSQLHttpServer: 2 assertions passed 4.39ms
using HTTP API 2.0
- TSQLHttpClient: 3 assertions passed 29.16ms
- HTTP client keep alive: 3,087 assertions passed 448.02ms
4818 B, first 6.67ms, done 417.23ms i.e. 2396/s, aver. 417us, 11.2 MB/s
- HTTP client multi connect: 3,087 assertions passed 381.44ms
4818 B, first 1.90ms, done 351.20ms i.e. 2847/s, aver. 351us, 13.3 MB/s
- HTTP client encrypted: 3,087 assertions passed 482.64ms
4818 B, first 745us, done 459.15ms i.e. 2177/s, aver. 459us, 10.1 MB/s
- Named pipe access: 3,089 assertions passed 595.13ms
4818 B, first 256.61ms, done 117.76ms i.e. 8491/s, aver. 117us, 39.7 MB/s
- Local window messages: 3,088 assertions passed 112.02ms
4818 B, first 266us, done 94.18ms i.e. 10617/s, aver. 94us, 49.6 MB/s
- Direct in process access: 3,056 assertions passed 37.53ms
4818 B, first 37us, done 30.60ms i.e. 32670/s, aver. 30us, 152.7 MB/s
- HTTP several DB servers: 9,604 assertions passed 1.46s
4818 B, first 695us, done 424.69ms i.e. 2354/s, aver. 424us, 11.0 MB/s
4818 B, first 740us, done 416.07ms i.e. 2403/s, aver. 416us, 11.2 MB/s
4818 B, first 739us, done 449.91ms i.e. 2222/s, aver. 449us, 10.3 MB/s
Total failed: 0 / 28,103 - Client server access PASSED 3.56s
2.7. Service oriented architecture:
- Weak interfaces: 56 assertions passed 546us
- Service initialization: 200 assertions passed 2.65ms
- Direct call: 577,083 assertions passed 33.09ms
- Server side: 577,102 assertions passed 42.37ms
- Client side REST: 577,107 assertions passed 508.39ms
- Client side REST result as object: 577,101 assertions passed 514.09ms
- Client side REST locked: 577,104 assertions passed 495.11ms
- Client side REST synchronized: 577,104 assertions passed 1.20s
- Client side REST background thread: 577,104 assertions passed 1.06s
- Client side REST weak authentication: 577,101 assertions passed 466.62ms
- Client side REST custom record layout: 577,101 assertions passed 500.51ms
- Client side JSONRPC: 577,101 assertions passed 544.11ms
- Test over HTTP: 9,524 assertions passed 814.27ms
- Security: 135 assertions passed 3.92ms
- Mocks and stubs: 30,031 assertions passed 61.26ms
Total failed: 0 / 5,810,954 - Service oriented architecture PASSED 6.26s
2.8. External database:
- External records: 2 assertions passed 670us
- Auto adapt SQL: 448 assertions passed 35.55ms
- Crypted database: 253,275 assertions passed 278.45ms
- External via REST: 168,343 assertions passed 1.29s
- External via virtual table: 168,343 assertions passed 2.96s
- JET database: 7,007 assertions passed 1.12s
Total failed: 0 / 597,418 - External database PASSED 5.69s
2.9. Multi thread process:
- Create thread pool: 1 assertion passed 3.93ms
- TSQLRestServerDB: 4,822 assertions passed 92.30ms
1=29418/s 2=26418/s 5=27047/s 10=26996/s 30=29076/s 50=25834/s
- TSQLRestClientDB: 4,822 assertions passed 153.67ms
1=27647/s 2=21180/s 5=16107/s 10=19250/s 30=15521/s 50=9195/s
- TSQLRestClientURINamedPipe: 2,411 assertions passed 1.50s
1=1182/s 2=1108/s 5=666/s
- TSQLRestClientURIMessage: 3,222 assertions passed 264.42ms
1=4688/s 2=9997/s 5=8107/s 10=5087/s
- TSQLHttpClientWinHTTP_HTTPAPI: 4,795 assertions passed 520.02ms
1=3029/s 2=4455/s 5=5496/s 10=4833/s 30=6375/s 50=5599/s
- TSQLHttpClientWinSock_WinSock: 4,819 assertions passed 423.05ms
1=8550/s 2=6860/s 5=7637/s 10=7704/s 30=6947/s 50=2773/s
- Locked: 4,822 assertions passed 179.75ms
1=25992/s 2=18309/s 5=14345/s 10=12970/s 30=14398/s 50=7920/s
- Unlocked: 4,822 assertions passed 171.18ms
1=23540/s 2=16152/s 5=9330/s 10=13961/s 30=16201/s 50=14719/s
- Background thread: 4,822 assertions passed 585.05ms
1=22026/s 2=14927/s 5=11818/s 10=7876/s 30=2355/s 50=1452/s
- Main thread: 4,822 assertions passed 249.12ms
1=9653/s 2=5074/s 5=9568/s 10=20360/s 30=10879/s 50=16382/s
Total failed: 0 / 44,180 - Multi thread process PASSED 4.16s
Synopse framework used: 1.18
SQlite3 engine used: 3.8.4.3
Generated with: Delphi XE6 compiler
Time elapsed for all tests: 49.32s
Tests performed at 2014/4/29 9:58:03
Total assertions failed for all test suits: 209 / 35,572,952
! Some tests FAILED: please correct the code.Thank you very much for your knowledgeable comments !
Could you help to comment on another two questions of mine ?
1.
On Page 87 of Doc v1.18, "4.3.3 Capacity handling via an external Count", it is mentioned that "That is, whether you call Add or Delete methods, an internal call to SetLength(DynArrayVariable) is performed.". I am wondering, does the dynamic array grow by 1 or exponentially every time ?
2.
Your unitary tests are not contained in the "nightly" zip file. I wonder where to download them ? (For example, 4.3.5 on Page 87 mentions TTestLowLevelCommon where one could learn how to use TDynArray/TDynArrayHashed.) (Found in "SynSelfTests.pas".
)
Thank you for your helpful comments very much !
I want to learn your great mORMot framework. Could you help to comment on the three questions below ?
procedure TForm1.FormCreate(Sender: TObject);
type
TGroup = array of Integer;
var
Group: TGroup;
GroupA: TDynArray;
I, V: Integer;
Test: RawByteString;
begin
GroupA.Init(TypeInfo(TGroup),Group);
for I := 0 to 1000 do
begin
//GroupA.Add(I); // Question 1: Why "I" is not used directly ? (Page 85 of doc v1.18 says "need argument passed as a const variable". However, I do not understand what bad effects will come otherwise.)
V := I ;
GroupA.Add(V); // Question 2: TDynArray does not have type-check ? It seems anything can be added here, which is not alerting enough ?
end;
Test := GroupA.SaveTo;
GroupA.Clear;
//GroupA.LoadFrom(Test); // Question 3: This line (from Page 86) does not compile ? Should one hard-case as below ?
GroupA.LoadFrom(PAnsiChar(Test));
Caption := FloatToStrF(Group[50], ffFixed, 12, 6);
end;Thank you very much for your comments!
I had tried the "THashedStringList" together with a separate TObject list/array to mimic a Dictionary/HashMap/HashTable before, but I didn't know the "best practice" to do it in Delphi 7. Besides, there have been discussions and THashedStringList was said to be low efficient generally (i.e., a simple linear search for bucket collisions is used internally, which is a bad choice in general and an especially bad choice for a fixed small bucket count. See https://forums.embarcadero.com/message. … geID=86963). In that post, DIContainers has been recommended, but it doesn't provide Kylix compatibility.
Regarding IniFiles.TStringHash, because the key is string type and the value is integer type, I would think its usage is the same as THashedStringList. Could you help to comment whether it has the same problem of bucket collision search as THashedStringList?
You mentioned that coding in Delphi 7 manner helps to migrate to Free Pascal and so forth. However, Delphi 7 doesn't provide TDictionary/HashMap/HashTable, which is convenient sometimes.
Could you help to comment on this issue?
Dear Arnaud, thank you very much for your time! I don't know how to send bug requests; I will then send the link of this page to him via email.
Furthermore, I have sent you an email regarding another question to "freelance at synopse dot info" (with a zipped file attachment as large as 1.5 MB). Thank you very much again!
Thank you very much for your time and kindness!!
1.
I have tried the following steps several times in clean virtual machines (clean means fresh-installed Windows Xp Sp2, without any other programs):
(1) Install Delphi 7
(2) Install CrossKylix + Kylix files
(3) Install CrossKylix ideplugin into Delphi 7 IDE; as prompted by the plugin itself and mentioned kindly by you, I have to filled in the path of crosskylix installation (, and the "unit+include+object" will be filled by itself).
(4) Try to use "Build with Kylix"
(5) Reboot the virtual machine, try to use "Build with Kylix"The same problem occurred as in my workstation and laptop: in step (5), "Build with Kylix" will not respond.
2.
HOWEVER, I accidentally found that, after each rebooting, if I ran ckdcc.exe once, by double clicking for instance, and THEN open Delphi 7, the "Build with Kylix" will work!
I tried this workaround on my workstation and laptop (i.e., run ckdcc.exe once before opening Delphi 7 IDE) and it is also valid. I didn't know why, though.
Thank you very much for your prompt suggestions!
1. I didn't install or uninstall any experts plugin.
2, 4. I installed once in my workstation (using default options as in #4 post), and now in my laptop. Thus, I didn't need to uninstall.
3. Yes. I mean, after I just installed Delphi 7, CrossKylix and kylix files, I indeed can use "Build with Kylix". After restarting the computer, the menuitem will not respond my click (error log as in #4 post). The command line compiler works however.
I will then try carefully as you advised in clean virtual machines (because the state of the virtual machine can be saved and restored quite easily), and report what happens later.
Thank you for your prompt help very much!
I am sorry that:
The information at #4 post is when I installed CrossKylix at its default directory.
After that, I tried to install CrossKylix without space characters under C:\CrossKylix, which is the information at #5 post.
I forgot to mention that:
1.
Despite the fact that the "Build with Kylix" menuitem in the Delphi 7 IDE will not respond after I click it, with the .conf file generated by CrossKylix, a manual call like:
C:\TestProject1> "C:\Program Files\CrossKylix\ckdcc.exe" Project1.dpr
still works.
2.
When I tried to install CrossKylix into another directory without space characters in the path, like C:\crosskylix, the same problem exists, i.e. :
The "Build with Kylix" menuitem in the Delphi 7 IDE will not respond after I click it.
With the .conf file generated by CrossKylix, a manual call like:
C:\TestProject1> C:\CrossKylix\ckdcc.exe Project1.dpr
works.
Could you help me with this problem? Thank you very much!!