queryfy 0.2.2 → 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: b8245801e6c8695ed9ac50a84d9aeb6f7179a946
4
- data.tar.gz: de1e2a5ff538749f4d6b27e632015048ccd5a7db
3
+ metadata.gz: 2fc1d0e6915ee945c426a61ee049a041382a974c
4
+ data.tar.gz: 4d9f896e6af4697c878667732959ae6075ec25aa
5
5
  SHA512:
6
- metadata.gz: 0ad2bda81f8b531a0ebcc7163becbed28c5817561b96236d5e7e543b518e000679d73f32d1c47b2abaa7b46c83f404838d9339475caa6dd344fad9f187d1188e
7
- data.tar.gz: e39d222be50aae99827b6b0020776099ccea9f9dc9bd069f681df2a2eec06f90dc28fe4214fa96f18a45e9055c730350532183ebfc202314f27d067d4e9592fd
6
+ metadata.gz: fc91b3768dc4fae24b95854a1c5f0183df525a593d615a2b74d37cd2f5fdbeaa84174d2f0639adb3d8cb09676ce1b9503bbc010bab3590277bf550d7253ff3f3
7
+ data.tar.gz: 4a0de0c99bee227edda239c6047b072e18956c9835496c665e3e7f268cf37880e8e13240ab853c539cc70f65fd132e07abf572bb812db2d1537f1a580dfc7465
data/README.md CHANGED
@@ -54,9 +54,9 @@ SomeModel.queryfy(queryparams)
54
54
  The gem adds makes a `queryfy` method available to ActiveRecord::Base when included.
55
55
  The queryfy method takes a hash in the following format:
56
56
  ```
57
- {'filter': 'name=="name", 'offset': 50, 'limit': 10}
57
+ {'filter': 'name=="name", 'order': 'id-', 'offset': 50, 'limit': 10}
58
58
  ```
59
- All three are optional, and any extra values are ignored.
59
+ All four are optional, and any extra values are ignored.
60
60
 
61
61
  Defaults:
62
62
  ```
@@ -71,6 +71,28 @@ After calling `queryfy` you will get back the following:
71
71
  {data: [your data], count: total results, offset: the offset used, limit: the limit used}
72
72
  ```
73
73
 
74
+ ### Pagination
75
+
76
+ Queryfy supports pagination by passing offset and limit queryparams. offset
77
+ skips the first x records, while limit only selects y records
78
+
79
+ ```
80
+ # Returns the second page of results since we skip the first 25 and want 25 records a page
81
+ offset=25&limit=25
82
+ ```
83
+
84
+ ### Ordering
85
+
86
+ Ordering is also supported by queryfy. To add a certain order you use the order
87
+ queryparam. To order on multiple fields you should pass the fields comma
88
+ seperated. By default fields are ordered ascending, to order them descending
89
+ you postfix the field with a minus, i.e `id-,name+,email-`
90
+
91
+ ```
92
+ # Would order the results by name, and within that by the records that were created the farthest back.
93
+ name-,created_at+
94
+ ```
95
+
74
96
  ### Exceptions
75
97
 
76
98
  All exceptions queryfy can raise inherit from `QueryfyError`
@@ -8,17 +8,8 @@ module FilterLexer
8
8
  operator_method = elements[1].to_arel
9
9
  val = elements[2].text_value
10
10
 
11
- # Check if the field we want to filter on exists
12
- field_index = arel_table.engine.column_names.index(field)
11
+ field = Queryfy.get_arel_field(arel_table, field)
13
12
 
14
- # Field does not exist, fail
15
- if field_index.nil?
16
- raise NoSuchFieldError.new("Unknown field #{ field }", field)
17
- else
18
- # Get the arel field name from our input, just to make sure
19
- # there is nothing weird is in the input
20
- field = arel_table.engine.column_names[field_index]
21
- end
22
13
  ast_node = arel_table[field.to_sym]
23
14
 
24
15
  # Build an arel node from the resolved operator, value and field
@@ -1,3 +1,3 @@
1
1
  module Queryfy
