#2 mORMot 2 » Using "PUREMORMOT2" I can no longer use VirtualTableExternalRegister » 2026-02-10 10:45:17

larand54
Replies: 2

I think I found a replacement - "TRestExternalDBCreate" but it requires "TSynConnectionDefinition" and I can not find out how to make it work with SQLServer.

#3 Re: mORMot 2 » How to create a server from IRestOrmServer » 2026-01-16 15:57:30

Ok, I think I understand so I did like this:

  fDBServer := TRestServerDB.Create(Model).Server;

And that made it!

Sorry but I have obviosly very hard to finds things in the doc. I always try to find things in the source and mostly I find it there but not too often.

#4 mORMot 2 » How to create a server from IRestOrmServer » 2026-01-16 15:05:42

larand54
Replies: 2

Obviosly I can not do like this:

// Some declarations:
  private
    fModel: TOrmModel;
    fDBServer: IRestOrmServer;
    fProps: TSqlDBOleDBConnectionProperties;

The init code:
  fModel := CreateLOBModel;
  ConnectDB(LOBMonSetupRec.DBServer, LOBMonSetupRec.Database, LOBMonSetupRec.UserName, LOBMonSetupRec.PassWord);
  VirtualTableExternalRegister(Model, TSQLLobUserControllv2, fProps, 'dbo.LobUserControllv2');
  VirtualTableExternalRegister(Model, TSQLLob_GroupUsers, fProps, 'dbo.Lob_GroupUsers');
  VirtualTableExternalRegister(Model, TSQLLobGroupDtl, fProps, 'dbo.LobGroupDtl');
  
  rs := TRestServerDB.Create(Model);
  fDBServer := TRestOrmServer.Create(rs); // Gives the exception: First chance exception at $77171E94. Exception class ERestException with message 'TRestServerDB.SetOrmInstance twice'.

// Never reach this  part cause of the exception
  DBServer.CreateMissingTables;

I can not use the TRestServerDB instance when I creates the fDBServer as both calls SetOrmInstance so, what type should I use?

#5 mORMot 2 » Replacement for FlushInternalDBCache in Mormot2 » 2026-01-13 12:01:20

larand54
Replies: 1

I'm trying to convert a mormot1-project to mormot2 and have a lot of questions.  Start here asking if there is a replacement of the function "FlushInternalDBCache" ?

#6 Re: mORMot 2 » Can not have a field with "Stored AS_UNIQUE" using the new OLEDB-drive » 2026-01-01 23:55:31

Problem now solved.
The error messages comes when the tables have no data, if you put data into the tables then there is no error about the "already existing index"

First run goes ok as the index does not exist and they will be created.
If the server are stopped before any data is stored on the table and then restarted again, the server checks if there is any existing index on the table it doesnt recognize that the table already got an an index so it try to create one again. But this time the database server (here MS SQL Server) finds an existing index and returns an error.

I wouldnt mind if this error message could be avoided in the future even if I never will forget it ;-)

#7 Re: mORMot 2 » Can not have a field with "Stored AS_UNIQUE" using the new OLEDB-drive » 2025-12-29 12:27:36

Very strange... I removed all tables from the database and then started the server again and all tables where created with index as they where before.
Then I closed the server and restarted again, now all tables gives error telling that: 'the index already exists'.

So... what I have I done wrong here? Without index everything works ok except I don't have any index on the tables.

#8 Re: mORMot 2 » Can not have a field with "Stored AS_UNIQUE" using the new OLEDB-drive » 2025-12-25 17:44:22

Ok, that was what I missed - the length.
Well after that I ran into next problem, It creates the index perfectly but if I close down the server and then start again, it gives the following error in 'CreateMissingTables':

