Goodie
Goodie

Reputation: 11

How to import settings/variables from a json file into a procedure?

I'm trying to make it so that properties are easily adjustable using a .ini file.

The problem currently is that currently these properties are defined using the "&global-define". With this the properties are not easily adjustable.

I want to put all of these variables inside of a settings file, and import that settings file inside of the procedure. I was thinking about using a settings.ini file for this.

I hope I can further clarify what I'm trying to achieve down below.

settings.ini

port = 19995

procedure.p

import settings.ini .
define variable iPort as integer no-undo .
iPort = port .

Let me know if more explanation is needed.

Thanks in advance

I looked for a solution on the internet but was unable to find one.

A solution I tried was reading the file and based on the propertyName I would assign a variable, however this seems very inefficient when dealing with a high amount of variables. Example shown below:

input from value("settings.ini") .
repeat:
    import unformatted vLine.
    iIndex = index(vLine, "=") .
    cPropertyName = trim (substring (vLine, 1, iIndex - 1)) .
    cPropertyValue =  trim (substring (vLine, iIndex + 1)) .
    case cPropertyName:
        when "port" then 
            if cPropertyValue <> "" then iPort = cPropertyValue .
            else iPort = "" . 
    end case.
end.
input CLOSE.

Another solution I found was: https://community.progress.com/s/article/is-it-possible-to-set-custom-variables-in-an-ini-file-to-use-with-abl-code

But as stated in the comments this solution only works for windows.

I now have a new solution which makes use of a temp-table: procedure.p

define temp-table ttSettings no-undo
    field port as integer .
temp-table ttSettings:read-json ("file", "settings.json").
find first ttSettings .
message ttSettings.port view-as alert-box.

settings.json

{
    "port": 19995
}

Upvotes: 0

Views: 251

Answers (2)

Jensd
Jensd

Reputation: 8011

If you stick to the "import"-approach you could also IMPORT with =as delimiter. However you need to trim away whitespaces.

If you want to use headers in your setting-file you will need to change things.

DEFINE TEMP-TABLE ttSetting NO-UNDO 
    FIELD settingKey   AS CHARACTER 
    FIELD settingValue AS CHARACTER.
    
INPUT FROM VALUE("c:/temp/settings.ini").
REPEAT :
    CREATE ttSetting.
    IMPORT DELIMITER "=" ttSetting.
    ASSIGN 
        ttSetting.settingKey   = TRIM(ttSetting.settingKey)
        ttSetting.settingValue = TRIM(ttSetting.settingValue).
END.
INPUT CLOSE.

FOR EACH ttSetting:
    DISPLAY ttSetting.
END.

Upvotes: 0

nwahmaet
nwahmaet

Reputation: 3909

You can read the ini file into a temp-table, keyed on section and name. Then, getting the value out becomes a simple FIND statement (or a FOR EACH through a section).

The code should work, but you will want to tighten up the error handling.

block-level on error undo, throw.

define temp-table ttIniSetting no-undo
    field Section as character
    field KeyName as character
    field KeyValue as character
    index idx1 as primary unique Section KeyName.
    
define variable cLine as character.
define variable cSection as character.
define variable iPos as integer.
    
input from value('/path/to/file.ini').

repeat:
    import unformatted cLine.
    cLine = trim(cLine).
    
    if cLine begins '#' 
    or cLine begins ';' 
    or cLine eq ''
    then
        next.
        
    if cLine matches '[*]' then
    do:
        cSection = substring(cLine, 2, r-index(cLine, ']') - 2).
        next.
    end.    
    
    iPos = index(cLine, '=').
    
    create ttIniSetting.
    ttIniSetting.Section = cSection.
    ttIniSetting.KeyName = substring(cLine, 1, iPos - 1).
    ttIniSetting.KeyValue = substring(cLine, iPos + 1).
    
end.    

Upvotes: 2

Related Questions