DBIx-Custom / lib / DBIx / Custom / QueryBuilder.pm /
Newer Older
296 lines | 8.429kb
renamed default_query_filter...
yuki-kimoto authored on 2010-08-03
1
package DBIx::Custom::QueryBuilder;
2

            
updatedd pod
Yuki Kimoto authored on 2011-06-12
3
use Object::Simple -base;
renamed default_query_filter...
yuki-kimoto authored on 2010-08-03
4

            
5
use Carp 'croak';
6
use DBIx::Custom::Query;
cleanup
Yuki Kimoto authored on 2011-04-25
7
use DBIx::Custom::Util '_subname';
renamed default_query_filter...
yuki-kimoto authored on 2010-08-03
8

            
fixed Carp trast relationshi...
yuki-kimoto authored on 2010-08-12
9
# Carp trust relationship
10
push @DBIx::Custom::CARP_NOT, __PACKAGE__;
updated document
Yuki Kimoto authored on 2011-01-20
11
push @DBIx::Custom::Where::CARP_NOT, __PACKAGE__;
12

            
cleanup
yuki-kimoto authored on 2010-10-17
13
sub build_query {
micro optimization
Yuki Kimoto authored on 2011-10-24
14
    my ($self, $sql) = @_;
- update_param_tag is DEPREC...
Yuki Kimoto authored on 2011-06-07
15
    
16
    # Parse tag. tag is DEPRECATED!
cleanup
Yuki Kimoto authored on 2011-11-16
17
    if ($self->dbi->{tag_parse} && $sql =~ /(\s|^)\{/) {
micro optimization
Yuki Kimoto authored on 2011-10-24
18
        my $query = $self->_parse_tag($sql);
- update_param_tag is DEPREC...
Yuki Kimoto authored on 2011-06-07
19
        my $tag_count = delete $query->{tag_count};
fixed DEPRECATED message bug
Yuki Kimoto authored on 2011-06-10
20
        warn qq/Tag system such as {? name} is DEPRECATED! / .
21
             qq/use parameter system such as :name instead/
- update_param_tag is DEPREC...
Yuki Kimoto authored on 2011-06-07
22
          if $tag_count;
23
        my $query2 = $self->_parse_parameter($query->sql);
24
        $query->sql($query2->sql);
25
        for (my $i =0; $i < @{$query->columns}; $i++) {
26
            my $column = $query->columns->[$i];
27
            if ($column eq 'RESERVED_PARAMETER') {
28
                my $column2 = shift @{$query2->columns};
29
                croak ":name syntax is wrong"
30
                  unless defined $column2;
31
                $query->columns->[$i] = $column2;
32
            }
33
        }
micro optimization
Yuki Kimoto authored on 2011-10-24
34
        return $query;
- update_param_tag is DEPREC...
Yuki Kimoto authored on 2011-06-07
35
    }
cleanup
yuki-kimoto authored on 2010-10-17
36
    
micro optimization
Yuki Kimoto authored on 2011-10-24
37
    $sql ||= '';
38
    my $columns = [];
39
    my $c = ($self->{dbi} || {})->{safety_character}
40
      || $self->dbi->safety_character;
41
    # Parameter regex
42
    $sql =~ s/([0-9]):/$1\\:/g;
43
    while ($sql =~ /(^|.*?[^\\]):([$c\.]+)(?:\{(.*?)\})?(.*)/sg) {
44
        push @$columns, $2;
45
        $sql = defined $3 ? "$1$2 $3 ?$4" : "$1?$4";
46
    }
47
    $sql =~ s/\\:/:/g if index($sql, "\\:") != -1;
48

            
49
    # Create query
cleanup
Yuki Kimoto authored on 2011-11-16
50
    return {sql => $sql, columns => $columns, duplicate => 1};
cleanup
yuki-kimoto authored on 2010-10-17
51
}
52

            
cleanup
Yuki Kimoto authored on 2011-10-24
53
# DEPRECATED!
- update_param_tag is DEPREC...
Yuki Kimoto authored on 2011-06-07
54
sub _parse_parameter {
55
    my ($self, $source) = @_;
fixed named placeholder bug ...
Yuki Kimoto authored on 2011-08-01
56
    
- update_param_tag is DEPREC...
Yuki Kimoto authored on 2011-06-07
57
    # Get and replace parameters
58
    my $sql = $source || '';
59
    my $columns = [];
removed undocumented DBIx::C...
Yuki Kimoto authored on 2011-08-02
60
    my $c = $self->dbi->safety_character;
cleanup
Yuki Kimoto authored on 2011-07-29
61
    # Parameter regex
fixed named placeholder bug ...
Yuki Kimoto authored on 2011-08-01
62
    $sql =~ s/([^:]):(\d+):([^:])/$1\\:$2\\:$3/g;
63
    my $re = qr/(^|.*?[^\\]):([$c\.]+)(?:\{(.*?)\})?(.*)/s;
cleanup
Yuki Kimoto authored on 2011-07-29
64
    while ($sql =~ /$re/g) {
- update_param_tag is DEPREC...
Yuki Kimoto authored on 2011-06-07
65
        push @$columns, $2;
added EXPERIMENTAL parameter...
Yuki Kimoto authored on 2011-07-29
66
        $sql = defined $3 ? "$1$2 $3 ?$4" : "$1?$4";
cleanup
yuki-kimoto authored on 2010-10-17
67
    }
fixed named placeholder bug ...
Yuki Kimoto authored on 2011-08-01
68
    $sql =~ s/\\:/:/g;
cleanup
yuki-kimoto authored on 2010-10-17
69

            
- update_param_tag is DEPREC...
Yuki Kimoto authored on 2011-06-07
70
    # Create query
add table tag
Yuki Kimoto authored on 2011-02-09
71
    my $query = DBIx::Custom::Query->new(
72
        sql => $sql,
- update_param_tag is DEPREC...
Yuki Kimoto authored on 2011-06-07
73
        columns => $columns
add table tag
Yuki Kimoto authored on 2011-02-09
74
    );
renamed default_query_filter...
yuki-kimoto authored on 2010-08-03
75
    
76
    return $query;
77
}
- DBIx::Custom::QueryBuilder...
Yuki Kimoto authored on 2011-11-04
78

            
79
# DEPRECATED
80
has 'dbi';
81

            
- update_param_tag is DEPREC...
Yuki Kimoto authored on 2011-06-07
82
# DEPRECATED!
cleanup
Yuki Kimoto authored on 2011-06-13
83
has tags => sub { {} };
- update_param_tag is DEPREC...
Yuki Kimoto authored on 2011-06-07
84

            
85
# DEPRECATED!
86
sub register_tag {
87
    my $self = shift;
renamed default_query_filter...
yuki-kimoto authored on 2010-08-03
88
    
added warnings
Yuki Kimoto authored on 2011-06-07
89
    warn "register_tag is DEPRECATED!";
90
    
- update_param_tag is DEPREC...
Yuki Kimoto authored on 2011-06-07
91
    # Merge tag
92
    my $tags = ref $_[0] eq 'HASH' ? $_[0] : {@_};
93
    $self->tags({%{$self->tags}, %$tags});
94
    
95
    return $self;
96
}
97

            
98
# DEPRECATED!
99
sub _parse_tag {
100
    my ($self, $source) = @_;
remove DBIx::Custom::QueryBu...
yuki-kimoto authored on 2010-08-05
101
    # Source
renamed default_query_filter...
yuki-kimoto authored on 2010-08-03
102
    $source ||= '';
remove DBIx::Custom::QueryBu...
yuki-kimoto authored on 2010-08-05
103
    # Tree
removed DBIx::Custom::Query ...
yuki-kimoto authored on 2010-08-12
104
    my @tree;
105
    # Value
106
    my $value = '';
107
    # State
renamed default_query_filter...
yuki-kimoto authored on 2010-08-03
108
    my $state = 'text';
removed DBIx::Custom::Query ...
yuki-kimoto authored on 2010-08-12
109
    # Before charactor
110
    my $before = '';
111
    # Position
fixed DBIx::Custom::QueryBui...
yuki-kimoto authored on 2010-08-15
112
    my $pos = 0;
renamed default_query_filter...
yuki-kimoto authored on 2010-08-03
113
    # Parse
added tests
yuki-kimoto authored on 2010-08-12
114
    my $original = $source;
- update_param_tag is DEPREC...
Yuki Kimoto authored on 2011-06-07
115
    my $tag_count = 0;
fixed DBIx::Custom::QueryBui...
yuki-kimoto authored on 2010-08-15
116
    while (defined(my $c = substr($source, $pos, 1))) {
117
        # Last
118
        last unless length $c;
- update_param_tag is DEPREC...
Yuki Kimoto authored on 2011-06-07
119
        # Parameter
120
        if ($c eq ':' && (substr($source, $pos + 1, 1) || '') =~ /\w/) {
121
            push @tree, {type => 'param'};;
122
        }
removed DBIx::Custom::Query ...
yuki-kimoto authored on 2010-08-12
123
        # State is text
124
        if ($state eq 'text') {
125
            # Tag start charactor
126
            if ($c eq '{') {
127
                # Escaped charactor
128
                if ($before eq "\\") {
129
                    substr($value, -1, 1, '');
130
                    $value .= $c;
131
                }
132
                # Tag start
133
                else {
134
                    # Change state
135
                    $state = 'tag';
136
                    # Add text
137
                    push @tree, {type => 'text', value => $value}
138
                      if $value;
139
                    # Clear
140
                    $value = '';
141
                }
142
            }
143
            # Tag end charactor
144
            elsif ($c eq '}') {
145
                # Escaped charactor
146
                if ($before eq "\\") {
147
                    substr($value, -1, 1, '');
148
                    $value .= $c;
149
                }
150
                # Unexpected
151
                else {
improved error messages
Yuki Kimoto authored on 2011-04-18
152
                    croak qq{Parsing error. unexpected "\}". }
cleanup
Yuki Kimoto authored on 2011-04-25
153
                        . qq{pos $pos of "$original" } . _subname
removed DBIx::Custom::Query ...
yuki-kimoto authored on 2010-08-12
154
                }
155
            }
156
            # Normal charactor
157
            else { $value .= $c }
158
        }
159
        # State is tags
added tests
yuki-kimoto authored on 2010-08-12
160
        else {
removed DBIx::Custom::Query ...
yuki-kimoto authored on 2010-08-12
161
            # Tag start charactor
162
            if ($c eq '{') {
163
                # Escaped charactor
164
                if ($before eq "\\") {
165
                    substr($value, -1, 1, '');
166
                    $value .= $c;
167
                }
168
                # Unexpected
169
                else {
improved error messages
Yuki Kimoto authored on 2011-04-18
170
                    croak qq{Parsing error. unexpected "\{". }
cleanup
Yuki Kimoto authored on 2011-04-25
171
                        . qq{pos $pos of "$original" } . _subname
removed DBIx::Custom::Query ...
yuki-kimoto authored on 2010-08-12
172
                }
173
            }
174
            # Tag end charactor
175
            elsif ($c eq '}') {
176
                # Escaped charactor
177
                if ($before eq "\\") {
178
                    substr($value, -1, 1, '');
179
                    $value .= $c;
180
                }
181
                # Tag end
182
                else {
183
                    # Change state
184
                    $state = 'text';
185
                    # Add tag
186
                    my ($tag_name, @tag_args) = split /\s+/, $value;
187
                    push @tree, {type => 'tag', tag_name => $tag_name, 
188
                                 tag_args => \@tag_args};
189
                    # Clear
190
                    $value = '';
- update_param_tag is DEPREC...
Yuki Kimoto authored on 2011-06-07
191
                    # Countup
192
                    $tag_count++;
removed DBIx::Custom::Query ...
yuki-kimoto authored on 2010-08-12
193
                }
194
            }
195
            # Normal charactor
196
            else { $value .= $c }
renamed default_query_filter...
yuki-kimoto authored on 2010-08-03
197
        }
removed DBIx::Custom::Query ...
yuki-kimoto authored on 2010-08-12
198
        # Save before charactor
199
        $before = $c;
200
        # increment position
201
        $pos++;
renamed default_query_filter...
yuki-kimoto authored on 2010-08-03
202
    }
removed DBIx::Custom::Query ...
yuki-kimoto authored on 2010-08-12
203
    # Tag not finished
cleanup
Yuki Kimoto authored on 2011-04-25
204
    croak qq{Tag not finished. "$original" } . _subname
removed DBIx::Custom::Query ...
yuki-kimoto authored on 2010-08-12
205
      if $state eq 'tag';
- update_param_tag is DEPREC...
Yuki Kimoto authored on 2011-06-07
206
    # Not contains tag
207
    return DBIx::Custom::Query->new(sql => $source, tag_count => $tag_count)
208
      if $tag_count == 0;
removed DBIx::Custom::Query ...
yuki-kimoto authored on 2010-08-12
209
    # Add rest text
210
    push @tree, {type => 'text', value => $value}
211
      if $value;
- update_param_tag is DEPREC...
Yuki Kimoto authored on 2011-06-07
212
    # SQL
213
    my $sql = '';
214
    # All Columns
215
    my $all_columns = [];
216
    # Tables
217
    my $tables = [];
218
    # Build SQL 
cleanup
Yuki Kimoto authored on 2011-10-21
219
    for my $node (@tree) {
- update_param_tag is DEPREC...
Yuki Kimoto authored on 2011-06-07
220
        # Text
221
        if ($node->{type} eq 'text') { $sql .= $node->{value} }
222
        # Parameter
223
        elsif ($node->{type} eq 'param') {
224
            push @$all_columns, 'RESERVED_PARAMETER';
225
        }
226
        # Tag
227
        else {
228
            # Tag name
229
            my $tag_name = $node->{tag_name};
230
            # Tag arguments
231
            my $tag_args = $node->{tag_args};
232
            # Table
233
            if ($tag_name eq 'table') {
234
                my $table = $tag_args->[0];
235
                push @$tables, $table;
236
                $sql .= $table;
237
                next;
238
            }
239
            # Get tag
cleanup
Yuki Kimoto authored on 2011-08-13
240
            $self->dbi->{_tags} ||= {};
- update_param_tag is DEPREC...
Yuki Kimoto authored on 2011-06-07
241
            my $tag = $self->tag_processors->{$tag_name}
cleanup
Yuki Kimoto authored on 2011-08-13
242
                             || $self->dbi->{_tags}->{$tag_name};
- update_param_tag is DEPREC...
Yuki Kimoto authored on 2011-06-07
243
            # Tag is not registered
244
            croak qq{Tag "$tag_name" is not registered } . _subname
245
              unless $tag;
246
            # Tag not sub reference
247
            croak qq{Tag "$tag_name" must be sub reference } . _subname
248
              unless ref $tag eq 'CODE';
249
            # Execute tag
250
            my $r = $tag->(@$tag_args);
251
            # Check tag return value
252
            croak qq{Tag "$tag_name" must return [STRING, ARRAY_REFERENCE] }
253
                . _subname
254
              unless ref $r eq 'ARRAY' && defined $r->[0] && ref $r->[1] eq 'ARRAY';
255
            # Part of SQL statement and colum names
256
            my ($part, $columns) = @$r;
257
            # Add columns
258
            push @$all_columns, @$columns;
259
            # Join part tag to SQL
260
            $sql .= $part;
261
        }
renamed default_query_filter...
yuki-kimoto authored on 2010-08-03
262
    }
- update_param_tag is DEPREC...
Yuki Kimoto authored on 2011-06-07
263
    # Query
264
    my $query = DBIx::Custom::Query->new(
265
        sql => $sql,
266
        columns => $all_columns,
267
        tables => $tables,
268
        tag_count => $tag_count
269
    );
270
    return $query;
renamed default_query_filter...
yuki-kimoto authored on 2010-08-03
271
}
272

            
cleanup
Yuki Kimoto authored on 2011-01-25
273
# DEPRECATED!
cleanup
Yuki Kimoto authored on 2011-06-13
274
has tag_processors => sub { {} };
renamed DBIx::Custom::TagPro...
Yuki Kimoto authored on 2011-01-24
275

            
cleanup
Yuki Kimoto authored on 2011-01-25
276
# DEPRECATED!
renamed DBIx::Custom::TagPro...
Yuki Kimoto authored on 2011-01-24
277
sub register_tag_processor {
278
    my $self = shift;
- added EXPERIMENTAL order m...
Yuki Kimoto authored on 2011-06-28
279
    warn "register_tag_processor is DEPRECATED!";
cleanup
Yuki Kimoto authored on 2011-01-25
280
    # Merge tag
renamed DBIx::Custom::TagPro...
Yuki Kimoto authored on 2011-01-24
281
    my $tag_processors = ref $_[0] eq 'HASH' ? $_[0] : {@_};
282
    $self->tag_processors({%{$self->tag_processors}, %{$tag_processors}});
283
    return $self;
284
}
285

            
renamed default_query_filter...
yuki-kimoto authored on 2010-08-03
286
1;
287

            
288
=head1 NAME
289

            
- DBIx::Custom::QueryBuilder...
Yuki Kimoto authored on 2011-11-04
290
DBIx::Custom::QueryBuilder - DEPRECATED!
renamed default_query_filter...
yuki-kimoto authored on 2010-08-03
291

            
- DBIx::Custom::QueryBuilder...
Yuki Kimoto authored on 2011-11-04
292
=head1 DESCRIPTION
renamed default_query_filter...
yuki-kimoto authored on 2010-08-03
293

            
- DBIx::Custom::QueryBuilder...
Yuki Kimoto authored on 2011-11-04
294
This module functionality will be moved to DBIx::Custom
update document
yuki-kimoto authored on 2010-08-07
295

            
- update_param_tag is DEPREC...
Yuki Kimoto authored on 2011-06-07
296
=cut