0251225 17140140  ! ERROR mormot.db.raw.oledb.EOleDBException(02af0e90) {"EOleDBException(02af0e90)":{Message:"TSqlDBOleDBConnection: OleDB error [] (0x80040E14) -  
 (line 1): The operation failed because an index or statistics with name 'NDXCustomerCustomerID' already exists on table 'dbo.Customer'.\r\n",Statement:null}}
20251225 17140658  ! EXC   EOleDBException {Message:"TSqlDBOleDBConnection: OleDB error [] (0x80040E14) -  
 (line 1): The operation failed because an index or statistics with name 'NDXCustomerCustomerID' already exists on table 'dbo.Customer'.\r\n",Statement:null} [Main] at 01277edf   {24 65535.15 65535.28 12 15.6GB/31.3GB 23f00f01}

To have something to compare against I tok an example (\martin-doyle\04-InterfacedBasedServices) and made  the 'Name'-field unique. No problems there so I added another new table to the project, no problem there either.

Well then I decided to take my own table 'dbo.Customer' to the project. The two first tables worked as usual but my Customer-table still failed.

It look like this:

  TOrmCustomer = class(TOrm)
  private
    fName: RawUTF8;
    fCustomerID: RawUTF8;
    fCreateTime: TCreateTime;
    fModTime: TModTime;
  published
    property CustomerID: RawUTF8 index 50 read fCustomerID write fCustomerID stored AS_UNIQUE;
    property Name: RawUTF8 read fName write fName ;
    property CreateTime: TCreateTime read fCreateTime write fCreateTime;
    property ModTime: TModTime read fModTime write fModTime;
  end;

I have tried to debug but it is a bit too complex for me I think. At least I found that in the 'function TRestStorageExternal.CreateSqlMultiIndex' it fail's here:

    if not NeedDesc then
    begin
      // we identify just if indexed, not the order
      extfield := fFieldsInternalToExternal[IntFieldIndex[0] + 1];
      if (extfield >= 0) and
         (fFieldsExternal[extfield].ColumnIndexed) then
      begin
        result := true; // column already indexed
        exit;
      end;
    end;

The value of the field: 'ColumnIndexed' is 'false' , and therefore  it tries to create the index again.

I can't see no reason why this table fails where the other doesn't.

Need some help here. sad

#9 Re: mORMot 2 » Can not have a field with "Stored AS_UNIQUE" using the new OLEDB-drive » 2025-12-19 20:34:11

I Use Microsofts sql server  and there is no table in the database it should have been created by "CreateMissingTables".

#10 mORMot 2 » Can not have a field with "Stored AS_UNIQUE" using the new OLEDB-drive » 2025-12-19 16:08:03

larand54
Replies: 6

I get the following Error message:

Project TestExtDBConnection.exe raised exception class EOleDBException with message 'TSqlDBOleDBConnection: OleDB error [] (0x80040E14) -   (line 1): Could not create constraint or index. See previous errors.
  (line 1): Column 'CustomerID' in table 'Customer' is of a type that is invalid for use as a key column in an index.'.

The ORM-table:

  TOrmCustomer = class(TOrm)
  private
    fName: RawUTF8;
    fCustomerID: RawUTF8;
  published
    property Name: RawUTF8 read fName write fName;
    property CustomerID: RawUTF8 read fCustomerID write fCustomerID stored AS_UNIQUE;
  end;

Some code:

function CreateOSModel: TOrmModel;
begin
  result := TOrmModel.Create([TOrmCustomer]);
end;

var
  model: TOrmModel;
  props: TSQLDBConnectionProperties;
  RestServer: TRestServerDB;
begin
  model := CreateOSModel;
  Props := GetODBCDriverSpec.Create('MyServer', 'MyDB', '', '');

  VirtualTableExternalRegister(Model, TOrmCustomer, props, 'dbo.Customer');
  RestServer :=  TRestServerDB.Create(Model, ':memory:');
  RestServer.CreateMissingTables;             <<<---- Getting error here.

#11 Re: mORMot 1 » OSAuthentication in windows on MSSqlServer » 2025-12-17 20:44:56

Ok, I fixed things after I looked back into an old article by Stephan-Bester. He noted that you just need to set the Username to '' (void parameter) to make login possible without user and password.
So now I can relax without urgent need to move my old mormot1 projects to mormot2. Allthough it migtht happen later on.

#12 mORMot 1 » OSAuthentication in windows on MSSqlServer » 2025-12-17 15:02:56

larand54
Replies: 2

I read a post "https://blog.synopse.info/?post/2013/06 … horization"
Where I can read about "Authentication using Windows credentials" but I don't understand how it can be done.

It mentioned that any call to TSQLRestClientURI.SetUser() method with a void aUserName parameter will try to use current logged name and password to perform a secure Client-Server authentication..
What is a void parameter? is it just a blank string as: '' ?

Then there is a prerequisite that  the TSQLAuthUser table shall contain a corresponding entry, with its LogonName column equals to 'DomainNameUserName' value.
But how can this table be queried before the app logged in?

#13 mORMot 1 » New odbcdriver for MSSql win11 » 2025-12-10 16:04:20

larand54
Replies: 1

I've just installed windows11 on a new computer and had difficulties with mORMot1 and odbc-driver against latest MSSQL DB.

I had to add some code in SynOleDB:

{ TOleDBMSSQL2018ConnectionProperties }

procedure TOleDBMSSQL2018ConnectionProperties.SetInternalProperties;
begin
  if OSVersion>wVista then
    fProviderName := 'MSOLEDBSQL';
  inherited SetInternalProperties;
end;

Hope this is correct or...

#14 Re: mORMot 1 » SQLite static files again » 2025-12-02 18:10:58

Well, my library settings in delphi fooled me,
My library settings in delphi/mormot was ../mORMot/static and not ../mORMot/sqlite3/static as it was before.

In mORMot2 it is set as:
{$L ..\..\static\delphi\sqlite3.o} CPU64
{$L ..\..\static\delphi\sqlite3.obj} CPU32
And that worked as it was the same as in github.

But in mORMot1 it is:
{$L sqlite3.o} CPU64
{$L sqlite3.obj} CPU32

So I needed to put the files ../mORMot/static/ instead of ../mORMot/sqlite3/static as what you get when you pull  from github.

So... sorry my fault again.

#15 mORMot 1 » SQLite static files again » 2025-12-02 16:07:53

larand54
Replies: 2

Few weeks ago I pulled a new version of mORMot2 and got the message of SQLite outdated version, ok I downloaded the static files and I was back on track again.
Today I pulled the latest version of mORMot1 and tried to compile/run an older Mormot1 project but got the error message also this time.
I've downloaded the static files but still got the message. Then I renamed all versions of the files I found and tried compile/run again I still get the same message:

"Linked version is 3.44.2 whereas the current/expected is 3.46.1."

To me it seems to be an existing file left somwhere that is accessed but where can it be?
I have checked delphi settings and it looks all ok.

So I need some ideas what to do/look at.

Thank's in advance!

#16 mORMot 2 » Error in tbo:s example » 2025-11-15 05:39:32

larand54
Replies: 1

I am trying to help a friend using mORMot2 by giving him some examples but have hard to make some of them to work.

I thought I could use some of the examples in the "ex"-folder but failed to compile some of them.

Here I show the problems with tbo:s example:
04-HttpServer-InterfaceServices
This one I could make to work though:
TestRestClient.dpr

unit frm_Main;
    if FDocumentService.Client.SetUser(pmcUserName, TAuthUser.ComputeHashedPassword(pmcPassword), True) then             //  - Does not compile

I added pmcUserName:

    if FDocumentService.Client.SetUser(pmcUserName, TAuthUser.ComputeHashedPassword(pmcUserName,pmcPassword), True) then // - Compile

   
Have not found a solution for this:
TestRestServer.dpr
unit u_ServiceServer;

  if IsValidJson(json)
    and (DynArrayLoadJson(customers, json, TypeInfo(TCustomerItemArray)) <> Nil)// - Does not compile - "Incompatible types"

So I need some help to fix this code and wonder how this could happend?
Have mormot2 later updates caused this or have I missed something?

#17 Re: mORMot 2 » How to add a new json item into a jsonarray » 2025-11-12 03:03:34

That was a big difference! smile Perfect!
But I could not use _ObjFast I needed to change to  _JsonFast like:

 TDocVariantData(fOrderLines).AddItem(_JsonFast(RecordSaveJson(pmcOrderLine, TypeInfo(TOrderLine))));

That really helped, but what did you meen with "AdditemRtti() method?

#18 Re: mORMot 2 » How to add a new json item into a jsonarray » 2025-11-09 06:43:50

I couldn't give up compleatly and I found an article which helped me finally.
link: https://blog.synopse.info/?post/2024/02 … hi-and-FPC

I'll put my solution here but want to ask for comment on this solution and if there are better way to do it.

function TForm2.addMember(const pmcFam: TOrmFamily;
  const pmcMbr: TMember): boolean;
var
  Jss, js, js2: RawByteString;
  val: variant;
  list,list2: IDocList;
  Dict: IDocDict;
  f: TDocDictFields;

  DocVariant: TDocVariant;
  v: variant;
  doc: TDocVariantData;
begin
  Js := RecordSaveJson(pmcMbr, TypeInfo(TMember));
  val := _JsonFast(js);
  js2 := _JsonFast(pmcFam.Members);
  list := DocList(js2);
  List.Append(val);
  v := List.AsVariant;
    if list.Len > 0 then
    while list.PopItem(v) do
    begin
      assert(list.Count(v) = 0); // count the number of appearances
      assert(not list.Exists(v));
      Listbox1.Items.Add(v.Name); // late binding
      dict := DocDictFrom(v); // transtyping from variant to IDocDict
      // enumerate the key:value elements of this dictionary
      for f in dict do
      begin
        Listbox2.Items.Add(f.Key);
        Listbox3.Items.Add(f.Value);
      end;
    end;
end;

#19 mORMot 2 » How to add a new json item into a jsonarray » 2025-11-09 04:07:42

larand54
Replies: 9

Ive been working for hours to make it work search through google without finding anything that work. Google AI answers looks nice but they are compleatly wrong, all of them.
So I finally gave up and hope I can get an answer here.

Some code:

type
  TOrmFamily = class(TOrm)
    private
      fFamilyName: RawUTF8;
      fMembers: Variant;
    published
      property FamilyName: RawUTF8 read fFamilyName write fFamilyName;
      property Members: variant read fMembers write fMembers;
  end;
  TFamilyArray = array of TOrmFamily;

  TMember = Object//packed record
    Name: RawUTF8;
    Age: integer;
  end;
  
  fam1 := TOrmFamily.Create;
  fam1.FamilyName := 'Larson';
  fam1.fMembers := '';
  addFamily(fam1);

  mbr11.Name := 'Tommy'; mbr.Age := 45;
  addMember(fam1, mbr11);
  mbr12.Name := 'Linda'; mbr.Age := 43;
  addMember(fam1, mbr12);

function TForm2.addFamily(const pmcFam: TOrmFamily): boolean;
var
  ID: TID;
begin
  ID := Server.Server.orm.Add(pmcFam,true);
  result := ID > 0;
end;

function TForm2.addMember(const pmcFam: TOrmFamily;
  const pmcMbr: TMember): boolean;
var
  Jss, js: RawByteString;
  DocVariant: TDocVariant;
  v: variant;
  doc: TDocVariantData;
begin
end;

Expected result:
[{"name":"Tommy","age":45},{"name":"Linda","age":43}]]

It's no idea to show all tests i've done here but it is the function "addMember" where I like to make this work. It show some variables I used in my tests.

#20 Re: mORMot 2 » TRestServerFullMemory.SetOrmInstance twice » 2025-10-10 20:40:18

Super that worked! I easily get confused when there are so many options.

Now I have:

  Server := TRestServerDB.Create(fModel);
  fDBserver := Server.server;

and thats it!

#21 Re: mORMot 2 » TRestServerFullMemory.SetOrmInstance twice » 2025-10-10 15:38:13

I just want a handle that I can use to read and write data from a MSSQL database as I can in the old mormot.
I thought I could use the same code as I used in mormot1 but it doesnt look like that.
I've tried a lot of different ways but this is the closest I got. That's why it looks confusing.
I've tried to find any example about external databases but everything is about sqlite3 and I have no problems with that using sqlitebased mormot.

An example of code where I query the database in the old mssql/mormot-version can look like this:

 
    user := TOrmUsers.Create;
    user.FillPrepare(fDBServer, 'ID=?', [aUserID]);
    if user.FillOne then begin
      clientNo := user.companyNo;
      result := user.fFirstName + ' ' +user.LastName;
    end;

#22 mORMot 2 » TRestServerFullMemory.SetOrmInstance twice » 2025-10-10 14:45:53

larand54
Replies: 4

Try to work with MSSQL but fails using this code:

constructor TTest.create(const aConnection: TStrings);
var
  model: TOrmModel;
  connection: TsqlDBConnectionPropertiesClass;
  serverName, DBName, UserID, Passw: RawUTF8;
  rest: TRestServerFullMemory;
begin
  fModel := TOrmModel.Create([TOrmUsers], '');
  connection := GetODBCDriverSpec;
  serverName := aConnection.Values['Server'];
  DBName := aConnection.Values['Database'];
  UserId := aConnection.Values['User_Name'];
  Passw := aConnection.Values['Password'];
  fProps := connection.Create(serverName, DBName, UserID, Passw);
  VirtualTableExternalRegister(fModel, TOrmUsers, fProps, 'dbo.Users');
  fModel.Props[TOrmUsers].ExternalDB.MapField('ID', 'UserID');
  fModel.Props[TOrmUsers].ExternalDB.MapField('UserEmail', 'Description');
  rest := TRestServerFullMemory.create(fModel);
  fDBServer := TRestOrmServerDB.Create(rest); // <<--- occurs here!
  try
    fDBServer.CreateMissingTables;
  finally
  end;
end;

#23 Re: mORMot 2 » TSqlDBOleDBConnectionProperties not compatible » 2025-10-08 12:57:10

Thanks! I had missed a couple of units, after correcting that I could go on and now made it  work.

ODBC?... well I have used this type for many years and had no idea of that key. Is there some benefits by using OleDB keys?

I'll look at this later on.

#24 mORMot 2 » TSqlDBOleDBConnectionProperties not compatible » 2025-10-07 16:12:37

larand54
Replies: 2

I get the following error compiling the code below

E2010 Incompatible types: 'TSqlDBOleDBConnectionProperties' and 'class of TSqlDBOleDBMSSQL2012ConnectionProperties'

function TMMBaseDB.GetODBCDriverSpec: TOleDBConnectionProperties;
const
  ODBCDriverKey_2018 = '\SOFTWARE\ODBC\ODBCINST.INI\ODBC Driver 17 for SQL Server';
  ODBCDriverKey_2012 = '\SOFTWARE\ODBC\ODBCINST.INI\SQL Server Native Client 11.0';
  ODBCDriverKey_2008 = '\SOFTWARE\ODBC\ODBCINST.INI\SQL Server Native Client 10.0';
begin
  with TRegistry.Create do
    try
      RootKey :=  HKEY_LOCAL_MACHINE;  //2147483650;//
      if OpenKeyReadOnly(ODBCDriverKey_2012) then
      begin
        result := TOleDBMSSQL2012ConnectionProperties;
        CloseKey;
      end
      else if OpenKeyReadOnly(ODBCDriverKey_2008) then
      begin
        result := TOleDBMSSQL2008ConnectionProperties;
        CloseKey;
      end
      else
        result := TOleDBMSSQLConnectionProperties;
    finally
      Free;
    end;
end;

I can not understand this as it is declared in unit "mormot.db.sql.oledb" like:

TSqlDBOleDBMSSQL2012ConnectionProperties = class(TSqlDBOleDBMSSQLConnectionProperties)

Hope I can get some help solving this, the code is converted from an old mormot-1 unit, and it worked there.

This is my uses clause:

uses
  mormot.core.base
  , mormot.orm.base
  , mormot.orm.core
  , mormot.rest.server
  , mormot.db.sql.oledb
  , mormot.orm.sql
  , system.classes
  , Winapi.Windows
  ;

#25 Re: Free Pascal Compiler » Linking errors when compiling the example "httpServerFiles" on lazarus » 2024-10-15 12:27:22

Ok, I found the reason... The linker searches the path: "/home/larand/fpc-library/mORMot2/static/x86_64-linux" but of some reason I got all files directly under the "static" folder.
I could have looked up a bit better. roll

#26 Re: Free Pascal Compiler » Linking errors when compiling the example "httpServerFiles" on lazarus » 2024-10-15 11:01:30

Sorry I forgot to tell that I also added the static library. Here is what I got there:

larand@larand-VirtualBox:~$ ls fpc-library/mORMot2/static
crc32c64.o  libdeflatepas.a  quickjs.o  sha512-x64sse4.o
dev.sha256  liblizard.a      README.md  sqlite3.o
larand@larand-VirtualBox:~$ 

#27 Free Pascal Compiler » Linking errors when compiling the example "httpServerFiles" on lazarus » 2024-10-15 09:14:50

larand54
Replies: 4

Running Lazarus-3.6 on Ubuntu-20.04 using oracle vm.

I followed the instructions on GIT-ReadMe

"On Lazarus:

    Just open and compile the /packages/lazarus/mormot2.lpk package;
    and mormot2ui.lpk if needed.
"
And it executed without problem.

But when I tried to compile the example code I got the following messages:

Compile Project, Target: /home/larand/fpc-library/mORMot2/ex/http-server-files/exe/httpServerFiles: Exit code 1, Errors: 1, Warnings: 6
httpServerFiles.dpr(34,1) Warning: Library libdeflatepas.a not found, Linking may fail !
httpServerFiles.dpr(34,1) Warning: Object ../../static/x86_64-linux/sha512-x64sse4.o not found, Linking may fail !
httpServerFiles.dpr(34,1) Warning: Object ../../static/x86_64-linux/crc32c64.o not found, Linking may fail !
Warning: linker: /usr/bin/ld: cannot find ../../static/x86_64-linux/sha512-x64sse4.o: No such file or directory
Warning: linker: /usr/bin/ld: cannot find ../../static/x86_64-linux/crc32c64.o: No such file or directory
Warning: linker: /usr/bin/ld: cannot find libdeflatepas.a: No such file or directory
httpServerFiles.dpr(34,1) Error: Error while linking

It is probably something wrong with my setup of lazarus but I have no idea.

The reason for me to use ubuntu and lazarus is to create an application running on a PI-Zero2W having it to send messages over internet.
//LG

#28 mORMot 2 » Problems convert mormotDDD unit to mormot2 » 2024-07-22 11:25:01

larand54
Replies: 1

I try to convert the  "mormotDDD" unit to be used by mORMot2 because I like to use "CQRS" the way it is used in the old mormot DDD-example.

It seemed to be an easy task from the beginning but I'm stopped by a few things.

The TClassInstance is not available in mORMot2. It look like "TRttiClass" could be used here but it is not defined the same.
The "    property Aggregate: TClass read fAggregate.rttiClass ;" does not work as rttiClass is a function and not a field.

There are a few more things to fix but I think this is the most important to fix. The other may be solved easier when this is solved. Otherwise I'll come back and ask for more help.

#30 Re: mORMot 2 » How to make a flat table from a rather complex json » 2024-06-19 16:03:24

I'm not sure I understand the last sentence. I can show you the last part of the jsonfile if that helps.

            "DetaljReferens": [
              {
                "Referens": null, 
                "Referens_ReferensLista": "BSAB96:PR", 
                "Referens_ReferensKod": ""
              },
              {
                "Referens": null, 
                "Referens_ReferensLista": "SBEF:Byggdel", 
                "Referens_ReferensKod": "90"
              },
              {
                "Referens": null, 
                "Referens_ReferensLista": "PRODKOD", 
                "Referens_ReferensKod": ""
              }
            ]
          }
        }
      ]
    }
  }
}

