cassie 1.0.0.beta.17 → 1.0.0.beta.21

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.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/bin/cassie +40 -15
  3. data/lib/cassie/configuration/templates/cassandra.yml +1 -2
  4. data/lib/cassie/connection.rb +3 -3
  5. data/lib/cassie/connection_handler/cluster.rb +1 -1
  6. data/lib/cassie/connection_handler/sessions.rb +1 -1
  7. data/lib/cassie/connection_handler.rb +4 -2
  8. data/lib/cassie/definition.rb +8 -0
  9. data/lib/cassie/modification.rb +9 -0
  10. data/lib/cassie/query.rb +3 -15
  11. data/lib/cassie/statements/README.md +710 -0
  12. data/lib/cassie/statements/core.rb +23 -0
  13. data/lib/cassie/{queries/statement/batches.rb → statements/execution/batched_fetching.rb} +7 -11
  14. data/lib/cassie/{queries/statement → statements/execution}/callbacks.rb +1 -1
  15. data/lib/cassie/{queries/statement → statements/execution}/consistency.rb +1 -1
  16. data/lib/cassie/statements/execution/deserialization.rb +13 -0
  17. data/lib/cassie/{queries/statement → statements/execution}/fetching.rb +10 -21
  18. data/lib/cassie/{queries/instrumentation/execution.rb → statements/execution/instrumentation.rb} +6 -2
  19. data/lib/cassie/statements/execution/partition_linking/cursoring_policy.rb +13 -0
  20. data/lib/cassie/statements/execution/partition_linking/policy_methods.rb +128 -0
  21. data/lib/cassie/statements/execution/partition_linking/simple_policy.rb +19 -0
  22. data/lib/cassie/statements/execution/partition_linking.rb +49 -0
  23. data/lib/cassie/statements/execution/peeking.rb +28 -0
  24. data/lib/cassie/statements/execution/results/core.rb +11 -0
  25. data/lib/cassie/statements/execution/results/cursored_result.rb +26 -0
  26. data/lib/cassie/statements/execution/results/instrumentation.rb +18 -0
  27. data/lib/cassie/statements/execution/results/modification.rb +12 -0
  28. data/lib/cassie/statements/execution/results/modification_result.rb +8 -0
  29. data/lib/cassie/statements/execution/results/peeking.rb +42 -0
  30. data/lib/cassie/statements/execution/results/peeking_result.rb +10 -0
  31. data/lib/cassie/statements/execution/results/query_result.rb +9 -0
  32. data/lib/cassie/statements/execution/results/querying.rb +66 -0
  33. data/lib/cassie/statements/execution/results/result.rb +23 -0
  34. data/lib/cassie/statements/execution/results.rb +12 -0
  35. data/lib/cassie/statements/execution.rb +69 -0
  36. data/lib/cassie/statements/instrumenting.rb +6 -0
  37. data/lib/cassie/{queries/logging/building_resources_event.rb → statements/logging/deserialize_event.rb} +4 -4
  38. data/lib/cassie/statements/logging/deserialize_subscriber.rb +19 -0
  39. data/lib/cassie/{queries/logging/cql_execution_event.rb → statements/logging/execute_event.rb} +8 -4
  40. data/lib/cassie/statements/logging/execute_subscriber.rb +19 -0
  41. data/lib/cassie/statements/logging.rb +12 -0
  42. data/lib/cassie/statements/modification.rb +14 -0
  43. data/lib/cassie/statements/query.rb +12 -0
  44. data/lib/cassie/statements/statement/assignment.rb +51 -0
  45. data/lib/cassie/statements/statement/assignments.rb +87 -0
  46. data/lib/cassie/{queries → statements}/statement/conditions.rb +1 -3
  47. data/lib/cassie/{queries → statements}/statement/deleting.rb +15 -12
  48. data/lib/cassie/{queries → statements}/statement/inserting.rb +13 -10
  49. data/lib/cassie/statements/statement/limiting.rb +89 -0
  50. data/lib/cassie/{queries → statements}/statement/mapping.rb +21 -41
  51. data/lib/cassie/{queries → statements}/statement/ordering.rb +1 -1
  52. data/lib/cassie/statements/statement/pagination/cursors.rb +112 -0
  53. data/lib/cassie/statements/statement/pagination.rb +19 -0
  54. data/lib/cassie/{queries → statements}/statement/preparation/cache.rb +1 -1
  55. data/lib/cassie/{queries → statements}/statement/preparation.rb +4 -5
  56. data/lib/cassie/statements/statement/relation.rb +68 -0
  57. data/lib/cassie/statements/statement/relations.rb +93 -0
  58. data/lib/cassie/statements/statement/selection.rb +86 -0
  59. data/lib/cassie/{queries → statements}/statement/updating.rb +9 -10
  60. data/lib/cassie/{queries → statements}/statement.rb +10 -20
  61. data/lib/cassie/statements.rb +9 -0
  62. data/lib/cassie/testing/fake/definition.rb +11 -0
  63. data/lib/cassie/testing/fake/modification.rb +11 -0
  64. data/lib/cassie/testing/fake/result.rb +15 -3
  65. data/lib/cassie/testing.rb +2 -0
  66. data/lib/cassie.rb +2 -0
  67. metadata +57 -34
  68. data/lib/cassie/queries/README.md +0 -458
  69. data/lib/cassie/queries/instrumentation/loading.rb +0 -15
  70. data/lib/cassie/queries/instrumentation.rb +0 -18
  71. data/lib/cassie/queries/logging/subscription.rb +0 -24
  72. data/lib/cassie/queries/logging.rb +0 -21
  73. data/lib/cassie/queries/statement/assignment.rb +0 -36
  74. data/lib/cassie/queries/statement/assignments.rb +0 -67
  75. data/lib/cassie/queries/statement/execution.rb +0 -45
  76. data/lib/cassie/queries/statement/limiting.rb +0 -36
  77. data/lib/cassie/queries/statement/loading.rb +0 -24
  78. data/lib/cassie/queries/statement/pagination/cursors.rb +0 -168
  79. data/lib/cassie/queries/statement/pagination/page_size.rb +0 -7
  80. data/lib/cassie/queries/statement/pagination.rb +0 -37
  81. data/lib/cassie/queries/statement/relation.rb +0 -74
  82. data/lib/cassie/queries/statement/relations.rb +0 -66
  83. data/lib/cassie/queries/statement/selection.rb +0 -63
