fastapi 0.1.2 → 0.1.3

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: f404875852a90f7b72255293e1ea77b775bebd50
4
- data.tar.gz: 3c50ae17829b4838528e6bd199ddee967c241af4
3
+ metadata.gz: 4460407df7d3911b524f6dd308dbedbae42d0adc
4
+ data.tar.gz: bda3575a0b7923296a47a545983637f0dc8858a7
5
5
  SHA512:
6
- metadata.gz: 0edb07fcd025e2663d52b2034dcb6167eec57c0820b915278232dc60a4822dd0bd1123e24528f4cd02795c38222fdc4133f562f31e75cddd0604f9bf9ece37f6
7
- data.tar.gz: ecf66e27e516ea0847e795ef25e49e23666bd7acde5c4251245e11a630b95f6000af9e87447fab2a58b1d6bebbf35e8dcfb3e2e2ca68780bd8d61e3755c973b0
6
+ metadata.gz: 4f154e7c32f580077ab94fc229469c7b1d6e844733ccead5d6cd3e689b611953921243245be63ea62086e0345c3b44baeb9988922e050fcaba0cb23615e7fb89
7
+ data.tar.gz: 33b875319c13e7269fa914d5773c1c23c2ed73c03fe68841ebff7be90de58dc47e419e43ff3d73b7318c5cb931765d91dffa607618ec33fc60734d3fd43883e5
@@ -65,6 +65,36 @@ class FastAPI
65
65
 
66
66
  end
67
67
 
68
+ # Create and execute an optimized SQL query based on specified filters.
69
+ # Runs through mode fastapi_safe_fields list
70
+ #
71
+ # @param filters [Hash] a hash containing the intended filters
72
+ # @param meta [Hash] a hash containing custom metadata
73
+ # @return [FastAPI] the current instance
74
+ def safe_filter(filters = {}, meta = {})
75
+
76
+ result = fastapi_query(filters, true)
77
+
78
+ metadata = {}
79
+
80
+ meta.each do |key, value|
81
+ metadata[key] = value
82
+ end
83
+
84
+ metadata[:total] = result[:total]
85
+ metadata[:offset] = result[:offset]
86
+ metadata[:count] = result[:count]
87
+ metadata[:error] = result[:error]
88
+
89
+ @metadata = metadata
90
+ @data = result[:data]
91
+
92
+ @result_type = @@result_types[:multiple]
93
+
94
+ self
95
+
96
+ end
97
+
68
98
  # Create and execute an optimized SQL query based on specified object id.
69
99
  # Provides customized error response if not found.
70
100
  #
@@ -164,7 +194,7 @@ class FastAPI
164
194
 
165
195
  private
166
196
 
167
- def fastapi_query(filters = {})
197
+ def fastapi_query(filters = {}, safe = false)
168
198
 
169
199
  offset = 0
170
200
  count = 500
@@ -180,7 +210,17 @@ class FastAPI
180
210
  filters.delete(:__count)
181
211
  end
182
212
 
183
- prepared_data = api_generate_sql(filters, offset, count)
213
+ begin
214
+ prepared_data = api_generate_sql(filters, offset, count, safe)
215
+ rescue Exception => error
216
+ return {
217
+ data: [],
218
+ total: 0,
219
+ count: 0,
220
+ offset: offset,
221
+ error: error.message
222
+ }
223
+ end
184
224
 
185
225
  model_lookup = {}
186
226
  prepared_data[:models].each do |key, model|
@@ -221,7 +261,7 @@ class FastAPI
221
261
  row.each_with_index do |val, key_index|
222
262
 
223
263
  field = fields[key_index]
224
- split_index = field.index('__')
264
+ split_index = field.rindex('__')
225
265
 
226
266
  if field[0..7] == '__many__'
227
267
 
@@ -432,14 +472,66 @@ class FastAPI
432
472
 
433
473
  end
434
474
 
435
- def parse_filters(filters, model = nil)
475
+ def parse_filters(filters, safe = false, model = nil)
476
+
477
+ self_obj = model.nil? ? @model : model
478
+ self_string_table = model.nil? ? @model.to_s.tableize : '__' + model.to_s.tableize
479
+
480
+ # if we're at the top level...
481
+ if model.nil?
482
+
483
+ if safe
484
+ filters.each do |key, value|
485
+ found_index = key.to_s.rindex('__')
486
+ key_root = found_index.nil? ? key : key.to_s[0...found_index].to_sym
487
+ if not [:__order, :__offset, :__count].include? key and not self_obj.fastapi_fields_whitelist.include? key_root
488
+ raise 'Filter "' + key.to_s + '" not supported'
489
+ end
490
+ end
491
+ end
492
+
493
+ all_filters = {}
494
+
495
+ @model.fastapi_filters.each do |key, value|
496
+ if value.is_a? Hash
497
+ copy = {}
498
+ value.each do |key, value|
499
+ copy[key] = value
500
+ end
501
+ value = copy
502
+ end
503
+ all_filters[key] = value
504
+ end
505
+
506
+ filters.each do |field, value|
507
+ all_filters[field.to_sym] = value
508
+ end
509
+
510
+ filters = all_filters
511
+
512
+ end
436
513
 
