You are not logged in.
Can these two VMs PING each other?
The tests are made in the same machine both server and clients so there's actually no need to separate them.
The server freezes if there's two clients or more.
I've tried switching between TServiceInstanceImplementation values :
sicSingle, sicShared,sicPerThread but the same behaviour.
On my laptop it works perfectly but on some physical machines the clients number is restricted in 1 or 2.
There is something strange.
Hi all,
I've a strange behavior of an SOA service witch works perfectly on physical machine but gives request timeout under virtual one.
May be some parameter for the vm.
Here some informations :
The timeout message appears only when working in concurrential mode (2 clients or more for the same call), it looks like the vms don't allow multithreading.
D11, mormot 2.2, two VMs win10 under Hyper-V and Proxmox same behaviour.
Regards,
Hello,
You're right AB I used plain TDate which is supported as float. Now I change it to TDateTime and it works.
Thnx,
Hi,
mormot1 was handling Tdate/TDateTime as text in database and we can filter on with some funtions like here https://synopse.info/forum/viewtopic.php?id=4909
but in mormot2 it's handled as float and some of these functions aren't available.
How we can filter on a Tdate/TDateTime field on mormot2 ?
Regards,
You're right, the VM doesn't have acces to the Internet, now all tests passed successfully.
Thank you AB.
Hi all,
I've tested the mormot v2.2 under Delphi12 and windows 10 and I got some failling regression tests :
1.2. Core process:
...
! - Encode decode JSON: 3 / 578,038 FAILED 1m03
! - Mustache renderer: 5 / 62 FAILED 7m00
...
Total failed: 8 / 936,795 - Core process FAILED 8m04
Regards,
The basic usage is to create a TDataSet compatible class either from JSON or SynDB binary serialization.
From a TSQLRestClientURI, you can use the RetrieveListJSON() method to return some JSON, then fill a TDataSet from it using e.g mormot's SynDBVCL.pas.
See "17 - TClientDataset use" sample folder.
Thank you for the fast answer, I'll check this.
Hi,
How to implement a client side synchronization with TSynRestDataset as described here https://synopse.info/files/html/Synopse … #TITLE_267
AFAIK , TSynRestDataset does not have any TSQLRestClientURI property.
Thanks,
Win10, Delphi 10.4.2, mormot v 1.18.6249
@radexpol
Thanks for the answer, I'll explore your solution asap.
Nice, i'm in the same situation and have a huge business application developed with firebird and UIB components.
Needs :
Use the app over vpn network whitch is a nigthmare because firebird protocol is to much slower
Have a possibility of changing the RDBMS to meet some customers obligations like MS SQL or POSTGRESQL
Problems :
The app is about 10 years development and we can't refactor it quickly to adopt mormot and enjoy its many advantages
DB layer is hardly coded with a lot of SQL queries.
@radexpol
Can your solution resolve some points of my needs ?
Regards,
Hello,
I've compiled the "10 - Background Http service" under lazarus and it installs and runs fine, when i moved the example folder to another folder i modified the project paths like this :
-Fu : ..\..\..\ccr\mORMot;..\..\..\ccr\mORMot\SQLite3
-Fi : ..\..\..\ccr\mORMot;..\..\..\ccr\mORMot\SQLite3;$(ProjOutDir)
-FU : ..\..\..\ccr\mORMot\static\$(TargetCPU)-$(TargetOS)
The projects compile well but when trying to install ther service with this :
httpservicesetup /install
I got this error :
An unhandled exception occurred at $0000000100060905:
EAccessViolation: Access violation
$0000000100060905 INIT, line 49759 of ../../../ccr/mORMot/SynCommons.pas
$000000010006216E INIT, line 50603 of ../../../ccr/mORMot/SynCommons.pas
$0000000100074598 CREATE, line 58986 of ../../../ccr/mORMot/SynCommons.pas
$000000010007A45D INITSYNCOMMONSCONVERSIONTABLES, line 63292 of ../../../ccr/mORMot/SynCommons.pas
$000000010007A6B0 SYNCOMMONS_$$_init$, line 63340 of ../../../ccr/mORMot/SynCommons.pas
$000000010000D3BC
$0000000100001E22 main, line 23 of httpserviceSetup.dpr
$0000000100001F76 main, line 35 of httpserviceSetup.dpr
$0000000100013550
$0000000100001DC7
$00007FFC4E3D7974
$00007FFC4E51A271
There is no log file generated.
Environnement : Fpcupdeluxe_v1.6.4, lazarus 2.1.0, FPC 3.3.1, SVN Revision : 62372 and mORMot version of yesterday.
Regards,
Ok great that works without spaces/linefeeds.
I'll test your proposation about REST service.
Thank you AB.
I think the problem is at line 28828 of mormot.pas
P := GotoNextJSONObjectOrArray(Beg);
for the example above, this command returns the next jsonobject for the two first objects, but for the last one it retuns a null pointer what is normal and abort the post process with the exception "Wrong POST".
It sounds pretty unsafe to do so on production anyway...
Anyone with the URI could break your data...
What is the safe way to invoke a batch from a javascript client to prevent breaking data?
Regards,
Hi,
I am trying to send a batch insert with postman to the sample 04- HTTP Server, but I get "TSQLRestServerDB.EngineBatchSend: Wrong POST" and only 2 inserted records for this example :
URI : localhost:8080/root/samplerecord/batch
{"samplerecord":["POST", { "Time": "135504637423","Name": "Name1","Question": "Question1"},
"POST", { "Time": "135504637423","Name": "Name2","Question": "Question2"},
"POST", { "Time": "135504637423","Name": "Name3","Question": "Question3"}
]
}
It seems like my json file is not complete.
Regards,
I apologize for my last message, and I promise you that it will not happen again.
But I stumble on the problem and my knowledge on the different types of installation of FPC are limited.
Please can someone give me a start to solve my problem?
Thnx,
I've installed laz4android1.7.0-53387-FPC3.1.1 and get the same error but when i've istalled newpascal with lazarus 1.9 and fpc 3.1.1 all work fine.
I find a différence between the two files and don't understand why !
typinfo.pp from laz4android1.7-FPC3.1.1
{
This file is part of the Free Pascal run time library.
(EDITED / TRUNCATED)
Thnx for the answer
Hi all,
I've installed laz4android with LAMW laz4android1.8.0-FPC3.0.4 and the latest mormot sources version '1.18.4779',
the sample 27 - CrossPlatform Clients\FPC compiles well, but i get this error with the 01 - In Memory ORM .
Perhaps i need some things on the typinf.pp.
Regards,
Ok, thank you.
Hi,
I'm planning to use mormot on a new production project and i want to know what's the best RDBMS from those supported by mormot.
The prject requirements are :
about 30 client connections
Mixed ui clients between delphi, web and mobile
the system must be operational about 24/24 h and 7/7 without any latency.
Maximum size of the db is about 10 Gb.
Regards,
Yes ab you're rigth, my parameters are not ok. now it works fine.
Thanks,
Is there at least a Project19Server.db3 file with such a table?
Yes there is a biolife table on the db file as shown with sqlitemanager addon for firefox
Note also that only a single process can access the .db3 file at the same time.
Are you sure no other process has currently opened it? For instance, the 19 sample service?
Yes i'm sure because i've copied the .db3 into the sysndbexplorer folder as shown on the config file here
[
{"RowID":1,"Ident":"Project19Server","Connection":5,"Server":"","Database":"E:\\Projets\\composants\\mORMot\\SQLite3\\Samples\\12 - SynDB Explorer\\Project19Server.db3","UserName":"","Password":"","TableNames":"BAoA","ForeignKeys":"AwAAAAAAAAAaAEAA4+FjAAA="}]
Thank you for the answer,
Hello all,
I got a ESQLite3Exception with message 'Error SQLITE_ERROR (1) [select * from biolife] using 3.19.2 - no such table: biolife, extended_errcode=1' when trying to connect to the "Project19Server.db3" with SyndbExplorer.
After selecting the db file, no tables names appear on the table tab.
here is the config file of syndbexplorer :
[
{"RowID":1,"Ident":"Project19Server","Connection":5,"Server":"","Database":"E:\\Projets\\composants\\mORMot\\SQLite3\\Samples\\19 - AJAX ExtJS FishFacts\\Project19Server.db3","UserName":"","Password":"","TableNames":"BAoA","ForeignKeys":"AwAAAAAAAAAaAEAA4+FjAAA="}]
Regards,
Hello all,
I've developped with lazarus a program that runs well under wince 6, but now the same program those not run under wince7 and gives this error "an unhandled exception occurred at $00012300: EAccessViolation ...." at startup. Is anyone ever encountered this problem ?
Lazarus 1.4, device is symbol MC32N0 with a cortex-A9-OMAP4430-800MHz
thank you for helping me even if it's off topic
Regards,
Thank you AB,
But this can affect the performance. I'll try to have an idea about response time.
Hi all,
I want to use mormot on an existing project which uses delphi and firebird engine. I want to use mormot for the new features as stated in § "1.4. Legacy code and existing projects" of documentation and move little by little.
The question is : can mormot server see modifications applied on the firebird database with the existing project ? I know that mormot by design can't do that but how can I get around ?
thnx,
Good information.
Hi,
For the moment I set this property on database, but you can create a UI for admin only where you can update this visibility.
hi mariomoretti,
this is the code of the class :
TSQLMenus = class(TSQLRecord)
protected
fTable: RawUTF8;
fCustomCaption: PResStringRec;
fCustomHint: PResStringRec;
fSelect: RawUTF8;
fSQLWhere : RawUTF8;
fGroup: integer;
fOrdre : integer;
fFieldWidth: RawUTF8;
fFieldAlign: RawUTF8;
fShowID: boolean;
fOrderFieldIndex: integer;
fReverseOrder: boolean;
fLayout: TSQLListLayout;
fListWidth: integer;
fNoReport: boolean;
fAutoRefresh: boolean;
fEditFieldHints: PResStringRec;
fEditExpandFieldHints: boolean;
fEditFieldNameWidth: integer;
fEditFieldNameToHideCSV: RawUTF8;
fEditFieldHintsToReport: boolean;
fVisible : boolean;
published
property TableName: RawUTF8 read fTable write fTable;
property Selection: RawUTF8 read fSelect write fSelect;
property SQLWhere : RawUTF8 read fSQLWhere write fSQLWhere;
property Groupe: integer read fGroup write fGroup;
property Ordre : integer read fOrdre write fOrdre;
property FieldWidth: RawUTF8 read fFieldWidth write fFieldWidth;
property FieldAlign: RawUTF8 read fFieldAlign write fFieldAlign;
property ShowID: boolean read fShowID write fShowID;
property OrderFieldIndex: integer read fOrderFieldIndex write fOrderFieldIndex;
property ReverseOrder: boolean read fReverseOrder write fReverseOrder;
property Layout: TSQLListLayout read fLayout write fLayout;
property ListWidth: integer read fListWidth write fListWidth;
property NoReport: boolean read fNoReport write fNoReport;
property AutoRefresh: boolean read fAutoRefresh write fAutoRefresh;
property EditExpandFieldHints: boolean read fEditExpandFieldHints write fEditExpandFieldHints;
property EditFieldNameWidth: integer read fEditFieldNameWidth write fEditFieldNameWidth;
property EditFieldNameToHideCSV: RawUTF8 read fEditFieldNameToHideCSV write fEditFieldNameToHideCSV;
property EditFieldHintsToReport: boolean read fEditFieldHintsToReport write fEditFieldHintsToReport;
property Visible : boolean read fVisible write fVisible;
public
property Operation : TRecOper read fOperation write fOperation;
end;
This is the code of the main unit :
var globalClient: TSQLHttpClient;
globalModel: TSQLModel;
function CopyFromFileTabs:boolean;
var i : integer;
begin
result := false;
SetLength(menuTabs, length(FileTabs));
for i:=Low(FileTabs) to high(FileTabs) do
begin
menuTabs[i].Table := FileTabs[i].Table;
menuTabs[i].Select := FileTabs[i].Select;
menuTabs[i].SQLWhere := FileTabs[i].SQLWhere;
menuTabs[i].Group := FileTabs[i].Group;
menuTabs[i].FieldWidth := FileTabs[i].FieldWidth;
menuTabs[i].FieldAlign := FileTabs[i].FieldAlign;
menuTabs[i].ShowID := FileTabs[i].ShowID;
menuTabs[i].OrderFieldIndex := FileTabs[i].OrderFieldIndex;
menuTabs[i].ReverseOrder := FileTabs[i].ReverseOrder;
menuTabs[i].Layout := FileTabs[i].Layout;
menuTabs[i].ListWidth := FileTabs[i].ListWidth;
menuTabs[i].NoReport := FileTabs[i].NoReport;
menuTabs[i].AutoRefresh := FileTabs[i].AutoRefresh;
end;
result := True;
end;
procedure TMainForm.FormCreate(Sender: TObject);
var menuTabs : array of TFileRibbonTabParameters;
menu : TSQLMenus;
begin
try
menu := TSQLMenus.CreateAndFillPrepare(globalParam, 'visible=? order by ordre', [True]);
while menu.FillOne do
begin
SetLength(menuTabs, length(menuTabs)+1);
with menuTabs[high(menuTabs)] do
begin
Table := globalModel.Table[menu.TableName];
Select := menu.Selection;
SQLWhere := menu.SQLWhere;
FieldWidth := menu.FieldWidth;
FieldAlign := menu.FieldAlign;
Group := menu.Groupe;
ShowID := menu.ShowID;
OrderFieldIndex := menu.OrderFieldIndex;
ReverseOrder := menu.ReverseOrder;
Layout := menu.Layout;
ListWidth := menu.ListWidth;
NoReport := menu.NoReport;
AutoRefresh := menu.AutoRefresh;
end;
end;
finally
menu.Free;
end;
LoadImageListFromEmbeddedZip(ImgListe32,'buttons.bmp');
ImageListStretch(ImgListe32,ImgList16);
if length(menutabs) = 0 then
begin
if CopyFromFileTabs then
Ribbon := TSQLRibbon.Create(self, nil, nil, ImgListe32, ImgList16,
globalClient, ALL_ACCESS_RIGHTS, ValueText, globalClient.OnSetAction, sFileActionsToolbar,
sFileActionsHints, nil, ActionClick, integer(faRefresh), 1, false,
length(menutabs), @menutabs[0], sizeof(menutabs[0]),
sFileTabsGroup, ',BannerData,BannerSafe',true)
else
Ribbon := TSQLRibbon.Create(self, nil, nil, ImgListe32, ImgList16,
globalClient, ALL_ACCESS_RIGHTS, ValueText, globalClient.OnSetAction, sFileActionsToolbar,
sFileActionsHints, nil, ActionClick, integer(faRefresh), 1, false,
length(FileTabs), @FileTabs[0], sizeof(FileTabs[0]),
sFileTabsGroup, ',BannerData,BannerSafe',true);
end
else
Ribbon := TSQLRibbon.Create(self, nil, nil, ImgListe32, ImgList16,
globalClient, ALL_ACCESS_RIGHTS, ValueText, globalClient.OnSetAction, sFileActionsToolbar,
sFileActionsHints, nil, ActionClick, integer(faRefresh), 1, false,
length(menutabs), @menutabs[0], sizeof(menutabs[0]),
sFileTabsGroup, ',BannerData,BannerSafe',true);
Ribbon.ToolBar.Caption.Caption := Caption;
Ribbon.ToolBar.HelpButton.OnClick := HelpClick;
for P := 0 to high(Ribbon.Page) do
with Ribbon.Page[P] do
if Lister<>nil then
begin
Lister.Grid.OnDblClick := ListDblClick;
end;
end;
procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
var menu : TSQLMenus;
i : integer;
old : boolean;
Results: TIntegerDynArray;
begin
try
menu := TSQLMenus.Create();
if globalClient.TransactionBegin(TSQLMenus, 20) then
try
if globalClient.BatchStart(TSQLMenus) then
begin
for i:=low(menuTabs) to high(menuTabs) do
begin
old := False;
menu.FillPrepare(globalParam, 'TableName=?', [menuTabs[i].Table.SQLTableName]);
old := menu.FillOne;
menu.TableName := menuTabs[i].Table.SQLTableName;
menu.Selection := menuTabs[i].Select;
menu.SQLWhere := menuTabs[i].SQLWhere;
menu.Groupe := menuTabs[i].Group;
menu.Ordre := i;
menu.FieldWidth := menuTabs[i].FieldWidth;
menu.FieldAlign := menuTabs[i].FieldAlign;
menu.ShowID := menuTabs[i].ShowID;
menu.OrderFieldIndex := menuTabs[i].OrderFieldIndex;
menu.ReverseOrder := menuTabs[i].ReverseOrder;
menu.Layout := menuTabs[i].Layout;
menu.ListWidth := menuTabs[i].ListWidth;
menu.NoReport := menuTabs[i].NoReport;
menu.AutoRefresh := menuTabs[i].AutoRefresh;
menu.Visible := True;
if not old then
globalClient.Add(menu, True)
else
globalClient.Update(menu);
end;
globalClient.BatchSend(Results);
end;
globalClient.Commit(0);
except
globalClient.RollBack(0);
end;
finally
menu.Free;
end;
end;
For the moment I hide menu manually by editing the visibile property on the table. For the future I want to add the ability of selecting menus to each user.
The easy way is to define a dynamic array of TFileRibbonTabParameters that you fill only with the visible tables.
Personally I do that to persist the menu with possiblity of hiding some tables.
I found remotevcl url on the web archive http://web.archive.org/web/201111142137 … tcp.rmtvcl
Hi AntonE,
I think that is a very good idea and can give us the possibility to build true thin clients (or Universal ) with delphi. All the code source is on the server side and the thin client brings it to build the app at runtime.
These are some benefic points that I see :
1) Easy deployement for projects and updates (only on the server side) either for the .pas files than UI;
2) Universal client, the same for different projects;
3) Projects are customizable (different between users/customers);
4) There is no need to compile the source juste for UI modification;
and many others ...
The universal client is a dream for me for some years ago when I discovered the AS400 OS for the first time, because we don't have to deploy all apps on all client machines, juste the TN5250 must be installed to have the access to this famous plateform then apps/envirennoments are configured on the server side.
The universal client that I've in minde is the same as TN5250 but with UI, one time the user is logged on, he must chose the project to open from available projects.
I saw some tentative like the remotevcl from Paul TOTH, and thin client based on plugins (bpl) stored on firebird database but I can't find urls.
thnx a lot for sharing,
You can see this thread for a sample http://synopse.info/forum/viewtopic.php?id=164
No, you must declareTSQLOrdereItems explecitly inheriting from tSQLRecordmany then maintain the has many relationship manually with some dedicated functions.
Ok I understand, thx to all.
@A.B : on the client side or server side ?
@edwinsn : Yes wat I want is before adding a TSQLRecord.
Hi,
I'm about making an invoice system and I've the invoice number composed by the date and an increment, my idea is to retrieve the new ID value and compose the invoice number. Is it possible ?
Thnx,
Very well, it works fine thanks a lot
Hi,
I've changed the TLabelEdit with the tntEdit to be able to put/show some arabic chars but I get '?' chars either in the tntEdit and in the database. When I put the arabic text directly with Sqlite database browser, it appears correctly on the MainDemo DrawGrid but not on the tntLabel ! What I'm doing wrong here ?
D7, win8, SQLite3
thnx,
Many thx
Hi all,
I need to know if a class A has a field inherited from TSQLRecordMany.
Hi AB,
I've convert the TMemoryStream to TStringStream and that works fine with U2S on the loadfromStream function
function TF_Etat.LoadFromStream():boolean;
var Stream : TStringStream; <---------------------------------- Modification
begin
if not globalClient.RetrieveBlobFields(fEtat) then
begin
result := False;
exit;
end
else
result := True;
try
Stream := TStringStream.Create(u2S(fEtat.Etat)); <----------------- Conversion u2s
//WriteStringToStream(Stream, fEtat.Etat);
if (Stream.Size > 0) and (fEtat.Etat <> '') then
begin
Stream.Position := 0;
frxReport.LoadFromStream(Stream);
frxReport.ShowReport();
end
else
result := False;
finally
Stream.Free;
end;
end;
Thnx
Yes, and the exe created a new db file.
I've changed the TSQRawBlob by RawUTF8 but it doesn't work for me, I've already this following line on the save function
fEtat.Etat := S2U(Stream.DataString);
I think that because of this line that I got that "Libelé", now we need to convert U2S for this line
WriteStringToStream(Stream, fEtat.Etat);
The class :
TSQLEtat = class(TSQLRecord)
private
fLibelle : RawUTF8;
fFiche : RawUTF8;
fEtat : TSQLRawBlob;
published
property ManCode : RawUTF8 index 10 read fManCode write fManCode stored AS_UNIQUE;
property Fiche : RawUTF8 index 20 read fFiche write fFiche;
property Etat : TSQLRawBlob read fEtat write fEtat;
end;
The function to save the report :
function TF_Etat.frxDesigner1SaveReport(Report: TfrxReport;
SaveAs: Boolean): Boolean;
var Stream: TRawByteStringStream;
fEtat : TSQLEtat;
begin
try
fEtat := TSQLEtat.Create;
Stream := TRawByteStringStream.Create;
Stream.Position := 0;
Report.SaveToStream(Stream);
Stream.seek(0,soBeginning);
fEtat.Etat := S2U(Stream.DataString);
globalClient.Add(fetat, true);
finally
fEtat.Free;
Stream.Free;
end;
end;
The function to load the report :
function TF_Etat.LoadFromStream():boolean;
var Stream : TMemoryStream;
begin
if not globalClient.RetrieveBlobFields(fEtat) then
begin
result := False;
exit;
end
else
result := True;
try
Stream := TMemoryStream.Create;
WriteStringToStream(Stream, fEtat.Etat);
if (Stream.Size > 0) and (fEtat.Etat <> '') then
begin
Stream.Position := 0;
frxReport.LoadFromStream(Stream);
frxReport.ShowReport();
end
else
result := False;
finally
Stream.Free;
end;
end;
Now I'm using SQLite but for the future I'll use perhaps Firebird.
I don't see where can I use RawUTF8ToString() on the Report.saveToStream ?
Thnx
Hi AB,
The TRawByteStringStream works fine but I've the UTF-8 content problem. Normaly fastreport creates a UTF-8 content but when I put a text "Libellé" on the report and save it, I got on the database "Libelé".
How can I fix that ?
BTW, the new version of mORMot compiles fine with D7.
Hi AB,
I've transformed my sharding invoice details into TSQLRecordMany and it works correctly. Now I want to calculate some invoice totals automaticly after adding TSQLRecordMany records, is there a call back/event triggered after ManyAdd() function ?
thnx,
What I want to is simple, I have some classes like this
TsqlArticle=(Name, Brand, Family ...)
TsqlInvoice=(like documentation)
Each invoice can have several Articles (pivot table in RAD).
I want that the ui be able to add the invoice and details at once like in RAD. I'm using fastreport for some reasons and I need to serialize the invoice with details to dataset.
Well, I think that I'll replace the sharding by a RecordMany class because in my business logic an invoice record can have many TSQLArticle instances.
I'm right or there's another way to do that ?
thnx for all explanations