File Coverage

blib/lib/Data/Generator/FromDDL/Builder/SerialOrder.pm
Criterion Covered Total %
statement 24 24 100.0
branch n/a
condition n/a
subroutine 8 8 100.0
pod n/a
total 32 32 100.0


line stmt bran cond sub pod time code
1             package Data::Generator::FromDDL::Builder::SerialOrder;
2 6     6   1299 use strict;
  6         14  
  6         236  
3 6     6   34 use warnings;
  6         12  
  6         233  
4 6     6   34 use List::Util qw(first);
  6         13  
  6         525  
5 6     6   39 use Carp qw(croak);
  6         17  
  6         348  
6 6     6   5254 use POSIX qw(strftime);
  6         28130  
  6         49  
7              
8 6     6   10331 use Data::Generator::FromDDL::Builder;
  6         22  
  6         357  
9 6     6   47 use Data::Generator::FromDDL::RecordSet;
  6         20  
  6         146  
10 6     6   35 use Data::Generator::FromDDL::Util qw(get_numeric_type_byte);
  6         15  
  6         7032  
11             our @ISA = qw(Data::Generator::FromDDL::Builder);
12              
13              
14             datatype 'integer' => sub {
15             my ($builder, $field, $n, $recordsets) = @_;
16              
17             if ($field->is_foreign_key) {
18             my $constraint = $field->foreign_key_reference;
19             my $ref_table = $constraint->reference_table;
20             my $recordset = first { $_->table->name eq $ref_table } @$recordsets;
21              
22             my $ref_field = $constraint->reference_fields->[0];
23             my @values = $recordset->get_column_values($ref_field);
24             croak("[Foreign key] Field not found: $ref_field in table $ref_table\n")
25             unless @values;
26              
27             my $v_size = scalar(@values);
28             return map { $values[int(rand($v_size))] } (1..$n);
29             } elsif ($field->is_primary_key or
30             $field->is_unique or
31             $field->is_auto_increment) {
32             return (1..$n);
33             }
34              
35             my $is_unsigned = $field->extra->{unsigned} || 0;
36             my $byte = get_numeric_type_byte($field->data_type);
37             if ($is_unsigned) {
38             return map { int(rand(2 ** ($byte * 8))) } (1..$n);
39             } else {
40             return map {
41             [1, -1]->[int(rand(2))] * int(rand(2 ** ($byte * 8 - 1)))
42             } (1..$n);
43             }
44             };
45              
46             datatype 'bigint' => sub {
47             return shift->redispatch('integer', @_);
48             };
49              
50             datatype 'int' => sub {
51             return shift->redispatch('integer', @_);
52             };
53              
54             datatype 'mediumint' => sub {
55             return shift->redispatch('integer', @_);
56             };
57              
58             datatype 'smallint' => sub {
59             return shift->redispatch('integer', @_);
60             };
61              
62             datatype 'tinyint' => sub {
63             return shift->redispatch('integer', @_);
64             };
65              
66             datatype 'float, double' => sub {
67             my ($builder, $field, $n, $recordsets) = @_;
68              
69             my @size = $field->size();
70             my $total_len = $size[0] || 32;
71             my $decimal_len = $size[1] || 0;
72             my $integer_len = $total_len - $decimal_len;
73             my $max_integer = 10 ** $integer_len - 1 || 1;
74              
75             my $format = '%.' . $decimal_len . 'f';
76             my $c = 0.1 ** $decimal_len; # for avoiding round-up
77             return map {
78             sprintf $format, [1, -1]->[int(rand(2))] * (rand($max_integer) - $c)
79             } (1..$n);
80             };
81              
82             datatype 'boolean, bool' => sub {
83             my ($builder, $field, $n, $recordsets) = @_;
84             return map { int(rand(2)) } (1..$n); # 0 or 1
85             };
86              
87             datatype 'timestamp' => sub {
88             my @values = shift->redispatch('integer', @_);
89             return map {
90             strftime '%Y-%m-%d %H:%M:%S', localtime(abs($_))
91             } @values;
92             };
93              
94             datatype 'char, varchar, tinytext, text, mediumtext' => sub {
95             my ($builder, $field, $n, $recordsets) = @_;
96             my $field_name = $field->name;
97             my $field_size = $field->size;
98              
99             my $record_prefix = substr $field_name, 0, $field_size - length($n);
100             my $format = $record_prefix . "%0" . length($n) . "d";
101             return map { sprintf $format, $_ } (1..$n);
102             };
103              
104             datatype 'enum' => sub {
105             my ($builder, $field, $n, $recordsets) = @_;
106             my $list = $field->extra->{list} || [];
107             my $size = scalar(@$list);
108             croak("Can't select value from empty ENUM list: " . $field->name . "\n")
109             if $size == 0;
110             return map { $list->[int(rand($size))] } (1..$n);
111             };
112              
113             1;