#1 2015-04-11 13:25:08

ASiwon
Member
From: Poland
Registered: 2015-01-30
Posts: 82

Access Violation while creating client instance

Hello,

I have AV exception on the following code:

  FModel := TSQLModel.Create;
  FClient := TSQLRestClientDB.Create(FModel, nil, SQLITE_MEMORY_DATABASE_NAME, TSQLRestServerDB, False);

I know - this is stupid code because empty model is unusable, but I just need a client instance to create some unit tests. Even if model cannot be empty then it would be nice to get more comprehensible message than: Access Violation.

Last edited by ASiwon (2015-04-11 20:23:36)


best regards
Adam Siwon

Offline

#2 2015-04-12 06:33:57

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

Re: Access Violation while creating client instance

Use TSQLRestServer.CreateWithOwnModel() model if you want a "minimal" model.

I've enhanced TSQLRestServer.Create to intercept aModel=nil parameter as an explicit exception.
See http://synopse.info/fossil/info/91959008ae

Offline

#3 2015-04-12 06:56:04

ASiwon
Member
From: Poland
Registered: 2015-01-30
Posts: 82

Re: Access Violation while creating client instance

Use TSQLRestServer.CreateWithOwnModel() model if you want a "minimal" model.

Thank you very much for information. I will try this.

I've enhanced TSQLRestServer.Create to intercept aModel=nil parameter as an explicit exception.
See http://synopse.info/fossil/info/91959008ae

As you can see in attached code AModel parameter has not nil value. The Access Violation exception is raised in the following lines of the TSQLModel constructor:

constructor TSQLModel.Create(CloneFrom: TSQLModel);
var i: integer;
begin
  if CloneFrom=nil then
    raise EModelException.CreateUTF8('%.Create(CloneFrom=nil)',[self]);
  fTables := CloneFrom.fTables;
  fTablesMax := CloneFrom.fTablesMax;
  fRoot := CloneFrom.fRoot;
  fActions := CloneFrom.fActions;
  fEvents := CloneFrom.fEvents;
  fRestOwner := CloneFrom.fRestOwner;
  fSortedTablesName := CloneFrom.fSortedTablesName;
  fSortedTablesNameIndex := CloneFrom.fSortedTablesNameIndex;
  fRecordReferences := CloneFrom.fRecordReferences;
  fVirtualTableModule := CloneFrom.fVirtualTableModule;
  fCustomCollationForAllRawUTF8 := CloneFrom.fCustomCollationForAllRawUTF8;
  SetLength(fTableProps,fTablesMax+1);
  for i := 0 to fTablesMax do
    fTableProps[i] := TSQLModelRecordProperties.CreateFrom(
      self,CloneFrom.fTableProps[i]);
end;

TSQLModel is called from TSQLRestClientDB.Create constructor when AServerModel parameters has value nil. In the last instruction (for loop) is raised exception. Its because fTableMax variable has value 0 and for loop is executed one iteration. In this iteration CloneFrom.fTableProps[index] tries to get element of array which not exists. ANd here is AV raised.


best regards
Adam Siwon

Offline

#4 2015-04-12 07:16:53

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

Re: Access Violation while creating client instance

I do not understand why fTableMax variable has value 0 ?

All TSQLModel.Create constructors should set fTableMax with the proper value.

Offline

#5 2015-04-12 07:58:00

ASiwon
Member
From: Poland
Registered: 2015-01-30
Posts: 82

Re: Access Violation while creating client instance

I don't know why FTableMax has value 0. Probably after initialization. I just see if I execute following code:

  model := TSQLModel.Create;
  client := TSQLRestClientDB.Create(model, nil, SQLITE_MEMORY_DATABASE_NAME, TSQLRestServerDB, False);

it raises AV exception. Here is call stack

mORMot.TSQLModel.Create($13F6C78)
mORMotSQLite3.TSQLRestClientDB.Create($13F6C78,nil,$13FDDE0,TSQLRestServerDB,False)
mORMotSQLite3.TSQLRestClientDB.Create($13F6C78,nil,':memory:',TSQLRestServerDB,False,'')

I hope this helps.


best regards
Adam Siwon

Offline

#6 2015-04-12 10:15:48

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

Re: Access Violation while creating client instance

You should NOT use plain TSQLModel.Create constructor, but one of the reintroduced version.

model := TSQLModel.Create([]);

I've added an overloaded TSQLModel.Create method, raising an explict EModelException to ensure the proper Create() constructors are used.
See http://synopse.info/fossil/info/da792ff2f3

Offline

Board footer

Powered by FluxBB