believer 0.2.4 → 0.2.5
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/README.md +20 -0
- data/lib/believer/base.rb +7 -5
- data/lib/believer/command.rb +12 -8
- data/lib/believer/ddl.rb +1 -1
- data/lib/believer/environment/base_env.rb +0 -3
- data/lib/believer/extending.rb +58 -0
- data/lib/believer/extensions/will_paginate.rb +173 -0
- data/lib/believer/filter_command.rb +0 -1
- data/lib/believer/query.rb +34 -5
- data/lib/believer/test/test_run_life_cycle.rb +10 -5
- data/lib/believer/version.rb +1 -1
- data/spec/believer/environment_spec.rb +8 -4
- data/spec/believer/extensions/will_paginate_spec.rb +12 -0
- data/spec/believer/query_spec.rb +70 -9
- data/spec/believer/test_run_life_cycle_spec.rb +30 -20
- data/spec/support/test_classes.rb +1 -1
- metadata +22 -2
data/README.md
CHANGED
@@ -72,6 +72,7 @@ The following methods can be used to query class instances.
|
|
72
72
|
* select: specify which fields to load. Using none defaults to all fields being loaded.
|
73
73
|
* limit: limit the number of results to a maximum
|
74
74
|
* order: specify the order of the results
|
75
|
+
* allow_filtering: allow or disallow filtering (see ALLOW FILTERING in Cassandra CQL docs)
|
75
76
|
|
76
77
|
All methods are chainable, meaning you can
|
77
78
|
|
@@ -121,6 +122,23 @@ Album.order(:name, :asc)
|
|
121
122
|
Album.order(:name, :desc)
|
122
123
|
```
|
123
124
|
|
125
|
+
#### pluck
|
126
|
+
In order to retrieve just the the value(s) of one or more columns, the pluck method can be used.
|
127
|
+
This method does not instantiate any Believer::Base instances
|
128
|
+
|
129
|
+
``` ruby
|
130
|
+
# Select single column value
|
131
|
+
Album.where(:artist_name => 'Michael Jackson').pluck(:name) # -> ['Off the wall', 'Thriller', 'Bad']
|
132
|
+
# Select multiple column values
|
133
|
+
Album.where(:artist_name => 'Michael Jackson').pluck(:name, :release_date) # -> [['Off the wall', '1979-01-01', 'Thriller', 'Bad']
|
134
|
+
```
|
135
|
+
|
136
|
+
#### allow_filtering
|
137
|
+
``` ruby
|
138
|
+
Album.allow_filtering(true) # -> SELECT * FROM albums ALLOW FILTERING
|
139
|
+
Album.allow_filtering(false) # -> SELECT * FROM albums
|
140
|
+
```
|
141
|
+
|
124
142
|
#### Method chaining
|
125
143
|
All query methods can be chained.
|
126
144
|
This is done by creating and returning a clone of the receiver. The clone is the receiver of the query method.
|
@@ -194,6 +212,8 @@ development:
|
|
194
212
|
logger:
|
195
213
|
# Use STDOUT to log messages
|
196
214
|
use_environment: false
|
215
|
+
# Log at info (1) level -> no CQL prints
|
216
|
+
level: 1
|
197
217
|
|
198
218
|
development:
|
199
219
|
host: 127.0.0.1
|
data/lib/believer/base.rb
CHANGED
@@ -21,10 +21,6 @@ module Believer
|
|
21
21
|
|
22
22
|
def initialize(attrs = {})
|
23
23
|
@attributes = {}
|
24
|
-
#puts "Attrs: #{attrs.to_json}"
|
25
|
-
#self.class.columns.each do |name, colum_definition|
|
26
|
-
# send("#{name}=".to_sym, attrs[name.to_s])
|
27
|
-
#end if attrs.present?
|
28
24
|
attrs.each do |name, val|
|
29
25
|
send("#{name}=".to_sym, val)
|
30
26
|
end if attrs.present?
|
@@ -37,6 +33,10 @@ module Believer
|
|
37
33
|
end
|
38
34
|
|
39
35
|
def ==(obj)
|
36
|
+
eql?(obj)
|
37
|
+
end
|
38
|
+
|
39
|
+
def eql?(obj)
|
40
40
|
return false if obj.nil?
|
41
41
|
return false unless obj.is_a?(self.class)
|
42
42
|
equal_key_values?(obj)
|
@@ -49,4 +49,6 @@ module Believer
|
|
49
49
|
end
|
50
50
|
|
51
51
|
|
52
|
-
end
|
52
|
+
end
|
53
|
+
|
54
|
+
ActiveSupport.run_load_hooks(:believer, Believer::Base)
|
data/lib/believer/command.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Believer
|
2
2
|
class Command
|
3
3
|
|
4
|
-
attr_accessor :record_class
|
4
|
+
attr_accessor :record_class, :consistency_level
|
5
5
|
|
6
6
|
def initialize(attrs = {})
|
7
7
|
attrs.each do |name, value|
|
@@ -14,8 +14,14 @@ module Believer
|
|
14
14
|
self.class.new(query_attributes)
|
15
15
|
end
|
16
16
|
|
17
|
+
def consistency(level)
|
18
|
+
c = clone
|
19
|
+
c.consistency_level = level
|
20
|
+
c
|
21
|
+
end
|
22
|
+
|
17
23
|
def query_attributes
|
18
|
-
{:record_class => @record_class}
|
24
|
+
{:record_class => @record_class, :consistency_level => @consistency_level}
|
19
25
|
end
|
20
26
|
|
21
27
|
def command_name
|
@@ -23,16 +29,14 @@ module Believer
|
|
23
29
|
end
|
24
30
|
|
25
31
|
def execute(name = nil)
|
26
|
-
name = "#{record_class.name} #{command_name}" if name.nil?
|
27
32
|
@record_class.connection_pool.with do |connection|
|
28
33
|
cql = to_cql
|
29
34
|
begin
|
30
|
-
|
31
|
-
#res = connection.execute(cql)
|
32
|
-
#puts "#{name} #{sprintf "%.3f", (Time.now - start)*1000.0} ms: #{cql}"
|
33
|
-
#return res
|
35
|
+
name = "#{record_class.name} #{command_name}" if name.nil?
|
34
36
|
return ActiveSupport::Notifications.instrument('cql.believer', :cql => cql, :name => name) do
|
35
|
-
|
37
|
+
exec_opts = {}
|
38
|
+
exec_opts[:consistency] = consistency_level unless consistency_level.nil?
|
39
|
+
return connection.execute(cql, exec_opts)
|
36
40
|
end
|
37
41
|
rescue Cql::Protocol::DecodingError => e
|
38
42
|
# Decoding errors tend to #$%# up the connection, resulting in no more activity, so a reconnect is performed here.
|
data/lib/believer/ddl.rb
CHANGED
@@ -8,7 +8,7 @@ module Believer
|
|
8
8
|
def drop_table
|
9
9
|
connection_pool.with do |connection|
|
10
10
|
cql = "DROP TABLE #{table_name}"
|
11
|
-
ActiveSupport::Notifications.instrument('
|
11
|
+
ActiveSupport::Notifications.instrument('ddl.believer', :class => self, :cql => cql, :method => :drop) do
|
12
12
|
connection.execute(cql)
|
13
13
|
end
|
14
14
|
end
|
@@ -24,7 +24,6 @@ module Believer
|
|
24
24
|
return nil unless believer_configuration[:logger]
|
25
25
|
return environment_logger if believer_configuration[:logger][:use_environment] && respond_to?(:environment_logger)
|
26
26
|
unless @std_logger
|
27
|
-
puts believer_configuration[:logger]
|
28
27
|
@std_logger = ::Logger.new(STDOUT)
|
29
28
|
if believer_configuration[:logger][:level] && believer_configuration[:logger][:level].is_a?(Numeric)
|
30
29
|
@std_logger.level = believer_configuration[:logger][:level].to_i
|
@@ -102,8 +101,6 @@ module Believer
|
|
102
101
|
WITH #{ks_props_s}
|
103
102
|
KS_DEF
|
104
103
|
|
105
|
-
puts ks_def
|
106
|
-
|
107
104
|
conn.execute(ks_def)
|
108
105
|
end
|
109
106
|
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Believer
|
2
|
+
module Extending
|
3
|
+
|
4
|
+
# Used to extend a scope with additional methods, either through
|
5
|
+
# a module or through a block provided.
|
6
|
+
#
|
7
|
+
# The object returned is a relation, which can be further extended.
|
8
|
+
#
|
9
|
+
# === Using a module
|
10
|
+
#
|
11
|
+
# module Pagination
|
12
|
+
# def page(number)
|
13
|
+
# # pagination code goes here
|
14
|
+
# end
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# scope = Model.scoped.extending(Pagination)
|
18
|
+
# scope.page(params[:page])
|
19
|
+
#
|
20
|
+
# You can also pass a list of modules:
|
21
|
+
#
|
22
|
+
# scope = Model.scoped.extending(Pagination, SomethingElse)
|
23
|
+
#
|
24
|
+
# === Using a block
|
25
|
+
#
|
26
|
+
# scope = Model.scoped.extending do
|
27
|
+
# def page(number)
|
28
|
+
# # pagination code goes here
|
29
|
+
# end
|
30
|
+
# end
|
31
|
+
# scope.page(params[:page])
|
32
|
+
#
|
33
|
+
# You can also use a block and a module list:
|
34
|
+
#
|
35
|
+
# scope = Model.scoped.extending(Pagination) do
|
36
|
+
# def per_page(number)
|
37
|
+
# # pagination code goes here
|
38
|
+
# end
|
39
|
+
# end
|
40
|
+
def extending(*modules)
|
41
|
+
modules << Module.new(&Proc.new) if block_given?
|
42
|
+
|
43
|
+
return self if modules.empty?
|
44
|
+
|
45
|
+
relation = clone
|
46
|
+
relation.send(:apply_modules, modules.flatten)
|
47
|
+
relation
|
48
|
+
end
|
49
|
+
|
50
|
+
def apply_modules(modules)
|
51
|
+
unless modules.empty?
|
52
|
+
@extensions += modules
|
53
|
+
modules.each {|extension| extend(extension) }
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,173 @@
|
|
1
|
+
require 'will_paginate/per_page'
|
2
|
+
require 'will_paginate/page_number'
|
3
|
+
require 'will_paginate/collection'
|
4
|
+
require 'believer'
|
5
|
+
|
6
|
+
module Believer
|
7
|
+
module Extensions
|
8
|
+
# = Paginating finders for Believer models
|
9
|
+
#
|
10
|
+
# WillPaginate adds +paginate+, +per_page+ and other methods to
|
11
|
+
# Believer::Base class methods and associations.
|
12
|
+
#
|
13
|
+
# In short, paginating finders are equivalent to ActiveRecord finders; the
|
14
|
+
# only difference is that we start with "paginate" instead of "find" and
|
15
|
+
# that <tt>:page</tt> is required parameter:
|
16
|
+
#
|
17
|
+
# @posts = Post.paginate :all, :page => params[:page], :order => 'created_at DESC'
|
18
|
+
#
|
19
|
+
module WillPaginate
|
20
|
+
# makes a Relation look like WillPaginate::Collection
|
21
|
+
module RelationMethods
|
22
|
+
include ::WillPaginate::CollectionMethods
|
23
|
+
|
24
|
+
attr_accessor :current_page
|
25
|
+
attr_writer :total_entries, :wp_count_options
|
26
|
+
|
27
|
+
def per_page(value = nil)
|
28
|
+
if value.nil? then
|
29
|
+
limit_value
|
30
|
+
else
|
31
|
+
limit(value)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# TODO: solve with less relation clones and code dups
|
36
|
+
def limit(num)
|
37
|
+
rel = super
|
38
|
+
if rel.current_page
|
39
|
+
rel.offset rel.current_page.to_offset(rel.limit_value).to_i
|
40
|
+
else
|
41
|
+
rel
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def offset(value = nil)
|
46
|
+
if value.nil? then
|
47
|
+
offset_value
|
48
|
+
else
|
49
|
+
super(value)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def total_entries
|
54
|
+
@total_entries ||= begin
|
55
|
+
if loaded? and size < limit_value and (current_page == 1 or size > 0)
|
56
|
+
offset_value + size
|
57
|
+
else
|
58
|
+
@total_entries_queried = true
|
59
|
+
result = count
|
60
|
+
result = result.size if result.respond_to?(:size) and !result.is_a?(Integer)
|
61
|
+
result
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def count
|
67
|
+
if limit_value
|
68
|
+
excluded = [:order, :limit, :offset]
|
69
|
+
excluded << :includes unless eager_loading?
|
70
|
+
rel = self.except(*excluded)
|
71
|
+
# TODO: hack. decide whether to keep
|
72
|
+
rel = rel.apply_finder_options(@wp_count_options) if defined? @wp_count_options
|
73
|
+
rel.count
|
74
|
+
else
|
75
|
+
super
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# workaround for Active Record 3.0
|
80
|
+
def size
|
81
|
+
if !loaded? and limit_value and group_values.empty?
|
82
|
+
[super, limit_value].min
|
83
|
+
else
|
84
|
+
super
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# overloaded to be pagination-aware
|
89
|
+
def empty?
|
90
|
+
if !loaded? and offset_value
|
91
|
+
result = count
|
92
|
+
result = result.size if result.respond_to?(:size) and !result.is_a?(Integer)
|
93
|
+
result <= offset_value
|
94
|
+
else
|
95
|
+
super
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def clone
|
100
|
+
copy_will_paginate_data super
|
101
|
+
end
|
102
|
+
|
103
|
+
# workaround for Active Record 3.0
|
104
|
+
def scoped(options = nil)
|
105
|
+
copy_will_paginate_data super
|
106
|
+
end
|
107
|
+
|
108
|
+
def to_a
|
109
|
+
if current_page.nil? then
|
110
|
+
super # workaround for Active Record 3.0
|
111
|
+
else
|
112
|
+
::WillPaginate::Collection.create(current_page, limit_value) do |col|
|
113
|
+
col.replace super
|
114
|
+
col.total_entries ||= total_entries
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
private
|
120
|
+
|
121
|
+
def copy_will_paginate_data(other)
|
122
|
+
other.current_page = current_page unless other.current_page
|
123
|
+
other.total_entries = nil if defined? @total_entries_queried
|
124
|
+
other.wp_count_options = @wp_count_options if defined? @wp_count_options
|
125
|
+
other
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
module Pagination
|
130
|
+
def paginate(options)
|
131
|
+
options = options.dup
|
132
|
+
pagenum = options.fetch(:page) { raise ArgumentError, ":page parameter required" }
|
133
|
+
per_page = options.delete(:per_page) || self.per_page
|
134
|
+
total = options.delete(:total_entries)
|
135
|
+
|
136
|
+
count_options = options.delete(:count)
|
137
|
+
options.delete(:page)
|
138
|
+
|
139
|
+
rel = limit(per_page.to_i).page(pagenum)
|
140
|
+
rel = rel.apply_finder_options(options) if options.any?
|
141
|
+
rel.wp_count_options = count_options if count_options
|
142
|
+
rel.total_entries = total.to_i unless total.blank?
|
143
|
+
rel
|
144
|
+
end
|
145
|
+
|
146
|
+
def page(num)
|
147
|
+
rel = scoped.extending(RelationMethods)
|
148
|
+
pagenum = ::WillPaginate::PageNumber(num.nil? ? 1 : num)
|
149
|
+
per_page = rel.limit_value || self.per_page
|
150
|
+
rel = rel.offset(pagenum.to_offset(per_page).to_i)
|
151
|
+
rel = rel.limit(per_page) unless rel.limit_value
|
152
|
+
rel.current_page = pagenum
|
153
|
+
rel
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
module BaseMethods
|
158
|
+
|
159
|
+
end
|
160
|
+
|
161
|
+
# mix everything into Believer
|
162
|
+
::Believer::Base.extend ::WillPaginate::PerPage
|
163
|
+
::Believer::Base.extend Pagination
|
164
|
+
#::Believer::Base.extend BaseMethods
|
165
|
+
|
166
|
+
klasses = [::Believer::Relation]
|
167
|
+
|
168
|
+
# support pagination on associations and scopes
|
169
|
+
klasses.each { |klass| klass.send(:include, Pagination) }
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
data/lib/believer/query.rb
CHANGED
@@ -1,6 +1,11 @@
|
|
1
|
+
require 'believer/extending'
|
2
|
+
|
1
3
|
module Believer
|
2
4
|
class Query < FilterCommand
|
3
|
-
|
5
|
+
include Extending
|
6
|
+
|
7
|
+
attr_accessor :record_class, :selects, :order_by, :limit_to, :filtering_allowed
|
8
|
+
alias :filtering_allowed? :filtering_allowed
|
4
9
|
|
5
10
|
delegate *(Enumerable.instance_methods(false).map {|enum_method| enum_method.to_sym}), :to => :to_a
|
6
11
|
delegate :each, :size, :[], :to => :to_a
|
@@ -12,7 +17,26 @@ module Believer
|
|
12
17
|
|
13
18
|
def query_attributes
|
14
19
|
attrs = super
|
15
|
-
attrs.merge(:order_by => @order_by, :selects => @selects, :limit_to => @limit_to)
|
20
|
+
attrs.merge(:order_by => @order_by, :selects => @selects, :limit_to => @limit_to, :filtering_allowed => filtering_allowed)
|
21
|
+
end
|
22
|
+
|
23
|
+
def pluck(*fields)
|
24
|
+
fields.each do |f|
|
25
|
+
raise "Unknown field #{f} for class #{record_class}" unless record_class.columns.has_key?(f)
|
26
|
+
end
|
27
|
+
q = clone
|
28
|
+
q.selects = fields
|
29
|
+
rows = q.execute
|
30
|
+
pluck_res = []
|
31
|
+
rows.each do |r|
|
32
|
+
if fields.size > 1
|
33
|
+
pluck_res << fields.map {|f| record_class.columns[f].convert_to_type(r[f.to_s]) }
|
34
|
+
else
|
35
|
+
f = fields[0]
|
36
|
+
pluck_res << record_class.columns[f].convert_to_type(r[f.to_s])
|
37
|
+
end
|
38
|
+
end
|
39
|
+
pluck_res
|
16
40
|
end
|
17
41
|
|
18
42
|
def select(*fields)
|
@@ -20,7 +44,6 @@ module Believer
|
|
20
44
|
q.selects ||= []
|
21
45
|
q.selects += fields
|
22
46
|
q.selects.flatten!
|
23
|
-
#puts "New selects: #{q.selects}, added: #{fields}"
|
24
47
|
q
|
25
48
|
end
|
26
49
|
|
@@ -44,11 +67,18 @@ module Believer
|
|
44
67
|
end
|
45
68
|
end
|
46
69
|
|
70
|
+
def allow_filtering(b = true)
|
71
|
+
q = clone
|
72
|
+
q.filtering_allowed = b
|
73
|
+
q
|
74
|
+
end
|
75
|
+
|
47
76
|
def to_cql
|
48
77
|
cql = "SELECT "
|
49
78
|
if @selects && @selects.any?
|
50
79
|
cql << "#{@selects.join(', ')}"
|
51
80
|
else
|
81
|
+
#@record_class.environment.believer_configuration[:expand_columns]
|
52
82
|
cql << @record_class.columns.keys.join(',')
|
53
83
|
#cql << "*"
|
54
84
|
end
|
@@ -57,6 +87,7 @@ module Believer
|
|
57
87
|
cql << " WHERE #{wheres.map { |wc| "#{wc.to_cql}" }.join(' AND ')}" if wheres.any?
|
58
88
|
cql << " #{order_by.to_cql}" unless order_by.nil?
|
59
89
|
cql << " #{limit_to.to_cql}" unless limit_to.nil?
|
90
|
+
cql << " ALLOW FILTERING" if filtering_allowed?
|
60
91
|
cql
|
61
92
|
end
|
62
93
|
|
@@ -90,7 +121,6 @@ module Believer
|
|
90
121
|
result = execute
|
91
122
|
notify_payload = {:class => @record_class}
|
92
123
|
@loaded_objects = ActiveSupport::Notifications.instrument('deserialize.believer', notify_payload) do
|
93
|
-
start = Time.now
|
94
124
|
objects = []
|
95
125
|
result.each do |row|
|
96
126
|
objects << record_class.instantiate_from_result_rows(row)
|
@@ -98,7 +128,6 @@ module Believer
|
|
98
128
|
notify_payload[:count] = objects.count
|
99
129
|
objects
|
100
130
|
end
|
101
|
-
#puts "Took #{sprintf "%.3f", (Time.now - start)*1000.0} ms to deserialize #{@loaded_objects.size} object(s)"
|
102
131
|
end
|
103
132
|
@loaded_objects
|
104
133
|
end
|
@@ -17,21 +17,26 @@ module Believer
|
|
17
17
|
observe Believer::Base
|
18
18
|
|
19
19
|
def cleanup
|
20
|
-
unless @
|
21
|
-
@
|
20
|
+
unless @observed_models.nil? || @observed_models.empty?
|
21
|
+
@observed_models.each do |model|
|
22
22
|
begin
|
23
23
|
model.destroy
|
24
24
|
rescue Exception => e
|
25
25
|
puts "Could not destroy model #{model}: #{e}\n#{e.backtrace.join("\n")}"
|
26
26
|
end
|
27
27
|
end
|
28
|
-
@
|
28
|
+
@observed_models = nil
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
+
def observed_models
|
33
|
+
return @observed_models.dup unless @observed_models.nil?
|
34
|
+
[]
|
35
|
+
end
|
36
|
+
|
32
37
|
def after_save(model)
|
33
|
-
@
|
34
|
-
@
|
38
|
+
@observed_models ||= []
|
39
|
+
@observed_models << model
|
35
40
|
end
|
36
41
|
|
37
42
|
end
|
data/lib/believer/version.rb
CHANGED
@@ -12,21 +12,25 @@ describe Believer::Environment do
|
|
12
12
|
end
|
13
13
|
|
14
14
|
it 'load the rails configuration' do
|
15
|
+
if defined?(Rails)
|
16
|
+
puts "Rails: #{Rails}"
|
17
|
+
end
|
15
18
|
Rails = Struct.new(:root, :env, :logger).new(File.join(RSpec.configuration.test_files_dir, 'rails'), :test, nil)
|
16
19
|
env = Believer::Base.environment
|
17
20
|
env.class.should == Believer::Environment::RailsEnv
|
18
21
|
env.configuration[:host].should == '123.456.789.0'
|
19
|
-
|
20
|
-
Rails = nil
|
22
|
+
Object.instance_eval { remove_const :Rails}
|
21
23
|
end
|
22
24
|
|
23
25
|
it 'load the Merb configuration' do
|
26
|
+
if defined?(Merb)
|
27
|
+
puts "Rails: #{Merb}"
|
28
|
+
end
|
24
29
|
Merb = Struct.new(:root, :environment, :logger).new(File.join(RSpec.configuration.test_files_dir, 'merb'), :test, nil)
|
25
30
|
env = Believer::Base.environment
|
26
31
|
env.class.should == Believer::Environment::MerbEnv
|
27
32
|
env.configuration[:host].should == 'merb.test.local'
|
28
|
-
|
29
|
-
Merb = nil
|
33
|
+
Object.instance_eval { remove_const :Merb}
|
30
34
|
end
|
31
35
|
|
32
36
|
end
|
data/spec/believer/query_spec.rb
CHANGED
@@ -1,7 +1,28 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Believer::Query do
|
4
|
-
|
4
|
+
include Believer::Test::TestRunLifeCycle
|
5
|
+
|
6
|
+
let :artists do
|
7
|
+
Test::Artist.create(
|
8
|
+
[
|
9
|
+
{:name => 'Beatles', :label => 'Apple'},
|
10
|
+
{:name => 'Jethro Tull', :label => 'Crysalis'},
|
11
|
+
{:name => 'Pink Floyd', :label => 'Epic'},
|
12
|
+
{:name => 'Michael Jackson', :label => 'Epic'}
|
13
|
+
])
|
14
|
+
end
|
15
|
+
|
16
|
+
let :albums do
|
17
|
+
Test::Album.create(
|
18
|
+
[
|
19
|
+
{:artist_name => 'Beatles', :name => 'Help'},
|
20
|
+
{:artist_name => 'Jethro Tull', :name => 'Aqualung'},
|
21
|
+
{:artist_name => 'Jethro Tull', :name => 'Standup'},
|
22
|
+
{:artist_name => 'Michael Jackson', :name => 'Thriller'}
|
23
|
+
])
|
24
|
+
|
25
|
+
end
|
5
26
|
|
6
27
|
it 'create simple statement' do
|
7
28
|
q = Believer::Query.new(:record_class => Test::Album)
|
@@ -14,18 +35,58 @@ describe Believer::Query do
|
|
14
35
|
q.to_cql.should == "SELECT name, artist FROM albums WHERE name = 'Revolver' AND release_date = '2013-01-01 00:00:00+0000' ORDER BY name DESC LIMIT 10"
|
15
36
|
end
|
16
37
|
|
17
|
-
it 'should
|
38
|
+
it 'should include allow filtering clause' do
|
39
|
+
q = Believer::Query.new(:record_class => Test::Album)
|
40
|
+
q = q.select(:name)
|
41
|
+
expect(q.to_cql).to eql "SELECT name FROM albums"
|
42
|
+
q = q.allow_filtering(true)
|
43
|
+
expect(q.to_cql).to eql "SELECT name FROM albums ALLOW FILTERING"
|
44
|
+
q = q.allow_filtering(false)
|
45
|
+
expect(q.to_cql).to eql "SELECT name FROM albums"
|
46
|
+
end
|
18
47
|
|
19
|
-
|
20
|
-
|
21
|
-
{:name => 'Jethro Tull', :label => 'Crysalis'},
|
22
|
-
{:name => 'Pink Floyd', :label => 'Epic'}
|
23
|
-
])
|
24
|
-
q = Believer::Query.new(:record_class => Test::Artist).where(:name => @objects.map {|o|o.name})
|
48
|
+
it 'should behave like an Enumerable' do
|
49
|
+
q = Believer::Query.new(:record_class => Test::Artist).where(:name => artists.map { |o| o.name })
|
25
50
|
Enumerable.instance_methods(false).each do |enum_method|
|
26
51
|
q.respond_to?(enum_method.to_sym).should == true
|
27
52
|
end
|
28
|
-
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should order' do
|
56
|
+
q = Believer::Query.new(:record_class => Test::Album).select(:name)
|
57
|
+
q = q.order(:release_date, :desc)
|
58
|
+
expect(q.to_cql).to eql("SELECT name FROM albums ORDER BY release_date DESC")
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'should be able to pluck single column values' do
|
62
|
+
albums
|
63
|
+
q = Believer::Query.new(:record_class => Test::Album).where(:artist_name => 'Jethro Tull')
|
64
|
+
album_names = q.pluck(:name)
|
65
|
+
expect(album_names.size).to eql(2)
|
66
|
+
expect(album_names).to include('Standup')
|
67
|
+
expect(album_names).to include('Aqualung')
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'should be able to pluck multiple column values' do
|
71
|
+
albums
|
72
|
+
q = Believer::Query.new(:record_class => Test::Album).where(:artist_name => 'Jethro Tull').order(:name)
|
73
|
+
album_names = q.pluck(:name, :artist_name)
|
74
|
+
expect(album_names).to eql([['Aqualung', 'Jethro Tull'], ['Standup', 'Jethro Tull']])
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'should not be able to pluck if an unknown column name is used' do
|
78
|
+
albums
|
79
|
+
q = Believer::Query.new(:record_class => Test::Album).where(:artist_name => 'Jethro Tull').order(:name)
|
80
|
+
begin
|
81
|
+
q.pluck(:artist_xxx)
|
82
|
+
fail
|
83
|
+
rescue Exception => e
|
84
|
+
end
|
85
|
+
begin
|
86
|
+
q.pluck(:name, :artist_xxx)
|
87
|
+
fail
|
88
|
+
rescue Exception => e
|
89
|
+
end
|
29
90
|
end
|
30
91
|
|
31
92
|
end
|
@@ -4,47 +4,57 @@ require 'spec_helper'
|
|
4
4
|
describe Believer::Test::TestRunLifeCycle do
|
5
5
|
include Believer::Test::TestRunLifeCycle
|
6
6
|
|
7
|
-
|
8
|
-
@destroyed_count = 0
|
9
|
-
@destroy_monitor = lambda do |obj|
|
10
|
-
@destroyed_count += 1
|
11
|
-
end
|
7
|
+
CREATE_COUNT = 10
|
12
8
|
|
9
|
+
before :all do
|
10
|
+
@monitor = Monitor.new
|
13
11
|
begin
|
14
|
-
|
15
|
-
|
12
|
+
Fly.drop_table
|
16
13
|
rescue
|
17
14
|
ensure
|
18
|
-
|
15
|
+
Fly.create_table
|
16
|
+
@created = []
|
17
|
+
CREATE_COUNT.times do |i|
|
18
|
+
@created << Fly.create(:name => "artist_#{i}", :kill_monitor => @monitor)
|
19
|
+
end
|
19
20
|
end
|
20
21
|
end
|
21
22
|
|
22
23
|
after :all do
|
23
|
-
|
24
|
-
@
|
25
|
-
|
24
|
+
Fly.drop_table
|
25
|
+
@monitor.kill_count.should == @created.size
|
26
|
+
end
|
27
|
+
|
28
|
+
after :each do
|
26
29
|
end
|
27
30
|
|
28
31
|
before :each do
|
29
|
-
@created = []
|
30
|
-
10.times do |i|
|
31
|
-
@created << XXX.create(:name => "artist_#{i}", :destroy_monitor => @destroy_monitor)
|
32
|
-
end
|
33
32
|
end
|
34
33
|
|
35
34
|
it "should clean all created objects, even after a fail" do
|
36
|
-
|
35
|
+
Believer::Test::TestRunLifeCycle::Destructor.instance.observed_models.size.should == CREATE_COUNT
|
36
|
+
end
|
37
|
+
|
38
|
+
class Monitor
|
39
|
+
attr_reader :kill_count
|
40
|
+
|
41
|
+
def initialize
|
42
|
+
@kill_count = 0
|
43
|
+
end
|
44
|
+
|
45
|
+
def destroyed
|
46
|
+
@kill_count += 1
|
47
|
+
end
|
37
48
|
end
|
38
49
|
|
39
|
-
class
|
50
|
+
class Fly < Believer::Base
|
40
51
|
column :name, :type => :string
|
41
52
|
primary_key :name
|
42
|
-
cattr_accessor :destroyed_count
|
43
53
|
|
44
|
-
attr_accessor :
|
54
|
+
attr_accessor :kill_monitor
|
45
55
|
|
46
56
|
before_destroy do
|
47
|
-
|
57
|
+
self.kill_monitor.destroyed
|
48
58
|
end
|
49
59
|
end
|
50
60
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: believer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-10-
|
12
|
+
date: 2013-10-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activemodel
|
@@ -107,6 +107,22 @@ dependencies:
|
|
107
107
|
- - '='
|
108
108
|
- !ruby/object:Gem::Version
|
109
109
|
version: 0.7.1
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: will_paginate
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
110
126
|
description: ! 'An Object Relational Mapping library for CQL3 '
|
111
127
|
email:
|
112
128
|
- jerphaes@gmail.com
|
@@ -130,6 +146,8 @@ files:
|
|
130
146
|
- lib/believer/environment/merb_env.rb
|
131
147
|
- lib/believer/environment/rails_env.rb
|
132
148
|
- lib/believer/environment.rb
|
149
|
+
- lib/believer/extending.rb
|
150
|
+
- lib/believer/extensions/will_paginate.rb
|
133
151
|
- lib/believer/filter_command.rb
|
134
152
|
- lib/believer/finder_methods.rb
|
135
153
|
- lib/believer/insert.rb
|
@@ -154,6 +172,7 @@ files:
|
|
154
172
|
- spec/believer/delete_spec.rb
|
155
173
|
- spec/believer/empty_result_spec.rb
|
156
174
|
- spec/believer/environment_spec.rb
|
175
|
+
- spec/believer/extensions/will_paginate_spec.rb
|
157
176
|
- spec/believer/finder_methods_spec.rb
|
158
177
|
- spec/believer/insert_spec.rb
|
159
178
|
- spec/believer/limit_spec.rb
|
@@ -198,6 +217,7 @@ test_files:
|
|
198
217
|
- spec/believer/delete_spec.rb
|
199
218
|
- spec/believer/empty_result_spec.rb
|
200
219
|
- spec/believer/environment_spec.rb
|
220
|
+
- spec/believer/extensions/will_paginate_spec.rb
|
201
221
|
- spec/believer/finder_methods_spec.rb
|
202
222
|
- spec/believer/insert_spec.rb
|
203
223
|
- spec/believer/limit_spec.rb
|