baseapi 0.2.6 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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