pg 0.13.2-x86-mingw32 → 0.14.0.pre.353-x86-mingw32

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.
@@ -21,32 +21,38 @@ static PGresult* pgresult_get( VALUE );
21
21
  * Result constructor
22
22
  */
23
23
  VALUE
24
- pg_new_result(PGresult *result, PGconn *conn)
24
+ pg_new_result(PGresult *result, VALUE rb_pgconn)
25
25
  {
26
+ PGconn *conn = pg_get_pgconn( rb_pgconn );
26
27
  VALUE val = Data_Wrap_Struct(rb_cPGresult, NULL, pgresult_gc_free, result);
27
28
  #ifdef M17N_SUPPORTED
28
29
  rb_encoding *enc = pg_conn_enc_get( conn );
29
30
  ENCODING_SET( val, rb_enc_to_index(enc) );
30
31
  #endif
31
32
 
33
+ rb_iv_set( val, "@connection", rb_pgconn );
34
+
32
35
  return val;
33
36
  }
34
37
 
35
38
  /*
36
- * Raises appropriate exception if PGresult is
37
- * in a bad state.
39
+ * call-seq:
40
+ * res.result -> nil
41
+ *
42
+ * Raises appropriate exception if PG::Result is in a bad state.
38
43
  */
39
- void
40
- pg_check_result(VALUE rb_pgconn, VALUE rb_pgresult)
44
+ VALUE
45
+ pg_result_check( VALUE self )
41
46
  {
42
47
  VALUE error, exception;
48
+ VALUE rb_pgconn = rb_iv_get( self, "@connection" );
43
49
  PGconn *conn = pg_get_pgconn(rb_pgconn);
44
50
  PGresult *result;
45
51
  #ifdef M17N_SUPPORTED
46
52
  rb_encoding *enc = pg_conn_enc_get( conn );
47
53
  #endif
48
54
 
49
- Data_Get_Struct(rb_pgresult, PGresult, result);
55
+ Data_Get_Struct(self, PGresult, result);
50
56
 
51
57
  if(result == NULL)
52
58
  {
@@ -59,9 +65,12 @@ pg_check_result(VALUE rb_pgconn, VALUE rb_pgresult)
59
65
  case PGRES_TUPLES_OK:
60
66
  case PGRES_COPY_OUT:
61
67
  case PGRES_COPY_IN:
68
+ #ifdef HAVE_CONST_PGRES_COPY_BOTH
69
+ case PGRES_COPY_BOTH:
70
+ #endif
62
71
  case PGRES_EMPTY_QUERY:
63
72
  case PGRES_COMMAND_OK:
64
- return;
73
+ return Qnil;
65
74
  case PGRES_BAD_RESPONSE:
66
75
  case PGRES_FATAL_ERROR:
67
76
  case PGRES_NONFATAL_ERROR:
@@ -77,10 +86,11 @@ pg_check_result(VALUE rb_pgconn, VALUE rb_pgresult)
77
86
  #endif
78
87
  exception = rb_exc_new3( rb_ePGerror, error );
79
88
  rb_iv_set( exception, "@connection", rb_pgconn );
80
- rb_iv_set( exception, "@result", rb_pgresult );
89
+ rb_iv_set( exception, "@result", self );
81
90
  rb_exc_raise( exception );
82
91
 
83
- return;
92
+ /* Not reached */
93
+ return Qnil;
84
94
  }
85
95
 
86
96
 
@@ -94,7 +104,7 @@ pg_check_result(VALUE rb_pgconn, VALUE rb_pgresult)
94
104
  * call-seq:
95
105
  * res.clear() -> nil
96
106
  *
97
- * Clears the PGresult object as the result of the query.
107
+ * Clears the PG::Result object as the result of the query.
98
108
  */
99
109
  VALUE
100
110
  pg_result_clear(VALUE self)
@@ -135,7 +145,7 @@ pgresult_get(VALUE self)
135
145
 
136
146
  /********************************************************************
137
147
  *
138
- * Document-class: PGresult
148
+ * Document-class: PG::Result
139
149
  *
140
150
  * The class to represent the query result tuples (rows).
141
151
  * An instance of this class is created as the result of every query.
@@ -153,7 +163,7 @@ pgresult_get(VALUE self)
153
163
  */
154
164
 
155
165
  /**************************************************************************
156
- * PGresult INSTANCE METHODS
166
+ * PG::Result INSTANCE METHODS
157
167
  **************************************************************************/
158
168
 
159
169
  /*
@@ -229,20 +239,20 @@ pgresult_error_message(VALUE self)
229
239
  *
230
240
  * begin
231
241
  * conn.exec( "SELECT * FROM nonexistant_table" )
232
- * rescue PGError => err
242
+ * rescue PG::Error => err
233
243
  * p [
234
- * result.error_field( PGresult::PG_DIAG_SEVERITY ),
235
- * result.error_field( PGresult::PG_DIAG_SQLSTATE ),
236
- * result.error_field( PGresult::PG_DIAG_MESSAGE_PRIMARY ),
237
- * result.error_field( PGresult::PG_DIAG_MESSAGE_DETAIL ),
238
- * result.error_field( PGresult::PG_DIAG_MESSAGE_HINT ),
239
- * result.error_field( PGresult::PG_DIAG_STATEMENT_POSITION ),
240
- * result.error_field( PGresult::PG_DIAG_INTERNAL_POSITION ),
241
- * result.error_field( PGresult::PG_DIAG_INTERNAL_QUERY ),
242
- * result.error_field( PGresult::PG_DIAG_CONTEXT ),
243
- * result.error_field( PGresult::PG_DIAG_SOURCE_FILE ),
244
- * result.error_field( PGresult::PG_DIAG_SOURCE_LINE ),
245
- * result.error_field( PGresult::PG_DIAG_SOURCE_FUNCTION ),
244
+ * result.error_field( PG::Result::PG_DIAG_SEVERITY ),
245
+ * result.error_field( PG::Result::PG_DIAG_SQLSTATE ),
246
+ * result.error_field( PG::Result::PG_DIAG_MESSAGE_PRIMARY ),
247
+ * result.error_field( PG::Result::PG_DIAG_MESSAGE_DETAIL ),
248
+ * result.error_field( PG::Result::PG_DIAG_MESSAGE_HINT ),
249
+ * result.error_field( PG::Result::PG_DIAG_STATEMENT_POSITION ),
250
+ * result.error_field( PG::Result::PG_DIAG_INTERNAL_POSITION ),
251
+ * result.error_field( PG::Result::PG_DIAG_INTERNAL_QUERY ),
252
+ * result.error_field( PG::Result::PG_DIAG_CONTEXT ),
253
+ * result.error_field( PG::Result::PG_DIAG_SOURCE_FILE ),
254
+ * result.error_field( PG::Result::PG_DIAG_SOURCE_LINE ),
255
+ * result.error_field( PG::Result::PG_DIAG_SOURCE_FUNCTION ),
246
256
  * ]
247
257
  * end
248
258
  *
@@ -492,7 +502,7 @@ pgresult_fsize(VALUE self, VALUE index)
492
502
  static VALUE
493
503
  pgresult_getvalue(VALUE self, VALUE tup_num, VALUE field_num)
494
504
  {
495
- VALUE ret;
505
+ VALUE val;
496
506
  PGresult *result;
497
507
  int i = NUM2INT(tup_num);
498
508
  int j = NUM2INT(field_num);
@@ -506,10 +516,19 @@ pgresult_getvalue(VALUE self, VALUE tup_num, VALUE field_num)
506
516
  }
507
517
  if(PQgetisnull(result, i, j))
508
518
  return Qnil;
509
- ret = rb_tainted_str_new(PQgetvalue(result, i, j),
519
+ val = rb_tainted_str_new(PQgetvalue(result, i, j),
510
520
  PQgetlength(result, i, j));
511
- ASSOCIATE_INDEX(ret, self);
512
- return ret;
521
+
522
+ #ifdef M17N_SUPPORTED
523
+ /* associate client encoding for text format only */
524
+ if ( 0 == PQfformat(result, j) ) {
525
+ ASSOCIATE_INDEX( val, self );
526
+ } else {
527
+ rb_enc_associate( val, rb_ascii8bit_encoding() );
528
+ }
529
+ #endif
530
+
531
+ return val;
513
532
  }
