From a893de222b97ce1222a55324f1811b0262aae2d0 Mon Sep 17 00:00:00 2001 From: HD Moore Date: Sun, 15 Apr 2012 13:56:47 -0500 Subject: [PATCH] Detect older installation environments and load the arch-lib directories into the search path --- .../win32/pg-0.13.2-x86-mingw32/.gemtest | 0 .../arch-old/win32/pg-0.13.2-x86-mingw32/BSDL | 22 + .../win32/pg-0.13.2-x86-mingw32/ChangeLog | 2171 +++++++++++ .../pg-0.13.2-x86-mingw32/Contributors.rdoc | 46 + .../win32/pg-0.13.2-x86-mingw32/History.rdoc | 119 + .../win32/pg-0.13.2-x86-mingw32/LICENSE | 56 + .../win32/pg-0.13.2-x86-mingw32/Manifest.txt | 42 + .../win32/pg-0.13.2-x86-mingw32/POSTGRES | 23 + .../pg-0.13.2-x86-mingw32/README-OS_X.rdoc | 68 + .../pg-0.13.2-x86-mingw32/README-Windows.rdoc | 67 + .../pg-0.13.2-x86-mingw32/README.ja.rdoc | 7 + .../win32/pg-0.13.2-x86-mingw32/README.rdoc | 100 + .../win32/pg-0.13.2-x86-mingw32/Rakefile | 148 + .../pg-0.13.2-x86-mingw32/Rakefile.cross | 239 ++ .../pg-0.13.2-x86-mingw32/ext/extconf.rb | 76 + .../win32/pg-0.13.2-x86-mingw32/ext/pg.c | 447 +++ .../win32/pg-0.13.2-x86-mingw32/ext/pg.h | 123 + .../pg-0.13.2-x86-mingw32/ext/pg_connection.c | 3288 +++++++++++++++++ .../pg-0.13.2-x86-mingw32/ext/pg_result.c | 905 +++++ .../win32/pg-0.13.2-x86-mingw32/ext/vc/pg.sln | 26 + .../ext/vc/pg_18/pg.vcproj | 216 ++ .../ext/vc/pg_19/pg_19.vcproj | 209 ++ .../pg-0.13.2-x86-mingw32/lib/1.8/pg_ext.so | Bin 0 -> 1738240 bytes .../pg-0.13.2-x86-mingw32/lib/1.9/pg_ext.so | Bin 0 -> 1640448 bytes .../win32/pg-0.13.2-x86-mingw32/lib/pg.rb | 52 + .../lib/pg/connection.rb | 58 + .../pg-0.13.2-x86-mingw32/lib/pg/constants.rb | 11 + .../lib/pg/exceptions.rb | 11 + .../pg-0.13.2-x86-mingw32/lib/pg/result.rb | 11 + .../pg-0.13.2-x86-mingw32/sample/async_api.rb | 104 + .../sample/async_copyto.rb | 39 + .../sample/async_mixed.rb | 56 + .../pg-0.13.2-x86-mingw32/sample/copyfrom.rb | 81 + .../pg-0.13.2-x86-mingw32/sample/copyto.rb | 19 + .../pg-0.13.2-x86-mingw32/sample/cursor.rb | 21 + .../pg-0.13.2-x86-mingw32/sample/losample.rb | 69 + .../sample/notify_wait.rb | 72 + .../sample/test_binary_values.rb | 33 + .../spec/data/expected_trace.out | 26 + .../spec/data/random_binary_data | Bin 0 -> 5120 bytes .../pg-0.13.2-x86-mingw32/spec/lib/helpers.rb | 244 ++ .../spec/pg/connection_spec.rb | 825 +++++ .../spec/pg/result_spec.rb | 251 ++ .../pg-0.13.2-x86-mingw32/spec/pg_spec.rb | 22 + lib/msf/env/gemcache.rb | 13 +- 45 files changed, 10414 insertions(+), 2 deletions(-) create mode 100644 lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/.gemtest create mode 100644 lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/BSDL create mode 100644 lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/ChangeLog create mode 100644 lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/Contributors.rdoc create mode 100644 lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/History.rdoc create mode 100644 lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/LICENSE create mode 100644 lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/Manifest.txt create mode 100644 lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/POSTGRES create mode 100644 lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/README-OS_X.rdoc create mode 100644 lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/README-Windows.rdoc create mode 100644 lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/README.ja.rdoc create mode 100644 lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/README.rdoc create mode 100644 lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/Rakefile create mode 100644 lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/Rakefile.cross create mode 100644 lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/ext/extconf.rb create mode 100644 lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/ext/pg.c create mode 100644 lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/ext/pg.h create mode 100644 lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/ext/pg_connection.c create mode 100644 lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/ext/pg_result.c create mode 100644 lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/ext/vc/pg.sln create mode 100644 lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/ext/vc/pg_18/pg.vcproj create mode 100644 lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/ext/vc/pg_19/pg_19.vcproj create mode 100644 lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/lib/1.8/pg_ext.so create mode 100644 lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/lib/1.9/pg_ext.so create mode 100644 lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/lib/pg.rb create mode 100644 lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/lib/pg/connection.rb create mode 100644 lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/lib/pg/constants.rb create mode 100644 lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/lib/pg/exceptions.rb create mode 100644 lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/lib/pg/result.rb create mode 100644 lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/sample/async_api.rb create mode 100644 lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/sample/async_copyto.rb create mode 100644 lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/sample/async_mixed.rb create mode 100644 lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/sample/copyfrom.rb create mode 100644 lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/sample/copyto.rb create mode 100644 lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/sample/cursor.rb create mode 100644 lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/sample/losample.rb create mode 100644 lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/sample/notify_wait.rb create mode 100644 lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/sample/test_binary_values.rb create mode 100644 lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/spec/data/expected_trace.out create mode 100644 lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/spec/data/random_binary_data create mode 100644 lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/spec/lib/helpers.rb create mode 100644 lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/spec/pg/connection_spec.rb create mode 100644 lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/spec/pg/result_spec.rb create mode 100644 lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/spec/pg_spec.rb diff --git a/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/.gemtest b/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/.gemtest new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/BSDL b/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/BSDL new file mode 100644 index 000000000000..82725534facb --- /dev/null +++ b/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/BSDL @@ -0,0 +1,22 @@ +Copyright (C) 1993-2010 Yukihiro Matsumoto. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. diff --git a/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/ChangeLog b/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/ChangeLog new file mode 100644 index 000000000000..513d2d31e018 --- /dev/null +++ b/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/ChangeLog @@ -0,0 +1,2171 @@ +2012-02-22 Michael Granger + + * .hgtags: + Added tag v0.13.2 for changeset c79cd308363d + [d8e73919acb6] [tip] + + * .hgsigs: + Added signature for changeset 41e071bdd6ed + [c79cd308363d] [v0.13.2] + + * History.rdoc, lib/pg.rb: + Bumped patch version, updated history. + [41e071bdd6ed] + + * ext/extconf.rb: + Abort early if libpq is too old. + [fa5f8e1d7c19] + + * .rvmrc: + Updated rvmrc + [dbd04c449eea] + +2012-02-12 Michael Granger + + * .hgtags: + Added tag v0.13.1 for changeset 9e60b2c477cd + [f20d1b488312] + + * .hgsigs: + Added signature for changeset 1ba641824000 + [9e60b2c477cd] [v0.13.1] + + * .hoerc, History.rdoc, Manifest.txt, lib/pg.rb: + Bumped patch version, updated History, Manifest. + [1ba641824000] + + * ext/pg_connection.c, spec/pg/connection_spec.rb: + Raise a rescue-able exception when a connection is used after it's + been closed. (fixes #110) + [679b1db2b430] + +2012-02-11 Lars Kanis + + * Rakefile: + allow overriding of RUBY_CC_VERSION + [a9b8576bb35c] + + * Rakefile.cross: + update Postgresql download URL for cross compilation + [216d08f2bc92] + +2012-02-09 Michael Granger + + * misc/postgres/README.txt, misc/postgres/lib/postgres.rb: + Fix the Google group email and bump the patch version + [64aa4a38059e] + + * .hgignore, misc/postgres/History.txt, misc/postgres/Manifest.txt, + misc/postgres/README.txt, misc/postgres/Rakefile, + misc/postgres/lib/postgres.rb: + Add a stub gem build for the deprecated 'postgres' gem + [62271bf75eac] + + * .hgignore, misc/ruby-pg/History.txt, misc/ruby-pg/Manifest.txt, misc + /ruby-pg/README.txt, misc/ruby-pg/Rakefile, misc/ruby- + pg/lib/ruby/pg.rb: + Add a stub gem build for the deprecated 'ruby-pg' gem + [b7521150de9d] + + * BSDL: + Add missing BSDL license file (fixes #108) + [4d629ff60589] + + * History.rdoc: + Add the missing date to the History file + [29de189a4581] + + * .hgtags: + Added tag v0.13.0 for changeset 7b2da7e0815c + [150ea5f80ee4] + + * .hgsigs: + Added signature for changeset 9c262b875047 + [7b2da7e0815c] [v0.13.0] + +2012-01-28 Michael Granger + + * .hgsigs: + Added signature for changeset 0e7f0c2451e5 + [9c262b875047] + + * ext/extconf.rb: + Backed out the addition of `pg_config --libs` to the linked + libraries + [0e7f0c2451e5] + +2012-01-27 Michael Granger + + * Manifest.txt, README-OS_X.rdoc, README-Windows.rdoc, readme- + os_x.rdoc, readme-windows.rdoc: + More case-corrections + [5732b34d5769] + +2012-01-27 Michael Granger + + * postgres: + Merged in larskanis/ruby-pg (pull request #5) + [ad3e4338ad35] + +2012-01-26 Michael Granger + + * .hgsigs: + Added signature for changeset b67309d3ccf2 + [8f5629b33d76] + +2012-01-27 Lars Kanis + + * Manifest.txt, POSTGRES, Rakefile, ext/extconf.rb, ext/pg.h, + postgres: + fix cross compilation of win32 binary gem, fix mixed case file + naming + [17151d677ad7] + +2012-01-26 Michael Granger + + * .rvmrc, ext/pg_connection.c, spec/pg/connection_spec.rb: + Fix for Ruby 1.8, removed accidentally-committed encoding-testing + method. + [b67309d3ccf2] + +2012-01-24 Michael Granger + + * History.rdoc, Manifest.txt, README.rdoc, Rakefile, lib/pg.rb: + Updated the History file, Manifest, README, added missing require. + [b2cd37832d02] + + * .rvm.gems: + Removed rspec 2.8.1 -- not yet released, and 2.8.0 is now pulled in + via hoe-deveiate + [a4494f18a0d3] + + * lib/pg/constants.rb: + Whitespace cleanup + [e1b146cd9c2f] + + * sample/async_api.rb, sample/notify_wait.rb, sample/psql.rb, + sample/psqlHelp.rb, sample/test1.rb, sample/test2.rb, + sample/test4.rb, sample/test_binary_values.rb: + Cleaned up the sample/ directory + [287c71f3c89e] + + * .rvm.gems: + Bump hoe-deveiate version in the rvm gemset + [59d4530b4e43] + + * .rvm.gems, BSD, Contributors.rdoc, GPL, LICENSE, Manifest.txt, + README.OS_X.rdoc, README.ja.rdoc, README.rdoc, README.windows.rdoc, + Rakefile, postgres, readme-os_x.rdoc, readme-windows.rdoc: + Updated/simplified authors/license sections of the README, API doc + cleanup, updated license files (fixes #72). + [29a15971cd3a] + + * ext/pg.c, ext/pg_connection.c, ext/pg_result.c, spec/lib/helpers.rb, + spec/pg/connection_spec.rb: + Fix for exception message encoding (#96) + [1cdad2ce8993] + + * .pryrc, .tm_properties, Manifest.txt, README.rdoc, ext/compat.c, + ext/compat.h, ext/extconf.rb, ext/pg.c, ext/pg.h, + ext/pg_connection.c, ext/pg_result.c, lib/pg.rb, + lib/pg/connection.rb, lib/pg/constants.rb, lib/pg/exceptions.rb, + lib/pg/result.rb, misc/openssl-pg-segfault.rb, sample/async_api.rb, + sample/async_copyto.rb, sample/async_mixed.rb, sample/copyfrom.rb, + sample/copyto.rb, sample/cursor.rb, sample/losample.rb, + sample/notify_wait.rb, sample/psql.rb, sample/test1.rb, + sample/test2.rb, sample/test4.rb, sample/test_binary_values.rb, + spec/lib/helpers.rb, spec/m17n_spec.rb, spec/pg/connection_spec.rb, + spec/pg/result_spec.rb, spec/pg_spec.rb, spec/pgconn_spec.rb, + spec/pgresult_spec.rb: + Rearranging classes under the PG namespace to be a better Ruby + citizen + [f346861fbb8b] + +2012-01-19 Michael Granger + + * .hoerc, .rvm.gems, .rvmrc: + Adding rvmrc and gemset + [dca3d7464a00] + +2012-01-13 Michael Granger + + * Manifest.txt, sample/async_mixed.rb: + Adding an example of mixed synchronous/async API. + [3ba256ccee89] + +2012-01-03 Michael Granger + + * .hgtags: + Added tag v0.12.2 for changeset 88bd78632f86 + [622bef3960c3] + + * .hgsigs: + Added signature for changeset f3dfdb6929b7 + [88bd78632f86] [v0.12.2] + + * History.rdoc, ext/pg.c: + Bump patch version for release. + [f3dfdb6929b7] + + * ext/pg.c, spec/m17n_spec.rb: + Encode the messages of PGErrors with the encoding of the connection. + (fixes #96) + [b62c49d91eb2] + + * History.rdoc: + Updating history for Lars's patch + [5daf0ca646d2] + + * spec/m17n_spec.rb, spec/pgconn_spec.rb, spec/pgresult_spec.rb: + Moved all the spec hooks to the top of the file + [42671e5d4d67] + +2012-01-03 Michael Granger + + * Merged in larskanis/ruby-pg (pull request #4) + [8d88c47ccc9b] + +2012-01-03 Michael Granger + + * Merged with 6fc514ea2547 + [5ec3792d1cac] + +2011-12-27 Michael Granger + + * History.rdoc: + Updating history file with the st.h change + [935f29411410] + +2012-01-03 Lars Kanis + + * ext/extconf.rb, ext/pg.h: + Alternatively include 'st.h' instead of 'ruby/st.h'. This fixes + compilation on Ruby 1.8. + [0cf272cb383f] + +2012-01-02 Michael Granger + + * .hgtags: + Added tag v0.12.1 for changeset 21f84883e5c2 + [6fc514ea2547] + + * .hgsigs: + Added signature for changeset f72b14d349bf + [21f84883e5c2] [v0.12.1] + +2011-12-27 Michael Granger + + * Merged with f8d66e32b9a8 + [f72b14d349bf] + +2011-12-14 Michael Granger + + * History.rdoc, ext/pg.c: + Bumped patch version, updated History. + [f8d66e32b9a8] + +2011-12-27 Michael Granger + + * .tm_properties: + Adding my TextMate2 project settings + [daa6f202c54a] + + * ext/extconf.rb, ext/pg.h: + Explicitly include the st.h file for interpreters that need it + (fixes #95) + [448cccfe5bbb] + + * Rakefile.cross: + Allow native compiles without Mingw tools present + [f15ac13b396b] + + * Rakefile, Rakefile.cross: + Whitespace consistency fixes + [784c6c5cbea9] + +2011-12-14 Michael Granger + + * Rakefile: + Made rake-compiler a dev dependency. Thanks to eolamey@bitbucket and + Jeremy Evans for pointing out that it isn't needed for gem + installation. (Fixes #93) + [af645318f239] + +2011-12-07 Michael Granger + + * .hgtags: + Added tag v0.12.0 for changeset b767401684d8 + [1060487e7621] + + * .hgsigs: + Added signature for changeset 19b551f972e2 + [b767401684d8] [v0.12.0] + + * Contributors.rdoc, History.rdoc, Manifest.txt, README.rdoc: + Updated some metadata files in preparation for release. + [19b551f972e2] + +2011-10-31 Lars Kanis + + * README.windows.rdoc, Rakefile, Rakefile.cross: + re-add mingw32 cross compilation tasks, updated to current + pg,openssl,ruby versions + [a8b505d430d0] + +2011-12-07 Michael Granger + + * Rakefile: + Fix for the 'clobber' rake task under 1.9.x. + [c4952fd07cc0] + + * .hgignore: + Adding binary build dir to the ignorefile + [12ae62d666cb] + +2011-12-05 Michael Granger + + * Manifest.txt, Rakefile, ext/pg.c, spec/lib/helpers.rb, + spec/pgconn_spec.rb, spec/pgresult_spec.rb: + Fixes for PGresult#error_field + - Return +nil+ for unset PQresultErrorField() results instead of a + String wrapped around a NULL pointer + - Rename PGresult#result_error_field -> #error_field and + #result_error_message -> #error_message; aliases for backward + compatibility + - Add an example of how to COPY asynchronously + - Make the 'clobber' task clobber the spec tmpdir + - Log the command being run during test database setup/teardown + [6cece559d01c] + +2011-11-28 Michael Granger + + * sample/async_copyto.rb: + Adding an example of how to use COPY asynchronously + [9ebcdc3394fb] + + * sample/copyto.rb, sample/cursor.rb: + Fixing some comments + [13cd5d7e1307] + +2011-10-31 Michael Granger + + * Manifest.txt, ext/extconf.rb, ext/pg.c, spec/m17n_spec.rb: + Encdb fix for Ruby 1.9.3-rc1; thanks to wishdev@bitbucket for the + patch (fixes #88). + [31ff2758248a] + +2011-10-10 Michael Granger + + * sample/cursor.rb: + Adding an example of using a cursor with PGconn#exec + [0639e0040af1] + +2011-10-07 Michael Granger + + * .hgignore, Contributors, Contributors.rdoc, History.md, + History.rdoc, Manifest.txt, README.OS_X.md, README.OS_X.rdoc, + README.ja.md, README.ja.rdoc, README.md, README.rdoc, + README.windows.md, README.windows.rdoc, Rakefile, lib/pg.rb, + misc/openssl-1.0.0a.mingw-nocapi.patch: + Documentation update + [d8eea3141983] + + * ext/pg.c: + Ensure values returned from #wait_for_notify are tainted and encoded + [6d565a8c3670] + + * .hgtags: + Added tag v0.8.0 for changeset 7fbe4187e9e5 + [6f043966cbe4] + + * .hgtags: + Added tag v0.9.0 for changeset da726282493c + [ee09cf2d34ee] + + * ext/pg.c: + Bumping minor version. + [5acdaac61975] + + * ext/pg.c, spec/pgconn_spec.rb: + Make PGconn#wait_for_notify send nil as the payload argument if the + NOTIFY didn't have one. + [e47aa3bf402a] + + * ext/pg.c, spec/pgconn_spec.rb: + Making #wait_for_notify accept a nil argument for no timeout (Sequel + support) + [2d2e977241e4] + + * sample/async_api.rb, sample/copyfrom.rb, sample/losample.rb, + sample/psql.rb, sample/psqlHelp.rb, sample/test1.rb, + sample/test2.rb, sample/test4.rb: + Made all the samples executable + [7bc74288b271] + + * .gemtest, .hgsub, .hgsubstate, Contributors, History.md, + Manifest.txt, README, README.OS_X, README.OS_X.md, README.ja, + README.ja.md, README.md, README.windows, README.windows.md, + Rakefile, Rakefile.local, doc/postgres.html, doc/postgres.jp.html, + ext/extconf.rb, ext/mingw/Rakefile, ext/mingw/build.rake, + project.yml: + Converted to Hoe + [30bd5229899d] + +2011-09-18 Michael Granger + + * ext/pg.c: + Handle errors while rb_thread_select()ing in PGconn#block. Thanks to + Brian Weaver for the patch. + [adb5bb3175a4] + +2011-10-06 Michael Granger + + * ext/pg.c: + Added docs for the payload argument to the block from + PGconn#wait_for_notify + [3623caf38391] + +2011-09-16 Michael Granger + + * sample/copyto.rb: + Added an example of PGconn#get_copy_data. + [857ec5164f03] + +2011-09-01 Michael Granger + + * misc/openssl-pg-segfault.rb: + Adding a test file for duplicating the OpenSSL linking problem + [a810901bff03] + +2011-07-31 cwgem + + * sample/test1.rb: + Fixing an issue with out of data properties and constants in the + sample file. + [44b5f65d0abe] + +2011-06-17 Michael Granger + + * ext/pg.c: + Split out pgconn_block #ifdef madness into three functions; added + error-checking that will hopefully help with #75 + [3d744d9776c3] + +2011-06-07 Michael Granger + + * ext/pg.c: + Fix #ifdef for Ruby 1.9.2 under non-windows platform. + [88f7f11fe764] + + * ext/pg.c: + Merged Rafał Bigaj's fixes for Win32 async queries + [315a497006a3] + +2011-05-13 rafal + + * ext/pg.c: + Memory leak fixed: Closing opened WSA event. + [2bc78e46c1b6] + +2011-05-04 rafal + + * ext/pg.c: + Fixes for #66 Win32 asynchronous queries hang on connection error. + Using Winsock events and rb_w32_wait_events() on WIN32 and Ruby 1.9 + instead of rb_thread_select(). + [fc4109b2ddba] + +2011-04-14 rafal + + * ext/pg.c: + Fixes #66 Win32 asynchronous queries hang on connection error + [17a6a01c1725] + +2011-05-30 Michael Granger + + * spec/m17n_spec.rb, spec/pgconn_spec.rb, spec/pgresult_spec.rb: + Fixed executable name in spec shebangs (refs #74) + [70bf05114369] + +2011-05-18 Michael Granger + + * sample/async_api.rb: + Added a few more comments to the results part of the async example + [b5361e087db3] + + * sample/async_api.rb: + Adding an asynchronous API example + [cf4c3a05a380] + + * ext/pg.c: + Fixed a typo in PGconn#error_message's documentation + [34fc8e167542] + +2011-05-04 Michael Granger + + * ext/extconf.rb: + Quote the path to pg_config, since now we're using backticks instead + of pipe+exec. Closes #65. + [3ec32bb496b9] + +2011-04-22 Aaron Patterson + + * lib/pg.rb: + fixing unused variable warnings for ruby 1.9.3 + [37d40754ae58] + +2011-04-18 Michael Granger + + * .hgtags: + Added tag v0.11.0 for changeset 3cb8e57c6c80 + [9e8896275efa] + + * .hgsigs: + Added signature for changeset 24aa7899c696 + [3cb8e57c6c80] [v0.11.0] + + * ext/pg.c, lib/pg.rb, spec/pgconn_spec.rb: + Move connection-parameter parsing into Ruby, and make option- + handling more flexible. No longer segfaults on no-option, <7-option + array, and other combinations of arguments to ::connect and + ::connect_start. Fixes #67. + [24aa7899c696] + +2011-03-30 Michael Granger + + * Automated merge with ssh://bitbucket.org/larskanis/ruby-pg + [b477174160c8] + +2011-03-15 Lars Kanis + + * README.windows, Rakefile.local: + Update cross compilation tasks to use Ruby 1.8.7 instead of 1.8.6, + since pg.gem requires at least 1.8.7 to get installed + [cc3a7476465c] + +2011-03-12 Lars Kanis + + * README.windows: + Update readme for cross compile + [b90f74cb11a5] + + * Rakefile.local: + Use RUBY_CC_VERSION from command line, if set + [780650f201e3] + +2011-03-11 Lars Kanis + + * Rakefile.local: + update PG and OpenSSL version for cross compile + [31089d6c9dde] + + * Rakefile.local: + always run "make libpq.a" for cross compilation + [dfe3e7c1ea27] + + * Rakefile.local, ext/extconf.rb: + re-add required libs for cross compilation add ws2_32.dll because + libpq of PostgreSQL 9.0 makes use of it to determine host IP + addresses + [06e17573b133] + +2011-03-30 Michael Granger + + * ext/pg.c: + Comment the WIN32 console FD stuff so I remember what it does. + [56098b479a23] + +2011-02-23 Michael Granger + + * ext/pg.c: + Whitespace/line-ending fixes + [1baa7a8e673e] + + * ext/pg.c: + Merged with 1c3a1ca9f0cd + [fb7d22101adf] + +2011-01-22 Greg Hazel + + * ext/pg.c: + for windows support, duplicate the sockets from libpq and create + temporary CRT fds + [1c3a1ca9f0cd] + +2011-01-22 Michael Granger + + * Pulling fixes for Windows from ghazel on Github + [c3f163bf1ecd] + +2011-02-10 Michael Granger + + * ext/pg.c: + Bump minor version. + [18f413081e0c] + +2011-01-31 Michael Granger + + * Contributors, ext/pg.c, spec/pgresult_spec.rb: + Reformatting fixes for PGresult#[] and PGresult#values + [739692aa8dd1] + +2011-01-31 Jason Yanowitz + + * ext/pg.c, spec/pgresult_spec.rb: + added PGresult#values to get an array of arrays + [59679aee98ee] + +2011-01-19 Michael Granger + + * .hgtags: + Added tag v0.10.1 for changeset de10b5d8e442 + [8ab3dd3c757b] + + * .hgsigs: + Added signature for changeset 230ea3e68db2 + [de10b5d8e442] [v0.10.1] + + * ext/pg.h: + Add an include guard for pg.h + [230ea3e68db2] + + * lib/pg.rb: + Simplify the common case require of the ext + [f877d2d399cc] + + * ext/compat.h: + Include the extconf header + [8e1707a90330] + +2010-12-06 Michael Granger + + * ext/extconf.rb: + Experimenting with a greatly-simplified extconf, since the complex + one isn't solving any problems + [89348c8bb6d1] + + * ext/pg.c: + Bumping version to 0.10.1. + [aea173eec98a] + + * ext/extconf.rb, ext/pg.c: + Fixing compatibility with versions of PostgreSQL without + PQgetCancel. (fixes #36) + [d61e3310ea3d] + + * .hgsubstate, lib/pg.rb: + Fix require for natively-compiled extension under Windows. (fixes + #55) + [89979f184b22] + + * ext/pg.c, spec/pgconn_spec.rb: + Change rb_yield_splat() to rb_yield_values() for compatibility with + Rubinius. (fixes #54) + [9e11be78bfe4] + +2010-12-01 Michael Granger + + * .hgtags: + Removed tag 0.10.0 + [eb0d4b1df418] + + * .hgtags: + Added tag v0.10.0 for changeset 1822a169c4fe + [78a63dce1491] + + * spec/pgconn_spec.rb: + Fix deprecated expectation. + [469211f606ea] + + * .hgpatchinfo/pg90_notify_payload.dep, + .hgpatchinfo/pg90_notify_payload.desc: + Merged in Mahlon's wait_for_notify update for PostgreSQL 9's + notification payload + [857722663a6f] + + * Closing pg90_notify_payload pbranch for merge into default + [8ffb67a23f45] + + * ext/pg.c, spec/pgconn_spec.rb: + Finished the merge of default; fixed specs under 1.9.2. + [de86dca00ad2] + + * .hgpatchinfo/pg90_notify_payload.dep, ext/extconf.rb, ext/pg.c, + spec/lib/helpers.rb, spec/pgconn_spec.rb: + merge of default + [60664b2495cf] + + * .hgtags: + Added tag 0.10.0 for changeset 1822a169c4fe + [148d0cc3db4a] + + * .hgsigs: + Added signature for changeset 3993015a841e + [1822a169c4fe] [v0.10.0] + + * .hgignore, Rakefile.local: + Ignore the yard cache, handle missing rake-compiler for non-compile- + related tasks. + [3993015a841e] + +2010-11-11 Michael Granger + + * .hgsubstate, Rakefile, ext/pg.c, project.yml: + Build/gem updates + * Updated the build system with Rubygems suggestions from RubyConf + 2010 + * Bumped version to 0.10.0 to follow the Semantic Versioning spec + (http://semver.org/) + [71786704391b] + + * README, spec/pgconn_spec.rb: + Added a spec for collapsed notifications. + [899329ce1b4e] + +2010-11-01 Michael Granger + + * Rakefile.local, ext/extconf.rb: + More work trying to get the Windows-native gem to compile. No luck, + but it's closer. + * Revert the 1.8 build back to 1.8.6 on the advice of Louis Lavena's + blog: http://bit.ly/bFs4hj + * Undo the ARCHLIBDIR change + * Don't depend on the static-build option for the cross-compilation + section of extconf.rb to facilitate easy testing while the static + build parts are commented out. + [413f9e81e3ea] + +2010-10-31 Michael Granger + + * ext/compat.c, ext/pg.c, spec/lib/helpers.rb, spec/m17n_spec.rb, + spec/pgconn_spec.rb: + Fixed issue with PGconn#wait_for_notify that caused it to miss + notifications that happened after the LISTEN but before the + wait_for_notify. + [3402babf2cdf] + +2010-10-29 Michael Granger + + * .hgsubstate, Rakefile, project.yml, spec/m17n_spec.rb, + spec/pgconn_spec.rb, spec/pgresult_spec.rb: + Updated to RSpec 2.0 + [9d8f82721f69] + +2010-10-11 Michael Granger + + * Rakefile.local, ext/extconf.rb, misc/openssl-1.0.0a.mingw- + nocapi.patch: + Fixes for windows static build. + * Disable capi engine in OpenSSL build until it's fixed + (http://rt.openssl.org/Ticket/Display.html?id=1747) + * Rearrange some stuff in Rakefile.local to make the logic more + obvious + [b2df89600d95] + +2010-10-08 Michael Granger + + * ext/extconf.rb, ext/pg.c, spec/lib/helpers.rb, spec/pgconn_spec.rb: + Added support for the payload of NOTIFY events (w/Mahlon E. Smith) + [193043bf2244] + + * .hgpatchinfo/pg90_notify_payload.dep, + .hgpatchinfo/pg90_notify_payload.desc: + start new patch on default + [ce9b893ff824] + + * Rakefile.local, ext/extconf.rb: + Fixes to get the static windows build to work with PostgreSQL 9.0 + and OpenSSL 1.0.0a + [49ff3442c2ee] + +2010-09-28 Michael Granger + + * Rakefile.local: + More work trying to get the native windows gem to compile under + PostgreSQL 9.0 + [1fa5cd6851e3] + + * sample/copyfrom.rb: + Adding a sample of how to use COPY FROM + [c9fb855a7d50] + +2010-09-24 Michael Granger + + * .hgsubstate, Rakefile, Rakefile.local, project.yml, + spec/m17n_spec.rb, spec/pgconn_spec.rb, spec/pgresult_spec.rb: + Fixes for Ruby 1.9.2. + [d85ff87e5949] + + * Rakefile, ext/pg.c, lib/pg.rb, spec/lib/helpers.rb, + spec/pgconn_spec.rb: + Version bump, updates for PostgreSQL 9. + * Bump version to 0.9.1. + * Fixed the specs for JRuby (and other no-fork Ruby interpreters) + [5dbc24f596c8] + +2010-08-03 Michael Granger + + * .hgsubstate, Rakefile: + Merged JRuby fix into the build system, pulled down other build- + system updates. Thanks to timfel for the fix. + [1f8dd92ca16c] + +2010-08-03 Tim Felgentreff + + * Rakefile: + Fix to allow Rakefile to work on JRuby + [4f705f605e51] + +2010-08-02 Michael Granger + + * ext/pg.c, spec/m17n_spec.rb: + Honor Ruby's default_internal encoding when connecting via the + synchronous interface; fixes #33 + [92cc211ef553] + + * ext/extconf.rb: + Don't treat the installed pg_config not having archflags as an + error; fixes #39 + [a2237e39d399] + + * Rakefile.local, lib/pg.rb: + Install extension under arch-specific directory (RPS fix) + [14b882b7b88c] + +2010-07-26 Michael Granger + + * .hgsub, .hgsubstate: + Adding rake tasklibs as a sub-repo + [b0a5ae858569] + +2010-07-21 Michael Granger + + * spec/pgresult_spec.rb: + Removed spec for issue #22, as the library is behaving the same as + the underlying library; closes #22 + [37835e3b8701] + + * Merged with 168:dfaa59767b2e + [86f238c12fa3] + + * spec/pgconn_spec.rb: + Reworded an example's description and added a specific transaction- + abort spec + [dfaa59767b2e] + +2010-06-22 Michael Granger + + * Rakefile.local: + Merged with 170:5418a1d86d91 + [e756f8fb15d8] + + * Rakefile.local, ext/pg.c, sample/test_binary_values.rb: + Adding example of invalid binary data issue (refs #22), fixing + EXT_SO path + [8922f0a8ee44] + +2010-02-25 Michael Granger + + * spec/pgresult_spec.rb: + Adding a spec to test bug #12 + [cb92aa4b6599] + + * project.yml: + Adding rake-compiler to the dev dependencies + [86026f5ecf70] + +2010-06-22 Michael Granger + + * Rakefile.local, ext/extconf.rb: + Cross-compile tasks cleanup, extconf diagnostic improvement. + * Cleaned up the cross-compilation task, factored stuff up into + constants, used pure-ruby download, untar, etc. + * Improved diagnostics of failed extconf runs (refs #32, #24) + [5418a1d86d91] + + * .hgignore: + Adding some more stuff to the ignorefile + [07502a793f3a] + + * sample/losample.rb: + Modified the large-object sample script to reflect the pg library's + API (refs #35) + [873867122e80] + +2010-06-21 Michael Granger + + * .hgignore, Rakefile: + Updating build system, adding .orig files to ignore list. + [ea6eae59e917] + +2010-06-14 Michael Granger + + * spec/m17n_spec.rb: + Whitespace fix + [bb8a3baad96e] + +2010-05-26 Michael Granger + + * ext/extconf.rb: + Actually, just use the cflags from pg_config, which should resolve + both the -Wall and the -lsocket issue (refs #30) + [45e6518b780d] + + * ext/extconf.rb: + Fixing compilation for non-GCC platforms (fixes #30) + [730fb885ce08] + +2010-03-16 Michael Granger + + * ext/extconf.rb: + Fixed typo in ext/extconf.rb -- thanks to Keith Cascio for spotting + this. Closes #27. + [a47ffe890970] + +2010-02-28 Michael Granger + + * .hgtags: + Added tag 0.9.0 for changeset da726282493c + [9a296096f7e9] + + * .hgsigs: + Added signature for changeset 872063e42b12 + [da726282493c] [0.9.0, v0.9.0] + +2010-02-19 Michael Granger + + * Rakefile.local, ext/extconf.rb, ext/pg.c, ext/pg.h, lib/pg.rb: + Adding "fat gem" compatible loader, set the default RUBY_CC_VERSION. + [872063e42b12] + + * Rakefile, Rakefile.local: + Updated the Rakefile so it includes itself in gems. (closes #15) + Thanks to flameeyes@bitbucket for noticing this. + [ab525ca90531] + +2010-02-18 Michael Granger + + * ext/pg.c, spec/pgconn_spec.rb: + Applied patch for PGconn#async_exec to make it have the same + semantics as PGconn#exec (closes #19). Thanks again to Lars Kanis + for the patch. + [9c65eb905416] + +2010-02-17 Michael Granger + + * Rakefile: + Updated the Rakefile to always default the package version even if a + version can't be read from the VERSION_FILE. + [b0017ac0ecb5] + + * spec/lib/helpers.rb: + Improving spec database setup function (closes #18). Thanks to Lars + Kanis for another fine patch. + [c7d5458af696] + + * spec/m17n_spec.rb: + Ack! Removing typo + [39b11474d035] + + * spec/m17n_spec.rb: + Adding a test to ensure the result encoding remains the same even + when client_encoding in the connection changes. + [9d54bbc98488] + +2010-01-27 COMCARD-NT\kanis + + * spec/lib/helpers.rb: + drop an recreate the test db for each test + [bbe869c00d46] + +2010-01-26 kueche + + * ext/pg.c: + same behavior for async_exec like exec + [fdb088fca6e0] + + * spec/lib/helpers.rb: + improved test database setup + [825e424a4b08] + +2010-01-18 Michael Granger + + * ext/extconf.rb: + Made the 'make_header' in the extconf more clear. + [31afece7c203] + +2010-01-13 Jeff Davis + + * spec/pgconn_spec.rb: + Merged + [d9c920068712] + + * spec/pgconn_spec.rb: + In rspec tests, replace the pattern: CREATE TABLE ... INSERT ... + SELECT ... with: VALUES ... + [294eb6d5530b] + +2010-01-11 Michael Granger + + * ext/extconf.rb, ext/pg.c, spec/pgconn_spec.rb: + A better fix for the PGconn#block weirdness on Win32 (closes #16). + * Replaced the WIN32 conditionals in PGconn#block with a much simpler + solution. + * Added a few specs to test PGconn#block based on Lars Kanis's + proposed one. + + Thanks to both Lars and Shun for all their help with this issue. + [74fab32c2687] + +2010-01-11 COMCARD-NT\kanis + + * ext/pg.c: + remaped to async_exec + [df509c9a45c0] + + * merged from default + [7f9623f8af4c] + +2010-01-06 Michael Granger + + * README: + Rearranged the sections of the README. + [f8dfc1b6c51c] + +2010-01-08 COMCARD-NT\kanis + + * ext/pg.c, ext/pg.h, spec/pgconn_spec.rb: + reworked patch that should not block a second thread + [01ad62c60c74] + + * ext/pg.c: + merged with default + [d8936a677dd0] + +2010-01-05 Michael Granger + + * README.OS_X: + Updating MacOS X README. + [0df792de2a19] + +2010-01-04 Michael Granger + + * ext/pg.c: + Work around broken rb_thread_select() on win32; thanks to Lars Kanis + for the patch! + [2894973bc63f] + + * ext/pg.c, spec/pgresult_spec.rb: + Reverted removal of PGresult::InvalidOid, fixed broken spec. + [88dacdb9c97d] + + * .hgignore, README, Rakefile, ext/pg.c, project.yml: + Ignore some generated files, documentation work, removed type OID + constants. + * Updated the various READMEs with more up-to-date info. + * Updated build system (rdoc fixes, packaged files) + * Fixed some RDoc problems and formatting glitches + * Removed the type OID constants from PGresult; I was including them + so they could be used for comparison with PGresult#ftype return + values. RhodiumToad on #postgresql@freenode showed me the + format_type() SQL function, so I added an example of how to get + the same information via that function instead, which is + guaranteed to be correct even if src/include/catalog/pg_type.h + changes. + [739cec560448] + + * README.windows, Rakefile.local, ext/extconf.rb: + Applied patch for static cross-compilation of win32 gem from Lars + Kanis with a few changes to support MacOS X as a host as well. + Closes #13. Thanks Lars! + [38a0d2a90664] + +2010-01-04 COMCARD-NT\kanis + + * README.windows, Rakefile.local, ext/extconf.rb: + win32 cross-compilation patch applied + [b55949db8e2e] + + * ext/pg.c: + win32 workaround rb_thread_select() applied + [78fbefffe863] + +2010-01-03 Michael Granger + + * .irbrc, COPYING.txt, ChangeLog, MANIFEST, README, README.OS_X, + Rakefile, Rakefile.local, ext/extconf.rb, ext/pg.h, ext_helper.rb: + Updated build system + * Backed out the experimental arch-specific subdir of lib + * Removed second copy of GPL; one is more than enough. + * Removed the ChangeLog -- this should be built on demand instead of + checked in. + * Removed the out-of-date and now-superfluous MANIFEST + * Started updating the remaining documentation to reflect the current + state of the library/build instructions/people. + * Pass options to 'rake' through to extconf.rb, allowing 'rake -- + --with-pg-dir=/path/to/pg' + * Updated the handling of compilation on MacOS X to use the + architectures common to both libpq and Ruby. + * Use an extconf.h for configuration + * Removed the now-unused ext_helper.rb + + Still more work to be done, but I'm checkpointing this so it's not + too huge. + [f31202539234] + +2010-01-02 Michael Granger + + * .hgtags: + Added tag 0.8.0 for changeset 7fbe4187e9e5 + [cc09390cb0a8] + +2009-12-31 Michael Granger + + * Closing branch + [d5fa3e079a55] + + * ext/pg.c: + Bumped version to 0.9.0 + [05834d47aac3] + + * ext/mkrf_config.rb: + Merged i17n-19-patches branch + [0997a0aa7624] + +2009-12-30 COMCARD-NT\kanis + + * README.windows, Rakefile.local, ext/extconf.rb: + static library building for cross compilation + [065a842e7bf8] + +2009-12-28 Michael Granger + + * .hgignore, ext/pg.c, spec/pgconn_spec.rb: + Make PGconn.connect_start use PQconnectStart instead of PQconnectdb + so asynchronous connection works. Fixes #14; thanks to 'ibc' + @bitbucket for submitting the test case that brought this to my + attention. + [f5af71167dea] + + * ext/pg.c, spec/pgconn_spec.rb: + Added column-selection methods to PGresult (#field_values and + #column_values). Closes #12. Thanks to Sugano Yoshihisa for the + patch on which these methods were based. + [42919e2a4ef8] + +2009-12-23 Michael Granger + + * ext/pg.c, spec/pgconn_spec.rb: + Fixed #11: encrypt_arguments doesn't receive password, thanks to + Yuki Miyauchi for the patch. + [39fdb2552163] + + * .hgignore, ext/pg.c, spec/pgconn_spec.rb: + Fixed infinite loop in async_exec("COPY"), thanks to Mike Pomraning + for the patch. Closes #9. + [df770b6ad237] + +2009-12-16 Michael Granger + + * .hgignore, Contributors, Rakefile, Rakefile.local, ext/extconf.rb, + ext/pg.c, project.yml, spec/m17n_spec.rb, spec/pgconn_spec.rb, + spec/pgresult_spec.rb: + New build system, build with rake-compiler, added PGconn::VERSION. + * Replaced the existing Rakefile with a small core set of tasks and + task libraries under rake/. + * Added a PGconn::VERSION constant (closes #4). + * Replaced the ARCHFLAGS warning under Darwin with code to duplicate + the archflags Postgres was compiled with. + [4cbcf197cb82] + +2009-12-15 Michael Granger + + * Rakefile, ext/pg.c, spec/lib/helpers.rb, spec/pgconn_spec.rb: + Applied Rubyforge patch 26282; fixes #1. Thanks to Nikolai Lugovoi + for the patch. + [6ba661bbdb28] + +2009-12-11 Michael Granger + + * Rakefile, ext/pg.c, spec/lib/helpers.rb, spec/pgconn_spec.rb: + Notify spec fixes, cleanup, Rakefile clean task adjustments. + * Made PGconn#wait_for_notify do more error-checking to track down a + problem with running it in transactions. + * Moved PGconn#wait_for_notify source closer to PGconn#notifies + * Split some stuff that used to get removed by 'clean' into the + 'clobber' task instead. + [3e42badc15de] + + * .hgignore, spec/lib/helpers.rb, spec/pgconn_spec.rb: + Simplified the spec for PGconn#notify, still segfaulting. + [659d80221a45] + + * Merged Mahlon's examples-directory patch from default. + [26b614a7ece8] + + * ext/pg.c, spec/pgconn_spec.rb: + Merged Mahlon's notify patch from default. + [66234afab283] + +2009-12-10 Mahlon E. Smith + + * sample/notify_wait.rb: + Add a sample (usage example) for wait_for_notify(). + [1e6349a799c3] + + * ext/pg.c, sample/psql.rb, sample/psqlHelp.rb, spec/pgconn_spec.rb: + * Small documentation fix for conn.notifies() + * Add wait_for_notify(), a method to do a blocking select() for a + NOTIFY event. + [a3434e641f6a] + +2009-10-29 Michael Granger + + * ext/mkrf_config.rb: + Remove old mkrf config file to avoid confusion + [59549227d7c3] + +2009-10-28 Michael Granger + + * .hgignore, ext/pg.c, spec/pgresult_spec.rb: + Write specs for and applied patch #26283; thanks to Nikolai Lugovoi. + [f30139fb0587] + + * .hgignore, spec/data/expected_trace.out, spec/m17n_spec.rb, + spec/pgconn_spec.rb: + Fixups after conversion to Mercurial, fixing tests broken by the + changes in the previous commit. + * Fixed differences in expected trace output caused by every test + being wrapped in a transaction. + * Fixed require-order bug in two of the specs + * Corrected a mis-paste in the m17n spec before:all block + [a41d4291ffbb] + + * Rakefile, spec/lib/helpers.rb, spec/m17n_spec.rb, + spec/pgconn_spec.rb, spec/pgresult_spec.rb: + * Made spec output elide output from the command line by default, + and log everything for diagnostics. + * Factored out the database setup and teardown functions into helpers, + added a collection of other helper functions for specs. + * Added specs to cover behavior around Nikolai Lugovoi's patch + (#26283) for PGresult#fmod, #ftable, and #ftablecol prior to + applying it. + [91ee1ac36a54] + +2009-10-17 Michael Granger + + * .irbrc, Rakefile, ext/pg.c, ext/pg.h, spec/pgconn_spec.rb, + spec/pgresult_spec.rb: + Applied patch #26277; thanks to Nikolai Lugovoi. + * fixed number of parameters in definition of PGresult#paramtype -- + expected 1 but was declared 0 + * minor consistency update for range checks of column/tuple indices + * PGconn#lo_read : fixed to return string with length of really read + data, not provided length + + I also added: + * Constants for paramtype Oids. + * A couple of additional rake tasks + * Append PQerrorMessage to some exception messages + * Specs for the above patch + [0b28f9bd8935] + +2009-10-16 Michael Granger + + * Rakefile, ext/extconf.rb, ext/pg.c, ext/pg.h, spec/m17n_spec.rb, + spec/pgconn_spec.rb, spec/pgresult_spec.rb: + Build and warnings cleanup. + * Added a :default task + * Made spec execution quieter + * Silenced warning about 'dup()' by including unistd.h if we have it. + * Silenced warnings about generated exception messages by adding a + format. + [cb5335861c5d] + +2009-08-28 Michael Granger + + * ext/pg.c, spec/m17n_spec.rb: + Applied patch #26116; thanks to Nikolai Lugovoi. + * apply client encoding to result of @conn.escape(string) + * set ASCII_8BIT for results returned in binary format + * fixed memory leak on exception in @conn.escape(string) for truncated + multibyte + [1d001b550715] + + * ext/pg.c, spec/m17n_spec.rb, spec/pgconn_spec.rb, + spec/pgresult_spec.rb: + * Use pg_ctl -w instead of sleep for specs + * Fix up the specs to use #external_encoding, #internal_encoding, + and #internal_encoding= + * Added a pending spec for Johab (I can't figure out how to return + JOHAB-encoded results from Postgres) + [d67c62945540] + +2009-08-25 Michael Granger + + * Rakefile, ext/pg.c, ext_helper.rb, spec/m17n_spec.rb, + spec/pgconn_spec.rb, spec/pgresult_spec.rb: + * Applied patch from (rubyforge:25931), fixes (rubyforge:22925). + * Normalized indentation + * Create all databases without locale to ensure consistency. + * Fixed the gemspec to make copying of the .so to lib/ unnecessary. + Extensions belong in ext/. + [0524dd20fb0f] + +2009-07-30 Michael Granger + + * Making a branch for merging the patches and new specs to test them. + [d0267176eb61] + +2009-03-28 Jeff Davis + + * Rakefile, spec/pgconn_spec.rb, spec/pgresult_spec.rb: + Bump version to 0.8.0 + + Update tests. + [7fbe4187e9e5] [0.8.0, v0.8.0] + +2009-03-28 Charlie Savage + + * spec/pgconn_spec.rb: + Don't call file trace on windows. + [39a19c65b0a0] + + * Updated VC2008 project + [c4598eee6d1b] + + * ext/vc/pg.sln, ext/vc/pg_18/pg.vcproj, ext/vc/pg_19/pg_19.vcproj: + Updated VC2008 project + [c75883fb5979] + +2009-03-28 Jeff Davis + + * ext/pg.c: + Fix socket leak when connection error occurs. + + Thanks to: Andrea Barisani Rob Holland + + [4192e6d1ccc0] + + * ext/pg.c: + PGconn#lo_close was calling lo_unlink. + [03d6ef0de9ef] + + * ext/pg.h: + Change header so it builds correctly on 1.8 and 1.9. + [b27b4b4a54eb] + +2009-03-14 Charlie Savage + + * ext/pg.c: + Oops - use ALLOC_N not ALLOC, fixes compile error with VC2008. + [f7b97416c101] + + * spec/pgconn_spec.rb: + Ignore rdoc directory, pkg directory, nbproject directory. + [c0fd7531850f] + + * ext/mingw/Rakefile: + This rakefile is just used for installing the windows gem. + [c675c7534c4d] + + * ext/mingw/build.rake: + Split out building on mingw to a separate rake file. + [c3329724ef5b] + + * ext/vc/pg.sln, ext/vc/pg.vcproj, ext/vc/pg_18/pg.vcproj, + ext/vc/pg_19/pg_19.vcproj: + Updated VC2008 projects for Ruby 1.8 and Ruby 1.9 (1.9 not quite + setup yet). + [01e1dbb950c8] + + * Rakefile: + Added rdoc task so you can type rake rdoc. Makes it easier to debug + rdoc documentation. + [677d3eae5b16] + + * spec/pgresult_spec.rb: + Windows compatibility - use tcp/ip sockets, use full path names, + read files in binary mode. + [c33a73c14126] + + * spec/pgconn_spec.rb: + Ripple port change through text. Always full path to open spec + file. + [241d3410b875] + + * spec/pgconn_spec.rb: + First stab at getting test to work on Windows. Windows does not + support unix-sockets, so have to use tcp/ip sockets. Also windows + requires that command line parameters are quoted with " and not '. + [1bf29d30c16c] + + * ext/pg.h: + Export Init_pg in windows shared library. + [4dae2cabb5ae] + + * ext/pg.c: + Fix up memory handling for Windows (match ALLOC with xfree). + [4e9b028c55cd] + +2009-03-06 Jeff Davis + + * ext/pg.c: + 1.9 compatibility fixes. + [4a9ffd0aa913] + +2008-12-03 Jeff Davis + + * Rakefile, ext/compat.c, ext/mingw/Rakefile, ext/mingw/build.rake, + ext/mkrf_config.rb, ext/pg.c, ext/vc/pg.sln, ext/vc/pg.vcproj: + Add better support for windows build. + + Big thanks to Charlie Savage. + [7178d13749b7] + +2008-10-14 Jeff Davis + + * ext/extconf.rb: + Merged revisions 175 via svnmerge from + svn+ssh://jdavis@rubyforge.org/var/svn/ruby-pg/ruby-pg/trunk + + ........ r175 | jdavis | 2008-10-13 22:25:00 -0700 (Mon, 13 Oct + 2008) | 4 lines + + Revert r172. ........ + [4c2ea65f2eb9] + + * ext/extconf.rb: + Revert r172. + [3bf9ef75bae5] + +2008-10-05 Jeff Davis + + * ext/extconf.rb, ext/pg.c, spec/pgconn_spec.rb: + Merged revisions 169-173 via svnmerge from + svn+ssh://jdavis@rubyforge.org/var/svn/ruby-pg/ruby-pg/trunk + + ........ r169 | jdavis | 2008-08-20 19:48:10 -0700 (Wed, 20 Aug + 2008) | 6 lines + + Fixed option connection argument in the case of using 7 + arguments. + + Thanks Erik Hollensbe (erikh) for the bug report. ........ r170 + | jdavis | 2008-10-05 11:01:40 -0700 (Sun, 05 Oct 2008) | 4 lines + + Throw correct exception when result is NULL. ........ r171 | + jdavis | 2008-10-05 11:47:01 -0700 (Sun, 05 Oct 2008) | 12 lines + + Fix PGconn#async_exec and PGconn#get_last_result to properly clear + all results when an exception is raised. Before, the connection + could be left in a state that is not ready for new commands. + + Also, change PGconn#get_result to not raise an exception + when the result is in an error state. You can still check the + result object for an error, but it's not appropriate to raise an + exception, because that could prevent the caller from properly + clearing all results. + + Thanks to Tarmo Tänav. ........ r172 | jdavis | 2008-10-05 + 12:04:45 -0700 (Sun, 05 Oct 2008) | 6 lines + + Include all libraries listed in "pg_config --libs" in the build. + + Thanks Hans-Thomas Mueller. ........ r173 | jdavis | 2008-10-05 + 12:18:58 -0700 (Sun, 05 Oct 2008) | 4 lines + + Update spec tests. ........ + [7e7c22be0302] + + * spec/pgconn_spec.rb: + Update spec tests. + [cdf306d84adf] + + * ext/extconf.rb: + Include all libraries listed in "pg_config --libs" in the build. + + Thanks Hans-Thomas Mueller. + [0386537bd139] + + * ext/pg.c: + Fix PGconn#async_exec and PGconn#get_last_result to properly clear + all results when an exception is raised. Before, the connection + could be left in a state that is not ready for new commands. + + Also, change PGconn#get_result to not raise an exception when the + result is in an error state. You can still check the result object + for an error, but it's not appropriate to raise an exception, + because that could prevent the caller from properly clearing all + results. + + Thanks to Tarmo Tänav. + [68473ee45e28] + + * ext/pg.c: + Throw correct exception when result is NULL. + [622eec9c6b0b] + +2008-08-21 Jeff Davis + + * ext/pg.c: + Fixed option connection argument in the case of using 7 arguments. + + Thanks Erik Hollensbe (erikh) for the bug report. + [8e8045947a9c] + +2008-08-17 Jeff Davis + + * ext/pg.c: + Merged revisions 166 via svnmerge from + svn+ssh://jdavis@rubyforge.org/var/svn/ruby-pg/ruby-pg/trunk + + ........ r166 | jdavis | 2008-08-17 13:35:51 -0700 (Sun, 17 Aug + 2008) | 4 lines + + Typo fix. ........ + [3e9dda291ef3] + + * ext/pg.c: + Typo fix. + [c5c44a6267f7] + + * ext_helper.rb: + Add ext_helper.rb + [3686c9944fe1] + + * Rakefile, ext/extconf.rb, ext/pg.c, pg.gemspec, + spec/data/expected_trace.out, spec/data/random_binary_data, + spec/pgconn_spec.rb, spec/pgresult_spec.rb: + Merged revisions 149-160 via svnmerge from + svn+ssh://jdavis@rubyforge.org/var/svn/ruby-pg/ruby-pg/trunk + + ........ r149 | jdavis | 2008-03-19 14:17:20 -0700 (Wed, 19 Mar + 2008) | 5 lines + + This commmit just cleans up indenting and coding + conventions. It's a big patch, but does nothing meaningful. ........ + r150 | jdavis | 2008-03-19 14:19:53 -0700 (Wed, 19 Mar 2008) | 5 + lines + + + * forgot to add the expected output to the repository, so one + test was failing. Corrected now. ........ r151 | jdavis | + 2008-03-20 11:20:25 -0700 (Thu, 20 Mar 2008) | 12 lines + + + * added PGconn.connect_start(...) -> PGconn + * added test for PGconn.connect_start() + * refactored to separate the complexity of parsing the connection + arguments + * Removed some superfluous code for old versions of Ruby that + don't support rb_define_alloc_func(). Those versions of Ruby + most likely don't work anyway, and I'm not testing them. + + ........ r152 | jdavis | 2008-03-20 12:16:06 -0700 (Thu, 20 Mar + 2008) | 5 lines + + + * added PGconn#cancel() -> String + * added test for PGconn#cancel() ........ r153 | jdavis | 2008-04-21 + 10:13:39 -0700 (Mon, 21 Apr 2008) | 4 lines + + + * added some tests for binary data ........ r154 | jdavis | + 2008-04-21 10:24:05 -0700 (Mon, 21 Apr 2008) | 5 lines + + + * applied patch from Louis Lavena to improve the build process + (particularly for windows). ........ r155 | jdavis | 2008-04-21 + 10:41:04 -0700 (Mon, 21 Apr 2008) | 6 lines + + + * backtracked a small piece of the patch, to catch the condition + where pg_config is not in the PATH on posix platforms. ........ + r156 | jdavis | 2008-07-07 23:21:07 -0700 (Mon, 07 Jul 2008) | 6 + lines + + Fix oversight in connect arguments for options and + connect_timeout when passed in a hash. (Thanks Rob Holland for + the bug report). ........ r157 | jdavis | 2008-07-23 22:33:26 + -0700 (Wed, 23 Jul 2008) | 10 lines + + Changed all temporary allocations to use ALLOC_N (heap + allocation) rather than ALLOCA_N (stack allocation). In + particular, this allows PGconn#escape_string to accept larger + input strings without fear of exceeding the stack size. + + Thanks to Brett Neumeier. ........ r158 | jdavis | 2008-07-23 + 22:46:34 -0700 (Wed, 23 Jul 2008) | 6 lines + + Fixed PGconn#setnonblocking + + Thanks to Mohammad Ali (oldmoe) for the report. ........ r159 | + jdavis | 2008-08-17 11:19:09 -0700 (Sun, 17 Aug 2008) | 4 lines + + Applied build patch from Brett Neumeier. Thanks! ........ r160 + | jdavis | 2008-08-17 12:26:33 -0700 (Sun, 17 Aug 2008) | 7 lines + + Properly protect variables from garbage collection, preventing + possible memory corruption. + + Big thanks to Peter Seebach for reporting and clearly diagnosing + the problem. ........ + [ed3294b76bf7] + + * Initialized merge tracking via "svnmerge" with revisions "1-146" + from svn+ssh://jdavis@rubyforge.org/var/svn/ruby-pg/ruby-pg/trunk + [ff6af5fc4dc3] + + * Initialized merge tracking via "svnmerge" with revisions "1-146" + from svn+ssh://jdavis@rubyforge.org/var/svn/ruby-pg/ruby- + pg/trunk@146 + [1a7b63bacfee] + + * ext/pg.c: + Properly protect variables from garbage collection, preventing + possible memory corruption. + + Big thanks to Peter Seebach for reporting and clearly diagnosing the + problem. + [ed8927d7f45d] + + * Rakefile: + Applied build patch from Brett Neumeier. Thanks! + [c7c5d25c851c] + +2008-07-24 Jeff Davis + + * ext/pg.c: + Fixed PGconn#setnonblocking + + Thanks to Mohammad Ali (oldmoe) for the report. + [48d2bdfcc630] + + * ext/pg.c: + Changed all temporary allocations to use ALLOC_N (heap allocation) + rather than ALLOCA_N (stack allocation). In particular, this allows + PGconn#escape_string to accept larger input strings without fear of + exceeding the stack size. + + Thanks to Brett Neumeier. + [b2e1bc03aca5] + +2008-07-08 Jeff Davis + + * ext/pg.c: + Fix oversight in connect arguments for options and connect_timeout + when passed in a hash. (Thanks Rob Holland for the bug report). + [c775c24a75f9] + +2008-04-21 Jeff Davis + + * ext/extconf.rb, pg.gemspec: + * backtracked a small piece of the patch, to catch the condition + where pg_config is not in the PATH on posix platforms. + [b86f0f75181e] + + * Rakefile, ext/extconf.rb, ext_helper.rb, pg.gemspec: + * applied patch from Louis Lavena to improve the build process + (particularly for windows). + [b3a05d09fb27] + + * spec/data/random_binary_data, spec/pgconn_spec.rb, + spec/pgresult_spec.rb: + * added some tests for binary data + [7579885aff18] + +2008-03-20 Jeff Davis + + * ext/pg.c, spec/pgconn_spec.rb: + * added PGconn#cancel() -> String + * added test for PGconn#cancel() + [de58e242dd99] + + * ext/pg.c, spec/pgconn_spec.rb: + * added PGconn.connect_start(...) -> PGconn + * added test for PGconn.connect_start() + * refactored to separate the complexity of parsing the connection + arguments + * Removed some superfluous code for old versions of Ruby that don't + support rb_define_alloc_func(). Those versions of Ruby most + likely don't work anyway, and I'm not testing them. + [778892302876] + +2008-03-19 Jeff Davis + + * spec/data/expected_trace.out: + * forgot to add the expected output to the repository, so one + test was failing. Corrected now. + [630cca5e74c1] + + * ext/pg.c: + This commmit just cleans up indenting and coding conventions. It's + a big patch, but does nothing meaningful. + [661ed2fea9e2] + +2008-03-18 Jeff Davis + + * BSD, README, ext/compat.c, ext/compat.h, ext/extconf.rb, + ext/mkrf_config.rb, ext/pg.c, ext/pg.h, pg.gemspec, + spec/pgconn_spec.rb, spec/pgresult_spec.rb: + merged ruby-pg/trunk rev 123:146 with ruby-pg/branches/stable + [f9cd915ea427] + +2008-03-17 Jeff Davis + + * ext/mkrf_config.rb: + re-adding mkrf_config.rb + [d821d50b7d95] + + * ext/mkrf_config.rb: + temporarily removing mkrf_config.rb and will re-add it in the next + revision. This is an attempt to fix what may be a repository + problem. + [a66f44648857] + + * COPYING, README.windows, ext/extconf.rb, ext/pg.c, ext/pg.h, + spec/pgconn_spec.rb, spec/pgresult_spec.rb: + merged ruby-pg/trunk rev 123:125 with ruby-pg/branches/stable + [bae01401c92b] + + * ext/compat.c, ext/compat.h, ext/extconf.rb, ext/pg.c, pg.gemspec: + * 7.3 compatibility fixes + * cleanup + [c8752b1a33cd] + + * ext/pg.c: + * Added PGconn#reset_start + * Added PGconn#reset_poll + * Added PGconn#socket + * Added PGconn#connect_poll (needs docs) + [4aa1190e1873] + +2008-03-12 Jeff Davis + + * spec/pgconn_spec.rb: + * added SQLSTATE test + * added binary format test + [1224350cdcb6] + + * README: + * updated the README to reflect the fact that the pg module is + supported by ActiveRecord now. + [639f8bf03621] + +2008-03-11 Jeff Davis + + * BSD, COPYING, README, ext/pg.c: + * tried to make it easier to find the license information + [1fd6244025c5] + +2008-03-10 Jeff Davis + + * ext/pg.c, spec/pgconn_spec.rb, spec/pgresult_spec.rb: + * add better checking to make sure that PGconn#trace is passed a + stream that can provide a valid and writable file descriptor + * added test case for PGconn#trace + [1c4f58ec2264] + + * ext/pg.c: + * corrected handling of bytea when passed in binary format + * corrected handling of +nil+ values passed as type or format + specifiers when using the array-of-hashes form of parameterization + for PGconn#exec + [e94ce7f92a06] + + * ext/pg.c: + * make PGconn#trace accept any object that provides a writable + file descriptor via the method "fileno". + [221e68f16f2d] + + * ext/pg.c: + * Added PGconn#trace(filename) + [2e722b22b4bc] + +2008-03-07 Jeff Davis + + * ext/extconf.rb, ext/mkrf_config.rb: + * Added check to find pg_config. If not found, throw an error. + This should make it more obvious when pg_config is not in your + path. + + * Added proper check on MAC OS X so that it gives the correct + warning on ppc when ARCHFLAGS isn't set. + [9b1308e85390] + +2008-02-22 Jeff Davis + + * ext/pg.c, ext/pg.h: + * fixed PGconn#trace + [480eae4733ff] + +2008-02-21 Jeff Davis + + * ext/pg.c: + * added PGconn#set_notice_receiver{ |result| ... } + - This is a more powerful form of PGconn#set_notice_processor + * cleaned up PGconn#set_notice_processor + * removed superfluous debugging from PGconn#transaction + * fixed PGresult#result_error_field + [a6a1c8613b31] + +2008-02-19 Jeff Davis + + * ext/mkrf_config.rb: + quick change + [8a6e663a70f7] + + * ext/mkrf_config.rb: + fix escaping of paths on windows (another try) + [5fc41a8f71f0] + +2008-02-18 Jeff Davis + + * ext/mkrf_config.rb, ext/pg.c: + * attempted some compatibility fixes for windows + * fixed some warnings + [a465fe9f95a3] + +2008-02-13 Jeff Davis + + * ext/mkrf_config.rb: + * better quoting and error handling when invoking other programs, + e.g. pg_config + [5a91f5660c17] + + * ext/mkrf_config.rb: + quote include and library paths + [5289d5034472] + + * ext/mkrf_config.rb: + * created a mkrf_config.rb. I am attempting to transition away from + mkmf to mkrf + [ed53517514b1] + +2008-02-11 Jeff Davis + + * README.windows, ext/extconf.rb, ext/pg.h: + * windows fixes (thanks Daniel Berger!) + [21bf96d0f702] + + * spec/pgconn_spec.rb, spec/pgresult_spec.rb: + * fix temporary postgresql test installation in test. + [9d0a23cf2113] + +2008-02-08 Jeff Davis + + * ext/pg.c: + * properly retrieve binary data from result sets + [7fcd53437c79] + +2008-02-05 Jeff Davis + + * Rakefile, ext/compat.h, ext/pg.c, pg.gemspec, ruby-pg.gemspec, + sample/losample.rb, sample/psql.rb, sample/test1.rb, + sample/test2.rb, sample/test4.rb, spec/pgconn_spec.rb, + spec/pgresult_spec.rb, tests/pg_spec.rb: + merged ruby-pg/trunk rev 109:121 with ruby-pg/branches/stable + [83e5013eccc8] + + * ext/compat.h: + fixed bug caused by a typo. HAVE_LOCREATE should have been + HAVE_LO_CREATE + [295c477ed74f] + +2008-02-01 Jeff Davis + + * ext/pg.c, spec/pgresult_spec.rb: + * made exec, exec_prepared, send_query, and send_prepared with + parameters accept nil as NULL + * updated comments and tests to reflect that + [ef2214d7f448] + + * ext/pg.c, sample/losample.rb, sample/psql.rb, sample/test1.rb, + sample/test2.rb, sample/test4.rb: + * Corrected a comment. + * Cleaned up the sample directory somewhat. It's still out of date, + though. + [7303b8165a37] + +2008-01-31 Jeff Davis + + * ext/pg.c: + * removed duplicate definition of PGconn.open + [b3ad2112a91e] + + * spec/pgconn_spec.rb, spec/pgresult_spec.rb, tests/pgconn_spec.rb, + tests/pgresult_spec.rb: + more test improvements + [ce9c0e52eec6] + + * Rakefile, tests/pg_spec.rb, tests/pgconn_spec.rb: + renamed pg_spec to pgconn_spec + [97cbdebaeb11] + + * Rakefile, tests/pg_spec.rb, tests/pgresult_spec.rb: + * Added some tests + * Added a Rakefile + [1cb0537730bf] + +2008-01-30 Jeff Davis + + * ext/pg.c: + * added PGconn.conndefaults + * replaced a macro with a function to make it more understandable + [29b827c7dbd0] + +2008-01-29 Jeff Davis + + * ext/pg.c: + corrected the tainting of some strings returned by the database + [c18f38225bc7] + + * ruby-pg.gemspec: + changed gem name from 'ruby-pg' to just 'pg' + [56cd8c6ee046] + +2008-01-28 Jeff Davis + + * pg.gemspec: + made a pg.gemspec so that people can build 'pg' gem + [a9097dead780] + + * ext/pg.c: + merged ruby-pg/trunk rev 104 with ruby-pg/branches/stable + [abfe9a457946] + +2008-01-26 Jeff Davis + + * ext/pg.c: + changed exception type for empty data structures + [cfdcfcd445ab] + +2008-01-25 Jeff Davis + + * ext/pg.c: + * added PGconn#async_exec and alias PGconn#async_query + * added PGconn#get_last_result + * properly check index bounds in pgresult_aref ( PGresult#[] ) + * PGresult#getvalue now returns nil instead of empty string for NULL + [81cd03f8a2c3] + + * ext/pg.c: + added PGresult#cmdtuples as alias for PGresult#cmd_tuples + + This is for better compatibility with ActiveRecord. + [29d775393e88] + + * ext/pg.c: + Added: + * PGresult#num_tuples as alias for PGresult#ntuples + * PGresult#num_fields as alias for PGresult#nfields + + This should result in easier compatibility with ActiveRecord + [eac7df0aa291] + +2008-01-24 Jeff Davis + + * README.OS_X, README.windows, ext/extconf.rb: + moved a few minor changes over before release + [c7ddb58579d3] + + * README.OS_X, README.windows, ext/extconf.rb: + Added README.windows and README.OS_X Changed special case in + extconf.rb from '/ms/libpq.lib' to '/ms/libpq' + [7908e778e7c3] + + * ext/compat.c, ext/compat.h, ext/extconf.rb, ext/pg.c, ext/pg.h, + tests/pg_spec.rb, tests/tc_postgres.rb: + merged revision 77:HEAD of ruby-pg/trunk to ruby-pg/branches/stable + [8df9da92380e] + + * ext/extconf.rb: + Another change to improve windows compatibility. Thanks to Laurent + Francioli. + [7cc13a1f3010] + + * ext/extconf.rb: + fixed typo + [ee0577472b67] + + * ext/extconf.rb: + My previous fix for OS X compatibility didn't work well enough. + + The only effective solution is to generate a warning message and + tell the user what to do. That's what this commit does. + [eaf3b1825d56] + +2008-01-23 Jeff Davis + + * ext/compat.h, ext/pg.h: + * had to include that file conditionally in compat.h for + postgresql 7.3 compatibility + [12b2568a0ada] + + * ext/pg.h: + * included an additional file so that it works with PostgreSQL + 8.3 + [34dd04d21a78] + + * ext/extconf.rb, ext/pg.c: + * added PGconn.quote_ident to quote identifiers + * added special case in extconf to build correctly on windows + [4cf66b7302bf] + +2008-01-22 Jeff Davis + + * ext/pg.c: + * made PGconn#query alias for PGconn#exec + [081e4d8ee394] + + * ext/extconf.rb, ext/pg.c: + * Detect if compiling on OS X, and if so set $ARCHFLAGS correctly. + This should resolve the problem of building on OS X. + * A couple comment fixes. + [4774578059e1] + +2008-01-21 Jeff Davis + + * ext/pg.c: + made conn.block cleaner and it should be more portable. + [204f4b591614] + +2008-01-18 Jeff Davis + + * ext/extconf.rb, ext/pg.c: + Miscellaneous changes: + * in 'pg' module, added PGconn#close as an alias for PGconn#finish, + for easier compatibility with AR adapter. + * removed extra CFLAGS because they were causing portability problems. + [449d54289f07] + +2008-01-17 Jeff Davis + + * tests/pg_spec.rb, tests/tc_postgres.rb: + started creating a rspec test, more tests to come later + [aadd4008d2e3] + + * ext/pg.c: + properly free memory in conn.get_copy_data + [4f276bb9c4b1] + +2008-01-15 Jeff Davis + + * ext/pg.c, ext/pg.h: + Added conn.block( [ timeout ] ) -> Boolean + [95d9ff13c269] + +2008-01-14 Jeff Davis + + * ext/pg.c: + Added conn.transaction{ |conn| ... } + [4cefa3b1ecbb] + + * ext/compat.c, ext/compat.h, ext/extconf.rb, ext/pg.c, ext/pg.h: + Support for PostgreSQL 7.3. + [ae8c3b66c48d] + +2008-01-09 Jeff Davis + + * compat-ruby-postgres/extconf.rb, compat-ruby-postgres/libpq- + compat.c, compat-ruby-postgres/postgres.c, compat-ruby-postgres + /type-oids.h: + removed extra directory that was left in the merge + [8eb1346cb9aa] + + * README, ext/compat.c, ext/compat.h, ext/extconf.rb, ext/pg.c, ruby- + pg.gemspec: + merged ruby-pg/trunk rev 69 to ruby-pg/branches/stable + [d6d19e5371d4] + +2008-01-08 Jeff Davis + + * ext/pg.c: + Added: + * conn.set_client_encoding + * conn.get_client_encoding + + get_client_encoding returns a string, and the PQclientEncoding + function returns an encoding ID, which is why I didn't use the name + client_encoding. That leaves room later to add a wrapper for the + libpq PQclientEncoding if there is a need, without a name conflict. + [1fd8b2aaac4c] + + * ext/pg.c: + Added: + * conn.make_empty_pgresult(status) + * conn.flush + * conn.set_error_verbosity + [5c0a63028583] + +2008-01-07 Jeff Davis + + * ext/pg.c: + fixed a few method defines for async query processing + [40270de77f48] + + * ext/pg.c: + Change conn.exec to use PQexec if no parameters are passed, and + use PQexecParams if optional parameters are passed. + + Change conn.send_query to use PQsendQuery if no parameters are + passed, and use PQsendQueryParams if optional parameters are + passed. + [d05d9f2042d7] + + * compat-ruby-postgres/extconf.rb, compat-ruby-postgres/libpq- + compat.c, compat-ruby-postgres/postgres.c, compat-ruby-postgres + /type-oids.h, ruby-pg.gemspec: + Cleanup after the repository reorganization. + [a531a7bc9241] + + * COPYING, COPYING.txt, ChangeLog, Contributors, GPL, LICENSE, + MANIFEST, README, README.ja, compat-ruby-postgres/extconf.rb, + compat-ruby-postgres/libpq-compat.c, compat-ruby- + postgres/postgres.c, compat-ruby-postgres/type-oids.h, + doc/postgres.html, doc/postgres.jp.html, ext/compat.c, ext/compat.h, + ext/extconf.rb, ext/pg.c, ext/pg.h, ruby-pg.gemspec, + sample/losample.rb, sample/psql.rb, sample/psqlHelp.rb, + sample/test1.rb, sample/test2.rb, sample/test4.rb, + tests/tc_postgres.rb: + Split 'ruby-pg' module and 'postgres' module into separate parts of + the repository. They will be maintained separately, and be released + as separate gems from this point forward. + + One reason for this change is because we need separate gems. If we + distribute both modules as one gem, the documentation is not + properly generated due to class name conflicts. + + Another reason is to reduce confusion between the two modules. + + Also, I don't plan on making many improvements (aside from bugfixes + and portability issues) to the old 'postgres' code. I'd like to get + it to a stable state, and leave it alone. Meanwhile, the 'pg' module + can be developed on a faster timeline. + [aafc8cf17567] + + * COPYING, COPYING.txt, ChangeLog, Contributors, GPL, LICENSE, + MANIFEST, README, README.ja, compat-ruby-postgres/extconf.rb, + compat-ruby-postgres/libpq-compat.c, compat-ruby- + postgres/postgres.c, compat-ruby-postgres/type-oids.h, + doc/postgres.html, doc/postgres.jp.html, ext/compat.c, ext/compat.h, + ext/extconf.rb, ext/pg.c, ext/pg.h, ruby-pg.gemspec, + sample/losample.rb, sample/psql.rb, sample/psqlHelp.rb, + sample/test1.rb, sample/test2.rb, sample/test4.rb, + tests/tc_postgres.rb: + Split 'ruby-pg' module and 'postgres' module into separate parts of + the repository. They will be maintained separately, and be released + as separate gems from this point forward. + + One reason for this change is because we need separate gems. If we + distribute both modules as one gem, the documentation is not + properly generated due to class name conflicts. + + Another reason is to reduce confusion between the two modules. + + Also, I don't plan on making many improvements (aside from bugfixes + and portability issues) to the old 'postgres' code. I'd like to get + it to a stable state, and leave it alone. Meanwhile, the 'pg' module + can be developed on a faster timeline. + [7716d24a143b] diff --git a/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/Contributors.rdoc b/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/Contributors.rdoc new file mode 100644 index 000000000000..3ce8298f353a --- /dev/null +++ b/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/Contributors.rdoc @@ -0,0 +1,46 @@ + +Thanks to all the great people that have contributed code, suggestions, and patches through the +years. If you contribute a patch, please include a patch for this file that adds your name to the +list. + +* Dennis Vshivkov +* Gabriel Emerson +* Noboru Saitou +* Akinori MUSHA +* Andy Yu +* Ceri Storey +* Gavin Kistner +* Henry T. So Jr. +* Jeremy Henty +* +* Leon Brooks +* Martin Hedenfalk +* Yukihiro Matsumoto +* Eiji Matsumoto +* MoonWolf +* +* Nate Haggard +* Neil Conway +* Noboru Matui +* Okada Jun +* Shirai,Kaoru +* Riley +* shibata +* +* ts +* Yuta TSUBOI +* Lugovoi Nikolai +* Jeff Davis +* Bertram Scharpf +* Michael Granger +* Mahlon E. Smith +* Lars Kanis +* Jason Yanowitz +* Charlie Savage +* Rafał Bigaj +* Jason Yanowitz +* Greg Hazel +* Chris White +* Aaron Patterson +* Tim Felgentreff + diff --git a/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/History.rdoc b/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/History.rdoc new file mode 100644 index 000000000000..7cf775fe39c0 --- /dev/null +++ b/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/History.rdoc @@ -0,0 +1,119 @@ +== v0.13.2 [2012-02-22] Michael Granger + +- Make builds against PostgreSQL earlier than 8.3 fail with a descriptive + message instead of a compile failure. + + +== v0.13.1 [2012-02-12] Michael Granger + +- Made use of a finished PG::Connection raise a PG::Error instead of + a fatal error (#110). +- Added missing BSDL license file (#108) + + +== v0.13.0 [2012-02-09] Michael Granger + +Reorganization of modules/classes to be better Ruby citizens (with backward-compatible aliases): +- Created toplevel namespace 'PG' to correspond with the gem name. +- Renamed PGconn to PG::Connection (with ::PGconn alias) +- Renamed PGresult to PG::Result (with ::PGresult alias) +- Renamed PGError to PG::Error (with ::PGError alias) +- Declare all constants inside PG::Constants, then include them in + PG::Connection and PG::Result for backward-compatibility, and + in PG for convenience. +- Split the extension source up by class/module. +- Removed old compatibility code for PostgreSQL versions < 8.3 + +Documentation: +- Clarified licensing, updated to Ruby 1.9's license. +- Merged authors list, added some missing people to the Contributor's + list. +- Cleaned up the sample/ directory +- Making contact info a bit clearer, link to the Google+ page and + the mailing list + +Enhancements: +- Added a convenience method: PG.connect -> PG::Connection.new + +Bugfixes: +- Fixed LATIN5-LATIN10 Postgres<->Ruby encoding conversions + + + +== v0.12.2 [2012-01-03] Michael Granger + +- Fix for the 1.8.7 breakage introduced by the st.h fix for alternative Ruby + implementations (#97 and #98). Thanks to Lars Kanis for the patch. +- Encode error messages with the connection's encoding under 1.9 (#96) + + +== v0.12.1 [2011-12-14] Michael Granger + +- Made rake-compiler a dev dependency, as Rubygems doesn't use the Rakefile + for compiling the extension. Thanks to eolamey@bitbucket and Jeremy Evans + for pointing this out. +- Added an explicit include for ruby/st.h for implementations that need it + (fixes #95). + + +== v0.12.0 [2011-12-07] Michael Granger + +- PGconn#wait_for_notify + * send nil as the payload argument if the NOTIFY didn't have one. + * accept a nil argument for no timeout (Sequel support) + * Fixed API docs + * Taint and encode event name and payload +- Handle errors while rb_thread_select()ing in PGconn#block. + (Brian Weaver). +- Fixes for Win32 async queries (Rafał Bigaj) +- Memory leak fixed: Closing opened WSA event. (rafal) +- Fixes for #66 Win32 asynchronous queries hang on connection + error. (rafal) +- Fixed a typo in PGconn#error_message's documentation +- fixing unused variable warnings for ruby 1.9.3 (Aaron Patterson) +- Build system bugfixes +- Converted to Hoe +- Updates for the Win32 binary gem builds (Lars Kanis) + + +== v0.11.0 [2011-02-09] Michael Granger + +Enhancements: + +* Added a PGresult#values method to fetch all result rows as an Array of + Arrays. Thanks to Jason Yanowitz (JYanowitz at enovafinancial dot com) for + the patch. + + +== v0.10.1 [2011-01-19] Michael Granger + +Bugfixes: + +* Add an include guard for pg.h +* Simplify the common case require of the ext +* Include the extconf header +* Fix compatibility with versions of PostgreSQL without PQgetCancel. (fixes #36) +* Fix require for natively-compiled extension under Windows. (fixes #55) +* Change rb_yield_splat() to rb_yield_values() for compatibility with Rubinius. (fixes #54) + + +== v0.10.0 [2010-12-01] Michael Granger + +Enhancements: + +* Added support for the payload of NOTIFY events (w/Mahlon E. Smith) +* Updated the build system with Rubygems suggestions from RubyConf 2010 + +Bugfixes: + +* Fixed issue with PGconn#wait_for_notify that caused it to miss notifications that happened after + the LISTEN but before the wait_for_notify. + +== v0.9.0 [2010-02-28] Michael Granger + +Bugfixes. + +== v0.8.0 [2009-03-28] Jeff Davis + +Bugfixes, better Windows support. + diff --git a/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/LICENSE b/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/LICENSE new file mode 100644 index 000000000000..a1f19ff99db1 --- /dev/null +++ b/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/LICENSE @@ -0,0 +1,56 @@ +Ruby is copyrighted free software by Yukihiro Matsumoto . +You can redistribute it and/or modify it under either the terms of the +2-clause BSDL (see the file BSDL), or the conditions below: + + 1. You may make and give away verbatim copies of the source form of the + software without restriction, provided that you duplicate all of the + original copyright notices and associated disclaimers. + + 2. You may modify your copy of the software in any way, provided that + you do at least ONE of the following: + + a) place your modifications in the Public Domain or otherwise + make them Freely Available, such as by posting said + modifications to Usenet or an equivalent medium, or by allowing + the author to include your modifications in the software. + + b) use the modified software only within your corporation or + organization. + + c) give non-standard binaries non-standard names, with + instructions on where to get the original software distribution. + + d) make other distribution arrangements with the author. + + 3. You may distribute the software in object code or binary form, + provided that you do at least ONE of the following: + + a) distribute the binaries and library files of the software, + together with instructions (in the manual page or equivalent) + on where to get the original distribution. + + b) accompany the distribution with the machine-readable source of + the software. + + c) give non-standard binaries non-standard names, with + instructions on where to get the original software distribution. + + d) make other distribution arrangements with the author. + + 4. You may modify and include the part of the software into any other + software (possibly commercial). But some files in the distribution + are not written by the author, so that they are not under these terms. + + For the list of those files and their copying conditions, see the + file LEGAL. + + 5. The scripts and library files supplied as input to or produced as + output from the software do not automatically fall under the + copyright of the software, but belong to whomever generated them, + and may be sold commercially, and may be aggregated with this + software. + + 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. diff --git a/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/Manifest.txt b/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/Manifest.txt new file mode 100644 index 000000000000..57940eb5944f --- /dev/null +++ b/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/Manifest.txt @@ -0,0 +1,42 @@ +.gemtest +BSDL +ChangeLog +Contributors.rdoc +History.rdoc +LICENSE +Manifest.txt +POSTGRES +README-OS_X.rdoc +README-Windows.rdoc +README.ja.rdoc +README.rdoc +Rakefile +Rakefile.cross +ext/extconf.rb +ext/pg.c +ext/pg.h +ext/pg_connection.c +ext/pg_result.c +ext/vc/pg.sln +ext/vc/pg_18/pg.vcproj +ext/vc/pg_19/pg_19.vcproj +lib/pg.rb +lib/pg/connection.rb +lib/pg/constants.rb +lib/pg/exceptions.rb +lib/pg/result.rb +sample/async_api.rb +sample/async_copyto.rb +sample/async_mixed.rb +sample/copyfrom.rb +sample/copyto.rb +sample/cursor.rb +sample/losample.rb +sample/notify_wait.rb +sample/test_binary_values.rb +spec/data/expected_trace.out +spec/data/random_binary_data +spec/lib/helpers.rb +spec/pg/connection_spec.rb +spec/pg/result_spec.rb +spec/pg_spec.rb diff --git a/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/POSTGRES b/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/POSTGRES new file mode 100644 index 000000000000..8389909dae74 --- /dev/null +++ b/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/POSTGRES @@ -0,0 +1,23 @@ +PostgreSQL Database Management System +(formerly known as Postgres, then as Postgres95) + +Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group + +Portions Copyright (c) 1994, The Regents of the University of California + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose, without fee, and without a written agreement +is hereby granted, provided that the above copyright notice and this +paragraph and the following two paragraphs appear in all copies. + +IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR +DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING +LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS +ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO +PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. diff --git a/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/README-OS_X.rdoc b/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/README-OS_X.rdoc new file mode 100644 index 000000000000..e3aaacf84487 --- /dev/null +++ b/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/README-OS_X.rdoc @@ -0,0 +1,68 @@ += Compiling on MacOS X + +The EnterpriseDB packages are the recommended PostgreSQL installations to use +with MacOS X. They eliminate most or all of the issues with getting 'pg' +installed, linked correctly, and running. + +== Segfaults and SSL Support + +If you need a custom installation of PostgreSQL, you should ensure that you +either compile it against the same version of OpenSSL as the OpenSSL extension +of the Ruby you'll be using, or compile it without SSL support. If you fail to +do this, you will likely see segfaults when you use 'pg' and the 'openssl' +extension at the same time. You can see what library it's linked against using +'otool -L'; for example, on my 10.7 machine I use for 'pg' development: + + $ otool -L /System/Library/Frameworks/Ruby.framework/Versions\ + /1.8/usr/lib/ruby/1.8/universal-darwin11.0/openssl.bundle + + /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/\ + lib/ruby/1.8/universal-darwin11.0/openssl.bundle: + /System/Library/Frameworks/Ruby.framework/Versions/1.8/\ + usr/lib/libruby.1.dylib (compatibility version 1.8.0, \ + current version 1.8.7) + /usr/lib/libssl.0.9.8.dylib (compatibility version 0.9.8, \ + current version 0.9.8) + /usr/lib/libcrypto.0.9.8.dylib (compatibility version 0.9.8, \ + current version 0.9.8) + /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, \ + current version 159.0.0) + + +== Dealing with Installation Problems + +If you are building/installing pg on MacOS X, and the installation doesn't +work at first, here are a few things you can try. + +=== pg_config + +The first thing you should do is ensure that the 'pg_config' tool that comes +with Postgres is in your path. If it isn't, or the one that's first in your +path isn't the one that was installed with the Postgres you want to build +against, you can specify the path to it with the --with-pg-config option. + +For example, if you're using the Ruby binary that comes with OSX, and +PostgreSQL 9.0.x installed from MacPorts, do: + + gem install -- --with-pg-config=/opt/local/lib/postgresql90/bin/pg_config + +=== ARCHFLAGS and Universal Binaries + +OS X supports both architecture-specific binaries (e.g. i386), as well as +universal binaries (i.e. i386 & ppc). If Ruby is built as a universal binary +and PostgreSQL is not, you need to specify the path to the appropriate +pg_config binary or set the environment variable ARCHFLAGS appropriately. + +Alternatively, if the build system can't figure out which architectures it +should include, you may need to set the 'ARCHFLAGS' environment variable +explicitly: + + sudo env ARCHFLAGS='-arch x86_64' gem install pg + +or, if you're building from source: + + rake compile ARCHFLAGS="-arch x86_64" + +Note that the recommended EnterpriseDB packages are correctly compiled as +universal binaries, and don't need any of these workarounds. + diff --git a/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/README-Windows.rdoc b/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/README-Windows.rdoc new file mode 100644 index 000000000000..6379206f1437 --- /dev/null +++ b/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/README-Windows.rdoc @@ -0,0 +1,67 @@ += Compiling 'pg' on MS Windows + +In order to build this extension on MS Windows you will need a couple things. + +First, a compiler. For the one click installer this means you should either +use VC++ 6.0 or the compiler that comes with cygwin or mingw if you're +building on that platform. + +If you've built Ruby yourself, you should use the same compiler to build +this library that you used to build Ruby. + +Second, PostgreSQL. Be sure you installed it with the development header +files if you installed it using the standard PostgreSQL installer for +Windows. If you didn't, you can run the installer again, select "modify", +and then select the 'development headers' option to install them. + +I recommend making sure that 'pg_config.exe' is in your PATH. The PostgreSQL +installer for Windows does not necessarily update your PATH when it installs +itself, so you may need to do this manually. This isn't strictly necessary, +however. + +In order to build ruby-pg, just run 'rake'. If the pg_config.exe executable +is not in your PATH, you'll need to explicitly point ruby-pg to where your +PostgreSQL headers and libraries are with something like this: + + rake --with-pg-dir=c:/progra~1/postgr~1/8.3 + +Adjust your path accordingly. BE SURE TO USE THE SHORT PATH NAMES! If you +try to use a path with spaces in it, the nmake.exe program will choke. + + +== Cross compiling for mswin32 + +Using rake-compiler a cross compiled pg gem can be build on a Linux or MacOS X +host for the win32 platform. The generated gem is statically linked against +libpq and libssl. OpenSSL and PostgreSQL are downloaded and compiled from the +sources. There are no runtime dependencies to any but the standard Windows +DLLs. + +Install mingw32 using the instructions in rake-compiler's README. +For Debian/Ubuntu it is apt-get install gcc-mingw32 . +Use ruby-1.8.7 for the following commands. + +Download and cross compile ruby 1.8 and 1.9 for win32 with: + + rake-compiler cross-ruby VERSION=1.8.7-p352 + rake-compiler cross-ruby VERSION=1.9.2-p290 + +Download and cross compile pg for win32: + + rake cross native gem + +or with custom versions: + + rake cross native gem RUBY_CC_VERSION=1.8.7:1.9.2 \ + OPENSSL_VERSION=1.0.0e POSTGRESQL_VERSION=9.1.1 + +If everything works, there should be pg-VERSION-x86-mingw32.gem in the pkg +directory. + + +== Reporting Problems + +If you have any problems you can submit them via +[the project's issue-tracker][bitbucket]. And submit questions, problems, or +solutions, so that it can be improved. + diff --git a/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/README.ja.rdoc b/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/README.ja.rdoc new file mode 100644 index 000000000000..846d6595d96e --- /dev/null +++ b/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/README.ja.rdoc @@ -0,0 +1,7 @@ += pg + +* https://bitbucket.org/ged/ruby-pg + +This file needs translation. Anyone who is willing to volunteer, please +mail . + diff --git a/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/README.rdoc b/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/README.rdoc new file mode 100644 index 000000000000..0b7288a2a7cf --- /dev/null +++ b/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/README.rdoc @@ -0,0 +1,100 @@ += pg + +* https://bitbucket.org/ged/ruby-pg + +== Description + +Pg is the Ruby interface to the {PostgreSQL RDBMS}[http://www.postgresql.org/]. + +It works with {PostgreSQL 8.3 and later}[http://bit.ly/6AfPhm]. + +A small example usage: + + #!/usr/bin/env ruby + + require 'pg' + + # Output a table of current connections to the DB + conn = PG.connect( dbname: 'sales' ) + conn.exec( "SELECT * FROM pg_stat_activity" ) do |result| + puts " PID | User | Query" + result.each do |row| + puts " %7d | %-16s | %s " % + row.values_at('procpid', 'usename', 'current_query') + end + end + + +== Requirements + +* Ruby 1.8.7-p249 or 1.9.3-p0. +* PostgreSQL 8.3.x (with headers, -dev packages, etc). + +It may work with earlier versions of Ruby as well, but those are not regularly tested. + + +== How To Install + +Install via RubyGems: + + gem install pg + +You may need to specify the path to the 'pg_config' program installed with +Postgres: + + gem install pg -- --with-pg-config= + +See README-OS_X.rdoc for more information about installing under MacOS X, and +README-Windows.rdoc for Windows build/installation instructions. + +There's also {a Google+ group}[http://goo.gl/TFy1U] and a +{mailing list}[http://groups.google.com/group/ruby-pg] if you get stuck, or just +want to chat about something. + + +== Contributing + +To report bugs, suggest features, or check out the source with Mercurial, +{check out the project page}[http://bitbucket.org/ged/ruby-pg]. If you prefer +Git, there's also a {Github mirror}[https://github.com/ged/ruby-pg]. + +After checking out the source, run: + + $ rake newb + +This task will install any missing dependencies, run the tests/specs, and +generate the API documentation. + +The current maintainer is Michael Granger . + + +== Copying + +Copyright (c) 1997-2012 by the authors. + +* Jeff Davis +* Guy Decoux (ts) +* Michael Granger +* Dave Lee +* Eiji Matsumoto +* Yukihiro Matsumoto +* Noboru Saitou + +You may redistribute this software under the same terms as Ruby itself; see +http://www.ruby-lang.org/en/LICENSE.txt or the LICENSE file in the source +for details. + +Portions of the code are from the PostgreSQL project, and are distributed +under the terms of the PostgreSQL license, included in the file POSTGRES. + +Portions copyright LAIKA, Inc. + + +== Acknowledgments + +See Contributors.rdoc for the many additional fine people that have contributed +to this library over the years. + +We are thankful to the people at the ruby-list and ruby-dev mailing lists. +And to the people who developed PostgreSQL. + diff --git a/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/Rakefile b/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/Rakefile new file mode 100644 index 000000000000..90225a4225da --- /dev/null +++ b/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/Rakefile @@ -0,0 +1,148 @@ +#!/usr/bin/env rake + +require 'rbconfig' +require 'pathname' +require 'tmpdir' + +begin + require 'rake/extensiontask' +rescue LoadError + abort "This Rakefile requires rake-compiler (gem install rake-compiler)" +end + +begin + require 'hoe' +rescue LoadError + abort "This Rakefile requires hoe (gem install hoe)" +end + +require 'rake/clean' + +# Build directory constants +BASEDIR = Pathname( __FILE__ ).dirname +SPECDIR = BASEDIR + 'spec' +LIBDIR = BASEDIR + 'lib' +EXTDIR = BASEDIR + 'ext' +PKGDIR = BASEDIR + 'pkg' +TMPDIR = BASEDIR + 'tmp' + +DLEXT = Config::CONFIG['DLEXT'] +EXT = LIBDIR + "pg_ext.#{DLEXT}" + +TEST_DIRECTORY = BASEDIR + "tmp_test_specs" + +CLOBBER.include( TEST_DIRECTORY.to_s ) +CLEAN.include( PKGDIR.to_s, TMPDIR.to_s ) + +# Set up Hoe plugins +Hoe.plugin :mercurial +Hoe.plugin :signing + +Hoe.plugins.delete :rubyforge +Hoe.plugins.delete :compiler + +load 'Rakefile.cross' + + +# Hoe specification +$hoespec = Hoe.spec 'pg' do + self.readme_file = 'README.rdoc' + self.history_file = 'History.rdoc' + self.extra_rdoc_files = Rake::FileList[ '*.rdoc' ] + self.extra_rdoc_files.include( 'POSTGRES', 'LICENSE' ) + self.extra_rdoc_files.include( 'ext/*.c' ) + + self.developer 'Michael Granger', 'ged@FaerieMUD.org' + + self.dependency 'rake-compiler', '~> 0.7', :developer + self.dependency 'rspec', '~> 2.6', :developer + + self.spec_extras[:licenses] = ['BSD', 'Ruby', 'GPL'] + self.spec_extras[:extensions] = [ 'ext/extconf.rb' ] + + self.require_ruby_version( '>= 1.8.7' ) + + self.hg_sign_tags = true if self.respond_to?( :hg_sign_tags= ) + self.check_history_on_release = true if self.respond_to?( :check_history_on_release= ) + + self.rdoc_locations << "deveiate:/usr/local/www/public/code/#{remote_rdoc_dir}" +end + +ENV['VERSION'] ||= $hoespec.spec.version.to_s + +# Tests should pass before checking in +task 'hg:precheckin' => [ :check_history, :check_manifest, :spec ] + +# Support for 'rvm specs' +task :specs => :spec + +# Compile before testing +task :spec => :compile + +# gem-testers support +task :test do + # rake-compiler always wants to copy the compiled extension into lib/, but + # we don't want testers to have to re-compile, especially since that + # often fails because they can't (and shouldn't have to) write to tmp/ in + # the installed gem dir. So we clear the task rake-compiler set up + # to break the dependency between :spec and :compile when running under + # rubygems-test, and then run :spec. + Rake::Task[ EXT.to_s ].clear + Rake::Task[ :spec ].execute +end + +desc "Turn on warnings and debugging in the build." +task :maint do + ENV['MAINTAINER_MODE'] = 'yes' +end + +ENV['RUBY_CC_VERSION'] ||= '1.8.7:1.9.2' + +# Rake-compiler task +Rake::ExtensionTask.new do |ext| + ext.name = 'pg_ext' + ext.gem_spec = $hoespec.spec + ext.ext_dir = 'ext' + ext.lib_dir = 'lib' + ext.source_pattern = "*.{c,h}" + ext.cross_compile = true + ext.cross_platform = %w[i386-mingw32] + + # configure options only for cross compile + ext.cross_config_options += [ + "--with-pg-include=#{STATIC_POSTGRESQL_LIBDIR}", + "--with-opt-include=#{STATIC_POSTGRESQL_INCDIR}", + "--with-pg-lib=#{STATIC_POSTGRESQL_LIBDIR}", + "--with-opt-lib=#{STATIC_OPENSSL_BUILDDIR}", + ] +end + + +# Make the ChangeLog update if the repo has changed since it was last built +file '.hg/branch' do + abort "You need the Mercurial repo to make packages" +end +file 'ChangeLog' => '.hg/branch' do |task| + $stderr.puts "Updating the changelog..." + begin + include Hoe::MercurialHelpers + content = make_changelog() + rescue NameError + abort "Packaging tasks require the hoe-mercurial plugin (gem install hoe-mercurial)" + end + File.open( task.name, 'w', 0644 ) do |fh| + fh.print( content ) + end +end + +# Rebuild the ChangeLog immediately before release +task :prerelease => 'ChangeLog' + + +desc "Stop any Postmaster instances that remain after testing." +task :cleanup_testing_dbs do + require 'spec/lib/helpers' + PgTestingHelpers.stop_existing_postmasters() + Rake::Task[:clean].invoke +end + diff --git a/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/Rakefile.cross b/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/Rakefile.cross new file mode 100644 index 000000000000..6de41b251486 --- /dev/null +++ b/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/Rakefile.cross @@ -0,0 +1,239 @@ +#!/usr/bin/env rake + +require 'uri' +require 'tempfile' +require 'rbconfig' +require 'rake/clean' +require 'rake/extensiontask' +require 'rake/extensioncompiler' + +MISCDIR = BASEDIR + 'misc' + +NUM_CPUS = if File.exist?('/proc/cpuinfo') + File.read('/proc/cpuinfo').scan('processor').length +elsif RUBY_PLATFORM.include?( 'darwin' ) + `system_profiler SPHardwareDataType | grep 'Cores' | awk '{print $5}'`.chomp +else + 1 +end + +# Cross-compilation constants +OPENSSL_VERSION = ENV['OPENSSL_VERSION'] || '1.0.0e' +POSTGRESQL_VERSION = ENV['POSTGRESQL_VERSION'] || '9.1.1' + +COMPILE_HOME = Pathname( "./build" ).expand_path +STATIC_SOURCESDIR = COMPILE_HOME + 'sources' +STATIC_BUILDDIR = COMPILE_HOME + 'builds' + +# Static OpenSSL build vars +STATIC_OPENSSL_BUILDDIR = STATIC_BUILDDIR + "openssl-#{OPENSSL_VERSION}" + +OPENSSL_SOURCE_URI = + URI( "http://www.openssl.org/source/openssl-#{OPENSSL_VERSION}.tar.gz" ) +OPENSSL_TARBALL = STATIC_SOURCESDIR + File.basename( OPENSSL_SOURCE_URI.path ) +OPENSSL_MAKEFILE = STATIC_OPENSSL_BUILDDIR + 'Makefile' + +LIBSSLEAY32 = STATIC_OPENSSL_BUILDDIR + 'libssleay32.a' +LIBEAY32 = STATIC_OPENSSL_BUILDDIR + 'libeay32.a' + +OPENSSL_PATCHES = Rake::FileList[ MISCDIR + "openssl-#{OPENSSL_VERSION}.*.patch" ] + +# Static PostgreSQL build vars +STATIC_POSTGRESQL_BUILDDIR = STATIC_BUILDDIR + "postgresql-#{POSTGRESQL_VERSION}" +POSTGRESQL_SOURCE_URI = begin + uristring = "http://ftp.postgresql.org/pub/source/v%s/postgresql-%s.tar.bz2" % + [ POSTGRESQL_VERSION, POSTGRESQL_VERSION ] + URI( uristring ) +end +POSTGRESQL_TARBALL = STATIC_SOURCESDIR + File.basename( POSTGRESQL_SOURCE_URI.path ) + +STATIC_POSTGRESQL_SRCDIR = STATIC_POSTGRESQL_BUILDDIR + 'src' +STATIC_POSTGRESQL_LIBDIR = STATIC_POSTGRESQL_SRCDIR + 'interfaces/libpq' +STATIC_POSTGRESQL_INCDIR = STATIC_POSTGRESQL_SRCDIR + 'include' + +POSTGRESQL_GLOBAL_MAKEFILE = STATIC_POSTGRESQL_SRCDIR + 'Makefile.global' +POSTGRESQL_SHLIB_MAKEFILE = STATIC_POSTGRESQL_SRCDIR + 'Makefile.shlib' +POSTGRESQL_SHLIB_MF_ORIG = STATIC_POSTGRESQL_SRCDIR + 'Makefile.shlib.orig' +POSTGRESQL_LIB = STATIC_POSTGRESQL_LIBDIR + 'libpq.a' + +CROSS_PREFIX = begin + Rake::ExtensionCompiler.mingw_host +rescue => err + $stderr.puts "Cross-compilation disabled -- %s" % [ err.message ] + 'unknown' +end + + +# clean intermediate files and folders +CLEAN.include( STATIC_BUILDDIR.to_s ) + + +ENV['RUBY_CC_VERSION'] ||= '1.8.7:1.9.3' + +def download(url, save_to) + part = save_to+".part" + sh "wget #{url.to_s.inspect} -O #{part.inspect} || curl #{url.to_s.inspect} -o #{part.inspect}" + FileUtils.mv part, save_to +end + +def run(*args) + sh *args +end + +##################################################################### +### C R O S S - C O M P I L A T I O N - T A S K S +##################################################################### + + +directory STATIC_SOURCESDIR.to_s + +# +# Static OpenSSL build tasks +# +directory STATIC_OPENSSL_BUILDDIR.to_s + +# openssl source file should be stored there +file OPENSSL_TARBALL => STATIC_SOURCESDIR do |t| + download( OPENSSL_SOURCE_URI, t.name ) +end + +# Extract the openssl builds +file STATIC_OPENSSL_BUILDDIR => OPENSSL_TARBALL do |t| + puts "extracting %s to %s" % [ OPENSSL_TARBALL, STATIC_OPENSSL_BUILDDIR.parent ] + STATIC_OPENSSL_BUILDDIR.mkpath + run 'tar', '-xzf', OPENSSL_TARBALL.to_s, '-C', STATIC_OPENSSL_BUILDDIR.parent.to_s + OPENSSL_MAKEFILE.unlink if OPENSSL_MAKEFILE.exist? + + OPENSSL_PATCHES.each do |patchfile| + puts " applying patch #{patchfile}..." + run 'patch', '-Np1', '-d', STATIC_OPENSSL_BUILDDIR.to_s, + '-i', File.expand_path( patchfile, BASEDIR ) + end +end + +CMD_PRELUDE = [ + 'env', + "CC=#{CROSS_PREFIX}-gcc", + "CFLAGS=-DDSO_WIN32", + "AR=#{CROSS_PREFIX}-ar", + "RANLIB=#{CROSS_PREFIX}-ranlib" +] + + +# generate the makefile in a clean build location +file OPENSSL_MAKEFILE => STATIC_OPENSSL_BUILDDIR do |t| + Dir.chdir( STATIC_OPENSSL_BUILDDIR ) do + cmd = CMD_PRELUDE.dup + cmd << "./Configure" << 'mingw' + + run( *cmd ) + end +end + +desc "compile static openssl libraries" +task :openssl_libs => [ LIBSSLEAY32, LIBEAY32 ] + +task :compile_static_openssl => OPENSSL_MAKEFILE do |t| + Dir.chdir( STATIC_OPENSSL_BUILDDIR ) do + cmd = CMD_PRELUDE.dup + cmd << 'make' << "-j#{NUM_CPUS}" << 'build_libs' + + run( *cmd ) + end +end + +desc "compile static #{LIBEAY32}" +file LIBEAY32 => :compile_static_openssl do |t| + FileUtils.cp( STATIC_OPENSSL_BUILDDIR + 'libcrypto.a', LIBEAY32.to_s ) +end + +desc "compile static #{LIBSSLEAY32}" +file LIBSSLEAY32 => :compile_static_openssl do |t| + FileUtils.cp( STATIC_OPENSSL_BUILDDIR + 'libssl.a', LIBSSLEAY32.to_s ) +end + + + +# +# Static PostgreSQL build tasks +# +directory STATIC_POSTGRESQL_BUILDDIR.to_s + + +# postgresql source file should be stored there +file POSTGRESQL_TARBALL => STATIC_SOURCESDIR do |t| + download( POSTGRESQL_SOURCE_URI, t.name ) +end + +# Extract the postgresql sources +file STATIC_POSTGRESQL_BUILDDIR => POSTGRESQL_TARBALL do |t| + puts "extracting %s to %s" % [ POSTGRESQL_TARBALL, STATIC_POSTGRESQL_BUILDDIR.parent ] + STATIC_POSTGRESQL_BUILDDIR.mkpath + run 'tar', '-xjf', POSTGRESQL_TARBALL.to_s, '-C', STATIC_POSTGRESQL_BUILDDIR.parent.to_s + mv POSTGRESQL_SHLIB_MAKEFILE, POSTGRESQL_SHLIB_MF_ORIG +end + +# generate the makefile in a clean build location +file POSTGRESQL_GLOBAL_MAKEFILE => [ STATIC_POSTGRESQL_BUILDDIR, :openssl_libs ] do |t| + options = [ + '--target=i386-mingw32', + "--host=#{Rake::ExtensionCompiler.mingw_host}", + '--with-openssl', + '--without-zlib', + '--disable-shared', + ] + + Dir.chdir( STATIC_POSTGRESQL_BUILDDIR ) do + configure_path = STATIC_POSTGRESQL_BUILDDIR + 'configure' + cmd = [ configure_path.to_s, *options ] + cmd << "CFLAGS=-L#{STATIC_OPENSSL_BUILDDIR}" + cmd << "LDFLAGS=-L#{STATIC_OPENSSL_BUILDDIR}" + cmd << "LDFLAGS_SL=-L#{STATIC_OPENSSL_BUILDDIR}" + cmd << "LIBS=-lwsock32 -lws2_32 -lgdi32" + cmd << "CPPFLAGS=-I#{STATIC_OPENSSL_BUILDDIR}/include" + + run( *cmd ) + end +end + + +# patch the Makefile.shlib -- depend on the build dir so it's only +# rewritten if the tarball is re-extracted. +file POSTGRESQL_SHLIB_MAKEFILE => POSTGRESQL_SHLIB_MF_ORIG do |t| + tf = Tempfile.new( POSTGRESQL_SHLIB_MAKEFILE.basename ) + POSTGRESQL_SHLIB_MF_ORIG.open( File::RDONLY ) do |ifh| + ifh.each_line do |line| + tf.print( line.sub(/^(\s*haslibarule\s*=\s*yes)/, "# \\1 ") ) + end + end + tf.close + + FileUtils.mv( tf.path, t.name, :verbose => $puts ) +end + + +# make libpq.a +task POSTGRESQL_LIB => [ POSTGRESQL_GLOBAL_MAKEFILE, POSTGRESQL_SHLIB_MAKEFILE ] do |t| + Dir.chdir( POSTGRESQL_LIB.dirname ) do + sh 'make', "-j#{NUM_CPUS}", POSTGRESQL_LIB.basename.to_s, 'PORTNAME=win32' + end +end + + +#desc 'compile static libpg.a' +task :static_libpq => POSTGRESQL_LIB + +desc 'cross compile pg for win32' +task :cross do + ENV['CROSS_COMPILING'] = 'yes' +end +task :cross => [ :mingw32, :static_libpq ] + +task :mingw32 do + # Use Rake::ExtensionCompiler helpers to find the proper host + unless Rake::ExtensionCompiler.mingw_host then + warn "You need to install mingw32 cross compile functionality to be able to continue." + warn "Please refer to your distribution/package manager documentation about installation." + fail + end +end diff --git a/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/ext/extconf.rb b/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/ext/extconf.rb new file mode 100644 index 000000000000..0301d9b41516 --- /dev/null +++ b/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/ext/extconf.rb @@ -0,0 +1,76 @@ +require 'pp' +require 'mkmf' + + +if ENV['MAINTAINER_MODE'] + $stderr.puts "Maintainer mode enabled." + $CFLAGS << + ' -Wall' << + ' -ggdb' << + ' -DDEBUG' << + ' -pedantic' +end + +if pgdir = with_config( 'pg' ) + ENV['PATH'] = "#{pgdir}/bin" + File::PATH_SEPARATOR + ENV['PATH'] +end + +if ENV['CROSS_COMPILING'] + $LDFLAGS << " -L#{CONFIG['libdir']}" + + # Link against all required libraries for static build, if they are available + have_library( 'gdi32', 'CreateDC' ) && append_library( $libs, 'gdi32' ) + have_library( 'secur32' ) && append_library( $libs, 'secur32' ) + have_library( 'ws2_32', 'WSASocket') && append_library( $libs, 'ws2_32' ) + have_library( 'crypto', 'BIO_new' ) && append_library( $libs, 'crypto' ) + have_library( 'ssl', 'SSL_new' ) && append_library( $libs, 'ssl' ) +end + +dir_config 'pg' + +if pgconfig = ( with_config('pg-config') || with_config('pg_config') || find_executable('pg_config') ) + $stderr.puts "Using config values from %s" % [ pgconfig ] + $CPPFLAGS << " -I%s" % [ `"#{pgconfig}" --includedir`.chomp ] + $LDFLAGS << " -L%s" % [ `"#{pgconfig}" --libdir`.chomp ] +else + $stderr.puts "No pg_config... trying anyway. If building fails, please try again with", + " --with-pg-config=/path/to/pg_config" +end + +find_header( 'libpq-fe.h' ) or abort "Can't find the 'libpq-fe.h header" +find_header( 'libpq/libpq-fs.h' ) or abort "Can't find the 'libpq/libpq-fs.h header" +find_header( 'pg_config_manual.h' ) or abort "Can't find the 'pg_config_manual.h' header" + +abort "Can't find the PostgreSQL client library (libpq)" unless + have_library( 'pq', 'PQconnectdb', ['libpq-fe.h'] ) || + have_library( 'libpq', 'PQconnectdb', ['libpq-fe.h'] ) || + have_library( 'ms/libpq', 'PQconnectdb', ['libpq-fe.h'] ) + +# optional headers/functions +have_func 'PQconnectionUsedPassword' or + abort "Your PostgreSQL is too old. Either install an older version " + + "of this gem or upgrade your database." +have_func 'PQisthreadsafe' +have_func 'PQprepare' +have_func 'PQexecParams' +have_func 'PQescapeString' +have_func 'PQescapeStringConn' +have_func 'PQgetCancel' +have_func 'lo_create' +have_func 'pg_encoding_to_char' +have_func 'pg_char_to_encoding' +have_func 'PQsetClientEncoding' + +have_func 'rb_encdb_alias' +have_func 'rb_enc_alias' + +$defs.push( "-DHAVE_ST_NOTIFY_EXTRA" ) if + have_struct_member 'struct pgNotify', 'extra', 'libpq-fe.h' + +# unistd.h confilicts with ruby/win32.h when cross compiling for win32 and ruby 1.9.1 +have_header 'unistd.h' +have_header 'ruby/st.h' or have_header 'st.h' or abort "pg currently requires the ruby/st.h header" + +create_header() +create_makefile( "pg_ext" ) + diff --git a/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/ext/pg.c b/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/ext/pg.c new file mode 100644 index 000000000000..7e815428259e --- /dev/null +++ b/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/ext/pg.c @@ -0,0 +1,447 @@ +/* + * pg.c - Toplevel extension + * $Id$ + * + * Author/s: + * + * - Jeff Davis + * - Guy Decoux (ts) + * - Michael Granger + * - Dave Lee + * - Eiji Matsumoto + * - Yukihiro Matsumoto + * - Noboru Saitou + * + * See Contributors.rdoc for the many additional fine people that have contributed + * to this library over the years. + * + * Copyright (c) 1997-2012 by the authors. + * + * You may redistribute this software under the same terms as Ruby itself; see + * http://www.ruby-lang.org/en/LICENSE.txt or the LICENSE file in the source + * for details. + * + * Portions of the code are from the PostgreSQL project, and are distributed + * under the terms of the PostgreSQL license, included in the file "POSTGRES". + * + * Portions copyright LAIKA, Inc. + * + * + * The following functions are part of libpq, but not available from ruby-pg, + * because they are deprecated, obsolete, or generally not useful: + * + * - PQfreemem -- unnecessary: copied to ruby object, then freed. Ruby object's + * memory is freed when it is garbage collected. + * - PQbinaryTuples -- better to use PQfformat + * - PQprint -- not very useful + * - PQsetdb -- not very useful + * - PQoidStatus -- deprecated, use PQoidValue + * - PQrequestCancel -- deprecated, use PQcancel + * - PQfn -- use a prepared statement instead + * - PQgetline -- deprecated, use PQgetCopyData + * - PQgetlineAsync -- deprecated, use PQgetCopyData + * - PQputline -- deprecated, use PQputCopyData + * - PQputnbytes -- deprecated, use PQputCopyData + * - PQendcopy -- deprecated, use PQputCopyEnd + */ + +#include "pg.h" + +VALUE rb_mPG; +VALUE rb_ePGerror; +VALUE rb_mPGconstants; + + +/* + * Document-class: PGError + * + * This is the exception class raised when an error is returned from + * a libpq API call. + * + * The attributes +connection+ and +result+ are set to the connection + * object and result set object, respectively. + * + * If the connection object or result set object is not available from + * the context in which the error was encountered, it is +nil+. + */ + +/* + * M17n functions + */ + +#ifdef M17N_SUPPORTED +/** + * The mapping from canonical encoding names in PostgreSQL to ones in Ruby. + */ +const char * const (pg_enc_pg2ruby_mapping[][2]) = { + {"BIG5", "Big5" }, + {"EUC_CN", "GB2312" }, + {"EUC_JP", "EUC-JP" }, + {"EUC_JIS_2004", "EUC-JP" }, + {"EUC_KR", "EUC-KR" }, + {"EUC_TW", "EUC-TW" }, + {"GB18030", "GB18030" }, + {"GBK", "GBK" }, + {"ISO_8859_5", "ISO-8859-5" }, + {"ISO_8859_6", "ISO-8859-6" }, + {"ISO_8859_7", "ISO-8859-7" }, + {"ISO_8859_8", "ISO-8859-8" }, + /* {"JOHAB", "JOHAB" }, dummy */ + {"KOI8", "KOI8-R" }, + {"KOI8R", "KOI8-R" }, + {"KOI8U", "KOI8-U" }, + {"LATIN1", "ISO-8859-1" }, + {"LATIN2", "ISO-8859-2" }, + {"LATIN3", "ISO-8859-3" }, + {"LATIN4", "ISO-8859-4" }, + {"LATIN5", "ISO-8859-9" }, + {"LATIN6", "ISO-8859-10" }, + {"LATIN7", "ISO-8859-13" }, + {"LATIN8", "ISO-8859-14" }, + {"LATIN9", "ISO-8859-15" }, + {"LATIN10", "ISO-8859-16" }, + {"MULE_INTERNAL", "Emacs-Mule" }, + {"SJIS", "Windows-31J" }, + {"SHIFT_JIS_2004","Windows-31J" }, + /* {"SQL_ASCII", NULL }, special case*/ + {"UHC", "CP949" }, + {"UTF8", "UTF-8" }, + {"WIN866", "IBM866" }, + {"WIN874", "Windows-874" }, + {"WIN1250", "Windows-1250"}, + {"WIN1251", "Windows-1251"}, + {"WIN1252", "Windows-1252"}, + {"WIN1253", "Windows-1253"}, + {"WIN1254", "Windows-1254"}, + {"WIN1255", "Windows-1255"}, + {"WIN1256", "Windows-1256"}, + {"WIN1257", "Windows-1257"}, + {"WIN1258", "Windows-1258"} +}; + + +/* + * A cache of mapping from PostgreSQL's encoding indices to Ruby's rb_encoding*s. + */ +static struct st_table *enc_pg2ruby; +static ID s_id_index; + + +/* + * Get the index of encoding +val+. + * :FIXME: Look into replacing this with rb_enc_get_index() since 1.9.1 isn't really + * used anymore. + */ +int +pg_enc_get_index(VALUE val) +{ + int i = ENCODING_GET_INLINED(val); + if (i == ENCODING_INLINE_MAX) { + VALUE iv = rb_ivar_get(val, s_id_index); + i = NUM2INT(iv); + } + return i; +} + + +/* + * Look up the JOHAB encoding, creating it as a dummy encoding if it's not + * already defined. + */ +static rb_encoding * +pg_find_or_create_johab(void) +{ + static const char * const aliases[] = { "JOHAB", "Windows-1361", "CP1361" }; + int enc_index; + size_t i; + + for (i = 0; i < sizeof(aliases)/sizeof(aliases[0]); ++i) { + enc_index = rb_enc_find_index(aliases[i]); + if (enc_index > 0) return rb_enc_from_index(enc_index); + } + + enc_index = rb_define_dummy_encoding(aliases[0]); + for (i = 1; i < sizeof(aliases)/sizeof(aliases[0]); ++i) { + ENC_ALIAS(aliases[i], aliases[0]); + } + return rb_enc_from_index(enc_index); +} + +/* + * Return the given PostgreSQL encoding ID as an rb_encoding. + * + * - returns NULL if the client encoding is 'SQL_ASCII'. + * - returns ASCII-8BIT if the client encoding is unknown. + */ +rb_encoding * +pg_get_pg_encoding_as_rb_encoding( int enc_id ) +{ + rb_encoding *enc; + + /* Use the cached value if it exists */ + if ( st_lookup(enc_pg2ruby, (st_data_t)enc_id, (st_data_t*)&enc) ) { + return enc; + } + else { + const char *name = pg_encoding_to_char( enc_id ); + + enc = pg_get_pg_encname_as_rb_encoding( name ); + st_insert( enc_pg2ruby, (st_data_t)enc_id, (st_data_t)enc ); + + return enc; + } + +} + +/* + * Return the given PostgreSQL encoding name as an rb_encoding. + */ +rb_encoding * +pg_get_pg_encname_as_rb_encoding( const char *pg_encname ) +{ + size_t i; + + /* Trying looking it up in the conversion table */ + for ( i = 0; i < sizeof(pg_enc_pg2ruby_mapping)/sizeof(pg_enc_pg2ruby_mapping[0]); ++i ) { + if ( strcmp(pg_encname, pg_enc_pg2ruby_mapping[i][0]) == 0 ) + return rb_enc_find( pg_enc_pg2ruby_mapping[i][1] ); + } + + /* JOHAB isn't a builtin encoding, so make up a dummy encoding if it's seen */ + if ( strncmp(pg_encname, "JOHAB", 5) == 0 ) + return pg_find_or_create_johab(); + + /* Fallthrough to ASCII-8BIT */ + return rb_ascii8bit_encoding(); +} + +/* + * Get the client encoding of the specified connection handle and return it as a rb_encoding. + */ +rb_encoding * +pg_conn_enc_get( PGconn *conn ) +{ + int enc_id = PQclientEncoding( conn ); + return pg_get_pg_encoding_as_rb_encoding( enc_id ); +} + + +/* + * Returns the given rb_encoding as the equivalent PostgreSQL encoding string. + */ +const char * +pg_get_rb_encoding_as_pg_encoding( rb_encoding *enc ) +{ + const char *rb_encname = rb_enc_name( enc ); + const char *encname = NULL; + size_t i; + + for (i = 0; i < sizeof(pg_enc_pg2ruby_mapping)/sizeof(pg_enc_pg2ruby_mapping[0]); ++i) { + if (strcmp(rb_encname, pg_enc_pg2ruby_mapping[i][1]) == 0) { + encname = pg_enc_pg2ruby_mapping[i][0]; + } + } + + if ( !encname ) encname = "SQL_ASCII"; + + return encname; +} + +#endif /* M17N_SUPPORTED */ + + +void +Init_pg_ext() +{ + rb_mPG = rb_define_module( "PG" ); + rb_ePGerror = rb_define_class_under( rb_mPG, "Error", rb_eStandardError ); + rb_mPGconstants = rb_define_module_under( rb_mPG, "Constants" ); + + /************************* + * PG::Error + *************************/ + rb_define_alias( rb_ePGerror, "error", "message" ); + rb_define_attr( rb_ePGerror, "connection", 1, 0 ); + rb_define_attr( rb_ePGerror, "result", 1, 0 ); + + /****** PG::Connection CLASS CONSTANTS: Connection Status ******/ + + /* Connection succeeded */ + rb_define_const(rb_mPGconstants, "CONNECTION_OK", INT2FIX(CONNECTION_OK)); + /* Connection failed */ + rb_define_const(rb_mPGconstants, "CONNECTION_BAD", INT2FIX(CONNECTION_BAD)); + + /****** PG::Connection CLASS CONSTANTS: Nonblocking connection status ******/ + + /* Waiting for connection to be made. */ + rb_define_const(rb_mPGconstants, "CONNECTION_STARTED", INT2FIX(CONNECTION_STARTED)); + /* Connection OK; waiting to send. */ + rb_define_const(rb_mPGconstants, "CONNECTION_MADE", INT2FIX(CONNECTION_MADE)); + /* Waiting for a response from the server. */ + rb_define_const(rb_mPGconstants, "CONNECTION_AWAITING_RESPONSE", INT2FIX(CONNECTION_AWAITING_RESPONSE)); + /* Received authentication; waiting for backend start-up to finish. */ + rb_define_const(rb_mPGconstants, "CONNECTION_AUTH_OK", INT2FIX(CONNECTION_AUTH_OK)); + /* Negotiating SSL encryption. */ + rb_define_const(rb_mPGconstants, "CONNECTION_SSL_STARTUP", INT2FIX(CONNECTION_SSL_STARTUP)); + /* Negotiating environment-driven parameter settings. */ + rb_define_const(rb_mPGconstants, "CONNECTION_SETENV", INT2FIX(CONNECTION_SETENV)); + + /****** PG::Connection CLASS CONSTANTS: Nonblocking connection polling status ******/ + + /* Async connection is waiting to read */ + rb_define_const(rb_mPGconstants, "PGRES_POLLING_READING", INT2FIX(PGRES_POLLING_READING)); + /* Async connection is waiting to write */ + rb_define_const(rb_mPGconstants, "PGRES_POLLING_WRITING", INT2FIX(PGRES_POLLING_WRITING)); + /* Async connection failed or was reset */ + rb_define_const(rb_mPGconstants, "PGRES_POLLING_FAILED", INT2FIX(PGRES_POLLING_FAILED)); + /* Async connection succeeded */ + rb_define_const(rb_mPGconstants, "PGRES_POLLING_OK", INT2FIX(PGRES_POLLING_OK)); + + /****** PG::Connection CLASS CONSTANTS: Transaction Status ******/ + + /* Transaction is currently idle (#transaction_status) */ + rb_define_const(rb_mPGconstants, "PQTRANS_IDLE", INT2FIX(PQTRANS_IDLE)); + /* Transaction is currently active; query has been sent to the server, but not yet completed. (#transaction_status) */ + rb_define_const(rb_mPGconstants, "PQTRANS_ACTIVE", INT2FIX(PQTRANS_ACTIVE)); + /* Transaction is currently idle, in a valid transaction block (#transaction_status) */ + rb_define_const(rb_mPGconstants, "PQTRANS_INTRANS", INT2FIX(PQTRANS_INTRANS)); + /* Transaction is currently idle, in a failed transaction block (#transaction_status) */ + rb_define_const(rb_mPGconstants, "PQTRANS_INERROR", INT2FIX(PQTRANS_INERROR)); + /* Transaction's connection is bad (#transaction_status) */ + rb_define_const(rb_mPGconstants, "PQTRANS_UNKNOWN", INT2FIX(PQTRANS_UNKNOWN)); + + /****** PG::Connection CLASS CONSTANTS: Error Verbosity ******/ + + /* Terse error verbosity level (#set_error_verbosity) */ + rb_define_const(rb_mPGconstants, "PQERRORS_TERSE", INT2FIX(PQERRORS_TERSE)); + /* Default error verbosity level (#set_error_verbosity) */ + rb_define_const(rb_mPGconstants, "PQERRORS_DEFAULT", INT2FIX(PQERRORS_DEFAULT)); + /* Verbose error verbosity level (#set_error_verbosity) */ + rb_define_const(rb_mPGconstants, "PQERRORS_VERBOSE", INT2FIX(PQERRORS_VERBOSE)); + + /****** PG::Connection CLASS CONSTANTS: Large Objects ******/ + + /* Flag for #lo_creat, #lo_open -- open for writing */ + rb_define_const(rb_mPGconstants, "INV_WRITE", INT2FIX(INV_WRITE)); + /* Flag for #lo_creat, #lo_open -- open for reading */ + rb_define_const(rb_mPGconstants, "INV_READ", INT2FIX(INV_READ)); + /* Flag for #lo_lseek -- seek from object start */ + rb_define_const(rb_mPGconstants, "SEEK_SET", INT2FIX(SEEK_SET)); + /* Flag for #lo_lseek -- seek from current position */ + rb_define_const(rb_mPGconstants, "SEEK_CUR", INT2FIX(SEEK_CUR)); + /* Flag for #lo_lseek -- seek from object end */ + rb_define_const(rb_mPGconstants, "SEEK_END", INT2FIX(SEEK_END)); + + + /****** PG::Result CONSTANTS: result status ******/ + + /* #result_status constant: The string sent to the server was empty. */ + rb_define_const(rb_mPGconstants, "PGRES_EMPTY_QUERY", INT2FIX(PGRES_EMPTY_QUERY)); + /* #result_status constant: Successful completion of a command returning no data. */ + rb_define_const(rb_mPGconstants, "PGRES_COMMAND_OK", INT2FIX(PGRES_COMMAND_OK)); + /* #result_status constant: Successful completion of a command returning data + (such as a SELECT or SHOW). */ + rb_define_const(rb_mPGconstants, "PGRES_TUPLES_OK", INT2FIX(PGRES_TUPLES_OK)); + /* #result_status constant: Copy Out (from server) data transfer started. */ + rb_define_const(rb_mPGconstants, "PGRES_COPY_OUT", INT2FIX(PGRES_COPY_OUT)); + /* #result_status constant: Copy In (to server) data transfer started. */ + rb_define_const(rb_mPGconstants, "PGRES_COPY_IN", INT2FIX(PGRES_COPY_IN)); + /* #result_status constant: The server’s response was not understood. */ + rb_define_const(rb_mPGconstants, "PGRES_BAD_RESPONSE", INT2FIX(PGRES_BAD_RESPONSE)); + /* #result_status constant: A nonfatal error (a notice or warning) occurred. */ + rb_define_const(rb_mPGconstants, "PGRES_NONFATAL_ERROR",INT2FIX(PGRES_NONFATAL_ERROR)); + /* #result_status constant: A fatal error occurred. */ + rb_define_const(rb_mPGconstants, "PGRES_FATAL_ERROR", INT2FIX(PGRES_FATAL_ERROR)); + + /****** Result CONSTANTS: result error field codes ******/ + + /* #result_error_field argument constant: The severity; the field contents + * are ERROR, FATAL, or PANIC (in an error message), or WARNING, NOTICE, + * DEBUG, INFO, or LOG (in a notice message), or a localized translation + * of one of these. Always present. + */ + rb_define_const(rb_mPGconstants, "PG_DIAG_SEVERITY", INT2FIX(PG_DIAG_SEVERITY)); + + /* #result_error_field argument constant: The SQLSTATE code for the + * error. The SQLSTATE code identies the type of error that has occurred; + * it can be used by front-end applications to perform specic operations + * (such as er- ror handling) in response to a particular database + * error. For a list of the possible SQLSTATE codes, see Appendix A. + * This eld is not localizable, and is always present. + */ + rb_define_const(rb_mPGconstants, "PG_DIAG_SQLSTATE", INT2FIX(PG_DIAG_SQLSTATE)); + + /* #result_error_field argument constant: The primary human-readable + * error message (typically one line). Always present. */ + rb_define_const(rb_mPGconstants, "PG_DIAG_MESSAGE_PRIMARY", INT2FIX(PG_DIAG_MESSAGE_PRIMARY)); + + /* #result_error_field argument constant: Detail: an optional secondary + * error message carrying more detail about the problem. Might run to + * multiple lines. + */ + rb_define_const(rb_mPGconstants, "PG_DIAG_MESSAGE_DETAIL", INT2FIX(PG_DIAG_MESSAGE_DETAIL)); + + /* #result_error_field argument constant: Hint: an optional suggestion + * what to do about the problem. This is intended to differ from detail + * in that it offers advice (potentially inappropriate) rather than + * hard facts. Might run to multiple lines. + */ + + rb_define_const(rb_mPGconstants, "PG_DIAG_MESSAGE_HINT", INT2FIX(PG_DIAG_MESSAGE_HINT)); + /* #result_error_field argument constant: A string containing a decimal + * integer indicating an error cursor position as an index into the + * original statement string. The rst character has index 1, and + * positions are measured in characters not bytes. + */ + + rb_define_const(rb_mPGconstants, "PG_DIAG_STATEMENT_POSITION", INT2FIX(PG_DIAG_STATEMENT_POSITION)); + /* #result_error_field argument constant: This is dened the same as + * the PG_DIAG_STATEMENT_POSITION eld, but it is used when the cursor + * position refers to an internally generated command rather than the + * one submitted by the client. The PG_DIAG_INTERNAL_QUERY eld will + * always appear when this eld appears. + */ + + rb_define_const(rb_mPGconstants, "PG_DIAG_INTERNAL_POSITION", INT2FIX(PG_DIAG_INTERNAL_POSITION)); + /* #result_error_field argument constant: The text of a failed + * internally-generated command. This could be, for example, a SQL + * query issued by a PL/pgSQL function. + */ + + rb_define_const(rb_mPGconstants, "PG_DIAG_INTERNAL_QUERY", INT2FIX(PG_DIAG_INTERNAL_QUERY)); + /* #result_error_field argument constant: An indication of the context + * in which the error occurred. Presently this includes a call stack + * traceback of active procedural language functions and internally-generated + * queries. The trace is one entry per line, most recent rst. + */ + + rb_define_const(rb_mPGconstants, "PG_DIAG_CONTEXT", INT2FIX(PG_DIAG_CONTEXT)); + /* #result_error_field argument constant: The le name of the source-code + * location where the error was reported. */ + rb_define_const(rb_mPGconstants, "PG_DIAG_SOURCE_FILE", INT2FIX(PG_DIAG_SOURCE_FILE)); + + /* #result_error_field argument constant: The line number of the + * source-code location where the error was reported. */ + rb_define_const(rb_mPGconstants, "PG_DIAG_SOURCE_LINE", INT2FIX(PG_DIAG_SOURCE_LINE)); + + /* #result_error_field argument constant: The name of the source-code + * function reporting the error. */ + rb_define_const(rb_mPGconstants, "PG_DIAG_SOURCE_FUNCTION", INT2FIX(PG_DIAG_SOURCE_FUNCTION)); + + /* Invalid OID constant */ + rb_define_const(rb_mPGconstants, "INVALID_OID", INT2FIX(InvalidOid)); + rb_define_const(rb_mPGconstants, "InvalidOid", INT2FIX(InvalidOid)); + + /* Add the constants to the toplevel namespace */ + rb_include_module( rb_mPG, rb_mPGconstants ); + +#ifdef M17N_SUPPORTED + enc_pg2ruby = st_init_numtable(); + s_id_index = rb_intern("@encoding"); +#endif + + /* Initialize the main extension classes */ + init_pg_connection(); + init_pg_result(); +} + diff --git a/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/ext/pg.h b/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/ext/pg.h new file mode 100644 index 000000000000..1a6827cbd44a --- /dev/null +++ b/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/ext/pg.h @@ -0,0 +1,123 @@ +#ifndef __pg_h +#define __pg_h + +#ifdef RUBY_EXTCONF_H +# include RUBY_EXTCONF_H +#endif + +/* System headers */ +#include +#include +#include +#if defined(HAVE_UNISTD_H) && !defined(_WIN32) +# include +#endif /* HAVE_UNISTD_H */ + +/* Ruby headers */ +#include "ruby.h" +#ifdef HAVE_RUBY_ST_H +# include "ruby/st.h" +#elif HAVE_ST_H +# include "st.h" +#endif + +#if defined(HAVE_RUBY_ENCODING_H) && HAVE_RUBY_ENCODING_H +# include "ruby/encoding.h" +# define M17N_SUPPORTED +# define ASSOCIATE_INDEX( obj, index_holder ) rb_enc_associate_index((obj), pg_enc_get_index((index_holder))) +# ifdef HAVE_RB_ENCDB_ALIAS + extern int rb_encdb_alias(const char *, const char *); +# define ENC_ALIAS(name, orig) rb_encdb_alias((name), (orig)) +# elif HAVE_RB_ENC_ALIAS + extern int rb_enc_alias(const char *, const char *); +# define ENC_ALIAS(name, orig) rb_enc_alias((name), (orig)) +# else + extern int rb_enc_alias(const char *alias, const char *orig); /* declaration missing in Ruby 1.9.1 */ +# define ENC_ALIAS(name, orig) rb_enc_alias((name), (orig)) +# endif +#else +# define ASSOCIATE_INDEX( obj, index_holder ) /* nothing */ +#endif + +#if RUBY_VM != 1 +# define RUBY_18_COMPAT +#endif + +#ifndef RARRAY_LEN +# define RARRAY_LEN(x) RARRAY((x))->len +#endif /* RARRAY_LEN */ + +#ifndef RSTRING_LEN +# define RSTRING_LEN(x) RSTRING((x))->len +#endif /* RSTRING_LEN */ + +#ifndef RSTRING_PTR +# define RSTRING_PTR(x) RSTRING((x))->ptr +#endif /* RSTRING_PTR */ + +#ifndef StringValuePtr +# define StringValuePtr(x) STR2CSTR(x) +#endif /* StringValuePtr */ + +#ifdef RUBY_18_COMPAT +# define rb_io_stdio_file GetWriteFile +# include "rubyio.h" +#else +# include "ruby/io.h" +#endif + +/* PostgreSQL headers */ +#include "libpq-fe.h" +#include "libpq/libpq-fs.h" /* large-object interface */ +#include "pg_config_manual.h" + +#if defined(_WIN32) +# include +__declspec(dllexport) +typedef long suseconds_t; +#endif + + +/*************************************************************************** + * Globals + **************************************************************************/ + +extern VALUE rb_mPG; +extern VALUE rb_ePGerror; +extern VALUE rb_mPGconstants; +extern VALUE rb_cPGconn; +extern VALUE rb_cPGresult; + + +/*************************************************************************** + * MACROS + **************************************************************************/ + +#define UNUSED(x) ((void)(x)) +#define SINGLETON_ALIAS(klass,new,old) rb_define_alias(rb_singleton_class((klass)),(new),(old)) + + +/*************************************************************************** + * PROTOTYPES + **************************************************************************/ +void Init_pg_ext _(( void )); + +void init_pg_connection _(( void )); +void init_pg_result _(( void )); + +PGconn *pg_get_pgconn _(( VALUE )); + +VALUE pg_new_result _(( PGresult *, PGconn * )); +void pg_check_result _(( VALUE, VALUE )); +VALUE pg_result_clear _(( VALUE )); + +#ifdef M17N_SUPPORTED +rb_encoding * pg_get_pg_encoding_as_rb_encoding _(( int )); +rb_encoding * pg_get_pg_encname_as_rb_encoding _(( const char * )); +const char * pg_get_rb_encoding_as_pg_encoding _(( rb_encoding * )); +int pg_enc_get_index _(( VALUE )); +rb_encoding *pg_conn_enc_get _(( PGconn * )); +#endif /* M17N_SUPPORTED */ + + +#endif /* end __pg_h */ diff --git a/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/ext/pg_connection.c b/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/ext/pg_connection.c new file mode 100644 index 000000000000..035c03d733c6 --- /dev/null +++ b/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/ext/pg_connection.c @@ -0,0 +1,3288 @@ +/* + * pg_connection.c - PG::Connection class extension + * $Id$ + * + */ + +#include "pg.h" + + +/******************************************************************** + * + * Document-class: PG::Connection + * + * The class to access PostgreSQL RDBMS, based on the libpq interface, + * provides convenient OO methods to interact with PostgreSQL. + * + * For example, to send query to the database on the localhost: + * require 'pg' + * conn = PG::Connection.open(:dbname => 'test') + * res = conn.exec('SELECT $1 AS a, $2 AS b, $3 AS c',[1, 2, nil]) + * # Equivalent to: + * # res = conn.exec('SELECT 1 AS a, 2 AS b, NULL AS c') + * + * See the PGresult class for information on working with the results of a query. + * + */ +VALUE rb_cPGconn; + +static PQnoticeReceiver default_notice_receiver = NULL; +static PQnoticeProcessor default_notice_processor = NULL; + +static PGconn *pgconn_check( VALUE ); +static VALUE pgconn_finish( VALUE ); + + +/* + * Global functions + */ + +/* + * Fetch the data pointer and check it for sanity. + */ +PGconn * +pg_get_pgconn( VALUE self ) +{ + PGconn *conn = pgconn_check( self ); + + if ( !conn ) + rb_raise( rb_ePGerror, "connection is closed" ); + + return conn; +} + + +/* + * Allocation/ + */ + +/* + * Object validity checker. Returns the data pointer. + */ +static PGconn * +pgconn_check( VALUE self ) { + + Check_Type( self, T_DATA ); + + if ( !rb_obj_is_kind_of(self, rb_cPGconn) ) { + rb_raise( rb_eTypeError, "wrong argument type %s (expected PG::Connection)", + rb_obj_classname( self ) ); + } + + return DATA_PTR( self ); +} + + +/* + * GC Free function + */ +static void +pgconn_gc_free( PGconn *conn ) +{ + if (conn != NULL) + PQfinish( conn ); +} + + +/************************************************************************** + * Class Methods + **************************************************************************/ + +/* + * Document-method: allocate + * + * call-seq: + * PG::Connection.allocate -> conn + */ +static VALUE +pgconn_s_allocate( VALUE klass ) +{ + return Data_Wrap_Struct( klass, NULL, pgconn_gc_free, NULL ); +} + + +/* + * Document-method: new + * + * call-seq: + * PG::Connection.new -> conn + * PG::Connection.new(connection_hash) -> conn + * PG::Connection.new(connection_string) -> conn + * PG::Connection.new(host, port, options, tty, dbname, user, password) -> conn + * + * Create a connection to the specified server. + * + * [+host+] + * server hostname + * [+hostaddr+] + * server address (avoids hostname lookup, overrides +host+) + * [+port+] + * server port number + * [+dbname+] + * connecting database name + * [+user+] + * login user name + * [+password+] + * login password + * [+connect_timeout+] + * maximum time to wait for connection to succeed + * [+options+] + * backend options + * [+tty+] + * (ignored in newer versions of PostgreSQL) + * [+sslmode+] + * (disable|allow|prefer|require) + * [+krbsrvname+] + * kerberos service name + * [+gsslib+] + * GSS library to use for GSSAPI authentication + * [+service+] + * service name to use for additional parameters + * + * Examples: + * + * # Connect using all defaults + * PG::Connection.new + * + * # As a Hash + * PG::Connection.new( :dbname => 'test', :port => 5432 ) + * + * # As a String + * PG::Connection.new( "dbname=test port=5432" ) + * + * # As an Array + * PG::Connection.new( nil, 5432, nil, nil, 'test', nil, nil ) + * + * If the Ruby default internal encoding is set (i.e., Encoding.default_internal != nil), the + * connection will have its +client_encoding+ set accordingly. + * + * Raises a PG::Error if the connection fails. + */ +static VALUE +pgconn_init(int argc, VALUE *argv, VALUE self) +{ + PGconn *conn = NULL; + VALUE conninfo; + VALUE error; +#ifdef M17N_SUPPORTED + rb_encoding *enc; + const char *encname; +#endif + + conninfo = rb_funcall2( rb_cPGconn, rb_intern("parse_connect_args"), argc, argv ); + conn = PQconnectdb(StringValuePtr(conninfo)); + + if(conn == NULL) + rb_raise(rb_ePGerror, "PQconnectStart() unable to allocate structure"); + + Check_Type(self, T_DATA); + DATA_PTR(self) = conn; + + if (PQstatus(conn) == CONNECTION_BAD) { + error = rb_exc_new2(rb_ePGerror, PQerrorMessage(conn)); + rb_iv_set(error, "@connection", self); + rb_exc_raise(error); + } + +#ifdef M17N_SUPPORTED + /* If Ruby has its Encoding.default_internal set, set PostgreSQL's client_encoding + * to match */ + if (( enc = rb_default_internal_encoding() )) { + encname = pg_get_rb_encoding_as_pg_encoding( enc ); + if ( PQsetClientEncoding(conn, encname) != 0 ) + rb_warn( "Failed to set the default_internal encoding to %s: '%s'", + encname, PQerrorMessage(conn) ); + } +#endif + + if (rb_block_given_p()) { + return rb_ensure(rb_yield, self, pgconn_finish, self); + } + return self; +} + +/* + * call-seq: + * PG::Connection.connect_start(connection_hash) -> conn + * PG::Connection.connect_start(connection_string) -> conn + * PG::Connection.connect_start(host, port, options, tty, dbname, login, password) -> conn + * + * This is an asynchronous version of PG::Connection.connect(). + * + * Use #connect_poll to poll the status of the connection. + * + * NOTE: this does *not* set the connection's +client_encoding+ for you if + * Encoding.default_internal is set. To set it after the connection is established, + * call #internal_encoding=. You can also set it automatically by setting + * ENV['PGCLIENTENCODING'], or include the 'options' connection parameter. + * + */ +static VALUE +pgconn_s_connect_start( int argc, VALUE *argv, VALUE klass ) +{ + PGconn *conn = NULL; + VALUE rb_conn; + VALUE conninfo; + VALUE error; + + /* + * PG::Connection.connect_start must act as both alloc() and initialize() + * because it is not invoked by calling new(). + */ + rb_conn = pgconn_s_allocate( klass ); + conninfo = rb_funcall2( klass, rb_intern("parse_connect_args"), argc, argv ); + conn = PQconnectStart( StringValuePtr(conninfo) ); + + if( conn == NULL ) + rb_raise(rb_ePGerror, "PQconnectStart() unable to allocate structure"); + + Check_Type(rb_conn, T_DATA); + DATA_PTR(rb_conn) = conn; + + if ( PQstatus(conn) == CONNECTION_BAD ) { + error = rb_exc_new2(rb_ePGerror, PQerrorMessage(conn)); + rb_iv_set(error, "@connection", rb_conn); + rb_exc_raise(error); + } + + if ( rb_block_given_p() ) { + return rb_ensure( rb_yield, rb_conn, pgconn_finish, rb_conn ); + } + return rb_conn; +} + +/* + * call-seq: + * PG::Connection.conndefaults() -> Array + * + * Returns an array of hashes. Each hash has the keys: + * [+:keyword+] + * the name of the option + * [+:envvar+] + * the environment variable to fall back to + * [+:compiled+] + * the compiled in option as a secondary fallback + * [+:val+] + * the option's current value, or +nil+ if not known + * [+:label+] + * the label for the field + * [+:dispchar+] + * "" for normal, "D" for debug, and "*" for password + * [+:dispsize+] + * field size + */ +static VALUE +pgconn_s_conndefaults(VALUE self) +{ + PQconninfoOption *options = PQconndefaults(); + VALUE ary = rb_ary_new(); + VALUE hash; + int i = 0; + + UNUSED( self ); + + for(i = 0; options[i].keyword != NULL; i++) { + hash = rb_hash_new(); + if(options[i].keyword) + rb_hash_aset(hash, ID2SYM(rb_intern("keyword")), rb_str_new2(options[i].keyword)); + if(options[i].envvar) + rb_hash_aset(hash, ID2SYM(rb_intern("envvar")), rb_str_new2(options[i].envvar)); + if(options[i].compiled) + rb_hash_aset(hash, ID2SYM(rb_intern("compiled")), rb_str_new2(options[i].compiled)); + if(options[i].val) + rb_hash_aset(hash, ID2SYM(rb_intern("val")), rb_str_new2(options[i].val)); + if(options[i].label) + rb_hash_aset(hash, ID2SYM(rb_intern("label")), rb_str_new2(options[i].label)); + if(options[i].dispchar) + rb_hash_aset(hash, ID2SYM(rb_intern("dispchar")), rb_str_new2(options[i].dispchar)); + rb_hash_aset(hash, ID2SYM(rb_intern("dispsize")), INT2NUM(options[i].dispsize)); + rb_ary_push(ary, hash); + } + PQconninfoFree(options); + return ary; +} + + +/* + * call-seq: + * PG::Connection.encrypt_password( password, username ) -> String + * + * This function is intended to be used by client applications that + * send commands like: +ALTER USER joe PASSWORD 'pwd'+. + * The arguments are the cleartext password, and the SQL name + * of the user it is for. + * + * Return value is the encrypted password. + */ +static VALUE +pgconn_s_encrypt_password(VALUE self, VALUE password, VALUE username) +{ + char *encrypted = NULL; + VALUE rval = Qnil; + + UNUSED( self ); + + Check_Type(password, T_STRING); + Check_Type(username, T_STRING); + + encrypted = PQencryptPassword(StringValuePtr(password), StringValuePtr(username)); + rval = rb_str_new2( encrypted ); + PQfreemem( encrypted ); + + OBJ_INFECT( rval, password ); + OBJ_INFECT( rval, username ); + + return rval; +} + + +/* + * call-seq: + * PG::Connection.isthreadsafe() -> Boolean + * + * Returns +true+ if libpq is thread safe, +false+ otherwise. + */ +static VALUE +pgconn_s_isthreadsafe(VALUE self) +{ + UNUSED( self ); + return PQisthreadsafe() ? Qtrue : Qfalse; +} + +/************************************************************************** + * PG::Connection INSTANCE METHODS + **************************************************************************/ + +/* + * call-seq: + * conn.connect_poll() -> Fixnum + * + * Returns one of: + * [+PGRES_POLLING_READING+] + * wait until the socket is ready to read + * [+PGRES_POLLING_WRITING+] + * wait until the socket is ready to write + * [+PGRES_POLLING_FAILED+] + * the asynchronous connection has failed + * [+PGRES_POLLING_OK+] + * the asynchronous connection is ready + * + * Example: + * conn = PG::Connection.connect_start("dbname=mydatabase") + * socket = IO.for_fd(conn.socket) + * status = conn.connect_poll + * while(status != PG::PGRES_POLLING_OK) do + * # do some work while waiting for the connection to complete + * if(status == PG::PGRES_POLLING_READING) + * if(not select([socket], [], [], 10.0)) + * raise "Asynchronous connection timed out!" + * end + * elsif(status == PG::PGRES_POLLING_WRITING) + * if(not select([], [socket], [], 10.0)) + * raise "Asynchronous connection timed out!" + * end + * end + * status = conn.connect_poll + * end + * # now conn.status == CONNECTION_OK, and connection + * # is ready. + */ +static VALUE +pgconn_connect_poll(VALUE self) +{ + PostgresPollingStatusType status; + status = PQconnectPoll(pg_get_pgconn(self)); + return INT2FIX((int)status); +} + +/* + * call-seq: + * conn.finish + * + * Closes the backend connection. + */ +static VALUE +pgconn_finish(VALUE self) +{ + PQfinish(pg_get_pgconn(self)); + DATA_PTR(self) = NULL; + return Qnil; +} + + +/* + * call-seq: + * conn.finished? -> boolean + * + * Returns +true+ if the backend connection has been closed. + */ +static VALUE +pgconn_finished_p( VALUE self ) +{ + if ( DATA_PTR(self) ) return Qfalse; + return Qtrue; +} + + +/* + * call-seq: + * conn.reset() + * + * Resets the backend connection. This method closes the + * backend connection and tries to re-connect. + */ +static VALUE +pgconn_reset(VALUE self) +{ + PQreset(pg_get_pgconn(self)); + return self; +} + +/* + * call-seq: + * conn.reset_start() -> nil + * + * Initiate a connection reset in a nonblocking manner. + * This will close the current connection and attempt to + * reconnect using the same connection parameters. + * Use #reset_poll to check the status of the + * connection reset. + */ +static VALUE +pgconn_reset_start(VALUE self) +{ + if(PQresetStart(pg_get_pgconn(self)) == 0) + rb_raise(rb_ePGerror, "reset has failed"); + return Qnil; +} + +/* + * call-seq: + * conn.reset_poll -> Fixnum + * + * Checks the status of a connection reset operation. + * See #connect_start and #connect_poll for + * usage information and return values. + */ +static VALUE +pgconn_reset_poll(VALUE self) +{ + PostgresPollingStatusType status; + status = PQresetPoll(pg_get_pgconn(self)); + return INT2FIX((int)status); +} + +/* + * call-seq: + * conn.db() + * + * Returns the connected database name. + */ +static VALUE +pgconn_db(VALUE self) +{ + char *db = PQdb(pg_get_pgconn(self)); + if (!db) return Qnil; + return rb_tainted_str_new2(db); +} + +/* + * call-seq: + * conn.user() + * + * Returns the authenticated user name. + */ +static VALUE +pgconn_user(VALUE self) +{ + char *user = PQuser(pg_get_pgconn(self)); + if (!user) return Qnil; + return rb_tainted_str_new2(user); +} + +/* + * call-seq: + * conn.pass() + * + * Returns the authenticated user name. + */ +static VALUE +pgconn_pass(VALUE self) +{ + char *user = PQpass(pg_get_pgconn(self)); + if (!user) return Qnil; + return rb_tainted_str_new2(user); +} + +/* + * call-seq: + * conn.host() + * + * Returns the connected server name. + */ +static VALUE +pgconn_host(VALUE self) +{ + char *host = PQhost(pg_get_pgconn(self)); + if (!host) return Qnil; + return rb_tainted_str_new2(host); +} + +/* + * call-seq: + * conn.port() + * + * Returns the connected server port number. + */ +static VALUE +pgconn_port(VALUE self) +{ + char* port = PQport(pg_get_pgconn(self)); + return INT2NUM(atol(port)); +} + +/* + * call-seq: + * conn.tty() + * + * Returns the connected pgtty. (Obsolete) + */ +static VALUE +pgconn_tty(VALUE self) +{ + char *tty = PQtty(pg_get_pgconn(self)); + if (!tty) return Qnil; + return rb_tainted_str_new2(tty); +} + +/* + * call-seq: + * conn.options() + * + * Returns backend option string. + */ +static VALUE +pgconn_options(VALUE self) +{ + char *options = PQoptions(pg_get_pgconn(self)); + if (!options) return Qnil; + return rb_tainted_str_new2(options); +} + +/* + * call-seq: + * conn.status() + * + * Returns status of connection : CONNECTION_OK or CONNECTION_BAD + */ +static VALUE +pgconn_status(VALUE self) +{ + return INT2NUM(PQstatus(pg_get_pgconn(self))); +} + +/* + * call-seq: + * conn.transaction_status() + * + * returns one of the following statuses: + * PQTRANS_IDLE = 0 (connection idle) + * PQTRANS_ACTIVE = 1 (command in progress) + * PQTRANS_INTRANS = 2 (idle, within transaction block) + * PQTRANS_INERROR = 3 (idle, within failed transaction) + * PQTRANS_UNKNOWN = 4 (cannot determine status) + */ +static VALUE +pgconn_transaction_status(VALUE self) +{ + return INT2NUM(PQtransactionStatus(pg_get_pgconn(self))); +} + +/* + * call-seq: + * conn.parameter_status( param_name ) -> String + * + * Returns the setting of parameter _param_name_, where + * _param_name_ is one of + * * +server_version+ + * * +server_encoding+ + * * +client_encoding+ + * * +is_superuser+ + * * +session_authorization+ + * * +DateStyle+ + * * +TimeZone+ + * * +integer_datetimes+ + * * +standard_conforming_strings+ + * + * Returns nil if the value of the parameter is not known. + */ +static VALUE +pgconn_parameter_status(VALUE self, VALUE param_name) +{ + const char *ret = PQparameterStatus(pg_get_pgconn(self), StringValuePtr(param_name)); + if(ret == NULL) + return Qnil; + else + return rb_tainted_str_new2(ret); +} + +/* + * call-seq: + * conn.protocol_version -> Integer + * + * The 3.0 protocol will normally be used when communicating with PostgreSQL 7.4 + * or later servers; pre-7.4 servers support only protocol 2.0. (Protocol 1.0 is + * obsolete and not supported by libpq.) + */ +static VALUE +pgconn_protocol_version(VALUE self) +{ + return INT2NUM(PQprotocolVersion(pg_get_pgconn(self))); +} + +/* + * call-seq: + * conn.server_version -> Integer + * + * The number is formed by converting the major, minor, and revision + * numbers into two-decimal-digit numbers and appending them together. + * For example, version 7.4.2 will be returned as 70402, and version + * 8.1 will be returned as 80100 (leading zeroes are not shown). Zero + * is returned if the connection is bad. + * + */ +static VALUE +pgconn_server_version(VALUE self) +{ + return INT2NUM(PQserverVersion(pg_get_pgconn(self))); +} + +/* + * call-seq: + * conn.error_message -> String + * + * Returns the error message about connection. + */ +static VALUE +pgconn_error_message(VALUE self) +{ + char *error = PQerrorMessage(pg_get_pgconn(self)); + if (!error) return Qnil; + return rb_tainted_str_new2(error); +} + +/* + * call-seq: + * conn.socket() -> Fixnum + * + * Returns the socket's file descriptor for this connection. + */ +static VALUE +pgconn_socket(VALUE self) +{ + int sd; + if( (sd = PQsocket(pg_get_pgconn(self))) < 0) + rb_raise(rb_ePGerror, "Can't get socket descriptor"); + return INT2NUM(sd); +} + + +/* + * call-seq: + * conn.backend_pid() -> Fixnum + * + * Returns the process ID of the backend server + * process for this connection. + * Note that this is a PID on database server host. + */ +static VALUE +pgconn_backend_pid(VALUE self) +{ + return INT2NUM(PQbackendPID(pg_get_pgconn(self))); +} + +/* + * call-seq: + * conn.connection_needs_password() -> Boolean + * + * Returns +true+ if the authentication method required a + * password, but none was available. +false+ otherwise. + */ +static VALUE +pgconn_connection_needs_password(VALUE self) +{ + return PQconnectionNeedsPassword(pg_get_pgconn(self)) ? Qtrue : Qfalse; +} + +/* + * call-seq: + * conn.connection_used_password() -> Boolean + * + * Returns +true+ if the authentication method used + * a caller-supplied password, +false+ otherwise. + */ +static VALUE +pgconn_connection_used_password(VALUE self) +{ + return PQconnectionUsedPassword(pg_get_pgconn(self)) ? Qtrue : Qfalse; +} + + +/* :TODO: get_ssl */ + + +/* + * call-seq: + * conn.exec(sql [, params, result_format ] ) -> PGresult + * conn.exec(sql [, params, result_format ] ) {|pg_result| block } + * + * Sends SQL query request specified by _sql_ to PostgreSQL. + * Returns a PGresult instance on success. + * On failure, it raises a PGError exception. + * + * +params+ is an optional array of the bind parameters for the SQL query. + * Each element of the +params+ array may be either: + * a hash of the form: + * {:value => String (value of bind parameter) + * :type => Fixnum (oid of type of bind parameter) + * :format => Fixnum (0 for text, 1 for binary) + * } + * or, it may be a String. If it is a string, that is equivalent to the hash: + * { :value => , :type => 0, :format => 0 } + * + * PostgreSQL bind parameters are represented as $1, $1, $2, etc., + * inside the SQL query. The 0th element of the +params+ array is bound + * to $1, the 1st element is bound to $2, etc. +nil+ is treated as +NULL+. + * + * If the types are not specified, they will be inferred by PostgreSQL. + * Instead of specifying type oids, it's recommended to simply add + * explicit casts in the query to ensure that the right type is used. + * + * For example: "SELECT $1::int" + * + * The optional +result_format+ should be 0 for text results, 1 + * for binary. + * + * If the optional code block is given, it will be passed result as an argument, + * and the PGresult object will automatically be cleared when the block terminates. + * In this instance, conn.exec returns the value of the block. + */ +static VALUE +pgconn_exec(int argc, VALUE *argv, VALUE self) +{ + PGconn *conn = pg_get_pgconn(self); + PGresult *result = NULL; + VALUE rb_pgresult; + VALUE command, params, in_res_fmt; + VALUE param, param_type, param_value, param_format; + VALUE param_value_tmp; + VALUE sym_type, sym_value, sym_format; + VALUE gc_array; + int i=0; + int nParams; + Oid *paramTypes; + char ** paramValues; + int *paramLengths; + int *paramFormats; + int resultFormat; + + rb_scan_args(argc, argv, "12", &command, ¶ms, &in_res_fmt); + + Check_Type(command, T_STRING); + + /* If called with no parameters, use PQexec */ + if(NIL_P(params)) { + result = PQexec(conn, StringValuePtr(command)); + rb_pgresult = pg_new_result(result, conn); + pg_check_result(self, rb_pgresult); + if (rb_block_given_p()) { + return rb_ensure(rb_yield, rb_pgresult, pg_result_clear, rb_pgresult); + } + return rb_pgresult; + } + + /* If called with parameters, and optionally result_format, + * use PQexecParams + */ + Check_Type(params, T_ARRAY); + + if(NIL_P(in_res_fmt)) { + resultFormat = 0; + } + else { + resultFormat = NUM2INT(in_res_fmt); + } + + gc_array = rb_ary_new(); + rb_gc_register_address(&gc_array); + sym_type = ID2SYM(rb_intern("type")); + sym_value = ID2SYM(rb_intern("value")); + sym_format = ID2SYM(rb_intern("format")); + nParams = (int)RARRAY_LEN(params); + paramTypes = ALLOC_N(Oid, nParams); + paramValues = ALLOC_N(char *, nParams); + paramLengths = ALLOC_N(int, nParams); + paramFormats = ALLOC_N(int, nParams); + for(i = 0; i < nParams; i++) { + param = rb_ary_entry(params, i); + if (TYPE(param) == T_HASH) { + param_type = rb_hash_aref(param, sym_type); + param_value_tmp = rb_hash_aref(param, sym_value); + if(param_value_tmp == Qnil) + param_value = param_value_tmp; + else + param_value = rb_obj_as_string(param_value_tmp); + param_format = rb_hash_aref(param, sym_format); + } + else { + param_type = Qnil; + if(param == Qnil) + param_value = param; + else + param_value = rb_obj_as_string(param); + param_format = Qnil; + } + + if(param_type == Qnil) + paramTypes[i] = 0; + else + paramTypes[i] = NUM2INT(param_type); + + if(param_value == Qnil) { + paramValues[i] = NULL; + paramLengths[i] = 0; + } + else { + Check_Type(param_value, T_STRING); + /* make sure param_value doesn't get freed by the GC */ + rb_ary_push(gc_array, param_value); + paramValues[i] = StringValuePtr(param_value); + paramLengths[i] = (int)RSTRING_LEN(param_value); + } + + if(param_format == Qnil) + paramFormats[i] = 0; + else + paramFormats[i] = NUM2INT(param_format); + } + + result = PQexecParams(conn, StringValuePtr(command), nParams, paramTypes, + (const char * const *)paramValues, paramLengths, paramFormats, resultFormat); + + rb_gc_unregister_address(&gc_array); + + xfree(paramTypes); + xfree(paramValues); + xfree(paramLengths); + xfree(paramFormats); + + rb_pgresult = pg_new_result(result, conn); + pg_check_result(self, rb_pgresult); + if (rb_block_given_p()) { + return rb_ensure(rb_yield, rb_pgresult, + pg_result_clear, rb_pgresult); + } + return rb_pgresult; +} + +/* + * call-seq: + * conn.prepare(stmt_name, sql [, param_types ] ) -> PGresult + * + * Prepares statement _sql_ with name _name_ to be executed later. + * Returns a PGresult instance on success. + * On failure, it raises a PGError exception. + * + * +param_types+ is an optional parameter to specify the Oids of the + * types of the parameters. + * + * If the types are not specified, they will be inferred by PostgreSQL. + * Instead of specifying type oids, it's recommended to simply add + * explicit casts in the query to ensure that the right type is used. + * + * For example: "SELECT $1::int" + * + * PostgreSQL bind parameters are represented as $1, $1, $2, etc., + * inside the SQL query. + */ +static VALUE +pgconn_prepare(int argc, VALUE *argv, VALUE self) +{ + PGconn *conn = pg_get_pgconn(self); + PGresult *result = NULL; + VALUE rb_pgresult; + VALUE name, command, in_paramtypes; + VALUE param; + int i = 0; + int nParams = 0; + Oid *paramTypes = NULL; + + rb_scan_args(argc, argv, "21", &name, &command, &in_paramtypes); + Check_Type(name, T_STRING); + Check_Type(command, T_STRING); + + if(! NIL_P(in_paramtypes)) { + Check_Type(in_paramtypes, T_ARRAY); + nParams = (int)RARRAY_LEN(in_paramtypes); + paramTypes = ALLOC_N(Oid, nParams); + for(i = 0; i < nParams; i++) { + param = rb_ary_entry(in_paramtypes, i); + Check_Type(param, T_FIXNUM); + if(param == Qnil) + paramTypes[i] = 0; + else + paramTypes[i] = NUM2INT(param); + } + } + result = PQprepare(conn, StringValuePtr(name), StringValuePtr(command), + nParams, paramTypes); + + xfree(paramTypes); + + rb_pgresult = pg_new_result(result, conn); + pg_check_result(self, rb_pgresult); + return rb_pgresult; +} + +/* + * call-seq: + * conn.exec_prepared(statement_name [, params, result_format ] ) -> PGresult + * conn.exec_prepared(statement_name [, params, result_format ] ) {|pg_result| block } + * + * Execute prepared named statement specified by _statement_name_. + * Returns a PGresult instance on success. + * On failure, it raises a PGError exception. + * + * +params+ is an array of the optional bind parameters for the + * SQL query. Each element of the +params+ array may be either: + * a hash of the form: + * {:value => String (value of bind parameter) + * :format => Fixnum (0 for text, 1 for binary) + * } + * or, it may be a String. If it is a string, that is equivalent to the hash: + * { :value => , :format => 0 } + * + * PostgreSQL bind parameters are represented as $1, $1, $2, etc., + * inside the SQL query. The 0th element of the +params+ array is bound + * to $1, the 1st element is bound to $2, etc. +nil+ is treated as +NULL+. + * + * The optional +result_format+ should be 0 for text results, 1 + * for binary. + * + * If the optional code block is given, it will be passed result as an argument, + * and the PGresult object will automatically be cleared when the block terminates. + * In this instance, conn.exec_prepared returns the value of the block. + */ +static VALUE +pgconn_exec_prepared(int argc, VALUE *argv, VALUE self) +{ + PGconn *conn = pg_get_pgconn(self); + PGresult *result = NULL; + VALUE rb_pgresult; + VALUE name, params, in_res_fmt; + VALUE param, param_value, param_format; + VALUE param_value_tmp; + VALUE sym_value, sym_format; + VALUE gc_array; + int i = 0; + int nParams; + char ** paramValues; + int *paramLengths; + int *paramFormats; + int resultFormat; + + + rb_scan_args(argc, argv, "12", &name, ¶ms, &in_res_fmt); + Check_Type(name, T_STRING); + + if(NIL_P(params)) { + params = rb_ary_new2(0); + resultFormat = 0; + } + else { + Check_Type(params, T_ARRAY); + } + + if(NIL_P(in_res_fmt)) { + resultFormat = 0; + } + else { + resultFormat = NUM2INT(in_res_fmt); + } + + gc_array = rb_ary_new(); + rb_gc_register_address(&gc_array); + sym_value = ID2SYM(rb_intern("value")); + sym_format = ID2SYM(rb_intern("format")); + nParams = (int)RARRAY_LEN(params); + paramValues = ALLOC_N(char *, nParams); + paramLengths = ALLOC_N(int, nParams); + paramFormats = ALLOC_N(int, nParams); + for(i = 0; i < nParams; i++) { + param = rb_ary_entry(params, i); + if (TYPE(param) == T_HASH) { + param_value_tmp = rb_hash_aref(param, sym_value); + if(param_value_tmp == Qnil) + param_value = param_value_tmp; + else + param_value = rb_obj_as_string(param_value_tmp); + param_format = rb_hash_aref(param, sym_format); + } + else { + if(param == Qnil) + param_value = param; + else + param_value = rb_obj_as_string(param); + param_format = INT2NUM(0); + } + if(param_value == Qnil) { + paramValues[i] = NULL; + paramLengths[i] = 0; + } + else { + Check_Type(param_value, T_STRING); + /* make sure param_value doesn't get freed by the GC */ + rb_ary_push(gc_array, param_value); + paramValues[i] = StringValuePtr(param_value); + paramLengths[i] = (int)RSTRING_LEN(param_value); + } + + if(param_format == Qnil) + paramFormats[i] = 0; + else + paramFormats[i] = NUM2INT(param_format); + } + + result = PQexecPrepared(conn, StringValuePtr(name), nParams, + (const char * const *)paramValues, paramLengths, paramFormats, + resultFormat); + + rb_gc_unregister_address(&gc_array); + + xfree(paramValues); + xfree(paramLengths); + xfree(paramFormats); + + rb_pgresult = pg_new_result(result, conn); + pg_check_result(self, rb_pgresult); + if (rb_block_given_p()) { + return rb_ensure(rb_yield, rb_pgresult, + pg_result_clear, rb_pgresult); + } + return rb_pgresult; +} + +/* + * call-seq: + * conn.describe_prepared( statement_name ) -> PGresult + * + * Retrieve information about the prepared statement + * _statement_name_. + */ +static VALUE +pgconn_describe_prepared(VALUE self, VALUE stmt_name) +{ + PGresult *result; + VALUE rb_pgresult; + PGconn *conn = pg_get_pgconn(self); + char *stmt; + if(stmt_name == Qnil) { + stmt = NULL; + } + else { + Check_Type(stmt_name, T_STRING); + stmt = StringValuePtr(stmt_name); + } + result = PQdescribePrepared(conn, stmt); + rb_pgresult = pg_new_result(result, conn); + pg_check_result(self, rb_pgresult); + return rb_pgresult; +} + + +/* + * call-seq: + * conn.describe_portal( portal_name ) -> PGresult + * + * Retrieve information about the portal _portal_name_. + */ +static VALUE +pgconn_describe_portal(self, stmt_name) + VALUE self, stmt_name; +{ + PGresult *result; + VALUE rb_pgresult; + PGconn *conn = pg_get_pgconn(self); + char *stmt; + if(stmt_name == Qnil) { + stmt = NULL; + } + else { + Check_Type(stmt_name, T_STRING); + stmt = StringValuePtr(stmt_name); + } + result = PQdescribePortal(conn, stmt); + rb_pgresult = pg_new_result(result, conn); + pg_check_result(self, rb_pgresult); + return rb_pgresult; +} + + +/* + * call-seq: + * conn.make_empty_pgresult( status ) -> PGresult + * + * Constructs and empty PGresult with status _status_. + * _status_ may be one of: + * * +PGRES_EMPTY_QUERY+ + * * +PGRES_COMMAND_OK+ + * * +PGRES_TUPLES_OK+ + * * +PGRES_COPY_OUT+ + * * +PGRES_COPY_IN+ + * * +PGRES_BAD_RESPONSE+ + * * +PGRES_NONFATAL_ERROR+ + * * +PGRES_FATAL_ERROR+ + */ +static VALUE +pgconn_make_empty_pgresult(VALUE self, VALUE status) +{ + PGresult *result; + VALUE rb_pgresult; + PGconn *conn = pg_get_pgconn(self); + result = PQmakeEmptyPGresult(conn, NUM2INT(status)); + rb_pgresult = pg_new_result(result, conn); + pg_check_result(self, rb_pgresult); + return rb_pgresult; +} + + +/* + * call-seq: + * conn.escape_string( str ) -> String + * + * Connection instance method for versions of 8.1 and higher of libpq + * uses PQescapeStringConn, which is safer. Avoid calling as a class method, + * the class method uses the deprecated PQescapeString() API function. + * + * Returns a SQL-safe version of the String _str_. + * This is the preferred way to make strings safe for inclusion in + * SQL queries. + * + * Consider using exec_params, which avoids the need for passing values + * inside of SQL commands. + * + * Encoding of escaped string will be equal to client encoding of connection. + */ +static VALUE +pgconn_s_escape(VALUE self, VALUE string) +{ + char *escaped; + size_t size; + int error; + VALUE result; +#ifdef M17N_SUPPORTED + rb_encoding* enc; +#endif + + Check_Type(string, T_STRING); + + escaped = ALLOC_N(char, RSTRING_LEN(string) * 2 + 1); + if(rb_obj_class(self) == rb_cPGconn) { + size = PQescapeStringConn(pg_get_pgconn(self), escaped, + RSTRING_PTR(string), RSTRING_LEN(string), &error); + if(error) { + xfree(escaped); + rb_raise(rb_ePGerror, "%s", PQerrorMessage(pg_get_pgconn(self))); + } + } else { + size = PQescapeString(escaped, RSTRING_PTR(string), (int)RSTRING_LEN(string)); + } + result = rb_str_new(escaped, size); + xfree(escaped); + OBJ_INFECT(result, string); + +#ifdef M17N_SUPPORTED + if ( rb_obj_class(self) == rb_cPGconn ) { + enc = pg_conn_enc_get( pg_get_pgconn(self) ); + } else { + enc = rb_enc_get(string); + } + rb_enc_associate(result, enc); +#endif + + return result; +} + +/* + * call-seq: + * conn.escape_bytea( string ) -> String + * + * Connection instance method for versions of 8.1 and higher of libpq + * uses PQescapeByteaConn, which is safer. Avoid calling as a class method, + * the class method uses the deprecated PQescapeBytea() API function. + * + * Use the instance method version of this function, it is safer than the + * class method. + * + * Escapes binary data for use within an SQL command with the type +bytea+. + * + * Certain byte values must be escaped (but all byte values may be escaped) + * when used as part of a +bytea+ literal in an SQL statement. In general, to + * escape a byte, it is converted into the three digit octal number equal to + * the octet value, and preceded by two backslashes. The single quote (') and + * backslash (\) characters have special alternative escape sequences. + * #escape_bytea performs this operation, escaping only the minimally required + * bytes. + * + * Consider using exec_params, which avoids the need for passing values inside of + * SQL commands. + */ +static VALUE +pgconn_s_escape_bytea(VALUE self, VALUE str) +{ + unsigned char *from, *to; + size_t from_len, to_len; + VALUE ret; + + Check_Type(str, T_STRING); + from = (unsigned char*)RSTRING_PTR(str); + from_len = RSTRING_LEN(str); + + if(rb_obj_class(self) == rb_cPGconn) { + to = PQescapeByteaConn(pg_get_pgconn(self), from, from_len, &to_len); + } else { + to = PQescapeBytea( from, from_len, &to_len); + } + + ret = rb_str_new((char*)to, to_len - 1); + OBJ_INFECT(ret, str); + PQfreemem(to); + return ret; +} + + +/* + * call-seq: + * PG::Connection.unescape_bytea( string ) + * + * Converts an escaped string representation of binary data into binary data --- the + * reverse of #escape_bytea. This is needed when retrieving +bytea+ data in text format, + * but not when retrieving it in binary format. + * + */ +static VALUE +pgconn_s_unescape_bytea(VALUE self, VALUE str) +{ + unsigned char *from, *to; + size_t to_len; + VALUE ret; + + UNUSED( self ); + + Check_Type(str, T_STRING); + from = (unsigned char*)StringValuePtr(str); + + to = PQunescapeBytea(from, &to_len); + + ret = rb_str_new((char*)to, to_len); + OBJ_INFECT(ret, str); + PQfreemem(to); + return ret; +} + +/* + * call-seq: + * conn.send_query(sql [, params, result_format ] ) -> nil + * + * Sends SQL query request specified by _sql_ to PostgreSQL for + * asynchronous processing, and immediately returns. + * On failure, it raises a PGError exception. + * + * +params+ is an optional array of the bind parameters for the SQL query. + * Each element of the +params+ array may be either: + * a hash of the form: + * {:value => String (value of bind parameter) + * :type => Fixnum (oid of type of bind parameter) + * :format => Fixnum (0 for text, 1 for binary) + * } + * or, it may be a String. If it is a string, that is equivalent to the hash: + * { :value => , :type => 0, :format => 0 } + * + * PostgreSQL bind parameters are represented as $1, $1, $2, etc., + * inside the SQL query. The 0th element of the +params+ array is bound + * to $1, the 1st element is bound to $2, etc. +nil+ is treated as +NULL+. + * + * If the types are not specified, they will be inferred by PostgreSQL. + * Instead of specifying type oids, it's recommended to simply add + * explicit casts in the query to ensure that the right type is used. + * + * For example: "SELECT $1::int" + * + * The optional +result_format+ should be 0 for text results, 1 + * for binary. + */ +static VALUE +pgconn_send_query(int argc, VALUE *argv, VALUE self) +{ + PGconn *conn = pg_get_pgconn(self); + int result; + VALUE command, params, in_res_fmt; + VALUE param, param_type, param_value, param_format; + VALUE param_value_tmp; + VALUE sym_type, sym_value, sym_format; + VALUE gc_array; + VALUE error; + int i=0; + int nParams; + Oid *paramTypes; + char ** paramValues; + int *paramLengths; + int *paramFormats; + int resultFormat; + + rb_scan_args(argc, argv, "12", &command, ¶ms, &in_res_fmt); + Check_Type(command, T_STRING); + + /* If called with no parameters, use PQsendQuery */ + if(NIL_P(params)) { + if(PQsendQuery(conn,StringValuePtr(command)) == 0) { + error = rb_exc_new2(rb_ePGerror, PQerrorMessage(conn)); + rb_iv_set(error, "@connection", self); + rb_exc_raise(error); + } + return Qnil; + } + + /* If called with parameters, and optionally result_format, + * use PQsendQueryParams + */ + Check_Type(params, T_ARRAY); + + if(NIL_P(in_res_fmt)) { + resultFormat = 0; + } + else { + resultFormat = NUM2INT(in_res_fmt); + } + + gc_array = rb_ary_new(); + rb_gc_register_address(&gc_array); + sym_type = ID2SYM(rb_intern("type")); + sym_value = ID2SYM(rb_intern("value")); + sym_format = ID2SYM(rb_intern("format")); + nParams = (int)RARRAY_LEN(params); + paramTypes = ALLOC_N(Oid, nParams); + paramValues = ALLOC_N(char *, nParams); + paramLengths = ALLOC_N(int, nParams); + paramFormats = ALLOC_N(int, nParams); + for(i = 0; i < nParams; i++) { + param = rb_ary_entry(params, i); + if (TYPE(param) == T_HASH) { + param_type = rb_hash_aref(param, sym_type); + param_value_tmp = rb_hash_aref(param, sym_value); + if(param_value_tmp == Qnil) + param_value = param_value_tmp; + else + param_value = rb_obj_as_string(param_value_tmp); + param_format = rb_hash_aref(param, sym_format); + } + else { + param_type = INT2NUM(0); + if(param == Qnil) + param_value = param; + else + param_value = rb_obj_as_string(param); + param_format = INT2NUM(0); + } + + if(param_type == Qnil) + paramTypes[i] = 0; + else + paramTypes[i] = NUM2INT(param_type); + + if(param_value == Qnil) { + paramValues[i] = NULL; + paramLengths[i] = 0; + } + else { + Check_Type(param_value, T_STRING); + /* make sure param_value doesn't get freed by the GC */ + rb_ary_push(gc_array, param_value); + paramValues[i] = StringValuePtr(param_value); + paramLengths[i] = (int)RSTRING_LEN(param_value); + } + + if(param_format == Qnil) + paramFormats[i] = 0; + else + paramFormats[i] = NUM2INT(param_format); + } + + result = PQsendQueryParams(conn, StringValuePtr(command), nParams, paramTypes, + (const char * const *)paramValues, paramLengths, paramFormats, resultFormat); + + rb_gc_unregister_address(&gc_array); + + xfree(paramTypes); + xfree(paramValues); + xfree(paramLengths); + xfree(paramFormats); + + if(result == 0) { + error = rb_exc_new2(rb_ePGerror, PQerrorMessage(conn)); + rb_iv_set(error, "@connection", self); + rb_exc_raise(error); + } + return Qnil; +} + +/* + * call-seq: + * conn.send_prepare( stmt_name, sql [, param_types ] ) -> nil + * + * Prepares statement _sql_ with name _name_ to be executed later. + * Sends prepare command asynchronously, and returns immediately. + * On failure, it raises a PGError exception. + * + * +param_types+ is an optional parameter to specify the Oids of the + * types of the parameters. + * + * If the types are not specified, they will be inferred by PostgreSQL. + * Instead of specifying type oids, it's recommended to simply add + * explicit casts in the query to ensure that the right type is used. + * + * For example: "SELECT $1::int" + * + * PostgreSQL bind parameters are represented as $1, $1, $2, etc., + * inside the SQL query. + */ +static VALUE +pgconn_send_prepare(int argc, VALUE *argv, VALUE self) +{ + PGconn *conn = pg_get_pgconn(self); + int result; + VALUE name, command, in_paramtypes; + VALUE param; + VALUE error; + int i = 0; + int nParams = 0; + Oid *paramTypes = NULL; + + rb_scan_args(argc, argv, "21", &name, &command, &in_paramtypes); + Check_Type(name, T_STRING); + Check_Type(command, T_STRING); + + if(! NIL_P(in_paramtypes)) { + Check_Type(in_paramtypes, T_ARRAY); + nParams = (int)RARRAY_LEN(in_paramtypes); + paramTypes = ALLOC_N(Oid, nParams); + for(i = 0; i < nParams; i++) { + param = rb_ary_entry(in_paramtypes, i); + Check_Type(param, T_FIXNUM); + if(param == Qnil) + paramTypes[i] = 0; + else + paramTypes[i] = NUM2INT(param); + } + } + result = PQsendPrepare(conn, StringValuePtr(name), StringValuePtr(command), + nParams, paramTypes); + + xfree(paramTypes); + + if(result == 0) { + error = rb_exc_new2(rb_ePGerror, PQerrorMessage(conn)); + rb_iv_set(error, "@connection", self); + rb_exc_raise(error); + } + return Qnil; +} + +/* + * call-seq: + * conn.send_query_prepared( statement_name [, params, result_format ] ) + * -> nil + * + * Execute prepared named statement specified by _statement_name_ + * asynchronously, and returns immediately. + * On failure, it raises a PGError exception. + * + * +params+ is an array of the optional bind parameters for the + * SQL query. Each element of the +params+ array may be either: + * a hash of the form: + * {:value => String (value of bind parameter) + * :format => Fixnum (0 for text, 1 for binary) + * } + * or, it may be a String. If it is a string, that is equivalent to the hash: + * { :value => , :format => 0 } + * + * PostgreSQL bind parameters are represented as $1, $1, $2, etc., + * inside the SQL query. The 0th element of the +params+ array is bound + * to $1, the 1st element is bound to $2, etc. +nil+ is treated as +NULL+. + * + * The optional +result_format+ should be 0 for text results, 1 + * for binary. + */ +static VALUE +pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self) +{ + PGconn *conn = pg_get_pgconn(self); + int result; + VALUE name, params, in_res_fmt; + VALUE param, param_value, param_format; + VALUE param_value_tmp; + VALUE sym_value, sym_format; + VALUE gc_array; + VALUE error; + int i = 0; + int nParams; + char ** paramValues; + int *paramLengths; + int *paramFormats; + int resultFormat; + + rb_scan_args(argc, argv, "12", &name, ¶ms, &in_res_fmt); + Check_Type(name, T_STRING); + + if(NIL_P(params)) { + params = rb_ary_new2(0); + resultFormat = 0; + } + else { + Check_Type(params, T_ARRAY); + } + + if(NIL_P(in_res_fmt)) { + resultFormat = 0; + } + else { + resultFormat = NUM2INT(in_res_fmt); + } + + gc_array = rb_ary_new(); + rb_gc_register_address(&gc_array); + sym_value = ID2SYM(rb_intern("value")); + sym_format = ID2SYM(rb_intern("format")); + nParams = (int)RARRAY_LEN(params); + paramValues = ALLOC_N(char *, nParams); + paramLengths = ALLOC_N(int, nParams); + paramFormats = ALLOC_N(int, nParams); + for(i = 0; i < nParams; i++) { + param = rb_ary_entry(params, i); + if (TYPE(param) == T_HASH) { + param_value_tmp = rb_hash_aref(param, sym_value); + if(param_value_tmp == Qnil) + param_value = param_value_tmp; + else + param_value = rb_obj_as_string(param_value_tmp); + param_format = rb_hash_aref(param, sym_format); + } + else { + if(param == Qnil) + param_value = param; + else + param_value = rb_obj_as_string(param); + param_format = INT2NUM(0); + } + + if(param_value == Qnil) { + paramValues[i] = NULL; + paramLengths[i] = 0; + } + else { + Check_Type(param_value, T_STRING); + /* make sure param_value doesn't get freed by the GC */ + rb_ary_push(gc_array, param_value); + paramValues[i] = StringValuePtr(param_value); + paramLengths[i] = (int)RSTRING_LEN(param_value); + } + + if(param_format == Qnil) + paramFormats[i] = 0; + else + paramFormats[i] = NUM2INT(param_format); + } + + result = PQsendQueryPrepared(conn, StringValuePtr(name), nParams, + (const char * const *)paramValues, paramLengths, paramFormats, + resultFormat); + + rb_gc_unregister_address(&gc_array); + + xfree(paramValues); + xfree(paramLengths); + xfree(paramFormats); + + if(result == 0) { + error = rb_exc_new2(rb_ePGerror, PQerrorMessage(conn)); + rb_iv_set(error, "@connection", self); + rb_exc_raise(error); + } + return Qnil; +} + +/* + * call-seq: + * conn.send_describe_prepared( statement_name ) -> nil + * + * Asynchronously send _command_ to the server. Does not block. + * Use in combination with +conn.get_result+. + */ +static VALUE +pgconn_send_describe_prepared(VALUE self, VALUE stmt_name) +{ + VALUE error; + PGconn *conn = pg_get_pgconn(self); + /* returns 0 on failure */ + if(PQsendDescribePrepared(conn,StringValuePtr(stmt_name)) == 0) { + error = rb_exc_new2(rb_ePGerror, PQerrorMessage(conn)); + rb_iv_set(error, "@connection", self); + rb_exc_raise(error); + } + return Qnil; +} + + +/* + * call-seq: + * conn.send_describe_portal( portal_name ) -> nil + * + * Asynchronously send _command_ to the server. Does not block. + * Use in combination with +conn.get_result+. + */ +static VALUE +pgconn_send_describe_portal(VALUE self, VALUE portal) +{ + VALUE error; + PGconn *conn = pg_get_pgconn(self); + /* returns 0 on failure */ + if(PQsendDescribePortal(conn,StringValuePtr(portal)) == 0) { + error = rb_exc_new2(rb_ePGerror, PQerrorMessage(conn)); + rb_iv_set(error, "@connection", self); + rb_exc_raise(error); + } + return Qnil; +} + + +/* + * call-seq: + * conn.get_result() -> PGresult + * conn.get_result() {|pg_result| block } + * + * Blocks waiting for the next result from a call to + * #send_query (or another asynchronous command), and returns + * it. Returns +nil+ if no more results are available. + * + * Note: call this function repeatedly until it returns +nil+, or else + * you will not be able to issue further commands. + * + * If the optional code block is given, it will be passed result as an argument, + * and the PGresult object will automatically be cleared when the block terminates. + * In this instance, conn.exec returns the value of the block. + */ +static VALUE +pgconn_get_result(VALUE self) +{ + PGconn *conn = pg_get_pgconn(self); + PGresult *result; + VALUE rb_pgresult; + + result = PQgetResult(conn); + if(result == NULL) + return Qnil; + rb_pgresult = pg_new_result(result, conn); + if (rb_block_given_p()) { + return rb_ensure(rb_yield, rb_pgresult, + pg_result_clear, rb_pgresult); + } + return rb_pgresult; +} + +/* + * call-seq: + * conn.consume_input() + * + * If input is available from the server, consume it. + * After calling +consume_input+, you can check +is_busy+ + * or *notifies* to see if the state has changed. + */ +static VALUE +pgconn_consume_input(self) + VALUE self; +{ + VALUE error; + PGconn *conn = pg_get_pgconn(self); + /* returns 0 on error */ + if(PQconsumeInput(conn) == 0) { + error = rb_exc_new2(rb_ePGerror, PQerrorMessage(conn)); + rb_iv_set(error, "@connection", self); + rb_exc_raise(error); + } + return Qnil; +} + +/* + * call-seq: + * conn.is_busy() -> Boolean + * + * Returns +true+ if a command is busy, that is, if + * PQgetResult would block. Otherwise returns +false+. + */ +static VALUE +pgconn_is_busy(self) + VALUE self; +{ + return PQisBusy(pg_get_pgconn(self)) ? Qtrue : Qfalse; +} + +/* + * call-seq: + * conn.setnonblocking(Boolean) -> nil + * + * Sets the nonblocking status of the connection. + * In the blocking state, calls to #send_query + * will block until the message is sent to the server, + * but will not wait for the query results. + * In the nonblocking state, calls to #send_query + * will return an error if the socket is not ready for + * writing. + * Note: This function does not affect #exec, because + * that function doesn't return until the server has + * processed the query and returned the results. + * Returns +nil+. + */ +static VALUE +pgconn_setnonblocking(self, state) + VALUE self, state; +{ + int arg; + VALUE error; + PGconn *conn = pg_get_pgconn(self); + if(state == Qtrue) + arg = 1; + else if (state == Qfalse) + arg = 0; + else + rb_raise(rb_eArgError, "Boolean value expected"); + + if(PQsetnonblocking(conn, arg) == -1) { + error = rb_exc_new2(rb_ePGerror, PQerrorMessage(conn)); + rb_iv_set(error, "@connection", self); + rb_exc_raise(error); + } + return Qnil; +} + + +/* + * call-seq: + * conn.isnonblocking() -> Boolean + * + * Returns +true+ if a command is busy, that is, if + * PQgetResult would block. Otherwise returns +false+. + */ +static VALUE +pgconn_isnonblocking(self) + VALUE self; +{ + return PQisnonblocking(pg_get_pgconn(self)) ? Qtrue : Qfalse; +} + +/* + * call-seq: + * conn.flush() -> Boolean + * + * Attempts to flush any queued output data to the server. + * Returns +true+ if data is successfully flushed, +false+ + * if not (can only return +false+ if connection is + * nonblocking. + * Raises PGError exception if some other failure occurred. + */ +static VALUE +pgconn_flush(self) + VALUE self; +{ + PGconn *conn = pg_get_pgconn(self); + int ret; + VALUE error; + ret = PQflush(conn); + if(ret == -1) { + error = rb_exc_new2(rb_ePGerror, PQerrorMessage(conn)); + rb_iv_set(error, "@connection", self); + rb_exc_raise(error); + } + return (ret) ? Qfalse : Qtrue; +} + +/* + * call-seq: + * conn.cancel() -> String + * + * Requests cancellation of the command currently being + * processed. (Only implemented in PostgreSQL >= 8.0) + * + * Returns +nil+ on success, or a string containing the + * error message if a failure occurs. + */ +static VALUE +pgconn_cancel(VALUE self) +{ +#ifdef HAVE_PQGETCANCEL + char errbuf[256]; + PGcancel *cancel; + VALUE retval; + int ret; + + cancel = PQgetCancel(pg_get_pgconn(self)); + if(cancel == NULL) + rb_raise(rb_ePGerror,"Invalid connection!"); + + ret = PQcancel(cancel, errbuf, 256); + if(ret == 1) + retval = Qnil; + else + retval = rb_str_new2(errbuf); + + PQfreeCancel(cancel); + return retval; +#else + rb_notimplement(); +#endif +} + + +/* + * call-seq: + * conn.notifies() + * + * Returns a hash of the unprocessed notifications. + * If there is no unprocessed notifier, it returns +nil+. + */ +static VALUE +pgconn_notifies(VALUE self) +{ + PGconn* conn = pg_get_pgconn(self); + PGnotify *notification; + VALUE hash; + VALUE sym_relname, sym_be_pid, sym_extra; + VALUE relname, be_pid, extra; + + sym_relname = ID2SYM(rb_intern("relname")); + sym_be_pid = ID2SYM(rb_intern("be_pid")); + sym_extra = ID2SYM(rb_intern("extra")); + + notification = PQnotifies(conn); + if (notification == NULL) { + return Qnil; + } + + hash = rb_hash_new(); + relname = rb_tainted_str_new2(notification->relname); + be_pid = INT2NUM(notification->be_pid); + extra = rb_tainted_str_new2(notification->extra); + + rb_hash_aset(hash, sym_relname, relname); + rb_hash_aset(hash, sym_be_pid, be_pid); + rb_hash_aset(hash, sym_extra, extra); + + PQfreemem(notification); + return hash; +} + + +#ifdef _WIN32 +/* + * Duplicate the sockets from libpq and create temporary CRT FDs + */ +void create_crt_fd(fd_set *os_set, fd_set *crt_set) +{ + int i; + crt_set->fd_count = os_set->fd_count; + for (i = 0; i < os_set->fd_count; i++) { + WSAPROTOCOL_INFO wsa_pi; + /* dupicate the SOCKET */ + int r = WSADuplicateSocket(os_set->fd_array[i], GetCurrentProcessId(), &wsa_pi); + SOCKET s = WSASocket(wsa_pi.iAddressFamily, wsa_pi.iSocketType, wsa_pi.iProtocol, &wsa_pi, 0, 0); + /* create the CRT fd so ruby can get back to the SOCKET */ + int fd = _open_osfhandle(s, O_RDWR|O_BINARY); + os_set->fd_array[i] = s; + crt_set->fd_array[i] = fd; + } +} + +/* + * Clean up the CRT FDs from create_crt_fd() + */ +void cleanup_crt_fd(fd_set *os_set, fd_set *crt_set) +{ + int i; + for (i = 0; i < os_set->fd_count; i++) { + /* cleanup the CRT fd */ + _close(crt_set->fd_array[i]); + /* cleanup the duplicated SOCKET */ + closesocket(os_set->fd_array[i]); + } +} +#endif + +/* + * call-seq: + * conn.wait_for_notify( [ timeout ] ) -> String + * conn.wait_for_notify( [ timeout ] ) { |event, pid| block } + * conn.wait_for_notify( [ timeout ] ) { |event, pid, payload| block } # PostgreSQL 9.0 + * + * Blocks while waiting for notification(s), or until the optional + * _timeout_ is reached, whichever comes first. _timeout_ is + * measured in seconds and can be fractional. + * + * Returns +nil+ if _timeout_ is reached, the name of the NOTIFY + * event otherwise. If used in block form, passes the name of the + * NOTIFY +event+ and the generating +pid+ into the block. + * + * Under PostgreSQL 9.0 and later, if the notification is sent with + * the optional +payload+ string, it will be given to the block as the + * third argument. + * + */ +static VALUE +pgconn_wait_for_notify(int argc, VALUE *argv, VALUE self) +{ + PGconn *conn = pg_get_pgconn( self ); + PGnotify *notification; + int sd = PQsocket( conn ); + int ret; + struct timeval timeout; + struct timeval *ptimeout = NULL; + VALUE timeout_in = Qnil, relname = Qnil, be_pid = Qnil, extra = Qnil; + double timeout_sec; + fd_set sd_rset; +#ifdef _WIN32 + fd_set crt_sd_rset; +#endif + + if ( sd < 0 ) + rb_bug( "PQsocket(conn): couldn't fetch the connection's socket!" ); + + rb_scan_args( argc, argv, "01", &timeout_in ); + + if ( RTEST(timeout_in) ) { + timeout_sec = NUM2DBL( timeout_in ); + timeout.tv_sec = (time_t)timeout_sec; + timeout.tv_usec = (suseconds_t)( (timeout_sec - (long)timeout_sec) * 1e6 ); + ptimeout = &timeout; + } + + /* Check for notifications */ + while ( (notification = PQnotifies(conn)) == NULL ) { + FD_ZERO( &sd_rset ); + FD_SET( sd, &sd_rset ); + +#ifdef _WIN32 + create_crt_fd(&sd_rset, &crt_sd_rset); +#endif + + /* Wait for the socket to become readable before checking again */ + ret = rb_thread_select( sd+1, &sd_rset, NULL, NULL, ptimeout ); + +#ifdef _WIN32 + cleanup_crt_fd(&sd_rset, &crt_sd_rset); +#endif + + if ( ret < 0 ) + rb_sys_fail( 0 ); + + /* Return nil if the select timed out */ + if ( ret == 0 ) return Qnil; + + /* Read the socket */ + if ( (ret = PQconsumeInput(conn)) != 1 ) + rb_raise( rb_ePGerror, "PQconsumeInput == %d: %s", ret, PQerrorMessage(conn) ); + } + + relname = rb_tainted_str_new2( notification->relname ); + ASSOCIATE_INDEX( relname, self ); + be_pid = INT2NUM( notification->be_pid ); +#ifdef HAVE_ST_NOTIFY_EXTRA + if ( *notification->extra ) { + extra = rb_tainted_str_new2( notification->extra ); + ASSOCIATE_INDEX( extra, self ); + } +#endif + PQfreemem( notification ); + + if ( rb_block_given_p() ) + rb_yield_values( 3, relname, be_pid, extra ); + + return relname; +} + + +/* + * call-seq: + * conn.put_copy_data( buffer ) -> Boolean + * + * Transmits _buffer_ as copy data to the server. + * Returns true if the data was sent, false if it was + * not sent (false is only possible if the connection + * is in nonblocking mode, and this command would block). + * + * Raises an exception if an error occurs. + */ +static VALUE +pgconn_put_copy_data(self, buffer) + VALUE self, buffer; +{ + int ret; + VALUE error; + PGconn *conn = pg_get_pgconn(self); + Check_Type(buffer, T_STRING); + + ret = PQputCopyData(conn, RSTRING_PTR(buffer), (int)RSTRING_LEN(buffer)); + if(ret == -1) { + error = rb_exc_new2(rb_ePGerror, PQerrorMessage(conn)); + rb_iv_set(error, "@connection", self); + rb_exc_raise(error); + } + return (ret) ? Qtrue : Qfalse; +} + +/* + * call-seq: + * conn.put_copy_end( [ error_message ] ) -> Boolean + * + * Sends end-of-data indication to the server. + * + * _error_message_ is an optional parameter, and if set, + * forces the COPY command to fail with the string + * _error_message_. + * + * Returns true if the end-of-data was sent, false if it was + * not sent (false is only possible if the connection + * is in nonblocking mode, and this command would block). + */ +static VALUE +pgconn_put_copy_end(int argc, VALUE *argv, VALUE self) +{ + VALUE str; + VALUE error; + int ret; + char *error_message = NULL; + PGconn *conn = pg_get_pgconn(self); + + if (rb_scan_args(argc, argv, "01", &str) == 0) + error_message = NULL; + else + error_message = StringValuePtr(str); + + ret = PQputCopyEnd(conn, error_message); + if(ret == -1) { + error = rb_exc_new2(rb_ePGerror, PQerrorMessage(conn)); + rb_iv_set(error, "@connection", self); + rb_exc_raise(error); + } + return (ret) ? Qtrue : Qfalse; +} + +/* + * call-seq: + * conn.get_copy_data( [ async = false ] ) -> String + * + * Return a string containing one row of data, +nil+ + * if the copy is done, or +false+ if the call would + * block (only possible if _async_ is true). + * + */ +static VALUE +pgconn_get_copy_data(int argc, VALUE *argv, VALUE self ) +{ + VALUE async_in; + VALUE error; + VALUE result_str; + int ret; + int async; + char *buffer; + PGconn *conn = pg_get_pgconn(self); + + if (rb_scan_args(argc, argv, "01", &async_in) == 0) + async = 0; + else + async = (async_in == Qfalse || async_in == Qnil) ? 0 : 1; + + ret = PQgetCopyData(conn, &buffer, async); + if(ret == -2) { /* error */ + error = rb_exc_new2(rb_ePGerror, PQerrorMessage(conn)); + rb_iv_set(error, "@connection", self); + rb_exc_raise(error); + } + if(ret == -1) { /* No data left */ + return Qnil; + } + if(ret == 0) { /* would block */ + return Qfalse; + } + result_str = rb_tainted_str_new(buffer, ret); + PQfreemem(buffer); + return result_str; +} + +/* + * call-seq: + * conn.set_error_verbosity( verbosity ) -> Fixnum + * + * Sets connection's verbosity to _verbosity_ and returns + * the previous setting. Available settings are: + * * PQERRORS_TERSE + * * PQERRORS_DEFAULT + * * PQERRORS_VERBOSE + */ +static VALUE +pgconn_set_error_verbosity(VALUE self, VALUE in_verbosity) +{ + PGconn *conn = pg_get_pgconn(self); + PGVerbosity verbosity = NUM2INT(in_verbosity); + return INT2FIX(PQsetErrorVerbosity(conn, verbosity)); +} + +/* + * call-seq: + * conn.trace( stream ) -> nil + * + * Enables tracing message passing between backend. The + * trace message will be written to the stream _stream_, + * which must implement a method +fileno+ that returns + * a writable file descriptor. + */ +static VALUE +pgconn_trace(VALUE self, VALUE stream) +{ + VALUE fileno; + FILE *new_fp; + int old_fd, new_fd; + VALUE new_file; + + if(rb_respond_to(stream,rb_intern("fileno")) == Qfalse) + rb_raise(rb_eArgError, "stream does not respond to method: fileno"); + + fileno = rb_funcall(stream, rb_intern("fileno"), 0); + if(fileno == Qnil) + rb_raise(rb_eArgError, "can't get file descriptor from stream"); + + /* Duplicate the file descriptor and re-open + * it. Then, make it into a ruby File object + * and assign it to an instance variable. + * This prevents a problem when the File + * object passed to this function is closed + * before the connection object is. */ + old_fd = NUM2INT(fileno); + new_fd = dup(old_fd); + new_fp = fdopen(new_fd, "w"); + + if(new_fp == NULL) + rb_raise(rb_eArgError, "stream is not writable"); + + new_file = rb_funcall(rb_cIO, rb_intern("new"), 1, INT2NUM(new_fd)); + rb_iv_set(self, "@trace_stream", new_file); + + PQtrace(pg_get_pgconn(self), new_fp); + return Qnil; +} + +/* + * call-seq: + * conn.untrace() -> nil + * + * Disables the message tracing. + */ +static VALUE +pgconn_untrace(VALUE self) +{ + VALUE trace_stream; + PQuntrace(pg_get_pgconn(self)); + trace_stream = rb_iv_get(self, "@trace_stream"); + rb_funcall(trace_stream, rb_intern("close"), 0); + rb_iv_set(self, "@trace_stream", Qnil); + return Qnil; +} + + +/* + * Notice callback proxy function -- delegate the callback to the + * currently-registered Ruby notice_receiver object. + */ +static void +notice_receiver_proxy(void *arg, const PGresult *result) +{ + VALUE proc; + VALUE self = (VALUE)arg; + + if ((proc = rb_iv_get(self, "@notice_receiver")) != Qnil) { + rb_funcall(proc, rb_intern("call"), 1, + Data_Wrap_Struct(rb_cPGresult, NULL, NULL, (PGresult*)result)); + } + return; +} + +/* + * call-seq: + * conn.set_notice_receiver {|result| ... } -> Proc + * + * Notice and warning messages generated by the server are not returned + * by the query execution functions, since they do not imply failure of + * the query. Instead they are passed to a notice handling function, and + * execution continues normally after the handler returns. The default + * notice handling function prints the message on stderr, but the + * application can override this behavior by supplying its own handling + * function. + * + * For historical reasons, there are two levels of notice handling, called the + * notice receiver and notice processor. The default behavior is for the notice + * receiver to format the notice and pass a string to the notice processor for + * printing. However, an application that chooses to provide its own notice + * receiver will typically ignore the notice processor layer and just do all + * the work in the notice receiver. + * + * This function takes a new block to act as the handler, which should + * accept a single parameter that will be a PGresult object, and returns + * the Proc object previously set, or +nil+ if it was previously the default. + * + * If you pass no arguments, it will reset the handler to the default. + */ +static VALUE +pgconn_set_notice_receiver(VALUE self) +{ + VALUE proc, old_proc; + PGconn *conn = pg_get_pgconn(self); + + /* If default_notice_receiver is unset, assume that the current + * notice receiver is the default, and save it to a global variable. + * This should not be a problem because the default receiver is + * always the same, so won't vary among connections. + */ + if(default_notice_receiver == NULL) + default_notice_receiver = PQsetNoticeReceiver(conn, NULL, NULL); + + old_proc = rb_iv_get(self, "@notice_receiver"); + if( rb_block_given_p() ) { + proc = rb_block_proc(); + PQsetNoticeReceiver(conn, notice_receiver_proxy, (void *)self); + } else { + /* if no block is given, set back to default */ + proc = Qnil; + PQsetNoticeReceiver(conn, default_notice_receiver, NULL); + } + + rb_iv_set(self, "@notice_receiver", proc); + return old_proc; +} + + +/* + * Notice callback proxy function -- delegate the callback to the + * currently-registered Ruby notice_processor object. + */ +static void +notice_processor_proxy(void *arg, const char *message) +{ + VALUE proc; + VALUE self = (VALUE)arg; + + if ((proc = rb_iv_get(self, "@notice_processor")) != Qnil) { + rb_funcall(proc, rb_intern("call"), 1, rb_tainted_str_new2(message)); + } + return; +} + +/* + * call-seq: + * conn.set_notice_processor {|message| ... } -> Proc + * + * See #set_notice_receiver for the desription of what this and the + * notice_processor methods do. + * + * This function takes a new block to act as the notice processor and returns + * the Proc object previously set, or +nil+ if it was previously the default. + * The block should accept a single PG::Result object. + * + * If you pass no arguments, it will reset the handler to the default. + */ +static VALUE +pgconn_set_notice_processor(VALUE self) +{ + VALUE proc, old_proc; + PGconn *conn = pg_get_pgconn(self); + + /* If default_notice_processor is unset, assume that the current + * notice processor is the default, and save it to a global variable. + * This should not be a problem because the default processor is + * always the same, so won't vary among connections. + */ + if(default_notice_processor == NULL) + default_notice_processor = PQsetNoticeProcessor(conn, NULL, NULL); + + old_proc = rb_iv_get(self, "@notice_processor"); + if( rb_block_given_p() ) { + proc = rb_block_proc(); + PQsetNoticeProcessor(conn, notice_processor_proxy, (void *)self); + } else { + /* if no block is given, set back to default */ + proc = Qnil; + PQsetNoticeProcessor(conn, default_notice_processor, NULL); + } + + rb_iv_set(self, "@notice_processor", proc); + return old_proc; +} + + +/* + * call-seq: + * conn.get_client_encoding() -> String + * + * Returns the client encoding as a String. + */ +static VALUE +pgconn_get_client_encoding(VALUE self) +{ + char *encoding = (char *)pg_encoding_to_char(PQclientEncoding(pg_get_pgconn(self))); + return rb_tainted_str_new2(encoding); +} + + +/* + * call-seq: + * conn.set_client_encoding( encoding ) + * + * Sets the client encoding to the _encoding_ String. + */ +static VALUE +pgconn_set_client_encoding(VALUE self, VALUE str) +{ + PGconn *conn = pg_get_pgconn( self ); + + Check_Type(str, T_STRING); + + if ( (PQsetClientEncoding(conn, StringValuePtr(str))) == -1 ) { + rb_raise(rb_ePGerror, "invalid encoding name: %s",StringValuePtr(str)); + } + + return Qnil; +} + +/* + * call-seq: + * conn.transaction { |conn| ... } -> nil + * + * Executes a +BEGIN+ at the start of the block, + * and a +COMMIT+ at the end of the block, or + * +ROLLBACK+ if any exception occurs. + */ +static VALUE +pgconn_transaction(VALUE self) +{ + PGconn *conn = pg_get_pgconn(self); + PGresult *result; + VALUE rb_pgresult; + int status; + + if (rb_block_given_p()) { + result = PQexec(conn, "BEGIN"); + rb_pgresult = pg_new_result(result, conn); + pg_check_result(self, rb_pgresult); + rb_protect(rb_yield, self, &status); + if(status == 0) { + result = PQexec(conn, "COMMIT"); + rb_pgresult = pg_new_result(result, conn); + pg_check_result(self, rb_pgresult); + } + else { + /* exception occurred, ROLLBACK and re-raise */ + result = PQexec(conn, "ROLLBACK"); + rb_pgresult = pg_new_result(result, conn); + pg_check_result(self, rb_pgresult); + rb_jump_tag(status); + } + + } + else { + /* no block supplied? */ + rb_raise(rb_eArgError, "Must supply block for PG::Connection#transaction"); + } + return Qnil; +} + + +/* + * call-seq: + * PG::Connection.quote_ident( str ) -> String + * conn.quote_ident( str ) -> String + * + * Returns a string that is safe for inclusion in a SQL query as an + * identifier. Note: this is not a quote function for values, but for + * identifiers. + * + * For example, in a typical SQL query: SELECT FOO FROM MYTABLE + * The identifier FOO is folded to lower case, so it actually + * means foo. If you really want to access the case-sensitive + * field name FOO, use this function like + * PG::Connection.quote_ident('FOO'), which will return "FOO" + * (with double-quotes). PostgreSQL will see the double-quotes, and + * it will not fold to lower case. + * + * Similarly, this function also protects against special characters, + * and other things that might allow SQL injection if the identifier + * comes from an untrusted source. + */ +static VALUE +pgconn_s_quote_ident(VALUE self, VALUE in_str) +{ + VALUE ret; + char *str = StringValuePtr(in_str); + /* result size at most NAMEDATALEN*2 plus surrounding + * double-quotes. */ + char buffer[NAMEDATALEN*2+2]; + unsigned int i=0,j=0; + + UNUSED( self ); + + if(strlen(str) >= NAMEDATALEN) { + rb_raise(rb_eArgError, + "Input string is longer than NAMEDATALEN-1 (%d)", + NAMEDATALEN-1); + } + buffer[j++] = '"'; + for(i = 0; i < strlen(str) && str[i]; i++) { + if(str[i] == '"') + buffer[j++] = '"'; + buffer[j++] = str[i]; + } + buffer[j++] = '"'; + ret = rb_str_new(buffer,j); + OBJ_INFECT(ret, in_str); + return ret; +} + + +#ifndef _WIN32 + +/* + * call-seq: + * conn.block( [ timeout ] ) -> Boolean + * + * Blocks until the server is no longer busy, or until the + * optional _timeout_ is reached, whichever comes first. + * _timeout_ is measured in seconds and can be fractional. + * + * Returns +false+ if _timeout_ is reached, +true+ otherwise. + * + * If +true+ is returned, +conn.is_busy+ will return +false+ + * and +conn.get_result+ will not block. + */ +static VALUE +pgconn_block( int argc, VALUE *argv, VALUE self ) { + PGconn *conn = pg_get_pgconn( self ); + int sd = PQsocket( conn ); + int ret; + + /* If WIN32 and Ruby 1.9 do not use rb_thread_select() which sometimes hangs + * and does not wait (nor sleep) any time even if timeout is given. + * Instead use the Winsock events and rb_w32_wait_events(). */ + + struct timeval timeout; + struct timeval *ptimeout = NULL; + fd_set sd_rset; + VALUE timeout_in; + double timeout_sec; + + if ( rb_scan_args(argc, argv, "01", &timeout_in) == 1 ) { + timeout_sec = NUM2DBL( timeout_in ); + timeout.tv_sec = (time_t)timeout_sec; + timeout.tv_usec = (suseconds_t)((timeout_sec - (long)timeout_sec) * 1e6); + ptimeout = &timeout; + } + + /* Check for connection errors (PQisBusy is true on connection errors) */ + if ( PQconsumeInput(conn) == 0 ) + rb_raise( rb_ePGerror, "%s", PQerrorMessage(conn) ); + + while ( PQisBusy(conn) ) { + FD_ZERO( &sd_rset ); + FD_SET( sd, &sd_rset ); + + if ( (ret = rb_thread_select( sd+1, &sd_rset, NULL, NULL, ptimeout )) < 0 ) + rb_sys_fail( "rb_thread_select()" ); /* Raises */ + + /* Return false if there was a timeout argument and the select() timed out */ + if ( ret == 0 && argc ) + return Qfalse; + + /* Check for connection errors (PQisBusy is true on connection errors) */ + if ( PQconsumeInput(conn) == 0 ) + rb_raise( rb_ePGerror, "%s", PQerrorMessage(conn) ); + } + + return Qtrue; +} + + +#else /* _WIN32 */ + +/* + * Win32 PG::Connection#block -- on Windows, use platform-specific strategies to wait for the socket + * instead of rb_thread_select(). + */ + +/* Win32 + Ruby 1.9+ */ +#ifdef HAVE_RUBY_VM_H + +int rb_w32_wait_events( HANDLE *events, int num, DWORD timeout ); + +/* If WIN32 and Ruby 1.9 do not use rb_thread_select() which sometimes hangs + * and does not wait (nor sleep) any time even if timeout is given. + * Instead use the Winsock events and rb_w32_wait_events(). */ + +static VALUE +pgconn_block( int argc, VALUE *argv, VALUE self ) { + PGconn *conn = pg_get_pgconn( self ); + int sd = PQsocket( conn ); + int ret; + + DWORD timeout_milisec = INFINITY; + DWORD wait_ret; + WSAEVENT hEvent; + VALUE timeout_in; + double timeout_sec; + + hEvent = WSACreateEvent(); + + if ( rb_scan_args(argc, argv, "01", &timeout_in) == 1 ) { + timeout_sec = NUM2DBL( timeout_in ); + timeout_milisec = (DWORD)( (timeout_sec - (DWORD)timeout_sec) * 1e3 ); + } + + /* Check for connection errors (PQisBusy is true on connection errors) */ + if( PQconsumeInput(conn) == 0 ) { + WSACloseEvent( hEvent ); + rb_raise( rb_ePGerror, PQerrorMessage(conn) ); + } + + while ( PQisBusy(conn) ) { + if ( WSAEventSelect(sd, hEvent, FD_READ|FD_CLOSE) == SOCKET_ERROR ) { + WSACloseEvent( hEvent ); + rb_raise( rb_ePGerror, "WSAEventSelect socket error: %d", WSAGetLastError() ); + } + + wait_ret = rb_w32_wait_events( &hEvent, 1, 100 ); + + if ( wait_ret == WAIT_TIMEOUT ) { + ret = 0; + } else if ( wait_ret == WAIT_OBJECT_0 ) { + ret = 1; + } else if ( wait_ret == WAIT_FAILED ) { + WSACloseEvent( hEvent ); + rb_raise( rb_ePGerror, "Wait on socket error (WaitForMultipleObjects): %d", GetLastError() ); + } else { + WSACloseEvent( hEvent ); + rb_raise( rb_ePGerror, "Wait on socket abandoned (WaitForMultipleObjects)" ); + } + + /* Return false if there was a timeout argument and the select() timed out */ + if ( ret == 0 && argc ) { + WSACloseEvent( hEvent ); + return Qfalse; + } + + /* Check for connection errors (PQisBusy is true on connection errors) */ + if ( PQconsumeInput(conn) == 0 ) { + WSACloseEvent( hEvent ); + rb_raise( rb_ePGerror, PQerrorMessage(conn) ); + } + } + + WSACloseEvent( hEvent ); + + return Qtrue; +} + +#else /* Win32 + Ruby < 1.9 */ + +static VALUE +pgconn_block( int argc, VALUE *argv, VALUE self ) { + PGconn *conn = pg_get_pgconn( self ); + int sd = PQsocket( conn ); + int ret; + + struct timeval timeout; + struct timeval *ptimeout = NULL; + fd_set sd_rset; + fd_set crt_sd_rset; + VALUE timeout_in; + double timeout_sec; + + /* Always set a timeout, as rb_thread_select() sometimes + * doesn't return when a second ruby thread is running although data + * could be read. So we use timeout-based polling instead. + */ + timeout.tv_sec = 0; + timeout.tv_usec = 10000; /* 10ms */ + ptimeout = &timeout; + + if ( rb_scan_args(argc, argv, "01", &timeout_in) == 1 ) { + timeout_sec = NUM2DBL( timeout_in ); + timeout.tv_sec = (time_t)timeout_sec; + timeout.tv_usec = (suseconds_t)((timeout_sec - (long)timeout_sec) * 1e6); + ptimeout = &timeout; + } + + /* Check for connection errors (PQisBusy is true on connection errors) */ + if( PQconsumeInput(conn) == 0 ) + rb_raise( rb_ePGerror, PQerrorMessage(conn) ); + + while ( PQisBusy(conn) ) { + FD_ZERO( &sd_rset ); + FD_SET( sd, &sd_rset ); + + create_crt_fd( &sd_rset, &crt_sd_rset ); + ret = rb_thread_select( sd+1, &sd_rset, NULL, NULL, ptimeout ); + cleanup_crt_fd( &sd_rset, &crt_sd_rset ); + + /* Return false if there was a timeout argument and the select() timed out */ + if ( ret == 0 && argc ) + return Qfalse; + + /* Check for connection errors (PQisBusy is true on connection errors) */ + if ( PQconsumeInput(conn) == 0 ) + rb_raise( rb_ePGerror, PQerrorMessage(conn) ); + } + + return Qtrue; +} + +#endif /* Ruby 1.9 */ +#endif /* Win32 */ + + +/* + * call-seq: + * conn.get_last_result( ) -> PGresult + * + * This function retrieves all available results + * on the current connection (from previously issued + * asynchronous commands like +send_query()+) and + * returns the last non-NULL result, or +nil+ if no + * results are available. + * + * This function is similar to #get_result + * except that it is designed to get one and only + * one result. + */ +static VALUE +pgconn_get_last_result(VALUE self) +{ + PGconn *conn = pg_get_pgconn(self); + VALUE rb_pgresult = Qnil; + PGresult *cur, *prev; + + + cur = prev = NULL; + while ((cur = PQgetResult(conn)) != NULL) { + int status; + + if (prev) PQclear(prev); + prev = cur; + + status = PQresultStatus(cur); + if (status == PGRES_COPY_OUT || status == PGRES_COPY_IN) + break; + } + + if (prev) { + rb_pgresult = pg_new_result(prev, conn); + pg_check_result(self, rb_pgresult); + } + + return rb_pgresult; +} + + +/* + * call-seq: + * conn.async_exec(sql [, params, result_format ] ) -> PGresult + * conn.async_exec(sql [, params, result_format ] ) {|pg_result| block } + * + * This function has the same behavior as #exec, + * except that it's implemented using asynchronous command + * processing and ruby's +rb_thread_select+ in order to + * allow other threads to process while waiting for the + * server to complete the request. + */ +static VALUE +pgconn_async_exec(int argc, VALUE *argv, VALUE self) +{ + VALUE rb_pgresult = Qnil; + + /* remove any remaining results from the queue */ + pgconn_block( 0, NULL, self ); /* wait for input (without blocking) before reading the last result */ + pgconn_get_last_result( self ); + + pgconn_send_query( argc, argv, self ); + pgconn_block( 0, NULL, self ); + rb_pgresult = pgconn_get_last_result( self ); + + if ( rb_block_given_p() ) { + return rb_ensure( rb_yield, rb_pgresult, pg_result_clear, rb_pgresult ); + } + return rb_pgresult; +} + + +/************************************************************************** + * LARGE OBJECT SUPPORT + **************************************************************************/ + +/* + * call-seq: + * conn.lo_creat( [mode] ) -> Fixnum + * + * Creates a large object with mode _mode_. Returns a large object Oid. + * On failure, it raises PGError exception. + */ +static VALUE +pgconn_locreat(int argc, VALUE *argv, VALUE self) +{ + Oid lo_oid; + int mode; + VALUE nmode; + PGconn *conn = pg_get_pgconn(self); + + if (rb_scan_args(argc, argv, "01", &nmode) == 0) + mode = INV_READ; + else + mode = NUM2INT(nmode); + + lo_oid = lo_creat(conn, mode); + if (lo_oid == 0) + rb_raise(rb_ePGerror, "lo_creat failed"); + + return INT2FIX(lo_oid); +} + +/* + * call-seq: + * conn.lo_create( oid ) -> Fixnum + * + * Creates a large object with oid _oid_. Returns the large object Oid. + * On failure, it raises PGError exception. + */ +static VALUE +pgconn_locreate(VALUE self, VALUE in_lo_oid) +{ + Oid ret, lo_oid; + PGconn *conn = pg_get_pgconn(self); + lo_oid = NUM2INT(in_lo_oid); + + ret = lo_create(conn, lo_oid); + if (ret == InvalidOid) + rb_raise(rb_ePGerror, "lo_create failed"); + + return INT2FIX(ret); +} + +/* + * call-seq: + * conn.lo_import(file) -> Fixnum + * + * Import a file to a large object. Returns a large object Oid. + * + * On failure, it raises a PGError exception. + */ +static VALUE +pgconn_loimport(VALUE self, VALUE filename) +{ + Oid lo_oid; + + PGconn *conn = pg_get_pgconn(self); + + Check_Type(filename, T_STRING); + + lo_oid = lo_import(conn, StringValuePtr(filename)); + if (lo_oid == 0) { + rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn)); + } + return INT2FIX(lo_oid); +} + +/* + * call-seq: + * conn.lo_export( oid, file ) -> nil + * + * Saves a large object of _oid_ to a _file_. + */ +static VALUE +pgconn_loexport(VALUE self, VALUE lo_oid, VALUE filename) +{ + PGconn *conn = pg_get_pgconn(self); + int oid; + Check_Type(filename, T_STRING); + + oid = NUM2INT(lo_oid); + if (oid < 0) { + rb_raise(rb_ePGerror, "invalid large object oid %d",oid); + } + + if (lo_export(conn, oid, StringValuePtr(filename)) < 0) { + rb_raise(rb_ePGerror, "%s", PQerrorMessage(conn)); + } + return Qnil; +} + +/* + * call-seq: + * conn.lo_open( oid, [mode] ) -> Fixnum + * + * Open a large object of _oid_. Returns a large object descriptor + * instance on success. The _mode_ argument specifies the mode for + * the opened large object,which is either +INV_READ+, or +INV_WRITE+. + * + * If _mode_ is omitted, the default is +INV_READ+. + */ +static VALUE +pgconn_loopen(int argc, VALUE *argv, VALUE self) +{ + Oid lo_oid; + int fd, mode; + VALUE nmode, selfid; + PGconn *conn = pg_get_pgconn(self); + + rb_scan_args(argc, argv, "11", &selfid, &nmode); + lo_oid = NUM2INT(selfid); + if(NIL_P(nmode)) + mode = INV_READ; + else + mode = NUM2INT(nmode); + + if((fd = lo_open(conn, lo_oid, mode)) < 0) { + rb_raise(rb_ePGerror, "can't open large object: %s", PQerrorMessage(conn)); + } + return INT2FIX(fd); +} + +/* + * call-seq: + * conn.lo_write( lo_desc, buffer ) -> Fixnum + * + * Writes the string _buffer_ to the large object _lo_desc_. + * Returns the number of bytes written. + */ +static VALUE +pgconn_lowrite(VALUE self, VALUE in_lo_desc, VALUE buffer) +{ + int n; + PGconn *conn = pg_get_pgconn(self); + int fd = NUM2INT(in_lo_desc); + + Check_Type(buffer, T_STRING); + + if( RSTRING_LEN(buffer) < 0) { + rb_raise(rb_ePGerror, "write buffer zero string"); + } + if((n = lo_write(conn, fd, StringValuePtr(buffer), + RSTRING_LEN(buffer))) < 0) { + rb_raise(rb_ePGerror, "lo_write failed: %s", PQerrorMessage(conn)); + } + + return INT2FIX(n); +} + +/* + * call-seq: + * conn.lo_read( lo_desc, len ) -> String + * + * Attempts to read _len_ bytes from large object _lo_desc_, + * returns resulting data. + */ +static VALUE +pgconn_loread(VALUE self, VALUE in_lo_desc, VALUE in_len) +{ + int ret; + PGconn *conn = pg_get_pgconn(self); + int len = NUM2INT(in_len); + int lo_desc = NUM2INT(in_lo_desc); + VALUE str; + char *buffer; + + buffer = ALLOC_N(char, len); + if(buffer == NULL) + rb_raise(rb_eNoMemError, "ALLOC failed!"); + + if (len < 0){ + rb_raise(rb_ePGerror,"nagative length %d given", len); + } + + if((ret = lo_read(conn, lo_desc, buffer, len)) < 0) + rb_raise(rb_ePGerror, "lo_read failed"); + + if(ret == 0) { + xfree(buffer); + return Qnil; + } + + str = rb_tainted_str_new(buffer, ret); + xfree(buffer); + + return str; +} + + +/* + * call-seq: + * conn.lo_lseek( lo_desc, offset, whence ) -> Fixnum + * + * Move the large object pointer _lo_desc_ to offset _offset_. + * Valid values for _whence_ are +SEEK_SET+, +SEEK_CUR+, and +SEEK_END+. + * (Or 0, 1, or 2.) + */ +static VALUE +pgconn_lolseek(VALUE self, VALUE in_lo_desc, VALUE offset, VALUE whence) +{ + PGconn *conn = pg_get_pgconn(self); + int lo_desc = NUM2INT(in_lo_desc); + int ret; + + if((ret = lo_lseek(conn, lo_desc, NUM2INT(offset), NUM2INT(whence))) < 0) { + rb_raise(rb_ePGerror, "lo_lseek failed"); + } + + return INT2FIX(ret); +} + +/* + * call-seq: + * conn.lo_tell( lo_desc ) -> Fixnum + * + * Returns the current position of the large object _lo_desc_. + */ +static VALUE +pgconn_lotell(VALUE self, VALUE in_lo_desc) +{ + int position; + PGconn *conn = pg_get_pgconn(self); + int lo_desc = NUM2INT(in_lo_desc); + + if((position = lo_tell(conn, lo_desc)) < 0) + rb_raise(rb_ePGerror,"lo_tell failed"); + + return INT2FIX(position); +} + +/* + * call-seq: + * conn.lo_truncate( lo_desc, len ) -> nil + * + * Truncates the large object _lo_desc_ to size _len_. + */ +static VALUE +pgconn_lotruncate(VALUE self, VALUE in_lo_desc, VALUE in_len) +{ + PGconn *conn = pg_get_pgconn(self); + int lo_desc = NUM2INT(in_lo_desc); + size_t len = NUM2INT(in_len); + + if(lo_truncate(conn,lo_desc,len) < 0) + rb_raise(rb_ePGerror,"lo_truncate failed"); + + return Qnil; +} + +/* + * call-seq: + * conn.lo_close( lo_desc ) -> nil + * + * Closes the postgres large object of _lo_desc_. + */ +static VALUE +pgconn_loclose(VALUE self, VALUE in_lo_desc) +{ + PGconn *conn = pg_get_pgconn(self); + int lo_desc = NUM2INT(in_lo_desc); + + if(lo_close(conn,lo_desc) < 0) + rb_raise(rb_ePGerror,"lo_close failed"); + + return Qnil; +} + +/* + * call-seq: + * conn.lo_unlink( oid ) -> nil + * + * Unlinks (deletes) the postgres large object of _oid_. + */ +static VALUE +pgconn_lounlink(VALUE self, VALUE in_oid) +{ + PGconn *conn = pg_get_pgconn(self); + int oid = NUM2INT(in_oid); + + if (oid < 0) + rb_raise(rb_ePGerror, "invalid oid %d",oid); + + if(lo_unlink(conn,oid) < 0) + rb_raise(rb_ePGerror,"lo_unlink failed"); + + return Qnil; +} + + +#ifdef M17N_SUPPORTED + +/* + * call-seq: + * conn.internal_encoding -> Encoding + * + * defined in Ruby 1.9 or later. + * + * Returns: + * * an Encoding - client_encoding of the connection as a Ruby Encoding object. + * * nil - the client_encoding is 'SQL_ASCII' + */ +static VALUE +pgconn_internal_encoding(VALUE self) +{ + PGconn *conn = pg_get_pgconn( self ); + rb_encoding *enc = pg_conn_enc_get( conn ); + + if ( enc ) { + return rb_enc_from_encoding( enc ); + } else { + return Qnil; + } +} + +static VALUE pgconn_external_encoding(VALUE self); + +/* + * call-seq: + * conn.internal_encoding = value + * + * A wrapper of #set_client_encoding. + * defined in Ruby 1.9 or later. + * + * +value+ can be one of: + * * an Encoding + * * a String - a name of Encoding + * * +nil+ - sets the client_encoding to SQL_ASCII. + */ +static VALUE +pgconn_internal_encoding_set(VALUE self, VALUE enc) +{ + if (NIL_P(enc)) { + pgconn_set_client_encoding( self, rb_usascii_str_new_cstr("SQL_ASCII") ); + return enc; + } + else if ( TYPE(enc) == T_STRING && strcasecmp("JOHAB", RSTRING_PTR(enc)) == 0 ) { + pgconn_set_client_encoding(self, rb_usascii_str_new_cstr("JOHAB")); + return enc; + } + else { + rb_encoding *rbenc = rb_to_encoding( enc ); + const char *name = pg_get_rb_encoding_as_pg_encoding( rbenc ); + + if ( PQsetClientEncoding(pg_get_pgconn( self ), name) == -1 ) { + VALUE server_encoding = pgconn_external_encoding( self ); + rb_raise( rb_eEncCompatError, "incompatible character encodings: %s and %s", + rb_enc_name(rb_to_encoding(server_encoding)), name ); + } + return enc; + } + + rb_raise( rb_ePGerror, "unknown encoding: %s", RSTRING_PTR(rb_inspect(enc)) ); + + return Qnil; +} + + + +/* + * call-seq: + * conn.external_encoding() -> Encoding + * + * defined in Ruby 1.9 or later. + * - Returns the server_encoding of the connected database as a Ruby Encoding object. + * - Maps 'SQL_ASCII' to ASCII-8BIT. + */ +static VALUE +pgconn_external_encoding(VALUE self) +{ + PGconn *conn = pg_get_pgconn( self ); + VALUE encoding = rb_iv_get( self, "@external_encoding" ); + rb_encoding *enc = NULL; + const char *pg_encname = NULL; + + /* Use cached value if found */ + if ( RTEST(encoding) ) return encoding; + + pg_encname = PQparameterStatus( conn, "server_encoding" ); + enc = pg_get_pg_encname_as_rb_encoding( pg_encname ); + encoding = rb_enc_from_encoding( enc ); + + rb_iv_set( self, "@external_encoding", encoding ); + + return encoding; +} + +#endif /* M17N_SUPPORTED */ + + + +void +init_pg_connection() +{ + rb_cPGconn = rb_define_class_under( rb_mPG, "Connection", rb_cObject ); + rb_include_module(rb_cPGconn, rb_mPGconstants); + + /****** PG::Connection CLASS METHODS ******/ + rb_define_alloc_func( rb_cPGconn, pgconn_s_allocate ); + + SINGLETON_ALIAS(rb_cPGconn, "connect", "new"); + SINGLETON_ALIAS(rb_cPGconn, "open", "new"); + SINGLETON_ALIAS(rb_cPGconn, "setdb", "new"); + SINGLETON_ALIAS(rb_cPGconn, "setdblogin", "new"); + rb_define_singleton_method(rb_cPGconn, "escape_string", pgconn_s_escape, 1); + SINGLETON_ALIAS(rb_cPGconn, "escape", "escape_string"); + rb_define_singleton_method(rb_cPGconn, "escape_bytea", pgconn_s_escape_bytea, 1); + rb_define_singleton_method(rb_cPGconn, "unescape_bytea", pgconn_s_unescape_bytea, 1); + rb_define_singleton_method(rb_cPGconn, "isthreadsafe", pgconn_s_isthreadsafe, 0); + rb_define_singleton_method(rb_cPGconn, "encrypt_password", pgconn_s_encrypt_password, 2); + rb_define_singleton_method(rb_cPGconn, "quote_ident", pgconn_s_quote_ident, 1); + rb_define_singleton_method(rb_cPGconn, "connect_start", pgconn_s_connect_start, -1); + rb_define_singleton_method(rb_cPGconn, "conndefaults", pgconn_s_conndefaults, 0); + + /****** PG::Connection INSTANCE METHODS: Connection Control ******/ + rb_define_method(rb_cPGconn, "initialize", pgconn_init, -1); + rb_define_method(rb_cPGconn, "connect_poll", pgconn_connect_poll, 0); + rb_define_method(rb_cPGconn, "finish", pgconn_finish, 0); + rb_define_method(rb_cPGconn, "finished?", pgconn_finished_p, 0); + rb_define_method(rb_cPGconn, "reset", pgconn_reset, 0); + rb_define_method(rb_cPGconn, "reset_start", pgconn_reset_start, 0); + rb_define_method(rb_cPGconn, "reset_poll", pgconn_reset_poll, 0); + rb_define_method(rb_cPGconn, "conndefaults", pgconn_s_conndefaults, 0); + rb_define_alias(rb_cPGconn, "close", "finish"); + + /****** PG::Connection INSTANCE METHODS: Connection Status ******/ + rb_define_method(rb_cPGconn, "db", pgconn_db, 0); + rb_define_method(rb_cPGconn, "user", pgconn_user, 0); + rb_define_method(rb_cPGconn, "pass", pgconn_pass, 0); + rb_define_method(rb_cPGconn, "host", pgconn_host, 0); + rb_define_method(rb_cPGconn, "port", pgconn_port, 0); + rb_define_method(rb_cPGconn, "tty", pgconn_tty, 0); + rb_define_method(rb_cPGconn, "options", pgconn_options, 0); + rb_define_method(rb_cPGconn, "status", pgconn_status, 0); + rb_define_method(rb_cPGconn, "transaction_status", pgconn_transaction_status, 0); + rb_define_method(rb_cPGconn, "parameter_status", pgconn_parameter_status, 1); + rb_define_method(rb_cPGconn, "protocol_version", pgconn_protocol_version, 0); + rb_define_method(rb_cPGconn, "server_version", pgconn_server_version, 0); + rb_define_method(rb_cPGconn, "error_message", pgconn_error_message, 0); + rb_define_method(rb_cPGconn, "socket", pgconn_socket, 0); + rb_define_method(rb_cPGconn, "backend_pid", pgconn_backend_pid, 0); + rb_define_method(rb_cPGconn, "connection_needs_password", pgconn_connection_needs_password, 0); + rb_define_method(rb_cPGconn, "connection_used_password", pgconn_connection_used_password, 0); + /* rb_define_method(rb_cPGconn, "getssl", pgconn_getssl, 0); */ + + /****** PG::Connection INSTANCE METHODS: Command Execution ******/ + rb_define_method(rb_cPGconn, "exec", pgconn_exec, -1); + rb_define_alias(rb_cPGconn, "query", "exec"); + rb_define_method(rb_cPGconn, "prepare", pgconn_prepare, -1); + rb_define_method(rb_cPGconn, "exec_prepared", pgconn_exec_prepared, -1); + rb_define_method(rb_cPGconn, "describe_prepared", pgconn_describe_prepared, 1); + rb_define_method(rb_cPGconn, "describe_portal", pgconn_describe_portal, 1); + rb_define_method(rb_cPGconn, "make_empty_pgresult", pgconn_make_empty_pgresult, 1); + rb_define_method(rb_cPGconn, "escape_string", pgconn_s_escape, 1); + rb_define_alias(rb_cPGconn, "escape", "escape_string"); + rb_define_method(rb_cPGconn, "escape_bytea", pgconn_s_escape_bytea, 1); + rb_define_method(rb_cPGconn, "unescape_bytea", pgconn_s_unescape_bytea, 1); + + /****** PG::Connection INSTANCE METHODS: Asynchronous Command Processing ******/ + rb_define_method(rb_cPGconn, "send_query", pgconn_send_query, -1); + rb_define_method(rb_cPGconn, "send_prepare", pgconn_send_prepare, -1); + rb_define_method(rb_cPGconn, "send_query_prepared", pgconn_send_query_prepared, -1); + rb_define_method(rb_cPGconn, "send_describe_prepared", pgconn_send_describe_prepared, 1); + rb_define_method(rb_cPGconn, "send_describe_portal", pgconn_send_describe_portal, 1); + rb_define_method(rb_cPGconn, "get_result", pgconn_get_result, 0); + rb_define_method(rb_cPGconn, "consume_input", pgconn_consume_input, 0); + rb_define_method(rb_cPGconn, "is_busy", pgconn_is_busy, 0); + rb_define_method(rb_cPGconn, "setnonblocking", pgconn_setnonblocking, 1); + rb_define_method(rb_cPGconn, "isnonblocking", pgconn_isnonblocking, 0); + rb_define_alias(rb_cPGconn, "nonblocking?", "isnonblocking"); + rb_define_method(rb_cPGconn, "flush", pgconn_flush, 0); + + /****** PG::Connection INSTANCE METHODS: Cancelling Queries in Progress ******/ + rb_define_method(rb_cPGconn, "cancel", pgconn_cancel, 0); + + /****** PG::Connection INSTANCE METHODS: NOTIFY ******/ + rb_define_method(rb_cPGconn, "notifies", pgconn_notifies, 0); + + /****** PG::Connection INSTANCE METHODS: COPY ******/ + rb_define_method(rb_cPGconn, "put_copy_data", pgconn_put_copy_data, 1); + rb_define_method(rb_cPGconn, "put_copy_end", pgconn_put_copy_end, -1); + rb_define_method(rb_cPGconn, "get_copy_data", pgconn_get_copy_data, -1); + + /****** PG::Connection INSTANCE METHODS: Control Functions ******/ + rb_define_method(rb_cPGconn, "set_error_verbosity", pgconn_set_error_verbosity, 1); + rb_define_method(rb_cPGconn, "trace", pgconn_trace, 1); + rb_define_method(rb_cPGconn, "untrace", pgconn_untrace, 0); + + /****** PG::Connection INSTANCE METHODS: Notice Processing ******/ + rb_define_method(rb_cPGconn, "set_notice_receiver", pgconn_set_notice_receiver, 0); + rb_define_method(rb_cPGconn, "set_notice_processor", pgconn_set_notice_processor, 0); + + /****** PG::Connection INSTANCE METHODS: Other ******/ + rb_define_method(rb_cPGconn, "get_client_encoding", pgconn_get_client_encoding, 0); + rb_define_method(rb_cPGconn, "set_client_encoding", pgconn_set_client_encoding, 1); + rb_define_alias(rb_cPGconn, "client_encoding=", "set_client_encoding"); + rb_define_method(rb_cPGconn, "transaction", pgconn_transaction, 0); + rb_define_method(rb_cPGconn, "block", pgconn_block, -1); + rb_define_method(rb_cPGconn, "wait_for_notify", pgconn_wait_for_notify, -1); + rb_define_alias(rb_cPGconn, "notifies_wait", "wait_for_notify"); + rb_define_method(rb_cPGconn, "quote_ident", pgconn_s_quote_ident, 1); + rb_define_method(rb_cPGconn, "async_exec", pgconn_async_exec, -1); + rb_define_alias(rb_cPGconn, "async_query", "async_exec"); + rb_define_method(rb_cPGconn, "get_last_result", pgconn_get_last_result, 0); + + /****** PG::Connection INSTANCE METHODS: Large Object Support ******/ + rb_define_method(rb_cPGconn, "lo_creat", pgconn_locreat, -1); + rb_define_alias(rb_cPGconn, "locreat", "lo_creat"); + rb_define_method(rb_cPGconn, "lo_create", pgconn_locreate, 1); + rb_define_alias(rb_cPGconn, "locreate", "lo_create"); + rb_define_method(rb_cPGconn, "lo_import", pgconn_loimport, 1); + rb_define_alias(rb_cPGconn, "loimport", "lo_import"); + rb_define_method(rb_cPGconn, "lo_export", pgconn_loexport, 2); + rb_define_alias(rb_cPGconn, "loexport", "lo_export"); + rb_define_method(rb_cPGconn, "lo_open", pgconn_loopen, -1); + rb_define_alias(rb_cPGconn, "loopen", "lo_open"); + rb_define_method(rb_cPGconn, "lo_write",pgconn_lowrite, 2); + rb_define_alias(rb_cPGconn, "lowrite", "lo_write"); + rb_define_method(rb_cPGconn, "lo_read",pgconn_loread, 2); + rb_define_alias(rb_cPGconn, "loread", "lo_read"); + rb_define_method(rb_cPGconn, "lo_lseek",pgconn_lolseek, 3); + rb_define_alias(rb_cPGconn, "lolseek", "lo_lseek"); + rb_define_alias(rb_cPGconn, "lo_seek", "lo_lseek"); + rb_define_alias(rb_cPGconn, "loseek", "lo_lseek"); + rb_define_method(rb_cPGconn, "lo_tell",pgconn_lotell, 1); + rb_define_alias(rb_cPGconn, "lotell", "lo_tell"); + rb_define_method(rb_cPGconn, "lo_truncate", pgconn_lotruncate, 2); + rb_define_alias(rb_cPGconn, "lotruncate", "lo_truncate"); + rb_define_method(rb_cPGconn, "lo_close",pgconn_loclose, 1); + rb_define_alias(rb_cPGconn, "loclose", "lo_close"); + rb_define_method(rb_cPGconn, "lo_unlink", pgconn_lounlink, 1); + rb_define_alias(rb_cPGconn, "lounlink", "lo_unlink"); + +#ifdef M17N_SUPPORTED + rb_define_method(rb_cPGconn, "internal_encoding", pgconn_internal_encoding, 0); + rb_define_method(rb_cPGconn, "internal_encoding=", pgconn_internal_encoding_set, 1); + rb_define_method(rb_cPGconn, "external_encoding", pgconn_external_encoding, 0); +#endif /* M17N_SUPPORTED */ + +} + + diff --git a/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/ext/pg_result.c b/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/ext/pg_result.c new file mode 100644 index 000000000000..d39c32b55e50 --- /dev/null +++ b/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/ext/pg_result.c @@ -0,0 +1,905 @@ +/* + * pg_result.c - PG::Result class extension + * $Id$ + * + */ + +#include "pg.h" + + +VALUE rb_cPGresult; + +static void pgresult_gc_free( PGresult * ); +static PGresult* pgresult_get( VALUE ); + + +/* + * Global functions + */ + +/* + * Result constructor + */ +VALUE +pg_new_result(PGresult *result, PGconn *conn) +{ + VALUE val = Data_Wrap_Struct(rb_cPGresult, NULL, pgresult_gc_free, result); +#ifdef M17N_SUPPORTED + rb_encoding *enc = pg_conn_enc_get( conn ); + ENCODING_SET( val, rb_enc_to_index(enc) ); +#endif + + return val; +} + +/* + * Raises appropriate exception if PGresult is + * in a bad state. + */ +void +pg_check_result(VALUE rb_pgconn, VALUE rb_pgresult) +{ + VALUE error, exception; + PGconn *conn = pg_get_pgconn(rb_pgconn); + PGresult *result; +#ifdef M17N_SUPPORTED + rb_encoding *enc = pg_conn_enc_get( conn ); +#endif + + Data_Get_Struct(rb_pgresult, PGresult, result); + + if(result == NULL) + { + error = rb_str_new2( PQerrorMessage(conn) ); + } + else + { + switch (PQresultStatus(result)) + { + case PGRES_TUPLES_OK: + case PGRES_COPY_OUT: + case PGRES_COPY_IN: + case PGRES_EMPTY_QUERY: + case PGRES_COMMAND_OK: + return; + case PGRES_BAD_RESPONSE: + case PGRES_FATAL_ERROR: + case PGRES_NONFATAL_ERROR: + error = rb_str_new2( PQresultErrorMessage(result) ); + break; + default: + error = rb_str_new2( "internal error : unknown result status." ); + } + } + +#ifdef M17N_SUPPORTED + rb_enc_set_index( error, rb_enc_to_index(enc) ); +#endif + exception = rb_exc_new3( rb_ePGerror, error ); + rb_iv_set( exception, "@connection", rb_pgconn ); + rb_iv_set( exception, "@result", rb_pgresult ); + rb_exc_raise( exception ); + + return; +} + + +/* + * :TODO: This shouldn't be a global function, but it needs to be as long as pg_new_result + * doesn't handle blocks, check results, etc. Once connection and result are disentangled + * a bit more, I can make this a static pgresult_clear() again. + */ + +/* + * call-seq: + * res.clear() -> nil + * + * Clears the PGresult object as the result of the query. + */ +VALUE +pg_result_clear(VALUE self) +{ + PQclear(pgresult_get(self)); + DATA_PTR(self) = NULL; + return Qnil; +} + + + +/* + * DATA pointer functions + */ + +/* + * GC Free function + */ +static void +pgresult_gc_free( PGresult *result ) +{ + if(result != NULL) + PQclear(result); +} + +/* + * Fetch the data pointer for the result object + */ +static PGresult* +pgresult_get(VALUE self) +{ + PGresult *result; + Data_Get_Struct(self, PGresult, result); + if (result == NULL) rb_raise(rb_ePGerror, "result has been cleared"); + return result; +} + + +/******************************************************************** + * + * Document-class: PGresult + * + * The class to represent the query result tuples (rows). + * An instance of this class is created as the result of every query. + * You may need to invoke the #clear method of the instance when finished with + * the result for better memory performance. + * + * Example: + * require 'pg' + * conn = PGconn.open(:dbname => 'test') + * res = conn.exec('SELECT 1 AS a, 2 AS b, NULL AS c') + * res.getvalue(0,0) # '1' + * res[0]['b'] # '2' + * res[0]['c'] # nil + * + */ + +/************************************************************************** + * PGresult INSTANCE METHODS + **************************************************************************/ + +/* + * call-seq: + * res.result_status() -> Fixnum + * + * Returns the status of the query. The status value is one of: + * * +PGRES_EMPTY_QUERY+ + * * +PGRES_COMMAND_OK+ + * * +PGRES_TUPLES_OK+ + * * +PGRES_COPY_OUT+ + * * +PGRES_COPY_IN+ + * * +PGRES_BAD_RESPONSE+ + * * +PGRES_NONFATAL_ERROR+ + * * +PGRES_FATAL_ERROR+ + */ +static VALUE +pgresult_result_status(VALUE self) +{ + return INT2FIX(PQresultStatus(pgresult_get(self))); +} + +/* + * call-seq: + * res.res_status( status ) -> String + * + * Returns the string representation of status +status+. + * +*/ +static VALUE +pgresult_res_status(VALUE self, VALUE status) +{ + VALUE ret = rb_tainted_str_new2(PQresStatus(NUM2INT(status))); + ASSOCIATE_INDEX(ret, self); + return ret; +} + +/* + * call-seq: + * res.error_message() -> String + * + * Returns the error message of the command as a string. + */ +static VALUE +pgresult_error_message(VALUE self) +{ + VALUE ret = rb_tainted_str_new2(PQresultErrorMessage(pgresult_get(self))); + ASSOCIATE_INDEX(ret, self); + return ret; +} + +/* + * call-seq: + * res.error_field(fieldcode) -> String + * + * Returns the individual field of an error. + * + * +fieldcode+ is one of: + * * +PG_DIAG_SEVERITY+ + * * +PG_DIAG_SQLSTATE+ + * * +PG_DIAG_MESSAGE_PRIMARY+ + * * +PG_DIAG_MESSAGE_DETAIL+ + * * +PG_DIAG_MESSAGE_HINT+ + * * +PG_DIAG_STATEMENT_POSITION+ + * * +PG_DIAG_INTERNAL_POSITION+ + * * +PG_DIAG_INTERNAL_QUERY+ + * * +PG_DIAG_CONTEXT+ + * * +PG_DIAG_SOURCE_FILE+ + * * +PG_DIAG_SOURCE_LINE+ + * * +PG_DIAG_SOURCE_FUNCTION+ + * + * An example: + * + * begin + * conn.exec( "SELECT * FROM nonexistant_table" ) + * rescue PGError => err + * p [ + * result.error_field( PGresult::PG_DIAG_SEVERITY ), + * result.error_field( PGresult::PG_DIAG_SQLSTATE ), + * result.error_field( PGresult::PG_DIAG_MESSAGE_PRIMARY ), + * result.error_field( PGresult::PG_DIAG_MESSAGE_DETAIL ), + * result.error_field( PGresult::PG_DIAG_MESSAGE_HINT ), + * result.error_field( PGresult::PG_DIAG_STATEMENT_POSITION ), + * result.error_field( PGresult::PG_DIAG_INTERNAL_POSITION ), + * result.error_field( PGresult::PG_DIAG_INTERNAL_QUERY ), + * result.error_field( PGresult::PG_DIAG_CONTEXT ), + * result.error_field( PGresult::PG_DIAG_SOURCE_FILE ), + * result.error_field( PGresult::PG_DIAG_SOURCE_LINE ), + * result.error_field( PGresult::PG_DIAG_SOURCE_FUNCTION ), + * ] + * end + * + * Outputs: + * + * ["ERROR", "42P01", "relation \"nonexistant_table\" does not exist", nil, nil, + * "15", nil, nil, nil, "path/to/parse_relation.c", "857", "parserOpenTable"] + */ +static VALUE +pgresult_error_field(VALUE self, VALUE field) +{ + PGresult *result = pgresult_get( self ); + int fieldcode = NUM2INT( field ); + char * fieldstr = PQresultErrorField( result, fieldcode ); + VALUE ret = Qnil; + + if ( fieldstr ) { + ret = rb_tainted_str_new2( fieldstr ); + ASSOCIATE_INDEX( ret, self ); + } + + return ret; +} + +/* + * call-seq: + * res.ntuples() -> Fixnum + * + * Returns the number of tuples in the query result. + */ +static VALUE +pgresult_ntuples(VALUE self) +{ + return INT2FIX(PQntuples(pgresult_get(self))); +} + +/* + * call-seq: + * res.nfields() -> Fixnum + * + * Returns the number of columns in the query result. + */ +static VALUE +pgresult_nfields(VALUE self) +{ + return INT2NUM(PQnfields(pgresult_get(self))); +} + +/* + * call-seq: + * res.fname( index ) -> String + * + * Returns the name of the column corresponding to _index_. + */ +static VALUE +pgresult_fname(VALUE self, VALUE index) +{ + VALUE fname; + PGresult *result; + int i = NUM2INT(index); + + result = pgresult_get(self); + if (i < 0 || i >= PQnfields(result)) { + rb_raise(rb_eArgError,"invalid field number %d", i); + } + fname = rb_tainted_str_new2(PQfname(result, i)); + ASSOCIATE_INDEX(fname, self); + return fname; +} + +/* + * call-seq: + * res.fnumber( name ) -> Fixnum + * + * Returns the index of the field specified by the string _name_. + * + * Raises an ArgumentError if the specified _name_ isn't one of the field names; + * raises a TypeError if _name_ is not a String. + */ +static VALUE +pgresult_fnumber(VALUE self, VALUE name) +{ + int n; + + Check_Type(name, T_STRING); + + n = PQfnumber(pgresult_get(self), StringValuePtr(name)); + if (n == -1) { + rb_raise(rb_eArgError,"Unknown field: %s", StringValuePtr(name)); + } + return INT2FIX(n); +} + +/* + * call-seq: + * res.ftable( column_number ) -> Fixnum + * + * Returns the Oid of the table from which the column _column_number_ + * was fetched. + * + * Raises ArgumentError if _column_number_ is out of range or if + * the Oid is undefined for that column. + */ +static VALUE +pgresult_ftable(VALUE self, VALUE column_number) +{ + Oid n ; + int col_number = NUM2INT(column_number); + PGresult *pgresult = pgresult_get(self); + + if( col_number < 0 || col_number >= PQnfields(pgresult)) + rb_raise(rb_eArgError,"Invalid column index: %d", col_number); + + n = PQftable(pgresult, col_number); + return INT2FIX(n); +} + +/* + * call-seq: + * res.ftablecol( column_number ) -> Fixnum + * + * Returns the column number (within its table) of the table from + * which the column _column_number_ is made up. + * + * Raises ArgumentError if _column_number_ is out of range or if + * the column number from its table is undefined for that column. + */ +static VALUE +pgresult_ftablecol(VALUE self, VALUE column_number) +{ + int col_number = NUM2INT(column_number); + PGresult *pgresult = pgresult_get(self); + + int n; + + if( col_number < 0 || col_number >= PQnfields(pgresult)) + rb_raise(rb_eArgError,"Invalid column index: %d", col_number); + + n = PQftablecol(pgresult, col_number); + return INT2FIX(n); +} + +/* + * call-seq: + * res.fformat( column_number ) -> Fixnum + * + * Returns the format (0 for text, 1 for binary) of column + * _column_number_. + * + * Raises ArgumentError if _column_number_ is out of range. + */ +static VALUE +pgresult_fformat(VALUE self, VALUE column_number) +{ + PGresult *result = pgresult_get(self); + int fnumber = NUM2INT(column_number); + if (fnumber < 0 || fnumber >= PQnfields(result)) { + rb_raise(rb_eArgError, "Column number is out of range: %d", + fnumber); + } + return INT2FIX(PQfformat(result, fnumber)); +} + +/* + * call-seq: + * res.ftype( column_number ) + * + * Returns the data type associated with _column_number_. + * + * The integer returned is the internal +OID+ number (in PostgreSQL) + * of the type. To get a human-readable value for the type, use the + * returned OID and the field's #fmod value with the format_type() SQL + * function: + * + * # Get the type of the second column of the result 'res' + * typename = conn. + * exec( "SELECT format_type($1,$2)", [res.ftype(1), res.fmod(1)] ). + * getvalue( 0, 0 ) + * + * Raises an ArgumentError if _column_number_ is out of range. + */ +static VALUE +pgresult_ftype(VALUE self, VALUE index) +{ + PGresult* result = pgresult_get(self); + int i = NUM2INT(index); + if (i < 0 || i >= PQnfields(result)) { + rb_raise(rb_eArgError, "invalid field number %d", i); + } + return INT2NUM(PQftype(result, i)); +} + +/* + * call-seq: + * res.fmod( column_number ) + * + * Returns the type modifier associated with column _column_number_. See + * the #ftype method for an example of how to use this. + * + * Raises an ArgumentError if _column_number_ is out of range. + */ +static VALUE +pgresult_fmod(VALUE self, VALUE column_number) +{ + PGresult *result = pgresult_get(self); + int fnumber = NUM2INT(column_number); + int modifier; + if (fnumber < 0 || fnumber >= PQnfields(result)) { + rb_raise(rb_eArgError, "Column number is out of range: %d", + fnumber); + } + modifier = PQfmod(result,fnumber); + + return INT2NUM(modifier); +} + +/* + * call-seq: + * res.fsize( index ) + * + * Returns the size of the field type in bytes. Returns -1 if the field is variable sized. + * + * res = conn.exec("SELECT myInt, myVarChar50 FROM foo") + * res.size(0) => 4 + * res.size(1) => -1 + */ +static VALUE +pgresult_fsize(VALUE self, VALUE index) +{ + PGresult *result; + int i = NUM2INT(index); + + result = pgresult_get(self); + if (i < 0 || i >= PQnfields(result)) { + rb_raise(rb_eArgError,"invalid field number %d", i); + } + return INT2NUM(PQfsize(result, i)); +} + +/* + * call-seq: + * res.getvalue( tup_num, field_num ) + * + * Returns the value in tuple number _tup_num_, field _field_num_, + * or +nil+ if the field is +NULL+. + */ +static VALUE +pgresult_getvalue(VALUE self, VALUE tup_num, VALUE field_num) +{ + VALUE ret; + PGresult *result; + int i = NUM2INT(tup_num); + int j = NUM2INT(field_num); + + result = pgresult_get(self); + if(i < 0 || i >= PQntuples(result)) { + rb_raise(rb_eArgError,"invalid tuple number %d", i); + } + if(j < 0 || j >= PQnfields(result)) { + rb_raise(rb_eArgError,"invalid field number %d", j); + } + if(PQgetisnull(result, i, j)) + return Qnil; + ret = rb_tainted_str_new(PQgetvalue(result, i, j), + PQgetlength(result, i, j)); + ASSOCIATE_INDEX(ret, self); + return ret; +} + +/* + * call-seq: + * res.getisnull(tuple_position, field_position) -> boolean + * + * Returns +true+ if the specified value is +nil+; +false+ otherwise. + */ +static VALUE +pgresult_getisnull(VALUE self, VALUE tup_num, VALUE field_num) +{ + PGresult *result; + int i = NUM2INT(tup_num); + int j = NUM2INT(field_num); + + result = pgresult_get(self); + if (i < 0 || i >= PQntuples(result)) { + rb_raise(rb_eArgError,"invalid tuple number %d", i); + } + if (j < 0 || j >= PQnfields(result)) { + rb_raise(rb_eArgError,"invalid field number %d", j); + } + return PQgetisnull(result, i, j) ? Qtrue : Qfalse; +} + +/* + * call-seq: + * res.getlength( tup_num, field_num ) -> Fixnum + * + * Returns the (String) length of the field in bytes. + * + * Equivalent to res.value(tup_num,field_num).length. + */ +static VALUE +pgresult_getlength(VALUE self, VALUE tup_num, VALUE field_num) +{ + PGresult *result; + int i = NUM2INT(tup_num); + int j = NUM2INT(field_num); + + result = pgresult_get(self); + if (i < 0 || i >= PQntuples(result)) { + rb_raise(rb_eArgError,"invalid tuple number %d", i); + } + if (j < 0 || j >= PQnfields(result)) { + rb_raise(rb_eArgError,"invalid field number %d", j); + } + return INT2FIX(PQgetlength(result, i, j)); +} + +/* + * call-seq: + * res.nparams() -> Fixnum + * + * Returns the number of parameters of a prepared statement. + * Only useful for the result returned by conn.describePrepared + */ +static VALUE +pgresult_nparams(VALUE self) +{ + PGresult *result; + + result = pgresult_get(self); + return INT2FIX(PQnparams(result)); +} + +/* + * call-seq: + * res.paramtype( param_number ) -> Oid + * + * Returns the Oid of the data type of parameter _param_number_. + * Only useful for the result returned by conn.describePrepared + */ +static VALUE +pgresult_paramtype(VALUE self, VALUE param_number) +{ + PGresult *result; + + result = pgresult_get(self); + return INT2FIX(PQparamtype(result,NUM2INT(param_number))); +} + +/* + * call-seq: + * res.cmd_status() -> String + * + * Returns the status string of the last query command. + */ +static VALUE +pgresult_cmd_status(VALUE self) +{ + VALUE ret = rb_tainted_str_new2(PQcmdStatus(pgresult_get(self))); + ASSOCIATE_INDEX(ret, self); + return ret; +} + +/* + * call-seq: + * res.cmd_tuples() -> Fixnum + * + * Returns the number of tuples (rows) affected by the SQL command. + * + * If the SQL command that generated the PGresult was not one of: + * * +INSERT+ + * * +UPDATE+ + * * +DELETE+ + * * +MOVE+ + * * +FETCH+ + * or if no tuples were affected, 0 is returned. + */ +static VALUE +pgresult_cmd_tuples(VALUE self) +{ + long n; + n = strtol(PQcmdTuples(pgresult_get(self)),NULL, 10); + return INT2NUM(n); +} + +/* + * call-seq: + * res.oid_value() -> Fixnum + * + * Returns the +oid+ of the inserted row if applicable, + * otherwise +nil+. + */ +static VALUE +pgresult_oid_value(VALUE self) +{ + Oid n = PQoidValue(pgresult_get(self)); + if (n == InvalidOid) + return Qnil; + else + return INT2FIX(n); +} + +/* Utility methods not in libpq */ + +/* + * call-seq: + * res[ n ] -> Hash + * + * Returns tuple _n_ as a hash. + */ +static VALUE +pgresult_aref(VALUE self, VALUE index) +{ + PGresult *result = pgresult_get(self); + int tuple_num = NUM2INT(index); + int field_num; + VALUE fname,val; + VALUE tuple; + + if ( tuple_num < 0 || tuple_num >= PQntuples(result) ) + rb_raise( rb_eIndexError, "Index %d is out of range", tuple_num ); + + tuple = rb_hash_new(); + for ( field_num = 0; field_num < PQnfields(result); field_num++ ) { + fname = rb_tainted_str_new2( PQfname(result,field_num) ); + ASSOCIATE_INDEX(fname, self); + if ( PQgetisnull(result, tuple_num, field_num) ) { + rb_hash_aset( tuple, fname, Qnil ); + } + else { + val = rb_tainted_str_new( PQgetvalue(result, tuple_num, field_num ), + PQgetlength(result, tuple_num, field_num) ); + +#ifdef M17N_SUPPORTED + /* associate client encoding for text format only */ + if ( 0 == PQfformat(result, field_num) ) { + ASSOCIATE_INDEX( val, self ); + } else { + rb_enc_associate( val, rb_ascii8bit_encoding() ); + } +#endif + + rb_hash_aset( tuple, fname, val ); + } + } + return tuple; +} + + +/* + * call-seq: + * res.values -> Array + * + * Returns all tuples as an array of arrays. + */ +static VALUE +pgresult_values(VALUE self) +{ + PGresult* result = (PGresult*) pgresult_get(self); + int row; + int field; + int num_rows = PQntuples(result); + int num_fields = PQnfields(result); + VALUE ary = rb_ary_new2(num_rows); + + for ( row = 0; row < num_rows; row++ ) { + /* create new row */ + VALUE new_row = rb_ary_new2(num_fields); + + /* add to return array */ + rb_ary_store( ary, row, new_row ); + + /* populate it */ + for ( field = 0; field < num_fields; field++ ) { + if ( PQgetisnull(result, row, field) ) { + rb_ary_store( new_row, field, Qnil ); + } + else { + VALUE val = rb_tainted_str_new( PQgetvalue(result, row, field), + PQgetlength(result, row, field) ); + +#ifdef M17N_SUPPORTED + /* associate client encoding for text format only */ + if ( 0 == PQfformat(result, field) ) { + ASSOCIATE_INDEX( val, self ); + } else { + rb_enc_associate( val, rb_ascii8bit_encoding() ); + } +#endif + + rb_ary_store( new_row, field, val ); + } + } + } + return ary; +} + + +/* + * Make a Ruby array out of the encoded values from the specified + * column in the given result. + */ +static VALUE +make_column_result_array( VALUE self, int col ) +{ + PGresult *result = pgresult_get( self ); + int row = PQntuples( result ); + VALUE ary = rb_ary_new2( row ); + VALUE val = Qnil; + + if ( col >= PQnfields(result) ) + rb_raise( rb_eIndexError, "no column %d in result", col ); + + while ( row-- ) { + val = rb_tainted_str_new( PQgetvalue(result, row, col), + PQgetlength(result, row, col) ); + +#ifdef M17N_SUPPORTED + /* associate client encoding for text format only */ + if ( 0 == PQfformat(result, col) ) { + ASSOCIATE_INDEX( val, self ); + } else { + rb_enc_associate( val, rb_ascii8bit_encoding() ); + } +#endif + + rb_ary_store( ary, row, val ); + } + + return ary; +} + + +/* + * call-seq: + * res.column_values( n ) -> array + * + * Returns an Array of the values from the nth column of each + * tuple in the result. + * + */ +static VALUE +pgresult_column_values(VALUE self, VALUE index) +{ + int col = NUM2INT( index ); + return make_column_result_array( self, col ); +} + + +/* + * call-seq: + * res.field_values( field ) -> array + * + * Returns an Array of the values from the given _field_ of each tuple in the result. + * + */ +static VALUE +pgresult_field_values( VALUE self, VALUE field ) +{ + PGresult *result = pgresult_get( self ); + const char *fieldname = RSTRING_PTR( field ); + int fnum = PQfnumber( result, fieldname ); + + if ( fnum < 0 ) + rb_raise( rb_eIndexError, "no such field '%s' in result", fieldname ); + + return make_column_result_array( self, fnum ); +} + + +/* + * call-seq: + * res.each{ |tuple| ... } + * + * Invokes block for each tuple in the result set. + */ +static VALUE +pgresult_each(VALUE self) +{ + PGresult *result = pgresult_get(self); + int tuple_num; + + for(tuple_num = 0; tuple_num < PQntuples(result); tuple_num++) { + rb_yield(pgresult_aref(self, INT2NUM(tuple_num))); + } + return self; +} + +/* + * call-seq: + * res.fields() -> Array + * + * Returns an array of Strings representing the names of the fields in the result. + */ +static VALUE +pgresult_fields(VALUE self) +{ + PGresult *result; + VALUE ary; + int n, i; + + result = pgresult_get(self); + n = PQnfields(result); + ary = rb_ary_new2(n); + for (i=0;i + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/ext/vc/pg_19/pg_19.vcproj b/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/ext/vc/pg_19/pg_19.vcproj new file mode 100644 index 000000000000..13666b53e2c0 --- /dev/null +++ b/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/ext/vc/pg_19/pg_19.vcproj @@ -0,0 +1,209 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/lib/1.8/pg_ext.so b/lib/gemcache/ruby/1.9.1/arch-old/win32/pg-0.13.2-x86-mingw32/lib/1.8/pg_ext.so new file mode 100644 index 0000000000000000000000000000000000000000..c4bb33c3a776c5d300d333276e0c0a4618bf0451 GIT binary patch literal 1738240 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

Fs? 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

(w%bA9e9Uc+X9= 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