cequel 2.0.3 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2ff9eed6cd9463e5896643152fd7314b4df3324e
4
- data.tar.gz: 6e62173d98fa94f77d6022ca22501ae778e40139
3
+ metadata.gz: 31fac6cdfcc42c42c1cd03489d11aa97e4791193
4
+ data.tar.gz: 5d86e45f0dac711e70936c61ff7a4879095b28d8
5
5
  SHA512:
6
- metadata.gz: 4ad422adb85827d83efa126565c8d43f4c1b34626a154e2f627fcdb7d04e0567d6635941cc88bfa622a3f79aeec875fd30da653ecbe9c71f0f9a45a1bc738c1b
7
- data.tar.gz: 1d157437a9c7d435412a22206d8e2103b2b214c494acdd2719a3aae8d7ef5969dd674036b271f823bd026aa50b664afd99413afc5b4edb0bfd61cb2f249f773c
6
+ metadata.gz: b4a4696642f07aed6bf5e777b57fd48a9f570eb7ae370e31f8b37d92770874b9d25b0b72d0159dc3501d2d94671e0845f33119895cadc4bbe3498c668ee38fe7
7
+ data.tar.gz: 7600517db78e87916d1f40584d21f181388ee91b2c21a73d26db17a598ce5c4bbee627ed26cfab4c33f0a84908bd568ab3e0cd9df67df76eec1eaa4242c5969c
@@ -1,3 +1,12 @@
1
+ ## 2.1.0
2
+
3
+ * Add ActiveRecord::Enum like support `column :status, :enum, values: { open: 1, closed: 2 }` ([PR 354](https://github.com/cequel/cequel/pull/354))
4
+ * Fix bug CQL statement execution error handling ([PR 357](https://github.com/cequel/cequel/pull/357)
5
+ * Documentation fixes ([PR 355](https://github.com/cequel/cequel/pull/355))
6
+ * Add support for `ALLOW FILTERING` queries ([PR 353](https://github.com/cequel/cequel/pull/353))
7
+ * Add support for `IF EXISTS` to schema modifications ([PR 349](https://github.com/cequel/cequel/pull/349))
8
+ * Make `test` the default rake tast ([PR 348](https://github.com/cequel/cequel/pull/348))
9
+
1
10
  ## 2.0.3
2
11
 
3
12
  * Add synchronization around use of @cluster and other variables Fix ([PR 333](https://github.com/cequel/cequel/pull/333))
data/Gemfile CHANGED
@@ -3,8 +3,7 @@ source 'https://rubygems.org'
3
3
  gemspec
4
4
 
5
5
  group :debug do
6
- gem 'debugger', '~> 1.6', :platforms => :mri_19
7
- gem 'byebug', '~> 2.7', :platforms => [:mri_20, :mri_21]
6
+ gem 'byebug', '~> 2.7'
8
7
  gem 'pry', '~> 0.9'
9
8
  end
10
9
 
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cequel (2.0.3)
4
+ cequel (2.1.0)
5
5
  activemodel (>= 4.0)
6
6
  cassandra-driver (~> 3.0)
7
7
 
@@ -30,12 +30,7 @@ GEM
30
30
  coderay (1.1.1)
31
31
  columnize (0.9.0)
32
32
  concurrent-ruby (1.0.2)
33
- debugger (1.6.8)
34
- columnize (>= 0.3.1)
35
- debugger-linecache (~> 1.2.0)
36
- debugger-ruby_core_source (~> 1.3.5)
37
33
  debugger-linecache (1.2.0)
38
- debugger-ruby_core_source (1.3.8)
39
34
  diff-lcs (1.2.5)
40
35
  ethon (0.9.1)
41
36
  ffi (>= 1.3.0)
@@ -103,6 +98,8 @@ GEM
103
98
  rspec-mocks (3.5.0)
104
99
  diff-lcs (>= 1.2.0, < 2.0)
105
100
  rspec-support (~> 3.5.0)
101
+ rspec-retry (0.5.3)
102
+ rspec-core (> 3.3, < 3.6)
106
103
  rspec-support (3.5.0)
107
104
  rubocop (0.43.0)
108
105
  parser (>= 2.3.1.1, < 3.0)
@@ -345,13 +342,13 @@ DEPENDENCIES
345
342
  appraisal (~> 1.0)
346
343
  byebug (~> 2.7)
347
344
  cequel!
348
- debugger (~> 1.6)
349
345
  pry (~> 0.9)
350
346
  psych (~> 2.0)
351
347
  racc (~> 1.4)
352
348
  rake (~> 10.1)
353
- rspec (~> 3.1)
349
+ rspec (~> 3.5)
354
350
  rspec-its (~> 1.0)
351
+ rspec-retry (~> 0.5)
355
352
  rubocop
356
353
  rubysl (~> 2.0)
357
354
  timecop (~> 0.7)
data/README.md CHANGED
@@ -159,6 +159,8 @@ To add timestamp columns, simply use the `timestamps` class macro:
159
159
 
160
160
  ```ruby
161
161
  class Blog
162
+ include Cequel::Record
163
+
162
164
  key :subdomain, :text
163
165
  column :name, :text
164
166
  timestamps
@@ -171,6 +173,29 @@ populate them appropriately on save.
171
173
  If the creation time can be extracted from the primary key as outlined above,
172
174
  this method will be preferred and no `created_at` column will be defined.
173
175
 
176
+ ### Enums ###
177
+
178
+ If your a column should behave like an `ActiveRecord::Enum` you can use the
179
+ column type `:enum`. It will be handled by the data-type `:int` and expose some
180
+ helper methods on the model:
181
+
182
+ ```ruby
183
+ class Blog
184
+ include Cequel::Record
185
+
186
+ key :subdomain, :text
187
+ column :name, :text
188
+ column :status, :enum, values: { open: 1, closed: 2 }
189
+ end
190
+
191
+ blog = Blog.new(status: :open)
192
+ blog.open? # true
193
+ blog.closed? # false
194
+ blog.status # :open
195
+
196
+ Blog.status # { open: 1, closed: 2 }
197
+ ```
198
+
174
199
  ### Schema synchronization ###
175
200
 
176
201
  Cequel will automatically synchronize the schema stored in Cassandra to match
@@ -608,35 +633,8 @@ See
608
633
 
609
634
  ## Credits ##
610
635
 
611
- Cequel was written by:
612
-
613
- * Mat Brown
614
- * Aubrey Holland
615
- * Keenan Brock
616
- * Insoo Buzz Jung
617
- * Louis Simoneau
618
- * Peter Williams
619
- * Kenneth Hoffman
620
- * Antti Tapio
621
- * Ilya Bazylchuk
622
- * Dan Cardamore
623
- * Kei Kusakari
624
- * Oleh Novosad
625
- * John Smart
626
- * Angelo Lakra
627
- * Olivier Lance
628
- * Tomohiro Nishimura
629
- * Masaki Takahashi
630
- * G Gordon Worley III
631
- * Clark Bremer
632
- * Tamara Temple
633
- * Long On
634
- * Lucas Mundim
635
- * Luke Duncalfe
636
- * Eric Betts
637
- * Maxim Dobryakov
638
- * Yi-Cyuan Chen
639
- * Justin Hannus
636
+ Cequel was written by an [awesome lot](https://github.com/cequel/cequel/graphs/contributors). Thanks to you all.
637
+
640
638
 
641
639
  Special thanks to [Brewster](http://www.brewster.com), which supported the 0.x
642
640
  releases of Cequel.
data/Rakefile CHANGED
@@ -8,7 +8,8 @@ require File.expand_path('../lib/cequel/version', __FILE__)
8
8
 
9
9
  RUBY_VERSIONS = YAML.load_file(File.expand_path('../.travis.yml', __FILE__))['rvm']
10
10
 
11
- task :default => :release
11
+ task default: :test
12
+
12
13
  task :release => [
13
14
  :verify_changelog,
14
15
  :"test:all",
@@ -14,7 +14,7 @@ module Cequel
14
14
  # Example:
15
15
  #
16
16
  # extend Instrumentation
17
- # instrument :create, "create.cequel", data: {table_name: table_name}
17
+ # instrument :create, data: {topic: "create.cequel", table_name: table_name}
18
18
  #
19
19
  # @param method_name [Symbol,String] The method to instrument
20
20
  #
@@ -50,6 +50,7 @@ module Cequel
50
50
  attr_reader :query_consistency
51
51
  attr_reader :query_page_size
52
52
  attr_reader :query_paging_state
53
+ attr_reader :allow_filtering
53
54
 
54
55
  def_delegator :keyspace, :write_with_options
55
56
 
@@ -573,6 +574,15 @@ module Cequel
573
574
  end
574
575
  end
575
576
 
577
+ #
578
+ # @see RecordSet#allow_filtering!
579
+ #
580
+ def allow_filtering!
581
+ clone.tap do |data_set|
582
+ data_set.allow_filtering = true
583
+ end
584
+ end
585
+
576
586
  def paging_state(paging_state)
577
587
  clone.tap do |data_set|
578
588
  data_set.query_paging_state = paging_state
@@ -645,6 +655,7 @@ module Cequel
645
655
  .append(*row_specifications_cql)
646
656
  .append(sort_order_cql)
647
657
  .append(limit_cql)
658
+ .append(allow_filtering_cql)
648
659
  end
649
660
 
650
661
  #
@@ -675,9 +686,17 @@ module Cequel
675
686
  end
676
687
  end
677
688
 
689
+ # @private
690
+ def allow_filtering_cql
691
+ if allow_filtering
692
+ ' ALLOW FILTERING'
693
+ else ''
694
+ end
695
+ end
696
+
678
697
  protected
679
698
 
680
- attr_writer :row_limit, :query_consistency, :query_page_size, :query_paging_state
699
+ attr_writer :row_limit, :query_consistency, :query_page_size, :query_paging_state, :allow_filtering
681
700
 
682
701
  private
683
702
 
@@ -47,7 +47,7 @@ module Cequel
47
47
  yield
48
48
  rescue Cassandra::Errors::NoHostsAvailable,
49
49
  Cassandra::Errors::ExecutionError,
50
- Cassandra::Errors::TimeoutError => exc
50
+ Cassandra::Errors::TimeoutError => error
51
51
  raise error if retries_remaining == 0
52
52
  sleep(retry_delay)
53
53
  keyspace.clear_active_connections! if clear_before_retry
@@ -40,6 +40,7 @@ module Cequel
40
40
  add_bounds
41
41
  add_order
42
42
  set_consistency
43
+ set_allow_filtering
43
44
  set_page_size
44
45
  set_paging_state
45
46
  data_set
@@ -53,7 +54,8 @@ module Cequel
53
54
  :scoped_key_names, :scoped_key_values,
54
55
  :scoped_indexed_column, :lower_bound,
55
56
  :upper_bound, :reversed?, :order_by_column,
56
- :query_consistency, :query_page_size, :query_paging_state, :ascends_by?
57
+ :query_consistency, :query_page_size, :query_paging_state,
58
+ :ascends_by?, :allow_filtering
57
59
 
58
60
  private
59
61
 
@@ -99,6 +101,12 @@ module Cequel
99
101
  end
100
102
  end
101
103
 
104
+ def set_allow_filtering
105
+ if allow_filtering
106
+ self.data_set = data_set.allow_filtering!
107
+ end
108
+ end
109
+
102
110
  def set_page_size
103
111
  if query_page_size
104
112
  self.data_set = data_set.page_size(query_page_size)
@@ -123,6 +123,14 @@ module Cequel
123
123
  # this column
124
124
  # @return [void]
125
125
  #
126
+ # @note Using type :enum will behave similar to an ActiveRecord enum:
127
+ # example: `column :status, :enum, values: { open: 1, closed: 2 }`
128
+ # will be handled as type Int
129
+ # calling model.status will return the symbol ie. :open or :closed
130
+ # expects setter to be called with symbol ie. model.status(:open)
131
+ # exposes helpers ie. model.open?
132
+ # exposes values-mapping on a class-level ModelClass.status
133
+ #
126
134
  # @note Secondary indexes are not nearly as flexible as primary keys:
127
135
  # you cannot query for multiple values or for ranges of values. You
128
136
  # also cannot combine a secondary index restriction with a primary
@@ -131,6 +139,7 @@ module Cequel
131
139
  #
132
140
  def column(name, type, options = {})
133
141
  def_accessors(name)
142
+ def_enum(name, options[:values]) if type == :enum
134
143
  set_attribute_default(name, options[:default])
135
144
  end
136
145
 
@@ -193,6 +202,34 @@ module Cequel
193
202
 
194
203
  private
195
204
 
205
+ def def_enum(name, values)
206
+ name = name.to_sym
207
+ def_enum_values(name, values)
208
+ def_enum_reader(name, values)
209
+ def_enum_writer(name, values)
210
+ end
211
+
212
+ def def_enum_values(name, values)
213
+ define_singleton_method(name) { values }
214
+ end
215
+
216
+ def def_enum_reader(name, values)
217
+ module_eval <<-RUBY, __FILE__, __LINE__+1
218
+ def #{name}; #{values.invert}[read_attribute(#{name.inspect})]; end
219
+ RUBY
220
+ values.each do |key, value|
221
+ module_eval <<-RUBY, __FILE__, __LINE__+1
222
+ def #{key}?; read_attribute(#{name.inspect}) == #{value}; end
223
+ RUBY
224
+ end
225
+ end
226
+
227
+ def def_enum_writer(name, values)
228
+ module_eval <<-RUBY, __FILE__, __LINE__+1
229
+ def #{name}=(value); write_attribute(#{name.inspect}, #{values}[value]); end
230
+ RUBY
231
+ end
232
+
196
233
  def def_accessors(name)
197
234
  name = name.to_sym
198
235
  def_reader(name)
@@ -464,6 +464,22 @@ module Cequel
464
464
  scoped(query_consistency: consistency)
465
465
  end
466
466
 
467
+ #
468
+ # Add `ALLOW FILTERING` to select-queries for filtering of none-indexed fields.
469
+ #
470
+ # `Post.allow_filtering!.where(title: 'Cequel 0')`
471
+ #
472
+ # Available as of Cassandra 3.6
473
+ #
474
+ # @return [RecordSet] record set tuned to given consistency
475
+
476
+ # @see https://docs.datastax.com/en/cql/3.3/cql/cql_reference/cqlSelect.html#cqlSelect__filtering-on-clustering-column
477
+ # @note Filtering can incurr a significant performance overhead or even timeout on a large data-set.
478
+ #
479
+ def allow_filtering!
480
+ scoped(allow_filtering: true)
481
+ end
482
+
467
483
  #
468
484
  # Set the page_size at which to read records into the record set.
469
485
  #
@@ -695,10 +711,11 @@ module Cequel
695
711
  hattr_reader :attributes, :select_columns, :scoped_key_values,
696
712
  :row_limit, :lower_bound, :upper_bound,
697
713
  :scoped_indexed_column, :query_consistency,
698
- :query_page_size, :query_paging_state
714
+ :query_page_size, :query_paging_state,
715
+ :allow_filtering
699
716
  protected :select_columns, :scoped_key_values, :row_limit, :lower_bound,
700
717
  :upper_bound, :scoped_indexed_column, :query_consistency,
701
- :query_page_size, :query_paging_state
718
+ :query_page_size, :query_paging_state, :allow_filtering
702
719
  hattr_inquirer :attributes, :reversed
703
720
  protected :reversed?
704
721
 
@@ -812,7 +829,7 @@ module Cequel
812
829
  fail IllegalQuery,
813
830
  "Can't scope by more than one indexed column in the same query"
814
831
  end
815
- unless column.indexed?
832
+ unless column.indexed? || allow_filtering
816
833
  fail ArgumentError,
817
834
  "Can't scope by non-indexed column #{column_name}"
818
835
  end
@@ -192,20 +192,22 @@ module Cequel
192
192
  # Drop this table from the keyspace
193
193
  #
194
194
  # @param name [Symbol] name of the table to drop
195
+ # @param exists [Boolean] if set to true, will drop only if exists (Cassandra 3.x)
195
196
  # @return [void]
196
197
  #
197
- def drop_table(name)
198
- keyspace.execute("DROP TABLE #{name}")
198
+ def drop_table(name, exists: false)
199
+ keyspace.execute("DROP TABLE #{'IF EXISTS ' if exists}#{name}")
199
200
  end
200
201
 
201
202
  #
202
203
  # Drop this materialized view from the keyspace
203
204
  #
204
205
  # @param name [Symbol] name of the materialized view to drop
206
+ # @param exists [Boolean] if set to true, will drop only if exists (Cassandra 3.x)
205
207
  # @return [void]
206
208
  #
207
- def drop_materialized_view(name)
208
- keyspace.execute("DROP MATERIALIZED VIEW #{name}")
209
+ def drop_materialized_view(name, exists: false)
210
+ keyspace.execute("DROP MATERIALIZED VIEW #{'IF EXISTS ' if exists}#{name}")
209
211
  end
210
212
 
211
213
  #
@@ -104,6 +104,9 @@ module Cequel
104
104
  options = {index: options} unless options.is_a?(Hash)
105
105
  index_name = options[:index]
106
106
  index_name = :"#{@name}_#{name}_idx" if index_name == true
107
+ if type == :enum
108
+ type = :int
109
+ end
107
110
  DataColumn.new(name, type(type), index_name)
108
111
  .tap { |column| @data_columns << add_column(column) }
109
112
  end
@@ -1,5 +1,5 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
  module Cequel
3
3
  # The current version of the library
4
- VERSION = '2.0.3'
4
+ VERSION = '2.1.0'
5
5
  end
@@ -73,7 +73,7 @@ describe Cequel::Metal::Keyspace do
73
73
  end
74
74
 
75
75
  describe "#exists?" do
76
- it "is true for existent keyspaces" do
76
+ it "is true for existent keyspaces", :retry => 1, :retry_wait => 1 do
77
77
  expect(cequel.exists?).to eq true
78
78
  end
79
79
 
@@ -86,6 +86,20 @@ describe Cequel::Metal::Keyspace do
86
86
  end
87
87
  end
88
88
 
89
+ describe "#drop_table", cassandra: '~> 3.x' do
90
+ it "allows IF EXISTS" do
91
+ expect { cequel.schema.drop_table(:unknown) }.to raise_error(Cassandra::Errors::InvalidError)
92
+ expect { cequel.schema.drop_table(:unknown, exists: true) }.not_to raise_error(Cassandra::Errors::InvalidError)
93
+ end
94
+ end
95
+
96
+ describe "#drop_materialized_view", cassandra: '~> 3.x' do
97
+ it "allows IF EXISTS" do
98
+ expect { cequel.schema.drop_materialized_view(:unknown) }.to raise_error(Cassandra::Errors::ConfigurationError)
99
+ expect { cequel.schema.drop_materialized_view(:unknown, exists: true) }.not_to raise_error(Cassandra::Errors::ConfigurationError)
100
+ end
101
+ end
102
+
89
103
  describe "#ssl_config" do
90
104
  it "ssl configuration settings get extracted correctly for sending to cluster" do
91
105
  connect = Cequel.connect host: Cequel::SpecSupport::Helpers.host,
@@ -115,99 +129,99 @@ describe Cequel::Metal::Keyspace do
115
129
  expect(connect.client_compression).to eq client_compression
116
130
  end
117
131
  end
118
-
119
- describe '#cassandra_options' do
132
+
133
+ describe '#cassandra_options' do
120
134
  let(:cassandra_options) { {foo: :bar} }
121
135
  let(:connect) do
122
136
  Cequel.connect host: Cequel::SpecSupport::Helpers.host,
123
137
  port: Cequel::SpecSupport::Helpers.port,
124
138
  cassandra_options: cassandra_options
125
139
  end
126
- it 'passes the cassandra options as part of the client options' do
140
+ it 'passes the cassandra options as part of the client options' do
127
141
  expect(connect.send(:client_options)).to have_key(:foo)
128
142
  end
129
143
  end
130
-
144
+
131
145
  describe 'cassandra error handling' do
132
- let(:connect_options) do
146
+ let(:connect_options) do
133
147
  {
134
148
  host: Cequel::SpecSupport::Helpers.host,
135
149
  port: Cequel::SpecSupport::Helpers.port
136
- }
137
- end
138
-
139
- let(:default_connect) do
150
+ }
151
+ end
152
+
153
+ let(:default_connect) do
140
154
  Cequel.connect(connect_options)
141
- end
142
-
155
+ end
156
+
143
157
  class SpecCassandraErrorHandler
144
158
  def initialize(options = {})
145
159
  end
146
-
160
+
147
161
  def execute_stmt(keyspace)
148
162
  yield
149
- end
163
+ end
150
164
  end
151
-
152
- it 'uses the error handler passed in as a string' do
165
+
166
+ it 'uses the error handler passed in as a string' do
153
167
  obj = Cequel.connect connect_options.merge(
154
168
  cassandra_error_policy: 'SpecCassandraErrorHandler')
155
-
169
+
156
170
  expect(obj.error_policy.class).to equal(SpecCassandraErrorHandler)
157
- end
158
-
159
- it 'uses the error handler passed in as a module' do
171
+ end
172
+
173
+ it 'uses the error handler passed in as a module' do
160
174
  obj = Cequel.connect connect_options.merge(
161
175
  cassandra_error_policy: SpecCassandraErrorHandler)
162
-
176
+
163
177
  expect(obj.error_policy.class).to equal(SpecCassandraErrorHandler)
164
178
  end
165
-
179
+
166
180
  it 'uses the instance of an error handler passed in' do
167
- policy = SpecCassandraErrorHandler.new
168
-
181
+ policy = SpecCassandraErrorHandler.new
182
+
169
183
  obj = Cequel.connect connect_options.merge(
170
184
  cassandra_error_policy: policy)
171
-
185
+
172
186
  expect(obj.error_policy).to equal(policy)
173
187
  end
174
-
188
+
175
189
  it 'responds to error policy' do
176
- # Always defined, even if config does not specify it
190
+ # Always defined, even if config does not specify it
177
191
  expect(default_connect).to respond_to(:error_policy)
178
192
  end
179
-
180
- it 'calls execute_stmt on the error policy' do
181
- policy = ::Cequel::Metal::Policy::CassandraError::RetryPolicy.new
182
-
193
+
194
+ it 'calls execute_stmt on the error policy' do
195
+ policy = ::Cequel::Metal::Policy::CassandraError::RetryPolicy.new
196
+
183
197
  obj = Cequel.connect connect_options.merge(
184
198
  cassandra_error_policy: policy)
185
199
  expect(policy).to receive(:execute_stmt).at_least(:once)
186
200
  obj.execute_with_options(Cequel::Metal::Statement.new('select * from system.peers;'))
187
- end
188
-
189
- it 'rejects a negative value for retry delay' do
201
+ end
202
+
203
+ it 'rejects a negative value for retry delay' do
190
204
  expect { Cequel.connect connect_options.merge(
191
205
  retry_delay: -1.0)
192
206
  }.to raise_error(ArgumentError)
193
207
  end
194
-
208
+
195
209
  it 'accepts a configured value for retry delay' do
196
210
  obj = Cequel.connect connect_options.merge(
197
211
  retry_delay: 1337.0)
198
-
212
+
199
213
  # do not compare floats exactly, it is error prone
200
214
  # the value is passed to the error policy
201
- expect(obj.error_policy.retry_delay).to be_within(0.1).of(1337.0)
215
+ expect(obj.error_policy.retry_delay).to be_within(0.1).of(1337.0)
202
216
  end
203
-
204
- it 'can clear active connections' do
217
+
218
+ it 'can clear active connections' do
205
219
  expect {
206
220
  default_connect.clear_active_connections!
207
221
  }.to change {
208
222
  default_connect.client
209
223
  }
210
- end
224
+ end
211
225
  end
212
226
 
213
227
  describe "#execute" do
@@ -7,6 +7,7 @@ describe Cequel::Record::Properties do
7
7
  model :Post do
8
8
  key :permalink, :text
9
9
  column :title, :text
10
+ column :status, :enum, values: { open: 1, closed: 2 }
10
11
  list :tags, :text
11
12
  set :categories, :text
12
13
  map :shares, :text, :int
@@ -30,6 +31,17 @@ describe Cequel::Record::Properties do
30
31
  expect(Post.new.permalink).to be_nil
31
32
  end
32
33
 
34
+ it 'should have enums' do
35
+ expect(Post.new.status).to be_nil
36
+ expect(Post.status).to eql({ open: 1, closed: 2 })
37
+ expect(Post.new { |post| post.status = :open }.status).to eq(:open)
38
+ expect(Post.new { |post| post.status = :open }).to be_open
39
+ expect(Post.new { |post| post.status = :closed }.status).to eq(:closed)
40
+ expect(Post.new { |post| post.status = :closed }).to be_closed
41
+ expect(Post.new { |post| post.status = :closed }.attributes['status']).to eq(2)
42
+ expect(Post.new { |post| post.status = :unknown }.status).to eq(nil)
43
+ end
44
+
33
45
  it 'should provide accessor for data column' do
34
46
  expect(Post.new { |post| post.title = 'Big Data' }.title).to eq('Big Data')
35
47
  end
@@ -197,7 +209,7 @@ describe Cequel::Record::Properties do
197
209
  end
198
210
 
199
211
  it 'should run default proc on keys' do
200
- expect(Post.new.subid).to eq("subid #{1+1}")
212
+ expect(Post.new.subid).to eq("subid #{1+1}")
201
213
  end
202
214
 
203
215
  it 'should run default proc' do
@@ -805,6 +805,12 @@ describe Cequel::Record::RecordSet do
805
805
  to raise_error(ArgumentError)
806
806
  end
807
807
  end
808
+
809
+ context 'allow_filtering!', cassandra: '~> 3.x' do
810
+ it 'should allow filtering for none indexed columns' do
811
+ expect(Post.allow_filtering!.where(title: 'Cequel 0').entries.length).to be(1)
812
+ end
813
+ end
808
814
  end
809
815
 
810
816
  describe '#consistency' do
@@ -15,10 +15,15 @@ RSpec.configure do |config|
15
15
  config.include(Cequel::SpecSupport::Helpers)
16
16
  config.extend(Cequel::SpecSupport::Macros)
17
17
 
18
- config.filter_run_excluding rails: ->(requirement) {
19
- !Gem::Requirement.new(requirement).
20
- satisfied_by?(Gem::Version.new(ActiveSupport::VERSION::STRING))
21
- }
18
+ {
19
+ rails: ActiveSupport::VERSION::STRING,
20
+ cassandra: ENV.fetch('CASSANDRA_VERSION', '3.0'),
21
+ }.each do |tag, version|
22
+ config.filter_run_excluding tag => ->(requirement) {
23
+ !Gem::Requirement.new(requirement).
24
+ satisfied_by?(Gem::Version.new(version))
25
+ }
26
+ end
22
27
 
23
28
  unless defined? CassandraCQL
24
29
  config.filter_run_excluding thrift: true
@@ -41,6 +46,9 @@ RSpec.configure do |config|
41
46
  config.filter_run :focus => true
42
47
  config.run_all_when_everything_filtered = true
43
48
  config.order = "random"
49
+
50
+ config.verbose_retry = true
51
+ config.default_retry_count = 0
44
52
  end
45
53
 
46
54
  if defined? byebug
@@ -10,7 +10,7 @@ describe Cequel::SpecSupport::Preparation do
10
10
  expect(prep.drop_keyspace).to eq prep
11
11
  end
12
12
 
13
- it "returns itself from #create_keyspace" do
13
+ it "returns itself from #create_keyspace", :retry => 1, :retry_wait => 1 do
14
14
  expect(prep.create_keyspace).to eq prep
15
15
  end
16
16
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cequel
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.3
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mat Brown
@@ -29,7 +29,7 @@ authors:
29
29
  autorequire:
30
30
  bindir: bin
31
31
  cert_chain: []
32
- date: 2017-01-06 00:00:00.000000000 Z
32
+ date: 2017-01-26 00:00:00.000000000 Z
33
33
  dependencies:
34
34
  - !ruby/object:Gem::Dependency
35
35
  name: activemodel
@@ -107,14 +107,14 @@ dependencies:
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: '3.1'
110
+ version: '3.5'
111
111
  type: :development
112
112
  prerelease: false
113
113
  version_requirements: !ruby/object:Gem::Requirement
114
114
  requirements:
115
115
  - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: '3.1'
117
+ version: '3.5'
118
118
  - !ruby/object:Gem::Dependency
119
119
  name: rspec-its
120
120
  requirement: !ruby/object:Gem::Requirement
@@ -129,6 +129,20 @@ dependencies:
129
129
  - - "~>"
130
130
  - !ruby/object:Gem::Version
131
131
  version: '1.0'
132
+ - !ruby/object:Gem::Dependency
133
+ name: rspec-retry
134
+ requirement: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '0.5'
139
+ type: :development
140
+ prerelease: false
141
+ version_requirements: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '0.5'
132
146
  - !ruby/object:Gem::Dependency
133
147
  name: rubocop
134
148
  requirement: !ruby/object:Gem::Requirement