1
0
mirror of https://gitlab.com/depesz/explain.depesz.com.git synced 2025-07-03 00:58:12 +02:00
Files
explain.depesz.com/lib/Explain/Plugin/Database.pm

206 lines
4.6 KiB
Perl
Raw Normal View History

package Explain::Plugin::Database;
use Mojo::Base 'Mojolicious::Plugin';
2011-03-11 10:33:49 +00:00
use Mojo::Util 'trim';
use Carp;
use DBI;
2011-03-11 10:33:49 +00:00
use Date::Simple;
has dbh => undef;
has connection_args => sub { [] };
sub register {
my ( $self, $app, $config ) = @_;
# data source name
my $dsn = $config->{ dsn };
# if DSN not set directly
unless ( $dsn ) {
# driver
my $driver = $config->{ driver } || 'Pg';
# database name
my $database = $config->{ database } || lc( $ENV{ MOJO_APP } );
# assemble
my $dsn = sprintf 'dbi:%s:database=%s', $driver, $database;
$dsn .= ';host=' . $config->{ host } if $config->{ host };
$dsn .= ';port=' . $config->{ port } if $config->{ port };
}
# database (DBI) connection arguments
$self->connection_args(
[
$config->{ dsn },
$config->{ username },
$config->{ password },
$config->{ options } || {}
]
);
# log debug message
2011-03-14 13:37:48 +00:00
$app->log->debug( 'Database connection args: ' . $app->dumper( $self->connection_args ) );
# register helper
$app->helper(
2011-03-14 13:37:48 +00:00
database => sub {
# not conected yet
unless ( $self->dbh ) {
# connect
$self->dbh( DBI->connect( @{ $self->connection_args } ) );
# raise error (for case, when "RaiseError" option is not set)
confess qq|Can't connect database| unless $self->dbh;
}
return $self;
}
);
return;
}
sub save_with_random_name {
my $self = shift;
my ( $title, $content, $is_public, $is_anon ) = @_;
my @row = $self->dbh->selectrow_array(
'SELECT id, delete_key FROM register_plan(?, ?, ?, ?)',
undef,
$title, $content, $is_public, $is_anon,
);
# return id and delete_key
return @row;
}
sub get_plan {
my $self = shift;
my ( $plan_id ) = @_;
my @row = $self->dbh->selectrow_array(
'SELECT plan, title FROM plans WHERE id = ? AND NOT is_deleted',
undef,
$plan_id,
);
# return plan
return @row;
}
sub delete_plan {
my $self = shift;
my ( $plan_id, $delete_key ) = @_;
my @row = $self->dbh->selectrow_array(
'UPDATE plans SET plan = ?, title = ?, is_deleted = true, delete_key = NULL WHERE id = ? and delete_key = ? RETURNING 1',
undef,
'',
'This plan has been deleted.',
$plan_id,
$delete_key
);
return 1 if $row[ 0 ];
return;
}
sub get_public_list {
my $self = shift;
return $self->dbh->selectall_arrayref(
'SELECT id, to_char( entered_on, ? ) as date FROM plans WHERE is_public ORDER BY entered_on DESC',
{ Slice => {} },
'YYYY-MM-DD'
);
}
sub get_public_list_paged {
my $self = shift;
2011-03-11 10:33:49 +00:00
# param "date"
my $date = defined( $_[ 0 ] ) ? $_[ 0 ] : '';
2011-03-11 10:33:49 +00:00
# trim
trim $date;
2011-03-11 10:33:49 +00:00
# today
my $today = Date::Simple->new;
2011-03-11 10:33:49 +00:00
# scalar $date to Date::Simple
my $to = eval { Date::Simple->new( $date ) };
# error
unless ( $to ) {
# invalid date, like: 2010-02-31
return { error => qq|Invalid date "$date" given.| }
if $date =~ /\A\d\d\d\d\-\d\d\-\d\d\z/;
# invalid format
return { error => qq|Invalid value "$date" given.| }
if length $date;
# fallback
$to = $today;
}
# time travel exception
return { error => qq|Date "$date" is in future!| } if $to > $today;
# since SCALAR value
my $since = ( $to - 7 )->as_str( '%Y-%m-%d' );
# select
my $rows = $self->dbh->selectall_arrayref(
'SELECT id, to_char( entered_on, ? ) as date
FROM plans
WHERE is_public
2011-03-11 10:33:49 +00:00
AND entered_on > ?::date
AND entered_on < ?::date
AND NOT is_deleted
ORDER BY entered_on
DESC',
{ Slice => {} },
'YYYY-MM-DD',
2011-03-11 10:33:49 +00:00
$since,
( $to + 1 )->as_str( '%Y-%m-%d' )
);
2011-03-11 10:33:49 +00:00
# next week
my $next = $to + 7;
$next = ( $next > $today ) ? undef : $next->as_str( '%Y-%m-%d' );
2011-03-11 10:33:49 +00:00
return {
since => $since,
to => $to->as_str( '%Y-%m-%d' ),
rows => $rows || [],
next_date => $next,
2011-03-14 11:07:08 +00:00
prev_date => ( $to - 8 )->as_str( '%Y-%m-%d' )
2011-03-11 10:33:49 +00:00
};
}
sub DESTROY {
my $self = shift;
# nothing to do...
return unless $self->dbh;
# rollback uncommited transactions
$self->dbh->rollback unless $self->connection_args->[ 3 ]->{ auto_commit };
# disconnect
$self->dbh->disconnect;
$self->dbh( undef );
return;
}
1;