gotime-cassandra_object 2.8.3 → 2.8.4
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.
- data/Gemfile +4 -0
- data/Rakefile +0 -1
- data/gotime-cassandra_object.gemspec +1 -1
- data/lib/cassandra_object/attribute_methods.rb +3 -41
- data/lib/cassandra_object/attribute_methods/typecasting.rb +52 -0
- data/lib/cassandra_object/base.rb +2 -1
- data/lib/cassandra_object/batches.rb +1 -1
- data/lib/cassandra_object/finder_methods.rb +1 -1
- data/lib/cassandra_object/persistence.rb +8 -7
- data/lib/gotime-cassandra_object.rb +1 -0
- data/test/attribute_methods/definition_test.rb +1 -1
- data/test/attribute_methods/typecasting_test.rb +87 -0
- data/test/attribute_methods_test.rb +17 -51
- data/test/batches_test.rb +2 -2
- data/test/test_helper.rb +2 -4
- metadata +10 -8
data/Gemfile
CHANGED
data/Rakefile
CHANGED
@@ -4,51 +4,13 @@ module CassandraObject
|
|
4
4
|
include ActiveModel::AttributeMethods
|
5
5
|
|
6
6
|
included do
|
7
|
-
|
8
|
-
|
7
|
+
alias :[] :read_attribute
|
8
|
+
alias :[]= :write_attribute
|
9
9
|
|
10
10
|
attribute_method_suffix("", "=")
|
11
|
-
|
12
|
-
%w(array boolean date float integer json string time time_with_zone).each do |type|
|
13
|
-
instance_eval <<-EOV, __FILE__, __LINE__ + 1
|
14
|
-
def #{type}(name, options = {}) # def string(name, options = {})
|
15
|
-
attribute(name, options.update(type: :#{type})) # attribute(name, options.update(type: :string))
|
16
|
-
end # end
|
17
|
-
EOV
|
18
|
-
end
|
19
11
|
end
|
20
12
|
|
21
13
|
module ClassMethods
|
22
|
-
def inherited(child)
|
23
|
-
super
|
24
|
-
child.attribute_definitions = attribute_definitions.dup
|
25
|
-
end
|
26
|
-
|
27
|
-
#
|
28
|
-
# attribute :name, type: :string
|
29
|
-
# attribute :ammo, type: Ammo, coder: AmmoCodec
|
30
|
-
#
|
31
|
-
def attribute(name, options)
|
32
|
-
type = options.delete :type
|
33
|
-
coder = options.delete :coder
|
34
|
-
|
35
|
-
if type.is_a?(Symbol)
|
36
|
-
coder = CassandraObject::Type.get_coder(type) || (raise "Unknown type #{type}")
|
37
|
-
elsif coder.nil?
|
38
|
-
raise "Must supply a :coder for #{name}"
|
39
|
-
end
|
40
|
-
|
41
|
-
attribute_definitions[name.to_sym] = AttributeMethods::Definition.new(name, coder, options)
|
42
|
-
end
|
43
|
-
|
44
|
-
def instantiate_attribute(record, name, value)
|
45
|
-
if attribute_definition = attribute_definitions[name.to_sym]
|
46
|
-
attribute_definition.instantiate(record, value)
|
47
|
-
else
|
48
|
-
raise NoMethodError, "Unknown attribute #{name.inspect}"
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
14
|
def define_attribute_methods
|
53
15
|
return if attribute_methods_generated?
|
54
16
|
super(attribute_definitions.keys)
|
@@ -61,7 +23,7 @@ module CassandraObject
|
|
61
23
|
end
|
62
24
|
|
63
25
|
def write_attribute(name, value)
|
64
|
-
@attributes[name.to_s] = self.class.
|
26
|
+
@attributes[name.to_s] = self.class.typecast_attribute(self, name, value)
|
65
27
|
end
|
66
28
|
|
67
29
|
def read_attribute(name)
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module CassandraObject
|
2
|
+
module AttributeMethods
|
3
|
+
module Typecasting
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
class_attribute :attribute_definitions
|
8
|
+
self.attribute_definitions = {}
|
9
|
+
|
10
|
+
%w(array boolean date float integer json string time time_with_zone).each do |type|
|
11
|
+
instance_eval <<-EOV, __FILE__, __LINE__ + 1
|
12
|
+
def #{type}(name, options = {}) # def string(name, options = {})
|
13
|
+
attribute(name, options.update(type: :#{type})) # attribute(name, options.update(type: :string))
|
14
|
+
end # end
|
15
|
+
EOV
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
module ClassMethods
|
20
|
+
def inherited(child)
|
21
|
+
super
|
22
|
+
child.attribute_definitions = attribute_definitions.dup
|
23
|
+
end
|
24
|
+
|
25
|
+
#
|
26
|
+
# attribute :name, type: :string
|
27
|
+
# attribute :ammo, type: Ammo, coder: AmmoCodec
|
28
|
+
#
|
29
|
+
def attribute(name, options)
|
30
|
+
type = options.delete :type
|
31
|
+
coder = options.delete :coder
|
32
|
+
|
33
|
+
if type.is_a?(Symbol)
|
34
|
+
coder = CassandraObject::Type.get_coder(type) || (raise "Unknown type #{type}")
|
35
|
+
elsif coder.nil?
|
36
|
+
raise "Must supply a :coder for #{name}"
|
37
|
+
end
|
38
|
+
|
39
|
+
attribute_definitions[name.to_sym] = AttributeMethods::Definition.new(name, coder, options)
|
40
|
+
end
|
41
|
+
|
42
|
+
def typecast_attribute(record, name, value)
|
43
|
+
if attribute_definition = attribute_definitions[name.to_sym]
|
44
|
+
attribute_definition.instantiate(record, value)
|
45
|
+
else
|
46
|
+
raise NoMethodError, "Unknown attribute #{name.inspect}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -36,6 +36,7 @@ module CassandraObject
|
|
36
36
|
include Batches
|
37
37
|
include AttributeMethods
|
38
38
|
include AttributeMethods::Dirty
|
39
|
+
include AttributeMethods::Typecasting
|
39
40
|
include Callbacks
|
40
41
|
include Validations
|
41
42
|
include Associations
|
@@ -56,7 +57,7 @@ module CassandraObject
|
|
56
57
|
self.attributes = attributes
|
57
58
|
attribute_definitions.each do |attr, attribute_definition|
|
58
59
|
unless attribute_exists?(attr)
|
59
|
-
self.attributes[attr.to_s] = self.class.
|
60
|
+
self.attributes[attr.to_s] = self.class.typecast_attribute(self, attr, nil)
|
60
61
|
end
|
61
62
|
end
|
62
63
|
|
@@ -24,7 +24,7 @@ module CassandraObject
|
|
24
24
|
def all(options = {})
|
25
25
|
limit = options[:limit] || 100
|
26
26
|
results = ActiveSupport::Notifications.instrument("get_range.cassandra_object", column_family: column_family, key_count: limit) do
|
27
|
-
connection.get_range(column_family, key_count: limit, consistency: thrift_read_consistency)
|
27
|
+
connection.get_range(column_family, key_count: limit, consistency: thrift_read_consistency, count: 500)
|
28
28
|
end
|
29
29
|
|
30
30
|
results.map do |k, v|
|
@@ -22,11 +22,12 @@ module CassandraObject
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def write(key, attributes, schema_version)
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
25
|
+
attributes = encode_attributes(attributes, schema_version)
|
26
|
+
ActiveSupport::Notifications.instrument("insert.cassandra_object", column_family: column_family, key: key, attributes: attributes) do
|
27
|
+
connection.insert(column_family, key.to_s, attributes, consistency: thrift_write_consistency)
|
28
|
+
# if nil_attributes.any?
|
29
|
+
# connection.remove(connection, key.to_s, *nil_attributes)
|
30
|
+
# end
|
30
31
|
end
|
31
32
|
end
|
32
33
|
|
@@ -36,7 +37,7 @@ module CassandraObject
|
|
36
37
|
object.instance_variable_set("@key", parse_key(key)) if key
|
37
38
|
object.instance_variable_set("@new_record", false)
|
38
39
|
object.instance_variable_set("@destroyed", false)
|
39
|
-
object.instance_variable_set("@attributes",
|
40
|
+
object.instance_variable_set("@attributes", typecast_attributes(object, attributes))
|
40
41
|
end
|
41
42
|
end
|
42
43
|
|
@@ -51,7 +52,7 @@ module CassandraObject
|
|
51
52
|
encoded
|
52
53
|
end
|
53
54
|
|
54
|
-
def
|
55
|
+
def typecast_attributes(object, attributes)
|
55
56
|
attributes = attributes.symbolize_keys
|
56
57
|
Hash[attribute_definitions.map { |k, attribute_definition| [k.to_s, attribute_definition.instantiate(object, attributes[k])] }]
|
57
58
|
end
|
@@ -4,7 +4,7 @@ class CassandraObject::AttributeMethods::DefinitionTest < CassandraObject::TestC
|
|
4
4
|
class TestType < CassandraObject::Types::BaseType
|
5
5
|
end
|
6
6
|
|
7
|
-
test '
|
7
|
+
test 'typecast' do
|
8
8
|
definition = CassandraObject::AttributeMethods::Definition.new(:foo, TestType, {a: :b})
|
9
9
|
|
10
10
|
assert_equal 'foo', definition.name
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class CassandraObject::AttributeMethods::TypecastingTest < CassandraObject::TestCase
|
4
|
+
class CustomType
|
5
|
+
end
|
6
|
+
|
7
|
+
class CustomCoder < CassandraObject::Types::BaseType
|
8
|
+
end
|
9
|
+
|
10
|
+
class TestIssue < CassandraObject::Base
|
11
|
+
key :uuid
|
12
|
+
self.column_family = 'Issues'
|
13
|
+
|
14
|
+
attribute :custom_column, type: CustomType, coder: CustomCoder
|
15
|
+
boolean :enabled
|
16
|
+
float :rating
|
17
|
+
integer :price
|
18
|
+
json :orders
|
19
|
+
string :name
|
20
|
+
end
|
21
|
+
|
22
|
+
class TestChildIssue < TestIssue
|
23
|
+
string :description
|
24
|
+
end
|
25
|
+
|
26
|
+
test 'attributes not shared' do
|
27
|
+
assert_nothing_raised { Issue.new.description }
|
28
|
+
assert_raise(NoMethodError) { TestIssue.new.description }
|
29
|
+
assert_nothing_raised { TestChildIssue.new.description }
|
30
|
+
end
|
31
|
+
|
32
|
+
test 'custom attribute definer' do
|
33
|
+
model_attribute = TestIssue.attribute_definitions[:custom_column]
|
34
|
+
|
35
|
+
assert_kind_of CustomCoder, model_attribute.coder
|
36
|
+
assert_equal 'custom_column', model_attribute.name
|
37
|
+
end
|
38
|
+
|
39
|
+
test 'typecast_attribute' do
|
40
|
+
assert_equal 1, TestIssue.typecast_attribute(TestIssue.new, 'price', 1)
|
41
|
+
assert_equal 1, TestIssue.typecast_attribute(TestIssue.new, :price, 1)
|
42
|
+
|
43
|
+
assert_raise NoMethodError do
|
44
|
+
TestIssue.typecast_attribute(TestIssue.new, 'wtf', 1)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
test 'boolean attribute' do
|
49
|
+
issue = TestIssue.create! enabled: '1'
|
50
|
+
assert_equal true, issue.enabled
|
51
|
+
|
52
|
+
issue = TestIssue.find issue.id
|
53
|
+
assert_equal true, issue.enabled
|
54
|
+
end
|
55
|
+
|
56
|
+
test 'float attribute' do
|
57
|
+
issue = TestIssue.create! rating: '4.5'
|
58
|
+
assert_equal 4.5, issue.rating
|
59
|
+
|
60
|
+
issue = TestIssue.find issue.id
|
61
|
+
assert_equal(4.5, issue.rating)
|
62
|
+
end
|
63
|
+
|
64
|
+
test 'integer attribute' do
|
65
|
+
issue = TestIssue.create! price: '101'
|
66
|
+
assert_equal 101, issue.price
|
67
|
+
|
68
|
+
issue = TestIssue.find issue.id
|
69
|
+
assert_equal(101, issue.price)
|
70
|
+
end
|
71
|
+
|
72
|
+
test 'json attribute' do
|
73
|
+
issue = TestIssue.create! orders: {'a' => 'b'}
|
74
|
+
assert_equal({'a' => 'b'}, issue.orders)
|
75
|
+
|
76
|
+
issue = TestIssue.find issue.id
|
77
|
+
assert_equal({'a' => 'b'}, issue.orders)
|
78
|
+
end
|
79
|
+
|
80
|
+
test 'string attribute' do
|
81
|
+
issue = TestIssue.create! name: 'hola'
|
82
|
+
assert_equal('hola', issue.name)
|
83
|
+
|
84
|
+
issue = TestIssue.find issue.id
|
85
|
+
assert_equal('hola', issue.name)
|
86
|
+
end
|
87
|
+
end
|
@@ -1,54 +1,31 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
3
|
class CassandraObject::AttributeMethodsTest < CassandraObject::TestCase
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
class CustomCoder < CassandraObject::Types::BaseType
|
8
|
-
end
|
9
|
-
|
10
|
-
class TestIssue < CassandraObject::Base
|
11
|
-
key :uuid
|
12
|
-
self.column_family = 'Issues'
|
13
|
-
|
14
|
-
attribute :custom_column, type: CustomType, coder: CustomCoder
|
15
|
-
integer :price
|
16
|
-
json :orders
|
17
|
-
end
|
18
|
-
|
19
|
-
class TestChildIssue < TestIssue
|
20
|
-
string :description
|
21
|
-
end
|
4
|
+
test 'read and write attributes' do
|
5
|
+
issue = Issue.new
|
6
|
+
assert_nil issue.read_attribute(:description)
|
22
7
|
|
23
|
-
|
24
|
-
|
8
|
+
issue.write_attribute(:description, nil)
|
9
|
+
assert_nil issue.read_attribute(:description)
|
25
10
|
|
26
|
-
|
27
|
-
assert_equal '
|
11
|
+
issue.write_attribute(:description, 'foo')
|
12
|
+
assert_equal 'foo', issue.read_attribute(:description)
|
28
13
|
end
|
29
14
|
|
30
|
-
test '
|
31
|
-
issue =
|
32
|
-
|
33
|
-
issue = TestIssue.find issue.id
|
34
|
-
|
35
|
-
assert_equal({'a' => 'b'}, issue.orders)
|
36
|
-
end
|
15
|
+
test 'hash accessor aliases' do
|
16
|
+
issue = Issue.new
|
37
17
|
|
38
|
-
|
39
|
-
assert_equal 1, TestIssue.instantiate_attribute(TestIssue.new, 'price', 1)
|
40
|
-
assert_equal 1, TestIssue.instantiate_attribute(TestIssue.new, :price, 1)
|
18
|
+
issue[:description] = 'bar'
|
41
19
|
|
42
|
-
|
43
|
-
TestIssue.instantiate_attribute(TestIssue.new, 'wtf', 1)
|
44
|
-
end
|
20
|
+
assert_equal 'bar', issue[:description]
|
45
21
|
end
|
46
22
|
|
47
|
-
test '
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
23
|
+
# test 'attribute_exists' do
|
24
|
+
# assert !Issue.new.attribute_exists?(:description)
|
25
|
+
# assert Issue.new(description: nil).attribute_exists?(:description)
|
26
|
+
# assert Issue.new(description: false).attribute_exists?(:description)
|
27
|
+
# assert Issue.new(description: 'hey').attribute_exists?(:description)
|
28
|
+
# end
|
52
29
|
|
53
30
|
test 'attributes setter' do
|
54
31
|
issue = Issue.new
|
@@ -59,15 +36,4 @@ class CassandraObject::AttributeMethodsTest < CassandraObject::TestCase
|
|
59
36
|
|
60
37
|
assert_equal 'foo', issue.description
|
61
38
|
end
|
62
|
-
|
63
|
-
test 'read and write attributes' do
|
64
|
-
issue = Issue.new
|
65
|
-
assert_nil issue.read_attribute(:description)
|
66
|
-
|
67
|
-
issue.write_attribute(:description, nil)
|
68
|
-
assert_nil issue.read_attribute(:description)
|
69
|
-
|
70
|
-
issue.write_attribute(:description, 'foo')
|
71
|
-
assert_equal 'foo', issue.read_attribute(:description)
|
72
|
-
end
|
73
39
|
end
|
data/test/batches_test.rb
CHANGED
@@ -17,12 +17,12 @@ class CassandraObject::BatchesTest < CassandraObject::TestCase
|
|
17
17
|
Issue.create
|
18
18
|
Issue.create
|
19
19
|
Issue.create
|
20
|
-
|
20
|
+
|
21
21
|
issue_batches = []
|
22
22
|
Issue.find_in_batches(batch_size: 2) do |issues|
|
23
23
|
issue_batches << issues
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
assert_equal 2, issue_batches.size
|
27
27
|
assert issue_batches.any? { |issues| issues.size == 2 }
|
28
28
|
assert issue_batches.any? { |issues| issues.size == 1 }
|
data/test/test_helper.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
|
-
require 'rubygems'
|
2
1
|
require 'bundler/setup'
|
3
|
-
require '
|
4
|
-
require
|
5
|
-
require 'gotime-cassandra_object'
|
2
|
+
require 'minitest/autorun'
|
3
|
+
Bundler.require(:default, :test)
|
6
4
|
|
7
5
|
CassandraObject::Base.establish_connection(
|
8
6
|
keyspace: 'place_directory_development',
|
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.8.
|
4
|
+
version: 2.8.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,11 +10,11 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2011-11-
|
13
|
+
date: 2011-11-19 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activemodel
|
17
|
-
requirement: &
|
17
|
+
requirement: &70143745006900 !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: *70143745006900
|
26
26
|
- !ruby/object:Gem::Dependency
|
27
27
|
name: cassandra
|
28
|
-
requirement: &
|
28
|
+
requirement: &70143745002740 !ruby/object:Gem::Requirement
|
29
29
|
none: false
|
30
30
|
requirements:
|
31
31
|
- - ~>
|
@@ -33,10 +33,10 @@ dependencies:
|
|
33
33
|
version: 0.12.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
|
-
version_requirements: *
|
36
|
+
version_requirements: *70143745002740
|
37
37
|
- !ruby/object:Gem::Dependency
|
38
38
|
name: bundler
|
39
|
-
requirement: &
|
39
|
+
requirement: &70143744999540 !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: *70143744999540
|
48
48
|
description: Cassandra ActiveModel
|
49
49
|
email: gems@gotime.com
|
50
50
|
executables: []
|
@@ -66,6 +66,7 @@ files:
|
|
66
66
|
- lib/cassandra_object/attribute_methods.rb
|
67
67
|
- lib/cassandra_object/attribute_methods/definition.rb
|
68
68
|
- lib/cassandra_object/attribute_methods/dirty.rb
|
69
|
+
- lib/cassandra_object/attribute_methods/typecasting.rb
|
69
70
|
- lib/cassandra_object/base.rb
|
70
71
|
- lib/cassandra_object/batches.rb
|
71
72
|
- lib/cassandra_object/callbacks.rb
|
@@ -115,6 +116,7 @@ files:
|
|
115
116
|
- test/active_model_test.rb
|
116
117
|
- test/attribute_methods/definition_test.rb
|
117
118
|
- test/attribute_methods/dirty_test.rb
|
119
|
+
- test/attribute_methods/typecasting_test.rb
|
118
120
|
- test/attribute_methods_test.rb
|
119
121
|
- test/base_test.rb
|
120
122
|
- test/batches_test.rb
|