Lazarus

Programming => Databases => Topic started by: cov on April 27, 2013, 10:38:29 am

Title: Firebird: how to tell if the database is running.
Post by: cov on April 27, 2013, 10:38:29 am
If the Database isn't running, then I get an exception

Quote
Project raised exception class 'EIBDatabaseError' with message:
IBConnection1 : DoInternalConnect:
- unavailable database


Code: [Select]
    with IBConnection1 do
    begin
      try
        DatabaseName:=fbhost+DatabaseList;
        UserName:=dbUser;
        Password:=dbPass;
        tableList:= TStringList.Create;
        GetTableNames(tableList,False);
        if tableList.Count<4 then
          createTables;
        tableList.Free;
      except
        Form1.showDatabaseHelp;
      end;
    end;

How can I check if the database is running?
Title: Re: Firebird: how to tell if the database is running.
Post by: ludob on April 27, 2013, 10:59:21 am
Quote
How can I check if the database is running?
By doing as you just did, trying to connect to it. That is the best and most universal approach.

If you want to find out why it is not running, then you have many options depending on what your architecture is (embedded, server on same computer, remote server,...) but none belong in a DB application.

See more here: http://www.firebirdfaq.org/faq123/


Title: Re: Firebird: how to tell if the database is running.
Post by: cov on April 27, 2013, 11:20:58 am
Thanks for the response.

I want the showDatabaseHelp form to be displayed if the Database isn't running, rather than the Exception error messages.

What's happening now is that the user just gets an access violation and an offer to close the program or risk data corruption.
Title: Re: Firebird: how to tell if the database is running.
Post by: BigChimp on April 27, 2013, 11:26:47 am
BTW: please always post FPC+Lazarus+OS version. There were problems with older 64 bit windows Lazarus+embedded Firebird versions.

You can add the info to your forum signature (go to the profile page) so you don't need to remember to write it down.

I'll also let Ludo have a go, but: I don't see anything that activates the connection. I'm assuming GetTableNames does that? Do you have an exception handler there? Does it run showDatabaseHelp?
Title: Re: Firebird: how to tell if the database is running.
Post by: ludob on April 27, 2013, 11:47:03 am
Quote
I want the showDatabaseHelp form to be displayed if the Database isn't running, rather than the Exception error messages.
Do an explicit IBConnection1.Connected:=true inside a try except and show the form in the except block. Put the lot inside a loop that exits only when the connection is made or the user cancels your form.

EDIT: And since you are apparently using Lazarus, make sure that you haven't already set connected:=true in the Object Inspector.
Title: Re: Firebird: how to tell if the database is running.
Post by: cov on April 27, 2013, 11:50:53 am
Well, I'm hoping to compile under various Operating systems, but am currently using Lazarus 1.1 r40379 FPC 2.6.1 i386-win32-win32/win64 on a Virtualbox VM running Windows XP on a Linux 3.2.0-36-generic #57-Ubuntu SMP Tue Jan 8 21:44:52 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux host.

Title: Re: Firebird: how to tell if the database is running.
Post by: cov on April 27, 2013, 12:04:35 pm
I don't see anything that activates the connection. I'm assuming GetTableNames does that? Do you have an exception handler there? Does it run showDatabaseHelp?

Thanks, that may well be the problem.

What action will generate an exception if Firebird isn't running? Do I need to have a path to the database?
Title: Re: Firebird: how to tell if the database is running.
Post by: BigChimp on April 27, 2013, 12:29:16 pm
What Ludo said: IBConnection1.Connected:=true.
And yes, you need a path to the db or an alias set up on the server - if so you can connect without a path.
See the docs eg
http://www.freepascal.org/docs-html/fcl/ibconnection/tibconnection.databasename.html
Title: Re: Firebird: how to tell if the database is running.
Post by: cov on April 27, 2013, 12:51:36 pm
Code: [Select]
  DatabaseRunning:=True;
  IBConnection1.DatabaseName:=tmpPath+'tmp.fdb';
  IBConnection1.UserName:=dbUser;
  IBConnection1.Password:=dbPass;
  try
    IBConnection1.CreateDB;<- Exception raised here
  except
    ShowMessage('Database not running');
    DatabaseRunning:=False;
  end;

The gdb raises the "unavailable database" exception, but running the executable shows the "Database not running" message but the error generates an alert that says: "Access violation. Press OK to ignore and risk data corruption. Press Cancel to kill the program."

I want to give the user a hint into what the problem might be.
Title: Re: Firebird: how to tell if the database is running.
Post by: BigChimp on April 27, 2013, 12:59:53 pm
Seems you haven't set the connection's hostname?
http://www.freepascal.org/docs-html/fcl/ibconnection/tibconnection.createdb.html

Could be wrong path. Is the path allowed on the server?


Note: if you hit errors, I would strongly suggest reviewing the documentation of the relevant keywords/functions/methods first.

Edit: you can use the Connected property of the connection instead of your DatabaseRunning variable if you want to...
Title: Re: Firebird: how to tell if the database is running.
Post by: cov on April 27, 2013, 01:54:28 pm
The Path is fine.

'C:\DOCUME~1\dave\LOCALS~1\Temp\TMP.FDB'

It works fine if the Database is running.

I just get errors if Firebird is not running.

These are the errors I'm trying to intercept.

And yes, I did read the Documentation.

As for using the 'Connected' property, my understanding is that this gives an indication of whether the IBConnection component is connected or not, which would be different to whether Firebird is actually running.

