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   1742088 use 5.014002;
  27         100  
3              
4 27     27   8386 use namespace::autoclean;
  27         316825  
  27         118  
5 27     27   2063 use Mouse v2.4.5;
  27         18875  
  27         167  
6              
7 27     27   20645 use Module::Load ();
  27         22749  
  27         526  
8 27     27   9112 use Aniki::Filter;
  27         2294  
  27         779  
9 27     27   8551 use Aniki::Handler;
  27         2440  
  27         912  
10 27     27   10018 use Aniki::Row;
  27         2232  
  27         854  
11 27     27   9751 use Aniki::Result::Collection;
  27         1863  
  27         825  
12 27     27   9101 use Aniki::Schema;
  27         2086  
  27         979  
13 27     27   10516 use Aniki::QueryBuilder;
  27         103  
  27         818  
14 27     27   9280 use Aniki::QueryBuilder::Canonical;
  27         84  
  27         1018  
15              
16             our $VERSION = '1.06';
17              
18 27     27   9607 use SQL::Maker::SQLType qw/sql_type/;
  27         8028  
  27         1449  
19 27     27   10633 use Class::Inspector;
  27         58587  
  27         974  
20 27     27   199 use Carp qw/croak confess/;
  27         62  
  27         1408  
21 27     27   163 use Try::Tiny;
  27         65  
  27         1390  
22 27     27   157 use Scalar::Util qw/blessed/;
  27         57  
  27         1079  
23 27     27   10591 use String::CamelCase qw/camelize/;
  27         11534  
  27         1410  
24 27     27   9425 use SQL::NamedPlaceholder qw/bind_named/;
  27         35568  
  27         171  
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   798 my ($class, $database) = @_;
68 56         228 state $map = {
69             MySQL => 'mysql',
70             PostgreSQL => 'Pg',
71             SQLite => 'SQLite',
72             Oracle => 'Oracle',
73             DB2 => 'DB2',
74             };
75 56         163 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 298 sub handler_class { 'Aniki::Handler' }
87              
88             # You can override this method on your application.
89 409     409 1 1450 sub use_prepare_cached { 1 }
90 28     28 1 440 sub use_strict_query_builder { 1 }
91              
92             sub setup {
93 28     28 1 118649 my ($class, %args) = @_;
94              
95             # schema
96 28 50       144 if (my $schema_class = $args{schema}) {
97 28 50       244 Module::Load::load($schema_class) unless Class::Inspector->loaded($schema_class);
98              
99 28         196542 my $schema = Aniki::Schema->new(schema_class => $schema_class);
100 28     367   377 $class->meta->add_method(schema => sub { $schema });
  367     367   59148  
        8      
        8      
101             }
102             else {
103 0         0 croak 'schema option is required.';
104             }
105              
106             # filter
107 28 50       1041 if (my $filter_class = $args{filter}) {
108 28 100       278 Module::Load::load($filter_class) unless Class::Inspector->loaded($filter_class);
109              
110 28         728 my $filter = $filter_class->instance();
111 28     382   182 $class->meta->add_method(filter => sub { $filter });
  382         1314  
112             }
113             else {
114 0         0 my $filter = Aniki::Filter->new;
115 0     382   0 $class->meta->add_method(filter => sub { $filter });
  0         0  
116             }
117              
118             # handler
119 28 50       737 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         126 my $driver = lc $class->_database2driver($class->schema->database);
127 28 50       445 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         132 $class->meta->add_method(last_insert_id => $method);
129             }
130              
131             # query_builder
132             {
133 28 50       62 my $query_builder_class = $class->use_prepare_cached ? 'Aniki::QueryBuilder::Canonical' : 'Aniki::QueryBuilder';
  28         183  
134 28 50       128 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         104 my $driver = $class->_database2driver($class->schema->database);
139 28         261 my $query_builder = $query_builder_class->new(driver => $driver, strict => $class->use_strict_query_builder);
140 28     180   892 $class->meta->add_method(query_builder => sub { $query_builder });
  180         716  
141             }
142              
143             # row
144             {
145 28         522 my $root_row_class = 'Aniki::Row';
  28         69  
146 28     180   99 my $guess_row_class = sub { $root_row_class };
  0         0  
147 28 50       127 if ($args{row}) {
148 28 100       177 Module::Load::load($args{row}) unless Class::Inspector->loaded($args{row});
149 28         24151 $root_row_class = $args{row};
150              
151 28         75 my %table_row_class;
152             $guess_row_class = sub {
153 88     88   174 my $table_name = $_[1];
154             return $table_row_class{$table_name} //= try {
155 25         1414 my $table_row_class = sprintf '%s::%s', $root_row_class, camelize($table_name);
156 25         554 Module::Load::load($table_row_class);
157 20         19532 return $table_row_class;
158             } catch {
159 5 50       1663 die $_ unless /\A\QCan't locate/imo;
160 5         64 return $root_row_class;
161 88   66     701 };
162 28         162 };
163             }
164 28     88   232 $class->meta->add_method(root_row_class => sub { $root_row_class });
  0         0  
