Hi Jon. What do you mean with limitations in firebird?
Yeah, I would say the other way around. Although there is a bit of fiddling with firebird to get it to go, vs just choosing the driver with SQLite. Not a lot of fiddling, but itâs not as easy.
Firebird also has the option to expand to true DBMS with little effort, which is worth something.
Hi Dirk,
Talking specifically about the embedded version (not client-server)âŚthe help says:
Client access can be only via the local (XNET) protocol, i.e. NOT a TCP/IP local loopback connection string that includes the server name âlocalhostâ or the IP address 127.0.0.1. The embedded server supports only the local connect to an absolute database file path without a server name.
The client program gets exclusive access to the database file after successful connect. If another Firebird server already has a client attached to the database, the client program will be denied access. This is intentional.
Compare that to SQLite, where the client program does not get exclusive access to the file, so you can have multiple clients happily retrieving information from the same SQLite database concurrently. Changing data is another story.
Jon
Hi Jon,
By default, Firebird 3 embedded will indeed require exclusive access to the database. This can be changed by making sure there is a firebird.conf
in the same location as your fbclient.dll
used by your application, and setting the ServerMode
setting to SuperClassic
or ThreadedShared
So what i have is:
if ~exists(Clip(glo:uncDatapath)&'\fbclient.dll')
stop(' Firebird file fbclient.dll is not found')
HALT(0,'fbclient.dll is not found')
elsif ~exists(Clip( glo:uncDatapath)&'\firebird.conf')
...........
This also prevents a problem if a firebird server is installed for another program on the same machine because first it will look for gds32.dll in c:\windows\system32
Hi Dirk - Can you show what the conf file looks like?
Thank you
Hi Jeff,
I only commented the last sentence in the conf file
#ServerMode = Super
and added
ServerMode = SuperClassic
Using fbclient.dll version 3.0x
Two more settings i have are
a: to prevent looking for gds32.dll in c:\windows\system32
LOC:ODBCDriver=clip(LOC:ODBCDriver)&â;CLIENT=fbclient.dllâ
b: if firebird odbc is not found on the machine
loc:longpath=makeunc(getreg(reg_local_machine,'SOFTWARE\ODBC\ODBCINST.INI\Firebird/InterBase(r) driver','Driver'))
if ~exists(clip(loc:longpath))
CASE MESSAGE('The Firebird ODBC driver is not found do you want to install it now?','Error',ICON:Question,BUTTON:Yes+BUTTON:No,BUTTON:No,1)
OF BUTTON:YES
if exists(clip(glo:uncInstallatPath)&'\Firebird_ODBC_2.0.5.156_Win32.exe')
run(clip(glo:uncInstallatiepad)&'\Firebird_ODBC_2.0.5.156_Win32.exe /VERYSILENT',1)
else
message('Copy: https://firebirdsql.org/en/odbc-driver and surf to|Download 32 bits Windows ODBC version 2.05|(Firebird_ODBC_2.0.5.156_Win32.exe) and install it','Message',,,,MSGMODE:CANCOPY)
HALT(0,'Firebird ODBC not correct installed')
! HALT should not be used in multi-DLL application?
end
END !case
end !exists
We are in the process of migrating away from TPS to SQLite3.
To keep it short:
- Clarion SQLite3 driver had a bunch of issues that made the migration a no-go in a multi-user environment
- SQLite3 is extremely capable and fast
- SQLite3 adds some extra complexity if you need to use it over LAN due to how file locking works
- Full text search out of the box
I made the necessary plumbing that keeps the SQLite3 databases in sync with the TPS files, allowing us to leverage full SQL reads on TPS databases. Thatâs been a gamechanger so far, as the replica both acts as a live backup if a TPSfix (TPS file repair tool) fails, and as a massive accelerator when it comes to data retrieval, for the low cost of some overhead in write operations.
Sounds interesting. In the first thing I tried with SQLite I ran into the Clarion driver causing locking issues even before I got to multi-user. For that project I opted to have data stored in TPS first, and transferred to SQLite for reporting. It didnât have to be immediate, they were only doing monthly reports. But immediate would be cool.
Did you notice any file size differences between the SQLite and TPS files?
I made a simple ABC app (almost out of the wizard box) with embedded Firebird. If you start the app 2 times and change the same form you will be informed with the message changed by another station.
FB_Clarion.clw (4,4 MB)
Change clw to 7z and unpack
thatâs what you would expect isnât it? I tried it and it only gave that message if I did in fact change the record in the other instance.
Maybe I am misunderstanding you, but I could not get it to misbehave.
Hi Geoff,
Itâs not a problem itâs a solution. Others where questioning if it was possible with embedded Firebird
Ok thanks. I definitely misunderstood you!
Cheers
Thanks Dirk, thatâs a nice example. Do you enable tracing somewhere in the app, if so where? Itâs generating a trace log and I couldnât see why?
Hi Geoff,
Maybe because trace.exe is found?
You can disable it with:
SYSTEM{PROP:DriverTracing} = ââ
ââ= off. Trace saves passwords and login information in plain text so itâs not save
Sorry just realized I never clicked the button to finish this replyâŚ
RUN() can fail and sets an ERRORCODE(). Its good to check and display a Message so there is no mystery for Tech Support or yourself why the install did not run. You could have bad code where your EXISTS(xxx) is different than your RUN(xxx). Or it could fail to run due to rights, elevation, corrupt EXE, etc. E.g. add IF Error and Halt
if exists(clip(glo:uncInstallatPath)&'\Firebird_ODBC_2.0.5.156_Win32.exe')
run(clip(glo:uncInstallatiepad)&'\Firebird_ODBC_2.0.5.156_Win32.exe /VERYSILENT',1)
!--- Check if Run ok
if ErrorCode() then
HALT(0,'Run Install Firebird ODBC failed error '& ErrorCode() &' '& Error() ) !should be more
end
Having worked where there were 10+ people in Tech Support I realized I needed problem/fail Messages to make obvious many details of the problem.
Best bet put that Run EXE in a variable so its just once in code and so the Halt() can inform Tech support what failed to run:
InstallFireBirdExe STRING(260)
FireBirdODBCEXE EQUATE('Firebird_ODBC_2.0.5.156_Win32.exe')
...
InstallFireBirdODBCExe = clip(glo:uncInstallAtPath) &'\'& FireBirdODBCEXE
if exists(InstallFireBirdODBCExe)
run(clip(InstallFireBirdODBCExe)&' /VERYSILENT',1)
!--- Check if Run ok
if ErrorCode() then
HALT(0,'Run Install Firebird ODBC failed Error: '& ErrorCode() &' '& Error() &' |
'<13,10,13,10>ODBC Installer: ' & InstallFireBirdODBCExe )
end
You could also check RUNCODE() for the return code from the Installer.
I think I would also open a simple Window otherwise the program appears to hang with no idea what is happening.
RunWindow WINDOW('Running Install'),AT(,,250,60),CENTER,GRAY,FONT('Microsoft Sans Serif',10)
STRING('Running FireBird Installer ... Please Wait'),AT(66,15)
STRING(@s260),AT(4,35),USE(InstallFireBirdODBCExe)
END
...
OPEN(RunWindow) ; DISPLAY()
RUN( ... )
IF ERRORCODE() THEN ...
END
CLOSE(RunWindow)
Thanks Carl,
Noted and i use this in my code now.