baseapi 0.2.6 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b486cc640688c880add31f0b1df884a6d4081d6f
4
- data.tar.gz: 9f5b742b010b10813ecd0e13597b6e4a89d16788
3
+ metadata.gz: 882b13dcaa0fe4c292bde76d4f651fec3d39f196
4
+ data.tar.gz: 5f8e66928bbb68e3e2973af93f51f55571af1b1b
5
5
  SHA512:
6
- metadata.gz: ba207bcdb7d590eca91a3a549bd25067a9395a29eec03f2b5d6934a0f0e241192e86fb2fd04d92aaed60a5b5611237d442ec43a4733cff44115745fd7045641e
7
- data.tar.gz: 33e784e1606e9dab1fb1d93fd11ffe1b3c3079f35f0d8b7692d8f3357f71c26667343ce386c117e29c1416845027b08403967263cea6af4af9b6c3ce9c0b8fbc
6
+ metadata.gz: 77ff560cb6c413e88b8a6583ced02478f1bf9d000b927fed215246d7cdb420fea30f0def64ad15a3b7a77a566987a5fff3c3c31deda648ec5b15ed59036bc97f
7
+ data.tar.gz: f6b6b0a3f9d5dbd07f98bcb4ba5ec1c48b84b206abbbc372682f230bf3d66b6c19d6d4cf291888f1a34220c01af9389725923907e8b8ab29314c66ddc0305679
@@ -9,6 +9,30 @@ module ActiveRecordBaseExtension extend ActiveSupport::Concern
9
9
 
10
10
  module ClassMethods
11
11
 
12
+ # @param Hash params getparams
13
+ # String/Array {column} search column value
14
+ # String orderby order column
15
+ # String order sort order ('asc' or 'desc')
16
+ # Integer count page count (all = '0' or '-1')
17
+ # Integer page paged
18
+ def search(params)
19
+ models = self._all
20
+
21
+ # recursive empty delete
22
+ clean_hash!(params)
23
+
24
+ # filter
25
+ models.filtering!(params)
26
+
27
+ # pager
28
+ models.paging!(params)
29
+
30
+ # sort
31
+ models.sorting!(params)
32
+
33
+ return models.uniq
34
+ end
35
+
12
36
  # reserved word prefix(count,page,order,orderby...)
13
37
  # @return String
14
38
  def get_reserved_word_prefix
@@ -34,10 +58,9 @@ module ActiveRecordBaseExtension extend ActiveSupport::Concern
34
58
  # @param String column column name
35
59
  # @param Array/String values search values
36
60
  # @option String operator 'or' or 'and'
37
- def column_match(models, column, values, operator:'or')
38
- column_call(models, column, values, ->(column, value){
39
- "#{getPrefix(value)} #{models.name.pluralize.underscore}.#{column} #{getOperator(value)} #{getValue("#{models.name.pluralize.underscore}.#{column}", value, "'")}"
40
- }, operator:operator)
61
+ def column_match(models, column, values, operator: 'or')
62
+ callable = arel_match(self)
63
+ column_call(models, column, values, callable, operator: operator)
41
64
  end
42
65
 
43
66
  # column like search
@@ -46,23 +69,27 @@ module ActiveRecordBaseExtension extend ActiveSupport::Concern
46
69
  # @param Array/String values search values
47
70
  # @option String operator 'or' or 'and'
48
71
  def column_like(models, column, values, operator:'or')
49
- column_call(models, column, values, ->(column, value){
50
- "#{getPrefix(value)} #{models.name.pluralize.underscore}.#{column} #{getOperator(value, 'like')} #{getValue("#{models.name.pluralize.underscore}.#{column}", escape_like(value), "%", "'")}"
51
- }, operator:operator)
72
+ callable = arel_like(self)
73
+ column_call(models, column, values, callable, operator: operator)
52
74
  end
53
75
 
54
76
  # @param ActiveRecordRelation models
55
77
  # @param String column column name
56
78
  # @param Array/String values search values
57
- # @param Callable callable
58
- # @option String operator orかand
79
+ # @param Callable callable Arel
59
80
  def column_call(models, column, values, callable, operator:'or')
81
+ base_arel = nil
60
82
  column_values = values.instance_of?(Array) ? values : [values]
