cassie 1.0.0.beta.24 → 1.0.0.beta.25

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 65b5763101f92f5797356a1081e0fee0219cd86a
4
- data.tar.gz: ff6994cee1c3f6d04d4ff35f01bd2e59e4d50ac5
3
+ metadata.gz: ada280d1a8cc943ec5c6a2fd096b7721134c6f79
4
+ data.tar.gz: 27c7f3ec0cd636839891747a298d1c3af13ad232
5
5
  SHA512:
6
- metadata.gz: 77986c9aeb90d02ef1fdb107d168312390099ac0094ebef092985b737436f7ad5f23ce97f5068e4b0ca27579431fed9d7c95a426318b4008052dd5c9ebbe1b60
7
- data.tar.gz: 961f2603659b2d3a770425fa571ea715ebe12314b602cd21539af579fcd48b0ff48a11aaf45d3304c3ca2211ed0a27303f6b36b76972d64782eac0637470baab
6
+ metadata.gz: 3b893a1bf8402d76a5c1c79e832dfe543afac03bbb2033d88e53c9985b1adc9aa5756ebe237926e3e2814ad256679339993b75fb48f5e847cc4a7edbbbcc418e
7
+ data.tar.gz: cbda596807f165500df579cf8a8d88a8210bfbcfb800024a7fe0ddfee618f406ef8bedbeb76144c865eb0ea914f9a61a90b84ed45376bbac01d54a8f8af323bc
@@ -0,0 +1,30 @@
1
+ module Cassie::Statements
2
+
3
+ class ExecutionError < StandardError
4
+ attr_reader :statement
5
+
6
+ def initialize(statement)
7
+ @statement = statement
8
+ super
9
+ end
10
+
11
+ def message
12
+ "Failed to execute statement: #{cql}"
13
+ end
14
+
15
+ private
16
+
17
+ def cql
18
+ case
19
+ when statement.respond_to?(:to_cql)
20
+ statement.to_cql
21
+ when statement.result && statement.result.execution_info && statement.result.execution_info.statement
22
+ statement.result.execution_info.statement.to_cql
23
+ when statement.respond_to?(:statement)
24
+ statement.statement.to_s
25
+ else
26
+ statement.to_s
27
+ end
28
+ end
29
+ end
30
+ end
@@ -2,12 +2,33 @@ require_relative 'simple_policy'
2
2
 
3
3
  module Cassie::Statements::Execution::PartitionLinking
4
4
  class CursoringPolicy < SimplePolicy
5
+
6
+ def combine_rows(rows_a, rows_b)
7
+ return super unless peeking_execution.since_cursor
8
+ rows_b
9
+ end
10
+
11
+ def adjust_limit
12
+ return super unless peeking_execution.since_cursor
13
+ # leave the limit to return all results
14
+ # from latest partition
15
+ end
5
16
 
6
- def prepare_execution
7
- super
8
- # We are changing to the next partition
9
- # so, reset the max cursor to start at the top
10
- # execution.max_cursor = nil
17
+ def seek_partition?
18
+ return super unless peeking_execution.since_cursor
19
+ raise "linking partitions only supported for descending orderings. Open an issue if you need this!" if ascending?
20
+
21
+ # linking while cursoring with since
22
+ # should return latest results
23
+ current_key != last_key
24
+ end
25
+
26
+ def previous_key(current_key)
27
+ return super unless peeking_execution.since_cursor
28
+
29
+ # linking while cursoring with since
30
+ # should return results from latest partition
31
+ last_key
11
32
  end
12
33
  end
13
34
  end
@@ -14,9 +14,10 @@ module Cassie::Statements::Execution::PartitionLinking
14
14
  @direction = direction
15
15
  @range = range
16
16
  end
17
-
17
+
18
+ # returns linked result
18
19
  def link
19
- if end_of_partition? && partition_available?
20
+ if seek_partition? && partition_available?
20
21
  prepare_execution
21
22
  execution.execute
22
23
  combine_results
@@ -31,6 +32,10 @@ module Cassie::Statements::Execution::PartitionLinking
31
32
  adjust_limit
32
33
  execution
