You are not logged in.
After performing TSQLRestServerDB.Backup, the server could not execute any SQL anymore.
Error:
ESQLite3Exception ("TSQLRequest.Reset called with no previous Request") at 00328938 SynSQLite3.TSQLRequest.Reset (4127) stack trace API 0029F900 SynCommons.SynRtlUnwind (37997) 00009790 System.@HandleOnException (18403) To solve this problem, we need to add fStatementCache.Init(DB.DB); after opening DB.
function TSQLRestServerDB.Backup(Dest: TStream): boolean;
{$ifdef CPU64} // currently not working on Win64 - never mind
begin
result := false;
end;
{$else}
var Source: TFileStream;
Closed: boolean;
user_version: cardinal;
begin
result := false;
if (Self=nil) or (DB=nil) then
exit;
fStatementCache.ReleaseAllDBStatements;
user_version := DB.user_version;
DB.LockAndFlushCache;
try
try
// perform a VACCUM to recreate the database content
EngineExecute('VACUUM');
Closed := false;
try
Closed := DB.DBClose=SQLITE_OK;
// compress the database content file
Source := TFileStream.Create(DB.FileName,fmOpenRead or fmShareDenyNone);
try
Dest.CopyFrom(Source,0); // Count=0 for whole stream copy
result := true;
finally
Source.Free;
end;
finally
if Closed then begin
DB.DBOpen; // reopen the database if was previously closed
fStatementCache.Init(DB.DB); // <-- NEED TO ADD THIS
FreeAndNil(fRegisteredVirtualTableModules); // force register modules
InitializeEngine; // register functions and modules
CreateMissingTables(user_version); // register virtual tables
end;
end;
finally
DB.UnLock;
end;
except
on E: Exception do
result := false;
end;
end;
{$endif}The problem is that calling the Http.CreateRequestQueue function gives the error:
HttpCreateRequestQueue failed: Cannot create a file when that file already exists (183)
It seems the problem is in the generation of the name for CreateRequestQueue.
I added logging:
constructor THttpApiServer.Create(CreateSuspended: Boolean);
var bindInfo: HTTP_BINDING_INFO;
...
LogToTextFile('fServerSessionID:= ' + Int64ToUtf8(fServerSessionID));
LogToTextFile('fServerSessionID_BIN:= ' + BinToHexDisplayW(@fServerSessionID,SizeOf(fServerSessionID)));
LogToTextFile('fServerSessionID_UIN:= ' + UIntToStr(fServerSessionID));
LogToTextFile('fServerSessionID_IntToHex:= ' + IntToHex(fServerSessionID, 16));
EHttpApiServer.RaiseOnError(hCreateRequestQueue,Http.CreateRequestQueue(
Http.Version,pointer(BinToHexDisplayW(@fServerSessionID,SizeOf(fServerSessionID))),
nil,0,fReqQueue));and saw that BinToHexDisplayW often returns the name for RequestQueue, which already exists in the system.
Probably IntToHex or as mpv suggested UIntToStr is a better choice for the name generation?
As you see BinToHexDisplayW and IntToHex give different results for the same fServerSessionID:
2014-04-08 15:29:38 fServerSessionID:= -72057576321187757
2014-04-08 15:29:38 fServerSessionID_BIN:= FF00000022000055
2014-04-08 15:29:38 fServerSessionID_UIN:= 18374686497388363859
2014-04-08 15:29:38 fServerSessionID_IntToHex:= FF00000420000053Yes, I'm using version from 01 apr.
Without adding port to the firewall, I did not get to connect to the server. I tried it on windows 8 and windows server 2012
During the installation the Setup program runs exe, which registers the ports in http.sys
After that, the client connects to the server (Server - windows service) via network and all works fine.
After the system restart, the same client connects to the server again and this time it takes toooooo much time to connect. The execution of several methods takes more than a minute.
HttpSysManager.exe shows that the ports are registered.
(
http://+:50888/wps/
http://+:50888/wp/
http://+:50999/svc/
)
If the server and client are installed on the local computer, no problem occurs.
When using http.sys API v.1 the problem does not exist.
The code which is called with the Administrator execution rights during the installation:
ini := TIniFile.Create(DefaultWorkPlace + 'port.ini');
try
port := ini.ReadString('main','port', '50888');
svcport := ini.ReadString('svc', 'port', '50999');
ssl := ini.ReadInteger('main','ssl', 1);
finally
ini.Free;
end;
delete := SameText(ParamStr(1),'/DELETE');
// parameters below must match class function
// TTestClientServerAccess.RegisterAddUrl in mORMotHttpServer.pas:
writeln(REGSTR[delete],' of /wps:' + port + ' for http.sys');
writeln(REGSTR[delete],' of /wp:' + port + ' for http.sys');
writeln(REGSTR[delete],' of /svc:' + svcport + ' for http.sys');
writeln(THttpApiServer.AddUrlAuthorize('wps',port, ssl=2, '+',delete));
writeln(THttpApiServer.AddUrlAuthorize('wp',port, ssl=2, '+',delete));
writeln(THttpApiServer.AddUrlAuthorize('svc',svcport, ssl=2, '+',delete));
AddApplicationToFirewall('Delivery Server', ExtractFilePath(ParamStr(0)) + 'xxxx.exe');
AddApplicationToFirewall('Delivery Controller', ExtractFilePath(ParamStr(0)) + 'yyyy.exe');
AddPortToFirewall('Delivery Server Port', StrToIntDef(Port, 50888));
AddPortToFirewall('Delivery Controller Port', StrToIntDef(svcport, 50999));Creating HTTP server in server application:
try
HttpServer := TRootWebServer.Create(port, [WPlaceServer], '+', useHttpApi, 32, SSL); // 32
except
on e : exception do
raise Exception.Create('Port: '+ port + ' in use');
end;
HttpServer.AccessControlAllowOrigin := '*';
....
HttpServer.AddServer(FSettingsServer, nil, ssl);
HttpServer.AddServer(FGroupServer, nil, ssl);
HttpServer.AddServer(FBounceServer, nil, ssl);
...
The model contains TSqlRawBlob field.
When field data is transferred via JSON it is encoded as SQLite3 BLOB literals (X'53514C697465' e.g.)
TMode = class(TSqlRecord)
...
published property Source: TSqlRawBlob read FSource write FSource;
...
FModel.Source := StringFromFile(FileName);
Ctxt.Returns(ObjectToJSON(FModel,[]));The file content:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title></title>
</head>
<body>
<p>Привет Алекс Саша</p>
</body>
</html>After content is transmitted via JSON and decoded on the client (or server) side, the source file content is different:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title></title>
</head>
<body>
<p>Привет Алекс Саша</p>
</body>
</html>I think that the problem is in the TSQLRawBlobToBlob function
I agree, the TextColumnShouldNotBeEscaped will be a best solution.
I made for myself a little hack that allows you to give the contents of fields whose names end with "List" (AccountList, GroupList, AttachList) as they are in the database. Maybe someone will be useful.
unit SynSQLite3;
...
procedure TSQLRequest.FieldsToJSON(WR: TJSONWriter; DoNotFletchBlobs: boolean);
...
SQLITE_TEXT: begin
if pos('List":',WR.ColNames[i]) > 2 then // if field name end with "List" do not transfer as TEXT value
wr.AddString(sqlite3.column_text(Request,i))
else
begin
WR.Add('"');
WR.AddJSONEscape(sqlite3.column_text(Request,i),0);
WR.Add('"');
end;
end;
...In the model I have PersonalList property as TCollection.
Type
TAttItem = class(TCollectionItem)
...
published
property FileName : RawUtf8 read FFileName write FFileName;
property DisplayName : RawUtf8 read FDisplayName write FDisplayName;
end;
Type
TAttItems = Class(TCollection)
private
function GetItem(index: integer): TAttItem;
procedure SetItem(index: integer; value: TAttItem);
public
constructor Create;
function Add(_FFileName: RawUtf8; _FDisplayName: RawUtf8): TAttItem;
property Items[index: integer]: TAttItem read GetItem write SetItem; default;
end;
Type
TMyRecord = class(TSQLRecord)
...
published property PersonalList : TAttItems read FPersonalList write FPersonalList ; In DB PersonalList stored as:
[{"FileName":"C:\\Users\\Dig\\Desktop\\alex.jpg","DisplayName":"foto.jpg"},{"FileName":"C:\\Users\\Dig\\Desktop\\Report.pdf","DisplayName":"%%First_Name%%_report.pdf"}]ObjectToJson:
{
"AccountList": ["15"],
"GroupList": ["86"],
"Guid": "{10A06F2A-FA70-4068-8086-8EB13703F1BA}",
"PersonalList": [ {
"FileName": "C:\\Users\\Dig\\Desktop\\alex.jpg",
"DisplayName": "foto.jpg"
},
{
"FileName": "C:\\Users\\Dig\\Desktop\\Report.pdf",
"DisplayName": "%%First_Name%%_report.pdf"
}
]
}GET ModelRoot/TableName/TableID: returns PersonalList as TEXT.
procedure TSQLRestServerURIContext.ExecuteORMGet;
...
// get JSON object '{...}'
Call.OutBody := TableEngine.EngineRetrieve(TableIndex,TableID);
"AccountList": "[\"15\"]",
"GroupList": "[\"86\"]",
"Guid": "{10A06F2A-FA70-4068-8086-8EB13703F1BA}",
"PersonalList": "[{\"FileName\":\"C:\\\\Users\\\\Dig\\\\Desktop\\\\alex.jpg\",\"DisplayName\":\"foto.jpg\"},{\"FileName\":\"C:\\\\Users\\\\Dig\\\\Desktop\\\\Report.pdf\",\"DisplayName\":\"%%First_Name%%_report.pdf\"}]"How to return TCollection as list via GET ModelRoot/TableName/TableID?
The problem is that if one TSQLRestServer (http://host:port/wp/1/settings/SomeMethod) executes the method long, other TSQLRestServer (http://host:port/wp/1/group/SomeMethod2) can not handle at this point its methods and the client receives a 503 error
Sorry, I mean TSQLHttpServer.Request
Do I understand correctly that mORMot works as a model 1?
Еhen what's the point in creating multiple threads, if all the TSQLRestServer share the same THttpApiServer.fReqQueue handler? I just thought that each server will have its own thread pool.
In my case four TSQLRestServer servers handle different URIs:
http://host:port/wps/
http://host:port/wp/1/settings
http://host:port/wp/1/group
http://host:port/wp/1/onemore
When HttpServer is created it's cloned to the 32 threads to handle incoming connections.
Later I register 3 more TSQLRestServer instances to the HTTP server
HttpServer := TRootWebServer.Create(port, [WPlaceServer], '+', useHttpApi, 32, SSL);
...
HttpServer.AddServer(FSettingsServer, nil, ssl);
HttpServer.AddServer(FGroupServer, nil, ssl);
HttpServer.AddServer(FBounceServer, nil, ssl);
...The problem is that all 32 threads process requests for one server WPlaceServer (TWPManagerServer in the log), and for processing requests for other TSQLRestServerDB instances only 1 thread is used, which is seen in the log.
20140131 12520142 info TSettingsServer(04568000) { "ClientsCurrent": 1, "ClientsMax": 1, "Invalid": 0, "Responses": 23, "Modified": 0, "IncomingBytes": 12246, "OutcomingBytes": 139805, "OutcomingFiles": 0, "ServiceCalls": 5, "CurrentThreadCount": 1, "ProcessTime": "44.68ms" }
20140131 12520142 + 00315CBA SynSQLite3.TSQLDatabase.DBClose (3361)
20140131 12520142 - 00.000.450
20140131 12520142 info TGroupServer(0453F190) { "ClientsCurrent": 1, "ClientsMax": 1, "Invalid": 0, "Responses": 11, "Modified": 0, "IncomingBytes": 5204, "OutcomingBytes": 9060, "OutcomingFiles": 0, "ServiceCalls": 3, "CurrentThreadCount": 1, "ProcessTime": "20.20ms" }
20140131 12520142 + 00315CBA SynSQLite3.TSQLDatabase.DBClose (3361)
20140131 12520142 - 00.000.208
20140131 12520142 info TBounceServer(0452FFD0) { "ClientsCurrent": 1, "ClientsMax": 1, "Invalid": 0, "Responses": 11, "Modified": 0, "IncomingBytes": 5173, "OutcomingBytes": 3417, "OutcomingFiles": 0, "ServiceCalls": 3, "CurrentThreadCount": 1, "ProcessTime": "10.70ms" }
20140131 12520142 + 00315CBA SynSQLite3.TSQLDatabase.DBClose (3361)
20140131 12520142 - 00.000.104
20140131 12520142 info TWPManagerServer(045649A0) { "ClientsCurrent": 1, "ClientsMax": 1, "Invalid": 0, "Responses": 7, "Modified": 0, "IncomingBytes": 2943, "OutcomingBytes": 1426, "OutcomingFiles": 0, "ServiceCalls": 6, "CurrentThreadCount": 32, "ProcessTime": "6.46ms" }
20140131 12520142 + 00315CBA SynSQLite3.TSQLDatabase.DBClose (3361) During an active work of the server, if the method execution takes a long time, clients get the 503 error - service unavailable.
It would be good if it was the possibility to set the number of threads to handle incoming connections when calling the HttpServer.AddServer method.
Thanks ab.
Now it works fine.
I will try to create a simple project to reproduce the BeginCurrentThread() problem.
P.S. if add before httpserver.free
HttpServer.RemoveServer(FSettingsServer);
HttpServer.RemoveServer(FGroupServer);
HttpServer.RemoveServer(FBounceServer);the EndCurrentThread executes without any issue.
I use http://synopse.info/fossil/info/9014c28bd5 version
In my application I have 4 TSQLRestServerDB and one HttpApi server
HttpServer := TRootWebServer.Create(port, [WPlaceServer], '+', useHttpApi, 32, SSL);
...
HttpServer.AddServer(FSettingsServer, nil, ssl);
HttpServer.AddServer(FGroupServer, nil, ssl);
HttpServer.AddServer(FBounceServer, nil, ssl);
...During communication I often get an Exception:
ECommunicationException ("BeginCurrentThread() twice") at 002E855E mORMot.TSQLRestServer.BeginCurrentThread (25553) And when I destroy HttpServer I got ECommunicationException:
Unexpected EndCurrentThread().The version from 23.12.2013 does not have these problems
exception class : ECommunicationException
exception message : Unexpected EndCurrentThread().
thread $17d8:
006e98e1 +1f1 EasyMail7Server.exe mORMot 25593 +25 TSQLRestServer.EndCurrentThread
007921e5 +03d EasyMail7Server.exe mORMotHttpServer 592 +3 TSQLHttpServer.HttpThreadTerminate
0078c384 +024 EasyMail7Server.exe SynCrtSock 2615 +2 TNotifiedThread.DoTerminate
005399d3 +083 EasyMail7Server.exe System.Classes 14576 +19 ThreadProc
0040b1b8 +028 EasyMail7Server.exe System 21627 +45 ThreadWrapper
004abe39 +00d EasyMail7Server.exe madExcept CallThreadProcSafe
004abe9e +032 EasyMail7Server.exe madExcept ThreadExceptFrame
7607495b +00c KERNEL32.DLL BaseThreadInitThunk
main thread ($84c):
75948668 +000 KERNELBASE.dll WaitForMultipleObjectsEx
757dadc4 +153 user32.dll MsgWaitForMultipleObjectsEx
757dae24 +01a user32.dll MsgWaitForMultipleObjects
0053a99f +06f EasyMail7Server.exe System.Classes 15342 +13 TThread.WaitFor
00539b81 +039 EasyMail7Server.exe System.Classes 14652 +6 TThread.Destroy
0078f37a +092 EasyMail7Server.exe SynCrtSock 4001 +10 THttpApiServer.Destroy
00409558 +008 EasyMail7Server.exe System 15046 +4 TObject.Free
00597646 +016 EasyMail7Server.exe System.Contnrs 340 +3 TObjectList.Notify
005222a4 +084 EasyMail7Server.exe System.Classes 4440 +17 TList.SetCount
00521d97 +007 EasyMail7Server.exe System.Classes 4173 +1 TList.Clear
00521d3f +00f EasyMail7Server.exe System.Classes 4157 +1 TList.Destroy
00409558 +008 EasyMail7Server.exe System 15046 +4 TObject.Free
00791d18 +02c EasyMail7Server.exe mORMotHttpServer 514 +1 TSQLHttpServer.Destroy
00409558 +008 EasyMail7Server.exe System 15046 +4 TObject.Free
00b4539e +0ce EasyMail7Server.exe DeliveryServer 580 +19 TEMServer.Destroysample code:
destructor TEMServer.Destroy;
var
i : integer;
List : TList;
begin
List := ServerList.LockList;
try
for I := List.Count-1 downto 0 do
TWPServer(List[i]).Free;
finally
List.Clear;
ServerList.UnlockList;
ServerList.Free;
end;
WPModel.Free;
WPlaceServer.Free;
HttpServer.Free;
inherited;
end;
destructor TWPServer.Destroy;
var
i : integer;
FList : TList;
begin
SettingsModel.free;
GroupsModel.Free;
BouncedModel.Free;
FSettingsServer.Free;
FGroupServer.Free;
FBounceServer.Free;
FList := ConnectionList.LockList;
try
for i := FList.Count-1 downto 0 do
begin
TSQLDBFireDACConnectionProperties(FList[i]).Free;
end;
finally
ConnectionList.UnlockList;
end;
ConnectionList.Free;
FList := OutboxServerList.LockList;
try
for i := FList.Count-1 downto 0 do
TOutboxServer(FList[i]).free;
finally
OutboxServerList.UnlockList;
end;
OutboxServerList.Free;
DeleteCriticalSection(ThCriticalSection);
inherited;
end;20140120 11525707 + TRootWebServer(07D2FE48).003905C6 mORMotHttpServer.TSQLHttpServer.Create (420)
20140120 11525707 trace TWPManagerServer(045BD670).BeginCurrentThread(THttpApiServer(06CE65C0)) ThreadID=1972 ThreadCount=1
20140120 11525707 trace TWPManagerServer(045BD670).BeginCurrentThread(THttpApiServer(06CE6640)) ThreadID=7152 ThreadCount=2
20140120 11525707 trace TWPManagerServer(045BD670).BeginCurrentThread(THttpApiServer(06CE6740)) ThreadID=10280 ThreadCount=3
20140120 11525707 trace TWPManagerServer(045BD670).BeginCurrentThread(THttpApiServer(06CE67C0)) ThreadID=10456 ThreadCount=4
20140120 11525707 trace TWPManagerServer(045BD670).BeginCurrentThread(THttpApiServer(06CE6840)) ThreadID=4300 ThreadCount=5
20140120 11525707 trace TWPManagerServer(045BD670).BeginCurrentThread(THttpApiServer(06CE66C0)) ThreadID=4496 ThreadCount=6
20140120 11525707 trace TWPManagerServer(045BD670).BeginCurrentThread(THttpApiServer(06CE6940)) ThreadID=1936 ThreadCount=8
20140120 11525707 trace TWPManagerServer(045BD670).BeginCurrentThread(THttpApiServer(06CE68C0)) ThreadID=11136 ThreadCount=7
20140120 11525707 trace TWPManagerServer(045BD670).BeginCurrentThread(THttpApiServer(06CE69C0)) ThreadID=6872 ThreadCount=9
20140120 11525707 trace TWPManagerServer(045BD670).BeginCurrentThread(THttpApiServer(06CE6A40)) ThreadID=5440 ThreadCount=10
20140120 11525707 trace TWPManagerServer(045BD670).BeginCurrentThread(THttpApiServer(06CE6AC0)) ThreadID=11124 ThreadCount=11
20140120 11525707 trace TWPManagerServer(045BD670).BeginCurrentThread(THttpApiServer(06CE6B40)) ThreadID=552 ThreadCount=12
20140120 11525707 trace TWPManagerServer(045BD670).BeginCurrentThread(THttpApiServer(06CE6BC0)) ThreadID=10672 ThreadCount=13
20140120 11525707 trace TWPManagerServer(045BD670).BeginCurrentThread(THttpApiServer(06CE6C40)) ThreadID=4612 ThreadCount=14
20140120 11525707 trace TWPManagerServer(045BD670).BeginCurrentThread(THttpApiServer(06CE6CC0)) ThreadID=10484 ThreadCount=15
20140120 11525707 trace TWPManagerServer(045BD670).BeginCurrentThread(THttpApiServer(06CE6D40)) ThreadID=3752 ThreadCount=16
20140120 11525707 trace TWPManagerServer(045BD670).BeginCurrentThread(THttpApiServer(06CE6DC0)) ThreadID=11004 ThreadCount=17
20140120 11525707 trace TWPManagerServer(045BD670).BeginCurrentThread(THttpApiServer(06CE6EC0)) ThreadID=10540 ThreadCount=18
20140120 11525707 trace TWPManagerServer(045BD670).BeginCurrentThread(THttpApiServer(06CE6F40)) ThreadID=3336 ThreadCount=19
20140120 11525707 trace TWPManagerServer(045BD670).BeginCurrentThread(THttpApiServer(06CE6E40)) ThreadID=4976 ThreadCount=20
20140120 11525707 trace TWPManagerServer(045BD670).BeginCurrentThread(THttpApiServer(06CE6FC0)) ThreadID=9764 ThreadCount=21
20140120 11525707 trace TWPManagerServer(045BD670).BeginCurrentThread(THttpApiServer(06CE7040)) ThreadID=9988 ThreadCount=22
20140120 11525707 trace TWPManagerServer(045BD670).BeginCurrentThread(THttpApiServer(06CE70C0)) ThreadID=9188 ThreadCount=23
20140120 11525707 trace TWPManagerServer(045BD670).BeginCurrentThread(THttpApiServer(06CE71C0)) ThreadID=10336 ThreadCount=28
20140120 11525707 trace TWPManagerServer(045BD670).BeginCurrentThread(THttpApiServer(06CE7240)) ThreadID=9820 ThreadCount=25
20140120 11525707 trace TWPManagerServer(045BD670).BeginCurrentThread(THttpApiServer(06CE72C0)) ThreadID=10788 ThreadCount=26
20140120 11525707 trace TWPManagerServer(045BD670).BeginCurrentThread(THttpApiServer(06CE7340)) ThreadID=11044 ThreadCount=27
20140120 11525707 trace TWPManagerServer(045BD670).BeginCurrentThread(THttpApiServer(06CE7140)) ThreadID=10104 ThreadCount=24
20140120 11525707 trace TWPManagerServer(045BD670).BeginCurrentThread(THttpApiServer(06CE73C0)) ThreadID=3888 ThreadCount=29
20140120 11525707 trace TWPManagerServer(045BD670).BeginCurrentThread(THttpApiServer(06CE7440)) ThreadID=9868 ThreadCount=30
20140120 11525707 info TRootWebServer(07D2FE48) THttpApiServer(06CE6540) initialized at http://localhost/wps:50888
20140120 11525707 - 00.013.357
20140120 11525707 trace TWPManagerServer(045BD670).BeginCurrentThread(THttpApiServer(06CE74C0)) ThreadID=6104 ThreadCount=31...
20140120 11525711 + TRootWebServer(07D2FE48).003901E7 mORMotHttpServer.TSQLHttpServer.AddServer (350)
20140120 11525711 debug result=true for Root=wp/1/settings
20140120 11525711 - 00.000.694
20140120 11525711 + TRootWebServer(07D2FE48).003901E7 mORMotHttpServer.TSQLHttpServer.AddServer (350)
20140120 11525711 debug result=true for Root=wp/1/group
20140120 11525711 - 00.000.669
20140120 11525711 + TRootWebServer(07D2FE48).003901E7 mORMotHttpServer.TSQLHttpServer.AddServer (350)
20140120 11525711 debug result=true for Root=wp/1/bounce
20140120 11525711 - 00.000.706...
20140120 11525711 + TRootWebServer(07D2FE48).003901E7 mORMotHttpServer.TSQLHttpServer.AddServer (350)
20140120 11525711 debug result=true for Root=wp/1/settings
20140120 11525711 - 00.000.694
20140120 11525711 + TRootWebServer(07D2FE48).003901E7 mORMotHttpServer.TSQLHttpServer.AddServer (350)
20140120 11525711 debug result=true for Root=wp/1/group
20140120 11525711 - 00.000.669
20140120 11525711 + TRootWebServer(07D2FE48).003901E7 mORMotHttpServer.TSQLHttpServer.AddServer (350)
20140120 11525711 debug result=true for Root=wp/1/bounce
20140120 11525711 - 00.000.706
20140120 11525711 cache TSQLDatabase(07D3C010) not in cache
20140120 11525711 SQL TSettingsServer(045C1090) SELECT ID,AccountType,AccountName,DisplayName,EmailAddress,ReplyEmail,ReturnEmail,Organization,DefaultSelect,Properties,AvailableSlots,MessagesPerHour,MessagesPerDay,SentInHour,StartDay,StartHour,SentInDay,HeaderFields FROM Account; is no prepared statement
20140120 11525711 res TSQLDatabase(07D3C010) [{"ID":1,"AccountType":2,"AccountName":"G-Lock Software","DisplayName":"Julia from G-Lock Software","EmailAddress":"support@glocksoft.com","ReplyEmail":"support@glocksoft.com","ReturnEmail":"bounce@glocksoft.com","Organization":"","DefaultSelect":0,"Properties":"{\"USEPOPBefore\":false,\"POPServer\":\"\",\"POPPort\":110,\"PopLogin\":\"\",\"PopPassword\":\"\",\"SMTPServer\":\"mail.glocksoft.com\",\"SMTPPort\":25,\"USESMTPAuth\":true,\"SMTPLogin\":\"support@glocksoft.com\",\"SMTPPassword\":\"IBiUQI0a5zCE3fOq+
20140120 11525711 cache TSQLDatabase(07D3C010) not in cache
20140120 11525711 SQL TSettingsServer(045C1090) SELECT ID,CharSet,Subject,MailTo,Attempt,Total,Processed,Sent,Excluded,Failed,Unsubscribed,Bounced,Complaint,Total_Opens,Unique_Opens,Total_Clicks,Unique_Clicks,Status,StatusMessage,CreateTime,StartTime,FinishTime,UseAnalytics,CID,CName,SendMode,TrackMethod,TrackName,Priority,ConfirmRead,AttachList,AccountList,GroupList,Deleted,Guid,MessageFormat,ResumeTime,User FROM Outbox WHERE Status=1; is no prepared statement
20140120 11525712 res TSQLDatabase(07D3C010) {"fieldCount":38,"values":["ID","CharSet","Subject","MailTo","Attempt","Total","Processed","Sent","Excluded","Failed","Unsubscribed","Bounced","Complaint","Total_Opens","Unique_Opens","Total_Clicks","Unique_Clicks","Status","StatusMessage","CreateTime","StartTime","FinishTime","UseAnalytics","CID","CName","SendMode","TrackMethod","TrackName","Priority","ConfirmRead","AttachList","AccountList","GroupList","Deleted","Guid","MessageFormat","ResumeTime","User"],"rowCount":0}
20140120 11525712 cache TSQLDatabase(0461AE00) not in cache
20140120 11525712 SQL TWPManagerServer(045BD670) SELECT ID,Ident,SessionTimeout,AccessRights FROM AuthGroup WHERE Ident=:('Guest'):; prepared as SELECT ID,Ident,SessionTimeout,AccessRights FROM AuthGroup WHERE Ident=?; with 1 param
20140120 11525712 res TSQLDatabase(0461AE00) [{"ID":4,"Ident":"Guest","SessionTimeout":60,"AccessRights":"0,1,4-256,0,0,0,0"}]
20140120 11525712 cache TSQLDatabase(0461AE00) not in cache
20140120 11525712 SQL TWPManagerServer(045BD670) SELECT ID,LogonName,DisplayName,PasswordHashHexa,GroupRights,Created,Email,FirstName,LastName,ValidTill,Guid FROM AuthUser; is no prepared statement
20140120 11525712 res TSQLDatabase(0461AE00) [{"ID":1,"LogonName":"Admin","DisplayName":"Super Admin","PasswordHashHexa":"c2fc6c6adf8ba0f575a35f48df52c0968a3dcd3c577c2769dc2f1035943b975e","GroupRights":1,"Created":"2013-10-22T10:28:38","Email":"support@glocksoft.com","FirstName":"Super","LastName":"Admin","ValidTill":"2014-10-22T10:28:38","Guid":"{4791D897-6ADF-42E6-A335-4307866DDB1A}"},{"ID":3,"LogonName":"Julia","DisplayName":"Julia","PasswordHashHexa":"c2fc6c6adf8ba0f575a35f48df52c0968a3dcd3c577c2769dc2f1035943b975e","GroupRights":3,"Created":"2013
20140120 11530329 trace TWPManagerServer(045BD670).BeginCurrentThread(THttpApiServer(06CE6540)) ThreadID=10412 ThreadCount=32
20140120 11530329 trace TSettingsServer(045C1090).BeginCurrentThread(THttpApiServer(06CE6540)) ThreadID=10412 ThreadCount=1
20140120 11530329 EXC ECommunicationException ("BeginCurrentThread() twice") at 002E855E mORMot.TSQLRestServer.BeginCurrentThread (25553) stack trace API 00292A18 SynCommons.SynRtlUnwind (35051) 00009790 System.@HandleOnException (18403)
20140120 11530329 + TWPManagerServer(045BD670).wps/TimeStamp...
20140120 11530334 + TSettingsServer(045C1090).wp/1/settings
20140120 11530334 auth TSQLRestRoutingREST(06CE75C0) Admin/TAuthSession(045937F0)
20140120 11530334 cache TSQLDatabase(07D3C010) not in cache
20140120 11530334 SQL TSettingsServer(045C1090) SELECT ID,GroupID,Name,Match,Criteria FROM Segment WHERE GroupID=:(19):; prepared as SELECT ID,GroupID,Name,Match,Criteria FROM Segment WHERE GroupID=?; with 1 param
20140120 11530334 res TSQLDatabase(07D3C010) {"fieldCount":5,"values":["ID","GroupID","Name","Match","Criteria"],"rowCount":0}
20140120 11530334 srvr TSettingsServer(045C1090) GET -> 200
20140120 11530334 - 00.002.085
20140120 11530334 trace TWPManagerServer(045BD670).BeginCurrentThread(THttpApiServer(06CE6540)) ThreadID=10412 ThreadCount=33
20140120 11530334 EXC ECommunicationException ("BeginCurrentThread() twice") at 002E855E mORMot.TSQLRestServer.BeginCurrentThread (25553) stack trace API 00292A18 SynCommons.SynRtlUnwind (35051) 00009790 System.@HandleOnException (18403)
20140120 11530335 + TSettingsServer(045C1090).wp/1/settings...
20140120 11531245 trace TWPManagerServer(045BD670).BeginCurrentThread(THttpApiServer(06CE6540)) ThreadID=10412 ThreadCount=34
20140120 11531245 EXC ECommunicationException ("BeginCurrentThread() twice") at 002E855E mORMot.TSQLRestServer.BeginCurrentThread (25553) stack trace API 00292A18 SynCommons.SynRtlUnwind (35051) 00009790 System.@HandleOnException (18403)
20140120 11531247 + TSettingsServer(045C1090).wp/1/settings/GetSentItems?MessageID=51&SQL=Select+count%28%2A%29+from+SentItems+Where+%28Status+%3D+1%29
20140120 11531247 auth TSQLRestRoutingREST(06CE78C0) Admin/TAuthSession(045937F0)
20140120 11531247 call TSettingsServer(045C1090) GetSentItemsand when destroy servers
20140120 11532529 info TSettingsServer(045C1090) { "ClientsCurrent": 1, "ClientsMax": 1, "Invalid": 2, "Responses": 79, "Modified": 0, "IncomingBytes": 42566, "OutcomingBytes": 228617, "OutcomingFiles": 0, "ServiceCalls": 53, "CurrentThreadCount": 1, "ProcessTime": "480.51ms" }
20140120 11532529 + 00315166 SynSQLite3.TSQLDatabase.DBClose (3348)
20140120 11532529 - 00.000.437
20140120 11532529 info TGroupServer(0458C200) { "ClientsCurrent": 1, "ClientsMax": 1, "Invalid": 1, "Responses": 3, "Modified": 0, "IncomingBytes": 1640, "OutcomingBytes": 437, "OutcomingFiles": 0, "ServiceCalls": 4, "CurrentThreadCount": 0, "ProcessTime": "5.07ms" }
20140120 11532529 + 00315166 SynSQLite3.TSQLDatabase.DBClose (3348)
20140120 11532529 - 00.000.112
20140120 11532529 info TBounceServer(045A1570) { "ClientsCurrent": 1, "ClientsMax": 1, "Invalid": 1, "Responses": 3, "Modified": 0, "IncomingBytes": 1644, "OutcomingBytes": 437, "OutcomingFiles": 0, "ServiceCalls": 4, "CurrentThreadCount": 0, "ProcessTime": "6.01ms" }
20140120 11532529 + 00315166 SynSQLite3.TSQLDatabase.DBClose (3348)
20140120 11532529 - 00.000.107
20140120 11532529 info TWPManagerServer(045BD670) { "ClientsCurrent": 1, "ClientsMax": 1, "Invalid": 0, "Responses": 7, "Modified": 0, "IncomingBytes": 2943, "OutcomingBytes": 1258, "OutcomingFiles": 0, "ServiceCalls": 6, "CurrentThreadCount": 35, "ProcessTime": "17.17ms" }
20140120 11532529 + 00315166 SynSQLite3.TSQLDatabase.DBClose (3348)
20140120 11532529 - 00.000.111
20140120 11532529 trace TWPManagerServer(045BD670).EndCurrentThread(THttpApiServer(06CE6940)) ThreadID=1936 ThreadCount=34
20140120 11532529 trace TWPManagerServer(045BD670).EndCurrentThread(THttpApiServer(06CE6E40)) ThreadID=4976 ThreadCount=27
20140120 11532529 trace TSettingsServer(045C1090).EndCurrentThread(THttpApiServer(06CE6E40)) ThreadID=4976 ThreadCount=-1
20140120 11532529 trace TWPManagerServer(045BD670).EndCurrentThread(THttpApiServer(06CE6B40)) ThreadID=552 ThreadCount=31
20140120 11532529 trace TSettingsServer(045C1090).EndCurrentThread(THttpApiServer(06CE6B40)) ThreadID=552 ThreadCount=-2
20140120 11532529 trace TWPManagerServer(045BD670).EndCurrentThread(THttpApiServer(06CE6D40)) ThreadID=3752 ThreadCount=29
20140120 11532529 trace TSettingsServer(045C1090).EndCurrentThread(THttpApiServer(06CE6D40)) ThreadID=3752 ThreadCount=-3
20140120 11532529 trace TSettingsServer(045C1090).EndCurrentThread(THttpApiServer(06CE6940)) ThreadID=1936 ThreadCount=0
20140120 11532529 trace TWPManagerServer(045BD670).EndCurrentThread(THttpApiServer(06CE68C0)) ThreadID=11136 ThreadCount=33
20140120 11532529 trace TSettingsServer(045C1090).EndCurrentThread(THttpApiServer(06CE68C0)) ThreadID=11136 ThreadCount=-4
20140120 11532529 trace TWPManagerServer(045BD670).EndCurrentThread(THttpApiServer(06CE6F40)) ThreadID=3336 ThreadCount=25
20140120 11532529 trace TSettingsServer(045C1090).EndCurrentThread(THttpApiServer(06CE6F40)) ThreadID=3336 ThreadCount=-5
20140120 11532529 trace TWPManagerServer(045BD670).EndCurrentThread(THttpApiServer(06CE7240)) ThreadID=9820 ThreadCount=23
20140120 11532529 trace TSettingsServer(045C1090).EndCurrentThread(THttpApiServer(06CE7240)) ThreadID=9820 ThreadCount=-6
20140120 11532529 trace TWPManagerServer(045BD670).EndCurrentThread(THttpApiServer(06CE7340)) ThreadID=11044 ThreadCount=21
20140120 11532529 trace TSettingsServer(045C1090).EndCurrentThread(THttpApiServer(06CE7340)) ThreadID=11044 ThreadCount=-7
20140120 11532529 trace TWPManagerServer(045BD670).EndCurrentThread(THttpApiServer(06CE6DC0)) ThreadID=11004 ThreadCount=19
20140120 11532529 trace TSettingsServer(045C1090).EndCurrentThread(THttpApiServer(06CE6DC0)) ThreadID=11004 ThreadCount=-8
20140120 11532529 trace TWPManagerServer(045BD670).EndCurrentThread(THttpApiServer(06CE6A40)) ThreadID=5440 ThreadCount=32
20140120 11532529 trace TSettingsServer(045C1090).EndCurrentThread(THttpApiServer(06CE6A40)) ThreadID=5440 ThreadCount=-9
20140120 11532529 trace TWPManagerServer(045BD670).EndCurrentThread(THttpApiServer(06CE6EC0)) ThreadID=10540 ThreadCount=16
20140120 11532529 trace TSettingsServer(045C1090).EndCurrentThread(THttpApiServer(06CE6EC0)) ThreadID=10540 ThreadCount=-10
20140120 11532529 trace TWPManagerServer(045BD670).EndCurrentThread(THttpApiServer(06CE6AC0)) ThreadID=11124 ThreadCount=14
20140120 11532529 trace TSettingsServer(045C1090).EndCurrentThread(THttpApiServer(06CE6AC0)) ThreadID=11124 ThreadCount=-11
20140120 11532529 trace TWPManagerServer(045BD670).EndCurrentThread(THttpApiServer(06CE65C0)) ThreadID=1972 ThreadCount=12
20140120 11532529 trace TSettingsServer(045C1090).EndCurrentThread(THttpApiServer(06CE65C0)) ThreadID=1972 ThreadCount=-12
20140120 11532529 trace TWPManagerServer(045BD670).EndCurrentThread(THttpApiServer(06CE6740)) ThreadID=10280 ThreadCount=10
20140120 11532529 trace TSettingsServer(045C1090).EndCurrentThread(THttpApiServer(06CE6740)) ThreadID=10280 ThreadCount=-13
20140120 11532529 trace TWPManagerServer(045BD670).EndCurrentThread(THttpApiServer(06CE6C40)) ThreadID=4612 ThreadCount=28
20140120 11532529 trace TSettingsServer(045C1090).EndCurrentThread(THttpApiServer(06CE6C40)) ThreadID=4612 ThreadCount=-14
20140120 11532529 trace TWPManagerServer(045BD670).EndCurrentThread(THttpApiServer(06CE6FC0)) ThreadID=9764 ThreadCount=24
20140120 11532529 trace TSettingsServer(045C1090).EndCurrentThread(THttpApiServer(06CE6FC0)) ThreadID=9764 ThreadCount=-15
20140120 11532529 trace TWPManagerServer(045BD670).EndCurrentThread(THttpApiServer(06CE7140)) ThreadID=10104 ThreadCount=20
20140120 11532529 trace TSettingsServer(045C1090).EndCurrentThread(THttpApiServer(06CE7140)) ThreadID=10104 ThreadCount=-16
20140120 11532529 trace TWPManagerServer(045BD670).EndCurrentThread(THttpApiServer(06CE70C0)) ThreadID=9188 ThreadCount=17
20140120 11532529 trace TSettingsServer(045C1090).EndCurrentThread(THttpApiServer(06CE70C0)) ThreadID=9188 ThreadCount=-17
20140120 11532529 trace TWPManagerServer(045BD670).EndCurrentThread(THttpApiServer(06CE74C0)) ThreadID=6104 ThreadCount=13
20140120 11532529 trace TSettingsServer(045C1090).EndCurrentThread(THttpApiServer(06CE74C0)) ThreadID=6104 ThreadCount=-18
20140120 11532529 trace TWPManagerServer(045BD670).EndCurrentThread(THttpApiServer(06CE69C0)) ThreadID=6872 ThreadCount=30
20140120 11532529 trace TSettingsServer(045C1090).EndCurrentThread(THttpApiServer(06CE69C0)) ThreadID=6872 ThreadCount=-19
20140120 11532529 trace TWPManagerServer(045BD670).EndCurrentThread(THttpApiServer(06CE72C0)) ThreadID=10788 ThreadCount=22
20140120 11532529 trace TSettingsServer(045C1090).EndCurrentThread(THttpApiServer(06CE72C0)) ThreadID=10788 ThreadCount=-20
20140120 11532529 trace TWPManagerServer(045BD670).EndCurrentThread(THttpApiServer(06CE6640)) ThreadID=7152 ThreadCount=15
20140120 11532529 trace TSettingsServer(045C1090).EndCurrentThread(THttpApiServer(06CE6640)) ThreadID=7152 ThreadCount=-21
20140120 11532529 trace TWPManagerServer(045BD670).EndCurrentThread(THttpApiServer(06CE6CC0)) ThreadID=10484 ThreadCount=26
20140120 11532529 trace TSettingsServer(045C1090).EndCurrentThread(THttpApiServer(06CE6CC0)) ThreadID=10484 ThreadCount=-22
20140120 11532529 trace TWPManagerServer(045BD670).EndCurrentThread(THttpApiServer(06CE6840)) ThreadID=4300 ThreadCount=11
20140120 11532529 trace TSettingsServer(045C1090).EndCurrentThread(THttpApiServer(06CE6840)) ThreadID=4300 ThreadCount=-23
20140120 11532529 trace TWPManagerServer(045BD670).EndCurrentThread(THttpApiServer(06CE66C0)) ThreadID=4496 ThreadCount=18
20140120 11532529 trace TSettingsServer(045C1090).EndCurrentThread(THttpApiServer(06CE66C0)) ThreadID=4496 ThreadCount=-24
20140120 11532530 trace TWPManagerServer(045BD670).EndCurrentThread(THttpApiServer(06CE7440)) ThreadID=9868 ThreadCount=9
20140120 11532530 trace TSettingsServer(045C1090).EndCurrentThread(THttpApiServer(06CE7440)) ThreadID=9868 ThreadCount=-25
20140120 11532530 trace TWPManagerServer(045BD670).EndCurrentThread(THttpApiServer(06CE71C0)) ThreadID=10336 ThreadCount=7
20140120 11532530 trace TSettingsServer(045C1090).EndCurrentThread(THttpApiServer(06CE71C0)) ThreadID=10336 ThreadCount=-26
20140120 11532530 trace TWPManagerServer(045BD670).EndCurrentThread(THttpApiServer(06CE7040)) ThreadID=9988 ThreadCount=8
20140120 11532530 trace TSettingsServer(045C1090).EndCurrentThread(THttpApiServer(06CE7040)) ThreadID=9988 ThreadCount=-27
20140120 11532530 trace TWPManagerServer(045BD670).EndCurrentThread(THttpApiServer(06CE67C0)) ThreadID=10456 ThreadCount=6
20140120 11532530 trace TSettingsServer(045C1090).EndCurrentThread(THttpApiServer(06CE67C0)) ThreadID=10456 ThreadCount=-28
20140120 11532530 trace TWPManagerServer(045BD670).EndCurrentThread(THttpApiServer(06CE6BC0)) ThreadID=10672 ThreadCount=5
20140120 11532530 trace TSettingsServer(045C1090).EndCurrentThread(THttpApiServer(06CE6BC0)) ThreadID=10672 ThreadCount=-29
20140120 11532530 trace TWPManagerServer(045BD670).EndCurrentThread(THttpApiServer(06CE73C0)) ThreadID=3888 ThreadCount=4
20140120 11532530 trace TSettingsServer(045C1090).EndCurrentThread(THttpApiServer(06CE73C0)) ThreadID=3888 ThreadCount=-30I think it is still necessary to add support for next-gen compiler in the future. There are interesting projects that facilitate the development for ios at Delphi and do not depend from FMX.
https://forums.embarcadero.com/thread.j … &tstart=45
http://www.tmssoftware.com/site/tmsicl.asp
It will be nice to add the checking of user rights to the TSQLRestServer.Batch method
procedure TSQLRestServer.Batch(Ctxt: TSQLRestServerURIContext);
...
if Ctxt.Table<>nil then begin
TableIndex := Model.GetTableIndexExisting(Ctxt.Table);
if not (TableIndex in Ctxt.Call.RestAccessRights^.DELETE) then // check User
begin
Ctxt.Error('', HTML_NOTALLOWED);
exit;
end;
...I found the problem:
Method should be declared:
published procedure GetLicenceInfo(Ctxt: TSQLRestServerURIContext);Because changed type TSQLRestServerCallBack;
TSQLRestServerCallBack = procedure(Ctxt: TSQLRestServerURIContext) of object; TWPManagerServer = class(TSQLRestServerDB)
private
protected
public
published procedure GetLicenceInfo(var Ctxt: TSQLRestServerURIContext);
...The AV occurs in procedure TSQLRestServerURIContext.Returns(
procedure TSQLRestServerURIContext.Returns(const Result: RawUTF8;
Status: integer; const CustomHeader: RawUTF8; Handle304NotModified: boolean);
var clientHash, serverHash: RawUTF8;
begin
if Status in [HTML_SUCCESS,HTML_CREATED] then begin
Call.OutStatus := Status; <- Access violation here
Call.OutBody := Result;I found the problem - after starting the program, I create backup of the database:
WPlaceServer.BackupGZ(DefaultWorkPlace + 'wp.db3.backup');After this WPlaceServer is not working correctly.
Without password works fine. Before execute application the database file does not exists. Version latest.
When I create DBServer with password protection, the DBServer is not working (ESQLite3Exception is raised with message: "library routine called out of sequence").
WPlaceServer := TWPManagerServer.Create(WPModel, DefaultWorkPlace + 'wp.db3', true, 'password');20131004 11315922 + TWPManagerServer(0177FA90).wps/auth?UserName=Admin&Password=d9d759bb3ce365ff9ab7f15f6ee96e64be0886b15df2e547fb13f95faef7d4ec&ClientNonce=fee18bc34e265666e1549fe5f1e8ef9b99dfede52907dbd2946be260e3266277
20131004 11315922 call TWPManagerServer(0177FA90) Auth
20131004 11315922 cache TSQLDatabase(017FA9A0) not in cache
20131004 11315922 SQL TWPManagerServer(0177FA90) SELECT ID,LogonName,DisplayName,PasswordHashHexa,GroupRights FROM AuthUser WHERE LogonName=:('Admin'): LIMIT 1; prepared as SELECT ID,LogonName,DisplayName,PasswordHashHexa,GroupRights FROM AuthUser WHERE LogonName=? LIMIT 1; with 1 param
20131004 11315922 EXC ESQLite3Exception ("library routine called out of sequence") at 002A24A3 SynSQLite3.sqlite3_check (3977) stack trace API 00220850 SynCommons.SynRtlUnwind (31343) 000096C4 System.@HandleOnException (18403)
20131004 11315922 res nullDoes anyone have example how to perform JavaScript execution using the SpiderMonkey library in mORMot?
Using the article from http://www.codeproject.com/Articles/240 … CF-Service
I registered the SSL certificate on my dev computer. But the SSL connection to the mORMot server fails.
After editing unit mORMotHttpServer.pas SSL connection works fine.
I added the optional parameter UseSSL: boolean;
TSQLHttpServer = class
...
constructor Create(const aPort: AnsiString;
const aServers: array of TSQLRestServer;
UseSSL: Boolean = False;
const aDomainName: AnsiString='+';
aHttpServerKind: TSQLHttpServerOptions=useHttpApi; ServerThreadPoolCount: Integer=32); reintroduce; overload;
...
constructor Create(const aPort: AnsiString; aServer: TSQLRestServer;
UseSSL: Boolean = False;
const aDomainName: AnsiString='+';
aHttpServerKind: TSQLHttpServerOptions=useHttpApi; aRestAccessRights: PSQLAccessRights=nil;
ServerThreadPoolCount: Integer=32); reintroduce; overload;
...
function AddServer(aServer: TSQLRestServer; UseSSL: boolean = False; aRestAccessRights: PSQLAccessRights=nil): boolean;
...
function TSQLHttpServer.AddServer(aServer: TSQLRestServer; UseSSL: Boolean;
aRestAccessRights: PSQLAccessRights): boolean;
var i, n: integer;
{$ifdef WITHLOG}
Log: ISynLog;
{$endif}
begin
result := False;
{$ifdef WITHLOG}
Log := TSQLLog.Enter(self);
try
{$endif}
if (self=nil) or (aServer=nil) or (aServer.Model=nil) then
exit;
for i := 0 to high(fDBServers) do
if fDBServers[i].Server.Model.Root=aServer.Model.Root then
exit; // register only once per URI Root address
if fHttpServer.InheritsFrom(THttpApiServer) then
// try to register the URL to http.sys
if THttpApiServer(fHttpServer).
AddUrl(aServer.Model.Root,fPort,UseSSL, fDomainName)<>NO_ERROR then
...
constructor TSQLHttpServer.Create(const aPort: AnsiString;
const aServers: array of TSQLRestServer;
UseSSL: Boolean;
const aDomainName: AnsiString;
aHttpServerKind: TSQLHttpServerOptions; ServerThreadPoolCount: Integer);
var i,j: integer;
ErrMsg: string;
{$ifdef WITHLOG}
Log: ISynLog;
{$endif}
begin
...
if aHttpServerKind in [useHttpApi,useHttpApiRegisteringURI] then
try
// first try to use fastest http.sys
fHttpServer := THttpApiServer.Create(false);
for i := 0 to high(aServers) do begin
j := THttpApiServer(fHttpServer).AddUrl(
aServers[i].Model.Root,aPort,UseSSL,aDomainName, // false
(aHttpServerKind=useHttpApiRegisteringURI));
...
constructor TSQLHttpServer.Create(const aPort: AnsiString;
aServer: TSQLRestServer;
UseSSL: Boolean;
const aDomainName: AnsiString;
aHttpServerKind: TSQLHttpServerOptions; aRestAccessRights: PSQLAccessRights;
ServerThreadPoolCount: integer);
begin
Create(aPort,[aServer],UseSSL, aDomainName,aHttpServerKind,ServerThreadPoolCount);
if aRestAccessRights<>nil then
DBServerAccessRight[0] := aRestAccessRights;
end; I make backup on the server using TZipWrite and download it using http.sys (HTTP_RESP_STATICFILE). No problem here. It can be downloaded with any client having a progress bar.
During backup restoration, I need to upload a file of a big size say 100-500 MB to the server. If I use Client.UpdateBlobField, there is no possibility to output, even approximately, the progress bar.
Is there a possibility to directly upload big size files to the server by using http.sys at the server side?
Thanks ab, with today version all works fine.
If I use more than one TSQLRestClientURI for which OnIdle is defined, the program comes into the loop (the OnIdle event is called all the time).
This can be easily reproduced at the example "04 - HTTP Client-Server".
Database: TSQLRestClientURI;
NewClient : TSQLRestClientURI;
...
procedure TForm1.FindButtonClick(Sender: TObject);
var Rec: TSQLSampleRecord;
begin
Database.OnIdle := OnIdleClient;
...
procedure TForm1.FormCreate(Sender: TObject);
begin
Model := CreateSampleModel; // from SampleData unit
NewClient := TSQLHttpClient.Create( 'localhost','888',Model);
NewClient.OnIdle := OnIdleClient; // NewClient.OnIdle := OnIdleClient2;
NewClient.SetUser('User','synopse');
end;I agree, but JSON was generated by function ISQLDBRows.FetchAllAsJSON
var
res : ISQLDBRows;
Result : RawUtf8;
FProp : TSQLDBFireDACConnectionProperties;
begin
...
Res := FProp.ExecuteInlined(SQL, True);
if res = nil then
Result := ''
else
Result := res.FetchAllAsJSON(False);
end;With the last source (edf68f6b07 ) all work fine.
When JSON looks like:
{"fieldCount":2,"values":["email","licNum","x1@macau.ctm.net",01,"x2@gte.net",01,"x3@active8.nl",01,"x4@unetek.com",01,"x5@home.com",01,"x6@harvard.edu",01,"x7@eds.com",01,"x8@optonline.net",01,"x9@maties.sun.ac.za",01,"x10@pateam.com",01],"rowCount":10}The JSONToDataSet parses only first row and the other rows of FDataSet is empty
FDataSet := JSONToDataSet(self, FRawResult);Screenshot:
Is it correct that while decoding a string field that contains NULL in JSON, decoding must be interrupted? Probably it would be correct to continue decoding?
Type
TLinkItem = class(TCollectionItem)
private
Fid : integer;
Fanchor : String;
Furl : String;
public
constructor Create(Collection: TCollection); override;
destructor Destroy; override;
published
property Anchor : String read Fanchor write Fanchor;
property Id : integer read Fid write Fid;
property Url : String read Furl write Furl;
end;
Type
TLinkItems = Class(TCollection)
private
function GetItem(index: integer): TLinkItem;
procedure SetItem(index: integer; value : TLinkItem);
public
constructor Create;
function Add(_Fid : integer; _Fanchor : String; _Furl : String): TLinkItem;
property Items[index: integer]: TLinkItem read GetItem write SetItem; default;
end;JSON:
[
{
id: 107309,
url: null,
anchor: ""
},
{
id: 107312,
url: "http://www.google.com",
anchor: "google"
}
]Thanks for the answer. I will try to use external shared database.
The OnUpdateEvent at the server side will trigger after Client.Update(U);
It would be nice to add OnUpdateBlobEvent to the TSQLRestServer implementation that would be triggered after UpdateBlobFields
Client Side:
var
U: TSQLAuthUser;
FData : TSQLRawBlob;
begin
U.LogonName := 'blabla';
FData := 'Some data';
....
Client.Update(U);
Client.UpdateBlob(TSQLAuthUser, FID, 'Data', FData);
end;Server Side:
...
WPlaceServer.OnUpdateEvent := UpdateWP;
...
function TEMServer.UpdateWP(Sender: TSQLRestServer; Event: TSQLEvent; aTable: TSQLRecordClass; aID: integer): boolean;
begin
if (Event = seUpdate) and (aTable = TSQLAuthUser) then
begin
U := TSQLAuthUser.CreateAndFillPrepare(sender, 'ID=?', [aID]);
try
U.FillOne;
sender.RetrieveBlob(TSQLAuthUser, U.ID, 'Data', FUserData);
U.Data := FUserData; // ----------------------------------------------------- at this point FUserData - contains old value
g := TSQLAuthGroup.CreateAndFillPrepare(sender, 'ID=?', [U.GroupRights.ID]);
try
g.FillOne;
UpdateUser(U, G);
finally
g.Free;
end;
finally
u.Free;
end;
end;At this time while adding (modifying) TSQLAuthUser in WorkplaceGlobalServer I add (modify)TSQLAuthUser in all WorkplaceXX_Server, which is not convenient. Is there a way to put TSQLAuthUser to the higher (global) level so when you try to query the Workplace1_Server the user authentication is done at the WorkplaceGlobalServer level?
WorkplaceGlobalServer___
|__ TSQLAuthGroup
|__ TSQLAuthUser {user info changed} -> need to change all TSQLAuthUser in Workplace1_Server, Workplace2_Server ...}
|__ WorkplaceNames_
|__ Workplace1_Server
| |____TSQLAuthGroup
| |____TSQLAuthUser
| |____TMyModel1
| |____TMyModel2
|__ Workplace2_Server
| |____TSQLAuthGroup
| |____TSQLAuthUser
| |____TMyModel1
| |____TMyModel2
|__ WorkPlace3_Server
|____TSQLAuthGroup
|____TSQLAuthUser
|____TMyModel1
|____TMyModel2
Is it possible to register (AddServer) TSQLRestServerDB created in the interface based service method to the TSQLWebServer (HttpServer)?
unit GroupItemInterface;
type
IGroup = interface(IInvokable)
['{9A60C8ED-CEB5-4E19-88D4-4A16F496E5FE}']
function Connect(ID: integer): integer;
end;unit MyServer;
type
TGroupItem = class(TInterfacedObject, IGroup)
protected
FModel : TSQLModel;
FServer : TSQLRestServerDB;
public
destructor Destroy; override;
public
function Connect(ID: Integer): Integer;
end;
....
Type
TMyServer = class(TObject)
private
HttpServer : TSQLWebServer;
AbkServer : TSQLRestServerFullMemory;
end;
...
GroupItemModel := CreateGroupItemModel;
AbkServer := TSQLRestServerFullMemory.Create(GroupItemModel,'users.json',false,true);
AbkServer.ServiceRegister(TGroupItem,[TypeInfo(IGroup)],sicPerUser).SetOptions([],[optExecInMainThread,optFreeInMainThread]);
HttpServer := TSQLWebServer.Create('8080',[AbkServer]);
HttpServer.AccessControlAllowOrigin := '*';
..
function TGroupItem.Connect(ID: Integer): Integer;
begin
FModel := TSQLModel.Create([TEmailItem, TExclusionItem],'groupitem_'+inttostr(ID));
FModel.SetCustomCollationForAllRawUTF8('NOCASE');
FServer := TSQLRestServerDB.Create(FModel, 'd:\em\abk_'+inttostr(ID)+',db3', True);
FServer.CreateMissingTables(0);
end;or am I on the wrong way?
Is there a possibility to organize a kind of workplaces using framework in order a separate copy of data is created on the server for each client?
If the client User_A connects to the server, the database for this client will be d:\storage_User_A.db
StorageServer := TSQLRestServerDB.Create(StorageModel, 'd:\storage_User_A.db3', true);
For User_B the database will be d:\storage_User_B.db accordingly.
RestClient -> URL: http://localhost/root/User_A/SampleRecord -> RestServer -> DB_User_A.db3
RestClient -> URL: http://localhost/root/User_B/SampleRecord -> RestServer -> DB_User_B.db3