cassie 1.0.0.beta.33 → 1.0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/cassie +8 -181
- data/lib/cassie/configuration/core.rb +26 -3
- data/lib/cassie/configuration/generator.rb +1 -0
- data/lib/cassie/configuration/loading.rb +5 -2
- data/lib/cassie/configuration.rb +1 -0
- data/lib/cassie/connection.rb +13 -7
- data/lib/cassie/connection_handler/README.md +13 -3
- data/lib/cassie/connection_handler/cluster.rb +11 -0
- data/lib/cassie/connection_handler/sessions.rb +9 -0
- data/lib/cassie/connection_handler.rb +8 -7
- data/lib/cassie/definition.rb +28 -0
- data/lib/cassie/extensions/object/color_methods.rb +21 -0
- data/lib/cassie/instrumentation.rb +4 -0
- data/lib/cassie/modification.rb +29 -0
- data/lib/cassie/query.rb +27 -0
- data/lib/cassie/schema/README.md +306 -0
- data/lib/cassie/schema/apply_command.rb +24 -0
- data/lib/cassie/schema/cassandra_migrations/importer.rb +91 -0
- data/lib/cassie/schema/cassandra_migrations/migration_file.rb +51 -0
- data/lib/cassie/schema/configuration.rb +35 -0
- data/lib/cassie/schema/migration/cassandra_support.rb +34 -0
- data/lib/cassie/schema/migration/dsl/announcing.rb +47 -0
- data/lib/cassie/schema/migration/dsl/column_operations.rb +42 -0
- data/lib/cassie/schema/migration/dsl/table_definition.rb +299 -0
- data/lib/cassie/schema/migration/dsl/table_operations.rb +64 -0
- data/lib/cassie/schema/migration/dsl.rb +17 -0
- data/lib/cassie/schema/migration.rb +12 -0
- data/lib/cassie/schema/migrator.rb +115 -0
- data/lib/cassie/schema/queries/create_keyspace_query.rb +26 -0
- data/lib/cassie/{migration → schema}/queries/create_versions_table_query.rb +6 -6
- data/lib/cassie/schema/queries/delete_version_query.rb +17 -0
- data/lib/cassie/schema/queries/drop_keyspace_query.rb +14 -0
- data/lib/cassie/schema/queries/insert_version_query.rb +22 -0
- data/lib/cassie/schema/queries/select_versions_query.rb +18 -0
- data/lib/cassie/{migration → schema}/queries.rb +4 -2
- data/lib/cassie/schema/rollback_command.rb +24 -0
- data/lib/cassie/schema/structure_dumper.rb +117 -0
- data/lib/cassie/{migration → schema}/structure_loader.rb +3 -3
- data/lib/cassie/schema/version.rb +143 -0
- data/lib/cassie/schema/version_file_loader.rb +34 -0
- data/lib/cassie/schema/version_loader.rb +31 -0
- data/lib/cassie/schema/version_object_loader.rb +19 -0
- data/lib/cassie/schema/version_writer.rb +108 -0
- data/lib/cassie/schema/versioning.rb +162 -0
- data/lib/cassie/schema.rb +24 -0
- data/lib/cassie/statements/README.md +61 -9
- data/lib/cassie/statements/core.rb +16 -5
- data/lib/cassie/statements/execution/results/core.rb +1 -1
- data/lib/cassie/statements/execution/results/modification_result.rb +1 -1
- data/lib/cassie/statements/execution/results/query_result.rb +1 -1
- data/lib/cassie/statements/execution.rb +40 -13
- data/lib/cassie/statements/statement/assignments.rb +33 -3
- data/lib/cassie/statements/statement/conditions.rb +3 -1
- data/lib/cassie/statements/statement/deleting.rb +27 -19
- data/lib/cassie/statements/statement/idempotency.rb +23 -4
- data/lib/cassie/statements/statement/inserting.rb +17 -10
- data/lib/cassie/statements/statement/limiting.rb +5 -2
- data/lib/cassie/statements/statement/mapping.rb +34 -6
- data/lib/cassie/statements/statement/preparation/cache.rb +1 -1
- data/lib/cassie/statements/statement/preparation.rb +37 -7
- data/lib/cassie/statements/statement/relations.rb +29 -8
- data/lib/cassie/statements/statement/selection.rb +51 -15
- data/lib/cassie/statements/statement/type_hinting.rb +12 -4
- data/lib/cassie/statements/statement/updating.rb +22 -8
- data/lib/cassie/statements/statement.rb +39 -14
- data/lib/cassie/statements.rb +12 -0
- data/lib/cassie/support/server_process.rb +117 -0
- data/lib/cassie/support/statement_parser.rb +3 -5
- data/lib/cassie/support/{command_runner.rb → system_command.rb} +22 -13
- data/lib/cassie/support.rb +3 -1
- data/lib/cassie/tasks/configuration/generate.rake +35 -0
- data/lib/cassie/tasks/io.rb +15 -0
- data/lib/cassie/tasks/migration/create.rake +49 -0
- data/lib/cassie/tasks/migration/import.rake +39 -0
- data/lib/cassie/tasks/migration/reset.rake +9 -0
- data/lib/cassie/tasks/restart.rake +5 -0
- data/lib/cassie/tasks/schema/drop.rake +28 -0
- data/lib/cassie/tasks/schema/dump.rake +21 -0
- data/lib/cassie/tasks/schema/history.rake +18 -0
- data/lib/cassie/tasks/schema/import.rake +40 -0
- data/lib/cassie/tasks/schema/init.rake +54 -0
- data/lib/cassie/tasks/schema/load.rake +19 -0
- data/lib/cassie/tasks/schema/migrate.rake +42 -0
- data/lib/cassie/tasks/schema/reset.rake +6 -0
- data/lib/cassie/tasks/schema/status.rake +19 -0
- data/lib/cassie/tasks/schema/version.rake +18 -0
- data/lib/cassie/tasks/schema/version_display.rb +50 -0
- data/lib/cassie/tasks/start.rake +17 -0
- data/lib/cassie/tasks/stop.rake +33 -0
- data/lib/cassie/tasks/tail.rake +14 -0
- data/lib/cassie/tasks/task_runner.rb +49 -0
- data/lib/cassie/tasks.rb +18 -0
- data/lib/cassie/testing/fake/execution_info.rb +1 -1
- data/lib/cassie/testing/fake/result.rb +3 -3
- data/lib/cassie/testing.rb +4 -0
- data/lib/cassie/version.rb +1 -1
- data/lib/cassie.rb +4 -1
- metadata +73 -17
- data/lib/cassie/migration/README.md +0 -141
- data/lib/cassie/migration/configuration.rb +0 -18
- data/lib/cassie/migration/initialization.rb +0 -70
- data/lib/cassie/migration/queries/create_schema_keyspace_query.rb +0 -17
- data/lib/cassie/migration/queries/insert_version_query.rb +0 -23
- data/lib/cassie/migration/queries/select_versions_query.rb +0 -14
- data/lib/cassie/migration/structure_dumper.rb +0 -94
- data/lib/cassie/migration/version.rb +0 -4
- data/lib/cassie/migration.rb +0 -30
@@ -16,7 +16,9 @@ Cassie.insert(:users_by_username,
|
|
16
16
|
"id = #{some_id}",
|
17
17
|
username: some_username)
|
18
18
|
```
|
19
|
+
|
19
20
|
or
|
21
|
+
|
20
22
|
```
|
21
23
|
Cassie.select_from(:table)
|
22
24
|
.where(id: some_id)
|
@@ -24,6 +26,7 @@ Cassie.select_from(:table)
|
|
24
26
|
```
|
25
27
|
|
26
28
|
Queries defined on the fly like this tend to create debt for an application in the long term. They:
|
29
|
+
|
27
30
|
* create gaps in test coverage
|
28
31
|
* lack clear documentation
|
29
32
|
* resist refactoring
|
@@ -327,6 +330,7 @@ which is the same as
|
|
327
330
|
|
328
331
|
select count
|
329
332
|
```
|
333
|
+
|
330
334
|
```
|
331
335
|
#=> SELECT COUNT(*) FROM posts_by_author;
|
332
336
|
```
|
@@ -339,9 +343,11 @@ Aliasing is supported with the `as` option.
|
|
339
343
|
select ttl(:popular)
|
340
344
|
select writetime(:popular), as: :created_at
|
341
345
|
```
|
346
|
+
|
342
347
|
```
|
343
348
|
#=> SELECT id, TTL(popular), WRITETIME(popular) AS created_at FROM posts_by_author;
|
344
349
|
```
|
350
|
+
|
345
351
|
Arbitrary strings are supported as well in case the DSL gets in the way.
|
346
352
|
|
347
353
|
```ruby
|
@@ -350,6 +356,7 @@ Arbitrary strings are supported as well in case the DSL gets in the way.
|
|
350
356
|
select 'cowboy, coder'
|
351
357
|
```
|
352
358
|
```
|
359
|
+
|
353
360
|
#=> SELECT cowboy, coder FROM posts_by_author;
|
354
361
|
```
|
355
362
|
|
@@ -362,6 +369,7 @@ By default, all columns for specified CQL rows will be deleted. Identify a subse
|
|
362
369
|
column :nickname
|
363
370
|
where :id, :eq
|
364
371
|
```
|
372
|
+
|
365
373
|
```
|
366
374
|
#=> DELETE nickname FROM authors_by_id where id = 123;
|
367
375
|
```
|
@@ -378,6 +386,7 @@ query.result.class
|
|
378
386
|
```
|
379
387
|
|
380
388
|
The result lazily enumerates domain objects
|
389
|
+
|
381
390
|
```ruby
|
382
391
|
query.execute
|
383
392
|
#=> true
|
@@ -386,6 +395,7 @@ query.result.each
|
|
386
395
|
```
|
387
396
|
|
388
397
|
The result has a `first!` method that raises if no result is available
|
398
|
+
|
389
399
|
```ruby
|
390
400
|
query.execute
|
391
401
|
#=> true
|
@@ -393,7 +403,8 @@ query.result.first!
|
|
393
403
|
Cassie::Statements::RecordNotFound: CQL row does not exist
|
394
404
|
```
|
395
405
|
|
396
|
-
The result delegates to the `Cassandra::Result
|
406
|
+
The result delegates to the `Cassandra::Result`
|
407
|
+
|
397
408
|
```ruby
|
398
409
|
query.result.execution_info
|
399
410
|
#=> #<Cassandra::Execution::Info:0x007fb404b51390 @payload=nil, @warnings=nil, @keyspace="cassie_test", @statement=#<Cassandra::Statements::Bound:0x3fda0258dee8 @cql="SELECT * FROM users_by_username LIMIT 500;" @params=[]>, @options=#<Cassandra::Execution::Options:0x007fb404b1b880 @consistency=:local_one, @page_size=10000, @trace=false, @timeout=12, @serial_consistency=nil, @arguments=[], @type_hints=[], @paging_state=nil, @idempotent=false, @payload=nil>, @hosts=[#<Cassandra::Host:0x3fda02541390 @ip=127.0.0.1>], @consistency=:local_one, @retries=0, @trace=nil>
|
@@ -489,7 +500,7 @@ UsersByUsernameQuery.new.fetch_first!(username: "eprothro").username
|
|
489
500
|
#=> "eprothro"
|
490
501
|
```
|
491
502
|
|
492
|
-
Most applications will want to
|
503
|
+
Most applications will want to provide a `build_result` method to construct more useful domain objects
|
493
504
|
|
494
505
|
```ruby
|
495
506
|
class UsersByUsernameQuery < Cassie::Query
|
@@ -509,7 +520,7 @@ UsersByUsernameQuery.new.fetch_first(username: "eprothro")
|
|
509
520
|
#=> #<User:0x007fedec219cd8 @id=123, @username="eprothro">
|
510
521
|
```
|
511
522
|
|
512
|
-
`build_results` may be
|
523
|
+
`build_results` may be provided as well to define custom definition of the enumeration of rows returned from Cassandra.
|
513
524
|
|
514
525
|
#### Cursored paging
|
515
526
|
|
@@ -625,6 +636,7 @@ class RecordsByOwnerQuery < Cassie::Query
|
|
625
636
|
end
|
626
637
|
end
|
627
638
|
```
|
639
|
+
|
628
640
|
```ruby
|
629
641
|
RecordsByOwnerQuery.new(owner: owner, min_record: 99,990).fetch.map(&:record)
|
630
642
|
(2.9ms) SELECT * FROM records_by_owner WHERE owner_id = ? AND bucket = ? AND record >= ? LIMIT 100; [123, 0, 99990]
|
@@ -638,9 +650,38 @@ By default, this works for ascending and descending orderings when paging in the
|
|
638
650
|
|
639
651
|
Custom policies can be defined by setting `Query.partition_linker` for more complex schemas. See the `SimplePolicy` source for an example.
|
640
652
|
|
641
|
-
#### Consistency configuration
|
642
653
|
|
643
|
-
|
654
|
+
#### Connection options
|
655
|
+
|
656
|
+
Options are searched for in the following order:
|
657
|
+
|
658
|
+
1. the object instance value
|
659
|
+
2. the class instance value
|
660
|
+
3. the `Cassie` instance value
|
661
|
+
4. the `Cassie::configuruation[:option]` value
|
662
|
+
5. the `Cassandra::cluster` value (default cassandra driver value)
|
663
|
+
|
664
|
+
Connection options include:
|
665
|
+
|
666
|
+
* `keyspace`
|
667
|
+
|
668
|
+
See the [Connection Readme](./lib/cassie/configuration/README.md#connection-options) for additional information. Cassie query superclasses include `Cassie::Connection`.
|
669
|
+
|
670
|
+
#### Statement options
|
671
|
+
|
672
|
+
Like connection options, statement options offer a similar fallback chain for flexibility.
|
673
|
+
|
674
|
+
1. the object instance value
|
675
|
+
2. the class instance value (e.g. the class inheriting from `Cassie::Query`, `Cassie::Modification`, etc)
|
676
|
+
3. the superclass instance value (e.g. `Cassie::Query`, `Cassie::Modification`, etc)
|
677
|
+
3. the `Cassie::Statment::default_foo` value (where foo is the option name)
|
678
|
+
4. the `Cassandra::cluster` value (default cassandra driver value)
|
679
|
+
|
680
|
+
Statement options include:
|
681
|
+
|
682
|
+
* `consistency` [symbol](http://datastax.github.io/ruby-driver/api/cassandra/#consistencies-constant)
|
683
|
+
* `limit` integer
|
684
|
+
* `idempotent` boolean
|
644
685
|
|
645
686
|
```ruby
|
646
687
|
Cassie.configuration[:consistency]
|
@@ -650,15 +691,18 @@ Cassie.cluster.instance_variable_get(:@execution_options).consistency
|
|
650
691
|
#=> :one
|
651
692
|
```
|
652
693
|
|
653
|
-
|
694
|
+
See the examples below of setting the `consistency` option at various places.
|
654
695
|
|
655
696
|
Object writer:
|
697
|
+
|
656
698
|
```ruby
|
657
699
|
query = MyQuery.new
|
658
700
|
query.consistency = :all
|
659
701
|
query.execute
|
660
702
|
```
|
703
|
+
|
661
704
|
Override Object reader:
|
705
|
+
|
662
706
|
```ruby
|
663
707
|
select_from :posts_by_author_category
|
664
708
|
|
@@ -680,6 +724,7 @@ Override Object reader:
|
|
680
724
|
```
|
681
725
|
|
682
726
|
Class writer
|
727
|
+
|
683
728
|
```ruby
|
684
729
|
select_from :posts_by_author_category
|
685
730
|
|
@@ -689,24 +734,28 @@ Class writer
|
|
689
734
|
consistency :quorum
|
690
735
|
```
|
691
736
|
|
692
|
-
Cassie
|
737
|
+
`Cassie::Query` or `Cassie::Modificaton` superclass writer
|
738
|
+
|
693
739
|
```ruby
|
694
740
|
# lib/tasks/interesting_task.rake
|
695
741
|
require_relative "interesting_worker"
|
696
742
|
|
697
743
|
task :interesting_task do
|
744
|
+
# All modification queries execute with :all consistency
|
698
745
|
Cassie::Modification.consistency = :all
|
699
746
|
|
700
747
|
InterestingWorker.new.perform
|
701
748
|
end
|
702
749
|
```
|
703
750
|
|
704
|
-
Cassie global default
|
751
|
+
`Cassie` global default
|
752
|
+
|
705
753
|
```ruby
|
706
754
|
# lib/tasks/interesting_task.rake
|
707
755
|
require_relative "interesting_worker"
|
708
756
|
|
709
757
|
task :interesting_task do
|
758
|
+
# All `Cassie` statements execute with :all consistency
|
710
759
|
Cassie::Statements.default_consistency = :all
|
711
760
|
|
712
761
|
InterestingWorker.new.perform
|
@@ -719,7 +768,7 @@ Cassie statements are set as [idempotent](http://datastax.github.io/ruby-driver/
|
|
719
768
|
|
720
769
|
Mark queries that are not idempotent, so that the driver won't automatically retry for certain failure scenarios.
|
721
770
|
|
722
|
-
Similar to other
|
771
|
+
Similar to other statement options, there is a `Cassie::Statements.default_idempotency`, class level setting, and object level setting.
|
723
772
|
|
724
773
|
```ruby
|
725
774
|
class MyQuery < Cassie::Modification
|
@@ -732,6 +781,7 @@ class MyQuery < Cassie::Modification
|
|
732
781
|
end
|
733
782
|
end
|
734
783
|
```
|
784
|
+
|
735
785
|
```
|
736
786
|
MyQuery.idempotent?
|
737
787
|
# => true
|
@@ -750,6 +800,7 @@ class MyQuery < Cassie::Modification
|
|
750
800
|
end
|
751
801
|
end
|
752
802
|
```
|
803
|
+
|
753
804
|
```
|
754
805
|
MyQuery.idempotent?
|
755
806
|
# => false
|
@@ -881,6 +932,7 @@ Cassie Queries instrument execution time as `cassie.cql.execution` and logs a de
|
|
881
932
|
SelectUserByUsernameQuery.new('some_user').execute
|
882
933
|
(5.5ms) SELECT * FROM users_by_username WHERE username = ? LIMIT 1; ["some_user"] [LOCAL_ONE]
|
883
934
|
```
|
935
|
+
|
884
936
|
This measures the time to build the CQL query (statement and bindings), transmit the query to the cassandra coordinator, receive the result from the cassandra coordinator, and have the cassandra ruby driver build the ruby representation of the results. It does not include the time it takes for the Cassie Query to build its resource objects.
|
885
937
|
|
886
938
|
#### Result Deserialization
|
@@ -4,14 +4,25 @@ require_relative 'logging'
|
|
4
4
|
|
5
5
|
module Cassie::Statements
|
6
6
|
module Core
|
7
|
-
extend ActiveSupport::Concern
|
8
7
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
# @!visibility private
|
9
|
+
# @!parse include Statement
|
10
|
+
# @!parse include Statement::ClassMethods
|
11
|
+
# @!parse include Execution
|
12
|
+
# @!parse include Execution::ClassMethods
|
13
|
+
# @!parse include Logging
|
14
|
+
# @!parse include Logging::ClassMethods
|
15
|
+
def self.included(base)
|
16
|
+
base.instance_eval do
|
17
|
+
include Statement
|
18
|
+
include Execution
|
19
|
+
include Logging
|
20
|
+
end
|
13
21
|
end
|
14
22
|
|
23
|
+
# Create a new statement-based object, sending
|
24
|
+
# all options passed as a hash to attribute setters
|
25
|
+
# Similar to ActiveModel::Model initialization
|
15
26
|
def initialize(params={})
|
16
27
|
params.each do |attr, value|
|
17
28
|
self.public_send("#{attr}=", value)
|
@@ -1,4 +1,11 @@
|
|
1
1
|
module Cassie::Statements
|
2
|
+
# Execution support for Cassandra Statements
|
3
|
+
#
|
4
|
+
# Requires the following methods be provided:
|
5
|
+
# * +statement+
|
6
|
+
# * CQL +String+ or +Cassandra::Statements:Statement+ executable by a +Cassandra::Session+
|
7
|
+
# * +session+
|
8
|
+
# * A +Cassandra::Session+ scoped to an appropriate keyspace
|
2
9
|
module Execution
|
3
10
|
require_relative 'execution/errors'
|
4
11
|
require_relative 'execution/consistency'
|
@@ -7,22 +14,35 @@ module Cassie::Statements
|
|
7
14
|
require_relative 'execution/partition_linking'
|
8
15
|
require_relative 'execution/instrumentation'
|
9
16
|
|
10
|
-
|
11
|
-
|
12
|
-
|
17
|
+
# @!visibility private
|
18
|
+
# @!parse include Consistency
|
19
|
+
# @!parse include Callbacks
|
20
|
+
# @!parse include PartitionLinking
|
21
|
+
# @!parse include Instrumentation
|
22
|
+
def self.included(base)
|
23
|
+
base.instance_eval do
|
24
|
+
# The result from execution.
|
25
|
+
# Includes all attributes and methods available from
|
26
|
+
# a +Cassandra::Result+
|
27
|
+
# @return [Cassie::Statements::Results::Result] A decorated +Cassandra::Result+ object
|
28
|
+
attr_reader :result
|
13
29
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
30
|
+
include Consistency
|
31
|
+
include Callbacks
|
32
|
+
include PartitionLinking
|
33
|
+
include Instrumentation
|
34
|
+
end
|
35
|
+
base.extend ClassMethods
|
18
36
|
end
|
19
37
|
|
38
|
+
# @!parse extend ClassMethods
|
20
39
|
module ClassMethods
|
21
40
|
def inherited(subclass)
|
22
41
|
subclass.result_class = result_class if defined?(@result_class)
|
23
42
|
super
|
24
43
|
end
|
25
|
-
|
44
|
+
# The class to use for decorating the +Cassandra::Result+
|
45
|
+
# @!parse attr_accessor :result_class
|
26
46
|
def result_class
|
27
47
|
return @result_class if defined?(@result_class)
|
28
48
|
Cassie::Statements::Results::Result
|
@@ -33,22 +53,25 @@ module Cassie::Statements
|
|
33
53
|
end
|
34
54
|
end
|
35
55
|
|
36
|
-
# Executes the statment
|
37
|
-
#
|
56
|
+
# Executes the statment and populates result
|
57
|
+
# @return [Boolean] indicating a successful execution or not
|
38
58
|
def execute
|
39
59
|
@result = result_class.new(session.execute(statement, execution_options), result_opts)
|
40
60
|
result.success?
|
41
61
|
end
|
42
62
|
|
43
|
-
#
|
44
|
-
#
|
63
|
+
# Same as {#execute}. Raises if not succesfull.
|
64
|
+
# @return [Boolean] true if sucessful
|
65
|
+
# @raise [Cassie::Statements::ExecutionError] if the result was not sucessful, see {Cassie::Statements::Results::Core#success?}
|
45
66
|
def execute!
|
46
67
|
execute || (raise Cassie::Statements::ExecutionError.new(result))
|
47
68
|
end
|
48
69
|
|
70
|
+
# The session exection options configured for statement execution
|
71
|
+
# @return [Hash{Symbol => Object}]
|
49
72
|
def execution_options
|
50
73
|
{}.tap do |opts|
|
51
|
-
#
|
74
|
+
# @todo rework consistency module to be more
|
52
75
|
# abstract implementation for all execution options
|
53
76
|
opts[:consistency] = consistency if consistency
|
54
77
|
opts[:paging_state] = paging_state if respond_to?(:paging_state) && paging_state
|
@@ -68,6 +91,10 @@ module Cassie::Statements
|
|
68
91
|
|
69
92
|
private
|
70
93
|
|
94
|
+
# Ensures that +clone+ and +dup+ drops the reference to the
|
95
|
+
# result object. The cloned object should be able to mutate
|
96
|
+
# the statement and execute without affecting the original
|
97
|
+
# objecthe resulting object or its results.
|
71
98
|
def initialize_copy(other)
|
72
99
|
super
|
73
100
|
@result = nil
|
@@ -22,11 +22,36 @@ module Cassie::Statements::Statement
|
|
22
22
|
module Assignments
|
23
23
|
extend ActiveSupport::Concern
|
24
24
|
|
25
|
-
|
26
|
-
|
25
|
+
# @!visibility private
|
26
|
+
# @!parse include Mapping
|
27
|
+
# @!parse extend Mapping::ClassMethods
|
28
|
+
def self.included(base)
|
29
|
+
base.instance_eval do
|
30
|
+
include Mapping
|
31
|
+
end
|
32
|
+
base.extend ClassMethods
|
27
33
|
end
|
28
34
|
|
29
35
|
module ClassMethods
|
36
|
+
# DSL to set an assigment (+SET+ or +VALUES+ clause) for +UPDATE+ and +INSERT+ statements.
|
37
|
+
#
|
38
|
+
# Defining an assigment also defines an +attr_accessor+ with the same name as
|
39
|
+
# the identifier (or the +:value+ option if a symbol is used). The underlying instance
|
40
|
+
# variable value for this accessor will be used when determining the value for the assigment.
|
41
|
+
#
|
42
|
+
# @param [String, Symbol] identifier The column name to set.
|
43
|
+
# @param [Hash] opts options for the assigment
|
44
|
+
# @option opts [Symbol, Object] :value The value to use for the assigment (constraint). If a [Symbol], a method with that name will be called when the statement is built. Otherwise, the value itself will be used.
|
45
|
+
# @option opts [Symbol, Object] :if Determines if the assigment is applied to the statement or not. If a [Symbol], a method with that name will be called when the statement is built. Otherwise, the value itself will be used.
|
46
|
+
# @option opts [String] :term The argument value to use instead of a positional placeholder (?). If a [Symbol], a method with that name will be called when the statement is built. Otherwise, the value itself will be used.
|
47
|
+
# @return [Enumerable<Array<Object>>] The enumeration of current assigments' parameters
|
48
|
+
# @raise [StandardError] if there is already a getter or setter method defined for the
|
49
|
+
# assigment value's implied accessor (+identifier+ or symbol +:value+ option).
|
50
|
+
#
|
51
|
+
# @example Assigment with implied accessor
|
52
|
+
# set :username #<= gets assigment value from `:username` method
|
53
|
+
# @example Assigment with explicit accessor
|
54
|
+
# set :username, value: :name #<= gets assigment value from `:name` method
|
30
55
|
def set(identifier, opts={})
|
31
56
|
opts[:value] ||= identifier.to_sym
|
32
57
|
|
@@ -35,17 +60,22 @@ module Cassie::Statements::Statement
|
|
35
60
|
assignments_args << [identifier, opts.delete(:value), opts]
|
36
61
|
end
|
37
62
|
|
63
|
+
# The enumeration of current assignments' parameters that will be
|
64
|
+
# used to build Assignment objects when the statement is built
|
38
65
|
def assignments_args
|
39
66
|
@assignments_args ||= []
|
40
67
|
end
|
41
68
|
end
|
42
69
|
|
70
|
+
# The enumeration of current assignments' parameters that will be
|
71
|
+
# used to build Assignment objects when the statement is built
|
43
72
|
def assignments_args
|
44
73
|
self.class.assignments_args
|
45
74
|
end
|
46
75
|
|
76
|
+
protected
|
77
|
+
|
47
78
|
def build_update_and_params
|
48
|
-
cql = ""
|
49
79
|
arguments = []
|
50
80
|
assignment_strings = []
|
51
81
|
|
@@ -4,22 +4,30 @@ require_relative 'mapping'
|
|
4
4
|
|
5
5
|
module Cassie::Statements::Statement
|
6
6
|
module Deleting
|
7
|
-
extend ::ActiveSupport::Concern
|
8
7
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
# @!visibility private
|
9
|
+
# @!parse include Relations
|
10
|
+
# @!parse extend Relations::ClassMethods
|
11
|
+
# @!parse include Conditions
|
12
|
+
# @!parse extend Conditions::ClassMethods
|
13
|
+
# @!parse include Mapping
|
14
|
+
# @!parse extend Mapping::ClassMethods
|
15
|
+
def self.included(base)
|
16
|
+
base.instance_eval do
|
17
|
+
include Relations
|
18
|
+
include Conditions
|
19
|
+
include Mapping
|
13
20
|
|
14
|
-
|
21
|
+
@result_class = Cassie::Statements::Results::ModificationResult
|
22
|
+
end
|
23
|
+
base.extend ClassMethods
|
15
24
|
end
|
16
25
|
|
26
|
+
# @!parse extend ClassMethods
|
17
27
|
module ClassMethods
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
# t.name as: :username
|
22
|
-
# end
|
28
|
+
# DSL to set the statement type and table for deleting
|
29
|
+
# @param [String, Symbol] table The table to taret for the delete statement
|
30
|
+
# @return [void]
|
23
31
|
def delete_from(table)
|
24
32
|
self.table = table
|
25
33
|
self.type = :delete
|
@@ -27,16 +35,16 @@ module Cassie::Statements::Statement
|
|
27
35
|
yield(self) if block_given?
|
28
36
|
end
|
29
37
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
def column(identifier, opts={})
|
38
|
+
# Add a specific column to tombstone by this statement
|
39
|
+
# @param [String, Symbol] identifier the column to tombstone
|
40
|
+
def column(identifier)
|
41
|
+
# @todo replace with Selection
|
42
|
+
# Module and aliases?
|
37
43
|
columns << identifier.to_s
|
38
44
|
end
|
39
45
|
|
46
|
+
# The columns to be tombstoned from this statement
|
47
|
+
# @return [Array<String>] column names
|
40
48
|
def columns
|
41
49
|
@columns ||= []
|
42
50
|
end
|
@@ -64,7 +72,7 @@ module Cassie::Statements::Statement
|
|
64
72
|
end
|
65
73
|
|
66
74
|
def build_delete_clause
|
67
|
-
|
75
|
+
if columns.empty?
|
68
76
|
''
|
69
77
|
else
|
70
78
|
columns.join(', ')
|
@@ -9,14 +9,19 @@ module Cassie::Statements
|
|
9
9
|
end
|
10
10
|
|
11
11
|
|
12
|
+
# Sepcific functionality and DSL for idempotent statements.
|
12
13
|
module Statement::Idempotency
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
# @!visibility private
|
15
|
+
def self.included(base)
|
16
|
+
base.instance_eval do
|
17
|
+
attr_writer :idempotent
|
18
|
+
end
|
19
|
+
base.extend ClassMethods
|
17
20
|
end
|
18
21
|
|
22
|
+
# @!parse extend ClassMethods
|
19
23
|
module ClassMethods
|
24
|
+
# @!visibility private
|
20
25
|
def inherited(subclass)
|
21
26
|
subclass.idempotent = idempotent if defined?(@idempotent)
|
22
27
|
super
|
@@ -26,6 +31,9 @@ module Cassie::Statements
|
|
26
31
|
@idempotent = val
|
27
32
|
end
|
28
33
|
|
34
|
+
# DSL to set a statement as idempotent
|
35
|
+
# @param [Boolean] val The value to set for idempotency. Returns the current value if no parameter is given.
|
36
|
+
# @return [Boolean] idempotent value
|
29
37
|
def idempotent(val=:get)
|
30
38
|
if val == :get
|
31
39
|
return @idempotent if defined?(@idempotent)
|
@@ -35,20 +43,31 @@ module Cassie::Statements
|
|
35
43
|
end
|
36
44
|
end
|
37
45
|
|
46
|
+
# DSL to set a satement as non-idempotent
|
47
|
+
# @return [Boolean] false
|
38
48
|
def non_idempotent
|
39
49
|
self.idempotent = false
|
40
50
|
end
|
41
51
|
|
52
|
+
# Indicates where the statement has no negative side-effect
|
53
|
+
# if issued multiple times.
|
54
|
+
# @return [Boolean] indicating idempotency. Defaults to {Cassie::Statements.default_idempotency} if no value has been set.
|
42
55
|
def idempotent?
|
43
56
|
!!idempotent
|
44
57
|
end
|
45
58
|
end
|
46
59
|
|
60
|
+
# Indicates where the statement has no negative side-effect
|
61
|
+
# if issued multiple times.
|
62
|
+
# @return [Boolean] indicating idempotency. Defaults to {Cassie::Statements.default_idempotency} if no value has been set.
|
47
63
|
def idempotent
|
48
64
|
return @idempotent if defined?(@idempotent)
|
49
65
|
self.class.idempotent
|
50
66
|
end
|
51
67
|
|
68
|
+
# Indicates where the statement has no negative side-effect
|
69
|
+
# if issued multiple times.
|
70
|
+
# @return [Boolean] indicating idempotency. Defaults to {Cassie::Statements.default_idempotency} if no value has been set.
|
52
71
|
def idempotent?
|
53
72
|
!!idempotent
|
54
73
|
end
|
@@ -3,26 +3,33 @@ require_relative 'conditions'
|
|
3
3
|
|
4
4
|
module Cassie::Statements::Statement
|
5
5
|
module Inserting
|
6
|
-
extend ::ActiveSupport::Concern
|
7
6
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
7
|
+
# @!visibility private
|
8
|
+
# @!parse include Assignments
|
9
|
+
# @!parse extend Assignments::ClassMethods
|
10
|
+
# @!parse include Conditions
|
11
|
+
# @!parse extend Conditions::ClassMethods
|
12
|
+
def self.included(base)
|
13
|
+
base.instance_eval do
|
14
|
+
include Assignments
|
15
|
+
include Conditions
|
16
|
+
|
17
|
+
@result_class = Cassie::Statements::Results::ModificationResult
|
18
|
+
end
|
19
|
+
base.extend ClassMethods
|
13
20
|
end
|
14
21
|
|
22
|
+
# @!parse extend ClassMethods
|
15
23
|
module ClassMethods
|
24
|
+
# DSL to set the statement type and table for insertion
|
25
|
+
# @param [String, Symbol] table The table to taret for the insert statement
|
26
|
+
# @return [void]
|
16
27
|
def insert_into(table)
|
17
28
|
self.table = table
|
18
29
|
self.type = :insert
|
19
30
|
|
20
31
|
yield(self) if block_given?
|
21
32
|
end
|
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
|
26
33
|
end
|
27
34
|
|
28
35
|
protected
|
@@ -12,8 +12,11 @@ module Cassie::Statements
|
|
12
12
|
module Statement::Limiting
|
13
13
|
extend ActiveSupport::Concern
|
14
14
|
|
15
|
-
included
|
16
|
-
|
15
|
+
def self.included(base)
|
16
|
+
base.instance_eval do
|
17
|
+
attr_writer :limit
|
18
|
+
end
|
19
|
+
base.extend ClassMethods
|
17
20
|
end
|
18
21
|
|
19
22
|
module ClassMethods
|