| Filename | /home/mickey/git_tree/PONAPI/Server/lib/Test/PONAPI/Repository/MockDB/Table.pm |
| Statements | Executed 7923372 statements in 20.1s |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 368116 | 3 | 1 | 12.4s | 24.5s | Test::PONAPI::Repository::MockDB::Table::select_stmt |
| 368116 | 1 | 1 | 5.79s | 7.22s | Test::PONAPI::Repository::MockDB::Table::_stmt_filters |
| 368116 | 1 | 1 | 4.21s | 4.78s | Test::PONAPI::Repository::MockDB::Table::_stmt_columns |
| 1 | 1 | 1 | 18µs | 3.06ms | Test::PONAPI::Repository::MockDB::Table::BEGIN@4 |
| 1 | 1 | 1 | 9µs | 9µs | Test::PONAPI::Repository::MockDB::Table::BEGIN@6 |
| 1 | 1 | 1 | 8µs | 80µs | Test::PONAPI::Repository::MockDB::Table::BEGIN@167 |
| 4 | 1 | 1 | 4µs | 4µs | Test::PONAPI::Repository::MockDB::Table::__ANON__[lib/Test/PONAPI/Repository/MockDB/Table.pm:23] |
| 0 | 0 | 0 | 0s | 0s | Test::PONAPI::Repository::MockDB::Table::delete_stmt |
| 0 | 0 | 0 | 0s | 0s | Test::PONAPI::Repository::MockDB::Table::insert_stmt |
| 0 | 0 | 0 | 0s | 0s | Test::PONAPI::Repository::MockDB::Table::update_stmt |
| Line | State ments |
Time on line |
Calls | Time in subs |
Code |
|---|---|---|---|---|---|
| 1 | # ABSTRACT: mock repository - table class | ||||
| 2 | package Test::PONAPI::Repository::MockDB::Table; | ||||
| 3 | |||||
| 4 | 2 | 52µs | 2 | 6.10ms | # spent 3.06ms (18µs+3.04) within Test::PONAPI::Repository::MockDB::Table::BEGIN@4 which was called:
# once (18µs+3.04ms) by Module::Runtime::require_module at line 4 # spent 3.06ms making 1 call to Test::PONAPI::Repository::MockDB::Table::BEGIN@4
# spent 3.04ms making 1 call to Moose::import |
| 5 | |||||
| 6 | 2 | 706µs | 1 | 9µs | # spent 9µs within Test::PONAPI::Repository::MockDB::Table::BEGIN@6 which was called:
# once (9µs+0s) by Module::Runtime::require_module at line 6 # spent 9µs making 1 call to Test::PONAPI::Repository::MockDB::Table::BEGIN@6 |
| 7 | |||||
| 8 | 1 | 3µs | 1 | 9.40ms | has [qw/TYPE TABLE ID_COLUMN/] => ( # spent 9.40ms making 1 call to Moose::has |
| 9 | is => 'ro', | ||||
| 10 | isa => 'Str', | ||||
| 11 | required => 1, | ||||
| 12 | ); | ||||
| 13 | |||||
| 14 | 1 | 2µs | 1 | 1.24ms | has COLUMNS => ( # spent 1.24ms making 1 call to Moose::has |
| 15 | is => 'ro', | ||||
| 16 | isa => 'ArrayRef', | ||||
| 17 | required => 1, | ||||
| 18 | ); | ||||
| 19 | |||||
| 20 | has RELATIONS => ( | ||||
| 21 | is => 'ro', | ||||
| 22 | isa => 'HashRef[Test::PONAPI::Repository::MockDB::Table::Relationships]', | ||||
| 23 | 4 | 14µs | # spent 4µs within Test::PONAPI::Repository::MockDB::Table::__ANON__[lib/Test/PONAPI/Repository/MockDB/Table.pm:23] which was called 4 times, avg 1µs/call:
# 4 times (4µs+0s) by Test::PONAPI::Repository::MockDB::Table::Relationships::new at line 75 of (eval 45)[Eval/Closure.pm:144], avg 1µs/call | ||
| 24 | 1 | 4µs | 1 | 2.44ms | ); # spent 2.44ms making 1 call to Moose::has |
| 25 | |||||
| 26 | sub insert_stmt { | ||||
| 27 | my ($self, %args) = @_; | ||||
| 28 | |||||
| 29 | my $table = $args{table}; | ||||
| 30 | my $values = $args{values}; | ||||
| 31 | |||||
| 32 | # NOTE: this is a bunch of bad practices rolled together. | ||||
| 33 | # We're crafting our own SQL and not escaping the table/columns, | ||||
| 34 | # as well as using sqlite-specific features. | ||||
| 35 | # Ordinarily, you'd use DBIx::Class or at least SQL::Composer | ||||
| 36 | # for this, but we got reports that packaging PONAPI::Server | ||||
| 37 | # becomes hugely complex by adding either of those as dependencies. | ||||
| 38 | # Since this is just for testing, let's forgo a couple of good practices | ||||
| 39 | # and do it all manually. | ||||
| 40 | my @keys = keys %$values; | ||||
| 41 | my @values = values %$values; | ||||
| 42 | my $sql = "INSERT INTO $table " . (@keys | ||||
| 43 | ? '(' . join( ",", @keys) . ') VALUES (' . join(',', ('?') x @keys) . ')' | ||||
| 44 | : 'DEFAULT VALUES'); | ||||
| 45 | |||||
| 46 | my $stmt = { | ||||
| 47 | sql => $sql, | ||||
| 48 | bind => \@values, | ||||
| 49 | }; | ||||
| 50 | |||||
| 51 | return $stmt; | ||||
| 52 | } | ||||
| 53 | |||||
| 54 | sub delete_stmt { | ||||
| 55 | my ($self, %args) = @_; | ||||
| 56 | |||||
| 57 | my $table = $args{table}; | ||||
| 58 | my $where = $args{where}; | ||||
| 59 | |||||
| 60 | my @keys = keys %$where; | ||||
| 61 | my @values = values %$where; | ||||
| 62 | |||||
| 63 | my $sql = "DELETE FROM $table WHERE " | ||||
| 64 | . join " AND ", map "$_=?", @keys; | ||||
| 65 | |||||
| 66 | my $stmt = { sql => $sql, bind => \@values }; | ||||
| 67 | |||||
| 68 | return $stmt; | ||||
| 69 | } | ||||
| 70 | |||||
| 71 | # spent 24.5s (12.4+12.1) within Test::PONAPI::Repository::MockDB::Table::select_stmt which was called 368116 times, avg 67µs/call:
# 187055 times (5.69s+5.16s) by Test::PONAPI::Repository::MockDB::_fetchall_relationships at line 728 of lib/Test/PONAPI/Repository/MockDB.pm, avg 58µs/call
# 100001 times (4.09s+4.56s) by Test::PONAPI::Repository::MockDB::retrieve_all at line 88 of lib/Test/PONAPI/Repository/MockDB.pm, avg 86µs/call
# 81060 times (2.58s+2.41s) by Test::PONAPI::Repository::MockDB::_add_included at line 675 of lib/Test/PONAPI/Repository/MockDB.pm, avg 62µs/call | ||||
| 72 | 368116 | 885ms | my ($self, %args) = @_; | ||
| 73 | |||||
| 74 | 368116 | 227ms | my $type = $args{type}; | ||
| 75 | 368116 | 867ms | 368116 | 7.22s | my $filters = $self->_stmt_filters($type, $args{filter}); # spent 7.22s making 368116 calls to Test::PONAPI::Repository::MockDB::Table::_stmt_filters, avg 20µs/call |
| 76 | |||||
| 77 | 368116 | 743ms | my %limit = %{ $args{page} || {} }; | ||
| 78 | 368116 | 277ms | my $sort = $args{sort} || []; | ||
| 79 | |||||
| 80 | 25306 | 284ms | 25306 | 131ms | my @order_by = map { # spent 131ms making 25306 calls to Test::PONAPI::Repository::MockDB::Table::CORE:match, avg 5µs/call |
| 81 | 368116 | 352ms | my ($desc, $col) = /\A(-?)(.+)\z/s; | ||
| 82 | 25306 | 58.1ms | join ' ', $col => uc( $desc ? 'desc' : 'asc' ); | ||
| 83 | } @$sort; | ||||
| 84 | |||||
| 85 | 368116 | 937ms | 368116 | 4.78s | my $columns = $self->_stmt_columns(\%args); # spent 4.78s making 368116 calls to Test::PONAPI::Repository::MockDB::Table::_stmt_columns, avg 13µs/call |
| 86 | 368116 | 876ms | my @values = map { ref($_) ? @$_ : $_ } values %$filters; | ||
| 87 | 317871 | 173ms | my $sql = join "\n", | ||
| 88 | 'SELECT ' . join(',', @$columns), | ||||
| 89 | 'FROM ' . $type, | ||||
| 90 | (%$filters | ||||
| 91 | ? 'WHERE ' . join(' AND ', map { | ||||
| 92 | 368116 | 1.95s | my $val = $filters->{$_}; | ||
| 93 | ref($val) | ||||
| 94 | 317871 | 380ms | ? "$_ IN (@{[ join ',', ('?') x @$val ]})" | ||
| 95 | : "$_=?" | ||||
| 96 | } keys %$filters) | ||||
| 97 | : '' | ||||
| 98 | ), | ||||
| 99 | (@order_by ? 'ORDER BY ' . join(', ', @order_by) : ''), | ||||
| 100 | (%limit ? "LIMIT $limit{limit} OFFSET $limit{offset}" : '' ); | ||||
| 101 | |||||
| 102 | 368116 | 684ms | my $stmt = { | ||
| 103 | sql => $sql, | ||||
| 104 | bind => \@values, | ||||
| 105 | }; | ||||
| 106 | |||||
| 107 | 368116 | 2.38s | return $stmt; | ||
| 108 | } | ||||
| 109 | |||||
| 110 | sub update_stmt { | ||||
| 111 | my ($self, %args) = @_; | ||||
| 112 | |||||
| 113 | my $id = $args{id}; | ||||
| 114 | my $table = $args{table}; | ||||
| 115 | my $values = $args{values} || {}; | ||||
| 116 | my $where = $args{where}; | ||||
| 117 | |||||
| 118 | my @cols = keys %$values; | ||||
| 119 | my @values = values %$values; | ||||
| 120 | push @values, values %$where; | ||||
| 121 | |||||
| 122 | my $sql = join "\n", | ||||
| 123 | "UPDATE $table", | ||||
| 124 | "SET " . join(', ', map "$_=?", @cols), | ||||
| 125 | "WHERE " . join( ' AND ', map "$_=?", keys %$where ); | ||||
| 126 | |||||
| 127 | my $stmt = { | ||||
| 128 | sql => $sql, | ||||
| 129 | bind => \@values, | ||||
| 130 | }; | ||||
| 131 | |||||
| 132 | return $stmt; | ||||
| 133 | } | ||||
| 134 | |||||
| 135 | # spent 4.78s (4.21+564ms) within Test::PONAPI::Repository::MockDB::Table::_stmt_columns which was called 368116 times, avg 13µs/call:
# 368116 times (4.21s+564ms) by Test::PONAPI::Repository::MockDB::Table::select_stmt at line 85, avg 13µs/call | ||||
| 136 | 368116 | 135ms | my $self = shift; | ||
| 137 | 368116 | 94.8ms | my $args = shift; | ||
| 138 | 368116 | 467ms | my ( $fields, $type ) = @{$args}{qw< fields type >}; | ||
| 139 | |||||
| 140 | 368116 | 165ms | my $ref = ref $fields; | ||
| 141 | |||||
| 142 | 368116 | 1.22s | 187055 | 219ms | return [ $self->ID_COLUMN, @$fields ] if $ref eq 'ARRAY'; # spent 219ms making 187055 calls to Test::PONAPI::Repository::MockDB::Table::ID_COLUMN, avg 1µs/call |
| 143 | |||||
| 144 | 181061 | 1.38s | 150192 | 117ms | $ref eq 'HASH' and exists $fields->{$type} # spent 86.0ms making 74135 calls to Test::PONAPI::Repository::MockDB::Table::COLUMNS, avg 1µs/call
# spent 30.9ms making 76057 calls to Test::PONAPI::Repository::MockDB::Table::Articles::COLUMNS, avg 406ns/call |
| 145 | or return $self->COLUMNS; | ||||
| 146 | |||||
| 147 | my @fields_minus_relationship_keys = | ||||
| 148 | grep { !exists $self->RELATIONS->{$_} } | ||||
| 149 | 30869 | 186ms | 82744 | 125ms | @{ $fields->{$type} }; # spent 125ms making 82744 calls to Test::PONAPI::Repository::MockDB::Table::RELATIONS, avg 2µs/call |
| 150 | |||||
| 151 | 30869 | 309ms | 30869 | 103ms | return +[ $self->ID_COLUMN, @fields_minus_relationship_keys ]; # spent 103ms making 30869 calls to Test::PONAPI::Repository::MockDB::Table::ID_COLUMN, avg 3µs/call |
| 152 | } | ||||
| 153 | |||||
| 154 | # spent 7.22s (5.79+1.43) within Test::PONAPI::Repository::MockDB::Table::_stmt_filters which was called 368116 times, avg 20µs/call:
# 368116 times (5.79s+1.43s) by Test::PONAPI::Repository::MockDB::Table::select_stmt at line 75, avg 20µs/call | ||||
| 155 | 368116 | 159ms | my ( $self, $type, $filter ) = @_; | ||
| 156 | |||||
| 157 | 368116 | 755ms | 368116 | 773ms | return $filter if $self->TABLE ne $type; # spent 773ms making 368116 calls to Test::PONAPI::Repository::MockDB::Table::TABLE, avg 2µs/call |
| 158 | |||||
| 159 | return +{ | ||||
| 160 | map { $_ => $filter->{$_} } | ||||
| 161 | grep { exists $filter->{$_} } | ||||
| 162 | 368116 | 4.22s | 368116 | 660ms | @{ $self->COLUMNS } # spent 587ms making 275779 calls to Test::PONAPI::Repository::MockDB::Table::COLUMNS, avg 2µs/call
# spent 73.3ms making 92337 calls to Test::PONAPI::Repository::MockDB::Table::Articles::COLUMNS, avg 794ns/call |
| 163 | }; | ||||
| 164 | } | ||||
| 165 | |||||
| 166 | 1 | 5µs | 2 | 4.14ms | __PACKAGE__->meta->make_immutable; # spent 4.13ms making 1 call to Class::MOP::Class::make_immutable
# spent 12µs making 1 call to Test::PONAPI::Repository::MockDB::Table::meta |
| 167 | 3 | 49µs | 2 | 152µs | # spent 80µs (8+72) within Test::PONAPI::Repository::MockDB::Table::BEGIN@167 which was called:
# once (8µs+72µs) by Module::Runtime::require_module at line 167 # spent 80µs making 1 call to Test::PONAPI::Repository::MockDB::Table::BEGIN@167
# spent 72µs making 1 call to Moose::unimport |
| 168 | |||||
| 169 | __END__ |