File Coverage

blib/lib/Aniki.pm
Criterion Covered Total %
statement 315 394 79.9
branch 108 170 63.5
condition 25 39 64.1
subroutine 70 90 77.7
pod 28 44 63.6
total 546 737 74.0


line stmt bran cond sub pod time code
1             package Aniki;
2 27     27   2044270 use 5.014002;
  27         118  
3              
4 27     27   9382 use namespace::autoclean;
  27         361360  
  27         143  
5 27     27   2599 use Mouse v2.4.5;
  27         20934  
  27         214  
6              
7 27     27   24599 use Module::Load ();
  27         24728  
  27         643  
8 27     27   9696 use Aniki::Filter;
  27         2801  
  27         930  
9 27     27   10245 use Aniki::Handler;
  27         3016  
  27         1006  
10 27     27   11951 use Aniki::Row;
  27         2336  
  27         860  
11 27     27   10681 use Aniki::Result::Collection;
  27         1966  
  27         891  
12 27     27   9696 use Aniki::Schema;
  27         2116  
  27         972  
13 27     27   11654 use Aniki::QueryBuilder;
  27         121  
  27         942  
14 27     27   10260 use Aniki::QueryBuilder::Canonical;
  27         94  
  27         1422  
15              
16             our $VERSION = '1.04_02';
17              
18 27     27   10558 use SQL::Maker::SQLType qw/sql_type/;
  27         9122  
  27         1800  
19 27     27   12310 use Class::Inspector;
  27         64369  
  27         975  
20 27     27   205 use Carp qw/croak confess/;
  27         62  
  27         1590  
21 27     27   181 use Try::Tiny;
  27         73  
  27         1428  
22 27     27   170 use Scalar::Util qw/blessed/;
  27         70  
  27         1188  
23 27     27   11426 use String::CamelCase qw/camelize/;
  27         12171  
  27         1521  
24 27     27   10428 use SQL::NamedPlaceholder qw/bind_named/;
  27         40183  
  27         190  
25              
26       0     sub _noop {}
27              
28             around BUILDARGS => sub {
29             my $orig = shift;
30             my $class = shift;
31             my %args = (@_ == 1 && ref $_[0] eq 'HASH') ? %{$_[0]} : @_;
32              
33             if (not exists $args{handler}) {
34             my $connect_info = delete $args{connect_info} or confess 'Attribute (connect_info) is required';
35             my $on_connect_do = delete $args{on_connect_do};
36             my $on_disconnect_do = delete $args{on_disconnect_do};
37             my $trace_query = delete $args{trace_query} || 0;
38             my $trace_ignore_if = delete $args{trace_ignore_if} || \&_noop;
39             $args{handler} = $class->handler_class->new(
40             connect_info => $connect_info,
41             on_connect_do => $on_connect_do,
42             on_disconnect_do => $on_disconnect_do,
43             trace_query => $trace_query,
44             trace_ignore_if => $trace_ignore_if,
45             );
46             }
47              
48             return $class->$orig(\%args);
49             };
50              
51             has handler => (
52             is => 'ro',
53             required => 1,
54             );
55              
56             has suppress_row_objects => (
57             is => 'rw',
58             default => 0,
59             );
60              
61             has suppress_result_objects => (
62             is => 'rw',
63             default => 0,
64             );
65              
66             sub _database2driver {
67 56     56   841 my ($class, $database) = @_;
68 56         243 state $map = {
69             MySQL => 'mysql',
70             PostgreSQL => 'Pg',
71             SQLite => 'SQLite',
72             Oracle => 'Oracle',
73             DB2 => 'DB2',
74             };
75 56         167 return $map->{$database};
76             }
77              
78 0     0 1 0 sub schema { croak 'This is abstract method. (required to call setup method before call it)' }
79 0     0 1 0 sub query_builder { croak 'This is abstract method. (required to call setup method before call it)' }
80 0     0 1 0 sub filter { croak 'This is abstract method. (required to call setup method before call it)' }
81 0     0 0 0 sub last_insert_id { croak 'This is abstract method. (required to call setup method before call it)' }
82 0     0 1 0 sub root_row_class { croak 'This is abstract method. (required to call setup method before call it)' }
83 0     0 1 0 sub guess_row_class { croak 'This is abstract method. (required to call setup method before call it)' }
84 0     0 1 0 sub root_result_class { croak 'This is abstract method. (required to call setup method before call it)' }
85 0     0 1 0 sub guess_result_class { croak 'This is abstract method. (required to call setup method before call it)' }
86 24     24 0 333 sub handler_class { 'Aniki::Handler' }
87              
88             # You can override this method on your application.
89 403     403 1 1517 sub use_prepare_cached { 1 }
90 28     28 1 473 sub use_strict_query_builder { 1 }
91              
92             sub setup {
93 28     28 1 92437 my ($class, %args) = @_;
94              
95             # schema
96 28 50       153 if (my $schema_class = $args{schema}) {
97 28 50       284 Module::Load::load($schema_class) unless Class::Inspector->loaded($schema_class);
98              
99 28         210665 my $schema = Aniki::Schema->new(schema_class => $schema_class);
100 28     358   420 $class->meta->add_method(schema => sub { $schema });
  358     358   54474  
        8      
        8      
101             }
102             else {
103 0         0 croak 'schema option is required.';
104             }
105              
106             # filter
107 28 50       1127 if (my $filter_class = $args{filter}) {
108 28 100       315 Module::Load::load($filter_class) unless Class::Inspector->loaded($filter_class);
109              
110 28         789 my $filter = $filter_class->instance();
111 28     375   188 $class->meta->add_method(filter => sub { $filter });
  375         1626  
112             }
113             else {
114 0         0 my $filter = Aniki::Filter->new;
115 0     375   0 $class->meta->add_method(filter => sub { $filter });
  0         0  
116             }
117              
118             # handler
119 28 50       753 if (my $handler_class = $args{handler}) {
120 0 0       0 Module::Load::load($handler_class) unless Class::Inspector->loaded($handler_class);
121 0     0   0 $class->meta->add_method(handler_class => sub { $handler_class });
  0         0  
122             }
123              
124             # last_insert_id
125             {
126 28         113 my $driver = lc $class->_database2driver($class->schema->database);
127 28 50       483 my $method = $class->can("_fetch_last_insert_id_from_$driver") or Carp::croak "Don't know how to get last insert id for $driver";
128 28         141 $class->meta->add_method(last_insert_id => $method);
129             }
130              
131             # query_builder
132             {
133 28 50       66 my $query_builder_class = $class->use_prepare_cached ? 'Aniki::QueryBuilder::Canonical' : 'Aniki::QueryBuilder';
  28         187  
134 28 50       121 if ($args{query_builder}) {
135 0 0       0 Module::Load::load($args{query_builder}) unless Class::Inspector->loaded($args{query_builder});
136 0         0 $query_builder_class = $args{query_builder};
137             }
138 28         107 my $driver = $class->_database2driver($class->schema->database);
139 28         229 my $query_builder = $query_builder_class->new(driver => $driver, strict => $class->use_strict_query_builder);
140 28     174   961 $class->meta->add_method(query_builder => sub { $query_builder });
  174         865  
141             }
142              
143             # row
144             {
145 28         553 my $root_row_class = 'Aniki::Row';
  28         75  
146 28     174   127 my $guess_row_class = sub { $root_row_class };
  0         0  
147 28 50       134 if ($args{row}) {
148 28 100       202 Module::Load::load($args{row}) unless Class::Inspector->loaded($args{row});
149 28         23855 $root_row_class = $args{row};
150              
151 28         71 my %table_row_class;
152             $guess_row_class = sub {
153 85     85   217 my $table_name = $_[1];
154             return $table_row_class{$table_name} //= try {
155 25         1732 my $table_row_class = sprintf '%s::%s', $root_row_class, camelize($table_name);
156 25         609 Module::Load::load($table_row_class);
157 20         20425 return $table_row_class;
158             } catch {
159 5 50       2298 die $_ unless /\A\QCan't locate/imo;
160 5         89 return $root_row_class;
161 85   66     856 };
162 28         171 };
163             }
164 28     85   234 $class->meta->add_method(root_row_class => sub { $root_row_class });
  0         0  
165 28         628 $class->meta->add_method(guess_row_class => $guess_row_class);
166             }
167              
168             # result
169             {
170 28         619 my $root_result_class = 'Aniki::Result::Collection';
  28         461  
  28         76  
171 28     77   119 my $guess_result_class = sub { $root_result_class };
  77         223  
172 28 50       142 if ($args{result}) {
173 0 0       0 Module::Load::load($args{result}) unless Class::Inspector->loaded($args{result});
174 0         0 $root_result_class = $args{result};
175              
176 0         0 my %table_result_class;
177             $guess_result_class = sub {
178 0     77   0 my $table_name = $_[1];
179             return $table_result_class{$table_name} //= try {
180 0         0 my $table_result_class = sprintf '%s::%s', $root_result_class, camelize($table_name);
181 0         0 Module::Load::load($table_result_class);
182 0         0 return $table_result_class;
183             } catch {
184 0 0       0 die $_ unless /\A\QCan't locate/imo;
185 0         0 return $root_result_class;
186 0   0     0 };
187 0         0 };
188             }
189              
190 28     25   163 $class->meta->add_method(root_result_class => sub { $root_result_class });
  0         0  
