whi-cassie 1.1.1 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.github/dependabot.yml +12 -0
- data/.github/workflows/continuous_integration.yml +63 -0
- data/.gitignore +4 -15
- data/.standard.yml +11 -0
- data/Appraisals +13 -0
- data/Gemfile +10 -0
- data/Gemfile.lock +89 -0
- data/HISTORY.md +5 -0
- data/README.md +14 -10
- data/Rakefile +13 -12
- data/VERSION +1 -1
- data/gemfiles/activemodel_4.gemfile +14 -0
- data/gemfiles/activemodel_5.gemfile +14 -0
- data/gemfiles/activemodel_6.gemfile +14 -0
- data/lib/cassie.rb +55 -57
- data/lib/cassie/config.rb +8 -7
- data/lib/cassie/model.rb +111 -110
- data/lib/cassie/railtie.rb +7 -5
- data/lib/cassie/schema.rb +35 -28
- data/lib/cassie/subscribers.rb +10 -12
- data/lib/cassie/testing.rb +15 -15
- data/lib/whi-cassie.rb +2 -0
- data/spec/cassie/config_spec.rb +20 -22
- data/spec/cassie/model_spec.rb +310 -311
- data/spec/cassie/subscribers_spec.rb +19 -21
- data/spec/cassie_spec.rb +86 -87
- data/spec/models/thing.rb +11 -11
- data/spec/models/type_tester.rb +7 -7
- data/spec/spec_helper.rb +29 -19
- data/whi-cassie.gemspec +16 -20
- metadata +13 -33
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: cc03cb8a9fdac75018c3c31a5466a681a7e57f4584c5d3c4540d012da48c8bc9
|
4
|
+
data.tar.gz: 7576c9d2d998329cc918cc8c7dad45eda0012d420c123b7cfb9412c82873ab24
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c60020caa9c11330c2c5713bbd0962cf1682f07f351815b60975b608af50031627a08c27d50e1175ffc02d44da368cc64e71f7a337164cf1dddd75da415e6dc6
|
7
|
+
data.tar.gz: 2690d2fb060d226a11d81cba9db78251bce6ca0a744e27ddd1975e82b2db7376bc247c58b6a1af895da0b81a2d21e1e3b6f3eda64234e52a973b3d0ce221743b
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# Dependabot update strategy
|
2
|
+
version: 2
|
3
|
+
updates:
|
4
|
+
- package-ecosystem: bundler
|
5
|
+
directory: "/"
|
6
|
+
schedule:
|
7
|
+
interval: daily
|
8
|
+
allow:
|
9
|
+
# Automatically keep all runtime dependencies updated
|
10
|
+
- dependency-name: "*"
|
11
|
+
dependency-type: "production"
|
12
|
+
versioning-strategy: lockfile-only
|
@@ -0,0 +1,63 @@
|
|
1
|
+
name: Continuous Integration
|
2
|
+
on:
|
3
|
+
push:
|
4
|
+
branches:
|
5
|
+
- master
|
6
|
+
- actions-*
|
7
|
+
tags:
|
8
|
+
- v*
|
9
|
+
pull_request:
|
10
|
+
env:
|
11
|
+
BUNDLE_CLEAN: "true"
|
12
|
+
BUNDLE_PATH: vendor/bundle
|
13
|
+
BUNDLE_JOBS: 3
|
14
|
+
BUNDLE_RETRY: 3
|
15
|
+
jobs:
|
16
|
+
specs:
|
17
|
+
name: ${{ matrix.job }} ruby-${{ matrix.ruby }} ${{ matrix.activemodel && format('activemodel-{0}', matrix.activemodel) }} cassandra-${{ matrix.cassandra_version }}
|
18
|
+
runs-on: ubuntu-latest
|
19
|
+
services:
|
20
|
+
cassandra:
|
21
|
+
image: cassandra:${{ matrix.cassandra_version }}
|
22
|
+
ports:
|
23
|
+
- 9042:9042
|
24
|
+
strategy:
|
25
|
+
fail-fast: false
|
26
|
+
matrix:
|
27
|
+
ruby: [2.7]
|
28
|
+
activemodel: [6]
|
29
|
+
job: [rspec]
|
30
|
+
cassandra_version: ["4.0"]
|
31
|
+
include:
|
32
|
+
- ruby: 2.6
|
33
|
+
activemodel: 5
|
34
|
+
job: rspec
|
35
|
+
cassandra_version: "3"
|
36
|
+
- ruby: 2.4
|
37
|
+
activemodel: 4
|
38
|
+
job: rspec
|
39
|
+
cassandra_version: "2"
|
40
|
+
- ruby: 2.7
|
41
|
+
job: standardrb
|
42
|
+
cassandra_version: "latest"
|
43
|
+
steps:
|
44
|
+
- name: checkout
|
45
|
+
uses: actions/checkout@v2
|
46
|
+
- name: set up Ruby
|
47
|
+
uses: ruby/setup-ruby@v1
|
48
|
+
with:
|
49
|
+
ruby-version: ${{ matrix.ruby }}
|
50
|
+
- name: inject activemodel ${{ matrix.activemodel }}
|
51
|
+
if: matrix.activemodel != 'original' && matrix.activemodel != null
|
52
|
+
run: | # inject a specific version of activemodel into the Gemfile
|
53
|
+
bundle update
|
54
|
+
bundle exec appraisal generate
|
55
|
+
bundle config set gemfile "gemfiles/activemodel_${{ matrix.activemodel }}.gemfile"
|
56
|
+
- name: install dependencies
|
57
|
+
run: bundle install
|
58
|
+
- name: specs
|
59
|
+
if: matrix.job == 'rspec'
|
60
|
+
run: bundle exec rake spec
|
61
|
+
- name: standardrb
|
62
|
+
if: matrix.job == 'standardrb'
|
63
|
+
run: bundle exec rake standard
|
data/.gitignore
CHANGED
data/.standard.yml
ADDED
data/Appraisals
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
whi-cassie (1.2.0)
|
5
|
+
activemodel (>= 4.0)
|
6
|
+
cassandra-driver (~> 3.0)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
activemodel (6.0.3.4)
|
12
|
+
activesupport (= 6.0.3.4)
|
13
|
+
activesupport (6.0.3.4)
|
14
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
15
|
+
i18n (>= 0.7, < 2)
|
16
|
+
minitest (~> 5.1)
|
17
|
+
tzinfo (~> 1.1)
|
18
|
+
zeitwerk (~> 2.2, >= 2.2.2)
|
19
|
+
appraisal (2.3.0)
|
20
|
+
bundler
|
21
|
+
rake
|
22
|
+
thor (>= 0.14.0)
|
23
|
+
ast (2.4.1)
|
24
|
+
cassandra-driver (3.2.5)
|
25
|
+
ione (~> 1.2)
|
26
|
+
concurrent-ruby (1.1.7)
|
27
|
+
diff-lcs (1.4.4)
|
28
|
+
i18n (1.8.5)
|
29
|
+
concurrent-ruby (~> 1.0)
|
30
|
+
ione (1.2.4)
|
31
|
+
minitest (5.14.2)
|
32
|
+
parallel (1.19.2)
|
33
|
+
parser (2.7.2.0)
|
34
|
+
ast (~> 2.4.1)
|
35
|
+
rainbow (3.0.0)
|
36
|
+
rake (13.0.1)
|
37
|
+
regexp_parser (1.8.2)
|
38
|
+
rexml (3.2.4)
|
39
|
+
rspec (3.9.0)
|
40
|
+
rspec-core (~> 3.9.0)
|
41
|
+
rspec-expectations (~> 3.9.0)
|
42
|
+
rspec-mocks (~> 3.9.0)
|
43
|
+
rspec-core (3.9.3)
|
44
|
+
rspec-support (~> 3.9.3)
|
45
|
+
rspec-expectations (3.9.3)
|
46
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
47
|
+
rspec-support (~> 3.9.0)
|
48
|
+
rspec-mocks (3.9.1)
|
49
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
50
|
+
rspec-support (~> 3.9.0)
|
51
|
+
rspec-support (3.9.4)
|
52
|
+
rubocop (1.0.0)
|
53
|
+
parallel (~> 1.10)
|
54
|
+
parser (>= 2.7.1.5)
|
55
|
+
rainbow (>= 2.2.2, < 4.0)
|
56
|
+
regexp_parser (>= 1.8)
|
57
|
+
rexml
|
58
|
+
rubocop-ast (>= 0.6.0)
|
59
|
+
ruby-progressbar (~> 1.7)
|
60
|
+
unicode-display_width (>= 1.4.0, < 2.0)
|
61
|
+
rubocop-ast (1.1.0)
|
62
|
+
parser (>= 2.7.1.5)
|
63
|
+
rubocop-performance (1.8.1)
|
64
|
+
rubocop (>= 0.87.0)
|
65
|
+
rubocop-ast (>= 0.4.0)
|
66
|
+
ruby-progressbar (1.10.1)
|
67
|
+
standard (0.8.1)
|
68
|
+
rubocop (= 1.0.0)
|
69
|
+
rubocop-performance (= 1.8.1)
|
70
|
+
thor (1.0.1)
|
71
|
+
thread_safe (0.3.6)
|
72
|
+
tzinfo (1.2.7)
|
73
|
+
thread_safe (~> 0.1)
|
74
|
+
unicode-display_width (1.7.0)
|
75
|
+
zeitwerk (2.4.0)
|
76
|
+
|
77
|
+
PLATFORMS
|
78
|
+
ruby
|
79
|
+
|
80
|
+
DEPENDENCIES
|
81
|
+
appraisal
|
82
|
+
bundler (~> 2.0)
|
83
|
+
rake
|
84
|
+
rspec
|
85
|
+
standard (~> 0.8.1)
|
86
|
+
whi-cassie!
|
87
|
+
|
88
|
+
BUNDLED WITH
|
89
|
+
2.1.4
|
data/HISTORY.md
CHANGED
data/README.md
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
![Continuous Integration](https://github.com/weheartit/cassie/workflows/Continuous%20Integration/badge.svg)
|
2
|
+
[![Maintainability](https://api.codeclimate.com/v1/badges/129ede20094ea298c687/maintainability)](https://codeclimate.com/github/weheartit/cassie/maintainability)
|
3
|
+
[![Ruby Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://github.com/testdouble/standard)
|
4
|
+
|
1
5
|
# Cassie
|
2
6
|
|
3
7
|
The short and sweet Cassandra object mapper from [We Heart It](http://weheartit.com/)
|
@@ -8,34 +12,34 @@ The short and sweet Cassandra object mapper from [We Heart It](http://weheartit.
|
|
8
12
|
class Thing
|
9
13
|
# Your model must include this
|
10
14
|
include Cassie::Model
|
11
|
-
|
15
|
+
|
12
16
|
# Set the table name where the data lives.
|
13
17
|
self.table_name = "things"
|
14
|
-
|
18
|
+
|
15
19
|
# Set the keyspace where the table lives. Keyspaces can be defined abstractly and mapped
|
16
20
|
# and mapped in a configuration file. This can allow you to have different keyspace names
|
17
21
|
# between different environments and still use the same code.
|
18
22
|
self.keyspace = "default"
|
19
|
-
|
23
|
+
|
20
24
|
# You must defind the primary key. They columns must be listed in the order that they apper
|
21
25
|
# in the Cassandra CQL PRIMARY KEY clause defining the table.
|
22
26
|
self.primary_key = [:owner, :id]
|
23
|
-
|
27
|
+
|
24
28
|
# All columns are explicitly defined with their name and data type and an optional
|
25
29
|
# alias name.
|
26
30
|
column :owner, :int
|
27
31
|
column :id, :int, :as => :identifier
|
28
32
|
column :val, :varchar, :as => :value
|
29
|
-
|
33
|
+
|
30
34
|
# The ordering keys should also be defined along with how they are ordered.
|
31
35
|
ordering_key :id, :desc
|
32
|
-
|
36
|
+
|
33
37
|
# You can use all the standard ActiveModel validations.
|
34
38
|
validates_presence_of :owner, :id
|
35
|
-
|
39
|
+
|
36
40
|
# You also get before and after callbacks for create, update, save, and destroy.
|
37
41
|
before_save :some_callback_method
|
38
|
-
|
42
|
+
|
39
43
|
...
|
40
44
|
end
|
41
45
|
|
@@ -176,13 +180,13 @@ To use it with rspec you should add this code to your spec_helper.rb file:
|
|
176
180
|
end
|
177
181
|
Cassie::Testing.prepare!
|
178
182
|
end
|
179
|
-
|
183
|
+
|
180
184
|
config.after(:suite) do
|
181
185
|
Cassie::Schema.all do |keyspace|
|
182
186
|
Cassie::Schema.drop!(keyspace)
|
183
187
|
end
|
184
188
|
end
|
185
|
-
|
189
|
+
|
186
190
|
config.around(:each) do |example|
|
187
191
|
Cassie::Testing.cleanup! do
|
188
192
|
example.run
|
data/Rakefile
CHANGED
@@ -1,18 +1,19 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
|
+
require "rspec/core/rake_task"
|
3
|
+
require "standard/rake"
|
2
4
|
|
3
|
-
|
4
|
-
task :default => :test
|
5
|
+
RSpec::Core::RakeTask.new(:spec)
|
5
6
|
|
6
|
-
|
7
|
-
task :tests => :test
|
7
|
+
task default: :spec
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
9
|
+
desc "run the specs using appraisal"
|
10
|
+
task :appraisals do
|
11
|
+
exec "bundle exec appraisal rake spec"
|
12
|
+
end
|
13
|
+
|
14
|
+
namespace :appraisals do
|
15
|
+
desc "install all the appraisal gemspecs"
|
16
|
+
task :install do
|
17
|
+
exec "bundle exec appraisal install"
|
17
18
|
end
|
18
19
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.2.0
|
data/lib/cassie.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "cassandra"
|
2
4
|
|
3
5
|
# This class provides a lightweight wrapper around the Cassandra driver. It provides
|
4
6
|
# a foundation for maintaining a connection and constructing CQL statements.
|
@@ -9,35 +11,35 @@ class Cassie
|
|
9
11
|
require File.expand_path("../cassie/schema.rb", __FILE__)
|
10
12
|
require File.expand_path("../cassie/testing.rb", __FILE__)
|
11
13
|
require File.expand_path("../cassie/railtie.rb", __FILE__) if defined?(Rails)
|
12
|
-
|
14
|
+
|
13
15
|
class RecordNotFound < StandardError
|
14
16
|
end
|
15
|
-
|
17
|
+
|
16
18
|
class RecordInvalid < StandardError
|
17
19
|
attr_reader :record
|
18
|
-
|
20
|
+
|
19
21
|
def initialize(record)
|
20
22
|
super("Errors on #{record.class.name}: #{record.errors.to_hash.inspect}")
|
21
23
|
@record = record
|
22
24
|
end
|
23
25
|
end
|
24
|
-
|
26
|
+
|
25
27
|
# Message passed to subscribers with the statement, options, and time for each statement
|
26
28
|
# to execute. Note that if statements are batched they will be packed into one message
|
27
29
|
# with a Cassandra::Statements::Batch statement and empty options.
|
28
30
|
class Message
|
29
31
|
attr_reader :statement, :options, :elapsed_time
|
30
|
-
|
32
|
+
|
31
33
|
def initialize(statement, options, elapsed_time)
|
32
34
|
@statement = statement
|
33
35
|
@options = options
|
34
36
|
@elapsed_time = elapsed_time
|
35
37
|
end
|
36
38
|
end
|
37
|
-
|
39
|
+
|
38
40
|
attr_reader :config, :subscribers
|
39
41
|
attr_accessor :consistency
|
40
|
-
|
42
|
+
|
41
43
|
class << self
|
42
44
|
# A singleton instance that can be shared to communicate with a Cassandra cluster.
|
43
45
|
def instance
|
@@ -47,7 +49,7 @@ class Cassie
|
|
47
49
|
end
|
48
50
|
@instance
|
49
51
|
end
|
50
|
-
|
52
|
+
|
51
53
|
# Call this method to load the Cassie::Config from the specified file for the
|
52
54
|
# specified environment.
|
53
55
|
def configure!(options)
|
@@ -58,7 +60,7 @@ class Cassie
|
|
58
60
|
end
|
59
61
|
@config = Cassie::Config.new(options)
|
60
62
|
end
|
61
|
-
|
63
|
+
|
62
64
|
# This method can be used to set a consistency level for all Cassandra queries
|
63
65
|
# within a block that don't explicitly define them. It can be used where consistency
|
64
66
|
# is important (i.e. on validation queries) but where a higher level method
|
@@ -72,18 +74,16 @@ class Cassie
|
|
72
74
|
Thread.current[:cassie_consistency] = save_val
|
73
75
|
end
|
74
76
|
end
|
75
|
-
|
77
|
+
|
76
78
|
# Get a Logger compatible object if it has been set.
|
77
79
|
def logger
|
78
80
|
@logger if defined?(@logger)
|
79
81
|
end
|
80
|
-
|
82
|
+
|
81
83
|
# Set a logger with a Logger compatible object.
|
82
|
-
|
83
|
-
@logger = value
|
84
|
-
end
|
84
|
+
attr_writer :logger
|
85
85
|
end
|
86
|
-
|
86
|
+
|
87
87
|
def initialize(config)
|
88
88
|
@config = config
|
89
89
|
@monitor = Monitor.new
|
@@ -93,14 +93,14 @@ class Cassie
|
|
93
93
|
@subscribers = Subscribers.new
|
94
94
|
@consistency = ((config.cluster || {})[:consistency] || :local_one)
|
95
95
|
end
|
96
|
-
|
96
|
+
|
97
97
|
# Open a connection to the Cassandra cluster.
|
98
98
|
def connect
|
99
99
|
start_time = Time.now
|
100
100
|
cluster_config = config.cluster
|
101
|
-
cluster_config = cluster_config.merge(:
|
101
|
+
cluster_config = cluster_config.merge(logger: logger) if logger
|
102
102
|
cluster = Cassandra.cluster(cluster_config)
|
103
|
-
logger
|
103
|
+
logger&.info("Cassie.connect with #{config.sanitized_cluster} in #{((Time.now - start_time) * 1000).round}ms")
|
104
104
|
@monitor.synchronize do
|
105
105
|
@session = cluster.connect(config.default_keyspace)
|
106
106
|
@prepared_statements = {}
|
@@ -109,19 +109,19 @@ class Cassie
|
|
109
109
|
|
110
110
|
# Close the connections to the Cassandra cluster.
|
111
111
|
def disconnect
|
112
|
-
logger
|
112
|
+
logger&.info("Cassie.disconnect from #{config.sanitized_cluster}")
|
113
113
|
@monitor.synchronize do
|
114
|
-
@session
|
114
|
+
@session&.close
|
115
115
|
@session = nil
|
116
116
|
@prepared_statements = {}
|
117
117
|
end
|
118
118
|
end
|
119
|
-
|
119
|
+
|
120
120
|
# Return true if the connection to the Cassandra cluster has been established.
|
121
121
|
def connected?
|
122
122
|
!!@session
|
123
123
|
end
|
124
|
-
|
124
|
+
|
125
125
|
# Force reconnection. If you're using this code in conjunction in a forking server environment
|
126
126
|
# like passenger or unicorn you should call this method after forking.
|
127
127
|
def reconnect
|
@@ -150,13 +150,13 @@ class Cassie
|
|
150
150
|
end
|
151
151
|
end
|
152
152
|
end
|
153
|
-
|
153
|
+
|
154
154
|
if cache_filled_up && logger && Time.now > @last_prepare_warning + 10
|
155
155
|
# Set a throttle on how often this message is logged so we don't kill performance enven more.
|
156
156
|
@last_prepare_warning = Time.now
|
157
157
|
logger.warn("Cassie.prepare cache filled up. Consider increasing the size from #{config.max_prepared_statements}.")
|
158
158
|
end
|
159
|
-
|
159
|
+
|
160
160
|
statement
|
161
161
|
end
|
162
162
|
|
@@ -210,22 +210,22 @@ class Cassie
|
|
210
210
|
columns = []
|
211
211
|
values = []
|
212
212
|
values_hash.each do |column, value|
|
213
|
-
|
213
|
+
unless value.nil?
|
214
214
|
columns << column
|
215
215
|
values << value
|
216
216
|
end
|
217
217
|
end
|
218
|
-
cql = "INSERT INTO #{table} (#{columns.join(
|
219
|
-
|
220
|
-
if options
|
218
|
+
cql = "INSERT INTO #{table} (#{columns.join(", ")}) VALUES (#{question_marks(columns.size)})"
|
219
|
+
|
220
|
+
if options&.include?(:ttl)
|
221
221
|
options = options.dup
|
222
222
|
ttl = options.delete(:ttl)
|
223
223
|
if ttl
|
224
|
-
cql
|
224
|
+
cql += " USING TTL ?"
|
225
225
|
values << Integer(ttl)
|
226
226
|
end
|
227
227
|
end
|
228
|
-
|
228
|
+
|
229
229
|
batch_or_execute(cql, values, options)
|
230
230
|
end
|
231
231
|
|
@@ -248,20 +248,20 @@ class Cassie
|
|
248
248
|
end
|
249
249
|
end
|
250
250
|
values = update_values + key_values
|
251
|
-
|
251
|
+
|
252
252
|
cql = "UPDATE #{table}"
|
253
|
-
|
254
|
-
if options
|
253
|
+
|
254
|
+
if options&.include?(:ttl)
|
255
255
|
options = options.dup
|
256
256
|
ttl = options.delete(:ttl)
|
257
257
|
if ttl
|
258
|
-
cql
|
258
|
+
cql += " USING TTL ?"
|
259
259
|
values.unshift(Integer(ttl))
|
260
260
|
end
|
261
261
|
end
|
262
262
|
|
263
|
-
cql
|
264
|
-
|
263
|
+
cql += " SET #{update_cql.join(", ")} WHERE #{key_cql}"
|
264
|
+
|
265
265
|
batch_or_execute(cql, values, options)
|
266
266
|
end
|
267
267
|
|
@@ -281,31 +281,31 @@ class Cassie
|
|
281
281
|
start_time = Time.now
|
282
282
|
begin
|
283
283
|
statement = nil
|
284
|
-
if cql.is_a?(String)
|
284
|
+
statement = if cql.is_a?(String)
|
285
285
|
if values.present?
|
286
|
-
|
286
|
+
prepare(cql)
|
287
287
|
else
|
288
|
-
|
288
|
+
Cassandra::Statements::Simple.new(cql)
|
289
289
|
end
|
290
290
|
else
|
291
|
-
|
291
|
+
cql
|
292
292
|
end
|
293
|
-
|
293
|
+
|
294
294
|
if values.present?
|
295
295
|
values = Array(values)
|
296
|
-
options = (options ? options.merge(:
|
296
|
+
options = (options ? options.merge(arguments: values) : {arguments: values})
|
297
297
|
end
|
298
|
-
|
298
|
+
|
299
299
|
# Set a default consistency from a block context if it isn't explicitly set.
|
300
300
|
statement_consistency = current_consistency
|
301
301
|
if statement_consistency
|
302
302
|
if options
|
303
|
-
options = options.merge(:
|
303
|
+
options = options.merge(consistency: statement_consistency) if options[:consistency].nil?
|
304
304
|
else
|
305
|
-
options = {:
|
305
|
+
options = {consistency: statement_consistency}
|
306
306
|
end
|
307
307
|
end
|
308
|
-
|
308
|
+
|
309
309
|
session.execute(statement, options || {})
|
310
310
|
rescue Cassandra::Errors::IOError => e
|
311
311
|
disconnect
|
@@ -313,18 +313,18 @@ class Cassie
|
|
313
313
|
ensure
|
314
314
|
if statement.is_a?(Cassandra::Statement) && !subscribers.empty?
|
315
315
|
payload = Message.new(statement, options, Time.now - start_time)
|
316
|
-
subscribers.each{|subscriber| subscriber.call(payload)}
|
316
|
+
subscribers.each { |subscriber| subscriber.call(payload) }
|
317
317
|
end
|
318
318
|
end
|
319
319
|
end
|
320
|
-
|
320
|
+
|
321
321
|
# Return the current consistency level that has been set for statements.
|
322
322
|
def current_consistency
|
323
323
|
Thread.current[:cassie_consistency] || consistency
|
324
324
|
end
|
325
325
|
|
326
326
|
private
|
327
|
-
|
327
|
+
|
328
328
|
def logger
|
329
329
|
self.class.logger
|
330
330
|
end
|
@@ -333,7 +333,7 @@ class Cassie
|
|
333
333
|
connect unless connected?
|
334
334
|
@session
|
335
335
|
end
|
336
|
-
|
336
|
+
|
337
337
|
def batch_or_execute(cql, values, options = nil)
|
338
338
|
batch = Thread.current[:cassie_batch]
|
339
339
|
if batch
|
@@ -345,9 +345,7 @@ class Cassie
|
|
345
345
|
end
|
346
346
|
|
347
347
|
def question_marks(size)
|
348
|
-
|
349
|
-
(size - 1).times{ q << ',?' }
|
350
|
-
q
|
348
|
+
"?#{",?" * (size - 1)}"
|
351
349
|
end
|
352
350
|
|
353
351
|
def key_clause(key_hash)
|
@@ -357,9 +355,9 @@ class Cassie
|
|
357
355
|
cql << "#{key} = ?"
|
358
356
|
values << value
|
359
357
|
end
|
360
|
-
[cql.join(
|
358
|
+
[cql.join(" AND "), values]
|
361
359
|
end
|
362
|
-
|
360
|
+
|
363
361
|
# Extract the CQL from a statement
|
364
362
|
def statement_cql(statement, previous = nil)
|
365
363
|
cql = nil
|
@@ -368,7 +366,7 @@ class Cassie
|
|
368
366
|
elsif statement.respond_to?(:statements) && (previous.nil? || !previous.include?(statement))
|
369
367
|
previous ||= []
|
370
368
|
previous << statement
|
371
|
-
cql = statement.statements.collect{|s| statement_cql(s, previous)}.join(
|
369
|
+
cql = statement.statements.collect { |s| statement_cql(s, previous) }.join("; ")
|
372
370
|
end
|
373
371
|
cql
|
374
372
|
end
|