ghost_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.
- data/.autotest +29 -0
- data/.document +5 -0
- data/.gitignore +35 -0
- data/.yardopts +1 -0
- data/Gemfile +65 -0
- data/LICENSE +20 -0
- data/README.md +269 -0
- data/Rakefile +4 -0
- data/dm-core.gemspec +24 -0
- data/lib/dm-core.rb +292 -0
- data/lib/dm-core/adapters.rb +222 -0
- data/lib/dm-core/adapters/abstract_adapter.rb +237 -0
- data/lib/dm-core/adapters/in_memory_adapter.rb +113 -0
- data/lib/dm-core/associations/many_to_many.rb +499 -0
- data/lib/dm-core/associations/many_to_one.rb +290 -0
- data/lib/dm-core/associations/one_to_many.rb +348 -0
- data/lib/dm-core/associations/one_to_one.rb +86 -0
- data/lib/dm-core/associations/relationship.rb +663 -0
- data/lib/dm-core/backwards.rb +13 -0
- data/lib/dm-core/collection.rb +1515 -0
- data/lib/dm-core/core_ext/kernel.rb +23 -0
- data/lib/dm-core/core_ext/pathname.rb +6 -0
- data/lib/dm-core/core_ext/symbol.rb +10 -0
- data/lib/dm-core/identity_map.rb +7 -0
- data/lib/dm-core/model.rb +874 -0
- data/lib/dm-core/model/hook.rb +103 -0
- data/lib/dm-core/model/is.rb +32 -0
- data/lib/dm-core/model/property.rb +249 -0
- data/lib/dm-core/model/relationship.rb +378 -0
- data/lib/dm-core/model/scope.rb +89 -0
- data/lib/dm-core/property.rb +866 -0
- data/lib/dm-core/property/binary.rb +21 -0
- data/lib/dm-core/property/boolean.rb +20 -0
- data/lib/dm-core/property/class.rb +17 -0
- data/lib/dm-core/property/date.rb +10 -0
- data/lib/dm-core/property/date_time.rb +10 -0
- data/lib/dm-core/property/decimal.rb +36 -0
- data/lib/dm-core/property/discriminator.rb +44 -0
- data/lib/dm-core/property/float.rb +16 -0
- data/lib/dm-core/property/integer.rb +22 -0
- data/lib/dm-core/property/invalid_value_error.rb +22 -0
- data/lib/dm-core/property/lookup.rb +27 -0
- data/lib/dm-core/property/numeric.rb +38 -0
- data/lib/dm-core/property/object.rb +34 -0
- data/lib/dm-core/property/serial.rb +14 -0
- data/lib/dm-core/property/string.rb +38 -0
- data/lib/dm-core/property/text.rb +9 -0
- data/lib/dm-core/property/time.rb +10 -0
- data/lib/dm-core/property_set.rb +177 -0
- data/lib/dm-core/query.rb +1366 -0
- data/lib/dm-core/query/conditions/comparison.rb +911 -0
- data/lib/dm-core/query/conditions/operation.rb +721 -0
- data/lib/dm-core/query/direction.rb +36 -0
- data/lib/dm-core/query/operator.rb +35 -0
- data/lib/dm-core/query/path.rb +114 -0
- data/lib/dm-core/query/sort.rb +39 -0
- data/lib/dm-core/relationship_set.rb +72 -0
- data/lib/dm-core/repository.rb +226 -0
- data/lib/dm-core/resource.rb +1214 -0
- data/lib/dm-core/resource/persistence_state.rb +75 -0
- data/lib/dm-core/resource/persistence_state/clean.rb +40 -0
- data/lib/dm-core/resource/persistence_state/deleted.rb +30 -0
- data/lib/dm-core/resource/persistence_state/dirty.rb +96 -0
- data/lib/dm-core/resource/persistence_state/immutable.rb +34 -0
- data/lib/dm-core/resource/persistence_state/persisted.rb +29 -0
- data/lib/dm-core/resource/persistence_state/transient.rb +80 -0
- data/lib/dm-core/spec/lib/adapter_helpers.rb +64 -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 +174 -0
- data/lib/dm-core/spec/shared/adapter_spec.rb +341 -0
- data/lib/dm-core/spec/shared/public/property_spec.rb +229 -0
- data/lib/dm-core/spec/shared/resource_spec.rb +1232 -0
- data/lib/dm-core/spec/shared/sel_spec.rb +111 -0
- data/lib/dm-core/spec/shared/semipublic/property_spec.rb +176 -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 +405 -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 +90 -0
- data/lib/dm-core/support/ordered_set.rb +380 -0
- data/lib/dm-core/support/subject.rb +33 -0
- data/lib/dm-core/support/subject_set.rb +250 -0
- data/lib/dm-core/version.rb +3 -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 +68 -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 +76 -0
- data/spec/public/model/hook_spec.rb +246 -0
- data/spec/public/model/property_spec.rb +88 -0
- data/spec/public/model/relationship_spec.rb +1040 -0
- data/spec/public/model_spec.rb +462 -0
- data/spec/public/property/binary_spec.rb +41 -0
- data/spec/public/property/boolean_spec.rb +22 -0
- data/spec/public/property/class_spec.rb +28 -0
- data/spec/public/property/date_spec.rb +22 -0
- data/spec/public/property/date_time_spec.rb +22 -0
- data/spec/public/property/decimal_spec.rb +23 -0
- data/spec/public/property/discriminator_spec.rb +135 -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 +107 -0
- data/spec/public/property/serial_spec.rb +22 -0
- data/spec/public/property/string_spec.rb +22 -0
- data/spec/public/property/text_spec.rb +63 -0
- data/spec/public/property/time_spec.rb +22 -0
- data/spec/public/property_spec.rb +341 -0
- data/spec/public/resource_spec.rb +288 -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 +1667 -0
- data/spec/public/shared/finder_shared_spec.rb +1629 -0
- data/spec/rcov.opts +6 -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 +1501 -0
- data/spec/semipublic/query/conditions/operation_spec.rb +1294 -0
- data/spec/semipublic/query/path_spec.rb +471 -0
- data/spec/semipublic/query_spec.rb +3682 -0
- data/spec/semipublic/resource/state/clean_spec.rb +88 -0
- data/spec/semipublic/resource/state/deleted_spec.rb +78 -0
- data/spec/semipublic/resource/state/dirty_spec.rb +162 -0
- data/spec/semipublic/resource/state/immutable_spec.rb +105 -0
- data/spec/semipublic/resource/state/transient_spec.rb +162 -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 +199 -0
- data/spec/semipublic/shared/resource_state_shared_spec.rb +79 -0
- data/spec/semipublic/shared/subject_shared_spec.rb +79 -0
- data/spec/spec.opts +5 -0
- data/spec/spec_helper.rb +38 -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 +28 -0
- data/spec/unit/hook_spec.rb +1235 -0
- data/spec/unit/inflections_spec.rb +16 -0
- data/spec/unit/lazy_array_spec.rb +1949 -0
- data/spec/unit/mash_spec.rb +312 -0
- data/spec/unit/module_spec.rb +71 -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 +38 -0
- data/tasks/yard.rake +9 -0
- data/tasks/yardstick.rake +19 -0
- metadata +365 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module DataMapper
|
|
2
|
+
class Property
|
|
3
|
+
class Binary < String
|
|
4
|
+
|
|
5
|
+
if RUBY_VERSION >= "1.9"
|
|
6
|
+
|
|
7
|
+
def load(value)
|
|
8
|
+
super.dup.force_encoding("BINARY") unless value.nil?
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def dump(value)
|
|
12
|
+
value.dup.force_encoding("BINARY") unless value.nil?
|
|
13
|
+
rescue
|
|
14
|
+
value
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
end # class Binary
|
|
20
|
+
end # class Property
|
|
21
|
+
end # module DataMapper
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module DataMapper
|
|
2
|
+
class Property
|
|
3
|
+
class Boolean < Object
|
|
4
|
+
load_as ::TrueClass
|
|
5
|
+
dump_as ::TrueClass
|
|
6
|
+
coercion_method :to_boolean
|
|
7
|
+
|
|
8
|
+
# @api semipublic
|
|
9
|
+
def value_dumped?(value)
|
|
10
|
+
value_loaded?(value)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# @api semipublic
|
|
14
|
+
def value_loaded?(value)
|
|
15
|
+
value == true || value == false
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
end # class Boolean
|
|
19
|
+
end # class Property
|
|
20
|
+
end # module DataMapper
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module DataMapper
|
|
2
|
+
class Property
|
|
3
|
+
class Class < Object
|
|
4
|
+
load_as ::Class
|
|
5
|
+
dump_as ::Class
|
|
6
|
+
coercion_method :to_constant
|
|
7
|
+
|
|
8
|
+
# @api semipublic
|
|
9
|
+
def typecast(value)
|
|
10
|
+
DataMapper::Ext::Module.find_const(model, value.to_s) unless value.nil?
|
|
11
|
+
rescue NameError
|
|
12
|
+
value
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
end # class Class
|
|
16
|
+
end # class Property
|
|
17
|
+
end # module DataMapper
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module DataMapper
|
|
2
|
+
class Property
|
|
3
|
+
class Decimal < Numeric
|
|
4
|
+
load_as BigDecimal
|
|
5
|
+
dump_as BigDecimal
|
|
6
|
+
coercion_method :to_decimal
|
|
7
|
+
|
|
8
|
+
DEFAULT_PRECISION = 10
|
|
9
|
+
DEFAULT_SCALE = 0
|
|
10
|
+
|
|
11
|
+
precision(DEFAULT_PRECISION)
|
|
12
|
+
scale(DEFAULT_SCALE)
|
|
13
|
+
|
|
14
|
+
protected
|
|
15
|
+
|
|
16
|
+
def initialize(model, name, options = {})
|
|
17
|
+
super
|
|
18
|
+
|
|
19
|
+
[ :scale, :precision ].each do |key|
|
|
20
|
+
unless @options.key?(key)
|
|
21
|
+
warn "options[#{key.inspect}] should be set for #{self.class}, defaulting to #{send(key).inspect} (#{caller.first})"
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
unless @scale >= 0
|
|
26
|
+
raise ArgumentError, "scale must be equal to or greater than 0, but was #{@scale.inspect}"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
unless @precision >= @scale
|
|
30
|
+
raise ArgumentError, "precision must be equal to or greater than scale, but was #{@precision.inspect} and scale was #{@scale.inspect}"
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
end # class Decimal
|
|
35
|
+
end # class Property
|
|
36
|
+
end # module DataMapper
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
module DataMapper
|
|
2
|
+
class Property
|
|
3
|
+
class Discriminator < Class
|
|
4
|
+
default lambda { |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.kind_of?(Hash)
|
|
20
|
+
discriminator = properties(repository_name).discriminator
|
|
21
|
+
|
|
22
|
+
if discriminator_value = args.first[discriminator.name]
|
|
23
|
+
model = discriminator.typecast(discriminator_value)
|
|
24
|
+
|
|
25
|
+
if model.kind_of?(Model) && !model.equal?(self)
|
|
26
|
+
return model.new(*args, &block)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
super
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
def set_discriminator_scope_for(model)
|
|
37
|
+
discriminator = self.properties.discriminator
|
|
38
|
+
default_scope = model.default_scope(discriminator.repository_name)
|
|
39
|
+
default_scope.update(discriminator.name => model.descendants.dup << model)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end # class Discriminator
|
|
43
|
+
end # module Property
|
|
44
|
+
end # module DataMapper
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module DataMapper
|
|
2
|
+
class Property
|
|
3
|
+
class Float < Numeric
|
|
4
|
+
load_as ::Float
|
|
5
|
+
dump_as ::Float
|
|
6
|
+
coercion_method :to_float
|
|
7
|
+
|
|
8
|
+
DEFAULT_PRECISION = 10
|
|
9
|
+
DEFAULT_SCALE = nil
|
|
10
|
+
|
|
11
|
+
precision(DEFAULT_PRECISION)
|
|
12
|
+
scale(DEFAULT_SCALE)
|
|
13
|
+
|
|
14
|
+
end # class Float
|
|
15
|
+
end # class Property
|
|
16
|
+
end # module DataMapper
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module DataMapper
|
|
2
|
+
class Property
|
|
3
|
+
class Integer < Numeric
|
|
4
|
+
load_as ::Integer
|
|
5
|
+
dump_as ::Integer
|
|
6
|
+
coercion_method :to_integer
|
|
7
|
+
|
|
8
|
+
accept_options :serial
|
|
9
|
+
|
|
10
|
+
protected
|
|
11
|
+
|
|
12
|
+
# @api semipublic
|
|
13
|
+
def initialize(model, name, options = {})
|
|
14
|
+
if options.key?(:serial) && !kind_of?(Serial)
|
|
15
|
+
raise "Integer #{name} with explicit :serial option is deprecated, use Serial instead (#{caller[2]})"
|
|
16
|
+
end
|
|
17
|
+
super
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
end # class Integer
|
|
21
|
+
end # class Property
|
|
22
|
+
end # module DataMapper
|
|
@@ -0,0 +1,22 @@
|
|
|
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 = "Invalid value %s for property %s (%s) on model %s" %
|
|
10
|
+
[ value.inspect,
|
|
11
|
+
property.name.inspect,
|
|
12
|
+
property.class.name,
|
|
13
|
+
property.model.name
|
|
14
|
+
]
|
|
15
|
+
super(msg)
|
|
16
|
+
@property = property
|
|
17
|
+
@value = value
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
end # class InvalidValueError
|
|
21
|
+
end # class Property
|
|
22
|
+
end # module DataMapper
|
|
@@ -0,0 +1,27 @@
|
|
|
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
|
+
def const_missing(name)
|
|
22
|
+
Property.find_class(name.to_s) || super
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
end # module Lookup
|
|
26
|
+
end # class Property
|
|
27
|
+
end # module DataMapper
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module DataMapper
|
|
2
|
+
class Property
|
|
3
|
+
class Numeric < Object
|
|
4
|
+
accept_options :precision, :scale, :min, :max
|
|
5
|
+
|
|
6
|
+
attr_reader :precision, :scale, :min, :max
|
|
7
|
+
|
|
8
|
+
DEFAULT_NUMERIC_MIN = 0
|
|
9
|
+
DEFAULT_NUMERIC_MAX = 2**31-1
|
|
10
|
+
|
|
11
|
+
protected
|
|
12
|
+
|
|
13
|
+
def initialize(model, name, options = {})
|
|
14
|
+
super
|
|
15
|
+
|
|
16
|
+
if kind_of?(Decimal) || kind_of?(Float)
|
|
17
|
+
@precision = @options.fetch(:precision)
|
|
18
|
+
@scale = @options.fetch(:scale)
|
|
19
|
+
|
|
20
|
+
unless @precision > 0
|
|
21
|
+
raise ArgumentError, "precision must be greater than 0, but was #{@precision.inspect}"
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
if @options.key?(:min) || @options.key?(:max)
|
|
26
|
+
@min = @options.fetch(:min, self.class::DEFAULT_NUMERIC_MIN)
|
|
27
|
+
@max = @options.fetch(:max, self.class::DEFAULT_NUMERIC_MAX)
|
|
28
|
+
|
|
29
|
+
if @max < DEFAULT_NUMERIC_MIN && !@options.key?(:min)
|
|
30
|
+
raise ArgumentError, "min should be specified when the max is less than #{DEFAULT_NUMERIC_MIN}"
|
|
31
|
+
elsif @max < @min
|
|
32
|
+
raise ArgumentError, "max must be less than the min, but was #{@max} while the min was #{@min}"
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end # class Numeric
|
|
37
|
+
end # class Property
|
|
38
|
+
end # module DataMapper
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
module DataMapper
|
|
2
|
+
class Property
|
|
3
|
+
class Object < Property
|
|
4
|
+
load_as ::Object
|
|
5
|
+
dump_as ::Object
|
|
6
|
+
coercion_method :to_object
|
|
7
|
+
|
|
8
|
+
# @api semipublic
|
|
9
|
+
def dump(value)
|
|
10
|
+
instance_of?(Object) ? marshal(value) : value
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# @api semipublic
|
|
14
|
+
def load(value)
|
|
15
|
+
typecast(instance_of?(Object) ? unmarshal(value) : value)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# @api semipublic
|
|
19
|
+
def marshal(value)
|
|
20
|
+
[ Marshal.dump(value) ].pack('m') unless value.nil?
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# @api semipublic
|
|
24
|
+
def unmarshal(value)
|
|
25
|
+
Marshal.load(value.unpack('m').first) unless value.nil?
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# @api private
|
|
29
|
+
def to_child_key
|
|
30
|
+
self.class
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module DataMapper
|
|
2
|
+
class Property
|
|
3
|
+
class String < Object
|
|
4
|
+
load_as ::String
|
|
5
|
+
dump_as ::String
|
|
6
|
+
coercion_method :to_string
|
|
7
|
+
|
|
8
|
+
accept_options :length
|
|
9
|
+
|
|
10
|
+
DEFAULT_LENGTH = 50
|
|
11
|
+
length(DEFAULT_LENGTH)
|
|
12
|
+
|
|
13
|
+
# Returns maximum property length (if applicable).
|
|
14
|
+
# This usually only makes sense when property is of
|
|
15
|
+
# type Range or custom
|
|
16
|
+
#
|
|
17
|
+
# @return [Integer, nil]
|
|
18
|
+
# the maximum length of this property
|
|
19
|
+
#
|
|
20
|
+
# @api semipublic
|
|
21
|
+
def length
|
|
22
|
+
if @length.kind_of?(Range)
|
|
23
|
+
@length.max
|
|
24
|
+
else
|
|
25
|
+
@length
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
protected
|
|
30
|
+
|
|
31
|
+
def initialize(model, name, options = {})
|
|
32
|
+
super
|
|
33
|
+
@length = @options.fetch(:length)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
end # class String
|
|
37
|
+
end # class Property
|
|
38
|
+
end # module DataMapper
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
module DataMapper
|
|
2
|
+
# Set of Property objects, used to associate
|
|
3
|
+
# queries with set of fields it performed over,
|
|
4
|
+
# to represent composite keys (esp. for associations)
|
|
5
|
+
# and so on.
|
|
6
|
+
class PropertySet < SubjectSet
|
|
7
|
+
include Enumerable
|
|
8
|
+
|
|
9
|
+
def <<(property)
|
|
10
|
+
clear_cache
|
|
11
|
+
super
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Make sure that entry is part of this PropertySet
|
|
15
|
+
#
|
|
16
|
+
# @param [#to_s] name
|
|
17
|
+
# @param [#name] entry
|
|
18
|
+
#
|
|
19
|
+
# @return [#name]
|
|
20
|
+
# the entry that is now part of this PropertySet
|
|
21
|
+
#
|
|
22
|
+
# @api semipublic
|
|
23
|
+
def []=(name, entry)
|
|
24
|
+
warn "#{self.class}#[]= is deprecated. Use #{self.class}#<< instead: #{caller.first}"
|
|
25
|
+
raise "#{entry.class} is not added with the correct name" unless name && name.to_s == entry.name.to_s
|
|
26
|
+
self << entry
|
|
27
|
+
entry
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def |(other)
|
|
31
|
+
self.class.new(to_a | other.to_a)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def &(other)
|
|
35
|
+
self.class.new(to_a & other.to_a)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def -(other)
|
|
39
|
+
self.class.new(to_a - other.to_a)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def +(other)
|
|
43
|
+
self.class.new(to_a + other.to_a)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def ==(other)
|
|
47
|
+
to_a == other.to_a
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# TODO: make PropertySet#reject return a PropertySet instance
|
|
51
|
+
# @api semipublic
|
|
52
|
+
def defaults
|
|
53
|
+
@defaults ||= self.class.new(key | [ discriminator ].compact | reject { |property| property.lazy? }).freeze
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# @api semipublic
|
|
57
|
+
def key
|
|
58
|
+
@key ||= self.class.new(select { |property| property.key? }).freeze
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# @api semipublic
|
|
62
|
+
def discriminator
|
|
63
|
+
@discriminator ||= detect { |property| property.kind_of?(Property::Discriminator) }
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# @api semipublic
|
|
67
|
+
def indexes
|
|
68
|
+
index_hash = {}
|
|
69
|
+
each { |property| parse_index(property.index, property.field, index_hash) }
|
|
70
|
+
index_hash
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# @api semipublic
|
|
74
|
+
def unique_indexes
|
|
75
|
+
index_hash = {}
|
|
76
|
+
each { |property| parse_index(property.unique_index, property.field, index_hash) }
|
|
77
|
+
index_hash
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# @api semipublic
|
|
81
|
+
def get(resource)
|
|
82
|
+
return [] if resource.nil?
|
|
83
|
+
map { |property| resource.__send__(property.name) }
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# @api semipublic
|
|
87
|
+
def get!(resource)
|
|
88
|
+
map { |property| property.get!(resource) }
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# @api semipublic
|
|
92
|
+
def set(resource, values)
|
|
93
|
+
zip(values) { |property, value| resource.__send__("#{property.name}=", value) }
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# @api semipublic
|
|
97
|
+
def set!(resource, values)
|
|
98
|
+
zip(values) { |property, value| property.set!(resource, value) }
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# @api semipublic
|
|
102
|
+
def loaded?(resource)
|
|
103
|
+
all? { |property| property.loaded?(resource) }
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# @api semipublic
|
|
107
|
+
def valid?(values)
|
|
108
|
+
zip(values.nil? ? [] : values).all? { |property, value| property.valid?(value) }
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# @api semipublic
|
|
112
|
+
def typecast(values)
|
|
113
|
+
zip(values.nil? ? [] : values).map { |property, value| property.typecast(value) }
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# @api private
|
|
117
|
+
def property_contexts(property)
|
|
118
|
+
contexts = []
|
|
119
|
+
lazy_contexts.each do |context, properties|
|
|
120
|
+
contexts << context if properties.include?(property)
|
|
121
|
+
end
|
|
122
|
+
contexts
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# @api private
|
|
126
|
+
def lazy_context(context)
|
|
127
|
+
lazy_contexts[context] ||= []
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# @api private
|
|
131
|
+
def in_context(properties)
|
|
132
|
+
properties_in_context = properties.map do |property|
|
|
133
|
+
if (contexts = property_contexts(property)).any?
|
|
134
|
+
lazy_contexts.values_at(*contexts)
|
|
135
|
+
else
|
|
136
|
+
property
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
properties_in_context.flatten.uniq
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# @api private
|
|
144
|
+
def field_map
|
|
145
|
+
Hash[ map { |property| [ property.field, property ] } ]
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def inspect
|
|
149
|
+
to_a.inspect
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
private
|
|
153
|
+
|
|
154
|
+
# @api private
|
|
155
|
+
def clear_cache
|
|
156
|
+
@defaults, @key, @discriminator = nil
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
# @api private
|
|
160
|
+
def lazy_contexts
|
|
161
|
+
@lazy_contexts ||= {}
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
# @api private
|
|
165
|
+
def parse_index(index, property, index_hash)
|
|
166
|
+
case index
|
|
167
|
+
when true
|
|
168
|
+
index_hash[property] = [ property ]
|
|
169
|
+
when Symbol
|
|
170
|
+
index_hash[index] ||= []
|
|
171
|
+
index_hash[index] << property
|
|
172
|
+
when Array
|
|
173
|
+
index.each { |idx| parse_index(idx, property, index_hash) }
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
end # class PropertySet
|
|
177
|
+
end # module DataMapper
|