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.
Files changed (108) hide show
  1. checksums.yaml +7 -0
  2. data/lib/cequel.rb +5 -8
  3. data/lib/cequel/errors.rb +1 -0
  4. data/lib/cequel/metal.rb +17 -0
  5. data/lib/cequel/metal/batch.rb +62 -0
  6. data/lib/cequel/metal/cql_row_specification.rb +26 -0
  7. data/lib/cequel/metal/data_set.rb +461 -0
  8. data/lib/cequel/metal/deleter.rb +47 -0
  9. data/lib/cequel/metal/incrementer.rb +35 -0
  10. data/lib/cequel/metal/inserter.rb +53 -0
  11. data/lib/cequel/metal/keyspace.rb +213 -0
  12. data/lib/cequel/metal/row.rb +48 -0
  13. data/lib/cequel/metal/row_specification.rb +37 -0
  14. data/lib/cequel/metal/statement.rb +30 -0
  15. data/lib/cequel/metal/updater.rb +65 -0
  16. data/lib/cequel/metal/writer.rb +73 -0
  17. data/lib/cequel/model.rb +12 -84
  18. data/lib/cequel/model/association_collection.rb +23 -0
  19. data/lib/cequel/model/associations.rb +84 -80
  20. data/lib/cequel/model/base.rb +74 -0
  21. data/lib/cequel/model/belongs_to_association.rb +31 -0
  22. data/lib/cequel/model/callbacks.rb +14 -10
  23. data/lib/cequel/model/collection.rb +255 -0
  24. data/lib/cequel/model/errors.rb +6 -6
  25. data/lib/cequel/model/has_many_association.rb +26 -0
  26. data/lib/cequel/model/mass_assignment.rb +31 -0
  27. data/lib/cequel/model/persistence.rb +119 -115
  28. data/lib/cequel/model/properties.rb +89 -87
  29. data/lib/cequel/model/railtie.rb +21 -14
  30. data/lib/cequel/model/record_set.rb +285 -0
  31. data/lib/cequel/model/schema.rb +33 -0
  32. data/lib/cequel/model/scoped.rb +5 -48
  33. data/lib/cequel/model/validations.rb +18 -18
  34. data/lib/cequel/schema.rb +15 -0
  35. data/lib/cequel/schema/column.rb +135 -0
  36. data/lib/cequel/schema/create_table_dsl.rb +56 -0
  37. data/lib/cequel/schema/keyspace.rb +50 -0
  38. data/lib/cequel/schema/table.rb +120 -0
  39. data/lib/cequel/schema/table_property.rb +67 -0
  40. data/lib/cequel/schema/table_reader.rb +139 -0
  41. data/lib/cequel/schema/table_synchronizer.rb +114 -0
  42. data/lib/cequel/schema/table_updater.rb +83 -0
  43. data/lib/cequel/schema/table_writer.rb +80 -0
  44. data/lib/cequel/schema/update_table_dsl.rb +60 -0
  45. data/lib/cequel/type.rb +232 -0
  46. data/lib/cequel/version.rb +1 -1
  47. data/spec/environment.rb +5 -1
  48. data/spec/examples/metal/data_set_spec.rb +608 -0
  49. data/spec/examples/model/associations_spec.rb +84 -74
  50. data/spec/examples/model/callbacks_spec.rb +66 -59
  51. data/spec/examples/model/list_spec.rb +393 -0
  52. data/spec/examples/model/map_spec.rb +229 -0
  53. data/spec/examples/model/mass_assignment_spec.rb +55 -0
  54. data/spec/examples/model/naming_spec.rb +11 -4
  55. data/spec/examples/model/persistence_spec.rb +140 -150
  56. data/spec/examples/model/properties_spec.rb +122 -75
  57. data/spec/examples/model/record_set_spec.rb +285 -0
  58. data/spec/examples/model/schema_spec.rb +44 -0
  59. data/spec/examples/model/serialization_spec.rb +20 -14
  60. data/spec/examples/model/set_spec.rb +133 -0
  61. data/spec/examples/model/spec_helper.rb +0 -10
  62. data/spec/examples/model/validations_spec.rb +51 -38
  63. data/spec/examples/schema/table_reader_spec.rb +328 -0
  64. data/spec/examples/schema/table_synchronizer_spec.rb +172 -0
  65. data/spec/examples/schema/table_updater_spec.rb +157 -0
  66. data/spec/examples/schema/table_writer_spec.rb +225 -0
  67. data/spec/examples/spec_helper.rb +29 -0
  68. data/spec/examples/type_spec.rb +204 -0
  69. data/spec/support/helpers.rb +67 -8
  70. metadata +121 -152
  71. data/lib/cequel/batch.rb +0 -58
  72. data/lib/cequel/cql_row_specification.rb +0 -22
  73. data/lib/cequel/data_set.rb +0 -371
  74. data/lib/cequel/keyspace.rb +0 -205
  75. data/lib/cequel/model/class_internals.rb +0 -49
  76. data/lib/cequel/model/column.rb +0 -20
  77. data/lib/cequel/model/counter.rb +0 -35
  78. data/lib/cequel/model/dictionary.rb +0 -126
  79. data/lib/cequel/model/dirty.rb +0 -53
  80. data/lib/cequel/model/dynamic.rb +0 -31
  81. data/lib/cequel/model/inheritable.rb +0 -48
  82. data/lib/cequel/model/instance_internals.rb +0 -23
  83. data/lib/cequel/model/local_association.rb +0 -42
  84. data/lib/cequel/model/magic.rb +0 -79
  85. data/lib/cequel/model/mass_assignment_security.rb +0 -21
  86. data/lib/cequel/model/naming.rb +0 -17
  87. data/lib/cequel/model/observer.rb +0 -42
  88. data/lib/cequel/model/readable_dictionary.rb +0 -182
  89. data/lib/cequel/model/remote_association.rb +0 -40
  90. data/lib/cequel/model/scope.rb +0 -362
  91. data/lib/cequel/model/subclass_internals.rb +0 -45
  92. data/lib/cequel/model/timestamps.rb +0 -52
  93. data/lib/cequel/model/translation.rb +0 -17
  94. data/lib/cequel/row_specification.rb +0 -63
  95. data/lib/cequel/statement.rb +0 -23
  96. data/spec/examples/data_set_spec.rb +0 -444
  97. data/spec/examples/keyspace_spec.rb +0 -84
  98. data/spec/examples/model/counter_spec.rb +0 -94
  99. data/spec/examples/model/dictionary_spec.rb +0 -301
  100. data/spec/examples/model/dirty_spec.rb +0 -39
  101. data/spec/examples/model/dynamic_spec.rb +0 -41
  102. data/spec/examples/model/inheritable_spec.rb +0 -45
  103. data/spec/examples/model/magic_spec.rb +0 -199
  104. data/spec/examples/model/mass_assignment_security_spec.rb +0 -13
  105. data/spec/examples/model/observer_spec.rb +0 -86
  106. data/spec/examples/model/scope_spec.rb +0 -677
  107. data/spec/examples/model/timestamps_spec.rb +0 -52
  108. data/spec/examples/model/translation_spec.rb +0 -23
@@ -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
@@ -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
@@ -1,17 +0,0 @@
1
- module Cequel
2
-
3
- module Model
4
-
5
- module Naming
6
-
7
- extend ActiveSupport::Concern
8
-
9
- included do
10
- include ActiveModel::Naming
11
- end
12
-
13
- end
14
-
15
- end
16
-
17
- end
@@ -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