Table of Contents

Accesso a DB tramite prepared statement

Generalità

<agent lib="/usr/lib/libiadata.so.0.0.0" create="agentData" live="1" name="prepstat">
	<param name="agdb" value="tpevodb"/>
	<param name="path" value="/code/cpp/uml/proled/config/iadata"/>
</agent>

Key

JSON

[
	{
	   "subkey":"insert",
	   "sql":"insert into operalang (codice,descrizio) values ($[codice],$[descrizio]) returning *"
	},
  	{
		"subkey":"update",
		"sql":"update operalang set descrizio=$[descrizio] where codice=$[codice] returning *"
	},
  	{
		"subkey":"select",
		"sql":"select * from operalang where codice=$[codice]"
	}
]

Parametri e Query

--Forma espressiva
SELECT * FROM nodi WHERE id=$[idnodo] AND codprg=$[codice progetto];
 
--Forma numerata
SELECT * FROM nodi WHERE id=$1 AND codprg=$2;
INSERT INTO operalang (codice,descrizio) VALUES ($[codice], $[descrizio]) returning *

AgentData e funzionalità

Esecuzione dei prepared statement

[
	{
		"subkey":"select",
		"sql":"select * from operacom where codice=$[codice]"
	},
	{
		"subkey":"selectkey",
		"sql":"select * from operacom where key=$[key]"
	}
]

[
  {
    "codice":3,
    "key":"errormsg",
    "tipo":"M"
  }
]

Esecuzione multi-query implicita

[
	{
		"subkey":"nodiprogetto",
		"sql":"select codice,id,tipoarm,h,hftmax,css from nodi where codprg=$[codprg] and id=$[idnodo] order by id"
	},
	{
		"subkey":"ramiprogetto",
		"sql":"select codice,id,nodosx,nododx,lc,leq from rami where codprg=$[codprg] and id=$[idramo] order by id"
	},
	{
		"subkey":"prgmezzi",
		"sql":"select * from prgmezzi where codprg=$[codprg] order by codice"
	}
]

[
  {
    "topology.ramiprogetto":{ 
      "codice": 53730,
      "id": 1,
      "nodosx": 49641,
      "nododx": 49642,
      "lc": 350.0,
      "leq": 350.0 
    },
    "topology.nodiprogetto":{ 
      "codice": 49641,
      "id": 1, 
      "tipoarm": "A", 
      "h": 27.0, 
      "hftmax": 42.0, 
      "css": 2826 
    }
  }
]

Esecuzione multi-query esplicita

Esempio

[ 
	{ 
		"subkey": "operacom", 
		"sql": "insert into operacom (codice,key,tipo) values ($[codice],$[key],$[tipo]) returning *" 
	}, 
	{ 
		"subkey": "operamsg", 
		"sql": "insert into operamsg (codcom,codlang,msg) values ($[codcom],$[codlang],$[msg]) returning *" 
	}, 
	{ 
		"subkey": "operalang", 
		"sql": "insert into operalang (codice,descrizio) values ($[codice],$[descrizio]) returning *" 
	} 
]
[
  {
    "_subkey":"operacom",
    "_params":{
      "codice":"_getnume",
      "tipo":"M",
      "key":"errmsg"
    }
  }, 
  {
    "_subkey":"operamsg",
    "_params":[
      {
        "codcom":"$[operacom.codice]",
        "codlang":"it", 
        "msg":"E' tutto sbagliato"
      },
      {
        "codcom":"$[operacom.codice]",
        "codlang":"en",
        "msg":"All is wrong"
      },
      {
        "codcom":"$[operacom.codice]",
        "codlang":"es",
        "msg":"Todo es erato"
      }
    ]
  }
]

Applicazione Funzioni Avanzate

Indipendentemente dal tipo di query (monoquery, multiquery implicete o esplicite) è possibile richiedere al sistema una combinazione delle seguenti funzionalità:

Per attivare una o tutte le funzioni indicate bisogna utilizzare il nume secondo la tabella seguente:

Nume Bit Descrizione Transazione Preprocessing Merge dei risultati
0 000 Nessuna Funzione
1 001 Transazione X
2 010 Preprocessing X
3 011 Transazione + Preprocessing X X
4 100 Merge X
5 101 Transazione + Merge X X
6 110 Preprocessing + Merge X X
7 111 Transazione + Preprocessing + Merge X X X

Come si osserva dalla tabella le transazioni sono attivate con nume=1, il preprocessing con nume = 2, il merge con nume = 4; gli altri valori del nume combinano le tre funzioni in modo opportuno (vedi tabella delle funzioni avanzate sopra).

Transazioni

Pre-Processing dei parametri

Merge dei risultati

Altre funzioni di AgentData

Lista parametri

Reload del repository

Costruzione automatica file JSon Insert / Update

Attraverso una chiamata tell all'agente sarà possibile creare automaticamente i prepared statement di:

