restful_query 0.3.0 → 0.3.1

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.
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ .DS_Store
2
+ tmp*
3
+ pkg*
4
+ .specification
5
+ _site*
data/History.txt CHANGED
@@ -1,3 +1,9 @@
1
+ == 0.3.1 2010-02-16
2
+
3
+ * Parser takes a :map_columns option which maps aliases column names
4
+ * The parser now strips all conditions with blank values. If you actually want
5
+ to compare on a blank value, use the convertable value ':blank'
6
+
1
7
  == 0.3.0 2009-08-10
2
8
 
3
9
  * Vast improvements/enhancements
data/README.rdoc CHANGED
@@ -54,11 +54,7 @@ http://code.quirkey.com/restful_query
54
54
  To install as a gem:
55
55
 
56
56
  sudo gem install restful_query
57
-
58
- or from github:
59
-
60
- sudo gem install quirkey-restful_query -s http://gems.github.com
61
-
57
+
62
58
  To install as a rails plugin
63
59
 
64
60
  ./script/plugin install git://github.com/quirkey/restful_query.git
data/Rakefile CHANGED
@@ -1,33 +1,30 @@
1
- %w[rubygems rake rake/clean hoe fileutils newgem rubigen].each { |f| require f }
1
+ %w[rubygems rake rake/clean rake/testtask fileutils].each { |f| require f }
2
2
  require File.dirname(__FILE__) + '/lib/restful_query'
3
3
 
4
- # Generate all the Rake tasks
5
- # Run 'rake -T' to see list of generated tasks (from gem root directory)
6
- $hoe = Hoe.spec('restful_query') do |p|
7
- p.version = RestfulQuery::VERSION
8
- p.developer('Aaron Quint', 'aaron@quirkey.com')
9
- p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
10
- p.rubyforge_name = 'quirkey'
11
- p.summary = 'Simple ActiveRecord and Sequel queries from a RESTful and safe interface'
12
- p.description = %q{RestfulQuery provides a simple interface in front of a complex parser to parse specially formatted query hashes into complex SQL queries. It includes ActiveRecord and Sequel extensions.}
13
- p.url = 'http://code.quirkey.com/restful_query'
14
- p.extra_deps = [
15
- ['activesupport','>= 2.2.0'],
16
- ['chronic','>= 0.2.3']
17
- ]
18
- p.extra_dev_deps = [
19
- ['newgem', ">= #{::Newgem::VERSION}"],
20
- ['Shoulda', '>= 1.2.0']
21
- ]
22
-
23
- p.clean_globs |= %w[**/.DS_Store tmp *.log]
24
- path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
25
- p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
26
- p.rsync_args = '-av --delete --ignore-errors'
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |s|
7
+ s.name = %q{restful_query}
8
+ s.version = RestfulQuery::VERSION
9
+ s.authors = ["Aaron Quint"]
10
+ s.summary = 'Simple ActiveRecord and Sequel queries from a RESTful and safe interface'
11
+ s.description = %q{RestfulQuery provides a simple interface in front of a complex parser to parse specially formatted query hashes into complex SQL queries. It includes ActiveRecord and Sequel extensions.}
12
+ s.rubyforge_project = %q{quirkey}
13
+ s.add_runtime_dependency(%q<activesupport>, [">= 2.2.0"])
14
+ s.add_runtime_dependency(%q<chronic>, [">= 0.2.3"])
15
+ s.add_development_dependency(%q<Shoulda>, [">= 1.2.0"])
16
+ end
17
+ Jeweler::GemcutterTasks.new
18
+ rescue LoadError
19
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
20
+ end
21
+
22
+ Rake::TestTask.new do |t|
23
+ t.libs << "test"
24
+ t.test_files = FileList['test/test*.rb']
25
+ t.verbose = true
27
26
  end
28
27
 
29
- require 'newgem/tasks' # load /tasks/*.rake
30
28
  Dir['tasks/**/*.rake'].each { |t| load t }
31
29
 
32
- # TODO - want other tests/tasks run by default? Add them to the list
33
- # task :default => [:spec, :features]
30
+ task :default => :test
@@ -22,7 +22,9 @@ module RestfulQuery
22
22
  ':true' => true,
