cipherstash-pg 1.0.0.beta.4-x86_64-darwin
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|