/usr/share/haci/modules/MySQL/Database.pm is in haci 0.97c-3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | package MySQL::Database;
use strict;
use Carp qw(:DEFAULT cluck);
use MySQL::Utils qw(debug auth_args_string read_file);
use MySQL::Table;
sub new {
my $class = shift;
my %p = @_;
my $self = {};
bless $self, ref $class || $class;
debug(2, " constructing new MySQL::Database\n");
$self->parse_auth_args($p{auth});
if ($p{file}) {
$self->canonicalise_file($p{file});
}
elsif ($p{db}) {
$self->read_db($p{db});
}
else {
confess "MySQL::Database::new called without db or file params";
}
$self->_parse_defs();
return $self;
}
sub parse_auth_args {
my $self = shift;
my ($args) = @_;
my $string = auth_args_string(%$args);
debug(3, " auth args: $string\n");
$self->{_source}{auth} = $string;
}
sub canonicalise_file {
my $self = shift;
my ($file) = @_;
$self->{_source}{file} = $file;
debug(3, " fetching table defs from file $file\n");
# FIXME: option to avoid create-and-dump bit
# create a temporary database using defs from file ...
# hopefully the temp db is unique!
my $temp_db = sprintf "HaCi_mysqldiff_temp_%d_%d", time(), int(rand(999999));
debug(3, " creating temporary database $temp_db\n");
my $defs = join '', read_file($file);
die "$file contains dangerous command '$1'; aborting.\n"
if $defs =~ /;\s*(use|((drop|create)\s+database))\s/i;
my $args = $self->auth_args;
open(MYSQL, "| mysql $args")
or die "Couldn't execute `mysql$args': $!\n";
print MYSQL <<EOF;
CREATE DATABASE $temp_db;
USE $temp_db;
EOF
print MYSQL $defs;
close(MYSQL);
# ... and then retrieve defs from mysqldump. Hence we've used
# MySQL to massage the defs file into canonical form.
$self->_get_defs($temp_db);
debug(3, " dropping temporary database $temp_db\n");
open(MYSQL, "| mysql $args")
or die "Couldn't execute `mysql$args': $!\n";
print MYSQL "DROP DATABASE $temp_db;\n";
close(MYSQL);
}
sub read_db {
my $self = shift;
my ($db) = @_;
$self->{_source}{db} = $db;
debug(3, " fetching table defs from db $db\n");
$self->_get_defs($db);
}
sub auth_args {
my $self = shift;
return $self->{_source}{auth};
}
sub _get_defs {
my $self = shift;
my ($db) = @_;
my $args = $self->auth_args;
open(MYSQLDUMP, "mysqldump -d $args $db |")
or die "Couldn't read ${db}'s table defs via mysqldump: $!\n";
debug(3, " running mysqldump -d $args $db\n");
my $defs = $self->{_defs} = [ <MYSQLDUMP> ];
close(MYSQLDUMP);
}
sub _parse_defs {
my $self = shift;
return if $self->{_tables};
debug(3, " parsing table defs\n");
my $defs = join '', grep ! /^\s*(\#|--)/, @{$self->{_defs}};
my @tables = split /(?=^\s*create\s+table\s+)/im, $defs;
$self->{_tables} = [];
foreach my $table (@tables) {
next unless $table =~ /create\s+table/i;
my $obj = MySQL::Table->new(source => $self->{_source},
def => $table);
push @{$self->{_tables}}, $obj;
$self->{_by_name}{$obj->name()} = $obj;
}
}
sub name {
my $self = shift;
return $self->{_source}{file} || $self->{_source}{db};
}
sub tables {
return @{$_[0]->{_tables}};
}
sub table_by_name {
my $self = shift;
my ($name) = @_;
return $self->{_by_name}{$name};
}
sub source_type {
my $self = shift;
return 'file' if $self->{_source}{file};
return 'db' if $self->{_source}{db};
}
sub summary {
my $self = shift;
if ($self->{_source}{file}) {
return "file: " . $self->{_source}{file};
}
elsif ($self->{_source}{db}) {
my $args = $self->{_source}{auth};
$args =~ tr/-//d;
$args =~ s/\bpassword=\S+//;
$args =~ s/^\s*(.*?)\s*$/$1/;
my $summary = " db: " . $self->{_source}{db};
$summary .= " ($args)" if $args;
return $summary;
}
else {
return 'unknown';
}
}
1;
|