mercoledì 3 novembre 2010

Oracle : Listener veramente lento

Se tnsping verso un database risponde in tempi lunghissimi, mentre ci si riesce a collegare al database dalla macchina stessa, senza passare dal listener, in tempi normali, il problema è molto probabilmente nel DNS : ad esempio il server DNS non è raggiungibile.

lunedì 1 novembre 2010

Ubuntu 10.10 + Driver Nvidia

Ho appena installato Ubuntu 10.10 su 2 pc : sul primo ho fatto un'installazione da zero, mentre sul secondo ho fatto l'upgrade partendo da una 10.04. In passato, ho sempre avuto qualche problema con i driver Nvidia ma questa volta tutto liscio. Ecco la procedura che ho seguito nei due casi.

  1. Installazione su sistema pulito : nessun problema, riavvio e da riga di comando eseguo sudo apt-get install nvidia-current. Riavvio e tutto funziona alla perfezione!
  2. Eseguo l'upgrade seguendo la documentazione Ubuntu, riavvio e vedo che il sistema non riesce a far partire X (probabilmente durante l'upgrade non sono stati ricompilati i moduli Nvidia...). A questo punto disinstallo tutti i pacchetti nvidia sudo apt-get remove nvidia* ed installo la versione corrente : sudo apt-get install nvidia-current. Riavvio, X parte ed utilizza i driver Nvidia!
Ormai è anni che utlizzo Linux (principalmente Fedora e Ubuntu) e posso affermare che questo è stato l'upgrade più indolore in assoluto!

domenica 31 ottobre 2010

Il Regno di Ga' Hoole - La leggenda dei guardiani

Ieri sera sono andato a vedere Il Regno di Ga' Hoole in un cinema in provincia di Pavia e devo dire che il 3D è stato eccezionale!! Credo che la differenza la facciano gli occhiali "attivi" che ci hanno fornito all'ingresso : con gli occhiali passivi che avevo provato in altri cinema, la qualità 3D era nettamente inferiore e, a me,  procuravano un leggero fastidio agli occhi mentre ,ad altri miei amici, dei noiosi mal di testa!
Comunque, oltre al 3D, il film presenta un'ottima animazione, paesaggi mozzafiato ed una buona trama : è un film che consiglio a tutti.
Ecco un link al trailer.

venerdì 29 ottobre 2010

Select * from C:\ ??? Ecco come farlo in Oracle

In questi giorni ho iniziato a sviluppare un nuovo processo che ha come database Oracle.
Prima di caricare alcuni file csv,l’utente deve avere la possibilità di vedere il contenuto di alcune directory non sempre visibili dalla macchina dell’utente quindi ho deciso che la soluzione ottimale fosse avere questo elenco all’interno di Oracle, ad esempio tramite una vista che interrogasse direttamente il filesystem. Ecco come fare tutto ciò :
  • CREATE OR REPLACE TYPE StringArray AS TABLE OF VARCHAR2(512);
  • CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED "FileHandler" AS
    import java.io.*;
    import java.sql.*;
    import oracle.sql.*;
    import oracle.jdbc.driver.*;
    public class FileHandler {
    public static oracle.sql.ARRAY list(String dirName) throws SQLException {
    Connection conn = null;
    int ret_code;
    String[] files = null;
    File file = new File(dirName);
    if (file.exists()) {
    if (file.isDirectory()) {
    if (file.canRead()) {
    files = file.list();
    }
    }
    }
    try {
    conn = new OracleDriver().defaultConnection();
    ArrayDescriptor x_ad = ArrayDescriptor.createDescriptor(
    "STRINGARRAY", conn);
    ARRAY x_array = new ARRAY(x_ad, conn, files);
    return x_array;
    } catch (SQLException e) {
    ret_code = e.getErrorCode();
    System.err.println(ret_code + e.getMessage());
    conn.close();
    return null;
    } finally {
    closeConnection(conn);
    }
    }private static void closeConnection(Connection connection) {
    if (connection == null) {
    return;
    } else {
    try {
    connection.close();
    } catch (Exception e) {
    System.out.println(e.getMessage());
    }
    connection = null;
    }}
    };
    /
  • CREATE OR REPLACE FUNCTION list (p_path IN VARCHAR2) RETURN StringArray AS LANGUAGE JAVA NAME 'FileHandler.list (java.lang.String) return oracle.sql.ARRAY';
  • EXEC DBMS_JAVA.grant_permission('SCHEMA-NAME', 'java.io.FilePermission', '<<ALL FILES>>', 'read ,write, execute, delete');
    EXEC DBMS_JAVA.grant_permission('SCHEMA-NAME', 'SYS:java.lang.RuntimePermission', 'writeFileDescriptor', '');
    EXEC DBMS_JAVA.grant_permission('SCHEMA-NAME', 'SYS:java.lang.RuntimePermission', 'readFileDescriptor', '');
    GRANT JAVAUSERPRIV TO SCHEMA-NAME;
