massive_record 0.2.1 → 0.2.2.rc1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|