But, as you point out in your NOTE, it is very likely that my understanding is deficient.
Title: Re: Firebird: how to tell if the database is running.
Post by: BigChimp on April 27, 2013, 02:04:02 pm
Ehm yes, as Ludo pointed out, you can only test whether you can have a connection to Firebird with .Connected.
I don't see how your DatabaseRunning gets more information though.

If you want to find out if Firebird is running on a server, you have to resort to other things (such as  run ps or tasklist on the server etc).

BTW, I'm assuming you only use CreateDB when the database does not yet exist? And that you use .Connected:=true somewhere else?
Title: Re: Firebird: how to tell if the database is running.
Post by: cov on April 27, 2013, 02:48:03 pm
Yes, I did follow the link that Ludo gave and, yes, the suggestion is that a try/except block is the best way to go.

Other options are to check whether port 3050 is open or look at which processes are running.

However, these aren't easily adapted to the various platforms.

The other option to ping the server doesn't seem very practical; you can still get a response, even if Firebird isn't running.

My problem is that the exception is not being caught: It's generating an error message which asks the user to shut down the program or risk data corruption, which is not what I want.
Title: Re: Firebird: how to tell if the database is running.
Post by: ludob on April 27, 2013, 02:54:06 pm
If you don't have an existing database to attach to, try to connect to the service manager:

Code: [Select]
uses
  ...,FBAdmin;

var
  adm:TFBAdmin;
begin
  adm:=TFBAdmin.Create(nil);
  try
    adm.User:='SYSDBA';
    adm.Password:='yourpassword';
// specify adm.Host if connectiong to a remote server
    if adm.connect then
       writeln('connected')
    else
       writeln('server not running');
  finally
    adm.Free;
  end;
end.

Title: Re: Firebird: how to tell if the database is running.
Post by: BigChimp on April 27, 2013, 02:58:28 pm
Quote
However, these aren't easily adapted to the various platforms.
Yes, it is platform dependent and even FB dependent (Classic versus Superserver) etc.

Quote
My problem is that the exception is not being caught: It's generating an error message which asks the user to shut down the program or risk data corruption, which is not what I want.
Yes. You're not especially clear in what code you currently have and you haven't showed us the code where .Connected is set to true, so there might be other errors, but that part with the .CreateDB shouldn't generate an AV (as you're running on 32 bits FPC you shouldn't have problems with the dlls I referred to earlier).

So: are you sure the access violation is in the code snippet you showed us and not somewhere down the line?

You could go project/publish project and zip up your project files and your Firebird DDL, and attach them as a zip, or send them via PM if you want me to take a look.
This piecemeal remote debugging via code snippets gets a bit tedious... for both ends, I think :)

If the project is confidential, you could perhaps create a non-confidential version.
Title: Re: Firebird: how to tell if the database is running.
Post by: JD on April 27, 2013, 04:23:41 pm
If you want to know if the Firebird Server is running, you can use the code at the following website http://www.chami.com/tips/delphi/031498D.html (http://www.chami.com/tips/delphi/031498D.html)

Before I try to connect to the database, I test to know if the Firebird server is running using the code below

Code: [Select]
  { Test for Firebird embedded, server and client installations }
  if FileExistsUTF8(ExtractFilePath(Application.ExeName) + 'fbclientd.dll') then
  begin
    strProtocolType := 'firebirdd-2.5';     // Firebird Embedded 2.1.3+
    frmMainform.strServerType := 'firebird embedded';
    UsesFirebirdEmbeddedServer := True;
  end
  else
  begin
    strProtocolType := 'firebird-2.5';     // Firebird Client or Server 2.1.3+
    if ServiceRunning('', 'FirebirdServerDefaultInstance') then        // Localhost
      frmMainform.strServerType := 'firebird server'
    else
      frmMainform.strServerType := 'firebird client';
    UsesFirebirdEmbeddedServer := False;
  end;

ServiceRunning is one of the functions at the website whose link is given above. Of course, this works only on Windows. I've never tried it on Linux BUT I would welcome any tips on how to test to see if Firebird server is running on Linux.

Hope it helps,

JD

Title: Re: Firebird: how to tell if the database is running.
Post by: BigChimp on April 27, 2013, 04:43:57 pm
Nice approach to query the Windows service - though I suspect you can start the FB server manually, too. I'd therefore rather use taskmanager (or the API equivalents with FPC)
Edit:
http://wiki.lazarus.freepascal.org/Windows_Programming_Tips#Showing.2Ffinding_processes

I've never tried it on Linux BUT I would welcome any tips on how to test to see if Firebird server is running on Linux.
http://www.firebirdfaq.org/faq123/

:)
Title: Re: Firebird: how to tell if the database is running.
Post by: cov on April 27, 2013, 04:58:52 pm
As Big Chimp correctly surmised, an error had crept into my code (I freed a dynamic form too early), so the error which came up was nothing to do with the fact that Firebird wasn't running and, although the GDB stopped my code at point where the IBDConnect component connected, running the executable on it's own allowed the exception to be caught correctly.

I hear what you're saying about the snippets of code.

Although the project isn't exactly top secret, I'd be a little peeved if a more competent programmer managed to put a product on the market which does what my app is supposed to do (and probably did it better).

I have, in the past, put together half-projects to demonstrate where some code was misbehaving and would have done so again, had your suggestion to look elsewhere not borne fruit.
Title: Re: Firebird: how to tell if the database is running.
Post by: BigChimp on April 27, 2013, 05:37:00 pm
Good - glad it's solved ;)
TinyPortal © 2005-2018