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.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/bin/cassie +8 -181
  3. data/lib/cassie/configuration/core.rb +26 -3
  4. data/lib/cassie/configuration/generator.rb +1 -0
  5. data/lib/cassie/configuration/loading.rb +5 -2
  6. data/lib/cassie/configuration.rb +1 -0
  7. data/lib/cassie/connection.rb +13 -7
  8. data/lib/cassie/connection_handler/README.md +13 -3
  9. data/lib/cassie/connection_handler/cluster.rb +11 -0
  10. data/lib/cassie/connection_handler/sessions.rb +9 -0
  11. data/lib/cassie/connection_handler.rb +8 -7
  12. data/lib/cassie/definition.rb +28 -0
  13. data/lib/cassie/extensions/object/color_methods.rb +21 -0
  14. data/lib/cassie/instrumentation.rb +4 -0
  15. data/lib/cassie/modification.rb +29 -0
  16. data/lib/cassie/query.rb +27 -0
  17. data/lib/cassie/schema/README.md +306 -0
  18. data/lib/cassie/schema/apply_command.rb +24 -0
  19. data/lib/cassie/schema/cassandra_migrations/importer.rb +91 -0
  20. data/lib/cassie/schema/cassandra_migrations/migration_file.rb +51 -0
  21. data/lib/cassie/schema/configuration.rb +35 -0
  22. data/lib/cassie/schema/migration/cassandra_support.rb +34 -0
  23. data/lib/cassie/schema/migration/dsl/announcing.rb +47 -0
  24. data/lib/cassie/schema/migration/dsl/column_operations.rb +42 -0
  25. data/lib/cassie/schema/migration/dsl/table_definition.rb +299 -0
  26. data/lib/cassie/schema/migration/dsl/table_operations.rb +64 -0
  27. data/lib/cassie/schema/migration/dsl.rb +17 -0
  28. data/lib/cassie/schema/migration.rb +12 -0
  29. data/lib/cassie/schema/migrator.rb +115 -0
  30. data/lib/cassie/schema/queries/create_keyspace_query.rb +26 -0
  31. data/lib/cassie/{migration → schema}/queries/create_versions_table_query.rb +6 -6
  32. data/lib/cassie/schema/queries/delete_version_query.rb +17 -0
  33. data/lib/cassie/schema/queries/drop_keyspace_query.rb +14 -0
  34. data/lib/cassie/schema/queries/insert_version_query.rb +22 -0
  35. data/lib/cassie/schema/queries/select_versions_query.rb +18 -0
  36. data/lib/cassie/{migration → schema}/queries.rb +4 -2
  37. data/lib/cassie/schema/rollback_command.rb +24 -0
  38. data/lib/cassie/schema/structure_dumper.rb +117 -0
  39. data/lib/cassie/{migration → schema}/structure_loader.rb +3 -3
  40. data/lib/cassie/schema/version.rb +143 -0
  41. data/lib/cassie/schema/version_file_loader.rb +34 -0
  42. data/lib/cassie/schema/version_loader.rb +31 -0
  43. data/lib/cassie/schema/version_object_loader.rb +19 -0
  44. data/lib/cassie/schema/version_writer.rb +108 -0
  45. data/lib/cassie/schema/versioning.rb +162 -0
  46. data/lib/cassie/schema.rb +24 -0
  47. data/lib/cassie/statements/README.md +61 -9
  48. data/lib/cassie/statements/core.rb +16 -5
  49. data/lib/cassie/statements/execution/results/core.rb +1 -1
  50. data/lib/cassie/statements/execution/results/modification_result.rb +1 -1
  51. data/lib/cassie/statements/execution/results/query_result.rb +1 -1
  52. data/lib/cassie/statements/execution.rb +40 -13
  53. data/lib/cassie/statements/statement/assignments.rb +33 -3
  54. data/lib/cassie/statements/statement/conditions.rb +3 -1
  55. data/lib/cassie/statements/statement/deleting.rb +27 -19
  56. data/lib/cassie/statements/statement/idempotency.rb +23 -4
  57. data/lib/cassie/statements/statement/inserting.rb +17 -10
  58. data/lib/cassie/statements/statement/limiting.rb +5 -2
  59. data/lib/cassie/statements/statement/mapping.rb +34 -6
  60. data/lib/cassie/statements/statement/preparation/cache.rb +1 -1
  61. data/lib/cassie/statements/statement/preparation.rb +37 -7
  62. data/lib/cassie/statements/statement/relations.rb +29 -8
  63. data/lib/cassie/statements/statement/selection.rb +51 -15
  64. data/lib/cassie/statements/statement/type_hinting.rb +12 -4
  65. data/lib/cassie/statements/statement/updating.rb +22 -8
  66. data/lib/cassie/statements/statement.rb +39 -14
  67. data/lib/cassie/statements.rb +12 -0
  68. data/lib/cassie/support/server_process.rb +117 -0
  69. data/lib/cassie/support/statement_parser.rb +3 -5
  70. data/lib/cassie/support/{command_runner.rb → system_command.rb} +22 -13
  71. data/lib/cassie/support.rb +3 -1
  72. data/lib/cassie/tasks/configuration/generate.rake +35 -0
  73. data/lib/cassie/tasks/io.rb +15 -0
  74. data/lib/cassie/tasks/migration/create.rake +49 -0
  75. data/lib/cassie/tasks/migration/import.rake +39 -0
  76. data/lib/cassie/tasks/migration/reset.rake +9 -0
  77. data/lib/cassie/tasks/restart.rake +5 -0
  78. data/lib/cassie/tasks/schema/drop.rake +28 -0
  79. data/lib/cassie/tasks/schema/dump.rake +21 -0
  80. data/lib/cassie/tasks/schema/history.rake +18 -0
  81. data/lib/cassie/tasks/schema/import.rake +40 -0
  82. data/lib/cassie/tasks/schema/init.rake +54 -0
  83. data/lib/cassie/tasks/schema/load.rake +19 -0
  84. data/lib/cassie/tasks/schema/migrate.rake +42 -0
  85. data/lib/cassie/tasks/schema/reset.rake +6 -0
  86. data/lib/cassie/tasks/schema/status.rake +19 -0
  87. data/lib/cassie/tasks/schema/version.rake +18 -0
  88. data/lib/cassie/tasks/schema/version_display.rb +50 -0
  89. data/lib/cassie/tasks/start.rake +17 -0
  90. data/lib/cassie/tasks/stop.rake +33 -0
  91. data/lib/cassie/tasks/tail.rake +14 -0
  92. data/lib/cassie/tasks/task_runner.rb +49 -0
  93. data/lib/cassie/tasks.rb +18 -0
  94. data/lib/cassie/testing/fake/execution_info.rb +1 -1
  95. data/lib/cassie/testing/fake/result.rb +3 -3
  96. data/lib/cassie/testing.rb +4 -0
  97. data/lib/cassie/version.rb +1 -1
  98. data/lib/cassie.rb +4 -1
  99. metadata +73 -17
  100. data/lib/cassie/migration/README.md +0 -141
  101. data/lib/cassie/migration/configuration.rb +0 -18
  102. data/lib/cassie/migration/initialization.rb +0 -70
  103. data/lib/cassie/migration/queries/create_schema_keyspace_query.rb +0 -17
  104. data/lib/cassie/migration/queries/insert_version_query.rb +0 -23
  105. data/lib/cassie/migration/queries/select_versions_query.rb +0 -14
  106. data/lib/cassie/migration/structure_dumper.rb +0 -94
  107. data/lib/cassie/migration/version.rb +0 -4
  108. 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 override `build_result` to construct more useful domain objects
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 overridden as well to define custom definition of the enumeration of rows returned from Cassandra.
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
- The [consistency level](http://datastax.github.io/ruby-driver/api/cassandra/#consistencies-constant) for a query is determined by your `Cassie::configuration` by default, falling to back to the `Cassandra` default if none is given.
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
- Cassie queries allow for a consistency level to be defined on the object, subclass, base class, and global levels. If none is found, it will default to the `cluster` default when the query is executed.
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 query classes
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 settings, there is a `Cassie::Statements.default_idempotency`, class level setting, and object level setting.
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
- included do
10
- include Statement
11
- include Execution
12
- include Logging
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)
@@ -2,7 +2,7 @@ module Cassie::Statements::Results
2
2
  module Core
