istox 0.1.97 → 0.1.98

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
  SHA256:
3
- metadata.gz: 6c5a7f018f60f1cb67728d6cdba0f6a10b5941cd7a9ac00e2957e2fe1041a174
4
- data.tar.gz: 053d1b2aece848ad1f662268a55bb6bf1dddb09ea9d6a0548b76576aa8b0df24
3
+ metadata.gz: b20425ff9b96da28ae9fdf1c6b47c7159df66d16b67d8e2fff99d8ed1d750312
4
+ data.tar.gz: a04b8779b0fa907bb8c58fcba28d26089836c1bfd6b055570d9222e57ebd530c
5
5
  SHA512:
6
- metadata.gz: 112f72f52eb1fd0781c821df36f509ebc6985b115eb6a9e86de2f37166f47ebf143a66af88f43e8615d2af34f8d16bd353fda9815ff78da15bf602c624b90f40
7
- data.tar.gz: 34b293dfe5bc081c1905b32a5856e937869ffaab0845614af000d1acfc2beb9cbf6a0efd51e31331cc496c270b94d567f67f37f728b7b5b6b00359a59fc70666
6
+ metadata.gz: f44c23b065a529e8403bae9317316e34d2c41b91a33356b60cc816c5b25ce04b7096a3c1bbffae58097b4995541622011014f826c5c6c1a2515cf774b4613347
7
+ data.tar.gz: 8838d137671e85a48f18cd4b1d919bdd391f177e66ffcc64f97108dd014134a6d006e74bae944e1f2450b063225c7e71c2e66f5615741aa344d7ec6d705e2c73
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- istox (0.1.91)
4
+ istox (0.1.97)
5
5
  binding_of_caller
6
6
  bunny (>= 2.12.0)
7
7
  graphlient
@@ -26,7 +26,8 @@ module Istox
26
26
  require 'istox/helpers/f_math'
27
27
  require 'istox/helpers/my_open_struct'
28
28
  require 'istox/helpers/common_helper'
29
- require 'istox/helpers/filter'
29
+ require 'istox/helpers/regex_helper'
30
+ require 'istox/helpers/result_handler'
30
31
  require 'istox/models/blockchain_receipt'
31
32
  require 'istox/models/concerns/blockchain_receipt_query'
32
33
  require 'istox/consumers/blockchain_status_handler'
@@ -1,5 +1,18 @@
1
1
  module Istox
2
2
  module CommonHelper
3
+ def self.to_datetime(input)
4
+ return nil if input.blank?
5
+
6
+ begin
7
+ is_numeric = true if Integer input
8
+ rescue StandardError
9
+ false
10
+ end
11
+
12
+ # is unix timestamp
13
+ is_numeric ? Time.at(input.to_i).to_datetime : Time.parse(input)
14
+ end
15
+
3
16
  def self.to_open_struct(model)
4
17
  return nil if model.blank?
5
18
 
