PDA

View Full Version : AppConfig, new feature in thinBASIC 1.10.5



Petr Schreiber
17-10-2018, 20:41
ThinBASIC is a script interpreter - however, its specific set of features enables it to step out from the world of neat console utilities to the realm of small apps with graphical user interface.

This particular type of use will benefit from the addition of new feature related to application configuration.

Even before 1.10.5, we had multiple ways how to approach application configuration:
- custom config format
- using INI file
- if you were ambitious, using XML and the built in functionality related to it

These approaches have a few issues with varying impact.

Custom formats are not standard and hard to navigate for your users. INI file handling is pretty simple, however it also limits the way your are able to structure of your data, as it allows just key-value pairs, organised in sections. Custom parsing of XML is possible with thinBASIC, but the code becomes pretty verbose.

And you don't want to write two screens of code just to load config values, do you? ;)

Standardizing the application configuration

ThinBASIC version 1.10.5 introduces a concept named directly AppConfig. It allows you to load configuration data from a XML file.

It sets the boundaries for how the configuration file can look like, and how it should be manipulated. All of that thanks to nifty AppConfig module.

Configuration file format
The configuration file is an XML with few mandatory features:

It must be a valid XML
Obvious, but worth mentioning. Later I will mention how to check the validity.

It must contain AppConfig tag at root level
This is a way to standardize the format, allowing ThinBASIC to rely on root tag name.

Example of valid config file


<?xml version="1.0" encoding="utf-8"?>
<AppConfig>
<ScreenResolution>
<Width>1920</Width>
<Height>1080</Height>
<BitDepth>32</BitDepth>
</ScreenResolution>
<License>
<Key><![CDATA]></Key>
</License>
</AppConfig>



[B]Loading the configuration

Oh my, that will be a hell of a parsing, right?

Right the opposite. Eros managed to grab the main benefit of XML - ability to store any, even binary, data and married it with easy way to reach the data via intuitive slash notation we are used to from a file system.

Example?

The AppConfig above can be loaded via single line:


uses "appConfig"

dim config as new cAppConfig("config.xml")


You can see you need to use appConfig module and create new object of type cAppConfig, which takes config file name as input.

Then, you should check for the validity of the input format. Checking for errors is a question of few lines:


if config.errorPresent then
msgBox 0, config.errorDescription, %MB_ICONERROR, "Configuration error, #" + config.errorCode
stop
end if


This will prevent the app from running, should there be some error, while displaying human readable reason of the problem.

To reach the data, you can use the getKey method of the configuration object:


long screenWidth = config.getKey("ScreenResolution\Width")
long screenHeight = config.getKey("ScreenResolution\Height")
long screenDepth = config.getKey("ScreenResolution\BitDepth")
string licenseKey = config.getKey ("License\Key")

msgbox 0, strFormat$("{1}x{2} at {3}bits, license key: {4}", screenWidth,
screenHeight,
screenDepth,
licenseKey)



This was cool, gimme more!

cAppConfig has an excellent documentation, just hit F1 while on cAppConfig in thinAir, and help file will teleport you to the right section of the help file.

For more complex example than in this article, please open SampleScript/AppConfig/AppConfig_test.tBasic script and feel free to examine and modify.

ErosOlmi
17-10-2018, 21:02
Thanks a lot Petr!

If any other feature could be needed in this module, just ask.

For example actually there is limitation of only 2 nested levels of parameters keys inside root <AppConfig> node , I think I will add one more.

Another thing I will try to add is introduction of node attribute parsing https://www.w3schools.com/xml/xml_dtd_el_vs_attr.asp
So in above Petr example <ScreenResolution> node could be specified also in terms of attributes:


<?xml version="1.0" encoding="utf-8"?>
<AppConfig>
<ScreenResolution Width="1920" Height="1080">
<BitDepth>32</BitDepth>
</ScreenResolution>
</AppConfig>

And reading back data something like:


config.getKey("ScreenResolution:Width")


Last ideas is the possibility to change parameters and write back into XML file

Just ideas.

Ciao
Eros

Petr Schreiber
17-10-2018, 21:13
One more nesting level would be nice, as it would allow to hold debug / production configuration in a single file, for example.

The second idea with attributes I do like as well - as it means less typing.

Thaaank yooou, Eros!


Petr

ErosOlmi
17-10-2018, 21:29
One more nesting level would be nice, as it would allow to hold debug / production configuration in a single file, for example.
Petr are you reading my mind ? :D

That's exactly the problem I've faced at office and that's why I will add one more level.
Something like the following where <ActiveNode> node will tell what path to follow, Debug or Production nodes:


<?xml version="1.0" encoding="utf-8"?><AppConfig>


<!--this is a comment-->


<ActiveNode>Debug</ActiveNode>


<Debug>
<AppVersion>1.0.0</AppVersion>


<AppData>
<Author_eMail>support@thinbasic.com</Author_eMail>
<Author_WebSite>http://www.thinbasic.com</Author_WebSite>
</AppData>


<AppFiles>
<File1>NameFile1.txt</File1>
<File2>NameFile2.txt</File2>
</AppFiles>


<Buffers>
<Buffer1><![CDATA[some stuff]]></Buffer1> <!-- Comment -->
</Buffers>


<DB>
<ConnectionString>Provider=SQLNCLI11;Server=myServerAddress;Database=myDataBase;Uid=myUsername;Pwd=myPassword;</ConnectionString>
<tblCust>tCustomers</tblCust>
<tblItems>tItems</tblItems>
</DB>
</Debug>

<Production>
<AppVersion>1.0.0</AppVersion>


<AppData>
<Author_eMail>support@thinbasic.com</Author_eMail>
<Author_WebSite>http://www.thinbasic.com</Author_WebSite>
</AppData>


<AppFiles>
<File1>NameFile1.txt</File1>
<File2>NameFile2.txt</File2>
</AppFiles>


<Buffers>
<Buffer1><![CDATA[some stuff]]></Buffer1> <!-- Comment -->
</Buffers>


<DB>
<ConnectionString>Provider=SQLNCLI11;Server=myDEBUGServerAddress;Database=myDataBase;Uid=myUsername;Pwd=myPassword;</ConnectionString>
<tblCust>tCustomers</tblCust>
<tblItems>tItems</tblItems>
</DB>
</Production>
</AppConfig>

ReneMiner
17-10-2018, 23:36
Hmmm...
Do you remember
App_IniFile
? ? ?

Check help if you don't know what it does...

If you know - how about:

App_ConfigFile

?
Save the user to create a filename when it's obvious.

ErosOlmi
18-10-2018, 07:17
Right you are René.
Will add

LuigiNiz
11-02-2024, 09:37
Are there plans to include a feature like "App_ConfigFile" in thinBASIC, similar to the existing "App_IniFile," to simplify the process of creating a configuration file without requiring the user to specify a filename?

ReneMiner
14-02-2024, 00:20
not that i know of. App_Config- module is working fine for years now, Why- something wrong with it? does it have to be reconfigured?