[AsteriskBrasil] ENC: queue_log -> PostgreSQL rotina em C...sugestao.

Claudio Polegato Junior cpolegatojr.asterisk em gmail.com
Terça Outubro 24 14:19:27 BRT 2006


Olá,

  Você fez uma salada entre meu código e o seu. Tente modularizar ao 
máximo usando funções. No seu exemplo, você usa fgets, que lê 
diretamente uma linha e não o arquivo todo como é o caso do meu código, 
tornando-os de certa forma incompatíveis. Vou dar uma rápida enxugada no 
que fez e teste esse que vou mandar em anexo.

  Olhando seu código não entendi o uso da variável "cons", que nunca 
recebe um valor e é utilizada para comparação. Creio que deveria ser 
"result".

  Tente compilar com a opção -Wall para ver todos os possíveis avisos e 
dicas. Não compilei, não tive tempo para isso. Tenta ae e posta os 
resultados.

  Abraços.






#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Número máximo de campos
#define MAX_CAMPOS 10
// Separador entre cada campo
#define DELIMITADOR '|'
// Tamanho máximo da cláusulo SQL Insert (100 kB)
#define MAX_INSERT 102400

// Variáveis para controle de Conexão com o BD
static PGconn *conn;
static PGresult *result;

// Variável que aponta para cada campo encontrada em uma linha
static char* campos[MAX_CAMPOS];
static int campos_lidos;

// Função que faz com que a variável acima tenha os apontamentos corretos
int Apontar_Campos(char *linha){
  char *inicio, *delimitador;
  int campo_atual = 0;
  inicio = linha;
  delimitador = strchr(inicio, DELIMITADOR);
  while (delimitador && campo_atual < MAX_CAMPOS-1){
    *delimitador = '\0';
    campos[campo_atual++] = inicio;
    inicio = delimitador + 1;
    delimitador = strchr(inicio, DELIMITADOR);
  }
  campos[campo_atual++] = inicio;
  return campo_atual;
}

// Lê um arquivo e o coloca na memória
int Por_Arquivo_Memoria(char **memoria){
  FILE *arquivo;
  int tamanho;

  if ((arquivo = fopen("/var/log/kdm.log", "rt")) == NULL){
    perror("Erro");
    return 0;
  }
  fseek(arquivo, 0, SEEK_END);
  tamanho = ftell(arquivo);
  rewind(arquivo);
  *memoria = (char*)malloc(tamanho + 1);
  fread(*memoria, tamanho, 1, arquivo);
  fclose(arquivo);
  (*memoria)[tamanho] = '\0';
  return 1;
}

// Realiza a conexão com o BD
int Conectar(){
  conn = PQconnectdb("host=localhost "
                     "user=asterisk "
                     "password=asterisk "
                     "dbname=asterisk"
                    );
  if(PQstatus(conn) != CONNECTION_OK) {
    printf("Falha na conexão. Erro: %s", PQerrorMessage(conn));
    PQfinish(conn);
    return 0;
  }
  printf("Conexão com o banco efetuada com sucesso. ");
  return 1;
}

// Insere um registro, com os campos detectados, no DB
int Inserir(int campos_lidos){
  char inserir[MAX_INSERT], *c;
  strncpy(inserir, "Insert Into Queue_Log Values ('", 31);
  c = inserir + 31;
  for (i=0; i<campos_lidos-1; i++){
    printf("Campo %2i: %s\n", i, campos[i]);
    strncpy(c, campos[i], campos[i+1]-campos[i]-1);
    c += campos[i+1]-campos[i]-1;
    strncpy(c, "', '", 4);
  }
  printf("Campo %2i: %s\n", i, campos[i]);
  strcat(c, campos[i]);
  strcat(c, "')");

  printf("\nSQL: %s\n", inserir);
  result = PQexec(conn, inserir);

  if(result) {
    switch(PQresultStatus(result)) {
      case PGRES_EMPTY_QUERY:
        printf("Nenhuma alteracao.\n");
        break;
      case PGRES_FATAL_ERROR:
        printf("Erro na query: %s\n", PQresultErrorMessage(result));
        break;
      case PGRES_COMMAND_OK:
        printf("%s linhas afetadas.\n", PQcmdTuples(result));
        break;
      default:
        printf("Query executada sem retorno.\n");
        break;
    }
  }
  else
    printf("Erro executando query.\n");
}

int main(int argc, char* argv[]){
  char *memoria, *inicio, *delimitador;

  // Se tiver problemas com o arquivo ou com a conexão, termina.
  if (!Por_Arquivo_Memoria(&memoria) || !Conectar())
    return -1;

  inicio = memoria;
  delimitador = strchr(inicio, '\n');
  while (delimitador){
    *delimitador = '\0';
    printf("\n*******************\nLinha: %s\n\n", inicio);
    campos_lidos = Preencher_Campos(inicio);
    // Insere os dados no BD
    Inserir();

    inicio = delimitador + 1;
    delimitador = strchr(inicio, '\n');
  }
  return 0;
}

-- 
Atenciosamente

           Claudio Polegato Junior

           Engenheiro Autônomo - Ribeirão Preto e Região
           Mestre em Física Aplicada à Medicina e Biologia - USP
           Engenheiro Computacional - USP
           Engenheiro Eletrônico - USP

Um peregrino de problemas; Um pergaminho de soluções!

-------------- Próxima Parte ----------
Um anexo não texto foi limpo...
Nome  : teste_campos.c
Tipo  : text/x-c++src
Tam   : 3408 bytes
Descr.: não disponível
Url   : http://listas.asteriskbrasil.org/pipermail/asteriskbrasil/attachments/20061024/792f8b43/teste_campos.bin


Mais detalhes sobre a lista de discussão AsteriskBrasil