dbagile 0.0.1

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 (305) hide show
  1. data/LICENCE.textile +12 -0
  2. data/README.textile +89 -0
  3. data/bin/dba +22 -0
  4. data/lib/dbagile/adapter/sequel/class_methods.rb +18 -0
  5. data/lib/dbagile/adapter/sequel/connection.rb +38 -0
  6. data/lib/dbagile/adapter/sequel/data/table_driven.rb +30 -0
  7. data/lib/dbagile/adapter/sequel/data/transaction_driven.rb +43 -0
  8. data/lib/dbagile/adapter/sequel/schema/concrete_script.rb +135 -0
  9. data/lib/dbagile/adapter/sequel/schema/physical_dump.rb +106 -0
  10. data/lib/dbagile/adapter/sequel/schema/schema2sequel_args.rb +71 -0
  11. data/lib/dbagile/adapter/sequel/schema/table_driven.rb +52 -0
  12. data/lib/dbagile/adapter/sequel/schema/transaction_driven.rb +46 -0
  13. data/lib/dbagile/adapter/sequel/sequel_tracer.rb +144 -0
  14. data/lib/dbagile/adapter/sequel.rb +46 -0
  15. data/lib/dbagile/adapter.rb +15 -0
  16. data/lib/dbagile/command/api.rb +49 -0
  17. data/lib/dbagile/command/bulk/commons.rb +130 -0
  18. data/lib/dbagile/command/bulk/export.rb +99 -0
  19. data/lib/dbagile/command/bulk/import.rb +147 -0
  20. data/lib/dbagile/command/bulk.rb +3 -0
  21. data/lib/dbagile/command/class_methods.rb +103 -0
  22. data/lib/dbagile/command/db/add.rb +94 -0
  23. data/lib/dbagile/command/db/list.rb +40 -0
  24. data/lib/dbagile/command/db/ping.rb +49 -0
  25. data/lib/dbagile/command/db/rm.rb +52 -0
  26. data/lib/dbagile/command/db/stage.rb +81 -0
  27. data/lib/dbagile/command/db/use.rb +48 -0
  28. data/lib/dbagile/command/db.rb +6 -0
  29. data/lib/dbagile/command/dba.rb +121 -0
  30. data/lib/dbagile/command/help.rb +50 -0
  31. data/lib/dbagile/command/repo/create.rb +54 -0
  32. data/lib/dbagile/command/repo.rb +1 -0
  33. data/lib/dbagile/command/robust.rb +86 -0
  34. data/lib/dbagile/command/schema/check.rb +59 -0
  35. data/lib/dbagile/command/schema/commons.rb +118 -0
  36. data/lib/dbagile/command/schema/diff.rb +101 -0
  37. data/lib/dbagile/command/schema/dump.rb +48 -0
  38. data/lib/dbagile/command/schema/merge.rb +55 -0
  39. data/lib/dbagile/command/schema/sql_script.rb +124 -0
  40. data/lib/dbagile/command/schema.rb +6 -0
  41. data/lib/dbagile/command/sql/drop.rb +40 -0
  42. data/lib/dbagile/command/sql/heading.rb +34 -0
  43. data/lib/dbagile/command/sql/send.rb +67 -0
  44. data/lib/dbagile/command/sql/show.rb +42 -0
  45. data/lib/dbagile/command/sql.rb +4 -0
  46. data/lib/dbagile/command/web/tools.rb +23 -0
  47. data/lib/dbagile/command/web.rb +1 -0
  48. data/lib/dbagile/command.rb +158 -0
  49. data/lib/dbagile/contract/connection.rb +66 -0
  50. data/lib/dbagile/contract/data/dataset.rb +69 -0
  51. data/lib/dbagile/contract/data/table_driven.rb +49 -0
  52. data/lib/dbagile/contract/data/transaction_driven.rb +74 -0
  53. data/lib/dbagile/contract/data.rb +3 -0
  54. data/lib/dbagile/contract/robust/helpers.rb +19 -0
  55. data/lib/dbagile/contract/robust/optimistic/data/table_driven.rb +31 -0
  56. data/lib/dbagile/contract/robust/optimistic/data/transaction_driven.rb +45 -0
  57. data/lib/dbagile/contract/robust/optimistic/schema/table_driven.rb +53 -0
  58. data/lib/dbagile/contract/robust/optimistic/schema/transaction_driven.rb +45 -0
  59. data/lib/dbagile/contract/robust/optimistic.rb +18 -0
  60. data/lib/dbagile/contract/robust.rb +20 -0
  61. data/lib/dbagile/contract/schema/table_driven.rb +89 -0
  62. data/lib/dbagile/contract/schema/transaction_driven.rb +68 -0
  63. data/lib/dbagile/contract/schema.rb +2 -0
  64. data/lib/dbagile/contract/utils/delegate.rb +17 -0
  65. data/lib/dbagile/contract/utils/full.rb +13 -0
  66. data/lib/dbagile/contract/utils.rb +2 -0
  67. data/lib/dbagile/contract.rb +5 -0
  68. data/lib/dbagile/core/chain.rb +92 -0
  69. data/lib/dbagile/core/connection.rb +51 -0
  70. data/lib/dbagile/core/database.rb +221 -0
  71. data/lib/dbagile/core/io/dsl.rb +95 -0
  72. data/lib/dbagile/core/io/robustness.rb +82 -0
  73. data/lib/dbagile/core/io.rb +2 -0
  74. data/lib/dbagile/core/repository/builder.rb +67 -0
  75. data/lib/dbagile/core/repository/yaml_methods.rb +82 -0
  76. data/lib/dbagile/core/repository.rb +211 -0
  77. data/lib/dbagile/core/schema/builder/coercion.rb +210 -0
  78. data/lib/dbagile/core/schema/builder/concept_factory.rb +61 -0
  79. data/lib/dbagile/core/schema/builder.rb +187 -0
  80. data/lib/dbagile/core/schema/composite.rb +239 -0
  81. data/lib/dbagile/core/schema/computations/filter.rb +40 -0
  82. data/lib/dbagile/core/schema/computations/merge.rb +55 -0
  83. data/lib/dbagile/core/schema/computations/minus.rb +44 -0
  84. data/lib/dbagile/core/schema/computations/split.rb +37 -0
  85. data/lib/dbagile/core/schema/computations.rb +4 -0
  86. data/lib/dbagile/core/schema/database_schema.rb +129 -0
  87. data/lib/dbagile/core/schema/errors.rb +173 -0
  88. data/lib/dbagile/core/schema/logical/attribute.rb +68 -0
  89. data/lib/dbagile/core/schema/logical/constraint/candidate_key.rb +70 -0
  90. data/lib/dbagile/core/schema/logical/constraint/foreign_key.rb +121 -0
  91. data/lib/dbagile/core/schema/logical/constraint.rb +58 -0
  92. data/lib/dbagile/core/schema/logical/constraints.rb +28 -0
  93. data/lib/dbagile/core/schema/logical/heading.rb +47 -0
  94. data/lib/dbagile/core/schema/logical/relvar.rb +81 -0
  95. data/lib/dbagile/core/schema/logical.rb +24 -0
  96. data/lib/dbagile/core/schema/migrate/abstract_script.rb +35 -0
  97. data/lib/dbagile/core/schema/migrate/collapse_table.rb +15 -0
  98. data/lib/dbagile/core/schema/migrate/create_table.rb +15 -0
  99. data/lib/dbagile/core/schema/migrate/drop_table.rb +15 -0
  100. data/lib/dbagile/core/schema/migrate/expand_table.rb +15 -0
  101. data/lib/dbagile/core/schema/migrate/operation.rb +141 -0
  102. data/lib/dbagile/core/schema/migrate/stager.rb +282 -0
  103. data/lib/dbagile/core/schema/migrate.rb +2 -0
  104. data/lib/dbagile/core/schema/part.rb +114 -0
  105. data/lib/dbagile/core/schema/physical/index.rb +64 -0
  106. data/lib/dbagile/core/schema/physical/indexes.rb +12 -0
  107. data/lib/dbagile/core/schema/physical.rb +26 -0
  108. data/lib/dbagile/core/schema/robustness.rb +39 -0
  109. data/lib/dbagile/core/schema/schema_object.rb +94 -0
  110. data/lib/dbagile/core/schema.rb +254 -0
  111. data/lib/dbagile/core/transaction.rb +74 -0
  112. data/lib/dbagile/core.rb +7 -0
  113. data/lib/dbagile/environment/buffering.rb +45 -0
  114. data/lib/dbagile/environment/delegator.rb +59 -0
  115. data/lib/dbagile/environment/interactions.rb +208 -0
  116. data/lib/dbagile/environment/on_error.rb +47 -0
  117. data/lib/dbagile/environment/repository.rb +161 -0
  118. data/lib/dbagile/environment/robustness.rb +7 -0
  119. data/lib/dbagile/environment/testing.rb +23 -0
  120. data/lib/dbagile/environment.rb +122 -0
  121. data/lib/dbagile/errors.rb +30 -0
  122. data/lib/dbagile/io/csv.rb +99 -0
  123. data/lib/dbagile/io/json.rb +41 -0
  124. data/lib/dbagile/io/pretty_table.rb +128 -0
  125. data/lib/dbagile/io/ruby.rb +62 -0
  126. data/lib/dbagile/io/text.rb +18 -0
  127. data/lib/dbagile/io/type_safe.rb +65 -0
  128. data/lib/dbagile/io/xml.rb +35 -0
  129. data/lib/dbagile/io/yaml.rb +30 -0
  130. data/lib/dbagile/io.rb +94 -0
  131. data/lib/dbagile/loader.rb +16 -0
  132. data/lib/dbagile/plugin.rb +29 -0
  133. data/lib/dbagile/restful/client/delete.rb +22 -0
  134. data/lib/dbagile/restful/client/get.rb +24 -0
  135. data/lib/dbagile/restful/client/post.rb +22 -0
  136. data/lib/dbagile/restful/client/utils.rb +16 -0
  137. data/lib/dbagile/restful/client.rb +41 -0
  138. data/lib/dbagile/restful/middleware/delete.rb +22 -0
  139. data/lib/dbagile/restful/middleware/get.rb +27 -0
  140. data/lib/dbagile/restful/middleware/one_database.rb +82 -0
  141. data/lib/dbagile/restful/middleware/post.rb +23 -0
  142. data/lib/dbagile/restful/middleware/utils.rb +65 -0
  143. data/lib/dbagile/restful/middleware.rb +54 -0
  144. data/lib/dbagile/restful/server.rb +65 -0
  145. data/lib/dbagile/restful.rb +9 -0
  146. data/lib/dbagile/robustness/dependencies.rb +36 -0
  147. data/lib/dbagile/robustness/file_system.rb +53 -0
  148. data/lib/dbagile/robustness.rb +14 -0
  149. data/lib/dbagile/tools/file_system.rb +24 -0
  150. data/lib/dbagile/tools/math.rb +11 -0
  151. data/lib/dbagile/tools/ordered_hash.rb +39 -0
  152. data/lib/dbagile/tools/ruby.rb +78 -0
  153. data/lib/dbagile/tools/string.rb +6 -0
  154. data/lib/dbagile/tools/tuple.rb +49 -0
  155. data/lib/dbagile/tools.rb +6 -0
  156. data/lib/dbagile.rb +66 -0
  157. data/test/assumptions/equality.spec +11 -0
  158. data/test/assumptions/fixtures.rb +39 -0
  159. data/test/assumptions/inheritance.spec +17 -0
  160. data/test/assumptions/sequel/autonumber.spec +19 -0
  161. data/test/assumptions/sequel/connect.spec +29 -0
  162. data/test/assumptions/sequel/test.db +0 -0
  163. data/test/assumptions/stdlib/pathname.spec +13 -0
  164. data/test/assumptions/yaml/fixtures.rb +25 -0
  165. data/test/assumptions/yaml/to_yaml.spec +10 -0
  166. data/test/assumptions.spec +2 -0
  167. data/test/commands/bulk/export.spec +100 -0
  168. data/test/commands/bulk/import.spec +49 -0
  169. data/test/commands/db/add.spec +31 -0
  170. data/test/commands/db/list.spec +29 -0
  171. data/test/commands/db/ping.spec +21 -0
  172. data/test/commands/db/rm.spec +18 -0
  173. data/test/commands/db/use.spec +18 -0
  174. data/test/commands/dba.spec +54 -0
  175. data/test/commands/repo/create.spec +30 -0
  176. data/test/commands/schema/check.spec +25 -0
  177. data/test/commands/schema/diff.spec +30 -0
  178. data/test/commands/schema/dump.spec +23 -0
  179. data/test/commands/schema/fixtures/add_constraint.yaml +30 -0
  180. data/test/commands/schema/fixtures/announced.yaml +28 -0
  181. data/test/commands/schema/fixtures/effective.yaml +20 -0
  182. data/test/commands/schema/fixtures/invalid.yaml +6 -0
  183. data/test/commands/schema/sql_script.spec +56 -0
  184. data/test/commands/sql/drop.spec +25 -0
  185. data/test/commands/sql/heading.spec +7 -0
  186. data/test/commands/sql/scripts/delete.sql +1 -0
  187. data/test/commands/sql/scripts/insert.sql +2 -0
  188. data/test/commands/sql/send.spec +29 -0
  189. data/test/commands/sql/show.spec +17 -0
  190. data/test/commands.spec +138 -0
  191. data/test/contract/connection/transaction.ex +11 -0
  192. data/test/contract/connection.spec +9 -0
  193. data/test/contract/data/dataset/columns.ex +5 -0
  194. data/test/contract/data/dataset/count.ex +5 -0
  195. data/test/contract/data/dataset.spec +9 -0
  196. data/test/contract/data/table_driven/dataset.ex +31 -0
  197. data/test/contract/data/table_driven/exists_q.ex +27 -0
  198. data/test/contract/data/table_driven.spec +9 -0
  199. data/test/contract/data/transaction_driven/delete.ex +29 -0
  200. data/test/contract/data/transaction_driven/direct_sql.ex +19 -0
  201. data/test/contract/data/transaction_driven/insert.ex +8 -0
  202. data/test/contract/data/transaction_driven/update.ex +19 -0
  203. data/test/contract/data/transaction_driven.spec +18 -0
  204. data/test/contract/robust/data/table_driven.spec +15 -0
  205. data/test/contract/robust/data/transaction_driven.spec +21 -0
  206. data/test/contract/robust/schema/table_driven.spec +21 -0
  207. data/test/contract/robust/schema/transaction_driven.spec +19 -0
  208. data/test/contract/schema/table_driven/column_names.ex +5 -0
  209. data/test/contract/schema/table_driven/has_column_q.ex +13 -0
  210. data/test/contract/schema/table_driven/has_table_q.ex +11 -0
  211. data/test/contract/schema/table_driven/heading.ex +5 -0
  212. data/test/contract/schema/table_driven.spec +9 -0
  213. data/test/contract/schema/transaction_driven/create_table.ex +10 -0
  214. data/test/contract/schema/transaction_driven/drop_table.ex +10 -0
  215. data/test/contract/schema/transaction_driven.spec +18 -0
  216. data/test/contract.spec +66 -0
  217. data/test/fixtures/basics/data/basic_values.rb +13 -0
  218. data/test/fixtures/basics/data/empty_table.rb +3 -0
  219. data/test/fixtures/basics/data/non_empty_table.rb +4 -0
  220. data/test/fixtures/basics/data/parts.rb +8 -0
  221. data/test/fixtures/basics/data/suppliers.rb +7 -0
  222. data/test/fixtures/basics/data/supplies.rb +14 -0
  223. data/test/fixtures/basics/dbagile.idx +20 -0
  224. data/test/fixtures/basics/fixtures.yaml +28 -0
  225. data/test/fixtures/basics/robust.db +0 -0
  226. data/test/fixtures/basics/suppliers.yaml +30 -0
  227. data/test/fixtures/basics/test.db +0 -0
  228. data/test/fixtures/empty/dbagile.idx +5 -0
  229. data/test/fixtures.rb +152 -0
  230. data/test/restful/delete/no_format.ex +32 -0
  231. data/test/restful/delete.spec +8 -0
  232. data/test/restful/get/csv_format.ex +12 -0
  233. data/test/restful/get/json_format.ex +19 -0
  234. data/test/restful/get/query_string.ex +11 -0
  235. data/test/restful/get/text_format.ex +12 -0
  236. data/test/restful/get/yaml_format.ex +14 -0
  237. data/test/restful/get.spec +5 -0
  238. data/test/restful/post/no_format.ex +22 -0
  239. data/test/restful/post.spec +8 -0
  240. data/test/restful.spec +32 -0
  241. data/test/run_all_suite.rb +51 -0
  242. data/test/spec_helper.rb +26 -0
  243. data/test/support/be_a_valid_json_string.rb +19 -0
  244. data/test/support/be_a_valid_yaml_string.rb +18 -0
  245. data/test/unit/adapter/factor.spec +13 -0
  246. data/test/unit/adapter/sequel/new.spec +19 -0
  247. data/test/unit/command/api.spec +12 -0
  248. data/test/unit/command/command_for.spec +36 -0
  249. data/test/unit/command/command_name_of.spec +21 -0
  250. data/test/unit/command/ruby_method_for.spec +21 -0
  251. data/test/unit/command/sanity.spec +34 -0
  252. data/test/unit/contract/utils/delegate/delegate.spec +23 -0
  253. data/test/unit/core/chain/chain.spec +57 -0
  254. data/test/unit/core/chain/connect.spec +22 -0
  255. data/test/unit/core/chain/delegate_chain.spec +16 -0
  256. data/test/unit/core/chain/initialize.spec +19 -0
  257. data/test/unit/core/chain/plug.spec +31 -0
  258. data/test/unit/core/io/dsl/scope.spec +9 -0
  259. data/test/unit/core/repository/create_bang.spec +31 -0
  260. data/test/unit/core/repository/current.spec +31 -0
  261. data/test/unit/core/repository/database.spec +47 -0
  262. data/test/unit/core/repository/fixtures/corrupted/dbagile.idx +1 -0
  263. data/test/unit/core/repository/fixtures/test_and_prod/dbagile.idx +21 -0
  264. data/test/unit/core/repository/fixtures.rb +25 -0
  265. data/test/unit/core/repository/has_database_q.spec +16 -0
  266. data/test/unit/core/repository/load.spec +51 -0
  267. data/test/unit/core/repository/to_yaml.spec +17 -0
  268. data/test/unit/core/schema/check.spec +32 -0
  269. data/test/unit/core/schema/empty_q.spec +18 -0
  270. data/test/unit/core/schema/filter.spec +42 -0
  271. data/test/unit/core/schema/fixtures/dbagile.yaml +7 -0
  272. data/test/unit/core/schema/fixtures/empty.yaml +11 -0
  273. data/test/unit/core/schema/fixtures/invalid.yaml +54 -0
  274. data/test/unit/core/schema/fixtures/left.yaml +46 -0
  275. data/test/unit/core/schema/fixtures/left_minus_right.yaml +31 -0
  276. data/test/unit/core/schema/fixtures/right.yaml +46 -0
  277. data/test/unit/core/schema/fixtures/right_minus_left.yaml +31 -0
  278. data/test/unit/core/schema/fixtures/suppliers_and_parts.yaml +30 -0
  279. data/test/unit/core/schema/fixtures.rb +32 -0
  280. data/test/unit/core/schema/merge.spec +72 -0
  281. data/test/unit/core/schema/minus.spec +26 -0
  282. data/test/unit/core/schema/sanity.spec +39 -0
  283. data/test/unit/core/schema/split.spec +58 -0
  284. data/test/unit/core/schema/stage_script.spec +26 -0
  285. data/test/unit/core/schema/to_yaml.spec +13 -0
  286. data/test/unit/core/schema/yaml_display.spec +14 -0
  287. data/test/unit/core/schema/yaml_load.spec +20 -0
  288. data/test/unit/core/transaction/transaction.spec +10 -0
  289. data/test/unit/fixtures.rb +67 -0
  290. data/test/unit/io/to_xxx.spec +52 -0
  291. data/test/unit/plugin/options.spec +21 -0
  292. data/test/unit/plugin/tuple_heading.spec +11 -0
  293. data/test/unit/plugin/with_options.spec +12 -0
  294. data/test/unit/tools/ruby/class_unqualified_name.spec +26 -0
  295. data/test/unit/tools/ruby/extract_file_rdoc.spec +10 -0
  296. data/test/unit/tools/ruby/fixtures/rdoc.txt +12 -0
  297. data/test/unit/tools/ruby/fixtures.rb +19 -0
  298. data/test/unit/tools/ruby/optional_args_block_call.spec +35 -0
  299. data/test/unit/tools/ruby/parent_module.spec +21 -0
  300. data/test/unit/tools/ruby/rdoc_file_paragraphs.spec +13 -0
  301. data/test/unit/tools/tuple/tuple_heading.spec +11 -0
  302. data/test/unit/tools/tuple/tuple_key.spec +27 -0
  303. data/test/unit/tools/tuple/tuple_project.spec +23 -0
  304. data/test/unit.spec +3 -0
  305. metadata +422 -0
