You are not logged in.
Pages: 1
And with case 3 ,database connections count number increase 1 every time from 32 up to 33,34,35 .......
all test on delphi 10.4.
Sorry for post a lot of Source Codes here....
1. GlobalCodeServer.dpr
program GlobalCodeServer;
uses
Vcl.Forms,
Main in 'Main.pas' {FormMain},
Services in 'Services.pas';
{$R *.res}
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TFormMain, FormMain);
Application.Run;
end.
1.1 Services.pas
unit Services;
interface
uses mORMot, Syncommons, SynOleDB, SynDB;
type
IVeCode = interface(IInvokable)
['{DE580C16-54F4-4C82-860C-D60BE6374F29}']
function GenCodes(aSetCode: RAWUTF8; aSvcCode: RAWUTF8): RAWUTF8;
end;
IPaCode = interface(IInvokable)
['{ED56F71A-37A3-4A3A-BB2B-827A6D03A390}']
function GenCodes(aSetCode: RAWUTF8; aSvcCode: RAWUTF8): RAWUTF8;
end;
TVeCode = Class(TInterfacedObject, IVeCode)
public
function GenCodes(aSetCode: RAWUTF8; aSvcCode: RAWUTF8): RAWUTF8;
End;
TPaCode = Class(TInterfacedObject, IPaCode)
public
function GenCodes(aSetCode: RAWUTF8; aSvcCode: RAWUTF8): RAWUTF8;
End;
var
VeProp, PaProp: TOleDbMssqlConnectionProperties;
implementation
{ TVeUniCode }
function TVeCode.GenCodes(aSetCode, aSvcCode: RAWUTF8): RAWUTF8;
var
_Data: Variant;
aQuery: TSQLDBStatement;
begin
// _Data := _Json(VeProp.Execute('select ?+? As Adata', [aSetCode, aSvcCode]).FetchAllAsJSON(true));
aQuery := VeProp.NewThreadSafeStatement;
aQuery.Execute('select ?+? As Adata', true, [aSetCode, aSvcCode]);
_Data := _Json(aQuery.FetchAllAsJSON(true));
aQuery.Free;
Result := _Data._(0).Adata;
end;
{ TPaUniCode }
function TPaCode.GenCodes(aSetCode, aSvcCode: RAWUTF8): RAWUTF8;
var
_Data: Variant;
aQuery: TSQLDBStatement;
begin
// _Data := _Json(PaProp.Execute('select ?+? As Adata', [aSetCode, aSvcCode]).FetchAllAsJSON(true));
aQuery := PaProp.NewThreadSafeStatement;
aQuery.Execute('select ?+? As Adata', true, [aSetCode, aSvcCode]);
_Data := _Json(aQuery.FetchAllAsJSON(true));
aQuery.Free;
Result := _Data._(0).Adata;
end;
end.
1.2 Main.pas
unit Main;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, mORMot, mORMotSqlite3, mORMotHttpServer, SynOleDB, SynSqlite3Static;
type
TFormMain = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
VeModel, PaModel: TSQLModel;
VeRest, PaRest: TSQLRestServerDB;
VeHttp, PaHttp: TSQLHttpServer;
public
{ Public declarations }
end;
var
FormMain: TFormMain;
implementation
{$R *.dfm}
uses Services;
procedure TFormMain.FormCreate(Sender: TObject);
begin
VeProp := TOleDBMssqlConnectionProperties.Create('127.0.0.1,1433', 'DB8', 'Sa', '1');
PaProp := TOleDBMssqlConnectionProperties.Create('127.0.0.1,1433', 'DB8', 'Sa', '1');
VeModel := TSQLModel.Create([], 'Ve');
PaModel := TSQLModel.Create([], 'Pa');
VeRest := TSQLRestServerDB.Create(VeModel, ':memory:');
PaRest := TSQLRestServerDB.Create(PaModel, ':memory:');
VeRest.ServiceRegister(TVeCode, [TypeInfo(IVeCode)], sicClientDriven);
PaRest.ServiceRegister(TPaCode, [TypeInfo(IPaCode)], sicClientDriven);
VeHttp := TSQLHttpServer.Create('888', [VeRest], '+');
PaHttp := TSQLHttpServer.Create('999', [PaRest], '+');
VeHttp.AccessControlAllowOrigin := '*';
PaHttp.AccessControlAllowOrigin := '*';
end;
procedure TFormMain.FormDestroy(Sender: TObject);
begin
VeHttp.Free;
PaHttp.Free;
VeRest.Free;
PaRest.Free;
VeModel.Free;
PaModel.Free;
VeProp.Free;
PaProp.Free;
end;
end.
2. GlobalCodeTest.dpr
program GlobalCodeTestCase;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
Services in 'Services.pas', SynTests, mORMotHttpClient, mORMot;
type
TTestClient = class(TSynTestCase)
published
procedure Test1;
end;
TTestSuit = class(TSynTestsLogged)
published
procedure MyTestSuit;
end;
{ TTestSuit }
procedure TTestSuit.MyTestSuit;
begin
AddCase([TTestClient]);
end;
{ TTestClient }
procedure TTestClient.Test1;
var
VeModel, PaModel: TSQLModel;
VeClient, PaClient: TSQLHttpClient;
VeCode: IVeCode;
Pacode: IPaCode;
i: integer;
begin
VeModel := TSQLModel.Create([], 'Ve');
VeClient := TSQLHttpClient.Create('127.0.0.1', '888', VeModel);
VeClient.ServiceRegister(TypeInfo(IVeCode), sicClientDriven);
VeClient.ServerTimestampSynchronize;
VeCode := VeClient.Service<IVeCode>;
PaModel := TSQLModel.Create([], 'Pa');
PaClient := TSQLHttpClient.Create('127.0.0.1', '999', PaModel);
PaClient.ServiceRegister(TypeInfo(IPaCode), sicClientDriven);
PaClient.ServerTimestampSynchronize;
Pacode := PaClient.Service<IPaCode>;
for i := 1 to 10000 do
begin
Check(VeCode.GenCodes('A', 'B') = 'AB');
Check(Pacode.GenCodes('C', 'D') = 'CD');
end;
VeCode := nil;
VeClient.Free;
VeModel.Free;
Pacode := nil;
PaClient.Free;
PaModel.Free;
end;
begin
with TTestSuit.Create do
try
Run;
readln;
finally
Free;
end;
end.
Access both server(888 and 999) on case 3.
like
client1.create(888); service1:=client1.service<IServiceA>; service1.dosomething;
client2.create(999); service2:=client2.service<IServiceB>; service2.dosomething;
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|No. | type | httpserver (Port) | Create threads | TestCase Console App | database connections count |DataBase |
| | | | | Run 1 or 4 TestCase App at same time | 3rd Tools Counted | |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |
| 1 | single | Sqlhttpserver1(888) | 32 | 1 / 4 | 32 / 32 | |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |
| 2 | single | Sqlhttpserver2(999) | 32 | 1 / 4 | 32 / 32 | Same One |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |
| 3 | both | Sqlhttpserver1(888),Sqlhttpserver2(999) | 32+32 | 1 / 4 | 32 / 32 | |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
I have tested all 3 scenarios .
The No.3 scenario confused me. The Database connections count still equals 32 ,not 64 .
Why this happened ?
I have setup 2 TSqlHttpServer in same project and same procedure with diffrent port (888,999).
Both are TSqlHttpServer
-->TSqlRestServerDb (with interfaced service sicShared or sicClientDriven)
-->TSqlModel (some TSqlRecords with diffrent rooturl)
-->TOleDbMssqlConnectionPropperties (connect to same one DB@Server).
And write a Console TestCase to Test 2 ways(port:888 And 999) interfaced service.
But 2 ways testcase are same DataBase connections counts with 1 way (port 888 or 999) testcase , count to 32.
Why not 2 way DataBase connections count to 32+32 ?
2 TSqlHttpServer with diffrent port(888 and 999) ,thread max count = 32+32 or 32?
These are confused me...............
Updated:
I Setup 2 TSqlHttpServer With 2 Propject(win32 application) ,and same result too.
Can we define an 'One to One to .... to One' SQLRecord model ?
TclassX=class(TSQLRecord)
ClassXProp:string;
end;
TClass(X-1)=class(TSQLRecord)
Class(X-1)Prop:string;
ClassX:TClassX;
end;
......
TClass2=class(TSQLRecord)
Class2Prop:String;
Class3:Tclass3;
end;
TClass1=class(TSQL)
Class1Prop:string;
Class2:TClass2;
end;
demo1 compile error
win10 64
delphi 10.3.3 target platform win32
[dcc32 Error] mORMot.pas(44390): E2003 Undeclared identifier: 'IsObjArray'
I found...
mORMot.pas(44390): fValues.{$ifdef UNDIRECTDYNARRAY}InternalDynArray.{$endif}IsObjArray := true;
Synopse.inc(407): {$define UNDIRECTDYNARRAY}
And file location...
/(root folder)
Synopse.inc
/SQLite3(sub folder)
mORMot.pas
So I changed...
mORMot.pas(71): {$I Synopse.inc} // define HASINLINE CPU32 CPU64 ⋙ {$I ../Synopse.inc} // define HASINLINE CPU32 CPU64
Compile Success...
Is this right ?
Hi,I got this ERROR with Demo 1.
Building Project01.dproj (Debug, Win32)
brcc32 command line for "Project01.vrc"
dcc32 command line for "Project01.dpr"
[dcc32 Error] SynCommons.pas(60169): E2034 Too many actual parameters
[dcc32 Fatal Error] Project01.dpr(86): F2063 Could not compile used unit 'SynCommons.pas'
Hi !
Finally,I had changed my project's structure。
unigui app<->mormot app<->database
TWinHttp(unigui app servermodule.pas) as httpclient。
THttpApiServer(mormot app) as httpserver。
TOleDBMSSQLConnectionProperties(mormot app) as database client( or manager)。
thanks mpv's replys.
Inside dbconn.ExecuteInLined mORMot create a connection based on thread ID in which code is executed, so if UniGui create a copy of TUniServerModule for each client (web) connection in separate thread (looks like this is true), then you got as many Db connection as unigui threads. This is as expected.
Sorry for reply so late.
UniGui's UniServerModule is the main thread(only one,and globe shared ) at runtime ,the UniMainModules(thread shared or one client shared) are create in separate threads for every client connect the server.
Hello every one .
Sorry for my poor english. I am a newbie with mormot.
I had create a unigui application,and use mormot as connection pool in unigui's servermodule unit.
This application connect a mssql database.
I got some problems on this project.
1.The pool create new connection several seconds or minutes. when i test this , got 40+ connects after 30 minutes.
2.The connection count look not accuracy.
What is wrong or missing ?
the source codes are here:
servermodule.pas unit
type
TUniServerModule = class(TUniGUIServerModule)
private
{ Private declarations }
dbConn: TOleDBMSSQLConnectionProperties;
protected
procedure FirstInit; override;
public
{ Public declarations }
Procedure OpenSql(aSql:String;aFDMemTable:TFDMemTable);
Procedure ExecSql(aSql:String);
function GetConCount:integer;
end;
implementation
Const
cServer:RawUTF8='127.0.0.1';
cDatabase:RawUTF8='testdb';
cUserId:RawUTF8='sa';
cUserPwd:RawUTF8='sapassword';
procedure TUniServerModule.ExecSql(aSql: String);
begin
dbconn.ExecuteNoResult(aSql,[]);
end;
procedure TUniServerModule.FirstInit;
begin
InitServerModule(Self);
//add by myself
dbconn:=TOleDBMSSQLConnectionProperties.Create(cServer,cDatabase,cUserId,cUserPwd);
dbconn.ConnectionTimeOutMinutes:=1;
//add by myself end
end;
function TUniServerModule.GetConCount: integer;
begin
result:=dbconn.MainConnection.TotalConnectionCount;
end;
procedure TUniServerModule.OpenSql(aSql: String; aFDMemTable: TFDMemTable);
var
rows: ISQLDBRows;
begin
rows:=dbconn.ExecuteInLined(aSql,True);
if aFDMemTable.Active=false then aFDMemTable.Open;
aFDMemTable.EmptyDataSet;
aFDMemTable.CopyDataSet(ToDataSet(aFDMemTable,rows),[coStructure,coRestart,coAppend]);
aFDMemTable.CommitUpdates;
// dbconn.EndCurrentThread;
end;
mainmodule.pas unit
type
TUniMainModule = class(TUniGUIMainModule)
private
{ Private declarations }
public
{ Public declarations }
procedure OpenSql(aSql:string;aFDMemTable:TFDMemTable);
procedure ExecSql(aSql:String);
function GetConCount:Integer;
end;
implementation
procedure TUniMainModule.ExecSql(aSql: String);
begin
UniServerModule.ExecSql(aSql);
end;
function TUniMainModule.GetConCount: Integer;
begin
Result:=UniServerMOdule.GetConCount;
end;
procedure TUniMainModule.OpenSql(aSql: string; aFDMemTable:TFDMemTable);
begin
UniServerModule.OpenSql(asql,aFDMemTable);
end;
mainform.pas unit
procedure TMainForm.UniButton1Click(Sender: TObject);
var
SQL:String;
begin
self.FDMemTable1.Close;
sql:='select * from testtable';
UniMainMOdule.OpenSql(sql,self.FDMemTable1);
end;
//value of unitimer1.interval is 5000;
procedure TMainForm.UniTimer1Timer(Sender: TObject);
begin
self.UniButton1.Click;
end;
Pages: 1