restful_query 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
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