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,41 @@
1
+ module DbAgile
2
+ module IO
3
+ module JSON
4
+ extend IO::TypeSafe
5
+
6
+ #
7
+ # Outputs some data as a JSON string
8
+ #
9
+ # @return [...] the buffer itself
10
+ #
11
+ def to_json(data, columns = nil, buffer = "", options = {})
12
+ require "json"
13
+ pretty, first = options[:pretty], true
14
+ buffer << (pretty ? "[\n" : "[")
15
+ with_type_safe_relation(data, options) do |tuple|
16
+ buffer << (pretty ? ",\n" : ",") unless first
17
+ if pretty
18
+ buffer << ::JSON::pretty_generate(tuple)
19
+ else
20
+ buffer << ::JSON::fast_generate(tuple)
21
+ end
22
+ first = false
23
+ end
24
+ buffer << (pretty ? "\n]" : "]")
25
+ buffer
26
+ end
27
+ module_function :to_json
28
+
29
+ #
30
+ # Loads some data from a json input. If a block is given, yields it with
31
+ # each tuple in turn and returns nil. Otherwise returns an array of tuples.
32
+ #
33
+ def from_json(input, options = {}, &block)
34
+ require "json"
35
+ from_typesafe_xxx(::JSON::load(input), options, &block)
36
+ end
37
+ module_function :from_json
38
+
39
+ end # module JSON
40
+ end # module IO
41
+ end # module DbAgile
@@ -0,0 +1,128 @@
1
+ #
2
+ # This file has been originally copied from Sequel, and is therefore distributed
3
+ # under Sequel's LICENCE.
4
+ #
5
+ # Copyright (c) 2007-2008 Sharon Rosner
6
+ # Copyright (c) 2008-2009 Jeremy Evans
7
+ #
8
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ # of this software and associated documentation files (the "Software"), to
10
+ # deal in the Software without restriction, including without limitation the
11
+ # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
12
+ # sell copies of the Software, and to permit persons to whom the Software is
13
+ # furnished to do so, subject to the following conditions:
14
+ #
15
+ # The above copyright notice and this permission notice shall be included in
16
+ # all copies or substantial portions of the Software.
17
+ #
18
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21
+ # THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
22
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
+
25
+ #
26
+ module DbAgile
27
+ module IO
28
+ #
29
+ # Helper to create pretty tables (very much inspired from Sequel's PrettyTable,
30
+ # see file licence header for details).
31
+ #
32
+ module PrettyTable
33
+
34
+ # Prints nice-looking plain-text tables
35
+ def self.print(records, columns, buffer = "", options = {}) # records is an array of hashes
36
+ # investigate arguments
37
+ sizes = column_sizes(records, columns)
38
+ sep_line = normalize_line(separator_line(columns, sizes), options)
39
+
40
+ # start generation now
41
+ buffer << sep_line << "\n"
42
+ buffer << normalize_line(header_line(columns, sizes),options) << "\n"
43
+ buffer << sep_line << "\n"
44
+ records.each {|r|
45
+ buffer << normalize_line(data_line(columns, sizes, r),options) << "\n"
46
+ }
47
+ buffer << sep_line << "\n"
48
+ buffer
49
+ end
50
+
51
+ ### Private Module Methods ###
52
+
53
+ # Normalize the line according to options
54
+ def self.normalize_line(line, options)
55
+ if options[:truncate_at] and line.length > options[:truncate_at]
56
+ ellipse = options[:append_with] || '...'
57
+ line = line[0..(options[:truncate_at]-ellipse.length)]
58
+ line += ellipse
59
+ end
60
+ line = line_wrap(line, options[:wrap_at]) if options[:wrap_at]
61
+ line
62
+ end
63
+
64
+ #
65
+ # Wraps a line at a given width
66
+ #
67
+ # Taken from Ruby Facets
68
+ # Copyright (c) 2004-2006 Thomas Sawyer
69
+ # Distributed under the terms of the Ruby license.
70
+ #
71
+ def self.line_wrap(line, width, tabs=2)
72
+ s = line.gsub(/\t/,' ' * tabs) # tabs default to 2 spaces
73
+ s = s.gsub(/\n/,' ')
74
+ r = s.scan( /.{1,#{width}}/ )
75
+ r.join("\n") << "\n"
76
+ end
77
+
78
+ # Hash of the maximum size of the value for each column
79
+ def self.column_sizes(records, columns) # :nodoc:
80
+ sizes = Hash.new {0}
81
+ columns.each do |c|
82
+ s = c.to_s.size
83
+ sizes[c.to_sym] = s if s > sizes[c.to_sym]
84
+ end
85
+ records.each do |r|
86
+ columns.each do |c|
87
+ s = r[c].to_s.size
88
+ sizes[c.to_sym] = s if s > sizes[c.to_sym]
89
+ end
90
+ end
91
+ sizes.each_key{|k| sizes[k] += 1}
92
+ sizes
93
+ end
94
+
95
+ # String for each data line
96
+ def self.data_line(columns, sizes, record) # :nodoc:
97
+ '|' << columns.map {|c| format_cell(sizes[c], record[c])}.join('|') << '|'
98
+ end
99
+
100
+ # Format the value so it takes up exactly size characters
101
+ def self.format_cell(size, v) # :nodoc:
102
+ case v
103
+ when NilClass
104
+ "%-#{size}s" % "[null]"
105
+ when Bignum, Fixnum
106
+ "%#{size}d" % v
107
+ when Float
108
+ "%#{size}g" % v
109
+ else
110
+ "%-#{size}s" % v.to_s
111
+ end
112
+ end
113
+
114
+ # String for header line
115
+ def self.header_line(columns, sizes) # :nodoc:
116
+ '|' << columns.map {|c| "%-#{sizes[c]}s" % c.to_s}.join('|') << '|'
117
+ end
118
+
119
+ # String for separtor line
120
+ def self.separator_line(columns, sizes) # :nodoc:
121
+ '+' << columns.map {|c| '-' * sizes[c]}.join('+') << '+'
122
+ end
123
+
124
+ private_class_method :column_sizes, :data_line, :format_cell, :header_line, :separator_line
125
+ private_class_method :line_wrap, :normalize_line
126
+ end # module PrettyTable
127
+ end # module IO
128
+ end # module DbAgile
@@ -0,0 +1,62 @@
1
+ module DbAgile
2
+ module IO
3
+ module Ruby
4
+
5
+ class Reader
6
+
7
+ def initialize(io, options)
8
+ @io = io
9
+ @options = options
10
+ end
11
+
12
+ # Reads content of a file
13
+ def read(file)
14
+ if @options[:input_file]
15
+ file = File.join(File.dirname(@options[:input_file]), file)
16
+ end
17
+ File.read(file)
18
+ end
19
+
20
+ def tuples
21
+ self.instance_eval(@io.read)
22
+ end
23
+
24
+ end
25
+
26
+ #
27
+ # Outputs some data as a Ruby string
28
+ #
29
+ # @return [...] the buffer itself
30
+ #
31
+ def to_ruby(data, columns = nil, buffer = "", options = {})
32
+ require 'sbyc/type_system/ruby'
33
+ buffer << "["
34
+ first = true
35
+ data.each{|t|
36
+ buffer << (first ? "\n " : ",\n ")
37
+ buffer << SByC::TypeSystem::Ruby::to_literal(t)
38
+ first = false
39
+ }
40
+ buffer << "\n]"
41
+ end
42
+ module_function :to_ruby
43
+
44
+ #
45
+ # Interprets io as ruby code that returns an array of tuples
46
+ # (Hash instance). If a block if given, yields it with each tuple in
47
+ # turn. Otherwise returns it.
48
+ #
49
+ def from_ruby(io, options = {}, &block)
50
+ tuples = Reader.new(io, options).tuples
51
+ if block
52
+ tuples.each(&block)
53
+ nil
54
+ else
55
+ tuples
56
+ end
57
+ end
58
+ module_function :from_ruby
59
+
60
+ end # module Ruby
61
+ end # module IO
62
+ end # module DbAgile
@@ -0,0 +1,18 @@
1
+ module DbAgile
2
+ module IO
3
+ module Text
4
+
5
+ #
6
+ # Outputs some data as a plain text string
7
+ #
8
+ # @return [...] the buffer itself
9
+ #
10
+ def to_text(data, columns, buffer = "", options = {})
11
+ ::DbAgile::IO::PrettyTable::print(data, columns, buffer, options)
12
+ buffer
13
+ end
14
+ module_function :to_text
15
+
16
+ end # module Text
17
+ end # module IO
18
+ end # module DbAgile
@@ -0,0 +1,65 @@
1
+ module DbAgile
2
+ module IO
3
+ module TypeSafe
4
+
5
+ # Encodes a tuple to a type safe tuple
6
+ def to_typesafe_tuple(type_system, tuple)
7
+ return tuple if type_system.nil?
8
+ copy = {}
9
+ tuple.each_pair{|k,v| copy[k] = type_system.to_literal(v)}
10
+ copy
11
+ end
12
+
13
+ # Yields the block with each tuple in turn
14
+ def with_type_safe_relation(data, options, &block)
15
+ if ts = options[:type_system]
16
+ data.each{|t| block.call(to_typesafe_tuple(ts, t))}
17
+ else
18
+ data.each(&block)
19
+ end
20
+ end
21
+
22
+ # Encodes a tuple to a type safe tuple
23
+ def to_typesafe_relation(type_system, relation)
24
+ return relation if type_system.nil?
25
+ relation.collect{|t| to_typesafe_tuple(type_system, t)}
26
+ end
27
+
28
+ # Decodes a type-safe tuple to a tuple
29
+ def from_typesafe_tuple(type_system, tuple)
30
+ return tuple if type_system.nil?
31
+ copy = {}
32
+ tuple.each_pair{|k,v|
33
+ k = k.to_sym unless k.kind_of?(Symbol)
34
+ copy[k] = type_system.parse_literal(v)
35
+ }
36
+ copy
37
+ end
38
+
39
+ # Decodes an type-safe encoded relation
40
+ def from_typesafe_relation(type_system, relation)
41
+ return relation if type_system.nil?
42
+ relation.collect{|t| from_typesafe_tuple(type_system, t)}
43
+ end
44
+
45
+ # Implements the from_xxx emitter spec
46
+ def from_typesafe_xxx(data, options, &block)
47
+ if block.nil?
48
+ from_typesafe_relation(options[:type_system], data)
49
+ else
50
+ if data.respond_to?(:each)
51
+ ts = options[:type_system]
52
+ data.each do |d|
53
+ raise DbAgile::InvalidFormatError, "Loaded tuple should be an hash (#{d.inspect})" unless d.kind_of?(Hash)
54
+ yield(from_typesafe_tuple(ts, d))
55
+ end
56
+ else
57
+ raise DbAgile::InvalidFormatError, "Loaded data should be an array of tuples (#{data.inspect})"
58
+ end
59
+ nil
60
+ end
61
+ end
62
+
63
+ end # module TypeSafe
64
+ end # module IO
65
+ end # module DbAgile
@@ -0,0 +1,35 @@
1
+ module DbAgile
2
+ module IO
3
+ module XML
4
+
5
+ DEFAULT_OPTIONS = { :table_element_name => "table",
6
+ :row_element_name => "record"}
7
+
8
+ #
9
+ # Outputs some data as a XML string
10
+ #
11
+ # @return [...] the buffer itself
12
+ #
13
+ def to_xml(data, columns = nil, buffer = "", options = {})
14
+ require 'builder'
15
+ options = DEFAULT_OPTIONS.merge(options)
16
+ ten, ren, cen = options[:table_element_name],
17
+ options[:row_element_name],
18
+ options[:column_element_name]
19
+ buffer << '<?xml version="1.0" encoding="UTF-8"?>' << "\n"
20
+ buffer << "<#{ten}>"<< "\n"
21
+ data.each{|row|
22
+ buffer << " " << "<#{ren}>" << "\n"
23
+ columns.each{|column|
24
+ buffer << " " << "<#{column}>#{row[column].to_s.to_xs}</#{column}>" << "\n"
25
+ }
26
+ buffer << " " << "</#{ren}>" << "\n"
27
+ }
28
+ buffer << "</#{ten}>"<< "\n"
29
+ buffer
30
+ end
31
+ module_function :to_xml
32
+
33
+ end # module YAML
34
+ end # module IO
35
+ end # module DbAgile
@@ -0,0 +1,30 @@
1
+ module DbAgile
2
+ module IO
3
+ module YAML
4
+ extend IO::TypeSafe
5
+
6
+ #
7
+ # Outputs some data as a YAML string
8
+ #
9
+ # @return [...] the buffer itself
10
+ #
11
+ def to_yaml(data, columns = nil, buffer = "", options = {})
12
+ require 'yaml'
13
+ ::YAML::dump(to_typesafe_relation(options[:type_system], data), buffer)
14
+ buffer
15
+ end
16
+ module_function :to_yaml
17
+
18
+ #
19
+ # Loads some data from a yaml input. If a block is given, yields it with
20
+ # each tuple in turn and returns nil. Otherwise returns an array of tuples.
21
+ #
22
+ def from_yaml(input, options = {}, &block)
23
+ require 'yaml'
24
+ from_typesafe_xxx(::YAML::load(input), options, &block)
25
+ end
26
+ module_function :from_yaml
27
+
28
+ end # module YAML
29
+ end # module IO
30
+ end # module DbAgile
data/lib/dbagile/io.rb ADDED
@@ -0,0 +1,94 @@
1
+ require 'dbagile/io/type_safe'
2
+ require 'dbagile/io/pretty_table'
3
+ require 'dbagile/io/csv'
4
+ require 'dbagile/io/json'
5
+ require 'dbagile/io/yaml'
6
+ require 'dbagile/io/xml'
7
+ require 'dbagile/io/ruby'
8
+ require 'dbagile/io/text'
9
+ module DbAgile
10
+ module IO
11
+
12
+ # Options to set to ensure roundtrip on each format
13
+ ROUND_TRIP_OPTIONS = {
14
+ :type_system => SByC::TypeSystem::Ruby
15
+ }
16
+
17
+ # Known IO formats
18
+ KNOWN_FORMATS = [:yaml, :csv, :json, :ruby, :text, :xml]
19
+
20
+ # Known to_xxx IO formats
21
+ KNOWN_TO_FORMATS = [:yaml, :csv, :json, :ruby, :text, :xml]
22
+
23
+ # Known from_xxx formats
24
+ KNOWN_FROM_FORMATS = [:yaml, :csv, :json, :ruby]
25
+
26
+ # Format to helper module
27
+ FORMAT_TO_MODULE = {
28
+ :yaml => DbAgile::IO::YAML,
29
+ :csv => DbAgile::IO::CSV,
30
+ :json => DbAgile::IO::JSON,
31
+ :ruby => DbAgile::IO::Ruby,
32
+ :text => DbAgile::IO::Text,
33
+ :xml => DbAgile::IO::XML
34
+ }
35
+
36
+ # Which format for what extension
37
+ EXTENSION_TO_FORMAT = {
38
+ ".csv" => :csv,
39
+ ".txt" => :text,
40
+ ".json" => :json,
41
+ ".yaml" => :yaml,
42
+ ".yml" => :yaml,
43
+ ".xml" => :xml,
44
+ ".ruby" => :ruby,
45
+ ".rb" => :ruby
46
+ }
47
+
48
+ # Which content type for which format
49
+ FORMAT_TO_CONTENT_TYPE = {
50
+ :csv => "text/csv",
51
+ :text => "text/plain",
52
+ :json => "application/json",
53
+ :yaml => "text/yaml",
54
+ :xml => "text/xml",
55
+ :ruby => "text/plain"
56
+ }
57
+
58
+ # Checks if an extension is known. Returns the associated format.
59
+ def known_extension?(f)
60
+ f = ".#{f}" unless f[0,1] == '.'
61
+ EXTENSION_TO_FORMAT[f]
62
+ end
63
+
64
+ # Checks if a format is known. Returns the associated content type.
65
+ def known_format?(f)
66
+ FORMAT_TO_CONTENT_TYPE[f]
67
+ end
68
+
69
+ # Returns roundtrip options
70
+ def roundtrip_options(format)
71
+ ROUND_TRIP_OPTIONS
72
+ end
73
+
74
+ # Install helper methods now
75
+ KNOWN_TO_FORMATS.each{|format|
76
+ module_eval <<-EOF
77
+ def to_#{format}(*args, &block)
78
+ FORMAT_TO_MODULE[#{format.inspect}].to_#{format}(*args, &block)
79
+ end
80
+ EOF
81
+ }
82
+
83
+ # Install helper methods now
84
+ KNOWN_FROM_FORMATS.each{|format|
85
+ module_eval <<-EOF
86
+ def from_#{format}(*args, &block)
87
+ FORMAT_TO_MODULE[#{format.inspect}].from_#{format}(*args, &block)
88
+ end
89
+ EOF
90
+ }
91
+
92
+ extend(DbAgile::IO)
93
+ end # module IO
94
+ end # module DbAgile
@@ -0,0 +1,16 @@
1
+ require 'dbagile/robustness'
2
+
3
+ # standard library
4
+ DbAgile::Robustness::has_stdlib! 'time'
5
+ DbAgile::Robustness::has_stdlib! 'fileutils'
6
+ DbAgile::Robustness::has_stdlib! 'pathname'
7
+ DbAgile::Robustness::has_stdlib! 'tempfile'
8
+ DbAgile::Robustness::has_stdlib! 'date'
9
+ DbAgile::Robustness::has_stdlib! 'yaml'
10
+ DbAgile::Robustness::has_stdlib! 'readline'
11
+ DbAgile::Robustness::has_stdlib! 'stringio'
12
+
13
+ # external gems
14
+ DbAgile::Robustness::has_gem! "sbyc", ">= 0.1.4"
15
+ DbAgile::Robustness::has_gem! "sequel", ">= 3.8.0"
16
+ DbAgile::Robustness::has_gem! 'highline', '>= 1.5.2'
@@ -0,0 +1,29 @@
1
+ module DbAgile
2
+ #
3
+ # Defines common contract of all plugins inside the adapter chain
4
+ #
5
+ class Plugin
6
+ include DbAgile::Contract::Utils::Delegate
7
+ include DbAgile::Tools::Tuple
8
+
9
+ # Plugin options
10
+ attr_reader :options
11
+
12
+ # Returns an instance
13
+ def self.[](*args)
14
+ self.new(*args)
15
+ end
16
+
17
+ # Creates a brick instance with a given delegate
18
+ def initialize(options = {})
19
+ @options = default_options.merge(options)
20
+ end
21
+
22
+ # Returns default brick options
23
+ def default_options
24
+ {}
25
+ end
26
+
27
+ private :default_options
28
+ end # class Plugin
29
+ end # module DbAgile
@@ -0,0 +1,22 @@
1
+ module DbAgile
2
+ module Restful
3
+ class Client
4
+ module Delete
5
+
6
+ # Makes a delete request
7
+ def delete(path, projection = nil)
8
+ with_uri(path, projection) do |uri|
9
+ Net::HTTP.start(uri.host, uri.port) {|http|
10
+ req = Net::HTTP::Delete.new(uri.path)
11
+ req.set_form_data(projection) unless projection.nil?
12
+ res = http.request(req)
13
+ yield(res, http)
14
+ res.body
15
+ }
16
+ end
17
+ end
18
+
19
+ end # module Delete
20
+ end # class Client
21
+ end # module Restful
22
+ end # module DbAgile
@@ -0,0 +1,24 @@
1
+ module DbAgile
2
+ module Restful
3
+ class Client
4
+ module Get
5
+
6
+ # Makes a get request
7
+ def get(path, projection = nil)
8
+ with_uri(path, projection) do |uri|
9
+ Net::HTTP.start(uri.host, uri.port) {|http|
10
+ res = if uri.query
11
+ http.get(uri.path + "?" + uri.query)
12
+ else
13
+ http.get(uri.path)
14
+ end
15
+ yield(res, http)
16
+ res.body
17
+ }
18
+ end
19
+ end
20
+
21
+ end # module Get
22
+ end # class Client
23
+ end # module Restful
24
+ end # module DbAgile
@@ -0,0 +1,22 @@
1
+ module DbAgile
2
+ module Restful
3
+ class Client
4
+ module Post
5
+
6
+ # Makes a post request
7
+ def post(path, tuple)
8
+ with_uri(path) do |uri|
9
+ Net::HTTP.start(uri.host, uri.port) {|http|
10
+ req = Net::HTTP::Post.new(uri.path)
11
+ req.set_form_data(tuple)
12
+ res = http.request(req)
13
+ yield(res, http)
14
+ res.body
15
+ }
16
+ end
17
+ end
18
+
19
+ end # module Post
20
+ end # class Client
21
+ end # module Restful
22
+ end # module DbAgile
@@ -0,0 +1,16 @@
1
+ module DbAgile
2
+ module Restful
3
+ class Client
4
+ module Utils
5
+
6
+ # Yields the block with an URI to access the server
7
+ def with_uri(path, projection = nil)
8
+ uri = "#{server_uri}#{path}"
9
+ uri += ("?" + tuple_to_querystring(projection)) if projection
10
+ yield(URI.parse(uri))
11
+ end
12
+
13
+ end # module Get
14
+ end # module Utils
15
+ end # module Restful
16
+ end # module DbAgile
@@ -0,0 +1,41 @@
1
+ require 'uri'
2
+ require 'cgi'
3
+ require 'net/http'
4
+ require 'dbagile/restful/client/utils'
5
+ require 'dbagile/restful/client/get'
6
+ require 'dbagile/restful/client/post'
7
+ require 'dbagile/restful/client/delete'
8
+ module DbAgile
9
+ module Restful
10
+ #
11
+ # Helper to query the restful server
12
+ #
13
+ class Client
14
+ include DbAgile::Restful::Client::Utils
15
+ include DbAgile::Restful::Client::Get
16
+ include DbAgile::Restful::Client::Post
17
+ include DbAgile::Restful::Client::Delete
18
+ include DbAgile::Tools::Tuple
19
+
20
+ # Server uri
21
+ attr_reader :server_uri
22
+
23
+ #
24
+ # Creates a client instance.
25
+ #
26
+ # @param [String|URI] the uri of the restful server
27
+ #
28
+ def initialize(server_uri)
29
+ @server_uri = case server_uri
30
+ when URI
31
+ server_uri
32
+ when String
33
+ URI.parse(server_uri)
34
+ else
35
+ raise ArgumentError, "Invalid server uri: #{server_uri}"
36
+ end
37
+ end
38
+
39
+ end # class Client
40
+ end # module Restful
41
+ end # module DbAgile
@@ -0,0 +1,22 @@
1
+ module DbAgile
2
+ module Restful
3
+ class Middleware
4
+ module Delete
5
+
6
+ # Implements DELETE access of the restful interface
7
+ def delete(env)
8
+ request = Rack::Request.new(env)
9
+ decode(env) do |connection, table, format|
10
+ heading = connection.heading(table)
11
+ tuple = params_to_tuple(request.POST, heading)
12
+ connection.transaction do |t|
13
+ t.delete(table, tuple)
14
+ end
15
+ [ :json, [ JSON::generate(:ok => true) ] ]
16
+ end
17
+ end
18
+
19
+ end # module Delete
20
+ end # class Middleware
21
+ end # module Restful
22
+ end # module Facts