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.
Files changed (76) hide show
  1. data/.gitignore +19 -0
  2. data/.rspec +1 -0
  3. data/.travis.yml +10 -0
  4. data/Gemfile +11 -0
  5. data/Guardfile +17 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +99 -0
  8. data/Rakefile +16 -0
  9. data/cassanity.gemspec +21 -0
  10. data/examples/_shared.rb +8 -0
  11. data/examples/batch.rb +40 -0
  12. data/examples/column_families.rb +68 -0
  13. data/examples/keyspaces.rb +57 -0
  14. data/lib/cassanity/argument_generators/batch.rb +52 -0
  15. data/lib/cassanity/argument_generators/column_family_alter.rb +47 -0
  16. data/lib/cassanity/argument_generators/column_family_create.rb +44 -0
  17. data/lib/cassanity/argument_generators/column_family_delete.rb +65 -0
  18. data/lib/cassanity/argument_generators/column_family_drop.rb +18 -0
  19. data/lib/cassanity/argument_generators/column_family_insert.rb +53 -0
  20. data/lib/cassanity/argument_generators/column_family_select.rb +34 -0
  21. data/lib/cassanity/argument_generators/column_family_truncate.rb +18 -0
  22. data/lib/cassanity/argument_generators/column_family_update.rb +69 -0
  23. data/lib/cassanity/argument_generators/index_create.rb +22 -0
  24. data/lib/cassanity/argument_generators/index_drop.rb +13 -0
  25. data/lib/cassanity/argument_generators/keyspace_create.rb +51 -0
  26. data/lib/cassanity/argument_generators/keyspace_drop.rb +13 -0
  27. data/lib/cassanity/argument_generators/keyspace_use.rb +13 -0
  28. data/lib/cassanity/argument_generators/keyspaces.rb +12 -0
  29. data/lib/cassanity/argument_generators/set_clause.rb +30 -0
  30. data/lib/cassanity/argument_generators/using_clause.rb +24 -0
  31. data/lib/cassanity/argument_generators/where_clause.rb +29 -0
  32. data/lib/cassanity/argument_generators/with_clause.rb +32 -0
  33. data/lib/cassanity/column_family.rb +233 -0
  34. data/lib/cassanity/connection.rb +88 -0
  35. data/lib/cassanity/error.rb +28 -0
  36. data/lib/cassanity/executors/cassandra_cql.rb +120 -0
  37. data/lib/cassanity/keyspace.rb +118 -0
  38. data/lib/cassanity/result_transformers/column_family_select.rb +15 -0
  39. data/lib/cassanity/result_transformers/mirror.rb +12 -0
  40. data/lib/cassanity/schema.rb +26 -0
  41. data/lib/cassanity/version.rb +3 -0
  42. data/lib/cassanity.rb +5 -0
  43. data/spec/helper.rb +27 -0
  44. data/spec/integration/cassanity/column_family_spec.rb +243 -0
  45. data/spec/integration/cassanity/connection_spec.rb +87 -0
  46. data/spec/integration/cassanity/keyspace_spec.rb +64 -0
  47. data/spec/support/cassanity_helpers.rb +35 -0
  48. data/spec/unit/cassanity/argument_generators/batch_spec.rb +36 -0
  49. data/spec/unit/cassanity/argument_generators/column_family_alter_spec.rb +85 -0
  50. data/spec/unit/cassanity/argument_generators/column_family_create_spec.rb +107 -0
  51. data/spec/unit/cassanity/argument_generators/column_family_delete_spec.rb +92 -0
  52. data/spec/unit/cassanity/argument_generators/column_family_drop_spec.rb +25 -0
  53. data/spec/unit/cassanity/argument_generators/column_family_insert_spec.rb +70 -0
  54. data/spec/unit/cassanity/argument_generators/column_family_select_spec.rb +113 -0
  55. data/spec/unit/cassanity/argument_generators/column_family_truncate_spec.rb +25 -0
  56. data/spec/unit/cassanity/argument_generators/column_family_update_spec.rb +109 -0
  57. data/spec/unit/cassanity/argument_generators/index_create_spec.rb +39 -0
  58. data/spec/unit/cassanity/argument_generators/index_drop_spec.rb +14 -0
  59. data/spec/unit/cassanity/argument_generators/keyspace_create_spec.rb +53 -0
  60. data/spec/unit/cassanity/argument_generators/keyspace_drop_spec.rb +14 -0
  61. data/spec/unit/cassanity/argument_generators/keyspace_use_spec.rb +14 -0
  62. data/spec/unit/cassanity/argument_generators/keyspaces_spec.rb +12 -0
  63. data/spec/unit/cassanity/argument_generators/set_clause_spec.rb +85 -0
  64. data/spec/unit/cassanity/argument_generators/using_clause_spec.rb +44 -0
  65. data/spec/unit/cassanity/argument_generators/where_clause_spec.rb +57 -0
  66. data/spec/unit/cassanity/argument_generators/with_clause_spec.rb +63 -0
  67. data/spec/unit/cassanity/column_family_spec.rb +250 -0
  68. data/spec/unit/cassanity/connection_spec.rb +75 -0
  69. data/spec/unit/cassanity/error_spec.rb +35 -0
  70. data/spec/unit/cassanity/executors/cassandra_cql_spec.rb +178 -0
  71. data/spec/unit/cassanity/keyspace_spec.rb +137 -0
  72. data/spec/unit/cassanity/result_transformers/column_family_select_spec.rb +0 -0
  73. data/spec/unit/cassanity/result_transformers/mirror_spec.rb +12 -0
  74. data/spec/unit/cassanity/schema_spec.rb +23 -0
  75. data/spec/unit/cassanity_spec.rb +5 -0
  76. metadata +172 -0
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ bin
19
+ vendor/gems
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,10 @@
1
+ gemfile:
2
+ - Gemfile
3
+ language: ruby
4
+ rvm:
5
+ - 1.9.3
6
+ notifications:
7
+ email: false
8
+ bundler_args: --without guard
9
+ services:
10
+ - cassandra
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
3
+
4
+ gem 'rake'
5
+ gem 'rspec', '~> 2.8'
6
+
7
+ group(:guard) do
8
+ gem 'guard', '~> 1.0.0'
9
+ gem 'guard-rspec', '~> 0.6.0'
10
+ gem 'guard-bundler', '~> 0.1.0'
11
+ end
data/Guardfile ADDED
@@ -0,0 +1,17 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'bundler' do
5
+ watch('Gemfile')
6
+ watch(/^.+\.gemspec/)
7
+ end
8
+
9
+ guard 'rspec', :version => 2 do
10
+ watch(%r{^spec/.+_spec\.rb$})
11
+ watch(%r{^lib/(.+)\.rb$}) { |m| [
12
+ "spec/unit/#{m[1]}_spec.rb",
13
+ "spec/integration/#{m[1]}_spec.rb",
14
+ ] }
15
+ watch('spec/helper.rb') { "spec" }
16
+ end
17
+
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 John Nunemaker
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,99 @@
1
+ # Cassanity
2
+
3
+ Layer of goodness on top of cassandra-cql so you do not have to write CQL strings all over the place.
4
+
5
+ Current status: Incomplete and changing fast. **Do not use this yet**, but feel free to follow along.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'cassanity'
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install cassanity
20
+
21
+ ## Usage
22
+
23
+ ```ruby
24
+ require 'cassanity'
25
+
26
+ # cassandra-cql connection
27
+ client = CassandraCQL::Database.new('127.0.0.1:9160', {
28
+ cql_version: '3.0.0',
29
+ })
30
+
31
+ # what is going to execute the cql queries?
32
+ executor = Cassanity::Executors::CassandraCql.new({
33
+ client: client,
34
+ })
35
+
36
+ # setup connection with something that can execute queries
37
+ connection = Cassanity::Connection.new({
38
+ executor: executor,
39
+ })
40
+
41
+ # get keyspace instance
42
+ keyspace = connection[:my_app]
43
+
44
+ # tell client to use keyspace for future queries
45
+ keyspace.use
46
+
47
+ # schema for apps column family
48
+ apps_schema = Cassanity::Schema.new({
49
+ primary_key: :id,
50
+ columns: {
51
+ id: :text,
52
+ name: :text,
53
+ created_at: :timestamp,
54
+ },
55
+ with: {
56
+ comment: 'For storing apps',
57
+ }
58
+ })
59
+
60
+ # get instance of column family with name and schema set
61
+ apps = keyspace.column_family({
62
+ name: :apps,
63
+ schema: apps_schema,
64
+ })
65
+
66
+ # create column family based on name and schema
67
+ apps.create
68
+
69
+ # insert row
70
+ apps.insert(data: {
71
+ id: '1',
72
+ name: 'GitHub.com',
73
+ created_at: Time.now,
74
+ })
75
+
76
+ # update name for row
77
+ apps.update(set: {name: 'GitHub'}, where: {id: '1'})
78
+
79
+ # delete row
80
+ apps.delete(where: {id: '1'})
81
+
82
+ # truncate column family (remove all rows, still can add new stuff)
83
+ apps.truncate
84
+
85
+ # drop column family (no more inserting into it, it is gone)
86
+ apps.drop
87
+ ```
88
+
89
+ ## Compatibility
90
+
91
+ * Ruby 1.9.3
92
+
93
+ ## Contributing
94
+
95
+ 1. Fork it
96
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
97
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
98
+ 4. Push to the branch (`git push origin my-new-feature`)
99
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,16 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'rspec/core/rake_task'
4
+ RSpec::Core::RakeTask.new
5
+
6
+ task :default => :spec
7
+
8
+ namespace :spec do
9
+ RSpec::Core::RakeTask.new(:integration) do |t|
10
+ t.pattern = './spec/integration/**/*_spec.rb'
11
+ end
12
+
13
+ RSpec::Core::RakeTask.new(:unit) do |t|
14
+ t.pattern = './spec/unit/**/*_spec.rb'
15
+ end
16
+ end
data/cassanity.gemspec ADDED
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'cassanity/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "cassanity"
8
+ gem.version = Cassanity::VERSION
9
+ gem.authors = ["John Nunemaker"]
10
+ gem.email = ["nunemaker@gmail.com"]
11
+ gem.description = %q{Layer of goodness on top of cassandra-cql so you do not have to write CQL strings all over the place.}
12
+ gem.summary = %q{Layer of goodness on top of cassandra-cql so you do not have to write CQL strings all over the place.}
13
+ gem.homepage = "https://github.com/jnunemaker/cassanity/"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_dependency 'cassandra-cql', '~> 1.1.3'
21
+ end
@@ -0,0 +1,8 @@
1
+ # Nothing to see here... move along.
2
+ # Sets up load path for examples and requires some stuff
3
+ require 'pp'
4
+ require 'pathname'
5
+
6
+ root_path = Pathname(__FILE__).dirname.join('..').expand_path
7
+ lib_path = root_path.join('lib')
8
+ $:.unshift(lib_path)
data/examples/batch.rb ADDED
@@ -0,0 +1,40 @@
1
+ require_relative '_shared'
2
+ require 'cassanity'
3
+
4
+ client = CassandraCQL::Database.new('127.0.0.1:9160')
5
+ executor = Cassanity::Executors::CassandraCql.new(client: client)
6
+
7
+ connection = Cassanity::Connection.new(executor: executor)
8
+ keyspace = connection['cassanity_examples']
9
+ keyspace.drop if connection.keyspace?('cassanity_examples')
10
+ keyspace.create
11
+
12
+ # setting up the apps column family
13
+ apps_schema = Cassanity::Schema.new({
14
+ primary_key: :id,
15
+ columns: {
16
+ id: :text,
17
+ name: :text,
18
+ },
19
+ })
20
+ apps = keyspace.column_family('apps', schema: apps_schema)
21
+ apps.create
22
+
23
+ # passing in keyspace and column family names by default
24
+ default_arguments = {
25
+ keyspace_name: keyspace.name,
26
+ name: apps.name,
27
+ }
28
+
29
+ # batch several operations in one network call
30
+ connection.batch({
31
+ modifications: [
32
+ [:insert, default_arguments.merge(data: {id: '1', name: 'github'})],
33
+ [:insert, default_arguments.merge(data: {id: '2', name: 'gist'})],
34
+ [:update, default_arguments.merge(set: {name: 'github.com'}, where: {id: '1'})],
35
+ [:delete, default_arguments.merge(where: {id: '2'})],
36
+ ],
37
+ })
38
+
39
+ # only github.com is left
40
+ pp apps.select
@@ -0,0 +1,68 @@
1
+ require_relative '_shared'
2
+ require 'cassanity'
3
+
4
+ client = CassandraCQL::Database.new('127.0.0.1:9160')
5
+ executor = Cassanity::Executors::CassandraCql.new(client: client)
6
+
7
+ connection = Cassanity::Connection.new(executor: executor)
8
+ keyspace = connection['cassanity_examples']
9
+ keyspace.drop if connection.keyspace?('cassanity_examples')
10
+ keyspace.create
11
+
12
+ apps_schema = Cassanity::Schema.new({
13
+ primary_key: :id,
14
+ columns: {
15
+ id: :text,
16
+ name: :text,
17
+ },
18
+ })
19
+
20
+ # get an instance of a column family, providing schema means it can create itself
21
+ apps = keyspace.column_family('apps', schema: apps_schema)
22
+
23
+ # create column family based on schema
24
+ apps.create
25
+
26
+ # insert a row
27
+ apps.insert(data: {id: '1', name: 'GitHub'})
28
+
29
+ # insert another row
30
+ apps.insert(data: {id: '2', name: 'Gist'})
31
+
32
+ # select rows from apps
33
+ pp apps.select
34
+
35
+ # update a row based on id
36
+ apps.update(set: {name: 'GitHub.com'}, where: {id: '1'})
37
+
38
+ # print out the rows again, note that GitHub is updated
39
+ pp apps.select
40
+
41
+ # now we add a timestamp column
42
+ apps.alter(add: {updated_at: :timestamp})
43
+
44
+ # note that updated_at is there now, but nil
45
+ pp apps.select
46
+
47
+ apps.update(set: {updated_at: Time.now}, where: {id: '1'})
48
+
49
+ # now the GitHub.com record has an updated_at
50
+ pp apps.select
51
+
52
+ # delete all data
53
+ apps.truncate
54
+
55
+ # now all the data is gone
56
+ pp apps.select
57
+
58
+ # completely drop the column family
59
+ apps.drop
60
+
61
+ begin
62
+ # we can no longer insert because the column family is gone
63
+ apps.insert(data: {id: '1', name: 'FAILBOAT'})
64
+
65
+ # All errors inherit from Cassanity::Error so you can catch everything easily
66
+ rescue Cassanity::Error => e
67
+ puts e.inspect
68
+ end
@@ -0,0 +1,57 @@
1
+ require_relative '_shared'
2
+ require 'cassanity'
3
+
4
+ client = CassandraCQL::Database.new('127.0.0.1:9160')
5
+ executor = Cassanity::Executors::CassandraCql.new(client: client)
6
+
7
+ connection = Cassanity::Connection.new(executor: executor)
8
+
9
+ # gets instance of keyspace
10
+ keyspace = connection['cassanity_examples']
11
+
12
+ # or you can do this...
13
+ keyspace = connection.keyspace('cassanity_examples')
14
+
15
+ pp keyspace
16
+
17
+ # you can also provide options
18
+ keyspace = connection.keyspace('cassanity_examples', {
19
+ strategy_class: 'SimpleStrategy',
20
+ strategy_options: {
21
+ replication_factor: 1,
22
+ },
23
+ })
24
+
25
+ # drop keyspace if it exists
26
+ keyspace.drop if connection.keyspace?('cassanity_examples')
27
+
28
+ # create the keyspace, uses options from above
29
+ keyspace.create
30
+
31
+ # use this keyspace
32
+ keyspace.use
33
+
34
+ # get an instance of a column family
35
+ apps = keyspace.column_family('apps')
36
+
37
+ # you can also pass a schema so the column family is all knowing
38
+ apps_schema = Cassanity::Schema.new({
39
+ primary_key: :id,
40
+ columns: {
41
+ id: :text,
42
+ name: :text,
43
+ },
44
+ })
45
+
46
+ apps = keyspace.column_family('apps', {
47
+ schema: apps_schema,
48
+ })
49
+ pp apps
50
+
51
+ # that was basically just a shortcut for this
52
+ apps = Cassanity::ColumnFamily.new({
53
+ name: 'apps',
54
+ keyspace: keyspace,
55
+ schema: apps_schema,
56
+ })
57
+ pp apps
@@ -0,0 +1,52 @@
1
+ require 'cassanity/argument_generators/using_clause'
2
+
3
+ module Cassanity
4
+ module ArgumentGenerators
5
+ class Batch
6
+
7
+ # Private: Map of command to argument generator
8
+ Commands = {
9
+ insert: ColumnFamilyInsert.new,
10
+ update: ColumnFamilyUpdate.new,
11
+ delete: ColumnFamilyDelete.new,
12
+ }
13
+
14
+ # Internal
15
+ def initialize(args = {})
16
+ @using_clause = args.fetch(:using_clause) { UsingClause.new }
17
+ @commands = args.fetch(:commands) { Commands }
18
+ end
19
+
20
+ # Internal
21
+ def call(args = {})
22
+ using = args[:using]
23
+ modifications_argument = args.fetch(:modifications) { [] }
24
+
25
+ variables = []
26
+ cql = "BEGIN BATCH"
27
+
28
+ using_cql, *using_variables = @using_clause.call(using: using)
29
+ cql << using_cql
30
+ variables.concat(using_variables)
31
+
32
+ modifications = []
33
+ modifications_argument.each do |modification|
34
+ command_name, command_arguments = modification
35
+ command = @commands.fetch(command_name)
36
+
37
+ modification_cql, *modification_variables = command.call(command_arguments)
38
+ modifications << modification_cql
39
+ variables.concat(modification_variables)
40
+ end
41
+
42
+ unless modifications.empty?
43
+ cql << " #{modifications.join(' ')}"
44
+ end
45
+
46
+ cql << " APPLY BATCH"
47
+
48
+ [cql, *variables]
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,47 @@
1
+ require 'cassanity/argument_generators/with_clause'
2
+
3
+ module Cassanity
4
+ module ArgumentGenerators
5
+ class ColumnFamilyAlter
6
+
7
+ # Internal
8
+ def initialize(args = {})
9
+ @with_clause = args.fetch(:with_clause) { WithClause.new }
10
+ end
11
+
12
+ # Internal
13
+ def call(args = {})
14
+ name = args.fetch(:name)
15
+ with = args[:with] || {}
16
+
17
+ variables = []
18
+
19
+ if (keyspace_name = args[:keyspace_name])
20
+ name = "#{keyspace_name}.#{name}"
21
+ end
22
+
23
+ cql = "ALTER COLUMNFAMILY #{name}"
24
+
25
+ if (alter = args[:alter])
26
+ column_name, column_type = alter.keys.first, alter.values.first
27
+ cql << " ALTER #{column_name} TYPE #{column_type}"
28
+ end
29
+
30
+ if (add = args[:add])
31
+ column_name, column_type = add.keys.first, add.values.first
32
+ cql << " ADD #{column_name} #{column_type}"
33
+ end
34
+
35
+ if (column_name = args[:drop])
36
+ cql << " DROP #{column_name}"
37
+ end
38
+
39
+ with_cql, *with_variables = @with_clause.call(with: with)
40
+ cql << with_cql
41
+ variables.concat(with_variables)
42
+
43
+ [cql, *variables]
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,44 @@
1
+ require 'cassanity/argument_generators/with_clause'
2
+
3
+ module Cassanity
4
+ module ArgumentGenerators
5
+ class ColumnFamilyCreate
6
+
7
+ # Internal
8
+ def initialize(args = {})
9
+ @with_clause = args.fetch(:with_clause) { WithClause.new }
10
+ end
11
+
12
+ # Internal
13
+ def call(args = {})
14
+ name = args.fetch(:name)
15
+ schema = args.fetch(:schema)
16
+ columns = schema.columns
17
+ primary_key = schema.primary_key
18
+ with = schema.with
19
+
20
+ definitions, variables = [], []
21
+
22
+ if (keyspace_name = args[:keyspace_name])
23
+ name = "#{keyspace_name}.#{name}"
24
+ end
25
+
26
+ columns.each do |name, type|
27
+ definitions << "#{name} #{type}"
28
+ end
29
+
30
+ definitions << "PRIMARY KEY (%s)" % Array(primary_key).join(', ')
31
+
32
+ cql_definition = definitions.join(', ')
33
+
34
+ cql = "CREATE COLUMNFAMILY #{name} (%s)" % cql_definition
35
+
36
+ with_cql, *with_variables = @with_clause.call(with: with)
37
+ cql << with_cql
38
+ variables.concat(with_variables)
39
+
40
+ [cql, *variables]
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,65 @@
1
+ require 'cassanity/argument_generators/where_clause'
2
+ require 'cassanity/argument_generators/using_clause'
3
+
4
+ module Cassanity
5
+ module ArgumentGenerators
6
+ class ColumnFamilyDelete
7
+
8
+ # Internal
9
+ def initialize(args = {})
10
+ @using_clause = args.fetch(:using_clause) { UsingClause.new }
11
+ @where_clause = args.fetch(:where_clause) { WhereClause.new }
12
+ end
13
+
14
+ # Internal: Converts a Hash of arguments to CQL with bound variables.
15
+ #
16
+ # args - The Hash of arguments to use.
17
+ # :name - The String name of the column family
18
+ # :where - The Hash of options to use to filter the delete
19
+ # :columns - The Array of columns you would like to delete
20
+ # (default is all columns) (optional).
21
+ # :using - The Hash of options for the query ie: consistency, ttl,
22
+ # and timestamp (default: {}) (optional).
23
+ #
24
+ # Examples
25
+ #
26
+ # call({
27
+ # name: 'apps',
28
+ # where: {
29
+ # id: '1',
30
+ # },
31
+ # })
32
+ #
33
+ # Returns Array where first element is CQL string and the rest are
34
+ # bound values.
35
+ def call(args = {})
36
+ name = args.fetch(:name)
37
+ where = args.fetch(:where)
38
+ columns = args.fetch(:columns) { [] }
39
+ using = args[:using]
40
+
41
+ if (keyspace_name = args[:keyspace_name])
42
+ name = "#{keyspace_name}.#{name}"
43
+ end
44
+
45
+ column_clause, variables = '', []
46
+
47
+ unless columns.empty?
48
+ column_clause = " #{columns.join(', ')}"
49
+ end
50
+
51
+ cql = "DELETE#{column_clause} FROM #{name}"
52
+
53
+ using_cql, *using_variables = @using_clause.call(using: using)
54
+ cql << using_cql
55
+ variables.concat(using_variables)
56
+
57
+ where_cql, *where_variables = @where_clause.call(where: where)
58
+ cql << where_cql
59
+ variables.concat(where_variables)
60
+
61
+ [cql, *variables]
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,18 @@
1
+ module Cassanity
2
+ module ArgumentGenerators
3
+ class ColumnFamilyDrop
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 = "DROP COLUMNFAMILY %s" % name
14
+ [cql]
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,53 @@
1
+ module Cassanity
2
+ module ArgumentGenerators
3
+ class ColumnFamilyInsert
4
+
5
+ # Internal: Converts a Hash of arguments to CQL with bound variables.
6
+ #
7
+ # args - The Hash of arguments to use.
8
+ # :name - The String name of the column family
9
+ # :data - The Hash of keys and values to insert
10
+ # :using - The Hash of options for the query ie: consistency, ttl,
11
+ # and timestamp (optional).
12
+ #
13
+ # Examples
14
+ #
15
+ # call({
16
+ # name: 'apps',
17
+ # data: {id: '1', name: 'GitHub'},
18
+ # })
19
+ #
20
+ # call({
21
+ # name: 'apps',
22
+ # data: {id: '1', name: 'GitHub'},
23
+ # using: {consistency: 'quorum'},
24
+ # })
25
+ #
26
+ # Returns Array where first element is CQL string and the rest are
27
+ # bound values.
28
+ def call(args = {})
29
+ name = args.fetch(:name)
30
+ data = args.fetch(:data)
31
+ using = args[:using] || {}
32
+ keys = data.keys
33
+ binders = ['?'] * keys.size
34
+
35
+ if (keyspace_name = args[:keyspace_name])
36
+ name = "#{keyspace_name}.#{name}"
37
+ end
38
+
39
+ cql = "INSERT INTO #{name} (#{keys.join(', ')}) VALUES (#{binders.join(', ')})"
40
+
41
+ unless using.empty?
42
+ statements = []
43
+ using.each do |key, value|
44
+ statements << "#{key.upcase} #{value}"
45
+ end
46
+ cql << " USING #{statements.join(' AND ')}"
47
+ end
48
+
49
+ [cql, *data.values]
50
+ end
51
+ end
52
+ end
53
+ end