I've been trying to get this work for two days and tried all suggestions that I could find. Alas, without success, so far.
This is what I'm trying to do: I am building a small (java swing) desktop database application. I'm using Netbeans 7.0 and SQLite, and found the JDBC driver from http://www.xerial.org/trac/Xerial/wiki/SQLiteJDBC to work fine as long as I specify an absolute path in the JDBC URL:
jdbc:sqlite://Users.../lib/db/ithildin.db
Here's how it looks in Netbeans' Services -> Databases tab, using an absolute URL:
opening the connection and then the tables node shows the available tables.
But because I intend to distribute this application to other people, using an absolute path is not going to work. From what I have read here and there it seems to be possible to also specify a relative path to the SQLite database file, but I cannot get it to work whatever I try.
The strange thing is that when I create a connection in Netbeans it initially seems to work when I put both the sqlite jdbc driver jar and the sqlite database file in a /db subdirectory in /lib (in the Netbeans project directory):
and when I open the new connection it maintains that illusion -
but when I open the "Tables" node it turns out to be empty:
Similary, this connection seems valid but as soon as I try to use it - for instance in "Generating Entity Classes From Database" it tells me that there aren't any tables in that database.
Does anyone know a way out of this? I'd much appreciate it.
LĂșthien
I've followed the same steps that you have and my findings suggest that the relative path in the New Connection Wizard is relative to NetBeans' working directory which is the directory that NetBeans is installed to.
For example, in your connection string you are "connecting" to a database that resides at <NetBeans-Install-Dir>/ithildin-13-11-11.db. Since this database does not exist, SQLite is creating it for you which is giving you the "illusion" that you are seeing. In my tests, the database that I was trying to connect to with a relative path was created in the NetBeans install directory.
In other words, everything is working as designed.
In your code you can use a relative path and it should be relative to the top of your project's directory. In NetBeans' Databases Service you will need to either use an absolute path to connect to the database that exists (in your project) or you will need to provide a relative path that begins at NetBeans' install directory.
My suggestion is that you use a relative path in your code and an absolute path in the New Connection Wizard.
Related
I have a Node-RED flow. It uses a sqlite node. I am using node-red-node-sqlite. My OS is Windows 10.
My sql database is configured just with name "db" :
My question is, where is located the sqlite database file?
I already search in the following places, but didn't found:
C:\Users\user\AppData\Roaming\npm\node_modules\node-red
C:\Users\user\.node-red
Thanks in advance.
Edit
I am also using pm2 with pm2-windows-service to start Node-RED.
If you don't specify a full path to the file in the Database field it will create the file in the current working directory for the process, which will be where you ran either node-red or npm start.
Use full path location with file name.
It should work i guess.
This isn't a valid answer, just a workaround for those who have the same problem.
I could't find my database file. But inside Node-RED everything worked just great. So. this is what I have done as a workaround:
In Node-RED, make some select nodes to get all data from tables
Store the tables values somewhere (in a .txt file or something like that)
Create your database outside Node-RED, somewhere like c:\sqlite\db.db. Check read/write permissions
Create the tables and insert the values stored from old database
In Node-RED, inside "Database", put the complete path of the database. For example, c:\sqlite\db.db
In my case this was easy because I only had two database with less than 10 rows.
Hope this can help others.
Anyway, still waiting for a valid answer :)
In replacement of my previous question which was confusing and poorly formulated, here is the "real" question.
I would like to known how to set, with Firedac, at runtime, a relative path to a sqlite database located in a subfolder of my application folder.
As Jerry Dodge stated :
Any application should never rely on writable data in the same directory anyway. Also, even if you did, you should make sure all your paths are relative to the application at least.
At the moment, the application I have in mind is portable and I would like the database file to be stored in a sub-folder of the main exe folder.
On the Form.Create event of my main form, is used first
path := ExtractFilePath(Application.ExeName);
And in then for FDConnection :
with FDConnection1 do begin
Close;
with Params do begin
Clear;
Add('DriverID=SQLite');
Add('Database='+path+'Data\sqlite.db');
end;
Open;
end;
I keep on getting an error saying "unable to open database file".
I don't want to set the path to the database file in the FiredDac Connection Editor because then it would be absolute and bound to my machine, right ?
How could I set this path to the database file so that it would work in any configuration, wherever the user puts the application folder ?
Thank you all in advance
Math
As I found my own solution, I decided to post it here for future users who might encounter the same problem (that is to say a Delphi beginner level and the need to link a database file relative to their project exe file).
FIRST STEP was to add a data module to the project. This was done by going to File -> New -> Other -> Delphi Files -> Data Module
SECOND STEP Once the data module added to the project, as my main Application Form makes a call to the database on creation, I had to make sure the Data Module was created first. To achive that, I went to Project -> Options -> Forms and dragged the datamodule in first position of the list of auto created Forms
THIRD STEP was to drop a FDConnection on the datamodule and set all parameters EXCEPT database file.
FOURTH STEP was to add an OnCreate event to the datamodule, to specify the path to the database relative to the application exe and connect. It was done like this :
procedure TDataModule1.DataModuleCreate(Sender: TObject);
begin
path := ExtractFilePath(ParamStr(0));
FDConnection.Params.Add('Database='+path+'Database\sqlite.db');
FDConnection.Connected := True;
end;
FIFTH AND FINAL STEP was to add the datamodule to the uses clause of all other units that needed a connection to the database.
I realize that this solution is far from perfect and that, as very experienced users already stated, storing the database in the same folder (or a sub-folder) as the main application Exe is not a good solution.
Also, I decided to connect to the database on DataModule creation, but another solution could be to connect on demand before triggering the queries and then disconnect. That's up to you and your needs
Thanks to all for your help, tips and advises
Math
PS : please notice I did not check my answer as accepted as the best answer, would not be fair right :-)
Introduction
IMHO
Database path and server name should not be hardcoded in applivcation.
Why ?
When you work on a project, you need to do many things on database connection, setting datasets, query etc. Usualy this is done on working database. Then server name and database path are different from those of the real database.
You should be able to set up server name and path to database easy and without to compile the project. This allows to set properly database connection params on a random computer.
Solution :
Setup the database connection component on design time, do not create it in runtime. Setup all parameters including server name , database path, charset etc. to your working copy of database. This will allow you to set up the other components associated with this database on design time.
(In your answer I see you have done almost the same.)
Save server name, database path and any other parameter you want, to an exterrnal resource, ini file, windows registry or something else. Then get these parameters when application started or before connect to database.
In your case, you use local server and the same path as application, so you don't need to store nothing.
Regarding the question
The code :
with FDConnection1 do begin
Close;
with Params do begin
Clear; <-- this removes all parameters
Add('DriverID=SQLite');
Add('Database='+path+'Data\sqlite.db');
end;
Open;
end;
removes all other parameters except DriverID and Database. Probably the error arise from that.
If you already setting all parameters in FDConnection:
Do not use:
FDConnection.Params.Add('Database='+path+'Data\sqlite.db');
This will add new parameter with the same name, but connection will use the first one.
This explains why everything works in your answer, because you did not set a parameter 'Database' on design time:
THIRD STEP was to drop a FDConnection on the datamodule and set all
parameters EXCEPT database file.
Instead use :
FDConnection.Params.Database := 'Database='+path+'Data\sqlite.db';
You may use this for example in
OnDataModuleCreate or FDConnectionBeforeConnect events
I hope this will be useful.
In android, I couldn't compile with fdConnection opened in design time, then certify it's closed. Your first line didn't work for me, but about takes the goal:
using following expression, it works for me:
FdConnection1.Params.Values['Database'] := GetHomePath
+ PathDelim + 'sqlite.db';
Look that I didn't use subfolder 'Data'. You can try simple first.
If your resources are light and read-olny for end-user, you could pack them direct into exe file. This would give you really portable application, which your user can run from arbitrary place, even from usb flash.
Go to Project->Resources and Images menu, add there you files.
You can access them in runtime with TStream:
var
s: TStream;
{.....}
s:=TResourceStream.Create(hinstance, 'myfile_1', RT_RCDATA);
Some resources you can handle direct in memory. As for sqlite database, you could copy it from app resources to user's documents path:
MyAppPath := Tpath.GetDocumentsPath+'\MyAppName'; // you need System.IOUtils in uses
If not DirectoryExists(MyAppPath) then CreateDir(MyAppPath);
MyDBPath := MyAppPath+'\Data\sqlite.db';
If not FileExists(MyDBPath) then begin
FL:=TFileStream.Create(MyDBPath ,fmCreate);
FL.CopyFrom(s,0); // this will copy your db into 'sqlite.db' file
end;
I have developed an application win QT which uses SQLIte database. The copy of database is located on each site.
On one site let's say site 'BOB1' it works perfectly without any problem. But when we try to use it on another site lets say 'BOB2' it takes long time to open a database connection(approx 2000 milliseconds).
I thought that perhaps there is a network problem, So they tried to use the server of the site 'BOB1' as their server, which works fine. But when i tried to use the server of the site 'BOB2' from the site 'BOB1', I have the same problem. So i thought it may not be the network issue.
Another thing that came to my mind was that, perhaps there is a problem of DNS resolution. But when i tried to ping the server using IP and hostname, the response time is the same.
Any idea or pointer that what can be the problem.
PS: Server + database file path is specified in the setDatabasePath() fuinction using enviornment variables.
Consider copying the database to the local machine (eg temp folder if transient, or other suitable location if permanent). You can safely use either file copy, or consider using the qt backup API to ensure that the transfer happens successfully (plus you get the option of progress feedback)
https://sqlite.org/backup.html
You could even "backup" the file from the remote server to in-memory if the file is small and you say you're reading only?
You can see some sample code here on how to import an sqlite DB into a Qt QSqlDatabase. Note that when you do this, you want to make sure the version of sqlite native API that you're using is the same as that compiled into Qt, or you may get error messages from sqlite or Qt.
I have downloaded the "Precompiled Binaries for windows" for the "SQLite" from here. I opened the command-line-shell and followed this, creating one table named "tbl1".
now I am looking at my desk trying to find the database file which contains tbl1, but I can't find it anywhere.
my question is: after creating a database in the SQLite, where the database file is stored ? i.e.: what is the path of my created-database ?
I am using windows7 and have basic knowledge about SQL and database
By default (if no additional path is specified), the database is created in the current working directory.
That is, sqlite.exe ex1 creates the "ex1" database in the current directory. (Use cd from the same command shell to see what what the current working directory is.)
On the other hand, sqlite.exe C:\databases\ex1 would create the "ex1" database in the "C:\databases" directory.
To create the database on the desktop for the current user, something sqlite.exe "%USERPROFILE%\Desktop\ex1" should work. (This uses an environment variable called USERPROFILE which is expanded and used as part of the path.)
The same principle holds for any SQLite connection - the path to the database file is first resolved; either relative (as in the first case) or absolute (as in the second and third).
It creates the DB file in the given file path else by default it will create the file in your current working directory. If you can't find it then just search for the .db file inside your current project directory.
I have an application that I deploy as an executable JAR file. Originally, this JAR file would communicate with a MySQL database but recently I have decided I want to go with SQLite instead. However, while testing I found that I could not access my SQLite database file when running my application from the JAR file.
I'm using the JDBC driver from the following website: http://zentus.com/sqlitejdbc/index.html
Is there a workaround I have to do?
The driver works great while testing in my Eclipse environment, but doesn't seem to work standalone in a JAR file. Any help would be greatly appreciated.
Well, here is such term as "working directory". It is the directory from where your application is started. So, every "relative" path in your application is usually relative to this "working directory".
Now let's return to your problem. When you set the path to a file you can make it either relative, absolute or relative to the JAR inner directory root, depending how you do create the file and set the path.
So, just recheck how paths are set in your application and try to use the relative one, running you application from the appropriate directory.