Simplify key search
|
1 |
use strict; |
2 |
use warnings; |
|
3 | ||
4 |
use Test::More 'no_plan'; |
|
5 | ||
6 |
use DBIx::Custom::SQL::Template; |
|
7 | ||
8 |
# Function for test name |
|
9 |
my $test; |
|
10 |
sub test{ |
|
11 |
$test = shift; |
|
12 |
} |
|
13 | ||
14 |
# Variable for test |
|
15 |
my $datas; |
|
16 |
my $sql_tmpl; |
|
17 |
my $query; |
|
18 |
my $ret_val; |
|
19 |
my $clone; |
|
20 | ||
21 |
test "Various template pattern"; |
|
22 |
$datas = [ |
|
23 |
# Basic tests |
|
24 |
{ name => 'placeholder basic', |
|
25 |
tmpl => "a {? k1} b {= k2} {<> k3} {> k4} {< k5} {>= k6} {<= k7} {like k8}", , |
|
26 |
sql_expected => "a ? b k2 = ? k3 <> ? k4 > ? k5 < ? k6 >= ? k7 <= ? k8 like ?;", |
|
27 |
key_infos_expected => [ |
|
28 |
{original_key => 'k1', table => '', column => 'k1', access_keys => [['k1']]}, |
|
29 |
{original_key => 'k2', table => '', column => 'k2', access_keys => [['k2']]}, |
|
30 |
{original_key => 'k3', table => '', column => 'k3', access_keys => [['k3']]}, |
|
31 |
{original_key => 'k4', table => '', column => 'k4', access_keys => [['k4']]}, |
|
32 |
{original_key => 'k5', table => '', column => 'k5', access_keys => [['k5']]}, |
|
33 |
{original_key => 'k6', table => '', column => 'k6', access_keys => [['k6']]}, |
|
34 |
{original_key => 'k7', table => '', column => 'k7', access_keys => [['k7']]}, |
|
35 |
{original_key => 'k8', table => '', column => 'k8', access_keys => [['k8']]}, |
|
36 |
], |
|
37 |
}, |
|
38 |
{ |
|
39 |
name => 'placeholder in', |
|
40 |
tmpl => "{in k1 3};", |
|
41 |
sql_expected => "k1 in (?, ?, ?);", |
|
42 |
key_infos_expected => [ |
|
43 |
{original_key => 'k1', table => '', column => 'k1', access_keys => [['k1', [0]]]}, |
|
44 |
{original_key => 'k1', table => '', column => 'k1', access_keys => [['k1', [1]]]}, |
|
45 |
{original_key => 'k1', table => '', column => 'k1', access_keys => [['k1', [2]]]}, |
|
46 |
], |
|
47 |
}, |
|
48 |
|
|
49 |
# Table name |
|
50 |
{ |
|
51 |
name => 'placeholder with table name', |
|
52 |
tmpl => "{= a.k1} {= a.k2}", |
|
53 |
sql_expected => "a.k1 = ? a.k2 = ?;", |
|
54 |
key_infos_expected => [ |
|
55 |
{original_key => 'a.k1', table => 'a', column => 'k1', access_keys => [['a.k1'], ['a', 'k1']]}, |
|
56 |
{original_key => 'a.k2', table => 'a', column => 'k2', access_keys => [['a.k2'], ['a', 'k2']]}, |
|
57 |
], |
|
58 |
}, |
|
59 |
{ |
|
60 |
name => 'placeholder in with table name', |
|
61 |
tmpl => "{in a.k1 2} {in b.k2 2}", |
|
62 |
sql_expected => "a.k1 in (?, ?) b.k2 in (?, ?);", |
|
63 |
key_infos_expected => [ |
|
64 |
{original_key => 'a.k1', table => 'a', column => 'k1', access_keys => [['a.k1', [0]], ['a', 'k1', [0]]]}, |
|
65 |
{original_key => 'a.k1', table => 'a', column => 'k1', access_keys => [['a.k1', [1]], ['a', 'k1', [1]]]}, |
|
66 |
{original_key => 'b.k2', table => 'b', column => 'k2', access_keys => [['b.k2', [0]], ['b', 'k2', [0]]]}, |
|
67 |
{original_key => 'b.k2', table => 'b', column => 'k2', access_keys => [['b.k2', [1]], ['b', 'k2', [1]]]}, |
|
68 |
], |
|
69 |
}, |
|
70 |
{ |
|
71 |
name => 'not contain tag', |
|
72 |
tmpl => "aaa", |
|
73 |
sql_expected => "aaa;", |
|
74 |
key_infos_expected => [], |
|
75 |
} |
|
76 |
]; |
|
77 | ||
78 |
for (my $i = 0; $i < @$datas; $i++) { |
|
79 |
my $data = $datas->[$i]; |
|
80 |
my $sql_tmpl = DBIx::Custom::SQL::Template->new; |
|
81 |
my $query = $sql_tmpl->create_query($data->{tmpl}); |
|
82 |
is($query->{sql}, $data->{sql_expected}, "$test : $data->{name} : sql"); |
|
83 |
is_deeply($query->{key_infos}, $data->{key_infos_expected}, "$test : $data->{name} : key_infos"); |
|
84 |
} |
|
85 | ||
86 | ||
87 |
test 'Original tag processor'; |
|
88 |
$sql_tmpl = DBIx::Custom::SQL::Template->new; |
|
89 | ||
90 |
$ret_val = $sql_tmpl->add_tag_processor( |
|
91 |
p => sub { |
|
92 |
my ($tag_name, $args) = @_; |
|
93 |
|
|
94 |
my $expand = "$tag_name ? $args->[0] $args->[1]"; |
|
95 |
my $key_infos = [2]; |
|
96 |
return ($expand, $key_infos); |
|
97 |
} |
|
98 |
); |
|
99 | ||
100 |
$query = $sql_tmpl->create_query("{p a b}"); |
|
101 |
is($query->{sql}, "p ? a b;", "$test : add_tag_processor sql"); |
|
102 |
is_deeply($query->{key_infos}, [2], "$test : add_tag_processor key_infos"); |
|
103 |
isa_ok($ret_val, 'DBIx::Custom::SQL::Template'); |
|
104 | ||
105 | ||
106 |
test "Tag processor error case"; |
|
107 |
$sql_tmpl = DBIx::Custom::SQL::Template->new; |
|
108 | ||
109 | ||
110 |
eval{$sql_tmpl->create_query("{a }")}; |
|
111 |
like($@, qr/Tag '{a }' in SQL template is not exist/, "$test : tag_processor not exist"); |
|
112 | ||
113 |
$sql_tmpl->add_tag_processor({ |
|
114 |
q => 'string' |
|
115 |
}); |
|
116 | ||
117 |
eval{$sql_tmpl->create_query("{q}", {})}; |
|
118 |
like($@, qr/Tag processor 'q' must be code reference/, "$test : tag_processor not code ref"); |
|
119 | ||
120 |
$sql_tmpl->add_tag_processor({ |
|
121 |
r => sub {} |
|
122 |
}); |
|
123 | ||
124 |
eval{$sql_tmpl->create_query("{r}")}; |
|
125 |
like($@, qr/\QTag processor 'r' must return (\E\$expand\Q, \E\$key_infos\Q)/, "$test : tag processor return noting"); |
|
126 | ||
127 |
$sql_tmpl->add_tag_processor({ |
|
128 |
s => sub { return ("a", "")} |
|
129 |
}); |
|
130 | ||
131 |
eval{$sql_tmpl->create_query("{s}")}; |
|
132 |
like($@, qr/\QTag processor 's' must return (\E\$expand\Q, \E\$key_infos\Q)/, "$test : tag processor return not array key_infos"); |
|
133 | ||
134 |
$sql_tmpl->add_tag_processor( |
|
135 |
t => sub {return ("a", [])} |
|
136 |
); |
|
137 | ||
138 |
eval{$sql_tmpl->create_query("{t ???}")}; |
|
139 |
like($@, qr/Tag '{t }' arguments cannot contain '?'/, "$test : cannot contain '?' in tag argument"); |
|
140 | ||
141 | ||
142 |
test 'General error case'; |
|
143 |
$sql_tmpl = DBIx::Custom::SQL::Template->new; |
|
144 |
$sql_tmpl->add_tag_processor( |
|
145 |
a => sub { |
|
146 |
return ("? ? ?", [[],[]]); |
|
147 |
} |
|
148 |
); |
|
149 |
eval{$sql_tmpl->create_query("{a}")}; |
|
150 |
like($@, qr/Placeholder count in SQL created by tag processor 'a' must be same as key informations count/, "$test placeholder count is invalid"); |
|
151 | ||
152 | ||
153 |
test 'Default tag processor Error case'; |
|
154 |
eval{$sql_tmpl->create_query("{= }")}; |
|
155 |
like($@, qr/You must be pass key as argument to tag '{= }'/, "$test : basic '=' : key not exist"); |
|
156 | ||
157 |
eval{$sql_tmpl->create_query("{in }")}; |
|
158 |
like($@, qr/You must be pass key as first argument of tag '{in }'/, "$test : in : key not exist"); |
|
159 | ||
160 |
eval{$sql_tmpl->create_query("{in a}")}; |
|
161 |
like($@, qr/\QYou must be pass placeholder count as second argument of tag '{in }'\E\n\QUsage: {in \E\$key\Q \E\$placeholder_count\Q}/, |
|
162 |
"$test : in : key not exist"); |
|
163 | ||
164 |
eval{$sql_tmpl->create_query("{in a r}")}; |
|
165 |
like($@, qr/\QYou must be pass placeholder count as second argument of tag '{in }'\E\n\QUsage: {in \E\$key\Q \E\$placeholder_count\Q}/, |
|
166 |
"$test : in : key not exist"); |
|
167 | ||
168 | ||
169 |
test 'Clone'; |
|
170 |
$sql_tmpl = DBIx::Custom::SQL::Template->new; |
|
171 |
$sql_tmpl |
|
172 |
->tag_start('[') |
|
173 |
->tag_end(']') |
|
174 |
->tag_syntax('syntax') |
|
175 |
->tag_processors({a => 1, b => 2}); |
|
176 | ||
177 |
$clone = $sql_tmpl->clone; |
|
178 |
is($clone->tag_start, $sql_tmpl->tag_start, "$test : tag_start"); |
|
179 |
is($clone->tag_end, $sql_tmpl->tag_end, "$test : tag_end"); |
|
180 |
is($clone->tag_syntax, $sql_tmpl->tag_syntax, "$test : tag_syntax"); |
|
181 | ||
182 |
is_deeply( scalar $clone->tag_processors, scalar $sql_tmpl->tag_processors, |
|
183 |
"$test : tag_processors deep clone"); |
|
184 | ||
185 |
isnt($clone->tag_processors, $sql_tmpl->tag_processors, |
|
186 |
"$test : tag_processors reference not copy"); |
|
187 | ||
188 |
$sql_tmpl->tag_processors(undef); |
|
189 | ||
190 |
$clone = $sql_tmpl->clone; |
|
191 |
is_deeply(scalar $clone->tag_processors, {}, "$test tag_processor undef copy"); |
|
192 | ||
193 | ||
194 | ||
195 |
__END__ |
|
196 | ||
197 | ||
198 |