Página 1 de 2

Perl y SQLite

NotaPublicado: 2015-07-17 21:19 @930
por situ
Tengo un script el cual se encarga de leer una base de datos SQLite y guardar su información en un documento Word. El script funciona pero no de la mejor forma, y por este motivo los molesto para pedirles si me ayudan a mejorarlo, por favor.

Como verán cuando guardo la descripción, riesgo y recomendación tuve que hacer 3 SELECT, pero quiero ver la posibilidad de achicar un poco el código.

Por otro lado quería consultarles cómo puedo hacer para asociar la variable $contador con el nombre de cada elemento que sale de $row[0], ya que me gustaría poder hacer que no se tenga que escribir el nombre del elemento como ahora, sino su número que sale por pantalla y separado por coma con otros. Así se listan varios y no solo uno.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2.  
  3. use DBI;
  4.  
  5. if ( @ARGV != 0 ) {
  6.  
  7. die "###############################################################\n"
  8. .   "#                    Crear reporte                            #\n"
  9. .   "###############################################################\n\n"
  10.       ;
  11. }
  12.  
  13. ############ Variables ############
  14. $contador=0;
  15. use utf8;
  16. ############ Conecto a la DB ############
  17. my $dbh = DBI->connect(          
  18.     "dbi:SQLite:dbname=issues_descripcion.s3db",
  19.     "",                          
  20.     "",                          
  21.     {
  22.         RaiseError => 1,
  23.         sqlite_unicode => 1,
  24.         },        
  25. ) or die $DBI::errstr;
  26.  
  27. ########### Creamos el documento word ############
  28. use MsOffice::Word::HTML::Writer;
  29.   my $doc = MsOffice::Word::HTML::Writer->new(
  30.     title        => "Reporte",
  31.     WordDocument => {View => 'Print'},
  32.   );
  33.  
  34.   $doc->create_section(
  35.     page => {size   => "21.0cm 29.7cm",
  36.              margin => "1.2cm 2.4cm 2.3cm 2.4cm"},
  37.   );
  38.  
  39. ############ Listado de vulnerabilidades ############
  40. print "\n\nListado de las vulnerabilidades almacenadas:\n";
  41. my $sth = $dbh->prepare("SELECT issues FROM informacion");
  42. $sth->execute();
  43. while (my @row = $sth->fetchrow_array) {
  44.    $contador ++;
  45.    print "$contador - $row[0]\n";
  46.    #$doc->write("<p>$contador - $row[0]</p>\n",
  47.    #);
  48. }
  49.  
  50. print "\n\nIngrese el nombre de la vulnerabilidad: ";
  51. $issues = <>;
  52. chomp $issues;
  53. print "Vulnerabilidad ingresada: $issues";
  54. $doc->write("<p><h2><b>$issues</b></h2></p>\n");
  55. $doc->write("<p><h3><b>Observacion:</h3></b></h2></p>\n");
  56. my $sth = $dbh->prepare("SELECT observacion FROM informacion WHERE issues='$issues'");
  57. $sth->execute();
  58.  
  59. while (my @row = $sth->fetchrow_array) {
  60.    $doc->write("<p>$row[0]</p>\n",
  61.    );
  62. }
  63.  
  64. my $sth = $dbh->prepare("SELECT riesgo FROM informacion WHERE issues='$issues'");
  65. $sth->execute();
  66. $doc->write("<p><h3><b>Riesgo:</h3></b></h2></p>\n");
  67. while (my @row = $sth->fetchrow_array) {
  68.    $doc->write("<p>$row[0]</p>\n",
  69.    );
  70. }
  71.  
  72. my $sth = $dbh->prepare("SELECT recomendacion FROM informacion WHERE issues='$issues'");
  73. $sth->execute();
  74. $doc->write("<p><h3><b>Recomendacion:</h3></b></h2></p>\n");
  75. while (my @row = $sth->fetchrow_array) {
  76.    $doc->write("<p>$row[0]</p>\n",
  77.    );
  78. }
  79.  
  80. $doc->save_as("reporte.doc");
  81. $sth->finish();
  82. $dbh->disconnect();
  83.  
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4


Muchas gracias.

Re: Perl y SQLite

NotaPublicado: 2015-07-19 20:13 @884
por explorer
No sé cómo responder a lo de $contador, pero a lo mejor lo puedes resolver con un simple hash.

