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
@@ -0,0 +1,112 @@
1
+ require_relative '../relations'
2
+ require_relative '../../execution/peeking'
3
+
4
+ module Cassie::Statements::Statement::Pagination
5
+ module Cursors
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ include Cassie::Statements::Statement::Relations
10
+ end
11
+
12
+ module ClassMethods
13
+ def max_cursor(key)
14
+ include Cassie::Statements::Execution::Peeking
15
+ self.partition_linker = Cassie::Statements::Execution::PartitionLinking::CursoringPolicy
16
+
17
+ @max_cursor_key = key
18
+
19
+ where(key,:lteq,
20
+ value: :"max_#{key}",
21
+ if: :max_cursor_enabled?)
22
+
23
+ define_max_accessors(key)
24
+ end
25
+
26
+ def since_cursor(key)
27
+ include Cassie::Statements::Execution::Peeking
28
+
29
+ @max_cursor_key = key
30
+
31
+ where(key, :gt,
32
+ value: :"since_#{key}",
33
+ if: :since_cursor_enabled?)
34
+
35
+ define_since_accessors(key)
36
+ end
37
+
38
+ def cursor_by(key)
39
+ max_cursor key
40
+ since_cursor key
41
+ end
42
+
43
+ def max_cursor_key
44
+ @max_cursor_key.to_s
45
+ end
46
+
47
+ private
48
+
49
+ def define_max_accessors(key)
50
+ attr_accessor :max_cursor
51
+
52
+ define_method :max_cursor_enabled? do
53
+ !max_cursor.nil?
54
+ end
55
+
56
+ getter = :"max_#{key}"
57
+ remove_method getter if method_defined?(getter)
58
+ define_method getter do
59
+ self.max_cursor
60
+ end
61
+
62
+ setter = :"max_#{key}="
63
+ remove_method setter if method_defined?(setter)
64
+ define_method setter do |val|
65
+ self.max_cursor = val
66
+ end
67
+ end
68
+
69
+ def define_since_accessors(key)
70
+ attr_accessor :since_cursor
71
+
72
+ define_method :since_cursor_enabled? do
73
+ !since_cursor.nil?
74
+ end
75
+
76
+ getter = :"since_#{key}"
77
+ remove_method getter if method_defined?(getter)
78
+ define_method getter do
79
+ self.since_cursor
80
+ end
81
+
82
+ setter = :"since_#{key}="
83
+ remove_method setter if method_defined?(setter)
84
+ define_method setter do |val|
85
+ self.since_cursor = val
86
+ end
87
+ end
88
+ end
89
+
90
+ def result_class
91
+ if cursored?
92
+ Cassie::Statements::Results::CursoredResult
93
+ else
94
+ super
95
+ end
96
+ end
97
+
98
+ def result_opts
99
+ if cursored?
100
+ super.merge({max_cursor_key: self.class.max_cursor_key})
101
+ else
102
+ super
103
+ end
104
+ end
105
+
106
+ protected
107
+
108
+ def cursored?
109
+ respond_to?(:max_cursor)
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,19 @@
1
+ require_relative 'pagination/cursors'
2
+
3
+ module Cassie::Statements
4
+ module Statement::Pagination
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ include Cursors
9
+
10
+ alias :page_size :limit
11
+ alias :page_size= :limit=
12
+
13
+ class << self
14
+ alias :page_size :limit
15
+ alias :page_size= :limit=
16
+ end
17
+ end
18
+ end
19
+ end
@@ -1,4 +1,4 @@
1
- module Cassie::Queries::Statement
1
+ module Cassie::Statements::Statement
2
2
  module Preparation
3
3
  class Cache
4
4
  attr_reader :data
@@ -1,6 +1,6 @@
1
1
  require_relative 'preparation/cache'
2
2
 
3
- module Cassie::Queries::Statement
3
+ module Cassie::Statements::Statement
4
4
  module Preparation
5
5
  extend ::ActiveSupport::Concern
6
6
 
@@ -24,12 +24,11 @@ module Cassie::Queries::Statement
24
24
 
25
25
  def statement
26
26
  statement = super
27
-
28
27
  if self.class.prepare?
29
- key = statement.cql if statement.respond_to?(:cql)
30
- key ||= statement.to_s
28
+ key = statement.respond_to?(:cql) ? statement.cql : statement.to_s
31
29
 
32
30
  unbound = statement_cache.fetch(key) do
