cassanity 0.1.0
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.
- data/.gitignore +19 -0
- data/.rspec +1 -0
- data/.travis.yml +10 -0
- data/Gemfile +11 -0
- data/Guardfile +17 -0
- data/LICENSE.txt +22 -0
- data/README.md +99 -0
- data/Rakefile +16 -0
- data/cassanity.gemspec +21 -0
- data/examples/_shared.rb +8 -0
- data/examples/batch.rb +40 -0
- data/examples/column_families.rb +68 -0
- data/examples/keyspaces.rb +57 -0
- data/lib/cassanity/argument_generators/batch.rb +52 -0
- data/lib/cassanity/argument_generators/column_family_alter.rb +47 -0
- data/lib/cassanity/argument_generators/column_family_create.rb +44 -0
- data/lib/cassanity/argument_generators/column_family_delete.rb +65 -0
- data/lib/cassanity/argument_generators/column_family_drop.rb +18 -0
- data/lib/cassanity/argument_generators/column_family_insert.rb +53 -0
- data/lib/cassanity/argument_generators/column_family_select.rb +34 -0
- data/lib/cassanity/argument_generators/column_family_truncate.rb +18 -0
- data/lib/cassanity/argument_generators/column_family_update.rb +69 -0
- data/lib/cassanity/argument_generators/index_create.rb +22 -0
- data/lib/cassanity/argument_generators/index_drop.rb +13 -0
- data/lib/cassanity/argument_generators/keyspace_create.rb +51 -0
- data/lib/cassanity/argument_generators/keyspace_drop.rb +13 -0
- data/lib/cassanity/argument_generators/keyspace_use.rb +13 -0
- data/lib/cassanity/argument_generators/keyspaces.rb +12 -0
- data/lib/cassanity/argument_generators/set_clause.rb +30 -0
- data/lib/cassanity/argument_generators/using_clause.rb +24 -0
- data/lib/cassanity/argument_generators/where_clause.rb +29 -0
- data/lib/cassanity/argument_generators/with_clause.rb +32 -0
- data/lib/cassanity/column_family.rb +233 -0
- data/lib/cassanity/connection.rb +88 -0
- data/lib/cassanity/error.rb +28 -0
- data/lib/cassanity/executors/cassandra_cql.rb +120 -0
- data/lib/cassanity/keyspace.rb +118 -0
- data/lib/cassanity/result_transformers/column_family_select.rb +15 -0
- data/lib/cassanity/result_transformers/mirror.rb +12 -0
- data/lib/cassanity/schema.rb +26 -0
- data/lib/cassanity/version.rb +3 -0
- data/lib/cassanity.rb +5 -0
- data/spec/helper.rb +27 -0
- data/spec/integration/cassanity/column_family_spec.rb +243 -0
- data/spec/integration/cassanity/connection_spec.rb +87 -0
- data/spec/integration/cassanity/keyspace_spec.rb +64 -0
- data/spec/support/cassanity_helpers.rb +35 -0
- data/spec/unit/cassanity/argument_generators/batch_spec.rb +36 -0
- data/spec/unit/cassanity/argument_generators/column_family_alter_spec.rb +85 -0
- data/spec/unit/cassanity/argument_generators/column_family_create_spec.rb +107 -0
- data/spec/unit/cassanity/argument_generators/column_family_delete_spec.rb +92 -0
- data/spec/unit/cassanity/argument_generators/column_family_drop_spec.rb +25 -0
- data/spec/unit/cassanity/argument_generators/column_family_insert_spec.rb +70 -0
- data/spec/unit/cassanity/argument_generators/column_family_select_spec.rb +113 -0
- data/spec/unit/cassanity/argument_generators/column_family_truncate_spec.rb +25 -0
- data/spec/unit/cassanity/argument_generators/column_family_update_spec.rb +109 -0
- data/spec/unit/cassanity/argument_generators/index_create_spec.rb +39 -0
- data/spec/unit/cassanity/argument_generators/index_drop_spec.rb +14 -0
- data/spec/unit/cassanity/argument_generators/keyspace_create_spec.rb +53 -0
- data/spec/unit/cassanity/argument_generators/keyspace_drop_spec.rb +14 -0
- data/spec/unit/cassanity/argument_generators/keyspace_use_spec.rb +14 -0
- data/spec/unit/cassanity/argument_generators/keyspaces_spec.rb +12 -0
- data/spec/unit/cassanity/argument_generators/set_clause_spec.rb +85 -0
- data/spec/unit/cassanity/argument_generators/using_clause_spec.rb +44 -0
- data/spec/unit/cassanity/argument_generators/where_clause_spec.rb +57 -0
- data/spec/unit/cassanity/argument_generators/with_clause_spec.rb +63 -0
- data/spec/unit/cassanity/column_family_spec.rb +250 -0
- data/spec/unit/cassanity/connection_spec.rb +75 -0
- data/spec/unit/cassanity/error_spec.rb +35 -0
- data/spec/unit/cassanity/executors/cassandra_cql_spec.rb +178 -0
- data/spec/unit/cassanity/keyspace_spec.rb +137 -0
- data/spec/unit/cassanity/result_transformers/column_family_select_spec.rb +0 -0
- data/spec/unit/cassanity/result_transformers/mirror_spec.rb +12 -0
- data/spec/unit/cassanity/schema_spec.rb +23 -0
- data/spec/unit/cassanity_spec.rb +5 -0
- metadata +172 -0
| @@ -0,0 +1,34 @@ | |
| 1 | 
            +
            require 'cassanity/argument_generators/where_clause'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Cassanity
         | 
