#1 Re: mORMot Framework » a little compile hit and warning » 2018-02-22 12:44:48

ab wrote:

Should be fine now.

Now all fine, thank you very much!

#3 mORMot Framework » a little compile hit and warning » 2018-02-21 12:48:53

mingda
Replies: 4

a little compile hit and warning

[DCC Hint] SynTable.pas(4900): H2443 Inline function 'TSynLocker.Lock' has not been expanded because unit 'Windows' is not specified in USES list
[DCC Hint] SynTable.pas(4908): H2443 Inline function 'TSynLocker.UnLock' has not been expanded because unit 'Windows' is not specified in USES list

[DCC Warning] mORMotReport.pas(1664): W1057 Implicit string cast from 'AnsiString' to 'string'
[DCC Warning] mORMotReport.pas(1674): W1057 Implicit string cast from 'AnsiString' to 'string'


thanks!

#6 mORMot Framework » TSQLRestServerURIContext.ReturnFile produce AV » 2018-02-21 07:59:28

mingda
Replies: 2

Hi,
  I have a running program, today i update mORMot to last 4322 trunk, from browser get a file will get a EAccessViolation,
i debug found when call function ExistsIniName(P: PUTF8Char; UpperName: PAnsiChar): boolean; parameter P is nil,

procedure TSQLRestServerURIContext.ReturnFile(const FileName: TFileName;
  Handle304NotModified: boolean; const ContentType,AttachmentFileName,
  Error404Redirect: RawUTF8);
var FileTime: TDateTime;
    clientHash, serverHash: RawUTF8;
begin
...
    if not ExistsIniName(pointer(Call.OutHead),HEADER_CONTENT_TYPE_UPPER) then begin   ==>run into ExistsIniName produce av
...
end;

DelphiXE with 4322 mORMot

thanks!

#7 Re: mORMot Framework » Wrong BatchUpdate will make subsequent BatchUpdate Server Error 500 » 2017-07-19 09:44:50

ab wrote:

Such buffer overflows can be tricky to fix.

something need to learn, thank your share!

#8 Re: mORMot Framework » Wrong BatchUpdate will make subsequent BatchUpdate Server Error 500 » 2017-07-19 08:53:25

After test, I confirm AV gone, server is still online.
Wonderful, you are a super man!
thanks!

#9 Re: mORMot Framework » Wrong BatchUpdate will make subsequent BatchUpdate Server Error 500 » 2017-07-19 02:00:24

Further debug, after first "Wrong PUT" error, subsequent BatchUpdate generate av at

function TSQLRequest.Step: integer;
{$ifdef RESETFPUEXCEPTION} // safest to reset x87 exceptions - inlined TSynFPUException
var cw87: word;
{$endif}
begin
  if Request=0 then
    raise ESQLite3Exception.Create(RequestDB,SQLITE_MISUSE,'Step');
  {$ifdef RESETFPUEXCEPTION}
  cw87 := Get8087CW;
  try
  {$endif}
    result := sqlite3_check(RequestDB,sqlite3.step(Request),'Step');     //<==== here generate av
  {$ifdef RESETFPUEXCEPTION}
  finally
    Set8087CW(cw87);
  end;
  {$endif}
end;

can't debug further because my ability, seem all av relative to the first "Wrong PUT" error.
When debug first "Wrong Put" error, follow step also generate some av, and when you close
applicaiton directly, final will have Runtime error 216.

thanks!

#10 Re: mORMot Framework » Wrong BatchUpdate will make subsequent BatchUpdate Server Error 500 » 2017-07-13 02:47:45

ab wrote:

The context is unclear...
Is there a "Wrong PUT" error before, or after the AV?

"Wrong PUT" error is first, this is the call stack

