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/model/dynamic.rb
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
module Cequel
|
2
|
-
|
3
|
-
module Model
|
4
|
-
|
5
|
-
module Dynamic
|
6
|
-
|
7
|
-
def [](column)
|
8
|
-
read_attribute(column)
|
9
|
-
end
|
10
|
-
|
11
|
-
def []=(column, value)
|
12
|
-
write_attribute(column, value)
|
13
|
-
end
|
14
|
-
|
15
|
-
private
|
16
|
-
|
17
|
-
def attribute_change(attr)
|
18
|
-
if attribute_changed?(attr)
|
19
|
-
if respond_to_without_attributes?(attr)
|
20
|
-
super
|
21
|
-
else
|
22
|
-
[changed_attributes[attr], self[attr]]
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
end
|
28
|
-
|
29
|
-
end
|
30
|
-
|
31
|
-
end
|
@@ -1,48 +0,0 @@
|
|
1
|
-
module Cequel
|
2
|
-
|
3
|
-
module Model
|
4
|
-
|
5
|
-
module Inheritable
|
6
|
-
|
7
|
-
module SubclassMethods
|
8
|
-
|
9
|
-
extend ActiveSupport::Concern
|
10
|
-
|
11
|
-
module ClassMethods
|
12
|
-
|
13
|
-
def all
|
14
|
-
super.where(@_cequel.type_column.name => name)
|
15
|
-
end
|
16
|
-
|
17
|
-
end
|
18
|
-
|
19
|
-
def initialize(*args, &block)
|
20
|
-
super
|
21
|
-
__send__("#{self.class.type_column.name}=", self.class.name)
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
25
|
-
|
26
|
-
def inherited(subclass)
|
27
|
-
super
|
28
|
-
unless @_cequel.type_column
|
29
|
-
raise ArgumentError,
|
30
|
-
"Can't subclass model class that does not define a type column"
|
31
|
-
end
|
32
|
-
subclass._cequel = SubclassInternals.new(subclass, @_cequel)
|
33
|
-
subclass.module_eval { include(SubclassMethods) }
|
34
|
-
end
|
35
|
-
|
36
|
-
def base_class
|
37
|
-
@_cequel.base_class
|
38
|
-
end
|
39
|
-
|
40
|
-
protected
|
41
|
-
|
42
|
-
attr_writer :_cequel
|
43
|
-
|
44
|
-
end
|
45
|
-
|
46
|
-
end
|
47
|
-
|
48
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
module Cequel
|
2
|
-
|
3
|
-
module Model
|
4
|
-
|
5
|
-
#
|
6
|
-
# @private
|
7
|
-
#
|
8
|
-
class InstanceInternals
|
9
|
-
|
10
|
-
attr_accessor :key, :attributes, :persisted
|
11
|
-
attr_reader :associations
|
12
|
-
|
13
|
-
def initialize(instance)
|
14
|
-
@instance = instance
|
15
|
-
@attributes = ActiveSupport::HashWithIndifferentAccess.new
|
16
|
-
@associations = {}
|
17
|
-
end
|
18
|
-
|
19
|
-
end
|
20
|
-
|
21
|
-
end
|
22
|
-
|
23
|
-
end
|
@@ -1,42 +0,0 @@
|
|
1
|
-
module Cequel
|
2
|
-
|
3
|
-
module Model
|
4
|
-
|
5
|
-
class LocalAssociation
|
6
|
-
|
7
|
-
attr_reader :clazz, :name
|
8
|
-
|
9
|
-
def initialize(name, owning_class, options)
|
10
|
-
@name, @owning_class = name, owning_class
|
11
|
-
@class_name = options[:class_name] || name.to_s.classify.to_sym
|
12
|
-
@foreign_key_name = options[:foreign_key]
|
13
|
-
end
|
14
|
-
|
15
|
-
def primary_key
|
16
|
-
@primary_key ||= clazz.key_column
|
17
|
-
end
|
18
|
-
|
19
|
-
def primary_key_name
|
20
|
-
@primary_key_name ||= primary_key.name
|
21
|
-
end
|
22
|
-
|
23
|
-
def foreign_key_name
|
24
|
-
@foreign_key_name ||= :"#{name}_id"
|
25
|
-
end
|
26
|
-
|
27
|
-
def scope(instance)
|
28
|
-
clazz.where(primary_key_name => instance.__send__(foreign_key_name))
|
29
|
-
end
|
30
|
-
|
31
|
-
def clazz
|
32
|
-
@clazz ||= @class_name.to_s.constantize
|
33
|
-
end
|
34
|
-
|
35
|
-
def dependent
|
36
|
-
end
|
37
|
-
|
38
|
-
end
|
39
|
-
|
40
|
-
end
|
41
|
-
|
42
|
-
end
|
data/lib/cequel/model/magic.rb
DELETED
@@ -1,79 +0,0 @@
|
|
1
|
-
module Cequel
|
2
|
-
|
3
|
-
module Model
|
4
|
-
|
5
|
-
module Magic
|
6
|
-
|
7
|
-
FIND_BY_PATTERN = /^find_by_(\w+)$/
|
8
|
-
FIND_ALL_BY_PATTERN = /^find_all_by_(\w+)$/
|
9
|
-
FIND_OR_CREATE_BY_PATTERN = /^find_or_create_by_(\w+)$/
|
10
|
-
FIND_OR_INITIALIZE_BY_PATTERN = /^find_or_initialize_by_(\w+)$/
|
11
|
-
|
12
|
-
def self.scope(scope, columns_string, args)
|
13
|
-
scope.where(extract_row_specifications(columns_string, args))
|
14
|
-
end
|
15
|
-
|
16
|
-
def self.find_or_create_by(scope, columns_string, args, &block)
|
17
|
-
find_or_initialize_by(scope, columns_string, args, &block).tap do |instance|
|
18
|
-
instance.save unless instance.persisted?
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def self.find_or_initialize_by(scope, columns_string, args, &block)
|
23
|
-
row_specifications = extract_row_specifications(columns_string, args)
|
24
|
-
instance = scope.where(row_specifications).first
|
25
|
-
if instance.nil?
|
26
|
-
if args.length == 1 && args.first.is_a?(Hash)
|
27
|
-
attributes = args.first
|
28
|
-
else
|
29
|
-
attributes = row_specifications
|
30
|
-
end
|
31
|
-
instance = scope.new(attributes, &block)
|
32
|
-
end
|
33
|
-
instance
|
34
|
-
end
|
35
|
-
|
36
|
-
def self.extract_row_specifications(columns_string, args)
|
37
|
-
columns = columns_string.split('_and_').map { |column| column.to_sym }
|
38
|
-
if args.length == 1 && args.first.is_a?(Hash)
|
39
|
-
args.first.symbolize_keys.slice(*columns)
|
40
|
-
else
|
41
|
-
if columns.length != args.length
|
42
|
-
raise ArgumentError,
|
43
|
-
"wrong number of arguments(#{args.length} for #{columns.length})"
|
44
|
-
end
|
45
|
-
Hash[columns.zip(args)]
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
def respond_to?(method, priv = false)
|
50
|
-
case method
|
51
|
-
when FIND_BY_PATTERN, FIND_ALL_BY_PATTERN,
|
52
|
-
FIND_OR_CREATE_BY_PATTERN, FIND_OR_INITIALIZE_BY_PATTERN
|
53
|
-
|
54
|
-
true
|
55
|
-
else
|
56
|
-
super
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
def method_missing(method, *args, &block)
|
61
|
-
case method.to_s
|
62
|
-
when FIND_BY_PATTERN
|
63
|
-
Magic.scope(all, $1, args).first
|
64
|
-
when FIND_ALL_BY_PATTERN
|
65
|
-
Magic.scope(all, $1, args).to_a
|
66
|
-
when FIND_OR_CREATE_BY_PATTERN
|
67
|
-
Magic.find_or_create_by(all, $1, args, &block)
|
68
|
-
when FIND_OR_INITIALIZE_BY_PATTERN
|
69
|
-
Magic.find_or_initialize_by(all, $1, args, &block)
|
70
|
-
else
|
71
|
-
super
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
end
|
76
|
-
|
77
|
-
end
|
78
|
-
|
79
|
-
end
|
@@ -1,21 +0,0 @@
|
|
1
|
-
module Cequel
|
2
|
-
|
3
|
-
module Model
|
4
|
-
|
5
|
-
module MassAssignmentSecurity
|
6
|
-
|
7
|
-
extend ActiveSupport::Concern
|
8
|
-
|
9
|
-
included do
|
10
|
-
include ActiveModel::MassAssignmentSecurity
|
11
|
-
end
|
12
|
-
|
13
|
-
def attributes=(attributes)
|
14
|
-
super(sanitize_for_mass_assignment(attributes))
|
15
|
-
end
|
16
|
-
|
17
|
-
end
|
18
|
-
|
19
|
-
end
|
20
|
-
|
21
|
-
end
|
data/lib/cequel/model/naming.rb
DELETED
@@ -1,42 +0,0 @@
|
|
1
|
-
module Cequel
|
2
|
-
|
3
|
-
module Model
|
4
|
-
|
5
|
-
#
|
6
|
-
# This is ripped directly off of ActiveRecord::Observer
|
7
|
-
#
|
8
|
-
class Observer < ActiveModel::Observer
|
9
|
-
|
10
|
-
protected
|
11
|
-
|
12
|
-
def observed_classes
|
13
|
-
klasses = super
|
14
|
-
klasses + klasses.map { |klass| klass.descendants }.flatten
|
15
|
-
end
|
16
|
-
|
17
|
-
def add_observer!(klass)
|
18
|
-
super
|
19
|
-
define_callbacks klass
|
20
|
-
end
|
21
|
-
|
22
|
-
def define_callbacks(klass)
|
23
|
-
observer = self
|
24
|
-
observer_name = observer.class.name.underscore.gsub('/', '__')
|
25
|
-
|
26
|
-
Cequel::Model::Callbacks::CALLBACKS.each do |callback|
|
27
|
-
next unless respond_to?(callback)
|
28
|
-
callback_meth = :"_notify_#{observer_name}_for_#{callback}"
|
29
|
-
unless klass.respond_to?(callback_meth)
|
30
|
-
klass.send(:define_method, callback_meth) do |&block|
|
31
|
-
observer.update(callback, self, &block)
|
32
|
-
end
|
33
|
-
klass.send(callback, callback_meth)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
end
|
39
|
-
|
40
|
-
end
|
41
|
-
|
42
|
-
end
|
@@ -1,182 +0,0 @@
|
|
1
|
-
module Cequel
|
2
|
-
|
3
|
-
module Model
|
4
|
-
|
5
|
-
class ReadableDictionary
|
6
|
-
|
7
|
-
class <<self
|
8
|
-
|
9
|
-
attr_writer :column_family, :default_batch_size
|
10
|
-
|
11
|
-
def key_alias
|
12
|
-
@key_alias ||= :KEY
|
13
|
-
end
|
14
|
-
|
15
|
-
def key_type
|
16
|
-
@key_type ||= :text
|
17
|
-
end
|
18
|
-
|
19
|
-
def comparator
|
20
|
-
@comparator ||= :text
|
21
|
-
end
|
22
|
-
|
23
|
-
def validation
|
24
|
-
:counter
|
25
|
-
end
|
26
|
-
|
27
|
-
def key(key_alias, type)
|
28
|
-
@key_alias, @key_type = key_alias, type
|
29
|
-
|
30
|
-
module_eval(<<-RUBY)
|
31
|
-
def #{key_alias.downcase}
|
32
|
-
@key
|
33
|
-
end
|
34
|
-
RUBY
|
35
|
-
end
|
36
|
-
|
37
|
-
def columns(comparator)
|
38
|
-
@comparator = comparator
|
39
|
-
end
|
40
|
-
|
41
|
-
def column_family
|
42
|
-
return @column_family if @column_family
|
43
|
-
self.column_family_name = name.underscore.to_sym
|
44
|
-
@column_family
|
45
|
-
end
|
46
|
-
|
47
|
-
def column_family_name=(column_family_name)
|
48
|
-
self.column_family = Cequel::Model.keyspace[column_family_name]
|
49
|
-
end
|
50
|
-
|
51
|
-
def default_batch_size
|
52
|
-
@default_batch_size || 1000
|
53
|
-
end
|
54
|
-
|
55
|
-
def [](key)
|
56
|
-
new(key)
|
57
|
-
end
|
58
|
-
private :new
|
59
|
-
|
60
|
-
def load(*keys)
|
61
|
-
keys.flatten!
|
62
|
-
column_family.
|
63
|
-
where(key_alias.to_s => keys).
|
64
|
-
map { |row| new(row.delete(key_alias.to_s), row) }
|
65
|
-
end
|
66
|
-
|
67
|
-
end
|
68
|
-
|
69
|
-
include Enumerable
|
70
|
-
|
71
|
-
def initialize(key, row = nil)
|
72
|
-
@key = key
|
73
|
-
setup(row)
|
74
|
-
end
|
75
|
-
|
76
|
-
def [](column)
|
77
|
-
if @loaded
|
78
|
-
@row[column]
|
79
|
-
else
|
80
|
-
scope.select(column).first[column]
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
def keys
|
85
|
-
@loaded ? @row.keys : each_pair.map { |key, value| key }
|
86
|
-
end
|
87
|
-
|
88
|
-
def values
|
89
|
-
@loaded ? @row.values : each_pair.map { |key, value| value }
|
90
|
-
end
|
91
|
-
|
92
|
-
def slice(*columns)
|
93
|
-
if @loaded
|
94
|
-
@row.slice(*columns)
|
95
|
-
else
|
96
|
-
deserialize_row(load_raw_slice(columns))
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
def first
|
101
|
-
@loaded ? @row.first : slice(:first => 1).first
|
102
|
-
end
|
103
|
-
|
104
|
-
def last
|
105
|
-
if @loaded
|
106
|
-
unless @row.empty?
|
107
|
-
key = @row.keys.last
|
108
|
-
[key, @row[key]]
|
109
|
-
end
|
110
|
-
else
|
111
|
-
slice(:last => 1).first
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
def key?(column)
|
116
|
-
@row.key?(column) || load_raw_slice([column])[column].present?
|
117
|
-
end
|
118
|
-
|
119
|
-
def each_pair(options = {}, &block)
|
120
|
-
return Enumerator.new(self, :each_pair, options) unless block
|
121
|
-
return @row.each_pair(&block) if @loaded
|
122
|
-
batch_size = options[:batch_size] || self.class.default_batch_size
|
123
|
-
each_slice(batch_size) do |batch_results|
|
124
|
-
batch_results.each_pair(&block)
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
def each(&block)
|
129
|
-
each_pair(&block)
|
130
|
-
end
|
131
|
-
|
132
|
-
def each_slice(batch_size)
|
133
|
-
batch_scope = scope.select(:first => batch_size)
|
134
|
-
key_alias = self.class.key_alias
|
135
|
-
last_key = nil
|
136
|
-
begin
|
137
|
-
batch_results = batch_scope.first
|
138
|
-
batch_results.delete(key_alias)
|
139
|
-
result_length = batch_results.length
|
140
|
-
batch_results.delete(last_key) unless last_key.nil?
|
141
|
-
yield deserialize_row(batch_results)
|
142
|
-
last_key = batch_results.keys.last
|
143
|
-
batch_scope = batch_scope.select(:from => last_key)
|
144
|
-
end while result_length == batch_size
|
145
|
-
end
|
146
|
-
|
147
|
-
def load
|
148
|
-
return self if @loaded
|
149
|
-
@row = {}
|
150
|
-
each_pair { |column, value| @row[column] = value }
|
151
|
-
@loaded = true
|
152
|
-
self
|
153
|
-
end
|
154
|
-
|
155
|
-
def loaded?
|
156
|
-
!!@loaded
|
157
|
-
end
|
158
|
-
|
159
|
-
private
|
160
|
-
|
161
|
-
def setup(init_row = nil)
|
162
|
-
@row = deserialize_row(init_row || {})
|
163
|
-
@loaded = !!init_row
|
164
|
-
end
|
165
|
-
|
166
|
-
def scope
|
167
|
-
self.class.column_family.where(self.class.key_alias => @key)
|
168
|
-
end
|
169
|
-
|
170
|
-
def load_raw_slice(columns)
|
171
|
-
row = scope.select(*columns).first.except(self.class.key_alias)
|
172
|
-
end
|
173
|
-
|
174
|
-
def deserialize_row(row)
|
175
|
-
row
|
176
|
-
end
|
177
|
-
|
178
|
-
end
|
179
|
-
|
180
|
-
end
|
181
|
-
|
182
|
-
end
|