| 4 | 
            +
              module ArgumentGenerators
         | 
| 5 | 
            +
                class ColumnFamilySelect
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                  # Internal
         | 
| 8 | 
            +
                  def initialize(args = {})
         | 
| 9 | 
            +
                    @where_clause = args.fetch(:where_clause) { WhereClause.new }
         | 
| 10 | 
            +
                  end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  # Internal
         | 
| 13 | 
            +
                  def call(args = {})
         | 
| 14 | 
            +
                    select = Array(args.fetch(:select, '*'))
         | 
| 15 | 
            +
                    name   = args.fetch(:name)
         | 
| 16 | 
            +
                    where  = args[:where]
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                    variables = []
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                    if (keyspace_name = args[:keyspace_name])
         | 
| 21 | 
            +
                      name = "#{keyspace_name}.#{name}"
         | 
| 22 | 
            +
                    end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                    cql = "SELECT #{select.join(', ')} FROM #{name}"
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                    where_cql, *where_variables = @where_clause.call(where: where)
         | 
| 27 | 
            +
                    cql << where_cql
         | 
| 28 | 
            +
                    variables.concat(where_variables)
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                    [cql, *variables]
         | 
| 31 | 
            +
                  end
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
              end
         | 
| 34 | 
            +
            end
         | 
| @@ -0,0 +1,18 @@ | |
| 1 | 
            +
            module Cassanity
         | 
| 2 | 
            +
              module ArgumentGenerators
         | 
| 3 | 
            +
                class ColumnFamilyTruncate
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                  # Internal
         | 
| 6 | 
            +
                  def call(args = {})
         | 
| 7 | 
            +
                    name = args.fetch(:name)
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                    if (keyspace_name = args[:keyspace_name])
         | 
| 10 | 
            +
                      name = "#{keyspace_name}.#{name}"
         | 
| 11 | 
            +
                    end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                    cql = "TRUNCATE #{name}"
         | 
| 14 | 
            +
                    [cql]
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
            end
         | 
| @@ -0,0 +1,69 @@ | |
| 1 | 
            +
            require 'cassanity/argument_generators/where_clause'
         | 
| 2 | 
            +
            require 'cassanity/argument_generators/set_clause'
         | 
| 3 | 
            +
            require 'cassanity/argument_generators/using_clause'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module Cassanity
         | 
| 6 | 
            +
              module ArgumentGenerators
         | 
| 7 | 
            +
                class ColumnFamilyUpdate
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                  # Internal
         | 
| 10 | 
            +
                  def initialize(args = {})
         | 
| 11 | 
            +
                    @using_clause = args.fetch(:using_clause) { UsingClause.new }
         | 
| 12 | 
            +
                    @set_clause   = args.fetch(:set_clause)   { SetClause.new }
         | 
| 13 | 
            +
                    @where_clause = args.fetch(:where_clause) { WhereClause.new }
         | 
| 14 | 
            +
                  end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                  # Internal: Converts a Hash of arguments to CQL with bound variables.
         | 
| 17 | 
            +
                  #
         | 
| 18 | 
            +
                  # args - The Hash of arguments to use.
         | 
| 19 | 
            +
                  #        :name - The String name of the column family
         | 
| 20 | 
            +
                  #        :set - The Hash of data to actually update
         | 
| 21 | 
            +
                  #        :where - The Hash of options to use to filter the update
         | 
| 22 | 
            +
                  #        :using - The Hash of options for the query ie: consistency, ttl,
         | 
| 23 | 
            +
                  #                 and timestamp (optional).
         | 
| 24 | 
            +
                  #
         | 
| 25 | 
            +
                  # Examples
         | 
| 26 | 
            +
                  #
         | 
| 27 | 
            +
                  #   call({
         | 
| 28 | 
            +
                  #     name: 'apps',
         | 
| 29 | 
            +
                  #     set: {
         | 
