sqlpostgres 1.2.4

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 (207) hide show
  1. data/Gemfile +8 -0
  2. data/Gemfile.lock +22 -0
  3. data/LICENSE.md +23 -0
  4. data/README.rdoc +59 -0
  5. data/Rakefile +32 -0
  6. data/VERSION +1 -0
  7. data/doc/BUGS +2 -0
  8. data/doc/examples/README +6 -0
  9. data/doc/examples/connection.rb +16 -0
  10. data/doc/examples/connection_auto.rb +22 -0
  11. data/doc/examples/connection_ctor.rb +18 -0
  12. data/doc/examples/connection_default.rb +15 -0
  13. data/doc/examples/connection_exec.rb +18 -0
  14. data/doc/examples/connection_manual.rb +12 -0
  15. data/doc/examples/connection_wrapped_new.rb +13 -0
  16. data/doc/examples/connection_wrapped_open.rb +13 -0
  17. data/doc/examples/cursor.rb +38 -0
  18. data/doc/examples/include_module.rb +9 -0
  19. data/doc/examples/include_module2.rb +12 -0
  20. data/doc/examples/insert.rb +30 -0
  21. data/doc/examples/insert2.rb +36 -0
  22. data/doc/examples/insert_bytea.rb +16 -0
  23. data/doc/examples/insert_bytea_array.rb +17 -0
  24. data/doc/examples/insert_default_values.rb +16 -0
  25. data/doc/examples/insert_insert.rb +16 -0
  26. data/doc/examples/insert_insert_default.rb +16 -0
  27. data/doc/examples/insert_insert_select.rb +20 -0
  28. data/doc/examples/insert_select.rb +20 -0
  29. data/doc/examples/interval.rb +17 -0
  30. data/doc/examples/savepoint.rb +38 -0
  31. data/doc/examples/select.rb +33 -0
  32. data/doc/examples/select2.rb +36 -0
  33. data/doc/examples/select_cross_join.rb +18 -0
  34. data/doc/examples/select_distinct.rb +18 -0
  35. data/doc/examples/select_distinct_on +19 -0
  36. data/doc/examples/select_for_update.rb +18 -0
  37. data/doc/examples/select_from.rb +17 -0
  38. data/doc/examples/select_from_subselect.rb +20 -0
  39. data/doc/examples/select_group_by.rb +19 -0
  40. data/doc/examples/select_having.rb +20 -0
  41. data/doc/examples/select_join_on.rb +18 -0
  42. data/doc/examples/select_join_using.rb +18 -0
  43. data/doc/examples/select_limit.rb +19 -0
  44. data/doc/examples/select_natural_join.rb +18 -0
  45. data/doc/examples/select_offset.rb +19 -0
  46. data/doc/examples/select_order_by.rb +20 -0
  47. data/doc/examples/select_select.rb +30 -0
  48. data/doc/examples/select_select_alias.rb +30 -0
  49. data/doc/examples/select_select_expression.rb +31 -0
  50. data/doc/examples/select_select_literal.rb +24 -0
  51. data/doc/examples/select_union.rb +21 -0
  52. data/doc/examples/select_where_array.rb +18 -0
  53. data/doc/examples/select_where_in.rb +18 -0
  54. data/doc/examples/select_where_string.rb +18 -0
  55. data/doc/examples/simple.rb +34 -0
  56. data/doc/examples/transaction.rb +30 -0
  57. data/doc/examples/transaction_abort.rb +30 -0
  58. data/doc/examples/transaction_commit.rb +34 -0
  59. data/doc/examples/translate_substitute_values.rb +17 -0
  60. data/doc/examples/update.rb +32 -0
  61. data/doc/examples/update2.rb +44 -0
  62. data/doc/examples/update_only.rb +17 -0
  63. data/doc/examples/update_set.rb +17 -0
  64. data/doc/examples/update_set_array.rb +16 -0
  65. data/doc/examples/update_set_bytea.rb +16 -0
  66. data/doc/examples/update_set_expression.rb +16 -0
  67. data/doc/examples/update_set_subselect.rb +20 -0
  68. data/doc/examples/update_where.rb +17 -0
  69. data/doc/examples/use_prefix.rb +8 -0
  70. data/doc/examples/use_prefix2.rb +11 -0
  71. data/doc/index.html +31 -0
  72. data/doc/insertexamples.rb +9 -0
  73. data/doc/makemanual +4 -0
  74. data/doc/makerdoc +5 -0
  75. data/doc/manual.dbk +622 -0
  76. data/lib/sqlpostgres/Connection.rb +198 -0
  77. data/lib/sqlpostgres/Cursor.rb +157 -0
  78. data/lib/sqlpostgres/Delete.rb +67 -0
  79. data/lib/sqlpostgres/Exceptions.rb +15 -0
  80. data/lib/sqlpostgres/Insert.rb +279 -0
  81. data/lib/sqlpostgres/NullConnection.rb +22 -0
  82. data/lib/sqlpostgres/PgBit.rb +73 -0
  83. data/lib/sqlpostgres/PgBox.rb +37 -0
  84. data/lib/sqlpostgres/PgCidr.rb +21 -0
  85. data/lib/sqlpostgres/PgCircle.rb +75 -0
  86. data/lib/sqlpostgres/PgInet.rb +21 -0
  87. data/lib/sqlpostgres/PgInterval.rb +208 -0
  88. data/lib/sqlpostgres/PgLineSegment.rb +37 -0
  89. data/lib/sqlpostgres/PgMacAddr.rb +21 -0
  90. data/lib/sqlpostgres/PgPath.rb +64 -0
  91. data/lib/sqlpostgres/PgPoint.rb +65 -0
  92. data/lib/sqlpostgres/PgPolygon.rb +56 -0
  93. data/lib/sqlpostgres/PgTime.rb +77 -0
  94. data/lib/sqlpostgres/PgTimeWithTimeZone.rb +98 -0
  95. data/lib/sqlpostgres/PgTimestamp.rb +93 -0
  96. data/lib/sqlpostgres/PgTwoPoints.rb +54 -0
  97. data/lib/sqlpostgres/PgType.rb +34 -0
  98. data/lib/sqlpostgres/PgWrapper.rb +41 -0
  99. data/lib/sqlpostgres/Savepoint.rb +98 -0
  100. data/lib/sqlpostgres/Select.rb +855 -0
  101. data/lib/sqlpostgres/Transaction.rb +120 -0
  102. data/lib/sqlpostgres/Translate.rb +436 -0
  103. data/lib/sqlpostgres/Update.rb +188 -0
  104. data/lib/sqlpostgres.rb +67 -0
  105. data/test/Assert.rb +72 -0
  106. data/test/Connection.test.rb +246 -0
  107. data/test/Cursor.test.rb +190 -0
  108. data/test/Delete.test.rb +68 -0
  109. data/test/Insert.test.rb +123 -0
  110. data/test/MockPGconn.rb +62 -0
  111. data/test/NullConnection.test.rb +32 -0
  112. data/test/PgBit.test.rb +98 -0
  113. data/test/PgBox.test.rb +108 -0
  114. data/test/PgCidr.test.rb +61 -0
  115. data/test/PgCircle.test.rb +107 -0
  116. data/test/PgInet.test.rb +61 -0
  117. data/test/PgInterval.test.rb +180 -0
  118. data/test/PgLineSegment.test.rb +108 -0
  119. data/test/PgMacAddr.test.rb +61 -0
  120. data/test/PgPath.test.rb +106 -0
  121. data/test/PgPoint.test.rb +100 -0
  122. data/test/PgPolygon.test.rb +95 -0
  123. data/test/PgTime.test.rb +120 -0
  124. data/test/PgTimeWithTimeZone.test.rb +117 -0
  125. data/test/PgTimestamp.test.rb +134 -0
  126. data/test/RandomThings.rb +25 -0
  127. data/test/Savepoint.test.rb +286 -0
  128. data/test/Select.test.rb +930 -0
  129. data/test/Test.rb +62 -0
  130. data/test/TestConfig.rb +21 -0
  131. data/test/TestSetup.rb +13 -0
  132. data/test/TestUtil.rb +92 -0
  133. data/test/Transaction.test.rb +275 -0
  134. data/test/Translate.test.rb +354 -0
  135. data/test/Update.test.rb +227 -0
  136. data/test/roundtrip.test.rb +565 -0
  137. data/test/test +34 -0
  138. data/tools/exampleinserter/ExampleInserter.rb +177 -0
  139. data/tools/rdoc/ChangeLog +796 -0
  140. data/tools/rdoc/EXAMPLE.rb +48 -0
  141. data/tools/rdoc/MANIFEST +58 -0
  142. data/tools/rdoc/Makefile +27 -0
  143. data/tools/rdoc/NEW_FEATURES +226 -0
  144. data/tools/rdoc/README +390 -0
  145. data/tools/rdoc/ToDo +6 -0
  146. data/tools/rdoc/contrib/Index +6 -0
  147. data/tools/rdoc/contrib/xslfo/ChangeLog +181 -0
  148. data/tools/rdoc/contrib/xslfo/README +106 -0
  149. data/tools/rdoc/contrib/xslfo/TODO +10 -0
  150. data/tools/rdoc/contrib/xslfo/convert.xsl +151 -0
  151. data/tools/rdoc/contrib/xslfo/demo/README +21 -0
  152. data/tools/rdoc/contrib/xslfo/demo/rdocfo +99 -0
  153. data/tools/rdoc/contrib/xslfo/fcm.xsl +54 -0
  154. data/tools/rdoc/contrib/xslfo/files.xsl +62 -0
  155. data/tools/rdoc/contrib/xslfo/labeled-lists.xsl +66 -0
  156. data/tools/rdoc/contrib/xslfo/lists.xsl +44 -0
  157. data/tools/rdoc/contrib/xslfo/modules.xsl +152 -0
  158. data/tools/rdoc/contrib/xslfo/rdoc.xsl +75 -0
  159. data/tools/rdoc/contrib/xslfo/source.xsl +66 -0
  160. data/tools/rdoc/contrib/xslfo/styles.xsl +69 -0
  161. data/tools/rdoc/contrib/xslfo/tables.xsl +67 -0
  162. data/tools/rdoc/contrib/xslfo/utils.xsl +21 -0
  163. data/tools/rdoc/debian/changelog +33 -0
  164. data/tools/rdoc/debian/compat +1 -0
  165. data/tools/rdoc/debian/control +20 -0
  166. data/tools/rdoc/debian/copyright +10 -0
  167. data/tools/rdoc/debian/dirs +2 -0
  168. data/tools/rdoc/debian/docs +2 -0
  169. data/tools/rdoc/debian/rdoc.1 +252 -0
  170. data/tools/rdoc/debian/rdoc.manpages +1 -0
  171. data/tools/rdoc/debian/rdoc.pod +149 -0
  172. data/tools/rdoc/debian/rules +9 -0
  173. data/tools/rdoc/dot/dot.rb +255 -0
  174. data/tools/rdoc/etc/rdoc.dtd +203 -0
  175. data/tools/rdoc/install.rb +137 -0
  176. data/tools/rdoc/markup/install.rb +43 -0
  177. data/tools/rdoc/markup/sample/sample.rb +42 -0
  178. data/tools/rdoc/markup/simple_markup/fragments.rb +323 -0
  179. data/tools/rdoc/markup/simple_markup/inline.rb +348 -0
  180. data/tools/rdoc/markup/simple_markup/lines.rb +147 -0
  181. data/tools/rdoc/markup/simple_markup/preprocess.rb +68 -0
  182. data/tools/rdoc/markup/simple_markup/to_html.rb +281 -0
  183. data/tools/rdoc/markup/simple_markup.rb +474 -0
  184. data/tools/rdoc/markup/test/AllTests.rb +2 -0
  185. data/tools/rdoc/markup/test/TestInline.rb +151 -0
  186. data/tools/rdoc/markup/test/TestParse.rb +411 -0
  187. data/tools/rdoc/rdoc/code_objects.rb +536 -0
  188. data/tools/rdoc/rdoc/diagram.rb +331 -0
  189. data/tools/rdoc/rdoc/generators/chm_generator.rb +112 -0
  190. data/tools/rdoc/rdoc/generators/html_generator.rb +1268 -0
  191. data/tools/rdoc/rdoc/generators/template/chm/chm.rb +86 -0
  192. data/tools/rdoc/rdoc/generators/template/html/html.rb +705 -0
  193. data/tools/rdoc/rdoc/generators/template/html/kilmer.rb +377 -0
  194. data/tools/rdoc/rdoc/generators/template/xml/rdf.rb +110 -0
  195. data/tools/rdoc/rdoc/generators/template/xml/xml.rb +110 -0
  196. data/tools/rdoc/rdoc/generators/xml_generator.rb +130 -0
  197. data/tools/rdoc/rdoc/options.rb +451 -0
  198. data/tools/rdoc/rdoc/parsers/parse_c.rb +287 -0
  199. data/tools/rdoc/rdoc/parsers/parse_f95.rb +118 -0
  200. data/tools/rdoc/rdoc/parsers/parse_rb.rb +2311 -0
  201. data/tools/rdoc/rdoc/parsers/parse_simple.rb +37 -0
  202. data/tools/rdoc/rdoc/parsers/parserfactory.rb +75 -0
  203. data/tools/rdoc/rdoc/rdoc.rb +219 -0
  204. data/tools/rdoc/rdoc/template.rb +234 -0
  205. data/tools/rdoc/rdoc/tokenstream.rb +25 -0
  206. data/tools/rdoc/rdoc.rb +9 -0
  207. metadata +291 -0
