Subject | Strange restore problem in embedded firebird |
---|---|
Author | Dave Hughes |
Post date | 2005-12-10T18:45:36Z |
Hi,
For a few months I've been working on an application using the Embedded
Firebird database engine (currently using the latest 1.5 release,
1.5.2.4731). However, I've been encountering a strange problem
when restoring databases from a backup. I've managed to workaround the
problem, but it's a horrible method which I suspect is bound to fail at
some point, and I'd really like to find out how to fix it properly...
Without going into too much boring detail, a "document" in this
application is essentially a *backup* of a Firebird database (the
application needs to use ALTER TABLE quite a bit, so using backups
in this way mitigates the problem of a database freezing after a table
has been altered 200 or so times). Hence, the usual operations in the
File menu are implemented as follows:
New
===
1. Use isc_dsql_execute_immediate to execute a CREATE DATABASE
statement, which creates a new firebird database in the system's TEMP
directory
2. Open a connection to the database and execute some SQL to
create various tables and views in the database that the application
needs
Save
====
1. Close the connection to the database
2. Use isc_service_attach to attach to the local service manager
3. Use isc_service_start with action isc_action_svc_backup to backup the
database from the system's TEMP directory to whatever file the user
specified in a save dialog
4. Use isc_service_detach to detach from the local service manager
5. Reopen the connection to the database
Close
=====
1. Close the connection to the database
2. Delete the database from the TEMP directory
Open
====
1. Use isc_service attach to attach to the local service manager
2. Use isc_service_start with action isc_action_svc_restore to restore
the file specified by the user in an open dialog to a database in the
system's TEMP directory
3. Use isc_service_detach to detach from the local service manager
4. SLEEP...
5. Open a connection to the database
The problem is step 4 in the Open operation. If, after restoring the
database from the user-specified file I *immediately* open a connection
to it and start running queries I always wind up with one of two errors:
1. Either the Firebird engine throws an error stating that the database
was truncated and it hit the end of the file before it expected to
2. Or, the first query to get run fails complaining that the view or
table it's trying to access doesn't exist
However, if I have the application sleep for at least a second after
restoring the database, but before opening a connection and querying
things then it works perfectly! This feels like a race condition to me,
as though the restore operation is happening in a background thread and
hasn't really finished by the time isc_service_detach returns.
So, are there any steps I'm missing? Should I be waiting on something
before trying to open a connection to the newly restored database? Or
is it possibly a bug in the embedded engine itself?
For reference, I'm writing the application in Delphi, and using the
ZeosDBO components (zeoslib.sourceforge.net) for connecting to the
embedded Firebird database engine (as well as other remote databases).
Any suggestions gratefully accepted!
Cheers,
Dave.
For a few months I've been working on an application using the Embedded
Firebird database engine (currently using the latest 1.5 release,
1.5.2.4731). However, I've been encountering a strange problem
when restoring databases from a backup. I've managed to workaround the
problem, but it's a horrible method which I suspect is bound to fail at
some point, and I'd really like to find out how to fix it properly...
Without going into too much boring detail, a "document" in this
application is essentially a *backup* of a Firebird database (the
application needs to use ALTER TABLE quite a bit, so using backups
in this way mitigates the problem of a database freezing after a table
has been altered 200 or so times). Hence, the usual operations in the
File menu are implemented as follows:
New
===
1. Use isc_dsql_execute_immediate to execute a CREATE DATABASE
statement, which creates a new firebird database in the system's TEMP
directory
2. Open a connection to the database and execute some SQL to
create various tables and views in the database that the application
needs
Save
====
1. Close the connection to the database
2. Use isc_service_attach to attach to the local service manager
3. Use isc_service_start with action isc_action_svc_backup to backup the
database from the system's TEMP directory to whatever file the user
specified in a save dialog
4. Use isc_service_detach to detach from the local service manager
5. Reopen the connection to the database
Close
=====
1. Close the connection to the database
2. Delete the database from the TEMP directory
Open
====
1. Use isc_service attach to attach to the local service manager
2. Use isc_service_start with action isc_action_svc_restore to restore
the file specified by the user in an open dialog to a database in the
system's TEMP directory
3. Use isc_service_detach to detach from the local service manager
4. SLEEP...
5. Open a connection to the database
The problem is step 4 in the Open operation. If, after restoring the
database from the user-specified file I *immediately* open a connection
to it and start running queries I always wind up with one of two errors:
1. Either the Firebird engine throws an error stating that the database
was truncated and it hit the end of the file before it expected to
2. Or, the first query to get run fails complaining that the view or
table it's trying to access doesn't exist
However, if I have the application sleep for at least a second after
restoring the database, but before opening a connection and querying
things then it works perfectly! This feels like a race condition to me,
as though the restore operation is happening in a background thread and
hasn't really finished by the time isc_service_detach returns.
So, are there any steps I'm missing? Should I be waiting on something
before trying to open a connection to the newly restored database? Or
is it possibly a bug in the embedded engine itself?
For reference, I'm writing the application in Delphi, and using the
ZeosDBO components (zeoslib.sourceforge.net) for connecting to the
embedded Firebird database engine (as well as other remote databases).
Any suggestions gratefully accepted!
Cheers,
Dave.