@@ -0,0 +1,11 @@
1
+ module Istox
2
+ module RegexHelper
3
+ def self.alphabet_only(input)
4
+ !input.match(/\A[a-zA-Z]*\z/).nil?
5
+ end
6
+
7
+ def self.symbol_only(input)
8
+ !input.match(/\A[^\w\s*]+\z/).nil?
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,131 @@
1
+ module Istox
2
+ module ResultHandler
3
+ ##### main method to be called, suggested to always use this method and not individual method below
4
+ def self.process(query:, meta:, exclude_filter: false, exclude_order: false, exclude_paginate: false)
5
+ query = filter(query: query, meta: meta) unless exclude_filter
6
+ query = order(query: query, meta: meta) unless exclude_order
7
+
8
+ return paginate(query: query, meta: meta) unless exclude_paginate
9
+
10
+ query
11
+ end
12
+
13
+ def self.filter(query:, meta:)
14
+ return query if meta.blank? || meta.filters.blank?
15
+
16
+ meta.filters.each do |filter|
17
+ # chain the query with AND conditions
18
+ if filter.field.present?
19
+ validate_filter(filter)
20
+ query = query.where("#{filter.field} #{transform_compare(filter.type, filter.compare)} ?",
21
+ transform_value(filter.type, filter.value))
22
+ end
23
+
24
+ next if filter.filters.blank?
25
+
26
+ # contains inner filters, chain the query with OR conditions
27
+ columns = []
28
+ values = []
29
+ filter.filters.each do |inner_filter|
30
+ validate_filter(filter)
31
+ columns.push("#{inner_filter.field} #{transform_compare(inner_filter.type, inner_filter.compare)} ?")
32
+ values.push(transform_value(inner_filter.type, inner_filter.value))
33
+ end
34
+
35
+ query = query.where(columns.join(' OR '), *values) unless columns.empty?
36
+ end
37
+
38
+ query
39
+ end
40
+
41
+ def self.order(query:, meta:)
42
+ return query if meta.blank? || meta.sorts.blank?
43
+
44
+ meta.sorts.each do |sort|
45
+ # to prevent sql injection
46
+ # sort.field should contains only alphabet and nothing else
47
+ raise StandardError, 'POSSIBLE_SQL_INJECTION' unless validate_column_name(sort.field)
48
+ # sort.order can only be asc or desc
49
+ raise StandardError, 'POSSIBLE_SQL_INJECTION' unless %w[asc desc].include?(sort.order.downcase)
50
+
51
+ query = query.order("#{sort.field.downcase} #{sort.order.upcase}")
52
+ end
53
+ query
54
+ end
55
+
56
+ def self.paginate(query:, meta:)
57
+ current_page = meta.page
58
+ offset = (current_page - 1) * meta.limit
59
+ total = query.count
60
+ data = query.limit(meta.limit).offset(offset)
61
+
62
+ page_count = (total + meta.limit - 1) / meta.limit
63
+
64
+ OpenStruct.new(
65
+ data: data,
66
+ pagination: OpenStruct.new(
67
+ page: current_page,
68
+ limit: meta.limit,
69
+ previous_page: current_page - 1,
70
+ current_page: current_page,
71
+ next_page: current_page < page_count ? current_page + 1 : 0,
72
+ page_count: page_count,
73
+ total_count: total
74
+ )
75
+ )
76
+ end
77
+
78
+ #######################################
79
+ ######
80
+ ###### private methods
81
+ ######
82
+ ######
83
+ ######
84
+ ##########################################
85
+
86
+ def self.validate_column_name(column)
87
+ # allow underscore
88
+ column = column.gsub('_', '')
89
+
90
+ Istox::RegexHelper.alphabet_only(column)
91
+ end
92
+
93
+ def self.validate_filter(filter)
94
+ # filter.field/column should contains only alphabet and nothing else
95
+ raise StandardError, 'POSSIBLE_SQL_INJECTION' unless validate_column_name(filter.field)
96
+
97
+ # filter.compare should only contains alphabets (eg. IN) or symbols only (eg. >=, =, <=, <>)
98
+ raise StandardError, 'POSSIBLE_SQL_INJECTION' unless validate_compare(filter.compare)
99
+ end
100
+
101
+ def self.transform_compare(type, compare)
102
+ return compare if type.blank?
103
+
104
+ return 'IS' if type.downcase == 'nullable' && ['=', 'is', '=='].include?(compare.downcase)
105
+
106
+ return 'IS NOT' if type.downcase == 'nullable' && ['<>', 'is not', '!='].include?(compare.downcase)
107
+
108
+ compare
109
+ end
110
+
111
+ def self.transform_value(type, value)
112
+ return value if value.blank? || type.blank? || type.downcase == 'string'
113
+
114
+ return 'NULL' if type.downcase == 'nullable' && %w[null true yes].include?(type.downcase)
115
+
116
+ return 'NOT NULL' if type.downcase == 'nullable' && %w[not_null false no].include?(type.downcase)
117
+
118
+ return value.to_i if type.downcase == 'integer'
119
+
120
+ return value.to_f if type.downcase == 'float'
121
+
122
+ return ::Istox::CommonHelper.to_datetime(value) if type.downcase == 'date' || type.downcase == 'datetime'
123
+ end
124
+
125
+ def self.validate_compare(compare)
126
+ Istox::RegexHelper.alphabet_only(compare) || Istox::RegexHelper.symbol_only(compare)
127
+ end
128
+
129
+ private_class_method :validate_compare, :validate_filter, :transform_value, :transform_compare, :validate_column_name
130
+ end
131
+ end
@@ -1,3 +1,3 @@
1
1
  module Istox
2
- VERSION = '0.1.97'.freeze
2
+ VERSION = '0.1.98'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: istox
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.97
4
+ version: 0.1.98
5
5
  platform: ruby
6
6
  authors:
7
7
  - Siong Leng
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-11-27 00:00:00.000000000 Z
11
+ date: 2019-12-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bunny
@@ -294,7 +294,6 @@ files:
294
294
  - lib/istox/helpers/bunny_boot.rb
295
295
  - lib/istox/helpers/common_helper.rb
296
296
  - lib/istox/helpers/f_math.rb
297
- - lib/istox/helpers/filter.rb
298
297
  - lib/istox/helpers/graphql_client.rb
299
298
  - lib/istox/helpers/grpc_client.rb
300
299
  - lib/istox/helpers/gruf_listener_hook.rb
@@ -303,6 +302,8 @@ files:
303
302
  - lib/istox/helpers/order_book_price_time.rb
304
303
  - lib/istox/helpers/order_book_prorate.rb
305
304
  - lib/istox/helpers/publisher.rb
305
+ - lib/istox/helpers/regex_helper.rb
306
+ - lib/istox/helpers/result_handler.rb
306
307
  - lib/istox/helpers/vault.rb
307
308
  - lib/istox/interfaces/chainhub/transaction.rb
308
309
  - lib/istox/models/blockchain_receipt.rb
@@ -1,37 +0,0 @@
1
- module Istox
2
- module Filter
3
- def self.order(query:, filters:)
4
- filters&.sort&.each do |x|
5
- query = query.order("#{x.field.downcase} #{x.order.upcase}")
6
- end
7
- query
8
- end
9
-
10
- def self.paginate(query:, filters:)
11
- current_page = filters.page
12
- offset = (current_page - 1) * filters.limit
13
- total = query.count
14
- data = query.limit(filters.limit).offset(offset)
15
-
16
- page_count = (total + filters.limit - 1) / filters.limit
17
-
18
- {
19
- data: data,
20
- pagination: {
21
- page: current_page,
22
- limit: filters.limit,
23
- previousPage: current_page - 1,
24
- currentPage: current_page,
25
- nextPage: current_page < page_count ? current_page + 1 : 0,
26
- pageCount: page_count,
27
- totalCount: total
28
- }
29
- }
30
- end
31
-
32
- def self.order_and_paginate(query:, filters:)
33
- query = order(query: query, filters: filters)
34
- paginate(query: query, filters: filters)
35
- end
36
- end
37
- end