Skip to content

Commit

Permalink
adding MySQL::Util::Protected
Browse files Browse the repository at this point in the history
  • Loading branch information
gravattj committed Nov 23, 2014
1 parent c547851 commit 1cc3c08
Show file tree
Hide file tree
Showing 2 changed files with 327 additions and 5 deletions.
11 changes: 6 additions & 5 deletions lib/MySQL/Util.pm
Original file line number Diff line number Diff line change
Expand Up @@ -1247,8 +1247,9 @@ sub get_indexes {

=item get_insert_stmt()
Returns an array with an insert statement and an array with bind variables
for the specified table. Default is to use all columns except auto_increment.
Returns an arrayref with an insert statement and optionally an arrayref with
bind variables for the specified table. Default is to use all columns except
auto_increment.
required args:
Expand Down Expand Up @@ -1339,12 +1340,12 @@ sub get_insert_stmt {
join( ', ', @qmarks )
);

my $data_aref;
if ($columns_href) {
my $data = [ @data ];
return [ $sql, $data ];
$data_aref = [ @data ];
}

return $sql;
return [ $sql, $data_aref ];
}

=item get_max_depth()
Expand Down
321 changes: 321 additions & 0 deletions lib/MySQL/Util/Protected.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,321 @@
package MySQL::Util::Protected;

use Modern::Perl;
use Moose::Role;
use namespace::autoclean;
use Smart::Args;
use DBI;
use Try::Tiny;

#################################################################
#################### PROTECTED METHODS ##########################
#################################################################

sub _get_attributes {
my $self = shift;

my $attr = {
RaiseError => 1,
FetchHashKeyName => 'NAME_uc',
AutoCommit => 0, # dbd::mysql workaround
PrintError => 0
};

if ( $self->attr ) {
foreach my $key ( keys %{ $self->attr } ) {
$attr->{$key} = $self->attr->{$key};
}
}

return $attr;
}

sub _hashkeys_to_lc {
args_pos

# required
my $self => 'Object',
my $href => 'HashRef';

my %tmp;
foreach my $key (%$href) {
$tmp{ lc($key) } = $href->{$key};
}

return \%tmp;
}

sub _read_netrc {
my $self = shift;

my $netrc_error;

try {
$self->_verbose( $self->host);
$self->_verbose($self->user) if $self->user;
$self->_verbose( my $out = `cat $ENV{HOME}/.netrc` );

my $netrc = Net::Netrc->lookup( $self->host, $self->user );
my ( $login, $password, $account ) = $netrc->lpa;
$self->_set_user($login) if !$self->user;
$self->_set_pass($password) if !$self->pass;
}
catch {

# still a chance a login will work with env vars so hold onto
# the error
$netrc_error = $_; # uncoverable statement
};

return $netrc_error;
}

sub _config_verbose_funcs {

# uncoverable subroutine
my $self = shift;

my $vf = $self->_verbose_funcs;

foreach my $func ( split /[,|:]/, $ENV{VERBOSE_FUNCS} ) {
$vf->{$func} = 1;
}

$self->_verbose_funcs($vf);
}

sub _show_create_table {
args_pos

# required
my $self => 'Object',
my $table => 'Str';

my $aref = $self->_dbh->selectall_arrayref("show create table $table");
my $show_create = $aref->[0]->[1];

return $show_create;
}

sub _get_fk_column {
my $self = shift;
my %a = @_;

my $table = $a{table} || confess "missing table arg";
my $column = $a{column} || confess "missing column arg";

my $fks_href = $self->get_fk_constraints($table);

foreach my $fk_name ( keys %$fks_href ) {

foreach my $fk_href ( @{ $fks_href->{$fk_name} } ) {

if ( $fk_href->{COLUMN_NAME} eq $column ) {
return $fk_href;
}
}
}

confess "couldn't find where $table.$column is part of an fk?";
}

sub _get_indexes_arrayref {
my $self = shift;
my $table = shift;

my $cache = '_index_cache';

if ( defined( $self->$cache->{$table} ) ) {
return $self->$cache->{$table}->data;
}

my $dbh = $self->_dbh;
my $sth = $dbh->prepare("show indexes in $table");
$sth->execute;

my $aref = [];
while ( my $href = $sth->fetchrow_hashref ) {
push( @$aref, {%$href} );
}

$self->$cache->{$table} = MySQL::Util::Data::Cache->new( data => $aref );
return $aref;
}