:76c85608 KERNELBASE.RaiseException + 0x48
mORMot.TSQLRestServer.EngineBatchSend(nil,'["automaticTransactionPerRow",2147483647,,"PUT@VoyageFee",{"ID":null,"Flag":1,"UpdateBy":"User","UpdateTime":1499911738644,"RemoteIP":"127.0.0.1"},"PUT@VoyageFee",{"ID":3096,"Flag":1,"UpdateBy":"User","UpdateTime":1499911738644,"RemoteIP":"127.0.0.1"},"PUT@VoyageFee",{"ID":3086,"Flag":1,"UpdateBy":"User","UpdateTime":1499911738644,"RemoteIP":"127.0.0.1"},"PUT@VoyageFee",{"ID":3084,"Flag":0,"DoneBill":1,"UpdateBy":"User","UpdateTime":1499911738644,"RemoteIP":"127.0.0.1"},"PUT@VoyageFee",{"ID":3086,"Flag":0,"DoneBill":1,"UpdateBy":"User","UpdateTime":1499911738644,"RemoteIP":"127.0.0.1"},"PUT@VoyageFee",{"ID":3096,"Flag":0,"DoneBill":1,"UpdateBy":"User","UpdateTime":1499911738644,"RemoteIP":"127.0.0.1"},"PUT@VoyageFee",{"ID":null,"Flag":0,"DoneBill":1,"UpdateBy":"User","UpdateTime":1499911738644,"RemoteIP":"127.0.0.1...
mORMot.TSQLRestServer.Batch($221C680)
uShipAgentRestServer.TShipAgentRestServer.ApplyUpdates($221C680)
mORMot.TSQLRestServerURIContext.ExecuteSOAByMethod
mORMot.TSQLRestServerURIContext.ExecuteCommand
mORMot.TSQLRestServer.URI($54CFD80)
mORMotHttpServer.TSQLHttpServer.Request($22B78D8)
SynCrtSock.THttpServerGeneric.Request($22B78D8)
SynCrtSock.THttpServer.Process($22152E0,4,$22CC2F8)
SynCrtSock.THttpServerResp.Execute
:004574b9 ThreadProc + $45
:00407e4a ThreadWrapper + $2A
:76e97c04 KERNEL32.BaseThreadInitThunk + 0x24
:7718ad2f ntdll.RtlInitializeExceptionChain + 0x8f
:7718acfa ntdll.RtlInitializeExceptionChain + 0x5a

after wrong Put, BatchUpdate will error, there have two debug Exception Notification:
when click Break, the first callstack is

:76c85608 KERNELBASE.RaiseException + 0x48
SynSQLite3Static.sqlite3_realloc($2212F78,145)

the second callstack is

:76c85608 KERNELBASE.RaiseException + 0x48
:00407224 NotifyNonDelphiException + $1C
:7716ff13 ; 
SynCommons.MoveX87
:7717068f ntdll.KiUserExceptionDispatcher + 0xf
SynLog.TSynMapFile.Log($22CC7D8,6696455,False)
SynLog.TSynLog.AddStackTrace(nil)
SynLog.TSynLog.LogInternal(sllError,'% for % // %',(...),$288E960)
SynLog.TSynLog.Log(sllError,'% for % // %',(...),$288E960)
mORMot.TSQLRest.InternalLog('% for % // %',(...),sllError)
mORMotSQLite3.TSQLRestServerDB.GetAndPrepareStatementRelease($22AD0F8,'')
mORMotSQLite3.TSQLRestServerDB.InternalExecute('UPDATE InvoiceType SET Attribute=:(''5''):,UpdateBy=:(''User''):,UpdateTime=:(1499911820772):,RemoteIP=:(''127.0.0.1''): WHERE RowID=:(4):;',False,nil,nil {''},nil,nil,nil)
mORMotSQLite3.TSQLRestServerDB.EngineExecute('UPDATE InvoiceType SET Attribute=:(''5''):,UpdateBy=:(''User''):,UpdateTime=:(1499911820772):,RemoteIP=:(''127.0.0.1''): WHERE RowID=:(4):;')
mORMot.TSQLRest.ExecuteFmt('UPDATE % SET % WHERE RowID=:(%):;',(...))
mORMotSQLite3.TSQLRestServerDB.MainEngineUpdate(23,4,'{"Attribute":"5","UpdateBy":"User","UpdateTime":1499911820772,"RemoteIP":"127.0.0.1"}')
mORMot.TSQLRestServer.EngineUpdate(23,4,'{"Attribute":"5","UpdateBy":"User","UpdateTime":1499911820772,"RemoteIP":"127.0.0.1"}')
mORMot.TSQLRestServer.EngineBatchSend(nil,'["automaticTransactionPerRow",2147483647,"PUT@InvoiceType'#0#0'{"ID":4{"Attribute":"5","UpdateBy":"User","UpdateTime":1499911820772,"RemoteIP":"127.0.0.1"}]',(304),0)
mORMot.TSQLRestServer.Batch($221C680)
uShipAgentRestServer.TShipAgentRestServer.ApplyUpdates($221C680)
mORMot.TSQLRestServerURIContext.ExecuteSOAByMethod
mORMot.TSQLRestServerURIContext.ExecuteCommand
mORMot.TSQLRestServer.URI($54CFD80)
mORMotHttpServer.TSQLHttpServer.Request($22B78D8)
SynCrtSock.THttpServerGeneric.Request($22B78D8)
SynCrtSock.THttpServer.Process($22152E0,5,$22CC2F8)
SynCrtSock.THttpServerResp.Execute
:004574b9 ThreadProc + $45
:00407e4a ThreadWrapper + $2A
:76e97c04 KERNEL32.BaseThreadInitThunk + 0x24
:7718ad2f ntdll.RtlInitializeExceptionChain + 0x8f
:7718acfa ntdll.RtlInitializeExceptionChain + 0x5a

I use this code make test:

  TShipAgentRestServer= class(TSQLRestServerDB)
  private
    f: boolean;
  publshied
    procedure ApplyUpdates(Ctx: TSQLRestServerURIContext);

procedure TShipAgentRestServer.ApplyUpdates(Ctx: TSQLRestServerURIContext);
var
  tempStr: rawUTF8;
begin
  if not f then begin
    Tempstr := AnyTextFileToRawUTF8('error.json');
    Ctx.Call.InBody := TempStr;
    f := True;
  end else begin
    Tempstr := AnyTextFileToRawUTF8('good.json');
    Ctx.Call.InBody := TempStr;
  end;

  Batch(Ctx);
end;

error.json 

["automaticTransactionPerRow", 2147483647, "PUT@VoyageFee", {
	"ID": 3084,
	"Flag": 1,
	"UpdateTime": 1499822856618,
	"RemoteIP": "127.0.0.1"
}, "PUT@VoyageFee", {
	"ID": 3096,
	"Flag": 0,
	"UpdateTime": 1499822856618,
	"RemoteIP": "127.0.0.1"
}, "PUT@VoyageFee", {
	"ID": null,
	"Flag": 1,
	"UpdateTime": 1499822856618,
	"RemoteIP": "127.0.0.1"
}, "PUT@VoyageFee", {
	"ID": 3098,
	"Flag": 1,
	"UpdateTime": 1499822856618,
	"RemoteIP": "127.0.0.1"
}]

good.json

["automaticTransactionPerRow", 2147483647, "PUT@VoyageFee", {
	"ID": 3084,
	"Flag": 1,
	"UpdateTime": 1499822856618,
	"RemoteIP": "127.0.0.1"
}, "PUT@VoyageFee", {
	"ID": 3096,
	"Flag": 0,
	"UpdateTime": 1499822856618,
	"RemoteIP": "127.0.0.1"
}, "PUT@VoyageFee", {
	"ID": 3098,
	"Flag": 1,
	"UpdateTime": 1499822856618,
	"RemoteIP": "127.0.0.1"
}]

make a web client,  call ApplyUpdates with any success content,
first call trigger error, then subsequent call will error,

Use DelphiXE, mORMot 3705, thanks!

#11 mORMot Framework » Wrong BatchUpdate will make subsequent BatchUpdate Server Error 500 » 2017-07-12 10:30:55

mingda
Replies: 8

using TSQLRestServerDB, when a error batchupdate cause by "EngineBatchSend: Wrong PUT",
then subsequent batchupdate will generate Server Error 500: Internal Server Error.

Debug find av occur at

function TSQLRestServerDB.InternalExecute(const aSQL: RawUTF8;

        if (ValueInt=nil) and (ValueUTF8=nil) then begin
          // default execution: loop through all rows
          repeat until fStatement^.Step<>SQLITE_ROW;     //<====== av occure at here, 

//raised exception class EAccessViolation with message 'Access violation at address 006BE19C

thanks!

#12 Re: mORMot Framework » ESynException with message 'TJSONSerializer.AddVariant VType=12864'. » 2017-05-05 08:33:57

My mistake, need set the object name

HeaderDoc := Ctx.Request.Server.RetrieveDocVariantArray(TSQLTest,'header','ID IN (' + IDs + ')', [], '*')

#13 mORMot Framework » ESynException with message 'TJSONSerializer.AddVariant VType=12864'. » 2017-05-05 08:28:32

mingda
Replies: 1

Hi, I use below code to generate content, when run will generate ESynException, but if debug step by step, will ok,

var
  HeaderTemplate, LineTemplate, IDs, HeaderContent, LineContent: RawUTF8;
  Ctx: PServiceRunningContext;
  Mustache: TSynMustache;
  HeaderDoc, LineDoc: Variant;

begin

...
  HeaderDoc := Ctx.Request.Server.RetrieveDocVariantArray(TSQLTest,'','ID IN (' + IDs + ')', [], '*');
  Mustache := TSynMustache.Parse(HeaderTemplate);
  HeaderContent := Mustache.Render(HeaderDoc);    //==>here Generate ESynException
...

where is the problem, any suggestions is welcome, thanks!

Mingda

#14 Re: mORMot Framework » SynMustache Expression Helpers Enhance » 2017-05-04 11:57:24

Have test, confirm it works now,
Can the empty between helper function and variable also support multi space, thanks!
Also If the space before comma can ignore then will Perfect.

#15 mORMot Framework » SynMustache Expression Helpers Enhance » 2017-05-02 08:03:17

mingda
Replies: 2

I just test Mustache, i found Expression helpers error prone, i want to change date display format,
so use {{datefmt Birthday, "YYYY-MM-DD"}}, but found not success, after debug, i found this is
because there is a space after comma, can enhance to let Mustache auto ignore the space,
end user easy make this mistake, thanks!

Mingda

#16 Re: mORMot Framework » Application Locking » 2017-04-12 08:46:38

ab wrote:

Are you sure your crypt salt rounds was 10000 ?

In unlock.bat i remove the salt, let input through console, ecc's default salt is 60000,
so this is the problem, after salt rounds change to 10000, test is pass,
Encryption is very interesting, thank you very much!

#17 Re: mORMot Framework » Application Locking » 2017-04-12 07:09:47

ab wrote:

One of the decryption parameters doesn't match the encryption parameter, I guess.

I start a fresh new test, make applock keys, except issuer, passPhrase of .private, all parameter else is the ecc tool default value,
user@host key, is auto generated by the call ECCAuthorize,

var
  S: PShortString;
  r: TECCAuthorize;
begin
  r := ECCAuthorize(FAppSecret, 0, '', 'abc', '', AppLockPublic64);
  S := ToText(r);
  ShowMessage(UTF8ToString(ShortStringToUTF8(s^)));
end;

so the parameter is

aSecretDays := 0;
aSecretPass := '';
aDPAPI := 'abc';
aDecryptSalt := '';
aAppLockPublic64 is copy from applock.public's base64 value;

1. call unlock.bat to use applock private key to sign user@host.json,
2. use user@host.public key to crypt user@host.json,
3. copy the new .json.synecc file to the test program,
4. rename it to .unlock file, then run, the same route, not success,
where is wrong, thanks!

#18 mORMot Framework » Application Locking » 2017-04-11 07:04:41

mingda
Replies: 6

I'm learn  Application Locking through doc.

Through these step:
1. first make a SelfSigned public and private key
2. make a test program, put a button

procedure TForm1.Button1Click(Sender: TObject);
const
  AppLockPublic64 =	'AQD9AP0AagIODCLNMfBnPirgW4w/EasRLQ1h6CyAAAAAAAAAAAAAAA4MIs0.....';
var
  S: PShortString;
  r: TECCAuthorize;
begin
  r := ECCAuthorize(FAppSecret, 0, '', 'abc', '', AppLockPublic64);
  S := ToText(r);
  ShowMessage(UTF8ToString(ShortStringToUTF8(s^)));
end;

AppLockPublic64 is copy from public key's "Base64" value, run  and click button, will get
another two user@host public and private file,

copy user@host.public to app.public directory, and make a user@host.json file, content is :

{
	"Root": "TestRoot"
}

run the bat file

@echo off
echo Usage: unlock user@host
echo.
ecc sign -file %1.json
ecc crypt -file %1.json
del %1.json.sign

use user@host.public to crypt, after crypt, rename the user@host.json.synecc file to user@host.unlock,
then copy it to test program's exe directory, click button1, but still show eaInvalidUnlockFile, after debug, the call

      decrypt := priv.Decrypt(unlock, json, @signature, nil, nil, aDecryptSalt, 10000);

decrypt return value is ecdDecryptError, what's wrong with my test, thanks!

Mingda

#19 Re: mORMot Framework » '0.42793' is not a valid timestamp » 2017-03-10 01:18:46

@Junior/RO
I use 3469,

@EMartin
Sorry, I can't reach the google site, only update from ab's

thank you two!

#20 mORMot Framework » '0.42793' is not a valid timestamp » 2017-03-09 07:34:58

mingda
Replies: 5

when I do report, i use ExecuteJson to get a sql json resut, then convert to TSynSQLTableDataSet,

json := Client.ExecuteJson([], DataSetSql);
JSONTODataSet(nil, Json),

just found, if there is only one row, if a RawUTF8 string field has 2017-02-27 content,
in the json content look like this, "XXX":"2017-02-27", then report engline use
     FValue := DataSet.Value[DataField];
to get value will generate AV '0.42793' is not a valid timestamp, seems the underline
field treat as datetime, how can resolve this.

Any help very thanks!

update:
I think if can manul set the field type, then will ok, I'll test this method.

update2:
Seems the under TSQLTable can SetFieldType, but the TSynSQLTableDataSet's field type
can't change, in
function TSynVirtualDataSet.GetFieldData(Field: TField; Buffer: Pointer): Boolean;

  Data := GetRowFieldData(Field,RowIndex,DataLen,OnlyTestForNull);

GetRowFieldData can work, but next run to

  ftDateTime:
    PDateTimeRec(Dest)^.DateTime := PDateTime(Data)^;

after that has become '0.0' is not a valid timestamp

update 3:
  First create a TSQLTable, manual set field type, then use it create DataSet seems resolve the problem.


Mingda

#21 Re: mORMot Framework » about javascript DateTime type » 2017-03-06 13:46:21

strange, after update, the fastreport connect to the dynamic create dateset, (TSynSQLTableDataSet create by JSONToDataSet in mORMotVCL) still display integer value. (By the way, you are a super man. smile)

update:

Perhaps i use raw sql to get the result, and column name use alias, in the json result, there is no column type info, like below

    DataSetSql := 'select columnA aliasA, columnB aliasB from table';
    Json := Client.ExecuteJson([], DataSetSql);
    if Json = '' then Continue;
    ReportDataSetDynArray[I].Dataset := JSONTODataSet(nil, Json);

#22 Re: mORMot Framework » about javascript DateTime type » 2017-03-06 00:43:03

ab wrote:

Use TUnixTime or TUnixMSTime types.

Just test, JSONToDataSet in mORMotVCL not deal with TUnixMSTime type, still show it's int64 value, -:(

#23 mORMot Framework » about javascript DateTime type » 2017-03-05 13:06:04

mingda
Replies: 4

For javascript datetime just integer value for milliseconds since midnight on January 1, 1970, when transmit json, encode just like integer, so i define it like this:


  TTimeStamp = type Int64;


  TSQLBase = class(TSQLRecord)
  private
    fEta: TTimeStamp;
  published
    property Eta: TTimeStamp read fEta write fEta;


this is all ok until now, now i need to generate report, i use
JSONToDataSet in unit mORMotVCL to convert json to TSynSQLTableDataSet,
but the datetime all display it's integer value, is there any method
let the javascript datetime to display ok, any suggest is welcome, thanks!

Mingda

#24 Re: mORMot Framework » MAX_SQLFIELDS default value » 2017-03-03 08:29:12

this is perfect, thank you very much!

#25 mORMot Framework » MAX_SQLFIELDS default value » 2017-03-03 03:40:39

mingda
Replies: 2

Can change MAX_SQLFIELDS default value to 128, current 64 everytime after update i need change, thanks!



Also current 3449 builder testSQL3 after run, when close has memory leak report:

Unexpected Memory Leak
---------------------------
An unexpected memory leak has occurred. The unexpected small block leaks are:

85 - 92 bytes: TSynThreadPoolSubThread x 32

thanks!

#27 Re: mORMot Framework » Sqlite3 db BatchInsert problem » 2016-09-13 13:32:30

The problem is indeed "ID":null caused, remove it works, I will update source to test, thank you very much!

#28 Re: mORMot Framework » Sqlite3 db BatchInsert problem » 2016-09-11 13:49:21

use DelphiXE, for multi row insert, every loop EngineAdd return 0, but for single row, return correct ID, thanks!

#29 mORMot Framework » Sqlite3 db BatchInsert problem » 2016-09-11 11:36:50

mingda
Replies: 5

sqlite3 db, a strange problem, from webclient, use BatchInsert, when only insert one row, in response text, can return the Insert ID, but when insert multi row, in response text, always return 0 ID

'["automaticTransactionPerRow",2147483647,"POST@test",{"ID":null,"Name":"B001","Question":"B001","Time":null}]'

return [87]

'["automaticTransactionPerRow",2147483647,"POST@test",{"ID":null,"Name":"A001","Question":"A001","Time":null},"POST@test",{"ID":null,"Name":"A002","Question":"A002","Time":null},"POST@test",{"ID":null,"Name":"A003","Question":"A003","Time":null}]'

return [0,0,0]

use version 2929

thanks

#30 Re: mORMot Framework » sometime AV occur at TDynArrayHashed.HashAdd » 2016-09-01 14:14:06

when reuse a cache statement

procedure TOleDBStatement.Reset;
begin
...
    fColumn.Clear;
    fColumn.ReHash;
...
end;

seems TDynArrayHashed.ReHash need add fHashsCount := 0

function TDynArrayHashed.ReHash(aHasher: TOnDynArrayHashOne=nil): boolean;
var i, n, cap, ndx: integer;
    P: PAnsiChar;
    aHashCode: cardinal;
begin
  result := false;
  fHashs := nil;
  fHashsCount := 0;    //add this to reset count
  n := Count;
  if (n=0) or (n<fHashCountTrigger) then
    exit; // hash only if needed, and avoid GPF after TDynArray.Clear (Count=0)

#31 mORMot Framework » sometime AV occur at TDynArrayHashed.HashAdd » 2016-09-01 09:16:17

mingda
Replies: 2

in TDynArrayHashed.HashAdd sometimes fHashsCount = 256, but Length(fHashs)=0,

  with fHashs[-result-1] do begin // HashFind returned negative index in fHashs[]
    Hash := aHashCode;
    Index := n;
  end;

this cause write fHashs[-result-1] will generate AV(here result=-1),

but not every time this occure, i have a function like this:

function test(const aParam: RawUTF8; aConnection: TSQLDBConnection): Boolean;
var
  sql: RawUTF8;
  rows, updateStatement: ISQLDBStatement;
begin
  rows := aConnection.NewStatementPrepared(sql, true);
  if not Assigned(rows) then exit;
  rows.Bind([aParam]);
  rows.ExecutePrepared;
....
end;

below is log, thanks

20160901 07132747 EXCOS EAccessViolation (C0000005) at 00516473 SynCommons.TDynArrayHashed.HashAdd (42926)  stack trace API 0051662B SynCommons.TDynArrayHashed.FindHashedForAdding (42960) 00516689 SynCommons.TDynArrayHashed.AddAndMakeUniqueName (42971) 0055C758 SynOleDB.TOleDBStatement.BindColumns (2215) 0055BDBD SynOleDB.TOleDBStatement.FromRowSet (2024) 0055B89B SynOleDB.TOleDBStatement.ExecutePrepared (1989) 006BF93F 

#33 mORMot Framework » Perhaps [2b444efbfd] commit is inverse » 2016-07-15 13:16:26

mingda
Replies: 4
constructor THttpClientSocket.Create(aTimeOut: cardinal);
begin
  if aTimeOut = 0 then
    inherited Create(aTimeOut) else
    inherited Create(HTTP_DEFAULT_RECEIVETIMEOUT);
  UserAgent := DefaultUserAgent(self);
end;

perhaps should be

constructor THttpClientSocket.Create(aTimeOut: cardinal);
begin
  if aTimeOut = 0 then
    inherited Create(HTTP_DEFAULT_RECEIVETIMEOUT) else
    inherited Create(aTimeOut);

/*
  //or
  if aTimeOut = 0 then aTimeOut := HTTP_DEFAULT_RECEIVETIMEOUT;
  inherited Create(aTimeOut);
*/
  UserAgent := DefaultUserAgent(self);
end;

#34 Re: mORMot Framework » OFF-TOPIC: Merry christmas... » 2015-12-26 00:18:37

Merry Christmas to ab and all, wish everyone a safe and happy holiday!

#35 Re: mORMot Framework » free objects on the server side » 2015-07-22 23:58:24

I think you can make a test case for anyone else to trace the problem, let ab debug it easy.

#36 Re: mORMot Framework » Perhaps some dead lock at TTestMultiThreadProcess.Websockets test » 2015-05-05 09:15:52

Delphi XE,

just another hit, below new test have 2 not passed test

2.9. External database:
!  - DB properties persistence: 2 / 7 FAILED  1.53ms

and current Synopse Library Test not enable in test

procedure TTestSynopsemORMotFramework.SynopseLibraries;
begin
  //
  exit;
  AddCase([TTestLowLevelCommon,

thanks.

#37 mORMot Framework » Perhaps some dead lock at TTestMultiThreadProcess.Websockets test » 2015-05-05 02:32:44

mingda
Replies: 3
 2.9. External database:
  - TQuery: 2,003 assertions passed  28.40ms
  - SynDBRemote: 30,095 assertions passed  822.17ms
!  - DB properties persistence: 2 / 7 FAILED  1.53ms
  - External records: 2 assertions passed  915us
  - Auto adapt SQL: 708 assertions passed  105.48ms
  - Crypted database: 253,275 assertions passed  435.42ms
  - External via REST: 170,354 assertions passed  2.36s
  - External via virtual table: 170,354 assertions passed  3.97s
  - External via REST with change tracking: 180,454 assertions passed  6.62s
  - JET database: 7,007 assertions passed  2.95s
  Total failed: 2 / 814,259  - External database FAILED  17.32s

 2.10. Multi thread process:
  - Create thread pool: 1 assertion passed  30.42ms
  - TSQLRestServerDB: 4,822 assertions passed  252.76ms
     1=14324/s  2=9596/s  5=10028/s  10=8694/s  30=13298/s  50=8482/s
  - TSQLRestClientDB: 4,822 assertions passed  266.99ms
     1=12823/s  2=12215/s  5=12357/s  10=11306/s  30=8394/s  50=5517/s
  - TSQLRestClientURINamedPipe: 2,412 assertions passed  1.67s
     1=991/s  2=927/s  5=639/s
  - TSQLRestClientURIMessage: 3,222 assertions passed  406.55ms
     1=3281/s  2=4975/s  5=5341/s  10=3603/s
  - Windows API: 4,822 assertions passed  1.65s
     1=1256/s  2=1400/s  5=1669/s  10=1758/s  30=1696/s  50=1272/s
  - Socket API: 4,822 assertions passed  929.12ms
     1=3127/s  2=2939/s  5=3043/s  10=2881/s  30=2592/s  50=1967/s

recent, run Testsql3 multi times, sometimes the test run stop at TTestMultiThreadProcess.Websockets, output like above, and cpu is 100%, but this is not always, sometime just 1 of 5, thanks.

#38 mORMot Framework » the {727} change cause testsql3 av » 2015-01-17 05:10:09

mingda
Replies: 1

this change in http://synopse.info/fossil/info/612863b … 6fe445c06f cause testsql3 occur av, test DelphiXE, test {726} is ok, thanks.

#39 Re: mORMot Framework » sqlite Deadlocks » 2014-11-26 08:02:23

I also found some problem relative TSQLDBConneciton TSQLDBConnectionProperties and the ClearConnectionPool, I first made this proposal ClearConnectionPool to fix the break connection, but now seem this fix is wrong, for Connection in ConnectionPool, every connection has different thread id, so every connection should free in their owner thread, this is particular for TOleDBMSSQLConnectionProperties, this also make use TSQLDBConnectionProperties.execute in thread should very careful, for RestServer we have EndCurrentThread call to release connection, but if directly use ConnectionProperties, then will no way to release the connection, current i have a backgroud thread to run, just after a day run, will not work, there is no memory leak, so i just change all TSQLDBConnectionProperties.execute to explicit new a Connection, then release it, today will test it, for release connection problem, this example can see this,

unit Unit6;

interface

uses
  Classes, SynDB;

type
  TTestThread = class(TThread)
  private
    { Private declarations }
    fProps: TSQLDBConnectionProperties;
  protected
    procedure Execute; override;
  public
    procedure SetSQLDBProperties(aProps: TSQLDBConnectionProperties);
  end;

implementation

{ TTestThread }

procedure TTestThread.Execute;
begin
  { Place thread code here }
  fProps.Execute('select * from test', []);
end;

procedure TTestThread.SetSQLDBProperties(aProps: TSQLDBConnectionProperties);
begin
  fProps := aProps;
end;

end.
unit Unit5;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, SynCommons, SynDB, SynOleDB, StdCtrls, Unit6;

type
  TForm5 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    Button2: TButton;
    Button3: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    fProps: TSQLDBConnectionProperties;
  end;

var
  Form5: TForm5;

implementation

{$R *.dfm}

procedure TForm5.Button1Click(Sender: TObject);
begin
  Memo1.Text := UTF8ToString(fProps.Execute('select * from test', []).FetchAllAsJSON(true));
end;

procedure TForm5.Button2Click(Sender: TObject);
var
  testThread: TTestThread;
begin
  testThread := TTestThread.Create(true);
  testThread.SetSQLDBProperties(fProps);
  testThread.FreeOnTerminate := true;
  testThread.Start;
end;

procedure TForm5.Button3Click(Sender: TObject);
begin
  fProps.ClearConnectionPool;
end;

procedure TForm5.FormCreate(Sender: TObject);
begin
  fProps := TOleDBMSSQLConnectionProperties.Create('localhost', 'testdb', '', '');
end;

procedure TForm5.FormDestroy(Sender: TObject);
begin
  fProps.Free;
end;

end.

after you run a thread, then close the program or call ClearConnectionPool will see EAssertionFailed, don't know if your problem is this relative, thanks!

#40 Re: mORMot Framework » Data replication in a multiple master environment » 2014-11-14 07:16:51

another function need consider, the TSQLRecord current don't have old value, for e.g.  a object

TTest = class(TSQLRecord)
published
  property column1 rawutf8;
  property column2 rawutf8;
  property column3 rawutf8;
  ...
end;

when two user read a object at same time, get the same object {"ID":1,"column1":"value","column2":"value","column3":"value"},
if userA update column1 to "value_updateA",
userB update column2 to "value_updateB",
current if userA update first, userB next, then the finally object value will be {"ID":1,"column1":"value","column2":"value_updateB","column3":"value"}, userA's change is lost,

if TSQLRecord have old value, use the old value generate upate sql,
userA update will generate
update Test set column1 = 'value_updateA' where id = 1 and column1 = 'value',
userB update will generate
update Test set column2 = 'value_updateB' where id = 1 and column2 = 'value',
this solve two problem, 1) update override other column's value 2) multi user update conflict.

for replication, if we have such journal,
1). {"ID":1,"column1":"value","column2":"value","column3":"value"}
2). {"ID":1,"column1":"value_updateA","column2":"value","column3":"value"}
3). {"ID":1,"column1":"value","column2":"value_updateB","column3":"value"}
after the last change merge, we only get the object value:
3). {"ID":1,"column1":"value","column2":"value_updateB","column3":"value"}, this is not expect.