31
+ statement.cql.freeze
33
32
  session.prepare(statement)
34
33
  end
35
34
  unbound.bind(statement.params)
@@ -41,7 +40,7 @@ module Cassie::Queries::Statement
41
40
  private
42
41
 
43
42
  def statement_cache
44
- Cassie::Queries::Statement::Preparation.cache
43
+ Cassie::Statements::Statement::Preparation.cache
45
44
  end
46
45
  end
47
46
  end
@@ -0,0 +1,68 @@
1
+ module Cassie::Statements::Statement
2
+ #
3
+ #
4
+ # relation :username, :eq
5
+ # relation :username, :eq, value: :method
6
+ # relation :phone, :in
7
+ # relation :user_id, :gteq, term: "minTimeuuid('2013-02-02 10:00+0000')"
8
+ class Relation
9
+ # https://cassandra.apache.org/doc/cql3/CQL.html#selectStmt
10
+
11
+ OPERATIONS = {
12
+ eq: "=",
13
+ lt: "<",
14
+ lteq: "<=",
15
+ gt: ">",
16
+ gteq: ">=",
17
+ in: "IN",
18
+ contains: "CONTAINS",
19
+ contains_key: "CONTAINS KEY",
20
+ }
21
+
22
+ attr_reader :source,
23
+ :identifier,
24
+ :operation,
25
+ :value,
26
+ :enabled,
27
+ :term
28
+
29
+
30
+ def initialize(source, identifier, op_type, value_method, opts={})
31
+ @source = source
32
+ @identifier = identifier
33
+ @operation = OPERATIONS[op_type.to_sym]
34
+ @value = source.send(value_method)
35
+ @enabled = opts.has_key?(:if) ? source_eval(opts[:if]) : true
36
+ @term = opts.has_key?(:term) ? source_eval(opts[:term]) : "?"
37
+ end
38
+
39
+ def enabled?
40
+ !!enabled
41
+ end
42
+
43
+ def argument
44
+ return nil unless enabled? && positional?
45
+ value
46
+ end
47
+
48
+ def positional?
49
+ term.to_s.include?("?")
50
+ end
51
+
52
+ def to_cql
53
+ return nil unless enabled?
54
+ "#{identifier} #{operation} #{term}"
55
+ end
56
+
57
+ private
58
+
59
+ def source_eval(value, _source=source)
60
+ case value
61
+ when Symbol
62
+ _source.send(value)
63
+ else
64
+ value
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,93 @@
1
+ # for pluralization
2
+ require 'active_support/core_ext/string'
3
+ require_relative 'relation'
4
+
5
+ module Cassie::Statements::Statement
6
+ # Provides support for a set of CQL relations
7
+ # and building the where clause and argument list
8
+ # for a cql statement
9
+ #
10
+ # CQL Relation terminology:
11
+ #
12
+ # "SELECT * FROM table WHERE id = ?", [1]
13
+ #
14
+ # relation: 'WHERE'
15
+ # identifier: 'id'
16
+ # operation: '='
17
+ # term: '?'
18
+ # argument: '1'
19
+ module Relations
20
+ extend ActiveSupport::Concern
21
+
22
+ module ClassMethods
23
+ # where :username, :eq, value: :method
24
+ # where :phone, :in
25
+ # relation :user_id, :gteq, term: "minTimeuuid('2013-02-02 10:00+0000')"
26
+ def where(identifier, op, opts={})
27
+ opts[:value] ||= implied_argument_method(identifier, op)
28
+
29
+ define_argument_accessor(opts[:value])
30
+
31
+ relations_args << [identifier, op, opts.delete(:value), opts]
32
+ end
33
+
34
+ def relations_args
35
+ @relations_args ||= []
36
+ end
37
+
38
+ protected
39
+
40
+ #TODO: extract argument accessor creation for
41
+ # more DRY and clear usage. See mapping module.
42
+ def define_argument_accessor(name)
43
+ unless Symbol === name
44
+ raise ArgumentError, "A Symbol is required for the accessor methods for setting/getting a relation's value. #{name.class} (#{name}) given."
45
+ end
46
+ #TODO: this should probably only raise
47
+ # if value option was nil and we
48
+ # are implicilty creating getter/setters.
49
+ if method_defined?(name) || method_defined?("#{name}=")
50
+ raise "accessor or getter already defined for #{name}. Fix the collisions by using the `:value` option."
51
+ else
52
+ attr_accessor name
53
+ end
54
+ end
55
+
56
+ private
57
+
58
+ def implied_argument_method(identifier, op)
59
+ method = if op == :in
60
+ identifier.to_s.pluralize
61
+ else
62
+ identifier
63
+ end
64
+
65
+ method.to_sym
66
+ end
67
+ end
68
+
69
+ # a where clause is built up of multiple 'relations'
70
+ def relations_args
71
+ self.class.relations_args
72
+ end
73
+
74
+ protected
75
+
76
+ def build_where_and_bindings
77
+ cql = ""
78
+ relation_strings = []
79
+ arguments = []
80
+
81
+ relations_args.each do |args|
82
+ r = Relation.new(self, *args)
83
+ relation_strings += Array(r.to_cql)
84
+ arguments += Array(r.argument)
85
+ end
86
+
87
+ cql = "WHERE #{relation_strings.join(' AND ')}" unless relation_strings.empty?
88
+
89
+ # where identifier inequality term AND identifier inequality term;
90
+ [cql , arguments]
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,86 @@
1
+ require_relative 'limiting'
2
+ require_relative 'pagination'
3
+ require_relative 'relations'
4
+ require_relative 'ordering'
5
+
6
+ module Cassie::Statements::Statement
7
+ module Selection
8
+ extend ::ActiveSupport::Concern
9
+
10
+ included do
11
+ include Relations
12
+ include Ordering
13
+ include Limiting
14
+ include Pagination
15
+
16
+ @result_class = Cassie::Statements::Results::QueryResult
17
+ end
18
+
19
+ module ClassMethods
20
+ def select_from(table)
21
+ self.table = table
22
+ self.type = :select
23
+
24
+ yield(self) if block_given?
25
+ end
26
+
27
+ def select(selector, opts={})
28
+ selector = selector.to_s
29
+ selector += " AS #{opts[:as]}" if opts[:as]
30
+ selectors << selector
31
+ end
32
+
33
+ # a select clause is built up of selectors
34
+ def selectors
35
+ @selectors ||= []
36
+ end
37
+
38
+ def write_time(selector)
39
+ "WRITETIME(#{selector})"
40
+ end
41
+ alias writetime write_time
42
+
43
+ def ttl(selector)
44
+ "TTL(#{selector})"
45
+ end
46
+
47
+ def count(selector='*')
48
+ "COUNT(#{selector})"
49
+ end
50
+ end
51
+
52
+ protected
53
+
54
+ def result_opts
55
+ opts = {}
56
+ opts[:each_deserializer] = method(:build_result) if respond_to?(:build_result, true)
57
+ opts[:deserializer] = method(:build_results) if respond_to?(:build_results, true)
58
+ super.merge(opts)
59
+ end
60
+
61
+ def build_select_cql_and_bindings
62
+ where_str, bindings = build_where_and_bindings
63
+
64
+ cql = %(
65
+ SELECT #{build_select_clause}
66
+ FROM #{table}
67
+ #{where_str}
68
+ #{build_order_str}
69
+ #{build_limit_str}
70
+ ).squish + ";"
71
+
72
+ [cql, bindings]
73
+ end
74
+
75
+ # a select clause is built up of selectors
76
+ def selectors
77
+ self.class.selectors
78
+ end
79
+
80
+ def build_select_clause
81
+ return '*' if selectors.empty?
82
+
83
+ selectors.join(', ')
84
+ end
85
+ end
86
+ end
@@ -1,16 +1,20 @@
1
1
  require_relative 'assignments'