| 30 | 
            +
                  #       name: 'GitHub',
         | 
| 31 | 
            +
                  #     },
         | 
| 32 | 
            +
                  #     where: {
         | 
| 33 | 
            +
                  #       :id => '1',
         | 
| 34 | 
            +
                  #     }
         | 
| 35 | 
            +
                  #   })
         | 
| 36 | 
            +
                  #
         | 
| 37 | 
            +
                  # Returns Array where first element is CQL string and the rest are
         | 
| 38 | 
            +
                  #   bound values.
         | 
| 39 | 
            +
                  def call(args = {})
         | 
| 40 | 
            +
                    name  = args.fetch(:name)
         | 
| 41 | 
            +
                    set   = args.fetch(:set)
         | 
| 42 | 
            +
                    where = args.fetch(:where)
         | 
| 43 | 
            +
                    using = args[:using] || {}
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                    variables = []
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                    if (keyspace_name = args[:keyspace_name])
         | 
| 48 | 
            +
                      name = "#{keyspace_name}.#{name}"
         | 
| 49 | 
            +
                    end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                    cql = "UPDATE #{name}"
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                    using_cql, *using_variables = @using_clause.call(using: using)
         | 
| 54 | 
            +
                    cql << using_cql
         | 
| 55 | 
            +
                    variables.concat(using_variables)
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                    set_cql, *set_variables = @set_clause.call(set: set)
         | 
| 58 | 
            +
                    cql << set_cql
         | 
| 59 | 
            +
                    variables.concat(set_variables)
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                    where_cql, *where_variables = @where_clause.call(where: where)
         | 
| 62 | 
            +
                    cql << where_cql
         | 
| 63 | 
            +
                    variables.concat(where_variables)
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                    [cql, *variables]
         | 
| 66 | 
            +
                  end
         | 
| 67 | 
            +
                end
         | 
| 68 | 
            +
              end
         | 
| 69 | 
            +
            end
         | 
| @@ -0,0 +1,22 @@ | |
| 1 | 
            +
            module Cassanity
         | 
| 2 | 
            +
              module ArgumentGenerators
         | 
| 3 | 
            +
                class IndexCreate
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                  # Internal
         | 
| 6 | 
            +
                  def call(args = {})
         | 
| 7 | 
            +
                    name = args[:name]
         | 
| 8 | 
            +
                    column_name = args.fetch(:column_name)
         | 
| 9 | 
            +
                    column_family_name = args.fetch(:column_family_name)
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                    if (keyspace_name = args[:keyspace_name])
         | 
| 12 | 
            +
                      column_family_name = "#{keyspace_name}.#{column_family_name}"
         | 
| 13 | 
            +
                    end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                    cql = "CREATE INDEX"
         | 
| 16 | 
            +
                    cql << " #{name}" unless name.nil?
         | 
| 17 | 
            +
                    cql << " ON #{column_family_name} (#{column_name})"
         | 
| 18 | 
            +
                    [cql]
         | 
| 19 | 
            +
                  end
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
            end
         | 
| @@ -0,0 +1,51 @@ | |
| 1 | 
            +
            module Cassanity
         | 
| 2 | 
            +
              module ArgumentGenerators
         | 
| 3 | 
            +
                class KeyspaceCreate
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                  # Internal
         | 
| 6 | 
            +
                  def call(args = {})
         | 
| 7 | 
            +
                    options, variables = [], []
         | 
| 8 | 
            +
                    name = args.fetch(:name)
         | 
| 9 | 
            +
                    cql = "CREATE KEYSPACE %s WITH " % name.to_s
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                    with = {
         | 
| 12 | 
            +
                      strategy_class: default_strategy_class,
         | 
| 13 | 
            +
                      strategy_options: default_strategy_options,
         | 
| 14 | 
            +
                    }
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                    if args[:strategy_class]
         | 
| 17 | 
            +
                      with[:strategy_class] = args[:strategy_class]
         | 
| 18 | 
            +
                    end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                    cql << "strategy_class = ? AND "
         | 
| 21 | 
            +
                    variables << with[:strategy_class]
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                    if args[:strategy_options]
         | 
| 24 | 
            +
                      args[:strategy_options].each do |key, value|
         | 
| 25 | 
            +
                        with[:strategy_options][key] = value
         | 
| 26 | 
            +
                      end
         | 
| 27 | 
            +
                    end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                    with[:strategy_options].each do |key, value|
         | 
| 30 | 
            +
                      options << "strategy_options:#{key} = ?"
         | 
| 31 | 
            +
                      variables << value
         | 
| 32 | 
            +
                    end
         | 
| 33 | 
            +
                    cql << options.join(' AND ')
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                    [cql, *variables]
         | 
