PDA

View Full Version : [help] web server and ado connection



smack_dead
05-05-2014, 02:20 PM
hey everyone im building a web server in delphi 7 with my sql, and after i finish i tried conect my web server with data base, so i use one ado conection but when i run my web server the service stop... some one can give me a tips for use ado connection ...

AthenaOfDelphi
05-05-2014, 02:28 PM
The short and somewhat unhelpful answer on tips to use ADO might be don't :)

On a more helpful note....

Which web server components are you using, the Indy ones, or are you writing a CGI app or an ISAPI/Apache module?

Are you creating one connection to the database and then using it when you process all the requests? Web servers are normally multi-threaded and you can get into a real mess if you're not handling ADO properly.

So, can you give us some example code? Where you setup the connection, where you use it, that sort of thing?

smack_dead
05-05-2014, 02:38 PM
;) so im using iis 7 , i creat new soap with cgi and with soap module... i creat some functions and some arrays ...

array implemented in interface

Tcustomer = class(Tremotable)
private
FcustUserName : String;
FcustCode : String;
FcustName : String;
FcustInvoiceAddress : Tadress;
FcustDeliveryAddress : Taddresses;
FcustNIF : String;
FcustLogged : String;
FcustCurrentAcount : String;
FcustCurrentAcountDocs : Tdocuments;
FcustPendingOrders : Torders;
published
property custUserName : string read FcustUserName write FcustUserName;
property custCode : string read FcustCode write FcustCode;
property custName : string read FcustName write FcustName;
property custInvoiceAddress : Tadress read FcustInvoiceAddress write FcustInvoiceAddress;
property custDeliveryAddress : Taddresses read FcustDeliveryAddress write FcustDeliveryAddress;
property custNIF : string read FcustNIF write FcustNIF;
property custLogged : string read FcustLogged write FcustLogged;
property custCurrentAcount : string read FcustCurrentAcount write FcustCurrentAcount;
property custCurrentAcountDocs : Tdocuments read FcustCurrentAcountDocs write FcustCurrentAcountDocs;
property custPendingOrders : Torders read FcustPendingOrders write FcustPendingOrders;
end;


and i try use in webmodule ado querys and ado connection for use in my function on the implementation

exemple..

function Twebserver.Login(AUserName, APassword: string) : Tcustomer;
VAR
lista_info: Tcustomer;

begin

lista_info := tcustomer.create;