di apposite liste di tabelle. Di seguito vediamo i 3 casi.

Insert

Update

Delete

Tutte le operazioni

Esempio Insert (stesso per update)

Utilizzo di più database

Esempio Json per più database

[
	{
            "db":"userdb",
	    "subkey":"operato",
	    "sql":"insert into operato (codice,pwd,nominati,email) values ($[codice],$[pwd],$[nominati],$[email]) returning *"
	},
	{
	    "db":"tpevooee",
	    "subkey":"operato_oee",
	    "sql":"insert into operato (codice,nominati,email) values ($[codice],$[nominati],$[email]) returning *"
	},
	{
	    "db":"tpevoml",
	    "subkey":"operato_ml",
	    "sql":"insert into operato (codice,nominati,email) values ($[codice],$[nominati],$[email]) returning *"
	}
]

Parameters Augmentation

L'AgentData implementa un algoritmo che permette di completare i parametri di una prepared statement, non forniti dal richiedente:

Di seguito la specifica dell'algoritmo:

[
    {"subkey":".","sql":".","paramsnull":0,"paramsql":".","paramsdef":{},"events":{}},
    {
        "subkey":"ubicaz",
        "sql":"insert into ubicaz (codice,descrizio,identif,tiposet,tipocom,tipodepo,codriso,impianto,utente,datareg,stato,codcate,codoper,locked,codqua,nqua,codubib,capacita,occupazione,pos,lim1,lim2,curop,codturno,agpausesap,plmaster,plslave,updw,kbterm,blink,visnum,codfase,codazi,schema,costo,defincdec,oeew,opts,thmonoee,thmonsetup,thmondownt,thmonscrap,thdayoee,thdaysetup,thdaydownt,thdayscrap,laps,linubi,defnpop,deftcpol,saveoeeshift,tmstart,started,mancost,amcilr,amsop,storcompo,supname,locname,extcost,tmstartto,ystart,ystartto,codtunext,tmtunext,tmtu) values ($[codice],$[descrizio],$[identif],'P',$[tipocom],$[tipodepo],$[codriso],$[impianto],$[utente],$[datareg],$[stato],$[codcate],$[codoper],$[locked],$[codqua],$[nqua],$[codubib],$[capacita],$[occupazione],$[pos],$[lim1],$[lim2],$[curop],$[codturno],$[agpausesap],$[plmaster],$[plslave],$[updw],$[kbterm],$[blink],$[visnum],$[codfase],$[codazi],$[schema],$[costo],$[defincdec],$[oeew],$[opts],$[thmonoee],$[thmonsetup],$[thmondownt],$[thmonscrap],$[thdayoee],$[thdaysetup],$[thdaydownt],$[thdayscrap],$[laps],$[linubi],$[defnpop],$[deftcpol],$[saveoeeshift],$[tmstart],$[started],$[mancost],$[amcilr],$[amsop],$[storcompo],$[supname],$[locname],$[extcost],$[tmstartto],$[ystart],$[ystartto],$[codtunext],$[tmtunext],$[tmtu]) returning *",
        "paramsnull":1
    },
    {
        "subkey":"lottim",
        "sql":"insert into lottim (codice) values ($[codice]) returning *",
    },
    {
        "subkey":"oeeconf_hourly",
        "sql":"insert into oeeconf (codice,codriso,codperiodo,durperiodo,nrperiodi,tmdisp,tpriso,tmlast,codmm,codrisodef,bgnper,availab,calcnop,kweek,lim1,lim2,mudoee,dircalcsca,disabled,nptots) values ($[codice] || $[codperiodo],$[codice],$[codperiodo],$[durperiodo],$[nrperiodi],$[tmdisp],$[tpriso],$[tmlast],$[codmm],$[codrisodef],$[bgnper],$[availab],$[calcnop],$[kweek],$[lim1],$[lim2],$[mudoee],$[dircalcsca],$[disabled],$[nptots]) returning *",
   	    "paramsdef":{
              "codice":"ora","codperiodo":"ORA","durperiodo":3600,"nrperiodi":24,"tmdisp":3600,"tpriso":"M",
              "tmlast":"_timenow","codmm":0,"codrisodef":"","bgnper":0,"availab":1,"calcnop":1,"kweek":"",
              "lim1":0,"lim2":0,"mudoee":"","dircalcsca":1,"disabled":1,"nptots":0
            }
    },
    {
        "subkey":"oeeconf_daily",
        "sql":"insert into oeeconf (codice,codriso,codperiodo,durperiodo,nrperiodi,tmdisp,tpriso,tmlast,codmm,codrisodef,bgnper,availab,calcnop,kweek,lim1,lim2,mudoee,dircalcsca,disabled,nptots) values ($[codice] || $[codperiodo],$[codice],$[codperiodo],$[durperiodo],$[nrperiodi],$[tmdisp],$[tpriso],$[tmlast],$[codmm],$[codrisodef],$[bgnper],$[availab],$[calcnop],$[kweek],$[lim1],$[lim2],$[mudoee],$[dircalcsca],$[disabled],$[nptots]) returning *",
   	    "paramsql":"ubicazdef.oeeconfd"
    }
]
[
	{
		"subkey":"oeeconfh",
		"sql":"select * from oeeconf where codice='ora'"
	},
	{
		"subkey":"oeeconfd",
		"sql":"select * from oeeconf where codice='day'"
	}
]



