| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package FU::SQL 1.4; |
|
2
|
2
|
|
|
2
|
|
273424
|
use v5.36; |
|
|
2
|
|
|
|
|
17
|
|
|
3
|
2
|
|
|
2
|
|
13
|
use Exporter 'import'; |
|
|
2
|
|
|
|
|
5
|
|
|
|
2
|
|
|
|
|
89
|
|
|
4
|
2
|
|
|
2
|
|
24
|
use Carp 'confess'; |
|
|
2
|
|
|
|
|
4
|
|
|
|
2
|
|
|
|
|
124
|
|
|
5
|
2
|
|
|
2
|
|
1048
|
use experimental 'builtin', 'for_list'; |
|
|
2
|
|
|
|
|
9473
|
|
|
|
2
|
|
|
|
|
34
|
|
|
6
|
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
our @EXPORT = qw/ |
|
8
|
|
|
|
|
|
|
P RAW IDENT SQL |
|
9
|
|
|
|
|
|
|
PARENS INTERSPERSE COMMA |
|
10
|
|
|
|
|
|
|
AND OR WHERE |
|
11
|
|
|
|
|
|
|
SET VALUES IN |
|
12
|
|
|
|
|
|
|
/; |
|
13
|
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
|
|
15
|
95
|
|
|
95
|
|
368
|
sub _obj { bless [@_], 'FU::SQL::val' } |
|
16
|
|
|
|
|
|
|
|
|
17
|
52
|
|
|
52
|
1
|
80316
|
sub P :prototype($) ($p) { bless \(my $x = $p), 'FU::SQL::p' } |
|
|
52
|
|
|
|
|
53
|
|
|
|
52
|
|
|
|
|
39
|
|
|
|
52
|
|
|
|
|
138
|
|
|
18
|
11
|
|
|
11
|
1
|
30
|
sub RAW :prototype($) ($s) { _obj "$s" } |
|
|
11
|
|
|
|
|
20
|
|
|
|
11
|
|
|
|
|
13
|
|
|
|
11
|
|
|
|
|
25
|
|
|
19
|
16
|
|
|
16
|
1
|
17
|
sub IDENT :prototype($) ($s) { bless \(my $x = "$s"), 'FU::SQL::i' } |
|
|
16
|
|
|
|
|
20
|
|
|
|
16
|
|
|
|
|
13
|
|
|
|
16
|
|
|
|
|
70
|
|
|
20
|
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
# These operate on $_ and must be called with &func syntax. |
|
22
|
|
|
|
|
|
|
# The readonly check can be finicky. |
|
23
|
243
|
100
|
|
243
|
|
838
|
sub _israw { builtin::created_as_string($_) && Internals::SvREADONLY($_) } |
|
24
|
243
|
100
|
|
243
|
|
245
|
sub _tosql { &_israw ? "$_" : ref($_) =~ /^FU::SQL::/ ? $_ : P $_ } |
|
|
|
100
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
|
|
26
|
62
|
|
|
62
|
1
|
2368
|
sub SQL { _obj map &_tosql, @_ } |
|
27
|
18
|
|
|
18
|
1
|
28
|
sub PARENS { SQL '(', @_, ')' } |
|
28
|
22
|
100
|
|
22
|
1
|
38
|
sub INTERSPERSE { my @a = map &_tosql, @_; _obj map $_ > 1 ? ($a[0],$a[$_]) : $a[$_], 1..$#a } |
|
|
22
|
|
|
|
|
81
|
|
|
29
|
12
|
|
|
12
|
1
|
19
|
sub COMMA { INTERSPERSE ',', @_ } |
|
30
|
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
sub _conditions { |
|
32
|
|
|
|
|
|
|
@_ == 1 && ref $_[0] eq 'HASH' |
|
33
|
|
|
|
|
|
|
? map PARENS(IDENT $_, |
|
34
|
|
|
|
|
|
|
!defined $_[0]{$_} ? ('IS NULL') : |
|
35
|
|
|
|
|
|
|
ref($_[0]{$_}) eq 'FU::SQL::in' ? ($_[0]{$_}) |
|
36
|
8
|
100
|
66
|
8
|
|
44
|
: ('=', $_[0]{$_}) |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
), sort keys $_[0]->%* |
|
38
|
|
|
|
|
|
|
: map PARENS($_), @_ |
|
39
|
|
|
|
|
|
|
} |
|
40
|
|
|
|
|
|
|
|
|
41
|
9
|
100
|
66
|
9
|
1
|
63
|
sub AND { !@_ || (@_ == 1 && ref $_[0] eq 'HASH' && keys $_[0]->%* == 0) ? RAW '1=1' : INTERSPERSE 'AND', _conditions @_ } |
|
42
|
3
|
100
|
100
|
3
|
1
|
23
|
sub OR { !@_ || (@_ == 1 && ref $_[0] eq 'HASH' && keys $_[0]->%* == 0) ? RAW '1=0' : INTERSPERSE 'OR', _conditions @_ } |
|
43
|
7
|
|
|
7
|
1
|
16
|
sub WHERE { SQL 'WHERE', AND @_ } |
|
44
|
|
|
|
|
|
|
|
|
45
|
2
|
|
|
2
|
1
|
3
|
sub SET($h) { SQL 'SET', COMMA map SQL(IDENT $_, '=', $h->{$_}), sort keys %$h } |
|
|
2
|
|
|
|
|
3
|
|
|
|
2
|
|
|
|
|
2
|
|
|
|
2
|
|
|
|
|
11
|
|
|
46
|
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
sub VALUES { |
|
48
|
|
|
|
|
|
|
@_ == 1 && ref $_[0] eq 'HASH' |
|
49
|
6
|
100
|
100
|
6
|
1
|
46
|
? SQL '(', COMMA(map IDENT $_, sort keys $_[0]->%*), ') VALUES (', COMMA(map $_[0]{$_}, sort keys $_[0]->%*), ')' |
|
|
|
100
|
100
|
|
|
|
|
|
50
|
|
|
|
|
|
|
: @_ == 1 && ref $_[0] eq 'ARRAY' |
|
51
|
|
|
|
|
|
|
? SQL 'VALUES (', COMMA($_[0]->@*), ')' |
|
52
|
|
|
|
|
|
|
: SQL 'VALUES (', COMMA(@_), ')'; |
|
53
|
|
|
|
|
|
|
} |
|
54
|
|
|
|
|
|
|
|
|
55
|
4
|
|
|
4
|
1
|
6
|
sub IN :prototype($) ($a) { |
|
|
4
|
|
|
|
|
4
|
|
|
|
4
|
|
|
|
|
6
|
|
|
56
|
4
|
50
|
|
|
|
10
|
confess "Expected arrayref" if ref $a ne 'ARRAY'; |
|
57
|
4
|
|
|
|
|
27
|
bless \$a, 'FU::SQL::in' |
|
58
|
|
|
|
|
|
|
} |
|
59
|
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
|
|
62
|
94
|
|
|
94
|
|
103
|
sub FU::SQL::val::_compile($self, $opt, $sql, $params) { |
|
|
94
|
|
|
|
|
86
|
|
|
|
94
|
|
|
|
|
77
|
|
|
|
94
|
|
|
|
|
99
|
|
|
|
94
|
|
|
|
|
75
|
|
|
|
94
|
|
|
|
|
60
|
|
|
63
|
94
|
|
|
|
|
129
|
for (@$self) { |
|
64
|
259
|
100
|
100
|
|
|
635
|
$$sql .= ' ' if length $$sql && $$sql !~ /\s$/; |
|
65
|
259
|
100
|
|
|
|
351
|
if (ref $_) { $_->_compile($opt, $sql, $params); } |
|
|
121
|
|
|
|
|
161
|
|
|
66
|
138
|
|
|
|
|
171
|
else { $$sql .= $_; } |
|
67
|
|
|
|
|
|
|
} |
|
68
|
|
|
|
|
|
|
} |
|
69
|
|
|
|
|
|
|
|
|
70
|
61
|
|
|
61
|
|
61
|
sub FU::SQL::p::_compile($self, $opt, $sql, $params) { |
|
|
61
|
|
|
|
|
48
|
|
|
|
61
|
|
|
|
|
39
|
|
|
|
61
|
|
|
|
|
70
|
|
|
|
61
|
|
|
|
|
55
|
|
|
|
61
|
|
|
|
|
41
|
|
|
71
|
61
|
|
|
|
|
78
|
push @$params, $$self; |
|
72
|
61
|
100
|
|
|
|
1983
|
$$sql .= $opt->{placeholder_style} eq 'pg' ? '$'.@$params : '?'; |
|
73
|
|
|
|
|
|
|
} |
|
74
|
|
|
|
|
|
|
|
|
75
|
16
|
|
|
16
|
|
16
|
sub FU::SQL::i::_compile($self, $opt, $sql, $params) { |
|
|
16
|
|
|
|
|
14
|
|
|
|
16
|
|
|
|
|
15
|
|
|
|
16
|
|
|
|
|
11
|
|
|
|
16
|
|
|
|
|
15
|
|
|
|
16
|
|
|
|
|
12
|
|
|
76
|
16
|
100
|
|
|
|
38
|
$$sql .= $opt->{quote_identifier} ? $opt->{quote_identifier}->($$self) : $$self; |
|
77
|
|
|
|
|
|
|
} |
|
78
|
|
|
|
|
|
|
|
|
79
|
4
|
|
|
4
|
|
6
|
sub FU::SQL::in::_compile($self, $opt, $sql, $params) { |
|
|
4
|
|
|
|
|
4
|
|
|
|
4
|
|
|
|
|
5
|
|
|
|
4
|
|
|
|
|
3
|
|
|
|
4
|
|
|
|
|
5
|
|
|
|
4
|
|
|
|
|
6
|
|
|
80
|
4
|
100
|
|
|
|
8
|
if ($opt->{in_style} eq 'pg') { |
|
81
|
2
|
|
|
|
|
5
|
$$sql .= '= ANY('; |
|
82
|
2
|
|
|
|
|
6
|
FU::SQL::p::_compile($self, $opt, $sql, $params); |
|
83
|
2
|
|
|
|
|
4
|
$$sql .= ')'; |
|
84
|
|
|
|
|
|
|
} else { |
|
85
|
2
|
|
|
|
|
4
|
$$sql .= 'IN('; |
|
86
|
2
|
|
|
|
|
8
|
for my($i,$v) (builtin::indexed @$$self) { |
|
87
|
7
|
100
|
|
|
|
11
|
$$sql .= ',' if $i; |
|
88
|
7
|
|
|
|
|
9
|
FU::SQL::p::_compile(\$v, $opt, $sql, $params); |
|
89
|
|
|
|
|
|
|
} |
|
90
|
2
|
|
|
|
|
4
|
$$sql .= ')'; |
|
91
|
|
|
|
|
|
|
} |
|
92
|
|
|
|
|
|
|
} |
|
93
|
|
|
|
|
|
|
|
|
94
|
46
|
|
|
46
|
|
306
|
sub FU::SQL::val::compile($self, %opt) { |
|
|
46
|
|
|
|
|
45
|
|
|
|
46
|
|
|
|
|
57
|
|
|
|
46
|
|
|
|
|
41
|
|
|
95
|
46
|
|
66
|
|
|
358
|
!/^(placeholder_style|in_style|quote_identifier)$/ && confess "Unknown flag: $_" for keys %opt; |
|
96
|
45
|
|
100
|
|
|
157
|
$opt{placeholder_style} ||= 'dbi'; |
|
97
|
45
|
|
100
|
|
|
121
|
$opt{in_style} ||= 'dbi'; |
|
98
|
45
|
|
|
|
|
85
|
my($sql, @params) = (''); |
|
99
|
45
|
|
|
|
|
115
|
$self->_compile(\%opt, \$sql, \@params); |
|
100
|
45
|
|
|
|
|
164
|
($sql, \@params) |
|
101
|
|
|
|
|
|
|
} |
|
102
|
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
*FU::SQL::p::compile = *FU::SQL::i::compile = *FU::SQL::in::compile = \*FU::SQL::val::compile; |
|
104
|
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
1; |
|
106
|
|
|
|
|
|
|
__END__ |