@@ -0,0 +1,19 @@
1
+ shared_examples_for "A robust Contract::Schema::TransactionDriven" do
2
+
3
+ it "should raise a TableAlreadyExistsError on create_table if name is already in use" do
4
+
5
+ subject.has_table?(:basic_values).should be_true
6
+
7
+ lambda{ subject.create_table(:basic_values, :id => Integer) }.should raise_error(DbAgile::TableAlreadyExistsError)
8
+
9
+ end
10
+
11
+ it "should raise a NoSuchTableError on drop_table if the table does not exist" do
12
+
13
+ subject.has_table?(:unexisting).should be_false
14
+
15
+ lambda{ subject.drop_table(:unexisting) }.should raise_error(DbAgile::NoSuchTableError)
16
+
17
+ end
18
+
19
+ end
@@ -0,0 +1,5 @@
1
+ it "should return valid columns when table exists" do
2
+
3
+ subject.column_names(:basic_values, true).should == basic_values_keys
4
+
5
+ end
@@ -0,0 +1,13 @@
1
+ it "should return true on exising column" do
2
+
3
+ subject.has_column?(:basic_values, :id).should be_true
4
+
5
+ end
6
+
7
+ it "should return true on unexising column" do
8
+
9
+ subject.has_column?(:basic_values, :unexisting).should be_false
10
+
11
+ end
12
+
13
+
@@ -0,0 +1,11 @@
1
+ it "should return true on existing tables" do
2
+
3
+ subject.has_table?(:basic_values).should be_true
4
+
5
+ end
6
+
7
+ it "should return false on unexisting tables" do
8
+
9
+ subject.has_table?(:unexisting).should be_false
10
+
11
+ end
@@ -0,0 +1,5 @@
1
+ it "should return valid valid heading when table exists" do
2
+
3
+ subject.heading(:basic_values).should == basic_values_heading
4
+
5
+ end
@@ -0,0 +1,9 @@
1
+ shared_examples_for "A Contract::Schema::TableDriven" do
2
+
3
+ ::DbAgile::Contract::Schema::TableDriven.instance_methods(false).each do |meth|
4
+ it { should respond_to(meth) }
5
+ end
6
+
7
+ dbagile_install_examples(__FILE__, self)
8
+
9
+ end
@@ -0,0 +1,10 @@
1
+ it "should allow creating tables if the don't exist" do
2
+
3
+ subject.has_table?(:unexisting).should be_false
4
+
5
+ subject.create_table(:unexisting, :id => Integer).should == {:id => Integer}
6
+
7
+ subject.has_table?(:unexisting).should be_true
8
+
9
+ end
10
+
@@ -0,0 +1,10 @@
1
+ it "should allow removing tables that exist" do
2
+
3
+ subject.has_table?(:existing).should be_true
4
+
5
+ subject.drop_table(:existing).should be_true
6
+
7
+ subject.has_table?(:existing).should be_false
8
+
9
+ end
10
+
@@ -0,0 +1,18 @@
1
+ shared_examples_for "A Contract::Schema::TransactionDriven" do
2
+
3
+ ::DbAgile::Contract::Schema::TransactionDriven.instance_methods(false).each do |meth|
4
+ it { should respond_to(meth) }
5
+ end
6
+
7
+ before(:each){
8
+ subject.drop_table(:unexisting) if subject.has_table?(:unexisting)
9
+ subject.create_table(:existing, :id => Integer) unless subject.has_table?(:existing)
10
+ }
11
+ after(:each){
12
+ subject.drop_table(:unexisting) if subject.has_table?(:unexisting)
13
+ subject.drop_table(:existing) if subject.has_table?(:existing)
14
+ }
15
+
16
+ dbagile_install_examples(__FILE__, self)
17
+
18
+ end
@@ -0,0 +1,66 @@
1
+ require File.expand_path('../spec_helper', __FILE__)
2
+ dbagile_load_all_subspecs(__FILE__)
3
+ describe "DbAgile::Contract /" do
4
+
5
+ let(:basic_values) { DbAgile::Fixtures::basic_values }
6
+ let(:basic_values_heading){ DbAgile::Fixtures::basic_values_heading }
7
+ let(:basic_values_tuple) { DbAgile::Fixtures::basic_values_tuple }
8
+ let(:basic_values_keys) { DbAgile::Fixtures::basic_values_keys }
9
+
10
+ DbAgile::Fixtures::environment.each_database do |database|
11
+ next if database.name == :unexisting
12
+ unless database.ping?
13
+ puts "skipping #{database.name} (no ping)"
14
+ next
15
+ end
16
+
17
+ describe "on #{database.name} /" do
18
+
19
+ let(:conn) { database.connect }
20
+ let(:trans) { DbAgile::Core::Transaction.new(conn) }
21
+
22
+ describe "::DbAgile::Core::Connection" do
23
+ subject{ conn }
24
+ it_should_behave_like("A Contract::Connection")
25
+ it_should_behave_like("A Contract::Data::TableDriven")
26
+ it_should_behave_like("A Contract::Schema::TableDriven")
27
+ if /robust/ =~ database.name.to_s
28
+ it_should_behave_like("A robust Contract::Data::TableDriven")
29
+ it_should_behave_like("A robust Contract::Schema::TableDriven")
30
+ end
31
+ end
32
+
33
+ describe "::DbAgile::Core::Transaction" do
34
+ subject{ trans }
35
+ it_should_behave_like("A Contract::Connection")
36
+ it_should_behave_like("A Contract::Data::TableDriven")
37
+ it_should_behave_like("A Contract::Data::TransactionDriven")
38
+ it_should_behave_like("A Contract::Schema::TableDriven")
39
+ it_should_behave_like("A Contract::Schema::TransactionDriven")
40
+ if /robust/ =~ database.name.to_s
41
+ it_should_behave_like("A robust Contract::Data::TableDriven")
42
+ it_should_behave_like("A robust Contract::Data::TransactionDriven")
43
+ it_should_behave_like("A robust Contract::Schema::TableDriven")
44
+ it_should_behave_like("A robust Contract::Schema::TransactionDriven")
45
+ end
46
+ end
47
+
48
+ describe "Result of dataset(Symbol)" do
49
+ subject{ conn.dataset(:basic_values) }
50
+ it_should_behave_like("A Contract::Data::Dataset")
51
+ end
52
+
53
+ describe "Result of dataset(String)" do
54
+ subject{ conn.dataset("SELECT * FROM basic_values") }
55
+ it_should_behave_like("A Contract::Data::Dataset")
56
+ end
57
+
58
+ describe "Result of direct_sql('SELECT ...')" do
59
+ subject{ trans.direct_sql("SELECT * FROM basic_values") }
60
+ it_should_behave_like("A Contract::Data::Dataset")
61
+ end
62
+
63
+ end # on #{database.name}
64
+ end # each database
65
+
66
+ end # describe DbAgile::Contract
@@ -0,0 +1,13 @@
1
+ [
2
+ {:neg_fixnum => -1,
3
+ :pos_bignum => 4294967296,
4
+ :name => "Standard values",
5
+ :neg_bignum => -4294967296,
6
+ :true_value => true,
7
+ :now => Time::parse("Fri Jul 16 00:09:56 +0200 2010"),
8
+ :false_value => false,
9
+ :id => 1,
10
+ :date => Date::parse("2010-07-16"),
11
+ :pos_fixnum => 1,
12
+ :ruby_nil => nil}
13
+ ]
@@ -0,0 +1,3 @@
1
+ [
2
+ {:id => 1}
3
+ ]
@@ -0,0 +1,4 @@
1
+ [
2
+ {:id => 1, :english => "One"},
3
+ {:id => 2, :english => "Two"}
4
+ ]
@@ -0,0 +1,8 @@
1
+ [
2
+ {:'p#' => 'P1', :name => 'Nut', :color => 'Red', :weight => 12.0, :city => 'London'},
3
+ {:'p#' => 'P2', :name => 'Bolt', :color => 'Green', :weight => 17.0, :city => 'Paris'},
4
+ {:'p#' => 'P3', :name => 'Screw', :color => 'Blue', :weight => 17.0, :city => 'Oslo'},
5
+ {:'p#' => 'P4', :name => 'Screw', :color => 'Red', :weight => 14.0, :city => 'London'},
6
+ {:'p#' => 'P5', :name => 'Cam', :color => 'Blue', :weight => 12.0, :city => 'Paris'},
7
+ {:'p#' => 'P6', :name => 'Cog', :color => 'Red', :weight => 19.0, :city => 'London'}
8
+ ]
@@ -0,0 +1,7 @@
1
+ [
2
+ {:'s#' => 'S1', :name => 'Smith', :status => 20, :city => 'London'},
3
+ {:'s#' => 'S2', :name => 'Jones', :status => 10, :city => 'Paris'},
4
+ {:'s#' => 'S3', :name => 'Blake', :status => 30, :city => 'Paris'},
5
+ {:'s#' => 'S4', :name => 'Clark', :status => 20, :city => 'London'},
6
+ {:'s#' => 'S5', :name => 'Adams', :status => 30, :city => 'Athens'}
7
+ ]
@@ -0,0 +1,14 @@
1
+ [
2
+ {:'s#' => 'S1', :'p#' => 'P1', :quantity => 300},
3
+ {:'s#' => 'S1', :'p#' => 'P2', :quantity => 200},
4
+ {:'s#' => 'S1', :'p#' => 'P3', :quantity => 400},
5
+ {:'s#' => 'S1', :'p#' => 'P4', :quantity => 200},
6
+ {:'s#' => 'S1', :'p#' => 'P5', :quantity => 100},
7
+ {:'s#' => 'S1', :'p#' => 'P6', :quantity => 100},
8
+ {:'s#' => 'S2', :'p#' => 'P1', :quantity => 300},
9
+ {:'s#' => 'S2', :'p#' => 'P2', :quantity => 400},
10
+ {:'s#' => 'S3', :'p#' => 'P2', :quantity => 200},
11
+ {:'s#' => 'S4', :'p#' => 'P2', :quantity => 200},
12
+ {:'s#' => 'S4', :'p#' => 'P4', :quantity => 300},
13
+ {:'s#' => 'S4', :'p#' => 'P5', :quantity => 400}
14
+ ]
@@ -0,0 +1,20 @@
1
+ ---
2
+ version: 0.0.1
3
+ databases:
4
+ unexisting:
5
+ uri: postgres://dbagile@localhost/dbagile_unexisting
6
+ sqlite:
7
+ uri: test.db
8
+ announced_schema:
9
+ - fixtures.yaml
10
+ robust:
11
+ uri: robust.db
12
+ announced_schema:
13
+ - fixtures.yaml
14
+ plugins:
15
+ - DbAgile::Contract::Robust::Optimistic
16
+ postgres:
17
+ uri: postgres://dbagile@localhost/dbagile_test
18
+ announced_schema:
19
+ - fixtures.yaml
20
+ current: sqlite
@@ -0,0 +1,28 @@
1
+ ---
2
+ logical:
3
+ basic_values:
4
+ heading:
5
+ date: {domain: Date, mandatory: false}
6
+ false_value: {domain: SByC::TypeSystem::Ruby::Boolean, mandatory: false}
7
+ id: {domain: Integer, mandatory: false}
8
+ name: {domain: String, mandatory: false}
9
+ neg_bignum: {domain: Integer, mandatory: false}
10
+ neg_fixnum: {domain: Integer, mandatory: false}
11
+ now: {domain: Time, mandatory: false}
12
+ pos_bignum: {domain: Integer, mandatory: false}
13
+ pos_fixnum: {domain: Integer, mandatory: false}
14
+ ruby_nil: {domain: String, mandatory: false}
15
+ true_value: {domain: SByC::TypeSystem::Ruby::Boolean, mandatory: false}
16
+ constraints:
17
+ pk: { type: primary_key, attributes: ['id'] }
18
+ empty_table:
19
+ heading:
20
+ id: {domain: Integer, mandatory: false}
21
+ constraints:
22
+ pk: { type: primary_key, attributes: ['id'] }
23
+ non_empty_table:
24
+ heading:
25
+ id: {domain: Integer, mandatory: false}
26
+ english: {domain: String, mandatory: false}
27
+ constraints:
28
+ pk: { type: primary_key, attributes: ['id'] }
Binary file
@@ -0,0 +1,30 @@
1
+ ---
2
+ logical:
3
+ suppliers:
4
+ heading:
5
+ s#: { domain: Integer, mandatory: true }
6
+ name: { domain: String, mandatory: true }
7
+ city: { domain: String, mandatory: true }
8
+ constraints:
9
+ pk: { type: :primary_key, attributes: [ 's#' ] }
10
+ parts:
11
+ heading:
12
+ p#: { domain: Integer, mandatory: true }
13
+ name: { domain: String, mandatory: true }
14
+ color: { domain: String, mandatory: true }
15
+ constraints:
16
+ pk: { type: :primary_key, attributes: [ 'p#' ] }
17
+ supplies:
18
+ heading:
19
+ s#: { domain: Integer, mandatory: true }
20
+ p#: { domain: Integer, mandatory: true }
21
+ qty: { domain: Integer, mandatory: true }
22
+ constraints:
23
+ pk: { type: :primary_key, attributes: [ 's#', 'p#' ] }
24
+ is_a_known_supplier: { type: :foreign_key, attributes: [ 's#' ], references: suppliers }
25
+ is_a_known_part: { type: :foreign_key, attributes: [ 'p#' ], references: parts }
26
+ ---
27
+ physical:
28
+ indexes:
29
+ supplier_name: { relvar: suppliers, attributes: [ 'name' ] }
30
+
Binary file
@@ -0,0 +1,5 @@
1
+ ---
2
+ version: 0.0.1
3
+ databases: {}
4
+
5
+ current: ""
data/test/fixtures.rb ADDED
@@ -0,0 +1,152 @@
1
+ module DbAgile
2
+ #
3
+ # Provides helper methods about fixture databases
4
+ #
5
+ module Fixtures
6
+ include DbAgile::Environment::Delegator
7
+ include DbAgile::Tools::Tuple
8
+
9
+ # Returns path to a repository
10
+ def repository_path(name)
11
+ File.expand_path("../fixtures/#{name}", __FILE__)
12
+ end
13
+
14
+ # Cleans and recreated the empty repository
15
+ def ensure_empty_repository!
16
+ path = repository_path(:empty)
17
+ FileUtils.rm_rf(path)
18
+ DbAgile::Core::Repository::create!(path)
19
+ path
20
+ end
21
+
22
+ # Returns the fixture environment
23
+ def environment
24
+ env = DbAgile::Environment.new
25
+ env.repository_path = repository_path(:basics)
26
+ env.output_buffer = StringIO.new
27
+ env.message_buffer = StringIO.new
28
+ env.interactive = true
29
+ env.console_width = 10
30
+ env
31
+ end
32
+
33
+ # Returns the path to the table/basic_values.rb file
34
+ def basic_values_path
35
+ File.expand_path('../fixtures/basics/data/basic_values.rb', __FILE__)
36
+ end
37
+
38
+ # Yields the block with each table file in turn
39
+ def each_table_file
40
+ Dir[File.expand_path('../fixtures/basics/data/*.rb', __FILE__)].each{|file|
41
+ name = File.basename(file, ".rb")
42
+ yield(name, file)
43
+ }
44
+ end
45
+
46
+ # Creates the physical databases for fixtures
47
+ def create_physical_databases
48
+ FileUtils.rm_rf File.expand_path('../fixtures/basics/test.db', __FILE__)
49
+ FileUtils.rm_rf File.expand_path('../fixtures/basics/robust.db', __FILE__)
50
+ require 'readline'
51
+ puts "#################################################################################"
52
+ puts "ATTENTION: This task will create physical test databases on your computer"
53
+ puts " A password will probably be asked as this task relies on 'sudo'."
54
+ puts " Please provide the root password"
55
+ puts "#################################################################################"
56
+ Readline.readline("Press enter to start")
57
+ puts "Creating the physical postgresql database ..."
58
+ puts `sudo su postgres -c 'dropdb dbagile_test'`
59
+ puts `sudo su postgres -c 'dropuser dbagile'`
60
+ puts `sudo su postgres -c 'createuser --no-superuser --no-createrole --createdb dbagile'`
61
+ puts `sudo su postgres -c 'createdb --encoding=utf8 --owner=dbagile dbagile_test'`
62
+ puts
63
+ puts "#################################################################################"
64
+ puts "Done."
65
+ puts "Please run 'rake fixtures'"
66
+ puts "#################################################################################"
67
+ true
68
+ end
69
+
70
+ # Ensures that physical databases are created
71
+ def ensure_physical_databases!
72
+ @ensure_physical_databases ||= create_physical_databases
73
+ end
74
+
75
+ # Creates logical fixtures
76
+ def create_fixtures
77
+ ensure_physical_databases!
78
+ DbAgile::dba(environment) do |dba|
79
+ dba.output_buffer = STDOUT
80
+ dba.console_width = nil
81
+ dba.repository.each do |db|
82
+ if db.ping?
83
+ puts "Installing fixture database on #{db.name.inspect}"
84
+ dba.db_use(db.name)
85
+ each_table_file{|name, file|
86
+ dba.bulk_import ["--ruby", "--drop-table", "--create-table", "--input=#{file}", name]
87
+ }
88
+ dba.sql_send "DELETE FROM empty_table"
89
+ else
90
+ puts "Skipping fixture database #{db.name.inspect} (no ping)"
91
+ end
92
+ end
93
+ end
94
+ end
95
+
96
+ # Returns basic_values tuple
97
+ def basic_values_tuple
98
+ basic_values[0]
99
+ end
100
+
101
+ # Returns basic_values keys (sorted by name)
102
+ def basic_values_keys
103
+ basic_values_tuple.keys.sort{|a,b| a.to_s <=> b.to_s}
104
+ end
105
+
106
+ # Returns basic_values heading
107
+ def basic_values_heading
108
+ heading = {}
109
+ basic_values[0].each_pair do |key, value|
110
+ heading[key] = case value
111
+ when NilClass
112
+ String
113
+ when TrueClass, FalseClass
114
+ SByC::TypeSystem::Ruby::Boolean
115
+ when Fixnum, Bignum
116
+ Integer
117
+ else
118
+ value.class
119
+ end
120
+ end
121
+ heading
122
+ end
123
+
124
+ # Empty the basic values on a db
125
+ def empty_basic_values(db)
126
+ db.with_connection{|c|
127
+ c.transaction{|t| t.delete(:basic_values) }
128
+ }
129
+ end
130
+
131
+ # Restored the basic values on a db
132
+ def restore_basic_values(db)
133
+ db.with_connection{|c|
134
+ c.transaction{|t|
135
+ t.delete(:basic_values)
136
+ t.insert(:basic_values, basic_values[0])
137
+ }
138
+ }
139
+ end
140
+
141
+ # Adds class methods now
142
+ extend Fixtures
143
+
144
+ # Provide helpers to get the contents of the tables
145
+ each_table_file do |name, file|
146
+ define_method name do
147
+ Kernel.eval(File.read(file))
148
+ end
149
+ end
150
+
151
+ end # module Fixtures
152
+ end # module DbAgile
@@ -0,0 +1,32 @@
1
+ # no format
2
+ describe "without extension /" do
3
+
4
+ it "should work as expected when no projection is provided" do
5
+ client.delete(basic_values_uri){|res,http|
6
+ res.content_type.should == 'application/json'
7
+ res.body.should be_a_valid_json_string
8
+ JSON::load(res.body).should == {"ok" => true}
9
+ }
10
+
11
+ # all tuples should have been deleted
12
+ client.get(basic_values_uri('.json')){|res,http|
13
+ res.body.should be_a_valid_json_string
14
+ JSON::load(res.body).should == []
15
+ }
16
+ end
17
+
18
+ it "should work as expected when a projection is provided" do
19
+ client.delete(basic_values_uri, {:id => 2}){|res,http|
20
+ res.content_type.should == 'application/json'
21
+ res.body.should be_a_valid_json_string
22
+ JSON::load(res.body).should == {"ok" => true}
23
+ }
24
+
25
+ # all tuples should have been deleted
26
+ client.get(basic_values_uri('.json')){|res,http|
27
+ res.body.should be_a_valid_json_string
28
+ JSON::load(res.body).size.should.should == 1
29
+ }
30
+ end
31
+
32
+ end
@@ -0,0 +1,8 @@
1
+ shared_examples_for("The Restful DELETE interface") do
2
+
3
+ before(:each){ DbAgile::Fixtures::restore_basic_values(database) }
4
+ after(:each) { DbAgile::Fixtures::restore_basic_values(database) }
5
+
6
+ dbagile_install_examples(__FILE__, self)
7
+
8
+ end
@@ -0,0 +1,12 @@
1
+ # .csv
2
+ describe "when called with .csv extension" do
3
+
4
+ it "should return a text/csv string" do
5
+ client.get(basic_values_uri('.csv')){|res,http|
6
+ res.content_type.should == 'text/csv'
7
+ res.body.should =~ /Standard values/
8
+ }
9
+ end
10
+
11
+ end # .csv
12
+
@@ -0,0 +1,19 @@
1
+ # .json
2
+ describe "when called with .json extension" do
3
+
4
+ it "should return a valid JSON string" do
5
+ client.get(basic_values_uri('.json')){|res,http|
6
+ res.content_type.should == 'application/json'
7
+ res.body.should be_a_valid_json_string
8
+ }
9
+ end
10
+
11
+ it "should be the default" do
12
+ client.get(basic_values_uri){|res,http|
13
+ res.content_type.should == 'application/json'
14
+ res.body.should be_a_valid_json_string
15
+ }
16
+ end
17
+
18
+ end # .json
19
+
@@ -0,0 +1,11 @@
1
+ describe "it should support projection through the query string" do
2
+
3
+ it "should correctly project the table" do
4
+ client.get(basic_values_uri('.json'), {:id => 0}){|res,http|
5
+ res.body.should be_a_valid_json_string
6
+ JSON::parse(res.body).size.should == 0
7
+ }
8
+ end
9
+
10
+
11
+ end
@@ -0,0 +1,12 @@
1
+ # .txt
2
+ describe "when called with .txt extension" do
3
+
4
+ it "should return a text string" do
5
+ client.get(basic_values_uri('.txt')){|res,http|
6
+ res.content_type.should == 'text/plain'
7
+ res.body.should =~ /Standard values/
8
+ }
9
+ end
10
+
11
+ end # .csv
12
+
@@ -0,0 +1,14 @@
1
+ # .yaml
2
+ [".yaml", ".yml"].each do |ext|
3
+ describe "when called with #{ext} extension" do
4
+
5
+ it "should return a valid YAML string" do
6
+ client.get(basic_values_uri(ext)){|res,http|
7
+ res.content_type.should == 'text/yaml'
8
+ res.body.should be_a_valid_yaml_string
9
+ }
10
+ end
11
+
12
+ end
13
+ end # .yaml
14
+
@@ -0,0 +1,5 @@
1
+ shared_examples_for("The Restful GET interface") do
2
+
3
+ dbagile_install_examples(__FILE__, self)
4
+
5
+ end
@@ -0,0 +1,22 @@
1
+ # no format
2
+ describe "when no extension is provided" do
3
+
4
+ it "should return a valid JSON string" do
5
+ client.post(basic_values_uri, {:id => 2, :name => "This is a second test"}){|res,http|
6
+ res.content_type.should == 'application/json'
7
+ res.body.should be_a_valid_json_string
8
+ res.body.should =~ /This is a second test/
9
+ }
10
+
11
+ # tuple should be inserted
12
+ client.get(basic_values_uri('.json'), {:id => 2}){|res,http|
13
+ res.body.should =~ /This is a second test/
14
+ }
15
+
16
+ # other tuples should not been touched
17
+ client.get(basic_values_uri('.json')){|res,http|
18
+ res.body.should =~ /Standard values/
19
+ }
20
+ end
21
+
22
+ end
@@ -0,0 +1,8 @@
1
+ shared_examples_for("The Restful POST interface") do
2
+
3
+ before(:each){ DbAgile::Fixtures::restore_basic_values(database) }
4
+ after(:each) { DbAgile::Fixtures::restore_basic_values(database) }
5
+
6
+ dbagile_install_examples(__FILE__, self)
7
+
8
+ end