#31 Re: mORMot 2 » How to make a flat table from a rather complex json » 2024-06-19 15:27:41

It has a fixed fields layout. I think it is created from a XML-file.
Just below 1MB > 24000 lines.
9 levels.

#32 mORMot 2 » How to make a flat table from a rather complex json » 2024-06-19 14:42:58

larand54
Replies: 6

The json file I got is a very big one with lot of levels and would normally be split up into several tables but I have been asked  to make one flat table of it.
To me it looks as very complicated task to solve so I would be happy to get some help to put me in the right direction.
I suppose that there are some very useful code in mormot. I've been looking a round a bit but it isn't that easy.

#33 Re: mORMot 2 » Can not make replication to work » 2023-11-06 12:32:59

I have another version written for Lazarus if that could be easier for someone to checkout.
https://gitlab.com/GIT-Testing/mormot-r … th-lazarus

This version works as bad as any other of my attempts to find a working solution.

Looks that it is not possible to have the real-time sync with this library.
//LG

#34 Re: mORMot 2 » Can not make replication to work » 2023-11-02 10:59:32

Please see my updated reply above.

It seems that it only works once after that I erase the user table first and then start the slave.
The data is copied from master to the slave just after the call:

fSlave.RecordVersionSynchronizeSlaveStart(TOrmUser, fMasterClient, nil);

