gotime-cassandra_object 4.11.6 → 4.12.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 +4 -4
- data/.travis.yml +5 -2
- data/gotime-cassandra_object.gemspec +1 -1
- data/lib/cassandra_object/adapters/abstract_adapter.rb +10 -8
- data/lib/cassandra_object/adapters/cassandra_adapter.rb +45 -62
- data/lib/cassandra_object/adapters/dynamo_adapter.rb +55 -2
- data/lib/cassandra_object/adapters/hstore_adapter.rb +143 -2
- data/lib/cassandra_object/callbacks.rb +1 -1
- data/lib/cassandra_object/connection.rb +1 -12
- data/lib/cassandra_object/counter_base.rb +12 -1
- data/lib/cassandra_object/persistence.rb +13 -8
- data/lib/cassandra_object/railtie.rb +19 -0
- data/lib/cassandra_object/schema/tasks.rb +1 -1
- data/lib/cassandra_object/scope.rb +7 -6
- data/lib/cassandra_object/scope/finder_methods.rb +2 -2
- data/lib/cassandra_object/scope/query_methods.rb +10 -5
- data/lib/cassandra_object/scoping.rb +1 -1
- data/test/support/issue.rb +1 -1
- data/test/unit/log_subscriber_test.rb +1 -1
- data/test/unit/schema/tasks_test.rb +2 -2
- data/test/unit/scope/query_methods_test.rb +2 -1
- 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: 84be31ff7407fc7ec88e53d411ddbd7ab067fb27
|
4
|
+
data.tar.gz: b364e2178974653ae11328b7c3b352d24d262a2a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3397a56b362a21c9a6a9e9480195fdc23334e4ff081f49ef19f84638239f3e562d2e6f81ccb9f1be7c04663f8ec53a298758b8dd44f84c79491d56732922d4b3
|
7
|
+
data.tar.gz: 123c09faf6d4e07fdd4354619dd8e49bfd97d6f58cf7684a950ffcdf5c474a8579d2ce35fb4abdb7c43d4d072ddfc6bfacf2ba6d62b5e0d7cb447f53830a3968
|
data/.travis.yml
CHANGED
@@ -2,7 +2,10 @@ language: ruby
|
|
2
2
|
rvm:
|
3
3
|
- 1.9.3
|
4
4
|
- 2.0.0
|
5
|
+
- 2.1.0
|
5
6
|
env: CQLSH=/usr/local/cassandra/bin/cqlsh
|
6
7
|
before_install:
|
7
|
-
-
|
8
|
-
-
|
8
|
+
- wget http://archive.apache.org/dist/cassandra/1.2.9/apache-cassandra-1.2.9-bin.tar.gz
|
9
|
+
- tar xfz apache-cassandra-1.2.9-bin.tar.gz
|
10
|
+
- sh -c "echo 'JVM_OPTS=\"\${JVM_OPTS} -Xss256k -Djava.net.preferIPv4Stack=false\"' >> apache-cassandra-1.2.9/conf/cassandra-env.sh"
|
11
|
+
- cd apache-cassandra-1.2.9 && sudo ./bin/cassandra 2>&1 >> cassandra.log &
|
@@ -6,18 +6,20 @@ module CassandraObject
|
|
6
6
|
@config = config
|
7
7
|
end
|
8
8
|
|
9
|
-
#
|
10
|
-
#
|
11
|
-
# Only select certain fields
|
12
|
-
# [:limit]
|
13
|
-
# Limit the results
|
14
|
-
def select(ids, options ={}) # abstract
|
9
|
+
# Read records from a instance of CassandraObject::Scope
|
10
|
+
def select(scope) # abstract
|
15
11
|
end
|
16
12
|
|
17
|
-
|
13
|
+
# Insert a new row
|
14
|
+
def insert(table, id, attributes) # abstract
|
18
15
|
end
|
19
16
|
|
20
|
-
|
17
|
+
# Update an existing row
|
18
|
+
def update(table, id, attributes) # abstract
|
19
|
+
end
|
20
|
+
|
21
|
+
# Delete rows by an array of ids
|
22
|
+
def delete(table, ids) # abstract
|
21
23
|
end
|
22
24
|
|
23
25
|
def execute_batch(statements) # abstract
|
@@ -1,28 +1,6 @@
|
|
1
1
|
module CassandraObject
|
2
2
|
module Adapters
|
3
3
|
class CassandraAdapter < AbstractAdapter
|
4
|
-
def cql
|
5
|
-
@cql ||= CassandraCQL::Database.new(config.servers, {keyspace: config.keyspace}, config.thrift_options)
|
6
|
-
end
|
7
|
-
|
8
|
-
def execute(statement)
|
9
|
-
ActiveSupport::Notifications.instrument("cql.cassandra_object", cql: statement) do
|
10
|
-
cql.execute statement
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
def select(statement)
|
15
|
-
execute(statement).fetch do |cql_row|
|
16
|
-
attributes = cql_row.to_hash
|
17
|
-
key = attributes.delete(primary_key_column)
|
18
|
-
yield(key, attributes) unless attributes.empty?
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def build_query(scope)
|
23
|
-
QueryBuilder.new(self, scope).to_query
|
24
|
-
end
|
25
|
-
|
26
4
|
class QueryBuilder
|
27
5
|
def initialize(adapter, scope)
|
28
6
|
@adapter = adapter
|
@@ -47,41 +25,13 @@ module CassandraObject
|
|
47
25
|
end
|
48
26
|
|
49
27
|
def where_string
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
@scope.where_values.map do |where_value|
|
54
|
-
wheres.concat format_where_statement(where_value)
|
55
|
-
end
|
56
|
-
|
57
|
-
"WHERE #{wheres * ' AND '}"
|
58
|
-
else
|
59
|
-
''
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
def format_where_statement(where_value)
|
64
|
-
if where_value.is_a?(String)
|
65
|
-
[where_value]
|
66
|
-
elsif where_value.is_a?(Hash)
|
67
|
-
where_value.map do |column, value|
|
68
|
-
if value.is_a?(Array)
|
69
|
-
"#{column} IN (#{escape_where_value(value)})"
|
70
|
-
else
|
71
|
-
"#{column} = #{escape_where_value(value)}"
|
72
|
-
end
|
73
|
-
end
|
28
|
+
wheres = @scope.where_values.dup
|
29
|
+
if @scope.id_values.any?
|
30
|
+
wheres << @adapter.create_ids_where_clause(@scope.id_values)
|
74
31
|
end
|
75
|
-
end
|
76
32
|
|
77
|
-
|
78
|
-
|
79
|
-
value.map { |v| escape_where_value(v) }.join(",")
|
80
|
-
elsif value.is_a?(String)
|
81
|
-
value = value.gsub("'", "''")
|
82
|
-
"'#{value}'"
|
83
|
-
else
|
84
|
-
value
|
33
|
+
if wheres.any?
|
34
|
+
"WHERE #{wheres * ' AND '}"
|
85
35
|
end
|
86
36
|
end
|
87
37
|
|
@@ -94,6 +44,38 @@ module CassandraObject
|
|
94
44
|
end
|
95
45
|
end
|
96
46
|
|
47
|
+
def primary_key_column
|
48
|
+
'KEY'
|
49
|
+
end
|
50
|
+
|
51
|
+
def connection
|
52
|
+
@connection ||= CassandraCQL::Database.new(config.servers, {keyspace: config.keyspace}, config.thrift_options)
|
53
|
+
end
|
54
|
+
|
55
|
+
def execute(statement)
|
56
|
+
ActiveSupport::Notifications.instrument("cql.cassandra_object", cql: statement) do
|
57
|
+
connection.execute statement
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def select(scope)
|
62
|
+
statement = QueryBuilder.new(self, scope).to_query
|
63
|
+
|
64
|
+
execute(statement).fetch do |cql_row|
|
65
|
+
attributes = cql_row.to_hash
|
66
|
+
key = attributes.delete(primary_key_column)
|
67
|
+
yield(key, attributes) unless attributes.empty?
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def insert(table, id, attributes)
|
72
|
+
write(table, id, attributes)
|
73
|
+
end
|
74
|
+
|
75
|
+
def update(table, id, attributes)
|
76
|
+
write(table, id, attributes)
|
77
|
+
end
|
78
|
+
|
97
79
|
def write(table, id, attributes)
|
98
80
|
if (not_nil_attributes = attributes.reject { |key, value| value.nil? }).any?
|
99
81
|
insert_attributes = {primary_key_column => id}.update(not_nil_attributes)
|
@@ -107,10 +89,9 @@ module CassandraObject
|
|
107
89
|
end
|
108
90
|
|
109
91
|
def delete(table, ids)
|
110
|
-
statement = "DELETE FROM #{table}#{write_option_string} WHERE "
|
111
|
-
statement += ids.is_a?(Array) ? "#{primary_key_column} IN (?)" : "#{primary_key_column} = ?"
|
92
|
+
statement = "DELETE FROM #{table}#{write_option_string} WHERE #{create_ids_where_clause(ids)}"
|
112
93
|
|
113
|
-
execute_batchable
|
94
|
+
execute_batchable statement
|
114
95
|
end
|
115
96
|
|
116
97
|
def execute_batch(statements)
|
@@ -133,16 +114,18 @@ module CassandraObject
|
|
133
114
|
@consistency = val
|
134
115
|
end
|
135
116
|
|
136
|
-
def primary_key_column
|
137
|
-
'KEY'
|
138
|
-
end
|
139
|
-
|
140
117
|
def write_option_string(ignore_batching = false)
|
141
118
|
if (ignore_batching || !batching?) && consistency
|
142
119
|
" USING CONSISTENCY #{consistency}"
|
143
120
|
end
|
144
121
|
end
|
145
122
|
|
123
|
+
def create_ids_where_clause(ids)
|
124
|
+
ids = ids.first if ids.is_a?(Array) && ids.one?
|
125
|
+
sql = ids.is_a?(Array) ? "#{primary_key_column} IN (?)" : "#{primary_key_column} = ?"
|
126
|
+
sanitize(sql, ids)
|
127
|
+
end
|
128
|
+
|
146
129
|
private
|
147
130
|
|
148
131
|
def sanitize(statement, *bind_vars)
|
@@ -1,6 +1,59 @@
|
|
1
1
|
module CassandraObject
|
2
|
-
module
|
3
|
-
class
|
2
|
+
module Adapters
|
3
|
+
class DynamoAdapter < AbstractAdapter
|
4
|
+
def primary_key_column
|
5
|
+
'id'
|
6
|
+
end
|
7
|
+
|
8
|
+
def connection
|
9
|
+
# self.namespace = spec[:namespace]
|
10
|
+
@connection ||= AWS::DynamoDB.new(
|
11
|
+
access_key_id: spec[:access_key_id],
|
12
|
+
secret_access_key: spec[:secret_access_key]
|
13
|
+
)
|
14
|
+
end
|
15
|
+
|
16
|
+
def select(scope)
|
17
|
+
dynamo_table.items[key_string].attributes.to_h
|
18
|
+
dynamo_table.batch_get(:all, keys.map(&:to_s))
|
19
|
+
end
|
20
|
+
|
21
|
+
def insert(table, id, attributes)
|
22
|
+
attributes = {primary_key => id}.update(attributes)
|
23
|
+
self.class.dynamo_table.items.create(attributes)
|
24
|
+
end
|
25
|
+
|
26
|
+
def update(table, id, attributes)
|
27
|
+
dynamo_db_item = self.class.dynamo_table.items[id]
|
28
|
+
|
29
|
+
dynamo_db_item.attributes.update do |u|
|
30
|
+
attributes.each do |attr, value|
|
31
|
+
if value.nil?
|
32
|
+
u.delete(attr)
|
33
|
+
else
|
34
|
+
u.set(attr => value)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def delete(table, ids)
|
41
|
+
ids.each do |id|
|
42
|
+
dynamo_table.items[id].delete
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def dynamo_table_name
|
47
|
+
"#{namespace}.#{column_family.underscore}"
|
48
|
+
end
|
49
|
+
|
50
|
+
def dynamo_table
|
51
|
+
@dynamo_table ||= begin
|
52
|
+
table = connection.tables[dynamo_table_name]
|
53
|
+
table.hash_key = [:id, :number]
|
54
|
+
table
|
55
|
+
end
|
56
|
+
end
|
4
57
|
end
|
5
58
|
end
|
6
59
|
end
|
@@ -1,6 +1,147 @@
|
|
1
1
|
module CassandraObject
|
2
|
-
module
|
3
|
-
class
|
2
|
+
module Adapters
|
3
|
+
class HstoreAdapter < AbstractAdapter
|
4
|
+
class QueryBuilder
|
5
|
+
def initialize(adapter, scope)
|
6
|
+
@adapter = adapter
|
7
|
+
@scope = scope
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_query
|
11
|
+
[
|
12
|
+
"SELECT #{select_string} FROM #{@scope.klass.column_family}",
|
13
|
+
where_string,
|
14
|
+
order_string,
|
15
|
+
limit_string,
|
16
|
+
].delete_if(&:blank?) * ' '
|
17
|
+
end
|
18
|
+
|
19
|
+
def select_string
|
20
|
+
if @scope.select_values.any?
|
21
|
+
"id, slice(attribute_store, #{@adapter.fields_to_postgres_array(@scope.select_values)}) as attribute_store"
|
22
|
+
else
|
23
|
+
'*'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def where_string
|
28
|
+
wheres = @scope.where_values.dup
|
29
|
+
if @scope.id_values.any?
|
30
|
+
wheres << @adapter.create_ids_where_clause(@scope.id_values)
|
31
|
+
end
|
32
|
+
|
33
|
+
if wheres.any?
|
34
|
+
"WHERE #{wheres * ' AND '}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def order_string
|
39
|
+
if @scope.id_values.many?
|
40
|
+
id_orders = @scope.id_values.map { |id| "ID=#{@adapter.quote(id)} DESC" }.join(',')
|
41
|
+
"ORDER BY #{id_orders}"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def limit_string
|
46
|
+
if @scope.limit_value
|
47
|
+
"LIMIT #{@scope.limit_value}"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def primary_key_column
|
53
|
+
'id'
|
54
|
+
end
|
55
|
+
|
56
|
+
def connection
|
57
|
+
conf = {:adapter=>"postgresql", :encoding=>"unicode", :database=>"axle_place_test", :pool=>5, :username=>"postgres"}
|
58
|
+
@connection ||= ActiveRecord::Base.postgresql_connection(conf)
|
59
|
+
# @connection ||= ActiveRecord::Base.postgresql_connection(config)
|
60
|
+
end
|
61
|
+
|
62
|
+
def execute(statement)
|
63
|
+
ActiveSupport::Notifications.instrument("cql.cassandra_object", cql: statement) do
|
64
|
+
connection.exec_query statement
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def select(scope)
|
69
|
+
statement = QueryBuilder.new(self, scope).to_query
|
70
|
+
|
71
|
+
connection.execute(statement).each do |attributes|
|
72
|
+
yield attributes[primary_key_column], hstore_to_attributes(attributes['attribute_store'])
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def insert(table, id, attributes)
|
77
|
+
not_nil_attributes = attributes.reject { |key, value| value.nil? }
|
78
|
+
statement = "INSERT INTO #{table} (#{primary_key_column}, attribute_store) VALUES (#{quote(id)}, #{attributes_to_hstore(not_nil_attributes)})"
|
79
|
+
execute_batchable statement
|
80
|
+
end
|
81
|
+
|
82
|
+
def update(table, id, attributes)
|
83
|
+
return if attributes.empty?
|
84
|
+
|
85
|
+
not_nil_attributes = attributes.reject { |key, value| value.nil? }
|
86
|
+
nil_attributes = attributes.select { |key, value| value.nil? }
|
87
|
+
|
88
|
+
if not_nil_attributes.any? && nil_attributes.any?
|
89
|
+
value_update = "(attribute_store - #{fields_to_postgres_array(nil_attributes.keys)}) || #{attributes_to_hstore(not_nil_attributes)}"
|
90
|
+
elsif not_nil_attributes.any?
|
91
|
+
value_update = "attribute_store || #{attributes_to_hstore(not_nil_attributes)}"
|
92
|
+
elsif nil_attributes.any?
|
93
|
+
value_update = "attribute_store - #{fields_to_postgres_array(nil_attributes.keys)}"
|
94
|
+
end
|
95
|
+
|
96
|
+
statement = "UPDATE #{table} SET attribute_store = #{value_update} WHERE #{primary_key_column} = #{quote(id)}"
|
97
|
+
execute_batchable statement
|
98
|
+
end
|
99
|
+
|
100
|
+
def delete(table, ids)
|
101
|
+
statement = "DELETE FROM #{table} WHERE #{create_ids_where_clause(ids)}"
|
102
|
+
|
103
|
+
execute_batchable statement
|
104
|
+
end
|
105
|
+
|
106
|
+
def execute_batch(statements)
|
107
|
+
stmt = [
|
108
|
+
"BEGIN",
|
109
|
+
statements * ";\n",
|
110
|
+
'COMMIT'
|
111
|
+
] * ";\n"
|
112
|
+
|
113
|
+
execute stmt
|
114
|
+
end
|
115
|
+
|
116
|
+
def create_ids_where_clause(ids)
|
117
|
+
ids = ids.first if ids.is_a?(Array) && ids.one?
|
118
|
+
|
119
|
+
if ids.is_a?(Array)
|
120
|
+
id_list = ids.map { |id| quote(id) }.join(',')
|
121
|
+
"#{primary_key_column} IN (#{id_list})"
|
122
|
+
else
|
123
|
+
"#{primary_key_column} = #{quote(ids)}"
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def quote(value)
|
128
|
+
connection.quote(value)
|
129
|
+
end
|
130
|
+
|
131
|
+
def fields_to_postgres_array(fields)
|
132
|
+
quoted_fields = fields.map { |field| "'#{field}'" }.join(',')
|
133
|
+
"ARRAY[#{quoted_fields}]"
|
134
|
+
end
|
135
|
+
|
136
|
+
private
|
137
|
+
|
138
|
+
def attributes_to_hstore(attributes)
|
139
|
+
quote ActiveRecord::ConnectionAdapters::PostgreSQLColumn.hstore_to_string(attributes)
|
140
|
+
end
|
141
|
+
|
142
|
+
def hstore_to_attributes(string)
|
143
|
+
ActiveRecord::ConnectionAdapters::PostgreSQLColumn.string_to_hstore(string)
|
144
|
+
end
|
4
145
|
end
|
5
146
|
end
|
6
147
|
end
|
@@ -20,20 +20,9 @@ module CassandraObject
|
|
20
20
|
extend ActiveSupport::Concern
|
21
21
|
|
22
22
|
module ClassMethods
|
23
|
-
def cql
|
24
|
-
@@cql ||= CassandraCQL::Database.new(config.servers, {keyspace: config.keyspace}, config.thrift_options)
|
25
|
-
end
|
26
|
-
|
27
23
|
def adapter
|
28
24
|
@@adapter ||= CassandraObject::Adapters::CassandraAdapter.new(config)
|
29
|
-
|
30
|
-
|
31
|
-
def execute_cql(cql_string, *bind_vars)
|
32
|
-
statement = CassandraCQL::Statement.sanitize(cql_string, bind_vars).force_encoding(Encoding::UTF_8)
|
33
|
-
|
34
|
-
ActiveSupport::Notifications.instrument("cql.cassandra_object", cql: statement) do
|
35
|
-
cql.execute statement
|
36
|
-
end
|
25
|
+
# @@adapter ||= CassandraObject::Adapters::HstoreAdapter.new(config)
|
37
26
|
end
|
38
27
|
end
|
39
28
|
end
|
@@ -30,6 +30,18 @@ module CassandraObject
|
|
30
30
|
execute_cql "UPDATE #{column_family} SET #{counter_updates(counter, count)} WHERE KEY = '#{group}'"
|
31
31
|
end
|
32
32
|
|
33
|
+
def cql
|
34
|
+
@@cql ||= CassandraCQL::Database.new(config.servers, {keyspace: config.keyspace}, config.thrift_options)
|
35
|
+
end
|
36
|
+
|
37
|
+
def execute_cql(cql_string, *bind_vars)
|
38
|
+
statement = CassandraCQL::Statement.sanitize(cql_string, bind_vars).force_encoding(Encoding::UTF_8)
|
39
|
+
|
40
|
+
ActiveSupport::Notifications.instrument("cql.cassandra_object", cql: statement) do
|
41
|
+
cql.execute statement
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
33
45
|
private
|
34
46
|
|
35
47
|
def counter_updates(counter, count=nil)
|
@@ -68,6 +80,5 @@ module CassandraObject
|
|
68
80
|
include Identity
|
69
81
|
include Inspect
|
70
82
|
extend Model
|
71
|
-
|
72
83
|
end
|
73
84
|
end
|
@@ -21,8 +21,12 @@ module CassandraObject
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
-
def
|
25
|
-
adapter.
|
24
|
+
def insert_record(id, attributes)
|
25
|
+
adapter.insert column_family, id, encode_attributes(attributes)
|
26
|
+
end
|
27
|
+
|
28
|
+
def update_record(id, attributes)
|
29
|
+
adapter.update column_family, id, encode_attributes(attributes)
|
26
30
|
end
|
27
31
|
|
28
32
|
def batching?
|
@@ -131,18 +135,19 @@ module CassandraObject
|
|
131
135
|
end
|
132
136
|
|
133
137
|
private
|
134
|
-
def update
|
135
|
-
write
|
136
|
-
end
|
137
138
|
|
138
139
|
def create
|
139
140
|
@new_record = false
|
140
|
-
write
|
141
|
+
write :insert_record
|
142
|
+
end
|
143
|
+
|
144
|
+
def update
|
145
|
+
write :update_record
|
141
146
|
end
|
142
147
|
|
143
|
-
def write
|
148
|
+
def write(method)
|
144
149
|
changed_attributes = Hash[changed.map { |attr| [attr, read_attribute(attr)] }]
|
145
|
-
self.class.
|
150
|
+
self.class.send(method, id, changed_attributes)
|
146
151
|
end
|
147
152
|
end
|
148
153
|
end
|
@@ -4,6 +4,25 @@ module CassandraObject
|
|
4
4
|
load 'cassandra_object/tasks/ks.rake'
|
5
5
|
end
|
6
6
|
|
7
|
+
initializer "cassandra_object.log_runtime" do |app|
|
8
|
+
ActiveSupport.on_load :cassandra_object do
|
9
|
+
pathname = Rails.root.join('config', 'cassandra.yml')
|
10
|
+
if pathname.exist?
|
11
|
+
config = YAML.load(pathname.read)
|
12
|
+
|
13
|
+
if config = config[Rails.env]
|
14
|
+
self.config = {
|
15
|
+
keyspace: config['keyspace'],
|
16
|
+
servers: config['servers'],
|
17
|
+
thrift: config['thrift']
|
18
|
+
}
|
19
|
+
else
|
20
|
+
raise "Missing environment #{Rails.env} in cassandra.yml"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
7
26
|
# Expose database runtime to controller for logging.
|
8
27
|
initializer "cassandra_object.log_runtime" do |app|
|
9
28
|
require "cassandra_object/railties/controller_runtime"
|
@@ -7,14 +7,15 @@ module CassandraObject
|
|
7
7
|
include Batches, FinderMethods, QueryMethods
|
8
8
|
|
9
9
|
attr_accessor :klass
|
10
|
-
attr_accessor :limit_value, :select_values, :where_values
|
10
|
+
attr_accessor :limit_value, :select_values, :where_values, :id_values
|
11
11
|
|
12
12
|
def initialize(klass)
|
13
13
|
@klass = klass
|
14
14
|
|
15
|
-
@limit_value
|
16
|
-
@select_values
|
17
|
-
@where_values
|
15
|
+
@limit_value = nil
|
16
|
+
@select_values = []
|
17
|
+
@where_values = []
|
18
|
+
@id_values = []
|
18
19
|
end
|
19
20
|
|
20
21
|
private
|
@@ -36,9 +37,9 @@ module CassandraObject
|
|
36
37
|
end
|
37
38
|
end
|
38
39
|
|
39
|
-
def
|
40
|
+
def select_records
|
40
41
|
results = []
|
41
|
-
klass.adapter.select(
|
42
|
+
klass.adapter.select(self) do |key, attributes|
|
42
43
|
results << klass.instantiate(key, attributes)
|
43
44
|
end
|
44
45
|
results.compact!
|
@@ -28,7 +28,7 @@ module CassandraObject
|
|
28
28
|
def find_one(id)
|
29
29
|
if id.blank?
|
30
30
|
raise CassandraObject::RecordNotFound, "Couldn't find #{self.name} with key #{id.inspect}"
|
31
|
-
elsif record =
|
31
|
+
elsif record = where_ids(id).first
|
32
32
|
record
|
33
33
|
else
|
34
34
|
raise CassandraObject::RecordNotFound
|
@@ -41,7 +41,7 @@ module CassandraObject
|
|
41
41
|
|
42
42
|
ids = ids.compact.map(&:to_s).uniq
|
43
43
|
|
44
|
-
|
44
|
+
where_ids(ids).to_a
|
45
45
|
end
|
46
46
|
end
|
47
47
|
end
|
@@ -23,6 +23,15 @@ module CassandraObject
|
|
23
23
|
clone.where! values
|
24
24
|
end
|
25
25
|
|
26
|
+
def where_ids!(*ids)
|
27
|
+
self.id_values += ids.flatten
|
28
|
+
self
|
29
|
+
end
|
30
|
+
|
31
|
+
def where_ids(*ids)
|
32
|
+
clone.where_ids! ids
|
33
|
+
end
|
34
|
+
|
26
35
|
def limit!(value)
|
27
36
|
self.limit_value = value
|
28
37
|
self
|
@@ -32,12 +41,8 @@ module CassandraObject
|
|
32
41
|
clone.limit! value
|
33
42
|
end
|
34
43
|
|
35
|
-
def to_cql
|
36
|
-
adapter.build_query(self)
|
37
|
-
end
|
38
|
-
|
39
44
|
def to_a
|
40
|
-
|
45
|
+
select_records
|
41
46
|
end
|
42
47
|
end
|
43
48
|
end
|
@@ -6,7 +6,7 @@ module CassandraObject
|
|
6
6
|
singleton_class.class_eval do
|
7
7
|
delegate :find, :find_by_id, :first, :all, to: :scope
|
8
8
|
delegate :find_each, :find_in_batches, to: :scope
|
9
|
-
delegate :select, :where, to: :scope
|
9
|
+
delegate :select, :where, :where_ids, to: :scope
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
data/test/support/issue.rb
CHANGED
@@ -15,8 +15,8 @@ class CassandraObject::Schema::TasksTest < CassandraObject::TestCase
|
|
15
15
|
end
|
16
16
|
|
17
17
|
test "load" do
|
18
|
-
CassandraObject::
|
19
|
-
CassandraObject::
|
18
|
+
CassandraObject::Schema.expects(:keyspace_execute).with("DO STUFF;")
|
19
|
+
CassandraObject::Schema.expects(:keyspace_execute).with("AND MORE;")
|
20
20
|
|
21
21
|
CassandraObject::Schema.load StringIO.new(
|
22
22
|
"DO\n" +
|
@@ -27,6 +27,7 @@ class CassandraObject::Scope::QueryMethodsTest < CassandraObject::TestCase
|
|
27
27
|
test "chaining where with scope" do
|
28
28
|
issue = Issue.create title: 'abc', description: 'def'
|
29
29
|
query = Issue.select(:title).for_key(issue.id)
|
30
|
-
|
30
|
+
|
31
|
+
assert_equal [:title], query.select_values
|
31
32
|
end
|
32
33
|
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: 4.
|
4
|
+
version: 4.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Koziarski
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-02-
|
12
|
+
date: 2014-02-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activemodel
|