| ... | ... | @@ -13,13 +13,11 @@ push @DBIx::Custom::Where::CARP_NOT, __PACKAGE__; | 
| 13 | 13 | has 'dbi'; | 
| 14 | 14 |  | 
| 15 | 15 |  sub build_query { | 
| 16 | - my ($self, $source) = @_; | |
| 17 | - | |
| 18 | - my $query; | |
| 16 | + my ($self, $sql) = @_; | |
| 19 | 17 |  | 
| 20 | 18 | # Parse tag. tag is DEPRECATED! | 
| 21 | -    if ($self->dbi->tag_parse && $source =~ /(\s|^)\{/) { | |
| 22 | - $query = $self->_parse_tag($source); | |
| 19 | +    if ($sql =~ /(\s|^)\{/ && $self->dbi->tag_parse) { | |
| 20 | + my $query = $self->_parse_tag($sql); | |
| 23 | 21 |          my $tag_count = delete $query->{tag_count}; | 
| 24 | 22 |          warn qq/Tag system such as {? name} is DEPRECATED! / . | 
| 25 | 23 | qq/use parameter system such as :name instead/ | 
| ... | ... | @@ -35,15 +33,23 @@ sub build_query { | 
| 35 | 33 | $query->columns->[$i] = $column2; | 
| 36 | 34 | } | 
| 37 | 35 | } | 
| 36 | + return $query; | |
| 38 | 37 | } | 
| 39 | 38 |  | 
| 40 | - # Parse parameter | |
| 41 | -    else { $query = $self->_parse_parameter($source) } | |
| 42 | - | |
| 43 | - my $sql = $query->sql; | |
| 44 | - $query->sql($sql); | |
| 45 | - | |
| 46 | - return $query; | |
| 39 | + $sql ||= ''; | |
| 40 | + my $columns = []; | |
| 41 | +    my $c = ($self->{dbi} || {})->{safety_character} | |
| 42 | + || $self->dbi->safety_character; | |
| 43 | + # Parameter regex | |
| 44 | + $sql =~ s/([0-9]):/$1\\:/g; | |
| 45 | +    while ($sql =~ /(^|.*?[^\\]):([$c\.]+)(?:\{(.*?)\})?(.*)/sg) { | |
| 46 | + push @$columns, $2; | |
| 47 | + $sql = defined $3 ? "$1$2 $3 ?$4" : "$1?$4"; | |
| 48 | + } | |
| 49 | + $sql =~ s/\\:/:/g if index($sql, "\\:") != -1; | |
| 50 | + | |
| 51 | + # Create query | |
| 52 | +    bless {sql => $sql, columns => $columns}, 'DBIx::Custom::Query'; | |
| 47 | 53 | } | 
| 48 | 54 |  | 
| 49 | 55 |  sub _parse_parameter { | 
| ... | ... | @@ -44,8 +44,20 @@ sub to_string { | 
| 44 | 44 | # Parse | 
| 45 | 45 | my $where = []; | 
| 46 | 46 |      my $count = {}; | 
| 47 | +    $self->{_query_builder} = $self->dbi->query_builder; | |
| 48 | +    $self->{_safety_character} = $self->dbi->safety_character; | |
| 49 | +    $self->{_quote} = $self->dbi->_quote; | |
| 47 | 50 | $self->_parse($clause, $where, $count, 'and'); | 
| 48 | - | |
| 51 | + | |
| 52 | + | |
| 53 | + # Check safety | |
| 54 | +    unless (join('', keys %$count) =~ /^[$self->{_safety_character}\.]+$/) { | |
| 55 | +        for my $column (keys %$count) { | |
| 56 | +            croak qq{"$column" is not safety column name (} . _subname . ")" | |
| 57 | +              unless $column =~ /^[$self->{_safety_character}\.]+$/; | |
| 58 | + } | |
| 59 | + } | |
| 60 | + | |
| 49 | 61 | # Stringify | 
| 50 | 62 | unshift @$where, 'where' if @$where; | 
| 51 | 63 |      return join(' ', @$where); | 
| ... | ... | @@ -53,7 +65,7 @@ sub to_string { | 
| 53 | 65 |  | 
| 54 | 66 |  our %VALID_OPERATIONS = map { $_ => 1 } qw/and or/; | 
| 55 | 67 |  sub _parse { | 
| 56 | - my ($self, $clause, $where, $count, $op) = @_; | |
| 68 | + my ($self, $clause, $where, $count, $op, $info) = @_; | |
| 57 | 69 |  | 
| 58 | 70 | # Array | 
| 59 | 71 |      if (ref $clause eq 'ARRAY') { | 
| ... | ... | @@ -93,7 +105,7 @@ sub _parse { | 
| 93 | 105 | my $pushed; | 
| 94 | 106 |  | 
| 95 | 107 | # Column | 
| 96 | - my $columns = $self->dbi->query_builder->build_query($clause)->columns; | |
| 108 | +        my $columns = $self->{_query_builder}->build_query($clause)->{columns}; | |
| 97 | 109 |          if (@$columns == 0) { | 
| 98 | 110 | push @$where, $clause; | 
| 99 | 111 | $pushed = 1; | 
| ... | ... | @@ -106,21 +118,16 @@ sub _parse { | 
| 106 | 118 |  | 
| 107 | 119 | # Remove quote | 
| 108 | 120 | my $column = $columns->[0]; | 
| 109 | -        if (my $q = $self->dbi->_quote) { | |
| 121 | +        if (my $q = $self->{_quote}) { | |
| 110 | 122 | $q = quotemeta($q); | 
| 111 | 123 | $column =~ s/[$q]//g; | 
| 112 | 124 | } | 
| 113 | 125 |  | 
| 114 | - # Check safety | |
| 115 | - my $safety = $self->dbi->safety_character; | |
| 116 | -        croak qq{"$column" is not safety column name (} . _subname . ")" | |
| 117 | - unless $column =~ /^[$safety\.]+$/; | |
| 118 | - | |
| 119 | 126 | # Column count up | 
| 120 | 127 |          my $count = ++$count->{$column}; | 
| 121 | 128 |  | 
| 122 | 129 | # Push | 
| 123 | - my $param = $self->param; | |
| 130 | +        my $param = $self->{param}; | |
| 124 | 131 |          if (ref $param eq 'HASH') { | 
| 125 | 132 |              if (exists $param->{$column}) { | 
| 126 | 133 |                  my $if = $self->{_if}; |