if we have old value, such journal will look like such:
1). {"ID":1,"column1":"value","column2":"value","column3":"value"}
2). {"old record":{"ID":1,"column1":"value","column2":"value","column3":"value"},
"new record":{{"ID":1,"column1":"value_updateA","column2":"value","column3":"value"}}}
3).{"old record":{"ID":1,"column1":"value","column2":"value","column3":"value"},
"new record":{{"ID":1,"column1":"value","column2":"value_updateB","column3":"value"}}}

or we can have the not update empty:

1). {"ID":1,"column1":"value","column2":"value","column3":"value"}
2). {"old record":{"ID":1,"column1":"value","column2":"value","column3":"value"},
"new record":{{"ID":1,"column1":"value_updateA"}}}
3).{"old record":{"ID":1,"column1":"value","column2":"value","column3":"value"},
"new record":{{"ID":1,"column2":"value_updateB"}}}

then we can merge it to
{"ID":1,"column1":"value_updateA","column2":"value_updateB","column3":"value"}

this will greatly reduce conflict, for userA, userB update same column, such change later user
update will get conflict hit, since the update will failed.

just my personal thought, thanks!

#42 Re: mORMot Framework » interface contract check » 2014-11-13 02:30:11

Ideally, if can check procedure contract one by one it would be great,
this will make backward compatible, for a server interface

  ITest = interface(IInvokable)
    procedure baba1;
    procedure baba2;
    procedure baba...;
  end;