| 36 | 
            +
                  end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                  # Private
         | 
| 39 | 
            +
                  def default_strategy_class
         | 
| 40 | 
            +
                    'SimpleStrategy'
         | 
| 41 | 
            +
                  end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                  # Private
         | 
| 44 | 
            +
                  def default_strategy_options
         | 
| 45 | 
            +
                    {
         | 
| 46 | 
            +
                      replication_factor: 1,
         | 
| 47 | 
            +
                    }
         | 
| 48 | 
            +
                  end
         | 
| 49 | 
            +
                end
         | 
| 50 | 
            +
              end
         | 
| 51 | 
            +
            end
         | 
| @@ -0,0 +1,30 @@ | |
| 1 | 
            +
            module Cassanity
         | 
| 2 | 
            +
              module ArgumentGenerators
         | 
| 3 | 
            +
                class SetClause
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                  # Internal
         | 
| 6 | 
            +
                  def call(args = {})
         | 
| 7 | 
            +
                    set = args.fetch(:set)
         | 
| 8 | 
            +
                    cql, variables, sets = '', [], []
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                    set.each do |key, value|
         | 
| 11 | 
            +
                      if counter?(key, value)
         | 
| 12 | 
            +
                        sets << "#{key} = #{value}"
         | 
| 13 | 
            +
                      else
         | 
| 14 | 
            +
                        sets << "#{key} = ?"
         | 
| 15 | 
            +
                        variables << value
         | 
| 16 | 
            +
                      end
         | 
| 17 | 
            +
                    end
         | 
| 18 | 
            +
                    cql << " SET #{sets.join(', ')}"
         | 
| 19 | 
            +
             | 
| 20 | 
            +
             | 
| 21 | 
            +
                    [cql, *variables]
         | 
| 22 | 
            +
                  end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                  # Private
         | 
| 25 | 
            +
                  def counter?(key, value)
         | 
