Analizo

 view release on metacpan or  search on metacpan

lib/Analizo/Batch/Output/DB.pm  view on Meta::CPAN

  $self->{st_mark_as_modified} ||= $self->{dbh}->prepare('UPDATE commits_module_versions SET modified = 1 WHERE commit_id = ? AND module_version_id = ?');
  $self->{st_mark_as_modified}->execute($commit_id, $module_version_id);
}

sub _metrics_sql($@) {
  my ($metrics_hash, @metric_columns) = @_;
  my $metric_placeholders_sql = join(',', map { '?' } @metric_columns);
  my $metric_column_names_sql = join(',', @metric_columns);
  my @metric_values = map { $metrics_hash->{$_} } @metric_columns;
  return ($metric_placeholders_sql, $metric_column_names_sql, @metric_values)
}

# Initializes the database
#
# TODO the current approach of feeding DDL SQL statements directly to the
# database handle might not be good enough, since the SQL being written might
# not be portable to other databases than SQLite. It would be nice to have
# something similar to the rails migrations DSL here.
sub initialize($) {
  my ($self) = @_;
  $self->{dbh} = DBI->connect($self->database, undef, undef, { RaiseError => 1, InactiveDestroy => 1});
  # assume that if there is a table called `analizo_metadata`, then the database was already initialized
  if (!grep { $_ =~ /analizo_metadata/ } $self->{dbh}->tables()) {
    for my $statement (ddl_statements()) {
      $statement =~ s/\@\@MODULE_METRICS\@\@/_metric_columns_ddl(_module_metric_columns())/egm;
      $statement =~ s/\@\@PROJECT_METRICS\@\@/_metric_columns_ddl(_project_metric_columns())/egm;
      $statement =~ s/\@\@NUMERIC_AUTOINC_PK\@\@/_numeric_autoinc_pk($self->database)/egm;
      $self->{dbh}->do($statement);
    }
  }
}

my $DDL_INITIALIZED = 0;
my @DDL_STATEMENTS = ();
sub ddl_statements($) {
  if (!$DDL_INITIALIZED) {
    my $sql = '';
    while (my $line = <DATA>) {
      $sql .= $line;
      if ($line =~ /;\s*$/) {
        # SQL statement is ready
        CORE::push @DDL_STATEMENTS, $sql;
        $sql = '';
      }
    }
    $DDL_INITIALIZED = 1;
  }
  return @DDL_STATEMENTS;
}

use Analizo::Metrics;
use Analizo::Model;
my $__metric_columns = undef;
sub _metric_columns() {
  if (!$__metric_columns) {
    my $metrics = Analizo::Metrics->new(model => Analizo::Model->new);

    my %module_metrics = $metrics->list_of_metrics();
    my @module_metrics= keys(%module_metrics);

    my %project_metrics = $metrics->list_of_global_metrics();
    my @project_metrics = keys(%project_metrics);

    $__metric_columns = {
      module => \@module_metrics,
      project => \@project_metrics,
    };
  }
  return $__metric_columns;
}

sub _module_metric_columns() {
  return @{ _metric_columns()->{module} };
}

sub _project_metric_columns() {
  return @{ _metric_columns()->{project} };
}

sub _metric_columns_ddl {
  my @columns = @_;
  my $ddl = join(",\n  ", map { "$_ REAL"} @columns);
  return $ddl;
}

my %NUMERIC_AUTOINC_PK = (
  'sqlite'  => 'INTEGER PRIMARY KEY AUTOINCREMENT',
  'pg'      => 'SERIAL PRIMARY KEY',
);

sub _numeric_autoinc_pk($) {
  my ($database) = @_;
  my $dbtype = lc($database);
  $dbtype =~ s/^dbi:(.*):.*/$1/;
  my $sql = $NUMERIC_AUTOINC_PK{$dbtype};
  die("Database $dbtype is not supported!") if (!defined($sql));
  return $sql;
}

1;

__DATA__

/* Analizo DB output schema definition */

CREATE TABLE projects (
  id @@NUMERIC_AUTOINC_PK@@,
  name CHAR(250)
);

CREATE TABLE developers (
  id @@NUMERIC_AUTOINC_PK@@,
  name CHAR(250),
  email CHAR(250)
);

CREATE TABLE commits (
  id CHAR(40) PRIMARY KEY,
  previous_commit_id CHAR(40),
  project_id INTEGER,
  date INTEGER,



( run in 0.844 second using v1.01-cache-2.11-cpan-5b529ec07f3 )