33
34
  end
35
+
36
+ def seek_partition?
37
+ end_of_partition?
38
+ end
34
39
 
35
40
  def end_of_partition?
36
41
  !peeking_execution.result.peeked_row
@@ -41,15 +46,8 @@ module Cassie::Statements::Execution::PartitionLinking
41
46
  end
42
47
 
43
48
  def partition_available?
44
- if ascending?
45
- # |0| |1| |2| |3|
46
- # |X| |✓| |✓| |✓| |X|
47
- current_key < last_key && current_key >= first_key
48
- else
49
- # |0| |1| |2| |3|
50
- # |X| |✓| |✓| |✓| |X|
51
- current_key > first_key && current_key <= last_key
52
- end
49
+ key = ascending? ? next_key(current_key) : previous_key(current_key)
50
+ key >= first_key && key <= last_key
53
51
  end
54
52
 
55
53
  protected
@@ -63,7 +61,7 @@ module Cassie::Statements::Execution::PartitionLinking
63
61
  end
64
62
 
65
63
  def change_partition
66
- _partition = if ascending?
64
+ key = if ascending?
67
65
  # explicitly pass key to keep policy subclass
68
66
  # interface clear and consistent
69
67
  next_key(current_key)
@@ -72,15 +70,15 @@ module Cassie::Statements::Execution::PartitionLinking
72
70
  # interface clear and consistent
73
71
  previous_key(current_key)
74
72
  end
75
- if _partition < first_key || _partition > last_key
76
- logger.warn("warning: linking to partition that is outside of ranges defined. #{_partition} outside of (#{first_key}..#{last_key}). This could result in unexpected records being returned.")
73
+ if key < first_key || key > last_key
74
+ logger.warn("warning: linking to partition that is outside of ranges defined. #{key} outside of (#{first_key}..#{last_key}). This could result in unexpected records being returned.")
77
75
  end
78
76
 
79
77
  # define object singleton method to
80
78
  # override getter for partition key
81
79
  # returning the partion that needs to be linked
82
80
  execution.define_singleton_method(identifier) do
83
- _partition
81
+ key
84
82
  end
85
83
  end
86
84
 
@@ -8,13 +8,20 @@ module Cassie::Statements::Execution
8
8
 
9
9
  def execute
10
10
  assert_limit
11
- with_limit(limit + 1) { super }
11
+ @unpeeked_limit = limit
12
+ with_limit(limit + 1) do
13
+ super
14
+ end
15
+ end
16
+
17
+ def unpeeked_limit
18
+ @unpeeked_limit if defined?(@unpeeked_limit)
12
19
  end
13
20
 
14
21
  protected
15
22
 
16
23
  def result_opts
17
- super.merge(limit: limit - 1)
24
+ super.merge(limit: unpeeked_limit || limit)
18
25
  end
19
26
 
20
27
  private
@@ -1,5 +1,6 @@
1
1
  module Cassie::Statements
2
2
  module Execution
3
+ require_relative 'execution/errors'
3
4
  require_relative 'execution/consistency'
4
5
  require_relative 'execution/callbacks'
5
6
  require_relative 'execution/results'
@@ -39,6 +40,12 @@ module Cassie::Statements
39
40
  result.success?
40
41
  end
41
42
 
43
+ # Executes the statment, populates result
44
+ # true or raises if the was not successful
45
+ def execute!
46
+ execute || (raise Cassie::Statements::ExecutionError.new(result))
47
+ end
48
+
42
49
  def execution_options
43
50
  {}.tap do |opts|
44
51
  #TODO: rework consistency module to be more
@@ -23,9 +23,12 @@ module Cassie::Statements::Statement
23
23
  !!enabled
24
24
  end
25
25
 
26
+ def argument?
27
+ enabled? && positional?
28
+ end
29
+
26
30
  def argument
27
- return nil unless enabled? && positional?
28
- value
31
+ value if argument?
29
32
  end
30
33
 
31
34
  def positional?
@@ -44,7 +44,7 @@ module Cassie::Statements::Statement
44
44
  self.class.assignments_args
45
45
  end
46
46
 
