Database connection for current directory

Discussion of open issues, suggestions and bugs regarding UniDAC (Universal Data Access Components) for Delphi, C++Builder, Lazarus (and FPC)
Post Reply
polsol
Posts: 71
Joined: Sun 20 May 2007 13:29
Contact:

Database connection for current directory

Post by polsol » Wed 02 Aug 2017 13:08

Is there no way of using a database at both design time and runtime that is in the current directory without specifying the exact connection string?
e.g. "./MyDatabase.db" vs "D:/Programs/NewProgram/MyDatabase.db"
Would make life easier when testing a program + DB on various machines without having to build a setup file first.
From memory one can do this with Firebird using an alias + aliases.conf
I'm using SqLite in direct mode though.

JensVitec
Posts: 9
Joined: Tue 25 Jul 2017 08:01

Re: Database connection for current directory

Post by JensVitec » Wed 02 Aug 2017 13:44

That actually does work. Maybe it is the compiler Output directory that is playing with you?
You in newer versions of Delphi have a default out-dir Win32/debug, Win64/debug, and this is where your exefile is.

Jens

polsol
Posts: 71
Joined: Sun 20 May 2007 13:29
Contact:

Re: Database connection for current directory

Post by polsol » Wed 02 Aug 2017 14:33

Thanks Jens
If one puts the 'MyDatabase.db' in the same directory as the program development files (dproj etc). then one can open the database using the connection string '.\MyDatabase.db' during design time.
At run time then the 'MyDatabase.db' must be in the specific debug (or release) 32/64 bit folder.
OK, it's a bit of a pain duplicating the DB amongst the various debug/release 32/64 bit folders but still easier to do than changing the SetUp program each time.

Thanks once again for your time and help!

ertank
Posts: 172
Joined: Wed 13 Jan 2016 16:00

Re: Database connection for current directory

Post by ertank » Wed 02 Aug 2017 15:32

Hello,

During OnCreate of your DataForm or Form, you may use a code as below:

Code: Select all

var
  TempString: string;
begin
  TempString := ExcludeTrailingPathDelimiter(ExtractFilePath(UniConnection1.Database)) + '\..\..\' + ExtractFileName(UniConnection1.Database);
  if FileExists(TempString) then
  begin
    UniConnection1.Disconnect();
    UniConnection1.Database := TempString;
    UniConnection1.Connect();
  end;
end;
So, you will be able to work on your database at design time, and use *same* database at run-time.

Of course, you can add more controls for your convenient way of working and deployment. Such as;

Code: Select all

{$IFDEF DEBUG}
  TempString := ExcludeTrailingPathDelimiter(ExtractFilePath(UniConnection1.Database)) + '\..\..\' + ExtractFileName(UniConnection1.Database);
  if FileExists(TempString) then
  begin
    UniConnection1.Disconnect();
    UniConnection1.Database := TempString;
    UniConnection1.Connect();
  end;
{$ENDIF}
Above code will execute only when your application is set to Delphi default Debug configuration in recent versions. Which is mostly the case. When you switch it to Release configuration it won't run.

One can add more example use cases. However, it is the programmer to decide his/her way in the end.

polsol
Posts: 71
Joined: Sun 20 May 2007 13:29
Contact:

Re: Database connection for current directory

Post by polsol » Wed 02 Aug 2017 16:51

