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
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
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
|
data/examples/_shared.rb
ADDED
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
|