A questo punto sarà sufficiente fare una query come quella seguente per ottenere tutti i file e directory presenti sul disco C della macchina sulla quale c’è il database.
SELECT * FROM TABLE(LIST('C:\'))
Naturalmente questo è solo un esempio che mostra la strada che ,secondo me, è meglio seguire; si potrebbero creare strutture più complesse che oltre al nome del file restituiscano la dimensione o la data dello stesso.

Lanciare un processo sincrono da Oracle tramite Java

Ecco una breve classe java che permette di lanciare un qualsiasi processo del sistema operativo da Oracle.

CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED "FileHandler" AS
import java.io.*;
import java.sql.*;
import oracle.sql.*;
import oracle.jdbc.driver.*;


class StreamReader extends Thread {
InputStream inputStream;
String prefix;

StreamReader(InputStream inputStream, String prefix) {
this.inputStream = inputStream;
this.prefix = prefix;
}

public void run() {
try {
InputStreamReader inputStreamReader = new InputStreamReader(
inputStream);
BufferedReader bufferedReader = new BufferedReader(
inputStreamReader);
String line = null;
while ((line = bufferedReader.readLine()) != null) {
System.out.println(prefix + " " + line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

class StreamWriter extends Thread {
OutputStream outputStream;
String prefix;

StreamWriter(OutputStream outputStream) {
this.outputStream = outputStream;
}

public void run() {
try {
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter);
while (true) {
bufferedWriter.newLine();
}
} catch (IOException e) {

}
}
}

public class FileHandler {

public static int run (String command) {
Runtime runtime = Runtime.getRuntime();
Process process;
int exitValue = -1;
try {
process = runtime.exec(command);

StreamReader errorReader = new StreamReader(process.getErrorStream(), "<<ERROR>>");
StreamReader outputReader = new StreamReader(process.getInputStream(), "<<OUTPUT>>");
StreamWriter inputWriter = new StreamWriter(process.getOutputStream());
errorReader.start();
outputReader.start();
inputWriter.start();
exitValue = process.waitFor();

} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
return exitValue;
}

};
La classe StreamReader serve per poter catturare lo standard output e lo standard error del processo lanciato e loggarli : in questo caso verranno scitti all’interno di trace file nella directory user dump di Oracle ma nulla ci vieta di inserire il tutto in una tabella per una consultazione più rapida. La classe StreamWriter invece impedisce che il processo si blocchi nel caso quest’ultimo sia in attesa sullo standard input. Nel mio caso ero solo interessato al fatto che il processo non si bloccasse quindi non faccio altro che simulare un invio da tastiera, però si potrebbero inviare delle informazioni tramite lo standard input se il processo lo richiedesse.
Il metodo run all’interno della classe FileHandler non fa altro che lanciare il processo e restituire il valore ritornato dal processo, solitamente 0 significa ‘terminato con successo’ e tutto il resto significa che si sono verificati degli errori.
Adesso creiamo una stored procedure che punti a questo metodo :
create or replace FUNCTION OSCommand_Run(Command IN STRING) RETURN NUMBER IS LANGUAGE JAVA NAME 'FileHandler.run(java.lang.String) return int';
Diamo i permessi necessari
EXEC DBMS_JAVA.grant_permission('SCHEMA-NAME', 'java.io.FilePermission', '<<ALL FILES>>', 'read ,write, execute, delete');
EXEC DBMS_JAVA.grant_permission(’SCHEMA-NAME’, ‘SYS:java.lang.RuntimePermission’, ‘writeFileDescriptor’, ”);
EXEC DBMS_JAVA.grant_permission(’SCHEMA-NAME’, ‘SYS:java.lang.RuntimePermission’, ‘readFileDescriptor’, ”);
A questo punto possiamo lanciare e monitorare un qualsiasi processo del sistema operativo da una stored procedure o package.

Linux : ruotare un video al volo

Ecco come ruotare un video in pochi secondi con mencoder :


mencoder -oac copy -ovc lavc -lavcopts vcodec=mjpeg -vf rotate=1  input.avi -o output.avi
Il parametro rotate puo assumere altri valori :
0 : ruota di 90° in senso orario e gira
1 : ruota di 90° in senso orario
2 : ruote di 90° in senso antiorario
3 : ruote di 90° in senso antiorario e gira
Analogamente valori dal 4 al 7 vengono utilizzati per quei video con geometria “ritratto” e non “paesaggio”.

Oracle : allocare/deallocare i CLOB

In una piattaforma che ho recentemente sviluppato in Oracle (PL/SQL) faccio un uso frequente di variabili CLOB che vanno correttamente deallocate soprattutto se utilizzate all'interno di un ciclo. Quindi mi sono creato due semplici procedure per creare e deallocare un CLOB.

PROCEDURE pr_Open_CLOB(pc_Clob IN OUT NOCOPY CLOB) AS
BEGIN
pc_Clob:=EMPTY_CLOB;
DBMS_LOB.CREATETEMPORARY(pc_Clob, TRUE);
DBMS_LOB.OPEN(pc_Clob, DBMS_LOB.LOB_READWRITE);
END pr_Open_CLOB;


PROCEDURE pr_Close_CLOB(pc_Clob IN OUT NOCOPY CLOB) AS
BEGIN
IF DBMS_LOB.ISOPEN(pc_Clob)=1 THEN
DBMS_LOB.CLOSE(pc_Clob);
END IF;
IF DBMS_LOB.ISTEMPORARY(pc_Clob)=1 THEN
DBMS_LOB.FREETEMPORARY(pc_Clob);
END IF;
END pr_Close_CLOB;



Ecco un esempietto su come utilizzarle : 


PROCEDURE pr_Test AS
c_Temp CLOB;
BEGIN
pr_Open_Clob(c_Temp);
--use clob
pr_Close_Clob(c_Temp);
EXCEPTION
WHEN OTHERS THEN
pr_Close_Clob(c_Temp);
END pr_Test;