dm-core 0.10.0 → 0.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +25 -5
- data/Manifest.txt +1 -0
- data/README.txt +67 -23
- data/Rakefile +0 -2
- data/deps.rip +1 -1
- data/dm-core.gemspec +6 -6
- data/lib/dm-core/adapters/abstract_adapter.rb +3 -76
- data/lib/dm-core/adapters/data_objects_adapter.rb +8 -39
- data/lib/dm-core/associations/many_to_many.rb +28 -16
- data/lib/dm-core/associations/many_to_one.rb +1 -45
- data/lib/dm-core/associations/one_to_many.rb +1 -38
- data/lib/dm-core/associations/relationship.rb +43 -20
- data/lib/dm-core/collection.rb +33 -32
- data/lib/dm-core/model/property.rb +8 -8
- data/lib/dm-core/model/relationship.rb +10 -12
- data/lib/dm-core/property.rb +20 -85
- data/lib/dm-core/property_set.rb +8 -8
- data/lib/dm-core/query/conditions/comparison.rb +13 -71
- data/lib/dm-core/query/conditions/operation.rb +73 -47
- data/lib/dm-core/query/operator.rb +3 -45
- data/lib/dm-core/query/path.rb +5 -41
- data/lib/dm-core/query.rb +37 -108
- data/lib/dm-core/repository.rb +3 -79
- data/lib/dm-core/resource.rb +54 -49
- data/lib/dm-core/support/chainable.rb +0 -2
- data/lib/dm-core/support/equalizer.rb +23 -0
- data/lib/dm-core/types/object.rb +4 -4
- data/lib/dm-core/version.rb +1 -1
- data/lib/dm-core.rb +3 -11
- data/spec/public/model/relationship_spec.rb +4 -4
- data/spec/public/property_spec.rb +5 -449
- data/spec/public/sel_spec.rb +52 -2
- data/spec/public/shared/collection_shared_spec.rb +79 -26
- data/spec/public/shared/finder_shared_spec.rb +6 -6
- data/spec/public/shared/resource_shared_spec.rb +2 -2
- data/spec/semipublic/property_spec.rb +524 -9
- data/spec/semipublic/query_spec.rb +6 -6
- data/tasks/hoe.rb +2 -2
- metadata +24 -4
data/lib/dm-core/resource.rb
CHANGED
@@ -21,7 +21,7 @@ module DataMapper
|
|
21
21
|
# @deprecated
|
22
22
|
def self.descendants
|
23
23
|
warn "DataMapper::Resource.descendants is deprecated, use DataMapper::Model.descendants instead (#{caller[0]})"
|
24
|
-
|
24
|
+
Model.descendants
|
25
25
|
end
|
26
26
|
|
27
27
|
# Deprecated API for updating attributes and saving Resource
|
@@ -118,6 +118,16 @@ module DataMapper
|
|
118
118
|
@saved == true
|
119
119
|
end
|
120
120
|
|
121
|
+
# Checks if this Resource instance is destroyed
|
122
|
+
#
|
123
|
+
# @return [Boolean]
|
124
|
+
# true if the resource has been destroyed
|
125
|
+
#
|
126
|
+
# @api public
|
127
|
+
def destroyed?
|
128
|
+
@destroyed == true
|
129
|
+
end
|
130
|
+
|
121
131
|
# Checks if the resource has no changes to save
|
122
132
|
#
|
123
133
|
# @return [Boolean]
|
@@ -283,7 +293,7 @@ module DataMapper
|
|
283
293
|
# @api public
|
284
294
|
def reload
|
285
295
|
if saved?
|
286
|
-
|
296
|
+
eager_load(loaded_properties)
|
287
297
|
child_relationships.each { |relationship| relationship.get!(self).reload }
|
288
298
|
end
|
289
299
|
|
@@ -364,13 +374,13 @@ module DataMapper
|
|
364
374
|
# @api public
|
365
375
|
def destroy!
|
366
376
|
if saved? && repository.delete(Collection.new(query, [ self ])) == 1
|
377
|
+
@destroyed = true
|
367
378
|
@collection.delete(self) if @collection
|
368
379
|
reset
|
369
380
|
freeze
|
370
|
-
true
|
371
|
-
else
|
372
|
-
false
|
373
381
|
end
|
382
|
+
|
383
|
+
destroyed?
|
374
384
|
end
|
375
385
|
|
376
386
|
# Compares another Resource for equality
|
@@ -388,9 +398,7 @@ module DataMapper
|
|
388
398
|
# @api public
|
389
399
|
def eql?(other)
|
390
400
|
return true if equal?(other)
|
391
|
-
|
392
|
-
|
393
|
-
cmp?(other, :eql?)
|
401
|
+
instance_of?(other.class) && cmp?(other, :eql?)
|
394
402
|
end
|
395
403
|
|
396
404
|
# Compares another Resource for equivalency
|
@@ -408,8 +416,8 @@ module DataMapper
|
|
408
416
|
# @api public
|
409
417
|
def ==(other)
|
410
418
|
return true if equal?(other)
|
411
|
-
|
412
|
-
|
419
|
+
other.respond_to?(:model) &&
|
420
|
+
model.base_model.equal?(other.model.base_model) &&
|
413
421
|
cmp?(other, :==)
|
414
422
|
end
|
415
423
|
|
@@ -429,7 +437,7 @@ module DataMapper
|
|
429
437
|
raise ArgumentError, "Cannot compare a #{other.model} instance with a #{model} instance"
|
430
438
|
end
|
431
439
|
cmp = 0
|
432
|
-
model.default_order(repository_name).
|
440
|
+
model.default_order(repository_name).each do |direction|
|
433
441
|
cmp = direction.get(self) <=> direction.get(other)
|
434
442
|
break if cmp != 0
|
435
443
|
end
|
@@ -506,27 +514,6 @@ module DataMapper
|
|
506
514
|
properties[name].loaded?(self)
|
507
515
|
end
|
508
516
|
|
509
|
-
# Fetches all the names of the attributes that have been loaded,
|
510
|
-
# even if they are lazy but have been called
|
511
|
-
#
|
512
|
-
# @example
|
513
|
-
# class Foo
|
514
|
-
# include DataMapper::Resource
|
515
|
-
#
|
516
|
-
# property :name, String
|
517
|
-
# property :description, Text, :lazy => false
|
518
|
-
# end
|
519
|
-
#
|
520
|
-
# Foo.new.loaded_properties #=> [ #<Property @model=Foo @name=:name> ]
|
521
|
-
#
|
522
|
-
# @return [Array(Property)]
|
523
|
-
# names of attributes that have been loaded
|
524
|
-
#
|
525
|
-
# @api private
|
526
|
-
def loaded_properties
|
527
|
-
properties.select { |property| property.loaded?(self) }
|
528
|
-
end
|
529
|
-
|
530
517
|
# Checks if an attribute has unsaved changes
|
531
518
|
#
|
532
519
|
# @param [Symbol] name
|
@@ -690,10 +677,9 @@ module DataMapper
|
|
690
677
|
model.relationships(repository_name)
|
691
678
|
end
|
692
679
|
|
693
|
-
# Returns identity map
|
694
|
-
# was loaded from
|
680
|
+
# Returns the identity map for the model from the repository
|
695
681
|
#
|
696
|
-
# @return [
|
682
|
+
# @return [IdentityMap]
|
697
683
|
# identity map of repository this object was loaded from
|
698
684
|
#
|
699
685
|
# @api semipublic
|
@@ -701,26 +687,41 @@ module DataMapper
|
|
701
687
|
repository.identity_map(model)
|
702
688
|
end
|
703
689
|
|
704
|
-
#
|
705
|
-
#
|
690
|
+
# Fetches all the names of the attributes that have been loaded,
|
691
|
+
# even if they are lazy but have been called
|
692
|
+
#
|
693
|
+
# @return [Array<Property>]
|
694
|
+
# names of attributes that have been loaded
|
706
695
|
#
|
707
696
|
# @api private
|
708
|
-
def
|
709
|
-
|
697
|
+
def loaded_properties
|
698
|
+
properties.select { |property| property.loaded?(self) }
|
699
|
+
end
|
700
|
+
|
701
|
+
# Lazy loads attributes not yet loaded
|
702
|
+
#
|
703
|
+
# @param [Array<Property>] fields
|
704
|
+
# the properties to reload
|
705
|
+
#
|
706
|
+
# @return [self]
|
707
|
+
#
|
708
|
+
# @api private
|
709
|
+
def lazy_load(fields)
|
710
|
+
eager_load(fields - loaded_properties)
|
710
711
|
end
|
711
712
|
|
712
713
|
# Reloads specified attributes
|
713
714
|
#
|
714
|
-
# @param [
|
715
|
-
#
|
715
|
+
# @param [Array<Property>] fields
|
716
|
+
# the properties to reload
|
716
717
|
#
|
717
718
|
# @return [Resource]
|
718
719
|
# the receiver, the current Resource instance
|
719
720
|
#
|
720
721
|
# @api private
|
721
|
-
def
|
722
|
-
unless
|
723
|
-
collection.reload(:fields =>
|
722
|
+
def eager_load(fields)
|
723
|
+
unless fields.empty? || new?
|
724
|
+
collection.reload(:fields => fields)
|
724
725
|
end
|
725
726
|
|
726
727
|
self
|
@@ -751,9 +752,9 @@ module DataMapper
|
|
751
752
|
parent_relationships
|
752
753
|
end
|
753
754
|
|
754
|
-
# Returns
|
755
|
+
# Returns loaded child relationships
|
755
756
|
#
|
756
|
-
# @return [Array<
|
757
|
+
# @return [Array<Associations::OneToMany::Relationship>]
|
757
758
|
# array of child relationships for which this resource is parent and is loaded
|
758
759
|
#
|
759
760
|
# @api private
|
@@ -770,14 +771,13 @@ module DataMapper
|
|
770
771
|
end
|
771
772
|
|
772
773
|
many_to_many, other = child_relationships.partition do |relationship|
|
773
|
-
relationship.kind_of?(
|
774
|
+
relationship.kind_of?(Associations::ManyToMany::Relationship)
|
774
775
|
end
|
775
776
|
|
776
777
|
many_to_many + other
|
777
778
|
end
|
778
779
|
|
779
|
-
#
|
780
|
-
# setting default values for any unset properties
|
780
|
+
# Creates the resource with default values
|
781
781
|
#
|
782
782
|
# If resource is not dirty or a new (not yet saved),
|
783
783
|
# this method returns false
|
@@ -878,6 +878,11 @@ module DataMapper
|
|
878
878
|
|
879
879
|
# Raises an exception if #update is performed on a dirty resource
|
880
880
|
#
|
881
|
+
# @param [Symbol] method
|
882
|
+
# the name of the method to use in the exception
|
883
|
+
#
|
884
|
+
# @return [undefined]
|
885
|
+
#
|
881
886
|
# @raise [UpdateConflictError]
|
882
887
|
# raise if the resource is dirty
|
883
888
|
#
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module DataMapper
|
2
|
+
module Equalizer
|
3
|
+
def equalize(*methods)
|
4
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
5
|
+
def eql?(other)
|
6
|
+
return true if equal?(other)
|
7
|
+
instance_of?(other.class) &&
|
8
|
+
#{methods.map { |method| "#{method}.eql?(other.#{method})" }.join(' && ')}
|
9
|
+
end
|
10
|
+
|
11
|
+
def ==(other)
|
12
|
+
return true if equal?(other)
|
13
|
+
#{methods.map { |method| "other.respond_to?(#{method.inspect})" }.join(' && ')} &&
|
14
|
+
#{methods.map { |method| "#{method} == other.#{method}" }.join(' && ')}
|
15
|
+
end
|
16
|
+
|
17
|
+
def hash
|
18
|
+
[ #{methods.join(', ')} ].hash
|
19
|
+
end
|
20
|
+
RUBY
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/dm-core/types/object.rb
CHANGED
@@ -2,8 +2,8 @@ module DataMapper
|
|
2
2
|
module Types
|
3
3
|
class Object < Type
|
4
4
|
primitive String
|
5
|
-
|
6
|
-
lazy
|
5
|
+
length 65535
|
6
|
+
lazy true
|
7
7
|
|
8
8
|
# TODO: document
|
9
9
|
# @api private
|
@@ -14,13 +14,13 @@ module DataMapper
|
|
14
14
|
# TODO: document
|
15
15
|
# @api private
|
16
16
|
def self.dump(value, property)
|
17
|
-
|
17
|
+
[ Marshal.dump(value) ].pack('m')
|
18
18
|
end
|
19
19
|
|
20
20
|
# TODO: document
|
21
21
|
# @api private
|
22
22
|
def self.load(value, property)
|
23
|
-
|
23
|
+
Marshal.load(value.unpack('m').first) unless value.nil?
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
data/lib/dm-core/version.rb
CHANGED
data/lib/dm-core.rb
CHANGED
@@ -1,13 +1,4 @@
|
|
1
|
-
# This file begins the loading sequence.
|
2
|
-
#
|
3
|
-
# Quick Overview:
|
4
|
-
# * Requires fastthread, support libs, and base.
|
5
|
-
# * Sets the application root and environment for compatibility with frameworks
|
6
|
-
# such as Rails or Merb.
|
7
|
-
#
|
8
|
-
|
9
1
|
require 'addressable/uri'
|
10
|
-
require 'base64'
|
11
2
|
require 'bigdecimal'
|
12
3
|
require 'bigdecimal/util'
|
13
4
|
require 'date'
|
@@ -27,6 +18,7 @@ dir = Pathname(__FILE__).dirname.expand_path / 'dm-core'
|
|
27
18
|
|
28
19
|
require dir / 'support' / 'chainable'
|
29
20
|
require dir / 'support' / 'deprecate'
|
21
|
+
require dir / 'support' / 'equalizer'
|
30
22
|
|
31
23
|
require dir / 'model'
|
32
24
|
require dir / 'model' / 'descendant_set'
|
@@ -117,9 +109,9 @@ DataMapper::Logger.new(StringIO.new, :fatal)
|
|
117
109
|
# === Logging
|
118
110
|
# To turn on error logging to STDOUT, issue:
|
119
111
|
#
|
120
|
-
# DataMapper::Logger.new(
|
112
|
+
# DataMapper::Logger.new($stdout, :debug)
|
121
113
|
#
|
122
|
-
# You can pass a file location ("/path/to/log/file.log") in place of
|
114
|
+
# You can pass a file location ("/path/to/log/file.log") in place of $stdout.
|
123
115
|
# see DataMapper::Logger for more information.
|
124
116
|
#
|
125
117
|
module DataMapper
|
@@ -799,8 +799,8 @@ describe DataMapper::Associations do
|
|
799
799
|
@engine_relationship = ElectricCar.relationships(@repository.name)[:engine]
|
800
800
|
end
|
801
801
|
|
802
|
-
it 'should have a source model equal to the
|
803
|
-
@engine_relationship.source_model.should equal(
|
802
|
+
it 'should have a source model equal to the ancestor' do
|
803
|
+
@engine_relationship.source_model.should equal(Car)
|
804
804
|
end
|
805
805
|
|
806
806
|
it 'should have a child key prefix the same as the inverse relationship' do
|
@@ -823,8 +823,8 @@ describe DataMapper::Associations do
|
|
823
823
|
@engine_relationship = ElectricCar.relationships(@repository.name)[:engine]
|
824
824
|
end
|
825
825
|
|
826
|
-
it 'should have a source model equal to the
|
827
|
-
@engine_relationship.source_model.should equal(
|
826
|
+
it 'should have a source model equal to the ancestor' do
|
827
|
+
@engine_relationship.source_model.should equal(Car)
|
828
828
|
end
|
829
829
|
|
830
830
|
it 'should have a child key prefix inferred from the source model name' do
|