Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Merge branch 'master' of git@github.com:sam/dm-more

  • Loading branch information...
commit 0489eaaf826343dfb2cc51ebf500479081212200 2 parents 3888768 + 7c2a30c
Adam French authored

Showing 347 changed files with 14,105 additions and 1,759 deletions. Show diff stats Hide diff stats

  1. +1 0  History.txt
  2. +9 0 Manifest.txt
  3. 0  README → README.txt
  4. +19 46 Rakefile
  5. +2 0  adapters/dm-couchdb-adapter/.gitignore
  6. +1 0  adapters/dm-couchdb-adapter/History.txt
  7. +13 0 adapters/dm-couchdb-adapter/Manifest.txt
  8. +0 4 adapters/dm-couchdb-adapter/README
  9. +27 0 adapters/dm-couchdb-adapter/README.txt
  10. +20 27 adapters/dm-couchdb-adapter/Rakefile
  11. +122 101 adapters/dm-couchdb-adapter/lib/couchdb_adapter.rb
  12. +35 0 adapters/dm-couchdb-adapter/lib/couchdb_adapter/json_object.rb
  13. +7 0 adapters/dm-couchdb-adapter/lib/couchdb_adapter/version.rb
  14. +55 0 adapters/dm-couchdb-adapter/lib/couchdb_adapter/view.rb
  15. +0 87 adapters/dm-couchdb-adapter/lib/couchdb_views.rb
  16. +43 2 adapters/dm-couchdb-adapter/spec/couchdb_adapter_spec.rb
  17. +0 13 adapters/dm-couchdb-adapter/spec/couchdb_view_spec.rb
  18. +1 0  adapters/dm-rest-adapter/History.txt
  19. +26 0 adapters/dm-rest-adapter/Manifest.txt
  20. +1 2  adapters/dm-rest-adapter/{README → README.txt}
  21. +19 25 adapters/dm-rest-adapter/Rakefile
  22. +0 1  adapters/dm-rest-adapter/TODO
  23. +256 0 adapters/dm-rest-adapter/fixtures/book_service/README
  24. +10 0 adapters/dm-rest-adapter/fixtures/book_service/Rakefile
  25. +15 0 adapters/dm-rest-adapter/fixtures/book_service/app/controllers/application.rb
  26. +85 0 adapters/dm-rest-adapter/fixtures/book_service/app/controllers/books_controller.rb
  27. +89 0 adapters/dm-rest-adapter/fixtures/book_service/app/controllers/shelves_controller.rb
  28. +3 0  adapters/dm-rest-adapter/fixtures/book_service/app/helpers/application_helper.rb
  29. +2 0  adapters/dm-rest-adapter/fixtures/book_service/app/helpers/books_helper.rb
  30. +2 0  adapters/dm-rest-adapter/fixtures/book_service/app/helpers/shelf_helper.rb
  31. +6 0 adapters/dm-rest-adapter/fixtures/book_service/app/models/book.rb
  32. +5 0 adapters/dm-rest-adapter/fixtures/book_service/app/models/shelf.rb
  33. +20 0 adapters/dm-rest-adapter/fixtures/book_service/app/views/books/edit.html.erb
  34. +22 0 adapters/dm-rest-adapter/fixtures/book_service/app/views/books/index.html.erb
  35. +19 0 adapters/dm-rest-adapter/fixtures/book_service/app/views/books/new.html.erb
  36. +13 0 adapters/dm-rest-adapter/fixtures/book_service/app/views/books/show.html.erb
  37. +17 0 adapters/dm-rest-adapter/fixtures/book_service/app/views/layouts/books.html.erb
  38. +16 0 adapters/dm-rest-adapter/fixtures/book_service/app/views/shelves/edit.html.erb
  39. +20 0 adapters/dm-rest-adapter/fixtures/book_service/app/views/shelves/index.html.erb
  40. +15 0 adapters/dm-rest-adapter/fixtures/book_service/app/views/shelves/new.html.erb
  41. +7 0 adapters/dm-rest-adapter/fixtures/book_service/app/views/shelves/show.html.erb
  42. +109 0 adapters/dm-rest-adapter/fixtures/book_service/config/boot.rb
  43. +19 0 adapters/dm-rest-adapter/fixtures/book_service/config/database.yml
  44. +67 0 adapters/dm-rest-adapter/fixtures/book_service/config/environment.rb
  45. +17 0 adapters/dm-rest-adapter/fixtures/book_service/config/environments/development.rb
  46. +22 0 adapters/dm-rest-adapter/fixtures/book_service/config/environments/production.rb
  47. +22 0 adapters/dm-rest-adapter/fixtures/book_service/config/environments/test.rb
  48. +10 0 adapters/dm-rest-adapter/fixtures/book_service/config/initializers/inflections.rb
  49. +5 0 adapters/dm-rest-adapter/fixtures/book_service/config/initializers/mime_types.rb
  50. +15 0 adapters/dm-rest-adapter/fixtures/book_service/config/initializers/new_rails_defaults.rb
  51. +44 0 adapters/dm-rest-adapter/fixtures/book_service/config/routes.rb
  52. BIN  adapters/dm-rest-adapter/fixtures/book_service/db/development.sqlite3
  53. +15 0 adapters/dm-rest-adapter/fixtures/book_service/db/migrate/20080608165526_create_books.rb
  54. +13 0 adapters/dm-rest-adapter/fixtures/book_service/db/migrate/20080621171551_create_shelves.rb
  55. +20 0 adapters/dm-rest-adapter/fixtures/book_service/db/migrate/20080629143033_create_fake_books_and_shelves.rb
  56. +28 0 adapters/dm-rest-adapter/fixtures/book_service/db/schema.rb
  57. +30 0 adapters/dm-rest-adapter/fixtures/book_service/public/404.html
  58. +30 0 adapters/dm-rest-adapter/fixtures/book_service/public/422.html
  59. +30 0 adapters/dm-rest-adapter/fixtures/book_service/public/500.html
  60. +10 0 adapters/dm-rest-adapter/fixtures/book_service/public/dispatch.cgi
  61. +24 0 adapters/dm-rest-adapter/fixtures/book_service/public/dispatch.fcgi
  62. +10 0 adapters/dm-rest-adapter/fixtures/book_service/public/dispatch.rb
  63. 0  adapters/dm-rest-adapter/fixtures/book_service/public/favicon.ico
  64. BIN  adapters/dm-rest-adapter/fixtures/book_service/public/images/rails.png
  65. +274 0 adapters/dm-rest-adapter/fixtures/book_service/public/index.html
  66. +2 0  adapters/dm-rest-adapter/fixtures/book_service/public/javascripts/application.js
  67. +963 0 adapters/dm-rest-adapter/fixtures/book_service/public/javascripts/controls.js
  68. +972 0 adapters/dm-rest-adapter/fixtures/book_service/public/javascripts/dragdrop.js
  69. +1,120 0 adapters/dm-rest-adapter/fixtures/book_service/public/javascripts/effects.js
  70. +4,225 0 adapters/dm-rest-adapter/fixtures/book_service/public/javascripts/prototype.js
  71. +5 0 adapters/dm-rest-adapter/fixtures/book_service/public/robots.txt
  72. +54 0 adapters/dm-rest-adapter/fixtures/book_service/public/stylesheets/scaffold.css
  73. +3 0  adapters/dm-rest-adapter/fixtures/book_service/script/about
  74. +3 0  adapters/dm-rest-adapter/fixtures/book_service/script/console
  75. +3 0  adapters/dm-rest-adapter/fixtures/book_service/script/dbconsole
  76. +3 0  adapters/dm-rest-adapter/fixtures/book_service/script/destroy
  77. +3 0  adapters/dm-rest-adapter/fixtures/book_service/script/generate
  78. +3 0  adapters/dm-rest-adapter/fixtures/book_service/script/performance/benchmarker
  79. +3 0  adapters/dm-rest-adapter/fixtures/book_service/script/performance/profiler
  80. +3 0  adapters/dm-rest-adapter/fixtures/book_service/script/performance/request
  81. +3 0  adapters/dm-rest-adapter/fixtures/book_service/script/plugin
  82. +3 0  adapters/dm-rest-adapter/fixtures/book_service/script/process/inspector
  83. +3 0  adapters/dm-rest-adapter/fixtures/book_service/script/process/reaper
  84. +3 0  adapters/dm-rest-adapter/fixtures/book_service/script/process/spawner
  85. +3 0  adapters/dm-rest-adapter/fixtures/book_service/script/runner
  86. +3 0  adapters/dm-rest-adapter/fixtures/book_service/script/server
  87. +9 0 adapters/dm-rest-adapter/fixtures/book_service/test/fixtures/books.yml
  88. +7 0 adapters/dm-rest-adapter/fixtures/book_service/test/fixtures/shelves.yml
  89. +45 0 adapters/dm-rest-adapter/fixtures/book_service/test/functional/books_controller_test.rb
  90. +8 0 adapters/dm-rest-adapter/fixtures/book_service/test/functional/shelf_controller_test.rb
  91. +38 0 adapters/dm-rest-adapter/fixtures/book_service/test/test_helper.rb
  92. +8 0 adapters/dm-rest-adapter/fixtures/book_service/test/unit/book_test.rb
  93. +8 0 adapters/dm-rest-adapter/fixtures/book_service/test/unit/shelf_test.rb
  94. +115 75 adapters/dm-rest-adapter/lib/rest_adapter.rb
  95. +7 0 adapters/dm-rest-adapter/lib/rest_adapter/version.rb
  96. +21 0 adapters/dm-rest-adapter/spec/create_spec.rb
  97. +22 0 adapters/dm-rest-adapter/spec/delete_spec.rb
  98. +22 74 adapters/dm-rest-adapter/spec/{rest_adapter_spec.rb → read_spec.rb}
  99. +1 1  adapters/dm-rest-adapter/spec/ruby_forker.rb
  100. +17 0 adapters/dm-rest-adapter/spec/spec_helper.rb
  101. +36 0 adapters/dm-rest-adapter/spec/update_spec.rb
  102. +25 2 adapters/dm-rest-adapter/stories/crud/create
  103. +19 7 adapters/dm-rest-adapter/stories/crud/read
  104. +15 4 adapters/dm-rest-adapter/stories/crud/stories.rb
  105. +31 3 adapters/dm-rest-adapter/stories/crud/update
  106. +1 1  adapters/dm-rest-adapter/stories/helper.rb
  107. +7 0 adapters/dm-rest-adapter/stories/resources/helpers/book.rb
  108. +1 1  adapters/dm-rest-adapter/stories/resources/helpers/story_helper.rb
  109. +35 0 adapters/dm-rest-adapter/stories/resources/steps/read.rb
  110. +28 23 adapters/dm-rest-adapter/stories/resources/steps/using_rest_adapter.rb
  111. +1 0  dm-adjust/History.txt
  112. +15 0 dm-adjust/Manifest.txt
  113. 0  dm-adjust/{README → README.txt}
  114. +20 27 dm-adjust/Rakefile
  115. +4 1 dm-adjust/lib/dm-adjust.rb
  116. +7 0 dm-adjust/lib/dm-adjust/version.rb
  117. +1 0  dm-aggregates/History.txt
  118. +17 0 dm-aggregates/Manifest.txt
  119. 0  dm-aggregates/{README → README.txt}
  120. +21 28 dm-aggregates/Rakefile
  121. +10 7 dm-aggregates/lib/dm-aggregates.rb
  122. +44 31 dm-aggregates/lib/dm-aggregates/adapters/data_objects_adapter.rb
  123. +200 0 dm-aggregates/lib/dm-aggregates/aggregate_functions.rb
  124. +3 10 dm-aggregates/lib/dm-aggregates/collection.rb
  125. +0 118 dm-aggregates/lib/dm-aggregates/functions.rb
  126. +3 10 dm-aggregates/lib/dm-aggregates/model.rb
  127. +2 18 dm-aggregates/lib/dm-aggregates/repository.rb
  128. +21 0 dm-aggregates/lib/dm-aggregates/support/symbol.rb
  129. +7 0 dm-aggregates/lib/dm-aggregates/version.rb
  130. +71 12 dm-aggregates/spec/integration/aggregates_spec.rb
  131. +1 0  dm-ar-finders/History.txt
  132. +11 0 dm-ar-finders/Manifest.txt
  133. +1 2  dm-ar-finders/{README → README.txt}
  134. +21 28 dm-ar-finders/Rakefile
  135. +5 0 dm-ar-finders/lib/dm-ar-finders/version.rb
  136. +1 0  dm-cli/History.txt
  137. +13 0 dm-cli/Manifest.txt
  138. +1 2  dm-cli/{README → README.txt}
  139. +22 30 dm-cli/Rakefile
  140. +1 0  dm-cli/lib/dm-cli.rb
  141. 0  dm-cli/lib/{data_mapper → dm-cli}/cli.rb
  142. +5 0 dm-cli/lib/dm-cli/version.rb
  143. +1 1  dm-cli/spec/unit/cli_spec.rb
  144. +1 0  dm-is-example/History.txt
  145. +12 0 dm-is-example/Manifest.txt
  146. +1 2  dm-is-example/{README → README.txt}
  147. +20 27 dm-is-example/Rakefile
  148. +7 0 dm-is-example/lib/dm-is-example/is/version.rb
  149. +1 0  dm-is-list/History.txt
  150. +12 0 dm-is-list/Manifest.txt
  151. +1 2  dm-is-list/{README → README.txt}
  152. +22 29 dm-is-list/Rakefile
  153. +1 1  dm-is-list/lib/dm-is-list/is/list.rb
  154. +7 0 dm-is-list/lib/dm-is-list/is/version.rb
  155. +1 0  dm-is-nested_set/History.txt
  156. +12 0 dm-is-nested_set/Manifest.txt
  157. +1 2  dm-is-nested_set/{README → README.txt}
  158. +21 28 dm-is-nested_set/Rakefile
  159. +16 27 dm-is-nested_set/lib/dm-is-nested_set/is/nested_set.rb
  160. +7 0 dm-is-nested_set/lib/dm-is-nested_set/is/version.rb
  161. +79 67 dm-is-nested_set/spec/integration/nested_set_spec.rb
  162. +1 0  dm-is-nested_set/spec/spec_helper.rb
  163. +1 0  dm-is-state_machine/History.txt
  164. +20 0 dm-is-state_machine/LICENSE
  165. +31 0 dm-is-state_machine/Manifest.txt
  166. +12 0 dm-is-state_machine/README.txt
  167. +51 0 dm-is-state_machine/Rakefile
  168. +11 0 dm-is-state_machine/TODO
  169. +27 0 dm-is-state_machine/lib/dm-is-state_machine.rb
  170. +25 0 dm-is-state_machine/lib/dm-is-state_machine/is/data/event.rb
  171. +69 0 dm-is-state_machine/lib/dm-is-state_machine/is/data/machine.rb
  172. +21 0 dm-is-state_machine/lib/dm-is-state_machine/is/data/state.rb
  173. +73 0 dm-is-state_machine/lib/dm-is-state_machine/is/dsl/event_dsl.rb
  174. +40 0 dm-is-state_machine/lib/dm-is-state_machine/is/dsl/state_dsl.rb
  175. +107 0 dm-is-state_machine/lib/dm-is-state_machine/is/state_machine.rb
  176. +7 0 dm-is-state_machine/lib/dm-is-state_machine/is/version.rb
  177. +20 0 dm-is-state_machine/spec/examples/invalid_events.rb
  178. +20 0 dm-is-state_machine/spec/examples/invalid_states.rb
  179. +22 0 dm-is-state_machine/spec/examples/invalid_transitions_1.rb
  180. +22 0 dm-is-state_machine/spec/examples/invalid_transitions_2.rb
  181. +45 0 dm-is-state_machine/spec/examples/traffic_light.rb
  182. +12 0 dm-is-state_machine/spec/integration/invalid_events_spec.rb
  183. +12 0 dm-is-state_machine/spec/integration/invalid_states_spec.rb
  184. +22 0 dm-is-state_machine/spec/integration/invalid_transitions_spec.rb
  185. +150 0 dm-is-state_machine/spec/integration/traffic_light_spec.rb
  186. +2 0  dm-is-state_machine/spec/spec.opts
  187. +28 0 dm-is-state_machine/spec/spec_helper.rb
  188. +28 0 dm-is-state_machine/spec/unit/data/event_spec.rb
  189. +97 0 dm-is-state_machine/spec/unit/data/machine_spec.rb
  190. +22 0 dm-is-state_machine/spec/unit/data/state_spec.rb
  191. +56 0 dm-is-state_machine/spec/unit/dsl/event_dsl_spec.rb
  192. +25 0 dm-is-state_machine/spec/unit/dsl/state_dsl_spec.rb
  193. +34 0 dm-is-state_machine/spec/unit/state_machine_spec.rb
  194. +1 0  dm-is-tree/History.txt
  195. +10 0 dm-is-tree/Manifest.txt
  196. +1 2  dm-is-tree/{README → README.txt}
  197. +21 28 dm-is-tree/Rakefile
  198. +7 0 dm-is-tree/lib/dm-is-tree/is/version.rb
  199. +1 0  dm-is-versioned/History.txt
  200. +12 0 dm-is-versioned/Manifest.txt
  201. +1 2  dm-is-versioned/{README → README.txt}
  202. +21 28 dm-is-versioned/Rakefile
  203. +7 0 dm-is-versioned/lib/dm-is-versioned/is/version.rb
  204. +1 0  dm-migrations/History.txt
  205. +38 0 dm-migrations/Manifest.txt
  206. +1 2  dm-migrations/{README → README.txt}
  207. +22 29 dm-migrations/Rakefile
  208. +5 0 dm-migrations/lib/dm-migrations/version.rb
  209. +9 11 dm-migrations/lib/migration.rb
  210. +3 103 dm-migrations/lib/sql.rb
  211. +10 10 dm-migrations/lib/sql/postgresql.rb
  212. +1 8 dm-migrations/lib/sql/sqlite3.rb
  213. +55 0 dm-migrations/lib/sql/table_creator.rb
  214. +53 0 dm-migrations/lib/sql/table_modifier.rb
  215. +58 55 dm-migrations/spec/integration/migration_runner_spec.rb
  216. +99 99 dm-migrations/spec/integration/migration_spec.rb
  217. +118 108 dm-migrations/spec/integration/sql_spec.rb
  218. +2 1  dm-migrations/spec/spec.opts
  219. +3 10 dm-migrations/spec/spec_helper.rb
  220. +447 0 dm-migrations/spec/unit/migration_spec.rb
  221. +18 0 dm-migrations/spec/unit/sql/column_spec.rb
  222. +99 0 dm-migrations/spec/unit/sql/postgresql_spec.rb
  223. +109 0 dm-migrations/spec/unit/sql/sqlite3_extensions_spec.rb
  224. +93 0 dm-migrations/spec/unit/sql/table_creator_spec.rb
  225. +52 0 dm-migrations/spec/unit/sql/table_modifier_spec.rb
  226. +31 0 dm-migrations/spec/unit/sql/table_spec.rb
  227. +10 0 dm-migrations/spec/unit/sql_spec.rb
  228. +1 0  dm-observer/History.txt
  229. +11 0 dm-observer/Manifest.txt
  230. +2 2 dm-observer/{README → README.txt}
  231. +21 28 dm-observer/Rakefile
  232. +5 0 dm-observer/lib/dm-observer/version.rb
  233. +1 0  dm-querizer/History.txt
  234. +14 0 dm-querizer/Manifest.txt
  235. +1 2  dm-querizer/{README → README.txt}
  236. +20 27 dm-querizer/Rakefile
  237. +1 1  dm-querizer/lib/dm-querizer.rb
  238. 0  dm-querizer/lib/{dm-core → dm-querizer}/collection.rb
  239. 0  dm-querizer/lib/{dm-core → dm-querizer}/model.rb
  240. +13 2 dm-querizer/lib/{dm-core → dm-querizer}/querizer.rb
  241. +5 0 dm-querizer/lib/dm-querizer/version.rb
  242. +1 0  dm-serializer/History.txt
  243. +20 0 dm-serializer/Manifest.txt
  244. +1 2  dm-serializer/{README → README.txt}
  245. +21 28 dm-serializer/Rakefile
  246. +13 11 dm-serializer/lib/dm-serializer.rb
  247. +5 0 dm-serializer/lib/dm-serializer/version.rb
  248. +4 0 dm-serializer/spec/fixtures/cow.rb
  249. +11 0 dm-serializer/spec/fixtures/quatum_cat.rb
  250. +1 0  dm-serializer/spec/spec_helper.rb
  251. +14 0 dm-serializer/spec/unit/to_csv_spec.rb
  252. +22 1 dm-serializer/spec/unit/to_json_spec.rb
  253. +15 0 dm-serializer/spec/unit/to_xml_spec.rb
  254. +14 0 dm-serializer/spec/unit/to_yaml_spec.rb
  255. +1 0  dm-shorthand/History.txt
  256. +11 0 dm-shorthand/Manifest.txt
  257. +2 3 dm-shorthand/{README → README.txt}
  258. +21 28 dm-shorthand/Rakefile
  259. +5 0 dm-shorthand/lib/dm-shorthand/version.rb
  260. +1 0  dm-timestamps/History.txt
  261. +11 0 dm-timestamps/Manifest.txt
  262. +1 2  dm-timestamps/{README → README.txt}
  263. +21 28 dm-timestamps/Rakefile
  264. +4 4 dm-timestamps/lib/dm-timestamps.rb
  265. +5 0 dm-timestamps/lib/dm-timestamps/version.rb
  266. +1 0  dm-types/History.txt
  267. +39 0 dm-types/Manifest.txt
  268. +1 2  dm-types/{README → README.txt}
  269. +21 28 dm-types/Rakefile
  270. +7 0 dm-types/lib/dm-types.rb
  271. +31 0 dm-types/lib/dm-types/bcrypt_hash.rb
  272. +10 0 dm-types/lib/dm-types/enum.rb
  273. +5 0 dm-types/lib/dm-types/file_path.rb
  274. +4 0 dm-types/lib/dm-types/ip_address.rb
  275. +9 0 dm-types/lib/dm-types/json.rb
  276. +4 0 dm-types/lib/dm-types/uri.rb
  277. +5 0 dm-types/lib/dm-types/version.rb
  278. +5 0 dm-types/lib/dm-types/yaml.rb
  279. +50 0 dm-types/spec/integration/bcrypt_hash_spec.rb
  280. +5 0 dm-types/spec/integration/enum_spec.rb
  281. +26 0 dm-types/spec/integration/file_path_spec.rb
  282. +4 0 dm-types/spec/integration/flag_spec.rb
  283. +26 0 dm-types/spec/integration/ip_address_spec.rb
  284. +26 0 dm-types/spec/integration/json_spec.rb
  285. +26 0 dm-types/spec/integration/uri_spec.rb
  286. +37 0 dm-types/spec/integration/yaml_spec.rb
  287. +50 0 dm-types/spec/unit/bcrypt_hash_spec.rb
  288. +37 0 dm-types/spec/unit/csv_spec.rb
  289. +19 0 dm-types/spec/unit/enum_spec.rb
  290. +11 0 dm-types/spec/unit/file_path_spec.rb
  291. +7 7 dm-types/spec/unit/flag_spec.rb
  292. +17 0 dm-types/spec/unit/ip_address_spec.rb
  293. +53 0 dm-types/spec/unit/json_spec.rb
  294. +11 0 dm-types/spec/unit/uri_spec.rb
  295. +58 0 dm-types/spec/unit/yaml_spec.rb
  296. +1 0  dm-validations/History.txt
  297. +45 0 dm-validations/Manifest.txt
  298. 0  dm-validations/{README → README.txt}
  299. +22 30 dm-validations/Rakefile
  300. +7 9 dm-validations/lib/dm-validations.rb
  301. +4 0 dm-validations/lib/dm-validations/confirmation_validator.rb
  302. +1 1  dm-validations/lib/dm-validations/length_validator.rb
  303. +1 1  dm-validations/lib/dm-validations/uniqueness_validator.rb
  304. +5 0 dm-validations/lib/dm-validations/version.rb
  305. +1 1  dm-validations/spec/integration/acceptance_validator_spec.rb
  306. +42 6 dm-validations/spec/integration/confirmation_validator_spec.rb
  307. +2 0  dm-validations/spec/integration/length_validator_spec.rb
  308. +13 0 dm-validations/spec/integration/validation_spec.rb
  309. +1 0  dm-validations/spec/spec_helper.rb
  310. +5 0 lib/dm-more/version.rb
