whi-cassie 1.1.1 → 1.2.0
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.
- 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
|
+

|
|
2
|
+
[](https://codeclimate.com/github/weheartit/cassie/maintainability)
|
|
3
|
+
[](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
|