61
- models.where!(column_values.map{|value| callable.call(column, value)}.join(" #{operator} "))
83
+ column_values.each do |value|
84
+ if column.present? and value.present?
85
+ arel = callable.call(column, value)
86
+ base_arel = arel_merge(base_arel, arel, operator: operator)
87
+ end
88
+ end
89
+ models.where!(base_arel)
62
90
  models
63
91
  end
64
92
 
65
-
66
93
  # override or create method '_belongs_to_{table}' if necessary
67
94
  # @param ActiveRecordRelation models
68
95
  # @param String table table name
@@ -84,10 +111,9 @@ module ActiveRecordBaseExtension extend ActiveSupport::Concern
84
111
  # @param String table table name
85
112
  # @param Hash hash column name => search values
86
113
  # @option String operator 'or' or 'and'
87
- def relation_match(models, table, hash, operator:'or')
88
- relation_call(models, table, hash, ->(table, column, value){
89
- "#{getPrefix(value)} #{table}.#{column} #{getOperator(value)} #{getValue("#{table}.#{column}", value, "'")}"
90
- }, operator:operator)
114
+ def relation_match(models, table, hash, operator: 'or')
115
+ callable = arel_match(table.camelize.singularize.constantize)
116
+ relation_call(models, hash, callable, operator: operator)
91
117
  end
92
118
 
93
119
  # like search
@@ -95,98 +121,32 @@ module ActiveRecordBaseExtension extend ActiveSupport::Concern
95
121
  # @param String table table name
96
122
  # @param Hash hash column name => search values
97
123
  # @option String operator 'or' or 'and'
98
- def relation_like(models, table, hash, operator:'or')
99
- relation_call(models, table, hash, ->(table, column, value){
100
- "#{getPrefix(value)} #{table}.#{column} #{getOperator(value, 'like')} #{getValue("#{table}.#{column}", escape_like(value), "%", "'")}"
101
- }, operator:operator)
124
+ def relation_like(models, table, hash, operator: 'or')
125
+ callable = arel_like(table.camelize.singularize.constantize)
126
+ relation_call(models, hash, callable, operator: operator)
102
127
  end
103
128
 
104
129
  # @param ActiveRecordRelation models
105
- # @param String table table name
106
130
  # @param Hash hash column name => search values
107
- # @param Callable callable
108
- # @option String operator orand
109
- def relation_call(models, table, hash, callable, operator:'or')
110
- hash.each do |column, value|
111
- if column.present? and value.present?
112
- relation_values = value.instance_of?(Array) ? value : [value]
113
- models.where!(relation_values.map{|value| callable.call(table.pluralize, column, value)}.join(" #{operator} "))
131
+ # @param Callable callable Arel
132
+ # @option String operator 'or' or 'and'
133
+ def relation_call(models, hash, callable, operator:'or')
134
+ base_arel = nil
135
+ hash.each do |column, values|
136
+ if column.present? and values.present?
137
+ relation_values = values.instance_of?(Array) ? values : [values]
138
+ relation_values.each do |value|
139
+ if column.present? and value.present?
140
+ arel = callable.call(column, value)
141
+ base_arel = arel_merge(base_arel, arel, operator: operator)
142
+ end
143
+ end
114
144
  end
115
145
  end
146
+ models.where!(base_arel)
116
147
  models
117
148
  end
118
149
 
