File Coverage

blib/lib/Data/Generator/FromDDL/Formatter.pm
Criterion Covered Total %
statement 48 57 84.2
branch 8 14 57.1
condition n/a
subroutine 7 8 87.5
pod 0 3 0.0
total 63 82 76.8


line stmt bran cond sub pod time code
1             package Data::Generator::FromDDL::Formatter;
2 6     6   30 use strict;
  6         22  
  6         188  
3 6     6   33 use warnings;
  6         11  
  6         154  
4 6     6   28 use Carp qw(croak);
  6         9  
  6         239  
5 6     6   5668 use JSON ();
  6         81251  
  6         234  
6             use Class::Accessor::Lite (
7 6         81 new => 1,
8             rw => [qw(format pretty bytes_per_sql)],
9 6     6   62 );
  6         13  
10              
11             sub to_string {
12 21     21 0 54 my ($self, $table, $fields, $rows) = @_;
13              
14 21         38 my $formatter = do {
15 21 50       92 if ($self->format =~ /sql/i) {
    0          
16 21         292 'to_sql';
17             } elsif ($self->format =~ /json/i) {
18 0         0 'to_json';
19             } else {
20 0         0 croak("Unsupported format: " . $self->format . "\n");
21             }
22             };
23              
24 21         111 $self->$formatter($table, $fields, $rows);
25             }
26              
27             sub to_sql {
28 21     21 0 47 my ($self, $table, $fields, $rows) = @_;
29              
30 21         41 my $insert_stmt;
31             my $record_sep;
32 21 100       93 if ($self->pretty) {
33 1         10 $insert_stmt = "INSERT IGNORE INTO\n `%s` (%s)\nVALUES\n ";
34 1         2 $record_sep = ",\n ";
35             } else {
36 20         131 $insert_stmt = 'INSERT IGNORE INTO `%s` (%s) VALUES ';
37 20         45 $record_sep = ',';
38             }
39              
40 21         52 my $columns = join ',', map { '`' . $_->name . '`' } @$fields;
  22         1363  
41 21         3271 $insert_stmt = sprintf $insert_stmt, $table->name, $columns;
42              
43 21         2182 my $sqls = '';
44 21         38 my @values;
45 21         155 my $sum_bytes = bytes::length($insert_stmt) + 1; # +1 is for trailing semicolon of sql
46 21         7857 my $record_sep_len = bytes::length($record_sep);
47 21         150 my $bytes_per_sql = $self->bytes_per_sql;
48 21         148 for my $row (@$rows) {
49 34         117 my $value = '(' . join(',', @$row) . ')';
50 34         101 my $v_len = bytes::length($value);
51 34 100       209 if ($sum_bytes + $v_len + $record_sep_len > $bytes_per_sql) {
52 6 100       23 if (@values) {
53 3         16 $sqls .= $insert_stmt . (join $record_sep, @values) . ";\n";
54 3         11 $sum_bytes = bytes::length($insert_stmt) + 1;
55 3         14 @values = ();
56             }
57             }
58 34         85 push @values, $value;
59 34         99 $sum_bytes += $v_len + $record_sep_len;
60             }
61              
62 21 50       91 if (@values) {
63 21         95 $sqls .= $insert_stmt . (join $record_sep, @values) . ';';
64             }
65 21         112 return $sqls;
66             }
67              
68             sub to_json {
69 0     0 0   my ($self, $table, $fields, $rows) = @_;
70 0           my $json = do {
71 0 0         if ($self->pretty) {
72 0           JSON->new->pretty;
73             } else {
74 0           JSON->new;
75             }
76             };
77              
78 0           return $json->encode({
79             table => $table->name,
80 0           fields => [ map { $_->name } @$fields ],
81             values => $rows,
82             });
83             }
84              
85             1;