client interface below will all pass check:

  ITest = interface(IInvokable)
    procedure baba1;
  end;

  ITest = interface(IInvokable)
    procedure baba1;
    procedure baba2;
  end;

  ITest = interface(IInvokable)
    procedure baba1;
    procedure baba2;
    procedure baba...;
  end;

I looked source, the parameter aContractExpected can't achieve this effect,
set server and client's aContractExpected a same value will just close the contract check function.

thanks!

#43 mORMot Framework » interface contract check » 2014-11-12 15:30:56

mingda
Replies: 5

first create a interface,

  ITest = interface(IInvokable)
    procedure baba1;
  end;

after server and client register the interface, then use the interface, every is ok.
then we delivery the client, after sometime, we need add procedure to ITest,
so interface looks like this,

  ITest = interface(IInvokable)
    procedure baba1;
    procedure baba2;
    procedure baba...;
  end;

but when run old client, will generate interface contract check exception,
can make wise since the procedure baba1 parameter is not change, thanks!

For some interface register in application start, will cause application
can not auto update.

#44 Re: mORMot Framework » ZEOS + Firebird + Update-Problem » 2014-09-04 12:20:55

danielkuettner wrote:

Do you have a second mMORmot server-service? Or do you you have a second TSQLRESTServer?

No, a normal application not use mORMot, only use SynDB to connection DB.

