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,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
@@ -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
@@ -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
@@ -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