119
- # get sql prefix 'NOT'
120
- # @param String value
121
- # @return String value
122
- def getPrefix(value)
123
- (value[0] == '!') ? 'NOT' : ''
124
- end
125
-
126
- # return = or IS
127
- # @param String value
128
- # @return String operator
129
- def getOperator(value, default = '=')
130
- operator = default
131
- val = value.clone
132
- val.slice!(0) if val[0] == '!'
133
- if ['NULL', 'EMPTY'].include?(val.upcase)
134
- operator = 'IS'
135
- elsif val.length >= 2 and ['<=', '>='].include?(val[0..1])
136
- operator = val[0..1]
137
- elsif ['<', '>'].include?(val[0])
138
- operator = val[0]
139
- end
140
- operator
141
- end
142
-
143
- # slice '!' value
144
- # @param String column
145
- # @param String value
146
- # @param String wraps ' or %
147
- # @return String val or sql
148
- def getValue(column, value, *wraps)
149
- original = value.clone
150
- val = value.clone
151
- val.slice!(0) if val[0] == '!'
152
- if val.upcase == 'NULL'
153
- val = 'NULL'
154
- elsif val.upcase == 'EMPTY'
155
- prefix = getPrefix(original)
156
- operator = prefix == 'NOT' ? 'AND' : 'OR'
157
- val = "NULL #{operator} #{prefix} #{column} = ''"
158
- elsif val.length >= 2 and ['<=', '>='].include?(val[0..1])
159
- val.sub!(val[0..1], '')
160
- elsif ['<', '>'].include?(value[0])
161
- val.sub!(val[0], '')
162
- else
163
- val = getNaturalValue(val)
164
- wraps.each do |wrap|
165
- val = "#{wrap}#{val}#{wrap}"
166
- end
167
- end
168
- return val
169
- end
170
-
171
- # removal of the enclosing
172
- # @param String value
173
- # @return String val
174
- def getNaturalValue(value)
175
- val = value.clone
176
- if ((/^[\'].+?[\']$/ =~ val) != nil) or ((/^[\"].+?[\"]$/ =~ val) != nil)
177
- val = val[1..val.length-2]
178
- end
179
- val
180
- end
181
-
182
- # escape like
183
- # @param String
184
- # @return String
185
- def escape_like(string)
186
- string.gsub(/[\\%_]/){|m| "\\#{m}"}
187
- end
188
-
189
-
190
150
  # get relation tables
191
151
  # @param String relate 'belongs_to','hasmany'..
192
152
  # @return Hash associations relation name => talbe name array
@@ -206,42 +166,160 @@ module ActiveRecordBaseExtension extend ActiveSupport::Concern
206
166
  end
207
167
 
208
168
 
209
- # @param Hash params getparams
210
- # String/Array {column} search column value
211
- # String orderby order column
212
- # String order sort order ('asc' or 'desc')
213
- # Integer count page count (all = '0' or '-1')
214
- # Integer page paged
215
- def search(params)
216
- models = self._all
217
169
 
218
- # recursive empty delete
219
- clean_hash!(params)
170
+ private
220
171
 
221
- # filter
222
- models.filtering!(params)
172
+ # create arel like
173
+ # @param Model model_class ActiveRecord class
174
+ # @return Callable create arel function
175
+ def arel_like(model_class)
176
+ return ->(column, value){
177
+ arel = model_class.arel_table[column.to_sym]
178
+ arel = arel.matches("%#{escape_value(value)}%")
179
+ arel = arel.not if value_is_not?(value)
180
+ arel
181
+ }
182
+ end
223
183
 
224
- # pager
225
- models.paging!(params)
184
+ # create arel match
185
+ # @param Model model_class ActiveRecord class
186
+ # @return Callable create arel function
187
+ def arel_match(model_class)
188
+ return ->(column, value){
189
+ arel = model_class.arel_table[column.to_sym]
190
+ if value_is_null?(value)
191
+ arel = arel.eq(nil)
192
+ elsif value_is_empty?(value)
193
+ arel = arel.eq(nil).send('or', model_class.arel_table[column.to_sym].eq(''))
194
+ elsif value_is_sign?(value)
195
+ arel = arel.send(get_sign_method(get_sign(value)), escape_value(value))
196
+ else
197
+ arel = arel.eq(escape_value(value))
198
+ end
199
+ arel = arel.not if value_is_not?(value)
200
+ arel
201
+ }
202
+ end
226
203
 
227
- # sort
228
- models.sorting!(params)
204
+ # create arel match
205
+ # @param Arel base_arel base arel
206
+ # @param Arel arel merge target arel
207
+ # @return Arel merged arel object
208
+ def arel_merge(base_arel, arel, operator: 'or')
209
+ return arel if base_arel.nil?
210
+ base_arel.send(operator, arel)
211
+ end
229
212
 
230
- return models.uniq
231
- end
213
+ # escape `!`
214
+ # @param String value
215
+ # @return String
216
+ def escape_not_value(value)
217
+ value = value[1..value.length-1] if value[0] == '!'
218
+ return value
219
+ end
232
220
 
233
- # hash params empty delete
234
- # @param hash param
235
- def clean_hash!(param)
236
- recursive_delete_if = -> (param) {
237
- param.each do |key, value|
238
- if value.is_a?(Hash)
239
- recursive_delete_if.call(value)
240
- end
221
+ # escape `>`,`<`,`=<`,`=>`
222
+ # @param String value
223
+ # @return String
224
+ def escape_sign_value(value)
225
+ if value.length >= 2 and ['<=', '>='].include?(value[0..1])
226
+ value = value[2..value.length-1]
227
+ elsif ['<', '>'].include?(value[0])
228
+ value = value[1..value.length-1]
241
229
  end
242
- param.delete_if { |k, v| v.blank? }
243
- }
244
- recursive_delete_if.call(param) if param.is_a?(Hash)
245
- end
230
+ return value
231
+ end
232
+
233
+ # escape `'`,`"`
234
+ # @param String value
235
+ # @return String
236
+ def escape_quotation_value(value)
237
+ if ((/^[\'].+?[\']$/ =~ value) != nil) or ((/^[\"].+?[\"]$/ =~ value) != nil)
238
+ value = value[1..value.length-2]
239
+ end
240
+ return value
241
+ end
242
+
243
+ # removal of the `!`,`>`,`<`,`=>`,`=<`,`'`,`"`
244
+ # @param String value
245
+ # @return String
246
+ def escape_value(value)
247
+ value = escape_not_value(value)
248
+ value = escape_sign_value(value)
249
+ value = escape_quotation_value(value)
250
+ return value
251
+ end
252
+
253
+ # request not?
254
+ # @param String value
255
+ # @return Boolean
256
+ def value_is_not?(value)
257
+ value[0] == '!'
258
+ end
259
+
260
+ # request null?
261
+ # @param String value
262
+ # @return Boolean
263
+ def value_is_null?(value)
264
+ escape_not_value(value).upcase == 'NULL'
265
+ end
266
+
267
+ # request empty?
268
+ # @param String value
269
+ # @return Boolean
270
+ def value_is_empty?(value)
271
+ escape_not_value(value).upcase == 'EMPTY'
272
+ end
273
+
274
+ # request less or greater?
275
+ # @param String value
276
+ # @return Boolean
277
+ def value_is_sign?(value)
278
+ value = escape_not_value(value)
279
+ value.length >= 2 and ['<=', '>='].include?(value[0..1]) || ['<', '>'].include?(value[0])
280
+ end
281
+
282
+ # get less or greater
283
+ # @param String value
284
+ # @return String sign > or < or => or <=
285
+ def get_sign(value)
286
+ value = escape_not_value(value)
287
+ if value.length >= 2 and ['<=', '>='].include?(value[0..1])
288
+ sign = value[0..1]
289
+ elsif ['<', '>'].include?(value[0])
290
+ sign = value[0]
291
+ end
292
+ sign
293
+ end
294
+
295
+ # less or greater to arel method
296
+ # @param String sign > or < or => or <=
297
+ # @return String Arel method
298
+ def get_sign_method(sign)
299
+ case sign
300
+ when '<'
301
+ return 'lt'
302
+ when '<='
303
+ return 'lteq'
304
+ when '>'
305
+ return 'gt'
306
+ when '>='
307
+ return 'gteq'
308
+ end
309
+ end
310
+
311
+ # hash params empty delete
312
+ # @param hash param
313
+ def clean_hash!(param)
314
+ recursive_delete_if = -> (param) {
315
+ param.each do |key, value|
316
+ if value.is_a?(Hash)
317
+ recursive_delete_if.call(value)
318
+ end
319
+ end
320
+ param.delete_if { |k, v| v.blank? }
321
+ }
322
+ recursive_delete_if.call(param) if param.is_a?(Hash)
323
+ end
246
324
  end
247
325
  end
@@ -1,3 +1,3 @@
1
1
  module Baseapi
2
- VERSION = "0.2.6"
2
+ VERSION = "0.3.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: baseapi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.6
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Moriyuki Arakawa
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-06-23 00:00:00.000000000 Z
11
+ date: 2016-07-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler