File Coverage

blib/lib/MySQL/Partition.pm
Criterion Covered Total %
statement 56 82 68.2
branch 4 12 33.3
condition 3 9 33.3
subroutine 15 23 65.2
pod 3 5 60.0
total 81 131 61.8


line stmt bran cond sub pod time code
1             package MySQL::Partition;
2 2     2   23569 use 5.008001;
  2         7  
  2         83  
3 2     2   12 use strict;
  2         5  
  2         80  
4 2     2   21 use warnings;
  2         3  
  2         95  
5              
6             our $VERSION = "0.04";
7              
8 2     2   1149 use MySQL::Partition::Handle;
  2         6  
  2         50  
9              
10 2     2   2669 use Module::Load ();
  2         2350  
  2         74  
11             use Class::Accessor::Lite (
12 2         26 rw => [qw/dry_run verbose/],
13             ro => [qw/type dbh table expression/],
14 2     2   12 );
  2         4  
15              
16             sub dbname {
17 0     0 0 0 my $self = shift;
18 0 0 0     0 exists $self->{dbname} ? $self->{dbname} : $self->{dbname} ||= _get_dbname($self->dbh->{Name});
19             }
20              
21             sub new {
22 5     5 1 15463 my $class = shift;
23 5 50       21 die q[can't call new method directory in sub class] if $class ne __PACKAGE__;
24 5 50       44 my %args = @_ == 1 ? %{$_[0]} : @_;
  0         0  
25              
26 5         18 $args{type} = uc $args{type};
27              
28 5         22 my ($type) = split /\s+/, $args{type};
29 5         21 my $sub_class = __PACKAGE__ . '::Type::' . ucfirst( lc $type );
30 5         24 Module::Load::load($sub_class);
31 5         261 bless \%args, $sub_class;
32             }
33              
34             __PACKAGE__->_grow_methods(qw/create_partitions add_partitions drop_partitions/);
35              
36             sub retrieve_partitions {
37 0     0 1 0 my ($self, $table) = @_;
38              
39 0   0     0 my $parts = $self->{partitions} ||= do {
40 0         0 my @parts;
41 0         0 my $sth = $self->dbh->prepare('
42             SELECT
43             partition_name
44             FROM
45             information_schema.PARTITIONS
46             WHERE
47             table_name = ? AND
48             table_schema = ? AND
49             partition_method = ?
50             ORDER BY
51             partition_name
52             ');
53 0         0 $sth->execute($self->table, $self->dbname, $self->type);
54 0         0 while (my $row = $sth->fetchrow_arrayref) {
55 0 0       0 push @parts, $row->[0] if defined $row->[0];
56             }
57 0         0 \@parts;
58             };
59 0         0 @$parts;
60             }
61              
62             sub is_partitioned {
63 0     0 1 0 my $self = shift;
64 0 0       0 $self->retrieve_partitions ? 1 : ();
65             }
66              
67             sub has_partition {
68 0     0 0 0 my ($self, $partition_name) = @_;
69 0         0 grep {$_ eq $partition_name} $self->retrieve_partitions;
  0         0  
70             }
71              
72             sub _build_create_partitions_sql {
73 3     3   1176 my ($self, @args) = @_;
74              
75 3 100 100     30 if ($self->isa('MySQL::Partition::Type::Range') && $self->catch_all_partition_name) {
76 1         15 push @args, $self->catch_all_partition_name, 'MAXVALUE';
77             }
78 3         39 sprintf 'ALTER TABLE %s PARTITION BY %s (%s) (%s)',
79             $self->table, $self->type, $self->expression, $self->_build_partition_parts(@args);
80             }
81              
82             sub _build_add_partitions_sql {
83 2     2   8 my ($self, @args) = @_;
84              
85 2         7 sprintf 'ALTER TABLE %s ADD PARTITION (%s)', $self->table, $self->_build_partition_parts(@args);
86             }
87              
88             sub _build_partition_parts {
89 6     6   136 my ($self, @args) = @_;
90              
91 6         9 my @parts;
92 6         25 while (my ($partition_name, $partition_description) = splice @args, 0, 2) {
93 8         27 push @parts, $self->_build_partition_part($partition_name, $partition_description);
94             }
95 6         53 join ', ', @parts;
96             }
97              
98             sub _build_partition_part {
99 0     0   0 die 'this is abstruct method';
100             }
101              
102             sub _build_drop_partitions_sql {
103 1     1   4 my ($self, @partition_names) = @_;
104              
105 1         5 sprintf 'ALTER TABLE %s DROP PARTITION %s', $self->table, join(', ', @partition_names);
106             }
107              
108             sub _grow_methods {
109 3     3   12 my ($class, @methods) = @_;
110              
111 3         7 for my $method (@methods) {
112 8         18 my $prepare_method = "prepare_$method";
113 8         14 my $sql_builder_method = "_build_${method}_sql";
114              
115 2     2   1794 no strict 'refs';
  2         3  
  2         94  
116 8         47 *{$class . '::' . $prepare_method} = sub {
117 2     2   10 use strict 'refs';
  2         4  
  2         246  
118 0     0   0 my ($self, @args) = @_;
119 0         0 my $sql = $self->$sql_builder_method(@args);
120              
121 0         0 return MySQL::Partition::Handle->new(
122             statement => $sql,
123             mysql_partition => $self,
124             );
125 8         29 };
126 8         47 *{$class . '::' . $method} = sub {
127 2     2   11 use strict 'refs';
  2         3  
  2         347  
128 0     0     my ($self, @args) = @_;
129 0           $self->$prepare_method(@args)->execute;
130 8         26 };
131             }
132             }
133              
134             sub _get_dbname {
135 0     0     my $connected_db = shift;
136              
137             # XXX can't parse 'host=hoge;database=fuga'
138 0           my ($dbname) = $connected_db =~ m!^(?:(?:database|dbname)=)?([^;]*)!i;
139 0           $dbname;
140             }
141              
142             1;
143             __END__