sub _fq {
args

# required
my $self => 'Object',
my $table => 'Str',

# optional
my $fq => { isa => 'Int', optional => 1, default => 1 },
my $schema => { isa => 'Str|Undef', optional => 1 };

if ($fq) {
if ( $table =~ /\w\.\w/ ) {
return $table;
}
elsif ($schema) {
return "$schema.$table";
}

return $self->_schema . ".$table";
}

if ( $table =~ /^(\w+)\.(\w+)$/ ) {
my $curr = $self->_schema;

confess "can't remove schema name from table name $table because we "
. "are not in the same db context (incoming fq table = $table, "
. "current schema = $curr"
if $curr ne $1;

return $2;
}

return $table;
}

sub _un_fq {
args_pos

# required
my $self => 'Object',
my $table => 'Str';

if ( $table =~ /^(\w+)\.(\w+)$/ ) {
return ( $1, $2 );
}

return ( $self->_schema, $table );
}

sub _get_fk_ddl {
my $self = shift;
my $table = shift;
my $fk = shift;

my $sql = "show create table $table";
my $sth = $self->_dbh->prepare($sql);
$sth->execute;

while ( my @a = $sth->fetchrow_array ) {

foreach my $data (@a) {
my @b = split( /\n/, $data );

foreach my $item (@b) {
if ( $item =~ /CONSTRAINT `$fk` FOREIGN KEY/ ) {
$item =~ s/^\s*//; # remove leading ws
$item =~ s/\s*//; # remove trailing ws
$item =~ s/,$//; # remove trailing comma
return "alter table $table add $item";
}
}
}
}
}

sub _column_exists {
my $self = shift;
my %a = @_;

my $table = $a{table} or confess "missing table arg";
my $column = $a{column} or confess "missing column arg";

my $desc_aref = $self->describe_table($table);

foreach my $col_href (@$desc_aref) {

if ( $col_href->{FIELD} eq $column ) {
return 1;
}
}

return 0;
}

sub _verbose {
my $caller_func = ( caller(1) )[3];
my $caller_line = ( caller(0) )[2];

args_pos

# required
my $self => 'Object',
my $msg => 'Str',

# optional
my $func_counter => { isa => 'Str', default => 0, optional => 1 };

my @caller_func = split( /\::/, $caller_func );
my $key = pop @caller_func;

# uncoverable branch true
if ( $self->_verbose_funcs->{$key} ) {
print STDERR "[VERBOSE] $caller_func ($caller_line) ";
print STDERR "[cnt=$func_counter]" if $func_counter;
print STDERR "\n";

chomp $msg;
foreach my $nl ( split /\n/, $msg ) {
print STDERR "\t$nl\n";
}
}
}

sub _verbose_sql {
args_pos

# required
my $self => 'Object',
my $sql => 'Str',

# optional
my $func_counter => { isa => 'Int', default => 0, optional => 1 };

my $caller_func = ( caller(1) )[3];
my $caller_line = ( caller(0) )[2];

my @caller_func = split( /\::/, $caller_func );
my $key = pop @caller_func;

if ( $self->_verbose_funcs->{$key} ) {
print STDERR "[VERBOSE] $caller_func ($caller_line) ";
print STDERR "[cnt=$func_counter]" if $func_counter;
print STDERR "\n";

$sql = SQL::Beautify->new( query => $sql )->beautify;
foreach my $l ( split /\n/, $sql ) {
print STDERR "\t$l\n";
}
}
}

sub _map_columns_to_fk_names {
args_pos

# required
my $self => 'Object',
my $table => 'Str';

# local variables
my $fk_href = $self->get_fk_constraints($table);
my %map;

foreach my $fk_name ( keys %$fk_href ) {

my $fk_aref = $fk_href->{$fk_name};

foreach my $col_href (@$fk_aref) {
my $col_name = $col_href->{COLUMN_NAME};
push( @{ $map{$col_name} }, $fk_name );
}
}

return %map;
}

1;

0 comments on commit 1cc3c08

Please sign in to comment.