Aquí hay una forma de abreviar el código:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use DBI;
  3. use utf8;
  4. use MsOffice::Word::HTML::Writer;
  5.  
  6. if ( @ARGV != 0 ) {
  7.  
  8.     die "###############################################################\n"
  9.     .   "#                    Crear reporte                            #\n"
  10.     .   "###############################################################\n\n"
  11.     ;
  12. }
  13.  
  14. ############ Variables ############
  15. my $contador = 0;
  16.  
  17. ############ Conecto a la DB ############
  18. my $dbh = DBI->connect(          
  19.     "dbi:SQLite:dbname=issues_descripcion.s3db",
  20.     "",                          
  21.     "",                          
  22.     {
  23.         RaiseError     => 1,
  24.         sqlite_unicode => 1,
  25.     },        
  26. ) or die $DBI::errstr;
  27.  
  28. ########### Creamos el documento word ############
  29. my $doc = MsOffice::Word::HTML::Writer->new(
  30.     title        => "Reporte",
  31.     WordDocument => {View => 'Print'},
  32. );
  33.  
  34. $doc->create_section(
  35.     page   => {size  => "21.0cm 29.7cm",
  36.     margin => "1.2cm 2.4cm 2.3cm 2.4cm"},
  37. );
  38.  
  39. ############ Listado de vulnerabilidades ############
  40. print "\n\nListado de las vulnerabilidades almacenadas:\n";
  41.  
  42. my $sth = $dbh->prepare("SELECT issues FROM informacion");
  43. $sth->execute();
  44. while (my @row = $sth->fetchrow_array) {
  45.     $contador++;
  46.     print "$contador - $row[0]\n";
  47.     #$doc->write("<p>$contador - $row[0]</p>\n",
  48.     #);
  49. }
  50.  
  51. print "\n\nIngrese el nombre de la vulnerabilidad: ";
  52.  
  53. chomp(my $issues = <>);
  54. print "Vulnerabilidad ingresada: $issues";
  55.  
  56. $doc->write("<p><h2><b>$issues</b></h2></p>\n");
  57.  
  58. for my $issue (qw(observacion riesgo recomendacion)) {
  59.  
  60.     my $sth = $dbh->prepare("SELECT $issue FROM informacion WHERE issues=?");
  61.     $sth->execute($issues);
  62.  
  63.     $doc->write("<p><h3><b>" . ucfirst($issues) . ":</h3></b></h2></p>\n");
  64.  
  65.     while (my @row = $sth->fetchrow_array) {
  66.         $doc->write("<p>$row[0]</p>\n",
  67.         );
  68.     }
  69. }
  70.  
  71. $doc->save_as("reporte.doc");
  72. $sth->finish();
  73. $dbh->disconnect();
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

Lo que no me queda tampoco claro es qué hace ahí un die().

Re: Perl y SQLite

NotaPublicado: 2015-07-19 20:27 @893
por situ
Muchas gracias por optimizar el código.

La verdad que estoy tratando de armarlo mediante ejemplos, por este motivo tengo seguramente código de más o mal posicionado.

Cuando ejecuto el script obtengo la lista de vulnerabilidad y mediante el contador lo que hago es ponerle un número a su izquierda, como se ve en la siguiente imagen.

Imagen

Mi idea es que el script consulte el número de la vulnerabilidad y de las vulnerabilidades separados por coma, así no hace falta poner todo el nombre de la vulnerabilidad o vulnerabilidades a exportar en el documento.

Como se ve ahora hay que ingresar todo el nombre de la vulnerabilidad.

Re: Perl y SQLite

NotaPublicado: 2015-07-20 20:14 @885
por explorer
¡Ah, ya entiendo! Quieres hacer una especie de menú.

