cequel 1.9.0 → 1.9.1
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 +4 -4
- data/CHANGELOG.md +5 -1
- data/CONTRIBUTING.md +4 -4
- data/Gemfile.lock +13 -13
- data/README.md +6 -5
- data/Rakefile +9 -8
- data/Vagrantfile +1 -1
- data/lib/cequel/metal/new_relic_instrumentation.rb +5 -4
- data/lib/cequel/record/dirty.rb +4 -0
- data/lib/cequel/record/tasks.rb +18 -0
- data/lib/cequel/type.rb +3 -2
- data/lib/cequel/version.rb +1 -1
- data/spec/examples/record/dirty_spec.rb +9 -1
- data/spec/examples/record/lazy_record_collection_spec.rb +1 -1
- data/spec/examples/record/timestamps_spec.rb +13 -8
- data/spec/support/helpers.rb +4 -0
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c8ca34779c245ed3e27bb1e4a848d6339e24fb3b
|
|
4
|
+
data.tar.gz: 0a05736a716c5cd814cdf2023bd839638cda5295
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d57a0397a6b72febadce5c620605d65f55e63b37825564fd55e5fc1131178ee59a65112fcc0ea3957da877116b47afb7db431b27180978c3edf1dc40165c4ed9
|
|
7
|
+
data.tar.gz: ab9cc098f8b0ed157f513ded783d523975703f779296f5b68ce3dd3e62715292f602c5da9e9c6ca60a8adada1432eadfa7eed29ca1b30837eedae18155ccd914
|
data/CHANGELOG.md
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
|
+
## 1.9.1
|
|
2
|
+
|
|
3
|
+
* fix dirty checking for timestamps more precise than Cassandra can store
|
|
4
|
+
* fix bug with new relic instrumentation
|
|
5
|
+
|
|
1
6
|
## 1.9.0
|
|
2
7
|
|
|
3
8
|
* NewRelic instrumentation
|
|
4
9
|
* fix querying tables whose first partition key is a timestamp
|
|
5
10
|
|
|
6
|
-
|
|
7
11
|
## 1.8.0
|
|
8
12
|
|
|
9
13
|
* remove false claims of Rubinius support from readme (we would gratefully accept a PR to fix compatibility)
|
data/CONTRIBUTING.md
CHANGED
|
@@ -37,7 +37,7 @@ $ git remote add upstream git@github.com:cequel/cequel.git
|
|
|
37
37
|
$ brew tap phinze/cask
|
|
38
38
|
$ brew install brew-cask
|
|
39
39
|
$ brew cask install virtualbox vagrant
|
|
40
|
-
$ vagrant up 2.
|
|
40
|
+
$ vagrant up 2.2.5
|
|
41
41
|
$ rake test
|
|
42
42
|
```
|
|
43
43
|
|
|
@@ -50,15 +50,15 @@ install [VirtualBox](https://www.virtualbox.org/) and
|
|
|
50
50
|
[Homebrew-cask](https://github.com/phinze/homebrew-cask) if you're on OS X.
|
|
51
51
|
|
|
52
52
|
Cequel's Vagrantfile can generate a virtual machine for any Cassandra version
|
|
53
|
-
that Cequel supports (i.e., 1.
|
|
53
|
+
that Cequel supports (i.e., 2.1.x & 2.2.x). You can run multiple VMs at the
|
|
54
54
|
same time; the first machine you boot will expose its Cassandra instance on
|
|
55
55
|
port `9042`, which is the default port that Cequel will look for.
|
|
56
56
|
|
|
57
57
|
Cequel is tested against a large range of Ruby, Rails, and Cassandra versions;
|
|
58
58
|
for most patches, you can just run the tests using the latest version of all of
|
|
59
59
|
them. If you're messing with the `Cequel::Schema` or `Cequel::Type` modules,
|
|
60
|
-
you'll want to test at least against an early 1
|
|
61
|
-
later 1
|
|
60
|
+
you'll want to test at least against an early 2.1 release, a
|
|
61
|
+
later 2.1 release (2.1.13), and the latest 2.2 release.
|
|
62
62
|
|
|
63
63
|
## And finally
|
|
64
64
|
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
cequel (1.9.
|
|
4
|
+
cequel (1.9.1)
|
|
5
5
|
activemodel (~> 4.0)
|
|
6
6
|
cassandra-driver (~> 2.0)
|
|
7
7
|
|
|
@@ -22,7 +22,7 @@ GEM
|
|
|
22
22
|
bundler
|
|
23
23
|
rake
|
|
24
24
|
thor (>= 0.14.0)
|
|
25
|
-
ast (2.
|
|
25
|
+
ast (2.2.0)
|
|
26
26
|
backports (3.6.8)
|
|
27
27
|
builder (3.2.2)
|
|
28
28
|
byebug (2.7.0)
|
|
@@ -66,10 +66,9 @@ GEM
|
|
|
66
66
|
multipart-post (2.0.0)
|
|
67
67
|
net-http-persistent (2.9.4)
|
|
68
68
|
net-http-pipeline (1.0.1)
|
|
69
|
-
parser (2.
|
|
70
|
-
ast (
|
|
71
|
-
|
|
72
|
-
powerpack (0.0.9)
|
|
69
|
+
parser (2.3.0.7)
|
|
70
|
+
ast (~> 2.2)
|
|
71
|
+
powerpack (0.1.1)
|
|
73
72
|
pry (0.10.1)
|
|
74
73
|
coderay (~> 1.1.0)
|
|
75
74
|
method_source (~> 0.8.1)
|
|
@@ -79,7 +78,7 @@ GEM
|
|
|
79
78
|
json
|
|
80
79
|
websocket (~> 1.0)
|
|
81
80
|
racc (1.4.12)
|
|
82
|
-
rainbow (2.
|
|
81
|
+
rainbow (2.1.0)
|
|
83
82
|
rake (10.3.2)
|
|
84
83
|
rb-readline (0.5.1)
|
|
85
84
|
rspec (3.4.0)
|
|
@@ -98,13 +97,13 @@ GEM
|
|
|
98
97
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
99
98
|
rspec-support (~> 3.4.0)
|
|
100
99
|
rspec-support (3.4.1)
|
|
101
|
-
rubocop (0.
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
powerpack (~> 0.0.6)
|
|
100
|
+
rubocop (0.39.0)
|
|
101
|
+
parser (>= 2.3.0.7, < 3.0)
|
|
102
|
+
powerpack (~> 0.1)
|
|
105
103
|
rainbow (>= 1.99.1, < 3.0)
|
|
106
|
-
ruby-progressbar (~> 1.
|
|
107
|
-
|
|
104
|
+
ruby-progressbar (~> 1.7)
|
|
105
|
+
unicode-display_width (~> 1.0, >= 1.0.1)
|
|
106
|
+
ruby-progressbar (1.7.5)
|
|
108
107
|
rubysl (2.1.0)
|
|
109
108
|
rubysl-abbrev (~> 2.0)
|
|
110
109
|
rubysl-base64 (~> 2.0)
|
|
@@ -322,6 +321,7 @@ GEM
|
|
|
322
321
|
ethon (>= 0.8.0)
|
|
323
322
|
tzinfo (1.2.2)
|
|
324
323
|
thread_safe (~> 0.1)
|
|
324
|
+
unicode-display_width (1.0.3)
|
|
325
325
|
websocket (1.2.2)
|
|
326
326
|
wwtd (0.9.1)
|
|
327
327
|
yard (0.8.7.6)
|
data/README.md
CHANGED
|
@@ -551,11 +551,9 @@ the columns that are given.
|
|
|
551
551
|
|
|
552
552
|
### Cassandra ###
|
|
553
553
|
|
|
554
|
-
* 2.x
|
|
554
|
+
* 2.1.x
|
|
555
|
+
* 2.2.x
|
|
555
556
|
|
|
556
|
-
Though Cequel is tested against Cassandra 2, it does not at this time support
|
|
557
|
-
any of the CQL3.1 features introduced in Cassandra 2. This will change in the
|
|
558
|
-
future.
|
|
559
557
|
|
|
560
558
|
## Support & Bugs ##
|
|
561
559
|
|
|
@@ -598,6 +596,9 @@ Cequel was written by:
|
|
|
598
596
|
* Tamara Temple
|
|
599
597
|
* Long On
|
|
600
598
|
* Lucas Mundim
|
|
599
|
+
* Luke Duncalfe
|
|
600
|
+
* Eric Betts
|
|
601
|
+
* Maxim Dobryakov
|
|
601
602
|
|
|
602
603
|
Special thanks to [Brewster](https://www.brewster.com), which supported the 0.x
|
|
603
604
|
releases of Cequel.
|
|
@@ -607,7 +608,7 @@ releases of Cequel.
|
|
|
607
608
|
If you're new to Cassandra, check out [Learning Apache
|
|
608
609
|
Cassandra](http://www.amazon.com/gp/product/1783989203/ref=s9_simh_co_p14_d4_i1?pf_rd_m=ATVPDKIKX0DER&pf_rd_s=left-1&pf_rd_r=1TX356WHGF06W32ZHD8S&pf_rd_t=3201&pf_rd_p=1953562742&pf_rd_i=typ01),
|
|
609
610
|
a hands-on guide to Cassandra application development by example, written by
|
|
610
|
-
the
|
|
611
|
+
the creator of Cequel.
|
|
611
612
|
|
|
612
613
|
## License ##
|
|
613
614
|
|
data/Rakefile
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
require 'rubocop'
|
|
2
|
-
require 'rubocop/rake_task'
|
|
3
1
|
require 'yaml'
|
|
4
2
|
require 'bundler/setup'
|
|
5
3
|
require 'rspec/core/rake_task'
|
|
4
|
+
require 'rubocop/rake_task'
|
|
6
5
|
require 'wwtd/tasks'
|
|
7
6
|
require 'travis'
|
|
8
7
|
require File.expand_path('../lib/cequel/version', __FILE__)
|
|
@@ -63,12 +62,12 @@ RSpec::Core::RakeTask.new(:test) do |t|
|
|
|
63
62
|
t.rspec_opts = rspec_opts
|
|
64
63
|
end
|
|
65
64
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
65
|
+
desc 'Check style with Rubocop'
|
|
66
|
+
RuboCop::RakeTask.new(:rubocop) do |task|
|
|
67
|
+
task.patterns = ['lib/**/*.rb']
|
|
68
|
+
task.formatters = ['files']
|
|
69
|
+
task.fail_on_error = true
|
|
70
|
+
end
|
|
72
71
|
|
|
73
72
|
namespace :test do
|
|
74
73
|
desc 'Run the specs with progress formatter'
|
|
@@ -126,6 +125,8 @@ namespace :cassandra do
|
|
|
126
125
|
listing = Net::HTTP.get(URI.parse("http://archive.apache.org/dist/cassandra/"))
|
|
127
126
|
versions = listing.scan(%r(href="(\d+\.\d+\.\d+)/")).map(&:first)
|
|
128
127
|
File.open(File.expand_path('../.cassandra-versions', __FILE__), 'w') do |f|
|
|
128
|
+
f.puts "# This file is automatically generated by `rake cassandra:versions:update`"
|
|
129
|
+
f.puts "# do not edit by hand."
|
|
129
130
|
f.puts(versions.sort_by(&Gem::Version.method(:new)).join("\n"))
|
|
130
131
|
end
|
|
131
132
|
end
|
data/Vagrantfile
CHANGED
|
@@ -135,7 +135,7 @@ exec /opt/apache-cassandra-$1/bin/cassandra" > /etc/init/cassandra.conf
|
|
|
135
135
|
SH
|
|
136
136
|
|
|
137
137
|
versions = File.read(File.expand_path('../.cassandra-versions', __FILE__)).each_line
|
|
138
|
-
.map(&:strip).grep(/^2\./)
|
|
138
|
+
.map(&:strip).grep(/^2\.[12]\./)
|
|
139
139
|
versions.each do |version|
|
|
140
140
|
java_version = version =~ /^1/ ? '6' : '7'
|
|
141
141
|
config.vm.define version do |machine|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
|
2
2
|
begin
|
|
3
3
|
require 'new_relic/agent/datastores'
|
|
4
|
-
rescue LoadError
|
|
4
|
+
rescue LoadError
|
|
5
5
|
fail LoadError, "Can't use NewRelic instrumentation without NewRelic gem"
|
|
6
6
|
end
|
|
7
7
|
|
|
@@ -13,7 +13,7 @@ module Cequel
|
|
|
13
13
|
module NewRelicInstrumentation
|
|
14
14
|
extend ActiveSupport::Concern
|
|
15
15
|
|
|
16
|
-
define_method :
|
|
16
|
+
define_method :execute_with_options_with_newrelic do |statement, bind_vars, options|
|
|
17
17
|
callback = Proc.new do |result, scoped_metric, elapsed|
|
|
18
18
|
NewRelic::Agent::Datastores.notice_statement(statement, elapsed)
|
|
19
19
|
end
|
|
@@ -33,12 +33,13 @@ module Cequel
|
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
NewRelic::Agent::Datastores.wrap("Cassandra", operation, table, callback) do
|
|
36
|
-
|
|
36
|
+
execute_with_options_without_newrelic(statement, bind_vars, options)
|
|
37
37
|
end
|
|
38
38
|
end
|
|
39
39
|
|
|
40
|
+
|
|
40
41
|
included do
|
|
41
|
-
alias_method_chain :
|
|
42
|
+
alias_method_chain :execute_with_options, :newrelic
|
|
42
43
|
end
|
|
43
44
|
end
|
|
44
45
|
end
|
data/lib/cequel/record/dirty.rb
CHANGED
|
@@ -56,6 +56,10 @@ module Cequel
|
|
|
56
56
|
private
|
|
57
57
|
|
|
58
58
|
def write_attribute(name, value)
|
|
59
|
+
column = self.class.reflect_on_column(name)
|
|
60
|
+
fail UnknownAttributeError, "unknown attribute: #{name}" unless column
|
|
61
|
+
value = column.cast(value) unless value.nil?
|
|
62
|
+
|
|
59
63
|
if loaded? && value != read_attribute(name)
|
|
60
64
|
__send__("#{name}_will_change!")
|
|
61
65
|
end
|
data/lib/cequel/record/tasks.rb
CHANGED
|
@@ -9,10 +9,28 @@ namespace :cequel do
|
|
|
9
9
|
create!
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
+
desc 'Initialize Cassandra keyspace if not exist'
|
|
13
|
+
task :create_if_not_exist => :environment do
|
|
14
|
+
if Cequel::Record.connection.schema.exists?
|
|
15
|
+
puts "Keyspace #{Cequel::Record.connection.name} already exists. Nothing to do."
|
|
16
|
+
next
|
|
17
|
+
end
|
|
18
|
+
create!
|
|
19
|
+
end
|
|
20
|
+
|
|
12
21
|
desc 'Drop Cassandra keyspace'
|
|
13
22
|
task :drop => :environment do
|
|
14
23
|
drop!
|
|
15
24
|
end
|
|
25
|
+
|
|
26
|
+
desc 'Drop Cassandra keyspace if exist'
|
|
27
|
+
task :drop_if_exist => :environment do
|
|
28
|
+
unless Cequel::Record.connection.schema.exists?
|
|
29
|
+
puts "Keyspace #{Cequel::Record.connection.name} doesn't exist. Nothing to do."
|
|
30
|
+
next
|
|
31
|
+
end
|
|
32
|
+
drop!
|
|
33
|
+
end
|
|
16
34
|
end
|
|
17
35
|
|
|
18
36
|
desc "Synchronize all models defined in `app/models' with Cassandra " \
|
data/lib/cequel/type.rb
CHANGED
|
@@ -379,7 +379,8 @@ module Cequel
|
|
|
379
379
|
|
|
380
380
|
#
|
|
381
381
|
# `timestamp` columns store timestamps. Timestamps do not include time zone
|
|
382
|
-
# data, and all input times are cast to UTC
|
|
382
|
+
# data, and all input times are cast to UTC and rounded to the nearest
|
|
383
|
+
# millisecond before being stored.
|
|
383
384
|
#
|
|
384
385
|
# @see http://cassandra.apache.org/doc/cql3/CQL.html#usingdates
|
|
385
386
|
# CQL3 documentation for date columns
|
|
@@ -395,7 +396,7 @@ module Cequel
|
|
|
395
396
|
elsif value.respond_to?(:to_time) then value.to_time
|
|
396
397
|
elsif value.is_a?(Numeric) then Time.at(value)
|
|
397
398
|
else Time.parse(value.to_s)
|
|
398
|
-
end.utc
|
|
399
|
+
end.utc.round(3)
|
|
399
400
|
end
|
|
400
401
|
end
|
|
401
402
|
register Timestamp.instance
|
data/lib/cequel/version.rb
CHANGED
|
@@ -6,14 +6,17 @@ describe Cequel::Record::Dirty do
|
|
|
6
6
|
key :permalink, :text
|
|
7
7
|
column :title, :text
|
|
8
8
|
set :categories, :text
|
|
9
|
+
column :created_at, :timestamp
|
|
9
10
|
end
|
|
10
11
|
|
|
11
12
|
context 'loaded model' do
|
|
13
|
+
let(:created_at_float) { 1455754622.8502421 }
|
|
12
14
|
let(:post) do
|
|
13
15
|
Post.create!(
|
|
14
16
|
permalink: 'cequel',
|
|
15
17
|
title: 'Cequel',
|
|
16
|
-
categories: Set['Libraries']
|
|
18
|
+
categories: Set['Libraries'],
|
|
19
|
+
created_at: created_at_float
|
|
17
20
|
)
|
|
18
21
|
end
|
|
19
22
|
|
|
@@ -57,6 +60,11 @@ describe Cequel::Record::Dirty do
|
|
|
57
60
|
with_indifferent_access
|
|
58
61
|
)
|
|
59
62
|
end
|
|
63
|
+
|
|
64
|
+
it 'should check dirty state against correctly cast timestamp values' do
|
|
65
|
+
post.created_at = created_at_float
|
|
66
|
+
expect(post.changed_attributes).to be_empty
|
|
67
|
+
end
|
|
60
68
|
end
|
|
61
69
|
|
|
62
70
|
end
|
|
@@ -17,44 +17,49 @@ describe Cequel::Record::Timestamps do
|
|
|
17
17
|
let!(:now) { Timecop.freeze }
|
|
18
18
|
|
|
19
19
|
context 'with simple primary key' do
|
|
20
|
-
let(:blog) { Blog.create!(subdomain: 'bigdata') }
|
|
20
|
+
let!(:blog) { Blog.create!(subdomain: 'bigdata') }
|
|
21
21
|
|
|
22
22
|
it 'should populate created_at after create new record' do
|
|
23
|
-
expect(blog.created_at).to
|
|
23
|
+
expect(blog.created_at).to be_within(one_millisecond).of(now)
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
it 'should populate updated_at after create new record' do
|
|
27
|
-
expect(blog.updated_at).to
|
|
27
|
+
expect(blog.updated_at).to be_within(one_millisecond).of(now)
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
it 'should update updated_at after record update but not created_at' do
|
|
31
31
|
future = Timecop.freeze(now + 2.minutes)
|
|
32
32
|
blog.name = 'name'
|
|
33
33
|
blog.save!
|
|
34
|
-
expect(blog.updated_at).to
|
|
34
|
+
expect(blog.updated_at).to be_within(one_millisecond).of(future)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'should cast the timestamp in the same way that Cassandra records it' do
|
|
38
|
+
expect(Blog.first.updated_at).to eq(blog.updated_at)
|
|
35
39
|
end
|
|
36
40
|
end
|
|
37
41
|
|
|
38
42
|
context 'with auto-generated timeuuid primary key' do
|
|
39
|
-
let(:post) { Post['bigdata'].create! }
|
|
43
|
+
let!(:post) { Post['bigdata'].create! }
|
|
40
44
|
|
|
41
45
|
it 'should not have created_at column' do
|
|
42
46
|
expect(Post.column_names).not_to include(:created_at)
|
|
43
47
|
end
|
|
44
48
|
|
|
45
49
|
it 'should expose created_at' do
|
|
46
|
-
expect(post.created_at
|
|
50
|
+
expect(post.created_at).to be_within(one_millisecond).of(now)
|
|
47
51
|
end
|
|
48
52
|
|
|
49
53
|
it 'should populate updated_at after create new record' do
|
|
50
|
-
expect(post.updated_at).to
|
|
54
|
+
expect(post.updated_at).to be_within(one_millisecond).of(now)
|
|
51
55
|
end
|
|
52
56
|
|
|
53
57
|
it 'should update updated_at after record update but not created_at' do
|
|
54
58
|
future = Timecop.freeze(now + 2.minutes)
|
|
55
59
|
post.name = 'name'
|
|
56
60
|
post.save!
|
|
57
|
-
expect(post.
|
|
61
|
+
expect(post.created_at).to be_within(one_millisecond).of(now)
|
|
62
|
+
expect(post.updated_at).to be_within(one_millisecond).of(future)
|
|
58
63
|
end
|
|
59
64
|
end
|
|
60
65
|
end
|
data/spec/support/helpers.rb
CHANGED
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: 1.9.
|
|
4
|
+
version: 1.9.1
|
|
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: 2016-
|
|
32
|
+
date: 2016-05-15 00:00:00.000000000 Z
|
|
33
33
|
dependencies:
|
|
34
34
|
- !ruby/object:Gem::Dependency
|
|
35
35
|
name: activemodel
|