queryfy 0.2.2 → 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: 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