But not after.

Very strange or...?

#35 Re: mORMot 2 » DynArrayLoadJson can not process the JSON with "a", "A" names data? » 2023-10-22 08:15:03

There is an error in the json structure
{
      "c": "28403.81000000",
      "a": "28420.61000000",
      "A": "0.00351000", <--- THIS COMMA is not valid here.
   },

You can use this link: https://jsonlint.com/
Best regards
//LG

#36 Re: mORMot 2 » Can not make replication to work » 2023-10-21 09:44:53

Hello ab,
I've already checked out that code and I did a new attempt with a small testproject but still fail.
I have this project available as a zip-file but I don't find any way to share that. PasteBin doesn't seem to to be used with anything but sourcefiles.
Any idea how I can share this file?

I have the project on GITLAB if it could work?
https://gitlab.com/GIT-Testing/test_mor … cation.git

I made a small program that more or less copies the code you have in your test suite.

https://paste.ee/p/cZ9sA

That code works but the difference is that I don't use services here. When simulating changes in the master table I do it directly through the TRestServerDB instance.

But in the real world I need to use services and then I need 2 different http-channels, one for update the table on the master and one for the replication.
And this case don't work for me. See the the GITLAB-project above.
I'm sure that I have misunderstood how to do this correct but I'm also sure it must be someone, that have a working solution of a similar system like mine, that could see what I've done wrong or..?

