mack-data_mapper 0.8.1 → 0.8.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (166) hide show
  1. data/lib/gems/addressable-2.0.0/lib/addressable/idna.rb +4867 -0
  2. data/lib/gems/addressable-2.0.0/lib/addressable/uri.rb +2469 -0
  3. data/lib/gems/addressable-2.0.0/lib/addressable/version.rb +35 -0
  4. data/lib/gems/dm-aggregates-0.9.7/lib/dm-aggregates/adapters/data_objects_adapter.rb +85 -0
  5. data/lib/gems/dm-aggregates-0.9.7/lib/dm-aggregates/aggregate_functions.rb +201 -0
  6. data/lib/gems/dm-aggregates-0.9.7/lib/dm-aggregates/collection.rb +11 -0
  7. data/lib/gems/dm-aggregates-0.9.7/lib/dm-aggregates/model.rb +11 -0
  8. data/lib/gems/dm-aggregates-0.9.7/lib/dm-aggregates/repository.rb +7 -0
  9. data/lib/gems/dm-aggregates-0.9.7/lib/dm-aggregates/support/symbol.rb +21 -0
  10. data/lib/gems/dm-aggregates-0.9.7/lib/dm-aggregates/version.rb +7 -0
  11. data/lib/gems/dm-aggregates-0.9.7/lib/dm-aggregates.rb +15 -0
  12. data/lib/gems/dm-core-0.9.7/lib/dm-core/adapters/abstract_adapter.rb +209 -0
  13. data/lib/gems/dm-core-0.9.7/lib/dm-core/adapters/data_objects_adapter.rb +709 -0
  14. data/lib/gems/dm-core-0.9.7/lib/dm-core/adapters/in_memory_adapter.rb +87 -0
  15. data/lib/gems/dm-core-0.9.7/lib/dm-core/adapters/mysql_adapter.rb +136 -0
  16. data/lib/gems/dm-core-0.9.7/lib/dm-core/adapters/postgres_adapter.rb +188 -0
  17. data/lib/gems/dm-core-0.9.7/lib/dm-core/adapters/sqlite3_adapter.rb +105 -0
  18. data/lib/gems/dm-core-0.9.7/lib/dm-core/adapters.rb +22 -0
  19. data/lib/gems/dm-core-0.9.7/lib/dm-core/associations/many_to_many.rb +147 -0
  20. data/lib/gems/dm-core-0.9.7/lib/dm-core/associations/many_to_one.rb +107 -0
  21. data/lib/gems/dm-core-0.9.7/lib/dm-core/associations/one_to_many.rb +318 -0
  22. data/lib/gems/dm-core-0.9.7/lib/dm-core/associations/one_to_one.rb +61 -0
  23. data/lib/gems/dm-core-0.9.7/lib/dm-core/associations/relationship.rb +223 -0
  24. data/lib/gems/dm-core-0.9.7/lib/dm-core/associations/relationship_chain.rb +81 -0
  25. data/lib/gems/dm-core-0.9.7/lib/dm-core/associations.rb +200 -0
  26. data/lib/gems/dm-core-0.9.7/lib/dm-core/auto_migrations.rb +105 -0
  27. data/lib/gems/dm-core-0.9.7/lib/dm-core/collection.rb +642 -0
  28. data/lib/gems/dm-core-0.9.7/lib/dm-core/dependency_queue.rb +32 -0
  29. data/lib/gems/dm-core-0.9.7/lib/dm-core/hook.rb +11 -0
  30. data/lib/gems/dm-core-0.9.7/lib/dm-core/identity_map.rb +42 -0
  31. data/lib/gems/dm-core-0.9.7/lib/dm-core/is.rb +16 -0
  32. data/lib/gems/dm-core-0.9.7/lib/dm-core/logger.rb +232 -0
  33. data/lib/gems/dm-core-0.9.7/lib/dm-core/migrations/destructive_migrations.rb +17 -0
  34. data/lib/gems/dm-core-0.9.7/lib/dm-core/migrator.rb +29 -0
  35. data/lib/gems/dm-core-0.9.7/lib/dm-core/model.rb +488 -0
  36. data/lib/gems/dm-core-0.9.7/lib/dm-core/naming_conventions.rb +84 -0
  37. data/lib/gems/dm-core-0.9.7/lib/dm-core/property.rb +663 -0
  38. data/lib/gems/dm-core-0.9.7/lib/dm-core/property_set.rb +169 -0
  39. data/lib/gems/dm-core-0.9.7/lib/dm-core/query.rb +628 -0
  40. data/lib/gems/dm-core-0.9.7/lib/dm-core/repository.rb +159 -0
  41. data/lib/gems/dm-core-0.9.7/lib/dm-core/resource.rb +637 -0
  42. data/lib/gems/dm-core-0.9.7/lib/dm-core/scope.rb +58 -0
  43. data/lib/gems/dm-core-0.9.7/lib/dm-core/support/array.rb +13 -0
  44. data/lib/gems/dm-core-0.9.7/lib/dm-core/support/assertions.rb +8 -0
  45. data/lib/gems/dm-core-0.9.7/lib/dm-core/support/errors.rb +23 -0
  46. data/lib/gems/dm-core-0.9.7/lib/dm-core/support/kernel.rb +11 -0
  47. data/lib/gems/dm-core-0.9.7/lib/dm-core/support/symbol.rb +41 -0
  48. data/lib/gems/dm-core-0.9.7/lib/dm-core/support.rb +7 -0
  49. data/lib/gems/dm-core-0.9.7/lib/dm-core/transaction.rb +267 -0
  50. data/lib/gems/dm-core-0.9.7/lib/dm-core/type.rb +160 -0
  51. data/lib/gems/dm-core-0.9.7/lib/dm-core/type_map.rb +80 -0
  52. data/lib/gems/dm-core-0.9.7/lib/dm-core/types/boolean.rb +7 -0
  53. data/lib/gems/dm-core-0.9.7/lib/dm-core/types/discriminator.rb +34 -0
  54. data/lib/gems/dm-core-0.9.7/lib/dm-core/types/object.rb +24 -0
  55. data/lib/gems/dm-core-0.9.7/lib/dm-core/types/paranoid_boolean.rb +34 -0
  56. data/lib/gems/dm-core-0.9.7/lib/dm-core/types/paranoid_datetime.rb +33 -0
  57. data/lib/gems/dm-core-0.9.7/lib/dm-core/types/serial.rb +9 -0
  58. data/lib/gems/dm-core-0.9.7/lib/dm-core/types/text.rb +10 -0
  59. data/lib/gems/dm-core-0.9.7/lib/dm-core/types.rb +19 -0
  60. data/lib/gems/dm-core-0.9.7/lib/dm-core/version.rb +3 -0
  61. data/lib/gems/dm-core-0.9.7/lib/dm-core.rb +217 -0
  62. data/lib/gems/dm-core-0.9.7/script/all +5 -0
  63. data/lib/gems/dm-core-0.9.7/script/performance.rb +284 -0
  64. data/lib/gems/dm-core-0.9.7/script/profile.rb +87 -0
  65. data/lib/gems/dm-migrations-0.9.7/lib/dm-migrations/version.rb +5 -0
  66. data/lib/gems/dm-migrations-0.9.7/lib/dm-migrations.rb +1 -0
  67. data/lib/gems/dm-migrations-0.9.7/lib/migration.rb +215 -0
  68. data/lib/gems/dm-migrations-0.9.7/lib/migration_runner.rb +88 -0
  69. data/lib/gems/dm-migrations-0.9.7/lib/spec/example/migration_example_group.rb +73 -0
  70. data/lib/gems/dm-migrations-0.9.7/lib/spec/matchers/migration_matchers.rb +107 -0
  71. data/lib/gems/dm-migrations-0.9.7/lib/sql/column.rb +9 -0
  72. data/lib/gems/dm-migrations-0.9.7/lib/sql/mysql.rb +52 -0
  73. data/lib/gems/dm-migrations-0.9.7/lib/sql/postgresql.rb +78 -0
  74. data/lib/gems/dm-migrations-0.9.7/lib/sql/sqlite3.rb +43 -0
  75. data/lib/gems/dm-migrations-0.9.7/lib/sql/table.rb +19 -0
  76. data/lib/gems/dm-migrations-0.9.7/lib/sql/table_creator.rb +81 -0
  77. data/lib/gems/dm-migrations-0.9.7/lib/sql/table_modifier.rb +53 -0
  78. data/lib/gems/dm-migrations-0.9.7/lib/sql.rb +10 -0
  79. data/lib/gems/dm-observer-0.9.7/lib/dm-observer/version.rb +5 -0
  80. data/lib/gems/dm-observer-0.9.7/lib/dm-observer.rb +91 -0
  81. data/lib/gems/dm-serializer-0.9.7/lib/dm-serializer/version.rb +5 -0
  82. data/lib/gems/dm-serializer-0.9.7/lib/dm-serializer.rb +183 -0
  83. data/lib/gems/dm-timestamps-0.9.7/lib/dm-timestamps/version.rb +5 -0
  84. data/lib/gems/dm-timestamps-0.9.7/lib/dm-timestamps.rb +57 -0
  85. data/lib/gems/dm-types-0.9.7/lib/dm-types/bcrypt_hash.rb +31 -0
  86. data/lib/gems/dm-types-0.9.7/lib/dm-types/csv.rb +28 -0
  87. data/lib/gems/dm-types-0.9.7/lib/dm-types/enum.rb +70 -0
  88. data/lib/gems/dm-types-0.9.7/lib/dm-types/epoch_time.rb +27 -0
  89. data/lib/gems/dm-types-0.9.7/lib/dm-types/file_path.rb +27 -0
  90. data/lib/gems/dm-types-0.9.7/lib/dm-types/flag.rb +61 -0
  91. data/lib/gems/dm-types-0.9.7/lib/dm-types/ip_address.rb +30 -0
  92. data/lib/gems/dm-types-0.9.7/lib/dm-types/json.rb +40 -0
  93. data/lib/gems/dm-types-0.9.7/lib/dm-types/regexp.rb +20 -0
  94. data/lib/gems/dm-types-0.9.7/lib/dm-types/serial.rb +8 -0
  95. data/lib/gems/dm-types-0.9.7/lib/dm-types/slug.rb +37 -0
  96. data/lib/gems/dm-types-0.9.7/lib/dm-types/uri.rb +29 -0
  97. data/lib/gems/dm-types-0.9.7/lib/dm-types/uuid.rb +64 -0
  98. data/lib/gems/dm-types-0.9.7/lib/dm-types/version.rb +5 -0
  99. data/lib/gems/dm-types-0.9.7/lib/dm-types/yaml.rb +36 -0
  100. data/lib/gems/dm-types-0.9.7/lib/dm-types.rb +28 -0
  101. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/absent_field_validator.rb +60 -0
  102. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/acceptance_validator.rb +76 -0
  103. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/auto_validate.rb +153 -0
  104. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/block_validator.rb +60 -0
  105. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/confirmation_validator.rb +80 -0
  106. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/contextual_validators.rb +56 -0
  107. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/custom_validator.rb +72 -0
  108. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/format_validator.rb +97 -0
  109. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/formats/email.rb +40 -0
  110. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/formats/url.rb +20 -0
  111. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/generic_validator.rb +100 -0
  112. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/length_validator.rb +113 -0
  113. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/method_validator.rb +68 -0
  114. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/numeric_validator.rb +83 -0
  115. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/primitive_validator.rb +60 -0
  116. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/required_field_validator.rb +88 -0
  117. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/support/object.rb +5 -0
  118. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/uniqueness_validator.rb +64 -0
  119. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/validation_errors.rb +63 -0
  120. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/version.rb +5 -0
  121. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/within_validator.rb +53 -0
  122. data/lib/gems/dm-validations-0.9.7/lib/dm-validations.rb +234 -0
  123. data/lib/gems/json_pure-1.1.3/GPL +340 -0
  124. data/lib/gems/json_pure-1.1.3/VERSION +1 -0
  125. data/lib/gems/json_pure-1.1.3/bin/edit_json.rb +10 -0
  126. data/lib/gems/json_pure-1.1.3/bin/prettify_json.rb +76 -0
  127. data/lib/gems/json_pure-1.1.3/lib/json/Array.xpm +21 -0
  128. data/lib/gems/json_pure-1.1.3/lib/json/FalseClass.xpm +21 -0
  129. data/lib/gems/json_pure-1.1.3/lib/json/Hash.xpm +21 -0
  130. data/lib/gems/json_pure-1.1.3/lib/json/Key.xpm +73 -0
  131. data/lib/gems/json_pure-1.1.3/lib/json/NilClass.xpm +21 -0
  132. data/lib/gems/json_pure-1.1.3/lib/json/Numeric.xpm +28 -0
  133. data/lib/gems/json_pure-1.1.3/lib/json/String.xpm +96 -0
  134. data/lib/gems/json_pure-1.1.3/lib/json/TrueClass.xpm +21 -0
  135. data/lib/gems/json_pure-1.1.3/lib/json/add/core.rb +135 -0
  136. data/lib/gems/json_pure-1.1.3/lib/json/add/rails.rb +58 -0
  137. data/lib/gems/json_pure-1.1.3/lib/json/common.rb +354 -0
  138. data/lib/gems/json_pure-1.1.3/lib/json/editor.rb +1362 -0
  139. data/lib/gems/json_pure-1.1.3/lib/json/ext.rb +13 -0
  140. data/lib/gems/json_pure-1.1.3/lib/json/json.xpm +1499 -0
  141. data/lib/gems/json_pure-1.1.3/lib/json/pure/generator.rb +394 -0
  142. data/lib/gems/json_pure-1.1.3/lib/json/pure/parser.rb +259 -0
  143. data/lib/gems/json_pure-1.1.3/lib/json/pure.rb +75 -0
  144. data/lib/gems/json_pure-1.1.3/lib/json/version.rb +9 -0
  145. data/lib/gems/json_pure-1.1.3/lib/json.rb +235 -0
  146. data/lib/gems/launchy-0.3.2/bin/launchy +12 -0
  147. data/lib/gems/launchy-0.3.2/lib/launchy/application.rb +163 -0
  148. data/lib/gems/launchy-0.3.2/lib/launchy/browser.rb +85 -0
  149. data/lib/gems/launchy-0.3.2/lib/launchy/command_line.rb +48 -0
  150. data/lib/gems/launchy-0.3.2/lib/launchy/gemspec.rb +53 -0
  151. data/lib/gems/launchy-0.3.2/lib/launchy/specification.rb +133 -0
  152. data/lib/gems/launchy-0.3.2/lib/launchy/version.rb +18 -0
  153. data/lib/gems/launchy-0.3.2/lib/launchy.rb +58 -0
  154. data/lib/gems/uuidtools-1.0.3/lib/uuidtools/version.rb +32 -0
  155. data/lib/gems/uuidtools-1.0.3/lib/uuidtools.rb +648 -0
  156. data/lib/gems.rb +13 -0
  157. data/lib/mack-data_mapper/migration_generator/migration_generator.rb +5 -0
  158. data/lib/mack-data_mapper/migration_generator/templates/db/migrations/%=@migration_name%.rb.template +1 -1
  159. data/lib/mack-data_mapper/model_generator/manifest.yml +3 -3
  160. data/lib/mack-data_mapper/model_generator/model_generator.rb +8 -1
  161. data/lib/mack-data_mapper/model_generator/templates/model.rb.template +1 -1
  162. data/lib/mack-data_mapper/model_generator/templates/rspec.rb.template +1 -1
  163. data/lib/mack-data_mapper/model_generator/templates/test_case.rb.template +1 -1
  164. data/lib/mack-data_mapper.rb +3 -2
  165. data/lib/mack-data_mapper_tasks.rb +7 -0
  166. metadata +235 -86
