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.
- data/Gemfile +8 -0
- data/Gemfile.lock +22 -0
- data/LICENSE.md +23 -0
- data/README.rdoc +59 -0
- data/Rakefile +32 -0
- data/VERSION +1 -0
- data/doc/BUGS +2 -0
- data/doc/examples/README +6 -0
- data/doc/examples/connection.rb +16 -0
- data/doc/examples/connection_auto.rb +22 -0
- data/doc/examples/connection_ctor.rb +18 -0
- data/doc/examples/connection_default.rb +15 -0
- data/doc/examples/connection_exec.rb +18 -0
- data/doc/examples/connection_manual.rb +12 -0
- data/doc/examples/connection_wrapped_new.rb +13 -0
- data/doc/examples/connection_wrapped_open.rb +13 -0
- data/doc/examples/cursor.rb +38 -0
- data/doc/examples/include_module.rb +9 -0
- data/doc/examples/include_module2.rb +12 -0
- data/doc/examples/insert.rb +30 -0
- data/doc/examples/insert2.rb +36 -0
- data/doc/examples/insert_bytea.rb +16 -0
- data/doc/examples/insert_bytea_array.rb +17 -0
- data/doc/examples/insert_default_values.rb +16 -0
- data/doc/examples/insert_insert.rb +16 -0
- data/doc/examples/insert_insert_default.rb +16 -0
- data/doc/examples/insert_insert_select.rb +20 -0
- data/doc/examples/insert_select.rb +20 -0
- data/doc/examples/interval.rb +17 -0
- data/doc/examples/savepoint.rb +38 -0
- data/doc/examples/select.rb +33 -0
- data/doc/examples/select2.rb +36 -0
- data/doc/examples/select_cross_join.rb +18 -0
- data/doc/examples/select_distinct.rb +18 -0
- data/doc/examples/select_distinct_on +19 -0
- data/doc/examples/select_for_update.rb +18 -0
- data/doc/examples/select_from.rb +17 -0
- data/doc/examples/select_from_subselect.rb +20 -0
- data/doc/examples/select_group_by.rb +19 -0
- data/doc/examples/select_having.rb +20 -0
- data/doc/examples/select_join_on.rb +18 -0
- data/doc/examples/select_join_using.rb +18 -0
- data/doc/examples/select_limit.rb +19 -0
- data/doc/examples/select_natural_join.rb +18 -0
- data/doc/examples/select_offset.rb +19 -0
- data/doc/examples/select_order_by.rb +20 -0
- data/doc/examples/select_select.rb +30 -0
- data/doc/examples/select_select_alias.rb +30 -0
- data/doc/examples/select_select_expression.rb +31 -0
- data/doc/examples/select_select_literal.rb +24 -0
- data/doc/examples/select_union.rb +21 -0
- data/doc/examples/select_where_array.rb +18 -0
- data/doc/examples/select_where_in.rb +18 -0
- data/doc/examples/select_where_string.rb +18 -0
- data/doc/examples/simple.rb +34 -0
- data/doc/examples/transaction.rb +30 -0
- data/doc/examples/transaction_abort.rb +30 -0
- data/doc/examples/transaction_commit.rb +34 -0
- data/doc/examples/translate_substitute_values.rb +17 -0
- data/doc/examples/update.rb +32 -0
- data/doc/examples/update2.rb +44 -0
- data/doc/examples/update_only.rb +17 -0
- data/doc/examples/update_set.rb +17 -0
- data/doc/examples/update_set_array.rb +16 -0
- data/doc/examples/update_set_bytea.rb +16 -0
- data/doc/examples/update_set_expression.rb +16 -0
- data/doc/examples/update_set_subselect.rb +20 -0
- data/doc/examples/update_where.rb +17 -0
- data/doc/examples/use_prefix.rb +8 -0
- data/doc/examples/use_prefix2.rb +11 -0
- data/doc/index.html +31 -0
- data/doc/insertexamples.rb +9 -0
- data/doc/makemanual +4 -0
- data/doc/makerdoc +5 -0
- data/doc/manual.dbk +622 -0
- data/lib/sqlpostgres/Connection.rb +198 -0
- data/lib/sqlpostgres/Cursor.rb +157 -0
- data/lib/sqlpostgres/Delete.rb +67 -0
- data/lib/sqlpostgres/Exceptions.rb +15 -0
- data/lib/sqlpostgres/Insert.rb +279 -0
- data/lib/sqlpostgres/NullConnection.rb +22 -0
- data/lib/sqlpostgres/PgBit.rb +73 -0
- data/lib/sqlpostgres/PgBox.rb +37 -0
- data/lib/sqlpostgres/PgCidr.rb +21 -0
- data/lib/sqlpostgres/PgCircle.rb +75 -0
- data/lib/sqlpostgres/PgInet.rb +21 -0
- data/lib/sqlpostgres/PgInterval.rb +208 -0
- data/lib/sqlpostgres/PgLineSegment.rb +37 -0
- data/lib/sqlpostgres/PgMacAddr.rb +21 -0
- data/lib/sqlpostgres/PgPath.rb +64 -0
- data/lib/sqlpostgres/PgPoint.rb +65 -0
- data/lib/sqlpostgres/PgPolygon.rb +56 -0
- data/lib/sqlpostgres/PgTime.rb +77 -0
- data/lib/sqlpostgres/PgTimeWithTimeZone.rb +98 -0
- data/lib/sqlpostgres/PgTimestamp.rb +93 -0
- data/lib/sqlpostgres/PgTwoPoints.rb +54 -0
- data/lib/sqlpostgres/PgType.rb +34 -0
- data/lib/sqlpostgres/PgWrapper.rb +41 -0
- data/lib/sqlpostgres/Savepoint.rb +98 -0
- data/lib/sqlpostgres/Select.rb +855 -0
- data/lib/sqlpostgres/Transaction.rb +120 -0
- data/lib/sqlpostgres/Translate.rb +436 -0
- data/lib/sqlpostgres/Update.rb +188 -0
- data/lib/sqlpostgres.rb +67 -0
- data/test/Assert.rb +72 -0
- data/test/Connection.test.rb +246 -0
- data/test/Cursor.test.rb +190 -0
- data/test/Delete.test.rb +68 -0
- data/test/Insert.test.rb +123 -0
- data/test/MockPGconn.rb +62 -0
- data/test/NullConnection.test.rb +32 -0
- data/test/PgBit.test.rb +98 -0
- data/test/PgBox.test.rb +108 -0
- data/test/PgCidr.test.rb +61 -0
- data/test/PgCircle.test.rb +107 -0
- data/test/PgInet.test.rb +61 -0
- data/test/PgInterval.test.rb +180 -0
- data/test/PgLineSegment.test.rb +108 -0
- data/test/PgMacAddr.test.rb +61 -0
- data/test/PgPath.test.rb +106 -0
- data/test/PgPoint.test.rb +100 -0
- data/test/PgPolygon.test.rb +95 -0
- data/test/PgTime.test.rb +120 -0
- data/test/PgTimeWithTimeZone.test.rb +117 -0
- data/test/PgTimestamp.test.rb +134 -0
- data/test/RandomThings.rb +25 -0
- data/test/Savepoint.test.rb +286 -0
- data/test/Select.test.rb +930 -0
- data/test/Test.rb +62 -0
- data/test/TestConfig.rb +21 -0
- data/test/TestSetup.rb +13 -0
- data/test/TestUtil.rb +92 -0
- data/test/Transaction.test.rb +275 -0
- data/test/Translate.test.rb +354 -0
- data/test/Update.test.rb +227 -0
- data/test/roundtrip.test.rb +565 -0
- data/test/test +34 -0
- data/tools/exampleinserter/ExampleInserter.rb +177 -0
- data/tools/rdoc/ChangeLog +796 -0
- data/tools/rdoc/EXAMPLE.rb +48 -0
- data/tools/rdoc/MANIFEST +58 -0
- data/tools/rdoc/Makefile +27 -0
- data/tools/rdoc/NEW_FEATURES +226 -0
- data/tools/rdoc/README +390 -0
- data/tools/rdoc/ToDo +6 -0
- data/tools/rdoc/contrib/Index +6 -0
- data/tools/rdoc/contrib/xslfo/ChangeLog +181 -0
- data/tools/rdoc/contrib/xslfo/README +106 -0
- data/tools/rdoc/contrib/xslfo/TODO +10 -0
- data/tools/rdoc/contrib/xslfo/convert.xsl +151 -0
- data/tools/rdoc/contrib/xslfo/demo/README +21 -0
- data/tools/rdoc/contrib/xslfo/demo/rdocfo +99 -0
- data/tools/rdoc/contrib/xslfo/fcm.xsl +54 -0
- data/tools/rdoc/contrib/xslfo/files.xsl +62 -0
- data/tools/rdoc/contrib/xslfo/labeled-lists.xsl +66 -0
- data/tools/rdoc/contrib/xslfo/lists.xsl +44 -0
- data/tools/rdoc/contrib/xslfo/modules.xsl +152 -0
- data/tools/rdoc/contrib/xslfo/rdoc.xsl +75 -0
- data/tools/rdoc/contrib/xslfo/source.xsl +66 -0
- data/tools/rdoc/contrib/xslfo/styles.xsl +69 -0
- data/tools/rdoc/contrib/xslfo/tables.xsl +67 -0
- data/tools/rdoc/contrib/xslfo/utils.xsl +21 -0
- data/tools/rdoc/debian/changelog +33 -0
- data/tools/rdoc/debian/compat +1 -0
- data/tools/rdoc/debian/control +20 -0
- data/tools/rdoc/debian/copyright +10 -0
- data/tools/rdoc/debian/dirs +2 -0
- data/tools/rdoc/debian/docs +2 -0
- data/tools/rdoc/debian/rdoc.1 +252 -0
- data/tools/rdoc/debian/rdoc.manpages +1 -0
- data/tools/rdoc/debian/rdoc.pod +149 -0
- data/tools/rdoc/debian/rules +9 -0
- data/tools/rdoc/dot/dot.rb +255 -0
- data/tools/rdoc/etc/rdoc.dtd +203 -0
- data/tools/rdoc/install.rb +137 -0
- data/tools/rdoc/markup/install.rb +43 -0
- data/tools/rdoc/markup/sample/sample.rb +42 -0
- data/tools/rdoc/markup/simple_markup/fragments.rb +323 -0
- data/tools/rdoc/markup/simple_markup/inline.rb +348 -0
- data/tools/rdoc/markup/simple_markup/lines.rb +147 -0
- data/tools/rdoc/markup/simple_markup/preprocess.rb +68 -0
- data/tools/rdoc/markup/simple_markup/to_html.rb +281 -0
- data/tools/rdoc/markup/simple_markup.rb +474 -0
- data/tools/rdoc/markup/test/AllTests.rb +2 -0
- data/tools/rdoc/markup/test/TestInline.rb +151 -0
- data/tools/rdoc/markup/test/TestParse.rb +411 -0
- data/tools/rdoc/rdoc/code_objects.rb +536 -0
- data/tools/rdoc/rdoc/diagram.rb +331 -0
- data/tools/rdoc/rdoc/generators/chm_generator.rb +112 -0
- data/tools/rdoc/rdoc/generators/html_generator.rb +1268 -0
- data/tools/rdoc/rdoc/generators/template/chm/chm.rb +86 -0
- data/tools/rdoc/rdoc/generators/template/html/html.rb +705 -0
- data/tools/rdoc/rdoc/generators/template/html/kilmer.rb +377 -0
- data/tools/rdoc/rdoc/generators/template/xml/rdf.rb +110 -0
- data/tools/rdoc/rdoc/generators/template/xml/xml.rb +110 -0
- data/tools/rdoc/rdoc/generators/xml_generator.rb +130 -0
- data/tools/rdoc/rdoc/options.rb +451 -0
- data/tools/rdoc/rdoc/parsers/parse_c.rb +287 -0
- data/tools/rdoc/rdoc/parsers/parse_f95.rb +118 -0
- data/tools/rdoc/rdoc/parsers/parse_rb.rb +2311 -0
- data/tools/rdoc/rdoc/parsers/parse_simple.rb +37 -0
- data/tools/rdoc/rdoc/parsers/parserfactory.rb +75 -0
- data/tools/rdoc/rdoc/rdoc.rb +219 -0
- data/tools/rdoc/rdoc/template.rb +234 -0
- data/tools/rdoc/rdoc/tokenstream.rb +25 -0
- data/tools/rdoc/rdoc.rb +9 -0
- 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:
|
data/lib/sqlpostgres.rb
ADDED
|
@@ -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:
|