//////////////login success///////////////////////////////////
// D.qUtilizadores.SQL.Clear;
webmodule.adologin.SQL.Text:='Select codentidade, nome, nipc, web_passwd from entidades where codentidade='''+AUserName+''' and web_passwd='''+APassword+'''';

result := lista _info
exit;


and in my client when i active the ado connection i got erro 500 in browser wsl and login in client dont work, he dont enter....

AthenaOfDelphi
05-05-2014, 02:50 PM
I'm sorry if I ask a dumb question... do you know how to do normal file handling in Delphi? If you're getting a 500 error then your CGI is probably excepting, you're going to need to find out what the exception message is before you go any further.

Simplest way would be to create a log file, and wrap the connection activation in a try..except block, capture the exception and write the message out to your log file. Let me know if you'd like some example code for this.

Without knowing what's going on when you try the connect, it's a complete guessing game.

smack_dead
05-05-2014, 03:07 PM
yeah i know but only apear this error when my ado connection are true and i build the web server if he stay false my webserver run normaly..

AthenaOfDelphi
05-05-2014, 03:16 PM
You're going to need to grab the exception that's being raised when you're connecting to the database I'm afraid before I can provide advice on how to fix it.

Dumb question time again... at design time, can you connect to the database using the ADOConnection object? Have you turned off the 'Login Prompt' (I think the property is LoginPrompt - set it to false if you haven't already).

smack_dead
05-05-2014, 03:20 PM
yup i can connect at the desing and login are false :S im using drives odbc may be this is the problem

AthenaOfDelphi
05-05-2014, 03:27 PM
So you've got the MySQL ODBC drivers installed... you can connect at design time and login prompt is false.... I'm afraid, it's exception catching time. I've used the MySQL ODBC drivers myself for a while in a CGI (admittedly it was a long time ago, but I know they used to work).



var
logFile : textFile;

....

assignFile(logFile,'MyLogFile.log');
rewrite(logFile);

....

try
adoConnection.connect; // I can't remember the exact method as I've not used ADO for a long time
except
on e:exception do
begin
writeLn(logFile,'Exception class '+e.className+'. Message:- '+e.message);
end;
end;

closeFile(logFile);


Something like that :-) If it's definitely going bang when you're connecting, then this should give you a fighting chance of figuring out why.

smack_dead
05-05-2014, 03:54 PM
and you know other method to doing web service??? easier...

AthenaOfDelphi
05-05-2014, 04:02 PM
If you were just going to write a web server that serves pages and files (as opposed to a web service like SOAP), I'd go for the completely self contained option using the Indy HTTP server. Unfortunately, you're not, so the answer is no I don't.

If it's going bang when you're connecting to the database, then something is either wrong with your connection settings (unlikely as you can connect at design time, unless you're testing it on another machine where the user doesn't have access to the database - MySQL permissions allow for host specific access control, so what works for one user on machine A may not work for that same user on machine B), or you've not done something that the IDE does for you at design time.

ADO uses COM (I believe), in your code, have you made a call to coInitialize? If not, the COM/ActiveX won't be initialised and all your ADO calls will fail. So if you've got a datamodule, then I would be inclined to use the create and destroy events of the module to call coInitialize and coUninitialize.

smack_dead
05-05-2014, 04:18 PM
i tried but i got the same error in client ...acecess violation at address....in module webserver.exe...... baah dont work and dont creat the file....

AthenaOfDelphi
05-05-2014, 04:26 PM
You're going to have to post the entire method where you are initialising the database.

smack_dead
05-05-2014, 04:30 PM
ok i have ado querys and in design and i use this
webmodule.adologin.SQL.Text:='Select codentidade, nome, nipc, web_passwd from entidades where codentidade='''+AUserName+''' and web_passwd='''+APassword+'''';
webmodule.adologin.SQL.open;

dont have nothing more in my query....
in my client im using this ....

var rest:tcustomer;

begin
try
result := (httprio as iwebserver).login(edit1.text, edit2.text);
except
on e:exception do
showmessage(E.message);
end;
end;

AthenaOfDelphi
05-05-2014, 04:37 PM
It's impossible to follow exactly what's going on from the snippets you're posting I'm afraid.

Is the code part of a commercial project or is it something you'd just rather not get out into the wider world?

If not, then my suggestion is ZIP it ALL up (and I mean everything, server, client, everything) and either attach it here or if you don't want it to be public, mail it to me (athena at pascalgamedevelopment dot com) and I'll take a look at it.

smack_dead
05-05-2014, 04:42 PM
i will send plz check it ... and tanx

pitfiend
05-05-2014, 04:46 PM
There are many things that could be wrong.
First, I suggest you to drop everything BDE/ADO/DBX and go with Zeoslib, direct connection with native libraries, and open source.
Second, did your mysql is well configured? no local bindings, open for all, no network filters, no weird firewall rules.
Thirth, check your dlls, sometimes wrong versions throw weird errors, you need to double check your path for multiple dlls (happens to me once, two weeks wasted looking for the problem source, I wasn't aware of a very old dll in the delphi bin dir).
Last, do you a favor, drop iis and go apache.

smack_dead
05-05-2014, 04:52 PM
can you help-me ??? send me your first change, because i dont know what is Zeoslib.... thanx for your time....

AthenaOfDelphi
05-05-2014, 05:22 PM
Ok, this is well outside my comfort zone as I've never worked with this kind of web service... but having just created one in D2009 (I haven't run it, just created the project), I have a few observations.

In the created one (with example methods), all methods use STDCALL;, both on the interface in the class definition AND in the actual implementation too.
All the parameters in the example are passed in as CONST.

So in WebServerIntf.pas you have:-



IWebServer = interface(IInvokable)
....
function Login(AUserName, APassword: string) : Tcustomer; stdcall;
....
end;


Change the parameters to:-



IWebServer = interface(IInvokable)
....
function Login(const AUserName:string;const APassword: string) : Tcustomer; stdcall;
....
end;


The same applies to all of them.

And in WebServerImpl.pas change the interface to have:-



function Login(const AUserName:string;const APassword: string) : Tcustomer; stdcall;


Change the parameters and add STDCALL to the implementation:-



function Twebserver.Login(const AUserName:string; const APassword: string) : Tcustomer; stdcall;


You may also need to use AnsiString instead of string... the example methods I had the IDE add pass strings around but they are AnsiString (this applies to the fields in objects). HTTP and CGI specs (at least as far as I know) do not support Unicode directly, so the strings etc. you receive from and send to the client can only ever be standard 8 bit chars, you have to handle character encoding yourself.

The fact that it didn't create the log file (unless it's been created in some obscure location) suggests that the access violation is being raised by some of the inner workings, possibly relating to the parameter passing and types.

I hope this helps, if not, I'm afraid I've reached the limits of my knowledge on this type of service.

smack_dead
05-05-2014, 05:26 PM
ok i will try but now only tomorow i will post the changes , thanx a lot, tomorow i will write to you...

smack_dead
06-05-2014, 01:25 PM
i tried but dont work :s

smack_dead
06-05-2014, 04:36 PM
ehhh thanx a lot my friend for your time i got the solution ..you cant use design mode you need create adoquerty in your code....in your implementation :DD

exemple:
adoquery.create(nil);
conectionstring:='Driver={MySQL ODBC 5.1(in my case 3.51) Driver};Server=localhost(in my case 127.0.0.1);database=mysql;User=root; Password(in my case root)=;Option=3;';
....
....

in my case of course , but i lose a lot of time with connectionstring...enjoy, may be in future some one will need :DDD