#45 Re: mORMot Framework » ZEOS + Firebird + Update-Problem » 2014-09-03 01:11:39

another hint, since the TSQLDBConnectionProperties can has some connections in pool, if db server's problem cause one connection break, generally else connection should also break, In my a little background service, if exception occur, i simple clear the connection pool, then every things later will ok, perhaps not need recreate one connection, since other connecitons also possible have breaked.

      try
        fDMInvoiceAssessment.InvoiceAssessment;
      except
        fDMInvoiceAssessment.ClearConnectionPool;
        HandleException;
      end;

procedure TDMInvoiceAssessment.ClearConnectionPool;
begin
  fProps.ClearConnectionPool;
end;

#46 Re: mORMot Framework » ZEOS + Firebird + Update-Problem » 2014-09-02 13:51:11

Can if after a exception occur, we do a "ping" to check if the connection is break, if break then recreate it else do nothing, this will not affect perform, this method after one client operation failed, then succedent client operation will success, if can monitor exact connection broke exception, then will better, since there are many db connection method, check at TSQlDBConnectionProperties level should conformable.

#47 Re: mORMot Framework » ZEOS + Firebird + Update-Problem » 2014-09-02 00:42:41

I think perhaps the pool connection has broke, I has a application not use mORMot but use ADO, even at localhost after sometimes the pool connection possible broke due to various reason, then need restart the server application, see my before post and the interrelated ticket

http://synopse.info/forum/viewtopic.php?id=1630
http://synopse.info/fossil/tktview?name=f024266c08

#49 Re: mORMot Framework » 2014-08-15 TestSQL3 at 2nd, 4th, 6th... run has exception » 2014-08-17 07:44:15

ab wrote:

We may switch back to CRLF, or put an option for it...
What do you think?

This is not a big problem, just keep it simple is ok, for windows CRLF is prefer.

#50 Re: mORMot Framework » 2014-08-15 TestSQL3 at 2nd, 4th, 6th... run has exception » 2014-08-17 01:55:19

Thank you for the quick fix, TestSQL works now, the exception is gone.

A little problem, the log file content between lines now not have CRLF, only have CR in windows.

Board footer

Powered by FluxBB