sessionm-cassandra_object 4.0.27 → 4.0.28
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/cassandra_object/adapters/cassandra_driver.rb +95 -19
- data/sessionm-cassandra_object.gemspec +1 -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: 23762bc97b24f059702d33a82198651dc12a5849
|
4
|
+
data.tar.gz: e5bdeca74f220ad8ade8f35a20b3751efd256eec
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ffff8841ff8da649d139ddc24d54c0a28bbba823fbe25ec7a00cde71a3685bc33e2ac92b1973a09208f419ef0660a03a2ae840dc008bd4af57ed3f8120399a39
|
7
|
+
data.tar.gz: 88af7c90d6177d05afaf0d37f0eee2ecc563dd4ea9a48e3195d587dad18e88768f5f40389be12eedac86554de24c507cca1f14af4f9a33711feb4d79cf301312
|
@@ -99,8 +99,13 @@ module CassandraObject
|
|
99
99
|
|
100
100
|
insert_into_options = ttl ? " USING TTL #{ttl}" : ''
|
101
101
|
|
102
|
+
key_fields = get_key_fields(column_family)
|
103
|
+
column_fields = get_column_fields(column_family)
|
104
|
+
|
105
|
+
key_parts = get_parts(column_family, key, key_fields)
|
102
106
|
insert_query = values.map do |name, value|
|
103
|
-
|
107
|
+
column_parts = get_parts(column_family, name, column_fields)
|
108
|
+
" INSERT INTO \"#{column_family}\" (#{key_fields.map(&:first).join(', ')}, #{column_fields.map(&:first).join(', ')}, #{VALUE_FIELD}) VALUES (#{key_parts.map { |f, v| escape(v, get_type(column_family, f)) }.join(', ')}, #{column_parts.map { |f, v| escape(v, get_type(column_family, f)) }.join(', ')}, #{escape(value, value_type(column_family))})#{insert_into_options}"
|
104
109
|
end.join("\n")
|
105
110
|
|
106
111
|
if batch_mode?
|
@@ -118,12 +123,13 @@ module CassandraObject
|
|
118
123
|
async = opts.try(:[], :async)
|
119
124
|
|
120
125
|
columns = columns_options.flatten.compact
|
126
|
+
column_fields = get_column_fields(column_family)
|
121
127
|
|
122
128
|
query =
|
123
129
|
if columns.size == 1
|
124
|
-
"SELECT #{VALUE_FIELD} FROM \"#{column_family}\" WHERE #{
|
130
|
+
"SELECT #{VALUE_FIELD} FROM \"#{column_family}\" WHERE #{key_clause(column_family, key)} AND #{column_clause(column_family, columns.first)}"
|
125
131
|
else
|
126
|
-
"SELECT #{
|
132
|
+
"SELECT #{column_fields.map(&:first).join(', ')}, #{VALUE_FIELD} FROM \"#{column_family}\" WHERE #{key_clause(column_family, key)}"
|
127
133
|
end
|
128
134
|
|
129
135
|
result = async ? self.execute_async(query, execute_options(opts)) : self.execute(query, execute_options(opts))
|
@@ -132,7 +138,7 @@ module CassandraObject
|
|
132
138
|
if columns.size == 1
|
133
139
|
result.size > 0 ? result.first[VALUE_FIELD] : nil
|
134
140
|
else
|
135
|
-
data = result.inject({}) { |hsh, row| hsh[row
|
141
|
+
data = result.inject({}) { |hsh, row| hsh[column_string(row, column_fields)] = row[VALUE_FIELD]; hsh }
|
136
142
|
columns.size > 0 ? data.slice(*columns.map(&:to_s)) : data
|
137
143
|
end
|
138
144
|
end
|
@@ -142,7 +148,7 @@ module CassandraObject
|
|
142
148
|
|
143
149
|
name_fields = columns.map { |c| escape(c, name_type(column_family)) }.join(', ')
|
144
150
|
|
145
|
-
query = "SELECT #{NAME_FIELD}, #{VALUE_FIELD} FROM \"#{column_family}\" WHERE #{NAME_FIELD} IN(#{name_fields}) AND #{
|
151
|
+
query = "SELECT #{NAME_FIELD}, #{VALUE_FIELD} FROM \"#{column_family}\" WHERE #{NAME_FIELD} IN(#{name_fields}) AND #{key_clause(column_family, key)};"
|
146
152
|
|
147
153
|
result = async ? self.execute_async(query, execute_options(opts)) : self.execute(query, execute_options(opts))
|
148
154
|
return result if async
|
@@ -158,7 +164,7 @@ module CassandraObject
|
|
158
164
|
|
159
165
|
name_fields = columns.map { |c| "'#{c}'" }.join(', ')
|
160
166
|
|
161
|
-
query = "SELECT #{NAME_FIELD}, #{VALUE_FIELD} FROM \"#{column_family}\" WHERE #{NAME_FIELD} IN(#{name_fields}) AND #{
|
167
|
+
query = "SELECT #{NAME_FIELD}, #{VALUE_FIELD} FROM \"#{column_family}\" WHERE #{NAME_FIELD} IN(#{name_fields}) AND #{key_clause(column_family, key)};"
|
162
168
|
|
163
169
|
result = async ? self.execute_async(query, execute_options(opts)) : self.execute(query, execute_options(opts))
|
164
170
|
return result if async
|
@@ -176,7 +182,7 @@ module CassandraObject
|
|
176
182
|
fields = [fields] unless fields.is_a?(Array)
|
177
183
|
|
178
184
|
fields.each do |field|
|
179
|
-
query = "UPDATE \"#{column_family}\" SET #{VALUE_FIELD} = #{VALUE_FIELD} + #{by} WHERE #{
|
185
|
+
query = "UPDATE \"#{column_family}\" SET #{VALUE_FIELD} = #{VALUE_FIELD} + #{by} WHERE #{key_clause(column_family, key)} AND #{column_clause(column_family, field)};"
|
180
186
|
async ? self.execute_async(query, execute_options(opts)) : self.execute(query, execute_options(opts))
|
181
187
|
end
|
182
188
|
end
|
@@ -186,7 +192,7 @@ module CassandraObject
|
|
186
192
|
fields = [fields] unless fields.is_a?(Array)
|
187
193
|
|
188
194
|
hash.each do |field, by|
|
189
|
-
query = "UPDATE \"#{column_family}\" SET #{VALUE_FIELD} = #{VALUE_FIELD} + #{by} WHERE #{
|
195
|
+
query = "UPDATE \"#{column_family}\" SET #{VALUE_FIELD} = #{VALUE_FIELD} + #{by} WHERE #{key_clause(column_family, key)} AND #{column_clause(column_family, field)};"
|
190
196
|
async ? self.execute_async(query, execute_options(opts)) : self.execute(query, execute_options(opts))
|
191
197
|
end
|
192
198
|
end
|
@@ -197,9 +203,9 @@ module CassandraObject
|
|
197
203
|
|
198
204
|
query =
|
199
205
|
if args.first.nil? || args.first.is_a?(Hash)
|
200
|
-
"DELETE FROM \"#{column_family}\" WHERE #{
|
206
|
+
"DELETE FROM \"#{column_family}\" WHERE #{key_clause(column_family, key)};"
|
201
207
|
else
|
202
|
-
"DELETE \"#{column_family}\" WHERE #{
|
208
|
+
"DELETE FROM \"#{column_family}\" WHERE #{key_clause(column_family, key)} AND #{column_clause(column_family, args.first)};"
|
203
209
|
end
|
204
210
|
|
205
211
|
async ? self.execute_async(query, execute_options(opts)) : self.execute(query, execute_options(opts))
|
@@ -227,15 +233,21 @@ module CassandraObject
|
|
227
233
|
def get_slice(column_family, key, column, start, finish, count, reversed, consistency, opts={})
|
228
234
|
opts[:consistency] = consistency
|
229
235
|
|
230
|
-
|
231
|
-
|
232
|
-
query
|
233
|
-
query << " AND #{
|
234
|
-
query << "
|
236
|
+
column_fields = get_column_fields(column_family)
|
237
|
+
|
238
|
+
query = "SELECT #{column_fields.map(&:first).join(', ')}, #{VALUE_FIELD} FROM \"#{column_family}\" WHERE #{key_clause(column_family, key)}"
|
239
|
+
query << " AND #{column_clause(column_family, column)}" if column
|
240
|
+
query << " AND #{column_clause(column_family, start, '>=')}" unless start.empty?
|
241
|
+
query << " AND #{column_clause(column_family, finish, '<=')}" unless finish.empty?
|
242
|
+
if reversed
|
243
|
+
direction = reverse_comparator(column_family) ? 'ASC' : 'DESC'
|
244
|
+
query << " ORDER BY "
|
245
|
+
query << column_fields.map { |f, _| "#{f} #{direction}" }.join(', ')
|
246
|
+
end
|
235
247
|
query << " LIMIT #{count}"
|
236
248
|
|
237
249
|
self.execute(query, execute_options(opts)).inject({}) do |results, row|
|
238
|
-
results[
|
250
|
+
results[column_string(row, column_fields)] = decode(row[VALUE_FIELD], value_type(column_family))
|
239
251
|
results
|
240
252
|
end
|
241
253
|
end
|
@@ -329,32 +341,87 @@ CQL
|
|
329
341
|
end
|
330
342
|
|
331
343
|
def key_type(column_family)
|
332
|
-
|
344
|
+
get_type(column_family, KEY_FIELD)
|
333
345
|
end
|
334
346
|
|
335
347
|
def name_type(column_family)
|
336
|
-
|
348
|
+
get_type(column_family, NAME_FIELD)
|
337
349
|
end
|
338
350
|
|
339
351
|
def value_type(column_family)
|
340
|
-
|
352
|
+
get_type(column_family, VALUE_FIELD)
|
353
|
+
end
|
354
|
+
|
355
|
+
def get_type(column_family, field)
|
356
|
+
cluster.keyspace(keyspace).table(column_family).column(field).type.kind
|
357
|
+
end
|
358
|
+
|
359
|
+
def get_key_fields(column_family)
|
360
|
+
cluster.keyspace(keyspace).table(column_family).columns.select { |c| c.name =~ /^key/ }.map { |c| [c.name, c.type.kind] }
|
361
|
+
end
|
362
|
+
|
363
|
+
def get_column_fields(column_family)
|
364
|
+
cluster.keyspace(keyspace).table(column_family).columns.select { |c| c.name =~ /^column/ }.map { |c| [c.name, c.type.kind] }
|
341
365
|
end
|
342
366
|
|
343
367
|
def reverse_comparator(column_family)
|
344
368
|
self.cluster.keyspace(keyspace).table(column_family).send(:clustering_order).first == :desc
|
345
369
|
end
|
346
370
|
|
371
|
+
def get_parts(column_family, val, fields)
|
372
|
+
val =
|
373
|
+
if fields.size > 1
|
374
|
+
Cassandra::Composite.new_from_packed(val.dup).parts
|
375
|
+
else
|
376
|
+
[val]
|
377
|
+
end
|
378
|
+
|
379
|
+
fields.each_with_index.map { |(field, type), idx| [field, normalize_composite_key_part(val[idx], type), type] }
|
380
|
+
end
|
381
|
+
|
382
|
+
def key_clause(column_family, val)
|
383
|
+
clause(column_family, val, get_key_fields(column_family))
|
384
|
+
end
|
385
|
+
|
386
|
+
def column_clause(column_family, val, operator='=')
|
387
|
+
clause(column_family, val, get_column_fields(column_family), operator)
|
388
|
+
end
|
389
|
+
|
390
|
+
def clause(column_family, val, fields, operator='=')
|
391
|
+
if operator == '='
|
392
|
+
get_parts(column_family, val, fields).map { |field, val, type| "#{field} #{operator} #{escape(val, type)}" }.join(' AND ')
|
393
|
+
else
|
394
|
+
field, val, type = get_parts(column_family, val, fields).first
|
395
|
+
"#{field} #{operator} #{escape(val, type)}"
|
396
|
+
end
|
397
|
+
end
|
398
|
+
|
347
399
|
def escape(str, type)
|
348
400
|
case type
|
349
401
|
when :timeuuid
|
350
402
|
convert_str_to_timeuuid str
|
351
403
|
when :blob
|
352
404
|
convert_str_to_hex str
|
405
|
+
when :int, :bigint
|
406
|
+
str
|
353
407
|
else
|
354
408
|
"'#{str}'"
|
355
409
|
end
|
356
410
|
end
|
357
411
|
|
412
|
+
def normalize_composite_key_part(val, type)
|
413
|
+
case type
|
414
|
+
when :timeuuid
|
415
|
+
SimpleUUID::UUID.new(val).to_s
|
416
|
+
when :int
|
417
|
+
val.unpack('N').first
|
418
|
+
when :bigint
|
419
|
+
Cassandra::Long.new(val).to_i
|
420
|
+
else
|
421
|
+
val
|
422
|
+
end
|
423
|
+
end
|
424
|
+
|
358
425
|
def decode(val, type)
|
359
426
|
case type
|
360
427
|
when :timeuuid
|
@@ -373,6 +440,15 @@ CQL
|
|
373
440
|
def convert_str_to_hex(str)
|
374
441
|
'0x' << str.unpack('H*').first
|
375
442
|
end
|
443
|
+
|
444
|
+
def column_string(row, fields)
|
445
|
+
if fields.size > 1
|
446
|
+
parts = fields.map { |f, t| decode(row[f], t) }
|
447
|
+
Cassandra::Composite.new(*parts).to_s
|
448
|
+
else
|
449
|
+
row[NAME_FIELD]
|
450
|
+
end
|
451
|
+
end
|
376
452
|
end
|
377
453
|
end
|
378
454
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sessionm-cassandra_object
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.0.
|
4
|
+
version: 4.0.28
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Doug Youch
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2017-12-
|
12
|
+
date: 2017-12-06 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: Cassandra ActiveModel
|
15
15
|
email: doug@sessionm.com
|