ghost_dm-core 1.3.0.beta

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 (254) hide show
  1. data/.autotest +29 -0
  2. data/.document +5 -0
  3. data/.gitignore +35 -0
  4. data/.yardopts +1 -0
  5. data/Gemfile +65 -0
  6. data/LICENSE +20 -0
  7. data/README.md +269 -0
  8. data/Rakefile +4 -0
  9. data/dm-core.gemspec +24 -0
  10. data/lib/dm-core.rb +292 -0
  11. data/lib/dm-core/adapters.rb +222 -0
  12. data/lib/dm-core/adapters/abstract_adapter.rb +237 -0
  13. data/lib/dm-core/adapters/in_memory_adapter.rb +113 -0
  14. data/lib/dm-core/associations/many_to_many.rb +499 -0
  15. data/lib/dm-core/associations/many_to_one.rb +290 -0
  16. data/lib/dm-core/associations/one_to_many.rb +348 -0
  17. data/lib/dm-core/associations/one_to_one.rb +86 -0
  18. data/lib/dm-core/associations/relationship.rb +663 -0
  19. data/lib/dm-core/backwards.rb +13 -0
  20. data/lib/dm-core/collection.rb +1515 -0
  21. data/lib/dm-core/core_ext/kernel.rb +23 -0
  22. data/lib/dm-core/core_ext/pathname.rb +6 -0
  23. data/lib/dm-core/core_ext/symbol.rb +10 -0
  24. data/lib/dm-core/identity_map.rb +7 -0
  25. data/lib/dm-core/model.rb +874 -0
  26. data/lib/dm-core/model/hook.rb +103 -0
  27. data/lib/dm-core/model/is.rb +32 -0
  28. data/lib/dm-core/model/property.rb +249 -0
  29. data/lib/dm-core/model/relationship.rb +378 -0
  30. data/lib/dm-core/model/scope.rb +89 -0
  31. data/lib/dm-core/property.rb +866 -0
  32. data/lib/dm-core/property/binary.rb +21 -0
  33. data/lib/dm-core/property/boolean.rb +20 -0
  34. data/lib/dm-core/property/class.rb +17 -0
  35. data/lib/dm-core/property/date.rb +10 -0
  36. data/lib/dm-core/property/date_time.rb +10 -0
  37. data/lib/dm-core/property/decimal.rb +36 -0
  38. data/lib/dm-core/property/discriminator.rb +44 -0
  39. data/lib/dm-core/property/float.rb +16 -0
  40. data/lib/dm-core/property/integer.rb +22 -0
  41. data/lib/dm-core/property/invalid_value_error.rb +22 -0
  42. data/lib/dm-core/property/lookup.rb +27 -0
  43. data/lib/dm-core/property/numeric.rb +38 -0
  44. data/lib/dm-core/property/object.rb +34 -0
  45. data/lib/dm-core/property/serial.rb +14 -0
  46. data/lib/dm-core/property/string.rb +38 -0
  47. data/lib/dm-core/property/text.rb +9 -0
  48. data/lib/dm-core/property/time.rb +10 -0
  49. data/lib/dm-core/property_set.rb +177 -0
  50. data/lib/dm-core/query.rb +1366 -0
  51. data/lib/dm-core/query/conditions/comparison.rb +911 -0
  52. data/lib/dm-core/query/conditions/operation.rb +721 -0
  53. data/lib/dm-core/query/direction.rb +36 -0
  54. data/lib/dm-core/query/operator.rb +35 -0
  55. data/lib/dm-core/query/path.rb +114 -0
  56. data/lib/dm-core/query/sort.rb +39 -0
  57. data/lib/dm-core/relationship_set.rb +72 -0
  58. data/lib/dm-core/repository.rb +226 -0
  59. data/lib/dm-core/resource.rb +1214 -0
  60. data/lib/dm-core/resource/persistence_state.rb +75 -0
  61. data/lib/dm-core/resource/persistence_state/clean.rb +40 -0
  62. data/lib/dm-core/resource/persistence_state/deleted.rb +30 -0
  63. data/lib/dm-core/resource/persistence_state/dirty.rb +96 -0
  64. data/lib/dm-core/resource/persistence_state/immutable.rb +34 -0
  65. data/lib/dm-core/resource/persistence_state/persisted.rb +29 -0
  66. data/lib/dm-core/resource/persistence_state/transient.rb +80 -0
  67. data/lib/dm-core/spec/lib/adapter_helpers.rb +64 -0
  68. data/lib/dm-core/spec/lib/collection_helpers.rb +21 -0
  69. data/lib/dm-core/spec/lib/counter_adapter.rb +38 -0
  70. data/lib/dm-core/spec/lib/pending_helpers.rb +50 -0
  71. data/lib/dm-core/spec/lib/spec_helper.rb +74 -0
  72. data/lib/dm-core/spec/setup.rb +174 -0
  73. data/lib/dm-core/spec/shared/adapter_spec.rb +341 -0
  74. data/lib/dm-core/spec/shared/public/property_spec.rb +229 -0
  75. data/lib/dm-core/spec/shared/resource_spec.rb +1232 -0
  76. data/lib/dm-core/spec/shared/sel_spec.rb +111 -0
  77. data/lib/dm-core/spec/shared/semipublic/property_spec.rb +176 -0
  78. data/lib/dm-core/spec/shared/semipublic/query/conditions/abstract_comparison_spec.rb +261 -0
  79. data/lib/dm-core/support/assertions.rb +8 -0
  80. data/lib/dm-core/support/chainable.rb +18 -0
  81. data/lib/dm-core/support/deprecate.rb +12 -0
  82. data/lib/dm-core/support/descendant_set.rb +89 -0
  83. data/lib/dm-core/support/equalizer.rb +48 -0
  84. data/lib/dm-core/support/ext/array.rb +22 -0
  85. data/lib/dm-core/support/ext/blank.rb +25 -0
  86. data/lib/dm-core/support/ext/hash.rb +67 -0
  87. data/lib/dm-core/support/ext/module.rb +47 -0
  88. data/lib/dm-core/support/ext/object.rb +57 -0
  89. data/lib/dm-core/support/ext/string.rb +24 -0
  90. data/lib/dm-core/support/ext/try_dup.rb +12 -0
  91. data/lib/dm-core/support/hook.rb +405 -0
  92. data/lib/dm-core/support/inflections.rb +60 -0
  93. data/lib/dm-core/support/inflector/inflections.rb +211 -0
  94. data/lib/dm-core/support/inflector/methods.rb +151 -0
  95. data/lib/dm-core/support/lazy_array.rb +451 -0
  96. data/lib/dm-core/support/local_object_space.rb +13 -0
  97. data/lib/dm-core/support/logger.rb +201 -0
  98. data/lib/dm-core/support/mash.rb +176 -0
  99. data/lib/dm-core/support/naming_conventions.rb +90 -0
  100. data/lib/dm-core/support/ordered_set.rb +380 -0
  101. data/lib/dm-core/support/subject.rb +33 -0
  102. data/lib/dm-core/support/subject_set.rb +250 -0
  103. data/lib/dm-core/version.rb +3 -0
  104. data/script/performance.rb +275 -0
  105. data/script/profile.rb +218 -0
  106. data/spec/lib/rspec_immediate_feedback_formatter.rb +54 -0
  107. data/spec/public/associations/many_to_many/read_multiple_join_spec.rb +68 -0
  108. data/spec/public/associations/many_to_many_spec.rb +197 -0
  109. data/spec/public/associations/many_to_one_spec.rb +83 -0
  110. data/spec/public/associations/many_to_one_with_boolean_cpk_spec.rb +40 -0
  111. data/spec/public/associations/many_to_one_with_custom_fk_spec.rb +49 -0
  112. data/spec/public/associations/one_to_many_spec.rb +81 -0
  113. data/spec/public/associations/one_to_one_spec.rb +176 -0
  114. data/spec/public/associations/one_to_one_with_boolean_cpk_spec.rb +46 -0
  115. data/spec/public/collection_spec.rb +69 -0
  116. data/spec/public/finalize_spec.rb +76 -0
  117. data/spec/public/model/hook_spec.rb +246 -0
  118. data/spec/public/model/property_spec.rb +88 -0
  119. data/spec/public/model/relationship_spec.rb +1040 -0
  120. data/spec/public/model_spec.rb +462 -0
  121. data/spec/public/property/binary_spec.rb +41 -0
  122. data/spec/public/property/boolean_spec.rb +22 -0
  123. data/spec/public/property/class_spec.rb +28 -0
  124. data/spec/public/property/date_spec.rb +22 -0
  125. data/spec/public/property/date_time_spec.rb +22 -0
  126. data/spec/public/property/decimal_spec.rb +23 -0
  127. data/spec/public/property/discriminator_spec.rb +135 -0
  128. data/spec/public/property/float_spec.rb +22 -0
  129. data/spec/public/property/integer_spec.rb +22 -0
  130. data/spec/public/property/object_spec.rb +107 -0
  131. data/spec/public/property/serial_spec.rb +22 -0
  132. data/spec/public/property/string_spec.rb +22 -0
  133. data/spec/public/property/text_spec.rb +63 -0
  134. data/spec/public/property/time_spec.rb +22 -0
  135. data/spec/public/property_spec.rb +341 -0
  136. data/spec/public/resource_spec.rb +288 -0
  137. data/spec/public/sel_spec.rb +53 -0
  138. data/spec/public/setup_spec.rb +145 -0
  139. data/spec/public/shared/association_collection_shared_spec.rb +309 -0
  140. data/spec/public/shared/collection_finder_shared_spec.rb +267 -0
  141. data/spec/public/shared/collection_shared_spec.rb +1667 -0
  142. data/spec/public/shared/finder_shared_spec.rb +1629 -0
  143. data/spec/rcov.opts +6 -0
  144. data/spec/semipublic/adapters/abstract_adapter_spec.rb +30 -0
  145. data/spec/semipublic/adapters/in_memory_adapter_spec.rb +13 -0
  146. data/spec/semipublic/associations/many_to_many_spec.rb +94 -0
  147. data/spec/semipublic/associations/many_to_one_spec.rb +63 -0
  148. data/spec/semipublic/associations/one_to_many_spec.rb +55 -0
  149. data/spec/semipublic/associations/one_to_one_spec.rb +53 -0
  150. data/spec/semipublic/associations/relationship_spec.rb +200 -0
  151. data/spec/semipublic/associations_spec.rb +177 -0
  152. data/spec/semipublic/collection_spec.rb +110 -0
  153. data/spec/semipublic/model_spec.rb +96 -0
  154. data/spec/semipublic/property/binary_spec.rb +13 -0
  155. data/spec/semipublic/property/boolean_spec.rb +47 -0
  156. data/spec/semipublic/property/class_spec.rb +33 -0
  157. data/spec/semipublic/property/date_spec.rb +43 -0
  158. data/spec/semipublic/property/date_time_spec.rb +46 -0
  159. data/spec/semipublic/property/decimal_spec.rb +83 -0
  160. data/spec/semipublic/property/discriminator_spec.rb +19 -0
  161. data/spec/semipublic/property/float_spec.rb +82 -0
  162. data/spec/semipublic/property/integer_spec.rb +82 -0
  163. data/spec/semipublic/property/lookup_spec.rb +29 -0
  164. data/spec/semipublic/property/serial_spec.rb +13 -0
  165. data/spec/semipublic/property/string_spec.rb +13 -0
  166. data/spec/semipublic/property/text_spec.rb +31 -0
  167. data/spec/semipublic/property/time_spec.rb +50 -0
  168. data/spec/semipublic/property_spec.rb +114 -0
  169. data/spec/semipublic/query/conditions/comparison_spec.rb +1501 -0
  170. data/spec/semipublic/query/conditions/operation_spec.rb +1294 -0
  171. data/spec/semipublic/query/path_spec.rb +471 -0
  172. data/spec/semipublic/query_spec.rb +3682 -0
  173. data/spec/semipublic/resource/state/clean_spec.rb +88 -0
  174. data/spec/semipublic/resource/state/deleted_spec.rb +78 -0
  175. data/spec/semipublic/resource/state/dirty_spec.rb +162 -0
  176. data/spec/semipublic/resource/state/immutable_spec.rb +105 -0
  177. data/spec/semipublic/resource/state/transient_spec.rb +162 -0
  178. data/spec/semipublic/resource/state_spec.rb +230 -0
  179. data/spec/semipublic/resource_spec.rb +23 -0
  180. data/spec/semipublic/shared/condition_shared_spec.rb +9 -0
  181. data/spec/semipublic/shared/resource_shared_spec.rb +199 -0
  182. data/spec/semipublic/shared/resource_state_shared_spec.rb +79 -0
  183. data/spec/semipublic/shared/subject_shared_spec.rb +79 -0
  184. data/spec/spec.opts +5 -0
  185. data/spec/spec_helper.rb +38 -0
  186. data/spec/support/core_ext/hash.rb +10 -0
  187. data/spec/support/core_ext/inheritable_attributes.rb +46 -0
  188. data/spec/support/properties/huge_integer.rb +17 -0
  189. data/spec/unit/array_spec.rb +23 -0
  190. data/spec/unit/blank_spec.rb +73 -0
  191. data/spec/unit/data_mapper/ordered_set/append_spec.rb +26 -0
  192. data/spec/unit/data_mapper/ordered_set/clear_spec.rb +24 -0
  193. data/spec/unit/data_mapper/ordered_set/delete_spec.rb +28 -0
  194. data/spec/unit/data_mapper/ordered_set/each_spec.rb +19 -0
  195. data/spec/unit/data_mapper/ordered_set/empty_spec.rb +20 -0
  196. data/spec/unit/data_mapper/ordered_set/entries_spec.rb +22 -0
  197. data/spec/unit/data_mapper/ordered_set/eql_spec.rb +51 -0
  198. data/spec/unit/data_mapper/ordered_set/equal_value_spec.rb +84 -0
  199. data/spec/unit/data_mapper/ordered_set/hash_spec.rb +12 -0
  200. data/spec/unit/data_mapper/ordered_set/include_spec.rb +23 -0
  201. data/spec/unit/data_mapper/ordered_set/index_spec.rb +28 -0
  202. data/spec/unit/data_mapper/ordered_set/initialize_spec.rb +32 -0
  203. data/spec/unit/data_mapper/ordered_set/merge_spec.rb +36 -0
  204. data/spec/unit/data_mapper/ordered_set/shared/append_spec.rb +24 -0
  205. data/spec/unit/data_mapper/ordered_set/shared/clear_spec.rb +9 -0
  206. data/spec/unit/data_mapper/ordered_set/shared/delete_spec.rb +25 -0
  207. data/spec/unit/data_mapper/ordered_set/shared/each_spec.rb +17 -0
  208. data/spec/unit/data_mapper/ordered_set/shared/empty_spec.rb +9 -0
  209. data/spec/unit/data_mapper/ordered_set/shared/entries_spec.rb +9 -0
  210. data/spec/unit/data_mapper/ordered_set/shared/include_spec.rb +9 -0
  211. data/spec/unit/data_mapper/ordered_set/shared/index_spec.rb +13 -0
  212. data/spec/unit/data_mapper/ordered_set/shared/initialize_spec.rb +28 -0
  213. data/spec/unit/data_mapper/ordered_set/shared/merge_spec.rb +28 -0
  214. data/spec/unit/data_mapper/ordered_set/shared/size_spec.rb +13 -0
  215. data/spec/unit/data_mapper/ordered_set/shared/to_ary_spec.rb +11 -0
  216. data/spec/unit/data_mapper/ordered_set/size_spec.rb +27 -0
  217. data/spec/unit/data_mapper/ordered_set/to_ary_spec.rb +23 -0
  218. data/spec/unit/data_mapper/subject_set/append_spec.rb +47 -0
  219. data/spec/unit/data_mapper/subject_set/clear_spec.rb +34 -0
  220. data/spec/unit/data_mapper/subject_set/delete_spec.rb +40 -0
  221. data/spec/unit/data_mapper/subject_set/each_spec.rb +30 -0
  222. data/spec/unit/data_mapper/subject_set/empty_spec.rb +31 -0
  223. data/spec/unit/data_mapper/subject_set/entries_spec.rb +31 -0
  224. data/spec/unit/data_mapper/subject_set/get_spec.rb +34 -0
  225. data/spec/unit/data_mapper/subject_set/include_spec.rb +32 -0
  226. data/spec/unit/data_mapper/subject_set/named_spec.rb +33 -0
  227. data/spec/unit/data_mapper/subject_set/shared/append_spec.rb +18 -0
  228. data/spec/unit/data_mapper/subject_set/shared/clear_spec.rb +9 -0
  229. data/spec/unit/data_mapper/subject_set/shared/delete_spec.rb +9 -0
  230. data/spec/unit/data_mapper/subject_set/shared/each_spec.rb +9 -0
  231. data/spec/unit/data_mapper/subject_set/shared/empty_spec.rb +9 -0
  232. data/spec/unit/data_mapper/subject_set/shared/entries_spec.rb +9 -0
  233. data/spec/unit/data_mapper/subject_set/shared/get_spec.rb +9 -0
  234. data/spec/unit/data_mapper/subject_set/shared/include_spec.rb +9 -0
  235. data/spec/unit/data_mapper/subject_set/shared/named_spec.rb +9 -0
  236. data/spec/unit/data_mapper/subject_set/shared/size_spec.rb +13 -0
  237. data/spec/unit/data_mapper/subject_set/shared/to_ary_spec.rb +9 -0
  238. data/spec/unit/data_mapper/subject_set/shared/values_at_spec.rb +44 -0
  239. data/spec/unit/data_mapper/subject_set/size_spec.rb +42 -0
  240. data/spec/unit/data_mapper/subject_set/to_ary_spec.rb +34 -0
  241. data/spec/unit/data_mapper/subject_set/values_at_spec.rb +57 -0
  242. data/spec/unit/hash_spec.rb +28 -0
  243. data/spec/unit/hook_spec.rb +1235 -0
  244. data/spec/unit/inflections_spec.rb +16 -0
  245. data/spec/unit/lazy_array_spec.rb +1949 -0
  246. data/spec/unit/mash_spec.rb +312 -0
  247. data/spec/unit/module_spec.rb +71 -0
  248. data/spec/unit/object_spec.rb +38 -0
  249. data/spec/unit/try_dup_spec.rb +46 -0
  250. data/tasks/ci.rake +1 -0
  251. data/tasks/spec.rake +38 -0
  252. data/tasks/yard.rake +9 -0
  253. data/tasks/yardstick.rake +19 -0
  254. metadata +365 -0
