Barracuda Blog


Web, Tecnologia e Mare
0

Generare una lista di anagrafiche random con codice fiscale

In un progetto di performance testing mi è capitata la necessità di avere a disposizione un grande numero di anagrafiche distinte (nell'ordine delle migliaia), con relativo codice fiscale. Queste anagrafiche dovevano essere su un file csv, che sarebbe stato utilizzato come input dai virtual user di Loadrunner per simulare uno scenario di inserimento anagrafica. Il tracciato del file csv era il seguente:

nome,cognome,stato di nascita,sesso,provincia di nascita,comune di nascita,data,codice fiscale

Per creare il file csv ho sviluppato uno script PHP, nel quale ho usato una delle tante classi che si trovano sul web per generare il codice fiscale. Nel mio caso ho utilizzato questa, disponibile su PHPclasses.org.

Di seguito il codice dello script:

require_once 'codicefiscale.class.php';


class CodiceFiscale extends CodiceFiscale_Abstract {
    
    private $_db;
    
    public function leggiCatastali($filename) {
        $this->_db = unserialize(file_get_contents($filename));
    }
    
    protected function _calcolaCatastale() {
        if (!$this->_db) {
            throw new CodiceFiscale_Exception('impossibile caricare il file dei catastali');
        }
        $comune    = strtoupper($this->comune);
        $provincia = strtoupper($this->provincia);
        if (!isset($this->_db[$provincia][$comune])) {
            $message = sprintf("codice catastale non trovato (provincia: %s, comune: %s)", $provincia, $comune);
            throw new CodiceFiscale_Exception($message);
        }
        return $this->_db[$provincia][$comune];
    }
}

function random_name( $length = 8 ) {
    $chars = "abcdefghijklmnopqrstuvwxyz";
    $name = substr( str_shuffle( $chars ), 0, $length );
    return $name;
}

//funzione di comodità per generare un array da passare alla classe
function componi($nome, $cognome, $data, $comune, $provincia, $sesso) {
    return [
       'nome'      => $nome,
       'cognome'   => $cognome,
       'data'      => $data,
       'comune'    => $comune,
       'provincia' => $provincia,
       'sesso'     => $sesso 
    ];
}

// istanzio la classe e carico il db dei catastali
$cf = new CodiceFiscale();
$cf->leggiCatastali('catastali.txt');
$dati = array();
$fp = fopen('elenco_vf.csv', 'w');
$pool_citta = array('roma', 'torino', 'milano', 'trieste');
$pool_province = array('roma' => 'rm', 'torino' => 'to', 'milano' => 'mi', 'trieste' => 'ts');

//Genero 4000 anagrafiche random con relativo codice fiscale
for($i=0;$i<4000;$i++)
{
    $int= rand(157762800,567990000);
    $nome = random_name();
    $cognome = random_name();
    if((rand(1,100)%2) == 0) 
        $sesso = "m";
    else $sesso = "f";
    $citta_temp = $pool_citta[rand(0,3)];
    $dati[] = componi($nome , $cognome, date("d-m-Y",$int), $citta_temp, $pool_province[$citta_temp], $sesso);
    
}

//Creo l'intestazione del file csv
$testata = array('nome','cognome','statoDiNascita','sesso','provinciaDiNascita','comuneDiNascita','data','cf','anagrafica');
fputcsv($fp,$testata);
//per ogni anagrafica scrivo una riga sul file csv
foreach($dati as $persona) {
    try {
        $cf->importa($persona);
        fputcsv($fp, array_map('strtoupper',array($persona['nome'], $persona['cognome'], 'Italia', $persona['sesso'], $persona['provincia'], $persona['comune'], date_format(date_create($persona['data']), 'Y-m-d'),$cf->calcola(), '')));
    } catch (CodiceFiscale_Exception $e) {
        print "Errore: ". $e->getMessage() . "\n";
        continue;
    }
}

fclose($fp);

Spero sia utile, perchè online si trovano solamente soluzioni per generare il singolo codice fiscale.

Categories: Web Development

Tags: csv, php, codice fiscale, anagrafica

0

Automatizzare la Database Extract in Siebel

In quasi tutti i progetti Siebel si hanno almeno due ambienti di sviluppo, uno per le evolutive e uno per il bug fixing. Su alcuni, gli ambienti di sviluppo evolutivo sono anche più di due. Nel momento in cui si importa il repository su un ambiente è necessario effettuare la Generate New Database e le relative Database Extract, una per ogni sviluppatore.

Per evitare ogni volta di creare i job a mano, si può creare uno script bash che lancia tutti i componenti necessari. Di seguito trovate una bozza di script:

#!/bin/bash

setGlobalVar()
{
    users=user1,user2,user3
    sServer_g=testserver01            
    sGateway_g=localhost
    sEnterprise_g=SBA_81
    sUser_g=SADMIN
    sPassword_g=sadmin
    sDirWork="/u01/siebel/dbextract"
    NOW=$(date +"%Y-%m-%d-%H-%M-%S")
    sLogFile="$NOW.txt"

    echo "sServer_g       --> $sServer_g"
    echo "sGateway_g      --> $sGateway_g"
    echo "sEnterprise_g   --> $sEnterprise_g"
    echo "sUser_g         --> $sUser_g"
    echo "sDirWork        --> $sDirWork"
} # setGlobalVar

startupCmpGenNewDB()
{
    echo "Starting Generate New Database"
    /u01/siebel/sba81/siebsrvr/bin/srvrmgr -g $sGateway_g -e $sEnterprise_g -u $sUser_g -p $sPassword_g -c "run task for component GenNewDb server $sServer_g with Lang=ITA, Connect=SBA_81_DSN, Password=sadmin, Username=SADMIN, TableOwnPass=SIEBEL, TableOwner=SIEBEL, Repository='Siebel Repository', DbfFile=sse_utf8.dbf"
    echo "Generate New Database completed"

} # startupCmpGenNewDB

startupCmpDBExtract()
{
  
    echo "Starting Database Extract"
    /u01/siebel/sba81/siebsrvr/bin/srvrmgr -g $sGateway_g -e $sEnterprise_g -u $sUser_g -p $sPassword_g -c "run task for component DbXtract server $sServer_g with Lang=ITA, ExtractRepos=True, EncryptLocalDbPwd=False, DbTmplFile=sse_utf8.dbf, Client='$users', EncryptLocalDbMethod=none"
    echo "Database Extract Completed"

} # startupCmpGenNewDB

# ################################################################################
# MAIN
# ################################################################################

    setGlobalVar
    cd /u01/siebel/sba81/siebsrvr/
    . ./siebenv.sh
    cd $sDirWork
    startupCmpGenNewDB >> $sLogFile
    startupCmpDBExtract >> $sLogFile
  
  

# ################################################################################
# END MAIN
# ################################################################################

exit

La variabile users=user1,user2,user3 contiene tutti gli utenti per cui eseguire la database extract. Questa lista viene passata al parametro Client del task, che eseguirà l'extract per ogni utente sequenzialmente.

Categories: Oracle Siebel

Tags: siebel, linux

0

Caricare file XML di grandi dimensioni con Mysql

Nell'ambito di un progetto e-commerce, mi sono trovato a dover caricare dei file XML che contenevano informazioni sui prodotti (es: nomi, scheda descrittiva, categorie, ecc.). Questi file dovevano essere caricati su tabelle di un database Mysql versione 5.7 a determinati intervalli.

Ho utilizzato il comando nativo di Mysql:

LOAD XML LOCAL INFILE nome_file INTO TABLE nome_tabella ROWS IDENTIFIED BY '<RECORD>';

Purtroppo ho riscontrato l'impossibilità di caricare file più grandi di 10-15 MB in tempi accettabili, in quanto il numero di righe caricate dopo qualche minuto crollava da qualche centinaia a poche unità al secondo. Ho provato a ottimizzare i parametri del database, senza ottenere alcun miglioramento. Sembrerebbe un problema di Mysql.

Dal momento che, invece, il caricamento dei file CSV è molto veloce, ho pensato di utilizzare una trasformazione XSLT per convertire il file da XML a CSV. Questo è un esempio di file XML da convertire:

<?xml version="1.0"?>
<ALLRECORDSDATASET>
  <RECORD>
    <FDI_0001>000367058</FDI_0001>
    <FDI_0004>Nome Prodotto</FDI_0004>
    <FDI_0040>3733</FDI_0040>
    <FDI_0008>D</FDI_0008>
    <FDI_0012>D</FDI_0012>
    <FDI_0329>A06AB06</FDI_0329>
    <FDI_0245>S</FDI_0245>
    <FDI_0250>2003-06-18</FDI_0250>
    <FDI_9007>8.500</FDI_9007>
    <FDI_9144>2009-09-01</FDI_9144>
    <FDI_9145>7.700</FDI_9145>
    <FDI_9146>2009-03-10</FDI_9146>
    <FDI_0248>10</FDI_0248>
  </RECORD>
  ....
  ....
</ALLRECORDSDATASET>

Il file XSL che ho usato è il seguente:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>
    <xsl:variable name="delimiter" select="','"/>
    <xsl:strip-space elements="*"/>
    <xsl:key name="field" match="/*/*/*" use="local-name()"/>

    <!-- variable containing the first occurrence of each field -->
    <xsl:variable name="allFields"
         select="/*/*/*[generate-id()=generate-id(key('field', local-name())[1])]" />

    <xsl:template match="/">
        <xsl:for-each select="$allFields">
            <xsl:value-of select="local-name()" />
            <xsl:if test="position() &lt; last()">
                <xsl:value-of select="$delimiter" />
            </xsl:if>
        </xsl:for-each>
        <xsl:text>&#10;</xsl:text>
        <xsl:apply-templates select="*/*" />
    </xsl:template>

    <xsl:template match="*">
        <xsl:variable name="this" select="." />
        <xsl:for-each select="$allFields">
            <xsl:variable name="x" select="$this/*[local-name() = local-name(current())]" />
                        <xsl:value-of select="concat('$', $x, '$')"/>
            <xsl:if test="position() &lt; last()">
                <xsl:value-of select="$delimiter" />
            </xsl:if>
        </xsl:for-each>
        <xsl:text>&#10;</xsl:text>
    </xsl:template>
</xsl:stylesheet>

Questo XSL trasforma il file XML in un file CSV avente come colonne i nome dei tag all'interno dei tag <RECORD> e come delimitatore dei campi il carattere $.

Per effettuare la trasformazione ho usato SAXON (la versione .NET), che tra tutti i processori xslt è risultato quello che consuma meno memoria. Scordatevi di usare sistemi operativi a 32-bit e un quantitativo di ram inferiore a 8 GB. Durante una trasformazione di un file XML di 500 MB ho rilevato un consumo di memoria di oltre 3 GB.

Una volta ottenuto il file CSV, caricarlo sarà molto semplice e impiegherà qualche secondo con il comando:

LOAD DATA LOCAL INFILE 'file.csv' INTO TABLE nome_tabella FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '$' LINES TERMINATED BY '\n' IGNORE 1 LINES (campo1, campo2, ...) SET ID = null;

Categories: Web Development

Tags: xml, mysql, xslt, csv