cassie 1.0.0.beta.5 → 1.0.0.beta.6
Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 40bb4e39b19017fcef0127c393ccb0280c8ea6bb
|
4
|
+
data.tar.gz: 9ed902fdd76d02a30e91ccb7385d761df6e4936b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 987f316efd2e36ca612f45fc212bcd6c967dd2e3cd6840923b159a1acb1fa35448843411b14d695125b8a277a966dbbd3d0068b7cf47c40ccea5a96a63a8ad53
|
7
|
+
data.tar.gz: 34edc2ed19b618c8297a9e8a925ae26262e627b14b272c57758f33b201d5c9f56191d78d5b958bdbc6e640db05046fb3f990bbf8e1a9367c7c7c5d02002033db
|
@@ -22,7 +22,7 @@ Queries defined on the fly like this tend to create debt for an application in t
|
|
22
22
|
* resist documentation
|
23
23
|
* resist refactoring
|
24
24
|
|
25
|
-
|
25
|
+
Application queries represent distinct application behavior, `cassie` queries are designed to help create query classes that are reusable, testable and maintainable (so you can sleep better at night).
|
26
26
|
|
27
27
|
```ruby
|
28
28
|
# Some PORO user model
|
@@ -9,7 +9,11 @@ module Cassie::Queries::Logging
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def message
|
12
|
-
|
12
|
+
{
|
13
|
+
duration: duration.round(1),
|
14
|
+
query: statement,
|
15
|
+
consistency: consistency.upcase
|
16
|
+
}.extend(Inspector)
|
13
17
|
end
|
14
18
|
|
15
19
|
protected
|
@@ -45,8 +49,20 @@ module Cassie::Queries::Logging
|
|
45
49
|
execution_info.trace
|
46
50
|
end
|
47
51
|
|
48
|
-
|
49
|
-
|
52
|
+
module Inspector
|
53
|
+
def inspect
|
54
|
+
color "(#{fetch(:duration).round(1)}ms) #{fetch(:query)} [#{fetch(:consistency).upcase}]"
|
55
|
+
end
|
56
|
+
|
57
|
+
def to_s
|
58
|
+
inspect
|
59
|
+
end
|
60
|
+
|
61
|
+
protected
|
62
|
+
|
63
|
+
def color(message)
|
64
|
+
"\e[1m\e[37m#{message}\e[0m\e[22m"
|
65
|
+
end
|
50
66
|
end
|
51
67
|
end
|
52
68
|
end
|
@@ -11,6 +11,23 @@ module Cassie::Queries::Statement
|
|
11
11
|
attr_accessor :stateless_page_size
|
12
12
|
end
|
13
13
|
|
14
|
+
# Uses #fetch_in_batches with a batch size of 1000 (or as
|
15
|
+
# specified by the +:batch_size+ option) to enumerate through all
|
16
|
+
# records, while using batches to limit resource consumption.
|
17
|
+
#
|
18
|
+
# If you do not provide a block to #fetch_each, it will return an Enumerator
|
19
|
+
# for chaining with other methods.
|
20
|
+
#
|
21
|
+
# UsersByPositionQuery.fetch_each.with_index do |user, index|
|
22
|
+
# user.position = index
|
23
|
+
# UserMapper.update_position(user)
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# ==== Options
|
27
|
+
# * <tt>:batch_size</tt> - Specifies the size of the batch. Default to 1000.
|
28
|
+
#
|
29
|
+
# NOTE: Any limit specified on the query will affect the batched set.
|
30
|
+
# Cassandra internal paging is used for batching.
|
14
31
|
def fetch_each(opts={})
|
15
32
|
return to_enum(:fetch_each, opts) unless block_given?
|
16
33
|
|
@@ -28,24 +45,30 @@ module Cassie::Queries::Statement
|
|
28
45
|
# end
|
29
46
|
#
|
30
47
|
# "max score in group: 26"
|
48
|
+
#
|
49
|
+
# ==== Options
|
50
|
+
# * <tt>:batch_size</tt> - Specifies the size of the batch. Default to 1000.
|
51
|
+
#
|
52
|
+
# NOTE: Any limit specified on the query will affect the batched set.
|
53
|
+
# Cassandra internal paging is used for batching.
|
31
54
|
def fetch_in_batches(opts={})
|
32
|
-
# we want to clone the query as soon as the enumerable is
|
33
|
-
# created, not wait until the firt iteration is called
|
34
|
-
# as the client could mutate the object between these states
|
35
|
-
# but we don't want to clone twice if enumerator returned
|
36
|
-
return to_enum(:fetch_in_batches, opts.merge(_paged_query: self.clone)) unless block_given?
|
37
|
-
|
38
55
|
opts[:batch_size] ||= 1000
|
39
56
|
|
57
|
+
# clone the query as soon as the enumerable is created
|
58
|
+
# rather than waiting until the firt iteration is executed
|
59
|
+
# as the client could mutate the object between these states.
|
60
|
+
# However we don't want to clone twice if a block isn't passed
|
61
|
+
paged_query = opts.delete(:_paged_query) || self.clone
|
62
|
+
|
63
|
+
return to_enum(:fetch_in_batches, opts.merge(_paged_query: paged_query)) unless block_given?
|
64
|
+
|
40
65
|
# use Cassandra internal paging
|
41
66
|
# but clone the query to isolate it
|
42
|
-
#
|
67
|
+
# and allow all paging queries
|
43
68
|
# to execute within a Cassie::Query
|
44
69
|
# for use of other features, like logging
|
45
|
-
|
46
|
-
|
47
|
-
# set cassandra internal
|
48
|
-
# stateless page size (independent from limit)
|
70
|
+
#
|
71
|
+
# note: stateless page size is independent from limit
|
49
72
|
paged_query.stateless_page_size = opts[:batch_size]
|
50
73
|
paged_query.paging_state = nil
|
51
74
|
done = false
|
@@ -2,12 +2,12 @@ require_relative 'execution_info'
|
|
2
2
|
|
3
3
|
module Cassie::Testing::Fake
|
4
4
|
class Result
|
5
|
-
|
5
|
+
attr_reader :rows, :statement, :opts
|
6
6
|
|
7
7
|
def initialize(statement, execution_opts={})
|
8
8
|
@statement = statement
|
9
9
|
@opts = execution_opts
|
10
|
-
@rows = @opts[:rows]
|
10
|
+
@rows = @data = opts[:rows] || []
|
11
11
|
end
|
12
12
|
|
13
13
|
def execution_info
|
@@ -15,29 +15,65 @@ module Cassie::Testing::Fake
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def rows
|
18
|
-
|
18
|
+
if paging_enabled?
|
19
|
+
index = current_page - 1
|
20
|
+
offset = index * page_size
|
21
|
+
@data.slice(offset, page_size) || []
|
22
|
+
else
|
23
|
+
@data
|
24
|
+
end
|
19
25
|
end
|
20
26
|
|
21
27
|
def empty?
|
22
28
|
rows.empty?
|
23
29
|
end
|
24
30
|
|
31
|
+
def paging_enabled?
|
32
|
+
!!page_size
|
33
|
+
end
|
34
|
+
|
35
|
+
def page_size
|
36
|
+
return nil unless opts[:page_size]
|
37
|
+
opts[:page_size].to_i
|
38
|
+
end
|
39
|
+
|
40
|
+
def pages
|
41
|
+
return nil unless paging_enabled?
|
42
|
+
(@data.count / page_size.to_f).ceil
|
43
|
+
end
|
44
|
+
|
45
|
+
def previous_page
|
46
|
+
return nil unless previous_paging_state
|
47
|
+
previous_paging_state.bytes[-1]
|
48
|
+
end
|
49
|
+
|
50
|
+
def current_page
|
51
|
+
return 1 unless paging_enabled? && previous_page
|
52
|
+
previous_page + 1
|
53
|
+
end
|
54
|
+
|
25
55
|
def last_page?
|
26
|
-
return nil unless
|
27
|
-
|
28
|
-
true
|
56
|
+
return nil unless paging_enabled?
|
57
|
+
current_page == pages
|
29
58
|
end
|
30
59
|
|
31
|
-
def
|
32
|
-
|
60
|
+
def previous_paging_state
|
61
|
+
return nil unless paging_enabled?
|
62
|
+
@opts[:paging_state]
|
33
63
|
end
|
34
64
|
|
35
65
|
def paging_state
|
36
|
-
return nil unless
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
66
|
+
return nil unless paging_enabled?
|
67
|
+
if previous_paging_state
|
68
|
+
bytes = previous_paging_state.bytes
|
69
|
+
raise 'Too many pages for Cassie testing harness!' if bytes[-1] >= 256
|
70
|
+
bytes[-1] = bytes[-1] + 1
|
71
|
+
bytes.pack('c*')
|
72
|
+
else
|
73
|
+
# use last byte of state string to store pages
|
74
|
+
# presume 255 pages is enough for any testing
|
75
|
+
"paging #{SecureRandom.hex(6)}:" + [1].pack('c*')
|
76
|
+
end
|
41
77
|
end
|
42
78
|
end
|
43
79
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cassie
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.beta.
|
4
|
+
version: 1.0.0.beta.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Evan Prothro
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-08-
|
11
|
+
date: 2016-08-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cassandra-driver
|