cequel 0.5.6 → 1.0.0.pre.1
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.
- checksums.yaml +7 -0
- data/lib/cequel.rb +5 -8
- data/lib/cequel/errors.rb +1 -0
- data/lib/cequel/metal.rb +17 -0
- data/lib/cequel/metal/batch.rb +62 -0
- data/lib/cequel/metal/cql_row_specification.rb +26 -0
- data/lib/cequel/metal/data_set.rb +461 -0
- data/lib/cequel/metal/deleter.rb +47 -0
- data/lib/cequel/metal/incrementer.rb +35 -0
- data/lib/cequel/metal/inserter.rb +53 -0
- data/lib/cequel/metal/keyspace.rb +213 -0
- data/lib/cequel/metal/row.rb +48 -0
- data/lib/cequel/metal/row_specification.rb +37 -0
- data/lib/cequel/metal/statement.rb +30 -0
- data/lib/cequel/metal/updater.rb +65 -0
- data/lib/cequel/metal/writer.rb +73 -0
- data/lib/cequel/model.rb +12 -84
- data/lib/cequel/model/association_collection.rb +23 -0
- data/lib/cequel/model/associations.rb +84 -80
- data/lib/cequel/model/base.rb +74 -0
- data/lib/cequel/model/belongs_to_association.rb +31 -0
- data/lib/cequel/model/callbacks.rb +14 -10
- data/lib/cequel/model/collection.rb +255 -0
- data/lib/cequel/model/errors.rb +6 -6
- data/lib/cequel/model/has_many_association.rb +26 -0
- data/lib/cequel/model/mass_assignment.rb +31 -0
- data/lib/cequel/model/persistence.rb +119 -115
- data/lib/cequel/model/properties.rb +89 -87
- data/lib/cequel/model/railtie.rb +21 -14
- data/lib/cequel/model/record_set.rb +285 -0
- data/lib/cequel/model/schema.rb +33 -0
- data/lib/cequel/model/scoped.rb +5 -48
- data/lib/cequel/model/validations.rb +18 -18
- data/lib/cequel/schema.rb +15 -0
- data/lib/cequel/schema/column.rb +135 -0
- data/lib/cequel/schema/create_table_dsl.rb +56 -0
- data/lib/cequel/schema/keyspace.rb +50 -0
- data/lib/cequel/schema/table.rb +120 -0
- data/lib/cequel/schema/table_property.rb +67 -0
- data/lib/cequel/schema/table_reader.rb +139 -0
- data/lib/cequel/schema/table_synchronizer.rb +114 -0
- data/lib/cequel/schema/table_updater.rb +83 -0
- data/lib/cequel/schema/table_writer.rb +80 -0
- data/lib/cequel/schema/update_table_dsl.rb +60 -0
- data/lib/cequel/type.rb +232 -0
- data/lib/cequel/version.rb +1 -1
- data/spec/environment.rb +5 -1
- data/spec/examples/metal/data_set_spec.rb +608 -0
- data/spec/examples/model/associations_spec.rb +84 -74
- data/spec/examples/model/callbacks_spec.rb +66 -59
- data/spec/examples/model/list_spec.rb +393 -0
- data/spec/examples/model/map_spec.rb +229 -0
- data/spec/examples/model/mass_assignment_spec.rb +55 -0
- data/spec/examples/model/naming_spec.rb +11 -4
- data/spec/examples/model/persistence_spec.rb +140 -150
- data/spec/examples/model/properties_spec.rb +122 -75
- data/spec/examples/model/record_set_spec.rb +285 -0
- data/spec/examples/model/schema_spec.rb +44 -0
- data/spec/examples/model/serialization_spec.rb +20 -14
- data/spec/examples/model/set_spec.rb +133 -0
- data/spec/examples/model/spec_helper.rb +0 -10
- data/spec/examples/model/validations_spec.rb +51 -38
- data/spec/examples/schema/table_reader_spec.rb +328 -0
- data/spec/examples/schema/table_synchronizer_spec.rb +172 -0
- data/spec/examples/schema/table_updater_spec.rb +157 -0
- data/spec/examples/schema/table_writer_spec.rb +225 -0
- data/spec/examples/spec_helper.rb +29 -0
- data/spec/examples/type_spec.rb +204 -0
- data/spec/support/helpers.rb +67 -8
- metadata +121 -152
- data/lib/cequel/batch.rb +0 -58
- data/lib/cequel/cql_row_specification.rb +0 -22
- data/lib/cequel/data_set.rb +0 -371
- data/lib/cequel/keyspace.rb +0 -205
- data/lib/cequel/model/class_internals.rb +0 -49
- data/lib/cequel/model/column.rb +0 -20
- data/lib/cequel/model/counter.rb +0 -35
- data/lib/cequel/model/dictionary.rb +0 -126
- data/lib/cequel/model/dirty.rb +0 -53
- data/lib/cequel/model/dynamic.rb +0 -31
- data/lib/cequel/model/inheritable.rb +0 -48
- data/lib/cequel/model/instance_internals.rb +0 -23
- data/lib/cequel/model/local_association.rb +0 -42
- data/lib/cequel/model/magic.rb +0 -79
- data/lib/cequel/model/mass_assignment_security.rb +0 -21
- data/lib/cequel/model/naming.rb +0 -17
- data/lib/cequel/model/observer.rb +0 -42
- data/lib/cequel/model/readable_dictionary.rb +0 -182
- data/lib/cequel/model/remote_association.rb +0 -40
- data/lib/cequel/model/scope.rb +0 -362
- data/lib/cequel/model/subclass_internals.rb +0 -45
- data/lib/cequel/model/timestamps.rb +0 -52
- data/lib/cequel/model/translation.rb +0 -17
- data/lib/cequel/row_specification.rb +0 -63
- data/lib/cequel/statement.rb +0 -23
- data/spec/examples/data_set_spec.rb +0 -444
- data/spec/examples/keyspace_spec.rb +0 -84
- data/spec/examples/model/counter_spec.rb +0 -94
- data/spec/examples/model/dictionary_spec.rb +0 -301
- data/spec/examples/model/dirty_spec.rb +0 -39
- data/spec/examples/model/dynamic_spec.rb +0 -41
- data/spec/examples/model/inheritable_spec.rb +0 -45
- data/spec/examples/model/magic_spec.rb +0 -199
- data/spec/examples/model/mass_assignment_security_spec.rb +0 -13
- data/spec/examples/model/observer_spec.rb +0 -86
- data/spec/examples/model/scope_spec.rb +0 -677
- data/spec/examples/model/timestamps_spec.rb +0 -52
- data/spec/examples/model/translation_spec.rb +0 -23
data/lib/cequel/keyspace.rb
DELETED
@@ -1,205 +0,0 @@
|
|
1
|
-
module Cequel
|
2
|
-
|
3
|
-
#
|
4
|
-
# Handle to a Cassandra keyspace.
|
5
|
-
#
|
6
|
-
class Keyspace
|
7
|
-
|
8
|
-
#
|
9
|
-
# @api private
|
10
|
-
# @see Cequel.connect
|
11
|
-
#
|
12
|
-
def initialize(configuration={})
|
13
|
-
configure(configuration)
|
14
|
-
end
|
15
|
-
|
16
|
-
def connection=(connection)
|
17
|
-
@connection = connection
|
18
|
-
end
|
19
|
-
|
20
|
-
def configure(configuration = {})
|
21
|
-
@configuration = configuration
|
22
|
-
@hosts = configuration[:host] || configuration[:hosts]
|
23
|
-
@thrift_options = configuration[:thrift].try(:symbolize_keys) || {}
|
24
|
-
@keyspace = configuration[:keyspace]
|
25
|
-
# reset the connections
|
26
|
-
clear_active_connections!
|
27
|
-
end
|
28
|
-
|
29
|
-
def logger=(logger)
|
30
|
-
@logger = logger
|
31
|
-
end
|
32
|
-
|
33
|
-
def logger
|
34
|
-
@logger
|
35
|
-
end
|
36
|
-
|
37
|
-
def slowlog=(slowlog)
|
38
|
-
@slowlog = slowlog
|
39
|
-
end
|
40
|
-
|
41
|
-
def slowlog
|
42
|
-
@slowlog
|
43
|
-
end
|
44
|
-
|
45
|
-
def slowlog_threshold=(slowlog_threshold)
|
46
|
-
@slowlog_threshold = slowlog_threshold
|
47
|
-
end
|
48
|
-
|
49
|
-
def slowlog_threshold
|
50
|
-
@slowlog_threshold
|
51
|
-
end
|
52
|
-
|
53
|
-
def with_consistency(consistency)
|
54
|
-
previous_consistency = default_consistency
|
55
|
-
Thread.current[consistency_key] = consistency
|
56
|
-
yield
|
57
|
-
ensure
|
58
|
-
Thread.current[consistency_key] = previous_consistency
|
59
|
-
end
|
60
|
-
|
61
|
-
def default_consistency
|
62
|
-
Thread.current[consistency_key]
|
63
|
-
end
|
64
|
-
|
65
|
-
def consistency_key
|
66
|
-
"Cequel::Keyspace[#{object_id}]#default_consistency"
|
67
|
-
end
|
68
|
-
|
69
|
-
def connection_pool
|
70
|
-
return @connection_pool if defined? @connection_pool
|
71
|
-
if @configuration[:pool]
|
72
|
-
options = {
|
73
|
-
:size => @configuration[:pool] || 10,
|
74
|
-
:timeout => @configuration[:pool_timeout] || 5
|
75
|
-
}
|
76
|
-
@connection_pool = ConnectionPool.new(options) do
|
77
|
-
build_connection
|
78
|
-
end
|
79
|
-
else
|
80
|
-
@connection_pool = nil
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
def connection
|
85
|
-
@connection ||= build_connection
|
86
|
-
end
|
87
|
-
|
88
|
-
def clear_active_connections!
|
89
|
-
remove_instance_variable(:@connection) if defined? @connection
|
90
|
-
remove_instance_variable(:@connection_pool) if defined? @connection_pool
|
91
|
-
end
|
92
|
-
|
93
|
-
def with_connection(&block)
|
94
|
-
if connection_pool
|
95
|
-
connection_pool.with(&block)
|
96
|
-
else
|
97
|
-
yield connection
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
#
|
102
|
-
# Get DataSet encapsulating a column family in this keyspace
|
103
|
-
#
|
104
|
-
# @param column_family_name [Symbol] the name of the column family
|
105
|
-
# @return [DataSet] a column family
|
106
|
-
#
|
107
|
-
def [](column_family_name)
|
108
|
-
DataSet.new(column_family_name.to_sym, self)
|
109
|
-
end
|
110
|
-
|
111
|
-
#
|
112
|
-
# Execute a CQL query in this keyspace.
|
113
|
-
#
|
114
|
-
# @param statement [String] CQL string
|
115
|
-
# @param *bind_vars [Object] values for bind variables
|
116
|
-
#
|
117
|
-
def execute(statement, *bind_vars)
|
118
|
-
log('CQL', statement, *bind_vars) do
|
119
|
-
with_connection do |conn|
|
120
|
-
conn.execute(statement, *bind_vars)
|
121
|
-
end
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
#
|
126
|
-
# Write data to this keyspace using a CQL query. Will be included the
|
127
|
-
# current batch operation if one is present.
|
128
|
-
#
|
129
|
-
# @param (see #execute)
|
130
|
-
#
|
131
|
-
def write(statement, *bind_vars)
|
132
|
-
if get_batch
|
133
|
-
get_batch.execute(statement, *bind_vars)
|
134
|
-
else
|
135
|
-
execute(statement, *bind_vars)
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
#
|
140
|
-
# Execute write operations in a batch. Any inserts, updates, and deletes
|
141
|
-
# inside this method's block will be executed inside a CQL BATCH operation.
|
142
|
-
#
|
143
|
-
# @param options [Hash]
|
144
|
-
# @option options [Fixnum] :auto_apply Automatically send batch to Cassandra after this many statements
|
145
|
-
#
|
146
|
-
# @example Perform inserts in a batch
|
147
|
-
# DB.batch do
|
148
|
-
# DB[:posts].insert(:id => 1, :title => 'One')
|
149
|
-
# DB[:posts].insert(:id => 2, :title => 'Two')
|
150
|
-
# end
|
151
|
-
#
|
152
|
-
def batch(options = {})
|
153
|
-
old_batch = get_batch
|
154
|
-
new_batch = Batch.new(self, options)
|
155
|
-
set_batch(new_batch)
|
156
|
-
yield
|
157
|
-
new_batch.apply
|
158
|
-
ensure
|
159
|
-
set_batch(old_batch)
|
160
|
-
end
|
161
|
-
|
162
|
-
private
|
163
|
-
|
164
|
-
def build_connection
|
165
|
-
options = @keyspace ? {:keyspace => @keyspace } : {}
|
166
|
-
CassandraCQL::Database.new(
|
167
|
-
@hosts,
|
168
|
-
options,
|
169
|
-
@thrift_options
|
170
|
-
)
|
171
|
-
end
|
172
|
-
|
173
|
-
def get_batch
|
174
|
-
::Thread.current[batch_key]
|
175
|
-
end
|
176
|
-
|
177
|
-
def set_batch(batch)
|
178
|
-
::Thread.current[batch_key] = batch
|
179
|
-
end
|
180
|
-
|
181
|
-
def batch_key
|
182
|
-
:"cequel-batch-#{object_id}"
|
183
|
-
end
|
184
|
-
|
185
|
-
def log(label, statement, *bind_vars)
|
186
|
-
return yield unless logger || slowlog
|
187
|
-
response = nil
|
188
|
-
time = Benchmark.ms { response = yield }
|
189
|
-
generate_message = proc do
|
190
|
-
sprintf(
|
191
|
-
'%s (%dms) %s', label, time.to_i,
|
192
|
-
CassandraCQL::Statement.sanitize(statement, bind_vars)
|
193
|
-
)
|
194
|
-
end
|
195
|
-
logger.debug(&generate_message) if self.logger
|
196
|
-
threshold = self.slowlog_threshold || 2000
|
197
|
-
if slowlog && time >= threshold
|
198
|
-
slowlog.warn(&generate_message)
|
199
|
-
end
|
200
|
-
response
|
201
|
-
end
|
202
|
-
|
203
|
-
end
|
204
|
-
|
205
|
-
end
|
@@ -1,49 +0,0 @@
|
|
1
|
-
module Cequel
|
2
|
-
|
3
|
-
module Model
|
4
|
-
|
5
|
-
#
|
6
|
-
# @private
|
7
|
-
#
|
8
|
-
class ClassInternals
|
9
|
-
|
10
|
-
attr_accessor :key, :default_scope
|
11
|
-
attr_reader :columns, :associations, :index_preference
|
12
|
-
attr_writer :column_family_name
|
13
|
-
|
14
|
-
def initialize(clazz)
|
15
|
-
@clazz = clazz
|
16
|
-
@columns, @associations = {}, {}
|
17
|
-
@index_preference = []
|
18
|
-
@lock = Monitor.new
|
19
|
-
end
|
20
|
-
|
21
|
-
def add_column(name, type, options = {})
|
22
|
-
@columns[name] = Column.new(name, type, options)
|
23
|
-
end
|
24
|
-
|
25
|
-
def type_column
|
26
|
-
@columns[:class_name]
|
27
|
-
end
|
28
|
-
|
29
|
-
def column_family_name
|
30
|
-
@column_family_name ||= @clazz.name.tableize
|
31
|
-
end
|
32
|
-
|
33
|
-
def base_class
|
34
|
-
@clazz
|
35
|
-
end
|
36
|
-
|
37
|
-
def association(name)
|
38
|
-
associations[name]
|
39
|
-
end
|
40
|
-
|
41
|
-
def synchronize(&block)
|
42
|
-
@lock.synchronize(&block)
|
43
|
-
end
|
44
|
-
|
45
|
-
end
|
46
|
-
|
47
|
-
end
|
48
|
-
|
49
|
-
end
|
data/lib/cequel/model/column.rb
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
module Cequel
|
2
|
-
|
3
|
-
module Model
|
4
|
-
|
5
|
-
#
|
6
|
-
# Encapsulates information about a column in a model's column family
|
7
|
-
#
|
8
|
-
class Column
|
9
|
-
attr_reader :name, :type, :default
|
10
|
-
|
11
|
-
def initialize(name, type, options = {})
|
12
|
-
@name, @type = name, type
|
13
|
-
@default = options[:default]
|
14
|
-
end
|
15
|
-
|
16
|
-
end
|
17
|
-
|
18
|
-
end
|
19
|
-
|
20
|
-
end
|
data/lib/cequel/model/counter.rb
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
require 'cequel/model/readable_dictionary'
|
2
|
-
|
3
|
-
module Cequel
|
4
|
-
|
5
|
-
module Model
|
6
|
-
|
7
|
-
class Counter < ReadableDictionary
|
8
|
-
|
9
|
-
def increment(columns_or_deltas, delta = 1)
|
10
|
-
scope.increment(construct_deltas(columns_or_deltas, delta))
|
11
|
-
end
|
12
|
-
|
13
|
-
def decrement(columns_or_deltas, delta = 1)
|
14
|
-
scope.decrement(construct_deltas(columns_or_deltas, delta))
|
15
|
-
end
|
16
|
-
|
17
|
-
private
|
18
|
-
|
19
|
-
def construct_deltas(columns_or_deltas, delta)
|
20
|
-
if Hash === columns_or_deltas
|
21
|
-
columns_or_deltas
|
22
|
-
else
|
23
|
-
{}.tap do |deltas|
|
24
|
-
Array.wrap(columns_or_deltas).each do |column|
|
25
|
-
deltas[column] = delta
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
end
|
32
|
-
|
33
|
-
end
|
34
|
-
|
35
|
-
end
|
@@ -1,126 +0,0 @@
|
|
1
|
-
require 'cequel/model/readable_dictionary'
|
2
|
-
|
3
|
-
module Cequel
|
4
|
-
|
5
|
-
module Model
|
6
|
-
|
7
|
-
class Dictionary < ReadableDictionary
|
8
|
-
|
9
|
-
class <<self
|
10
|
-
|
11
|
-
def validation
|
12
|
-
@validation ||= :text
|
13
|
-
end
|
14
|
-
|
15
|
-
def maps(options)
|
16
|
-
@comparator, @validation = *options.first
|
17
|
-
end
|
18
|
-
|
19
|
-
end
|
20
|
-
|
21
|
-
def each_pair(options = {})
|
22
|
-
return super if !block_given? || @loaded
|
23
|
-
new_columns = @changed_columns.dup
|
24
|
-
super do |column, value|
|
25
|
-
if @changed_columns.include?(column)
|
26
|
-
new_columns.delete(column)
|
27
|
-
yield column, @row[column]
|
28
|
-
elsif !@deleted_columns.include?(column)
|
29
|
-
yield column, value
|
30
|
-
end
|
31
|
-
end
|
32
|
-
new_columns.each do |column|
|
33
|
-
yield column, @row[column]
|
34
|
-
end
|
35
|
-
self
|
36
|
-
end
|
37
|
-
|
38
|
-
def [](column)
|
39
|
-
if @loaded || @changed_columns.include?(column)
|
40
|
-
@row[column]
|
41
|
-
elsif !@deleted_columns.include?(column)
|
42
|
-
value = super
|
43
|
-
deserialize_value(column, value) if value
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
def slice(*columns)
|
48
|
-
super.tap do |slice|
|
49
|
-
unless @loaded
|
50
|
-
slice.merge!(@row.slice(*columns))
|
51
|
-
@deleted_columns.each { |column| slice.delete(column) }
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
def []=(column, value)
|
57
|
-
if value.nil?
|
58
|
-
@deleted_columns << column
|
59
|
-
@changed_columns.delete(column)
|
60
|
-
else
|
61
|
-
@changed_columns << column
|
62
|
-
@deleted_columns.delete(column)
|
63
|
-
end
|
64
|
-
@row[column] = value
|
65
|
-
end
|
66
|
-
|
67
|
-
def destroy
|
68
|
-
scope.delete
|
69
|
-
setup
|
70
|
-
end
|
71
|
-
|
72
|
-
def save
|
73
|
-
batch_size = self.class.default_batch_size
|
74
|
-
@changed_columns.each_slice(batch_size) do |slice|
|
75
|
-
updates = {}
|
76
|
-
slice.each do |column|
|
77
|
-
updates[column] = serialize_value(@row[column])
|
78
|
-
end
|
79
|
-
scope.update(updates) if updates.any?
|
80
|
-
end
|
81
|
-
@deleted_columns.each_slice(batch_size) do |slice|
|
82
|
-
scope.delete(*slice.to_a) if slice.any?
|
83
|
-
end
|
84
|
-
@row.clear unless @loaded
|
85
|
-
@changed_columns.clear
|
86
|
-
@deleted_columns.clear
|
87
|
-
self
|
88
|
-
end
|
89
|
-
|
90
|
-
private
|
91
|
-
|
92
|
-
def setup(init_row = nil)
|
93
|
-
super
|
94
|
-
@changed_columns = Set[]
|
95
|
-
@deleted_columns = Set[]
|
96
|
-
end
|
97
|
-
|
98
|
-
#
|
99
|
-
# Subclasses may override this method to implement custom serialization
|
100
|
-
# strategies
|
101
|
-
#
|
102
|
-
def serialize_value(value)
|
103
|
-
value
|
104
|
-
end
|
105
|
-
|
106
|
-
#
|
107
|
-
# Subclasses may override this method to implement custom deserialization
|
108
|
-
# strategies
|
109
|
-
#
|
110
|
-
def deserialize_value(column, value)
|
111
|
-
value
|
112
|
-
end
|
113
|
-
|
114
|
-
def deserialize_row(row)
|
115
|
-
{}.tap do |slice|
|
116
|
-
row.each_pair do |column, value|
|
117
|
-
slice[column] = deserialize_value(column, value)
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
end
|
123
|
-
|
124
|
-
end
|
125
|
-
|
126
|
-
end
|
data/lib/cequel/model/dirty.rb
DELETED
@@ -1,53 +0,0 @@
|
|
1
|
-
module Cequel
|
2
|
-
|
3
|
-
module Model
|
4
|
-
|
5
|
-
module Dirty
|
6
|
-
|
7
|
-
extend ActiveSupport::Concern
|
8
|
-
|
9
|
-
included do
|
10
|
-
include ActiveModel::Dirty
|
11
|
-
include ChangedAttributesWithIndifferentAccess
|
12
|
-
end
|
13
|
-
|
14
|
-
module ClassMethods
|
15
|
-
|
16
|
-
def column(name, type, options = {})
|
17
|
-
define_attribute_method(name)
|
18
|
-
super
|
19
|
-
end
|
20
|
-
|
21
|
-
end
|
22
|
-
|
23
|
-
def save
|
24
|
-
super.tap do
|
25
|
-
@previously_changed = changes
|
26
|
-
changed_attributes.clear
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def _hydrate(row)
|
31
|
-
super.tap { changed_attributes.clear }
|
32
|
-
end
|
33
|
-
|
34
|
-
private
|
35
|
-
|
36
|
-
def write_attribute(name, value)
|
37
|
-
attribute_will_change!(name) if value != read_attribute(name)
|
38
|
-
super
|
39
|
-
end
|
40
|
-
|
41
|
-
end
|
42
|
-
|
43
|
-
module ChangedAttributesWithIndifferentAccess
|
44
|
-
|
45
|
-
def changed_attributes
|
46
|
-
@changed_attributes ||= HashWithIndifferentAccess.new
|
47
|
-
end
|
48
|
-
|
49
|
-
end
|
50
|
-
|
51
|
-
end
|
52
|
-
|
53
|
-
end
|