Showing 2 changed files with 95 additions and 2 deletions
+85 -2
lib/DBI/Custom.pm
... ...
@@ -95,8 +95,11 @@ sub create_sql {
95 95
 }
96 96
 
97 97
 sub query {
98
-    my $self = shift;
99
-    my ($sql, @bind) = $self->creqte_sql(@_);
98
+    my ($self, $template, $values, $filter)  = @_;
99
+    
100
+    $filter ||= $self->bind_filter;
101
+    
102
+    my ($sql, @bind) = $self->creqte_sql($template, $values, $filter);
100 103
     $self->prepare($sql);
101 104
     $self->execute(@bind);
102 105
 }
... ...
@@ -112,13 +115,93 @@ Object::Simple->build_class;
112 115
 package DBI::Custom::SQLTemplate;
113 116
 use Object::Simple;
114 117
 
118
+### Attributes;
119
+sub tag_start : Attr { default => '{' }
120
+sub tag_end   : Attr { default => '}' }
121
+sub template : Attr {};
122
+sub tree     : Attr { auto_build => sub { shift->tree([]) } }
123
+
124
+
115 125
 sub create_sql {
126
+    my ($self, $template, $values, $filter)  = @_;
127
+    
128
+    $self->parse($template);
129
+    
130
+    my ($sql, @bind);
131
+    
132
+    return ($sql, @bind);
133
+}
134
+
135
+our $TAG_SYNTAX = <<'EOS';
136
+[tag]            [expand]
137
+{= name}         name = ?
138
+{!= name}        name != ?
139
+
140
+{< name}         name < ?
141
+{> name}         name > ?
142
+{>= name}        name >= ?
143
+{<= name}        name <= ?
144
+
145
+{like name}      name like ?
146
+{in name}        name in [?, ?, ..]
147
+
148
+{insert_values}  (key1, key2, key3) values (?, ?, ?)
149
+{update_values}  set key1 = ?, key2 = ?, key3 = ?
150
+EOS
151
+
152
+our %VALID_TAG_NAMES = map {$_ => 1} qw/=/;
153
+sub parse {
154
+    my ($self, $template) = @_;
155
+    $self->template($template);
156
+    
157
+    # Clean start;
158
+    delete $self->{tree};
159
+    
160
+    # Tags
161
+    my $tag_start = quotemeta $self->tag_start;
162
+    my $tag_end   = quotemeta $self->tag_end;
116 163
     
164
+    # Tokenize
165
+    my $state = 'text';
166
+    
167
+    # Save original template
168
+    my $original_template = $template;
169
+    
170
+    # Text
171
+    while ($template =~ s/([^$tag_start]*?)$tag_start([^$tag_end].*?)$tag_end//sm) {
172
+        my $text          = $1;
173
+        my $tag  = $2;
174
+        
175
+        push @{$self->tree}, ['text', $text] if $text;
176
+        
177
+        if ($tag) {
178
+            
179
+            my ($tag_name, @params) = split /\s+/, $tag;
180
+            
181
+            croak("Tag name is empty in '$tag'.\n" .
182
+                  "Tag Syntax\n$TAG_SYNTAX.\n" .
183
+                  "Your SQL template is \n$original_template")
184
+              unless length $tag_name;
185
+            
186
+            croak("Tag name '$tag_name' in '$tag' is invalid.\n" .
187
+                  "Tag Syntax\n$TAG_SYNTAX.\n" .
188
+                  "Your SQL template is \n$original_template")
189
+              unless $VALID_TAG_NAMES{$tag_name}; 
190
+            
191
+            push @{$self->tree}, [$tag_name, @params];
192
+        }
193
+    }
194
+    
195
+    push @{$self->tree}, ['text', $template] if $template;
117 196
 }
118 197
 
119 198
 
120 199
 
121 200
 
201
+
202
+
203
+
204
+
122 205
 Object::Simple->build_class;
123 206
 
124 207
 =head1 NAME
+10
t/01-core.t
... ...
@@ -172,6 +172,16 @@ our ($U, $P, $D) = connect_info();
172 172
     like($@, qr/connect_info 'no_exist' is invald/, 'no exist');
173 173
 }
174 174
 
175
+{
176
+    my $dbi = DBI::Custom->new;
177
+    my $tmpl   = "select * from table where {= title};";
178
+    my $values = {title => 'a'};
179
+    my ($sql, @bind) = $dbi->create_sql($tmpl, $values);
180
+    is($sql, "select * from table where title = ?;");
181
+    is_deeply(\@bind, ['a']);
182
+    
183
+}
184
+
175 185
 sub connect_info {
176 186
     my $file = 'password.tmp';
177 187
     open my $fh, '<', $file