massive_record 0.2.1 → 0.2.2.rc1
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 +58 -2
- data/Gemfile.lock +17 -17
- data/README.md +98 -41
- data/lib/massive_record.rb +2 -1
- data/lib/massive_record/adapters/thrift/hbase/hbase.rb +2425 -2154
- data/lib/massive_record/adapters/thrift/hbase/hbase_constants.rb +3 -3
- data/lib/massive_record/adapters/thrift/hbase/hbase_types.rb +195 -195
- data/lib/massive_record/adapters/thrift/row.rb +35 -4
- data/lib/massive_record/adapters/thrift/table.rb +49 -12
- data/lib/massive_record/orm/attribute_methods.rb +77 -5
- data/lib/massive_record/orm/attribute_methods/cast_numbers_on_write.rb +24 -0
- data/lib/massive_record/orm/attribute_methods/dirty.rb +18 -0
- data/lib/massive_record/orm/attribute_methods/time_zone_conversion.rb +24 -3
- data/lib/massive_record/orm/attribute_methods/write.rb +8 -1
- data/lib/massive_record/orm/base.rb +62 -8
- data/lib/massive_record/orm/column.rb +7 -11
- data/lib/massive_record/orm/default_id.rb +1 -1
- data/lib/massive_record/orm/embedded.rb +66 -0
- data/lib/massive_record/orm/errors.rb +17 -0
- data/lib/massive_record/orm/finders.rb +124 -71
- data/lib/massive_record/orm/finders/rescue_missing_table_on_find.rb +1 -1
- data/lib/massive_record/orm/finders/scope.rb +58 -34
- data/lib/massive_record/orm/id_factory.rb +22 -105
- data/lib/massive_record/orm/id_factory/atomic_incrementation.rb +117 -0
- data/lib/massive_record/orm/id_factory/timestamp.rb +60 -0
- data/lib/massive_record/orm/identity_map.rb +256 -0
- data/lib/massive_record/orm/log_subscriber.rb +18 -0
- data/lib/massive_record/orm/observer.rb +69 -0
- data/lib/massive_record/orm/persistence.rb +47 -119
- data/lib/massive_record/orm/persistence/operations.rb +100 -0
- data/lib/massive_record/orm/persistence/operations/atomic_operation.rb +71 -0
- data/lib/massive_record/orm/persistence/operations/destroy.rb +17 -0
- data/lib/massive_record/orm/persistence/operations/embedded/destroy.rb +26 -0
- data/lib/massive_record/orm/persistence/operations/embedded/insert.rb +27 -0
- data/lib/massive_record/orm/persistence/operations/embedded/operation_helpers.rb +66 -0
- data/lib/massive_record/orm/persistence/operations/embedded/reload.rb +39 -0
- data/lib/massive_record/orm/persistence/operations/embedded/update.rb +29 -0
- data/lib/massive_record/orm/persistence/operations/insert.rb +19 -0
- data/lib/massive_record/orm/persistence/operations/reload.rb +26 -0
- data/lib/massive_record/orm/persistence/operations/suppress.rb +15 -0
- data/lib/massive_record/orm/persistence/operations/table_operation_helpers.rb +106 -0
- data/lib/massive_record/orm/persistence/operations/update.rb +25 -0
- data/lib/massive_record/orm/query_instrumentation.rb +26 -49
- data/lib/massive_record/orm/raw_data.rb +47 -0
- data/lib/massive_record/orm/relations.rb +4 -0
- data/lib/massive_record/orm/relations/interface.rb +134 -0
- data/lib/massive_record/orm/relations/metadata.rb +58 -12
- data/lib/massive_record/orm/relations/proxy.rb +17 -12
- data/lib/massive_record/orm/relations/proxy/embedded_in.rb +54 -0
- data/lib/massive_record/orm/relations/proxy/embedded_in_polymorphic.rb +15 -0
- data/lib/massive_record/orm/relations/proxy/embeds_many.rb +215 -0
- data/lib/massive_record/orm/relations/proxy/references_many.rb +112 -88
- data/lib/massive_record/orm/relations/proxy/references_one.rb +1 -1
- data/lib/massive_record/orm/relations/proxy/references_one_polymorphic.rb +1 -1
- data/lib/massive_record/orm/relations/proxy_collection.rb +84 -0
- data/lib/massive_record/orm/schema/column_family.rb +3 -2
- data/lib/massive_record/orm/schema/{column_interface.rb → embedded_interface.rb} +38 -4
- data/lib/massive_record/orm/schema/field.rb +2 -0
- data/lib/massive_record/orm/schema/table_interface.rb +19 -2
- data/lib/massive_record/orm/single_table_inheritance.rb +37 -2
- data/lib/massive_record/orm/timestamps.rb +17 -7
- data/lib/massive_record/orm/validations.rb +4 -0
- data/lib/massive_record/orm/validations/associated.rb +50 -0
- data/lib/massive_record/rails/railtie.rb +31 -0
- data/lib/massive_record/version.rb +1 -1
- data/lib/massive_record/wrapper/cell.rb +8 -1
- data/massive_record.gemspec +4 -4
- data/spec/adapter/thrift/atomic_increment_spec.rb +16 -0
- data/spec/adapter/thrift/table_find_spec.rb +14 -2
- data/spec/adapter/thrift/table_spec.rb +6 -6
- data/spec/adapter/thrift/utf8_encoding_of_id_spec.rb +71 -0
- data/spec/orm/cases/attribute_methods_spec.rb +215 -22
- data/spec/orm/cases/auto_generate_id_spec.rb +1 -1
- data/spec/orm/cases/change_id_spec.rb +62 -0
- data/spec/orm/cases/default_id_spec.rb +25 -6
- data/spec/orm/cases/default_values_spec.rb +6 -3
- data/spec/orm/cases/dirty_spec.rb +150 -102
- data/spec/orm/cases/embedded_spec.rb +250 -0
- data/spec/orm/cases/{finder_default_scope.rb → finder_default_scope_spec.rb} +4 -0
- data/spec/orm/cases/finder_scope_spec.rb +96 -29
- data/spec/orm/cases/finders_spec.rb +57 -10
- data/spec/orm/cases/id_factory/atomic_incrementation_spec.rb +72 -0
- data/spec/orm/cases/id_factory/timestamp_spec.rb +61 -0
- data/spec/orm/cases/identity_map/identity_map_spec.rb +357 -0
- data/spec/orm/cases/identity_map/middleware_spec.rb +74 -0
- data/spec/orm/cases/log_subscriber_spec.rb +15 -2
- data/spec/orm/cases/observing_spec.rb +61 -0
- data/spec/orm/cases/persistence_spec.rb +151 -60
- data/spec/orm/cases/raw_data_spec.rb +58 -0
- data/spec/orm/cases/single_table_inheritance_spec.rb +58 -2
- data/spec/orm/cases/table_spec.rb +3 -3
- data/spec/orm/cases/time_zone_awareness_spec.rb +27 -0
- data/spec/orm/cases/timestamps_spec.rb +23 -109
- data/spec/orm/cases/validation_spec.rb +9 -0
- data/spec/orm/models/address.rb +5 -1
- data/spec/orm/models/address_with_timestamp.rb +12 -0
- data/spec/orm/models/car.rb +5 -0
- data/spec/orm/models/person.rb +13 -1
- data/spec/orm/models/person_with_timestamp.rb +4 -2
- data/spec/orm/models/test_class.rb +1 -0
- data/spec/orm/persistence/operations/atomic_operation_spec.rb +58 -0
- data/spec/orm/persistence/operations/destroy_spec.rb +22 -0
- data/spec/orm/persistence/operations/embedded/destroy_spec.rb +71 -0
- data/spec/orm/persistence/operations/embedded/insert_spec.rb +59 -0
- data/spec/orm/persistence/operations/embedded/operation_helpers_spec.rb +92 -0
- data/spec/orm/persistence/operations/embedded/reload_spec.rb +67 -0
- data/spec/orm/persistence/operations/embedded/update_spec.rb +60 -0
- data/spec/orm/persistence/operations/insert_spec.rb +31 -0
- data/spec/orm/persistence/operations/reload_spec.rb +48 -0
- data/spec/orm/persistence/operations/suppress_spec.rb +17 -0
- data/spec/orm/persistence/operations/table_operation_helpers_spec.rb +98 -0
- data/spec/orm/persistence/operations/update_spec.rb +25 -0
- data/spec/orm/persistence/operations_spec.rb +58 -0
- data/spec/orm/relations/interface_spec.rb +188 -0
- data/spec/orm/relations/metadata_spec.rb +92 -15
- data/spec/orm/relations/proxy/embedded_in_polymorphic_spec.rb +37 -0
- data/spec/orm/relations/proxy/embedded_in_spec.rb +66 -0
- data/spec/orm/relations/proxy/embeds_many_spec.rb +651 -0
- data/spec/orm/relations/proxy/references_many_spec.rb +466 -2
- data/spec/orm/schema/column_family_spec.rb +21 -0
- data/spec/orm/schema/embedded_interface_spec.rb +181 -0
- data/spec/orm/schema/field_spec.rb +7 -0
- data/spec/orm/schema/table_interface_spec.rb +31 -1
- data/spec/shared/orm/id_factories.rb +44 -0
- data/spec/shared/orm/model_with_timestamps.rb +132 -0
- data/spec/shared/orm/persistence/a_persistence_embedded_operation_class.rb +3 -0
- data/spec/shared/orm/persistence/a_persistence_operation_class.rb +11 -0
- data/spec/shared/orm/persistence/a_persistence_table_operation_class.rb +11 -0
- data/spec/shared/orm/relations/proxy.rb +9 -2
- data/spec/spec_helper.rb +9 -0
- data/spec/support/mock_massive_record_connection.rb +2 -1
- metadata +106 -21
- data/spec/orm/cases/column_spec.rb +0 -49
- data/spec/orm/cases/id_factory_spec.rb +0 -92
- data/spec/orm/schema/column_interface_spec.rb +0 -136
@@ -5,6 +5,27 @@ module MassiveRecord
|
|
5
5
|
|
6
6
|
attr_accessor :connection, :name, :column_families
|
7
7
|
|
8
|
+
#
|
9
|
+
# TODO
|
10
|
+
# Helper method to inform about changed options. Remove this in next version..
|
11
|
+
# Also note that this method is used other places to wrap same functionality.
|
12
|
+
#
|
13
|
+
def self.warn_and_change_deprecated_finder_options(options)
|
14
|
+
deprecations = {
|
15
|
+
:start => :starts_with
|
16
|
+
}
|
17
|
+
|
18
|
+
deprecations.each do |deprecated, current|
|
19
|
+
if options.has_key? deprecated
|
20
|
+
# TODO remove this for next version
|
21
|
+
ActiveSupport::Deprecation.warn("finder option '#{deprecated}' is deprecated. Please use: '#{current}'")
|
22
|
+
options[current] = options.delete deprecated
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
options
|
27
|
+
end
|
28
|
+
|
8
29
|
def initialize(connection, table_name)
|
9
30
|
@connection = connection
|
10
31
|
@name = table_name.to_s
|
@@ -87,9 +108,14 @@ module MassiveRecord
|
|
87
108
|
end
|
88
109
|
|
89
110
|
def format_options_for_scanner(opts = {})
|
111
|
+
opts = self.class.warn_and_change_deprecated_finder_options(opts)
|
112
|
+
|
113
|
+
start = opts[:starts_with] && opts[:starts_with].dup.force_encoding(Encoding::BINARY)
|
114
|
+
offset = opts[:offset] && opts[:offset].dup.force_encoding(Encoding::BINARY)
|
115
|
+
|
90
116
|
{
|
91
|
-
:start_key =>
|
92
|
-
:offset_key =>
|
117
|
+
:start_key => start,
|
118
|
+
:offset_key => offset,
|
93
119
|
:created_at => opts[:created_at],
|
94
120
|
:columns => opts[:select], # list of column families to fetch from hbase
|
95
121
|
:limit => opts[:limit] || opts[:batch_size]
|
@@ -115,8 +141,16 @@ module MassiveRecord
|
|
115
141
|
# table.get("my_id", :info, :name) # => "Bob"
|
116
142
|
#
|
117
143
|
def get(id, column_family_name, column_name)
|
118
|
-
|
119
|
-
|
144
|
+
get_cell(id, column_family_name, column_name).try :value
|
145
|
+
end
|
146
|
+
|
147
|
+
|
148
|
+
#
|
149
|
+
# Fast way of fetching one cell
|
150
|
+
#
|
151
|
+
def get_cell(id, column_family_name, column_name)
|
152
|
+
if cell = connection.get(name, id.dup.force_encoding(Encoding::BINARY), "#{column_family_name.to_s}:#{column_name.to_s}").first
|
153
|
+
MassiveRecord::Wrapper::Cell.populate_from_tcell(cell)
|
120
154
|
end
|
121
155
|
end
|
122
156
|
|
@@ -126,17 +160,20 @@ module MassiveRecord
|
|
126
160
|
# Returns nil if id is not found
|
127
161
|
#
|
128
162
|
def find(*args)
|
129
|
-
what_to_find = args.first
|
130
163
|
options = args.extract_options!.symbolize_keys
|
164
|
+
what_to_find = args.first
|
131
165
|
|
132
|
-
if
|
133
|
-
|
134
|
-
|
135
|
-
if column_families_to_find = options[:select]
|
136
|
-
column_families_to_find = column_families_to_find.collect { |c| c.to_s }
|
137
|
-
end
|
166
|
+
if column_families_to_find = options[:select]
|
167
|
+
column_families_to_find = column_families_to_find.collect { |c| c.to_s }
|
168
|
+
end
|
138
169
|
|
139
|
-
|
170
|
+
if what_to_find.is_a? Array
|
171
|
+
what_to_find.collect! { |id| id.dup.force_encoding(Encoding::BINARY) }
|
172
|
+
connection.getRowsWithColumns(name, what_to_find, column_families_to_find).collect do |t_row_result|
|
173
|
+
Row.populate_from_trow_result(t_row_result, connection, name, column_families_to_find)
|
174
|
+
end
|
175
|
+
else
|
176
|
+
if t_row_result = connection.getRowWithColumns(name, what_to_find.dup.force_encoding(Encoding::BINARY), column_families_to_find).first
|
140
177
|
Row.populate_from_trow_result(t_row_result, connection, name, column_families_to_find)
|
141
178
|
end
|
142
179
|
end
|
@@ -37,14 +37,22 @@ module MassiveRecord
|
|
37
37
|
def attributes=(new_attributes)
|
38
38
|
return unless new_attributes.is_a?(Hash)
|
39
39
|
|
40
|
+
multiparameter_attributes = []
|
41
|
+
|
40
42
|
sanitize_for_mass_assignment(new_attributes).each do |attr, value|
|
41
|
-
|
42
|
-
|
43
|
-
send(writer_method, value)
|
43
|
+
if multiparameter? attr
|
44
|
+
multiparameter_attributes << [attr, value]
|
44
45
|
else
|
45
|
-
|
46
|
+
writer_method = "#{attr}="
|
47
|
+
if respond_to? writer_method
|
48
|
+
send(writer_method, value)
|
49
|
+
else
|
50
|
+
raise UnknownAttributeError.new("Unkown attribute: #{attr}")
|
51
|
+
end
|
46
52
|
end
|
47
53
|
end
|
54
|
+
|
55
|
+
assign_multiparameter_attributes(multiparameter_attributes)
|
48
56
|
end
|
49
57
|
|
50
58
|
|
@@ -84,10 +92,74 @@ module MassiveRecord
|
|
84
92
|
end
|
85
93
|
|
86
94
|
def fill_attributes_with_default_values_where_nil_is_not_allowed
|
87
|
-
attributes_schema.reject
|
95
|
+
attributes_to_fill = attributes_schema.reject do |attr_name, field|
|
96
|
+
field.allow_nil? || self[attr_name].present? || (field.type == :boolean && self[attr_name] == false)
|
97
|
+
end
|
98
|
+
|
99
|
+
attributes_to_fill.each do |attr_name, field|
|
88
100
|
self[attr_name] = field.default
|
89
101
|
end
|
90
102
|
end
|
103
|
+
|
104
|
+
|
105
|
+
|
106
|
+
|
107
|
+
|
108
|
+
|
109
|
+
def multiparameter?(attr)
|
110
|
+
attr.to_s.include?('(')
|
111
|
+
end
|
112
|
+
|
113
|
+
def assign_multiparameter_attributes(attribute_pairs)
|
114
|
+
convert_multiparameter_pairs_to_hash_with_initializer_arguments(attribute_pairs).each do |attr_name, initialize_values|
|
115
|
+
if field = attributes_schema[attr_name]
|
116
|
+
value = begin
|
117
|
+
if initialize_values.any?
|
118
|
+
case field.type
|
119
|
+
when :date
|
120
|
+
initialize_values = initialize_values[0, 3]
|
121
|
+
initialize_values.collect! { |v| v.nil? ? 1 : v }
|
122
|
+
Date.new(*initialize_values)
|
123
|
+
when :time
|
124
|
+
initialize_values = initialize_values[0, 6]
|
125
|
+
initialize_values.collect! { |v| v.nil? ? 0 : v }
|
126
|
+
Time.new(*initialize_values)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
rescue ArgumentError
|
130
|
+
nil
|
131
|
+
end
|
132
|
+
|
133
|
+
self[attr_name] = value
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def convert_multiparameter_pairs_to_hash_with_initializer_arguments(attribute_pairs)
|
139
|
+
out = Hash.new { |h, k| h[k] = [] }.tap do |hash|
|
140
|
+
attribute_pairs.each do |pair|
|
141
|
+
name, value = pair
|
142
|
+
attr_name = name.split('(').first
|
143
|
+
hash[attr_name] << [multiparameter_position(name), type_cast_multiparameter_value(name, value)]
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
out.each do |attr_name, positions_and_values|
|
148
|
+
out[attr_name] = positions_and_values.sort_by(&:first).collect(&:last)
|
149
|
+
end
|
150
|
+
|
151
|
+
out
|
152
|
+
end
|
153
|
+
|
154
|
+
def type_cast_multiparameter_value(name, value)
|
155
|
+
unless value.empty?
|
156
|
+
name =~ /\([0-9]*([if])\)/ ? value.send("to_" + $1) : value
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def multiparameter_position(name)
|
161
|
+
name.scan(/\(([0-9]*).*\)/).first.first
|
162
|
+
end
|
91
163
|
end
|
92
164
|
end
|
93
165
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module MassiveRecord
|
2
|
+
module ORM
|
3
|
+
module AttributeMethods
|
4
|
+
module CastNumbersOnWrite
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
def write_attribute(attr_name, value)
|
8
|
+
if value.present?
|
9
|
+
if field = attributes_schema[attr_name]
|
10
|
+
case field.type
|
11
|
+
when :integer
|
12
|
+
value = value.to_i
|
13
|
+
when :float
|
14
|
+
value = value.to_f
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
super
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -45,6 +45,24 @@ module MassiveRecord
|
|
45
45
|
end
|
46
46
|
|
47
47
|
|
48
|
+
def changed?
|
49
|
+
super || relation_proxies_for_embedded.any?(&:changed?)
|
50
|
+
end
|
51
|
+
|
52
|
+
def changed
|
53
|
+
super + relation_proxies_for_embedded.select(&:changed?).collect { |proxy| proxy.metadata.name }
|
54
|
+
end
|
55
|
+
|
56
|
+
def changes
|
57
|
+
changes_in_embedded_proxies = {}
|
58
|
+
|
59
|
+
relation_proxies_for_embedded.select(&:changed?).each do |proxy|
|
60
|
+
changes_in_embedded_proxies[proxy.metadata.name] = proxy.changes
|
61
|
+
end
|
62
|
+
|
63
|
+
super.update(changes_in_embedded_proxies)
|
64
|
+
end
|
65
|
+
|
48
66
|
private
|
49
67
|
|
50
68
|
def update(*)
|
@@ -56,16 +56,37 @@ module MassiveRecord
|
|
56
56
|
time.in_time_zone
|
57
57
|
end
|
58
58
|
end
|
59
|
+
alias_method attr_name, internal_read_method
|
59
60
|
end
|
60
61
|
else
|
61
62
|
super
|
62
63
|
end
|
63
64
|
end
|
64
65
|
|
65
|
-
# Redefine writer method if we are to do time zone configuration on field
|
66
66
|
def define_method_attribute=(attr_name)
|
67
|
-
|
68
|
-
|
67
|
+
if time_zone_conversion_on_field?(attributes_schema[attr_name])
|
68
|
+
internal_write_method = "_#{attr_name}="
|
69
|
+
|
70
|
+
if attr_name =~ ActiveModel::AttributeMethods::COMPILABLE_REGEXP
|
71
|
+
generated_attribute_methods.module_eval <<-RUBY, __FILE__, __LINE__
|
72
|
+
def #{internal_write_method}(time)
|
73
|
+
time = Time.zone.parse(time) if time.is_a? String
|
74
|
+
#{attr_name}_will_change! if will_change_attribute? #{attr_name}, time
|
75
|
+
@attributes['#{attr_name}'] = time
|
76
|
+
end
|
77
|
+
alias #{attr_name}= #{internal_write_method}
|
78
|
+
RUBY
|
79
|
+
else
|
80
|
+
generated_attribute_methods.send(:define_method, internal_write_method) do |time|
|
81
|
+
time = Time.zone.parse(time) if time.is_a? String
|
82
|
+
send("#{attr_name}_will_change!") if will_change_attribute? attr_name, time
|
83
|
+
@attributes[attr_name] = time
|
84
|
+
end
|
85
|
+
alias_method "#{attr_name}=", internal_write_method
|
86
|
+
end
|
87
|
+
else
|
88
|
+
super
|
89
|
+
end
|
69
90
|
end
|
70
91
|
|
71
92
|
|
@@ -28,7 +28,14 @@ module MassiveRecord
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def write_attribute(attr_name, value)
|
31
|
-
|
31
|
+
attr_name = attr_name.to_s
|
32
|
+
internal_write_method = "_#{attr_name}="
|
33
|
+
|
34
|
+
if respond_to? internal_write_method
|
35
|
+
send(internal_write_method, value)
|
36
|
+
else
|
37
|
+
@attributes[attr_name.to_s] = value
|
38
|
+
end
|
32
39
|
end
|
33
40
|
|
34
41
|
private
|
@@ -18,15 +18,19 @@ require 'massive_record/orm/finders/rescue_missing_table_on_find'
|
|
18
18
|
require 'massive_record/orm/attribute_methods'
|
19
19
|
require 'massive_record/orm/attribute_methods/time_zone_conversion'
|
20
20
|
require 'massive_record/orm/attribute_methods/write'
|
21
|
+
require 'massive_record/orm/attribute_methods/cast_numbers_on_write'
|
21
22
|
require 'massive_record/orm/attribute_methods/read'
|
22
23
|
require 'massive_record/orm/attribute_methods/dirty'
|
23
24
|
require 'massive_record/orm/single_table_inheritance'
|
24
25
|
require 'massive_record/orm/validations'
|
26
|
+
require 'massive_record/orm/validations/associated'
|
25
27
|
require 'massive_record/orm/callbacks'
|
26
28
|
require 'massive_record/orm/timestamps'
|
27
29
|
require 'massive_record/orm/persistence'
|
28
30
|
require 'massive_record/orm/default_id'
|
29
31
|
require 'massive_record/orm/query_instrumentation'
|
32
|
+
require 'massive_record/orm/observer'
|
33
|
+
require 'massive_record/orm/identity_map'
|
30
34
|
|
31
35
|
|
32
36
|
module MassiveRecord
|
@@ -75,8 +79,21 @@ module MassiveRecord
|
|
75
79
|
class_attribute :check_record_uniqueness_on_create, :instance_writer => false
|
76
80
|
self.check_record_uniqueness_on_create = false
|
77
81
|
|
78
|
-
|
79
|
-
|
82
|
+
|
83
|
+
#
|
84
|
+
# Default id and id facyory settings
|
85
|
+
# Should we set automatically the id, and which factory should we ask?
|
86
|
+
#
|
87
|
+
# The default id factory is set when massive record is fully loaded, as
|
88
|
+
# it uses MassiveRecord itself to communicate with the database.
|
89
|
+
# Take a look inside of orm/id_factory.rb; we are utilizing the on_load hook.
|
90
|
+
#
|
91
|
+
class_attribute :id_factory, :instance_writer => false
|
92
|
+
class_attribute :set_id_from_factory_before_create, :instance_writer => false
|
93
|
+
self.set_id_from_factory_before_create = true
|
94
|
+
|
95
|
+
|
96
|
+
|
80
97
|
|
81
98
|
class << self
|
82
99
|
def table_name
|
@@ -146,11 +163,13 @@ module MassiveRecord
|
|
146
163
|
@new_record = true
|
147
164
|
@destroyed = @readonly = false
|
148
165
|
@relation_proxy_cache = {}
|
166
|
+
@raw_data = Hash.new { |h,k| h[k] = {} }
|
167
|
+
|
168
|
+
clear_dirty_states!
|
149
169
|
|
150
170
|
self.attributes_raw = attributes_from_field_definition.merge('id' => id)
|
151
171
|
self.attributes = attributes
|
152
172
|
|
153
|
-
clear_dirty_states!
|
154
173
|
|
155
174
|
_run_initialize_callbacks
|
156
175
|
end
|
@@ -176,7 +195,7 @@ module MassiveRecord
|
|
176
195
|
@destroyed = @readonly = false
|
177
196
|
@relation_proxy_cache = {}
|
178
197
|
|
179
|
-
|
198
|
+
reinit_with(coder)
|
180
199
|
fill_attributes_with_default_values_where_nil_is_not_allowed
|
181
200
|
|
182
201
|
_run_find_callbacks
|
@@ -185,6 +204,12 @@ module MassiveRecord
|
|
185
204
|
self
|
186
205
|
end
|
187
206
|
|
207
|
+
def reinit_with(coder) # :nodoc:
|
208
|
+
@raw_data = Hash.new { |h,k| h[k] = {} }
|
209
|
+
@raw_data.update(coder['raw_data']) if coder.has_key? 'raw_data'
|
210
|
+
self.attributes_raw = coder['attributes']
|
211
|
+
end
|
212
|
+
|
188
213
|
|
189
214
|
def ==(other)
|
190
215
|
other.equal?(self) || other.instance_of?(self.class) && id == other.id
|
@@ -197,6 +222,7 @@ module MassiveRecord
|
|
197
222
|
|
198
223
|
def freeze
|
199
224
|
@attributes.freeze
|
225
|
+
self
|
200
226
|
end
|
201
227
|
|
202
228
|
def frozen?
|
@@ -242,6 +268,31 @@ module MassiveRecord
|
|
242
268
|
object.init_with('attributes' => attributes.select{|k| !['id', 'created_at', 'updated_at'].include?(k)})
|
243
269
|
object
|
244
270
|
end
|
271
|
+
|
272
|
+
|
273
|
+
#
|
274
|
+
# The raw data is raw values returned by the adapter.
|
275
|
+
# It is a nested hash like:
|
276
|
+
#
|
277
|
+
# {
|
278
|
+
# 'family' => {
|
279
|
+
# 'attr1' => 'value'
|
280
|
+
# 'attr2' => 'value'
|
281
|
+
# },
|
282
|
+
#
|
283
|
+
# 'addresses' => {
|
284
|
+
# 'address-1' => {'serialized' => 'attributes', 'for' => 'address-2'}
|
285
|
+
# }
|
286
|
+
# ...
|
287
|
+
# }
|
288
|
+
#
|
289
|
+
def raw_data
|
290
|
+
@raw_data.dup
|
291
|
+
end
|
292
|
+
|
293
|
+
def update_raw_data_for_column_family(column_family, new_values) # :nodoc:
|
294
|
+
@raw_data[column_family] = new_values
|
295
|
+
end
|
245
296
|
|
246
297
|
|
247
298
|
private
|
@@ -271,7 +322,7 @@ module MassiveRecord
|
|
271
322
|
|
272
323
|
|
273
324
|
def next_id
|
274
|
-
|
325
|
+
id_factory.next_for(self.class).to_s
|
275
326
|
end
|
276
327
|
end
|
277
328
|
|
@@ -279,19 +330,21 @@ module MassiveRecord
|
|
279
330
|
Base.class_eval do
|
280
331
|
include Config
|
281
332
|
include Persistence
|
282
|
-
include Relations::Interface
|
283
333
|
include Finders
|
334
|
+
include IdentityMap
|
284
335
|
extend RescueMissingTableOnFind
|
285
336
|
include AttributeMethods
|
337
|
+
include Relations::Interface
|
286
338
|
include AttributeMethods::Write, AttributeMethods::Read
|
287
339
|
include AttributeMethods::TimeZoneConversion
|
288
340
|
include AttributeMethods::Dirty
|
341
|
+
include AttributeMethods::CastNumbersOnWrite
|
289
342
|
include Validations
|
290
|
-
include Callbacks
|
343
|
+
include Callbacks, ActiveModel::Observing
|
291
344
|
include Timestamps
|
292
345
|
include SingleTableInheritance
|
293
346
|
include DefaultId
|
294
|
-
include QueryInstrumentation
|
347
|
+
include QueryInstrumentation::Table
|
295
348
|
|
296
349
|
|
297
350
|
alias [] read_attribute
|
@@ -302,6 +355,7 @@ end
|
|
302
355
|
|
303
356
|
require 'massive_record/orm/table'
|
304
357
|
require 'massive_record/orm/column'
|
358
|
+
require 'massive_record/orm/embedded'
|
305
359
|
require 'massive_record/orm/id_factory'
|
306
360
|
require 'massive_record/orm/log_subscriber'
|
307
361
|
|