cassanity 0.2.2 → 0.3.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/Changelog.md +5 -0
- data/Guardfile +8 -1
- data/README.md +8 -0
- data/examples/_shared.rb +1 -0
- data/examples/batch.rb +4 -1
- data/examples/column_families.rb +3 -1
- data/examples/counters.rb +90 -0
- data/examples/keyspaces.rb +3 -1
- data/examples/select_range.rb +118 -0
- data/lib/cassanity/argument_generators/set_clause.rb +7 -8
- data/lib/cassanity/argument_generators/where_clause.rb +19 -1
- data/lib/cassanity/decrement.rb +27 -0
- data/lib/cassanity/executors/cassandra_cql.rb +1 -1
- data/lib/cassanity/increment.rb +27 -0
- data/lib/cassanity/operator.rb +27 -0
- data/lib/cassanity/operators/eq.rb +15 -0
- data/lib/cassanity/operators/gt.rb +15 -0
- data/lib/cassanity/operators/gte.rb +15 -0
- data/lib/cassanity/operators/lt.rb +15 -0
- data/lib/cassanity/operators/lte.rb +15 -0
- data/lib/cassanity/version.rb +1 -1
- data/lib/cassanity.rb +84 -0
- data/spec/integration/cassanity/column_family_spec.rb +69 -2
- data/spec/unit/cassanity/argument_generators/set_clause_spec.rb +9 -46
- data/spec/unit/cassanity/argument_generators/where_clause_spec.rb +87 -8
- data/spec/unit/cassanity/decrement_spec.rb +68 -0
- data/spec/unit/cassanity/increment_spec.rb +68 -0
- data/spec/unit/cassanity/operator_spec.rb +58 -0
- data/spec/unit/cassanity/operators/eq_spec.rb +24 -0
- data/spec/unit/cassanity/operators/gt_spec.rb +24 -0
- data/spec/unit/cassanity/operators/gte_spec.rb +24 -0
- data/spec/unit/cassanity/operators/lt_spec.rb +24 -0
- data/spec/unit/cassanity/operators/lte_spec.rb +24 -0
- data/spec/unit/cassanity_spec.rb +118 -0
- metadata +30 -4
data/Changelog.md
CHANGED
@@ -2,6 +2,11 @@
|
|
2
2
|
|
3
3
|
Not all changes will be here, but the important ones will be for sure.
|
4
4
|
|
5
|
+
## 0.3.0
|
6
|
+
|
7
|
+
* Changed [update counter value API](https://github.com/jnunemaker/cassanity/commit/a0f5a76)
|
8
|
+
* Added [support for range queries](https://github.com/jnunemaker/cassanity/commit/5d89ada)
|
9
|
+
|
5
10
|
## 0.2.2
|
6
11
|
|
7
12
|
* Added [Keyspace#column_families](https://github.com/jnunemaker/cassanity/commit/8101835)
|
data/Guardfile
CHANGED
@@ -6,7 +6,14 @@ guard 'bundler' do
|
|
6
6
|
watch(/^.+\.gemspec/)
|
7
7
|
end
|
8
8
|
|
9
|
-
|
9
|
+
rspec_options = {
|
10
|
+
version: 2,
|
11
|
+
all_after_pass: false,
|
12
|
+
all_on_start: false,
|
13
|
+
keep_failed: false
|
14
|
+
}
|
15
|
+
|
16
|
+
guard 'rspec', rspec_options do
|
10
17
|
watch(%r{^spec/.+_spec\.rb$})
|
11
18
|
watch(%r{^lib/(.+)\.rb$}) { |m| [
|
12
19
|
"spec/unit/#{m[1]}_spec.rb",
|
data/README.md
CHANGED
@@ -84,6 +84,14 @@ apps.truncate
|
|
84
84
|
apps.drop
|
85
85
|
```
|
86
86
|
|
87
|
+
You can also do a lot more. Here are a few more [examples](https://github.com/jnunemaker/cassanity/tree/master/examples):
|
88
|
+
|
89
|
+
* [Batch Operations](https://github.com/jnunemaker/cassanity/tree/master/examples/batch.rb)
|
90
|
+
* [Counters](https://github.com/jnunemaker/cassanity/tree/master/examples/counters.rb)
|
91
|
+
* [Keyspaces](https://github.com/jnunemaker/cassanity/tree/master/examples/keyspaces.rb)
|
92
|
+
* [Column Families](https://github.com/jnunemaker/cassanity/tree/master/examples/column_families.rb)
|
93
|
+
* [Select a Range](https://github.com/jnunemaker/cassanity/tree/master/examples/select_range.rb)
|
94
|
+
|
87
95
|
## Compatibility
|
88
96
|
|
89
97
|
* Ruby 1.9.3
|
data/examples/_shared.rb
CHANGED
data/examples/batch.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
require_relative '_shared'
|
2
2
|
require 'cassanity'
|
3
3
|
|
4
|
-
client = CassandraCQL::Database.new('127.0.0.1:9160'
|
4
|
+
client = CassandraCQL::Database.new('127.0.0.1:9160', {
|
5
|
+
cql_version: '3.0.0',
|
6
|
+
})
|
7
|
+
|
5
8
|
executor = Cassanity::Executors::CassandraCql.new(client: client)
|
6
9
|
|
7
10
|
connection = Cassanity::Connection.new(executor: executor)
|
data/examples/column_families.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
require_relative '_shared'
|
2
2
|
require 'cassanity'
|
3
3
|
|
4
|
-
client = CassandraCQL::Database.new('127.0.0.1:9160'
|
4
|
+
client = CassandraCQL::Database.new('127.0.0.1:9160', {
|
5
|
+
cql_version: '3.0.0',
|
6
|
+
})
|
5
7
|
executor = Cassanity::Executors::CassandraCql.new(client: client)
|
6
8
|
|
7
9
|
connection = Cassanity::Connection.new(executor: executor)
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require_relative '_shared'
|
2
|
+
require 'cassanity'
|
3
|
+
|
4
|
+
client = CassandraCQL::Database.new('127.0.0.1:9160', {
|
5
|
+
cql_version: '3.0.0',
|
6
|
+
})
|
7
|
+
|
8
|
+
executor = Cassanity::Executors::CassandraCql.new({
|
9
|
+
client: client,
|
10
|
+
logger: Logger.new(STDOUT),
|
11
|
+
})
|
12
|
+
|
13
|
+
connection = Cassanity::Connection.new(executor: executor)
|
14
|
+
keyspace = connection['cassanity_examples']
|
15
|
+
keyspace.recreate
|
16
|
+
|
17
|
+
rollups_schema = Cassanity::Schema.new({
|
18
|
+
primary_key: :id,
|
19
|
+
columns: {
|
20
|
+
id: :text,
|
21
|
+
value: :counter,
|
22
|
+
},
|
23
|
+
})
|
24
|
+
|
25
|
+
# get an instance of a column family, providing schema means it can create itself
|
26
|
+
rollups = keyspace.column_family({
|
27
|
+
name: :rollups,
|
28
|
+
schema: rollups_schema,
|
29
|
+
})
|
30
|
+
|
31
|
+
# create column family based on schema
|
32
|
+
rollups.create
|
33
|
+
|
34
|
+
# increment by 1
|
35
|
+
rollups.update({
|
36
|
+
set: {value: Cassanity::Increment.new},
|
37
|
+
where: {id: :views},
|
38
|
+
})
|
39
|
+
|
40
|
+
# increment by 3
|
41
|
+
rollups.update({
|
42
|
+
set: {value: Cassanity::Increment.new(3)},
|
43
|
+
where: {id: :views},
|
44
|
+
})
|
45
|
+
|
46
|
+
# increment by 3
|
47
|
+
rollups.update({
|
48
|
+
set: {value: Cassanity::Increment(3)},
|
49
|
+
where: {id: :views},
|
50
|
+
})
|
51
|
+
|
52
|
+
# increment by 3
|
53
|
+
# you can also use .incr and .increment
|
54
|
+
rollups.update({
|
55
|
+
set: {value: Cassanity.inc(3)},
|
56
|
+
where: {id: :views},
|
57
|
+
})
|
58
|
+
|
59
|
+
# returns 10
|
60
|
+
pp rollups.select(where: {id: :views})[0]['value']
|
61
|
+
|
62
|
+
# decrement by 1
|
63
|
+
rollups.update({
|
64
|
+
set: {value: Cassanity::Decrement.new},
|
65
|
+
where: {id: :views},
|
66
|
+
})
|
67
|
+
|
68
|
+
# decrement by 2
|
69
|
+
rollups.update({
|
70
|
+
set: {value: Cassanity::Decrement.new(2)},
|
71
|
+
where: {id: :views},
|
72
|
+
})
|
73
|
+
|
74
|
+
# decrement by 2
|
75
|
+
rollups.update({
|
76
|
+
set: {value: Cassanity::Decrement(2)},
|
77
|
+
where: {id: :views},
|
78
|
+
})
|
79
|
+
|
80
|
+
# decrement by 2
|
81
|
+
# you can also use .decr and .decrement
|
82
|
+
rollups.update({
|
83
|
+
set: {value: Cassanity.dec(2)},
|
84
|
+
where: {id: :views},
|
85
|
+
})
|
86
|
+
|
87
|
+
# returns 3
|
88
|
+
pp rollups.select(where: {id: :views})[0]['value']
|
89
|
+
|
90
|
+
keyspace.drop
|
data/examples/keyspaces.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
require_relative '_shared'
|
2
2
|
require 'cassanity'
|
3
3
|
|
4
|
-
client = CassandraCQL::Database.new('127.0.0.1:9160'
|
4
|
+
client = CassandraCQL::Database.new('127.0.0.1:9160', {
|
5
|
+
cql_version: '3.0.0',
|
6
|
+
})
|
5
7
|
executor = Cassanity::Executors::CassandraCql.new(client: client)
|
6
8
|
|
7
9
|
connection = Cassanity::Connection.new(executor: executor)
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require_relative '_shared'
|
2
|
+
require 'cassanity'
|
3
|
+
|
4
|
+
client = CassandraCQL::Database.new('127.0.0.1:9160', {
|
5
|
+
cql_version: '3.0.0',
|
6
|
+
})
|
7
|
+
|
8
|
+
executor = Cassanity::Executors::CassandraCql.new({
|
9
|
+
client: client,
|
10
|
+
logger: Logger.new(STDOUT),
|
11
|
+
})
|
12
|
+
|
13
|
+
connection = Cassanity::Connection.new(executor: executor)
|
14
|
+
keyspace = connection['cassanity_examples']
|
15
|
+
keyspace.recreate
|
16
|
+
|
17
|
+
rollups_schema = Cassanity::Schema.new({
|
18
|
+
primary_key: [:id, :timestamp],
|
19
|
+
columns: {
|
20
|
+
id: :text,
|
21
|
+
timestamp: :int,
|
22
|
+
value: :counter,
|
23
|
+
},
|
24
|
+
})
|
25
|
+
|
26
|
+
# get an instance of a column family, providing schema means it can create itself
|
27
|
+
rollups = keyspace.column_family({
|
28
|
+
name: :rollups,
|
29
|
+
schema: rollups_schema,
|
30
|
+
})
|
31
|
+
|
32
|
+
# create column family based on schema
|
33
|
+
rollups.create
|
34
|
+
|
35
|
+
[
|
36
|
+
[1, rand(1_000)],
|
37
|
+
[2, rand(1_000)],
|
38
|
+
[3, rand(1_000)],
|
39
|
+
[4, rand(1_000)],
|
40
|
+
[5, rand(1_000)],
|
41
|
+
].each do |pair|
|
42
|
+
timestamp, value = pair
|
43
|
+
rollups.update({
|
44
|
+
set: {value: Cassanity::Increment.new(value)},
|
45
|
+
where: {
|
46
|
+
id: :views,
|
47
|
+
timestamp: timestamp,
|
48
|
+
}
|
49
|
+
})
|
50
|
+
end
|
51
|
+
|
52
|
+
# returns timestamps 1, 2 and 3
|
53
|
+
pp rollups.select({
|
54
|
+
where: {
|
55
|
+
id: :views,
|
56
|
+
timestamp: Range.new(1, 3),
|
57
|
+
}
|
58
|
+
})
|
59
|
+
|
60
|
+
# also works with exclusion of end ranges
|
61
|
+
# returns 1 and 2
|
62
|
+
pp rollups.select({
|
63
|
+
where: {
|
64
|
+
id: :views,
|
65
|
+
timestamp: Range.new(1, 3, true),
|
66
|
+
}
|
67
|
+
})
|
68
|
+
|
69
|
+
# also works with operators
|
70
|
+
# returns 3, 4 and 5
|
71
|
+
pp rollups.select({
|
72
|
+
where: {
|
73
|
+
id: :views,
|
74
|
+
timestamp: Cassanity::Operator.new(:>, 2),
|
75
|
+
}
|
76
|
+
})
|
77
|
+
|
78
|
+
# returns 2, 3, 4 and 5
|
79
|
+
pp rollups.select({
|
80
|
+
where: {
|
81
|
+
id: :views,
|
82
|
+
timestamp: Cassanity::Operator.new(:>=, 2),
|
83
|
+
}
|
84
|
+
})
|
85
|
+
|
86
|
+
puts "\n\n ALL BELOW SHOULD RETURN 1 \n\n"
|
87
|
+
|
88
|
+
# returns 1
|
89
|
+
pp rollups.select({
|
90
|
+
where: {
|
91
|
+
id: :views,
|
92
|
+
timestamp: Cassanity::Operator.new(:<, 2),
|
93
|
+
}
|
94
|
+
})
|
95
|
+
|
96
|
+
# returns 1
|
97
|
+
pp rollups.select({
|
98
|
+
where: {
|
99
|
+
id: :views,
|
100
|
+
timestamp: Cassanity::Operators::Lt.new(2),
|
101
|
+
}
|
102
|
+
})
|
103
|
+
|
104
|
+
# returns 1
|
105
|
+
pp rollups.select({
|
106
|
+
where: {
|
107
|
+
id: :views,
|
108
|
+
timestamp: Cassanity::Operators::Lt(2),
|
109
|
+
}
|
110
|
+
})
|
111
|
+
|
112
|
+
# returns 1
|
113
|
+
pp rollups.select({
|
114
|
+
where: {
|
115
|
+
id: :views,
|
116
|
+
timestamp: Cassanity.lt(2),
|
117
|
+
}
|
118
|
+
})
|
@@ -1,3 +1,6 @@
|
|
1
|
+
require 'cassanity/increment'
|
2
|
+
require 'cassanity/decrement'
|
3
|
+
|
1
4
|
module Cassanity
|
2
5
|
module ArgumentGenerators
|
3
6
|
class SetClause
|
@@ -8,8 +11,10 @@ module Cassanity
|
|
8
11
|
cql, variables, sets = '', [], []
|
9
12
|
|
10
13
|
set.each do |key, value|
|
11
|
-
|
12
|
-
|
14
|
+
case value
|
15
|
+
when Cassanity::Increment, Cassanity::Decrement
|
16
|
+
sets << "#{key} = #{key} #{value.symbol} ?"
|
17
|
+
variables << value.value
|
13
18
|
else
|
14
19
|
sets << "#{key} = ?"
|
15
20
|
variables << value
|
@@ -17,14 +22,8 @@ module Cassanity
|
|
17
22
|
end
|
18
23
|
cql << " SET #{sets.join(', ')}"
|
19
24
|
|
20
|
-
|
21
25
|
[cql, *variables]
|
22
26
|
end
|
23
|
-
|
24
|
-
# Private
|
25
|
-
def counter?(key, value)
|
26
|
-
value.is_a?(String) && value.match(/#{key}(\s+)?[\+\-](\s+)?\d/)
|
27
|
-
end
|
28
27
|
end
|
29
28
|
end
|
30
29
|
end
|
@@ -1,3 +1,10 @@
|
|
1
|
+
require 'cassanity/operator'
|
2
|
+
require 'cassanity/operators/eq'
|
3
|
+
require 'cassanity/operators/gt'
|
4
|
+
require 'cassanity/operators/gte'
|
5
|
+
require 'cassanity/operators/lt'
|
6
|
+
require 'cassanity/operators/lte'
|
7
|
+
|
1
8
|
module Cassanity
|
2
9
|
module ArgumentGenerators
|
3
10
|
class WhereClause
|
@@ -11,9 +18,20 @@ module Cassanity
|
|
11
18
|
variables, wheres = [], []
|
12
19
|
|
13
20
|
where.each do |key, value|
|
14
|
-
|
21
|
+
case value
|
22
|
+
when Array
|
15
23
|
wheres << "#{key} IN (?)"
|
16
24
|
variables << value
|
25
|
+
when Range
|
26
|
+
start, finish = value.begin, value.end
|
27
|
+
end_operator = value.exclude_end? ? '<' : '<='
|
28
|
+
wheres << "#{key} >= ?"
|
29
|
+
wheres << "#{key} #{end_operator} ?"
|
30
|
+
variables << start
|
31
|
+
variables << finish
|
32
|
+
when Cassanity::Operator
|
33
|
+
wheres << "#{key} #{value.symbol} ?"
|
34
|
+
variables << value.value
|
17
35
|
else
|
18
36
|
wheres << "#{key} = ?"
|
19
37
|
variables << value
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Cassanity
|
2
|
+
def self.Decrement(*args)
|
3
|
+
Decrement.new(*args)
|
4
|
+
end
|
5
|
+
|
6
|
+
class Decrement
|
7
|
+
# Internal
|
8
|
+
attr_reader :symbol
|
9
|
+
|
10
|
+
# Internal
|
11
|
+
attr_reader :value
|
12
|
+
|
13
|
+
# Public: Returns an decrement instance
|
14
|
+
def initialize(value = 1)
|
15
|
+
raise ArgumentError.new("value cannot be nil") if value.nil?
|
16
|
+
|
17
|
+
@symbol = :-
|
18
|
+
@value = value
|
19
|
+
end
|
20
|
+
|
21
|
+
def eql?(other)
|
22
|
+
self.class.eql?(other.class) && value == other.value
|
23
|
+
end
|
24
|
+
|
25
|
+
alias_method :==, :eql?
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Cassanity
|
2
|
+
def self.Increment(*args)
|
3
|
+
Increment.new(*args)
|
4
|
+
end
|
5
|
+
|
6
|
+
class Increment
|
7
|
+
# Internal
|
8
|
+
attr_reader :symbol
|
9
|
+
|
10
|
+
# Internal
|
11
|
+
attr_reader :value
|
12
|
+
|
13
|
+
# Public: Returns an increment instance
|
14
|
+
def initialize(value = 1)
|
15
|
+
raise ArgumentError.new("value cannot be nil") if value.nil?
|
16
|
+
|
17
|
+
@symbol = :+
|
18
|
+
@value = value
|
19
|
+
end
|
20
|
+
|
21
|
+
def eql?(other)
|
22
|
+
self.class.eql?(other.class) && value == other.value
|
23
|
+
end
|
24
|
+
|
25
|
+
alias_method :==, :eql?
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Cassanity
|
2
|
+
def self.Operator(*args)
|
3
|
+
Operator.new(*args)
|
4
|
+
end
|
5
|
+
|
6
|
+
class Operator
|
7
|
+
# Internal
|
8
|
+
attr_reader :symbol
|
9
|
+
|
10
|
+
# Internal
|
11
|
+
attr_reader :value
|
12
|
+
|
13
|
+
# Public: Returns an operator instance
|
14
|
+
def initialize(symbol, value)
|
15
|
+
@symbol = symbol
|
16
|
+
@value = value
|
17
|
+
end
|
18
|
+
|
19
|
+
def eql?(other)
|
20
|
+
self.class.eql?(other.class) &&
|
21
|
+
value == other.value &&
|
22
|
+
symbol == other.symbol
|
23
|
+
end
|
24
|
+
|
25
|
+
alias_method :==, :eql?
|
26
|
+
end
|
27
|
+
end
|
data/lib/cassanity/version.rb
CHANGED
data/lib/cassanity.rb
CHANGED
@@ -1,4 +1,88 @@
|
|
1
|
+
require 'cassanity/operators/eq'
|
2
|
+
require 'cassanity/operators/gt'
|
3
|
+
require 'cassanity/operators/gte'
|
4
|
+
require 'cassanity/operators/lt'
|
5
|
+
require 'cassanity/operators/lte'
|
6
|
+
|
1
7
|
module Cassanity
|
8
|
+
# Public: Shortcut for returning an equality operator.
|
9
|
+
#
|
10
|
+
# args - The arguments to pass to the initialize method of the operator.
|
11
|
+
#
|
12
|
+
# Returns a Cassanity::Operators::Eq instance.
|
13
|
+
def self.eq(*args)
|
14
|
+
Operators::Eq.new(*args)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Public: Shortcut for returning a less than operator.
|
18
|
+
#
|
19
|
+
# args - The arguments to pass to the initialize method of the operator.
|
20
|
+
#
|
21
|
+
# Returns a Cassanity::Operators::Lt instance.
|
22
|
+
def self.lt(*args)
|
23
|
+
Operators::Lt.new(*args)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Public: Shortcut for returning a less than or equal to operator.
|
27
|
+
#
|
28
|
+
# args - The arguments to pass to the initialize method of the operator.
|
29
|
+
#
|
30
|
+
# Returns a Cassanity::Operators::Lte instance.
|
31
|
+
def self.lte(*args)
|
32
|
+
Operators::Lte.new(*args)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Public: Shortcut for returning a greater than operator.
|
36
|
+
#
|
37
|
+
# args - The arguments to pass to the initialize method of the operator.
|
38
|
+
#
|
39
|
+
# Returns a Cassanity::Operators::Gt instance.
|
40
|
+
def self.gt(*args)
|
41
|
+
Operators::Gt.new(*args)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Public: Shortcut for returning a greater than or equal to operator.
|
45
|
+
#
|
46
|
+
# args - The arguments to pass to the initialize method of the operator.
|
47
|
+
#
|
48
|
+
# Returns a Cassanity::Operators::Gte instance.
|
49
|
+
def self.gte(*args)
|
50
|
+
Operators::Gte.new(*args)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Public: Shortcut for returning an increment value for a counter update.
|
54
|
+
#
|
55
|
+
# value - The value to initialize the increment with (optional, default: 1).
|
56
|
+
#
|
57
|
+
# Returns a Cassanity::Increment instance.
|
58
|
+
def self.inc(value = 1)
|
59
|
+
Increment.new(value)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Public: Shortcut for returning a decrement value for a counter update.
|
63
|
+
#
|
64
|
+
# value - The value to initialize the decrement with (optional, default: 1).
|
65
|
+
#
|
66
|
+
# Returns a Cassanity::Decrement instance.
|
67
|
+
def self.dec(value = 1)
|
68
|
+
Decrement.new(value)
|
69
|
+
end
|
70
|
+
|
71
|
+
class << self
|
72
|
+
alias_method :equal, :eq
|
73
|
+
|
74
|
+
alias_method :greater_than, :gt
|
75
|
+
alias_method :greater_than_or_equal_to, :gte
|
76
|
+
|
77
|
+
alias_method :less_than, :lt
|
78
|
+
alias_method :less_than_or_equal_to, :lte
|
79
|
+
|
80
|
+
alias_method :incr, :inc
|
81
|
+
alias_method :increment, :inc
|
82
|
+
|
83
|
+
alias_method :decr, :dec
|
84
|
+
alias_method :decrement, :dec
|
85
|
+
end
|
2
86
|
end
|
3
87
|
|
4
88
|
require 'cassanity/connection'
|