Otherwise I have to develop a compleatly different solution on my own :-(
Please help.

#37 Re: mORMot 2 » Can not make replication to work » 2023-10-13 11:14:35

No answer in a week, I hoped to find some anwer here at least a comment if some necessary information is missing.
I tried to find a solution myself and I feel that I've done what is needed but in spit of that, no success.
I don't believe that this function is incomplete or not functional in mORMot2 but it looks so to me. sad

#38 mORMot 2 » Can not make replication to work » 2023-10-05 10:04:15

larand54
Replies: 6

Only when the master server is restarted the sync works but only once.

In the slave log I can see the following repeated five times:

2023-10-05 09:24:14.640	Debug	    mormot.rest.sqlite3.TRestServerDB(035da1e0) RecordVersionSynchronizeSlaveStart(TORMUser) current=19 Subscribe(036ec488)
2023-10-05 09:24:14.640	Enter	    mormot.soa.client.TServiceFactoryClient(036fac98).InternalInvoke IServiceRecordVersion.Subscribe("User",19,1) 
2023-10-05 09:24:14.640	Enter	       mormot.rest.http.client.TRestHttpClientWebsockets(03d93730).InternalUri POST
2023-10-05 09:24:14.640	Trace	          mormot.rest.http.client.TRestHttpClientWebsockets(03d93730) InternalRequest POST calling THttpClientWebSockets(03d939a0).Request
2023-10-05 09:24:14.640	Client	          mormot.rest.http.client.TRestHttpClientWebsockets(03d93730) POST DHSSync/ServiceRecordVersion.Subscribe status=200 len=18 state=1
2023-10-05 09:24:14.640	Leave	       00.003.082
2023-10-05 09:24:14.640	Service return	       mormot.soa.client.TServiceFactoryClient(036fac98) {"result":[false]}

and then  I get an error:

2023-10-05 09:24:14.704	Error	    mormot.rest.sqlite3.TRestServerDB(035da1e0) RecordVersionSynchronizeSlaveStart(TORMUser): retry failure 

The code in the slave looks like this:

procedure TForm5.btnSynchronizeClick(Sender: TObject);
  function setUpSyncServer: TRestServerDB;
  begin
    result := TSQLRestServerDB.Create(CreateSyncModel, ChangeFileExt(Executable.ProgramFileName, '.db'));
    result.DB.Synchronous := smOff;
    result.DB.LockingMode := lmNormal;
    result.Server.CreateMissingTables;
  end;


begin
  if not fSyncRunning then
  begin
    btnSynchronize.Caption := 'Stopp Synk';
    fSyncServer := SetUpSyncServer;
    fHttpClientSync := TRestHttpClientWebSockets.Create('127.0.0.1', '8888', CreateSyncModel);

    fSyncServer.RecordVersionSynchronizeSlaveStart(TORMUser, fHttpClientSync);
    fSyncRunning := true;
  end
  else
  begin
    btnSynchronize.Caption := 'Synka';
    fSyncServer.RecordVersionSynchronizeSlaveStop(TORMUser);
    freeAndNil(fSyncServer);
    freeAndNil(fHttpClientSync);
    fSyncRunning := false;
  end;

end;

The master part:

function setUpOrmSyncServer: TRestServerDB;
begin
  result := TRestServerDB.Create(CreateSyncModel, ChangeFileExt(Executable.ProgramFileName, '.db'));
  result.DB.LockingMode := lmNormal;
end;

begin
  OrmSyncServer := setUpOrmSyncServer;
  HttpSyncServer := TRestHttpServer.Create('8888', [OrmSyncServer], '+', UseBidirSocket,4 );
  OrmSyncServer.RecordVersionSynchronizeMasterStart;

So I just wonder, What am I missing?

#39 Re: mORMot 2 » Examples on how to find an object in a dynamic array » 2023-07-28 14:10:23

Ok, I've done that already but as the array can contain several hundreds of object in the worst case I thought that using a dynamic array could be more effective.
In this case, load and response time is not an issue but I like to be more effective and I can think of cases where this could be an issue.
And why not to be prepared?

#40 mORMot 2 » Examples on how to find an object in a dynamic array » 2023-07-28 09:36:50

larand54
Replies: 3

I have a class that contains an array where I need to find a certain object in this array as I want to update this certain object.

I've tried to find examples of how to do this but still failed so my hope is that someone could have such an example to show how this could be done.

Thanks in advance!

#41 mORMot 2 » IRestOrm.add don't report duplicate error » 2023-05-26 07:11:00

larand54
Replies: 2

I would like to inform the client when trying to add an already existing record.
But the exception from sqlite3 is not forwarded. The call IRestOrm.add just return zero and the exception can only be seen in the server log.

How could I solve this?

#42 Re: mORMot 2 » Problem adding object to an ObjArray in a service. » 2023-05-12 09:08:12

Thanks Thomas, excelent solution even though it didn't help eliminate the invalid pointer operation.

Thanks ab, your comment woke me up, I asked myself why I use the whole objects in the parameter list when I only need the ID:s.
So I replaced those parameters with the id:s of the objects and now everything is alright again. smile

#43 mORMot 2 » Problem adding object to an ObjArray in a service. » 2023-05-11 20:56:10

larand54
Replies: 3

I have two classes TArticle and TSubProject. A SubProject can contain several articles.
Articles can be added by demand to the subproject.

I'm using "ObjArrayAdd" to add new articles to the subproject.
Like: ObjArrayAdd(aSubP.Articles, aArticle);

But that's not allowed - I get this message from delphi: "Constant object can not be passed as var parameter"

So I tried to use an intermediate variable and that calms delphi but executing the program gives me another error:
"Invalid pointer operation" when the function exits. But the database is updated then.

I' understand that I do something really wrong but how should I do?

The repository:

 
function TDHSSyncRepository.addArticleToSubProject(var aSubP: TSubProject;
  out aArticle: TArticle): TSyncRepoError;
var
  s: TArticleObjArray;
begin
  if RetrieveArticle(aArticle) <> srSuccess then begin
    result := srNotFound;
    exit;
  end;
  Result := srNotFound;
 // ---                         --> ObjArrayAdd(aSubP.Articles, aArticle); <<--- "Constant object can not be passed as var parameter
  s := aSubP.Articles;         //  <<---- Do this instead
  ObjArrayAdd(s, aArticle);  // << -- Works but gives "Invalid operation"
  aSubP.Articles := s;         //
 end;

Best regards,
LarsG

#44 Re: mORMot 2 » At client startup - Interface not found fInterfaces.FindHashed(aUri) » 2023-05-09 12:26:22

Oh, I got your answer while I was writing.

Yea, I can see now!

Maybe I was not completely wrong about the parameter..?
I took the code from an example just to get a kickstart for testing.
I should be more careful.

Thank's a lot!

#45 Re: mORMot 2 » At client startup - Interface not found fInterfaces.FindHashed(aUri) » 2023-05-09 12:05:29

Sorry, I found the problem. It's of course my mistake. I misunderstood the usage of the parameter "ContractExpected". It looks like it should have the same name as the service without the leading 'T'. I got the impression of that this parameter is used to make it possible of same version control of the interface. So if you add a new or changed a method you could change this parameter and in that way you get a signal if you have different versions between client and server.

Strange is that I'm sure I had a different name for this parameter from the beginning without any problem.

Sorry I bothered you with this.
Best regards
Lars-G.

#46 Re: mORMot 2 » At client startup - Interface not found fInterfaces.FindHashed(aUri) » 2023-05-09 10:51:41

To make a simple test client I added the following code:

procedure TForm4.FormCreate(Sender: TObject);
begin
  Model := TOrmModel.Create([],SYSTEMLocalROOT);
  HttpClient := TRestHttpClient.Create(IP_Local, HTTP_PORT, Model);
  HttpClient.ServiceDefine([IDHSLocalService], sicShared, DHS_LOCAL_CONTRACT);
  HttpClient.Services[DHS_LOCAL_CONTRACT].Get(fDHS_LocalService);
end;

In the function "TServiceContainerClientAbstract" the parameter aInterfaces contains one interface "IDHSLocalService" which is correct here. I' only use one interface so far.


The call "fHash.FindOrNew(fHash.HashOne(@Item), @Item, nil);" with Item as 'DHS_LOCAL_CONTRACT' returns -161.
This lead to that he interface pointer will be nil.
I'm not sure how to reproduce with a RawUTF8 list of interface. Where should I put the call?

#47 mORMot 2 » At client startup - Interface not found fInterfaces.FindHashed(aUri) » 2023-05-09 08:45:18

larand54
Replies: 5

Suddenly my testclient crashed at start with an access violation in this call: "HttpClient.Services[DHS_LOCAL_CONTRACT].Get(fDHS_LocalService);"
Debugging showed that the function "fInterfaces.FindHashed(aUri)" returns -1.

I've just added a method to the interface, recompile both the server and client and then this happened. I also removed those changes but still the same problem.
Something else must have been changed but I can't imagine what it could be.

I need some idea of where to start looking. sad

#48 Re: mORMot 2 » IList<T> in services » 2023-05-07 10:36:38

I solved it by replacing IList with an ordinary dynamic array for the service. It requires some more coding but it works. I kept using IList in the repository though as I can initiate the collection in the service before calling the repository methods.

It seems to require too much effort to be worth solving ?

#49 mORMot 2 » IList<T> in services » 2023-05-06 09:31:38

larand54
Replies: 3

I'm very fond of IList but I'm trapped by the fact that I have to declare it as a constant in the parameter list on a service method.
So there is no way to initialize it. sad

I'm sure that there is a solution to this but at the moment I'm lost.

#50 Re: mORMot 2 » Multiple field index » 2023-05-06 09:21:06

That looks good, I will soon test it.

Board footer

Powered by FluxBB