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.
- checksums.yaml +4 -4
- data/bin/cassie +40 -15
- data/lib/cassie/configuration/templates/cassandra.yml +1 -2
- data/lib/cassie/connection.rb +3 -3
- data/lib/cassie/connection_handler/cluster.rb +1 -1
- data/lib/cassie/connection_handler/sessions.rb +1 -1
- data/lib/cassie/connection_handler.rb +4 -2
- data/lib/cassie/definition.rb +8 -0
- data/lib/cassie/modification.rb +9 -0
- data/lib/cassie/query.rb +3 -15
- data/lib/cassie/statements/README.md +710 -0
- data/lib/cassie/statements/core.rb +23 -0
- data/lib/cassie/{queries/statement/batches.rb → statements/execution/batched_fetching.rb} +7 -11
- data/lib/cassie/{queries/statement → statements/execution}/callbacks.rb +1 -1
- data/lib/cassie/{queries/statement → statements/execution}/consistency.rb +1 -1
- data/lib/cassie/statements/execution/deserialization.rb +13 -0
- data/lib/cassie/{queries/statement → statements/execution}/fetching.rb +10 -21
- data/lib/cassie/{queries/instrumentation/execution.rb → statements/execution/instrumentation.rb} +6 -2
- data/lib/cassie/statements/execution/partition_linking/cursoring_policy.rb +13 -0
- data/lib/cassie/statements/execution/partition_linking/policy_methods.rb +128 -0
- data/lib/cassie/statements/execution/partition_linking/simple_policy.rb +19 -0
- data/lib/cassie/statements/execution/partition_linking.rb +49 -0
- data/lib/cassie/statements/execution/peeking.rb +28 -0
- data/lib/cassie/statements/execution/results/core.rb +11 -0
- data/lib/cassie/statements/execution/results/cursored_result.rb +26 -0
- data/lib/cassie/statements/execution/results/instrumentation.rb +18 -0
- data/lib/cassie/statements/execution/results/modification.rb +12 -0
- data/lib/cassie/statements/execution/results/modification_result.rb +8 -0
- data/lib/cassie/statements/execution/results/peeking.rb +42 -0
- data/lib/cassie/statements/execution/results/peeking_result.rb +10 -0
- data/lib/cassie/statements/execution/results/query_result.rb +9 -0
- data/lib/cassie/statements/execution/results/querying.rb +66 -0
- data/lib/cassie/statements/execution/results/result.rb +23 -0
- data/lib/cassie/statements/execution/results.rb +12 -0
- data/lib/cassie/statements/execution.rb +69 -0
- data/lib/cassie/statements/instrumenting.rb +6 -0
- data/lib/cassie/{queries/logging/building_resources_event.rb → statements/logging/deserialize_event.rb} +4 -4
- data/lib/cassie/statements/logging/deserialize_subscriber.rb +19 -0
- data/lib/cassie/{queries/logging/cql_execution_event.rb → statements/logging/execute_event.rb} +8 -4
- data/lib/cassie/statements/logging/execute_subscriber.rb +19 -0
- data/lib/cassie/statements/logging.rb +12 -0
- data/lib/cassie/statements/modification.rb +14 -0
- data/lib/cassie/statements/query.rb +12 -0
- data/lib/cassie/statements/statement/assignment.rb +51 -0
- data/lib/cassie/statements/statement/assignments.rb +87 -0
- data/lib/cassie/{queries → statements}/statement/conditions.rb +1 -3
- data/lib/cassie/{queries → statements}/statement/deleting.rb +15 -12
- data/lib/cassie/{queries → statements}/statement/inserting.rb +13 -10
- data/lib/cassie/statements/statement/limiting.rb +89 -0
- data/lib/cassie/{queries → statements}/statement/mapping.rb +21 -41
- data/lib/cassie/{queries → statements}/statement/ordering.rb +1 -1
- data/lib/cassie/statements/statement/pagination/cursors.rb +112 -0
- data/lib/cassie/statements/statement/pagination.rb +19 -0
- data/lib/cassie/{queries → statements}/statement/preparation/cache.rb +1 -1
- data/lib/cassie/{queries → statements}/statement/preparation.rb +4 -5
- data/lib/cassie/statements/statement/relation.rb +68 -0
- data/lib/cassie/statements/statement/relations.rb +93 -0
- data/lib/cassie/statements/statement/selection.rb +86 -0
- data/lib/cassie/{queries → statements}/statement/updating.rb +9 -10
- data/lib/cassie/{queries → statements}/statement.rb +10 -20
- data/lib/cassie/statements.rb +9 -0
- data/lib/cassie/testing/fake/definition.rb +11 -0
- data/lib/cassie/testing/fake/modification.rb +11 -0
- data/lib/cassie/testing/fake/result.rb +15 -3
- data/lib/cassie/testing.rb +2 -0
- data/lib/cassie.rb +2 -0
- metadata +57 -34
- data/lib/cassie/queries/README.md +0 -458
- data/lib/cassie/queries/instrumentation/loading.rb +0 -15
- data/lib/cassie/queries/instrumentation.rb +0 -18
- data/lib/cassie/queries/logging/subscription.rb +0 -24
- data/lib/cassie/queries/logging.rb +0 -21
- data/lib/cassie/queries/statement/assignment.rb +0 -36
- data/lib/cassie/queries/statement/assignments.rb +0 -67
- data/lib/cassie/queries/statement/execution.rb +0 -45
- data/lib/cassie/queries/statement/limiting.rb +0 -36
- data/lib/cassie/queries/statement/loading.rb +0 -24
- data/lib/cassie/queries/statement/pagination/cursors.rb +0 -168
- data/lib/cassie/queries/statement/pagination/page_size.rb +0 -7
- data/lib/cassie/queries/statement/pagination.rb +0 -37
- data/lib/cassie/queries/statement/relation.rb +0 -74
- data/lib/cassie/queries/statement/relations.rb +0 -66
- data/lib/cassie/queries/statement/selection.rb +0 -63
@@ -0,0 +1,69 @@
|
|
1
|
+
module Cassie::Statements
|
2
|
+
module Execution
|
3
|
+
require_relative 'execution/consistency'
|
4
|
+
require_relative 'execution/callbacks'
|
5
|
+
require_relative 'execution/results'
|
6
|
+
require_relative 'execution/partition_linking'
|
7
|
+
require_relative 'execution/instrumentation'
|
8
|
+
|
9
|
+
extend ActiveSupport::Concern
|
10
|
+
included do
|
11
|
+
attr_reader :result
|
12
|
+
|
13
|
+
include Consistency
|
14
|
+
include Callbacks
|
15
|
+
include PartitionLinking
|
16
|
+
include Instrumentation
|
17
|
+
end
|
18
|
+
|
19
|
+
module ClassMethods
|
20
|
+
def inherited(subclass)
|
21
|
+
subclass.result_class = result_class if defined?(@result_class)
|
22
|
+
super
|
23
|
+
end
|
24
|
+
|
25
|
+
def result_class
|
26
|
+
return @result_class if defined?(@result_class)
|
27
|
+
Cassie::Statements::Results::Result
|
28
|
+
end
|
29
|
+
|
30
|
+
def result_class=(val)
|
31
|
+
@result_class = val
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Executes the statment, populates result
|
36
|
+
# returns true or false indicating a successful execution or not
|
37
|
+
def execute
|
38
|
+
@result = result_class.new(session.execute(statement, execution_options), result_opts)
|
39
|
+
result.success?
|
40
|
+
end
|
41
|
+
|
42
|
+
def execution_options
|
43
|
+
{}.tap do |opts|
|
44
|
+
#TODO: rework consistency module to be more
|
45
|
+
# abstract implementation for all execution options
|
46
|
+
opts[:consistency] = consistency if consistency
|
47
|
+
opts[:paging_state] = paging_state if respond_to?(:paging_state) && paging_state
|
48
|
+
opts[:page_size] = stateless_page_size if respond_to?(:stateless_page_size) && stateless_page_size
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
protected
|
53
|
+
|
54
|
+
def result_class
|
55
|
+
self.class.result_class
|
56
|
+
end
|
57
|
+
|
58
|
+
def result_opts
|
59
|
+
{}
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def initialize_copy(other)
|
65
|
+
super
|
66
|
+
@result = nil
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
|
-
module Cassie::
|
2
|
-
class
|
1
|
+
module Cassie::Statements::Logging
|
2
|
+
class DeserializeEvent < ActiveSupport::Notifications::Event
|
3
3
|
|
4
4
|
def count
|
5
5
|
payload[:count]
|
@@ -7,7 +7,7 @@ module Cassie::Queries::Logging
|
|
7
7
|
|
8
8
|
def message
|
9
9
|
{
|
10
|
-
event: "cassie.
|
10
|
+
event: "cassie.deserialize",
|
11
11
|
duration: duration.round(1),
|
12
12
|
count: count
|
13
13
|
}.extend(Inspector)
|
@@ -15,7 +15,7 @@ module Cassie::Queries::Logging
|
|
15
15
|
|
16
16
|
module Inspector
|
17
17
|
def inspect
|
18
|
-
color("(#{fetch(:duration).round(1)}ms) #{fetch(:count)}
|
18
|
+
color("(#{fetch(:duration).round(1)}ms) #{fetch(:count)} #{'result'.pluralize(fetch(:count))} deserialized from Cassandra rows")
|
19
19
|
end
|
20
20
|
|
21
21
|
def to_s
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require_relative 'deserialize_event'
|
2
|
+
|
3
|
+
module Cassie::Statements::Logging
|
4
|
+
class DeserializeSubscriber
|
5
|
+
|
6
|
+
def call(*args)
|
7
|
+
# don't log if instrumentation failed
|
8
|
+
unless args.last[:exception]
|
9
|
+
logger.debug(DeserializeEvent.new(*args).message)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def logger
|
14
|
+
Cassie::Statements.logger
|
15
|
+
end
|
16
|
+
|
17
|
+
ActiveSupport::Notifications.subscribe('cassie.deserialize', new)
|
18
|
+
end
|
19
|
+
end
|
data/lib/cassie/{queries/logging/cql_execution_event.rb → statements/logging/execute_event.rb}
RENAMED
@@ -1,5 +1,5 @@
|
|
1
|
-
module Cassie::
|
2
|
-
class
|
1
|
+
module Cassie::Statements::Logging
|
2
|
+
class ExecuteEvent < ActiveSupport::Notifications::Event
|
3
3
|
|
4
4
|
def duration # in milliseconds
|
5
5
|
return super unless traced?
|
@@ -26,8 +26,12 @@ module Cassie::Queries::Logging
|
|
26
26
|
def statement
|
27
27
|
if execution_info
|
28
28
|
statement = execution_info.statement
|
29
|
-
|
30
|
-
|
29
|
+
if statement.respond_to? :cql
|
30
|
+
str = statement.cql.dup
|
31
|
+
str << " #{statement.params.map(&:to_s)}" if statement.respond_to? :params
|
32
|
+
else
|
33
|
+
str = statement.to_s
|
34
|
+
end
|
31
35
|
str
|
32
36
|
else
|
33
37
|
"CQL executed: (`execution_info` was not present?)"
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require_relative 'execute_event'
|
2
|
+
|
3
|
+
module Cassie::Statements::Logging
|
4
|
+
class ExecuteSubscriber
|
5
|
+
|
6
|
+
def call(*args)
|
7
|
+
# don't log if instrumentation failed
|
8
|
+
unless args.last[:exception]
|
9
|
+
logger.debug(ExecuteEvent.new(*args).message)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def logger
|
14
|
+
Cassie::Statements.logger
|
15
|
+
end
|
16
|
+
|
17
|
+
ActiveSupport::Notifications.subscribe('cassie.cql.execution', new)
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Cassie::Statements
|
2
|
+
require_relative 'logging/execute_subscriber'
|
3
|
+
require_relative 'logging/deserialize_subscriber'
|
4
|
+
|
5
|
+
def self.logger
|
6
|
+
@logger ||= Cassie.logger
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.logger=(new_logger)
|
10
|
+
@logger = new_logger || ::Logger.new('/dev/null')
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Cassie::Statements
|
2
|
+
require_relative 'statement/inserting'
|
3
|
+
require_relative 'statement/updating'
|
4
|
+
require_relative 'statement/deleting'
|
5
|
+
module Modification
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
include Statement::Updating
|
10
|
+
include Statement::Deleting
|
11
|
+
include Statement::Inserting
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Cassie::Statements::Statement
|
2
|
+
# set "username = ?", value: :username
|
3
|
+
# set :favs, term: 'favs + ?', value: "{ 'movie' : 'Cassablanca' }"
|
4
|
+
# set :username
|
5
|
+
class Assignment
|
6
|
+
# https://cassandra.apache.org/doc/cql3/CQL.html#updateStmt
|
7
|
+
|
8
|
+
attr_reader :source,
|
9
|
+
:identifier,
|
10
|
+
:value,
|
11
|
+
:enabled,
|
12
|
+
:term
|
13
|
+
|
14
|
+
def initialize(source, identifier, value_method, opts={})
|
15
|
+
@source = source
|
16
|
+
@identifier = identifier
|
17
|
+
@value = source.send(value_method)
|
18
|
+
@enabled = opts.has_key?(:if) ? source_eval(opts[:if]) : true
|
19
|
+
@term = opts.has_key?(:term) ? source_eval(opts[:term]) : "?"
|
20
|
+
end
|
21
|
+
|
22
|
+
def enabled?
|
23
|
+
!!enabled
|
24
|
+
end
|
25
|
+
|
26
|
+
def argument
|
27
|
+
return nil unless enabled? && positional?
|
28
|
+
value
|
29
|
+
end
|
30
|
+
|
31
|
+
def positional?
|
32
|
+
term.to_s.include?("?")
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_update_cql
|
36
|
+
return nil unless enabled?
|
37
|
+
"#{identifier} = #{term}"
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def source_eval(value, _source=source)
|
43
|
+
case value
|
44
|
+
when Symbol
|
45
|
+
_source.send(value)
|
46
|
+
else
|
47
|
+
value
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require_relative 'assignment'
|
2
|
+
require_relative 'mapping'
|
3
|
+
|
4
|
+
module Cassie::Statements::Statement
|
5
|
+
# Provides support for a set of CQL assignments
|
6
|
+
# and building the insert/update clause and argument list
|
7
|
+
# for a cql statement
|
8
|
+
#
|
9
|
+
# CQL Relation terminology:
|
10
|
+
#
|
11
|
+
# "INSERT INTO table (id, username) VALUES (?, ?);", [1, 'eprothro']
|
12
|
+
#
|
13
|
+
# identifiers: ['id', 'username']
|
14
|
+
# terms: ['?', '?']
|
15
|
+
# arguments: [1, 'eprothro']
|
16
|
+
#
|
17
|
+
# "UPDATE table SET id = ?, username = ? WHERE...;", [1, 'eprothro']
|
18
|
+
#
|
19
|
+
# identifiers: ['id', 'username']
|
20
|
+
# terms: ['?', '?']
|
21
|
+
# arguments: [1, 'eprothro']
|
22
|
+
module Assignments
|
23
|
+
extend ActiveSupport::Concern
|
24
|
+
|
25
|
+
included do
|
26
|
+
include Mapping
|
27
|
+
end
|
28
|
+
|
29
|
+
module ClassMethods
|
30
|
+
def set(identifier, opts={})
|
31
|
+
opts[:value] ||= identifier.to_sym
|
32
|
+
|
33
|
+
define_argument_accessor(opts[:value])
|
34
|
+
|
35
|
+
assignments_args << [identifier, opts.delete(:value), opts]
|
36
|
+
end
|
37
|
+
|
38
|
+
def assignments_args
|
39
|
+
@assignments_args ||= []
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def assignments_args
|
44
|
+
self.class.assignments_args
|
45
|
+
end
|
46
|
+
|
47
|
+
def build_update_and_bindings
|
48
|
+
cql = ""
|
49
|
+
arguments = []
|
50
|
+
assignment_strings = []
|
51
|
+
|
52
|
+
assignments_args.each do |args|
|
53
|
+
a = Assignment.new(self, *args)
|
54
|
+
assignment_strings += Array(a.to_update_cql)
|
55
|
+
arguments += Array(a.argument)
|
56
|
+
end
|
57
|
+
|
58
|
+
cql = assignment_strings.join(', ')
|
59
|
+
|
60
|
+
[cql , arguments]
|
61
|
+
end
|
62
|
+
|
63
|
+
def build_insert_and_bindings
|
64
|
+
identifiers = []
|
65
|
+
terms = []
|
66
|
+
arguments = []
|
67
|
+
|
68
|
+
assignments_args.each do |args|
|
69
|
+
a = Assignment.new(self, *args)
|
70
|
+
identifiers += Array(a.identifier)
|
71
|
+
terms += Array(a.term)
|
72
|
+
arguments += Array(a.argument)
|
73
|
+
end
|
74
|
+
|
75
|
+
identifiers_cql = identifiers.join(", ")
|
76
|
+
terms_cql = terms.join(", ")
|
77
|
+
|
78
|
+
# (indentifier, identifier)
|
79
|
+
# VALUES
|
80
|
+
# (term, term);
|
81
|
+
# (identifiers_cql)
|
82
|
+
# VALUES
|
83
|
+
# (terms_cql);
|
84
|
+
[identifiers_cql, terms_cql , arguments]
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -2,26 +2,34 @@ require_relative 'relations'
|
|
2
2
|
require_relative 'conditions'
|
3
3
|
require_relative 'mapping'
|
4
4
|
|
5
|
-
module Cassie::
|
5
|
+
module Cassie::Statements::Statement
|
6
6
|
module Deleting
|
7
7
|
extend ::ActiveSupport::Concern
|
8
8
|
|
9
|
+
included do
|
10
|
+
include Relations
|
11
|
+
include Conditions
|
12
|
+
include Mapping
|
13
|
+
|
14
|
+
@result_class = Cassie::Statements::Results::ModificationResult
|
15
|
+
end
|
16
|
+
|
9
17
|
module ClassMethods
|
10
18
|
#TODO: accept block to add specific selectors and aliases
|
11
|
-
#
|
19
|
+
# select_from :table do |t|
|
12
20
|
# t.id
|
13
21
|
# t.name as: :username
|
14
22
|
# end
|
15
|
-
def
|
16
|
-
include Relations
|
17
|
-
include Conditions
|
18
|
-
include Mapping
|
19
|
-
|
23
|
+
def delete_from(table)
|
20
24
|
self.table = table
|
21
25
|
self.type = :delete
|
22
26
|
|
23
27
|
yield(self) if block_given?
|
24
28
|
end
|
29
|
+
def delete(table)
|
30
|
+
Cassie.logger.warn "[DEPRECATION] `Cassie::Modification#delete` has been replaced by `delete_from` and will be removed."
|
31
|
+
delete_from(table)
|
32
|
+
end
|
25
33
|
|
26
34
|
# TODO rename to identifiers and extract
|
27
35
|
def selectors
|
@@ -29,11 +37,6 @@ module Cassie::Queries::Statement
|
|
29
37
|
end
|
30
38
|
end
|
31
39
|
|
32
|
-
def delete(opts={})
|
33
|
-
execute
|
34
|
-
execution_successful?
|
35
|
-
end
|
36
|
-
|
37
40
|
protected
|
38
41
|
|
39
42
|
def build_delete_cql_and_bindings
|
@@ -1,25 +1,28 @@
|
|
1
1
|
require_relative 'assignments'
|
2
2
|
require_relative 'conditions'
|
3
3
|
|
4
|
-
module Cassie::
|
4
|
+
module Cassie::Statements::Statement
|
5
5
|
module Inserting
|
6
6
|
extend ::ActiveSupport::Concern
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
include Conditions
|
8
|
+
included do
|
9
|
+
include Assignments
|
10
|
+
include Conditions
|
12
11
|
|
12
|
+
@result_class = Cassie::Statements::Results::ModificationResult
|
13
|
+
end
|
14
|
+
|
15
|
+
module ClassMethods
|
16
|
+
def insert_into(table)
|
13
17
|
self.table = table
|
14
18
|
self.type = :insert
|
15
19
|
|
16
20
|
yield(self) if block_given?
|
17
21
|
end
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
execution_successful?
|
22
|
+
def insert(table)
|
23
|
+
Cassie.logger.warn "[DEPRECATION] `Cassie::Modification#insert` has been replaced by `insert_into` and will be removed."
|
24
|
+
insert_into(table)
|
25
|
+
end
|
23
26
|
end
|
24
27
|
|
25
28
|
protected
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module Cassie::Statements
|
2
|
+
def self.default_limit
|
3
|
+
return @default_limit if defined?(@default_limit)
|
4
|
+
500
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.default_limit=(val)
|
8
|
+
@default_limit = val
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
module Statement::Limiting
|
13
|
+
extend ActiveSupport::Concern
|
14
|
+
|
15
|
+
included do
|
16
|
+
attr_writer :limit
|
17
|
+
end
|
18
|
+
|
19
|
+
module ClassMethods
|
20
|
+
def inherited(subclass)
|
21
|
+
subclass.limit = limit if defined?(@limit)
|
22
|
+
super
|
23
|
+
end
|
24
|
+
|
25
|
+
def limit=(val)
|
26
|
+
@limit = val
|
27
|
+
end
|
28
|
+
|
29
|
+
def limit(val=:get)
|
30
|
+
if val == :get
|
31
|
+
return @limit if defined?(@limit)
|
32
|
+
Cassie::Statements.default_limit
|
33
|
+
else
|
34
|
+
self.limit = val
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def limit
|
40
|
+
return @limit if defined?(@limit)
|
41
|
+
self.class.limit
|
42
|
+
end
|
43
|
+
|
44
|
+
def with_limit(temp_limit)
|
45
|
+
raise ArgumentError, "block required for passing temporary limit" unless block_given?
|
46
|
+
define_limit_singleton(temp_limit)
|
47
|
+
|
48
|
+
yield
|
49
|
+
ensure
|
50
|
+
remove_limit_singleton
|
51
|
+
end
|
52
|
+
|
53
|
+
protected
|
54
|
+
|
55
|
+
def build_limit_str
|
56
|
+
return "" if limit.nil?
|
57
|
+
|
58
|
+
"LIMIT #{limit}"
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def initialize_copy(other)
|
64
|
+
super
|
65
|
+
remove_limit_singleton
|
66
|
+
end
|
67
|
+
|
68
|
+
def define_limit_singleton(temp_limit)
|
69
|
+
assert_no_limit_singleton
|
70
|
+
define_singleton_method(:limit) do
|
71
|
+
temp_limit
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def remove_limit_singleton
|
76
|
+
if singleton_methods.include?(:limit)
|
77
|
+
class << self
|
78
|
+
remove_method :limit
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def assert_no_limit_singleton
|
84
|
+
if singleton_methods.include?(:limit)
|
85
|
+
raise NameError.new("A singleton method has already been defined for `limit`. `with_limit` can't be implemented.", :limit)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -1,37 +1,12 @@
|
|
1
|
-
module Cassie::
|
1
|
+
module Cassie::Statements::Statement
|
2
2
|
module Mapping
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
|
-
MAPPED_METHODS = [:insert, :update, :delete].freeze
|
6
|
-
|
7
5
|
included do
|
8
|
-
# We are mapping term values from a client
|
6
|
+
# We are mapping term values from a client provided resource.
|
9
7
|
# store this object in `_resource` attribte
|
10
8
|
# as they could reasonably want to name it `resource`
|
11
9
|
attr_accessor :_resource
|
12
|
-
|
13
|
-
#TODO: consider simplifying by overriding
|
14
|
-
# `execute` and aliasing via mapped methods
|
15
|
-
MAPPED_METHODS.each do |method|
|
16
|
-
# overwrite mapper methods that are defined (yuk)
|
17
|
-
next if !method_defined?(method)
|
18
|
-
|
19
|
-
define_method(method) do |value=nil, opts={}|
|
20
|
-
if value.nil?
|
21
|
-
# if no mapping is taking place, keep previously
|
22
|
-
# defined behavior/return value
|
23
|
-
return super(opts) if _resource.nil?
|
24
|
-
else
|
25
|
-
self._resource = value
|
26
|
-
end
|
27
|
-
|
28
|
-
if super(opts)
|
29
|
-
_resource
|
30
|
-
else
|
31
|
-
false
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
10
|
end
|
36
11
|
|
37
12
|
module ClassMethods
|
@@ -47,18 +22,22 @@ module Cassie::Queries::Statement
|
|
47
22
|
|
48
23
|
protected
|
49
24
|
|
50
|
-
#
|
51
|
-
# methods
|
25
|
+
# override definition of getter and setter
|
26
|
+
# methods to look up argument values
|
52
27
|
# from resource object
|
53
|
-
def
|
54
|
-
|
55
|
-
|
28
|
+
def define_argument_accessor(name)
|
29
|
+
unless Symbol === name
|
30
|
+
raise ArgumentError, "A Symbol is required for the accessor methods for setting/getting a relation's value. #{name.class} (#{name}) given."
|
31
|
+
end
|
32
|
+
|
33
|
+
getter = name
|
34
|
+
setter = "#{name}="
|
56
35
|
|
57
36
|
if method_defined?(getter) || method_defined?(setter)
|
58
|
-
raise "accessor or getter already defined for #{
|
37
|
+
raise "accessor or getter already defined for #{name}. Fix the collisions by using the `:value` option."
|
59
38
|
else
|
60
39
|
# Order of prefrence for finding term value
|
61
|
-
# 1.
|
40
|
+
# 1. overwritten getter instance method
|
62
41
|
# def id
|
63
42
|
# "some constant"
|
64
43
|
# end
|
@@ -71,28 +50,29 @@ module Cassie::Queries::Statement
|
|
71
50
|
# query.id
|
72
51
|
# => 105
|
73
52
|
define_method getter do
|
74
|
-
# 1 is handled by definition
|
53
|
+
# 1 is handled by overwritten definition
|
75
54
|
|
76
55
|
# 2: prefer instance value
|
77
|
-
if instance_variable_defined?("@#{
|
78
|
-
return instance_variable_get("@#{
|
56
|
+
if instance_variable_defined?("@#{name}")
|
57
|
+
return instance_variable_get("@#{name}")
|
79
58
|
end
|
80
59
|
|
81
60
|
# 3: fetch from resource
|
82
|
-
if _resource && _resource.respond_to?(
|
83
|
-
_resource.send(
|
61
|
+
if _resource && _resource.respond_to?(name)
|
62
|
+
_resource.send(name)
|
84
63
|
end
|
85
64
|
end
|
86
65
|
|
87
66
|
# query.id = 'some val'
|
88
|
-
#
|
67
|
+
# initialize underlying instance var
|
89
68
|
# which is preferred over resource object attribute
|
90
69
|
#
|
91
70
|
# Issue: if client defines value for attribute
|
92
71
|
# they might assume later setting to nil would
|
93
72
|
# revert to behavior of fetching from resource object attribute
|
94
73
|
# but that is not the case since the variable is defined
|
95
|
-
|
74
|
+
# and we can't know they didn't want the value of 'nil' to be used
|
75
|
+
attr_writer name
|
96
76
|
end
|
97
77
|
end
|
98
78
|
end
|