437
514
  if not filters.has_key? :__order
438
515
  filters[:__order] = [:created_at, 'DESC']
439
516
  end
440
517
 
441
- self_obj = model.nil? ? @model : model
442
- self_string_table = model.nil? ? @model.to_s.tableize : '__' + model.to_s.tableize
518
+
519
+ filters.each do |key, value|
520
+ if [:__order, :__offset, :__count].include? key
521
+ next
522
+ end
523
+ found_index = key.to_s.rindex('__')
524
+ key_root = found_index.nil? ? key : key.to_s[0...found_index].to_sym
525
+ if not self_obj.column_names.include? key_root.to_s
526
+ if not model.nil? or (
527
+ not @model.reflect_on_all_associations(:has_many).map(&:name).include? key_root and
528
+ not @model.reflect_on_all_associations(:belongs_to).map(&:name).include? key_root
529
+ )
530
+ raise 'Filter "' + key.to_s + '" not supported'
531
+ end
532
+ end
533
+ end
534
+
443
535
 
444
536
  filter_array = []
445
537
  filter_has_many = {}
@@ -482,12 +574,12 @@ class FastAPI
482
574
 
483
575
  field = key.to_s
484
576
 
485
- if field.index('__').nil?
577
+ if field.rindex('__').nil?
486
578
  comparator = 'is'
487
579
  else
488
580
 
489
- comparator = field[(field.index('__') + 2)..-1]
490
- field = field[0...field.index('__')]
581
+ comparator = field[(field.rindex('__') + 2)..-1]
582
+ field = field[0...field.rindex('__')]
491
583
 
492
584
  if not @@api_comparator_list.include? comparator
493
585
  next # skip dis bro
@@ -497,7 +589,7 @@ class FastAPI
497
589
 
498
590
  if model.nil? and self_obj.reflect_on_all_associations(:has_many).map(&:name).include? key
499
591
 
500
- filter_result = parse_filters(value, field.singularize.classify.constantize)
592
+ filter_result = parse_filters(value, safe, field.singularize.classify.constantize)
501
593
  # logger.info filter_result
502
594
  filter_has_many[key] = filter_result[:main]
503
595
  order_has_many[key] = filter_result[:main_order]
@@ -559,26 +651,9 @@ class FastAPI
559
651
 
560
652
  end
561
653
 
562
- def api_generate_sql(filters, offset, count)
563
-
564
- api_filters = {}
565
-
566
- @model.fastapi_filters.each do |key, value|
567
- if value.is_a? Hash
568
- copy = {}
569
- value.each do |key, value|
570
- copy[key] = value
571
- end
572
- value = copy
573
- end
574
- api_filters[key] = value
575
- end
576
-
577
- filters.each do |field, value|
578
- api_filters[field.to_sym] = value
579
- end
654
+ def api_generate_sql(filters, offset, count, safe = false)
580
655
 
581
- filters = parse_filters(api_filters)
656
+ filters = parse_filters(filters, safe)
582
657
 
583
658
  fields = []
584
659
  belongs = []
@@ -22,6 +22,14 @@ module FastAPIExtension
22
22
  @fastapi_fields_sub = fields
23
23
  end
24
24
 
25
+ # Set safe fields for FastAPIInstance.safe_filter
26
+ #
27
+ # @param fields [Array] a list of fields in the form of symbols
28
+ # @return [Array] the same array of fields
29
+ def fastapi_safe_fields(fields)
30
+ @fastapi_fields_whitelist = fields
31
+ end
32
+
25
33
  # Used to set any default filters for the top level fastapi response
26
34
  #
27
35
  # @param filters [Hash] a hash containing the intended filters
@@ -38,6 +46,10 @@ module FastAPIExtension
38
46
  @fastapi_fields_sub or [:id]
39
47
  end
40
48
 
49
+ def fastapi_fields_whitelist
50
+ @fastapi_fields_whitelist or @fastapi_fields or [:id]
51
+ end
52
+
41
53
  def fastapi_filters
42
54
  @fastapi_filters or {}
43
55
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fastapi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Keith Horwood
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-07-21 00:00:00.000000000 Z
11
+ date: 2014-07-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: oj
@@ -65,7 +65,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: '0'
68
+ version: 1.9.3
69
69
  required_rubygems_version: !ruby/object:Gem::Requirement
70
70
  requirements:
71
71
  - - ">="