@@ -0,0 +1,81 @@
1
+ module DataMapper
2
+ module Associations
3
+ class RelationshipChain < Relationship
4
+ OPTIONS = [
5
+ :repository_name, :near_relationship_name, :remote_relationship_name,
6
+ :child_model, :parent_model, :parent_key, :child_key,
7
+ :min, :max
8
+ ]
9
+
10
+ undef_method :get_parent
11
+ undef_method :attach_parent
12
+
13
+ # @api private
14
+ def child_model
15
+ near_relationship.child_model
16
+ end
17
+
18
+ # @api private
19
+ def get_children(parent, options = {}, finder = :all, *args)
20
+ query = @query.merge(options).merge(child_key.to_query(parent_key.get(parent)))
21
+
22
+ query[:links] = links
23
+ query[:unique] = true
24
+
25
+ with_repository(parent) do
26
+ results = grandchild_model.send(finder, *(args << query))
27
+ # FIXME: remove the need for the uniq.freeze
28
+ finder == :all ? (@mutable ? results : results.freeze) : results
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ # @api private
35
+ def initialize(options)
36
+ if (missing_options = OPTIONS - [ :min, :max ] - options.keys ).any?
37
+ raise ArgumentError, "The options #{missing_options * ', '} are required", caller
38
+ end
39
+
40
+ @repository_name = options.fetch(:repository_name)
41
+ @near_relationship_name = options.fetch(:near_relationship_name)
42
+ @remote_relationship_name = options.fetch(:remote_relationship_name)
43
+ @child_model = options.fetch(:child_model)
44
+ @parent_model = options.fetch(:parent_model)
45
+ @parent_properties = options.fetch(:parent_key)
46
+ @child_properties = options.fetch(:child_key)
47
+ @mutable = options.delete(:mutable) || false
48
+
49
+ @name = near_relationship.name
50
+ @query = options.reject{ |key,val| OPTIONS.include?(key) }
51
+ @extra_links = []
52
+ @options = options
53
+ end
54
+
55
+ # @api private
56
+ def near_relationship
57
+ parent_model.relationships[@near_relationship_name]
58
+ end
59
+
60
+ # @api private
61
+ def links
62
+ if remote_relationship.kind_of?(RelationshipChain)
63
+ remote_relationship.instance_eval { links } + [remote_relationship.instance_eval { near_relationship } ]
64
+ else
65
+ [ remote_relationship ]
66
+ end
67
+ end
68
+
69
+ # @api private
70
+ def remote_relationship
71
+ near_relationship.child_model.relationships[@remote_relationship_name] ||
72
+ near_relationship.child_model.relationships[@remote_relationship_name.to_s.singularize.to_sym]
73
+ end
74
+
75
+ # @api private
76
+ def grandchild_model
77
+ Class === @child_model ? @child_model : (Class === @parent_model ? @parent_model.find_const(@child_model) : Object.find_const(@child_model))
78
+ end
79
+ end # class Relationship
80
+ end # module Associations
81
+ end # module DataMapper
@@ -0,0 +1,200 @@
1
+ dir = Pathname(__FILE__).dirname.expand_path / 'associations'
2
+
3
+ require dir / 'relationship'
4
+ require dir / 'relationship_chain'
5
+ require dir / 'many_to_many'
6
+ require dir / 'many_to_one'
7
+ require dir / 'one_to_many'
8
+ require dir / 'one_to_one'
9
+
10
+ module DataMapper
11
+ module Associations
12
+ include Assertions
13
+
14
+ class ImmutableAssociationError < RuntimeError
15
+ end
16
+
17
+ class UnsavedParentError < RuntimeError
18
+ end
19
+
20
+ # Returns all relationships that are many-to-one for this model.
21
+ #
22
+ # Used to find the relationships that require properties in any Repository.
23
+ #
24
+ # Example:
25
+ # class Plur
26
+ # include DataMapper::Resource
27
+ # def self.default_repository_name
28
+ # :plur_db
29
+ # end
30
+ # repository(:plupp_db) do
31
+ # has 1, :plupp
32
+ # end
33
+ # end
34
+ #
35
+ # This resource has a many-to-one to the Plupp resource residing in the :plupp_db repository,
36
+ # but the Plur resource needs the plupp_id property no matter what repository itself lives in,
37
+ # ie we need to create that property when we migrate etc.
38
+ #
39
+ # Used in DataMapper::Model.properties_with_subclasses
40
+ #
41
+ # @api private
42
+ def many_to_one_relationships
43
+ relationships unless @relationships # needs to be initialized!
44
+ @relationships.values.collect do |rels| rels.values end.flatten.select do |relationship| relationship.child_model == self end
45
+ end
46
+
47
+ def relationships(repository_name = default_repository_name)
48
+ @relationships ||= {}
49
+ @relationships[repository_name] ||= repository_name == Repository.default_name ? {} : relationships(Repository.default_name).dup
50
+ end
51
+
52
+ def n
53
+ 1.0/0
54
+ end
55
+
56
+ ##
57
+ # A shorthand, clear syntax for defining one-to-one, one-to-many and
58
+ # many-to-many resource relationships.
59
+ #
60
+ # @example [Usage]
61
+ # * has 1, :friend # one friend
62
+ # * has n, :friends # many friends
63
+ # * has 1..3, :friends
64
+ # # many friends (at least 1, at most 3)
65
+ # * has 3, :friends
66
+ # # many friends (exactly 3)
67
+ # * has 1, :friend, :class_name => 'User'
68
+ # # one friend with the class name User
69
+ # * has 3, :friends, :through => :friendships
70
+ # # many friends through the friendships relationship
71
+ # * has n, :friendships => :friends
72
+ # # identical to above example
73
+ #
74
+ # @param cardinality [Integer, Range, Infinity]
75
+ # cardinality that defines the association type and constraints
76
+ # @param name <Symbol> the name that the association will be referenced by
77
+ # @param opts <Hash> an options hash
78
+ #
79
+ # @option :through[Symbol] A association that this join should go through to form
80
+ # a many-to-many association
81
+ # @option :class_name[String] The name of the class to associate with, if omitted
82
+ # then the association name is assumed to match the class name
83
+ # @option :remote_name[Symbol] In the case of a :through option being present, the
84
+ # name of the relationship on the other end of the :through-relationship
85
+ # to be linked to this relationship.
86
+ #
87
+ # @return [DataMapper::Association::Relationship] the relationship that was
88
+ # created to reflect either a one-to-one, one-to-many or many-to-many
89
+ # relationship
90
+ # @raise [ArgumentError] if the cardinality was not understood. Should be a
91
+ # Integer, Range or Infinity(n)
92
+ #
93
+ # @api public
94
+ def has(cardinality, name, options = {})
95
+
96
+ # NOTE: the reason for this fix is that with the ability to pass in two
97
+ # hashes into has() there might be instances where people attempt to
98
+ # pass in the options into the name part and not know why things aren't
99
+ # working for them.
100
+ if name.kind_of?(Hash)
101
+ name_through, through = name.keys.first, name.values.first
102
+ cardinality_string = cardinality.to_s == 'Infinity' ? 'n' : cardinality.inspect
103
+ warn("In #{self.name} 'has #{cardinality_string}, #{name_through.inspect} => #{through.inspect}' is deprecated. Use 'has #{cardinality_string}, #{name_through.inspect}, :through => #{through.inspect}' instead")
104
+ end
105
+
106
+ options = options.merge(extract_min_max(cardinality))
107
+ options = options.merge(extract_throughness(name))
108
+
109
+ # do not remove this. There is alot of confusion on people's
110
+ # part about what the first argument to has() is. For the record it
111
+ # is the min cardinality and max cardinality of the association.
112
+ # simply put, it constraints the number of resources that will be
113
+ # returned by the association. It is not, as has been assumed,
114
+ # the number of results on the left and right hand side of the
115
+ # reltionship.
116
+ if options[:min] == n && options[:max] == n
117
+ raise ArgumentError, 'Cardinality may not be n..n. The cardinality specifies the min/max number of results from the association', caller
118
+ end
119
+
120
+ klass = options[:max] == 1 ? OneToOne : OneToMany
121
+ klass = ManyToMany if options[:through] == DataMapper::Resource
122
+ relationship = klass.setup(options.delete(:name), self, options)
123
+
124
+ # Please leave this in - I will release contextual serialization soon
125
+ # which requires this -- guyvdb
126
+ # TODO convert this to a hook in the plugin once hooks work on class
127
+ # methods
128
+ self.init_has_relationship_for_serialization(relationship) if self.respond_to?(:init_has_relationship_for_serialization)
129
+
130
+ relationship
131
+ end
132
+
133
+ ##
134
+ # A shorthand, clear syntax for defining many-to-one resource relationships.
135
+ #
136
+ # @example [Usage]
137
+ # * belongs_to :user # many_to_one, :friend
138
+ # * belongs_to :friend, :class_name => 'User' # many_to_one :friends
139
+ #
140
+ # @param name [Symbol] The name that the association will be referenced by
141
+ # @see #has
142
+ #
143
+ # @return [DataMapper::Association::ManyToOne] The association created
144
+ # should not be accessed directly
145
+ #
146
+ # @api public
147
+ def belongs_to(name, options={})
148
+ @_valid_relations = false
149
+ relationship = ManyToOne.setup(name, self, options)
150
+ # Please leave this in - I will release contextual serialization soon
151
+ # which requires this -- guyvdb
152
+ # TODO convert this to a hook in the plugin once hooks work on class
153
+ # methods
154
+ self.init_belongs_relationship_for_serialization(relationship) if self.respond_to?(:init_belongs_relationship_for_serialization)
155
+
156
+ relationship
157
+ end
158
+
159
+ private
160
+
161
+ def extract_throughness(name)
162
+ assert_kind_of 'name', name, Hash, Symbol
163
+
164
+ case name
165
+ when Hash
166
+ unless name.keys.size == 1
167
+ raise ArgumentError, "name must have only one key, but had #{name.keys.size}", caller(2)
168
+ end
169
+
170
+ { :name => name.keys.first, :through => name.values.first }
171
+ when Symbol
172
+ { :name => name }
173
+ end
174
+ end
175
+
176
+ # A support method form converting Integer, Range or Infinity values into a
177
+ # { :min => x, :max => y } hash.
178
+ #
179
+ # @api private
180
+ def extract_min_max(constraints)
181
+ assert_kind_of 'constraints', constraints, Integer, Range unless constraints == n
182
+
183
+ case constraints
184
+ when Integer
185
+ { :min => constraints, :max => constraints }
186
+ when Range
187
+ if constraints.first > constraints.last
188
+ raise ArgumentError, "Constraint min (#{constraints.first}) cannot be larger than the max (#{constraints.last})"
189
+ end
190
+
191
+ { :min => constraints.first, :max => constraints.last }
192
+ when n
193
+ { :min => 0, :max => n }
194
+ end
195
+ end
196
+ end # module Associations
197
+
198
+ Model.append_extensions DataMapper::Associations
199
+
200
+ end # module DataMapper
@@ -0,0 +1,105 @@
1
+ # TODO: move to dm-more/dm-migrations
2
+
3
+ module DataMapper
4
+ class AutoMigrator
5
+ ##
6
+ # Destructively automigrates the data-store to match the model.
7
+ # First migrates all models down and then up.
8
+ # REPEAT: THIS IS DESTRUCTIVE
9
+ #
10
+ # @param Symbol repository_name the repository to be migrated
11
+ def self.auto_migrate(repository_name = nil, *descendants)
12
+ auto_migrate_down(repository_name, *descendants)
13
+ auto_migrate_up(repository_name, *descendants)
14
+ end
15
+
16
+ ##
17
+ # Destructively automigrates the data-store down
18
+ # REPEAT: THIS IS DESTRUCTIVE
19
+ #
20
+ # @param Symbol repository_name the repository to be migrated
21
+ # @calls DataMapper::Resource#auto_migrate_down!
22
+ # @api private
23
+ def self.auto_migrate_down(repository_name = nil, *descendants)
24
+ descendants = DataMapper::Resource.descendants.to_a if descendants.empty?
25
+ descendants.reverse.each do |model|
26
+ model.auto_migrate_down!(repository_name)
27
+ end
28
+ end
29
+
30
+ ##
31
+ # Automigrates the data-store up
32
+ #
33
+ # @param Symbol repository_name the repository to be migrated
34
+ # @calls DataMapper::Resource#auto_migrate_up!
35
+ # @api private
36
+ def self.auto_migrate_up(repository_name = nil, *descendants)
37
+ descendants = DataMapper::Resource.descendants.to_a if descendants.empty?
38
+ descendants.each do |model|
39
+ model.auto_migrate_up!(repository_name)
40
+ end
41
+ end
42
+
43
+ ##
44
+ # Safely migrates the data-store to match the model
45
+ # preserving data already in the data-store
46
+ #
47
+ # @param Symbol repository_name the repository to be migrated
48
+ # @calls DataMapper::Resource#auto_upgrade!
49
+ def self.auto_upgrade(repository_name = nil)
50
+ DataMapper::Resource.descendants.each do |model|
51
+ model.auto_upgrade!(repository_name)
52
+ end
53
+ end
54
+ end # class AutoMigrator
55
+
56
+ module AutoMigrations
57
+ ##
58
+ # Destructively automigrates the data-store to match the model
59
+ # REPEAT: THIS IS DESTRUCTIVE
60
+ #
61
+ # @param Symbol repository_name the repository to be migrated
62
+ def auto_migrate!(repository_name = self.repository_name)
63
+ auto_migrate_down!(repository_name)
64
+ auto_migrate_up!(repository_name)
65
+ end
66
+
67
+ ##
68
+ # Destructively migrates the data-store down, which basically
69
+ # deletes all the models.
70
+ # REPEAT: THIS IS DESTRUCTIVE
71
+ #
72
+ # @param Symbol repository_name the repository to be migrated
73
+ # @api private
74
+ def auto_migrate_down!(repository_name = self.repository_name)
75
+ # repository_name ||= default_repository_name
76
+ repository(repository_name) do |r|
77
+ r.adapter.destroy_model_storage(r, self.base_model)
78
+ end
79
+ end
80
+
81
+ ##
82
+ # Auto migrates the data-store to match the model
83
+ #
84
+ # @param Symbol repository_name the repository to be migrated
85
+ # @api private
86
+ def auto_migrate_up!(repository_name = self.repository_name)
87
+ repository(repository_name) do |r|
88
+ r.adapter.create_model_storage(r, self.base_model)
89
+ end
90
+ end
91
+
92
+ ##
93
+ # Safely migrates the data-store to match the model
94
+ # preserving data already in the data-store
95
+ #
96
+ # @param Symbol repository_name the repository to be migrated
97
+ def auto_upgrade!(repository_name = self.repository_name)
98
+ repository(repository_name) do |r|
99
+ r.adapter.upgrade_model_storage(r, self)
100
+ end
101
+ end
102
+
103
+ Model.send(:include, self)
104
+ end # module AutoMigrations
105
+ end # module DataMapper