Newer Older
257 lines | 6.106kb
added DBIx::Custom::Mapper
Yuki Kimoto authored on 2011-08-26
1
package DBIx::Custom::Mapper;
2
use Object::Simple -base;
3

            
- added EXPERIMENTAL pass at...
Yuki Kimoto authored on 2011-09-02
4
use DBIx::Custom::NotExists;
5

            
added tests
Yuki Kimoto authored on 2011-08-26
6
use Carp 'croak';
added DBIx::Custom::Mapper
Yuki Kimoto authored on 2011-08-26
7
use DBIx::Custom::Util '_subname';
8

            
9
# Carp trust relationship
10
push @DBIx::Custom::CARP_NOT, __PACKAGE__;
11

            
- added EXPERIMENTAL pass at...
Yuki Kimoto authored on 2011-09-02
12
has [qw/param/],
cleanup
Yuki Kimoto authored on 2012-01-20
13
  condition => sub {
14
    sub { defined $_[0] && length $_[0] }
15
  },
16
  pass => sub { [] };
added DBIx::Custom::Mapper
Yuki Kimoto authored on 2011-08-26
17

            
18
sub map {
cleanup
Yuki Kimoto authored on 2012-01-20
19
  my ($self, %rule) = @_;
20
  my $param = $self->param;
21
  $rule{$_} = {key => $_} for @{$self->pass};
22
  
23
  # Mapping
24
  my $new_param = {};
25
  for my $key (keys %rule) {
added DBIx::Custom::Mapper
Yuki Kimoto authored on 2011-08-26
26
    
cleanup
Yuki Kimoto authored on 2012-01-20
27
    my $mapping = $rule{$key};
28
    
29
    # Get mapping information
30
    my $new_key;
31
    my $value;
32
    my $condition;
33
    
34
    if (ref $mapping eq 'ARRAY') {
35
      $new_key = $mapping->[0];
36
      $value = $mapping->[1];
37
      $condition = ref $mapping->[2] eq 'HASH' ? $mapping->[2]->{condition} : $mapping->[2];
38
    }
39
    elsif (ref $mapping eq 'HASH') {
40
      $new_key = $mapping->{key};
41
      $value = $mapping->{value};
42
      $condition = $mapping->{condition};
43
    }
44
    elsif (!ref $mapping) {
45
      $new_key = $mapping;
46
      warn qq/map method's string value "$mapping" is DEPRECATED. / .
47
           qq/use {key => ...} syntax instead/
48
    }
49
    elsif (ref $mapping eq 'CODE') {
50
      $value = $mapping;
51
      warn qq/map method's code reference value "$mapping" is DEPRECATED. / .
52
           qq/use {value => ...} syntax instead/
53
    }
54
    
55
    $new_key = $key unless defined $new_key;
56
    $condition ||= $self->condition;
57
    $condition = $self->_condition_to_sub($condition);
58

            
59
    # Map parameter
60
    if (ref $condition eq 'CODE') {
61
      if (ref $param->{$key} eq 'ARRAY') {
62
        $new_param->{$new_key} = [];
63
        for (my $i = 0; $i < @{$param->{$key}}; $i++) {
64
          $new_param->{$new_key}->[$i]
65
            = $condition->($param->{$key}->[$i]) ? $param->{$key}->[$i]
66
            : DBIx::Custom::NotExists->singleton;
- added {key => ..., value =...
Yuki Kimoto authored on 2011-10-04
67
        }
cleanup
Yuki Kimoto authored on 2012-01-20
68
      }
69
      else {
70
        if ($condition->($param->{$key})) {
71
          $new_param->{$new_key} = defined $value
72
            ? $value->($param->{$key}) : $param->{$key};
- added {key => ..., value =...
Yuki Kimoto authored on 2011-10-04
73
        }
cleanup
Yuki Kimoto authored on 2012-01-20
74
      }
75
    }
76
    elsif ($condition eq 'exists') {
77
      if (ref $param->{$key} eq 'ARRAY') {
78
        $new_param->{$new_key} = [];
79
        for (my $i = 0; $i < @{$param->{$key}}; $i++) {
80
          $new_param->{$new_key}->[$i]
81
            = exists $param->{$key}->[$i] ? $param->{$key}->[$i]
82
            : DBIx::Custom::NotExists->singleton;
added DBIx::Custom::Mapper
Yuki Kimoto authored on 2011-08-26
83
        }
cleanup
Yuki Kimoto authored on 2012-01-20
84
      }
85
      else {
86
        if (exists $param->{$key}) {
87
          $new_param->{$new_key} = defined $value
88
            ? $value->($param->{$key}) : $param->{$key};
added DBIx::Custom::Mapper
Yuki Kimoto authored on 2011-08-26
89
        }
cleanup
Yuki Kimoto authored on 2012-01-20
90
      }
added DBIx::Custom::Mapper
Yuki Kimoto authored on 2011-08-26
91
    }
cleanup
Yuki Kimoto authored on 2012-01-20
92
    else { croak qq/Condition must be code reference or "exists" / . _subname }
93
  }
94
  
95
  return $new_param;
added DBIx::Custom::Mapper
Yuki Kimoto authored on 2011-08-26
96
}
97

            
98
sub new {
cleanup
Yuki Kimoto authored on 2012-01-20
99
  my $self = shift->SUPER::new(@_);
100
  
101
  # Check attribute names
102
  my @attrs = keys %$self;
103
  for my $attr (@attrs) {
104
    croak qq{"$attr" is invalid attribute name (} . _subname . ")"
105
      unless $self->can($attr);
106
  }
107
  
108
  return $self;
added DBIx::Custom::Mapper
Yuki Kimoto authored on 2011-08-26
109
}
110

            
111

            
112
sub _condition_to_sub {
cleanup
Yuki Kimoto authored on 2012-01-20
113
  my ($self, $if) = @_;
114
  $if = $if eq 'exists' ? $if
115
    : $if eq 'defined' ? sub { defined $_[0] }
116
    : $if eq 'length'  ? sub { defined $_[0] && length $_[0] }
117
    : ref $if eq 'CODE' ? $if
118
    : undef;
119

            
120
  croak "You can must specify right value to C<condition> " . _subname
121
    unless $if;
122
  
123
  return $if;
added DBIx::Custom::Mapper
Yuki Kimoto authored on 2011-08-26
124
}
125

            
126
1;
127

            
128
=head1 NAME
129

            
sqlfilter option is renamed ...
Yuki Kimoto authored on 2011-09-16
130
DBIx::Custom::Mapper - Mapper of parameter
added DBIx::Custom::Mapper
Yuki Kimoto authored on 2011-08-26
131

            
132
=head1 SYNOPSYS
133

            
cleanup
Yuki Kimoto authored on 2012-01-20
134
  my $mapper = $dbi->mapper(param => $param);
135
  my $new_param = $mapper->map(
136
    title => 'book.title', # Key
137
    author => sub { '%' . $_[0] . '%'} # Value
138
    price => ['book.price' => sub { '%' . $_[0] . '%' }], # Key and value
139
  );
added DBIx::Custom::Mapper
Yuki Kimoto authored on 2011-08-26
140

            
141
=head1 ATTRIBUTES
142

            
143
=head2 C<param>
144

            
cleanup
Yuki Kimoto authored on 2012-01-20
145
  my $param = $mapper->param;
146
  $mapper = $mapper->param({title => 'Perl', author => 'Ken'});
added DBIx::Custom::Mapper
Yuki Kimoto authored on 2011-08-26
147

            
148
Parameter.
149

            
- added EXPERIMENTAL pass at...
Yuki Kimoto authored on 2011-09-02
150
=head2 C<pass>
added DBIx::Custom::Mapper
Yuki Kimoto authored on 2011-08-26
151

            
cleanup
Yuki Kimoto authored on 2012-01-20
152
  my $pass = $mapper->pass;
153
  $mapper = $mapper->pass([qw/title author/]);
added DBIx::Custom::Mapper
Yuki Kimoto authored on 2011-08-26
154

            
- added EXPERIMENTAL pass at...
Yuki Kimoto authored on 2011-09-02
155
the key and value is copied without change when C<map> method is executed.
added DBIx::Custom::Mapper
Yuki Kimoto authored on 2011-08-26
156

            
157
=head2 C<condition>
158

            
cleanup
Yuki Kimoto authored on 2012-01-20
159
  my $condition = $mapper->condition;
160
  $mapper = $mapper->condition('exists');
added DBIx::Custom::Mapper
Yuki Kimoto authored on 2011-08-26
161

            
162
Mapping condtion, default to C<length>.
163

            
164
You can set the following values to C<condition>.
165

            
166
=over 4
167

            
168
=item * C<exists>
cleanup
Yuki Kimoto authored on 2012-01-20
169
 
170
  condition => 'exists'
added DBIx::Custom::Mapper
Yuki Kimoto authored on 2011-08-26
171

            
172
If key exists, key and value is mapped.
173

            
174
=item * C<defined>
175

            
cleanup
Yuki Kimoto authored on 2012-01-20
176
  condition => 'defined';
added DBIx::Custom::Mapper
Yuki Kimoto authored on 2011-08-26
177

            
178
If value is defined, key and value is mapped.
179

            
180
=item * C<length>
181

            
cleanup
Yuki Kimoto authored on 2012-01-20
182
  condition => 'length';
added DBIx::Custom::Mapper
Yuki Kimoto authored on 2011-08-26
183

            
184
If value is defined and has length, key and value is mapped.
185

            
186
=item * C<code reference>
187

            
cleanup
Yuki Kimoto authored on 2012-01-20
188
  condition => sub { defined $_[0] }
added DBIx::Custom::Mapper
Yuki Kimoto authored on 2011-08-26
189

            
190
You can set code reference to C<condtion>.
191
The subroutine return true, key and value is mapped.
192

            
193
=head1 METHODS
194

            
195
L<DBIx::Custom::Mapper> inherits all methods from L<Object::Simple>
196
and implements the following new ones.
197

            
198
=head2 C<map>
199

            
cleanup
Yuki Kimoto authored on 2012-01-20
200
  my $new_param = $mapper->map(
201
    price => {key => 'book.price'}
202
    title => {value => sub { '%' . $_[0] . '%'}}
203
    author => ['book.author' => sub { '%' . $_[0] . '%'}] # Key and value
204
  );
added DBIx::Custom::Mapper
Yuki Kimoto authored on 2011-08-26
205

            
- added {key => ..., value =...
Yuki Kimoto authored on 2011-10-04
206
Map C<param> into new parameter.
added DBIx::Custom::Mapper
Yuki Kimoto authored on 2011-08-26
207

            
208
For example, if C<param> is set to
209

            
cleanup
Yuki Kimoto authored on 2012-01-20
210
  {
211
    price => 1900,
212
    title => 'Perl',
213
    author => 'Ken',
214
    issue_date => '2010-11-11'
215
  }
added DBIx::Custom::Mapper
Yuki Kimoto authored on 2011-08-26
216

            
217
The following hash reference is returned.
218

            
cleanup
Yuki Kimoto authored on 2012-01-20
219
  {
220
    'book.price' => 1900,
221
    title => '%Perl%',
222
    'book.author' => '%Ken%',
223
  }
added DBIx::Custom::Mapper
Yuki Kimoto authored on 2011-08-26
224

            
225
By default, If the value has length, key and value is mapped.
226

            
cleanup
Yuki Kimoto authored on 2012-01-20
227
  title => 'Perl'  # Mapped
228
  {title => '' }   # Not mapped
229
  {title => undef} # Not mapped
230
  {}               # Not mapped
added DBIx::Custom::Mapper
Yuki Kimoto authored on 2011-08-26
231

            
232
You can set change mapping condition by C<condition> attribute.
233

            
cleanup
Yuki Kimoto authored on 2012-01-20
234
  $mapper->condition('defined');
added DBIx::Custom::Mapper
Yuki Kimoto authored on 2011-08-26
235

            
236
Or you can set C<condtion> option for each key.
237

            
cleanup
Yuki Kimoto authored on 2012-01-20
238
  my $new_param = $mapper->map(
239
    price => {key => 'book.price', condition => 'defined'}]
240
    title => {value => sub { '%' . $_[0] . '%'}, condition => 'defined'}
241
    author => ['book.author', sub { '%' . $_[0] . '%'}, 'exists']
242
  );
added DBIx::Custom::Mapper
Yuki Kimoto authored on 2011-08-26
243

            
- added EXPERIMENTAL pass at...
Yuki Kimoto authored on 2011-09-02
244
If C<pass> attrivute is set, the keys and value is copied without change.
added DBIx::Custom::Mapper
Yuki Kimoto authored on 2011-08-26
245

            
cleanup
Yuki Kimoto authored on 2012-01-20
246
  $mapper->pass([qw/title author/]);
247
  my $new_param = $mapper->map(price => {key => 'book.price'});
- added EXPERIMENTAL pass at...
Yuki Kimoto authored on 2011-09-02
248

            
249
The following hash reference
cleanup
Yuki Kimoto authored on 2012-01-20
250
  
251
  {title => 'Perl', author => 'Ken', price => 1900}
- added EXPERIMENTAL pass at...
Yuki Kimoto authored on 2011-09-02
252

            
253
is mapped to
254

            
cleanup
Yuki Kimoto authored on 2012-01-20
255
  {title => 'Perl', author => 'Ken', 'book.price' => 1900}
added DBIx::Custom::Mapper
Yuki Kimoto authored on 2011-08-26
256

            
257
=cut