Introdução
Então pensei em fazer algo simples, porém útil, um script em PHP que faça a consulta e apresente na saída padrão ( no terminal ).
Poderia ter sido usado qualquer outra linguagem de programação, usei o PHP por sua conexão com diferentes SGBD ser bem fácil e no momento estou mais familiarizado com sua sintaxe.
Preparando o Ambiente
Caso não tenha o PHP instalado ainda:
$ sudo apt-get install php5
Para este artigo, preparei o ambiente para realizar consultar no Postgres, MySQL e MS SQL Server.
Instale os módulos necessários para o PHP realizar a conexão:
$ sudo apt-get install php5-pgsql php5-mysql php5-sybase
Obs.: O php5-sybase é um módulo usado tanto para o Sybase como para o MS SQL Server.
Com a ajuda de um terminal embutido, como Guake, você nem vai precisar ir até um terminal usando o menu, basta usar o atalho configurado.
Ao final desse artigo teremos a possibilidade de fazer algo como:
Mão na massa ( O script PHP )
Arquivo de conexão
Para realizar a conexão com o SGBD fiz a classe DataBase ler um arquivo “.ini”, onde o mesmo é nomeado com o nome do SGBD seguido pelo nome da base de dados, e dentro dele seguem os dados do servidor (host), usuário, senha e opcionalmente a porta.
Exemplo de arquivo de configuração para conexão:
user = postgres
pass = gnuxx22l1n1
Classe de conexão
Seque o código da classe de conexão com os SGBD:
/*
* classe DataBase
* Gerencia conexoes com bancos de dados através de arquivos de configuracao.
* Baseada em TConnection.class.php do livro: PHP Programando com Orientação a Objetos (Pablo Dall”Oglio)
*/
class DataBase
{
public static $conn;
private function __construct() {}
/*
* metodo open()
* recebe o nome do banco de dados e instancia o objeto PDO correspondente
* o arquivo segue o padrao: tipobanco_nomebase
*/
private function open( $arquivo )
{
// verifica se existe o arquivo
if ( file_exists( “{$arquivo}.ini”) )
{
// le o INI e retorna um array
$nome = explode(‘_’, $arquivo );
$tipoBanco = $nome[0];
$nomeBase = $nome[1];
$db = parse_ini_file(“{$arquivo}.ini”);
}
else
{
// se nao existir, lanca um erro
throw new Exception(“Arquivo ‘$arquivo’ nao encontrado”);
}
// le as informacoes contidas no arquivo
$usuario = isset($db[‘user’]) ? $db[‘user’] : NULL;
$senha = isset($db[‘pass’]) ? $db[‘pass’] : NULL;
$host = isset($db[‘host’]) ? $db[‘host’] : NULL;
$porta = isset($db[‘port’]) ? $db[‘port’] : NULL;
// descobre qual o tipo (driver) de banco de dados a ser utilizado
switch ( $tipoBanco )
{
case ‘pgsql’:
$porta = $porta ? $porta : ‘5432’;
$conn = new PDO(“pgsql:dbname={$nomeBase}; user={$usuario}; password={$senha};
host=$host;port={$porta}”);
break;
case ‘mysql’:
$porta = $porta ? $porta : ‘3306’;
$conn = new PDO(“mysql:host={$host};port={$porta};dbname={$nomeBase}”, $usuario, $senha);
break;
case ‘mssql’:
$conn = new PDO(“dblib:host={$host};dbname={$nomeBase};charset=UTF-8”, $usuario, $senha);
break;
}
// define para que o PDO lance excecoes na ocorrencia de erros
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// retorna o objeto instanciado.
return $conn;
}
/*
* Metodo que implementa o padrao Singleton
* O mesmo retorna a instancia de conexao de um banco caso ja exista
* Evitando a criacao de uma nova a cada solicitacao
*/
public static function getConn( $nomeArquivo ) {
if ( ! isset( self::$conn[$nomeArquivo] ) ) {
self::$conn[$nomeArquivo] = DataBase::open( $nomeArquivo );
}
return self::$conn[$nomeArquivo];
}
}
?>
Script de consulta (shellquery)
Agora o código do script PHP que realiza de fato a consulta no banco de dados, mediante parâmetros fornecidos via terminal.
<?php
# uso: shellquery tipoBanco_nomeBase “comandoSQL”
include_once “DataBase.class.php”;
#———————————————-
$mostraNomeCampos = TRUE;
$banco = isset( $argv[1] ) ? $argv[1] : NULL;
$sql = isset( $argv[2] ) ? $argv[2] : NULL;
# se for passado um terceiro argumento, não exibe o nome dos campos
if ( isset( $argv[3] ) ) $mostraNomeCampos = FALSE;
if ( $banco == NULL || $sql == NULL ) {
echo “Sintaxe {$argv[0]} nomeArquivoConfiguracao comandoSQL\n”;
exit;
}
try {
$conn = DataBase::getConn( “$banco” );
$rs = $conn->query( $sql )->fetchAll();
} catch ( Exception $e ){
echo “Erro: {$e->getMessage()} :\nLinha: {$e->getLine()}\n”;
exit;
}
foreach ( $rs as $dados ) {
$ultimaCol = ( count( $dados ) / 2 ) – 1;
if ( $mostraNomeCampos == TRUE ) {
# obtem os nomes dos campos
$key = ( array_keys( $dados ) );
$x=0;
for ( $i=0; $i < count( $key ); $i++ ) {
if ( is_int( $key[$i] ) ) continue;
$campo[$x] = $key[$i];
$x++;
}
# exibe os nomes dos campos
for ( $i=0; $i < $ultimaCol; $i++ ) {
echo “{$campo[$i]}|”;
}
echo “{$campo[$ultimaCol]}\n”;
}
$mostraNomeCampos = FALSE;
# exibe os dados
for ( $i=0; $i < $ultimaCol; $i++ ) {
echo “{$dados[$i]}|”;
}
echo “{$dados[$ultimaCol]}\n”;
}
?>
Salve em um arquivo, como shellquery, dê permissão de execução:
$ chmod +x shellquery
E use à vontade.
Exemplo de uso
./shellquery pgsql_casa “SELECT * FROM disciplinas”
Resultado:
no_disciplina|id_disciplina
PORTUGUES|1
MATEMATICA|2
GEOGRAFIA|3
HISTORIA|4
Bom, a saída deixei bem simples, exibindo os registros um por linha, separados por “|”, assim poderá ser usado a seu gosto, para:
– Quantos registros foram retornados?:
$ ./shellquery pgsql_casa “SELECT * FROM disciplinas” QUALQUERCOISA | wc -l
Resultado:
4
– Criar um arquivo CSV com separdor “;” no lugar de “|”:
$ ./shellquery pgsql_casa “SELECT * FROM disciplinas” | tr ‘|’ ‘;’ > resultado.csv
Arquivo resultado.csv aberto no libreoffice:
Enfim, podem ser feitas as infinidades de modificações que o GNU/Linux permite via shell.
Espero que ajude e facilite a vida de vocês, pra mim é uma mão na roda, uso todos os dias!