Thanks for your input ertank.
Frankly it's easier to just put the database in the development progam's directory, use './MyDatabase' as the connection.Database input as per Jen's suggestion. Then you can do the 'live' designing'.
Compilation (no errors because the database string has been defined as 'the same directory' as the program files during design - thus one can set the connection to true as well as any Table or query to active) will go the the determined 32/64 bit debug/release folder.
Obviously if you try and run the executable from the debug/release folder at this time you'll get a 'database not found' error - because the DB is in the program's folder, not the executable's folder.
The compiled exe then can be combined with the database in any folder of choice and run from there.
The problem with 'ExtractFilePath' is that one has to put the complete file string (e.g. "F:/Development Programs/MyProgram/MyProgram.exe) as the argument to simply get the file path ('F:/Development ProgramsMyProgram/') to the file - i.e. it has to be known at compile time.
If you put the exe and DB into a different folder you have to change the string argument to the 'ExtractFilePath' routine - something I'm trying hard not to do.
Anyway, my few cent's worth.

MaximG
Devart Team
Posts: 1822
Joined: Mon 06 Jul 2015 11:34

Re: Database connection for current directory

Post by MaximG » Thu 03 Aug 2017 07:51

This issue is not related to our components work. To implement the needed behavior you can use the corresponding Microsoft guidelines when working with relative Windows paths. For example, search for a file by its name will be done in the following order: the current folder, the system folder (Windows, SYSTEM32), the folders specified in the PATH environment variable. Therefore, you can try using the following approach. Place the file from the database to a specific folder and specify the absolute path to this folder in the PATH variable.

polsol
Posts: 71
Joined: Sun 20 May 2007 13:29
Contact:

Re: Database connection for current directory

Post by polsol » Thu 03 Aug 2017 08:47

Hi Maxim,
Yesterday I placed the DB in the folder where the program was being developed. e.g. F:/Program Folder/MyProgram - the same as where the DFM, PAS files etc are. It worked fine with the UniconnectionDatabase specified as ./MyDatabase.DB
Today it's not working at design time - there was an error 'Can't open database' immediately when I started Delphi Tokyo. :cry: And I haven't been able to get the program to compile/run again unless I specify the absolute path.
The EXE's both 32 and 64 bit compiled with the same string yesterday - and with the DB in the same directory - work as expected.
Yesterday it worked at design time so I could compile the program with the Database string as ./MyDatabase.DB from the IDE into the 'release' folders
Yesterday I deleted the database from the (design) program folder and then I couldn't connect at design time as expected with this string. Next I replaced the DataBase into the design time folder - and it worked again.
Can't understand why the string doesn't work at design time today - unless Windows was caching the file or something yesterday?
I understand it's to do with Windows - or more possibly Delphi in this instance.
Question I suppose is what does Delphi consider as the 'Current Folder' at design time?
I would think it's the same as the DPROG/PAS/DFM folder as I'm attempting?
If so why can't the connection (direct because I'm encrypting) find the target DB?
Yes I can get around it with specifying the absolute path and then change this at run time but now it's bugging me why it won't work today.
Sorry for the long reply.

polsol
Posts: 71
Joined: Sun 20 May 2007 13:29
Contact:

Re: Database connection for current directory

Post by polsol » Thu 03 Aug 2017 10:15

Ok (well maybe for now)
So I placed the Database in the "C:\Program Files (x86)\Embarcadero\Studio\19.0\bin" directory (seems to be the default 'current directory' during design time (X32) - but it's also in the environmental path too ...
Used the ConnectionDatabase := './MyDatabase.DB and it works at design time.
Having compiled to the program to Win32/Debug I can confirm that the exe now uses the database contained in this directory (i.e. not in the "C:\Program Files (x86)\Embarcadero\Studio\19.0\bin" directory).
Obviously it's not sensible to put all ones DB's in the 'Bin' folder so will create and add a path to a "F:/Database" directory as suggested and will see what happens.
Still can't figure out why it worked yesterday and not today.

BTW, tried opening UniConnection without a database name at design time (Sqlite) - and it opened (connected)?
Both the object inspector and Uniconnection database were "" (empty string).

polsol
Posts: 71
Joined: Sun 20 May 2007 13:29
Contact:

Re: Database connection for current directory

Post by polsol » Thu 03 Aug 2017 13:59

So I tried setting up a Path to a 'joint' database directory and it does nothing at design time - cannot connect.
Thus the only way to implement a string like './MyDatabase.DB' at design time is to put the DB in the "C:\Program Files (x86)\Embarcadero\Studio\19.0\bin" directory.
Which is a PITA.
So we're back to specifying a complete path at design time and over-riding the Connection.database string at run time.
Pity.

MaximG
Devart Team
Posts: 1822
Joined: Mon 06 Jul 2015 11:34

Re: Database connection for current directory

Post by MaximG » Mon 07 Aug 2017 12:19

You wrote :
BTW, tried opening UniConnection without a database name at design time (Sqlite) - and it opened (connected)?
Both the object inspector and Uniconnection database were "" (empty string).
This is SQLite behavior. In case if DB represents an empty string, SQLite creates temporary on-disk database : http://www.sqlite.org/c3ref/open.html

As we already wrote, the rest of the issues that you mention are not related to our components work

Post Reply