165 28         609 $class->meta->add_method(guess_row_class => $guess_row_class);
166             }
167              
168             # result
169             {
170 28         590 my $root_result_class = 'Aniki::Result::Collection';
  28         531  
  28         74  
171 28     82   112 my $guess_result_class = sub { $root_result_class };
  82         173  
172 28 50       129 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     82   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   118 $class->meta->add_method(root_result_class => sub { $root_result_class });
  0         0  
191 28         565 $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 441     441 1 759 my $self = shift;
211             # (for mysql)
212             # XXX: `DBIx::Handler#dbh` send a ping to mysql.
213             # But, It removes `$dbh->{mysql_insertid}`.
214 441 100       1574 return $self->{_context} if exists $self->{_context};
215 344         1359 return $self->handler->dbh;
216             }
217              
218             sub insert {
219 67     67 1 249 my ($self, $table_name, $row, $opt) = @_;
220 67 100       385 $row = $self->filter_on_insert($table_name, $row) unless $opt->{no_filter};
221              
222 67         206 my $table = $self->schema->get_table($table_name);
223 67 50       317 $row = $self->_bind_sql_type_to_args($table, $row) if $table;
224              
225 67         242 my ($sql, @bind) = $self->query_builder->insert($table_name, $row, $opt);
226 67         9380 $self->execute($sql, @bind);
227 67         364 return;
228             }
229              
230             sub filter_on_insert {
231 100     100 0 211 my ($self, $table_name, $row) = @_;
232 100         275 $row = $self->filter->apply_trigger(insert => $table_name, $row);
233 100         257 return $self->filter->deflate_row($table_name, $row);
234             }
235              
236             sub update {
237 13     13 1 1471 my ($self, $table_name, $set, $where, $opt) = @_;
238              
239             # migrate for ($self, $row, $set, $opt)
240 13 100 66     127 if (blessed $_[1] && $_[1]->isa('Aniki::Row')) {
241 11         24 my $row = $_[1];
242 11         30 $table_name = $row->table_name;
243 11         20 $set = $_[2];
244 11         45 $where = $self->_where_row_cond($row->table, $row->row_data);
245 11         25 $opt = $_[3];
246             }
247              
248 13 100 100     449 croak '(Aniki#update) `set` is required for update ("SET" parameter)' unless $set && %$set;
249 9 100       98 croak '(Aniki#update) `where` condition must be a reference' unless ref $where;
250              
251 8 100       33 $set = $self->filter_on_update($table_name, $set) unless $opt->{no_filter};
252              
253 8         21 my $table = $self->schema->get_table($table_name);
254 8 50       22 if ($table) {
255 8         26 $set = $self->_bind_sql_type_to_args($table, $set);
256 8         21 $where = $self->_bind_sql_type_to_args($table, $where);
257             }
258              
259 8         26 my ($sql, @bind) = $self->query_builder->update($table_name, $set, $where);
260 8         1849 return $self->execute($sql, @bind)->rows;
261             }
262              
263             sub update_and_fetch_row {
264 5     5 1 7759 my ($self, $row, $set) = @_;
265 5 100 66     160 croak '(Aniki#update_and_fetch_row) condition must be a Aniki::Row object.'
266             unless blessed $row && $row->isa('Aniki::Row');
267              
268 4         15 my $emulated_row_data = $self->_update_and_emulate_row_data($row, $set);
269              
270 3         32 my $where = $self->_where_row_cond($row->table, $emulated_row_data);
271 3         12 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 8593 my ($self, $row, $set) = @_;
276 5 100 66     205 croak '(Aniki#update_and_emulate_row) condition must be a Aniki::Row object.' unless blessed $row && $row->isa('Aniki::Row');
277              
278 4         15 my $emulated_row_data = $self->_update_and_emulate_row_data($row, $set);
279 3 100       15 return $emulated_row_data if $self->suppress_row_objects;
280              
281 2         9 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   18 my ($self, $row, $set) = @_;
290 8         37 $set = $self->filter_on_update($row->table_name, $set);
291 8         43 $self->update($row, $set, { no_filter => 1 });
292             return {
293 6         15 %{ $row->row_data },
  6         51  
294             %$set,
295             };
296             }
297              
298             sub delete :method {
299 4     4 1 28 my $self = shift;
300 4 100 66     24 if (blessed $_[0] && $_[0]->isa('Aniki::Row')) {
301 1         8 return $self->delete($_[0]->table_name, $self->_where_row_cond($_[0]->table, $_[0]->row_data), @_);
302             }
303             else {
304 3         6 my ($table_name, $where, $opt) = @_;
305 3 100       133 croak '(Aniki#delete) `where` condition must be a reference' unless ref $where;
306              
307 2         5 my $table = $self->schema->get_table($table_name);
308 2 50       7 if ($table) {
309 2         5 $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         288 return $self->execute($sql, @bind)->rows;
314             }
315             }
316              
317             sub filter_on_update {
318 10     10 0 22 my ($self, $table_name, $row) = @_;
319 10         26 $row = $self->filter->apply_trigger(update => $table_name, $row);
320 10         26 return $self->filter->deflate_row($table_name, $row);
321             }
322              
323             sub insert_and_fetch_id {
324 21     21 1 2817 my $self = shift;
325              
326 21         45 local $self->{_context} = $self->dbh;
327 21         694 $self->insert(@_);
328 21 50       80 return unless defined wantarray;
329              
330 21         45 my $table_name = shift;
331 21         67 return $self->last_insert_id($table_name);
332             }
333              
334             sub insert_and_fetch_row {
335 6     6 1 118 my $self = shift;
336 6         14 my $table_name = shift;
337 6         14 my $row_data = shift;
338              
339 6 50       20 my $table = $self->schema->get_table($table_name) or croak "$table_name is not defined in schema.";
340              
341 6         19 local $self->{_context} = $self->dbh;
342              
343 6         202 $self->insert($table_name, $row_data, @_);
344 6 50       25 return unless defined wantarray;
345              
346 6         42 my $row = $self->select($table_name, $self->_where_row_cond($table, $row_data), { limit => 1, suppress_result_objects => 1 })->[0];
347 6 50       45 return $row if $self->suppress_row_objects;
348              
349 6         36 $row->is_new(1);
350 6         24 return $row;
351             }
352              
353             sub insert_and_emulate_row {
354 2     2 1 38 my ($self, $table_name, $row, $opt) = @_;
355              
356 2 50       8 my $table = $self->schema->get_table($table_name) or croak "$table_name is not defined in schema.";
357              
358 2         9 local $self->{_context} = $self->dbh;
359              
360 2 50       95 $row = $self->filter_on_insert($table_name, $row) unless $opt->{no_filter};
361              
362 2         13 $self->insert($table_name, $row, { %$opt, no_filter => 1 });
363 2 50       8 return unless defined wantarray;
364              
365 2         3 my %row_data;
366 2         10 for my $field ($table->get_fields) {
367 10 100       44 if (exists $row->{$field->name}) {
    100          
    50          
368 4         13 $row_data{$field->name} = $row->{$field->name};
369             }
370             elsif (defined(my $default_value = $field->default_value)) {
371 4 50       15 $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       10 return \%row_data if $self->suppress_row_objects;
381 2         8 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 14765 my ($self, $table_name, $values, $opts) = @_;
411 10 100       65 return unless @$values;
412              
413 9 50       42 $opts = defined $opts ? {%$opts} : {};
414              
415 9         32 my @values = map { $self->filter_on_insert($table_name, $_) } @$values;
  33         118  
416 9 50       49 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         61 my $table = $self->schema->get_table($table_name);
424 9 50       67 if ($table) {
425 9         77 $_ = $self->_bind_sql_type_to_args($table, $_) for @values;
426 9 50       43 if (exists $opts->{update}) {
427 0         0 $opts->{update} = $self->_bind_sql_type_to_args($table, $opts->{update});
428             }
429             }
430              
431 9 50       32 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   1519 local $self->{_context} = shift;
438 9         71 $self->insert($table_name, $_, $opts) for @values;
439 9         205 });
440             }
441 9         835 return;
442             }
443              
444             sub _where_row_cond {
445 24     24   50 my ($self, $table, $row_data) = @_;
446 24 50       134 die "@{[ $table->name ]} doesn't have primary key." unless $table->primary_key;
  0         0  
447              
448             # fetch by primary key
449 24         43 my %where;
450 24         104 for my $pk ($table->primary_key->fields) {
451 24 50       194 $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         96 return \%where;
458             }
459              
460             my $WILDCARD_COLUMNS = ['*'];
461              
462             sub select :method {
463 79     79 1 26662 my ($self, $table_name, $where, $opt) = @_;
464 79   50     232 $where //= {};
465 79   100     221 $opt //= {};
466              
467 79 50       205 croak '(Aniki#select) `where` condition must be a reference.' unless ref $where;
468              
469 79         204 my $table = $self->schema->get_table($table_name);
470              
471             my $columns = exists $opt->{columns} ? $opt->{columns}
472 79 50       418 : defined $table ? $table->field_names
    50          
473             : $WILDCARD_COLUMNS;
474              
475 79 50       306 $where = $self->_bind_sql_type_to_args($table, $where) if defined $table;
476              
477 79         164 local $Carp::CarpLevel = $Carp::CarpLevel + 1;
478 79         195 my ($sql, @bind) = $self->query_builder->select($table_name, $columns, $where, $opt);
479 79         40190 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 34     34 0 70 my ($self, $table_name, $prefetch, $rows) = @_;
488 34 50       81 return unless @$rows;
489              
490 34 50       87 $prefetch = [$prefetch] if ref $prefetch eq 'HASH';
491              
492 34         91 my $relationships = $self->schema->get_table($table_name)->get_relationships;
493 34         86 for my $key (@$prefetch) {
494 33 100 66     112 if (ref $key && ref $key eq 'HASH') {
495 5         21 my %prefetch = %$key;
496 5         14 for my $key (keys %prefetch) {
497 4         15 $self->_fetch_and_attach_relay_data($relationships, $rows, $key, $prefetch{$key});
498             }
499             }
500             else {
501 28         88 $self->_fetch_and_attach_relay_data($relationships, $rows, $key, []);
502             }
503             }
504             }
505              
506             sub _fetch_and_attach_relay_data {
507 32     32   78 my ($self, $relationships, $rows, $key, $prefetch) = @_;
508 32         103 my $relationship = $relationships->get($key);
509 32 50       81 unless ($relationship) {
510 0         0 croak "'$key' is not defined as relationship. (maybe possible typo?)";
511             }
512 32         136 $relationship->fetcher->execute($self, $rows, $prefetch);
513             }
514              
515             sub select_named {
516 3     3 1 9 my ($self, $sql, $bind, $opt) = @_;
517 3         21 return $self->select_by_sql(bind_named($sql, $bind), $opt);
518             }
519              
520             sub select_by_sql {
521 85     85 1 289 my ($self, $sql, $bind, $opt) = @_;
522 85   50     285 $opt //= {};
523              
524 85 100       250 local $self->{suppress_row_objects} = 1 if $opt->{suppress_row_objects};
525 85 100       222 local $self->{suppress_result_objects} = 1 if $opt->{suppress_result_objects};
526              
527 85 100       246 my $table_name = exists $opt->{table_name} ? $opt->{table_name} : $self->_guess_table_name($sql);
528 85 100       200 my $columns = exists $opt->{columns} ? $opt->{columns} : undef;
529 85 100       210 my $prefetch = exists $opt->{prefetch} ? $opt->{prefetch} : [];
530 85 100       259 $prefetch = [$prefetch] if ref $prefetch eq 'HASH';
531              
532 85   66     321 my $prefetch_enabled_fg = @$prefetch && !$self->suppress_row_objects && defined wantarray;
533 85 100       214 if ($prefetch_enabled_fg) {
534 8 100       11 my $txn; $txn = $self->txn_scope(caller => [caller]) unless $self->in_txn;
  8         25  
535              
536 8         451 my $sth = $self->execute($sql, @$bind);
537 8         29 my $result = $self->_fetch_by_sth($sth, $table_name, $columns);
538 8         32 $self->fetch_and_attach_relay_data($table_name, $prefetch, $result->rows);
539              
540 8 100       31 $txn->rollback if defined $txn; ## for read only
541 8         195 return $result;
542             }
543              
544 77         258 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 77 50       232 unless (defined wantarray) {
549 0         0 $sth->finish();
550 0         0 return;
551             }
552              
553 77         310 return $self->_fetch_by_sth($sth, $table_name, $columns);
554             }
555              
556             sub _fetch_by_sth {
557 85     85   216 my ($self, $sth, $table_name, $columns) = @_;
558 85   66     312 $columns //= $sth->{NAME};
559 85 50       271 $columns = $sth->{NAME} if $columns == $WILDCARD_COLUMNS;
560              
561 85         169 my @rows;
562              
563             my %row;
564 85         704 $sth->bind_columns(\@row{@$columns});
565 85         4122 push @rows => {%row} while $sth->fetch;
566 85         339 $sth->finish;
567              
568 85 100       395 if ($self->suppress_result_objects) {
569 11 100       60 return \@rows if $self->suppress_row_objects;
570              
571 9         34 my $row_class = $self->guess_row_class($table_name);
572             return [
573             map {
574 9         116 $row_class->new(
  9         125  
575             table_name => $table_name,
576             handler => $self,
577             row_data => $_,
578             )
579             } @rows
580             ];
581             }
582              
583 74         221 my $result_class = $self->guess_result_class($table_name);
584 74         957 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 381     381 0 2109 my ($self, $sql, @bind) = @_;
594 381         1824 $sql = $self->handler->trace_query_set_comment($sql);
595              
596 381 50       4614 my $sth = $self->use_prepare_cached ? $self->dbh->prepare_cached($sql) : $self->dbh->prepare($sql);
597 381         83244 $self->_bind_to_sth($sth, \@bind);
598 381         1594 eval {
599 381         17762 $sth->execute();
600             };
601 381 50       1412 if ($@) {
602 0         0 $self->handle_error($sql, \@bind, $@);
603             }
604              
605 381         1269 return $sth;
606             }
607              
608             sub _bind_sql_type_to_args {
609 197     197   373 my ($self, $table, $args) = @_;
610              
611 197         289 my %bind_args;
612 197         270 for my $col (keys %{$args}) {
  197         480  
613             # if $args->{$col} is a ref, it is scalar ref or already
614             # sql type bined parameter. so ignored.
615 220 100       1059 if (ref $args->{$col}) {
    50          
616 88         197 $bind_args{$col} = $args->{$col};
617             }
618             elsif (my $field = $table->get_field($col)) {
619 132         534 $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 197         1747 return \%bind_args;
627             }
628              
629             sub _bind_to_sth {
630 381     381   861 my ($self, $sth, $bind) = @_;
631 381         1271 for my $i (keys @$bind) {
632 203         721 my $v = $bind->[$i];
633 203 100 66     1241 if (blessed $v && $v->isa('SQL::Maker::SQLType')) {
634 132         237 $sth->bind_param($i + 1, ${$v->value_ref}, $v->type);
  132         372  
635             } else {
636 71         355 $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 24 my ($self, $table_name, $row_data) = @_;
661 1 50       8 return $row_data if $self->suppress_row_objects;
662              
663 1         5 my $row_class = $self->guess_row_class($table_name);
664 1         36 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 4447 my ($self, $table_name, $row_datas) = @_;
673 2 50       18 return $row_datas if $self->suppress_result_objects;
674              
675 2         10 my $result_class = $self->guess_result_class($table_name);
676 2         42 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   22 my ($self, $sql) = @_;
686 6 50       76 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 29     29   74 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 8 sub txn_manager { shift->handler->txn_manager }
707 9     9 0 87 sub txn { shift->handler->txn(@_) }
708 8     8 0 43 sub in_txn { shift->handler->in_txn(@_) }
709 5     5 0 178 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 9911 my $self = shift;
738 24 50       427 $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