cipherstash-pg 1.0.0.beta.4-x86_64-darwin
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.appveyor.yml +42 -0
- data/.gems +6 -0
- data/.gemtest +0 -0
- data/.github/workflows/binary-gems.yml +117 -0
- data/.github/workflows/source-gem.yml +137 -0
- data/.gitignore +19 -0
- data/.hgsigs +34 -0
- data/.hgtags +41 -0
- data/.irbrc +23 -0
- data/.pryrc +23 -0
- data/.tm_properties +21 -0
- data/.travis.yml +49 -0
- data/BSDL +22 -0
- data/Contributors.rdoc +46 -0
- data/Gemfile +14 -0
- data/Gemfile.lock +45 -0
- data/History.md +804 -0
- data/LICENSE +56 -0
- data/Manifest.txt +72 -0
- data/POSTGRES +23 -0
- data/README-OS_X.rdoc +68 -0
- data/README-Windows.rdoc +56 -0
- data/README.ja.md +266 -0
- data/README.md +272 -0
- data/Rakefile +76 -0
- data/Rakefile.cross +298 -0
- data/certs/ged.pem +24 -0
- data/certs/larskanis-2022.pem +26 -0
- data/certs/larskanis-2023.pem +24 -0
- data/cipherstash-pg.gemspec +0 -0
- data/lib/2.7/pg_ext.bundle +0 -0
- data/lib/3.0/pg_ext.bundle +0 -0
- data/lib/3.1/pg_ext.bundle +0 -0
- data/lib/3.2/pg_ext.bundle +0 -0
- data/lib/cipherstash-pg/basic_type_map_based_on_result.rb +11 -0
- data/lib/cipherstash-pg/basic_type_map_for_queries.rb +113 -0
- data/lib/cipherstash-pg/basic_type_map_for_results.rb +30 -0
- data/lib/cipherstash-pg/basic_type_registry.rb +206 -0
- data/lib/cipherstash-pg/binary_decoder.rb +21 -0
- data/lib/cipherstash-pg/coder.rb +82 -0
- data/lib/cipherstash-pg/connection.rb +467 -0
- data/lib/cipherstash-pg/constants.rb +3 -0
- data/lib/cipherstash-pg/exceptions.rb +19 -0
- data/lib/cipherstash-pg/result.rb +22 -0
- data/lib/cipherstash-pg/text_decoder.rb +43 -0
- data/lib/cipherstash-pg/text_encoder.rb +67 -0
- data/lib/cipherstash-pg/tuple.rb +24 -0
- data/lib/cipherstash-pg/type_map_by_column.rb +11 -0
- data/lib/cipherstash-pg/version.rb +3 -0
- data/lib/cipherstash-pg.rb +60 -0
- data/lib/libpq.5.dylib +0 -0
- data/misc/openssl-pg-segfault.rb +21 -0
- data/misc/postgres/History.txt +9 -0
- data/misc/postgres/Manifest.txt +5 -0
- data/misc/postgres/README.txt +21 -0
- data/misc/postgres/Rakefile +14 -0
- data/misc/postgres/lib/postgres.rb +12 -0
- data/misc/ruby-pg/History.txt +9 -0
- data/misc/ruby-pg/Manifest.txt +5 -0
- data/misc/ruby-pg/README.txt +21 -0
- data/misc/ruby-pg/Rakefile +14 -0
- data/misc/ruby-pg/lib/ruby/pg.rb +12 -0
- data/rakelib/task_extension.rb +32 -0
- data/sample/array_insert.rb +7 -0
- data/sample/async_api.rb +60 -0
- data/sample/async_copyto.rb +24 -0
- data/sample/async_mixed.rb +28 -0
- data/sample/check_conn.rb +9 -0
- data/sample/copydata.rb +21 -0
- data/sample/copyfrom.rb +29 -0
- data/sample/copyto.rb +13 -0
- data/sample/cursor.rb +11 -0
- data/sample/disk_usage_report.rb +92 -0
- data/sample/issue-119.rb +46 -0
- data/sample/losample.rb +51 -0
- data/sample/minimal-testcase.rb +6 -0
- data/sample/notify_wait.rb +26 -0
- data/sample/pg_statistics.rb +104 -0
- data/sample/replication_monitor.rb +123 -0
- data/sample/test_binary_values.rb +17 -0
- data/sample/wal_shipper.rb +202 -0
- data/sample/warehouse_partitions.rb +161 -0
- data/translation/.po4a-version +7 -0
- data/translation/po/all.pot +875 -0
- data/translation/po/ja.po +868 -0
- data/translation/po4a.cfg +9 -0
- data/vendor/database-extensions/install.sql +317 -0
- data/vendor/database-extensions/uninstall.sql +20 -0
- metadata +140 -0
@@ -0,0 +1,60 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module CipherStashPG
|
5
|
+
# cipherstash-pg *always* ships a "fat" gem with precompiled libs for
|
6
|
+
# each popular major.minor version of Ruby that is still in use.
|
7
|
+
major_minor = RUBY_VERSION[ /^(\d+\.\d+)/ ] or
|
8
|
+
raise "Oops, can't extract the major/minor version from #{RUBY_VERSION.dump}"
|
9
|
+
begin
|
10
|
+
require "#{major_minor}/pg_ext"
|
11
|
+
rescue => e
|
12
|
+
STDERR.puts "Failed to load pg_ext for #{RUBY_VERSION.dump}"
|
13
|
+
exit 1
|
14
|
+
end
|
15
|
+
|
16
|
+
# Provide a means to read the extension installation scripts
|
17
|
+
DB_EXT_DIR = File.join(__dir__, '../vendor/database-extensions')
|
18
|
+
def self.install_script
|
19
|
+
File.read(File.join(DB_EXT_DIR, "install.sql"))
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.uninstall_script
|
23
|
+
File.read(File.join(DB_EXT_DIR, "uninstall.sql"))
|
24
|
+
end
|
25
|
+
|
26
|
+
class NotAllCopyDataRetrieved < CipherStashPG::Error
|
27
|
+
end
|
28
|
+
|
29
|
+
class NotInBlockingMode < CipherStashPG::Error
|
30
|
+
end
|
31
|
+
|
32
|
+
# Get the CipherStashPG library version.
|
33
|
+
#
|
34
|
+
# +include_buildnum+ is no longer used and any value passed will be ignored.
|
35
|
+
def self.version_string( include_buildnum=nil )
|
36
|
+
"%s %s" % [ self.name, VERSION ]
|
37
|
+
end
|
38
|
+
|
39
|
+
### Convenience alias for CipherStashPG::Connection.new.
|
40
|
+
def self.connect( *args, &block )
|
41
|
+
Connection.new( *args, &block )
|
42
|
+
end
|
43
|
+
|
44
|
+
require 'cipherstash-pg/exceptions'
|
45
|
+
require 'cipherstash-pg/constants'
|
46
|
+
require 'cipherstash-pg/coder'
|
47
|
+
require 'cipherstash-pg/binary_decoder'
|
48
|
+
require 'cipherstash-pg/text_encoder'
|
49
|
+
require 'cipherstash-pg/text_decoder'
|
50
|
+
require 'cipherstash-pg/basic_type_registry'
|
51
|
+
require 'cipherstash-pg/basic_type_map_based_on_result'
|
52
|
+
require 'cipherstash-pg/basic_type_map_for_queries'
|
53
|
+
require 'cipherstash-pg/basic_type_map_for_results'
|
54
|
+
require 'cipherstash-pg/type_map_by_column'
|
55
|
+
require 'cipherstash-pg/connection'
|
56
|
+
require 'cipherstash-pg/result'
|
57
|
+
require 'cipherstash-pg/tuple'
|
58
|
+
require 'cipherstash-pg/version'
|
59
|
+
|
60
|
+
end # module CipherStashPG
|
data/lib/libpq.5.dylib
ADDED
Binary file
|
@@ -0,0 +1,21 @@
|
|
1
|
+
PGHOST = "localhost"
|
2
|
+
PGDB = "test"
|
3
|
+
SOCKHOST = "it-trac.laika.com"
|
4
|
+
require("cipherstash-pg")
|
5
|
+
$stderr.puts("connecting to postgres://#{PGHOST}/#{PGDB}")
|
6
|
+
conn = CipherStashPG.connect(PGHOST, :dbname => (PGDB))
|
7
|
+
require("socket")
|
8
|
+
require("openssl")
|
9
|
+
$stderr.puts("Connecting to #{SOCKHOST}")
|
10
|
+
sock = TCPSocket.open(SOCKHOST, 443)
|
11
|
+
ctx = OpenSSL::SSL::SSLContext.new
|
12
|
+
sock = OpenSSL::SSL::SSLSocket.new(sock, ctx)
|
13
|
+
sock.sync_close = true
|
14
|
+
$stderr.puts("Attempting to connect...")
|
15
|
+
begin
|
16
|
+
sock.connect
|
17
|
+
rescue Errno
|
18
|
+
$stderr.puts("Got an error connecting, but no segfault.")
|
19
|
+
else
|
20
|
+
$stderr.puts("Nope, no segfault!")
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
= postgres
|
2
|
+
|
3
|
+
* https://github.com/ged/ruby-pg
|
4
|
+
|
5
|
+
== Description
|
6
|
+
|
7
|
+
This is an old, deprecated version of the Ruby PostgreSQL driver that hasn't
|
8
|
+
been maintained or supported since early 2008.
|
9
|
+
|
10
|
+
You should install/require 'pg' instead.
|
11
|
+
|
12
|
+
If you need the 'postgres' gem for legacy code that can't be converted, you can
|
13
|
+
still install it using an explicit version, like so:
|
14
|
+
|
15
|
+
gem install postgres -v '0.7.9.2008.01.28'
|
16
|
+
gem uninstall postgres -v '>0.7.9.2008.01.28'
|
17
|
+
|
18
|
+
If you have any questions, the nice folks in the Google group can help:
|
19
|
+
|
20
|
+
http://goo.gl/OjOPP / ruby-pg@googlegroups.com
|
21
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require("date")
|
2
|
+
require("rubygems")
|
3
|
+
require("hoe")
|
4
|
+
require("pp")
|
5
|
+
Hoe.spec("postgres") do
|
6
|
+
self.developer("Michael Granger", "ged@FaerieMUD.org")
|
7
|
+
self.dependency("pg", "~> 0")
|
8
|
+
self.spec_extras[:date] = Date.parse("2008/01/30")
|
9
|
+
line = ("-" * 75)
|
10
|
+
msg = paragraphs_of("README.txt", (3..-1))
|
11
|
+
msg.unshift(line)
|
12
|
+
msg.push(line)
|
13
|
+
self.spec_extras[:post_install_message] = (msg.join("\n\n") + "\n")
|
14
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
= ruby-pg
|
2
|
+
|
3
|
+
* https://github.com/ged/ruby-pg
|
4
|
+
|
5
|
+
== Description
|
6
|
+
|
7
|
+
This is an old, deprecated version of the 'pg' gem that hasn't been
|
8
|
+
maintained or supported since early 2008.
|
9
|
+
|
10
|
+
You should install/require 'pg' instead.
|
11
|
+
|
12
|
+
If you need ruby-pg for legacy code that can't be converted, you can still
|
13
|
+
install it using an explicit version, like so:
|
14
|
+
|
15
|
+
gem install ruby-pg -v '0.7.9.2008.01.28'
|
16
|
+
gem uninstall ruby-pg -v '>0.7.9.2008.01.28'
|
17
|
+
|
18
|
+
If you have any questions, the nice folks in the Google group can help:
|
19
|
+
|
20
|
+
http://goo.gl/OjOPP / ruby-pg@googlegroups.com
|
21
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require("date")
|
2
|
+
require("rubygems")
|
3
|
+
require("hoe")
|
4
|
+
require("pp")
|
5
|
+
Hoe.spec("ruby-pg") do
|
6
|
+
self.developer("Michael Granger", "ged@FaerieMUD.org")
|
7
|
+
self.dependency("pg", "~> 0")
|
8
|
+
self.spec_extras[:date] = Date.parse("2008/01/30")
|
9
|
+
line = ("-" * 75)
|
10
|
+
msg = paragraphs_of("README.txt", (3..-1))
|
11
|
+
msg.unshift(line)
|
12
|
+
msg.push(line)
|
13
|
+
self.spec_extras[:post_install_message] = (msg.join("\n\n") + "\n")
|
14
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module TaskExtension
|
2
|
+
def file(name, *args, &block)
|
3
|
+
task_once(name, block) do
|
4
|
+
super(name, *args) do |ta|
|
5
|
+
block&.call(ta).tap do
|
6
|
+
unless File.exist?(ta.name) then
|
7
|
+
raise("file #{ta.name} is missing after task executed")
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def task(name, *args, &block)
|
15
|
+
task_once(name, block) { super }
|
16
|
+
end
|
17
|
+
|
18
|
+
private(def task_once(name, block)
|
19
|
+
name = name.keys.first if name.is_a?(Hash)
|
20
|
+
if block and (Rake::Task.task_defined?(name) and (Rake::Task[name].instance_variable_get("@task_block_location") == block.source_location)) then
|
21
|
+
Rake::Task[name]
|
22
|
+
else
|
23
|
+
if block then
|
24
|
+
yield.tap do
|
25
|
+
Rake::Task[name].instance_variable_set("@task_block_location", block.source_location)
|
26
|
+
end
|
27
|
+
else
|
28
|
+
yield
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end)
|
32
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
require("cipherstash-pg")
|
2
|
+
c = CipherStashPG.connect(:dbname => "test")
|
3
|
+
c.exec("DROP TABLE IF EXISTS foo")
|
4
|
+
c.exec("CREATE TABLE foo (strings character varying[]);")
|
5
|
+
c.set_error_verbosity(CipherStashPG::PQERRORS_VERBOSE)
|
6
|
+
c.prepare("stmt", "INSERT INTO foo VALUES ($1);")
|
7
|
+
c.exec_prepared("stmt", ["{'this','that'}"])
|
data/sample/async_api.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
require("cipherstash-pg")
|
2
|
+
TIMEOUT = 5.0
|
3
|
+
progress_thread = Thread.new { loop { print("x") } }
|
4
|
+
def output_progress(msg)
|
5
|
+
puts("\n>>> #{msg}\n")
|
6
|
+
end
|
7
|
+
output_progress("Starting connection...")
|
8
|
+
(conn = CipherStashPG::Connection.connect_start(:dbname => "test") or abort("Unable to create a new connection!"))
|
9
|
+
if (conn.status == CipherStashPG::CONNECTION_BAD) then
|
10
|
+
abort(("Connection failed: %s" % [conn.error_message]))
|
11
|
+
end
|
12
|
+
poll_status = CipherStashPG::PGRES_POLLING_WRITING
|
13
|
+
until ((poll_status == CipherStashPG::PGRES_POLLING_OK) or (poll_status == CipherStashPG::PGRES_POLLING_FAILED)) do
|
14
|
+
(case poll_status
|
15
|
+
when CipherStashPG::PGRES_POLLING_READING then
|
16
|
+
output_progress(" waiting for socket to become readable")
|
17
|
+
(select([conn.socket_io], nil, nil, TIMEOUT) or raise("Asynchronous connection timed out!"))
|
18
|
+
when CipherStashPG::PGRES_POLLING_WRITING then
|
19
|
+
output_progress(" waiting for socket to become writable")
|
20
|
+
(select(nil, [conn.socket_io], nil, TIMEOUT) or raise("Asynchronous connection timed out!"))
|
21
|
+
end
|
22
|
+
case conn.status
|
23
|
+
when CipherStashPG::CONNECTION_STARTED then
|
24
|
+
output_progress(" waiting for connection to be made.")
|
25
|
+
when CipherStashPG::CONNECTION_MADE then
|
26
|
+
output_progress(" connection OK; waiting to send.")
|
27
|
+
when CipherStashPG::CONNECTION_AWAITING_RESPONSE then
|
28
|
+
output_progress(" waiting for a response from the server.")
|
29
|
+
when CipherStashPG::CONNECTION_AUTH_OK then
|
30
|
+
output_progress(" received authentication; waiting for backend start-up to finish.")
|
31
|
+
when CipherStashPG::CONNECTION_SSL_STARTUP then
|
32
|
+
output_progress(" negotiating SSL encryption.")
|
33
|
+
when CipherStashPG::CONNECTION_SETENV then
|
34
|
+
output_progress(" negotiating environment-driven parameter settings.")
|
35
|
+
when CipherStashPG::CONNECTION_NEEDED then
|
36
|
+
output_progress(" internal state: connect() needed.")
|
37
|
+
end
|
38
|
+
poll_status = conn.connect_poll)
|
39
|
+
end
|
40
|
+
unless (conn.status == CipherStashPG::CONNECTION_OK) then
|
41
|
+
abort(("Connect failed: %s" % [conn.error_message]))
|
42
|
+
end
|
43
|
+
output_progress("Sending query")
|
44
|
+
conn.send_query("SELECT * FROM pg_stat_activity")
|
45
|
+
loop do
|
46
|
+
output_progress(" waiting for a response")
|
47
|
+
conn.consume_input
|
48
|
+
while conn.is_busy do
|
49
|
+
(select([conn.socket_io], nil, nil, TIMEOUT) or raise("Timeout waiting for query response."))
|
50
|
+
conn.consume_input
|
51
|
+
end
|
52
|
+
(result = conn.get_result or break)
|
53
|
+
puts(("\n\nQuery result:\n%p\n" % [result.values]))
|
54
|
+
end
|
55
|
+
output_progress("Done.")
|
56
|
+
conn.finish
|
57
|
+
if defined? progress_thread then
|
58
|
+
progress_thread.kill
|
59
|
+
progress_thread.join
|
60
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require("cipherstash-pg")
|
2
|
+
require("stringio")
|
3
|
+
$stderr.puts("Opening database connection ...")
|
4
|
+
conn = CipherStashPG.connect(:dbname => "test")
|
5
|
+
conn.setnonblocking(true)
|
6
|
+
socket = conn.socket_io
|
7
|
+
$stderr.puts("Running COPY command ...")
|
8
|
+
buf = ""
|
9
|
+
conn.transaction do
|
10
|
+
conn.send_query("COPY logs TO STDOUT WITH csv")
|
11
|
+
buf = nil
|
12
|
+
begin
|
13
|
+
($stderr.puts("COPY loop")
|
14
|
+
conn.consume_input
|
15
|
+
while conn.is_busy do
|
16
|
+
$stderr.puts(" ready loop")
|
17
|
+
(select([socket], nil, nil, 5.0) or raise("Timeout (5s) waiting for query response."))
|
18
|
+
conn.consume_input
|
19
|
+
end
|
20
|
+
buf = conn.get_copy_data
|
21
|
+
$stdout.puts(buf) if buf)
|
22
|
+
end until buf.nil?
|
23
|
+
end
|
24
|
+
conn.finish
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require("cipherstash-pg")
|
2
|
+
$stdout.sync = true
|
3
|
+
TIMEOUT = 5.0
|
4
|
+
CONN_OPTS = { :host => "localhost", :dbname => "test" }
|
5
|
+
def output_progress(msg)
|
6
|
+
puts(">>> #{msg}\n")
|
7
|
+
end
|
8
|
+
output_progress("Starting connection...")
|
9
|
+
(conn = CipherStashPG.connect(CONN_OPTS) or abort("Unable to create a new connection!"))
|
10
|
+
unless (conn.status == CipherStashPG::CONNECTION_OK) then
|
11
|
+
abort(("Connect failed: %s" % [conn.error_message]))
|
12
|
+
end
|
13
|
+
socket = conn.socket_io
|
14
|
+
output_progress("Sending query")
|
15
|
+
conn.send_query("SELECT * FROM pg_stat_activity")
|
16
|
+
loop do
|
17
|
+
output_progress(" waiting for a response")
|
18
|
+
conn.consume_input
|
19
|
+
while conn.is_busy do
|
20
|
+
output_progress((" waiting for data to be available on %p..." % [socket]))
|
21
|
+
(select([socket], nil, nil, TIMEOUT) or raise("Timeout waiting for query response."))
|
22
|
+
conn.consume_input
|
23
|
+
end
|
24
|
+
(result = conn.get_result or break)
|
25
|
+
output_progress(("Query result:\n%p\n" % [result.values]))
|
26
|
+
end
|
27
|
+
output_progress("Done.")
|
28
|
+
conn.finish
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require("cipherstash-pg")
|
2
|
+
def check_connection(conn)
|
3
|
+
conn.exec("SELECT 1")
|
4
|
+
rescue CipherStashPG::Error => err
|
5
|
+
$stderr.puts(("%p while testing connection: %s" % [err.class, err.message]))
|
6
|
+
conn.reset
|
7
|
+
end
|
8
|
+
conn = CipherStashPG.connect(:dbname => "test")
|
9
|
+
check_connection(conn)
|
data/sample/copydata.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require("cipherstash-pg")
|
2
|
+
require("stringio")
|
3
|
+
$stderr.puts("Opening database connection ...")
|
4
|
+
conn = CipherStashPG.connect(:dbname => "test")
|
5
|
+
conn.exec("DROP TABLE IF EXISTS logs;\nCREATE TABLE logs (\n\tclient_ip inet,\n\tusername text,\n\tts timestamp,\n\trequest text,\n\tstatus smallint,\n\tbytes int\n);\n")
|
6
|
+
csv_io = StringIO.new("\"127.0.0.1\",\"\",\"30/Aug/2010:08:21:24 -0700\",\"GET /manual/ HTTP/1.1\",404,205\n\"127.0.0.1\",\"\",\"30/Aug/2010:08:21:24 -0700\",\"GET /favicon.ico HTTP/1.1\",404,209\n\"127.0.0.1\",\"\",\"30/Aug/2010:08:21:24 -0700\",\"GET /favicon.ico HTTP/1.1\",404,209\n\"127.0.0.1\",\"\",\"30/Aug/2010:08:22:29 -0700\",\"GET /manual/ HTTP/1.1\",200,11094\n\"127.0.0.1\",\"\",\"30/Aug/2010:08:22:38 -0700\",\"GET /manual/index.html HTTP/1.1\",200,725\n\"127.0.0.1\",\"\",\"30/Aug/2010:08:27:56 -0700\",\"GET /manual/ HTTP/1.1\",200,11094\n\"127.0.0.1\",\"\",\"30/Aug/2010:08:27:57 -0700\",\"GET /manual/ HTTP/1.1\",200,11094\n\"127.0.0.1\",\"\",\"30/Aug/2010:08:28:06 -0700\",\"GET /manual/index.html HTTP/1.1\",200,7709\n\"127.0.0.1\",\"\",\"30/Aug/2010:08:28:06 -0700\",\"GET /manual/images/feather.gif HTTP/1.1\",200,6471\n\"127.0.0.1\",\"\",\"30/Aug/2010:08:28:06 -0700\",\"GET /manual/images/left.gif HTTP/1.1\",200,60\n\"127.0.0.1\",\"\",\"30/Aug/2010:08:28:06 -0700\",\"GET /manual/style/css/manual.css HTTP/1.1\",200,18674\n\"127.0.0.1\",\"\",\"30/Aug/2010:08:28:06 -0700\",\"GET /manual/style/css/manual-print.css HTTP/1.1\",200,13200\n\"127.0.0.1\",\"\",\"30/Aug/2010:08:28:06 -0700\",\"GET /manual/images/favicon.ico HTTP/1.1\",200,1078\n\"127.0.0.1\",\"\",\"30/Aug/2010:08:28:06 -0700\",\"GET /manual/style/css/manual-loose-100pc.css HTTP/1.1\",200,3065\n\"127.0.0.1\",\"\",\"30/Aug/2010:08:28:14 -0700\",\"OPTIONS * HTTP/1.0\",200,0\n\"127.0.0.1\",\"\",\"30/Aug/2010:08:28:15 -0700\",\"OPTIONS * HTTP/1.0\",200,0\n\"127.0.0.1\",\"\",\"30/Aug/2010:08:28:47 -0700\",\"GET /manual/mod/directives.html HTTP/1.1\",200,33561\n\"127.0.0.1\",\"\",\"30/Aug/2010:08:28:53 -0700\",\"GET /manual/mod/mpm_common.html HTTP/1.1\",200,67683\n\"127.0.0.1\",\"\",\"30/Aug/2010:08:28:53 -0700\",\"GET /manual/images/down.gif HTTP/1.1\",200,56\n\"127.0.0.1\",\"\",\"30/Aug/2010:08:28:53 -0700\",\"GET /manual/images/up.gif HTTP/1.1\",200,57\n\"127.0.0.1\",\"\",\"30/Aug/2010:09:19:58 -0700\",\"GET /manual/mod/mod_log_config.html HTTP/1.1\",200,28307\n\"127.0.0.1\",\"\",\"30/Aug/2010:09:20:19 -0700\",\"GET /manual/mod/core.html HTTP/1.1\",200,194144\n\"127.0.0.1\",\"\",\"30/Aug/2010:16:02:56 -0700\",\"GET /manual/ HTTP/1.1\",200,11094\n\"127.0.0.1\",\"\",\"30/Aug/2010:16:03:00 -0700\",\"GET /manual/ HTTP/1.1\",200,11094\n\"127.0.0.1\",\"\",\"30/Aug/2010:16:06:16 -0700\",\"GET /manual/mod/mod_dir.html HTTP/1.1\",200,10583\n\"127.0.0.1\",\"\",\"30/Aug/2010:16:06:44 -0700\",\"GET /manual/ HTTP/1.1\",200,7709\n")
|
7
|
+
$stderr.puts("Running COPY command with data ...")
|
8
|
+
buf = ""
|
9
|
+
conn.transaction do
|
10
|
+
res = conn.copy_data("COPY logs FROM STDIN WITH csv") do
|
11
|
+
$stderr.print("Sending lines... ")
|
12
|
+
csv_io.each_line.with_index do |buf, i|
|
13
|
+
$stderr.print("#{(i + 1)} ")
|
14
|
+
conn.put_copy_data(buf)
|
15
|
+
end
|
16
|
+
$stderr.puts("done.")
|
17
|
+
end
|
18
|
+
$stderr.puts(("Result of COPY is: %s" % [res.res_status(res.result_status)]))
|
19
|
+
$stderr.puts((" tuples copied: %p" % [res.cmd_tuples]))
|
20
|
+
end
|
21
|
+
conn.finish
|
data/sample/copyfrom.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require("cipherstash-pg")
|
2
|
+
require("stringio")
|
3
|
+
$stderr.puts("Opening database connection ...")
|
4
|
+
conn = CipherStashPG.connect(:dbname => "test")
|
5
|
+
conn.exec("DROP TABLE IF EXISTS logs;\nCREATE TABLE logs (\n\tclient_ip inet,\n\tusername text,\n\tts timestamp,\n\trequest text,\n\tstatus smallint,\n\tbytes int\n);\n")
|
6
|
+
copy_data = StringIO.new("\"127.0.0.1\",\"\",\"30/Aug/2010:08:21:24 -0700\",\"GET /manual/ HTTP/1.1\",404,205\n\"127.0.0.1\",\"\",\"30/Aug/2010:08:21:24 -0700\",\"GET /favicon.ico HTTP/1.1\",404,209\n\"127.0.0.1\",\"\",\"30/Aug/2010:08:21:24 -0700\",\"GET /favicon.ico HTTP/1.1\",404,209\n\"127.0.0.1\",\"\",\"30/Aug/2010:08:22:29 -0700\",\"GET /manual/ HTTP/1.1\",200,11094\n\"127.0.0.1\",\"\",\"30/Aug/2010:08:22:38 -0700\",\"GET /manual/index.html HTTP/1.1\",200,725\n\"127.0.0.1\",\"\",\"30/Aug/2010:08:27:56 -0700\",\"GET /manual/ HTTP/1.1\",200,11094\n\"127.0.0.1\",\"\",\"30/Aug/2010:08:27:57 -0700\",\"GET /manual/ HTTP/1.1\",200,11094\n\"127.0.0.1\",\"\",\"30/Aug/2010:08:28:06 -0700\",\"GET /manual/index.html HTTP/1.1\",200,7709\n\"127.0.0.1\",\"\",\"30/Aug/2010:08:28:06 -0700\",\"GET /manual/images/feather.gif HTTP/1.1\",200,6471\n\"127.0.0.1\",\"\",\"30/Aug/2010:08:28:06 -0700\",\"GET /manual/images/left.gif HTTP/1.1\",200,60\n\"127.0.0.1\",\"\",\"30/Aug/2010:08:28:06 -0700\",\"GET /manual/style/css/manual.css HTTP/1.1\",200,18674\n\"127.0.0.1\",\"\",\"30/Aug/2010:08:28:06 -0700\",\"GET /manual/style/css/manual-print.css HTTP/1.1\",200,13200\n\"127.0.0.1\",\"\",\"30/Aug/2010:08:28:06 -0700\",\"GET /manual/images/favicon.ico HTTP/1.1\",200,1078\n\"127.0.0.1\",\"\",\"30/Aug/2010:08:28:06 -0700\",\"GET /manual/style/css/manual-loose-100pc.css HTTP/1.1\",200,3065\n\"127.0.0.1\",\"\",\"30/Aug/2010:08:28:14 -0700\",\"OPTIONS * HTTP/1.0\",200,0\n\"127.0.0.1\",\"\",\"30/Aug/2010:08:28:15 -0700\",\"OPTIONS * HTTP/1.0\",200,0\n\"127.0.0.1\",\"\",\"30/Aug/2010:08:28:47 -0700\",\"GET /manual/mod/directives.html HTTP/1.1\",200,33561\n\"127.0.0.1\",\"\",\"30/Aug/2010:08:28:53 -0700\",\"GET /manual/mod/mpm_common.html HTTP/1.1\",200,67683\n\"127.0.0.1\",\"\",\"30/Aug/2010:08:28:53 -0700\",\"GET /manual/images/down.gif HTTP/1.1\",200,56\n\"127.0.0.1\",\"\",\"30/Aug/2010:08:28:53 -0700\",\"GET /manual/images/up.gif HTTP/1.1\",200,57\n\"127.0.0.1\",\"\",\"30/Aug/2010:09:19:58 -0700\",\"GET /manual/mod/mod_log_config.html HTTP/1.1\",200,28307\n\"127.0.0.1\",\"\",\"30/Aug/2010:09:20:19 -0700\",\"GET /manual/mod/core.html HTTP/1.1\",200,194144\n\"127.0.0.1\",\"\",\"30/Aug/2010:16:02:56 -0700\",\"GET /manual/ HTTP/1.1\",200,11094\n\"127.0.0.1\",\"\",\"30/Aug/2010:16:03:00 -0700\",\"GET /manual/ HTTP/1.1\",200,11094\n\"127.0.0.1\",\"\",\"30/Aug/2010:16:06:16 -0700\",\"GET /manual/mod/mod_dir.html HTTP/1.1\",200,10583\n\"127.0.0.1\",\"\",\"30/Aug/2010:16:06:44 -0700\",\"GET /manual/ HTTP/1.1\",200,7709\n")
|
7
|
+
$stderr.puts("Running COPY command with data ...")
|
8
|
+
buf = ""
|
9
|
+
conn.transaction do
|
10
|
+
conn.exec("COPY logs FROM STDIN WITH csv")
|
11
|
+
begin
|
12
|
+
while copy_data.read(256, buf) do
|
13
|
+
$stderr.puts(("\tsending %d bytes of data..." % [buf.length]))
|
14
|
+
until conn.put_copy_data(buf) do
|
15
|
+
($stderr.puts("\twaiting for connection to be writable...")
|
16
|
+
sleep(0.1))
|
17
|
+
end
|
18
|
+
end
|
19
|
+
rescue Errno => err
|
20
|
+
errmsg = ("%s while reading copy data: %s" % [err.class.name, err.message])
|
21
|
+
conn.put_copy_end(errmsg)
|
22
|
+
else
|
23
|
+
(conn.put_copy_end
|
24
|
+
while res = conn.get_result do
|
25
|
+
$stderr.puts(("Result of COPY is: %s" % [res.res_status(res.result_status)]))
|
26
|
+
end)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
conn.finish
|
data/sample/copyto.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require("cipherstash-pg")
|
2
|
+
require("stringio")
|
3
|
+
$stderr.puts("Opening database connection ...")
|
4
|
+
conn = CipherStashPG.connect(:dbname => "test")
|
5
|
+
$stderr.puts("Running COPY command ...")
|
6
|
+
buf = ""
|
7
|
+
conn.transaction do
|
8
|
+
conn.exec("COPY logs TO STDOUT WITH csv")
|
9
|
+
while buf = conn.get_copy_data do
|
10
|
+
$stdout.puts(buf)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
conn.finish
|
data/sample/cursor.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require("cipherstash-pg")
|
2
|
+
$stderr.puts("Opening database connection ...")
|
3
|
+
conn = CipherStashPG.connect(:dbname => "test")
|
4
|
+
conn.transaction do
|
5
|
+
conn.exec("DECLARE myportal CURSOR FOR select * from pg_database")
|
6
|
+
res = conn.exec("FETCH ALL IN myportal")
|
7
|
+
puts(res.fields.collect { |fname| ("%-15s" % [fname]) }.join(""))
|
8
|
+
res.values.collect do |row|
|
9
|
+
puts(row.collect { |col| ("%-15s" % [col]) }.join(""))
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require("ostruct")
|
2
|
+
require("optparse")
|
3
|
+
require("etc")
|
4
|
+
require("cipherstash-pg")
|
5
|
+
SCRIPT_VERSION = "Id"
|
6
|
+
def report(opts)
|
7
|
+
db = CipherStashPG.connect(:dbname => opts.database, :host => opts.host, :port => opts.port, :user => opts.user, :password => opts.pass, :sslmode => "prefer")
|
8
|
+
db_info = db.exec("\n\t\tSELECT\n\t\t\tcount(oid) AS num_relations,\n\t\t\tpg_size_pretty(pg_database_size('#{opts.database}')) AS dbsize\n\t\tFROM\n\t\t\tpg_class\n\t")
|
9
|
+
puts(("=" * 70))
|
10
|
+
puts(("Disk usage information for %s: (%d relations, %s total)" % [opts.database, db_info[0]["num_relations"], db_info[0]["dbsize"]]))
|
11
|
+
puts(("=" * 70))
|
12
|
+
top_twenty = db.exec("\n\t\tSELECT\n\t\t\trelname AS name,\n\t\t\trelkind AS kind,\n\t\t\tpg_size_pretty(pg_relation_size(pg_class.oid)) AS size\n\t\tFROM\n\t\t\tpg_class\n\t\tORDER BY\n\t\t\tpg_relation_size(pg_class.oid) DESC\n\t\tLIMIT 20\n\t")
|
13
|
+
puts("Top twenty objects by size:")
|
14
|
+
puts(("-" * 70))
|
15
|
+
top_twenty.each do |row|
|
16
|
+
type = case row["kind"]
|
17
|
+
when "i" then
|
18
|
+
"index"
|
19
|
+
when "t" then
|
20
|
+
"toast"
|
21
|
+
when "r" then
|
22
|
+
"table"
|
23
|
+
when "S" then
|
24
|
+
"sequence"
|
25
|
+
else
|
26
|
+
"???"
|
27
|
+
end
|
28
|
+
puts(("%40s %10s (%s)" % [row["name"], row["size"], type]))
|
29
|
+
end
|
30
|
+
puts(("-" * 70))
|
31
|
+
schema_sizes = db.exec("\n\t\tSELECT\n\t\t\ttable_schema,\n\t\t\tpg_size_pretty( CAST( SUM(pg_total_relation_size(table_schema || '.' || table_name)) AS bigint)) AS size\n\t\tFROM\n\t\t\tinformation_schema.tables\n\t\tGROUP BY\n\t\t\ttable_schema\n\t\tORDER BY\n\t\t\tCAST( SUM(pg_total_relation_size(table_schema || '.' || table_name)) AS bigint ) DESC\n\t")
|
32
|
+
puts("Size per schema:")
|
33
|
+
puts(("-" * 70))
|
34
|
+
schema_sizes.each do |row|
|
35
|
+
puts(("%20s %10s" % [row["table_schema"], row["size"]]))
|
36
|
+
end
|
37
|
+
puts(("-" * 70))
|
38
|
+
puts
|
39
|
+
db.finish
|
40
|
+
end
|
41
|
+
def parse_args(args)
|
42
|
+
options = OpenStruct.new
|
43
|
+
options.database = Etc.getpwuid(Process.uid).name
|
44
|
+
options.host = "127.0.0.1"
|
45
|
+
options.port = 5432
|
46
|
+
options.user = Etc.getpwuid(Process.uid).name
|
47
|
+
options.sslmode = "prefer"
|
48
|
+
options.interval = 5
|
49
|
+
opts = OptionParser.new do |opts|
|
50
|
+
opts.banner = "Usage: #{$0} [options]"
|
51
|
+
opts.separator("")
|
52
|
+
opts.separator("Connection options:")
|
53
|
+
opts.on("-d", "--database DBNAME", "specify the database to connect to (default: \"#{options.database}\")") do |db|
|
54
|
+
options.database = db
|
55
|
+
end
|
56
|
+
opts.on("-h", "--host HOSTNAME", "database server host") do |host|
|
57
|
+
options.host = host
|
58
|
+
end
|
59
|
+
opts.on("-p", "--port PORT", Integer, "database server port (default: \"#{options.port}\")") do |port|
|
60
|
+
options.port = port
|
61
|
+
end
|
62
|
+
opts.on("-U", "--user NAME", "database user name (default: \"#{options.user}\")") do |user|
|
63
|
+
options.user = user
|
64
|
+
end
|
65
|
+
opts.on("-W", "force password prompt") do |pw|
|
66
|
+
print("Password: ")
|
67
|
+
begin
|
68
|
+
(system("stty -echo")
|
69
|
+
options.pass = gets.chomp)
|
70
|
+
ensure
|
71
|
+
(system("stty echo")
|
72
|
+
puts)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
opts.separator("")
|
76
|
+
opts.separator("Other options:")
|
77
|
+
opts.on_tail("--help", "show this help, then exit") do
|
78
|
+
$stderr.puts(opts)
|
79
|
+
exit
|
80
|
+
end
|
81
|
+
opts.on_tail("--version", "output version information, then exit") do
|
82
|
+
puts(SCRIPT_VERSION)
|
83
|
+
exit
|
84
|
+
end
|
85
|
+
end
|
86
|
+
opts.parse!(args)
|
87
|
+
return options
|
88
|
+
end
|
89
|
+
if ("(string)" == $0) then
|
90
|
+
opts = parse_args(ARGV)
|
91
|
+
report(opts)
|
92
|
+
end
|
data/sample/issue-119.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
require("cipherstash-pg")
|
2
|
+
conn = CipherStashPG.connect(:dbname => "test")
|
3
|
+
table_name = "issue_119"
|
4
|
+
field_list = ["name", "body_weight", "brain_weight"]
|
5
|
+
method = 0
|
6
|
+
options = { :truncate => true }
|
7
|
+
sql_parameters = ""
|
8
|
+
conn.set_error_verbosity(CipherStashPG::PQERRORS_VERBOSE)
|
9
|
+
conn.exec("DROP TABLE IF EXISTS #{table_name}")
|
10
|
+
conn.exec("CREATE TABLE #{table_name} ( id SERIAL, name TEXT, body_weight REAL, brain_weight REAL )")
|
11
|
+
text = "Mountain beaver\t1.35\t465\nCow\t465\t423\nGrey wolf\t36.33\t119.5\nGoat\t27.66\t115\nGuinea pig\t1.04\t5.5\nDipliodocus\t11700\t50\nAsian elephant\t2547\t4603\nDonkey\t187.1\t419\nHorse\t521\t655\nPotar monkey\t10\t115\nCat\t3.3\t25.6\nGiraffe\t529\t680\nGorilla\t207\t406\nHuman\t62\t1320\nAfrican elephant\t6654\t5712\nTriceratops\t9400\t70\nRhesus monkey\t6.8\t179\nKangaroo\t35\t56\nGolden hamster\t0.12\t1\nMouse\t0.023\t0.4\nRabbit\t2.5\t12.1\nSheep\t55.5\t175\nJaguar\t100\t157\nChimpanzee\t52.16\t440\nBrachiosaurus\t87000\t154.5\nMole\t0.122\t3\nPig\t192\t18\n"
|
12
|
+
conn.transaction do
|
13
|
+
rc = conn
|
14
|
+
rc.exec("TRUNCATE TABLE #{table_name};") if options[:truncate]
|
15
|
+
sql = "COPY #{table_name} (#{field_list.join(",")}) FROM STDIN #{sql_parameters} "
|
16
|
+
p(sql)
|
17
|
+
rc.exec(sql)
|
18
|
+
errmsg = nil
|
19
|
+
begin
|
20
|
+
if (method == 1) then
|
21
|
+
rc.put_copy_data((text + "\\.\n"))
|
22
|
+
else
|
23
|
+
text.each_line { |line| rc.put_copy_data(line) }
|
24
|
+
end
|
25
|
+
rescue Errno => err
|
26
|
+
errmsg = ("%s while reading copy data: %s" % [err.class.name, err.message])
|
27
|
+
puts("an error occurred")
|
28
|
+
end
|
29
|
+
if errmsg then
|
30
|
+
rc.put_copy_end(errmsg)
|
31
|
+
puts("ERROR #{errmsg}")
|
32
|
+
else
|
33
|
+
rc.put_copy_end
|
34
|
+
end
|
35
|
+
while res = rc.get_result do
|
36
|
+
st = res.res_status(res.result_status)
|
37
|
+
puts(("Result of COPY is: %s" % [st]))
|
38
|
+
if (res.result_status != CipherStashPG::PGRES_COPY_IN) then
|
39
|
+
puts(res.error_message)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
puts("end")
|
43
|
+
end
|
44
|
+
conn.exec("SELECT name, brain_weight FROM #{table_name}") do |res|
|
45
|
+
p(res.values)
|
46
|
+
end
|