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 = ?
|