47
- def build_update_and_bindings
47
+ def build_update_and_params
48
48
  cql = ""
49
49
  arguments = []
50
50
  assignment_strings = []
@@ -52,7 +52,7 @@ module Cassie::Statements::Statement
52
52
  assignments_args.each do |args|
53
53
  a = Assignment.new(self, *args)
54
54
  assignment_strings += Array(a.to_update_cql)
55
- arguments += Array(a.argument)
55
+ arguments << a.argument if a.argument?
56
56
  end
57
57
 
58
58
  cql = assignment_strings.join(', ')
@@ -60,7 +60,7 @@ module Cassie::Statements::Statement
60
60
  [cql , arguments]
61
61
  end
62
62
 
63
- def build_insert_and_bindings
63
+ def build_insert_and_params
64
64
  identifiers = []
65
65
  terms = []
66
66
  arguments = []
@@ -28,7 +28,7 @@ module Cassie::Statements::Statement
28
28
  self.class.conditions
29
29
  end
30
30
 
31
- def build_condition_and_bindings
31
+ def build_condition_and_params
32
32
  condition_strings = []
33
33
  bindings = []
34
34
 
@@ -39,18 +39,18 @@ module Cassie::Statements::Statement
39
39
 
40
40
  protected
41
41
 
42
- def build_delete_cql_and_bindings
43
- where_str, where_bindings = build_where_and_bindings
44
- condition_str, condition_bindings = build_condition_and_bindings
42
+ def build_delete_cql_and_params
43
+ where_str, where_params = build_where_and_params
44
+ condition_str, condition_params = build_condition_and_params
45
45
 
