Qt / C++ - how to store configuration data - c++

What is the best way to store application configuration in a Qt application?

If You store only list of name-value pairs QSettings class will suffice. It is cross platform and works well.
Check this page for more info:
http://doc.qt.io/archives/qt-4.7/qsettings.html
On the other hand if You have to store data in multiple tables (many params, many rows) I suggest You use Sqlite and QtSQL. Sqlite is ralational database that can be embeded in your application without the need of starting any servers or installing additional software. Sqlite sotres all tables in one *.db file. You can place each user's configuration in his home directory.
This link demonstrates how QtSQL library works:
http://doc.qt.io/archives/qt-4.7/sql-sqlstatements.html

Well, as you're using Qt anyway, why not using QSettings? You can use its default settings to save your configuration in platform specific default locations (e.g. Registry under Windows) or use it to write to classic INI files.

Related

Where can I put my SQLite database in my QT application if I can't put it in my resources?

Recently I was trying to put a SQLite database into a QT 5 application I'm writing. I want it to be universally accessible - that is on all systems regardless of where it's installed. I put it as a resource then found out that evidently you can't put databases in resources as the string for the database path passed to setDatabaseName doesn't get translated to the resource system so the database can't be found.
So where can I put it? I don't want to just put it at the root of the drive like C:\repo.db or D:\repo.db as many people hate files cluttering their root directories (like me). I was going to put it just in the source folder and access it as "repo.db" or as I tried "./resources/database/repo.db" but even QFile doesn't see that. Where can I put it and how to access it there? My settings file was going to be in my resources but I wasn't sure if I could update the file then. I need a place that is available from the moment the application is installed on any system including my own so that it can be accessed both while coding it and when it's built.
I'm not asking for opinions - I want a place that is not in the root, somewhere universal like the installation directory (but how do I find that with code?) or a settings directory (but how do I set that somewhere so I can find it later??)
For such purposes Qt provides a list of QStandardPaths functions that return platform specific standard paths, such as a path to desktop, temp directory etc.
For your particular case you might put your database in the directory that corresponds to the QStandardPaths::AppDataLocation key.
You can use QSettings to save path,settings and restore them.
QSettings m_Arhive("Company", "app_name");
//Set DB path
m_Arhive.setValue("DBPath", "c:/somewhere/database");
//Get DB path
m_Arhive.value("DBPath").toString()

Convert an unknown database file from a windows software into a MySqli Database