Sorry, we could not display the entire diff because too many files (347) changed.
1  History.txt
... ... @@ -0,0 +1 @@
  1 +
9 Manifest.txt
... ... @@ -0,0 +1,9 @@
  1 +History.txt
  2 +MIT-LICENSE
  3 +Manifest.txt
  4 +README.textile
  5 +README.txt
  6 +Rakefile
  7 +TODO
  8 +lib/dm-more.rb
  9 +lib/dm-more/version.rb
0  README → README.txt
File renamed without changes
65 Rakefile
... ... @@ -1,22 +1,10 @@
1   -module DataMapper
2   - # Set this to the version of dm-core that you are building against/for
3   - VERSION = "0.9.3"
4   -
5   - # Set this to the version of dm-more you plan to release
6   - MORE_VERSION = "0.9.3"
7   -end
8   -
9 1 require 'pathname'
10   -require 'rake/clean'
11   -require 'rake/gempackagetask'
12   -require 'rake/contrib/rubyforgepublisher'
13 2 require 'spec/rake/spectask'
14 3 require 'rake/rdoctask'
15 4 require 'fileutils'
  5 +require 'lib/dm-more/version.rb'
16 6 include FileUtils
17 7
18   -DIR = Pathname(__FILE__).dirname.expand_path.to_s
19   -
20 8 ## ORDER IS IMPORTANT
21 9 # gems may depend on other member gems of dm-more
22 10 gem_paths = %w[
@@ -41,48 +29,34 @@ gem_paths = %w[
41 29 ]
42 30 gems = gem_paths.map { |p| File.basename(p) }
43 31
44   -PROJECT = "dm-more"
45   -
46   -dm_more_spec = Gem::Specification.new do |s|
47   - s.platform = Gem::Platform::RUBY
48   - s.name = PROJECT
49   - s.summary = "An Object/Relational Mapper for Ruby"
50   - s.description = "Faster, Better, Simpler."
51   - s.version = DataMapper::MORE_VERSION
52   -
53   - s.authors = "Sam Smoot"
54   - s.email = "ssmoot@gmail.com"
55   - s.rubyforge_project = PROJECT
56   - s.homepage = "http://datamapper.org"
57   -
58   - s.files = %w[ MIT-LICENSE README Rakefile TODO lib/dm-more.rb ]
59   - s.add_dependency('dm-core', "=#{DataMapper::VERSION}")
60   - s.add_dependency('merb_datamapper', '=0.9.3')
61   - (gems - %w[ merb_datamapper ]).each do |gem|
62   - s.add_dependency gem, "=#{DataMapper::VERSION}"
63   - end
64   -end
  32 +ROOT = Pathname(__FILE__).dirname.expand_path
65 33
66   -Rake::GemPackageTask.new(dm_more_spec) do |p|
67   - p.gem_spec = dm_more_spec
68   - p.need_tar = true
69   - p.need_zip = true
70   -end
  34 +AUTHOR = "Sam Smoot"
  35 +EMAIL = "ssmoot@gmail.com"
  36 +GEM_NAME = "dm-more"
  37 +GEM_VERSION = DataMapper::More::VERSION
  38 +GEM_DEPENDENCIES = [["dm-core", GEM_VERSION], *(gems - %w[ merb_datamapper ]).collect { |g| [g, GEM_VERSION] }]
  39 +GEM_CLEAN = ['**/*.{gem,DS_Store}', '*.db', "doc/rdoc", ".config", "coverage", "cache", "lib/merb-more.rb"]
  40 +GEM_EXTRAS = { :has_rdoc => false }
  41 +
  42 +PROJECT_NAME = "dm-more"
  43 +PROJECT_URL = "http://datamapper.org"
  44 +PROJECT_DESCRIPTION = "Faster, Better, Simpler."
  45 +PROJECT_SUMMARY = "An Object/Relational Mapper for Ruby"
71 46
72   -CLEAN.include ["**/.*.sw?", "pkg", "lib/*.bundle", "*.gem", "doc/rdoc", ".config", "coverage", "cache", "lib/merb-more.rb"]
  47 +require ROOT + 'tasks/hoe'
73 48
74 49 WIN32 = (RUBY_PLATFORM =~ /win32|mingw|cygwin/) rescue nil
75 50 SUDO = WIN32 ? '' : ('sudo' unless ENV['SUDOLESS'])
76 51
77 52 desc "Install it all"
78 53 task :install => [:install_gems, :package] do
79   - sh %{#{SUDO} gem install --local pkg/dm-more-#{DataMapper::MORE_VERSION}.gem --no-update-sources}
80   -# sh %{#{SUDO} gem install --local pkg/dm-#{DataMapper::MORE_VERSION}.gem --no-update-sources}
  54 + sh %{#{SUDO} gem install --local pkg/dm-more-#{DataMapper::More::VERSION}.gem --no-update-sources}
81 55 end
82 56
83 57 desc "Uninstall it all"
84 58 task :uninstall => [ :uninstall_gems, :clobber ] do
85   - sh "#{SUDO} gem uninstall dm-more -v#{DataMapper::MORE_VERSION} -I -x", :verbose => false rescue "dm-more not installed"
  59 + sh "#{SUDO} gem uninstall dm-more -v#{DataMapper::More::VERSION} -I -x", :verbose => false rescue "dm-more not installed"
86 60 end
87 61
88 62 desc "Build the dm-more gems"
@@ -122,8 +96,7 @@ end
122 96 desc "Bundle up all the dm-more gems"
123 97 task :bundle => [:package, :build_gems] do
124 98 mkdir_p "bundle"
125   -# cp "pkg/dm-#{DataMapper::MORE_VERSION}.gem", "bundle"
126   - cp "pkg/dm-more-#{DataMapper::MORE_VERSION}.gem", "bundle"
  99 + cp "pkg/dm-more-#{DataMapper::More::VERSION}.gem", "bundle"
127 100 gem_paths.each do |gem|
128 101 File.open("#{gem}/Rakefile") do |rakefile|
129 102 rakefile.read.detect {|l| l =~ /^VERSION\s*=\s*"(.*)"$/ }
@@ -176,7 +149,7 @@ namespace :ci do
176 149 gem_names.each do |gem_name|
177 150 Spec::Rake::SpecTask.new("#{gem_name}:spec") do |t|
178 151 t.spec_opts = ["--format", "specdoc", "--format", "html:rspec_report.html", "--diff"]
179   - t.spec_files = Pathname.glob(ENV['FILES'] || DIR + "/#{gem_name}/spec/**/*_spec.rb")
  152 + t.spec_files = Pathname.glob(ENV['FILES'] || ROOT + "/#{gem_name}/spec/**/*_spec.rb")
180 153 unless ENV['NO_RCOV']
181 154 t.rcov = true
182 155 t.rcov_opts << '--exclude' << "spec,gems,#{(gems - [gem_name]).join(',')}"
2  adapters/dm-couchdb-adapter/.gitignore
... ... @@ -0,0 +1,2 @@
  1 +couchdb.stderr
  2 +couchdb.stdout
1  adapters/dm-couchdb-adapter/History.txt
... ... @@ -0,0 +1 @@
  1 +
13 adapters/dm-couchdb-adapter/Manifest.txt
... ... @@ -0,0 +1,13 @@
  1 +History.txt
  2 +LICENSE
  3 +Manifest.txt
  4 +README.txt
  5 +Rakefile
  6 +TODO
  7 +lib/couchdb_adapter.rb
  8 +lib/couchdb_adapter/json_object.rb
  9 +lib/couchdb_adapter/version.rb
  10 +lib/couchdb_adapter/view.rb
  11 +spec/couchdb_adapter_spec.rb
  12 +spec/couchdb_view_spec.rb
  13 +spec/spec.opts
4 adapters/dm-couchdb-adapter/README
... ... @@ -1,4 +0,0 @@
1   -dm-couchdb-adapter
2   -==================
3   -
4   -A DataMapper adapter for CouchDB
27 adapters/dm-couchdb-adapter/README.txt
... ... @@ -0,0 +1,27 @@
  1 +This is a datamapper adapter to couchdb.
  2 +
  3 +== Setup
  4 +Install with the rest of the dm-more package, using:
  5 + gem install dm-more
  6 +
  7 +Then when initializing datamapper:
  8 + - adapter should be :couchdb
  9 + - database should be the name of the couch adapter
  10 + - host (probably localhost)
  11 + - port should be specified (couchdb defaults to port 5984)
  12 +
  13 +You should now be able to use resources and their properties and have them stored to couchdb.
  14 +
  15 +== Views
  16 +Special consideration has been made to help work with couch views. You can define them in the model using the view function and then use Model.auto_migrate! to add the views for Model to the database, or DataMapper.auto_migrate! to add the views for all models to the database.
  17 +
  18 +An example class with views defined:
  19 +
  20 +class User
  21 + include DataMapper::Resource
  22 +
  23 + property :name, String
  24 + view :by_name, "function(doc) { if (doc.type == 'user') map(doc.name, doc) }"
  25 +end
  26 +
  27 +You could then call User.by_name to get a listing of users ordered by name, or pass a key to try and find a specific user by their name, ie User.by_name(:key => 'username').
47 adapters/dm-couchdb-adapter/Rakefile
... ... @@ -1,45 +1,38 @@
1 1 require 'rubygems'
2 2 require 'spec'
3   -require 'rake/clean'
4   -require 'rake/gempackagetask'
5 3 require 'spec/rake/spectask'
6 4 require 'pathname'
7 5
8   -CLEAN.include '{log,pkg}/'
9   -
10   -spec = Gem::Specification.new do |s|
11   - s.name = 'dm-couchdb-adapter'
12   - s.version = '0.9.3'
13   - s.platform = Gem::Platform::RUBY
14   - s.has_rdoc = true
15   - s.extra_rdoc_files = %w[ README LICENSE TODO ]
16   - s.summary = 'CouchDB Adapter for DataMapper'
17   - s.description = s.summary
18   - s.author = 'Bernerd Schaefer'
19   - s.email = 'bj.schaefer@gmail.com'
20   - s.homepage = 'http://github.com/sam/dm-more/tree/master/adapters/dm-couchdb-adapter'
21   - s.require_path = 'lib'
22   - s.files = FileList[ '{lib,spec}/**/*.rb', 'spec/spec.opts', 'Rakefile', *s.extra_rdoc_files ]
23   - s.add_dependency('dm-core', "=#{s.version}")
24   -end
  6 +ROOT = Pathname(__FILE__).dirname.expand_path
  7 +require ROOT + 'lib/couchdb_adapter/version'
  8 +
  9 +AUTHOR = "Bernerd Schaefer"
  10 +EMAIL = "bj.schaefer@gmail.com"
  11 +GEM_NAME = "dm-couchdb-adapter"
  12 +GEM_VERSION = DataMapper::More::CouchDBAdapter::VERSION
  13 +GEM_DEPENDENCIES = [["dm-core", GEM_VERSION]]
  14 +GEM_CLEAN = ["log", "pkg"]
  15 +GEM_EXTRAS = { :has_rdoc => true, :extra_rdoc_files => %w[ README.txt LICENSE TODO ] }
  16 +
  17 +PROJECT_NAME = "dm-more"
  18 +PROJECT_URL = "http://github.com/sam/dm-more/tree/master/adapters/dm-couchdb-adapter"
  19 +PROJECT_DESCRIPTION = PROJECT_SUMMARY = "CouchDB Adapter for DataMapper"
  20 +
  21 +require ROOT.parent.parent + 'tasks/hoe'
25 22
26 23 task :default => [ :spec ]
27 24
28 25 WIN32 = (RUBY_PLATFORM =~ /win32|mingw|cygwin/) rescue nil
29 26 SUDO = WIN32 ? '' : ('sudo' unless ENV['SUDOLESS'])
30 27
31   -Rake::GemPackageTask.new(spec) do |pkg|
32   - pkg.gem_spec = spec
33   -end
34   -
35   -desc "Install #{spec.name} #{spec.version}"
  28 +desc "Install #{GEM_NAME} #{GEM_VERSION}"
36 29 task :install => [ :package ] do
37   - sh "#{SUDO} gem install --local pkg/#{spec.name}-#{spec.version} --no-update-sources", :verbose => false
  30 + sh "#{SUDO} gem install --local pkg/#{GEM_NAME}-#{GEM_VERSION} --no-update-sources", :verbose => false
38 31 end
39 32
40   -desc "Uninstall #{spec.name} #{spec.version} (default ruby)"
  33 +desc "Uninstall #{GEM_NAME} #{GEM_VERSION} (default ruby)"
41 34 task :uninstall => [ :clobber ] do
42   - sh "#{SUDO} gem uninstall #{spec.name} -v#{spec.version} -I -x", :verbose => false
  35 + sh "#{SUDO} gem uninstall #{GEM_NAME} -v#{GEM_VERSION} -I -x", :verbose => false
43 36 end
44 37
45 38 desc 'Run specifications'
223 adapters/dm-couchdb-adapter/lib/couchdb_adapter.rb
... ... @@ -1,12 +1,14 @@
1 1 require 'rubygems'
2   -gem 'dm-core', '=0.9.3'
3   -require 'base64'
  2 +require 'pathname'
  3 +require Pathname(__FILE__).dirname + 'couchdb_adapter/version'
  4 +gem 'dm-core', DataMapper::More::CouchDBAdapter::VERSION
4 5 require 'dm-core'
  6 +require 'base64'
5 7 require 'json'
6 8 require 'net/http'
7   -require 'pathname'
8 9 require 'uri'
9   -require Pathname(__FILE__).dirname + 'couchdb_views'
  10 +require Pathname(__FILE__).dirname + 'couchdb_adapter/json_object'
  11 +require Pathname(__FILE__).dirname + 'couchdb_adapter/view'
10 12
11 13 module DataMapper
12 14 module Resource
@@ -15,10 +17,12 @@ def to_json(dirty = false)
15 17 property_list = self.class.properties.select { |key, value| dirty ? self.dirty_attributes.key?(key) : true }
16 18 inferred_fields = {:type => self.class.name.downcase}
17 19 return (property_list.inject(inferred_fields) do |accumulator, property|
18   - accumulator[property.field] = instance_variable_get(property.instance_variable_name)
19   - if property.type == Object
20   - accumulator[property.field] = Base64.encode64(Marshal.dump(accumulator[property.field]))
21   - end
  20 + accumulator[property.field] =
  21 + unless property.type.respond_to?(:dump)
  22 + property.get!(self)
  23 + else
  24 + property.type.dump(property.get!(self), property)
  25 + end
22 26 accumulator
23 27 end).to_json
24 28 end
@@ -26,12 +30,6 @@ def to_json(dirty = false)
26 30 end
27 31
28 32 module DataMapper
29   - class Query
30   - attr_accessor :view
31   - end
32   -end
33   -
34   -module DataMapper
35 33 module Adapters
36 34 class CouchDBAdapter < AbstractAdapter
37 35 # Returns the name of the CouchDB database.
@@ -56,7 +54,14 @@ def escaped_db_name
56 54 def create(resources)
57 55 created = 0
58 56 resources.each do |resource|
59   - result = http_post("/#{self.escaped_db_name}", resource.to_json(true))
  57 + key = resource.class.key(self.name).map do |property|
  58 + resource.instance_variable_get(property.instance_variable_name)
  59 + end
  60 + if key.compact.empty?
  61 + result = http_post("/#{self.escaped_db_name}", resource.to_json(true))
  62 + else
  63 + result = http_put("/#{self.escaped_db_name}/#{key}", resource.to_json(true))
  64 + end
60 65 if result["ok"]
61 66 key = resource.class.key(self.name)
62 67 if key.size == 1
@@ -113,11 +118,29 @@ def read_many(query)
113 118 doc = request do |http|
114 119 http.request(build_request(query))
115 120 end
116   - Collection.new(query) do |collection|
117   - doc['rows'].each do |doc|
  121 + if doc['rows']
  122 + if doc['rows'].empty?
  123 + []
  124 + elsif query.view && query.model.views[query.view.to_sym].has_key?('reduce')
  125 + doc['rows']
  126 + else
  127 + Collection.new(query) do |collection|
  128 + doc['rows'].each do |doc|
  129 + data = doc["value"]
  130 + collection.load(
  131 + query.fields.map do |property|
  132 + data[property.field.to_s]
  133 + end
  134 + )
  135 + end
  136 + end
  137 + end
  138 + elsif doc['type'] && doc['type'].downcase == query.model.name.downcase
  139 + data = doc
  140 + Collection.new(query) do |collection|
118 141 collection.load(
119 142 query.fields.map do |property|
120   - property.typecast(doc["value"][property.field.to_s])
  143 + data[property.field.to_s]
121 144 end
122 145 )
123 146 end
@@ -128,52 +151,46 @@ def read_one(query)
128 151 doc = request do |http|
129 152 http.request(build_request(query))
130 153 end
131   - unless doc["total_rows"] == 0
132   - data = doc['rows'].first
  154 + if doc['rows'] && !doc['rows'].empty?
  155 + data = doc['rows'].first['value']
  156 + elsif !doc['rows']
  157 + data = doc if doc['type'] && doc['type'].downcase == query.model.name.downcase
  158 + end
  159 + if data
133 160 query.model.load(
134 161 query.fields.map do |property|
135   - data["value"][property.field.to_s]
  162 + data[property.field.to_s]
136 163 end,
137   - query)
  164 + query
  165 + )
138 166 end
139 167 end
140 168
141   - # Reads in a set from a stored view.
142   - def view(resource, proc_name, options = {})
143   - query = Query.new(repository, resource)
144   - query.view = { :name => proc_name }.merge!(options)
145   - read_many(query)
146   - end
147   -
148 169 protected
149   - # Converts the URI's scheme into a parsed HTTP identifier.
150   - def normalize_uri(uri_or_options)
151   - if String === uri_or_options
152   - uri_or_options = Addressable::URI.parse(uri_or_options)
153   - end
154   - if Addressable::URI === uri_or_options
155   - return uri_or_options.normalize
  170 + def build_request(query)
  171 + if query.view
  172 + view_request(query)
  173 + elsif query.conditions.length == 1 &&
  174 + query.conditions.first[0] == :eql &&
  175 + query.conditions.first[1].key?
  176 + get_request(query)
  177 + else
  178 + ad_hoc_request(query)
156 179 end
  180 + end
157 181
158   - user = uri_or_options.delete(:username)
159   - password = uri_or_options.delete(:password)
160   - host = (uri_or_options.delete(:host) || "")
161   - port = uri_or_options.delete(:port)
162   - database = uri_or_options.delete(:database)
163   - query = uri_or_options.to_a.map { |pair| pair.join('=') }.join('&')
164   - query = nil if query == ""
165   -
166   - return Addressable::URI.new(
167   - "http", user, password, host, port, database, query, nil
168   - )
  182 + def view_request(query)
  183 + uri = "/#{self.escaped_db_name}/" +
  184 + "_view/" +
  185 + "#{query.model.storage_name(self.name)}/" +
  186 + "#{query.view}" +
  187 + "#{query_string(query)}"
  188 + request = Net::HTTP::Get.new(uri)
169 189 end
170 190
171   - def build_request(query)
172   - unless query.view
173   - ad_hoc_request(query)
174   - else
175   - view_request(query)
176   - end
  191 + def get_request(query)
  192 + uri = "/#{self.escaped_db_name}/#{query.conditions.first[2]}"
  193 + request = Net::HTTP::Get.new(uri)
177 194 end
178 195
179 196 def ad_hoc_request(query)
@@ -186,65 +203,69 @@ def ad_hoc_request(query)
186 203 key = "[#{key}]"
187 204 end
188 205
189   - options = []
190   - options << "count=#{query.limit}" if query.limit
191   - options << "skip=#{query.offset}" if query.offset
192   - options = options.empty? ? nil : "?#{options.join('&')}"
193   -
194   - request = Net::HTTP::Post.new("/#{self.escaped_db_name}/_temp_view#{options}")
195   - request["Content-Type"] = "text/javascript"
  206 + request = Net::HTTP::Post.new("/#{self.escaped_db_name}/_temp_view#{query_string(query)}")
  207 + request["Content-Type"] = "application/json"
196 208
197 209 if query.conditions.empty?
198 210 request.body =
199   - "function(doc) {\n" +
200   - " if (doc.type == '#{query.model.name.downcase}') {\n" +
201   - " map(#{key}, doc);\n" +
202   - " }\n" +
203   - "}\n"
  211 +%Q({"map":
  212 + "function(doc) {
  213 + if (doc.type == '#{query.model.name.downcase}') {
  214 + emit(#{key}, doc);
  215 + }
  216 + }"
  217 +}
  218 +)
204 219 else
205 220 conditions = query.conditions.map do |operator, property, value|
206   - condition = "doc.#{property.field}"
207   - condition << case operator
208   - when :eql then " == #{value.to_json}"
209   - when :not then " != #{value.to_json}"
210   - when :gt then " > #{value.to_json}"
211   - when :gte then " >= #{value.to_json}"
212   - when :lt then " < #{value.to_json}"
213   - when :lte then " <= #{value.to_json}"
214   - when :like then like_operator(value)
  221 + if operator == :eql && value.is_a?(Array)
  222 + value.map do |sub_value|
  223 + json_sub_value = sub_value.to_json.gsub("\"", "'")
  224 + "doc.#{property.field} == #{json_sub_value}"
  225 + end.join(" || ")
  226 + else
  227 + json_value = value.to_json.gsub("\"", "'")
  228 + condition = "doc.#{property.field}"
  229 + condition << case operator
  230 + when :eql then " == #{json_value}"
  231 + when :not then " != #{json_value}"
  232 + when :gt then " > #{json_value}"
  233 + when :gte then " >= #{json_value}"
  234 + when :lt then " < #{json_value}"
  235 + when :lte then " <= #{json_value}"
  236 + when :like then like_operator(value)
  237 + end
215 238 end
216 239 end
217   - body = <<-JS
218   - function(doc) {
219   - if (doc.type == '#{query.model.name.downcase}') {
220   - if (#{conditions.join(" && ")}) {
221   - map(#{key}, doc);
222   - }
223   - }
224   - }
225   - JS
226   - space = body.split("\n")[0].to_s[/^(\s+)/, 0]
227   - request.body = body.gsub(/^#{space}/, '')
  240 + request.body =
  241 +%Q({"map":
  242 + "function(doc) {
  243 + if (doc.type == '#{query.model.name.downcase}' && #{conditions.join(" && ")}) {
  244 + emit(#{key}, doc);
  245 + }
  246 + }"
  247 +}
  248 +)
228 249 end
229 250 request
230 251 end
231 252
232   - def view_request(query)
233   - options = query.view.dup
234   - proc_name = options.delete(:name)
235   - options[:count] = query.limit if query.limit
236   - options[:skip] = query.offset if query.offset
237   - if options.empty?
238   - options = ''
239   - else
240   - options = "?" + options.to_a.map {|option| "#{option[0]}=#{option[1].to_json}"}.join("&")
  253 + def query_string(query)
  254 + query_string = []
  255 + if query.view_options
  256 + query_string +=
  257 + query.view_options.map do |key, value|
  258 + if [:endkey, :key, :startkey].include? key
  259 + URI.escape(%Q(#{key}=#{value.to_json}))
  260 + else
  261 + URI.escape("#{key}=#{value}")
  262 + end
  263 + end
241 264 end
242   - uri = "/#{self.escaped_db_name}/" +
243   - "_view/" +
244   - "#{query.model.storage_name(self.name)}/" +
245   - "#{proc_name}" +
246   - "#{options}"
247   - request = Net::HTTP::Get.new(uri)
  265 + query_string << "count=#{query.limit}" if query.limit
  266 + query_string << "descending=#{query.add_reversed?}" if query.add_reversed?
  267 + query_string << "skip=#{query.offset}" if query.offset != 0
  268 + query_string.empty? ? nil : "?#{query_string.join('&')}"
248 269 end
249 270
250 271 def like_operator(value)
@@ -290,7 +311,7 @@ def create_model_storage(repository, model)
290 311 view = Net::HTTP::Put.new(uri)
291 312 view['content-type'] = "text/javascript"
292 313 views = model.views.reject {|key, value| value.nil?}
293   - view.body = { :views => model.views }.to_json
  314 + view.body = { :views => views }.to_json
294 315
295 316 request do |http|
296 317 http.request(view)
35 adapters/dm-couchdb-adapter/lib/couchdb_adapter/json_object.rb
... ... @@ -0,0 +1,35 @@
  1 +require 'json'
  2 +
  3 +# Non-lazy objects that serialize to/from JSON, for use with couchdb
  4 +module DataMapper
  5 + module Types
  6 + class JsonObject < DataMapper::Type
  7 + primitive String
  8 + size 65535
  9 +
  10 + def self.load(value, property)
  11 + if value.nil?
  12 + nil
  13 + elsif value.is_a?(String)
  14 + ::JSON.load(value)
  15 + else
  16 + raise ArgumentError.new("+value+ must be nil or a String")
  17 + end
  18 + end
  19 +
  20 + def self.dump(value, property)
  21 + if value.nil?
  22 + nil
  23 + elsif value.is_a?(String)
  24 + value
  25 + else
  26 + ::JSON.dump(value)
  27 + end
  28 + end
  29 +
  30 + def self.typecast(value, property)
  31 + value
  32 + end
  33 + end # class JsonObject
  34 + end # module Types
  35 +end # module DataMapper
7 adapters/dm-couchdb-adapter/lib/couchdb_adapter/version.rb
... ... @@ -0,0 +1,7 @@
  1 +module DataMapper
  2 + module More
  3 + class CouchDBAdapter
  4 + VERSION = "0.9.3"
  5 + end
  6 + end
  7 +end
55 adapters/dm-couchdb-adapter/lib/couchdb_adapter/view.rb
... ... @@ -0,0 +1,55 @@
  1 +module DataMapper
  2 + class Query
  3 + attr_accessor :view, :view_options
  4 + end
  5 +end
  6 +
  7 +module DataMapper
  8 + class View
  9 + attr_reader :model, :name
  10 +
  11 + def initialize(model, name)
  12 + @model = model
  13 + @name = name
  14 +
  15 + create_getter
  16 + end
  17 +
  18 + def create_getter
  19 + @model.class_eval <<-EOS, __FILE__, __LINE__
  20 + def self.#{@name}(*args)
  21 + options = {}
  22 + if args.size == 1 && !args.first.is_a?(Hash)
  23 + options[:key] = args.shift
  24 + else
  25 + options = args.pop
  26 + end
  27 + query = Query.new(repository, self)
  28 + query.view_options = options
  29 + query.view = '#{@name}'
  30 + if options.is_a?(Hash) && options.has_key?(:repository)
  31 + repository(options.delete(:repository)).read_many(query)
  32 + else
  33 + repository.read_many(query)
  34 + end
  35 + end
  36 + EOS
  37 + end
  38 + end
  39 +end
  40 +
  41 +module DataMapper
  42 + module Model
  43 + def view(name, body = nil)
  44 + @views ||= Hash.new { |h,k| h[k] = {} }
  45 + proc = View.new(self, name)
  46 + @views[repository.name][name] = body
  47 + proc
  48 + end
  49 +
  50 + def views(repository_name = default_repository_name)
  51 + @views ||= Hash.new { |h,k| h[k] = {} }
  52 + @views[repository_name]
  53 + end
  54 + end
  55 +end
87 adapters/dm-couchdb-adapter/lib/couchdb_views.rb
... ... @@ -1,87 +0,0 @@
1   -# This provides a mechanism for accessing stored and indexed views
2   -# in the CouchDB database.
3   -#
4   -# Here's a sample model:
5   -#
6   -# class User
7   -# include DataMapper::Resource
8   -#
9   -# property :id, String, :key => true, :field => :_id
10   -# property :rev, String, :field => :_rev
11   -#
12   -# view :by_name
13   -# end
14   -#
15   -# And here's the DM code to generate the view:
16   -#
17   -# view = Net::HTTP::Put.new("/example_db/_design/users")
18   -# view["content-type"] = "text/javascript"
19   -# view.body = {
20   -# "language" => "text/javascript",
21   -# "views" => {
22   -# "by_name" => "function(doc) { map(doc.name, doc); }"
23   -# }
24   -# }.to_json
25   -# @adapter.send(:request, false) do |http|
26   -# http.request(view)
27   -# end
28   -#
29   -
30   -module DataMapper
31   - class Repository
32   - def view(model, name, options = {})
33   - adapter.view(model, name, options)
34   - end
35   - end
36   -end
37   -
38   -module DataMapper
39   - module Adapters
40   - class AbstractAdapter
41   - def view(resource, proc_name, options = {})
42   - raise NotImplementedError
43   - end
44   - end
45   - end
46   -end
47   -
48   -module DataMapper
49   - class View
50   - attr_reader :model, :name
51   -
52   - def initialize(model, name)
53   - @model = model
54   - @name = name
55   -
56   - create_getter
57   - end
58   -
59   - def create_getter
60   - @model.class_eval <<-EOS, __FILE__, __LINE__
61   - def self.#{@name}(options = {})
62   - if Hash === options && options.has_key?(:repository)
63   - repository(options.delete(:repository)).view(self, :#{@name}, options)
64   - else
65   - repository.view(self, :#{@name}, options)
66   - end
67   - end
68   - EOS
69   - end
70   - end
71   -end
72   -
73   -module DataMapper
74   - module Model
75   - def view(name, body = nil)
76   - @views ||= Hash.new { |h,k| h[k] = {} }
77   - proc = View.new(self, name)
78   - @views[repository.name][name] = body
79   - proc
80   - end
81   -
82   - def views(repository_name = default_repository_name)
83   - @views ||= Hash.new { |h,k| h[k] = {} }
84   - @views[repository_name]
85   - end
86   - end
87   -end
45 adapters/dm-couchdb-adapter/spec/couchdb_adapter_spec.rb
@@ -19,10 +19,13 @@ class User
19 19 property :wealth, Float
20 20 property :created_at, DateTime
21 21 property :created_on, Date
  22 + property :location, JsonObject
22 23
23 24 # creates methods for accessing stored/indexed views in the CouchDB database
24   - view :by_name, "function(doc) { if (doc.type == 'user') { map(doc.name, doc); } }"
25   - view :by_age, "function(doc) { if (doc.type == 'user') { map(doc.age, doc); } }"
  25 + view :by_name, { "map" => "function(doc) { if (doc.type == 'user') { emit(doc.name, doc); } }" }
  26 + view :by_age, { "map" => "function(doc) { if (doc.type == 'user') { emit(doc.age, doc); } }" }
  27 + view :count, { "map" => "function(doc) { if (doc.type == 'user') { emit(null, 1); } }",
  28 + "reduce" => "function(keys, values) { return sum(values); }" }
26 29
27 30 before :create do
28 31 self.created_at = DateTime.now
@@ -73,6 +76,15 @@ class Company
73 76 company.id.should_not == nil
74 77 end
75 78
  79 + it "should create a record with a specified id" do
  80 + pending("No CouchDB connection.") if @no_connection
  81 + user_with_id = new_user
  82 + user_with_id.id = 'user_id'
  83 + user_with_id.save.should == true
  84 + User.get!('user_id').should == user_with_id
  85 + user_with_id.destroy
  86 + end
  87 +
76 88 it "should get a record" do
77 89 pending("No CouchDB connection.") if @no_connection
78 90 created_user = new_user
@@ -83,6 +95,12 @@ class Company
83 95 user.age.should == 67
84 96 end
85 97
  98 + it "should not get records of the wrong type by id" do
  99 + pending("No CouchDB connection.") if @no_connection
  100 + Company.get(new_user.id).should == nil
  101 + lambda { Company.get!(new_user.id) }.should raise_error(DataMapper::ObjectNotFoundError)
  102 + end
  103 +
86 104 it "should update a record" do
87 105 pending("No CouchDB connection.") if @no_connection
88 106 created_user = new_user
@@ -182,14 +200,37 @@ class Company
182 200 User.get!(user.id).created_on.should == date
183 201 end
184 202
  203 + it "should handle JsonObject" do
  204 + pending("No CouchDB connection.") if @no_connection
  205 + user = new_user
  206 + location = { 'city' => 'San Francisco', 'state' => 'California' }
  207 + user.location = location
  208 + user.save
  209 + User.get!(user.id).location.should == location
  210 + end
  211 +
185 212 it "should be able to call stored views" do
186 213 pending("No CouchDB connection.") if @no_connection
187 214 User.by_name.first.should == User.all(:order => [:name]).first
188 215 User.by_age.first.should == User.all(:order => [:age]).first
189 216 end
190 217
  218 + it "should be able to call stored views with keys" do
  219 + pending("No CouchDB connection.") if @no_connection
  220 + User.by_name("Aaron").first == User.all(:name => "Aaron").first
  221 + User.by_age(30).first == User.all(:age => 30).first
  222 + User.by_name("Aaron").first == User.by_name(:key => "Aaron").first
  223 + User.by_age(30).first == User.by_age(:key => 30).first
  224 + end
  225 +
  226 + it "should return a value from a view with reduce defined" do
  227 + pending("No CouchDB connection.") if @no_connection
  228 + User.count.should == [ { "value" => User.all.length, "key" => nil } ]
  229 + end
  230 +
191 231 def create_procedures
192 232 DataMapper.auto_migrate!
  233 + DataMapper.auto_migrate!
193 234 end
194 235
195 236 def new_user(options = {})
13 adapters/dm-couchdb-adapter/spec/couchdb_view_spec.rb
@@ -38,16 +38,3 @@ def self.default_repository_name
38 38 Zoo.should respond_to(:open)
39 39 end
40 40 end
41   -
42   -describe DataMapper::Repository do
43   - it "should define a view method" do
44   - repository(:couchdb).should respond_to(:view)
45   - end
46   -end
47   -
48   -describe DataMapper::Adapters::AbstractAdapter do
49   - it "should have a view method" do
50   - DataMapper::Adapters::AbstractAdapter.
51   - instance_methods.should include("view")
52   - end
53   -end
1  adapters/dm-rest-adapter/History.txt
... ... @@ -0,0 +1 @@
  1 +
26 adapters/dm-rest-adapter/Manifest.txt
... ... @@ -0,0 +1,26 @@
  1 +History.txt
  2 +LICENSE
  3 +Manifest.txt
  4 +README.txt
  5 +Rakefile
  6 +TODO
  7 +lib/rest_adapter.rb
  8 +lib/rest_adapter/version.rb
  9 +spec/create_spec.rb
  10 +spec/delete_spec.rb
  11 +spec/read_spec.rb
  12 +spec/ruby_forker.rb
  13 +spec/spec.opts
  14 +spec/spec_helper.rb
  15 +spec/update_spec.rb
  16 +stories/all.rb
  17 +stories/crud/create
  18 +stories/crud/delete
  19 +stories/crud/read
  20 +stories/crud/stories.rb
  21 +stories/crud/update
  22 +stories/helper.rb
  23 +stories/resources/helpers/book.rb
  24 +stories/resources/helpers/story_helper.rb
  25 +stories/resources/steps/read.rb
  26 +stories/resources/steps/using_rest_adapter.rb
3  adapters/dm-rest-adapter/README → adapters/dm-rest-adapter/README.txt
... ... @@ -1,4 +1,3 @@
1   -dm-rest-adapter
2   -==================
  1 += dm-rest-adapter
3 2
4 3 A DataMapper adapter for REST Web Services
44 adapters/dm-rest-adapter/Rakefile