mack-data_mapper 0.8.1 → 0.8.2

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.
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