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,23 @@
1
+ #Some useful errors types
2
+ module DataMapper
3
+ class ValidationError < StandardError; end
4
+
5
+ class ObjectNotFoundError < StandardError; end
6
+
7
+ class MaterializationError < StandardError; end
8
+
9
+ class RepositoryNotSetupError < StandardError; end
10
+
11
+ class IncompleteResourceError < StandardError; end
12
+
13
+ class PersistenceError < StandardError; end
14
+
15
+ class PluginNotFoundError < StandardError; end
16
+ end # module DataMapper
17
+
18
+ class StandardError
19
+ # Displays the specific error message and the backtrace associated with it.
20
+ def display
21
+ "#{message}\n\t#{backtrace.join("\n\t")}"
22
+ end
23
+ end # class StandardError
@@ -0,0 +1,11 @@
1
+ module Kernel
2
+ # Delegates to DataMapper::repository.
3
+ # Will not overwrite if a method of the same name is pre-defined.
4
+ def repository(*args)
5
+ if block_given?
6
+ DataMapper.repository(*args) { |*block_args| yield(*block_args) }
7
+ else
8
+ DataMapper.repository(*args)
9
+ end
10
+ end
11
+ end # module Kernel
@@ -0,0 +1,41 @@
1
+ class Symbol
2
+ def gt
3
+ DataMapper::Query::Operator.new(self, :gt)
4
+ end
5
+
6
+ def gte
7
+ DataMapper::Query::Operator.new(self, :gte)
8
+ end
9
+
10
+ def lt
11
+ DataMapper::Query::Operator.new(self, :lt)
12
+ end
13
+
14
+ def lte
15
+ DataMapper::Query::Operator.new(self, :lte)
16
+ end
17
+
18
+ def not
19
+ DataMapper::Query::Operator.new(self, :not)
20
+ end
21
+
22
+ def eql
23
+ DataMapper::Query::Operator.new(self, :eql)
24
+ end
25
+
26
+ def like
27
+ DataMapper::Query::Operator.new(self, :like)
28
+ end
29
+
30
+ def in
31
+ DataMapper::Query::Operator.new(self, :in)
32
+ end
33
+
34
+ def asc
35
+ DataMapper::Query::Operator.new(self, :asc)
36
+ end
37
+
38
+ def desc
39
+ DataMapper::Query::Operator.new(self, :desc)
40
+ end
41
+ end # class Symbol
@@ -0,0 +1,7 @@
1
+ dir = Pathname(__FILE__).dirname.expand_path / 'support'
2
+
3
+ require dir / 'array'
4
+ require dir / 'assertions'
5
+ require dir / 'errors'
6
+ require dir / 'kernel'
7
+ require dir / 'symbol'
@@ -0,0 +1,267 @@
1
+ # TODO: move to dm-more/dm-transactions
2
+
3
+ module DataMapper
4
+ class Transaction
5
+
6
+ attr_reader :transaction_primitives, :adapters, :state
7
+
8
+ #
9
+ # Create a new DataMapper::Transaction
10
+ #
11
+ # @see DataMapper::Transaction#link
12
+ #
13
+ # In fact, it just calls #link with the given arguments at the end of the
14
+ # constructor.
15
+ #
16
+ def initialize(*things)
17
+ @transaction_primitives = {}
18
+ @state = :none
19
+ @adapters = {}
20
+ link(*things)
21
+ commit { |*block_args| yield(*block_args) } if block_given?
22
+ end
23
+
24
+ #
25
+ # Associate this Transaction with some things.
26
+ #
27
+ # @param things<any number of Object> the things you want this Transaction
28
+ # associated with
29
+ # @details [things a Transaction may be associatied with]
30
+ # DataMapper::Adapters::AbstractAdapter subclasses will be added as
31
+ # adapters as is.
32
+ # Arrays will have their elements added.
33
+ # DataMapper::Repositories will have their @adapters added.
34
+ # DataMapper::Resource subclasses will have all the repositories of all
35
+ # their properties added.
36
+ # DataMapper::Resource instances will have all repositories of all their
37
+ # properties added.
38
+ # @param block<Block> a block (taking one argument, the Transaction) to execute
39
+ # within this transaction. The transaction will begin and commit around
40
+ # the block, and rollback if an exception is raised.
41
+ #
42
+ def link(*things)
43
+ raise "Illegal state for link: #{@state}" unless @state == :none
44
+ things.each do |thing|
45
+ if thing.is_a?(Array)
46
+ link(*thing)
47
+ elsif thing.is_a?(DataMapper::Adapters::AbstractAdapter)
48
+ @adapters[thing] = :none
49
+ elsif thing.is_a?(DataMapper::Repository)
50
+ link(thing.adapter)
51
+ elsif thing.is_a?(Class) && thing.ancestors.include?(DataMapper::Resource)
52
+ link(*thing.repositories)
53
+ elsif thing.is_a?(DataMapper::Resource)
54
+ link(thing.model)
55
+ else
56
+ raise "Unknown argument to #{self}#link: #{thing.inspect}"
57
+ end
58
+ end
59
+ return commit { |*block_args| yield(*block_args) } if block_given?
60
+ return self
61
+ end
62
+
63
+ #
64
+ # Begin the transaction
65
+ #
66
+ # Before #begin is called, the transaction is not valid and can not be used.
67
+ #
68
+ def begin
69
+ raise "Illegal state for begin: #{@state}" unless @state == :none
70
+ each_adapter(:connect_adapter, [:log_fatal_transaction_breakage])
71
+ each_adapter(:begin_adapter, [:rollback_and_close_adapter_if_begin, :close_adapter_if_none])
72
+ @state = :begin
73
+ end
74
+
75
+ #
76
+ # Commit the transaction
77
+ #
78
+ # @param block<Block> a block (taking the one argument, the Transaction) to
79
+ # execute within this transaction. The transaction will begin and commit
80
+ # around the block, and roll back if an exception is raised.
81
+ #
82
+ # @note
83
+ # If no block is given, it will simply commit any changes made since the
84
+ # Transaction did #begin.
85
+ #
86
+ def commit
87
+ if block_given?
88
+ raise "Illegal state for commit with block: #{@state}" unless @state == :none
89
+ begin
90
+ self.begin
91
+ rval = within { |*block_args| yield(*block_args) }
92
+ self.commit if @state == :begin
93
+ return rval
94
+ rescue Exception => e
95
+ self.rollback if @state == :begin
96
+ raise e
97
+ end
98
+ else
99
+ raise "Illegal state for commit without block: #{@state}" unless @state == :begin
100
+ each_adapter(:prepare_adapter, [:rollback_and_close_adapter_if_begin, :rollback_prepared_and_close_adapter_if_prepare])
101
+ each_adapter(:commit_adapter, [:log_fatal_transaction_breakage])
102
+ each_adapter(:close_adapter, [:log_fatal_transaction_breakage])
103
+ @state = :commit
104
+ end
105
+ end
106
+
107
+ #
108
+ # Rollback the transaction
109
+ #
110
+ # Will undo all changes made during the transaction.
111
+ #
112
+ def rollback
113
+ raise "Illegal state for rollback: #{@state}" unless @state == :begin
114
+ each_adapter(:rollback_adapter_if_begin, [:rollback_and_close_adapter_if_begin, :close_adapter_if_none])
115
+ each_adapter(:rollback_prepared_adapter_if_prepare, [:rollback_prepared_and_close_adapter_if_begin, :close_adapter_if_none])
116
+ each_adapter(:close_adapter_if_open, [:log_fatal_transaction_breakage])
117
+ @state = :rollback
118
+ end
119
+
120
+ #
121
+ # Execute a block within this Transaction.
122
+ #
123
+ # @param block<Block> the block of code to execute.
124
+ #
125
+ # @note
126
+ # No #begin, #commit or #rollback is performed in #within, but this
127
+ # Transaction will pushed on the per thread stack of transactions for each
128
+ # adapter it is associated with, and it will ensures that it will pop the
129
+ # Transaction away again after the block is finished.
130
+ #
131
+ def within
132
+ raise "No block provided" unless block_given?
133
+ raise "Illegal state for within: #{@state}" unless @state == :begin
134
+ @adapters.each do |adapter, state|
135
+ adapter.push_transaction(self)
136
+ end
137
+ begin
138
+ return yield(self)
139
+ ensure
140
+ @adapters.each do |adapter, state|
141
+ adapter.pop_transaction
142
+ end
143
+ end
144
+ end
145
+
146
+ def method_missing(meth, *args, &block)
147
+ if args.size == 1 && args.first.is_a?(DataMapper::Adapters::AbstractAdapter)
148
+ if (match = meth.to_s.match(/^(.*)_if_(none|begin|prepare|rollback|commit)$/))
149
+ if self.respond_to?(match[1], true)
150
+ self.send(match[1], args.first) if state_for(args.first).to_s == match[2]
151
+ else
152
+ super
153
+ end
154
+ elsif (match = meth.to_s.match(/^(.*)_unless_(none|begin|prepare|rollback|commit)$/))
155
+ if self.respond_to?(match[1], true)
156
+ self.send(match[1], args.first) unless state_for(args.first).to_s == match[2]
157
+ else
158
+ super
159
+ end
160
+ else
161
+ super
162
+ end
163
+ else
164
+ super
165
+ end
166
+ end
167
+
168
+ def primitive_for(adapter)
169
+ raise "Unknown adapter #{adapter}" unless @adapters.include?(adapter)
170
+ raise "No primitive for #{adapter}" unless @transaction_primitives.include?(adapter)
171
+ @transaction_primitives[adapter]
172
+ end
173
+
174
+ private
175
+
176
+ def validate_primitive(primitive)
177
+ [:close, :begin, :prepare, :rollback, :rollback_prepared, :commit].each do |meth|
178
+ raise "Invalid primitive #{primitive}: doesnt respond_to?(#{meth.inspect})" unless primitive.respond_to?(meth)
179
+ end
180
+ return primitive
181
+ end
182
+
183
+ def each_adapter(method, on_fail)
184
+ begin
185
+ @adapters.each do |adapter, state|
186
+ self.send(method, adapter)
187
+ end
188
+ rescue Exception => e
189
+ @adapters.each do |adapter, state|
190
+ on_fail.each do |fail_handler|
191
+ begin
192
+ self.send(fail_handler, adapter)
193
+ rescue Exception => e2
194
+ DataMapper.logger.fatal("#{self}#each_adapter(#{method.inspect}, #{on_fail.inspect}) failed with #{e.inspect}: #{e.backtrace.join("\n")} - and when sending #{fail_handler} to #{adapter} we failed again with #{e2.inspect}: #{e2.backtrace.join("\n")}")
195
+ end
196
+ end
197
+ end
198
+ raise e
199
+ end
200
+ end
201
+
202
+ def state_for(adapter)
203
+ raise "Unknown adapter #{adapter}" unless @adapters.include?(adapter)
204
+ @adapters[adapter]
205
+ end
206
+
207
+ def do_adapter(adapter, what, prerequisite)
208
+ raise "No primitive for #{adapter}" unless @transaction_primitives.include?(adapter)
209
+ raise "Illegal state for #{what}: #{state_for(adapter)}" unless state_for(adapter) == prerequisite
210
+ DataMapper.logger.debug("#{adapter.name}: #{what}")
211
+ @transaction_primitives[adapter].send(what)
212
+ @adapters[adapter] = what
213
+ end
214
+
215
+ def log_fatal_transaction_breakage(adapter)
216
+ DataMapper.logger.fatal("#{self} experienced a totally broken transaction execution. Presenting member #{adapter.inspect}.")
217
+ end
218
+
219
+ def connect_adapter(adapter)
220
+ raise "Already a primitive for adapter #{adapter}" unless @transaction_primitives[adapter].nil?
221
+ @transaction_primitives[adapter] = validate_primitive(adapter.transaction_primitive)
222
+ end
223
+
224
+ def close_adapter_if_open(adapter)
225
+ if @transaction_primitives.include?(adapter)
226
+ close_adapter(adapter)
227
+ end
228
+ end
229
+
230
+ def close_adapter(adapter)
231
+ raise "No primitive for adapter" unless @transaction_primitives.include?(adapter)
232
+ @transaction_primitives[adapter].close
233
+ @transaction_primitives.delete(adapter)
234
+ end
235
+
236
+ def begin_adapter(adapter)
237
+ do_adapter(adapter, :begin, :none)
238
+ end
239
+
240
+ def prepare_adapter(adapter)
241
+ do_adapter(adapter, :prepare, :begin);
242
+ end
243
+
244
+ def commit_adapter(adapter)
245
+ do_adapter(adapter, :commit, :prepare)
246
+ end
247
+
248
+ def rollback_adapter(adapter)
249
+ do_adapter(adapter, :rollback, :begin)
250
+ end
251
+
252
+ def rollback_prepared_adapter(adapter)
253
+ do_adapter(adapter, :rollback_prepared, :prepare)
254
+ end
255
+
256
+ def rollback_prepared_and_close_adapter(adapter)
257
+ rollback_prepared_adapter(adapter)
258
+ close_adapter(adapter)
259
+ end
260
+
261
+ def rollback_and_close_adapter(adapter)
262
+ rollback_adapter(adapter)
263
+ close_adapter(adapter)
264
+ end
265
+
266
+ end # class Transaction
267
+ end # module DataMapper
@@ -0,0 +1,160 @@
1
+ module DataMapper
2
+
3
+ # = Types
4
+ # Provides means of writing custom types for properties. Each type is based
5
+ # on a ruby primitive and handles its own serialization and materialization,
6
+ # and therefore is responsible for providing those methods.
7
+ #
8
+ # To see complete list of supported types, see documentation for
9
+ # DataMapper::Property::TYPES
10
+ #
11
+ # == Defining new Types
12
+ # To define a new type, subclass DataMapper::Type, pick ruby primitive, and
13
+ # set the options for this type.
14
+ #
15
+ # class MyType < DataMapper::Type
16
+ # primitive String
17
+ # size 10
18
+ # end
19
+ #
20
+ # Following this, you will be able to use MyType as a type for any given
21
+ # property. If special materialization and serialization is required,
22
+ # override the class methods
23
+ #
24
+ # class MyType < DataMapper::Type
25
+ # primitive String
26
+ # size 10
27
+ #
28
+ # def self.dump(value, property)
29
+ # <work some magic>
30
+ # end
31
+ #
32
+ # def self.load(value)
33
+ # <work some magic>
34
+ # end
35
+ # end
36
+ class Type
37
+ PROPERTY_OPTIONS = [
38
+ :accessor, :reader, :writer,
39
+ :lazy, :default, :nullable, :key, :serial, :field, :size, :length,
40
+ :format, :index, :unique_index, :check, :ordinal, :auto_validation,
41
+ :validates, :unique, :track, :precision, :scale
42
+ ]
43
+
44
+ PROPERTY_OPTION_ALIASES = {
45
+ :size => [ :length ]
46
+ }
47
+
48
+ class << self
49
+
50
+ def configure(primitive_type, options)
51
+ @_primitive_type = primitive_type
52
+ @_options = options
53
+
54
+ def self.inherited(base)
55
+ base.primitive @_primitive_type
56
+
57
+ @_options.each do |k, v|
58
+ base.send(k, v)
59
+ end
60
+ end
61
+
62
+ self
63
+ end
64
+
65
+ # The Ruby primitive type to use as basis for this type. See
66
+ # DataMapper::Property::TYPES for list of types.
67
+ #
68
+ # @param primitive<Class, nil>
69
+ # The class for the primitive. If nil is passed in, it returns the
70
+ # current primitive
71
+ #
72
+ # @return <Class> if the <primitive> param is nil, return the current primitive.
73
+ #
74
+ # @api public
75
+ def primitive(primitive = nil)
76
+ return @primitive if primitive.nil?
77
+
78
+ # TODO: change Integer to be used internally once most in-the-wild code
79
+ # is updated to use Integer for properties instead of Fixnum, or before
80
+ # DM 1.0, whichever comes first
81
+ if Fixnum == primitive
82
+ warn "#{primitive} properties are deprecated. Please use Integer instead"
83
+ primitive = Integer
84
+ end
85
+
86
+ @primitive = primitive
87
+ end
88
+
89
+ # Load DataMapper::Property options
90
+ PROPERTY_OPTIONS.each do |property_option|
91
+ self.class_eval <<-EOS, __FILE__, __LINE__
92
+ def #{property_option}(arg = nil)
93
+ return @#{property_option} if arg.nil?
94
+
95
+ @#{property_option} = arg
96
+ end
97
+ EOS
98
+ end
99
+
100
+ # Create property aliases
101
+ PROPERTY_OPTION_ALIASES.each do |property_option, aliases|
102
+ aliases.each do |ali|
103
+ self.class_eval <<-EOS, __FILE__, __LINE__
104
+ alias #{ali} #{property_option}
105
+ EOS
106
+ end
107
+ end
108
+
109
+ # Gives all the options set on this type
110
+ #
111
+ # @return <Hash> with all options and their values set on this type
112
+ #
113
+ # @api public
114
+ def options
115
+ options = {}
116
+ PROPERTY_OPTIONS.each do |method|
117
+ next if (value = send(method)).nil?
118
+ options[method] = value
119
+ end
120
+ options
121
+ end
122
+ end
123
+
124
+ # Stub instance method for dumping
125
+ #
126
+ # @param value<Object, nil> the value to dump
127
+ # @param property<Property, nil> the property the type is being used by
128
+ #
129
+ # @return <Object> Dumped object
130
+ #
131
+ # @api public
132
+ def self.dump(value, property)
133
+ value
134
+ end
135
+
136
+ # Stub instance method for loading
137
+ #
138
+ # @param value<Object, nil> the value to serialize
139
+ # @param property<Property, nil> the property the type is being used by
140
+ #
141
+ # @return <Object> Serialized object. Must be the same type as the Ruby primitive
142
+ #
143
+ # @api public
144
+ def self.load(value, property)
145
+ value
146
+ end
147
+
148
+ def self.bind(property)
149
+ # This method should not modify the state of this type class, and
150
+ # should produce no side-effects on the type class. It's just a
151
+ # hook to allow your custom-type to modify the property it's bound to.
152
+ end
153
+
154
+ end # class Type
155
+
156
+ def self.Type(primitive_type, options = {})
157
+ Class.new(Type).configure(primitive_type, options)
158
+ end
159
+
160
+ end # module DataMapper
@@ -0,0 +1,80 @@
1
+ # TODO: move to dm-more/dm-migrations
2
+
3
+ module DataMapper
4
+ class TypeMap
5
+
6
+ attr_accessor :parent, :chains
7
+
8
+ def initialize(parent = nil, &blk)
9
+ @parent, @chains = parent, {}
10
+
11
+ blk.call(self) unless blk.nil?
12
+ end
13
+
14
+ def map(type)
15
+ @chains[type] ||= TypeChain.new
16
+ end
17
+
18
+ def lookup(type)
19
+ if type_mapped?(type)
20
+ lookup_from_map(type)
21
+ else
22
+ lookup_by_type(type)
23
+ end
24
+ end
25
+
26
+ def lookup_from_map(type)
27
+ lookup_from_parent(type).merge(map(type).translate)
28
+ end
29
+
30
+ def lookup_from_parent(type)
31
+ if !@parent.nil? && @parent.type_mapped?(type)
32
+ @parent[type]
33
+ else
34
+ {}
35
+ end
36
+ end
37
+
38
+ # @raise <DataMapper::TypeMap::Error> if the type is not a default primitive or has a type map entry.
39
+ def lookup_by_type(type)
40
+ raise DataMapper::TypeMap::Error.new(type) unless type.respond_to?(:primitive) && !type.primitive.nil?
41
+
42
+ lookup(type.primitive).merge(Type::PROPERTY_OPTIONS.inject({}) {|h, k| h[k] = type.send(k); h})
43
+ end
44
+
45
+ alias [] lookup
46
+
47
+ def type_mapped?(type)
48
+ @chains.has_key?(type) || (@parent.nil? ? false : @parent.type_mapped?(type))
49
+ end
50
+
51
+ class TypeChain
52
+ attr_accessor :primitive, :attributes
53
+
54
+ def initialize
55
+ @attributes = {}
56
+ end
57
+
58
+ def to(primitive)
59
+ @primitive = primitive
60
+ self
61
+ end
62
+
63
+ def with(attributes)
64
+ raise "method 'with' expects a hash" unless attributes.kind_of?(Hash)
65
+ @attributes.merge!(attributes)
66
+ self
67
+ end
68
+
69
+ def translate
70
+ @attributes.merge((@primitive.nil? ? {} : {:primitive => @primitive}))
71
+ end
72
+ end # class TypeChain
73
+
74
+ class Error < StandardError
75
+ def initialize(type)
76
+ super("Type #{type} must have a default primitive or type map entry")
77
+ end
78
+ end
79
+ end # class TypeMap
80
+ end # module DataMapper
@@ -0,0 +1,7 @@
1
+ module DataMapper
2
+ module Types
3
+ class Boolean < DataMapper::Type
4
+ primitive TrueClass
5
+ end # class Boolean
6
+ end # module Types
7
+ end # module DataMapper
@@ -0,0 +1,34 @@
1
+ module DataMapper
2
+ module Types
3
+ class Discriminator < DataMapper::Type
4
+ primitive Class
5
+ track :set
6
+ default lambda { |r,p| p.model }
7
+ nullable false
8
+
9
+ def self.bind(property)
10
+ model = property.model
11
+
12
+ model.class_eval <<-EOS, __FILE__, __LINE__
13
+ def self.descendants
14
+ (@descendants ||= []).uniq!
15
+ @descendants
16
+ end
17
+
18
+ after_class_method :inherited, :add_scope_for_discriminator
19
+
20
+ def self.add_scope_for_discriminator(retval, target)
21
+ target.descendants << target
22
+ target.default_scope.update(#{property.name.inspect} => target.descendants)
23
+ propagate_descendants(target)
24
+ end
25
+
26
+ def self.propagate_descendants(target)
27
+ descendants << target
28
+ superclass.propagate_descendants(target) if superclass.respond_to?(:propagate_descendants)
29
+ end
30
+ EOS
31
+ end
32
+ end # class Discriminator
33
+ end # module Types
34
+ end # module DataMapper
@@ -0,0 +1,24 @@
1
+ require "base64"
2
+
3
+ module DataMapper
4
+ module Types
5
+ class Object < DataMapper::Type
6
+ primitive String
7
+ size 65535
8
+ lazy true
9
+ track :hash
10
+
11
+ def self.typecast(value, property)
12
+ value
13
+ end
14
+
15
+ def self.dump(value, property)
16
+ Base64.encode64(Marshal.dump(value))
17
+ end
18
+
19
+ def self.load(value, property)
20
+ value.nil? ? nil : Marshal.load(Base64.decode64(value))
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,34 @@
1
+ module DataMapper
2
+ module Types
3
+ class ParanoidBoolean < DataMapper::Type(Boolean)
4
+ primitive TrueClass
5
+ default false
6
+ lazy true
7
+
8
+ def self.bind(property)
9
+ model = property.model
10
+ repository = property.repository
11
+
12
+ model.send(:set_paranoid_property, property.name){true}
13
+
14
+ model.class_eval <<-EOS, __FILE__, __LINE__
15
+
16
+ def self.with_deleted
17
+ with_exclusive_scope(#{property.name.inspect} => true) do
18
+ yield
19
+ end
20
+ end
21
+
22
+ def destroy
23
+ self.class.paranoid_properties.each do |name, blk|
24
+ attribute_set(name, blk.call(self))
25
+ end
26
+ save
27
+ end
28
+ EOS
29
+
30
+ model.default_scope(repository.name).update(property.name => false)
31
+ end
32
+ end # class ParanoidBoolean
33
+ end # module Types
34
+ end # module DataMapper