gotime-cassandra_object 2.1.2 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +1 -1
- data/README.markdown +2 -73
- data/gotime-cassandra_object.gemspec +1 -1
- data/lib/cassandra_object.rb +1 -0
- data/lib/cassandra_object/base.rb +3 -1
- data/lib/cassandra_object/callbacks.rb +17 -0
- data/lib/cassandra_object/errors.rb +10 -0
- data/lib/cassandra_object/finder_methods.rb +8 -0
- data/lib/cassandra_object/identity/uuid_key_factory.rb +2 -0
- data/lib/cassandra_object/persistence.rb +55 -39
- data/lib/cassandra_object/primary_key.rb +12 -0
- data/lib/cassandra_object/validation.rb +1 -1
- data/test/finder_methods_test.rb +17 -4
- data/test/identity_test.rb +10 -0
- data/test/persistence_test.rb +68 -1
- data/test/primary_key_test.rb +9 -0
- metadata +11 -8
- data/TODO +0 -2
data/Gemfile.lock
CHANGED
data/README.markdown
CHANGED
@@ -1,79 +1,8 @@
|
|
1
1
|
# Cassandra Object
|
2
2
|
|
3
|
-
Cassandra Object provides a
|
3
|
+
Cassandra Object provides a API for working with [Cassandra](http://incubator.apache.org/cassandra/).
|
4
4
|
|
5
|
-
|
6
|
-
* `:conditions`
|
7
|
-
* `:joins`
|
8
|
-
* `:group`
|
9
|
-
|
10
|
-
There isn't much in the way of documentation yet, but a few examples.
|
5
|
+
Example:
|
11
6
|
|
12
7
|
class Customer < CassandraObject::Base
|
13
|
-
attribute :first_name, :type => :string
|
14
|
-
attribute :last_name, :type => :string
|
15
|
-
attribute :date_of_birth, :type => :date
|
16
|
-
attribute :signed_up_at, :type => :time_with_zone
|
17
|
-
|
18
|
-
validate :should_be_cool
|
19
|
-
|
20
|
-
key :uuid
|
21
|
-
|
22
|
-
index :date_of_birth
|
23
|
-
|
24
|
-
association :invoices, :unique=>false, :inverse_of=>:customer
|
25
|
-
|
26
|
-
private
|
27
|
-
|
28
|
-
def should_be_cool
|
29
|
-
unless ["Michael", "Anika", "Evan", "James"].include?(first_name)
|
30
|
-
errors.add(:first_name, "must be that of a cool person")
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
class Invoice < CassandraObject::Base
|
36
|
-
attribute :number, :type=>:integer
|
37
|
-
attribute :total, :type=>:float
|
38
|
-
attribute :gst_number, :type=>:string
|
39
|
-
|
40
|
-
# indexes can have a single entry also.
|
41
|
-
index :number, :unique=>true
|
42
|
-
|
43
|
-
# bi-directional associations with read-repair support.
|
44
|
-
association :customer, :unique=>true, :inverse_of=>:invoices
|
45
|
-
|
46
|
-
# Read migration support
|
47
|
-
migrate 1 do |attrs|
|
48
|
-
attrs["total"] ||= rand(2000) / 100.0
|
49
|
-
end
|
50
|
-
|
51
|
-
migrate 2 do |attrs|
|
52
|
-
attrs["gst_number"] = "66-666-666"
|
53
|
-
end
|
54
|
-
|
55
|
-
key :natural, :attributes => :number
|
56
8
|
end
|
57
|
-
|
58
|
-
@invoice = Invoice.get("12345")
|
59
|
-
@invoice.customer.invoices.all.include?(@invoice) # true
|
60
|
-
|
61
|
-
# FAQ
|
62
|
-
|
63
|
-
## How do I make this work?
|
64
|
-
|
65
|
-
Here are some basic directions:
|
66
|
-
|
67
|
-
1. `git clone git://github.com/NZKoz/cassandra_object.git`
|
68
|
-
2. Run the bundler `gem bundle`
|
69
|
-
3. Make sure the tests pass `rake test`
|
70
|
-
|
71
|
-
This gem has backwards compatibility with active support version 2.3.x, this is to enable people to use it with rails 2.3 applications. This backwards compatibility may not continue after the 1.0 release.
|
72
|
-
|
73
|
-
## Should I use this in production?
|
74
|
-
|
75
|
-
Only if you're looking to help out with the development, there are a bunch of rough edges right now.
|
76
|
-
|
77
|
-
## Why do you use a superclass and not a module.
|
78
|
-
|
79
|
-
Because.
|
data/lib/cassandra_object.rb
CHANGED
@@ -3,6 +3,7 @@ require 'set'
|
|
3
3
|
|
4
4
|
require 'cassandra_object/log_subscriber'
|
5
5
|
require 'cassandra_object/types'
|
6
|
+
require 'cassandra_object/errors'
|
6
7
|
|
7
8
|
module CassandraObject
|
8
9
|
class Base
|
@@ -28,10 +29,11 @@ module CassandraObject
|
|
28
29
|
extend ActiveSupport::DescendantsTracker
|
29
30
|
|
30
31
|
include Connection
|
31
|
-
include
|
32
|
+
include PrimaryKey
|
32
33
|
include Identity
|
33
34
|
include Attributes
|
34
35
|
include Persistence
|
36
|
+
include Callbacks
|
35
37
|
include Indexes
|
36
38
|
include Dirty
|
37
39
|
include Validation
|
@@ -6,5 +6,22 @@ module CassandraObject
|
|
6
6
|
extend ActiveModel::Callbacks
|
7
7
|
define_model_callbacks :save, :create, :destroy, :update
|
8
8
|
end
|
9
|
+
|
10
|
+
def destroy #:nodoc:
|
11
|
+
_run_destroy_callbacks { super }
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
def create_or_update #:nodoc:
|
16
|
+
_run_save_callbacks { super }
|
17
|
+
end
|
18
|
+
|
19
|
+
def create #:nodoc:
|
20
|
+
_run_create_callbacks { super }
|
21
|
+
end
|
22
|
+
|
23
|
+
def update(*) #:nodoc:
|
24
|
+
_run_update_callbacks { super }
|
25
|
+
end
|
9
26
|
end
|
10
27
|
end
|
@@ -2,6 +2,14 @@ module CassandraObject
|
|
2
2
|
module FinderMethods
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
module ClassMethods
|
5
|
+
def find(key)
|
6
|
+
if parse_key(key) && attributes = connection.get(column_family, key)
|
7
|
+
instantiate(key, attributes)
|
8
|
+
else
|
9
|
+
raise CassandraObject::RecordNotFound
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
5
13
|
def all(options = {})
|
6
14
|
options = {:consistency => self.read_consistency, :limit => 100}.merge(options)
|
7
15
|
count = options[:limit]
|
@@ -89,62 +89,78 @@ module CassandraObject
|
|
89
89
|
def column_family_configuration
|
90
90
|
[{:Name => column_family, :CompareWith => "UTF8Type"}]
|
91
91
|
end
|
92
|
+
end
|
92
93
|
|
94
|
+
def new_record?
|
95
|
+
@new_record
|
93
96
|
end
|
94
97
|
|
95
|
-
def
|
96
|
-
|
97
|
-
create_or_update
|
98
|
-
end
|
98
|
+
def destroyed?
|
99
|
+
@destroyed
|
99
100
|
end
|
100
|
-
|
101
|
-
def
|
102
|
-
|
103
|
-
result != false
|
101
|
+
|
102
|
+
def persisted?
|
103
|
+
!(new_record? || destroyed?)
|
104
104
|
end
|
105
|
-
|
106
|
-
def
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
@key
|
105
|
+
|
106
|
+
def save(*)
|
107
|
+
begin
|
108
|
+
create_or_update
|
109
|
+
rescue CassandraObject::RecordInvalid
|
110
|
+
false
|
112
111
|
end
|
113
112
|
end
|
114
|
-
|
115
|
-
def
|
116
|
-
|
117
|
-
_write
|
118
|
-
end
|
113
|
+
|
114
|
+
def save!
|
115
|
+
create_or_update || raise(RecordNotSaved)
|
119
116
|
end
|
120
|
-
|
121
|
-
def
|
122
|
-
|
123
|
-
|
117
|
+
|
118
|
+
def destroy
|
119
|
+
self.class.remove(key)
|
120
|
+
@destroyed = true
|
121
|
+
freeze
|
124
122
|
end
|
125
123
|
|
126
|
-
def
|
127
|
-
|
124
|
+
def update_attribute(name, value)
|
125
|
+
name = name.to_s
|
126
|
+
send("#{name}=", value)
|
127
|
+
save(:validate => false)
|
128
128
|
end
|
129
129
|
|
130
|
-
def
|
131
|
-
|
130
|
+
def update_attributes(attributes)
|
131
|
+
self.attributes = attributes
|
132
|
+
save
|
132
133
|
end
|
133
134
|
|
134
|
-
def
|
135
|
-
|
135
|
+
def update_attributes!(attributes)
|
136
|
+
self.attributes = attributes
|
137
|
+
save!
|
136
138
|
end
|
137
139
|
|
138
|
-
def
|
139
|
-
|
140
|
-
self.class.remove(key)
|
141
|
-
@destroyed = true
|
142
|
-
freeze
|
143
|
-
end
|
140
|
+
def reload
|
141
|
+
@attributes.update(self.class.find(self.id).instance_variable_get('@attributes'))
|
144
142
|
end
|
143
|
+
|
144
|
+
private
|
145
|
+
def create_or_update
|
146
|
+
result = new_record? ? create : update
|
147
|
+
result != false
|
148
|
+
end
|
149
|
+
|
150
|
+
def create
|
151
|
+
@key ||= self.class.next_key(self)
|
152
|
+
write
|
153
|
+
@new_record = false
|
154
|
+
@key
|
155
|
+
end
|
145
156
|
|
146
|
-
|
147
|
-
|
148
|
-
|
157
|
+
def update
|
158
|
+
write
|
159
|
+
end
|
160
|
+
|
161
|
+
def write
|
162
|
+
changed_attributes = changed.inject({}) { |h, n| h[n] = read_attribute(n); h }
|
163
|
+
self.class.write(key, changed_attributes, schema_version)
|
164
|
+
end
|
149
165
|
end
|
150
166
|
end
|
data/test/finder_methods_test.rb
CHANGED
@@ -1,11 +1,17 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
3
|
class CassandraObject::FinderMethodsTest < CassandraObject::TestCase
|
4
|
-
test '
|
5
|
-
|
6
|
-
|
4
|
+
test 'find' do
|
5
|
+
persisted_issue = Issue.create
|
6
|
+
found_issue = Issue.find(persisted_issue.id)
|
7
7
|
|
8
|
-
|
8
|
+
assert_equal persisted_issue, found_issue
|
9
|
+
end
|
10
|
+
|
11
|
+
test 'find missing record' do
|
12
|
+
assert_raise CassandraObject::RecordNotFound do
|
13
|
+
Issue.find('what')
|
14
|
+
end
|
9
15
|
end
|
10
16
|
|
11
17
|
test 'all' do
|
@@ -15,6 +21,13 @@ class CassandraObject::FinderMethodsTest < CassandraObject::TestCase
|
|
15
21
|
assert_equal [first_issue, second_issue].to_set, Issue.all.to_set
|
16
22
|
end
|
17
23
|
|
24
|
+
test 'first' do
|
25
|
+
first_issue = Issue.create
|
26
|
+
second_issue = Issue.create
|
27
|
+
|
28
|
+
assert [first_issue, second_issue].include?(Issue.first)
|
29
|
+
end
|
30
|
+
|
18
31
|
test 'find_with_ids' do
|
19
32
|
first_issue = Issue.create
|
20
33
|
second_issue = Issue.create
|
data/test/identity_test.rb
CHANGED
@@ -1,6 +1,16 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
3
|
class CassandraObject::IdentityTest < CassandraObject::TestCase
|
4
|
+
test 'parse_key' do
|
5
|
+
# p "Issue.parse_key('bb4cbbbc-b7c7-11e0-9ca2-732604ff41fe') = #{Issue.parse_key('bb4cbbbc-b7c7-11e0-9ca2-732604ff41fe').class}"
|
6
|
+
assert_kind_of(
|
7
|
+
CassandraObject::Identity::UUIDKeyFactory::UUID,
|
8
|
+
Issue.parse_key('bb4cbbbc-b7c7-11e0-9ca2-732604ff41fe')
|
9
|
+
)
|
10
|
+
|
11
|
+
assert_nil Issue.parse_key('fail')
|
12
|
+
end
|
13
|
+
|
4
14
|
test 'equality of new records' do
|
5
15
|
assert_not_equal Issue.new, Issue.new
|
6
16
|
end
|
data/test/persistence_test.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
3
|
class CassandraObject::PersistenceTest < CassandraObject::TestCase
|
4
|
-
test '
|
4
|
+
test 'persistance inquiries' do
|
5
5
|
issue = Issue.new
|
6
6
|
assert issue.new_record?
|
7
7
|
assert !issue.persisted?
|
@@ -9,9 +9,76 @@ class CassandraObject::PersistenceTest < CassandraObject::TestCase
|
|
9
9
|
issue.save
|
10
10
|
assert issue.persisted?
|
11
11
|
assert !issue.new_record?
|
12
|
+
end
|
13
|
+
|
14
|
+
test 'save' do
|
15
|
+
issue = Issue.new
|
16
|
+
issue.save
|
17
|
+
|
18
|
+
assert_equal issue, Issue.find(issue.id)
|
19
|
+
end
|
12
20
|
|
21
|
+
test 'save!' do
|
22
|
+
begin
|
23
|
+
Issue.validates(:description, presence: true)
|
24
|
+
|
25
|
+
issue = Issue.new(description: 'bad')
|
26
|
+
issue.save!
|
27
|
+
|
28
|
+
issue = Issue.new
|
29
|
+
assert_raise(CassandraObject::RecordInvalid) { issue.save! }
|
30
|
+
ensure
|
31
|
+
Issue.reset_callbacks(:validate)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
test 'destroy' do
|
36
|
+
issue = Issue.create
|
13
37
|
issue.destroy
|
38
|
+
|
14
39
|
assert issue.destroyed?
|
15
40
|
assert !issue.persisted?
|
41
|
+
assert !issue.new_record?
|
42
|
+
end
|
43
|
+
|
44
|
+
test 'update_attribute' do
|
45
|
+
issue = Issue.create
|
46
|
+
issue.update_attribute(:description, 'lol')
|
47
|
+
|
48
|
+
assert !issue.changed?
|
49
|
+
assert_equal 'lol', issue.description
|
50
|
+
end
|
51
|
+
|
52
|
+
test 'update_attributes' do
|
53
|
+
issue = Issue.create
|
54
|
+
issue.update_attributes(description: 'lol')
|
55
|
+
|
56
|
+
assert !issue.changed?
|
57
|
+
assert_equal 'lol', issue.description
|
58
|
+
end
|
59
|
+
|
60
|
+
test 'update_attributes!' do
|
61
|
+
begin
|
62
|
+
Issue.validates(:description, presence: true)
|
63
|
+
|
64
|
+
issue = Issue.new(description: 'bad')
|
65
|
+
issue.save!
|
66
|
+
|
67
|
+
assert_raise CassandraObject::RecordInvalid do
|
68
|
+
issue.update_attributes! description: ''
|
69
|
+
end
|
70
|
+
ensure
|
71
|
+
Issue.reset_callbacks(:validate)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
test 'reload' do
|
76
|
+
persisted_issue = Issue.create
|
77
|
+
fresh_issue = Issue.find(persisted_issue.id)
|
78
|
+
fresh_issue.update_attribute(:description, 'say what')
|
79
|
+
|
80
|
+
assert_nil persisted_issue.description
|
81
|
+
persisted_issue.reload
|
82
|
+
assert_equal 'say what', persisted_issue.description
|
16
83
|
end
|
17
84
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gotime-cassandra_object
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -14,7 +14,7 @@ date: 2011-07-26 00:00:00.000000000Z
|
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rails
|
17
|
-
requirement: &
|
17
|
+
requirement: &2152763200 !ruby/object:Gem::Requirement
|
18
18
|
none: false
|
19
19
|
requirements:
|
20
20
|
- - ~>
|
@@ -22,10 +22,10 @@ dependencies:
|
|
22
22
|
version: '3.0'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
|
-
version_requirements: *
|
25
|
+
version_requirements: *2152763200
|
26
26
|
- !ruby/object:Gem::Dependency
|
27
27
|
name: cassandra
|
28
|
-
requirement: &
|
28
|
+
requirement: &2152762740 !ruby/object:Gem::Requirement
|
29
29
|
none: false
|
30
30
|
requirements:
|
31
31
|
- - ~>
|
@@ -33,10 +33,10 @@ dependencies:
|
|
33
33
|
version: 0.11.3
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
|
-
version_requirements: *
|
36
|
+
version_requirements: *2152762740
|
37
37
|
- !ruby/object:Gem::Dependency
|
38
38
|
name: bundler
|
39
|
-
requirement: &
|
39
|
+
requirement: &2152762280 !ruby/object:Gem::Requirement
|
40
40
|
none: false
|
41
41
|
requirements:
|
42
42
|
- - ~>
|
@@ -44,7 +44,7 @@ dependencies:
|
|
44
44
|
version: 1.0.0
|
45
45
|
type: :development
|
46
46
|
prerelease: false
|
47
|
-
version_requirements: *
|
47
|
+
version_requirements: *2152762280
|
48
48
|
description: Cassandra ActiveModel
|
49
49
|
email: gems@gotime.com
|
50
50
|
executables: []
|
@@ -60,7 +60,6 @@ files:
|
|
60
60
|
- MIT-LICENSE
|
61
61
|
- README.markdown
|
62
62
|
- Rakefile
|
63
|
-
- TODO
|
64
63
|
- gotime-cassandra_object.gemspec
|
65
64
|
- lib/cassandra_object.rb
|
66
65
|
- lib/cassandra_object/associations.rb
|
@@ -75,6 +74,7 @@ files:
|
|
75
74
|
- lib/cassandra_object/consistency.rb
|
76
75
|
- lib/cassandra_object/cursor.rb
|
77
76
|
- lib/cassandra_object/dirty.rb
|
77
|
+
- lib/cassandra_object/errors.rb
|
78
78
|
- lib/cassandra_object/finder_methods.rb
|
79
79
|
- lib/cassandra_object/generators/migration_generator.rb
|
80
80
|
- lib/cassandra_object/generators/templates/migration.rb.erb
|
@@ -91,6 +91,7 @@ files:
|
|
91
91
|
- lib/cassandra_object/migrations/migration.rb
|
92
92
|
- lib/cassandra_object/mocking.rb
|
93
93
|
- lib/cassandra_object/persistence.rb
|
94
|
+
- lib/cassandra_object/primary_key.rb
|
94
95
|
- lib/cassandra_object/railtie.rb
|
95
96
|
- lib/cassandra_object/schema.rb
|
96
97
|
- lib/cassandra_object/schema/migration.rb
|
@@ -143,6 +144,7 @@ files:
|
|
143
144
|
- test/finder_methods_test.rb
|
144
145
|
- test/identity_test.rb
|
145
146
|
- test/persistence_test.rb
|
147
|
+
- test/primary_key_test.rb
|
146
148
|
- test/test_helper.rb
|
147
149
|
- test/timestamps_test.rb
|
148
150
|
- test/types/array_type_test.rb
|
@@ -186,6 +188,7 @@ test_files:
|
|
186
188
|
- test/finder_methods_test.rb
|
187
189
|
- test/identity_test.rb
|
188
190
|
- test/persistence_test.rb
|
191
|
+
- test/primary_key_test.rb
|
189
192
|
- test/test_helper.rb
|
190
193
|
- test/timestamps_test.rb
|
191
194
|
- test/types/array_type_test.rb
|