46
- cql = %(
46
+ @cql = %(
47
47
  DELETE #{build_delete_clause}
48
48
  FROM #{table}
49
49
  #{where_str}
50
50
  #{condition_str}
51
51
  ).squish + ";"
52
52
 
53
- [cql, where_bindings + condition_bindings]
53
+ @params = where_params + condition_params
54
54
  end
55
55
 
56
56
  # a select clause is built up of selectors
@@ -0,0 +1,52 @@
1
+ module Cassie::Statements
2
+ def self.default_idempotency
3
+ return @default_idempotency if defined?(@default_idempotency)
4
+ false
5
+ end
6
+
7
+ def self.default_idempotency=(val)
8
+ @default_idempotency = val
9
+ end
10
+
11
+
12
+ module Statement::Idempotency
13
+ extend ActiveSupport::Concern
14
+
15
+ included do
16
+ attr_writer :idempotent
17
+ end
18
+
19
+ module ClassMethods
20
+ def inherited(subclass)
21
+ subclass.idempotent = idempotent if defined?(@idempotent)
22
+ super
23
+ end
24
+
25
+ def idempotent=(val)
26
+ @idempotent = val
27
+ end
28
+
29
+ def idempotent(val=:get)
30
+ if val == :get
31
+ return @idempotent if defined?(@idempotent)
32
+ Cassie::Statements.default_idempotency
33
+ else
34
+ self.idempotent = val
35
+ end
36
+ end
37
+
38
+ def idempotent?
39
+ !!idempotent
40
+ end
41
+ end
42
+
43
+ def idempotent
44
+ return @idempotent if defined?(@idempotent)
45
+ self.class.idempotent
46
+ end
47
+
48
+ def idempotent?
49
+ !!idempotent
50
+ end
51
+ end
52
+ end
@@ -27,18 +27,18 @@ module Cassie::Statements::Statement
27
27
 
28
28
  protected
29
29
 
30
- def build_insert_cql_and_bindings
31
- identifiers_str, terms_str, value_bindings = build_insert_and_bindings
32
- condition_str, condition_bindings = build_condition_and_bindings
30
+ def build_insert_cql_and_params
31
+ identifiers_str, terms_str, value_params = build_insert_and_params
32
+ condition_str, condition_params = build_condition_and_params
33
33
 
34
- cql = %(
34
+ @cql = %(
35
35
  INSERT INTO #{table}
36
36
  (#{identifiers_str})
37
37
  VALUES (#{terms_str})
38
38
  #{condition_str}
39
39
  ).squish + ";"
40
40
 
41
- [cql, value_bindings + condition_bindings]
41
+ @params = value_params + condition_params
42
42
  end
43
43
  end
44
44
  end
@@ -73,7 +73,7 @@ module Cassie::Statements::Statement
73
73
 
74
74
  protected
75
75
 
76
- def build_where_and_bindings
76
+ def build_where_and_params
77
77
  cql = ""
78
78
  relation_strings = []
79
79
  arguments = []
@@ -14,6 +14,7 @@ module Cassie::Statements::Statement
14
14
  include Pagination
15
15
 
16
16
  @result_class = Cassie::Statements::Results::QueryResult
17
+ @idempotent = true
17
18
  end
18
19
 
19
20
  module ClassMethods
@@ -58,18 +59,16 @@ module Cassie::Statements::Statement
58
59
  super.merge(opts)
59
60
  end
60
61
 
61
- def build_select_cql_and_bindings
62
- where_str, bindings = build_where_and_bindings
62
+ def build_select_cql_and_params
63
+ where_str, @params = build_where_and_params
63
64
 
64
- cql = %(
65
+ @cql = %(
65
66
  SELECT #{build_select_clause}
66
67
  FROM #{table}
67
68
  #{where_str}
68
69
  #{build_order_str}
69
70
  #{build_limit_str}
70
71
  ).squish + ";"
71
-
72
- [cql, bindings]
73
72
  end
74
73
 
75
74
  # a select clause is built up of selectors
@@ -0,0 +1,34 @@
1
+ module Cassie::Statements
2
+ module Statement::TypeHinting
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ attr_writer :type_hints
7
+ end
8
+
9
+ module ClassMethods
10
+ def inherited(subclass)
11
+ subclass.type_hints = type_hints if defined?(@type_hints)
12
+ super
13
+ end
14
+
15
+ def type_hints=(val)
16
+ @type_hints = val
17
+ end
18
+
19
+ def type_hints(val=:get)
20
+ if val == :get
21
+ return @type_hints if defined?(@type_hints)
22
+ nil
23
+ else
24
+ self.type_hints = val
25
+ end
26
+ end
27
+ end
28
+
29
+ def type_hints
30
+ return @type_hints if defined?(@type_hints)
31
+ self.class.type_hints
32
+ end
33
+ end
34
+ end
@@ -24,19 +24,19 @@ module Cassie::Statements::Statement
24
24
 
25
25
  protected
26
26
 
27
- def build_update_cql_and_bindings
28
- assignment_str, update_bindings = build_update_and_bindings
29
- where_str, where_bindings = build_where_and_bindings
30
- condition_str, condition_bindings = build_condition_and_bindings
27
+ def build_update_cql_and_params
28
+ assignment_str, update_params = build_update_and_params
29
+ where_str, where_params = build_where_and_params
30
+ condition_str, condition_params = build_condition_and_params
31
31
 
32
- cql = %(
32
+ @cql = %(
33
33
  UPDATE #{table}
34
34
  SET #{assignment_str}
35
35
  #{where_str}
36
36
  #{condition_str}
37
37
  ).squish + ";"
38
38
 
39
- [cql, update_bindings + where_bindings + condition_bindings]
39
+ @params = update_params + where_params + condition_params
40
40
  end
41
41
  end
42
42
  end
@@ -11,6 +11,8 @@ module Cassie::Statements
11
11
  # cql and bindings for different statement types.
12
12
  module Statement
13
13
  require_relative 'statement/preparation'
14
+ require_relative 'statement/type_hinting'
15
+ require_relative 'statement/idempotency'
14
16
 
15
17
  class Invalid < StandardError; end
16
18
 
@@ -18,6 +20,8 @@ module Cassie::Statements
18
20
 
19
21
  included do
20
22
  include Preparation
23
+ include TypeHinting
24
+ include Idempotency
21
25
 
22
26
  class << self
23
27
  attr_accessor :table
@@ -32,11 +36,11 @@ module Cassie::Statements
32
36
  # returns a CQL string, or a Cassandra::Statement
33
37
  # that is ready for execution
34
38
  def statement
35
- Cassandra::Statements::Simple.new(*build_cql_and_bindings)
39
+ Cassandra::Statements::Simple.new(*build_cql_and_params, type_hints, idempotent?)
36
40
  end
37
41
 
38
42
  # returns a CQL string with inline parameters, that
39
- # is representative of what would be executed in a CQL shell
43
+ # is representative of what could be executed in a CQL shell
40
44
  def to_cql
41
45
  if statement.respond_to?(:cql) && statement.respond_to?(:params)
42
46
  Cassie::Support::StatementParser.new(statement).to_cql
@@ -44,15 +48,28 @@ module Cassie::Statements
44
48
  statement.to_s
45
49
  end
46
50
  end
51
+
52
+ def logger
53
+ Cassie::Statements.logger
54
+ end
55
+
56
+ def cql
57
+ return @cql if defined?(@cql)
58
+ ""
59
+ end
60
+
61
+ def params
62
+ return @params if defined?(@params)
63
+ nil
64
+ end
47
65
 
48
66
  protected
49
67
 
50
- def build_cql_and_bindings
68
+ def build_cql_and_params
51
69
  if self.class.type
52
- send "build_#{self.class.type}_cql_and_bindings"
53
- else
54
- raise "No statement type has been declared. Call `.select`, `.update`, `.delete`, or `.insert` to set query type."
70
+ send "build_#{self.class.type}_cql_and_params"
55
71
  end
72
+ [cql, params]
56
73
  end
57
74
 
58
75
  private
@@ -1,69 +1,80 @@
1
- module Cassie::Support
2
- class CommandRunner
3
- attr_reader :binary, :args, :command, :status, :duration, :output
1
+ module Cassie
2
+ module Support
3
+ class CommandRunner
4
+ attr_reader :binary, :args, :command, :status, :duration, :output
4
5
 
5
- # When a block is given, the command runs before yielding
6
- def initialize(binary, args=[])
7
- @binary = binary
8
- @args = args
9
- @command = (Array(binary) + args).join(" ")
10
- @command = command + " 2>&1" unless command =~ / > /
6
+ # When a block is given, the command runs before yielding
7
+ def initialize(binary, args=[])
8
+ @binary = binary
9
+ @args = args
10
+ @command = (Array(binary) + args).join(" ")
11
+ @command = command + " 2>&1" unless command =~ / > /
11
12
 
12
- if block_given?
13
- run
14
- yield self
13
+ if block_given?
14
+ run
15
+ yield self
16
+ end
15
17
  end
16
- end
17
18
 
18
- # Runs the command
19
- def run
20
- t1=Time.now
19
+ # Runs the command
20
+ def run
21
+ t1=Time.now
22
+
23
+ IO.popen(command) do |io|
24
+ @output=io.read
25
+ @status=Process.waitpid2(io.pid)[1]
26
+ end
21
27
 
22
- IO.popen(command) do |io|
23
- @output=io.read
24
- @status=Process.waitpid2(io.pid)[1]
28
+ @duration=Time.now-t1
29
+ completed?
25
30
  end
26
31
 
27
- @duration=Time.now-t1
28
- completed?
29
- end
32
+ # Runs the command, raising if program
33
+ # was not run successfully
34
+ def run!
35
+ unless run && success?
36
+ raise RuntimeError.new(failure_message)
37
+ end
38
+ true
39
+ end
30
40
 
31
- # Returns false if the command hasn't been executed yet
32
- def run?
33
- !!@duration
34
- end
41
+ # Returns false if the command hasn't been executed yet
42
+ def run?
43
+ !!@duration
44
+ end
35
45
 
36
- # Returns the exit code for the command. Runs the command if it hasn't run yet.
37
- def exitcode
38
- status.exitstatus
39
- end
46
+ # Returns the exit code for the command. Runs the command if it hasn't run yet.
47
+ def exitcode
48
+ status.exitstatus
49
+ end
40
50
 
41
- # Returns true if exited 0
42
- def success?
43
- return false unless run?
44
- exitcode == 0
45
- end
51
+ # Returns true if exited 0
52
+ def success?
53
+ return false unless run?
54
+ exitcode == 0
55
+ end
46
56
 
47
- # Returns true if the command completed execution and success bits were set.
48
- # Will return false if the command hasn't been executed
49
- def completed?
50
- return false unless run?
51
- status.exited? && @status.success?
52
- end
57
+ # Returns true if the command completed execution and success bits were set.
58
+ # Will return false if the command hasn't been executed
59
+ def completed?
60
+ return false unless run?
61
+ status.exited? && @status.success?
62
+ end
53
63
 
54
- def failure_message
55
- msg = "---------------------\n"
56
- msg << red(output)
57
- msg << "---------------------\n"
58
- msg << "Failed to execute `#{command}`:\n"
59
- msg << "\tPlease check the output above for any errors and make sure that `#{binary}` is installed in your PATH with proper permissions."
60
- msg
61
- end
64
+ def failure_message
65
+ msg = "---------------------\n"
66
+ msg << red(output)
67
+ msg << "---------------------\n"
68
+ msg << "Failed to execute `#{command}`:\n"
69
+ msg << "\tPlease check the output above for any errors and make sure that `#{binary}` is installed in your PATH with proper permissions."
70
+ msg
71
+ end
62
72
 
63
- protected
73
+ protected
64
74
 
65
- def red(message)
66
- "\e[1m\e[31m#{message}\e[0m\e[22m"
75
+ def red(message)
76
+ "\e[1m\e[31m#{message}\e[0m\e[22m"
77
+ end
67
78
  end
68
79
  end
69
80
  end
@@ -1,3 +1,3 @@
1
1
  module Cassie
2
- VERSION = "1.0.0.beta.24"
2
+ VERSION = "1.0.0.beta.25"
3
3
  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.24
4
+ version: 1.0.0.beta.25
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-10-18 00:00:00.000000000 Z
11
+ date: 2016-11-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cassandra-driver
@@ -70,14 +70,14 @@ dependencies:
70
70
  requirements:
71
71
  - - "~>"
72
72
  - !ruby/object:Gem::Version
73
- version: '1.9'
73
+ version: '1.10'
74
74
  type: :development
75
75
  prerelease: false
76
76
  version_requirements: !ruby/object:Gem::Requirement
77
77
  requirements:
78
78
  - - "~>"
79
79
  - !ruby/object:Gem::Version
80
- version: '1.9'
80
+ version: '1.10'
81
81
  description: Cassie provides database configration, versioned migrations, efficient
82
82
  session management, and query classes. This allows applications to use the functionality
83
83
  provided by the official `cassandra-driver` through lightweight and easy to use
@@ -125,6 +125,7 @@ files:
125
125
  - lib/cassie/statements/execution/callbacks.rb
126
126
  - lib/cassie/statements/execution/consistency.rb
127
127
  - lib/cassie/statements/execution/deserialization.rb
128
+ - lib/cassie/statements/execution/errors.rb
128
129
  - lib/cassie/statements/execution/fetching.rb
129
130
  - lib/cassie/statements/execution/instrumentation.rb
130
131
  - lib/cassie/statements/execution/partition_linking.rb
@@ -156,6 +157,7 @@ files:
156
157
  - lib/cassie/statements/statement/assignments.rb
157
158
  - lib/cassie/statements/statement/conditions.rb
158
159
  - lib/cassie/statements/statement/deleting.rb
160
+ - lib/cassie/statements/statement/idempotency.rb
159
161
  - lib/cassie/statements/statement/inserting.rb
160
162
  - lib/cassie/statements/statement/limiting.rb
161
163
  - lib/cassie/statements/statement/mapping.rb
@@ -167,6 +169,7 @@ files:
167
169
  - lib/cassie/statements/statement/relation.rb
168
170
  - lib/cassie/statements/statement/relations.rb
169
171
  - lib/cassie/statements/statement/selection.rb
172
+ - lib/cassie/statements/statement/type_hinting.rb
170
173
  - lib/cassie/statements/statement/updating.rb
171
174
  - lib/cassie/support.rb
172
175
  - lib/cassie/support/command_runner.rb