514
533
 
515
534
  /*
@@ -612,7 +631,7 @@ pgresult_cmd_status(VALUE self)
612
631
  *
613
632
  * Returns the number of tuples (rows) affected by the SQL command.
614
633
  *
615
- * If the SQL command that generated the PGresult was not one of:
634
+ * If the SQL command that generated the PG::Result was not one of:
616
635
  * * +INSERT+
617
636
  * * +UPDATE+
618
637
  * * +DELETE+
@@ -706,19 +725,15 @@ pgresult_values(VALUE self)
706
725
  int field;
707
726
  int num_rows = PQntuples(result);
708
727
  int num_fields = PQnfields(result);
709
- VALUE ary = rb_ary_new2(num_rows);
728
+ VALUE rows[ num_rows ];
710
729
 
711
730
  for ( row = 0; row < num_rows; row++ ) {
712
- /* create new row */
713
- VALUE new_row = rb_ary_new2(num_fields);
731
+ VALUE new_row[ num_fields ];
714
732
 
715
- /* add to return array */
716
- rb_ary_store( ary, row, new_row );
717
-
718
- /* populate it */
733
+ /* populate the row */
719
734
  for ( field = 0; field < num_fields; field++ ) {
720
735
  if ( PQgetisnull(result, row, field) ) {
721
- rb_ary_store( new_row, field, Qnil );
736
+ new_row[ field ] = Qnil;
722
737
  }
723
738
  else {
724
739
  VALUE val = rb_tainted_str_new( PQgetvalue(result, row, field),
@@ -732,16 +747,18 @@ pgresult_values(VALUE self)
732
747
  rb_enc_associate( val, rb_ascii8bit_encoding() );
733
748
  }
734
749
  #endif
735
-
736
- rb_ary_store( new_row, field, val );
750
+ new_row[ field ] = val;
737
751
  }
738
752
  }
