query_string_interface 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,16 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ gem "rake", "0.8.7"
6
+ gem "i18n"
7
+
8
+ platforms :mri_18 do
9
+ gem "ruby-debug"
10
+ end
11
+
12
+ platforms :mri_19 do
13
+ gem "ruby-debug19", :require => 'ruby-debug' if RUBY_VERSION < "1.9.3"
14
+ gem 'simplecov', :require => false
15
+ end
16
+
data/Gemfile.lock ADDED
@@ -0,0 +1,61 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ query_string_interface (0.1.0)
5
+ activesupport (>= 3.0.0)
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ specs:
10
+ activesupport (3.1.0)
11
+ multi_json (~> 1.0)
12
+ archive-tar-minitar (0.5.2)
13
+ columnize (0.3.4)
14
+ diff-lcs (1.1.3)
15
+ i18n (0.6.0)
16
+ linecache (0.46)
17
+ rbx-require-relative (> 0.0.4)
18
+ linecache19 (0.5.12)
19
+ ruby_core_source (>= 0.1.4)
20
+ multi_json (1.0.3)
21
+ rake (0.8.7)
22
+ rbx-require-relative (0.0.5)
23
+ rspec (2.6.0)
24
+ rspec-core (~> 2.6.0)
25
+ rspec-expectations (~> 2.6.0)
26
+ rspec-mocks (~> 2.6.0)
27
+ rspec-core (2.6.4)
28
+ rspec-expectations (2.6.0)
29
+ diff-lcs (~> 1.1.2)
30
+ rspec-mocks (2.6.0)
31
+ ruby-debug (0.10.4)
32
+ columnize (>= 0.1)
33
+ ruby-debug-base (~> 0.10.4.0)
34
+ ruby-debug-base (0.10.4)
35
+ linecache (>= 0.3)
36
+ ruby-debug-base19 (0.11.25)
37
+ columnize (>= 0.3.1)
38
+ linecache19 (>= 0.5.11)
39
+ ruby_core_source (>= 0.1.4)
40
+ ruby-debug19 (0.11.6)
41
+ columnize (>= 0.3.1)
42
+ linecache19 (>= 0.5.11)
43
+ ruby-debug-base19 (>= 0.11.19)
44
+ ruby_core_source (0.1.5)
45
+ archive-tar-minitar (>= 0.5.2)
46
+ simplecov (0.5.3)
47
+ multi_json (~> 1.0.3)
48
+ simplecov-html (~> 0.5.3)
49
+ simplecov-html (0.5.3)
50
+
51
+ PLATFORMS
52
+ ruby
53
+
54
+ DEPENDENCIES
55
+ i18n
56
+ query_string_interface!
57
+ rake (= 0.8.7)
58
+ rspec (>= 2.6.0)
59
+ ruby-debug
60
+ ruby-debug19
61
+ simplecov
data/MIT_LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Vicente Mundim
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,44 @@
1
+ = Overview
2
+
3
+ == About QueryStringInterace
4
+
5
+ This gem extracts params given as a hash to structured data, that can be used when creating queries
6
+
7
+ == Repository
8
+
9
+ http://github.com/vicentemundim/query_string_interface
10
+
11
+ = Installing
12
+
13
+ This is a gem, so you can install it by:
14
+
15
+ sudo gem install query_string_interface
16
+
17
+ Or, if you are using rails, put this in your Gemfile:
18
+
19
+ gem 'query_string_interface'
20
+
21
+ = Usage
22
+
23
+ To use it, just extend QueryStringInterface in your document model:
24
+
25
+ class Document
26
+ include Mongoid::Document
27
+ extend QueryInterfaceString
28
+
29
+ # ... add fields here
30
+ end
31
+
32
+ Then, you can use some class methods with your ORM syntax:
33
+
34
+ def self.filter_by(params)
35
+ where(filtering_options(params)).order_by(*sorting_options(params))
36
+ end
37
+
38
+ = ORM Adapters
39
+
40
+ http://github.com/vicentemundim/mongoid_query_string_interface
41
+
42
+ = Credits
43
+
44
+ Vicente Mundim: vicente.mundim at gmail dot com
@@ -0,0 +1,69 @@
1
+ require "active_support/json"
2
+ require "active_support/core_ext/hash/indifferent_access"
3
+
4
+ module QueryStringInterface
5
+ NORMAL_CONDITIONAL_OPERATORS = [:exists, :gte, :gt, :lte, :lt, :ne, :size, :near, :within]
6
+ ARRAY_CONDITIONAL_OPERATORS = [:all, :in, :nin]
7
+ CONDITIONAL_OPERATORS = ARRAY_CONDITIONAL_OPERATORS + NORMAL_CONDITIONAL_OPERATORS
8
+ SORTING_OPERATORS = [:asc, :desc]
9
+ OR_OPERATOR = :or
10
+
11
+ OPERATORS = CONDITIONAL_OPERATORS + SORTING_OPERATORS + [OR_OPERATOR]
12
+
13
+
14
+ ATTRIBUTE_REGEX = /^(.*)\.(#{(OPERATORS).join('|')})$/
15
+ OPERATOR_REGEX = /^.*\.(#{CONDITIONAL_OPERATORS.join('|')})$/
16
+
17
+ ORDER_BY_PARAMETER = :order_by
18
+ PAGINATION_PARAMTERS = [:per_page, :page]
19
+ FRAMEWORK_PARAMETERS = [:controller, :action, :format]
20
+ CONTROL_PARAMETERS = [:disable_default_filters]
21
+ RESERVED_PARAMETERS = FRAMEWORK_PARAMETERS + PAGINATION_PARAMTERS + [ORDER_BY_PARAMETER] + CONTROL_PARAMETERS
22
+
23
+ def default_filtering_options
24
+ {}
25
+ end
26
+
27
+ def default_sorting_options
28
+ []
29
+ end
30
+
31
+ def default_pagination_options
32
+ { :per_page => 12, :page => 1 }
33
+ end
34
+
35
+ def sorting_attributes_to_replace
36
+ {}
37
+ end
38
+
39
+ def filtering_attributes_to_replace
40
+ {}
41
+ end
42
+
43
+ def pagination_options(options={})
44
+ default_pagination_options.with_indifferent_access.merge(options)
45
+ end
46
+
47
+ def filtering_options(options={})
48
+ QueryStringInterface::FilterCollection.new(
49
+ only_filtering(options),
50
+ options.has_key?(:disable_default_filters) ? {} : default_filtering_options,
51
+ filtering_attributes_to_replace
52
+ ).parse
53
+ end
54
+
55
+ def sorting_options(options={})
56
+ QueryStringInterface::SortingFilters.new(options, default_sorting_options, sorting_attributes_to_replace).parse
57
+ end
58
+
59
+ def only_filtering(options={})
60
+ options.with_indifferent_access.except(*RESERVED_PARAMETERS)
61
+ end
62
+ end
63
+
64
+ require "query_string_interface/version"
65
+ require "query_string_interface/helpers"
66
+ require "query_string_interface/parsers"
67
+ require "query_string_interface/filter"
68
+ require "query_string_interface/filter_collection"
69
+ require "query_string_interface/sorting_filters"
@@ -0,0 +1,148 @@
1
+ require 'cgi'
2
+ require 'json'
3
+
4
+ module QueryStringInterface
5
+ class Filter
6
+ include QueryStringInterface::Helpers
7
+
8
+ attr_reader :raw_attribute, :raw_value
9
+
10
+ PARSERS = [
11
+ QueryStringInterface::Parsers::ArrayParser.new,
12
+ QueryStringInterface::Parsers::DateTimeParser.new,
13
+ QueryStringInterface::Parsers::NumberParser.new,
14
+ QueryStringInterface::Parsers::RegexParser.new,
15
+ QueryStringInterface::Parsers::BooleanAndNilParser.new
16
+ ]
17
+
18
+ def initialize(raw_attribute, raw_value, attributes_to_replace={}, raw_params={})
19
+ @raw_attribute = raw_attribute
20
+ @raw_value = raw_value
21
+ @attributes_to_replace = attributes_to_replace
22
+ @raw_params = raw_params
23
+ end
24
+
25
+ def attribute
26
+ @attribute ||= replaced_attribute_name(parsed_attribute, @attributes_to_replace).to_s
27
+ end
28
+
29
+ def value
30
+ @value ||= expanded_value
31
+ end
32
+
33
+ def operator
34
+ @operator ||= operator_from(raw_attribute)
35
+ end
36
+
37
+ def or_attribute?
38
+ raw_attribute == 'or'
39
+ end
40
+
41
+ def include?(other_filter)
42
+ if or_attribute?
43
+ json_value.any? do |filters|
44
+ filters.filter_parsers.any? do |filter_parser|
45
+ filter_parser.attribute == other_filter.attribute &&
46
+ conditional_array_operators.include?(filter_parser.operator) &&
47
+ filter_parser.operator == other_filter.operator
48
+ end
49
+ end
50
+ end
51
+ end
52
+
53
+ def merge(other_filter)
54
+ if or_attribute?
55
+ @value = json_value.map do |filters|
56
+ filters.filter_parsers << other_filter
57
+ filters.parse
58
+ end
59
+ elsif conditional_array_operators.include?(other_filter.operator) && operator == other_filter.operator
60
+ @value = value.inject({}) do |result, filter|
61
+ filter_operation, filter_value = filter
62
+ filter_value = filter_value.concat(other_filter.value[filter_operation]) if other_filter.value[filter_operation]
63
+ result[filter_operation] = filter_value
64
+ result
65
+ end
66
+ else
67
+ @value = value.merge(other_filter.value)
68
+ end
69
+ end
70
+
71
+ private
72
+ def parsed_attribute
73
+ if raw_attribute.respond_to?(:key)
74
+ raw_attribute.key.to_s
75
+ elsif or_attribute?
76
+ '$or'
77
+ elsif raw_attribute =~ QueryStringInterface::ATTRIBUTE_REGEX
78
+ $1
79
+ else
80
+ raw_attribute
81
+ end
82
+ end
83
+
84
+ def expanded_value
85
+ if operator
86
+ if or_attribute?
87
+ parsed_json_value
88
+ else
89
+ { operator => replaced_attribute_value(parsed_attribute, parsed_value, @attributes_to_replace, @raw_params) }
90
+ end
91
+ else
92
+ replaced_attribute_value(parsed_attribute, parsed_value, @attributes_to_replace, @raw_params)
93
+ end
94
+ end
95
+
96
+ def parsed_value
97
+ if raw_value.is_a?(String)
98
+ PARSERS.each do |parser|
99
+ return parser.parse(unescaped_raw_value) if parser.parseable?(unescaped_raw_value, operator)
100
+ end
101
+
102
+ return nil
103
+ else
104
+ raw_value
105
+ end
106
+ end
107
+
108
+ def parsed_json_value
109
+ if unescaped_raw_value.is_a?(String)
110
+ json_value.map(&:parse)
111
+ else
112
+ unescaped_raw_value
113
+ end
114
+ end
115
+
116
+ def json_value
117
+ raw_or_data = ActiveSupport::JSON.decode(unescaped_raw_value)
118
+
119
+ raise "$or query filters must be given as an array of hashes" unless valid_or_filters?(raw_or_data)
120
+
121
+ raw_or_data.map do |filters|
122
+ FilterCollection.new(filters, {}, @attributes_to_replace, @raw_params)
123
+ end
124
+ end
125
+
126
+ def valid_or_filters?(raw_or_data)
127
+ raw_or_data.is_a?(Array) and raw_or_data.all? { |item| item.is_a?(Hash) }
128
+ end
129
+
130
+ def unescaped_raw_value
131
+ @unescaped_raw_value ||= raw_value.is_a?(String) ? CGI.unescape(raw_value) : raw_value
132
+ end
133
+
134
+ def conditional_array_operators
135
+ QueryStringInterface::ARRAY_CONDITIONAL_OPERATORS.map { |o| "$#{o}" }
136
+ end
137
+
138
+ def operator_from(attribute)
139
+ if attribute.respond_to?(:operator)
140
+ "$#{attribute.operator}"
141
+ elsif or_attribute?
142
+ '$or'
143
+ elsif attribute =~ QueryStringInterface::OPERATOR_REGEX
144
+ "$#{$1}"
145
+ end
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,73 @@
1
+ module QueryStringInterface
2
+ class FilterCollection
3
+ include QueryStringInterface::Helpers
4
+
5
+ attr_reader :filters, :default_filters
6
+
7
+ def initialize(filters, default_filters={}, attributes_to_replace={}, raw_filters=nil)
8
+ @filters = filters.with_indifferent_access
9
+ @default_filters = default_filters.with_indifferent_access
10
+ @attributes_to_replace = attributes_to_replace.with_indifferent_access
11
+ @raw_filters = raw_filters.nil? ? @filters : raw_filters.with_indifferent_access
12
+ end
13
+
14
+ def parse
15
+ result = default_filters.inject({}) do |result, item|
16
+ raw_attribute, raw_value = item
17
+ result[replaced_attribute_name(raw_attribute, @attributes_to_replace).to_s] = replaced_attribute_value(raw_attribute, raw_value, @attributes_to_replace, @raw_filters)
18
+ result
19
+ end
20
+ result.merge(parsed_filters)
21
+ end
22
+
23
+ def filter_parsers
24
+ @filter_parsers ||= filters.map do |raw_attribute, raw_value|
25
+ Filter.new(raw_attribute, raw_value, @attributes_to_replace, @raw_filters)
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ def parsed_filters
32
+ filter_parsers_hash.inject({}) do |result, item|
33
+ attribute, filter_parser = item
34
+
35
+ result[attribute] = filter_parser.value
36
+
37
+ result
38
+ end
39
+ end
40
+
41
+ def filter_parsers_hash
42
+ optimized_filter_parsers.inject({}) do |result, filter_parser|
43
+ if result.has_key?(filter_parser.attribute)
44
+ result[filter_parser.attribute].merge(filter_parser)
45
+ else
46
+ result[filter_parser.attribute] = filter_parser
47
+ end
48
+
49
+ result
50
+ end
51
+ end
52
+
53
+ def optimized_filter_parsers
54
+ if or_filter_parser
55
+ filter_parsers.inject([]) do |result, filter_parser|
56
+ if filter_parser != or_filter_parser && or_filter_parser.include?(filter_parser)
57
+ or_filter_parser.merge(filter_parser)
58
+ else
59
+ result << filter_parser
60
+ end
61
+
62
+ result
63
+ end
64
+ else
65
+ filter_parsers
66
+ end
67
+ end
68
+
69
+ def or_filter_parser
70
+ @or_filter_parser ||= filter_parsers.select { |filter_parser| filter_parser.or_attribute? }.first
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,22 @@
1
+ module QueryStringInterface
2
+ module Helpers
3
+ def hash_with_indifferent_access(params)
4
+ params.is_a?(HashWithIndifferentAccess) ? params : params.with_indifferent_access
5
+ end
6
+
7
+ def replace_attribute(attribute, hash_with_attributes_to_replace)
8
+ hash = hash_with_indifferent_access(hash_with_attributes_to_replace)
9
+ hash.has_key?(attribute) ? hash[attribute] : attribute
10
+ end
11
+
12
+ def replaced_attribute_name(attribute, hash_with_attributes_to_replace)
13
+ attribute = replace_attribute(attribute, hash_with_attributes_to_replace)
14
+ attribute.is_a?(Hash) ? attribute[:to] : attribute
15
+ end
16
+
17
+ def replaced_attribute_value(attribute, value, hash_with_attributes_to_replace, raw_params)
18
+ attribute = replace_attribute(attribute, hash_with_attributes_to_replace)
19
+ attribute.is_a?(Hash) ? attribute[:convert_value_to].call(value, raw_params) : value
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,5 @@
1
+ require "query_string_interface/parsers/date_time_parser"
2
+ require "query_string_interface/parsers/number_parser"
3
+ require "query_string_interface/parsers/array_parser"
4
+ require "query_string_interface/parsers/regex_parser"
5
+ require "query_string_interface/parsers/boolean_and_nil_parser"
@@ -0,0 +1,34 @@
1
+ module QueryStringInterface
2
+ module Parsers
3
+ class ArrayParser
4
+ ARRAY_SEPARATOR = '|'
5
+
6
+ def parseable?(value, operator)
7
+ operator && conditional_operators.include?(operator)
8
+ end
9
+
10
+ def parse(value)
11
+ value.split(ARRAY_SEPARATOR).map(&:strip).map do |item|
12
+ parse_item(item)
13
+ end
14
+ end
15
+
16
+ private
17
+ def parse_item(item)
18
+ other_parsers.each do |parser|
19
+ return parser.parse(item) if parser.parseable?(item, '')
20
+ end
21
+ end
22
+
23
+ def other_parsers
24
+ @other_parsers ||= QueryStringInterface::Filter::PARSERS.reject do |parser|
25
+ parser.is_a?(ArrayParser)
26
+ end
27
+ end
28
+
29
+ def conditional_operators
30
+ @conditional_operators ||= QueryStringInterface::ARRAY_CONDITIONAL_OPERATORS.map { |o| "$#{o}" }
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,28 @@
1
+ module QueryStringInterface
2
+ module Parsers
3
+ class BooleanAndNilParser
4
+ def parseable?(value, operator)
5
+ !value.nil? && !value.empty?
6
+ end
7
+
8
+ def parse(value)
9
+ if boolean?(value)
10
+ value.strip == 'true'
11
+ elsif value.nil? or value.empty? or nil_value?(value)
12
+ nil
13
+ else
14
+ value
15
+ end
16
+ end
17
+
18
+ private
19
+ def boolean?(value)
20
+ value && ['true', 'false'].include?(value.strip)
21
+ end
22
+
23
+ def nil_value?(value)
24
+ value && ['nil', 'null'].include?(value.strip)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,15 @@
1
+ module QueryStringInterface
2
+ module Parsers
3
+ class DateTimeParser
4
+ DATE_REGEX = /^(?:\d{4}-\d{2}-\d{2}|\d{4}-\d{1,2}-\d{1,2}[T \t]+\d{1,2}:\d{2}:\d{2}(\.[0-9]*)?([ \t]*)(Z?|[-+]\d{2}?(:?\d{2})?))$/
5
+
6
+ def parseable?(value, operator)
7
+ DATE_REGEX.match(value)
8
+ end
9
+
10
+ def parse(value)
11
+ Time.parse(value)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,26 @@
1
+ module QueryStringInterface
2
+ module Parsers
3
+ class NumberParser
4
+ def parseable?(value, operator)
5
+ integer?(value) or float?(value)
6
+ end
7
+
8
+ def parse(value)
9
+ if integer?(value)
10
+ value.to_i
11
+ elsif float?(value)
12
+ value.to_f
13
+ end
14
+ end
15
+
16
+ private
17
+ def integer?(value)
18
+ value =~ /^\d+$/
19
+ end
20
+
21
+ def float?(value)
22
+ value =~ /^(\d+)(\.?\d*)$/
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,15 @@
1
+ module QueryStringInterface
2
+ module Parsers
3
+ class RegexParser
4
+ def parseable?(value, operator)
5
+ value =~ /^\/(.*)\/(i|m|x)?$/
6
+ end
7
+
8
+ def parse(value)
9
+ if value =~ /^\/(.*)\/(i|m|x)?$/
10
+ eval($&)
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,51 @@
1
+ module QueryStringInterface
2
+ class SortingFilters
3
+ include QueryStringInterface::Helpers
4
+
5
+ SORTING_FIELD_REGEXP = /(.*)\.(#{QueryStringInterface::SORTING_OPERATORS.join('|')})/
6
+
7
+ def initialize(raw_filters, default_filters, attributes_to_replace={})
8
+ @raw_filters = raw_filters.with_indifferent_access
9
+ @default_filters = default_filters
10
+ @attributes_to_replace = attributes_to_replace
11
+ end
12
+
13
+ def parse
14
+ if @raw_filters.has_key?('order_by')
15
+ parse_filters(@raw_filters['order_by'])
16
+ else
17
+ parse_filters(@default_filters)
18
+ end
19
+ end
20
+
21
+ def parse_filters(filters)
22
+ filters = filters.split('|') if filters.is_a?(String)
23
+ filters.map do |filter|
24
+ replace(filter)
25
+ end
26
+ end
27
+
28
+ private
29
+ def replace(filter)
30
+ if filter.respond_to?(:key) && filter.respond_to?(:operator)
31
+ replaced_item_for filter.key, filter.operator
32
+ elsif filter.is_a?(String) or filter.is_a?(Symbol)
33
+ if match = matches?(filter)
34
+ replaced_item_for match[1], match[2]
35
+ else
36
+ replaced_item_for filter, :asc
37
+ end
38
+ elsif filter.is_a?(Hash)
39
+ replaced_item_for filter.keys.first, filter[filter.keys.first]
40
+ end
41
+ end
42
+
43
+ def replaced_item_for(key, value)
44
+ { replace_attribute(key, @attributes_to_replace).to_sym => value.to_sym }
45
+ end
46
+
47
+ def matches?(filter)
48
+ filter.match(SORTING_FIELD_REGEXP)
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,3 @@
1
+ module QueryStringInterface
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: query_string_interface
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.1.0
6
+ platform: ruby
7
+ authors:
8
+ - Vicente Mundim
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-09-26 00:00:00 -03:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: activesupport
18
+ prerelease: false
19
+ requirement: &id001 !ruby/object:Gem::Requirement
20
+ none: false
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: 3.0.0
25
+ type: :runtime
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ prerelease: false
30
+ requirement: &id002 !ruby/object:Gem::Requirement
31
+ none: false
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: 2.6.0
36
+ type: :development
37
+ version_requirements: *id002
38
+ description: This gem extracts params given as a hash to structured data, that can be used when creating queries
39
+ email:
40
+ - vicente.mundim@gmail.com
41
+ executables: []
42
+
43
+ extensions: []
44
+
45
+ extra_rdoc_files: []
46
+
47
+ files:
48
+ - lib/query_string_interface/filter.rb
49
+ - lib/query_string_interface/filter_collection.rb
50
+ - lib/query_string_interface/helpers.rb
51
+ - lib/query_string_interface/parsers/array_parser.rb
52
+ - lib/query_string_interface/parsers/boolean_and_nil_parser.rb
53
+ - lib/query_string_interface/parsers/date_time_parser.rb
54
+ - lib/query_string_interface/parsers/number_parser.rb
55
+ - lib/query_string_interface/parsers/regex_parser.rb
56
+ - lib/query_string_interface/parsers.rb
57
+ - lib/query_string_interface/sorting_filters.rb
58
+ - lib/query_string_interface/version.rb
59
+ - lib/query_string_interface.rb
60
+ - MIT_LICENSE
61
+ - README.rdoc
62
+ - Gemfile
63
+ - Gemfile.lock
64
+ has_rdoc: true
65
+ homepage: ""
66
+ licenses: []
67
+
68
+ post_install_message:
69
+ rdoc_options: []
70
+
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: "0"
79
+ required_rubygems_version: !ruby/object:Gem::Requirement
80
+ none: false
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: "0"
85
+ requirements: []
86
+
87
+ rubyforge_project: query_string_interface
88
+ rubygems_version: 1.6.2
89
+ signing_key:
90
+ specification_version: 3
91
+ summary: Extracts query string params to a structured data, suitable to use for model queries
92
+ test_files: []
93
+