Hagyományos konfigurációs állományok

Amikor én kezdtem informatikával foglalkozni, a Windows 3.1 idejében, akkor még INI fájlokban tároltuk a beállításokat. Egy ilyen INI fájl kb. így nézett ki:

; This is a comment row

[SQLServerData]

ServerName = WS2019SQL

IP         = 192.168.1.1

 

[DBData]

Database = MigrationData

Table    = Users

Columns  = Name, Samaccountname, Department

Orgs     = Marketing, Sales, Manfacturing,

    Finance,Engineering

Látható, hogy szögletes zárójelek közötti címkékkel adatcsoportokat lehetett definiálni, ezeken belül meg adatcímke-érték párokat tudtunk berakni. Ezek alapvetően mind szöveges adatok voltak, maximum az alkalmazás, ami olvasta ezeket, bizonyos értékeknél tudta, hogy azokat számmá vagy egyéb adattípussá kell alakítani. Ha egy kulcshoz tömböt akartunk rendelni, akkor simán vesszővel elválasztott módon fel kellett sorolni az értékeket. Ha nagyon sok eleme volt egy tömbnek, akkor több sorba is lehetett írni az elemeket, ilyenkor a folytatás sorban nem volt kulcs és egyenlőségjel, innen lehetett tudni, hogy az itteni adatok még az előző folytatásai. Ami még látszik, hogy az adatok „sekély” szerkezetbe szervezetők, azaz nem nagyon lehet mély, hierarchikus adatstruktúrákat tárolni.

Összeraktam egy egyszerű függvényt, amivel egy ilyen fájlt lehet olvasni és értelmeztetni:

function ParseINI {

param($path)

    $config = @{}

    switch -regex (Get-Content -Path $path){

        "^;|^\s*$" {continue}

        "^\[([^\]]+)\]\s*$" {

                $currenthive = $Matches[1].trim(); $config.$currenthive = @{}; continue

            }

        "^([^=]+)=([^=]+)$" {

                $valuename = $Matches[1].trim()

                $values = $Matches[2].trim() -split ",\s*" | Where-Object {$_ -and $_.trim()} | ForEach-Object {$_.trim()}

                $config.$currenthive.$valuename = $values

                continue

            }

        "^\s*(.+)$" {

                $values = $Matches[1].trim() -split ",\s*" | Where-Object {$_ -and $_.trim()} | ForEach-Object {$_.trim()}

                $config.$currenthive.$valuename += $values

                continue

            }

        default {

                Write-Error "Unknown line: '$_'"

            }

    }

    $config

}

A függvény egy hashtáblát fog visszaadni adatcsoportonkénti, azon belül adatcímkénti kulcsokkal. A függvény érdemi része egy nagy switch ciklus, elsőként a megjegyzéseket és az üres sorokat csak átugrom, majd vizsgálom, hogy csoportjelölő címke van-e a sorban, ebből csinál a kimeneti hashbe egy kulcsot. Majd nézem, hogy adatcímke és egyenlőségjel van-e a sorban, ha igen, akkor ezt szétszedem $valuename-re és $value-re és be is tárazom a kimeneti $config-ba. A következő esetben megpróbálom vesszőnkként feldarabolni a sort és az így megtrimmelt és megszűrt adatokat hozzáteszem a legutóbbi értékekhez.

Ha ettől eltérő sort találok a fájlban, akkor hibajelzéssel kilépek. Nézzük, mit ad ez a korábbi példa fájl esetében:

PS C:\> $result = ParseINI -path C:\PSTools\config.ini

PS C:\> $result

 

Name                           Value

----                           -----

DBData                         {Table, Database, Columns, Orgs}

SQLServerData                  {IP, ServerName}

 

 

PS C:\> $result.DBData

 

Name                           Value

----                           -----

Table                          Users

Database                       MigrationData

Columns                        {Name, Samaccountname, Department}

Orgs                           {Marketing, Sales, Manfacturing, Finance...}

 

 

PS C:\> $result.SQLServerData

 

Name                           Value

----                           -----

IP                             192.168.1.1

ServerName                     WS2019SQL

A függvény csodálatosan értelmezte és alakította át az INI fájlomat hashtáblává. Miért nem használunk manapság ilyen fájlokat? Mert a webes technológiák elterjedésével sokkal strukturáltabb és hibatűrőbb megoldásokra volt szükség. Ha egy INI fájlból lemarad néhány sor, akkor azt beolvasáskor nem valószínű, hogy minden esetben észre tudjuk venni.

Szóval fejlődött a világ, megjelent az XML. Hogyan nézne ki egy XML formátumú konfigurációs fájl:

<!-- comment -->

