You are not logged in.
Pages: 1
Hi,
I'm working on an Delphi project that use the mORMot Framework. I have a client/server application that work on a LAN but I think you just know it .
I want add advanced options to import and export data from databasefrom/to many types of files. I'd like create 2 DLL for these reason to not add many code to my application.
I only developed a library until now, so I'd like to know the opinion of the administrator.
The user can import/export data only from/to the opening database and I think I have 2 altervatives:
1) I can pass my database object (TSQLRestClientURI) from application to DLL: I don't know if this way works but if it works I can import/export data from any computer of my LAN. I have read of memory problem with DLL if I use object.
2) I can pass only database filename, then open this database from DLL and import/export data. In this way I open the some database both on application and DLL and I don't know if it is a good idea. Besides in this way I can use import/export data only from server application (not from client application).
I think the 1) is the best solution for me but I don't know if is possible. What do you think about it? Is possible pass the database object from application to DLL, make import/export function than close DLL without problem?
If you have other ideas, these are welcome.
Offline
I love most every day this framework. Is there a small example about it? Can you add a small demo to your framework demos?
I'have tried to load the documentation without success, I don't have write many DLL untiln now.
Offline
I have read the documentation to try to create my DLL.
1) In my DLL I will use TSQLRestClientURIDll to connect with my database (the database is open inside the application);
2) To create TSQLRestClientURIDll inside the DLL I need pass as parameter the TURIMapRequest object from my application to my DLL, this object. In fact I need use TSQLRestClientURIDll.Create(aModel: TSQLModel; aRequest: TURIMapRequest);
However I don't have understand how I can create TURIMapRequest from my server. In your documentation I see this:
TURIMapRequest = function(url, method, SendData: PUTF8Char; Resp, Head: PPUTF8Char): Int64Rec; cdecl;
But in practice how can I create this object? With such parameters?
Offline
Create a global function like this:
function MyUrlMapRequest(url, method, SendData: PUTF8Char; Resp, Head: PPUTF8Char): Int64Rec; cdecl;
begin
.... implement here
end;
In fact, this is not a class method, but a plain global function.
Online
OK, so this function is use inside the application to "execute" the request by the TSQLRestClientURIDll object inside the DLL, right?
and what I need implement in this function? For example my dll must import some new record inside a table of my database.
Offline
You have already a typical implementation of this function in SQLite3Commons.pas.
You only need to:
- Set a TSQLRestServer instance to the GlobalURIRequestServer variable - this can be done directly by calling the TSQLRestServer.ExportServer method;
- Use URIRequest global function, which maps TURIMapRequest prototype.
See:
/// this function can be exported from a DLL to remotely access to a TSQLRestServer
// - use TSQLRestServer.ExportServer to assign a server to this function
// - return 501 NOT IMPLEMENTED error if no TSQLRestServer.ExportServer has been assigned
// - memory for Resp and Head are allocated with GlobalAlloc(): client must release
// this pointers with GlobalFree() after having retrieved their content
// - simply use TSQLRestClientURIDll to access to an exported URIRequest() function
function URIRequest(url, method, SendData: PUTF8Char; Resp, Head: PPUTF8Char): Int64Rec; cdecl;
If you define USEFASTMM4ALLOC = true, it will use FastMM4 instead of slower GlobalAlloc/GlobalFree.
But the FastMM4 instance must be shared between the main process and the library.
Online
Until now I have understand:
1) On my application I must call TSQLRestServer.ExportServer to set GlobalURIRequestServer;
2) On my dll I must TSQLRestClientURIDll as client, however TSQLRestClientURIDll have 2 Create function and I think I must use Create(aModel: TSQLModel; aRequest: TURIMapRequest); because my database is on my application.
I don't understand this TURIMapRequest, you say "Use URIRequest global function, which maps TURIMapRequest prototype.". I must use the function URIRequest as aRequest parameter? What maen your post #5?
Offline
OK, I have make some test.
On my application I call my DLL function with this code:
var
fHND: THandle;
DLLTestExetute: TDLLTestExetute;
begin
if FileExists(AppPath + 'cltest.dll') then
begin
DatabaseServer.ExportServer;
fHND := LoadLibrary(pChar(AppPath + 'cltest.dll'));
try
if fHND <> 0 then
begin
@DLLTestExetute := getProcAddress(fHND, 'DLLExecute');
DLLTestExetute();
end
else
begin
// MSG DLL NOT LOAD
end;
finally
if fHND <> 0 then
FreeLibrary(fHND);
end;
end
else
begin
// MSG DLL NOT FOUND
end;
this is my dll code:
procedure DLLExecute();
var
client: TSQLRestClientURIDll;
test: TSQLTableJSON;
begin
client := TSQLRestClientURIDll.Create(GetDatabaseModel(), URIRequest);
MessageDlg('TableRowCount: ' + IntToStr(client.TableRowCount(TSQLProjects)), mtConfirmation, [mbOK], 0);
if client <> nil then
begin
test := client.ExecuteList([], 'SELECT COUNT(*) FROM Projects');
if test <> nil then
begin
try
if test.RowCount > 0 then
begin
MessageDlg('Record number: ' + IntToStr(test.RowCount), mtConfirmation, [mbOK], 0);
end
else
begin
MessageDlg('NO ROWS', mtConfirmation, [mbOK], 0);
end;
finally
test.Free;
end;
end
else
begin
MessageDlg('TEST NIL', mtConfirmation, [mbOK], 0);
end;
client.Free;
end
else
begin
MessageDlg('CLIENT NIL', mtConfirmation, [mbOK], 0);
end;
end;
exports
DLLExecute;
this code doesn't work, client.TableRowCount(TSQLProjects) = -1 but the Project table have 5 records besides TEST is nil.
So I think there are some errors on my code.
Any suggestions?
Offline
But the code is corret? I have debugger the application without success.
Offline
From my test when I use my code to call dll function (post #10) don't call TSQLRestServer.URI. So I think there is a error on my code but I don't understand where.
Offline
OK but I need the server on the application and the client on DLL. The dll is only a plugin of my application to import data into database from few file format (csv, xml, ...).
This is my idea: I have I server application and more client application, the server application can use the dll (as another client) to import the data into the database.
Is it possible?
On your framework I can use the DLL only as server? or there a solution for me
Offline
On your framework I can use the DLL only as server? or there a solution for me
You can do that, of course.
But you'll have to reverse the function use, and provide some external functions exported from the DLL to start and stop the server.
When starting the server, you can return a pointer to the may URIRequest function to be called from your main executable.
Online
There is something you still do not understand.
On application (for me the server) I use:
DatabaseServer.ExportServer;
then call the DLLExecute function to execute the code inside the dll, in my application I use:
client := TSQLRestClientURIDll.Create(GetDatabaseModel(), URIRequest);
to create my client and import the data inside the database, what are these functions that I need invert?
Offline
Pages: 1