remove DBIx::Custom::QueryBuilder::tag_syntax() ...
...(not backword compatible)
... | ... |
@@ -1,6 +1,8 @@ |
1 | 1 |
0.1605 |
2 |
- changed arguments of tag processor |
|
3 |
- remaned DBIx::Custom::QueryBuilder::TagProcessors functions |
|
2 |
+ remove DBIx::Custom::QueryBuilder::tag_syntax() (not backword compatible) |
|
3 |
+ renamed DBIx::Custom::TagProcessor to DBIx::Custom::TagProcessors (not backword compatible) |
|
4 |
+ changed arguments of tag processor(not backword compatible) |
|
5 |
+ renamed DBIx::Custom::QueryBuilder::TagProcessors functions(not backword compatible) |
|
4 | 6 |
0.1604 |
5 | 7 |
changed argument of tag processor(not backword compatible) |
6 | 8 |
renamed default_query_filter to default_bind_filter(not backword compatible) |
... | ... |
@@ -7,7 +7,7 @@ use base 'Object::Simple'; |
7 | 7 |
|
8 | 8 |
use Carp 'croak'; |
9 | 9 |
use DBIx::Custom::Query; |
10 |
-use DBIx::Custom::QueryBuilder::TagProcessor; |
|
10 |
+use DBIx::Custom::QueryBuilder::TagProcessors; |
|
11 | 11 |
|
12 | 12 |
__PACKAGE__->dual_attr('tag_processors', default => sub { {} }, inherit => 'hash_copy'); |
13 | 13 |
__PACKAGE__->register_tag_processor( |
... | ... |
@@ -27,28 +27,10 @@ __PACKAGE__->register_tag_processor( |
27 | 27 |
__PACKAGE__->attr(tag_start => '{'); |
28 | 28 |
__PACKAGE__->attr(tag_end => '}'); |
29 | 29 |
|
30 |
-__PACKAGE__->attr('tag_syntax' => <<'EOS'); |
|
31 |
-[tag] [expand] |
|
32 |
-{? NAME} ? |
|
33 |
-{= NAME} NAME = ? |
|
34 |
-{<> NAME} NAME <> ? |
|
35 |
- |
|
36 |
-{< NAME} NAME < ? |
|
37 |
-{> NAME} NAME > ? |
|
38 |
-{>= NAME} NAME >= ? |
|
39 |
-{<= NAME} NAME <= ? |
|
40 |
- |
|
41 |
-{like NAME} NAME like ? |
|
42 |
-{in NAME number} NAME in [?, ?, ..] |
|
43 |
- |
|
44 |
-{insert NAME1 NAME2} (NAME1, NAME2) values (?, ?) |
|
45 |
-{update NAME1 NAME2} set NAME1 = ?, NAME2 = ? |
|
46 |
-EOS |
|
47 |
- |
|
48 | 30 |
sub register_tag_processor { |
49 | 31 |
my $self = shift; |
50 | 32 |
|
51 |
- # Merge |
|
33 |
+ # Merge tag processor |
|
52 | 34 |
my $tag_processors = ref $_[0] eq 'HASH' ? $_[0] : {@_}; |
53 | 35 |
$self->tag_processors({%{$self->tag_processors}, %{$tag_processors}}); |
54 | 36 |
|
... | ... |
@@ -70,18 +52,26 @@ sub build_query { |
70 | 52 |
sub _parse { |
71 | 53 |
my ($self, $source) = @_; |
72 | 54 |
|
55 |
+ # Source |
|
73 | 56 |
$source ||= ''; |
74 | 57 |
|
58 |
+ # Tree |
|
75 | 59 |
my $tree = []; |
76 | 60 |
|
77 |
- # Tags |
|
61 |
+ # Start tag |
|
78 | 62 |
my $tag_start = quotemeta $self->tag_start; |
63 |
+ croak qq{tag_start must be a charactor} |
|
64 |
+ if !$tag_start || length $tag_start == 1; |
|
65 |
+ |
|
66 |
+ # End tag |
|
79 | 67 |
my $tag_end = quotemeta $self->tag_end; |
68 |
+ croak qq{tag_end must be a charactor} |
|
69 |
+ if !$tag_end || length $tag_end == 1; |
|
80 | 70 |
|
81 | 71 |
# Tokenize |
82 | 72 |
my $state = 'text'; |
83 | 73 |
|
84 |
- # Save original |
|
74 |
+ # Save original source |
|
85 | 75 |
my $original = $source; |
86 | 76 |
|
87 | 77 |
# Parse |
... | ... |
@@ -96,31 +86,27 @@ sub _parse { |
96 | 86 |
# Get tag name and arguments |
97 | 87 |
my ($tag_name, @tag_args) = split /\s+/, $tag; |
98 | 88 |
|
99 |
- # Tag processor is exist? |
|
100 |
- unless ($self->tag_processors->{$tag_name}) { |
|
101 |
- my $tag_syntax = $self->tag_syntax; |
|
102 |
- croak qq{Tag "{$tag}" is not registerd.\n\n} . |
|
103 |
- "<SQL builder syntax>\n" . |
|
104 |
- "$tag_syntax\n" . |
|
105 |
- "<Your source>\n" . |
|
106 |
- "$original\n\n"; |
|
107 |
- } |
|
89 |
+ # Tag processor not registerd |
|
90 |
+ croak qq{Tag "$tag" in "$original" is not registerd} |
|
91 |
+ unless $self->tag_processors->{$tag_name}; |
|
108 | 92 |
|
109 | 93 |
# Check tag arguments |
110 | 94 |
foreach my $tag_arg (@tag_args) { |
111 | 95 |
|
112 | 96 |
# Cannot cantain placehosder '?' |
113 |
- croak qq{Tag cannot contain "?"} |
|
97 |
+ croak qq{Tag cannot contains "?"} |
|
114 | 98 |
if $tag_arg =~ /\?/; |
115 | 99 |
} |
116 | 100 |
|
117 | 101 |
# Add tag to parsing tree |
118 |
- push @$tree, {type => 'tag', tag_name => $tag_name, tag_args => [@tag_args]}; |
|
102 |
+ push @$tree, {type => 'tag', tag_name => $tag_name, |
|
103 |
+ tag_args => [@tag_args]}; |
|
119 | 104 |
} |
120 | 105 |
} |
121 | 106 |
|
122 | 107 |
# Add text to parsing tree |
123 |
- push @$tree, {type => 'text', tag_args => [$source]} if $source; |
|
108 |
+ push @$tree, {type => 'text', tag_args => [$source]} |
|
109 |
+ if $source; |
|
124 | 110 |
|
125 | 111 |
return $tree; |
126 | 112 |
} |
... | ... |
@@ -154,26 +140,26 @@ sub _build_query { |
154 | 140 |
# Get tag processor |
155 | 141 |
my $tag_processor = $self->tag_processors->{$tag_name}; |
156 | 142 |
|
157 |
- # Tag processor is code ref? |
|
158 |
- croak qq{Tag processor "$tag_name" must be code reference} |
|
143 |
+ # Tag processor not sub reference |
|
144 |
+ croak qq{Tag processor "$tag_name" must be sub reference} |
|
159 | 145 |
unless ref $tag_processor eq 'CODE'; |
160 | 146 |
|
161 |
- # Expand tag using tag processor |
|
162 |
- my ($expand, $columns) = @{$tag_processor->(@$tag_args)}; |
|
147 |
+ # Execute tag processor |
|
148 |
+ my ($part, $columns) = @{$tag_processor->(@$tag_args)}; |
|
163 | 149 |
|
164 | 150 |
# Check tag processor return value |
165 |
- croak qq{Tag processor "$tag_name" must return [\$expand, \$columns]} |
|
166 |
- if !defined $expand || ref $columns ne 'ARRAY'; |
|
151 |
+ croak qq{Tag processor "$tag_name" must return [STRING, ARRAY_REFERENCE]} |
|
152 |
+ if !defined $part || ref $columns ne 'ARRAY'; |
|
167 | 153 |
|
168 | 154 |
# Check placeholder count |
169 |
- croak qq{Count of Placeholder must be same as count of columns in "$tag_name"} |
|
170 |
- unless $self->_placeholder_count($expand) eq @$columns; |
|
155 |
+ croak qq{Count of Placeholders must be same as count of columns in "$tag_name"} |
|
156 |
+ unless $self->_placeholder_count($part) eq @$columns; |
|
171 | 157 |
|
172 | 158 |
# Add columns |
173 | 159 |
push @$all_columns, @$columns; |
174 | 160 |
|
175 |
- # Join expand tag to SQL |
|
176 |
- $sql .= $expand; |
|
161 |
+ # Join part tag to SQL |
|
162 |
+ $sql .= $part; |
|
177 | 163 |
} |
178 | 164 |
} |
179 | 165 |
|
... | ... |
@@ -208,11 +194,9 @@ DBIx::Custom::QueryBuilder - Query builder |
208 | 194 |
=head1 SYNOPSIS |
209 | 195 |
|
210 | 196 |
my $builder = DBIx::Custom::QueryBuilder->new; |
211 |
- |
|
212 |
- my $source = "select from table {= k1} && {<> k2} || {like k3}"; |
|
213 |
- my $param = {k1 => 1, k2 => 2, k3 => 3}; |
|
214 |
- |
|
215 |
- my $query = $sql_builder->build_query($source); |
|
197 |
+ my $query = $builder->build_query( |
|
198 |
+ "select from table {= k1} && {<> k2} || {like k3}" |
|
199 |
+ ); |
|
216 | 200 |
|
217 | 201 |
=head1 ATTRIBUTES |
218 | 202 |
|
... | ... |
@@ -228,77 +212,66 @@ Tag processors. |
228 | 212 |
my $tag_start = $builder->tag_start; |
229 | 213 |
$builder = $builder->tag_start('{'); |
230 | 214 |
|
231 |
-String of tag start. |
|
232 |
-Default to '{' |
|
215 |
+Tag start charactor. |
|
216 |
+Default to '{'. |
|
233 | 217 |
|
234 | 218 |
=head2 C<tag_end> |
235 | 219 |
|
236 | 220 |
my $tag_end = $builder->tag_start; |
237 | 221 |
$builder = $builder->tag_start('}'); |
238 | 222 |
|
239 |
-String of tag end. |
|
240 |
-Default to '}' |
|
241 |
- |
|
242 |
-=head2 C<tag_syntax> |
|
223 |
+Tag end charactor. |
|
224 |
+Default to '}'. |
|
243 | 225 |
|
244 |
- my $tag_syntax = $builder->tag_syntax; |
|
245 |
- $builder = $builder->tag_syntax($tag_syntax); |
|
246 |
- |
|
247 |
-Tag syntax. |
|
248 |
- |
|
249 | 226 |
=head1 METHODS |
250 | 227 |
|
251 |
-This class is L<Object::Simple> subclass. |
|
252 |
-You can use all methods of L<Object::Simple> |
|
253 |
- |
|
254 |
-=head2 C<new> |
|
255 |
- |
|
256 |
- my $builder = DBIx::Custom::SQLBuilder->new; |
|
257 |
- my $builder = DBIx::Custom::SQLBuilder->new(%attrs); |
|
258 |
- my $builder = DBIx::Custom::SQLBuilder->new(\%attrs); |
|
259 |
- |
|
260 |
-Create a instance. |
|
228 |
+L<DBIx::Custom::QueryBuilder> inherits all methods from L<Object::Simple> |
|
229 |
+and implements the following new ones. |
|
261 | 230 |
|
262 | 231 |
=head2 C<build_query> |
263 | 232 |
|
264 | 233 |
my $query = $builder->build_query($source); |
265 | 234 |
|
266 |
-Build L<DBIx::Custom::Query> object. |
|
235 |
+Create a new L<DBIx::Custom::Query> object from SQL source. |
|
236 |
+SQL source contains tags, such as {= title}, {like author}. |
|
267 | 237 |
|
268 | 238 |
B<Example:> |
269 | 239 |
|
270 |
-Source: |
|
240 |
+SQL source |
|
271 | 241 |
|
272 |
- my $query = $builder->build_query( |
|
273 |
- "select * from table where {= title} && {like author} || {<= price}") |
|
242 |
+ "select * from table where {= title} && {like author} || {<= price}" |
|
274 | 243 |
|
275 |
-Query: |
|
244 |
+Query |
|
276 | 245 |
|
277 |
- $qeury->sql : "select * from table where title = ? && author like ? price <= ?;" |
|
278 |
- $query->columns : ['title', 'author', 'price'] |
|
246 |
+ { |
|
247 |
+ sql => "select * from table where title = ? && author like ? price <= ?;" |
|
248 |
+ columns => ['title', 'author', 'price'] |
|
249 |
+ } |
|
279 | 250 |
|
280 | 251 |
=head2 C<register_tag_processor> |
281 | 252 |
|
282 |
- $builder = $builder->register_tag_processor($tag_processor); |
|
253 |
+ $builder->register_tag_processor(\%tag_processors); |
|
254 |
+ $builder->register_tag_processor(%tag_processors); |
|
283 | 255 |
|
284 | 256 |
Register tag processor. |
285 | 257 |
|
258 |
+B<Examples:> |
|
259 |
+ |
|
286 | 260 |
$builder->register_tag_processor( |
287 | 261 |
'?' => sub { |
288 |
- my $args = shift; |
|
262 |
+ my $column = shift; |
|
289 | 263 |
|
290 |
- # Do something |
|
291 |
- |
|
292 |
- # Expanded tag and column names |
|
293 |
- return ($expand, $columns); |
|
264 |
+ return ['?', [$column]]; |
|
294 | 265 |
} |
295 | 266 |
); |
296 | 267 |
|
297 |
-Tag processor receive arguments in tags |
|
298 |
-and must return expanded tag and column names. |
|
268 |
+See L<DBIx::Custom::QueryBuilder::TagProcessors> about tag processor. |
|
299 | 269 |
|
300 | 270 |
=head1 Tags |
301 | 271 |
|
272 |
+You can use the following tags in SQL source. |
|
273 |
+ |
|
274 |
+ [Tags] [Replaced] |
|
302 | 275 |
{? NAME} -> ? |
303 | 276 |
{= NAME} -> NAME = ? |
304 | 277 |
{<> NAME} -> NAME <> ? |
... | ... |
@@ -311,5 +284,5 @@ and must return expanded tag and column names. |
311 | 284 |
{like NAME} -> NAME like ? |
312 | 285 |
{in NAME COUNT} -> NAME in [?, ?, ..] |
313 | 286 |
|
314 |
- {insert NAME1 NAME2 NAME3} -> (NAME1, NAME2, NAME3) values (?, ?, ?) |
|
315 |
- {update NAME1 NAME2 NAME3} -> set NAME1 = ?, NAME2 = ?, NAME3 = ? |
|
287 |
+ {insert NAME1 NAME2} -> (NAME1, NAME2) values (?, ?) |
|
288 |
+ {update NAME1 NAME2} -> set NAME1 = ?, NAME2 = ? |