<Config>

    <SQLServerData>

        <ServerName>WS2019SQL</ServerName>

        <IP>192.168.1.1</IP>

    </SQLServerData>

    <DBData>

        <Database>MigrationData</Database>

        <Table>Users</Table>

        <Columns>

            <Column>Name</Column>

            <Column>Samaccountname</Column>

            <Column>Department</Column>

        </Columns>

    </DBData>

    <Orgs>

        <Org>Marketing</Org>

        <Org>Sales</Org>

        <Org>Manfacturing</Org>

        <Org>Finance</Org>

        <Org>Engineering</Org>

    </Orgs>

</Config>

Itt már sokkal szigorúbb a szerkezet, ha valami lemarad, akkor nem lesznek jól lezárva az XML címkék és ebből tudni fogjuk, hogy valami baj van. Viszont tetszőlege mélységű hierarchiákat is tárolhatunk itt. Hogyan lehet egy ilyen fájlt beolvasni? Nagyon egyszerűen:

PS C:\> $PSConfigXML = [xml] (Get-Content C:\PSTools\config.xml)

PS C:\> $PSConfigXML

 

#comment  Config

--------  ------

 comment  Config

 

 

PS C:\> $PSConfigXML.Config

 

SQLServerData DBData Orgs

------------- ------ ----

SQLServerData DBData Orgs

 

 

PS C:\> $PSConfigXML.Config.SQLServerData

 

ServerName IP

---------- --

WS2019SQL  192.168.1.1

 

 

PS C:\> $PSConfigXML.Config.DBData

 

Database      Table Columns

--------      ----- -------

MigrationData Users Columns

 

 

PS C:\> $PSConfigXML.Config.Orgs

 

Org

---

{Marketing, Sales, Manfacturing, Finance...}

 

 

PS C:\> $PSConfigXML.Config.Orgs.Org

Marketing

Sales

Manfacturing

Finance

Engineering

Látható, hogy ehhez nem is kellett függvényt írnunk, ezt beépített eszközökkel is meg tudtuk oldani, egy egyszerű szöveges fájlbetöltéssel, majd ezt a szöveget XML-é alakítjuk. Miért nem szeretjük ma már ezt se? Mert túl szószátyár, minden nyitó címkéhez oda kell rakni a záró címkét. Ráadásul kis-nagybetű érzékeny a formátum, így nagyon könnyű hibát ejteni benne.

Ezután vált divatossá a JSON formátum és ehhez filozófiájában nagyon hasonló YAML és hasonló formátumok. Nézzünk egy JSON fájlt:

{

"SQLServerData": {

        "ServerName": "WS2019SQL",

        "IP": "192.168.1.1"

    },

"DBData": {

    "Database": "MigrationData",

    "Table": "Users",

    "Columns": [

            "Name", "Samaccountname", "Department"

        ],   

    "Orgs" : [

            "Marketing", "Sales", "Manfacturing",

            "Finance", "Engineering"

        ]

    }

}

Látható, hogy ez is hierarchikus adatstruktúra. Itt a fő nehézség a vesszők használata. Igazából a sortörésnek nincs jelentősége, így hiába kezdődik valami egy új sorban, a vesszőt akkor is ki kell rakni. A másik nehézség, hogy a szabvány szerint a JSON-ba nem lehet megjegyzéseket tenni, így emberi szemmel viszonylag tömény értelmezni.

Nézzük, hogyan lehet ezt beolvasni:

PS C:\> $PSConfigJSON = get-content -path C:\PSTools\config.json | ConvertFrom-

Json

PS C:\> $PSConfigJSON

 

SQLServerData                           DBData

-------------                           ------

@{ServerName=WS2019SQL; IP=192.168.1.1} @{Database=MigrationData; Table=Use...

 

 

PS C:\> $PSConfigJSON.DBData

 

Database      Table Columns                            Orgs

--------      ----- -------                            ----

MigrationData Users {Name, Samaccountname, Department} {Marketing, Sales, M...

 

 

PS C:\> $PSConfigJSON.DBData.Orgs

Marketing

Sales

Manfacturing

Finance

Engineering

A beolvasás tehát egyszerű szövegként történik, majd a ConvertFrom-Json-al értelmeztetjük a PowerShell-el a JSON formátumú szöveget. Az így beolvasott objektum egyedi objektum típusú.

Összefoglalva: egyik idáig látott típus sem ideális:

INI: nem igazán szabványos és nem biztonságos

XML: szabványos, de nem elég tömör, sok a hibalehetőség emberi előállítás során

JSON: szabványos, de kellemetlen a vesszők kezelése, nem lehet megjegyzésekkel ellátni

A megoldás a PSD1 fájl lesz!



Word To HTML Converter