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.
- data/lib/gems/addressable-2.0.0/lib/addressable/idna.rb +4867 -0
- data/lib/gems/addressable-2.0.0/lib/addressable/uri.rb +2469 -0
- data/lib/gems/addressable-2.0.0/lib/addressable/version.rb +35 -0
- data/lib/gems/dm-aggregates-0.9.7/lib/dm-aggregates/adapters/data_objects_adapter.rb +85 -0
- data/lib/gems/dm-aggregates-0.9.7/lib/dm-aggregates/aggregate_functions.rb +201 -0
- data/lib/gems/dm-aggregates-0.9.7/lib/dm-aggregates/collection.rb +11 -0
- data/lib/gems/dm-aggregates-0.9.7/lib/dm-aggregates/model.rb +11 -0
- data/lib/gems/dm-aggregates-0.9.7/lib/dm-aggregates/repository.rb +7 -0
- data/lib/gems/dm-aggregates-0.9.7/lib/dm-aggregates/support/symbol.rb +21 -0
- data/lib/gems/dm-aggregates-0.9.7/lib/dm-aggregates/version.rb +7 -0
- data/lib/gems/dm-aggregates-0.9.7/lib/dm-aggregates.rb +15 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/adapters/abstract_adapter.rb +209 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/adapters/data_objects_adapter.rb +709 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/adapters/in_memory_adapter.rb +87 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/adapters/mysql_adapter.rb +136 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/adapters/postgres_adapter.rb +188 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/adapters/sqlite3_adapter.rb +105 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/adapters.rb +22 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/associations/many_to_many.rb +147 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/associations/many_to_one.rb +107 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/associations/one_to_many.rb +318 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/associations/one_to_one.rb +61 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/associations/relationship.rb +223 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/associations/relationship_chain.rb +81 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/associations.rb +200 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/auto_migrations.rb +105 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/collection.rb +642 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/dependency_queue.rb +32 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/hook.rb +11 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/identity_map.rb +42 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/is.rb +16 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/logger.rb +232 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/migrations/destructive_migrations.rb +17 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/migrator.rb +29 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/model.rb +488 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/naming_conventions.rb +84 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/property.rb +663 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/property_set.rb +169 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/query.rb +628 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/repository.rb +159 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/resource.rb +637 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/scope.rb +58 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/support/array.rb +13 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/support/assertions.rb +8 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/support/errors.rb +23 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/support/kernel.rb +11 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/support/symbol.rb +41 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/support.rb +7 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/transaction.rb +267 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/type.rb +160 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/type_map.rb +80 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/types/boolean.rb +7 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/types/discriminator.rb +34 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/types/object.rb +24 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/types/paranoid_boolean.rb +34 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/types/paranoid_datetime.rb +33 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/types/serial.rb +9 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/types/text.rb +10 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/types.rb +19 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/version.rb +3 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core.rb +217 -0
- data/lib/gems/dm-core-0.9.7/script/all +5 -0
- data/lib/gems/dm-core-0.9.7/script/performance.rb +284 -0
- data/lib/gems/dm-core-0.9.7/script/profile.rb +87 -0
- data/lib/gems/dm-migrations-0.9.7/lib/dm-migrations/version.rb +5 -0
- data/lib/gems/dm-migrations-0.9.7/lib/dm-migrations.rb +1 -0
- data/lib/gems/dm-migrations-0.9.7/lib/migration.rb +215 -0
- data/lib/gems/dm-migrations-0.9.7/lib/migration_runner.rb +88 -0
- data/lib/gems/dm-migrations-0.9.7/lib/spec/example/migration_example_group.rb +73 -0
- data/lib/gems/dm-migrations-0.9.7/lib/spec/matchers/migration_matchers.rb +107 -0
- data/lib/gems/dm-migrations-0.9.7/lib/sql/column.rb +9 -0
- data/lib/gems/dm-migrations-0.9.7/lib/sql/mysql.rb +52 -0
- data/lib/gems/dm-migrations-0.9.7/lib/sql/postgresql.rb +78 -0
- data/lib/gems/dm-migrations-0.9.7/lib/sql/sqlite3.rb +43 -0
- data/lib/gems/dm-migrations-0.9.7/lib/sql/table.rb +19 -0
- data/lib/gems/dm-migrations-0.9.7/lib/sql/table_creator.rb +81 -0
- data/lib/gems/dm-migrations-0.9.7/lib/sql/table_modifier.rb +53 -0
- data/lib/gems/dm-migrations-0.9.7/lib/sql.rb +10 -0
- data/lib/gems/dm-observer-0.9.7/lib/dm-observer/version.rb +5 -0
- data/lib/gems/dm-observer-0.9.7/lib/dm-observer.rb +91 -0
- data/lib/gems/dm-serializer-0.9.7/lib/dm-serializer/version.rb +5 -0
- data/lib/gems/dm-serializer-0.9.7/lib/dm-serializer.rb +183 -0
- data/lib/gems/dm-timestamps-0.9.7/lib/dm-timestamps/version.rb +5 -0
- data/lib/gems/dm-timestamps-0.9.7/lib/dm-timestamps.rb +57 -0
- data/lib/gems/dm-types-0.9.7/lib/dm-types/bcrypt_hash.rb +31 -0
- data/lib/gems/dm-types-0.9.7/lib/dm-types/csv.rb +28 -0
- data/lib/gems/dm-types-0.9.7/lib/dm-types/enum.rb +70 -0
- data/lib/gems/dm-types-0.9.7/lib/dm-types/epoch_time.rb +27 -0
- data/lib/gems/dm-types-0.9.7/lib/dm-types/file_path.rb +27 -0
- data/lib/gems/dm-types-0.9.7/lib/dm-types/flag.rb +61 -0
- data/lib/gems/dm-types-0.9.7/lib/dm-types/ip_address.rb +30 -0
- data/lib/gems/dm-types-0.9.7/lib/dm-types/json.rb +40 -0
- data/lib/gems/dm-types-0.9.7/lib/dm-types/regexp.rb +20 -0
- data/lib/gems/dm-types-0.9.7/lib/dm-types/serial.rb +8 -0
- data/lib/gems/dm-types-0.9.7/lib/dm-types/slug.rb +37 -0
- data/lib/gems/dm-types-0.9.7/lib/dm-types/uri.rb +29 -0
- data/lib/gems/dm-types-0.9.7/lib/dm-types/uuid.rb +64 -0
- data/lib/gems/dm-types-0.9.7/lib/dm-types/version.rb +5 -0
- data/lib/gems/dm-types-0.9.7/lib/dm-types/yaml.rb +36 -0
- data/lib/gems/dm-types-0.9.7/lib/dm-types.rb +28 -0
- data/lib/gems/dm-validations-0.9.7/lib/dm-validations/absent_field_validator.rb +60 -0
- data/lib/gems/dm-validations-0.9.7/lib/dm-validations/acceptance_validator.rb +76 -0
- data/lib/gems/dm-validations-0.9.7/lib/dm-validations/auto_validate.rb +153 -0
- data/lib/gems/dm-validations-0.9.7/lib/dm-validations/block_validator.rb +60 -0
- data/lib/gems/dm-validations-0.9.7/lib/dm-validations/confirmation_validator.rb +80 -0
- data/lib/gems/dm-validations-0.9.7/lib/dm-validations/contextual_validators.rb +56 -0
- data/lib/gems/dm-validations-0.9.7/lib/dm-validations/custom_validator.rb +72 -0
- data/lib/gems/dm-validations-0.9.7/lib/dm-validations/format_validator.rb +97 -0
- data/lib/gems/dm-validations-0.9.7/lib/dm-validations/formats/email.rb +40 -0
- data/lib/gems/dm-validations-0.9.7/lib/dm-validations/formats/url.rb +20 -0
- data/lib/gems/dm-validations-0.9.7/lib/dm-validations/generic_validator.rb +100 -0
- data/lib/gems/dm-validations-0.9.7/lib/dm-validations/length_validator.rb +113 -0
- data/lib/gems/dm-validations-0.9.7/lib/dm-validations/method_validator.rb +68 -0
- data/lib/gems/dm-validations-0.9.7/lib/dm-validations/numeric_validator.rb +83 -0
- data/lib/gems/dm-validations-0.9.7/lib/dm-validations/primitive_validator.rb +60 -0
- data/lib/gems/dm-validations-0.9.7/lib/dm-validations/required_field_validator.rb +88 -0
- data/lib/gems/dm-validations-0.9.7/lib/dm-validations/support/object.rb +5 -0
- data/lib/gems/dm-validations-0.9.7/lib/dm-validations/uniqueness_validator.rb +64 -0
- data/lib/gems/dm-validations-0.9.7/lib/dm-validations/validation_errors.rb +63 -0
- data/lib/gems/dm-validations-0.9.7/lib/dm-validations/version.rb +5 -0
- data/lib/gems/dm-validations-0.9.7/lib/dm-validations/within_validator.rb +53 -0
- data/lib/gems/dm-validations-0.9.7/lib/dm-validations.rb +234 -0
- data/lib/gems/json_pure-1.1.3/GPL +340 -0
- data/lib/gems/json_pure-1.1.3/VERSION +1 -0
- data/lib/gems/json_pure-1.1.3/bin/edit_json.rb +10 -0
- data/lib/gems/json_pure-1.1.3/bin/prettify_json.rb +76 -0
- data/lib/gems/json_pure-1.1.3/lib/json/Array.xpm +21 -0
- data/lib/gems/json_pure-1.1.3/lib/json/FalseClass.xpm +21 -0
- data/lib/gems/json_pure-1.1.3/lib/json/Hash.xpm +21 -0
- data/lib/gems/json_pure-1.1.3/lib/json/Key.xpm +73 -0
- data/lib/gems/json_pure-1.1.3/lib/json/NilClass.xpm +21 -0
- data/lib/gems/json_pure-1.1.3/lib/json/Numeric.xpm +28 -0
- data/lib/gems/json_pure-1.1.3/lib/json/String.xpm +96 -0
- data/lib/gems/json_pure-1.1.3/lib/json/TrueClass.xpm +21 -0
- data/lib/gems/json_pure-1.1.3/lib/json/add/core.rb +135 -0
- data/lib/gems/json_pure-1.1.3/lib/json/add/rails.rb +58 -0
- data/lib/gems/json_pure-1.1.3/lib/json/common.rb +354 -0
- data/lib/gems/json_pure-1.1.3/lib/json/editor.rb +1362 -0
- data/lib/gems/json_pure-1.1.3/lib/json/ext.rb +13 -0
- data/lib/gems/json_pure-1.1.3/lib/json/json.xpm +1499 -0
- data/lib/gems/json_pure-1.1.3/lib/json/pure/generator.rb +394 -0
- data/lib/gems/json_pure-1.1.3/lib/json/pure/parser.rb +259 -0
- data/lib/gems/json_pure-1.1.3/lib/json/pure.rb +75 -0
- data/lib/gems/json_pure-1.1.3/lib/json/version.rb +9 -0
- data/lib/gems/json_pure-1.1.3/lib/json.rb +235 -0
- data/lib/gems/launchy-0.3.2/bin/launchy +12 -0
- data/lib/gems/launchy-0.3.2/lib/launchy/application.rb +163 -0
- data/lib/gems/launchy-0.3.2/lib/launchy/browser.rb +85 -0
- data/lib/gems/launchy-0.3.2/lib/launchy/command_line.rb +48 -0
- data/lib/gems/launchy-0.3.2/lib/launchy/gemspec.rb +53 -0
- data/lib/gems/launchy-0.3.2/lib/launchy/specification.rb +133 -0
- data/lib/gems/launchy-0.3.2/lib/launchy/version.rb +18 -0
- data/lib/gems/launchy-0.3.2/lib/launchy.rb +58 -0
- data/lib/gems/uuidtools-1.0.3/lib/uuidtools/version.rb +32 -0
- data/lib/gems/uuidtools-1.0.3/lib/uuidtools.rb +648 -0
- data/lib/gems.rb +13 -0
- data/lib/mack-data_mapper/migration_generator/migration_generator.rb +5 -0
- data/lib/mack-data_mapper/migration_generator/templates/db/migrations/%=@migration_name%.rb.template +1 -1
- data/lib/mack-data_mapper/model_generator/manifest.yml +3 -3
- data/lib/mack-data_mapper/model_generator/model_generator.rb +8 -1
- data/lib/mack-data_mapper/model_generator/templates/model.rb.template +1 -1
- data/lib/mack-data_mapper/model_generator/templates/rspec.rb.template +1 -1
- data/lib/mack-data_mapper/model_generator/templates/test_case.rb.template +1 -1
- data/lib/mack-data_mapper.rb +3 -2
- data/lib/mack-data_mapper_tasks.rb +7 -0
- 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
|