@@ -1,67 +0,0 @@
1
- require_relative 'assignment'
2
- require_relative 'mapping'
3
-
4
- module Cassie::Queries::Statement
5
- module Assignments
6
- extend ActiveSupport::Concern
7
-
8
- included do
9
- include Mapping
10
- end
11
-
12
- module ClassMethods
13
- def set(identifier, opts={})
14
- assignment = Assignment.new(identifier, opts)
15
- opts[:value] ||= identifier.to_sym
16
-
17
- if Symbol === opts[:value]
18
- define_term_methods(opts[:value])
19
- end
20
-
21
- assignments[assignment] = opts
22
- end
23
-
24
- def assignments
25
- @assignments ||= {}
26
- end
27
- end
28
-
29
- def assignments
30
- self.class.assignments
31
- end
32
-
33
- def build_update_and_bindings
34
- cql = ""
35
- bindings = []
36
- assignment_strings = []
37
-
38
- assignments.each do |a, opts|
39
- if eval_if_opt?(opts[:if])
40
- assignment_strings << a.to_update_cql
41
- bindings << eval_value_opt(opts[:value])
42
- end
43
- end
44
-
45
- cql = "#{assignment_strings.join(', ')}" unless bindings.empty?
46
-
47
- [cql , bindings]
48
- end
49
-
50
- def build_insert_and_bindings
51
- identifiers = []
52
- bindings = []
53
-
54
- assignments.each do |a, opts|
55
- if eval_if_opt?(opts[:if])
56
- identifiers << a.to_insert_cql
57
- bindings << eval_value_opt(opts[:value])
58
- end
59
- end
60
-
61
- identifiers_cql = "#{identifiers.join(', ')}"
62
- terms_cql = Array.new(identifiers.count){"?"}.join(", ")
63
-
64
- [identifiers_cql, terms_cql , bindings]
65
- end
66
- end
67
- end
@@ -1,45 +0,0 @@
1
- require_relative 'consistency'
2
-
3
- module Cassie::Queries::Statement
4
- module Execution
5
- extend ActiveSupport::Concern
6
-
7
- included do
8
- attr_reader :result
9
-
10
- include Consistency
11
- end
12
-
13
- # Executes the statment, populates result
14
- # returns true or false indicating a successful execution or not
15
- def execute
16
- @result = session.execute(statement, execution_options)
17
- execution_successful?
18
- end
19
-
20
- def execution_options
21
- {}.tap do |opts|
22
- #TODO: rework consistency module to be more
23
- # abstract implementation for all execution options
24
- opts[:consistency] = consistency if consistency
25
- opts[:paging_state] = paging_state if respond_to?(:paging_state) && paging_state
26
- opts[:page_size] = stateless_page_size if respond_to?(:stateless_page_size) && stateless_page_size
27
- end
28
- end
29
-
30
- protected
31
-
32
- def execution_successful?
33
- #TODO: rethink this, it knows too much
34
- raise "execution not complete, no results to parse" unless result
35
-
36
- # empty select
37
- return true if result.empty?
38
-
39
- # failed upsert
40
- return false if (!result.rows.first["[applied]"].nil?) && (result.rows.first["[applied]"] == false)
41
-
42
- true
43
- end
44
- end
45
- end
@@ -1,36 +0,0 @@
1
- module Cassie::Queries::Statement
2
- module Limiting
3
- extend ActiveSupport::Concern
4
-
5
- included do
6
- attr_writer :limit
7
- end
8
-
9
- module ClassMethods
10
- def limit=(val)
11
- @limit = val
12
- end
13
-
14
- def limit(val=:get)
15
- if val == :get
16
- @limit if defined?(@limit)
17
- else
18
- self.limit = val
19
- end
20
- end
21
- end
22
-
23
- def limit
24
- return @limit if defined?(@limit)
25
- self.class.limit
26
- end
27
-
28
- protected
29
-
30
- def build_limit_str
31
- return "" if limit.nil?
32
-
33
- "LIMIT #{limit}"
34
- end
35
- end
36
- end
@@ -1,24 +0,0 @@
1
- module Cassie::Queries::Statement
2
- module Loading
3
- extend ActiveSupport::Concern
4
-
5
- def fetch(args={})
6
- build_resources(super(args))
7
- end
8
-
9
- protected
10
-
11
- # Default implementation assumes
12
- # 1 row per resource, clients
13
- # may override if more complex
14
- def build_resources(rows)
15
- rows.map {|r| build_resource(r) }
16
- end
17
-
18
- # When class doesn't override
19
- # simply return a struct with the row data
20
- def build_resource(row)
21
- Struct.new(*row.keys.map(&:to_sym)).new(*row.values)
22
- end
23
- end
24
- end
@@ -1,168 +0,0 @@
1
- require_relative '../relations'
2
-
3
- module Cassie::Queries::Pagination
4
- module Cursors
5
- extend ActiveSupport::Concern
6
-
7
- included do
8
- include Cassie::Queries::Statement::Relations
9
- end
10
-
11
- module ClassMethods
12
- def max_cursor(key)
13
- include Peeking
14
-
15
- @max_cursor_key = key
16
-
17
- where(key,:lteq,
18
- value: :"max_#{key}",
19
- if: :max_cursor_enabled?)
20
-
21
- define_max_accessors(key)
22
- define_next_max_cursor_alias(key)
23
- end
24
-
25
- def since_cursor(key)
26
- include Peeking
27
-
28
- @max_cursor_key = key
29
-
30
- where(key, :gt,
31
- value: :"since_#{key}",
32
- if: :since_cursor_enabled?)
33
-
34
- define_since_accessors(key)
35
- define_next_max_cursor_alias(key)
36
- end
37
-
38
- def cursor_by(key)
39
- max_cursor key
40
- since_cursor key
41
- end
42
-
43
- private
44
-
45
- def define_max_accessors(key)
46
- attr_accessor :max_cursor
47
-
48
- define_method :max_cursor_enabled? do
49
- !max_cursor.nil?
50
- end
51
-
52
- getter = :"max_#{key}"
53
- remove_method getter if method_defined?(getter)
54
- define_method getter do
55
- self.max_cursor
56
- end
57
-
58
- setter = :"max_#{key}="
59
- remove_method setter if method_defined?(setter)
60
- define_method setter do |val|
61
- self.max_cursor = val
62
- end
63
- end
64
-
65
- def define_since_accessors(key)
66
- attr_accessor :since_cursor
67
-
68
- define_method :since_cursor_enabled? do
69
- !since_cursor.nil?
70
- end
71
-
72
- getter = :"since_#{key}"
73
- remove_method getter if method_defined?(getter)
74
- define_method getter do
75
- self.since_cursor
76
- end
77
-
78
- setter = :"since_#{key}="
79
- remove_method setter if method_defined?(setter)
80
- define_method setter do |val|
81
- self.since_cursor = val
82
- end
83
- end
84
-
85
- def define_next_max_cursor_alias(key)
86
- method = "next_max_#{key}"
87
-
88
- unless method_defined?(method)
89
- define_method method do
90
- next_max_cursor
91
- end
92
- end
93
- end
94
- end
95
-
96
- module Peeking
97
- extend ActiveSupport::Concern
98
-
99
- included do
100
- attr_reader :next_max_cursor
101
- end
102
-
103
- module ClassMethods
104
- def max_cursor_key
105
- @max_cursor_key.to_s
106
- end
107
- end
108
-
109
- def limit
110
- super || page_size
111
- end
112
-
113
- def execute
114
- # get 1 extra result to determing next page info
115
- # but massage results to only have what client expects
116
-
117
- val = peek_at_next_page do
118
- super
119
- end
120
-
121
- extract_next_max_cursor
122
-
123
- val
124
- end
125
-
126
- private
127
-
128
- # cache query object instance page_size
129
- # so we can revert _object_ back to
130
- # same state and preserve value
131
- # inheritance chain behavior
132
- def peek_at_next_page(&block)
133
- old_page_size = nil
134
- was_defined = false
135
-
136
- if defined?(@page_size)
137
- old_page_size = @page_size
138
- was_defined = true
139
- end
140
-
141
- @page_size = page_size + 1
142
- yield
143
- ensure
144
- if was_defined
145
- @page_size = old_page_size
146
- else
147
- remove_instance_variable(:@page_size)
148
- end
149
- end
150
-
151
- # Extracts the next_max_cursor from the query results
152
- # given then current max_cursor and since_cursor
153
- # leaving the results as cursoring client expects
154
- #
155
- # Note: We modify cassie private attribute in place
156
- # otherwise we have to copy rows, make results private
157
- # or have a mismatch between rows in results
158
- # and resources created by query class
159
- def extract_next_max_cursor
160
- raw_rows = result.instance_variable_get(:@rows)
161
-
162
- @next_max_cursor = if raw_rows.count > page_size
163
- raw_rows.delete_at(-1)[self.class.max_cursor_key]
164
- end
165
- end
166
- end
167
- end
168
- end
@@ -1,7 +0,0 @@
1
- module Cassie::Queries::Pagination
2
- module PageSize
3
- def self.default
4
- 100
5
- end
6
- end
7
- end
@@ -1,37 +0,0 @@
1
- require_relative 'pagination/cursors'
2
- require_relative 'pagination/page_size'
3
-
4
- module Cassie::Queries
5
- module Pagination
6
- extend ActiveSupport::Concern
7
-
8
- included do
9
- include Cursors
10
- end
11
-
12
- module ClassMethods
13
- def inherited(subclass)
14
- subclass.page_size = page_size
15
- super
16
- end
17
-
18
- def page_size
19
- return @page_size if defined?(@page_size)
20
- Cassie::Queries::Pagination::PageSize.default
21
- end
22
-
23
- def page_size=(val)
24
- @page_size = val
25
- end
26
- end
27
-
28
- def page_size
29
- return @page_size if defined?(@page_size)
30
- self.class.page_size
31
- end
32
-
33
- def page_size=(val)
34
- @page_size = val
35
- end
36
- end
37
- end
@@ -1,74 +0,0 @@
1
- # for pluralization
2
- require 'active_support/core_ext/string'
3
-
4
- module Cassie::Queries::Statement
5
- #
6
- #
7
- # relation "username = ?", value: :username
8
- # relation :username, :eq
9
- # relation :username, :eq, value: :method
10
- # relation :phone, :in
11
- class Relation
12
- # https://cassandra.apache.org/doc/cql3/CQL.html#selectStmt
13
-
14
- OPERATIONS = {
15
- eq: "=",
16
- lt: "<",
17
- lteq: "<=",
18
- gt: ">",
19
- gteq: ">=",
20
- in: "IN",
21
- contains: "CONTAINS",
22
- contains_key: "CONTAINS KEY",
23
- }
24
-
25
- attr_reader :identifier,
26
- :op_type
27
-
28
- def initialize(identifier, op_type, opts={})
29
- if Hash === op_type
30
- # custom relation is being defined:
31
- # `relation "username = ?", value: :username`
32
-
33
- # swap the 2nd arg that sucked in options hash
34
- # to keep consistent feeling interface
35
- opts.merge!(op_type)
36
-
37
- @cql = identifier
38
- @custom = true
39
- else
40
- @identifier = identifier
41
- @op_type = op_type.to_sym
42
- end
43
- end
44
-
45
- def custom?
46
- !!@custom
47
- end
48
-
49
- def to_cql
50
- cql
51
- end
52
-
53
- def multiple_term?
54
- op_type == :in
55
- end
56
-
57
- def implied_value_method
58
- method = if multiple_term?
59
- identifier.to_s.pluralize
60
- else
61
- identifier
62
- end
63
-
64
- method.to_sym
65
- end
66
-
67
- protected
68
-
69
- def cql
70
- # we always generate bound statements
71
- @cql ||= "#{identifier} #{OPERATIONS[op_type]} ?"
72
- end
73
- end
74
- end
@@ -1,66 +0,0 @@
1
- require_relative 'relation'
2
-
3
- module Cassie::Queries::Statement
4
- module Relations
5
- extend ActiveSupport::Concern
6
-
7
- module ClassMethods
8
- # where :username, :eq, value: :method
9
- # where :phone, :in
10
- # were "username = ?", value: :username
11
- def where(identifier, op, opts={})
12
- relation = Relation.new(identifier, op, opts)
13
-
14
- opts[:value] ||= relation.implied_value_method
15
-
16
- if Symbol === opts[:value]
17
- define_term_methods(opts[:value])
18
- end
19
-
20
- relations[relation] = opts
21
- end
22
-
23
- # a where clause is built up of multiple 'relations'
24
- def relations
25
- @relations ||= {}
26
- end
27
-
28
- protected
29
-
30
- def define_term_methods(name)
31
- #TODO: this should probably only raise
32
- # if value option was nil and we
33
- # are implicilty creating getter/setters.
34
- if method_defined?(name) || method_defined?("#{name}=")
35
- raise "accessor or getter already defined for #{name}. Fix the collisions by using the `:value` option."
36
- else
37
- attr_accessor name
38
- end
39
- end
40
- end
41
-
42
- # a where clause is built up of multiple 'relations'
43
- def relations
44
- self.class.relations
45
- end
46
-
47
- protected
48
-
49
- def build_where_and_bindings
50
- cql = ""
51
- bindings = []
52
- relation_strings = []
53
-
54
- relations.each do |r, opts|
55
- if eval_if_opt?(opts[:if])
56
- relation_strings << r.to_cql
57
- bindings << eval_value_opt(opts[:value])
58
- end
59
- end
60
-
61
- cql = "WHERE #{relation_strings.join(' AND ')}" unless bindings.empty?
62
-
63
- [cql , bindings]
64
- end
65
- end
66
- end
@@ -1,63 +0,0 @@
1
- require_relative 'relations'
2
- require_relative 'limiting'
3
- require_relative 'pagination'
4
- require_relative 'ordering'
5
- require_relative 'fetching'
6
-
7
- module Cassie::Queries::Statement
8
- module Selection
9
- extend ::ActiveSupport::Concern
10
-
11
- module ClassMethods
12
- #TODO: accept block to add specific selectors and aliases
13
- # select :table do |t|
14
- # t.id
15
- # t.name as: :username
16
- # end
17
- def select(table)
18
- include Relations
19
- include Ordering
20
- include Fetching
21
-
22
- self.table = table
23
- self.type = :select
24
-
25
- yield(self) if block_given?
26
- end
27
-
28
- # a select clause is built up of selectors
29
- def selectors
30
- @selectors ||= []
31
- end
32
- end
33
-
34
- protected
35
-
36
- def build_select_cql_and_bindings
37
- where_str, bindings = build_where_and_bindings
38
-
39
- cql = %(
40
- SELECT #{build_select_clause}
41
- FROM #{table}
42
- #{where_str}
43
- #{build_order_str}
44
- #{build_limit_str}
45
- ).squish + ";"
46
-
47
- [cql, bindings]
48
- end
49
-
50
- # a select clause is built up of selectors
51
- def selectors
52
- self.class.selectors
53
- end
54
-
55
- def build_select_clause
56
- str = if selectors.empty?
57
- '*'
58
- else
59
- selectors.join(', ')
60
- end
61
- end
62
- end
63
- end