| 26 | 
            +
                    value.is_a?(String) && value.match(/#{key}(\s+)?[\+\-](\s+)?\d/)
         | 
| 27 | 
            +
                  end
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
            end
         | 
| @@ -0,0 +1,24 @@ | |
| 1 | 
            +
            module Cassanity
         | 
| 2 | 
            +
              module ArgumentGenerators
         | 
| 3 | 
            +
                class UsingClause
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                  # Internal
         | 
| 6 | 
            +
                  def call(args = {})
         | 
| 7 | 
            +
                    using = args[:using]
         | 
| 8 | 
            +
                    cql = ''
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                    return [cql] if using.nil? || using.empty?
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                    variables, usings = [], []
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                    using.each do |key, value|
         | 
| 15 | 
            +
                      usings << "#{key.upcase} #{value}"
         | 
| 16 | 
            +
                    end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                    cql << " USING #{usings.join(' AND ')}"
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                    [cql, *variables]
         | 
| 21 | 
            +
                  end
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
            end
         | 
| @@ -0,0 +1,29 @@ | |
| 1 | 
            +
            module Cassanity
         | 
| 2 | 
            +
              module ArgumentGenerators
         | 
| 3 | 
            +
                class WhereClause
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                  # Internal
         | 
| 6 | 
            +
                  def call(args = {})
         | 
| 7 | 
            +
                    where = args[:where]
         | 
| 8 | 
            +
                    cql = ''
         | 
| 9 | 
            +
                    return [cql] if where.nil? || where.empty?
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                    variables, wheres = [], []
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                    where.each do |key, value|
         | 
| 14 | 
            +
                      if value.is_a?(Array)
         | 
| 15 | 
            +
                        wheres << "#{key} IN (?)"
         | 
| 16 | 
            +
                        variables << value
         | 
| 17 | 
            +
                      else
         | 
| 18 | 
            +
                        wheres << "#{key} = ?"
         | 
| 19 | 
            +
                        variables << value
         | 
| 20 | 
            +
                      end
         | 
| 21 | 
            +
                    end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                    cql << " WHERE #{wheres.join(' AND ')}"
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                    [cql, *variables]
         | 
| 26 | 
            +
                  end
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
              end
         | 
| 29 | 
            +
            end
         | 
| @@ -0,0 +1,32 @@ | |
| 1 | 
            +
            module Cassanity
         | 
| 2 | 
            +
              module ArgumentGenerators
         | 
| 3 | 
            +
                class WithClause
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                  # Internal
         | 
| 6 | 
            +
                  def call(args = {})
         | 
| 7 | 
            +
                    with = args[:with]
         | 
| 8 | 
            +
                    cql = ''
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                    return [cql] if with.nil? || with.empty?
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                    variables, withs = [], []
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                    with.each do |key, value|
         | 
| 15 | 
            +
                      if value.is_a?(Hash)
         | 
| 16 | 
            +
                        value.each do |sub_key, sub_value|
         | 
| 17 | 
            +
                          withs << "#{key}:#{sub_key} = ?"
         | 
| 18 | 
            +
                          variables << sub_value
         | 
| 19 | 
            +
                        end
         | 
| 20 | 
            +
                      else
         | 
| 21 | 
            +
                        withs << "#{key} = ?"
         | 
| 22 | 
            +
                        variables << value
         | 
| 23 | 
            +
                      end
         | 
| 24 | 
            +
                    end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                    cql << " WITH #{withs.join(' AND ')}"
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                    [cql, *variables]
         | 
| 29 | 
            +
                  end
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
              end
         | 
| 32 | 
            +
            end
         | 
| @@ -0,0 +1,233 @@ | |
| 1 | 
            +
            require 'cassanity/schema'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Cassanity
         | 
| 4 | 
            +
              class ColumnFamily
         | 
| 5 | 
            +
                # Public
         | 
| 6 | 
            +
                attr_reader :name
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                # Public
         | 
| 9 | 
            +
                attr_reader :keyspace
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                # Private
         | 
| 12 | 
            +
                attr_reader :executor
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                # Private
         | 
| 15 | 
            +
                attr_reader :schema
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                # Public: Initializes a ColumnFamily.
         | 
| 18 | 
            +
                #
         | 
| 19 | 
            +
                # args - The Hash of arguments (default: {}).
         | 
| 20 | 
            +
                #        :name - The String name of the column family.
         | 
| 21 | 
            +
                #        :keyspace - The Cassanity::Keyspace the column family is in.
         | 
| 22 | 
            +
                #        :executor - What will execute the queries (optional).
         | 
| 23 | 
            +
                #                    Must respond to `call`.
         | 
| 24 | 
            +
                #        :schema - The schema used to create the column family (optional).
         | 
| 25 | 
            +
                #
         | 
| 26 | 
            +
                def initialize(args = {})
         | 
| 27 | 
            +
                  @name = args.fetch(:name)
         | 
| 28 | 
            +
                  @keyspace = args.fetch(:keyspace)
         | 
| 29 | 
            +
                  @executor = args.fetch(:executor) { @keyspace.executor }
         | 
| 30 | 
            +
                  @schema = args[:schema]
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                # Public: Creates the column family in the keyspace based on the schema.
         | 
| 34 | 
            +
                #
         | 
| 35 | 
            +
                # args - The Hash of arguments to pass to the executor. Always passes
         | 
| 36 | 
            +
                #        :name and :keyspace_name.
         | 
| 37 | 
            +
                #        :schema - The Schema to use to create the column family
         | 
| 38 | 
            +
                #                  (defaults to schema provided during initialization).
         | 
| 39 | 
            +
                #
         | 
| 40 | 
            +
                # Examples
         | 
| 41 | 
            +
                #
         | 
| 42 | 
            +
                #   create # uses schema from initialization
         | 
| 43 | 
            +
                #   create(schema: Cassanity::Schema.new(...))
         | 
| 44 | 
            +
                #
         | 
| 45 | 
            +
                # Returns nothing.
         | 
| 46 | 
            +
                # Raises Cassanity::Error if schema not set during initialization and also
         | 
| 47 | 
            +
                #   not passed in via arguments.
         | 
| 48 | 
            +
                def create(args = {})
         | 
| 49 | 
            +
                  forced_arguments = {
         | 
| 50 | 
            +
                    name: @name,
         | 
| 51 | 
            +
                    keyspace_name: @keyspace.name,
         | 
| 52 | 
            +
                  }
         | 
| 53 | 
            +
                  arguments = args.merge(forced_arguments)
         | 
| 54 | 
            +
                  arguments[:schema] = schema unless arguments[:schema]
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                  @executor.call({
         | 
| 57 | 
            +
                    command: :column_family_create,
         | 
| 58 | 
            +
                    arguments: arguments,
         | 
| 59 | 
            +
                  })
         | 
| 60 | 
            +
                end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                # Public: Truncates the column family.
         | 
| 63 | 
            +
                #
         | 
| 64 | 
            +
                # args - The Hash of arguments to pass to the argument generator
         | 
| 65 | 
            +
                #        (default: {}). :name and :keyspace_name are always included.
         | 
| 66 | 
            +
                #
         | 
| 67 | 
            +
                # Examples
         | 
| 68 | 
            +
                #
         | 
| 69 | 
            +
                #   truncate # you should rarely need more than this
         | 
| 70 | 
            +
                #
         | 
| 71 | 
            +
                # Returns whatever is returned by executor.
         | 
| 72 | 
            +
                def truncate(args = {})
         | 
| 73 | 
            +
                  @executor.call({
         | 
| 74 | 
            +
                    command: :column_family_truncate,
         | 
| 75 | 
            +
                    arguments: args.merge({
         | 
| 76 | 
            +
                      name: @name,
         | 
| 77 | 
            +
                      keyspace_name: @keyspace.name,
         | 
| 78 | 
            +
                    }),
         | 
| 79 | 
            +
                  })
         | 
| 80 | 
            +
                end
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                # Public: Drops the column family.
         | 
| 83 | 
            +
                #
         | 
| 84 | 
            +
                # args - The Hash of arguments to pass to the argument generator
         | 
| 85 | 
            +
                #        (default: {}). :name and :keyspace_name are always included.
         | 
| 86 | 
            +
                #
         | 
| 87 | 
            +
                # Examples
         | 
| 88 | 
            +
                #
         | 
| 89 | 
            +
                #   drop # you should rarely need more than this
         | 
| 90 | 
            +
                #
         | 
| 91 | 
            +
                # Returns whatever is returned by executor.
         | 
| 92 | 
            +
                def drop(args = {})
         | 
| 93 | 
            +
                  @executor.call({
         | 
| 94 | 
            +
                    command: :column_family_drop,
         | 
| 95 | 
            +
                    arguments: args.merge({
         | 
| 96 | 
            +
                      name: @name,
         | 
| 97 | 
            +
                      keyspace_name: @keyspace.name,
         | 
| 98 | 
            +
                    }),
         | 
| 99 | 
            +
                  })
         | 
| 100 | 
            +
                end
         | 
| 101 | 
            +
             | 
| 102 | 
            +
                # Public: Alters the column family.
         | 
| 103 | 
            +
                #
         | 
| 104 | 
            +
                # args - The Hash of arguments to pass to the argument generator
         | 
| 105 | 
            +
                #        (default: {}). :name and :keyspace_name are always included.
         | 
| 106 | 
            +
                #
         | 
| 107 | 
            +
                # Examples
         | 
| 108 | 
            +
                #
         | 
| 109 | 
            +
                #   alter(alter: {created_at: :timestamp})
         | 
| 110 | 
            +
                #   alter(add: {description: :text})
         | 
| 111 | 
            +
                #   alter(drop: :description)
         | 
| 112 | 
            +
                #   alter(with: {read_repair_chance: 0.2})
         | 
| 113 | 
            +
                #
         | 
| 114 | 
            +
                # Returns whatever is returned by executor.
         | 
| 115 | 
            +
                def alter(args = {})
         | 
| 116 | 
            +
                  @executor.call({
         | 
| 117 | 
            +
                    command: :column_family_alter,
         | 
| 118 | 
            +
                    arguments: args.merge({
         | 
| 119 | 
            +
                      name: @name,
         | 
| 120 | 
            +
                      keyspace_name: @keyspace.name,
         | 
| 121 | 
            +
                    }),
         | 
| 122 | 
            +
                  })
         | 
| 123 | 
            +
                end
         | 
| 124 | 
            +
             | 
| 125 | 
            +
                # Public: Creates an index
         | 
| 126 | 
            +
                #
         | 
| 127 | 
            +
                # args - The Hash of arguments to pass to the argument generator
         | 
| 128 | 
            +
                #        (default: {}). :column_family_name and :keyspace_name are
         | 
| 129 | 
            +
                #        always included.
         | 
| 130 | 
            +
                #
         | 
| 131 | 
            +
                # Examples
         | 
| 132 | 
            +
                #
         | 
| 133 | 
            +
                #   create_index(column_name: 'ability_id')
         | 
| 134 | 
            +
                #   create_index(name: 'ability_index', column_name: 'ability_id')
         | 
| 135 | 
            +
                #
         | 
| 136 | 
            +
                # Returns whatever is returned by executor.
         | 
| 137 | 
            +
                def create_index(args = {})
         | 
| 138 | 
            +
                  @executor.call({
         | 
| 139 | 
            +
                    command: :index_create,
         | 
| 140 | 
            +
                    arguments: args.merge({
         | 
| 141 | 
            +
                      column_family_name: @name,
         | 
| 142 | 
            +
                      keyspace_name: @keyspace.name,
         | 
| 143 | 
            +
                    }),
         | 
| 144 | 
            +
                  })
         | 
| 145 | 
            +
                end
         | 
| 146 | 
            +
             | 
| 147 | 
            +
                # Public: Drops an index
         | 
| 148 | 
            +
                #
         | 
| 149 | 
            +
                # args - The Hash of arguments to pass to the argument generator
         | 
| 150 | 
            +
                #        (default: {}).
         | 
| 151 | 
            +
                #
         | 
| 152 | 
            +
                # Examples
         | 
| 153 | 
            +
                #
         | 
| 154 | 
            +
                #   drop_index(name: 'my_index_name')
         | 
| 155 | 
            +
                #
         | 
| 156 | 
            +
                # Returns whatever is returned by executor.
         | 
| 157 | 
            +
                def drop_index(args = {})
         | 
| 158 | 
            +
                  @executor.call({
         | 
| 159 | 
            +
                    command: :index_drop,
         | 
| 160 | 
            +
                    arguments: args,
         | 
| 161 | 
            +
                  })
         | 
| 162 | 
            +
                end
         | 
| 163 | 
            +
             | 
| 164 | 
            +
                # Public: Makes it possible to query data from the column family.
         | 
| 165 | 
            +
                #
         | 
| 166 | 
            +
                # args - The Hash of arguments to pass to the argument generator
         | 
| 167 | 
            +
                #        (default: {}). :name and :keyspace_name are always included.
         | 
| 168 | 
            +
                #
         | 
| 169 | 
            +
                # Returns whatever is returned by executor.
         | 
| 170 | 
            +
                def select(args = {})
         | 
| 171 | 
            +
                  @executor.call({
         | 
| 172 | 
            +
                    command: :column_family_select,
         | 
| 173 | 
            +
                    arguments: args.merge({
         | 
| 174 | 
            +
                      name: @name,
         | 
| 175 | 
            +
                      keyspace_name: @keyspace.name,
         | 
| 176 | 
            +
                    })
         | 
| 177 | 
            +
                  })
         | 
| 178 | 
            +
                end
         | 
| 179 | 
            +
             | 
| 180 | 
            +
                # Public: Makes it possible to insert data into the column family.
         | 
| 181 | 
            +
                #
         | 
| 182 | 
            +
                # args - The Hash of arguments to pass to the argument generator
         | 
| 183 | 
            +
                #        (default: {}). :name and :keyspace_name are always included.
         | 
| 184 | 
            +
                #
         | 
| 185 | 
            +
                # Returns whatever is returned by executor.
         | 
| 186 | 
            +
                def insert(args = {})
         | 
| 187 | 
            +
                  @executor.call({
         | 
| 188 | 
            +
                    command: :column_family_insert,
         | 
| 189 | 
            +
                    arguments: args.merge({
         | 
| 190 | 
            +
                      name: @name,
         | 
| 191 | 
            +
                      keyspace_name: @keyspace.name,
         | 
| 192 | 
            +
                    }),
         | 
| 193 | 
            +
                  })
         | 
| 194 | 
            +
                end
         | 
| 195 | 
            +
             | 
| 196 | 
            +
                # Public: Makes it possible to update data in the column family.
         | 
| 197 | 
            +
                #
         | 
| 198 | 
            +
                # args - The Hash of arguments to pass to the argument generator
         | 
| 199 | 
            +
                #        (default: {}). :name and :keyspace_name are always included.
         | 
| 200 | 
            +
                #
         | 
| 201 | 
            +
                # Returns whatever is returned by executor.
         | 
| 202 | 
            +
                def update(args = {})
         | 
| 203 | 
            +
                  @executor.call({
         | 
| 204 | 
            +
                    command: :column_family_update,
         | 
| 205 | 
            +
                    arguments: args.merge({
         | 
| 206 | 
            +
                      name: @name,
         | 
| 207 | 
            +
                      keyspace_name: @keyspace.name,
         | 
| 208 | 
            +
                    }),
         | 
| 209 | 
            +
                  })
         | 
| 210 | 
            +
                end
         | 
| 211 | 
            +
             | 
| 212 | 
            +
                # Public: Makes it possible to delete data from the column family.
         | 
| 213 | 
            +
                #
         | 
| 214 | 
            +
                # args - The Hash of arguments to pass to the argument generator
         | 
| 215 | 
            +
                #        (default: {}). :name and :keyspace_name are always included.
         | 
| 216 | 
            +
                #
         | 
| 217 | 
            +
                # Returns whatever is returned by executor.
         | 
| 218 | 
            +
                def delete(args = {})
         | 
| 219 | 
            +
                  @executor.call({
         | 
| 220 | 
            +
                    command: :column_family_delete,
         | 
| 221 | 
            +
                    arguments: args.merge({
         | 
| 222 | 
            +
                      name: @name,
         | 
| 223 | 
            +
                      keyspace_name: @keyspace.name,
         | 
| 224 | 
            +
                    }),
         | 
| 225 | 
            +
                  })
         | 
| 226 | 
            +
                end
         | 
| 227 | 
            +
             | 
| 228 | 
            +
                # Internal
         | 
| 229 | 
            +
                def schema
         | 
| 230 | 
            +
                  @schema || raise(Cassanity::Error.new(message: "No schema found to create #{@name} column family. Please set :schema during initialization or include it as a key in #create call."))
         | 
| 231 | 
            +
                end
         | 
| 232 | 
            +
              end
         | 
| 233 | 
            +
            end
         | 
| @@ -0,0 +1,88 @@ | |
| 1 | 
            +
            require 'cassanity/keyspace'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Cassanity
         | 
| 4 | 
            +
              class Connection
         | 
| 5 | 
            +
                # Internal
         | 
| 6 | 
            +
                attr_reader :executor
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                # Public: Initializes a connection
         | 
| 9 | 
            +
                #
         | 
| 10 | 
            +
                # args - The Hash of arguments (default: {}).
         | 
| 11 | 
            +
                #        :executor - What will execute the CQL statements.
         | 
| 12 | 
            +
                #                    Must respond to `call`.
         | 
| 13 | 
            +
                def initialize(args = {})
         | 
| 14 | 
            +
                  @executor = args.fetch(:executor)
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                # Public: Group multiple statements into a batch.
         | 
| 18 | 
            +
                #
         | 
| 19 | 
            +
                # args - The Hash of arguments to pass to the argument generator
         | 
| 20 | 
            +
                #        (default: {}).
         | 
| 21 | 
            +
                #
         | 
| 22 | 
            +
                # Examples
         | 
| 23 | 
            +
                #
         | 
| 24 | 
            +
                #   batch({
         | 
| 25 | 
            +
                #     modifications: [
         | 
| 26 | 
            +
                #       [:insert, name: 'apps', data: {id: '1', name: 'github'}],
         | 
| 27 | 
            +
                #       [:insert, name: 'apps', data: {id: '2', name: 'gist'}],
         | 
| 28 | 
            +
                #       [:update, name: 'apps', set: {name: 'github.com'}, where: {id: '1'}],
         | 
| 29 | 
            +
                #       [:delete, name: 'apps', where: {id: '2'}],
         | 
| 30 | 
            +
                #     ]
         | 
| 31 | 
            +
                #   })
         | 
| 32 | 
            +
                #
         | 
| 33 | 
            +
                # Returns whatever is returned by executor.
         | 
| 34 | 
            +
                def batch(args = {})
         | 
| 35 | 
            +
                  @executor.call({
         | 
| 36 | 
            +
                    command: :batch,
         | 
| 37 | 
            +
                    arguments: args,
         | 
| 38 | 
            +
                  })
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                # Public: Get all keyspaces.
         | 
| 42 | 
            +
                #
         | 
| 43 | 
            +
                # Returns Array of Cassanity::Keyspace instances.
         | 
| 44 | 
            +
                def keyspaces
         | 
| 45 | 
            +
                  keyspaces = []
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                  result = @executor.call({
         | 
| 48 | 
            +
                    command: :keyspaces,
         | 
| 49 | 
            +
                  })
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                  result.fetch_hash do |row|
         | 
| 52 | 
            +
                    keyspaces << row
         | 
| 53 | 
            +
                  end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                  keyspaces.map { |row|
         | 
| 56 | 
            +
                    Keyspace.new({
         | 
| 57 | 
            +
                      name: row['name'],
         | 
| 58 | 
            +
                      executor: @executor,
         | 
| 59 | 
            +
                    })
         | 
| 60 | 
            +
                  }
         | 
| 61 | 
            +
                end
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                # Public: Find out if a keyspace exists or not
         | 
| 64 | 
            +
                #
         | 
| 65 | 
            +
                # name - The String name of the keyspace
         | 
| 66 | 
            +
                #
         | 
| 67 | 
            +
                # Returns true if keyspace exists else false.
         | 
| 68 | 
            +
                def keyspace?(name)
         | 
| 69 | 
            +
                  keyspaces.map(&:name).include?(name)
         | 
| 70 | 
            +
                end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                # Public: Get a keyspace instance
         | 
| 73 | 
            +
                #
         | 
| 74 | 
            +
                # name - The String name of the keyspace.
         | 
| 75 | 
            +
                #
         | 
| 76 | 
            +
                # Returns a Cassanity::Keyspace instance.
         | 
| 77 | 
            +
                def keyspace(name, args = {})
         | 
| 78 | 
            +
                  keyspace_args = args.merge({
         | 
| 79 | 
            +
                    name: name,
         | 
| 80 | 
            +
                    executor: @executor,
         | 
| 81 | 
            +
                  })
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                  Keyspace.new(keyspace_args)
         | 
| 84 | 
            +
                end
         | 
| 85 | 
            +
             | 
| 86 | 
            +
                alias_method :[], :keyspace
         | 
| 87 | 
            +
              end
         | 
| 88 | 
            +
            end
         |