cassanity 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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