2
- VERSION = "0.2.2"
2
+ VERSION = "0.3.0"
3
3
  end
data/lib/queryfy.rb CHANGED
@@ -11,14 +11,15 @@ module Queryfy
11
11
  define_setting :default_limit, 50
12
12
 
13
13
  # Actually builds the query
14
- def self.build_query(klass, querystring, limit = 50, offset = 0)
14
+ def self.build_query(klass, querystring, orderstring, limit = 50, offset = 0)
15
15
  limit = [max_limit, limit.to_i].min
16
16
  offset = offset.to_i
17
17
  # Handle empty and nil queries
18
18
  if (querystring.nil? || querystring == '')
19
+ data = self.add_order(klass.arel_table, klass.limit(limit).offset(offset), orderstring)
19
20
  return {
20
- data: klass.limit(limit).offset(offset),
21
- count: klass.all.count,
21
+ data: data,
22
+ count: klass.all.count,
22
23
  limit: limit.to_i, offset: offset.to_i
23
24
  }
24
25
  end
@@ -37,6 +38,7 @@ module Queryfy
37
38
  arel_tree = self.cleaned_to_arel(klass.arel_table, cleaned_tree)
38
39
  # If we want to actually query, add the conditions to query
39
40
  query = query.where(arel_tree) unless arel_tree.nil?
41
+ query = self.add_order(klass.arel_table, query, orderstring)
40
42
 
41
43
  total = 0
42
44
  if arel_tree.nil?
@@ -103,14 +105,58 @@ module Queryfy
103
105
  def self.from_queryparams(klass, queryparams)
104
106
  filter = ''
105
107
  offset = 0
108
+ order = ''
106
109
  limit = Queryfy::default_limit
107
110
  if (queryparams.is_a?(Hash))
108
111
  filter = queryparams['filter'] unless queryparams['filter'].nil?
109
112
  offset = queryparams['offset'] unless queryparams['offset'].nil?
110
113
  limit = queryparams['limit'] unless queryparams['limit'].nil?
114
+ order = queryparams['order'] unless queryparams['order'].nil?
111
115
  elsif(queryparams.is_a?(String))
112
116
  filter = queryparams
113
117
  end
114
- return Queryfy.build_query(klass, filter, limit, offset)
118
+ return Queryfy.build_query(klass, filter, order, limit, offset)
119
+ end
120
+
121
+ def self.add_order(arel_table, arel_query, orderstring)
122
+ # adds order conditions to the passed query
123
+
124
+ # If we don't want to order, return the oridinal query
125
+ return arel_query if orderstring.nil? || orderstring == ''
126
+
127
+ # Split the fields we want to order on
128
+ split = orderstring.split(',')
129
+
130
+ # Determine how we want to order each field (asc or desc)
131
+ split.each do |s|
132
+ order_char = s[-1, 1]
133
+ s.chop! if order_char == '+' || order_char == '-'
134
+ next unless order_char == '+' || order_char == '-'
135
+ field = Queryfy.get_arel_field(arel_table, s)
136
+ order = :asc
137
+ if order_char == '-'
138
+ order = :desc
139
+ end
140
+
141
+ # Add the order as a string, since hash is unsupported with query
142
+ arel_query = arel_query.order("#{field} #{order}")
143
+ end
144
+ return arel_query
145
+ end
146
+
147
+ def self.get_arel_field(arel_table, field)
148
+ # Check if the field we want to filter on exists
149
+ field_index = arel_table.engine.column_names.index(field)
150
+ arel_field = nil
151
+
152
+ # Field does not exist, fail
153
+ if field_index.nil?
154
+ raise NoSuchFieldError.new("Unknown field #{ field }", field)
155
+ else
156
+ # Get the arel field name from our input, just to make sure
157
+ # there is nothing weird is in the input
158
+ arel_field = arel_table.engine.column_names[field_index]
159
+ end
160
+ return arel_field
115
161
  end
116
162
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: queryfy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bonemind
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-12-28 00:00:00.000000000 Z
11
+ date: 2016-02-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: filter_lexer