753
+
754
+ rows[ row ] = rb_ary_new4( num_fields, new_row );
739
755
  }
740
- return ary;
756
+
757
+ return rb_ary_new4( num_rows, rows );
741
758
  }
742
759
 
743
760
 
744
- /*
761
+ /*
745
762
  * Make a Ruby array out of the encoded values from the specified
746
763
  * column in the given result.
747
764
  */
@@ -749,16 +766,17 @@ static VALUE
749
766
  make_column_result_array( VALUE self, int col )
750
767
  {
751
768
  PGresult *result = pgresult_get( self );
752
- int row = PQntuples( result );
753
- VALUE ary = rb_ary_new2( row );
769
+ int rows = PQntuples( result );
770
+ int i;
754
771
  VALUE val = Qnil;
772
+ VALUE results[ rows ];
755
773
 
756
774
  if ( col >= PQnfields(result) )
757
775
  rb_raise( rb_eIndexError, "no column %d in result", col );
758
776
 
759
- while ( row-- ) {
760
- val = rb_tainted_str_new( PQgetvalue(result, row, col),
761
- PQgetlength(result, row, col) );
777
+ for ( i=0; i < rows; i++ ) {
778
+ val = rb_tainted_str_new( PQgetvalue(result, i, col),
779
+ PQgetlength(result, i, col) );
762
780
 
763
781
  #ifdef M17N_SUPPORTED
764
782
  /* associate client encoding for text format only */
@@ -769,10 +787,10 @@ make_column_result_array( VALUE self, int col )
769
787
  }
770
788
  #endif
771
789
 
772
- rb_ary_store( ary, row, val );
790
+ results[ i ] = val;
773
791
  }
774
792
 
775
- return ary;
793
+ return rb_ary_new4( rows, results );
776
794
  }
777
795
 
778
796
 
@@ -840,19 +858,18 @@ pgresult_each(VALUE self)
840
858
  static VALUE
841
859
  pgresult_fields(VALUE self)