IMPORTANTE : i parametri aggiunti con parameters augmentation possono essere soggetti a pre-processing dei parametri; ad esempio in un parametro default potrei impostare il valore di preprocessing _getnume

Events

[
    {
        "subkey":"operacom",
        "sql":"insert into operacom (codice,key,tipo) values ($[codice],$[key],$[tipo]) returning *",
        "paramsdef":{"codice":"_getnume"},
	"events":{"to":"mngevent","request":"newopera","param":""}
    },
    {
        "subkey":"operamsg",
        "sql":"insert into operamsg (codcom,codlang,msg) values ($[codcom],$[codlang],$[msg]) returning *",
        "paramsdef":{"codcom":"$[operacom.codice]"}
    }
]

Riga dummy

[
    {"subkey":".","sql":".","paramsnull":0,"paramsql":".","paramsdef":{},"events":{}},
    {...}
]

Generazione di csv da Prepared Statement

Attributi utili di una subkey

Rinominare nomi di campi

Con l'attributo renamemap del file JSON è possibile rinominare nomi dei campi della risposta di un prepared statement in modo arbitrario, ad esempio per stampare un CSV con nomi di campi significativi.

Vediamo il seguente esempio:

[
  {
		"subkey":"stab03",
		"db":"terranuovadb",
		"sql":"with d as (select d.* from dimension d inner join oeeconf o on o.codriso=d.d1 where tm>$[tmbgn] and tm<$[tmend] and d2='ORA' and o.disabled='0' and o.codperiodo='ORA'),e as (select u.descrizio as linea,round(sum(m_rep_nptc-m_rep_stc)/60) as lavorato,round(sum(m_rep_d)/60) as previsto from d inner join fact f on f.codice=d.kfact inner join ubicaz u on u.codice=d.d1 group by u.descrizio) select  'Terranuova' as dplant,*,round((case when previsto>0 then lavorato/previsto else 0 end)::numeric, 2) as e from e order by linea",
		"renamemap":{"dplant":"Stabilimento","linea":"Centro di lavoro","lavorato":"Tempo Lavorato (min)", "previsto":"Tempo Previsto (min)", "e":"Efficienza (%)"}
	}
]  

In questo caso renamemap rinomina i campi dbplant, linea, lavorato, previsto, e assegnando nomi esplicativi.

Normalizzare query lunghe

Per poter normalizzare query lunghe in cui si adoperano ritorni a capo e spazi per poterle leggere meglio nel file JSON si può attivare l'attributo normalize.

L'attributo normalize se posto a 1 attiva un algoritmo di normalizzazione della stringa SQL.

Questa operazione è particolarmente utile per la visualizzazione dei LOG delle stringhe lunghe.

{
        "subkey":"ubigiac",
        "sql":"SELECT
                g.codubi,
                l.codart,
                ca.tipopal as codpal,
                ug.xabs as x,
                ug.yabs as y,
                ug.zabs as z,
                CASE WHEN tp.stackable = 1 then 2 else 1 END as npallet,
                u.tipocom,
                u.tiposet,
                0.0 as a,
                0.0 as b
            FROM
                giacese g JOIN lottim l on l.codice=g.codlot
                JOIN catego ca ON l.codart = ca.codice
                JOIN ubicaz u on u.codice=g.codubi
                JOIN tipopal tp on tp.codice = l.umext
                LEFT JOIN ubigeo ug on ug.codubi = g.codubi
            WHERE
                g.codubi=$[codubi]
            GROUP BY
                g.codubi,
                l.codart,
                u.tipocom,
                u.tiposet,
                ca.tipopal,
                ug.xabs,
                ug.yabs,
                ug.zabs,
                tp.stackable
            ORDER BY
                max(g.codice)",
        "paramsdef":{"codubi":"LGV"},
        "normalize":1
	}

La normalize riduce tutti gli spazi doppi o i ritorni a capo o i segni di tabulazione ad un unico spazio, in modo da avere la query su una unica riga.

IMPORTANTE: Utilizzare con attenzione nel caso in cui gli spazi servano per impostare valori o condizioni.

Q&A

[
        ...
        {
		"subkey":"ubiany",
		"sql":"select * from ubicaz WHERE codice = ANY(string_to_array($[lista codici], ','))"
	},
        ...
]
[
  ...
	{
		"subkey":"ubilike",
		"sql":"select * from ubicaz WHERE codice like $[codice] || '%'"
	}
]