File Coverage

blib/lib/MySQL/Partition.pm
Criterion Covered Total %
statement 57 83 68.6
branch 4 12 33.3
condition 3 9 33.3
subroutine 16 24 66.6
pod 3 5 60.0
total 83 133 62.4


line stmt bran cond sub pod time code
1             package MySQL::Partition;
2 3     3   127205 use 5.008001;
  3         11  
3 3     3   16 use strict;
  3         5  
  3         69  
4 3     3   24 use warnings;
  3         4  
  3         139  
5              
6             our $VERSION = "0.05";
7              
8 3     3   1529 use MySQL::Partition::Handle;
  3         8  
  3         79  
9              
10 3     3   2439 use Module::Load ();
  3         3181  
  3         108  
11             use Class::Accessor::Lite (
12 3         44 rw => [qw/dry_run verbose/],
13             ro => [qw/type dbh table expression/],
14 3     3   18 );
  3         5  
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 8400 my $class = shift;
23 5 50       19 die q[can't call new method directory in sub class] if $class ne __PACKAGE__;
24 5 50       38 my %args = @_ == 1 ? %{$_[0]} : @_;
  0         0  
25              
26 5         20 $args{type} = uc $args{type};
27              
28 5         23 my ($type) = split /\s+/, $args{type};
29 5         19 my $sub_class = __PACKAGE__ . '::Type::' . ucfirst( lc $type );
30 5         25 Module::Load::load($sub_class);
31 5         267 bless \%args, $sub_class;
32             }
33              
34             __PACKAGE__->_grow_methods(qw/create_partitions add_partitions drop_partitions truncate_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   1107 my ($self, @args) = @_;
74              
75 3 100 100     31 if ($self->isa('MySQL::Partition::Type::Range') && $self->catch_all_partition_name) {
76 1         14 push @args, $self->catch_all_partition_name, 'MAXVALUE';
77             }
78 3         41 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         8 sprintf 'ALTER TABLE %s ADD PARTITION (%s)', $self->table, $self->_build_partition_parts(@args);
86             }
87              
88             sub _build_partition_parts {
89 6     6   112 my ($self, @args) = @_;
90              
91 6         9 my @parts;
92 6         27 while (my ($partition_name, $partition_description) = splice @args, 0, 2) {
93 8         31 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   6 my ($self, @partition_names) = @_;
104              
105 1         5 sprintf 'ALTER TABLE %s DROP PARTITION %s', $self->table, join(', ', @partition_names);
106             }
107              
108             sub _build_truncate_partitions_sql {
109 1     1   444 my ($self, @partition_names) = @_;
110              
111 1         5 sprintf 'ALTER TABLE %s TRUNCATE PARTITION %s', $self->table, join(', ', @partition_names);
112             }
113              
114             sub _grow_methods {
115 4     4   16 my ($class, @methods) = @_;
116              
117 4         9 for my $method (@methods) {
118 14         35 my $prepare_method = "prepare_$method";
119 14         30 my $sql_builder_method = "_build_${method}_sql";
120              
121 3     3   2431 no strict 'refs';
  3         6  
  3         136  
122 14         75 *{$class . '::' . $prepare_method} = sub {
123 3     3   15 use strict 'refs';
  3         5  
  3         310  
124 0     0   0 my ($self, @args) = @_;
125 0         0 my $sql = $self->$sql_builder_method(@args);
126              
127 0         0 return MySQL::Partition::Handle->new(
128             statement => $sql,
129             mysql_partition => $self,
130             );
131 14         47 };
132 14         84 *{$class . '::' . $method} = sub {
133 3     3   22 use strict 'refs';
  3         5  
  3         474  
134 0     0     my ($self, @args) = @_;
135 0           $self->$prepare_method(@args)->execute;
136 14         47 };
137             }
138             }
139              
140             sub _get_dbname {
141 0     0     my $connected_db = shift;
142              
143             # XXX can't parse 'host=hoge;database=fuga'
144 0           my ($dbname) = $connected_db =~ m!^(?:(?:database|dbname)=)?([^;]*)!i;
145 0           $dbname;
146             }
147              
148             1;
149             __END__