23
23
  ':false' => false,
24
24
  ':nil' => nil,
25
- ':null' => nil
25
+ ':null' => nil,
26
+ ':blank' => '',
27
+ ':empty' => ''
26
28
  }.freeze
27
29
 
28
30
  ENGLISH_OPERATOR_MAPPING = {
@@ -1,11 +1,12 @@
1
1
  module RestfulQuery
2
2
  class Parser
3
- attr_reader :query, :exclude_columns, :integer_columns, :options
3
+ attr_reader :query, :exclude_columns, :map_columns, :integer_columns, :options
4
4
 
5
5
  def initialize(query, options = {})
6
6
  @options = options || {}
7
- @exclude_columns = options[:exclude_columns] ? [options.delete(:exclude_columns)].flatten.collect {|c| c.to_s } : []
8
- @integer_columns = options[:integer_columns] ? [options.delete(:integer_columns)].flatten.collect {|c| c.to_s } : []
7
+ @exclude_columns = columns_from_options(:exclude, options)
8
+ @integer_columns = columns_from_options(:integer, options)
9
+ @map_columns = options[:map_columns] || {}
9
10
  @default_sort = options[:default_sort] ? [Sort.parse(options[:default_sort])] : []
10
11
  @single_sort = options[:single_sort] || false
11
12
  @query = (query || {}).dup
@@ -44,12 +45,7 @@ module RestfulQuery
44
45
  hash['_sort'] = sorts.collect {|s| s.to_s } unless sorts.empty?
45
46
  hash
46
47
  end
47
-
48
- def self.sorts_from_hash(sorts)
49
- sort_conditions = [sorts].flatten.compact
50
- sort_conditions.collect {|c| Sort.parse(c) }
51
- end
52
-
48
+
53
49
  def sort_sql
54
50
  @sorts.collect {|s| s.to_sql }.join(', ')
55
51
  end
@@ -66,16 +62,19 @@ module RestfulQuery
66
62
  sorts.collect {|s| s.column }
67
63
  end
68
64
 
69
- def sorted_by?(column)
65
+ def sorted_by?(column_name)
66
+ column = map_column(column_name)
70
67
  sorted_columns.include?(column.to_s)
71
68
  end
72
69
 
73
- def sort(column)
74
- sorts.detect {|s| s && s.column == column.to_s }
70
+ def sort(column_name)
71
+ column = map_column(column_name)
72
+ sorts.detect {|s| s && s.column == column }
75
73
  end
76
74
 
77
- def set_sort(column, direction)
78
- if new_sort = self.sort(column)
75
+ def set_sort(column_name, direction)
76
+ column = map_column(column_name)
77
+ if new_sort = self.sort(column_name)
79
78
  if direction.nil?
80
79
  self.sorts.reject! {|s| s.column == column.to_s }
81
80
  else
@@ -111,7 +110,7 @@ module RestfulQuery
111
110
  end
112
111
 
113
112
  def extract_sorts_from_conditions
114
- @sorts = self.class.sorts_from_hash(@query.delete('_sort'))
113
+ @sorts = sorts_from_hash(@query.delete('_sort'))
115
114
  @sorts = @default_sort if @sorts.empty?
116
115
  end
117
116
 
@@ -133,15 +132,35 @@ module RestfulQuery
133
132
  # with a normalized array of conditions
134
133
  conditions.each do |condition|
135
134
  column, operator, value = condition['column'], condition['operator'] || 'eq', condition['value']
136
- unless exclude_columns.include?(column.to_s)
135
+ unless exclude_columns.include?(column.to_s) || value == ''
137
136
  condition_options = {}
138
137
  condition_options[:chronic] = true if chronic_columns.include?(column.to_s)
139
138
  condition_options[:integer] = true if integer_columns.include?(column.to_s)
140
139
  condition_options.merge!(condition['options'] || {})
141
- add_condition_for(column, Condition.new(column, value, operator, condition_options))
140
+ column_name = map_column(column)
141
+ add_condition_for(column, Condition.new(column_name, value, operator, condition_options))
142
142
  end
143
143
  end
144
144
  end
145
145
 
146
+ def sorts_from_hash(sorts)
147
+ sort_conditions = [sorts].flatten.compact
148
+ sort_conditions.collect do |c|
149
+ s = Sort.parse(c)
150
+ s.column = map_column(s.column)
151
+ s
152
+ end
153
+ end
154
+
155
+ def columns_from_options(column_type, options)
156
+ option = "#{column_type}_columns".to_sym
157
+ options[option] ? [options.delete(option)].flatten.collect {|c| c.to_s } : []
158
+ end
159
+
160
+ def map_column(column_name)
161
+ map_columns[column_name.to_s] || column_name.to_s
162
+ end
163
+
164
+
146
165
  end
147
166
  end
data/lib/restful_query.rb CHANGED
@@ -11,12 +11,12 @@ rescue LoadError
11
11
  end
12
12
 
13
13
  module RestfulQuery
14
- VERSION = '0.3.0'
14
+ VERSION = '0.3.1'
15
15
 
16
16
  class Error < RuntimeError; end
17
17
  end
18
18
 
19
19
 
20
- %w{condition sort parser}.each do |lib|
20
+ %w{condition sort parser can_query}.each do |lib|
21
21
  require File.join("restful_query","#{lib}.rb")
22
22
  end
data/rails/init.rb CHANGED
@@ -1,4 +1,3 @@
1
1
  require File.join(File.dirname(__FILE__),'..','lib','restful_query.rb')
2
- require File.join(File.dirname(__FILE__),'..','lib','restful_query', 'can_query.rb')
3
2
 
4
3
  ActiveRecord::Base.send(:include, RestfulQuery::CanQuery)
@@ -1,23 +1,54 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
1
4
  # -*- encoding: utf-8 -*-
2
5
 
3
6
  Gem::Specification.new do |s|
4
7
  s.name = %q{restful_query}
5
- s.version = "0.3.0"
8
+ s.version = "0.3.1"
6
9
 
7
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
11
  s.authors = ["Aaron Quint"]
9
- s.date = %q{2009-08-10}
12
+ s.date = %q{2010-02-16}
10
13
  s.description = %q{RestfulQuery provides a simple interface in front of a complex parser to parse specially formatted query hashes into complex SQL queries. It includes ActiveRecord and Sequel extensions.}
11
- s.email = ["aaron@quirkey.com"]
12
- s.extra_rdoc_files = ["History.txt", "Manifest.txt"]
13
- s.files = ["History.txt", "LICENSE", "Manifest.txt", "README.rdoc", "Rakefile", "init.rb", "lib/restful_query.rb", "lib/restful_query/can_query.rb", "lib/restful_query/condition.rb", "lib/restful_query/parser.rb", "lib/restful_query/sort.rb", "lib/sequel/extensions/restful_query.rb", "rails/init.rb", "restful_query.gemspec", "tasks/restful_query_tasks.rake", "test/test_helper.rb", "test/test_restful_query_can_query.rb", "test/test_restful_query_condition.rb", "test/test_restful_query_parser.rb", "test/test_restful_query_sort.rb"]
14
- s.homepage = %q{http://code.quirkey.com/restful_query}
15
- s.rdoc_options = ["--main", "README.txt"]
14
+ s.extra_rdoc_files = [
15
+ "LICENSE",
16
+ "README.rdoc"
17
+ ]
18
+ s.files = [
19
+ ".gitignore",
20
+ "History.txt",
21
+ "LICENSE",
22
+ "README.rdoc",
23
+ "Rakefile",
24
+ "init.rb",
25
+ "lib/restful_query.rb",
26
+ "lib/restful_query/can_query.rb",
27
+ "lib/restful_query/condition.rb",
28
+ "lib/restful_query/parser.rb",
29
+ "lib/restful_query/sort.rb",
30
+ "lib/sequel/extensions/restful_query.rb",
31
+ "rails/init.rb",
32
+ "restful_query.gemspec",
33
+ "tasks/restful_query_tasks.rake",
34
+ "test/test_helper.rb",
35
+ "test/test_restful_query_can_query.rb",
36
+ "test/test_restful_query_condition.rb",
37
+ "test/test_restful_query_parser.rb",
38
+ "test/test_restful_query_sort.rb"
39
+ ]
40
+ s.rdoc_options = ["--charset=UTF-8"]
16
41
  s.require_paths = ["lib"]
17
42
  s.rubyforge_project = %q{quirkey}
18
43
  s.rubygems_version = %q{1.3.5}
19
44
  s.summary = %q{Simple ActiveRecord and Sequel queries from a RESTful and safe interface}
20
- s.test_files = ["test/test_helper.rb", "test/test_restful_query_can_query.rb", "test/test_restful_query_condition.rb", "test/test_restful_query_parser.rb", "test/test_restful_query_sort.rb"]
45
+ s.test_files = [
46
+ "test/test_helper.rb",
47
+ "test/test_restful_query_can_query.rb",
48
+ "test/test_restful_query_condition.rb",
49
+ "test/test_restful_query_parser.rb",
50
+ "test/test_restful_query_sort.rb"
51
+ ]
21
52
 
22
53
  if s.respond_to? :specification_version then
23
54
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
@@ -26,21 +57,16 @@ Gem::Specification.new do |s|
26
57
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
27
58
  s.add_runtime_dependency(%q<activesupport>, [">= 2.2.0"])
28
59
  s.add_runtime_dependency(%q<chronic>, [">= 0.2.3"])
29
- s.add_development_dependency(%q<newgem>, [">= 1.5.2"])
30
60
  s.add_development_dependency(%q<Shoulda>, [">= 1.2.0"])
31
- s.add_development_dependency(%q<hoe>, [">= 2.3.3"])
32
61
  else
33
62
  s.add_dependency(%q<activesupport>, [">= 2.2.0"])
34
63
  s.add_dependency(%q<chronic>, [">= 0.2.3"])
35
- s.add_dependency(%q<newgem>, [">= 1.5.2"])
36
64
  s.add_dependency(%q<Shoulda>, [">= 1.2.0"])
37
- s.add_dependency(%q<hoe>, [">= 2.3.3"])
38
65
  end
39
66
  else
40
67
  s.add_dependency(%q<activesupport>, [">= 2.2.0"])
41
68
  s.add_dependency(%q<chronic>, [">= 0.2.3"])
42
- s.add_dependency(%q<newgem>, [">= 1.5.2"])
43
69
  s.add_dependency(%q<Shoulda>, [">= 1.2.0"])
44
- s.add_dependency(%q<hoe>, [">= 2.3.3"])
45
70
  end
46
71
  end
72
+
@@ -80,6 +80,16 @@ class RestfulQueryConditionTest < Test::Unit::TestCase
80
80
  end
81
81
  end
82
82
 
83
+ context "with a value of ':blank'" do
84
+ setup do
85
+ @condition = RestfulQuery::Condition.new('created_at', ':blank')
86
+ end
87
+
88
+ should "convert value to true true" do
89
+ assert_equal('', @condition.value)
90
+ end
91
+ end
92
+
83
93
  context "with the IN operator" do
84
94
  setup do
85
95
  @condition = RestfulQuery::Condition.new('year', '1995,2005,2006', 'in')
@@ -100,6 +100,50 @@ class RestfulQueryParserTest < Test::Unit::TestCase
100
100
  assert_not_equal Chronic.parse('1 day ago').to_s, @parser.conditions_for(:updated_at).first.value.to_s
101
101
  end
102
102
  end
103
+
104
+ context "with blank values" do
105
+ setup do
106
+ new_parser_from_hash({'isblank' => ''})
107
+ end
108
+
109
+ should "return parser object" do
110
+ assert @parser.is_a?(RestfulQuery::Parser)
111
+ end
112
+
113
+ should "not include conditions for blank values" do
114
+ assert @parser.conditions_for('created_at')
115
+ assert_nil @parser.conditions_for('isblank')
116
+ end
117
+ end
118
+
119
+ context "with map_columns" do
120
+ setup do
121
+ new_parser_from_hash({'section' => 4, '_sort' => 'category-up'}, {:map_columns => {
122
+ 'section' => 'section_id',
123
+ 'category' => 'category_id'
124
+ }})
125
+ end
126
+
127
+ should "return parser object" do
128
+ assert @parser.is_a?(RestfulQuery::Parser)
129
+ end
130
+
131
+ should "set the map_columns attribute" do
132
+ assert @parser.map_columns.is_a?(Hash)
133
+ end
134
+
135
+ should "map condition column" do
136
+ assert @parser.conditions_for('section')
137
+ assert_equal 'section_id', @parser.conditions_for('section').first.column
138
+ end
139
+
140
+ should "map sort column" do
141
+ @sort = @parser.sorts.first
142
+ assert @sort.is_a?(RestfulQuery::Sort)
143
+ assert_equal 'ASC', @sort.direction
144
+ assert_equal 'category_id', @sort.column
145
+ end
146
+ end
103
147
 
104
148
  context "with sort as a single string" do
105
149
  setup do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: restful_query
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Quint
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-08-10 00:00:00 -04:00
12
+ date: 2010-02-16 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -32,16 +32,6 @@ dependencies:
32
32
  - !ruby/object:Gem::Version
33
33
  version: 0.2.3
34
34
  version:
35
- - !ruby/object:Gem::Dependency
36
- name: newgem
37
- type: :development
38
- version_requirement:
39
- version_requirements: !ruby/object:Gem::Requirement
40
- requirements:
41
- - - ">="
42
- - !ruby/object:Gem::Version
43
- version: 1.5.2
44
- version:
45
35
  - !ruby/object:Gem::Dependency
46
36
  name: Shoulda
47
37
  type: :development
@@ -52,30 +42,19 @@ dependencies:
52
42
  - !ruby/object:Gem::Version
53
43
  version: 1.2.0
54
44
  version:
55
- - !ruby/object:Gem::Dependency
56
- name: hoe
57
- type: :development
58
- version_requirement:
59
- version_requirements: !ruby/object:Gem::Requirement
60
- requirements:
61
- - - ">="
62
- - !ruby/object:Gem::Version
63
- version: 2.3.3
64
- version:
65
45
  description: RestfulQuery provides a simple interface in front of a complex parser to parse specially formatted query hashes into complex SQL queries. It includes ActiveRecord and Sequel extensions.
66
46
  email:
67
- - aaron@quirkey.com
68
47
  executables: []
69
48
 
70
49
  extensions: []
71
50
 
72
51
  extra_rdoc_files:
73
- - History.txt
74
- - Manifest.txt
52
+ - LICENSE
53
+ - README.rdoc
75
54
  files:
55
+ - .gitignore
76
56
  - History.txt
77
57
  - LICENSE
78
- - Manifest.txt
79
58
  - README.rdoc
80
59
  - Rakefile
81
60
  - init.rb
@@ -94,13 +73,12 @@ files:
94
73
  - test/test_restful_query_parser.rb
95
74
  - test/test_restful_query_sort.rb
96
75
  has_rdoc: true
97
- homepage: http://code.quirkey.com/restful_query
76
+ homepage:
98
77
  licenses: []
99
78
 
100
79
  post_install_message:
101
80
  rdoc_options:
102
- - --main
103
- - README.txt
81
+ - --charset=UTF-8
104
82
  require_paths:
105
83
  - lib
106
84
  required_ruby_version: !ruby/object:Gem::Requirement
data/Manifest.txt DELETED
@@ -1,20 +0,0 @@
1
- History.txt
2
- LICENSE
3
- Manifest.txt
4
- README.rdoc
5
- Rakefile
6
- init.rb
7
- lib/restful_query.rb
8
- lib/restful_query/can_query.rb
9
- lib/restful_query/condition.rb
10
- lib/restful_query/parser.rb
11
- lib/restful_query/sort.rb
12
- lib/sequel/extensions/restful_query.rb
13
- rails/init.rb
14
- restful_query.gemspec
15
- tasks/restful_query_tasks.rake
16
- test/test_helper.rb
17
- test/test_restful_query_can_query.rb
18
- test/test_restful_query_condition.rb
19
- test/test_restful_query_parser.rb
20
- test/test_restful_query_sort.rb