191 28         612 $class->meta->add_method(guess_result_class => $guess_result_class);
192             }
193             }
194              
195             sub preload_all_row_classes {
196 0     5 1 0 my $class = shift;
197 0         0 for my $table ($class->schema->get_tables) {
198 0         0 $class->guess_row_class($table->name);
199             }
200             }
201              
202             sub preload_all_result_classes {
203 0     0 1 0 my $class = shift;
204 0         0 for my $table ($class->schema->get_tables) {
205 0         0 $class->guess_result_class($table->name);
206             }
207             }
208              
209             sub dbh {
210 433     433 1 841 my $self = shift;
211             # (for mysql)
212             # XXX: `DBIx::Handler#dbh` send a ping to mysql.
213             # But, It removes `$dbh->{mysql_insertid}`.
214 433 100       1790 return $self->{_context} if exists $self->{_context};
215 338         1258 return $self->handler->dbh;
216             }
217              
218             sub insert {
219 66     66 1 342 my ($self, $table_name, $row, $opt) = @_;
220 66 100       397 $row = $self->filter_on_insert($table_name, $row) unless $opt->{no_filter};
221              
222 66         219 my $table = $self->schema->get_table($table_name);
223 66 50       360 $row = $self->_bind_sql_type_to_args($table, $row) if $table;
224              
225 66         278 my ($sql, @bind) = $self->query_builder->insert($table_name, $row, $opt);
226 66         11146 $self->execute($sql, @bind);
227 66         421 return;
228             }
229              
230             sub filter_on_insert {
231 99     99 0 233 my ($self, $table_name, $row) = @_;
232 99         292 $row = $self->filter->apply_trigger(insert => $table_name, $row);
233 99         255 return $self->filter->deflate_row($table_name, $row);
234             }
235              
236             sub update {
237 13     13 1 1727 my ($self, $table_name, $set, $where, $opt) = @_;
238              
239             # migrate for ($self, $row, $set, $opt)
240 13 100 66     141 if (blessed $_[1] && $_[1]->isa('Aniki::Row')) {
241 11         28 my $row = $_[1];
242 11         43 $table_name = $row->table_name;
243 11         23 $set = $_[2];
244 11         67 $where = $self->_where_row_cond($row->table, $row->row_data);
245 11         26 $opt = $_[3];
246             }
247              
248 13 100 100     572 croak '(Aniki#update) `set` is required for update ("SET" parameter)' unless $set && %$set;
249 9 100       109 croak '(Aniki#update) `where` condition must be a reference' unless ref $where;
250              
251 8 100       41 $set = $self->filter_on_update($table_name, $set) unless $opt->{no_filter};
252              
253 8         38 my $table = $self->schema->get_table($table_name);
254 8 50       33 if ($table) {
255 8         44 $set = $self->_bind_sql_type_to_args($table, $set);
256 8         32 $where = $self->_bind_sql_type_to_args($table, $where);
257             }
258              
259 8         38 my ($sql, @bind) = $self->query_builder->update($table_name, $set, $where);
260 8         2432 return $self->execute($sql, @bind)->rows;
261             }
262              
263             sub update_and_fetch_row {
264 5     5 1 8937 my ($self, $row, $set) = @_;
265 5 100 66     185 croak '(Aniki#update_and_fetch_row) condition must be a Aniki::Row object.'
266             unless blessed $row && $row->isa('Aniki::Row');
267              
268 4         19 my $emulated_row_data = $self->_update_and_emulate_row_data($row, $set);
269              
270 3         12 my $where = $self->_where_row_cond($row->table, $emulated_row_data);
271 3         18 return $self->select($row->table_name, $where, { limit => 1, suppress_result_objects => 1 })->[0];
272             }
273              
274             sub update_and_emulate_row {
275 5     5 1 14165 my ($self, $row, $set) = @_;
276 5 100 66     298 croak '(Aniki#update_and_emulate_row) condition must be a Aniki::Row object.' unless blessed $row && $row->isa('Aniki::Row');
277              
278 4         29 my $emulated_row_data = $self->_update_and_emulate_row_data($row, $set);
279 3 100       25 return $emulated_row_data if $self->suppress_row_objects;
280              
281 2         15 return $self->guess_row_class($row->table_name)->new(
282             table_name => $row->table_name,
283             handler => $self,
284             row_data => $emulated_row_data,
285             );
286             }
287              
288             sub _update_and_emulate_row_data {
289 8     8   26 my ($self, $row, $set) = @_;
290 8         71 $set = $self->filter_on_update($row->table_name, $set);
291 8         55 $self->update($row, $set, { no_filter => 1 });
292             return {
293 6         26 %{ $row->row_data },
  6         70  
294             %$set,
295             };
296             }
297              
298             sub delete :method {
299 4     4 1 29 my $self = shift;
300 4 100 66     31 if (blessed $_[0] && $_[0]->isa('Aniki::Row')) {
301 1         10 return $self->delete($_[0]->table_name, $self->_where_row_cond($_[0]->table, $_[0]->row_data), @_);
302             }
303             else {
304 3         8 my ($table_name, $where, $opt) = @_;
305 3 100       222 croak '(Aniki#delete) `where` condition must be a reference' unless ref $where;
306              
307 2         6 my $table = $self->schema->get_table($table_name);
308 2 50       8 if ($table) {
309 2         6 $where = $self->_bind_sql_type_to_args($table, $where);
310             }
311              
312 2         7 my ($sql, @bind) = $self->query_builder->delete($table_name, $where, $opt);
313 2         328 return $self->execute($sql, @bind)->rows;
314             }
315             }
316              
317             sub filter_on_update {
318 10     10 0 37 my ($self, $table_name, $row) = @_;
319 10         42 $row = $self->filter->apply_trigger(update => $table_name, $row);
320 10         41 return $self->filter->deflate_row($table_name, $row);
321             }
322              
323             sub insert_and_fetch_id {
324 20     20 1 3052 my $self = shift;
325              
326 20         64 local $self->{_context} = $self->dbh;
327 20         1008 $self->insert(@_);
328 20 50       94 return unless defined wantarray;
329              
330 20         55 my $table_name = shift;
331 20         84 return $self->last_insert_id($table_name);
332             }
333              
334             sub insert_and_fetch_row {
335 6     6 1 143 my $self = shift;
336 6         19 my $table_name = shift;
337 6         14 my $row_data = shift;
338              
339 6 50       27 my $table = $self->schema->get_table($table_name) or croak "$table_name is not defined in schema.";
340              
341 6         27 local $self->{_context} = $self->dbh;
342              
343 6         242 $self->insert($table_name, $row_data, @_);
344 6 50       30 return unless defined wantarray;
345              
346 6         52 my $row = $self->select($table_name, $self->_where_row_cond($table, $row_data), { limit => 1, suppress_result_objects => 1 })->[0];
347 6 50       54 return $row if $self->suppress_row_objects;
348              
349 6         60 $row->is_new(1);
350 6         29 return $row;
351             }
352              
353             sub insert_and_emulate_row {
354 2     2 1 30 my ($self, $table_name, $row, $opt) = @_;
355              
356 2 50       7 my $table = $self->schema->get_table($table_name) or croak "$table_name is not defined in schema.";
357              
358 2         6 local $self->{_context} = $self->dbh;
359              
360 2 50       79 $row = $self->filter_on_insert($table_name, $row) unless $opt->{no_filter};
361              
362 2         14 $self->insert($table_name, $row, { %$opt, no_filter => 1 });
363 2 50       7 return unless defined wantarray;
364              
365 2         5 my %row_data;
366 2         11 for my $field ($table->get_fields) {
367 10 100       45 if (exists $row->{$field->name}) {
    100          
    50          
368 4         14 $row_data{$field->name} = $row->{$field->name};
369             }
370             elsif (defined(my $default_value = $field->default_value)) {
371 4 50       16 $row_data{$field->name} = ref $default_value eq 'SCALAR' ? undef : $default_value;
372             }
373             elsif ($field->is_auto_increment) {
374 2         8 $row_data{$field->name} = $self->last_insert_id($table_name, $field->name);
375             }
376             else {
377 0         0 $row_data{$field->name} = undef;
378             }
379             }
380 2 50       11 return \%row_data if $self->suppress_row_objects;
381 2         7 return $self->guess_row_class($table_name)->new(
382             table_name => $table_name,
383             handler => $self,
384             row_data => \%row_data,
385             is_new => 1,
386             );
387             }
388              
389             sub insert_on_duplicate {
390 0     0 1 0 my ($self, $table_name, $insert, $update) = @_;
391 0 0       0 if ($self->schema->database ne 'MySQL') {
392 0         0 Carp::croak 'Cannot use insert_on_duplicate (unsupported without MySQL)';
393             }
394              
395 0         0 $insert = $self->filter_on_insert($table_name, $insert);
396 0         0 $update = $self->filter_on_update($table_name, $update);
397              
398 0         0 my $table = $self->schema->get_table($table_name);
399 0 0       0 if ($table) {
400 0         0 $insert = $self->_bind_sql_type_to_args($table, $insert);
401 0         0 $update = $self->_bind_sql_type_to_args($table, $update);
402             }
403              
404 0         0 my ($sql, @bind) = $self->query_builder->insert_on_duplicate($table_name, $insert, $update);
405 0         0 $self->execute($sql, @bind);
406 0         0 return;
407             }
408              
409             sub insert_multi {
410 10     10 1 14361 my ($self, $table_name, $values, $opts) = @_;
411 10 100       43 return unless @$values;
412              
413 9 50       40 $opts = defined $opts ? {%$opts} : {};
414              
415 9         26 my @values = map { $self->filter_on_insert($table_name, $_) } @$values;
  33         114  
416 9 50       42 if (exists $opts->{update}) {
417 0 0       0 if ($self->schema->database ne 'MySQL') {
418 0         0 Carp::croak 'Cannot use insert_multi with update option (unsupported without MySQL)';
419             }
420 0         0 $opts->{update} = $self->filter_on_update($table_name, $opts->{update});
421             }
422              
423 9         60 my $table = $self->schema->get_table($table_name);
424 9 50       56 if ($table) {
425 9         73 $_ = $self->_bind_sql_type_to_args($table, $_) for @values;
426 9 50       41 if (exists $opts->{update}) {
427 0         0 $opts->{update} = $self->_bind_sql_type_to_args($table, $opts->{update});
428             }
429             }
430              
431 9 50       30 if ($self->schema->database eq 'MySQL') {
432 0         0 my ($sql, @bind) = $self->query_builder->insert_multi($table_name, \@values, $opts);
433 0         0 $self->execute($sql, @bind);
434             }
435             else {
436             $self->txn(sub {
437 9     9   1691 local $self->{_context} = shift;
438 9         71 $self->insert($table_name, $_, $opts) for @values;
439 9         251 });
440             }
441 9         821 return;
442             }
443              
444             sub _where_row_cond {
445 24     24   69 my ($self, $table, $row_data) = @_;
446 24 50       195 die "@{[ $table->name ]} doesn't have primary key." unless $table->primary_key;
  0         0  
447              
448             # fetch by primary key
449 24         48 my %where;
450 24         155 for my $pk ($table->primary_key->fields) {
451 24 50       243 $where{$pk->name} = exists $row_data->{$pk->name} ? $row_data->{$pk->name}
    100          
452             : $pk->is_auto_increment ? $self->last_insert_id($table->name, $pk->name)
453             : undef
454             ;
455             }
456              
457 24         115 return \%where;
458             }
459              
460             my $WILDCARD_COLUMNS = ['*'];
461              
462             sub select :method {
463 74     74 1 30775 my ($self, $table_name, $where, $opt) = @_;
464 74   50     267 $where //= {};
465 74   100     240 $opt //= {};
466              
467 74 50       224 croak '(Aniki#select) `where` condition must be a reference.' unless ref $where;
468              
469 74         228 my $table = $self->schema->get_table($table_name);
470              
471             my $columns = exists $opt->{columns} ? $opt->{columns}
472 74 50       493 : defined $table ? $table->field_names
    50          
473             : $WILDCARD_COLUMNS;
474              
475 74 50       361 $where = $self->_bind_sql_type_to_args($table, $where) if defined $table;
476              
477 74         189 local $Carp::CarpLevel = $Carp::CarpLevel + 1;
478 74         227 my ($sql, @bind) = $self->query_builder->select($table_name, $columns, $where, $opt);
479 74         44505 return $self->select_by_sql($sql, \@bind, {
480             %$opt,
481             table_name => $table_name,
482             columns => $columns,
483             });
484             }
485              
486             sub fetch_and_attach_relay_data {
487 31     31 0 81 my ($self, $table_name, $prefetch, $rows) = @_;
488 31 50       93 return unless @$rows;
489              
490 31 50       100 $prefetch = [$prefetch] if ref $prefetch eq 'HASH';
491              
492 31         87 my $relationships = $self->schema->get_table($table_name)->get_relationships;
493 31         87 for my $key (@$prefetch) {
494 30 100 66     168 if (ref $key && ref $key eq 'HASH') {
495 5         16 my %prefetch = %$key;
496 5         15 for my $key (keys %prefetch) {
497 4         17 $self->_fetch_and_attach_relay_data($relationships, $rows, $key, $prefetch{$key});
498             }
499             }
500             else {
501 25         103 $self->_fetch_and_attach_relay_data($relationships, $rows, $key, []);
502             }
503             }
504             }
505              
506             sub _fetch_and_attach_relay_data {
507 29     29   78 my ($self, $relationships, $rows, $key, $prefetch) = @_;
508 29         107 my $relationship = $relationships->get($key);
509 29 50       84 unless ($relationship) {
510 0         0 croak "'$key' is not defined as relationship. (maybe possible typo?)";
511             }
512 29         174 $relationship->fetcher->execute($self, $rows, $prefetch);
513             }
514              
515             sub select_named {
516 3     3 1 10 my ($self, $sql, $bind, $opt) = @_;
517 3         17 return $self->select_by_sql(bind_named($sql, $bind), $opt);
518             }
519              
520             sub select_by_sql {
521 80     80 1 321 my ($self, $sql, $bind, $opt) = @_;
522 80   50     263 $opt //= {};
523              
524 80 100       276 local $self->{suppress_row_objects} = 1 if $opt->{suppress_row_objects};
525 80 100       255 local $self->{suppress_result_objects} = 1 if $opt->{suppress_result_objects};
526              
527 80 100       308 my $table_name = exists $opt->{table_name} ? $opt->{table_name} : $self->_guess_table_name($sql);
528 80 100       239 my $columns = exists $opt->{columns} ? $opt->{columns} : undef;
529 80 100       232 my $prefetch = exists $opt->{prefetch} ? $opt->{prefetch} : [];
530 80 100       284 $prefetch = [$prefetch] if ref $prefetch eq 'HASH';
531              
532 80   66     346 my $prefetch_enabled_fg = @$prefetch && !$self->suppress_row_objects && defined wantarray;
533 80 100       240 if ($prefetch_enabled_fg) {
534 8 100       13 my $txn; $txn = $self->txn_scope(caller => [caller]) unless $self->in_txn;
  8         30  
535              
536 8         628 my $sth = $self->execute($sql, @$bind);
537 8         35 my $result = $self->_fetch_by_sth($sth, $table_name, $columns);
538 8         41 $self->fetch_and_attach_relay_data($table_name, $prefetch, $result->rows);
539              
540 8 100       37 $txn->rollback if defined $txn; ## for read only
541 8         240 return $result;
542             }
543              
544 72         311 my $sth = $self->execute($sql, @$bind);
545              
546             # When the return value is never used, should not create object
547             # case example: use `FOR UPDATE` query for global locking
548 72 50       275 unless (defined wantarray) {
549 0         0 $sth->finish();
550 0         0 return;
551             }
552              
553 72         337 return $self->_fetch_by_sth($sth, $table_name, $columns);
554             }
555              
556             sub _fetch_by_sth {
557 80     80   240 my ($self, $sth, $table_name, $columns) = @_;
558 80   66     315 $columns //= $sth->{NAME};
559 80 50       292 $columns = $sth->{NAME} if $columns == $WILDCARD_COLUMNS;
560              
561 80         180 my @rows;
562              
563             my %row;
564 80         728 $sth->bind_columns(\@row{@$columns});
565 80         4378 push @rows => {%row} while $sth->fetch;
566 80         379 $sth->finish;
567              
568 80 100       454 if ($self->suppress_result_objects) {
569 11 100       88 return \@rows if $self->suppress_row_objects;
570              
571 9         36 my $row_class = $self->guess_row_class($table_name);
572             return [
573             map {
574 9         141 $row_class->new(
  9         150  
575             table_name => $table_name,
576             handler => $self,
577             row_data => $_,
578             )
579             } @rows
580             ];
581             }
582              
583 69         252 my $result_class = $self->guess_result_class($table_name);
584 69         1168 return $result_class->new(
585             table_name => $table_name,
586             handler => $self,
587             row_datas => \@rows,
588             suppress_row_objects => $self->suppress_row_objects,
589             );
590             }
591              
592             sub execute {
593 375     375 0 2174 my ($self, $sql, @bind) = @_;
594 375         2018 $sql = $self->handler->trace_query_set_comment($sql);
595              
596 375 50       5050 my $sth = $self->use_prepare_cached ? $self->dbh->prepare_cached($sql) : $self->dbh->prepare($sql);
597 375         90891 $self->_bind_to_sth($sth, \@bind);
598 375         1839 eval {
599 375         19434 $sth->execute();
600             };
601 375 50       1540 if ($@) {
602 0         0 $self->handle_error($sql, \@bind, $@);
603             }
604              
605 375         1471 return $sth;
606             }
607              
608             sub _bind_sql_type_to_args {
609 191     191   441 my ($self, $table, $args) = @_;
610              
611 191         321 my %bind_args;
612 191         323 for my $col (keys %{$args}) {
  191         550  
613             # if $args->{$col} is a ref, it is scalar ref or already
614             # sql type bined parameter. so ignored.
615 214 100       1284 if (ref $args->{$col}) {
    50          
616 83         204 $bind_args{$col} = $args->{$col};
617             }
618             elsif (my $field = $table->get_field($col)) {
619 131         679 $bind_args{$col} = sql_type(\$args->{$col}, $field->sql_data_type);
620             }
621             else {
622 0         0 $bind_args{$col} = $args->{$col};
623             }
624             }
625              
626 191         2136 return \%bind_args;
627             }
628              
629             sub _bind_to_sth {
630 375     375   917 my ($self, $sth, $bind) = @_;
631 375         1312 for my $i (keys @$bind) {
632 193         805 my $v = $bind->[$i];
633 193 100 66     1378 if (blessed $v && $v->isa('SQL::Maker::SQLType')) {
634 131         290 $sth->bind_param($i + 1, ${$v->value_ref}, $v->type);
  131         416  
635             } else {
636 62         336 $sth->bind_param($i + 1, $v);
637             }
638             }
639             }
640              
641             has _row_class_cache => (
642             is => 'rw',
643             default => sub {
644             my $self = shift;
645             my %cache = map { $_->name => undef } $self->schema->get_tables();
646             return \%cache;
647             },
648             );
649              
650             has _result_class_cache => (
651             is => 'rw',
652             default => sub {
653             my $self = shift;
654             my %cache = map { $_->name => undef } $self->schema->get_tables();
655             return \%cache;
656             },
657             );
658              
659             sub new_row_from_hashref {
660 1     1 0 25 my ($self, $table_name, $row_data) = @_;
661 1 50       8 return $row_data if $self->suppress_row_objects;
662              
663 1         4 my $row_class = $self->guess_row_class($table_name);
664 1         50 return $row_class->new(
665             table_name => $table_name,
666             handler => $self,
667             row_data => $row_data,
668             );
669             }
670              
671             sub new_collection_from_arrayref {
672 2     2 0 3500 my ($self, $table_name, $row_datas) = @_;
673 2 50       12 return $row_datas if $self->suppress_result_objects;
674              
675 2         7 my $result_class = $self->guess_result_class($table_name);
676 2         29 return $result_class->new(
677             table_name => $table_name,
678             handler => $self,
679             row_datas => $row_datas,
680             suppress_row_objects => $self->suppress_row_objects,
681             );
682             }
683              
684             sub _guess_table_name {
685 6     6   14 my ($self, $sql) = @_;
686 6 50       62 return $2 if $sql =~ /\sfrom\s+(["`]?)([\w]+)\1\s*/sio;
687 0         0 return;
688             }
689              
690             # --------------------------------------------------
691             # last_insert_id
692 0     0   0 sub _fetch_last_insert_id_from_mysql { shift->dbh->{mysql_insertid} }
693             sub _fetch_last_insert_id_from_pg {
694 0     0   0 my ($self, $table_name, $column) = @_;
695 0         0 my $dbh = $self->dbh;
696 0 0       0 return $dbh->last_insert_id(undef, undef, $table_name, undef) unless defined $column;
697              
698 0         0 my $sequence = join '_', $table_name, $column, 'seq';
699 0         0 return $dbh->last_insert_id(undef, undef, undef, undef, { sequence => $sequence });
700             }
701 28     28   95 sub _fetch_last_insert_id_from_sqlite { shift->dbh->sqlite_last_insert_rowid }
702 0     0   0 sub _fetch_last_insert_id_from_oracle { undef } ## XXX: Oracle haven't implement AUTO INCREMENT
703              
704             # --------------------------------------------------
705             # for transaction
706 1     1 1 14 sub txn_manager { shift->handler->txn_manager }
707 9     9 0 92 sub txn { shift->handler->txn(@_) }
708 8     8 0 48 sub in_txn { shift->handler->in_txn(@_) }
709 5     5 0 289 sub txn_scope { shift->handler->txn_scope(@_) }
710 0     0 0 0 sub txn_begin { shift->handler->txn_begin(@_) }
711 0     0 0 0 sub txn_rollback { shift->handler->txn_rollback(@_) }
712 0     0 0 0 sub txn_commit { shift->handler->txn_commit(@_) }
713              
714             # --------------------------------------------------
715             # error handling
716             sub handle_error {
717 0     0 0 0 my ($self, $sql, $bind, $e) = @_;
718 0         0 require Data::Dumper;
719              
720 0         0 local $Data::Dumper::Maxdepth = 2;
721 0         0 $sql =~ s/\n/\n /gm;
722 0         0 croak sprintf $self->exception_template, $e, $sql, Data::Dumper::Dumper($bind);
723             }
724              
725             sub exception_template {
726 0     0 0 0 return <<'__TRACE__';
727             @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
728             @@@@@ Aniki 's Exception @@@@@
729             Reason : %s
730             SQL : %s
731             BIND : %s
732             @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
733             __TRACE__
734             }
735              
736             sub DEMOLISH {
737 24     24 1 11911 my $self = shift;
738 24 50       516 $self->handler->disconnect() if $self->handler;
739             }
740              
741             __PACKAGE__->meta->make_immutable();
742             __END__
743              
744             =encoding utf-8
745              
746             =head1 NAME
747              
748             Aniki - The ORM as our great brother.
749              
750             =head1 SYNOPSIS
751              
752             use 5.014002;
753             package MyProj::DB::Schema {
754             use DBIx::Schema::DSL;
755              
756             create_table 'module' => columns {
757             integer 'id', primary_key, auto_increment;
758             varchar 'name';
759             integer 'author_id';
760              
761             add_index 'author_id_idx' => ['author_id'];
762              
763             belongs_to 'author';
764             };
765              
766             create_table 'author' => columns {
767             integer 'id', primary_key, auto_increment;
768             varchar 'name', unique;
769             };
770             };
771              
772             package MyProj::DB::Filter {
773             use Aniki::Filter::Declare;
774             use Scalar::Util qw/blessed/;
775             use Time::Moment;
776              
777             # define inflate/deflate filters in table context.
778             table author => sub {
779             inflate name => sub {
780             my $name = shift;
781             return uc $name;
782             };
783              
784             deflate name => sub {
785             my $name = shift;
786             return lc $name;
787             };
788             };
789              
790             inflate qr/_at$/ => sub {
791             my $datetime = shift;
792             $datetime =~ tr/ /T/;
793             $datetime .= 'Z';
794             return Time::Moment->from_string($datetime);
795             };
796              
797             deflate qr/_at$/ => sub {
798             my $datetime = shift;
799             return $datetime->at_utc->strftime('%F %T') if blessed $datetime and $datetime->isa('Time::Moment');
800             return $datetime;
801             };
802             };
803              
804             package MyProj::DB {
805             use Mouse v2.4.5;
806             extends qw/Aniki/;
807              
808             __PACKAGE__->setup(
809             schema => 'MyProj::DB::Schema',
810             filter => 'MyProj::DB::Filter',
811             row => 'MyProj::DB::Row',
812             );
813             };
814              
815             package main {
816             my $db = MyProj::DB->new(connect_info => ["dbi:SQLite:dbname=:memory:", "", ""]);
817             $db->execute($_) for split /;/, MyProj::DB::Schema->output;
818              
819             my $author_id = $db->insert_and_fetch_id(author => { name => 'songmu' });
820              
821             $db->insert(module => {
822             name => 'DBIx::Schema::DSL',
823             author_id => $author_id,
824             });
825             $db->insert(module => {
826             name => 'Riji',
827             author_id => $author_id,
828             });
829              
830             my $module = $db->select(module => {
831             name => 'Riji',
832             }, {
833             limit => 1,
834             })->first;
835             say '$module->name: ', $module->name; ## Riji
836             say '$module->author->name: ', $module->author->name; ## SONGMU
837              
838             my $author = $db->select(author => {
839             name => 'songmu',
840             }, {
841             limit => 1,
842             prefetch => [qw/modules/],
843             })->first;
844              
845             say '$author->name: ', $author->name; ## SONGMU
846             say 'modules[]->name: ', $_->name for $author->modules; ## DBIx::Schema::DSL, Riji
847             };
848              
849             1;
850              
851             =head1 DESCRIPTION
852              
853             Aniki is ORM.
854             Lite, but powerful.
855              
856             =head2 FEATURES
857              
858             =over 4
859              
860             =item Small & Simple
861              
862             You can read codes easily.
863              
864             =item Object mapping
865              
866             Inflates rows to L<Aniki::Result::Collection> object.
867             And inflates row to L<Aniki::Row> object.
868              
869             You can change result class, also we can change row class.
870             Aniki dispatches result/row class by table. (e.g. C<foo> table to C<MyDB::Row::Foo>)
871              
872             =item Raw SQL support
873              
874             Supports to execute raw C<SELECT> SQL and fetch rows of result.
875             Of course, Aniki can inflate to result/row also.
876              
877             =item Query builder
878              
879             Aniki includes query builder powered by L<SQL::Maker>.
880             L<SQL::Maker> is fast and secure SQL builder.
881              
882             =item Fork safe & Transaction support
883              
884             Aniki includes L<DBI> handler powered by L<DBIx::Handler>.
885              
886             =item Error handling
887              
888             Easy to handle execution errors by C<handle_error> method.
889             You can override it.
890              
891             =item Extendable
892              
893             You can extend Aniki by L<Mouse::Role>.
894             Aniki provides some default plugins as L<Mouse::Role>.
895              
896             =back
897              
898             =head2 RELATIONSHIP
899              
900             Aniki supports relationship.
901             Extracts relationship from schema class.
902              
903             Example:
904              
905             use 5.014002;
906             package MyProj::DB::Schema {
907             use DBIx::Schema::DSL;
908              
909             create_table 'module' => columns {
910             integer 'id', primary_key, auto_increment;
911             varchar 'name';
912             integer 'author_id';
913              
914             add_index 'author_id_idx' => ['author_id'];
915              
916             belongs_to 'author';
917             };
918              
919             create_table 'author' => columns {
920             integer 'id', primary_key, auto_increment;
921             varchar 'name', unique;
922             };
923             };
924              
925             A C<author> has many C<modules>.
926             So you can access C<author> row object to C<modules>.
927              
928             my $author = $db->select(author => { name => 'songmu' })->first;
929             say 'modules[]->name: ', $_->name for $author->modules; ## DBIx::Schema::DSL, Riji
930              
931             Also C<module> has a C<author>.
932             So you can access C<module> row object to C<author> also.
933              
934             my $module = $db->select(module => { name => 'Riji' })->first;
935             say "Riji's author is ", $module->author->name; ## SONGMU
936              
937             And you can pre-fetch related rows.
938              
939             my @modules = $db->select(module => {}, { prefetch => [qw/author/] });
940             say $_->name, "'s author is ", $_->author->name for @modules;
941              
942             =head1 SETUP
943              
944             Install Aniki from CPAN:
945              
946             cpanm Aniki
947              
948             And run C<install-aniki> command.
949              
950             install-aniki --lib=./lib MyApp::DB
951              
952             C<install-aniki> creates skeleton modules.
953              
954             =head1 METHODS
955              
956             =head2 CLASS METHODS
957              
958             =head3 C<setup(%args)>
959              
960             Initialize and customize Aniki class.
961             C<schema> is required. Others are optional.
962              
963             =head4 Arguments
964              
965             =over 4
966              
967             =item schema : ClassName
968              
969             =item handler : ClassName
970              
971             =item filter : ClassName
972              
973             =item row : ClassName
974              
975             =item result : ClassName
976              
977             =item query_builder : ClassName
978              
979             =back
980              
981             =head3 C<use_prepare_cached>
982              
983             If this method returns true value, Aniki uses C<preare_cached>.
984             This method returns true value default.
985             So you don't need to use C<preare_cached>, override it and return false value.
986              
987             =head3 C<use_strict_query_builder>
988              
989             If this method returns true value, Aniki enables L<SQL::Maker>'s strict mode.
990             This method returns true value default.
991             So you need to disable L<SQL::Maker>'s strict mode, override it and return false value.
992              
993             SEE ALSO: L<The JSON SQL Injection Vulnerability|http://blog.kazuhooku.com/2014/07/the-json-sql-injection-vulnerability.html>
994              
995             =head3 C<preload_all_row_classes>
996              
997             Preload all row classes.
998              
999             =head3 C<preload_all_result_classes>
1000              
1001             Preload all result classes.
1002              
1003             =head3 C<guess_result_class($table_name) : ClassName>
1004              
1005             Guesses result class by table name.
1006              
1007             =head3 C<guess_row_class($table_name) : ClassName>
1008              
1009             Guesses row class by table name.
1010              
1011             =head3 C<new(%args) : Aniki>
1012              
1013             Create instance of Aniki.
1014              
1015             =head4 Arguments
1016              
1017             =over 4
1018              
1019             =item C<handler : Aniki::Handler>
1020              
1021             Instance of Aniki::Hanlder.
1022             If this argument is given, not required to give C<connect_info> for arguments.
1023              
1024             =item C<connect_info : ArrayRef>
1025              
1026             Auguments for L<DBI>'s connect method.
1027              
1028             =item on_connect_do : CodeRef|ArrayRef[Str]|Str
1029              
1030             =item on_disconnect_do : CodeRef|ArrayRef[Str]|Str
1031              
1032             Execute SQL or CodeRef when connected/disconnected.
1033              
1034             =item trace_query : Bool
1035              
1036             Enables to inject a caller information as SQL comment.
1037             SEE ALSO: L<DBIx::Handler>
1038              
1039             =item trace_ignore_if : CodeRef
1040              
1041             Ignore to inject the SQL comment when trace_ignore_if's return value is true.
1042             SEE ALSO: L<DBIx::Handler>
1043              
1044             =item C<suppress_row_objects : Bool>
1045              
1046             If this option is true, no create row objects.
1047             Aniki's methods returns hash reference instead of row object.
1048              
1049             =item C<suppress_result_objects : Bool>
1050              
1051             If this option is true, no create result objects.
1052             Aniki's methods returns array reference instead of result object.
1053              
1054             =back
1055              
1056             =head2 INSTANCE METHODS
1057              
1058             =head3 C<select($table_name, \%where, \%opt)>
1059              
1060             Execute C<SELECT> query by generated SQL, and returns result object.
1061              
1062             my $result = $db->select(foo => { id => 1 }, { limit => 1 });
1063             # stmt: SELECT FROM foo WHERE id = ? LIMIT 1
1064             # bind: [1]
1065              
1066             =head4 Options
1067              
1068             There are the options of C<SELECT> query.
1069             See also L<SQL::Maker|https://metacpan.org/pod/SQL::Maker#opt>.
1070              
1071             And you can use there options:
1072              
1073             =over 4
1074              
1075             =item C<suppress_row_objects : Bool>
1076              
1077             If this option is true, no create row objects.
1078             This methods returns hash reference instead of row object.
1079              
1080             =item C<suppress_result_objects : Bool>
1081              
1082             If this option is true, no create result objects.
1083             This method returns array reference instead of result object.
1084              
1085             =item C<columns : ArrayRef[Str]>
1086              
1087             List for retrieving columns from database.
1088              
1089             =item C<prefetch : ArrayRef|HashRef>
1090              
1091             Pre-fetch specified related rows.
1092             See also L</"RELATIONSHIP"> section.
1093              
1094             =back
1095              
1096             =head3 C<select_named($sql, \%bind, \%opt)>
1097              
1098             =head3 C<select_by_sql($sql, \@bind, \%opt)>
1099              
1100             Execute C<SELECT> query by specified SQL, and returns result object.
1101              
1102             my $result = $db->select_by_sql('SELECT FROM foo WHERE id = ? LIMIT 1', [1]);
1103             # stmt: SELECT FROM foo WHERE id = ? LIMIT 1
1104             # bind: [1]
1105              
1106             =head4 Options
1107              
1108             You can use there options:
1109              
1110             =over 4
1111              
1112             =item C<table_name: Str>
1113              
1114             This is table name using row/result class guessing.
1115              
1116             =item C<columns: ArrayRef[Str]>
1117              
1118             List for retrieving columns from database.
1119              
1120             =item C<prefetch: ArrayRef|HashRef>
1121              
1122             Pre-fetch specified related rows.
1123             See also L</"RELATIONSHIP"> section.
1124              
1125             =back
1126              
1127             =head3 C<insert($table_name, \%values, \%opt)>
1128              
1129             Execute C<INSERT INTO> query.
1130              
1131             $db->insert(foo => { bar => 1 });
1132             # stmt: INSERT INTO foo (bar) VALUES (?)
1133             # bind: [1]
1134              
1135              
1136             =head3 C<insert_and_fetch_id($table_name, \%values, \%opt)>
1137              
1138             Execute C<INSERT INTO> query, and returns C<last_insert_id>.
1139              
1140             my $id = $db->insert_and_fetch_id(foo => { bar => 1 });
1141             # stmt: INSERT INTO foo (bar) VALUES (?)
1142             # bind: [1]
1143              
1144             =head3 C<insert_and_fetch_row($table_name, \%values, \%opt)>
1145              
1146             Execute C<INSERT INTO> query, and C<SELECT> it, and returns row object.
1147              
1148             my $row = $db->insert_and_fetch_row(foo => { bar => 1 });
1149             # stmt: INSERT INTO foo (bar) VALUES (?)
1150             # bind: [1]
1151              
1152             =head3 C<insert_and_emulate_row($table_name, \%values, \%opt)>
1153              
1154             Execute C<INSERT INTO> query, and returns row object created by C<$row> and schema definition.
1155              
1156             my $row = $db->insert_and_fetch_row(foo => { bar => 1 });
1157             # stmt: INSERT INTO foo (bar) VALUES (?)
1158             # bind: [1]
1159              
1160             This method is faster than C<insert_and_fetch_row>.
1161              
1162             =head4 WARNING
1163              
1164             If you use SQL C<TRIGGER> or dynamic default value, this method don't return the correct value, maybe.
1165             In this case, you should use C<insert_and_fetch_row> instead of this method.
1166              
1167             =head3 C<insert_on_duplicate($table_name, \%insert, \%update)>
1168              
1169             Execute C<INSERT ... ON DUPLICATE KEY UPDATE> query for MySQL.
1170              
1171             my $row = $db->insert_on_duplicate(foo => { bar => 1 }, { bar => \'VALUE(bar) + 1' });
1172             # stmt: INSERT INTO foo (bar) VALUES (?) ON DUPLICATE KEY UPDATE bar = VALUE(bar) + 1
1173             # bind: [1]
1174              
1175             SEE ALSO: L<INSERT ... ON DUPLICATE KEY UPDATE Syntax|https://dev.mysql.com/doc/refman/5.6/en/insert-on-duplicate.html>
1176              
1177             =head3 C<insert_multi($table_name, \@values, \%opts)>
1178              
1179             Execute C<INSERT INTO ... (...) VALUES (...), (...), ...> query for MySQL.
1180             Insert multiple rows at once.
1181              
1182             my $row = $db->insert_multi(foo => [{ bar => 1 }, { bar => 2 }, { bar => 3 }]);
1183             # stmt: INSERT INTO foo (bar) VALUES (?),(?),(?)
1184             # bind: [1, 2, 3]
1185              
1186             SEE ALSO: L<INSERT Syntax|https://dev.mysql.com/doc/refman/5.6/en/insert.html>
1187              
1188             =head3 C<update($table_name, \%set, \%where)>
1189              
1190             Execute C<UPDATE> query, and returns changed rows count.
1191              
1192             my $count = $db->update(foo => { bar => 2 }, { id => 1 });
1193             # stmt: UPDATE foo SET bar = ? WHERE id = ?
1194             # bind: [2, 1]
1195              
1196             =head3 C<update($row, \%set)>
1197              
1198             Execute C<UPDATE> query, and returns changed rows count.
1199              
1200             my $row = $db->select(foo => { id => 1 }, { limit => 1 })->first;
1201             my $count = $db->update($row => { bar => 2 });
1202             # stmt: UPDATE foo SET bar = ? WHERE id = ?
1203             # bind: [2, 1]
1204              
1205             =head3 C<update_and_fetch_row($row, \%set)>
1206              
1207             Execute C<UPDATE> query, and C<SELECT> it, and returns row object.
1208              
1209             my $row = $db->select(foo => { id => 1 }, { limit => 1 })->first;
1210             my $new_row = $db->update_and_fetch_row($row => { bar => 2 });
1211             # stmt: UPDATE foo SET bar = ? WHERE id = ?
1212             # bind: [2, 1]
1213              
1214             =head3 C<update_and_emulate_row($row, \%set)>
1215              
1216             Execute C<UPDATE> query, and returns row object created by C<$row> and C<%set>.
1217              
1218             my $row = $db->select(foo => { id => 1 }, { limit => 1 })->first;
1219             my $new_row = $db->update_and_emulate_row($row => { bar => 2 });
1220             # stmt: UPDATE foo SET bar = ? WHERE id = ?
1221             # bind: [2, 1]
1222              
1223             This method is faster than C<update_and_fetch_row>.
1224              
1225             =head4 WARNING
1226              
1227             If you use SQL C<TRIGGER> or C<AutoCommit>, this method don't return the correct value, maybe.
1228             In this case, you should use C<update_and_fetch_row> instead of this method.
1229              
1230             =head3 C<delete($table_name, \%where)>
1231              
1232             Execute C<DELETE> query, and returns changed rows count.
1233              
1234             my $count = $db->delete(foo => { id => 1 });
1235             # stmt: DELETE FROM foo WHERE id = ?
1236             # bind: [1]
1237              
1238             =head3 C<delete($row)>
1239              
1240             Execute C<DELETE> query, and returns changed rows count.
1241              
1242             my $row = $db->select(foo => { id => 1 }, { limit => 1 })->first;
1243             my $count = $db->delete($row);
1244             # stmt: DELETE foo WHERE id = ?
1245             # bind: [1]
1246              
1247             =head2 ACCESSORS
1248              
1249             =over 4
1250              
1251             =item C<schema : Aniki::Schema>
1252              
1253             =item C<filter : Aniki::Filter>
1254              
1255             =item C<query_builder : Aniki::QueryBuilder>
1256              
1257             =item C<root_row_class : Aniki::Row>
1258              
1259             =item C<root_result_class : Aniki::Result>
1260              
1261             =item C<connect_info : ArrayRef>
1262              
1263             =item C<on_connect_do : CodeRef|ArrayRef[Str]|Str>
1264              
1265             =item C<on_disconnect_do : CodeRef|ArrayRef[Str]|Str>
1266              
1267             =item C<suppress_row_objects : Bool>
1268              
1269             =item C<suppress_result_objects : Bool>
1270              
1271             =item C<dbh : DBI::db>
1272              
1273             =item C<handler : Aniki::Handler>
1274              
1275             =item C<txn_manager : DBIx::TransactionManager>
1276              
1277             =back
1278              
1279             =head1 CONTRIBUTE
1280              
1281             I need to support documentation and reviewing my english.
1282             This module is developed on L<Github|http://github.com/karupanerura/Aniki>.
1283              
1284             =head1 LICENSE
1285              
1286             Copyright (C) karupanerura.
1287              
1288             This library is free software; you can redistribute it and/or modify
1289             it under the same terms as Perl itself.
1290              
1291             =head1 CONTRIBUTORS
1292              
1293             =over 2
1294              
1295             =item watanabe-yocihi
1296              
1297             =item Pine Mizune
1298              
1299             =item Syohei YOSHIDA
1300              
1301             =back
1302              
1303             =head1 AUTHOR
1304              
1305             karupanerura E<lt>karupa@cpan.orgE<gt>
1306              
1307             =cut
1308