parser

Написать ответ на текущее сообщение

 

 
   команды управления поиском

Набросал класс - может кому пригодится

sergei v.2 05.07 11:46

Есть метод, который умеет превращать многоуровневый объект со вложенными хешами в плоский хеш с ключами, в имени которых закодирован путь до каждого значения (разделитель двойное подчеркивание).
Есть обратный метод, который умеет у плоского хеша сплитить ключи и делать многоуровневый объект.
Умеет читать /../.env.base (должен быть в репе) и мержить его с /../.env.local (должен быть в гит-игноре) + сверху все это можно переопределить переменными окружения сервера начинающимися с двух подчеркиваний "__". Каждый уровень так же разделяется "__"

Наверное можно это отрефакторить в плане красоты кода, именования переменных и методов и закинуть в копилку классов.

Например:
{
"__project-name":"API Parser3",
"__a1__b":"1",
"__a1__w":"www",
"__database__api__main-db__1__type":"pgsql",
"__database__api__main-db__1__host":"my-pg15-dev",
"__database__api__main-db__1__ports__write":"5432",
"__database__api__main-db__1__ports__read":"5433",
"__database__api__main-db__1__user":"",
"__database__api__main-db__1__password":"",
"__database__api__main-db__1__db_name":"b_dev",
"__database__api__contractor-db__2__type":"pgsql",
"__database__api__contractor-db__2__host":"my-pg15-dev",
"__database__api__contractor-db__2__ports__write":"5432",
"__database__api__contractor-db__2__ports__read":"5433",
"__database__api__contractor-db__2__user":"",
"__database__api__contractor-db__2__password":"",
"__database__api__contractor-db__2__db_name":"b_dev",
"__database__api__contractor-db__3__type":"pgsql",
"__database__api__contractor-db__3__host":"my-pg15-dev",
"__database__api__contractor-db__3__ports__write":"5432",
"__database__api__contractor-db__3__ports__read":"5433",
"__database__api__contractor-db__3__user":"",
"__database__api__contractor-db__3__password":"",
"__database__api__contractor-db__3__db_name":"b_dev",
"__database__pay-api__main-db__1__type":"pgsql",
"__database__pay-api__main-db__1__host":"my-pg15-pay-dev",
"__database__pay-api__main-db__1__ports__write":"5432",
"__database__pay-api__main-db__1__ports__read":"5433",
"__database__pay-api__main-db__1__user":"u_pay_dev",
"__database__pay-api__main-db__1__password":"qwerty",
"__database__pay-api__main-db__1__db_name":"b_pay_dev",
"__a1__c":"abc",
"__a1__d":"xyz",
"__a2__b":"1.1",
"__a2__b_2":"2.2",
"__a2__b_3":"3.3",
"__a2__d__da":"11",
"__a2__d__db":"22"
}
Пример .env.base и .env.local
{ 
	  "database": {
	    "api": {
	      	"main-db": {
		      "1": {
		        "name": "main",
		        "type": "pgsql",
		        "host": "my-pg15-dev",
		        "ports": {
		        	"write": "5432",
		        	"read": "5433"
		        },
		        "user": "",
		        "password": "",
		        "db_name": "b_dev"
		      }
		  	},
	      	"contractor-db": {
		      	"2":{
			        "type": "pgsql",
			        "host": "my-pg15-dev",
			        "ports": {
			        	"write": "5432", 
			        	"read": "5433"
			        },
			        "user": "",
			        "password": "",
			        "db_name": "b_dev"
		      	},
		      	"3":{
			        "type": "pgsql",
			        "host": "my-pg15-dev",
			        "ports": {
			        	"write": "5432", 
			        	"read": "5433"
			        },
			        "user": "",
			        "password": "",
			        "db_name": "b_dev"
			    }
		    }
	  },
	  "pay-api":{
	    "main-db": {
		    "1":{
		      	"type": "pgsql",
		      	"host": "my-pg15-pay-dev",
		     	"ports": {
		     		"write": "5432",
		     		"read": "5433"
		     	},
		      	"user": "u_pay_dev",
		      	"password": "qwertyU",
		      	"db_name": "b_pay_dev"
		    }
	    }
	  }
  	},
	"a1":{"b": 1, "c": "abc", "d": "xyz"},
	"a2":{"b": 1.1, "b": 2.2, "b": 3.3, "d": {"da": 11, "db": 22}}
}
###########################################################################
$oEnvConfig[^EnvConfig::create[]]
^json:string[$oEnvConfig]

@CLASS
EnvConfig


###########################################################################
@create[][f;hEnv;hEnvBase;hEnvLocal;hEnvServer;s]

^if(!def $env:SERVER_NAME){
    $hEnvBase[^getEnvFromFile[/../.env.base]]
    $hEnvLocal[^getEnvFromFile[/../.env.local]]
    ^hEnvBase.add[$hEnvLocal]
    $hEnvServer[^env:fields.select[k;v](^k.left(2) eq __)]
    ^hEnvBase.add[$hEnvServer]

    $s[^json:string[$hEnvBase]]
    ^s.save[/../.env-flat]

    $hEnv[^hash::create[]]
    ^hEnvBase.foreach[k;v]{
        ^addBranch[$hEnv;$k;$v]
    }

    $s[^json:string[$hEnv]]
    ^s.save[/../.env]
}{
    $f[^file::load[text;/../.env]]
    $hEnv[^json:parse[^taint[as-is;$f.text]]]
}

#    $hEnvDB[^hEnv.select[k;v](^k.left(10) eq __database)]

$result[$hEnv]


###########################################################################
@getEnvFromFile[sFileName][hTmp;h;ss]
    ^if(-f $sFileName){
        $f[^file::load[text;$sFileName]]
        $hFromFile[^json:parse[^taint[as-is][$f.text];$.double(false) $.distinct[all]]]
        
        $hTmp[^hash::create[]]

        $ss[]
        ^getKeys[$hFromFile;$hTmp;$ss]
        $result[$hTmp]
    }{
        $result[^hash::create[]]  
    }

    
###########################################################################
@getKeys[h;hRef;s][k;v;kParent;parts]
    ^h.foreach[k;v]{
        
        ^if($v is hash){
                        
            $s[${s}__$k]                        

            $kParent[$k]

            ^getKeys[$v;$hRef;$s]

            $parts[^s.split[__$kParent;lh]]
            $s[${parts.0}]
            $parts[^s.split[__;rh]]
            $kParent[$parts.0]
            
        }{
            $hRef.[${s}__$k][$v]
        }
    }


###########################################################
@addBranch[h;sPath;v][t;h1;h0]
    
    $sPath[^sPath.trim[__]]
    $t[^sPath.split[__;lv]]
  
    ^if($t==1){
      $h.[$t.piece][$v]
    }{
        ^if(!($h.[$t.piece] is hash)){
          $h0[$.[$t.piece][^hash::create[]]]
          ^h.add[$h0]  
        }


        $h1[^hash::create[$h]]

        ^t.menu{
          ^if(!($h1.[$t.piece] is hash)){
            $h1.[$t.piece][^hash::create[]]
          }

          ^if(^t.line[]!=$t){
            $h1[$h1.[$t.piece]]
          }{
            $h1.[$t.piece][$v]
          }
        }
    }