@@ -0,0 +1,188 @@
1
+ module SqlPostgres
2
+
3
+ # This class creates and executes an SQL update statement.
4
+ #
5
+ # Example:
6
+ #** Example: update
7
+ # update = Update.new('foo', connection)
8
+ # update.set('i', 2)
9
+ # p update.statement # "update foo set i = 2"
10
+ # update.exec
11
+ #**
12
+
13
+ class Update
14
+
15
+ # Create an update statement.
16
+ #
17
+ # [table]
18
+ # The table name
19
+ # [connection]
20
+ # The connection to use. If nil, use the default connection instead.
21
+
22
+ def initialize(table, connection = Connection.default)
23
+ @table = table
24
+ @connection = connection
25
+ @set_clauses = []
26
+ @conditions = []
27
+ @only = false
28
+ end
29
+
30
+ # Add "only" to this statement. This is a postgres extension
31
+ # which causes the update to *not* apply to derived tables.
32
+ #
33
+ # Example:
34
+ #** Example: update_only
35
+ # update = Update.new('foo')
36
+ # update.only
37
+ # update.set('i', 0)
38
+ # p update.statement # "update only foo set i = 0"
39
+ #**
40
+
41
+ def only
42
+ @only = true
43
+ end
44
+
45
+ # Set a column to a value.
46
+ #
47
+ # [column]
48
+ # The column name
49
+ # [value]
50
+ # The value to set the column to. Ruby data types are converted
51
+ # to SQL automatically using #escape_sql.
52
+ #
53
+ # Example showing a few different types:
54
+ #** Example: update_set
55
+ # update = Update.new('foo')
56
+ # update.set('name', 'Fred')
57
+ # update.set('hire_date', Time.local(2002, 1, 1))
58
+ # p update.statement # "update foo set name = E'Fred', hire_date =
59
+ # # timestamp '2002-01-01 00:00:00.000000'"
60
+ #**
61
+ #
62
+ # Example showing a subselect:
63
+ #** Example: update_set_subselect
64
+ # select = Select.new
65
+ # select.select('j')
66
+ # select.from('bar')
67
+ # select.where(["i = foo.i"])
68
+ # update = Update.new('foo')
69
+ # update.set('i', select)
70
+ # p update.statement # "update foo set i = (select j from bar
71
+ # # where i = foo.i)"
72
+ #**
73
+ #
74
+ # Example showing an expression:
75
+ #** Example: update_set_expression
76
+ # update = Update.new('foo')
77
+ # update.set('i', ['i + 1'])
78
+ # p update.statement # "update foo set i = i + 1"
79
+ #**
80
+
81
+ def set(column, value)
82
+ @set_clauses << [column, Translate.escape_sql(value)].join(' = ')
83
+ end
84
+
85
+ # Set a bytea column. You must use this function, not #set, when
86
+ # updating a bytea column. That's because bytea columns need
87
+ # special escaping.
88
+ #
89
+ # [column]
90
+ # The column name
91
+ # [value]
92
+ # The value to add.
93
+ #
94
+ # Example:
95
+ #** Example: update_set_bytea
96
+ # update = Update.new('foo')
97
+ # update.set_bytea('name', "\000\377")
98
+ # p update.statement # "update foo set name = E'\\\\000\\\\377'"
99
+ #**
100
+
101
+ def set_bytea(column, value)
102
+ @set_clauses << [column, Translate.escape_bytea(value)].join(' = ')
103
+ end
104
+
105
+ # Set a column to an array.
106
+ #
107
+ # [column]
108
+ # The column name
109
+ # [value]
110
+ # The value to set the column to. Ruby data types are converted
111
+ # to SQL automatically using #escape_array.
112
+ #
113
+ # Example:
114
+ #** Example: update_set_array
115
+ # update = Update.new('foo')
116
+ # update.set_array('i', [1, 2, 3])
117
+ # p update.statement # "update foo set i = ARRAY[1, 2, 3]"
118
+ #**
119
+
120
+ def set_array(column, value)
121
+ @set_clauses << [column, Translate.escape_array(value)].join(' = ')
122
+ end
123
+
124
+ # Add a where clause to the statement.
125
+ #
126
+ # [expression]
127
+ # A string or array, converted using #substitute_values
128
+ #
129
+ # Example:
130
+ #** Example: update_where
131
+ # update = Update.new('foo')
132
+ # update.set('i', 1)
133
+ # update.where(['t = %s', "bar"])
134
+ # p update.statement # "update foo set i = 1 where t = E'bar'"
135
+ #**
136
+
137
+ def where(condition)
138
+ @conditions << Translate.substitute_values(condition)
139
+ end
140
+
141
+ # Return the SQL statement. Especially useful for debugging.
142
+
143
+ def statement
144
+ "update#{only_option} #{@table} set #{set_clause_list}#{where_clause}"
145
+ end
146
+
147
+ # Execute the statement.
148
+ #
149
+ # [connection]
150
+ # If present, the connection to use.
151
+ # If nil, uses the connection passed to new or, if no connection was
152
+ # passed to new, uses the default connection.
153
+
154
+ def exec(connection = @connection)
155
+ connection.exec(statement)
156
+ end
157
+
158
+ private
159
+
160
+ def set_clause_list
161
+ @set_clauses.join(', ')
162
+ end
163
+
164
+ def where_clause
165
+ if @conditions.empty?
166
+ ""
167
+ else
168
+ " where #{@conditions.join(' and ')}"
169
+ end
170
+ end
171
+
172
+ def only_option
173
+ if @only
174
+ " only"
175
+ else
176
+ ""
177
+ end
178
+ end
179
+
180
+ end
181
+
182
+ end
183
+
184
+ # Local Variables:
185
+ # tab-width: 2
186
+ # ruby-indent-level: 2
187
+ # indent-tabs-mode: nil
188
+ # End:
@@ -0,0 +1,67 @@
1
+ require 'pg'
2
+
3
+ # sqlpostgres is a wrapper around the venerable Ruby postgres library.
4
+ # sqlpostgres builds and executes insert, update and select
5
+ # statements. sqlpostgres statements are easier to read and maintain
6
+ # than raw SQL. Ruby data types are automatically converted to and
7
+ # from SQL data types, and results are returned as an array of hashes
8
+ # rather than an array of arrays.
9
+ #
10
+ # Here's a small example showing some inserts, an update, and a
11
+ # select:
12
+ #
13
+ #** Example: simple
14
+ # require "sqlpostgres"
15
+ #
16
+ # include SqlPostgres
17
+ #
18
+ # Connection.open do |connection|
19
+ # connection.exec("create temporary table foo (t text)")
20
+ #
21
+ # insert = Insert.new('foo', connection)
22
+ # insert.insert('t', 'Smith')
23
+ # insert.exec
24
+ #
25
+ # insert = Insert.new('foo', connection)
26
+ # insert.insert('t', 'Jones')
27
+ # insert.exec
28
+ #
29
+ # update = Update.new('foo', connection)
30
+ # update.set('t', "O'Brien")
31
+ # update.where(["t = %s", "Smith"])
32
+ # update.exec
33
+ #
34
+ # select = Select.new(connection)
35
+ # select.select('t')
36
+ # select.from('foo')
37
+ # select.order_by('t')
38
+ # p select.exec # [{"t"=>"Jones"}, {"t"=>"O'Brien"}]
39
+ #
40
+ # end
41
+ #**
42
+ #
43
+ # All classes and functions in this library are in the SqlPostgres module.
44
+ # Users of this library should either use the module name as a prefix:
45
+ #
46
+ #** Example: use_prefix
47
+ # require 'sqlpostgres'
48
+ # insert = SqlPostgres::Insert.new('foo')
49
+ #**
50
+ #
51
+ # or include the module:
52
+ #
53
+ #** Example: include_module
54
+ # require 'sqlpostgres'
55
+ # include SqlPostgres
56
+ # insert = Insert.new('foo')
57
+ #**
58
+
59
+ for path in Dir[File.join(File.dirname(__FILE__), 'sqlpostgres', '*.rb')]
60
+ require File.expand_path(path)
61
+ end
62
+
63
+ # Local Variables:
64
+ # tab-width: 2
65
+ # ruby-indent-level: 2
66
+ # indent-tabs-mode: nil
67
+ # End:
data/test/Assert.rb ADDED
@@ -0,0 +1,72 @@
1
+ module Assert
2
+
3
+ class BlownAssert < Exception
4
+
5
+ attr_accessor :message
6
+
7
+ def initialize(message = "")
8
+ @message = message
9
+ end
10
+
11
+ def to_s
12
+ @message
13
+ end
14
+ end
15
+
16
+ def assert(condition)
17
+ fail("Assert failed") unless condition
18
+ end
19
+
20
+ def assertEquals(actual, expected)
21
+ return if expected === actual
22
+ fail("Expected:\n#{expected.inspect}\nbut got\n#{actual.inspect}")
23
+ end
24
+ module_function :assertEquals
25
+
26
+ def assertGreater(actual, expected)
27
+ return if actual > expected
28
+ fail("Expected > #{expected.inspect} but got #{actual.inspect}")
29
+ end
30
+
31
+ def assertGreaterOrEqual(actual, expected)
32
+ return if actual >= expected
33
+ fail("Expected >= #{expected.inspect} but got #{actual.inspect}")
34
+ end
35
+
36
+ def assertException(exceptionClass, exceptionString = nil)
37
+ begin
38
+ yield
39
+ rescue exceptionClass => e
40
+ assertEquals(e.to_s, exceptionString) unless exceptionString.nil?
41
+ else
42
+ fail("Exception #{exceptionClass} not thrown")
43
+ end
44
+ end
45
+
46
+ def assertInfo(info)
47
+ begin
48
+ yield
49
+ rescue Exception => e
50
+ newMessage = "#{info}: #{e}"
51
+ if e.is_a? BlownAssert
52
+ e.message = newMessage
53
+ raise
54
+ else
55
+ newMessage << "\nOriginal backtrace:\n#{e.backtrace.join("\n")}"
56
+ raise e.exception(newMessage)
57
+ end
58
+ end
59
+ end
60
+
61
+ def fail(why)
62
+ raise BlownAssert, why
63
+ end
64
+ module_function :fail
65
+
66
+ end
67
+
68
+ # Local Variables:
69
+ # tab-width: 2
70
+ # ruby-indent-level: 2
71
+ # indent-tabs-mode: nil
72
+ # End:
@@ -0,0 +1,246 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'bundler/setup'
5
+ $:.unshift(File.dirname(__FILE__))
6
+ require 'TestSetup'
7
+
8
+ require 'MockPGconn'
9
+ require 'RandomThings'
10
+
11
+ class ConnectionTest < Test
12
+
13
+ include SqlPostgres
14
+ include RandomThings
15
+ include TestConfig
16
+ include TestUtil
17
+
18
+ def test_ConnectionNewWrap
19
+ Connection.mockPgClass do
20
+ rawConnection = MockPGconn.new
21
+ assertEquals(MockPGconn.state[:encoding], nil)
22
+ connection = Connection.new('connection'=>rawConnection)
23
+ assertEquals(rawConnection.state[:encoding], 'unicode')
24
+ end
25
+ end
26
+
27
+ def test_ConnectionNewWithBlock
28
+ assertException(ArgumentError, "Block not allowed") do
29
+ Connection.new do |connection|
30
+ end
31
+ end
32
+ end
33
+
34
+ def testOpen_RealConnection
35
+ s = Connection.open(testDbArgs) do |connection|
36
+ assertEquals(connection.query("select 1;"), [["1"]])
37
+ "foo"
38
+ end
39
+ assertEquals(s, "foo")
40
+ end
41
+
42
+ def testOpen_RealConnection_SelectDatabase
43
+ dbName = "sqlpostgres_test1"
44
+ Connection.open(testDbArgs) do |connection1|
45
+ connection1.exec("create database #{dbName}")
46
+ begin
47
+ Connection.open('db_name'=>dbName) do |connection2|
48
+ rows = connection2.query("select current_database();")
49
+ assertEquals(rows[0][0], dbName)
50
+ end
51
+ sleep(0.1) # I don't know why, but it seems to take some time
52
+ # for the connection to be closed
53
+ ensure
54
+ connection1.exec("drop database #{dbName}")
55
+ end
56
+ end
57
+ end
58
+
59
+ def testClose
60
+ Connection.mockPgClass do
61
+ connection = Connection.new
62
+ assertEquals(MockPGconn.state[:open], true)
63
+ connection.close
64
+ assertEquals(MockPGconn.state[:open], false)
65
+ connection.close
66
+ assertEquals(MockPGconn.state[:open], false)
67
+ end
68
+ end
69
+
70
+ def testOpen_DefaultArgs
71
+ Connection.mockPgClass do
72
+ connection = Connection.new
73
+ assertEquals(MockPGconn.state[:open], true)
74
+ assertEquals(MockPGconn.state[:openArgs],
75
+ ["localhost", 5432, "", "", "", nil, nil])
76
+ end
77
+ end
78
+
79
+ def testConstructor
80
+ Connection.mockPgClass do
81
+ dbName = randomString
82
+ hostName = randomString
83
+ port = randomInteger
84
+ login = randomString
85
+ password = randomString
86
+ options = randomString
87
+ tty = randomString
88
+ connection = Connection.new('host_name'=>hostName,
89
+ 'port'=>port,
90
+ 'options'=>options,
91
+ 'tty'=>tty,
92
+ 'db_name'=>dbName,
93
+ 'login'=>login,
94
+ 'password'=>password)
95
+ assertEquals(MockPGconn.state[:open], true)
96
+ assertEquals(MockPGconn.state[:openArgs],
97
+ [hostName, port, options, tty, dbName, login, password])
98
+ assertEquals(MockPGconn.state[:encoding], 'unicode')
99
+ end
100
+ end
101
+
102
+ def testOpen
103
+ Connection.mockPgClass do
104
+ statement = randomString
105
+ Connection.open do |connection|
106
+ assertEquals(MockPGconn.state[:open], true)
107
+ connection.exec(statement)
108
+ end
109
+ assertEquals(MockPGconn.state[:statements], [statement])
110
+ assertEquals(MockPGconn.state[:open], false)
111
+ end
112
+ end
113
+
114
+ def testOpen_CloseOnException
115
+ Connection.mockPgClass do
116
+ statement = randomString
117
+ assertException(RuntimeError, "Foo") do
118
+ Connection.open do |connection|
119
+ assertEquals(MockPGconn.state[:open], true)
120
+ raise "Foo"
121
+ end
122
+ end
123
+ assertEquals(MockPGconn.state[:open], false)
124
+ end
125
+ end
126
+
127
+ def testOpen_CloseOnException_ExceptionDuringClose
128
+ Connection.mockPgClass do
129
+ statement = randomString
130
+ MockPGconn.state[:close_exception] = RuntimeError.new("Can't close")
131
+ assertException(RuntimeError, "Foo") do
132
+ Connection.open do |connection|
133
+ assertEquals(MockPGconn.state[:open], true)
134
+ raise "Foo"
135
+ end
136
+ end
137
+ assertEquals(MockPGconn.state[:open], false)
138
+ end
139
+ end
140
+
141
+ def testOpen_ExceptionDuringClose
142
+ Connection.mockPgClass do
143
+ statement = randomString
144
+ MockPGconn.state[:close_exception] = RuntimeError.new("Can't close")
145
+ assertException(RuntimeError, "Can't close") do
146
+ Connection.open do |connection|
147
+ assertEquals(MockPGconn.state[:open], true)
148
+ end
149
+ end
150
+ assertEquals(MockPGconn.state[:open], false)
151
+ end
152
+ end
153
+
154
+ def testDefaultConnection
155
+ default = randomWhatever
156
+ Connection.default = default
157
+ assertEquals(Connection.default, default)
158
+ Connection.default = nil
159
+ assert(Connection.default.is_a?(NullConnection))
160
+ end
161
+
162
+ def testExec
163
+ statement = randomString
164
+ result = randomWhatever
165
+ Connection.mockPgClass do
166
+ MockPGconn.state[:results] = [result]
167
+ connection = Connection.new
168
+ assertEquals(connection.exec(statement), result)
169
+ assertEquals(MockPGconn.state[:statements], [statement])
170
+ end
171
+ end
172
+
173
+ def testExec_Exception
174
+ Connection.mockPgClass do
175
+ MockPGconn.state[:results] = [RuntimeError.new("Foo")]
176
+ connection = Connection.new
177
+ assertException(RuntimeError, "Foo") do
178
+ connection.exec("foo")
179
+ end
180
+ end
181
+ end
182
+
183
+ def testExec_PGError
184
+ testCases = [
185
+ [false, "Foo\n"],
186
+ [true, "Foo\nThe offending statement is: \"bar\""],
187
+ ]
188
+ for statement_in_exception, message in testCases
189
+ Connection.mockPgClass do
190
+ MockPGconn.state[:results] = [PGError.new("Foo\n")]
191
+ connection = Connection.new
192
+ connection.statement_in_exception = statement_in_exception
193
+ assertException(PGError, message) do
194
+ connection.exec("bar")
195
+ end
196
+ end
197
+ end
198
+ end
199
+
200
+ def testQuery
201
+ statement = randomString
202
+ rows = randomWhatever
203
+ Connection.mockPgClass do
204
+ result = Object.new
205
+ class << result
206
+ attr_accessor :result
207
+ end
208
+ result.result = rows
209
+ MockPGconn.state[:results] = [result]
210
+ assertEquals(Connection.new.query(statement), rows)
211
+ assertEquals(MockPGconn.state[:statements], [statement])
212
+ end
213
+ end
214
+
215
+ def testStatement_In_Exception
216
+ for value in [false, true]
217
+ connection = Connection.new(testDbArgs.merge('statement_in_exception'=>value))
218
+ assertEquals(connection.statement_in_exception, value)
219
+ end
220
+ end
221
+
222
+ def testRealException
223
+ Connection.open(testDbArgs) do |connection|
224
+ assertException(PGError, /ERROR: (Attribute "foo" not found|column "foo" does not exist)/) do
225
+ connection.exec("select foo;")
226
+ end
227
+ end
228
+ end
229
+
230
+ def testPgconn
231
+ Connection.mockPgClass do
232
+ Connection.open(testDbArgs) do |connection|
233
+ assertEquals(connection.pgconn, MockPGconn.state[:connection])
234
+ end
235
+ end
236
+ end
237
+
238
+ end
239
+
240
+ ConnectionTest.new.run if $0 == __FILE__
241
+
242
+ # Local Variables:
243
+ # tab-width: 2
244
+ # ruby-indent-level: 2
245
+ # indent-tabs-mode: nil
246
+ # End: