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,64 @@
1
+ module DbAgile
2
+ module Core
3
+ module Schema
4
+ class Physical < Schema::Composite
5
+ class Index < Schema::Part
6
+
7
+ # Relation variable targettet by this index
8
+ def indexed_relvar
9
+ schema.logical.relation_variable(definition[:relvar])
10
+ end
11
+
12
+ # Returns indexed attributes
13
+ def indexed_attributes
14
+ definition[:attributes].collect{|k| indexed_relvar.heading[k]}
15
+ end
16
+
17
+ ############################################################################
18
+ ### Dependency control
19
+ ############################################################################
20
+
21
+ # @see DbAgile::Core::Schema::SchemaObject
22
+ def dependencies(include_parent = false)
23
+ deps = indexed_attributes
24
+ deps += [ parent ] if include_parent
25
+ deps
26
+ end
27
+
28
+ ############################################################################
29
+ ### Check interface
30
+ ############################################################################
31
+
32
+ # @see DbAgile::Core::Schema::SchemaObject
33
+ def _semantics_check(clazz, errors)
34
+ if (trv = indexed_relvar).nil?
35
+ code = clazz::InvalidIndex | clazz::NoSuchRelvar
36
+ errors.add_error(self, code, :relvar_name => definition[:relvar])
37
+ elsif !trv.heading.has_attributes?(definition[:attributes])
38
+ code = clazz::InvalidIndex | clazz::NoSuchRelvarAttributes
39
+ errors.add_error(self, code, :relvar_name => trv.name,
40
+ :attributes => definition[:attributes])
41
+ end
42
+ end
43
+
44
+ ############################################################################
45
+ ### About IO
46
+ ############################################################################
47
+
48
+ # Delegation pattern on YAML flushing
49
+ def to_yaml(opts = {})
50
+ YAML::quick_emit(self, opts){|out|
51
+ defn = definition
52
+ attrs = Schema::Builder::Coercion::unsymbolize_array(definition[:attributes])
53
+ out.map("tag:yaml.org,2002:map", :inline ) do |map|
54
+ map.add('relvar', definition[:relvar].to_s)
55
+ map.add('attributes', attrs)
56
+ end
57
+ }
58
+ end
59
+
60
+ end # class Index
61
+ end # module Physical
62
+ end # module Schema
63
+ end # module Core
64
+ end # module DbAgile
@@ -0,0 +1,12 @@
1
+ require 'dbagile/core/schema/physical/indexes'
2
+ require 'dbagile/core/schema/physical/index'
3
+ module DbAgile
4
+ module Core
5
+ module Schema
6
+ class Physical
7
+ class Indexes < Schema::Composite
8
+ end # class Indexes
9
+ end # class Logical
10
+ end # module Schema
11
+ end # module Core
12
+ end # module DbAgile
@@ -0,0 +1,26 @@
1
+ module DbAgile
2
+ module Core
3
+ module Schema
4
+ class Physical < Schema::Composite
5
+
6
+ # @see DbAgile::Core::Schema::Composite#_default_parts
7
+ def _default_parts
8
+ {:indexes => Physical::Indexes.new}
9
+ end
10
+
11
+ # @see DbAgile::Core::Schema::Composite#_install_eigenclass_methods?
12
+ def _install_eigenclass_methods?
13
+ true
14
+ end
15
+
16
+ # Returns an array with part dependencies
17
+ def dependencies(include_parent = false)
18
+ []
19
+ end
20
+
21
+ end # class Logical
22
+ end # module Schema
23
+ end # module Core
24
+ end # module DbAgile
25
+ require 'dbagile/core/schema/physical/indexes'
26
+ require 'dbagile/core/schema/physical/index'
@@ -0,0 +1,39 @@
1
+ module DbAgile
2
+ module Core
3
+ module Schema
4
+ module Robustness
5
+
6
+ #
7
+ # Asserts that _arg_ is a Schema::DatabaseSchema or raises an ArgumentError
8
+ #
9
+ def schema!(arg, arg_name = :schema, cal = caller)
10
+ unless arg.kind_of?(Schema::DatabaseSchema)
11
+ raise ArgumentError, "Schema expected for #{arg_name}, got #{arg.class}", cal
12
+ end
13
+ arg
14
+ end
15
+
16
+ #
17
+ # Asserts that _arg_ is a Schema::Builder or raises an ArgumentError
18
+ #
19
+ def builder!(arg, arg_name = :builder, cal = caller)
20
+ unless arg.kind_of?(Schema::Builder)
21
+ raise ArgumentError, "Builder expected for #{arg_name}, got #{arg.class}", cal
22
+ end
23
+ arg
24
+ end
25
+
26
+ #
27
+ # Asserts that _arg_ is a Hash or raises an ArgumentError
28
+ #
29
+ def hash!(arg, arg_name = :options, cal = caller)
30
+ unless arg.kind_of?(Hash)
31
+ raise ArgumentError, "Hash expected for #{arg_name}, got #{arg.class}", cal
32
+ end
33
+ arg
34
+ end
35
+
36
+ end # module Robustness
37
+ end # module Schema
38
+ end # module Core
39
+ end # module DbAgile
@@ -0,0 +1,94 @@
1
+ module DbAgile
2
+ module Core
3
+ module Schema
4
+ class SchemaObject
5
+
6
+ # Parent object
7
+ attr_accessor :parent
8
+
9
+ # Object status
10
+ attr_accessor :status
11
+
12
+ ############################################################################
13
+ ### Schema typing
14
+ ############################################################################
15
+
16
+ # Returns true if this schema object is composite, false
17
+ # otherwise
18
+ def composite?
19
+ self.kind_of?(Schema::Composite)
20
+ end
21
+
22
+ # Convenient method for !composite?
23
+ def part?
24
+ !composite?
25
+ end
26
+ alias :terminal? :part?
27
+
28
+ ############################################################################
29
+ ### Schema hierarchy
30
+ ############################################################################
31
+
32
+ # Returns the main schema instance
33
+ def schema
34
+ @schema ||= (parent && parent.schema)
35
+ end
36
+
37
+ # Returns object's ancestors
38
+ def ancestors
39
+ parent.nil? ? [] : [ parent ] + parent.ancestors
40
+ end
41
+
42
+ # Returns outside dependencies only
43
+ def outside_dependencies
44
+ deps = dependencies
45
+ deps.delete_if{|d| d.ancestors.include?(self)}
46
+ end
47
+
48
+ # Returns objects depending on this
49
+ def outside_dependents
50
+ selected = []
51
+ schema.visit{|part, parent|
52
+ if part.part? and not(part.ancestors.include?(self))
53
+ deps = part.outside_dependencies
54
+ deps = deps.collect{|d| d.ancestors}.flatten.uniq
55
+ selected << part if deps.include?(self)
56
+ end
57
+ }
58
+ selected
59
+ end
60
+
61
+ # Returns relation variable of this object, if any
62
+ def relation_variable
63
+ if self.kind_of?(DbAgile::Core::Schema::Logical::Relvar)
64
+ self
65
+ elsif parent
66
+ parent.relation_variable
67
+ else
68
+ raise NoMethodError, "undefined method relation_variable for #{self.class}"
69
+ end
70
+ end
71
+
72
+ ############################################################################
73
+ ### Package internal methods
74
+ ############################################################################
75
+
76
+ # Returns the builder handler for this object
77
+ def builder_handler
78
+ unqualified = DbAgile::RubyTools::class_unqualified_name(self.class).to_s
79
+ unqualified.gsub(/[A-Z]/){|x| "_#{x.downcase}"}[1..-1]
80
+ end
81
+
82
+ # Returns the arguments to pass to builder handler
83
+ def builder_args
84
+ []
85
+ end
86
+
87
+ private :parent=
88
+ end # class SchemaObject
89
+ end # module Schema
90
+ end # module Core
91
+ end # module DbAgile
92
+ require 'dbagile/core/schema/part'
93
+ require 'dbagile/core/schema/composite'
94
+ require 'dbagile/core/schema/database_schema'
@@ -0,0 +1,254 @@
1
+ require 'dbagile/core/schema/errors'
2
+ require 'dbagile/core/schema/robustness'
3
+ require 'dbagile/core/schema/schema_object'
4
+ require 'dbagile/core/schema/builder'
5
+ require 'dbagile/core/schema/computations'
6
+ require 'dbagile/core/schema/migrate'
7
+ module DbAgile
8
+ module Core
9
+ module Schema
10
+ extend(Schema::Robustness)
11
+
12
+ # An empty schema
13
+ EMPTY_SCHEMA = Schema::DatabaseSchema.new
14
+
15
+ # Status of objects that need to be created (on left)
16
+ TO_CREATE = :to_create
17
+
18
+ # Status of objects that need to be dropped (on left)
19
+ TO_DROP = :to_drop
20
+
21
+ # Status of objects that need to be altered (on left)
22
+ TO_ALTER = :to_alter
23
+
24
+ # Status of objects that need not being altered in any way
25
+ NO_CHANGE = :no_change
26
+
27
+ # Status of objects that have been created
28
+ CREATED = :created
29
+
30
+ # Status of objects that have been dropped
31
+ DROPPED = :dropped
32
+
33
+ # Status of objects that have been altered
34
+ ALTERED = :altered
35
+
36
+ # Status of objects whose migrayion is currently pending
37
+ PENDING = :pending
38
+
39
+ # Status of objects whose migration has been defered
40
+ DEFERED = :defered
41
+
42
+ STATUS_TO_COLOR = {
43
+ TO_CREATE => :green,
44
+ TO_DROP => :red,
45
+ TO_ALTER => :cyan,
46
+ NO_CHANGE => :black,
47
+ #
48
+ CREATED => :green,
49
+ DROPPED => :green,
50
+ ALTERED => :green,
51
+ PENDING => :red,
52
+ DEFERED => :red
53
+ }
54
+
55
+ #
56
+ # Creates a DatabaseSchema instance.
57
+ #
58
+ # Intent of this method is to hide implementation details of this package.
59
+ # It should ALWAYS be used for creating schema instances (no direct accesses
60
+ # to the DatabaseSchema should be made!).
61
+ #
62
+ # @param [Object] optional tracability identifier
63
+ # @return [DatabaseSchema] a database schema
64
+ #
65
+ def new(schema_identifier = nil)
66
+ Schema::DatabaseSchema.new(schema_identifier)
67
+ end
68
+ module_function :new
69
+
70
+
71
+ ##############################################################################
72
+ ### About schema building
73
+ ##############################################################################
74
+
75
+ #
76
+ # Creates a builder instance
77
+ #
78
+ def builder(schema = nil)
79
+ DbAgile::Core::Schema::Builder.new(schema)
80
+ end
81
+ module_function :builder
82
+
83
+ #
84
+ # Factors a Builder instance ready for loading a yaml schema file
85
+ #
86
+ def yaml_builder(schema = Schema.new)
87
+ DbAgile::Core::Schema::Builder.new(schema)
88
+ end
89
+ module_function :yaml_builder
90
+
91
+
92
+ ##############################################################################
93
+ ### About Schema and YAML
94
+ ##############################################################################
95
+
96
+ #
97
+ # Loads a database schema from a YAML string
98
+ #
99
+ # @param [String] str a YAML schema source
100
+ # @param [DbAgile::Core::Schema::Builder] a builder instance to use to
101
+ # populate the schema
102
+ # @returns [DbAgile::Core:Schema::DatabaseSchema] the loaded database
103
+ # schema
104
+ #
105
+ def yaml_load(str, builder = yaml_builder)
106
+ YAML::each_document(str){|doc|
107
+ builder._natural(doc)
108
+ }
109
+ builder._dump
110
+ rescue SByC::TypeSystem::CoercionError => ex
111
+ raise DbAgile::SchemaSyntaxError, "Syntax error in schema: #{ex.message}"
112
+ end
113
+ module_function :yaml_load
114
+
115
+ #
116
+ # Loads a schema from a YAML file
117
+ #
118
+ # @param [String|IO] a path name or an IO instance
119
+ # @param [DbAgile::Core::Schema::Builder] a builder instance to use to
120
+ # populate the schema
121
+ # @returns [DbAgile::Core:Schema::DatabaseSchema] the loaded database
122
+ # schema
123
+ #
124
+ def yaml_file_load(path_or_io, builder = yaml_builder)
125
+ case path_or_io
126
+ when String
127
+ File.open(path_or_io, 'r'){|io| yaml_load(io, builder) }
128
+ when IO, File, Tempfile
129
+ yaml_load(path_or_io, builder)
130
+ else
131
+ raise ArgumentError, "Unable to load schema from #{path_or_io}"
132
+ end
133
+ end
134
+ module_function :yaml_file_load
135
+
136
+
137
+ ##############################################################################
138
+ ### About Schema computations
139
+ ##############################################################################
140
+
141
+ # Resolver block that raises a SchemaConflictError
142
+ DEFAULT_CONFLICT_RESOLVER_BLOCK = lambda{|left,right|
143
+ raise SchemaConflictError.new(left, right)
144
+ }
145
+
146
+ #
147
+ # Computes a new schema by difference.
148
+ #
149
+ # @param [DbAgile::Core::Schema::DatabaseSchema] left reference schema
150
+ # @param [DbAgile::Core::Schema::DatabaseSchema] right retrieval schema
151
+ # @param [DbAgile::Core::Schema::Builder] builder to use for the operation
152
+ #
153
+ def minus(left, right,
154
+ builder = DbAgile::Core::Schema::builder)
155
+ schema!(left, :left, caller)
156
+ schema!(right, :right, caller)
157
+ builder!(builder, :builder, caller)
158
+ Computations::minus(left, right, builder)
159
+ end
160
+ module_function :minus
161
+
162
+ #
163
+ # Computes a new schema by merging two other schemas.
164
+ #
165
+ # @param [DbAgile::Core::Schema::DatabaseSchema] left schema one
166
+ # @param [DbAgile::Core::Schema::DatabaseSchema] right schema two
167
+ # @param [DbAgile::Core::Schema::Builder] builder to use for merging
168
+ # @param [Proc] conflict_resolver a optional block that resolves merging
169
+ # conflicts
170
+ #
171
+ def merge(left, right,
172
+ builder = DbAgile::Core::Schema::builder,
173
+ &conflict_resolver)
174
+ schema!(left, :left, caller)
175
+ schema!(right, :right, caller)
176
+ builder!(builder, :builder, caller)
177
+ if conflict_resolver.nil?
178
+ conflict_resolver = DEFAULT_CONFLICT_RESOLVER_BLOCK
179
+ end
180
+ Computations::merge(left, right, builder, &conflict_resolver)
181
+ end
182
+ module_function :merge
183
+
184
+ #
185
+ # Filters a schema according to a block
186
+ #
187
+ def filter(schema, options = {},
188
+ builder = DbAgile::Core::Schema::builder,
189
+ &filter_block)
190
+ schema!(schema, :schema, caller)
191
+ hash!(options, :options, caller)
192
+ builder!(builder, :builder, caller)
193
+ options = Computations::Filter::DEFAULT_OPTIONS.merge(options)
194
+ filtered = Schema::Computations::filter(schema, options, builder, &filter_block)._strip!
195
+ if options[:identifier]
196
+ filtered.schema_identifier = options[:identifier]
197
+ end
198
+ filtered
199
+ end
200
+ module_function :filter
201
+
202
+ #
203
+ # Splits a schema according to a block
204
+ #
205
+ def split(schema, options = {}, &filter_block)
206
+ schema!(schema, :schema, caller)
207
+ hash!(options, :options, caller)
208
+ options = Computations::Split::DEFAULT_OPTIONS.merge(options)
209
+ Schema::Computations::split(schema, options, &filter_block)
210
+ end
211
+ module_function :split
212
+
213
+ ##############################################################################
214
+ ### About Schema scripts
215
+ ##############################################################################
216
+
217
+ #
218
+ # Computes and returns a list of abstract operations to perform on a database
219
+ # given a annotated schema (typically, the result of a merge operation)
220
+ #
221
+ # @param [DbAgile::Core::Schema::DatabaseSchema] schema an annotated schema
222
+ # @param [Hash] options staging options
223
+ # @return [Migrate::AbstractScript] a list of abstract operations
224
+ #
225
+ def stage_script(schema, options = Migrate::Stager::DEFAULT_OPTIONS)
226
+ Migrate::Stager.new.run(schema, options)
227
+ end
228
+ module_function :stage_script
229
+
230
+ #
231
+ # Computes a create abstract script for a given schema.
232
+ #
233
+ # @param [DbAgile::Core::Schema::DatabaseSchema] any valid schema
234
+ # @return [Migrate::AbstractScript] a list of abstract operations
235
+ #
236
+ def create_script(schema)
237
+ stage_script(EMPTY_SCHEMA + schema)
238
+ end
239
+ module_function :create_script
240
+
241
+ #
242
+ # Computes a drop abstract script for a given schema.
243
+ #
244
+ # @param [DbAgile::Core::Schema::DatabaseSchema] any valid schema
245
+ # @return [Migrate::AbstractScript] a list of abstract operations
246
+ #
247
+ def drop_script(schema)
248
+ stage_script(schema + EMPTY_SCHEMA)
249
+ end
250
+ module_function :drop_script
251
+
252
+ end # module Schema
253
+ end # module Core
254
+ end # module DbAgile
@@ -0,0 +1,74 @@
1
+ module DbAgile
2
+ module Core
3
+ class Transaction
4
+
5
+ ### VARS AND INITIALIZE ######################################################
6
+
7
+ # Underlying connection
8
+ attr_reader :connection
9
+
10
+ # Creates a Transaction instance
11
+ def initialize(connection)
12
+ @connection = connection
13
+ end
14
+
15
+ ### ABOUT TRANSACTION MANAGEMENT #############################################
16
+
17
+ # Executes a block
18
+ def execute(&block)
19
+ raise ArgumentError, "Missing transaction block" unless block
20
+ connection.chain.transaction do
21
+ block.call(self)
22
+ end
23
+ end
24
+
25
+ # Commits the transaction
26
+ def commit
27
+ end
28
+
29
+ # Rollbacks the transaction
30
+ def rollback
31
+ raise DbAgile::AbordTransactionError
32
+ end
33
+
34
+ ### DELEGATE PATTERN #########################################################
35
+
36
+ # Automatically install methods of the Connection and *::TableDriven
37
+ # contracts
38
+ [ DbAgile::Contract::Connection,
39
+ DbAgile::Contract::Data::TableDriven,
40
+ DbAgile::Contract::Schema::TableDriven ].each do |mod|
41
+
42
+ mod.instance_methods(false).each do |method|
43
+ self.module_eval <<-EOF
44
+ def #{method}(*args)
45
+ connection.chain.#{method}(*args)
46
+ end
47
+ EOF
48
+ end
49
+
50
+ end # Connection and *::TableDriven
51
+
52
+ # Executes the block inside this transaction
53
+ def transaction(&block)
54
+ execute(&block)
55
+ end
56
+
57
+ # Automatically install methods of the *::TransactionDriven contract
58
+ [ DbAgile::Contract::Data::TransactionDriven,
59
+ DbAgile::Contract::Schema::TransactionDriven ].each do |mod|
60
+
61
+ mod.instance_methods(false).each do |method|
62
+ self.module_eval <<-EOF
63
+ def #{method}(*args)
64
+ connection.chain.#{method}(self, *args)
65
+ end
66
+ EOF
67
+ end
68
+
69
+ end
70
+
71
+ private :connection
72
+ end # class Transaction
73
+ end # module Core
74
+ end # module DbAgile
@@ -0,0 +1,7 @@
1
+ require 'dbagile/core/chain'
2
+ require 'dbagile/core/io'
3
+ require 'dbagile/core/repository'
4
+ require 'dbagile/core/database'
5
+ require 'dbagile/core/connection'
6
+ require 'dbagile/core/transaction'
7
+ require 'dbagile/core/schema'
@@ -0,0 +1,45 @@
1
+ module DbAgile
2
+ class Environment
3
+ module Buffering
4
+
5
+ # The output buffer to use for user requests
6
+ attr_accessor :input_buffer
7
+
8
+ # The output buffer to use for display
9
+ attr_accessor :output_buffer
10
+
11
+ #
12
+ # Flushes something on the output buffer
13
+ #
14
+ # Does nothing when no output buffer has been set.
15
+ #
16
+ # @param [Object] something to write on environment output
17
+ # @return [void]
18
+ #
19
+ def flush(something, append_new_line = true)
20
+ unless output_buffer.nil?
21
+ if something.kind_of?(String)
22
+ output_buffer << something
23
+ if append_new_line and not(something =~ /\n$/)
24
+ output_buffer << "\n"
25
+ end
26
+ elsif something.kind_of?(Enumerable)
27
+ something.each{|v| flush(v, true)}
28
+ else
29
+ flush(something.to_s)
30
+ end
31
+ end
32
+ nil
33
+ end
34
+
35
+ #
36
+ # Delegated to the input buffer. Returns nil if no input buffer
37
+ # has been set
38
+ #
39
+ def gets
40
+ input_buffer.nil? ? nil : input_buffer.gets
41
+ end
42
+
43
+ end # module Interactions
44
+ end # class Environment
45
+ end # module DbAgile
@@ -0,0 +1,59 @@
1
+ module DbAgile
2
+ class Environment
3
+ #
4
+ # Helper to be an environment delegator
5
+ #
6
+ module Delegator
7
+
8
+ [
9
+ #
10
+ :interactive?,
11
+ :interactive!,
12
+ :interactive=,
13
+ #
14
+ :flush,
15
+ :say,
16
+ :display,
17
+ #
18
+ :console_width,
19
+ :console_width=,
20
+ #
21
+ :repository_path,
22
+ :repository_path=,
23
+ :repository,
24
+ #
25
+ :input_buffer,
26
+ :input_buffer=,
27
+ :output_buffer,
28
+ :output_buffer=,
29
+ :asking_buffer,
30
+ :asking_buffer=,
31
+ :message_buffer,
32
+ :message_buffer=,
33
+ #
34
+ :with_repository,
35
+ :with_database,
36
+ :with_current_database,
37
+ #
38
+ :with_connection,
39
+ :with_current_connection
40
+ ].each do |method_name|
41
+ if method_name.to_s =~ /=$/
42
+ code = <<-EOF
43
+ def #{method_name}(value)
44
+ environment.#{method_name} value
45
+ end
46
+ EOF
47
+ else
48
+ code = <<-EOF
49
+ def #{method_name}(*args, &block)
50
+ environment.#{method_name}(*args, &block)
51
+ end
52
+ EOF
53
+ end
54
+ module_eval(code)
55
+ end
56
+
57
+ end # module Delegator
58
+ end # class Environment
59
+ end # module DbAgile