842
860
  {
843
- PGresult *result;
844
- VALUE ary;
845
- int n, i;
861
+ PGresult *result = pgresult_get( self );
862
+ int n = PQnfields( result );
863
+ VALUE fields[ n ];
864
+ int i;
846
865
 
847
- result = pgresult_get(self);
848
- n = PQnfields(result);
849
- ary = rb_ary_new2(n);
850
- for (i=0;i<n;i++) {
866
+ for ( i = 0; i < n; i++ ) {
851
867
  VALUE val = rb_tainted_str_new2(PQfname(result, i));
852
868
  ASSOCIATE_INDEX(val, self);
853
- rb_ary_push(ary, val);
869
+ fields[ i ] = val;
854
870
  }
855
- return ary;
871
+
872
+ return rb_ary_new4( n, fields );
856
873
  }
857
874
 
858
875
 
@@ -871,6 +888,8 @@ init_pg_result()
871
888
  rb_define_method(rb_cPGresult, "error_field", pgresult_error_field, 1);
872
889
  rb_define_alias( rb_cPGresult, "result_error_field", "error_field" );
873
890
  rb_define_method(rb_cPGresult, "clear", pg_result_clear, 0);
891
+ rb_define_method(rb_cPGresult, "check", pg_result_check, 0);
892
+ rb_define_alias (rb_cPGresult, "check_result", "check");
874
893
  rb_define_method(rb_cPGresult, "ntuples", pgresult_ntuples, 0);
875
894
  rb_define_alias(rb_cPGresult, "num_tuples", "ntuples");
876
895
  rb_define_method(rb_cPGresult, "nfields", pgresult_nfields, 0);
Binary file
Binary file
data/lib/pg.rb CHANGED
@@ -19,7 +19,7 @@ end
19
19
  module PG
20
20
 
21
21
  # Library version
22
- VERSION = '0.13.2'
22
+ VERSION = '0.14.0.pre.353'
23
23
 
24
24
  # VCS revision
25
25
  REVISION = %q$Revision$
@@ -51,6 +51,13 @@ class PG::Connection
51
51
  return connopts.join(' ')
52
52
  end
53
53
 
54
+
55
+ # Backward-compatibility aliases for stuff that's moved into PG.
56
+ class << self
57
+ define_method( :isthreadsafe, &PG.method(:isthreadsafe) )
58
+ end
59
+
60
+
54
61
  end # class PG::Connection
55
62
 
56
63
  # Backward-compatible alias
@@ -65,6 +65,8 @@ until poll_status == PG::PGRES_POLLING_OK ||
65
65
  output_progress " negotiating SSL encryption."
66
66
  when PG::CONNECTION_SETENV
67
67
  output_progress " negotiating environment-driven parameter settings."
68
+ when PG::CONNECTION_NEEDED
69
+ output_progress " internal state: connect() needed."
68
70
  end
69
71
 
70
72
  # Check to see if it's finished or failed yet
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env ruby
2
+ # vim: set nosta noet ts=4 sw=4:
3
+ # encoding: utf-8
4
+
5
+ require 'pg'
6
+
7
+ # This is a minimal example of a function that can test an existing PG::Connection and
8
+ # reset it if necessary.
9
+
10
+ def check_connection( conn )
11
+ begin
12
+ conn.exec( "SELECT 1" )
13
+ rescue PG::Error => err
14
+ $stderr.puts "%p while testing connection: %s" % [ err.class, err.message ]
15
+ conn.reset
16
+ end
17
+ end
18
+
19
+ conn = PG.connect( dbname: 'test' )
20
+ check_connection( conn )
21
+
@@ -0,0 +1,186 @@
1
+ #!/usr/bin/env ruby
2
+ # vim: set noet nosta sw=4 ts=4 :
3
+ #
4
+ # Quickly dump size information for a given database.
5
+ # Top twenty objects, and size per schema.
6
+ #
7
+ # Mahlon E. Smith <mahlon@martini.nu>
8
+ #
9
+ # Based on work by Jeff Davis <ruby@j-davis.com>.
10
+ #
11
+
12
+
13
+ begin
14
+ require 'ostruct'
15
+ require 'optparse'
16
+ require 'etc'
17
+ require 'pg'
18
+
19
+ rescue LoadError # 1.8 support
20
+ unless Object.const_defined?( :Gem )
21
+ require 'rubygems'
22
+ retry
23
+ end
24
+ raise
25
+ end
26
+
27
+ SCRIPT_VERSION = %q$Id$
28
+
29
+
30
+ ### Gather data and output it to $stdout.
31
+ ###
32
+ def report( opts )
33
+ db = PG.connect(
34
+ :dbname => opts.database,
35
+ :host => opts.host,
36
+ :port => opts.port,
37
+ :user => opts.user,
38
+ :password => opts.pass,
39
+ :sslmode => 'prefer'
40
+ )
41
+
42
+ # -----------------------------------------
43
+
44
+ db_info = db.exec %Q{
45
+ SELECT
46
+ count(oid) AS num_relations,
47
+ pg_size_pretty(pg_database_size('#{opts.database}')) AS dbsize
48
+ FROM
49
+ pg_class
50
+ }
51
+
52
+ puts '=' * 70
53
+ puts "Disk usage information for %s: (%d relations, %s total)" % [
54
+ opts.database,
55
+ db_info[0]['num_relations'],
56
+ db_info[0]['dbsize']
57
+ ]
58
+ puts '=' * 70
59
+
60
+ # -----------------------------------------
61
+
62
+ top_twenty = db.exec %q{
63
+ SELECT
64
+ relname AS name,
65
+ relkind AS kind,
66
+ pg_size_pretty(pg_relation_size(pg_class.oid)) AS size
67
+ FROM
68
+ pg_class
69
+ ORDER BY
70
+ pg_relation_size(pg_class.oid) DESC
71
+ LIMIT 20
72
+ }
73
+
74
+ puts 'Top twenty objects by size:'
75
+ puts '-' * 70
76
+ top_twenty.each do |row|
77
+ type = case row['kind']
78
+ when 'i'; 'index'
79
+ when 't'; 'toast'
80
+ when 'r'; 'table'
81
+ when 'S'; 'sequence'
82
+ else; '???'
83
+ end
84
+
85
+ puts "%40s %10s (%s)" % [ row['name'], row['size'], type ]
86
+ end
87
+ puts '-' * 70
88
+
89
+ # -----------------------------------------
90
+
91
+ schema_sizes = db.exec %q{
92
+ SELECT
93
+ table_schema,
94
+ pg_size_pretty( CAST( SUM(pg_total_relation_size(table_schema || '.' || table_name)) AS bigint)) AS size
95
+ FROM
96
+ information_schema.tables
97
+ GROUP BY
98
+ table_schema
99
+ ORDER BY
100
+ CAST( SUM(pg_total_relation_size(table_schema || '.' || table_name)) AS bigint ) DESC
101
+ }
102
+
103
+
104
+ puts 'Size per schema:'
105
+ puts '-' * 70
106
+ schema_sizes.each do |row|
107
+ puts "%20s %10s" % [ row['table_schema'], row['size'] ]
108
+ end
109
+ puts '-' * 70
110
+ puts
111
+
112
+ db.finish
113
+ end
114
+
115
+
116
+ ### Parse command line arguments. Return a struct of global options.
117
+ ###
118
+ def parse_args( args )
119
+ options = OpenStruct.new
120
+ options.database = Etc.getpwuid( Process.uid ).name
121
+ options.host = '127.0.0.1'
122
+ options.port = 5432
123
+ options.user = Etc.getpwuid( Process.uid ).name
124
+ options.sslmode = 'prefer'
125
+ options.interval = 5
126
+
127
+ opts = OptionParser.new do |opts|
128
+ opts.banner = "Usage: #{$0} [options]"
129
+
130
+ opts.separator ''
131
+ opts.separator 'Connection options:'
132
+
133
+ opts.on( '-d', '--database DBNAME',
134
+ "specify the database to connect to (default: \"#{options.database}\")" ) do |db|
135
+ options.database = db
136
+ end
137
+
138
+ opts.on( '-h', '--host HOSTNAME', 'database server host' ) do |host|
139
+ options.host = host
140
+ end
141
+
142
+ opts.on( '-p', '--port PORT', Integer,
143
+ "database server port (default: \"#{options.port}\")" ) do |port|
144
+ options.port = port
145
+ end
146
+
147
+ opts.on( '-U', '--user NAME',
148
+ "database user name (default: \"#{options.user}\")" ) do |user|
149
+ options.user = user
150
+ end
151
+
152
+ opts.on( '-W', 'force password prompt' ) do |pw|
153
+ print 'Password: '
154
+ begin
155
+ system 'stty -echo'
156
+ options.pass = gets.chomp
157
+ ensure
158
+ system 'stty echo'
159
+ puts
160
+ end
161
+ end
162
+
163
+ opts.separator ''
164
+ opts.separator 'Other options:'
165
+
166
+ opts.on_tail( '--help', 'show this help, then exit' ) do
167
+ $stderr.puts opts
168
+ exit
169
+ end
170
+
171
+ opts.on_tail( '--version', 'output version information, then exit' ) do
172
+ puts SCRIPT_VERSION
173
+ exit
174
+ end
175
+ end
176
+
177
+ opts.parse!( args )
178
+ return options
179
+ end
180
+
181
+
182
+ if __FILE__ == $0
183
+ opts = parse_args( ARGV )
184
+ report( opts )
185
+ end
186
+