3
3
 
4
4
  def success?
5
- # TODO: remove - don't think we need this exception
5
+ # @todo remove - don't think we need this exception
6
6
  # raise "execution not complete, no results to parse" unless result
7
7
 
8
8
  true
@@ -2,7 +2,7 @@ module Cassie::Statements::Results
2
2
  require_relative 'modification'
3
3
 
4
4
  class ModificationResult < Result
5
- include Modification
5
+ include Modification
6
6
 
7
7
  end
8
8
  end
@@ -2,7 +2,7 @@ module Cassie::Statements::Results
2
2
  require_relative 'querying'
3
3
 
4
4
  class QueryResult < Result
5
- include Querying
5
+ include Querying
6
6
 
7
7
  end
8
8
  end
@@ -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
- extend ActiveSupport::Concern
11
- included do
12
- attr_reader :result
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
- include Consistency
15
- include Callbacks
16
- include PartitionLinking
17
- include Instrumentation
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, populates result
37
- # returns true or false indicating a successful execution or not
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
- # Executes the statment, populates result
44
- # true or raises if the was not successful
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
- #TODO: rework consistency module to be more
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
- included do
26
- include Mapping
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
 
@@ -1,6 +1,8 @@
1
1
  module Cassie::Statements::Statement
2
2
  module Conditions
3
- extend ActiveSupport::Concern
3
+ def self.included(base)
4
+ base.extend ClassMethods
5
+ end
4
6
 
5
7
  module ClassMethods
6
8
  def if_not_exists(opts={})
@@ -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
- included do
10
- include Relations
11
- include Conditions
12
- include Mapping
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
- @result_class = Cassie::Statements::Results::ModificationResult
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
- #TODO: accept block to add specific selectors and aliases
19
- # select_from :table do |t|
20
- # t.id
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
- def delete(table)
31
- Cassie.logger.warn "[DEPRECATION] `Cassie::Modification#delete` has been replaced by `delete_from` and will be removed."
32
- delete_from(table)
33
- end
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
- str = if columns.empty?
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
- extend ActiveSupport::Concern
14
-
15
- included do
16
- attr_writer :idempotent
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
- included do
9
- include Assignments
10
- include Conditions
11
-
12
- @result_class = Cassie::Statements::Results::ModificationResult
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 do
16
- attr_writer :limit
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