sbf-dm-core 1.3.0.beta
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/.autotest +29 -0
- data/.document +5 -0
- data/.gitignore +44 -0
- data/.rspec +1 -0
- data/.rubocop.yml +468 -0
- data/.travis.yml +57 -0
- data/.yardopts +1 -0
- data/Gemfile +70 -0
- data/LICENSE +20 -0
- data/README.md +269 -0
- data/Rakefile +4 -0
- data/dm-core.gemspec +21 -0
- data/lib/dm-core/adapters/abstract_adapter.rb +233 -0
- data/lib/dm-core/adapters/in_memory_adapter.rb +110 -0
- data/lib/dm-core/adapters.rb +249 -0
- data/lib/dm-core/associations/many_to_many.rb +477 -0
- data/lib/dm-core/associations/many_to_one.rb +282 -0
- data/lib/dm-core/associations/one_to_many.rb +332 -0
- data/lib/dm-core/associations/one_to_one.rb +84 -0
- data/lib/dm-core/associations/relationship.rb +650 -0
- data/lib/dm-core/backwards.rb +11 -0
- data/lib/dm-core/collection.rb +1486 -0
- data/lib/dm-core/core_ext/kernel.rb +21 -0
- data/lib/dm-core/core_ext/pathname.rb +4 -0
- data/lib/dm-core/core_ext/symbol.rb +10 -0
- data/lib/dm-core/identity_map.rb +6 -0
- data/lib/dm-core/model/hook.rb +99 -0
- data/lib/dm-core/model/is.rb +30 -0
- data/lib/dm-core/model/property.rb +244 -0
- data/lib/dm-core/model/relationship.rb +366 -0
- data/lib/dm-core/model/scope.rb +87 -0
- data/lib/dm-core/model.rb +876 -0
- data/lib/dm-core/property/binary.rb +19 -0
- data/lib/dm-core/property/boolean.rb +35 -0
- data/lib/dm-core/property/class.rb +23 -0
- data/lib/dm-core/property/date.rb +45 -0
- data/lib/dm-core/property/date_time.rb +44 -0
- data/lib/dm-core/property/decimal.rb +47 -0
- data/lib/dm-core/property/discriminator.rb +40 -0
- data/lib/dm-core/property/float.rb +27 -0
- data/lib/dm-core/property/integer.rb +32 -0
- data/lib/dm-core/property/invalid_value_error.rb +17 -0
- data/lib/dm-core/property/lookup.rb +26 -0
- data/lib/dm-core/property/numeric.rb +35 -0
- data/lib/dm-core/property/object.rb +33 -0
- data/lib/dm-core/property/serial.rb +13 -0
- data/lib/dm-core/property/string.rb +47 -0
- data/lib/dm-core/property/text.rb +12 -0
- data/lib/dm-core/property/time.rb +46 -0
- data/lib/dm-core/property/typecast/numeric.rb +32 -0
- data/lib/dm-core/property/typecast/time.rb +33 -0
- data/lib/dm-core/property.rb +856 -0
- data/lib/dm-core/property_set.rb +177 -0
- data/lib/dm-core/query/conditions/comparison.rb +886 -0
- data/lib/dm-core/query/conditions/operation.rb +710 -0
- data/lib/dm-core/query/direction.rb +33 -0
- data/lib/dm-core/query/operator.rb +34 -0
- data/lib/dm-core/query/path.rb +113 -0
- data/lib/dm-core/query/sort.rb +38 -0
- data/lib/dm-core/query.rb +1352 -0
- data/lib/dm-core/relationship_set.rb +69 -0
- data/lib/dm-core/repository.rb +226 -0
- data/lib/dm-core/resource/persistence_state/clean.rb +36 -0
- data/lib/dm-core/resource/persistence_state/deleted.rb +26 -0
- data/lib/dm-core/resource/persistence_state/dirty.rb +91 -0
- data/lib/dm-core/resource/persistence_state/immutable.rb +32 -0
- data/lib/dm-core/resource/persistence_state/persisted.rb +25 -0
- data/lib/dm-core/resource/persistence_state/transient.rb +87 -0
- data/lib/dm-core/resource/persistence_state.rb +70 -0
- data/lib/dm-core/resource.rb +1220 -0
- data/lib/dm-core/spec/lib/adapter_helpers.rb +63 -0
- data/lib/dm-core/spec/lib/collection_helpers.rb +21 -0
- data/lib/dm-core/spec/lib/counter_adapter.rb +38 -0
- data/lib/dm-core/spec/lib/pending_helpers.rb +50 -0
- data/lib/dm-core/spec/lib/spec_helper.rb +74 -0
- data/lib/dm-core/spec/setup.rb +164 -0
- data/lib/dm-core/spec/shared/adapter_spec.rb +366 -0
- data/lib/dm-core/spec/shared/public/property_spec.rb +229 -0
- data/lib/dm-core/spec/shared/resource_spec.rb +1221 -0
- data/lib/dm-core/spec/shared/sel_spec.rb +111 -0
- data/lib/dm-core/spec/shared/semipublic/property_spec.rb +184 -0
- data/lib/dm-core/spec/shared/semipublic/query/conditions/abstract_comparison_spec.rb +261 -0
- data/lib/dm-core/support/assertions.rb +8 -0
- data/lib/dm-core/support/chainable.rb +18 -0
- data/lib/dm-core/support/deprecate.rb +12 -0
- data/lib/dm-core/support/descendant_set.rb +89 -0
- data/lib/dm-core/support/equalizer.rb +48 -0
- data/lib/dm-core/support/ext/array.rb +22 -0
- data/lib/dm-core/support/ext/blank.rb +25 -0
- data/lib/dm-core/support/ext/hash.rb +67 -0
- data/lib/dm-core/support/ext/module.rb +47 -0
- data/lib/dm-core/support/ext/object.rb +57 -0
- data/lib/dm-core/support/ext/string.rb +24 -0
- data/lib/dm-core/support/ext/try_dup.rb +12 -0
- data/lib/dm-core/support/hook.rb +388 -0
- data/lib/dm-core/support/inflections.rb +60 -0
- data/lib/dm-core/support/inflector/inflections.rb +211 -0
- data/lib/dm-core/support/inflector/methods.rb +151 -0
- data/lib/dm-core/support/lazy_array.rb +451 -0
- data/lib/dm-core/support/local_object_space.rb +13 -0
- data/lib/dm-core/support/logger.rb +201 -0
- data/lib/dm-core/support/mash.rb +176 -0
- data/lib/dm-core/support/naming_conventions.rb +109 -0
- data/lib/dm-core/support/ordered_set.rb +381 -0
- data/lib/dm-core/support/subject.rb +33 -0
- data/lib/dm-core/support/subject_set.rb +251 -0
- data/lib/dm-core/version.rb +3 -0
- data/lib/dm-core.rb +274 -0
- data/script/performance.rb +275 -0
- data/script/profile.rb +218 -0
- data/spec/lib/rspec_immediate_feedback_formatter.rb +54 -0
- data/spec/public/associations/many_to_many/read_multiple_join_spec.rb +69 -0
- data/spec/public/associations/many_to_many_spec.rb +197 -0
- data/spec/public/associations/many_to_one_spec.rb +83 -0
- data/spec/public/associations/many_to_one_with_boolean_cpk_spec.rb +40 -0
- data/spec/public/associations/many_to_one_with_custom_fk_spec.rb +49 -0
- data/spec/public/associations/one_to_many_spec.rb +81 -0
- data/spec/public/associations/one_to_one_spec.rb +176 -0
- data/spec/public/associations/one_to_one_with_boolean_cpk_spec.rb +46 -0
- data/spec/public/collection_spec.rb +69 -0
- data/spec/public/finalize_spec.rb +77 -0
- data/spec/public/model/hook_spec.rb +245 -0
- data/spec/public/model/property_spec.rb +91 -0
- data/spec/public/model/relationship_spec.rb +1040 -0
- data/spec/public/model_spec.rb +456 -0
- data/spec/public/property/binary_spec.rb +43 -0
- data/spec/public/property/boolean_spec.rb +21 -0
- data/spec/public/property/class_spec.rb +27 -0
- data/spec/public/property/date_spec.rb +21 -0
- data/spec/public/property/date_time_spec.rb +21 -0
- data/spec/public/property/decimal_spec.rb +23 -0
- data/spec/public/property/discriminator_spec.rb +134 -0
- data/spec/public/property/float_spec.rb +22 -0
- data/spec/public/property/integer_spec.rb +22 -0
- data/spec/public/property/object_spec.rb +117 -0
- data/spec/public/property/serial_spec.rb +22 -0
- data/spec/public/property/string_spec.rb +21 -0
- data/spec/public/property/text_spec.rb +62 -0
- data/spec/public/property/time_spec.rb +21 -0
- data/spec/public/property_spec.rb +333 -0
- data/spec/public/resource/state_spec.rb +72 -0
- data/spec/public/resource_spec.rb +289 -0
- data/spec/public/sel_spec.rb +53 -0
- data/spec/public/setup_spec.rb +145 -0
- data/spec/public/shared/association_collection_shared_spec.rb +309 -0
- data/spec/public/shared/collection_finder_shared_spec.rb +267 -0
- data/spec/public/shared/collection_shared_spec.rb +1637 -0
- data/spec/public/shared/finder_shared_spec.rb +1647 -0
- data/spec/semipublic/adapters/abstract_adapter_spec.rb +30 -0
- data/spec/semipublic/adapters/in_memory_adapter_spec.rb +13 -0
- data/spec/semipublic/associations/many_to_many_spec.rb +94 -0
- data/spec/semipublic/associations/many_to_one_spec.rb +63 -0
- data/spec/semipublic/associations/one_to_many_spec.rb +55 -0
- data/spec/semipublic/associations/one_to_one_spec.rb +53 -0
- data/spec/semipublic/associations/relationship_spec.rb +200 -0
- data/spec/semipublic/associations_spec.rb +177 -0
- data/spec/semipublic/collection_spec.rb +110 -0
- data/spec/semipublic/model_spec.rb +96 -0
- data/spec/semipublic/property/binary_spec.rb +13 -0
- data/spec/semipublic/property/boolean_spec.rb +47 -0
- data/spec/semipublic/property/class_spec.rb +33 -0
- data/spec/semipublic/property/date_spec.rb +43 -0
- data/spec/semipublic/property/date_time_spec.rb +46 -0
- data/spec/semipublic/property/decimal_spec.rb +83 -0
- data/spec/semipublic/property/discriminator_spec.rb +19 -0
- data/spec/semipublic/property/float_spec.rb +82 -0
- data/spec/semipublic/property/integer_spec.rb +82 -0
- data/spec/semipublic/property/lookup_spec.rb +29 -0
- data/spec/semipublic/property/serial_spec.rb +13 -0
- data/spec/semipublic/property/string_spec.rb +13 -0
- data/spec/semipublic/property/text_spec.rb +31 -0
- data/spec/semipublic/property/time_spec.rb +50 -0
- data/spec/semipublic/property_spec.rb +114 -0
- data/spec/semipublic/query/conditions/comparison_spec.rb +1502 -0
- data/spec/semipublic/query/conditions/operation_spec.rb +1296 -0
- data/spec/semipublic/query/path_spec.rb +471 -0
- data/spec/semipublic/query_spec.rb +3665 -0
- data/spec/semipublic/resource/state/clean_spec.rb +89 -0
- data/spec/semipublic/resource/state/deleted_spec.rb +79 -0
- data/spec/semipublic/resource/state/dirty_spec.rb +163 -0
- data/spec/semipublic/resource/state/immutable_spec.rb +107 -0
- data/spec/semipublic/resource/state/transient_spec.rb +163 -0
- data/spec/semipublic/resource/state_spec.rb +230 -0
- data/spec/semipublic/resource_spec.rb +23 -0
- data/spec/semipublic/shared/condition_shared_spec.rb +9 -0
- data/spec/semipublic/shared/resource_shared_spec.rb +198 -0
- data/spec/semipublic/shared/resource_state_shared_spec.rb +91 -0
- data/spec/semipublic/shared/subject_shared_spec.rb +79 -0
- data/spec/spec_helper.rb +34 -0
- data/spec/support/core_ext/hash.rb +10 -0
- data/spec/support/core_ext/inheritable_attributes.rb +46 -0
- data/spec/support/properties/huge_integer.rb +17 -0
- data/spec/unit/array_spec.rb +23 -0
- data/spec/unit/blank_spec.rb +73 -0
- data/spec/unit/data_mapper/ordered_set/append_spec.rb +26 -0
- data/spec/unit/data_mapper/ordered_set/clear_spec.rb +24 -0
- data/spec/unit/data_mapper/ordered_set/delete_spec.rb +28 -0
- data/spec/unit/data_mapper/ordered_set/each_spec.rb +19 -0
- data/spec/unit/data_mapper/ordered_set/empty_spec.rb +20 -0
- data/spec/unit/data_mapper/ordered_set/entries_spec.rb +22 -0
- data/spec/unit/data_mapper/ordered_set/eql_spec.rb +51 -0
- data/spec/unit/data_mapper/ordered_set/equal_value_spec.rb +84 -0
- data/spec/unit/data_mapper/ordered_set/hash_spec.rb +12 -0
- data/spec/unit/data_mapper/ordered_set/include_spec.rb +23 -0
- data/spec/unit/data_mapper/ordered_set/index_spec.rb +28 -0
- data/spec/unit/data_mapper/ordered_set/initialize_spec.rb +32 -0
- data/spec/unit/data_mapper/ordered_set/merge_spec.rb +36 -0
- data/spec/unit/data_mapper/ordered_set/shared/append_spec.rb +24 -0
- data/spec/unit/data_mapper/ordered_set/shared/clear_spec.rb +9 -0
- data/spec/unit/data_mapper/ordered_set/shared/delete_spec.rb +25 -0
- data/spec/unit/data_mapper/ordered_set/shared/each_spec.rb +17 -0
- data/spec/unit/data_mapper/ordered_set/shared/empty_spec.rb +9 -0
- data/spec/unit/data_mapper/ordered_set/shared/entries_spec.rb +9 -0
- data/spec/unit/data_mapper/ordered_set/shared/include_spec.rb +9 -0
- data/spec/unit/data_mapper/ordered_set/shared/index_spec.rb +13 -0
- data/spec/unit/data_mapper/ordered_set/shared/initialize_spec.rb +28 -0
- data/spec/unit/data_mapper/ordered_set/shared/merge_spec.rb +28 -0
- data/spec/unit/data_mapper/ordered_set/shared/size_spec.rb +13 -0
- data/spec/unit/data_mapper/ordered_set/shared/to_ary_spec.rb +11 -0
- data/spec/unit/data_mapper/ordered_set/size_spec.rb +27 -0
- data/spec/unit/data_mapper/ordered_set/to_ary_spec.rb +23 -0
- data/spec/unit/data_mapper/subject_set/append_spec.rb +47 -0
- data/spec/unit/data_mapper/subject_set/clear_spec.rb +34 -0
- data/spec/unit/data_mapper/subject_set/delete_spec.rb +40 -0
- data/spec/unit/data_mapper/subject_set/each_spec.rb +30 -0
- data/spec/unit/data_mapper/subject_set/empty_spec.rb +31 -0
- data/spec/unit/data_mapper/subject_set/entries_spec.rb +31 -0
- data/spec/unit/data_mapper/subject_set/get_spec.rb +34 -0
- data/spec/unit/data_mapper/subject_set/include_spec.rb +32 -0
- data/spec/unit/data_mapper/subject_set/named_spec.rb +33 -0
- data/spec/unit/data_mapper/subject_set/shared/append_spec.rb +18 -0
- data/spec/unit/data_mapper/subject_set/shared/clear_spec.rb +9 -0
- data/spec/unit/data_mapper/subject_set/shared/delete_spec.rb +9 -0
- data/spec/unit/data_mapper/subject_set/shared/each_spec.rb +9 -0
- data/spec/unit/data_mapper/subject_set/shared/empty_spec.rb +9 -0
- data/spec/unit/data_mapper/subject_set/shared/entries_spec.rb +9 -0
- data/spec/unit/data_mapper/subject_set/shared/get_spec.rb +9 -0
- data/spec/unit/data_mapper/subject_set/shared/include_spec.rb +9 -0
- data/spec/unit/data_mapper/subject_set/shared/named_spec.rb +9 -0
- data/spec/unit/data_mapper/subject_set/shared/size_spec.rb +13 -0
- data/spec/unit/data_mapper/subject_set/shared/to_ary_spec.rb +9 -0
- data/spec/unit/data_mapper/subject_set/shared/values_at_spec.rb +44 -0
- data/spec/unit/data_mapper/subject_set/size_spec.rb +42 -0
- data/spec/unit/data_mapper/subject_set/to_ary_spec.rb +34 -0
- data/spec/unit/data_mapper/subject_set/values_at_spec.rb +57 -0
- data/spec/unit/hash_spec.rb +27 -0
- data/spec/unit/hook_spec.rb +1216 -0
- data/spec/unit/inflections_spec.rb +14 -0
- data/spec/unit/lazy_array_spec.rb +1949 -0
- data/spec/unit/mash_spec.rb +289 -0
- data/spec/unit/module_spec.rb +70 -0
- data/spec/unit/object_spec.rb +38 -0
- data/spec/unit/try_dup_spec.rb +46 -0
- data/tasks/ci.rake +1 -0
- data/tasks/spec.rake +18 -0
- data/tasks/yard.rake +9 -0
- data/tasks/yardstick.rake +19 -0
- metadata +323 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module DataMapper
|
|
2
|
+
class Property
|
|
3
|
+
class Binary < String
|
|
4
|
+
if RUBY_VERSION >= '1.9'
|
|
5
|
+
|
|
6
|
+
def load(value)
|
|
7
|
+
super.dup.force_encoding('BINARY') unless value.nil?
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def dump(value)
|
|
11
|
+
value&.dup&.force_encoding('BINARY')
|
|
12
|
+
rescue
|
|
13
|
+
value
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module DataMapper
|
|
2
|
+
class Property
|
|
3
|
+
class Boolean < Object
|
|
4
|
+
load_as ::TrueClass
|
|
5
|
+
dump_as ::TrueClass
|
|
6
|
+
|
|
7
|
+
TRUE_VALUES = [1, '1', 't', 'T', 'true', 'TRUE'].freeze
|
|
8
|
+
FALSE_VALUES = [0, '0', 'f', 'F', 'false', 'FALSE'].freeze
|
|
9
|
+
BOOLEAN_MAP = (TRUE_VALUES.product([true]) + FALSE_VALUES.product([false])).to_h.freeze
|
|
10
|
+
|
|
11
|
+
# @api semipublic
|
|
12
|
+
def value_dumped?(value)
|
|
13
|
+
value_loaded?(value)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# @api semipublic
|
|
17
|
+
def value_loaded?(value)
|
|
18
|
+
[true, false].include?(value)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Typecast a value to a true or false
|
|
22
|
+
#
|
|
23
|
+
# @param [Integer, #to_str] value
|
|
24
|
+
# value to typecast
|
|
25
|
+
#
|
|
26
|
+
# @return [Boolean]
|
|
27
|
+
# true or false constructed from value
|
|
28
|
+
#
|
|
29
|
+
# @api private
|
|
30
|
+
def typecast_to_primitive(value)
|
|
31
|
+
BOOLEAN_MAP.fetch(value, value)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module DataMapper
|
|
2
|
+
class Property
|
|
3
|
+
class Class < Object
|
|
4
|
+
load_as ::Class
|
|
5
|
+
dump_as ::Class
|
|
6
|
+
|
|
7
|
+
# Typecast a value to a Class
|
|
8
|
+
#
|
|
9
|
+
# @param [#to_s] value
|
|
10
|
+
# value to typecast
|
|
11
|
+
#
|
|
12
|
+
# @return [Class]
|
|
13
|
+
# Class constructed from value
|
|
14
|
+
#
|
|
15
|
+
# @api private
|
|
16
|
+
def typecast_to_primitive(value)
|
|
17
|
+
DataMapper::Ext::Module.find_const(model, value.to_s)
|
|
18
|
+
rescue NameError
|
|
19
|
+
value
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
module DataMapper
|
|
2
|
+
class Property
|
|
3
|
+
class Date < Object
|
|
4
|
+
include Typecast::Time
|
|
5
|
+
|
|
6
|
+
load_as ::Date
|
|
7
|
+
dump_as ::Date
|
|
8
|
+
|
|
9
|
+
# Typecasts an arbitrary value to a Date
|
|
10
|
+
# Handles both Hashes and Date instances.
|
|
11
|
+
#
|
|
12
|
+
# @param [Hash, #to_mash, #to_s] value
|
|
13
|
+
# value to be typecast
|
|
14
|
+
#
|
|
15
|
+
# @return [Date]
|
|
16
|
+
# Date constructed from value
|
|
17
|
+
#
|
|
18
|
+
# @api private
|
|
19
|
+
def typecast_to_primitive(value)
|
|
20
|
+
if value.respond_to?(:to_date)
|
|
21
|
+
value.to_date
|
|
22
|
+
elsif value.is_a?(::Hash) || value.respond_to?(:to_mash)
|
|
23
|
+
typecast_hash_to_date(value)
|
|
24
|
+
else
|
|
25
|
+
::Date.parse(value.to_s)
|
|
26
|
+
end
|
|
27
|
+
rescue ArgumentError
|
|
28
|
+
value
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Creates a Date instance from a Hash with keys :year, :month, :day
|
|
32
|
+
#
|
|
33
|
+
# @param [Hash, #to_mash] value
|
|
34
|
+
# value to be typecast
|
|
35
|
+
#
|
|
36
|
+
# @return [Date]
|
|
37
|
+
# Date constructed from hash
|
|
38
|
+
#
|
|
39
|
+
# @api private
|
|
40
|
+
def typecast_hash_to_date(value)
|
|
41
|
+
::Date.new(*extract_time(value)[0, 3])
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
module DataMapper
|
|
2
|
+
class Property
|
|
3
|
+
class DateTime < Object
|
|
4
|
+
include Typecast::Time
|
|
5
|
+
|
|
6
|
+
load_as ::DateTime
|
|
7
|
+
dump_as ::DateTime
|
|
8
|
+
|
|
9
|
+
# Typecasts an arbitrary value to a DateTime.
|
|
10
|
+
# Handles both Hashes and DateTime instances.
|
|
11
|
+
#
|
|
12
|
+
# @param [Hash, #to_mash, #to_s] value
|
|
13
|
+
# value to be typecast
|
|
14
|
+
#
|
|
15
|
+
# @return [DateTime]
|
|
16
|
+
# DateTime constructed from value
|
|
17
|
+
#
|
|
18
|
+
# @api private
|
|
19
|
+
def typecast_to_primitive(value)
|
|
20
|
+
if value.is_a?(::Hash) || value.respond_to?(:to_mash)
|
|
21
|
+
typecast_hash_to_datetime(value)
|
|
22
|
+
else
|
|
23
|
+
::DateTime.parse(value.to_s)
|
|
24
|
+
end
|
|
25
|
+
rescue ArgumentError
|
|
26
|
+
value
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Creates a DateTime instance from a Hash with keys :year, :month, :day,
|
|
30
|
+
# :hour, :min, :sec
|
|
31
|
+
#
|
|
32
|
+
# @param [Hash, #to_mash] value
|
|
33
|
+
# value to be typecast
|
|
34
|
+
#
|
|
35
|
+
# @return [DateTime]
|
|
36
|
+
# DateTime constructed from hash
|
|
37
|
+
#
|
|
38
|
+
# @api private
|
|
39
|
+
def typecast_hash_to_datetime(value)
|
|
40
|
+
::DateTime.new(*extract_time(value))
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
module DataMapper
|
|
2
|
+
class Property
|
|
3
|
+
class Decimal < Numeric
|
|
4
|
+
load_as BigDecimal
|
|
5
|
+
dump_as BigDecimal
|
|
6
|
+
|
|
7
|
+
DEFAULT_PRECISION = 10
|
|
8
|
+
DEFAULT_SCALE = 0
|
|
9
|
+
|
|
10
|
+
precision(DEFAULT_PRECISION)
|
|
11
|
+
scale(DEFAULT_SCALE)
|
|
12
|
+
|
|
13
|
+
protected def initialize(model, name, options = {})
|
|
14
|
+
super
|
|
15
|
+
|
|
16
|
+
%i(scale precision).each do |key|
|
|
17
|
+
unless @options.key?(key)
|
|
18
|
+
warn "options[#{key.inspect}] should be set for #{self.class}, defaulting to #{send(key).inspect} (#{caller.first})"
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
raise ArgumentError, "scale must be equal to or greater than 0, but was #{@scale.inspect}" unless @scale >= 0
|
|
23
|
+
|
|
24
|
+
return if @precision >= @scale
|
|
25
|
+
|
|
26
|
+
raise ArgumentError, "precision must be equal to or greater than scale, but was #{@precision.inspect} and scale was #{@scale.inspect}"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Typecast a value to a BigDecimal
|
|
30
|
+
#
|
|
31
|
+
# @param [#to_str, #to_d, Integer] value
|
|
32
|
+
# value to typecast
|
|
33
|
+
#
|
|
34
|
+
# @return [BigDecimal]
|
|
35
|
+
# BigDecimal constructed from value
|
|
36
|
+
#
|
|
37
|
+
# @api private
|
|
38
|
+
protected def typecast_to_primitive(value)
|
|
39
|
+
if value.is_a?(::Integer)
|
|
40
|
+
value.to_s.to_d
|
|
41
|
+
else
|
|
42
|
+
typecast_to_numeric(value, :to_d)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module DataMapper
|
|
2
|
+
class Property
|
|
3
|
+
class Discriminator < Class
|
|
4
|
+
default ->(resource, _property) { resource.model }
|
|
5
|
+
required true
|
|
6
|
+
|
|
7
|
+
# @api private
|
|
8
|
+
def bind
|
|
9
|
+
model.extend Model unless model < Model
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
module Model
|
|
13
|
+
def inherited(model)
|
|
14
|
+
super # setup self.descendants
|
|
15
|
+
set_discriminator_scope_for(model)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def new(*args, &block)
|
|
19
|
+
if args.size == 1 && args.first.is_a?(Hash)
|
|
20
|
+
discriminator = properties(repository_name).discriminator
|
|
21
|
+
|
|
22
|
+
if (discriminator_value = args.first[discriminator.name])
|
|
23
|
+
model = discriminator.typecast_to_primitive(discriminator_value)
|
|
24
|
+
|
|
25
|
+
return model.new(*args, &block) if model.is_a?(Model) && !model.equal?(self)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
super
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private def set_discriminator_scope_for(model)
|
|
33
|
+
discriminator = properties.discriminator
|
|
34
|
+
default_scope = model.default_scope(discriminator.repository_name)
|
|
35
|
+
default_scope.update(discriminator.name => model.descendants.dup << model)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module DataMapper
|
|
2
|
+
class Property
|
|
3
|
+
class Float < Numeric
|
|
4
|
+
load_as ::Float
|
|
5
|
+
dump_as ::Float
|
|
6
|
+
|
|
7
|
+
DEFAULT_PRECISION = 10
|
|
8
|
+
DEFAULT_SCALE = nil
|
|
9
|
+
|
|
10
|
+
precision(DEFAULT_PRECISION)
|
|
11
|
+
scale(DEFAULT_SCALE)
|
|
12
|
+
|
|
13
|
+
# Typecast a value to a Float
|
|
14
|
+
#
|
|
15
|
+
# @param [#to_str, #to_f] value
|
|
16
|
+
# value to typecast
|
|
17
|
+
#
|
|
18
|
+
# @return [Float]
|
|
19
|
+
# Float constructed from value
|
|
20
|
+
#
|
|
21
|
+
# @api private
|
|
22
|
+
protected def typecast_to_primitive(value)
|
|
23
|
+
typecast_to_numeric(value, :to_f)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module DataMapper
|
|
2
|
+
class Property
|
|
3
|
+
class Integer < Numeric
|
|
4
|
+
load_as ::Integer
|
|
5
|
+
dump_as ::Integer
|
|
6
|
+
|
|
7
|
+
accept_options :serial
|
|
8
|
+
|
|
9
|
+
# @api semipublic
|
|
10
|
+
protected def initialize(model, name, options = {})
|
|
11
|
+
if options.key?(:serial) && !is_a?(Serial)
|
|
12
|
+
raise "Integer #{name} with explicit :serial option is deprecated, use Serial instead (#{caller[2]})"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
super
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Typecast a value to an Integer
|
|
19
|
+
#
|
|
20
|
+
# @param [#to_str, #to_i] value
|
|
21
|
+
# value to typecast
|
|
22
|
+
#
|
|
23
|
+
# @return [Integer]
|
|
24
|
+
# Integer constructed from value
|
|
25
|
+
#
|
|
26
|
+
# @api private
|
|
27
|
+
protected def typecast_to_primitive(value)
|
|
28
|
+
typecast_to_numeric(value, :to_i)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module DataMapper
|
|
2
|
+
class Property
|
|
3
|
+
# Exception raised when DataMapper is about to work with
|
|
4
|
+
# invalid property values.
|
|
5
|
+
class InvalidValueError < StandardError
|
|
6
|
+
attr_reader :property, :value
|
|
7
|
+
|
|
8
|
+
def initialize(property, value)
|
|
9
|
+
msg = format('Invalid value %s for property %s (%s) on model %s', value.inspect, property.name.inspect, property.class.name,
|
|
10
|
+
property.model.name)
|
|
11
|
+
super(msg)
|
|
12
|
+
@property = property
|
|
13
|
+
@value = value
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module DataMapper
|
|
2
|
+
class Property
|
|
3
|
+
module Lookup
|
|
4
|
+
#
|
|
5
|
+
# Provides transparent access to the Properties defined in
|
|
6
|
+
# {Property}.
|
|
7
|
+
#
|
|
8
|
+
# @param [Symbol] name
|
|
9
|
+
# The name of the property to lookup.
|
|
10
|
+
#
|
|
11
|
+
# @return [Property]
|
|
12
|
+
# The property with the given name.
|
|
13
|
+
#
|
|
14
|
+
# @raise [NameError]
|
|
15
|
+
# The property could not be found.
|
|
16
|
+
#
|
|
17
|
+
# @api private
|
|
18
|
+
#
|
|
19
|
+
# @since 1.0.1
|
|
20
|
+
#
|
|
21
|
+
protected def const_missing(name)
|
|
22
|
+
Property.find_class(name.to_s) || super
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module DataMapper
|
|
2
|
+
class Property
|
|
3
|
+
class Numeric < Object
|
|
4
|
+
include Typecast::Numeric
|
|
5
|
+
|
|
6
|
+
accept_options :precision, :scale, :min, :max
|
|
7
|
+
attr_reader :precision, :scale, :min, :max
|
|
8
|
+
|
|
9
|
+
DEFAULT_NUMERIC_MIN = 0
|
|
10
|
+
DEFAULT_NUMERIC_MAX = (2**31) - 1
|
|
11
|
+
|
|
12
|
+
protected def initialize(model, name, options = {})
|
|
13
|
+
super
|
|
14
|
+
|
|
15
|
+
if is_a?(Decimal) || is_a?(Float)
|
|
16
|
+
@precision = @options.fetch(:precision)
|
|
17
|
+
@scale = @options.fetch(:scale)
|
|
18
|
+
|
|
19
|
+
raise ArgumentError, "precision must be greater than 0, but was #{@precision.inspect}" unless @precision > 0
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
return unless @options.key?(:min) || @options.key?(:max)
|
|
23
|
+
|
|
24
|
+
@min = @options.fetch(:min, self.class::DEFAULT_NUMERIC_MIN)
|
|
25
|
+
@max = @options.fetch(:max, self.class::DEFAULT_NUMERIC_MAX)
|
|
26
|
+
|
|
27
|
+
if @max < DEFAULT_NUMERIC_MIN && !@options.key?(:min)
|
|
28
|
+
raise ArgumentError, "min should be specified when the max is less than #{DEFAULT_NUMERIC_MIN}"
|
|
29
|
+
elsif @max < @min
|
|
30
|
+
raise ArgumentError, "max must be less than the min, but was #{@max} while the min was #{@min}"
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module DataMapper
|
|
2
|
+
class Property
|
|
3
|
+
class Object < Property
|
|
4
|
+
load_as ::Object
|
|
5
|
+
dump_as ::Object
|
|
6
|
+
|
|
7
|
+
# @api semipublic
|
|
8
|
+
def dump(value)
|
|
9
|
+
instance_of?(Object) ? marshal(value) : value
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# @api semipublic
|
|
13
|
+
def load(value)
|
|
14
|
+
typecast(instance_of?(Object) ? unmarshal(value) : value)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# @api semipublic
|
|
18
|
+
def marshal(value)
|
|
19
|
+
[Marshal.dump(value)].pack('m') unless value.nil?
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# @api semipublic
|
|
23
|
+
def unmarshal(value)
|
|
24
|
+
Marshal.load(value.unpack1('m')) unless value.nil?
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# @api private
|
|
28
|
+
def to_child_key
|
|
29
|
+
self.class
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
module DataMapper
|
|
2
|
+
class Property
|
|
3
|
+
class String < Object
|
|
4
|
+
load_as ::String
|
|
5
|
+
dump_as ::String
|
|
6
|
+
|
|
7
|
+
accept_options :length
|
|
8
|
+
|
|
9
|
+
DEFAULT_LENGTH = 50
|
|
10
|
+
length(DEFAULT_LENGTH)
|
|
11
|
+
|
|
12
|
+
# Returns maximum property length (if applicable).
|
|
13
|
+
# This usually only makes sense when property is of
|
|
14
|
+
# type Range or custom
|
|
15
|
+
#
|
|
16
|
+
# @return [Integer, nil]
|
|
17
|
+
# the maximum length of this property
|
|
18
|
+
#
|
|
19
|
+
# @api semipublic
|
|
20
|
+
def length
|
|
21
|
+
if @length.is_a?(Range)
|
|
22
|
+
@length.max
|
|
23
|
+
else
|
|
24
|
+
@length
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
protected def initialize(model, name, options = {})
|
|
29
|
+
super
|
|
30
|
+
@length = @options.fetch(:length)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Typecast a value to a String
|
|
34
|
+
#
|
|
35
|
+
# @param [#to_s] value
|
|
36
|
+
# value to typecast
|
|
37
|
+
#
|
|
38
|
+
# @return [String]
|
|
39
|
+
# String constructed from value
|
|
40
|
+
#
|
|
41
|
+
# @api private
|
|
42
|
+
protected def typecast_to_primitive(value)
|
|
43
|
+
value.to_s
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
module DataMapper
|
|
2
|
+
class Property
|
|
3
|
+
class Time < Object
|
|
4
|
+
include Typecast::Time
|
|
5
|
+
|
|
6
|
+
load_as ::Time
|
|
7
|
+
dump_as ::Time
|
|
8
|
+
|
|
9
|
+
# Typecasts an arbitrary value to a Time
|
|
10
|
+
# Handles both Hashes and Time instances.
|
|
11
|
+
#
|
|
12
|
+
# @param [Hash, #to_mash, #to_s] value
|
|
13
|
+
# value to be typecast
|
|
14
|
+
#
|
|
15
|
+
# @return [Time]
|
|
16
|
+
# Time constructed from value
|
|
17
|
+
#
|
|
18
|
+
# @api private
|
|
19
|
+
def typecast_to_primitive(value)
|
|
20
|
+
if value.respond_to?(:to_time)
|
|
21
|
+
value.to_time
|
|
22
|
+
elsif value.is_a?(::Hash) || value.respond_to?(:to_mash)
|
|
23
|
+
typecast_hash_to_time(value)
|
|
24
|
+
else
|
|
25
|
+
::Time.parse(value.to_s)
|
|
26
|
+
end
|
|
27
|
+
rescue ArgumentError
|
|
28
|
+
value
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Creates a Time instance from a Hash with keys :year, :month, :day,
|
|
32
|
+
# :hour, :min, :sec
|
|
33
|
+
#
|
|
34
|
+
# @param [Hash, #to_mash] value
|
|
35
|
+
# value to be typecast
|
|
36
|
+
#
|
|
37
|
+
# @return [Time]
|
|
38
|
+
# Time constructed from hash
|
|
39
|
+
#
|
|
40
|
+
# @api private
|
|
41
|
+
def typecast_hash_to_time(value)
|
|
42
|
+
::Time.local(*extract_time(value))
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module DataMapper
|
|
2
|
+
class Property
|
|
3
|
+
module Typecast
|
|
4
|
+
module Numeric
|
|
5
|
+
# Match numeric string
|
|
6
|
+
#
|
|
7
|
+
# @param [#to_str, Numeric] value
|
|
8
|
+
# value to typecast
|
|
9
|
+
# @param [Symbol] method
|
|
10
|
+
# method to typecast with
|
|
11
|
+
#
|
|
12
|
+
# @return [Numeric]
|
|
13
|
+
# number if matched, value if no match
|
|
14
|
+
#
|
|
15
|
+
# @api private
|
|
16
|
+
def typecast_to_numeric(value, method)
|
|
17
|
+
if value.respond_to?(:to_str)
|
|
18
|
+
if value.to_str =~ /\A(-?(?:0|[1-9]\d*)(?:\.\d+)?|(?:\.\d+))\z/
|
|
19
|
+
::Regexp.last_match(1).send(method)
|
|
20
|
+
else
|
|
21
|
+
value
|
|
22
|
+
end
|
|
23
|
+
elsif value.respond_to?(method)
|
|
24
|
+
value.send(method)
|
|
25
|
+
else
|
|
26
|
+
value
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module DataMapper
|
|
2
|
+
class Property
|
|
3
|
+
module Typecast
|
|
4
|
+
module Time
|
|
5
|
+
include Numeric
|
|
6
|
+
|
|
7
|
+
# Extracts the given args from the hash. If a value does not exist, it
|
|
8
|
+
# uses the value of Time.now.
|
|
9
|
+
#
|
|
10
|
+
# @param [Hash, #to_mash] value
|
|
11
|
+
# value to extract time args from
|
|
12
|
+
#
|
|
13
|
+
# @return [Array]
|
|
14
|
+
# Extracted values
|
|
15
|
+
#
|
|
16
|
+
# @api private
|
|
17
|
+
def extract_time(value)
|
|
18
|
+
mash = if value.respond_to?(:to_mash)
|
|
19
|
+
value.to_mash
|
|
20
|
+
else
|
|
21
|
+
DataMapper::Ext::Hash.to_mash(value)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
now = ::Time.now
|
|
25
|
+
|
|
26
|
+
%i(year month day hour min sec).map do |segment|
|
|
27
|
+
typecast_to_numeric(mash.fetch(segment, now.send(segment)), :to_i)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|