pg 0.8.0-x86-mswin32-60
Sign up to get free protection for your applications and to get access to all the features.
- data/BSD +23 -0
- data/COPYING.txt +340 -0
- data/ChangeLog +261 -0
- data/Contributors +28 -0
- data/GPL +340 -0
- data/LICENSE +58 -0
- data/README +125 -0
- data/Rakefile +103 -0
- data/doc/postgres.html +278 -0
- data/doc/postgres.jp.html +256 -0
- data/ext/compat.c +541 -0
- data/ext/compat.h +180 -0
- data/ext/extconf.rb +87 -0
- data/ext/mingw/Rakefile +24 -0
- data/ext/mingw/build.rake +40 -0
- data/ext/mingw/pg.so +0 -0
- data/ext/mkrf_config.rb +138 -0
- data/ext/pg.c +3569 -0
- data/ext/pg.h +42 -0
- data/ext/vc/pg.sln +26 -0
- data/sample/losample.rb +47 -0
- data/sample/psql.rb +1181 -0
- data/sample/psqlHelp.rb +158 -0
- data/sample/test1.rb +63 -0
- data/sample/test2.rb +44 -0
- data/sample/test4.rb +71 -0
- data/spec/data/expected_trace.out +26 -0
- data/spec/data/random_binary_data +0 -0
- data/spec/pgconn_spec.rb +130 -0
- data/spec/pgresult_spec.rb +112 -0
- metadata +89 -0
data/sample/psqlHelp.rb
ADDED
@@ -0,0 +1,158 @@
|
|
1
|
+
#
|
2
|
+
# Help for query language syntax
|
3
|
+
#
|
4
|
+
# Original source code is written by C.
|
5
|
+
# Copyright (c) 1996, Regents of the University of California
|
6
|
+
#
|
7
|
+
# ruby version is written by ematsu
|
8
|
+
# Copyright (c) 1997 Eiji-usagi-MATSUmoto <ematsu@pfu.co.jp>
|
9
|
+
#
|
10
|
+
# $Id: psqlHelp.rb,v 1.1.1.2 2002/04/24 05:46:44 noboru Exp $
|
11
|
+
|
12
|
+
|
13
|
+
QL_HELP = [
|
14
|
+
[ "abort",
|
15
|
+
"abort the current transaction",
|
16
|
+
"abort [transaction];"],
|
17
|
+
[ "abort transaction",
|
18
|
+
"abort the current transaction",
|
19
|
+
"abort [transaction];"],
|
20
|
+
[ "alter table",
|
21
|
+
"add/rename attributes, rename tables",
|
22
|
+
"\talter table <class_name> [*] add column <attr> <type>;\n\talter table <class_name> [*] rename [column] <attr1> to <attr2>;\n\talter table <class_name1> rename to <class_name2>"],
|
23
|
+
[ "begin",
|
24
|
+
"begin a new transaction",
|
25
|
+
"begin [transaction|work];"],
|
26
|
+
[ "begin transaction",
|
27
|
+
"begin a new transaction",
|
28
|
+
"begin [transaction|work];"],
|
29
|
+
[ "begin work",
|
30
|
+
"begin a new transaction",
|
31
|
+
"begin [transaction|work];"],
|
32
|
+
[ "cluster",
|
33
|
+
"create a clustered index (from an existing index)",
|
34
|
+
"cluster <index_name> on <relation_name>"],
|
35
|
+
[ "close",
|
36
|
+
"close an existing cursor (cursor)",
|
37
|
+
"close <cursorname>;"],
|
38
|
+
[ "commit",
|
39
|
+
"commit a transaction",
|
40
|
+
"commit [work]"],
|
41
|
+
[ "commit work",
|
42
|
+
"commit a transaction",
|
43
|
+
"commit [work]"],
|
44
|
+
[ "copy",
|
45
|
+
"copy data to and from a table",
|
46
|
+
"copy [binary] <class_name> [with oids]\n\t{to|from} {<filename>|stdin|stdout} [using delimiters <delim>];"],
|
47
|
+
[ "create",
|
48
|
+
"Please more be specific:",
|
49
|
+
"\tcreate aggregate\n\tcreate database\n\tcreate function\n\tcreate index\n\tcreate operator\n\tcreate rule\n\tcreate table\n\tcreate type\n\tcreate view"],
|
50
|
+
[ "create aggregate",
|
51
|
+
"define an aggregate function",
|
52
|
+
"create aggregate <agg_name> [as] (basetype = <data_type>, \n\t[sfunc1 = <sfunc_1>, stype1 = <sfunc1_return_type>]\n\t[sfunc2 = <sfunc_2>, stype2 = <sfunc2_return_type>]\n\t[,finalfunc = <final-function>]\n\t[,initcond1 = <initial-cond1>][,initcond2 = <initial-cond2>]);"],
|
53
|
+
[ "create database",
|
54
|
+
"create a database",
|
55
|
+
"create database <dbname>"],
|
56
|
+
[ "create function",
|
57
|
+
"create a user-defined function",
|
58
|
+
"create function <function_name> ([<type1>,...<typeN>]) returns <return_type>\n\tas '<object_filename>'|'<sql-queries>'\n\tlanguage 'c'|'sql'|'internal';"],
|
59
|
+
[ "create index",
|
60
|
+
"construct an index",
|
61
|
+
"create [unique] index <indexname> on <class_name> [using <access_method>] (<attr1>|<funcname>(<attr1>,...) [<type_class1>]);"],
|
62
|
+
[ "create operator",
|
63
|
+
"create a user-defined operator",
|
64
|
+
"create operator <operator_name> (\n\t[leftarg = <type1>][,rightarg = <type2>]\n\t,procedure = <func_name>,\n\t[,commutator = <com_op>][,negator = <neg_op>]\n\t[,restrict = <res_proc>][,hashes]\n\t[,join = <join_proc>][,sort = <sort_op1>...<sort_opN>]);"],
|
65
|
+
[ "create rule",
|
66
|
+
"define a new rule",
|
67
|
+
"create rule <rule_name> as on\n\t[select|update|delete|insert]\n\tto <object> [where <qual>]\n\tdo [instead] [<action>|nothing| [<actions>]];"],
|
68
|
+
[ "create table",
|
69
|
+
"create a new table",
|
70
|
+
"create table <class_name> ( <attr1> <type1>,... <attrN> <typeN>)\n\t[inherits (<class_name1>,...<class_nameN>\n\tarchive=<archive_mode>\n\tstore=<smgr_name>\n\tarch_store=<smgr_name>];"],
|
71
|
+
[ "create type",
|
72
|
+
"create a new user-defined base data type",
|
73
|
+
"create type <typename> (\n\tinternallength = (<number> | variable),\n\t[externallength = (<number>|variable),]\n\tinput=<input_function>, output = <output_function>\n\t[,element = <typename>][,delimiter=<character>][,default=\'<string>\']\n\t[,send = <send_function>][,receive = <receive_function>][,passedbyvalue]);"],
|
74
|
+
[ "create view",
|
75
|
+
"create a view",
|
76
|
+
"create view <view_name> as select <expr1>[as <attr1>][,... <exprN>[as <attrN>]] [from <from_list>] [where <qual>];"],
|
77
|
+
[ "declare",
|
78
|
+
"set up a cursor",
|
79
|
+
"declare <cursorname> [binary] cursor for\n\tselect [distinct]\n\t<expr1> [as <attr1>],...<exprN> [as <attrN>]\n\t[from <from_list>] [where <qual>]\n\t[order by <attr1> [using <op1>],... <attrN> [using <opN>]];"],
|
80
|
+
[ "delete",
|
81
|
+
"delete tuples",
|
82
|
+
"delete from <class_name> [where <qual>];"],
|
83
|
+
[ "drop",
|
84
|
+
"Please more be specific:",
|
85
|
+
"\tdrop aggregate\n\tdrop database\n\tdrop function\n\tdrop index\n\tdrop operator\n\tdrop rule\n\tdrop table\n\tdrop type\n\tdrop view"],
|
86
|
+
[ "drop aggregate",
|
87
|
+
"remove an aggregate function",
|
88
|
+
"drop aggregate <agg_name>;"],
|
89
|
+
[ "drop database",
|
90
|
+
"remove a database",
|
91
|
+
"drop database <dbname>"],
|
92
|
+
[ "drop function",
|
93
|
+
"remove a user-defined function",
|
94
|
+
"drop function <funcname> ([<type1>,....<typeN>]);"],
|
95
|
+
[ "drop index",
|
96
|
+
"remove an existing index",
|
97
|
+
"drop index <indexname>;"],
|
98
|
+
[ "drop operator",
|
99
|
+
"remove a user-defined operator",
|
100
|
+
"drop operator <operator_name> ([<ltype>|none],[<rtype>|none]);"],
|
101
|
+
[ "drop rule",
|
102
|
+
"remove a rule",
|
103
|
+
"drop rule <rulename>;"],
|
104
|
+
[ "drop table",
|
105
|
+
"remove a table",
|
106
|
+
"drop table <class_name>[,...<class_nameN];"],
|
107
|
+
[ "drop type",
|
108
|
+
"remove a user-defined base type",
|
109
|
+
"drop type <typename>;"],
|
110
|
+
[ "drop view",
|
111
|
+
"remove a view",
|
112
|
+
"drop view <view_name>"],
|
113
|
+
[ "end",
|
114
|
+
"end the current transaction",
|
115
|
+
"end [transaction];"],
|
116
|
+
[ "end transaction",
|
117
|
+
"end the current transaction",
|
118
|
+
"end [transaction];"],
|
119
|
+
[ "explain",
|
120
|
+
"explain the query execution plan",
|
121
|
+
"explain [with {cost|plan|full}] <query>"],
|
122
|
+
[ "fetch",
|
123
|
+
"retrieve tuples from a cursor",
|
124
|
+
"fetch [forward|backward] [<number>|all] [in <cursorname>];"],
|
125
|
+
[ "grant",
|
126
|
+
"grant access control to a user or group",
|
127
|
+
"grant <privilege[,privilege,...]> on <rel1>[,...<reln>] to \n[public | group <group> | <username>]\n\t privilege is {ALL | SELECT | INSERT | UPDATE | DELETE | RULE}"],
|
128
|
+
[ "insert",
|
129
|
+
"insert tuples",
|
130
|
+
"insert into <class_name> [(<attr1>...<attrN>)]\n\t[values (<expr1>...<exprN>); |\n\tselect <expr1>,...<exprN> [from <from_clause>] [where <qual>];"],
|
131
|
+
[ "listen",
|
132
|
+
"listen for notification on a relation",
|
133
|
+
"listen <class_name>"],
|
134
|
+
[ "load",
|
135
|
+
"dynamically load a module",
|
136
|
+
"load <filename>;"],
|
137
|
+
[ "notify",
|
138
|
+
"signal all frontends and backends listening on a relation",
|
139
|
+
"notify <class_name>"],
|
140
|
+
[ "purge",
|
141
|
+
"purge historical data",
|
142
|
+
"purge <class_name> [before <abstime>] [after <reltime>];"],
|
143
|
+
[ "revoke",
|
144
|
+
"revoke access control from a user or group",
|
145
|
+
"revoke <privilege[,privilege,...]> on <rel1>[,...<reln>] from \n[public | group <group> | <username>]\n\t privilege is {ALL | SELECT | INSERT | UPDATE | DELETE | RULE}"],
|
146
|
+
[ "rollback",
|
147
|
+
"abort a transaction",
|
148
|
+
"rollback [transaction|work]"],
|
149
|
+
[ "select",
|
150
|
+
"retrieve tuples",
|
151
|
+
"select [distinct on <attr>] <expr1> [as <attr1>], ... <exprN> [as <attrN>]\n\t[into table <class_name>] [from <from_list>]\n\t[where <qual>]\n\t[order by <attr1>\n\t\t[using <op1>],..<attrN> [[using <opN>] | ASC | DESC]];" ],
|
152
|
+
[ "update",
|
153
|
+
"update tuples",
|
154
|
+
"update <class_name> set <attr1>=<expr1>,...<attrN>=<exprN> [from <from_clause>] [where <qual>];"],
|
155
|
+
[ "vacuum",
|
156
|
+
"vacuum the database, i.e. cleans out deleted records, updates statistics",
|
157
|
+
"vacuum [table];"]
|
158
|
+
]
|
data/sample/test1.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# original file src/test/examples/testlibpq.c
|
4
|
+
#
|
5
|
+
require 'pg'
|
6
|
+
|
7
|
+
def main
|
8
|
+
pghost = nil
|
9
|
+
pgport = nil
|
10
|
+
pgoptions = nil
|
11
|
+
pgtty = nil
|
12
|
+
dbname = "template1"
|
13
|
+
begin
|
14
|
+
conn = PGconn.connect(pghost,pgport,pgoptions,pgtty,dbname)
|
15
|
+
if $DEBUG
|
16
|
+
fd = open("/tmp/trace.out","w")
|
17
|
+
conn.trace(fd)
|
18
|
+
end
|
19
|
+
res = conn.exec("BEGIN")
|
20
|
+
res.clear
|
21
|
+
res = conn.exec("DECLARE myportal CURSOR FOR select * from pg_database")
|
22
|
+
res.clear
|
23
|
+
|
24
|
+
res = conn.exec("FETCH ALL in myportal")
|
25
|
+
if (res.status != PGresult::TUPLES_OK)
|
26
|
+
raise PGerror,"FETCH ALL command didn't return tuples properly\n"
|
27
|
+
end
|
28
|
+
|
29
|
+
for fld in res.fields
|
30
|
+
printf("%-15s",fld)
|
31
|
+
end
|
32
|
+
printf("\n\n")
|
33
|
+
|
34
|
+
res.result.each do |tupl|
|
35
|
+
tupl.each do |fld|
|
36
|
+
printf("%-15s",fld)
|
37
|
+
end
|
38
|
+
printf("\n")
|
39
|
+
end
|
40
|
+
res = conn.exec("CLOSE myportal")
|
41
|
+
res = conn.exec("END")
|
42
|
+
res.clear
|
43
|
+
conn.close
|
44
|
+
|
45
|
+
if $DEBUG
|
46
|
+
fl.close
|
47
|
+
end
|
48
|
+
rescue PGError
|
49
|
+
if (conn.status == PGconn::CONNECTION_BAD)
|
50
|
+
printf(STDERR, "We have lost the connection to the backend, so ")
|
51
|
+
printf(STDERR, "further processing is impossible. ")
|
52
|
+
printf(STDERR, "Terminating.\n")
|
53
|
+
else
|
54
|
+
printf(STDERR, conn.error)
|
55
|
+
end
|
56
|
+
exit(1)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
main
|
61
|
+
|
62
|
+
|
63
|
+
|
data/sample/test2.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# original file src/test/examples/testlibpq2.c
|
4
|
+
# Test of the asynchronous notification interface
|
5
|
+
# CREATE TABLE TBL1 (i int4);
|
6
|
+
# CREATE TABLE TBL2 (i int4);
|
7
|
+
# CREATE RULE r1 AS ON INSERT TO TBL1 DO (INSERT INTO TBL2 values (new.i); \
|
8
|
+
# NOTIFY TBL2);
|
9
|
+
# Then start up this program
|
10
|
+
# After the program has begun, do
|
11
|
+
# INSERT INTO TBL1 values (10);
|
12
|
+
|
13
|
+
|
14
|
+
require 'pg'
|
15
|
+
|
16
|
+
def main
|
17
|
+
pghost = nil
|
18
|
+
pgport = nil
|
19
|
+
pgoptions = nil
|
20
|
+
pgtty = nil
|
21
|
+
dbname = ENV['USER']
|
22
|
+
begin
|
23
|
+
conn = PGconn.connect(pghost,pgport,pgoptions,pgtty,dbname)
|
24
|
+
rescue PGError
|
25
|
+
printf(STDERR, "Connection to database '%s' failed.\n",dbname)
|
26
|
+
exit(2)
|
27
|
+
end
|
28
|
+
begin
|
29
|
+
res = conn.exec("LISTEN TBL2")
|
30
|
+
rescue PGError
|
31
|
+
printf(STDERR, "LISTEN command failed\n")
|
32
|
+
exit(2)
|
33
|
+
end
|
34
|
+
res.clear
|
35
|
+
while 1
|
36
|
+
notify = conn.get_notify
|
37
|
+
if (notify)
|
38
|
+
printf(STDERR,"ASYNC NOTIFY '%s' from backend pid '%d' received\n",notify[0],notify[1])
|
39
|
+
break
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
main
|
data/sample/test4.rb
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# original file src/test/examples/testlibpq4.c
|
4
|
+
# this test programs shows to use LIBPQ to make multiple backend
|
5
|
+
#
|
6
|
+
require 'pg'
|
7
|
+
|
8
|
+
def main
|
9
|
+
if (ARGV.size != 4)
|
10
|
+
printf(STDERR,"usage: %s tableName dbName1 dbName2\n", ARGV[0])
|
11
|
+
printf(STDERR," compares two tables in two databases\n")
|
12
|
+
exit(1)
|
13
|
+
end
|
14
|
+
tblname = ARGV[1]
|
15
|
+
dbname1 = ARGV[2]
|
16
|
+
dbname2 = ARGV[3]
|
17
|
+
pghost = nil
|
18
|
+
pgport = nil
|
19
|
+
pgoptions = nil
|
20
|
+
pgtty = nil
|
21
|
+
|
22
|
+
begin
|
23
|
+
conn1 = PGconn.connect(pghost,pgport,pgoptions,pgtty,dbname1)
|
24
|
+
conn2 = PGconn.connect(pghost,pgport,pgoptions,pgtty,dbname2)
|
25
|
+
rescue PGError
|
26
|
+
printf(STDERR,"connection to database.\n")
|
27
|
+
exit(1)
|
28
|
+
end
|
29
|
+
begin
|
30
|
+
res1 = conn1.exec("BEGIN")
|
31
|
+
res1.clear
|
32
|
+
res1 = conn1.exec("DECLARE myportal CURSOR FOR select * from pg_database")
|
33
|
+
res1.clear
|
34
|
+
|
35
|
+
res1 = conn1.exec("FETCH ALL in myportal")
|
36
|
+
if (res1.status != PGresult::TUPLES_OK)
|
37
|
+
raise PGerror,"FETCH ALL command didn't return tuples properly\n"
|
38
|
+
end
|
39
|
+
|
40
|
+
for fld in res1.fields
|
41
|
+
printf("%-15s",fld)
|
42
|
+
end
|
43
|
+
printf("\n\n")
|
44
|
+
|
45
|
+
res1.result.each do |tupl|
|
46
|
+
tupl.each do |fld|
|
47
|
+
printf("%-15s",fld)
|
48
|
+
end
|
49
|
+
printf("\n")
|
50
|
+
end
|
51
|
+
res1 = conn1.exec("CLOSE myportal")
|
52
|
+
res1 = conn1.exec("END")
|
53
|
+
res1.clear
|
54
|
+
conn1.close
|
55
|
+
|
56
|
+
rescue PGError
|
57
|
+
if (conn1.status == PGconn::CONNECTION_BAD)
|
58
|
+
printf(STDERR, "We have lost the connection to the backend, so ")
|
59
|
+
printf(STDERR, "further processing is impossible. ")
|
60
|
+
printf(STDERR, "Terminating.\n")
|
61
|
+
else
|
62
|
+
printf(STDERR, conn1.error)
|
63
|
+
end
|
64
|
+
exit(1)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
main
|
69
|
+
|
70
|
+
|
71
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
To backend> Msg Q
|
2
|
+
To backend> "SELECT 1 AS one"
|
3
|
+
To backend> Msg complete, length 21
|
4
|
+
From backend> T
|
5
|
+
From backend (#4)> 28
|
6
|
+
From backend (#2)> 1
|
7
|
+
From backend> "one"
|
8
|
+
From backend (#4)> 0
|
9
|
+
From backend (#2)> 0
|
10
|
+
From backend (#4)> 23
|
11
|
+
From backend (#2)> 4
|
12
|
+
From backend (#4)> -1
|
13
|
+
From backend (#2)> 0
|
14
|
+
From backend> D
|
15
|
+
From backend (#4)> 11
|
16
|
+
From backend (#2)> 1
|
17
|
+
From backend (#4)> 1
|
18
|
+
From backend (1)> 1
|
19
|
+
From backend> C
|
20
|
+
From backend (#4)> 11
|
21
|
+
From backend> "SELECT"
|
22
|
+
From backend> Z
|
23
|
+
From backend (#4)> 5
|
24
|
+
From backend> Z
|
25
|
+
From backend (#4)> 5
|
26
|
+
From backend> I
|
Binary file
|
data/spec/pgconn_spec.rb
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'spec'
|
3
|
+
|
4
|
+
$LOAD_PATH.unshift('ext')
|
5
|
+
require 'pg'
|
6
|
+
|
7
|
+
describe PGconn do
|
8
|
+
|
9
|
+
before( :all ) do
|
10
|
+
puts "====== TESTING PGconn ======"
|
11
|
+
@test_directory = File.join(Dir.getwd, "tmp_test_#{rand}")
|
12
|
+
@test_pgdata = File.join(@test_directory, 'data')
|
13
|
+
if File.exists?(@test_directory) then
|
14
|
+
raise "test directory exists!"
|
15
|
+
end
|
16
|
+
@port = 54321
|
17
|
+
@conninfo = "host=localhost port=#{@port} dbname=test"
|
18
|
+
Dir.mkdir(@test_directory)
|
19
|
+
Dir.mkdir(@test_pgdata)
|
20
|
+
cmds = []
|
21
|
+
cmds << "initdb -D \"#{@test_pgdata}\""
|
22
|
+
cmds << "pg_ctl -o \"-p #{@port}\" -D \"#{@test_pgdata}\" start"
|
23
|
+
cmds << "sleep 5"
|
24
|
+
cmds << "createdb -p #{@port} test"
|
25
|
+
|
26
|
+
cmds.each do |cmd|
|
27
|
+
if not system(cmd) then
|
28
|
+
raise "Error executing cmd: #{cmd}: #{$?}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
@conn = PGconn.connect(@conninfo)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should connect successfully with connection string" do
|
35
|
+
tmpconn = PGconn.connect(@conninfo)
|
36
|
+
tmpconn.status.should== PGconn::CONNECTION_OK
|
37
|
+
tmpconn.finish
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should connect using 7 arguments converted to strings" do
|
41
|
+
tmpconn = PGconn.connect('localhost', @port, nil, nil, :test, nil, nil)
|
42
|
+
tmpconn.status.should== PGconn::CONNECTION_OK
|
43
|
+
tmpconn.finish
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should connect using hash" do
|
47
|
+
tmpconn = PGconn.connect(
|
48
|
+
:host => 'localhost',
|
49
|
+
:port => @port,
|
50
|
+
:dbname => :test)
|
51
|
+
tmpconn.status.should== PGconn::CONNECTION_OK
|
52
|
+
tmpconn.finish
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should connect asynchronously" do
|
56
|
+
tmpconn = PGconn.connect_start(@conninfo)
|
57
|
+
socket = IO.for_fd(tmpconn.socket)
|
58
|
+
status = tmpconn.connect_poll
|
59
|
+
while(status != PGconn::PGRES_POLLING_OK) do
|
60
|
+
if(status == PGconn::PGRES_POLLING_READING)
|
61
|
+
if(not select([socket],[],[],5.0))
|
62
|
+
raise "Asynchronous connection timed out!"
|
63
|
+
end
|
64
|
+
elsif(status == PGconn::PGRES_POLLING_WRITING)
|
65
|
+
if(not select([],[socket],[],5.0))
|
66
|
+
raise "Asynchronous connection timed out!"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
status = tmpconn.connect_poll
|
70
|
+
end
|
71
|
+
tmpconn.status.should== PGconn::CONNECTION_OK
|
72
|
+
tmpconn.finish
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should not leave stale server connections after finish" do
|
76
|
+
PGconn.connect(@conninfo).finish
|
77
|
+
sleep 0.5
|
78
|
+
res = @conn.exec(%[SELECT COUNT(*) AS n FROM pg_stat_activity
|
79
|
+
WHERE usename IS NOT NULL])
|
80
|
+
# there's still the global @conn, but should be no more
|
81
|
+
res[0]['n'].should == '1'
|
82
|
+
end
|
83
|
+
|
84
|
+
unless RUBY_PLATFORM =~ /mswin|mingw/
|
85
|
+
it "should trace and untrace client-server communication" do
|
86
|
+
# be careful to explicitly close files so that the
|
87
|
+
# directory can be removed and we don't have to wait for
|
88
|
+
# the GC to run.
|
89
|
+
|
90
|
+
expected_trace_file = File.join(Dir.getwd, "spec/data", "expected_trace.out")
|
91
|
+
expected_trace_data = open(expected_trace_file, 'rb').read
|
92
|
+
trace_file = open(File.join(@test_directory, "test_trace.out"), 'wb')
|
93
|
+
@conn.trace(trace_file)
|
94
|
+
trace_file.close
|
95
|
+
res = @conn.exec("SELECT 1 AS one")
|
96
|
+
@conn.untrace
|
97
|
+
res = @conn.exec("SELECT 2 AS two")
|
98
|
+
trace_file = open(File.join(@test_directory, "test_trace.out"), 'rb')
|
99
|
+
trace_data = trace_file.read
|
100
|
+
trace_file.close
|
101
|
+
trace_data.should == expected_trace_data
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
it "should cancel a query" do
|
106
|
+
error = false
|
107
|
+
@conn.send_query("SELECT pg_sleep(1000)")
|
108
|
+
@conn.cancel
|
109
|
+
tmpres = @conn.get_result
|
110
|
+
if(tmpres.result_status != PGresult::PGRES_TUPLES_OK)
|
111
|
+
error = true
|
112
|
+
end
|
113
|
+
error.should == true
|
114
|
+
end
|
115
|
+
|
116
|
+
after( :all ) do
|
117
|
+
puts ""
|
118
|
+
@conn.finish
|
119
|
+
cmds = []
|
120
|
+
cmds << "pg_ctl -D \"#{@test_pgdata}\" stop"
|
121
|
+
cmds << "rm -rf \"#{@test_directory}\""
|
122
|
+
cmds.each do |cmd|
|
123
|
+
if not system(cmd) then
|
124
|
+
raise "Error executing cmd: #{cmd}: #{$?}"
|
125
|
+
end
|
126
|
+
end
|
127
|
+
puts "====== COMPLETED TESTING PGconn ======"
|
128
|
+
puts ""
|
129
|
+
end
|
130
|
+
end
|