Una opción sería la que te comenté: creas un hash que relacione el número con la cadena, y así luego es fácil recuperar los valores que solicita el usuario:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2.  
  3. # Imita el contenido de la base de datos ("SELECT issues FROM informacion")
  4. my @vulnerabilidades =
  5.     ( 'Software desactualizado'
  6.     , 'Comunidad SNMP por defecto'
  7.     , 'Otra'
  8.     , 'Y otra más'
  9. );
  10.  
  11. my $contador = 0;
  12.  
  13. my %vulnerabilidades;                           # hash a rellenar
  14.  
  15. for my $row (@vulnerabilidades) {
  16. #while (my @row = shift @vulnerabilidades) {
  17.     $contador++;
  18.     print "$contador - $row\n";
  19.  
  20.     $vulnerabilidades{$contador} = $row;        # guardamos la relación
  21. }
  22.  
  23. # ...
  24.  
  25. print "\nIngrese el número o números de las vulnerabilidades, separados por comas: ";
  26.  
  27. chomp(my $issues = <>);
  28. print "Vulnerabilidad ingresada: [$issues]\n";
  29.  
  30. my @numeros = split /,/, $issues;
  31.  
  32. for my $numero (@numeros) {
  33.     $numero += 0;                       # aseguramos que es un número
  34.  
  35.     if ($vulnerabilidades{$numero}) {
  36.         my $vulnera = $vulnerabilidades{$numero};
  37.  
  38.         print "Sacando vulnerabilidades de [$vulnera]:\n";
  39.  
  40.         #$doc->write("<p><h2><b>$vulnera</b></h2></p>\n");
  41.         #for my $issue (qw(observacion riesgo recomendacion)) {
  42.         #    my $sth = $dbh->prepare("SELECT $issue FROM informacion WHERE issues=?");
  43.         #    $sth->execute($vulnera);
  44.         #    $doc->write("<p><h3><b>" . ucfirst($vulnera) . ":</h3></b></h2></p>\n");
  45.         #    while (my @row = $sth->fetchrow_array) {
  46.         #        $doc->write("<p>$row[0]</p>\n",
  47.         #        );
  48.         #    }
  49.         #}
  50.     }
  51. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

De todas formas, la forma recomendada de hacer esto es usando un módulo de la familia Getopt, ya que permite hacer menús de forma sencilla.

Re: Perl y SQLite

NotaPublicado: 2015-07-21 07:57 @373
por situ
¡Perfecto! Muchas gracias.

Voy a continuar y cuando tenga el script con más funcionalidades lo comparto.
Saludos.

Re: Perl y SQLite

NotaPublicado: 2015-07-23 00:11 @049
por situ
Ahora estoy tratando de exportar la DB a un excel, pero no lo puedo lograr.

Necesito de alguna forma poder exportar issues/observacion/recomendacion de la base de datos y aparte en la columna "prueba" (columna que va antes de recomendaciones) ingresar el texto "chequeado".

Así quedo el script:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use DBI;
  3. use utf8;
  4. use Excel::Writer::XLSX;
  5. ############ Variables ############
  6. my $contador = 0;
  7. my %vulnerabilidades;
  8. my $workbook  = Excel::Writer::XLSX->new("reporte_issues.xlsx");
  9. my $worksheet = $workbook->add_worksheet('Vulnerabilades');
  10. $worksheet->set_tab_color('red');
  11.  
  12. #$worksheet->autofilter( 0, 0, 999999, 14 );
  13. $worksheet->set_column( 0, 14, 20 );
  14.  
  15. ############ Conecto a la DB ############
  16. my $dbh = DBI->connect(
  17.     "dbi:SQLite:dbname=midb.s3db",
  18.     "", "",
  19.     {
  20.         RaiseError     => 1,
  21.         sqlite_unicode => 1,
  22.     },
  23. ) or die $DBI::errstr;
  24.  
  25. ########### Creamos el reporte ############
  26. ##Iniciadores de las variables que corresponden a las columnas
  27. $a = 0;
  28. $b = 0;
  29. $c = 0;
  30. $d = 0;
  31.  
  32. ## Formato para los nombres de las columnas
  33. my $header = $workbook->add_format();
  34. $header->set_bold();
  35. $header->set_size(12);
  36. $header->set_color(0x09);
  37. $header->set_align('center');
  38. $header->set_fg_color(0x16);
  39. $header->set_border(1);
  40. $header->set_border_color('black');
  41. ## Nombre de las columnas del TAB vulnerabilidades
  42. my @columnas = qw(
  43.   Vulnerabilidad        Descripción    Prueba Recomendaciones
  44. );
  45. for ( my $i = 0 ; $i < @columnas ; $i++ ) {
  46.     $worksheet->write( 0, $i, $columnas[$i], $header );
  47. }
  48. ## Formato para las filas
  49. my $files = $workbook->add_format();
  50. $files->set_border(1);
  51. $files->set_border_color('black');
  52.  
  53. ############ Listado de vulnerabilidades ############
  54. print "\n\nListado de las vulnerabilidades almacenadas:\n";
  55. my $sth = $dbh->prepare("SELECT issues FROM mitabla");
  56. $sth->execute();
  57. while ( my @row = $sth->fetchrow_array ) {
  58.     $contador++;
  59.     print "$contador - $row[0]\n";
  60.     $vulnerabilidades{$contador} = $row[0];
  61. }
  62.  
  63. ############ Listado de vulnerabilidades ############
  64. print
  65. "\n\nIngrese el número o números de las vulnerabilidades, separados por comas: ";
  66. chomp( my $issues = <> );
  67. print "\n[+]Vulnerabilidad/es ingresada/s: [$issues]\n";
  68.  
  69. my @numeros = split /,/, $issues;
  70.  
  71. for my $numero (@numeros) {
  72.     $numero += 0;    # aseguramos que es un número
  73.  
  74.     if ( $vulnerabilidades{$numero} ) {
  75.         my $vulnera = $vulnerabilidades{$numero};
  76.  
  77.         print " [-]Exportando vulnerabilidad [$vulnera]\n";
  78.  
  79.         for my $issue (qw(issues observacion recomendacion)) {
  80.             my $sth =
  81.               $dbh->prepare("SELECT $issue FROM mitabla WHERE issues=?");
  82.             $sth->execute($vulnera);
  83.             @row = $sth->fetchrow_array;
  84.             foreach my $row (@row) {
  85.                 chomp $row;
  86.                 $worksheet->write( 1 + $a, 0, $row[0], $files );
  87.             }
  88.         }
  89.     }
  90. }
  91.  
  92. ############ Indicamos qué archivos fueron creados ############
  93. print "\n\n############################################################\n\n";
  94. print "\nSe creó el informe: reporte_issues.xlsx";
  95.  
  96. $sth->finish();
  97. $dbh->disconnect();
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4


Mil gracias, como siempre.

Re: Perl y SQLite

NotaPublicado: 2015-07-23 11:29 @520
por explorer
Lo mismo que antes: puedes usar un hash para saber en qué índice de columna debes escribir la vulnerabilidad que estás sacando de la base de datos.

Re: Perl y SQLite

NotaPublicado: 2015-07-23 14:57 @664
por situ
Estuve intentando y no pude, pensé que haciendo el "bucle" sobre el array podría llegar a solucionarlo pero no es así.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. ############ Listado de vulnerabilidades ############
  2.     print "\n\nIngrese el número o números de las vulnerabilidades, separados por comas: ";
  3.     chomp( my $issues = <> );
  4.     print "\n[+]Vulnerabilidad/es ingresada/s: [$issues]\n";
  5.  
  6.     my @numeros = split /,/, $issues;
  7.  
  8.     for my $numero (@numeros) {
  9.         $numero += 0;    # aseguramos que es un número
  10.  
  11.         if ( $vulnerabilidades{$numero} ) {
  12.             my $vulnera = $vulnerabilidades{$numero};
  13.  
  14.             print " [-]Exportando vulnerabilidad [$vulnera]\n";
  15.  
  16.             for my $issue (qw(observacion riesgo recomendacion)) {
  17.                 my $sth =
  18.                   $dbh->prepare("SELECT $issue FROM mitabla WHERE issues=?");
  19.                 $sth->execute($vulnera);
  20.                 push( @titulos, $sth->fetchrow_array );
  21.             }
  22.         }
  23.     }
  24.  
  25.     for my $testing (@titulos) {
  26.         print $testing[1];
  27.         $worksheet->write( 1 + $a, 0, $testing[0], $files );
  28.     }
  29.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Saludos.

Re: Perl y SQLite

NotaPublicado: 2015-07-23 18:18 @804
por explorer
Aquí hay errores:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.     for my $testing (@titulos) {
  2.         print $testing[1];
  3.         $worksheet->write( 1 + $a, 0, $testing[0], $files );
  4.     }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Resulta que si no varías el contenido de $a, estás guardando todos los valores de $testing[0] en la misma celda.

Prueba a cambiar $a por $a++

Re: Perl y SQLite

NotaPublicado: 2015-07-23 18:30 @813
por situ
Perfecto, ahora se guardan todos los valores en la columna A, pero como comentaba antes necesito que cada uno vaya a una columna diferente y entre medio de 2 columnas, ingresar un texto.

Gracias.