gotime-cassandra_object 4.5.1 → 4.6.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.
- data/.travis.yml +2 -0
- data/Gemfile +5 -1
- data/README.rdoc +0 -2
- data/gotime-cassandra_object.gemspec +1 -1
- data/lib/cassandra_object/attribute_methods.rb +4 -4
- data/lib/cassandra_object/attribute_methods/dirty.rb +1 -1
- data/lib/cassandra_object/attribute_methods/primary_key.rb +1 -1
- data/lib/cassandra_object/attribute_methods/typecasting.rb +9 -6
- data/lib/cassandra_object/base.rb +11 -43
- data/lib/cassandra_object/belongs_to.rb +1 -1
- data/lib/cassandra_object/belongs_to/association.rb +1 -1
- data/lib/cassandra_object/belongs_to/reflection.rb +2 -2
- data/lib/cassandra_object/config.rb +15 -0
- data/lib/cassandra_object/connection.rb +1 -19
- data/lib/cassandra_object/consistency.rb +1 -1
- data/lib/cassandra_object/core.rb +46 -0
- data/lib/cassandra_object/errors.rb +2 -2
- data/lib/cassandra_object/identity.rb +1 -1
- data/lib/cassandra_object/persistence.rb +21 -7
- data/lib/cassandra_object/railtie.rb +1 -1
- data/lib/cassandra_object/savepoints.rb +1 -1
- data/lib/cassandra_object/schema.rb +30 -15
- data/lib/cassandra_object/schema/tasks.rb +8 -4
- data/lib/cassandra_object/scope.rb +1 -1
- data/lib/cassandra_object/scope/batches.rb +1 -1
- data/lib/cassandra_object/scope/finder_methods.rb +1 -1
- data/lib/cassandra_object/scope/query_methods.rb +1 -1
- data/lib/cassandra_object/tasks/ks.rake +6 -6
- data/lib/cassandra_object/types/array_type.rb +1 -1
- data/lib/cassandra_object/types/base_type.rb +1 -1
- data/lib/cassandra_object/types/boolean_type.rb +2 -2
- data/lib/cassandra_object/types/float_type.rb +1 -1
- data/lib/cassandra_object/types/integer_type.rb +1 -1
- data/lib/cassandra_object/types/json_type.rb +1 -1
- data/lib/cassandra_object/types/string_type.rb +1 -1
- data/lib/cassandra_object/types/time_type.rb +1 -1
- data/lib/cassandra_object/validations.rb +3 -3
- data/lib/gotime-cassandra_object.rb +10 -8
- data/test/support/connect.rb +3 -3
- data/test/support/issue.rb +1 -1
- data/test/test_helper.rb +1 -1
- data/test/unit/active_model_test.rb +6 -1
- data/test/unit/attribute_methods/definition_test.rb +1 -1
- data/test/unit/attribute_methods/dirty_test.rb +2 -2
- data/test/unit/attribute_methods/primary_key_test.rb +1 -1
- data/test/unit/attribute_methods/typecasting_test.rb +28 -2
- data/test/unit/base_test.rb +1 -43
- data/test/unit/belongs_to/reflection_test.rb +12 -0
- data/test/unit/belongs_to_test.rb +1 -1
- data/test/unit/callbacks_test.rb +1 -1
- data/test/unit/config_test.rb +23 -0
- data/test/unit/connection_test.rb +0 -20
- data/test/unit/consistency_test.rb +1 -1
- data/test/unit/core_test.rb +50 -0
- data/test/unit/identity_test.rb +1 -1
- data/test/unit/inspect_test.rb +1 -1
- data/test/unit/persistence_test.rb +36 -7
- data/test/unit/savepoints_test.rb +7 -7
- data/test/unit/schema_test.rb +1 -1
- data/test/unit/scope/batches_test.rb +4 -4
- data/test/unit/scope/finder_methods_test.rb +3 -3
- data/test/unit/scope/query_methods_test.rb +1 -1
- data/test/unit/scoping_test.rb +1 -1
- data/test/unit/timestamps_test.rb +1 -1
- data/test/unit/types/array_type_test.rb +3 -3
- data/test/unit/types/base_type_test.rb +1 -1
- data/test/unit/types/float_type_test.rb +2 -2
- data/test/unit/types/integer_type_test.rb +1 -1
- data/test/unit/types/string_type_test.rb +1 -1
- data/test/unit/types/time_type_test.rb +1 -1
- data/test/unit/validations_test.rb +1 -1
- metadata +7 -2
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/README.rdoc
CHANGED
@@ -9,7 +9,7 @@ module CassandraObject
|
|
9
9
|
else
|
10
10
|
attribute_method_suffix("=")
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
# (Alias for the protected read_attribute method).
|
14
14
|
def [](attr_name)
|
15
15
|
read_attribute(attr_name)
|
@@ -26,11 +26,11 @@ module CassandraObject
|
|
26
26
|
def define_attribute_methods
|
27
27
|
return if attribute_methods_generated?
|
28
28
|
super(attribute_definitions.keys)
|
29
|
-
|
29
|
+
@@attribute_methods_generated = true
|
30
30
|
end
|
31
31
|
|
32
32
|
def attribute_methods_generated?
|
33
|
-
|
33
|
+
@@attribute_methods_generated ||= false
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
@@ -79,7 +79,7 @@ module CassandraObject
|
|
79
79
|
def attribute(name)
|
80
80
|
read_attribute(name)
|
81
81
|
end
|
82
|
-
|
82
|
+
|
83
83
|
def attribute=(name, value)
|
84
84
|
write_attribute(name, value)
|
85
85
|
end
|
@@ -9,9 +9,12 @@ module CassandraObject
|
|
9
9
|
|
10
10
|
%w(array boolean date float integer json string time).each do |type|
|
11
11
|
instance_eval <<-EOV, __FILE__, __LINE__ + 1
|
12
|
-
def #{type}(
|
13
|
-
|
14
|
-
|
12
|
+
def #{type}(*args)
|
13
|
+
options = args.extract_options!
|
14
|
+
args.each do |name|
|
15
|
+
attribute(name, options.merge(:type => :#{type}))
|
16
|
+
end
|
17
|
+
end
|
15
18
|
EOV
|
16
19
|
end
|
17
20
|
end
|
@@ -22,10 +25,10 @@ module CassandraObject
|
|
22
25
|
child.attribute_definitions = attribute_definitions.dup
|
23
26
|
end
|
24
27
|
|
25
|
-
#
|
28
|
+
#
|
26
29
|
# attribute :name, type: :string
|
27
30
|
# attribute :ammo, type: Ammo, coder: AmmoCodec
|
28
|
-
#
|
31
|
+
#
|
29
32
|
def attribute(name, options)
|
30
33
|
type = options[:type]
|
31
34
|
coder = options[:coder]
|
@@ -53,4 +56,4 @@ module CassandraObject
|
|
53
56
|
end
|
54
57
|
end
|
55
58
|
end
|
56
|
-
end
|
59
|
+
end
|
@@ -22,12 +22,20 @@ module CassandraObject
|
|
22
22
|
end
|
23
23
|
klass
|
24
24
|
end
|
25
|
+
|
26
|
+
def config=(config)
|
27
|
+
@@config = config.is_a?(Hash) ? CassandraObject::Config.new(config) : config
|
28
|
+
end
|
29
|
+
|
30
|
+
def config
|
31
|
+
@@config
|
32
|
+
end
|
25
33
|
end
|
26
34
|
|
27
35
|
extend ActiveModel::Naming
|
28
36
|
include ActiveModel::Conversion
|
29
37
|
extend ActiveSupport::DescendantsTracker
|
30
|
-
|
38
|
+
|
31
39
|
include Connection
|
32
40
|
include Consistency
|
33
41
|
include Identity
|
@@ -43,50 +51,10 @@ module CassandraObject
|
|
43
51
|
include Timestamps
|
44
52
|
include Savepoints
|
45
53
|
include Scoping
|
54
|
+
include Core
|
46
55
|
|
47
56
|
include Serialization
|
48
|
-
|
49
|
-
def initialize(attributes=nil)
|
50
|
-
@new_record = true
|
51
|
-
@destroyed = false
|
52
|
-
@attributes = {}
|
53
|
-
self.attributes = attributes || {}
|
54
|
-
attribute_definitions.each do |attr, attribute_definition|
|
55
|
-
unless attribute_exists?(attr)
|
56
|
-
@attributes[attr.to_s] = self.class.typecast_attribute(self, attr, nil)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def initialize_dup(other)
|
62
|
-
@attributes = other.attributes
|
63
|
-
@attributes['created_at'] = nil
|
64
|
-
@attributes['updated_at'] = nil
|
65
|
-
@attributes.delete(self.class.primary_key)
|
66
|
-
@id = nil
|
67
|
-
@new_record = true
|
68
|
-
@destroyed = false
|
69
|
-
super
|
70
|
-
end
|
71
|
-
|
72
|
-
def to_param
|
73
|
-
id
|
74
|
-
end
|
75
|
-
|
76
|
-
def hash
|
77
|
-
id.hash
|
78
|
-
end
|
79
|
-
|
80
|
-
def ==(comparison_object)
|
81
|
-
comparison_object.equal?(self) ||
|
82
|
-
(comparison_object.instance_of?(self.class) &&
|
83
|
-
comparison_object.id == id)
|
84
|
-
end
|
85
|
-
|
86
|
-
def eql?(comparison_object)
|
87
|
-
self == (comparison_object)
|
88
|
-
end
|
89
57
|
end
|
90
58
|
end
|
91
59
|
|
92
|
-
ActiveSupport.run_load_hooks(:cassandra_object, CassandraObject::Base)
|
60
|
+
ActiveSupport.run_load_hooks(:cassandra_object, CassandraObject::Base)
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'active_support/core_ext/hash/keys'
|
2
|
+
|
3
|
+
module CassandraObject
|
4
|
+
class Config
|
5
|
+
attr_accessor :servers, :keyspace, :thrift_options, :keyspace_options
|
6
|
+
|
7
|
+
def initialize(options)
|
8
|
+
options = options.symbolize_keys
|
9
|
+
self.servers = Array.wrap(options[:servers] || "127.0.0.1:9160")
|
10
|
+
self.keyspace = options[:keyspace]
|
11
|
+
self.thrift_options = (options[:thrift] || {}).symbolize_keys
|
12
|
+
self.keyspace_options = (options[:keyspace_options] || {}).symbolize_keys
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -16,30 +16,12 @@ module CassandraCQL
|
|
16
16
|
end
|
17
17
|
|
18
18
|
module CassandraObject
|
19
|
-
class Config
|
20
|
-
attr_accessor :servers, :keyspace, :thrift_options
|
21
|
-
|
22
|
-
def initialize(options)
|
23
|
-
self.servers = Array.wrap(options[:servers] || "127.0.0.1:9160")
|
24
|
-
self.keyspace = options[:keyspace]
|
25
|
-
self.thrift_options = (options[:thrift] || {}).symbolize_keys
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
19
|
module Connection
|
30
20
|
extend ActiveSupport::Concern
|
31
|
-
|
32
|
-
included do
|
33
|
-
class_attribute :connection_config
|
34
|
-
end
|
35
21
|
|
36
22
|
module ClassMethods
|
37
|
-
def establish_connection(spec)
|
38
|
-
self.connection_config = Config.new(spec)
|
39
|
-
end
|
40
|
-
|
41
23
|
def cql
|
42
|
-
@@cql ||= CassandraCQL::Database.new(
|
24
|
+
@@cql ||= CassandraCQL::Database.new(config.servers, {keyspace: config.keyspace}, config.thrift_options)
|
43
25
|
end
|
44
26
|
|
45
27
|
def execute_cql(cql_string, *bind_vars)
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module CassandraObject
|
2
|
+
module Core
|
3
|
+
def initialize(attributes=nil)
|
4
|
+
@new_record = true
|
5
|
+
@destroyed = false
|
6
|
+
@attributes = {}
|
7
|
+
self.attributes = attributes || {}
|
8
|
+
attribute_definitions.each do |attr, attribute_definition|
|
9
|
+
unless attribute_exists?(attr)
|
10
|
+
@attributes[attr.to_s] = self.class.typecast_attribute(self, attr, nil)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
yield self if block_given?
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize_dup(other)
|
18
|
+
@attributes = other.attributes
|
19
|
+
@attributes['created_at'] = nil
|
20
|
+
@attributes['updated_at'] = nil
|
21
|
+
@attributes.delete(self.class.primary_key)
|
22
|
+
@id = nil
|
23
|
+
@new_record = true
|
24
|
+
@destroyed = false
|
25
|
+
super
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_param
|
29
|
+
id
|
30
|
+
end
|
31
|
+
|
32
|
+
def hash
|
33
|
+
id.hash
|
34
|
+
end
|
35
|
+
|
36
|
+
def ==(comparison_object)
|
37
|
+
comparison_object.equal?(self) ||
|
38
|
+
(comparison_object.instance_of?(self.class) &&
|
39
|
+
comparison_object.id == id)
|
40
|
+
end
|
41
|
+
|
42
|
+
def eql?(comparison_object)
|
43
|
+
self == (comparison_object)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -11,8 +11,8 @@ module CassandraObject
|
|
11
11
|
execute_cql "TRUNCATE #{column_family}"
|
12
12
|
end
|
13
13
|
|
14
|
-
def create(attributes = {})
|
15
|
-
new(attributes).tap do |object|
|
14
|
+
def create(attributes = {}, &block)
|
15
|
+
new(attributes, &block).tap do |object|
|
16
16
|
object.save
|
17
17
|
end
|
18
18
|
end
|
@@ -20,12 +20,12 @@ module CassandraObject
|
|
20
20
|
def write(id, attributes)
|
21
21
|
if (encoded = encode_attributes(attributes)).any?
|
22
22
|
insert_attributes = {'KEY' => id}.update encode_attributes(attributes)
|
23
|
-
statement = "INSERT INTO #{column_family} (#{insert_attributes.keys * ','}) VALUES (#{Array.new(insert_attributes.size, '?') * ','})#{write_option_string}"
|
23
|
+
statement = "INSERT INTO #{column_family} (#{quote_columns(insert_attributes.keys) * ','}) VALUES (#{Array.new(insert_attributes.size, '?') * ','})#{write_option_string}"
|
24
24
|
execute_batchable_cql statement, *insert_attributes.values
|
25
25
|
end
|
26
26
|
|
27
27
|
if (nil_attributes = attributes.select { |key, value| value.nil? }).any?
|
28
|
-
execute_batchable_cql "DELETE #{nil_attributes.keys * ','} FROM #{column_family}#{write_option_string} WHERE KEY = ?", id
|
28
|
+
execute_batchable_cql "DELETE #{quote_columns(nil_attributes.keys) * ','} FROM #{column_family}#{write_option_string} WHERE KEY = ?", id
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
@@ -37,9 +37,9 @@ module CassandraObject
|
|
37
37
|
return nil unless @batch.any?
|
38
38
|
|
39
39
|
[
|
40
|
-
|
41
|
-
|
42
|
-
|
40
|
+
"BEGIN BATCH#{write_option_string(true)}",
|
41
|
+
@batch * "\n",
|
42
|
+
'APPLY BATCH'
|
43
43
|
] * "\n"
|
44
44
|
end
|
45
45
|
|
@@ -84,6 +84,11 @@ module CassandraObject
|
|
84
84
|
end
|
85
85
|
|
86
86
|
private
|
87
|
+
|
88
|
+
def quote_columns(column_names)
|
89
|
+
column_names.map { |name| "'#{name}'" }
|
90
|
+
end
|
91
|
+
|
87
92
|
def execute_batchable_cql(cql_string, *bind_vars)
|
88
93
|
if @batch
|
89
94
|
@batch << CassandraCQL::Statement.sanitize(cql_string, bind_vars)
|
@@ -142,8 +147,17 @@ module CassandraObject
|
|
142
147
|
save!
|
143
148
|
end
|
144
149
|
|
150
|
+
def becomes(klass)
|
151
|
+
became = klass.new
|
152
|
+
became.instance_variable_set("@attributes", @attributes)
|
153
|
+
became.instance_variable_set("@new_record", new_record?)
|
154
|
+
became.instance_variable_set("@destroyed", destroyed?)
|
155
|
+
became
|
156
|
+
end
|
157
|
+
|
145
158
|
def reload
|
146
159
|
@attributes.update(self.class.find(id).instance_variable_get('@attributes'))
|
160
|
+
self
|
147
161
|
end
|
148
162
|
|
149
163
|
private
|
@@ -5,10 +5,19 @@ module CassandraObject
|
|
5
5
|
extend Tasks
|
6
6
|
|
7
7
|
class << self
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
DEFAULT_CREATE_KEYSPACE = {
|
9
|
+
'strategy_class' => 'SimpleStrategy',
|
10
|
+
'strategy_options:replication_factor' => 1
|
11
|
+
}
|
12
|
+
|
13
|
+
def create_keyspace(keyspace, options = {})
|
14
|
+
stmt = "CREATE KEYSPACE #{keyspace}"
|
15
|
+
|
16
|
+
if options.empty?
|
17
|
+
options = DEFAULT_CREATE_KEYSPACE
|
18
|
+
end
|
19
|
+
|
20
|
+
system_execute statement_with_options(stmt, options)
|
12
21
|
end
|
13
22
|
|
14
23
|
def drop_keyspace(keyspace)
|
@@ -19,30 +28,36 @@ module CassandraObject
|
|
19
28
|
stmt = "CREATE COLUMNFAMILY #{column_family} " +
|
20
29
|
"(KEY varchar PRIMARY KEY)"
|
21
30
|
|
22
|
-
|
23
|
-
with_stmt = options.map do |k,v|
|
24
|
-
"#{k} = #{CassandraCQL::Statement.quote(v)}"
|
25
|
-
end.join(' AND ')
|
26
|
-
stmt << " WITH #{with_stmt}"
|
27
|
-
end
|
28
|
-
|
29
|
-
execute stmt
|
31
|
+
execute statement_with_options(stmt, options)
|
30
32
|
end
|
31
33
|
|
32
|
-
def
|
33
|
-
|
34
|
+
def alter_column_family(column_family, options)
|
35
|
+
stmt = "ALTER TABLE #{column_family}"
|
36
|
+
execute statement_with_options(stmt, options)
|
34
37
|
end
|
35
38
|
|
36
39
|
def add_index()
|
37
40
|
end
|
38
41
|
|
39
42
|
private
|
43
|
+
def statement_with_options(stmt, options)
|
44
|
+
if options.any?
|
45
|
+
with_stmt = options.map do |k,v|
|
46
|
+
"#{k} = #{CassandraCQL::Statement.quote(v)}"
|
47
|
+
end.join(' AND ')
|
48
|
+
|
49
|
+
stmt << " WITH #{with_stmt}"
|
50
|
+
end
|
51
|
+
|
52
|
+
stmt
|
53
|
+
end
|
54
|
+
|
40
55
|
def execute(cql)
|
41
56
|
CassandraObject::Base.execute_cql cql
|
42
57
|
end
|
43
58
|
|
44
59
|
def system_execute(cql)
|
45
|
-
@system_cql ||= CassandraCQL::Database.new(CassandraObject::Base.
|
60
|
+
@system_cql ||= CassandraCQL::Database.new(CassandraObject::Base.config.servers, keyspace: 'system')
|
46
61
|
@system_cql.execute cql
|
47
62
|
end
|
48
63
|
end
|