I have installed a software in my system and I have a lot of data from client in it. All the files which are inside DB folder of this software are with extensions for each individual party.
I want to to use these files to get converted to a MySqli Database.
Sample file from DB folder can be download from here
I have tried understanding for firebird service which this software uses to connect with these database files to get the things.
I want to extract database and import it inside MySqli (PhpMyAdmin)
The linked file seems to be a renamed Firebird database with structure version ODS 11.2 which corresponds to Firebird 2.5.x line.
For making a quick peep into the database you can use
IBSurgeon First Aid -- http://ib-aid.com
IB Expert (the Database Explorer feature) -- http://ibexpert.net
Free mode of FirstAID would let you peep into the data, but not extract it out, probably not even scroll ALL the tables. It also would most probably ignore all database structures that are not tables (UDF functions, procedures, VIEWs, auto-computed columns in tables) - afterall it is just low-level format parser, not an SQL engine.
IB Expert has as a non-commercial Personal edition, but it probably does not include DB Exp, however you may try a trial period of full version. However IBE's DBExp would probably also only show basic structures of the database, maybe it would be enough.
Alternatively you can install Firebird 2.5.8 - either a standalone version or maybe embedded (a set of DLLs used instead of FB server process) if your application can use it, then use any DB IDE suit to explore it. Most often mentioned for Firebird would be IBExpert, FlameRobin, Firebird Maestro or any other. Then you would be able to try different SQL queries, including SPs, VIEWs and UDF-functions if there were any registered for the database and actually used.
BTW IBExpert comes bundled with FB 2.5 Embedded, which one can use to open the database file.
After you figure out the format, you can either export required data into some intermediate format like CSV (for example: http://fbutils.sourceforge.net/ ) or use your C++ application (though why would anyone develop web-application in C++) using libraries like IB++ or OLE DB, etc. Maybe it would be better to just use the Firebird server and original DB files from PHP or what would you write the application in.

Best practices for storing settings

I have a fairly large C++ application (on Windows, no other platforms planned), which currently stores all settings (even some kind of addresses) in the Windows registry.
Sometimes this is inconvenient, because the users have difficulties changing entries in the registry. I would like to have settings versioned, so settings always match the current code. At the moment we version reg-files, but you are never sure, if all reg-files have been added on the target machines. With C# you can define default values in app.config, but don't overwrite existing settings. I don't know, if such a mechanism or library exists for C++.
I would like to have the following "features":
Settings can be versioned
Simple update on target machines (can be done by user)
Ensure that on update only new settings are added and no existing settings are overwritten with default values
Simple change of settings for user
Same workflow under Win XP and Win 7
As far as I see it, there are 3 possibilities to store settings on Windows:
Registry
Ini file
XML file
Only one application of our suite uses Qt at the moment, but Boost would be available.
For addresses, we will put them in some kind of XML address book, but for the other settings we are not sure, what's the best practise.
As comments mention, tree-based key/value structures are a common solution and libraries are easy to find.
Boost's property_tree is an excellent choice, as it is well-tested and can easily be exported as XML or JSON
Regarding your requirements:
Settings can be versioned
Yes! Make "version" a top-level key. Make it easily comparable with other versions.
You can also categorize your settings into various tree nodes and give each node a version.
Simple update on target machines (can be done by user)
Have your application do that when it runs. See below.
Ensure that on update only new settings are added and no existing settings are overwritten with default values
Simple change of settings for user
Same workflow under Win XP and Win 7
As settings change from one version to another, usually these changes fall into three categories. New properties are needed, old settings are abandoned, and some settings change their expected format. E.g. "32 Fahrenheit" becomes "0 Celsius"
When your application initializes:
Load the existing configuration file, regardless of its version.
If the version does not match what's current for the application:
Create a new blank property tree for the new configuration
For each node in the tree, have a set of expected property names, and a function pointer or similar to get this setting if it's absent in the old file's tree. If a setting changes its format, give it a new name.
Search for each setting in the old tree, copying it if it's found, and using the result of the supplied function if it's not.
Save your new settings file.
Your "missing setting" functions can:
Return a constant default value.
Query the tree for a different setting and convert it (with a default value if the old setting isn't found either)
Ask the user

Where to store data?

I have created a c++ program but now I need to store on the hard disk permanently some settings about the program.
Where do I have to store this data ?
In a sqlite database ?
In the windows registry ( if linux ? ) ?
In a XML file
In other files ?
It completely depends how much information it is and for which platform.
Viable options are a .ini file http://en.wikipedia.org/wiki/INI_file#Accessing_INI_files and for more data a SQLite database. I'm not a big fan of XML files.
It depends on the type and size of data. For small and less complex data simple text files are better. for complex data you can use XML or sqlite database. If you need to write complex queries go for sqlite. It stores data in files but will give better query options.
Modern applications use the system registry to store configuration information.
See the windows article: Using the Registry in a C++ Application
http://msdn.microsoft.com/en-us/library/ms838625.aspx

Application settings methods? c++

I am thinking about adding configurable settings to an application, and I think the easiest ways are an external file or win registry (its a win only app).
Which way would be better?
I was wondering, an user with not enough permissions may not be able to create/write the config file. And in the case of the registry, would todays antivirus allow me to add/edit/remove keys? Or they only monitor certain keys?
Also, if someone knows a class/lib to manage config settings (in pure win32) in vc++ please post it.
As far as I know:
an user with not enough permissions may not be able to create/write the config file
You should be able to make files inside user's "home directory" or "application data" directory, regardless of permissions. Normally those directories should be writeable.
would todays antivirus allow me to add/edit/remove keys?
Haven't ever seen my antivirus interfere with registry manipulation. You probably will be fine as long as you aren't doing anything suspicious in registry.
Which way would be better?
It is matter of taste. I think that text file is better - allows easier migration of settings. Just don't leave junk behind after uninstall.
Also, if someone knows a class/lib to manage config settings in vc++
QSettings in Qt 4. But using entire Qt for just saving settings is definitely an overkill. You could also check configuration languages like JSON, use lua for settings (less overkill than using Qt 4) or get any XML library. Also, working with registry directly or writing configuration files using iostreams or stdio shouldn't be hard. And you can always write your own configuration library - if you feel like it.
Is "Windows-only" a restriction or a restriction-relief? If you don't mind being cross-platform then I suggest you give boost::program_options a go. The library supports program options through commandline, through evironment-variables and through INI files. Boost's program_options also integrates and glues the various parsers very nicely with variables_map, which you can view as a map between options and their value.
For simple stuff, you might as well just use the registry. However, there are many benefits to a config file... you can save/load several different configs for different uses of your app, it's easier to share or migrate settings between users or machines, etc.
If you end up going the file route, I would recommend Boost's Property Tree library:
http://www.boost.org/doc/libs/1_41_0/doc/html/property_tree.html
It has a pretty nice syntax:
boost::property_tree::ptree properties;
std::string name = properties.get<std::string>("blah.name");
int score = properties.get<int>("blah.score");
properties.put("blah.name", "Inverse");
properties.put("blah.score", 1000);
It also supports reading and writing to various formats, like xml and others.
I think the new default thing is to write a configuration file in the user's "AppData" folder under the user's folder which should be safe to write/read from.
We're using a simple XML formatted file to store settings; but you could use a INI file type formatting.
If you save your configuration file in the Application Data directory SHGetFolderPath() with CSIDL_COMMON_APPDATA all users will be able to see the configuration. If you use CSIDL_LOCAL_APPDATA then only the one user will be able to see the configuration. The registry is not necessarily the place to save all configuration data.