2
2
  require_relative 'conditions'
3
3
 
4
- module Cassie::Queries::Statement
4
+ module Cassie::Statements::Statement
5
5
  module Updating
6
6
  extend ::ActiveSupport::Concern
7
7
 
8
+ included do
9
+ include Relations
10
+ include Assignments
11
+ include Conditions
12
+
13
+ @result_class = Cassie::Statements::Results::ModificationResult
14
+ end
15
+
8
16
  module ClassMethods
9
17
  def update(table)
10
- include Relations
11
- include Assignments
12
- include Conditions
13
-
14
18
  self.table = table
15
19
  self.type = :update
16
20
 
@@ -18,11 +22,6 @@ module Cassie::Queries::Statement
18
22
  end
19
23
  end
20
24
 
21
- def update(opts={})
22
- execute
23
- execution_successful?
24
- end
25
-
26
25
  protected
27
26
 
28
27
  def build_update_cql_and_bindings
@@ -1,33 +1,23 @@
1
1
  require 'active_support/core_ext/string/filters'
2
2
  require 'active_support/hash_with_indifferent_access'
3
- require_relative 'statement/execution'
4
- require_relative 'statement/preparation'
5
- require_relative 'statement/callbacks'
6
- require_relative 'statement/limiting'
7
- require_relative 'statement/pagination'
8
- require_relative 'statement/selection'
9
- require_relative 'statement/deleting'
10
- require_relative 'statement/updating'
11
- require_relative 'statement/inserting'
12
3
 