data/lib/dm-core.rb ADDED
@@ -0,0 +1,292 @@
1
+ require 'addressable/uri'
2
+ require 'bigdecimal'
3
+ require 'bigdecimal/util'
4
+ require 'date'
5
+ require 'pathname'
6
+ require 'set'
7
+ require 'time'
8
+ require 'yaml'
9
+
10
+ module DataMapper
11
+ module Undefined; end
12
+ end
13
+
14
+ require 'virtus'
15
+
16
+ class Virtus::Coercion::Object
17
+ def self.to_string(value)
18
+ value.nil? ? value : value.to_s
19
+ end
20
+ end
21
+
22
+ require 'dm-core/support/ext/blank'
23
+ require 'dm-core/support/ext/hash'
24
+ require 'dm-core/support/ext/object'
25
+ require 'dm-core/support/ext/string'
26
+
27
+ begin
28
+ require 'fastthread'
29
+ rescue LoadError
30
+ # fastthread not installed
31
+ end
32
+
33
+ require 'dm-core/core_ext/pathname'
34
+ require 'dm-core/support/ext/module'
35
+ require 'dm-core/support/ext/array'
36
+ require 'dm-core/support/ext/try_dup'
37
+
38
+ require 'dm-core/support/mash'
39
+ require 'dm-core/support/inflector/inflections'
40
+ require 'dm-core/support/inflector/methods'
41
+ require 'dm-core/support/inflections'
42
+ require 'dm-core/support/chainable'
43
+ require 'dm-core/support/deprecate'
44
+ require 'dm-core/support/descendant_set'
45
+ require 'dm-core/support/equalizer'
46
+ require 'dm-core/support/assertions'
47
+ require 'dm-core/support/lazy_array'
48
+ require 'dm-core/support/local_object_space'
49
+ require 'dm-core/support/hook'
50
+ require 'dm-core/support/subject'
51
+ require 'dm-core/support/ordered_set'
52
+ require 'dm-core/support/subject_set'
53
+
54
+ require 'dm-core/query'
55
+ require 'dm-core/query/conditions/operation'
56
+ require 'dm-core/query/conditions/comparison'
57
+ require 'dm-core/query/operator'
58
+ require 'dm-core/query/direction'
59
+ require 'dm-core/query/path'
60
+ require 'dm-core/query/sort'
61
+
62
+ require 'dm-core/resource'
63
+ require 'dm-core/resource/persistence_state'
64
+ require 'dm-core/resource/persistence_state/transient'
65
+ require 'dm-core/resource/persistence_state/immutable'
66
+ require 'dm-core/resource/persistence_state/persisted'
67
+ require 'dm-core/resource/persistence_state/clean'
68
+ require 'dm-core/resource/persistence_state/deleted'
69
+ require 'dm-core/resource/persistence_state/dirty'
70
+
71
+ require 'dm-core/property'
72
+ require 'dm-core/property/invalid_value_error'
73
+ require 'dm-core/property/object'
74
+ require 'dm-core/property/string'
75
+ require 'dm-core/property/binary'
76
+ require 'dm-core/property/text'
77
+ require 'dm-core/property/numeric'
78
+ require 'dm-core/property/float'
79
+ require 'dm-core/property/decimal'
80
+ require 'dm-core/property/boolean'
81
+ require 'dm-core/property/integer'
82
+ require 'dm-core/property/serial'
83
+ require 'dm-core/property/date'
84
+ require 'dm-core/property/date_time'
85
+ require 'dm-core/property/time'
86
+ require 'dm-core/property/class'
87
+ require 'dm-core/property/discriminator'
88
+ require 'dm-core/property/lookup'
89
+ require 'dm-core/property_set'
90
+
91
+ require 'dm-core/model'
92
+ require 'dm-core/model/hook'
93
+ require 'dm-core/model/is'
94
+ require 'dm-core/model/scope'
95
+ require 'dm-core/model/relationship'
96
+ require 'dm-core/model/property'
97
+
98
+ require 'dm-core/collection'
99
+ require 'dm-core/relationship_set'
100
+ require 'dm-core/associations/relationship'
101
+ require 'dm-core/associations/one_to_many'
102
+ require 'dm-core/associations/one_to_one'
103
+ require 'dm-core/associations/many_to_one'
104
+ require 'dm-core/associations/many_to_many'
105
+
106
+ require 'dm-core/identity_map'
107
+ require 'dm-core/repository'
108
+ require 'dm-core/adapters'
109
+ require 'dm-core/adapters/abstract_adapter'
110
+
111
+ require 'dm-core/support/logger'
112
+ require 'dm-core/support/naming_conventions'
113
+ require 'dm-core/version'
114
+
115
+ require 'dm-core/core_ext/kernel' # TODO: do not load automatically
116
+ require 'dm-core/core_ext/symbol' # TODO: do not load automatically
117
+
118
+ require 'dm-core/backwards' # TODO: do not load automatically
119
+
120
+ # A logger should always be present. Lets be consistent with DO
121
+ DataMapper::Logger.new(StringIO.new, :fatal)
122
+
123
+ unless defined?(Infinity)
124
+ Infinity = 1.0/0
125
+ end
126
+
127
+ # == Setup and Configuration
128
+ # DataMapper uses URIs or a connection hash to connect to your data-store.
129
+ # URI connections takes the form of:
130
+ # DataMapper.setup(:default, 'protocol://username:password@localhost:port/path/to/repo')
131
+ #
132
+ # Breaking this down, the first argument is the name you wish to give this
133
+ # connection. If you do not specify one, it will be assigned :default. If you
134
+ # would like to connect to more than one data-store, simply issue this command
135
+ # again, but with a different name specified.
136
+ #
137
+ # In order to issue ORM commands without specifying the repository context, you
138
+ # must define the :default database. Otherwise, you'll need to wrap your ORM
139
+ # calls in <tt>repository(:name) { }</tt>.
140
+ #
141
+ # Second, the URI breaks down into the access protocol, the username, the
142
+ # server, the password, and whatever path information is needed to properly
143
+ # address the data-store on the server.
144
+ #
145
+ # Here's some examples
146
+ # DataMapper.setup(:default, 'sqlite3://path/to/your/project/db/development.db')
147
+ # DataMapper.setup(:default, 'mysql://localhost/dm_core_test')
148
+ # # no auth-info
149
+ # DataMapper.setup(:default, 'postgres://root:supahsekret@127.0.0.1/dm_core_test')
150
+ # # with auth-info
151
+ #
152
+ #
153
+ # Alternatively, you can supply a hash as the second parameter, which would
154
+ # take the form:
155
+ #
156
+ # DataMapper.setup(:default, {
157
+ # :adapter => 'adapter_name_here',
158
+ # :database => 'path/to/repo',
159
+ # :username => 'username',
160
+ # :password => 'password',
161
+ # :host => 'hostname'
162
+ # })
163
+ #
164
+ # === Logging
165
+ # To turn on error logging to STDOUT, issue:
166
+ #
167
+ # DataMapper::Logger.new($stdout, :debug)
168
+ #
169
+ # You can pass a file location ("/path/to/log/file.log") in place of $stdout.
170
+ # see DataMapper::Logger for more information.
171
+ #
172
+ module DataMapper
173
+ extend DataMapper::Assertions
174
+
175
+ class RepositoryNotSetupError < StandardError; end
176
+
177
+ class IncompleteModelError < StandardError; end
178
+
179
+ class PluginNotFoundError < StandardError; end
180
+
181
+ class UnknownRelationshipError < StandardError; end
182
+
183
+ class ObjectNotFoundError < RuntimeError; end
184
+
185
+ class PersistenceError < RuntimeError; end
186
+
187
+ class UpdateConflictError < PersistenceError; end
188
+
189
+ class SaveFailureError < PersistenceError
190
+ attr_reader :resource
191
+
192
+ def initialize(message, resource)
193
+ super(message)
194
+ @resource = resource
195
+ end
196
+ end
197
+
198
+ class ImmutableError < RuntimeError; end
199
+
200
+ class ImmutableDeletedError < ImmutableError; end
201
+
202
+ # Raised on attempt to operate on collection of child objects
203
+ # when parent object is not yet saved.
204
+ # For instance, if your article object is not saved,
205
+ # but you try to fetch or scope down comments (1:n case), or
206
+ # publications (n:m case), operation cannot be completed
207
+ # because parent object's keys are not yet persisted,
208
+ # and thus there is no FK value to use in the query.
209
+ class UnsavedParentError < PersistenceError; end
210
+
211
+ # @api private
212
+ def self.root
213
+ @root ||= Pathname(__FILE__).dirname.parent.expand_path.freeze
214
+ end
215
+
216
+ # Setups up a connection to a data-store
217
+ #
218
+ # @param [Symbol] name
219
+ # a name for the context, defaults to :default
220
+ # @param [Hash(Symbol => String), Addressable::URI, String] uri_or_options
221
+ # connection information
222
+ #
223
+ # @return [DataMapper::Adapters::AbstractAdapter]
224
+ # the resulting setup adapter
225
+ #
226
+ # @raise [ArgumentError] "+name+ must be a Symbol, but was..."
227
+ # indicates that an invalid argument was passed for name[Symbol]
228
+ # @raise [ArgumentError] "+uri_or_options+ must be a Hash, URI or String, but was..."
229
+ # indicates that connection information could not be gleaned from
230
+ # the given uri_or_options[Hash, Addressable::URI, String]
231
+ #
232
+ # @api public
233
+ def self.setup(*args)
234
+ adapter = args.first
235
+
236
+ unless adapter.kind_of?(Adapters::AbstractAdapter)
237
+ adapter = Adapters.new(*args)
238
+ end
239
+
240
+ Repository.adapters[adapter.name] = adapter
241
+ end
242
+
243
+ # Block Syntax
244
+ # Pushes the named repository onto the context-stack,
245
+ # yields a new session, and pops the context-stack.
246
+ #
247
+ # Non-Block Syntax
248
+ # Returns the current session, or if there is none,
249
+ # a new Session.
250
+ #
251
+ # @param [Symbol] args the name of a repository to act within or return, :default is default
252
+ #
253
+ # @yield [Proc] (optional) block to execute within the context of the named repository
254
+ #
255
+ # @api public
256
+ def self.repository(name = nil)
257
+ context = Repository.context
258
+
259
+ current_repository = if name
260
+ name = name.to_sym
261
+ context.detect { |repository| repository.name == name }
262
+ else
263
+ name = Repository.default_name
264
+ context.last
265
+ end
266
+
267
+ current_repository ||= Repository.new(name)
268
+
269
+ if block_given?
270
+ current_repository.scope { |*block_args| yield(*block_args) }
271
+ else
272
+ current_repository
273
+ end
274
+ end
275
+
276
+ # Perform necessary steps to finalize DataMapper for the current repository
277
+ #
278
+ # This method should be called after loading all models and plugins.
279
+ #
280
+ # It ensures foreign key properties and anonymous join models are created.
281
+ # These are otherwise lazily declared, which can lead to unexpected errors.
282
+ # It also performs basic validity checking of the DataMapper models.
283
+ #
284
+ # @return [self]
285
+ #
286
+ # @api public
287
+ def self.finalize
288
+ Model.descendants.each { |model| model.finalize }
289
+ self
290
+ end
291
+
292
+ end # module DataMapper
@@ -0,0 +1,222 @@
1
+ module DataMapper
2
+ module Adapters
3
+ extend Chainable
4
+ extend DataMapper::Assertions
5
+
6
+ # Set up an adapter for a storage engine
7
+ #
8
+ # @see DataMapper.setup
9
+ #
10
+ # @api private
11
+ def self.new(repository_name, options)
12
+ options = normalize_options(options)
13
+ adapter_class(options.fetch(:adapter)).new(repository_name, options)
14
+ end
15
+
16
+ # The path used to require the in memory adapter
17
+ #
18
+ # Set this if you want to register your own adapter
19
+ # to be used when you specify an 'in_memory' connection
20
+ # during
21
+ #
22
+ # @see DataMapper.setup
23
+ #
24
+ # @param [String] path
25
+ # the path used to require the desired in memory adapter
26
+ #
27
+ # @api semipublic
28
+ def self.in_memory_adapter_path=(path)
29
+ @in_memory_adapter_path = path
30
+ end
31
+
32
+ # The path used to require the in memory adapter
33
+ #
34
+ # @see DataMapper.setup
35
+ #
36
+ # @return [String]
37
+ # the path used to require the desired in memory adapter
38
+ #
39
+ # @api semipublic
40
+ def self.in_memory_adapter_path
41
+ @in_memory_adapter_path ||= 'dm-core/adapters/in_memory_adapter'
42
+ end
43
+
44
+ class << self
45
+ private
46
+
47
+ # Normalize the arguments passed to new()
48
+ #
49
+ # Turns options hash or connection URI into the options hash used
50
+ # by the adapter.
51
+ #
52
+ # @param [Hash, Addressable::URI, String] options
53
+ # the options to be normalized
54
+ #
55
+ # @return [Mash]
56
+ # the options normalized as a Mash
57
+ #
58
+ # @api private
59
+ def normalize_options(options)
60
+ case options
61
+ when Hash then normalize_options_hash(options)
62
+ when Addressable::URI then normalize_options_uri(options)
63
+ when String then normalize_options_string(options)
64
+ else
65
+ assert_kind_of 'options', options, Hash, Addressable::URI, String
66
+ end
67
+ end
68
+
69
+ # Normalize Hash options into a Mash
70
+ #
71
+ # @param [Hash] hash
72
+ # the hash to be normalized
73
+ #
74
+ # @return [Mash]
75
+ # the options normalized as a Mash
76
+ #
77
+ # @api private
78
+ def normalize_options_hash(hash)
79
+ DataMapper::Ext::Hash.to_mash(hash)
80
+ end
81
+
82
+ # Normalize Addressable::URI options into a Mash
83
+ #
84
+ # @param [Addressable::URI] uri
85
+ # the uri to be normalized
86
+ #
87
+ # @return [Mash]
88
+ # the options normalized as a Mash
89
+ #
90
+ # @api private
91
+ def normalize_options_uri(uri)
92
+ options = normalize_options_hash(uri.to_hash)
93
+
94
+ # Extract the name/value pairs from the query portion of the
95
+ # connection uri, and set them as options directly.
96
+ if options.fetch(:query)
97
+ options.update(uri.query_values)
98
+ end
99
+
100
+ options[:adapter] = options.fetch(:scheme)
101
+
102
+ options
103
+ end
104
+
105
+ # Normalize String options into a Mash
106
+ #
107
+ # @param [String] string
108
+ # the string to be normalized
109
+ #
110
+ # @return [Mash]
111
+ # the options normalized as a Mash
112
+ #
113
+ # @api private
114
+ def normalize_options_string(string)
115
+ normalize_options_uri(Addressable::URI.parse(string))
116
+ end
117
+
118
+ # Return the adapter class constant
119
+ #
120
+ # @example
121
+ # DataMapper::Adapters.send(:adapter_class, 'mysql') # => DataMapper::Adapters::MysqlAdapter
122
+ #
123
+ # @param [Symbol] name
124
+ # the name of the adapter
125
+ #
126
+ # @return [Class]
127
+ # the AbstractAdapter subclass
128
+ #
129
+ # @api private
130
+ def adapter_class(name)
131
+ adapter_name = normalize_adapter_name(name)
132
+ class_name = (DataMapper::Inflector.camelize(adapter_name) << 'Adapter').to_sym
133
+ load_adapter(adapter_name) unless const_defined?(class_name)
134
+ const_get(class_name)
135
+ end
136
+
137
+ # Return the name of the adapter
138
+ #
139
+ # @example
140
+ # DataMapper::Adapters.adapter_name('MysqlAdapter') # => 'mysql'
141
+ #
142
+ # @param [String] const_name
143
+ # the adapter constant name
144
+ #
145
+ # @return [String]
146
+ # the name of the adapter
147
+ #
148
+ # @api semipublic
149
+ def adapter_name(const_name)
150
+ const_name.to_s.chomp('Adapter').downcase
151
+ end
152
+
153
+ # Require the adapter library
154
+ #
155
+ # @param [String, Symbol] name
156
+ # the name of the adapter
157
+ #
158
+ # @return [Boolean]
159
+ # true if the adapter is loaded
160
+ #
161
+ # @api private
162
+ def load_adapter(name)
163
+ require "dm-#{name}-adapter"
164
+ rescue LoadError => original_error
165
+ begin
166
+ require in_memory_adapter?(name) ? in_memory_adapter_path : legacy_path(name)
167
+ rescue LoadError
168
+ raise original_error
169
+ end
170
+ end
171
+
172
+ # Returns wether or not the given adapter name is considered an in memory adapter
173
+ #
174
+ # @param [String, Symbol] name
175
+ # the name of the adapter
176
+ #
177
+ # @return [Boolean]
178
+ # true if the adapter is considered to be an in memory adapter
179
+ #
180
+ # @api private
181
+ def in_memory_adapter?(name)
182
+ name.to_s == 'in_memory'
183
+ end
184
+
185
+ # Returns the fallback filename that would be used to require the named adapter
186
+ #
187
+ # The fallback format is "#{name}_adapter" and will be phased out in favor of
188
+ # the properly 'namespaced' "dm-#{name}-adapter" format.
189
+ #
190
+ # @param [String, Symbol] name
191
+ # the name of the adapter to require
192
+ #
193
+ # @return [String]
194
+ # the filename that gets required for the adapter identified by name
195
+ #
196
+ # @api private
197
+ def legacy_path(name)
198
+ "#{name}_adapter"
199
+ end
200
+
201
+ # Adjust the adapter name to match the name used in the gem providing the adapter
202
+ #
203
+ # @param [String, Symbol] name
204
+ # the name of the adapter
205
+ #
206
+ # @return [String]
207
+ # the normalized adapter name
208
+ #
209
+ # @api private
210
+ def normalize_adapter_name(name)
211
+ (original = name.to_s) == 'sqlite3' ? 'sqlite' : original
212
+ end
213
+
214
+ end
215
+
216
+ extendable do
217
+ # @api private
218
+ def const_added(const_name)
219
+ end
220
+ end
221
+ end # module Adapters
222
+ end # module DataMapper