13
-
14
- module Cassie::Queries
4
+ module Cassie::Statements
5
+ # Include Statement to provide support for a
6
+ # `statement` method returning a `Cassandra::Statements::Simple`
7
+ # statement with positional arguments.
8
+ #
9
+ # `type` and `table` attributes are also added,
10
+ # providing an extension interface for building
11
+ # cql and bindings for different statement types.
15
12
  module Statement
13
+ require_relative 'statement/preparation'
14
+
16
15
  class Invalid < StandardError; end
17
16
 
18
- # https://cassandra.apache.org/doc/cql3/CQL.html#selectStmt
19
17
  extend ::ActiveSupport::Concern
20
18
 
21
19
  included do
22
- include Execution
23
20
  include Preparation
24
- include Callbacks
25
- include Limiting
26
- include Pagination
27
- include Selection
28
- include Deleting
29
- include Updating
30
- include Inserting
31
21
 
32
22
  class << self
33
23
  attr_accessor :table
@@ -0,0 +1,9 @@
1
+ module Cassie
2
+ module Statements
3
+ require_relative 'statements/core'
4
+ require_relative 'statements/query'
5
+ require_relative 'statements/modification'
6
+ require_relative 'statements/instrumenting'
7
+ require_relative 'statements/logging'
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ require_relative 'session_methods'
2
+
3
+ module Cassie
4
+ module Testing::Fake::Definition
5
+ end
6
+
7
+ class FakeDefinition < Cassie::Definition
8
+ include Cassie::Testing::Fake::SessionMethods
9
+
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ require_relative 'session_methods'
2
+
3
+ module Cassie
4
+ module Testing::Fake::Modification
5
+ end
6
+
7
+ class FakeModification < Cassie::Modification
8
+ include Cassie::Testing::Fake::SessionMethods
9
+
10
+ end
11
+ end
@@ -2,6 +2,7 @@ require_relative 'execution_info'
2
2
 
3
3
  module Cassie::Testing::Fake
4
4
  class Result
5
+ include Enumerable
5
6
  attr_reader :rows, :statement, :opts
6
7
 
7
8
  def initialize(statement, execution_opts={})
@@ -14,18 +15,29 @@ module Cassie::Testing::Fake
14
15
  ExecutionInfo.new(statement)
15
16
  end
16
17
 
17
- def rows
18
- if paging_enabled?
18
+ def each
19
+ _rows = if paging_enabled?
19
20
  index = current_page - 1
20
21
  offset = index * page_size
21
22
  @data.slice(offset, page_size) || []
22
23
  else
23
24
  @data
24
25
  end
26
+
27
+ if block_given?
28
+ _rows.each(&block)
29
+ self
30
+ else
31
+ _rows.each
32
+ end
25
33
  end
34
+ alias rows each
35
+ alias each_row each
26
36
 
27
37
  def empty?
28
- rows.empty?
38
+ !!rows.peek
39
+ rescue StopIteration
40
+ true
29
41
  end
30
42
 
31
43
  def paging_enabled?
@@ -1,6 +1,8 @@
1
1
  module Cassie
2
2
  module Testing
3
+ require_relative 'testing/fake/definition'
3
4
  require_relative 'testing/fake/query'
5
+ require_relative 'testing/fake/modification'
4
6
 
5
7
  end
6
8
  end
data/lib/cassie.rb CHANGED
@@ -17,7 +17,9 @@ module Cassie
17
17
  require_relative 'cassie/configuration'
18
18
  require_relative 'cassie/connection_handler'
19
19
  require_relative 'cassie/connection'
20
+ require_relative 'cassie/definition'
20
21
  require_relative 'cassie/query'
22
+ require_relative 'cassie/modification'
21
23
 
22
24
  extend Configuration::Core
23
25
  extend ConnectionHandler