pg 0.7.9.2008.02.05 → 0.7.9.2008.03.18

Sign up to get free protection for your applications and to get access to all the features.
Files changed (9) hide show
  1. data/BSD +23 -0
  2. data/README +10 -10
  3. data/ext/compat.c +12 -0
  4. data/ext/compat.h +4 -0
  5. data/ext/extconf.rb +16 -11
  6. data/ext/pg.c +315 -105
  7. data/ext/pg.h +7 -4
  8. metadata +5 -5
  9. data/COPYING +0 -340
data/BSD ADDED
@@ -0,0 +1,23 @@
1
+ PostgreSQL Database Management System
2
+ (formerly known as Postgres, then as Postgres95)
3
+
4
+ Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
5
+
6
+ Portions Copyright (c) 1994, The Regents of the University of California
7
+
8
+ Permission to use, copy, modify, and distribute this software and its
9
+ documentation for any purpose, without fee, and without a written agreement
10
+ is hereby granted, provided that the above copyright notice and this
11
+ paragraph and the following two paragraphs appear in all copies.
12
+
13
+ IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
14
+ DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
15
+ LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
16
+ DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE
17
+ POSSIBILITY OF SUCH DAMAGE.
18
+
19
+ THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
20
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
21
+ AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
22
+ ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO
23
+ PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
data/README CHANGED
@@ -22,9 +22,13 @@ Maintainer:
22
22
  Jeff Davis <ruby-pg@j-davis.com>
23
23
 
24
24
  Copying:
25
- You may redistribute this software under the terms of the GPL,
26
- included in the file named GPL; or under the same terms as Ruby,
27
- included in the file name LICENSE.
25
+ You may redistribute this software under the terms of the Ruby license,
26
+ included in the file "LICENSE". The Ruby license also allows distribution
27
+ under the terms of the GPL, included in the file "COPYING.txt" and the
28
+ file "GPL".
29
+
30
+ Portions of the code are from the PostgreSQL project, and are distributed
31
+ under the terms of the BSD license, included in the file "BSD".
28
32
 
29
33
  - Summary
30
34
 
@@ -34,7 +38,7 @@ This library works with PostgreSQL 7.4 and later.
34
38
  - Requirements
35
39
 
36
40
  Ruby 1.8 or later.
37
- PostgreSQL 7.4 or later installed.
41
+ PostgreSQL 7.3 or later installed.
38
42
 
39
43
  It may work with earlier versions as well, but those are
40
44
  not regularly tested.
@@ -75,8 +79,7 @@ For example:
75
79
  - How to use ?
76
80
 
77
81
  This gem builds and installs two PostgreSQL database adapters, 'postgres'
78
- and 'pg'. 'postgres' is currently (Jan 2008) the recommended PostgreSQL
79
- adapter for use with Rails.
82
+ and 'pg'.
80
83
 
81
84
  The standard way to download and install the most current stable
82
85
  version of the postgres gem (from http://gems.rubyforge.org) is to use
@@ -98,14 +101,11 @@ on Mac OS X with PostgreSQL in /Library/PostgreSQL8 use
98
101
  --with-pgsql-include-dir=/Library/PostgreSQL8/include --with-pgsql-lib-
99
102
  dir=/Library/PostgreSQL8/lib
100
103
 
101
- To use the postgres adapter with Rails:
104
+ To use the module with Rails:
102
105
  refer to it as
103
106
  adapter: postgresql
104
107
  in your database:yaml file
105
108
 
106
- The pg adapter cannot be used with Rails yet and is available for
107
- testing and developer use.
108
-
109
109
  To use these modules in Ruby directly (not Rails), refer to the RDoc
110
110
  documentation.
111
111
 
@@ -209,6 +209,18 @@ PQfformat(const PGresult *res, int column_number)
209
209
  {
210
210
  rb_raise(rb_eStandardError, "PQfformat not supported by this client version.");
211
211
  }
212
+
213
+ PQnoticeReceiver
214
+ PQsetNoticeReceiver(PGconn *conn, PQnoticeReceiver proc, void *arg)
215
+ {
216
+ rb_raise(rb_eStandardError, "PQsetNoticeReceiver not supported by this client version.");
217
+ }
218
+
219
+ char *
220
+ PQresultErrorField(const PGresult *res, int fieldcode)
221
+ {
222
+ rb_raise(rb_eStandardError, "PQresultErrorField not supported by this client version.");
223
+ }
212
224
  #endif /* PG_BEFORE_070400 */
213
225
 
214
226
  #ifdef PG_BEFORE_070300
@@ -118,6 +118,8 @@ int PQserverVersion(const PGconn* conn);
118
118
  */
119
119
  #define CONNECTION_SSL_STARTUP 1000000
120
120
 
121
+ typedef void (*PQnoticeReceiver) (void *arg, const PGresult *res);
122
+
121
123
  typedef enum
122
124
  {
123
125
  PQERRORS_TERSE, /* single-line error messages */
@@ -156,6 +158,8 @@ PGVerbosity PQsetErrorVerbosity(PGconn *conn, PGVerbosity verbosity);
156
158
  Oid PQftable(const PGresult *res, int column_number);
157
159
  int PQftablecol(const PGresult *res, int column_number);
158
160
  int PQfformat(const PGresult *res, int column_number);
161
+ char *PQresultErrorField(const PGresult *res, int fieldcode);
162
+ PQnoticeReceiver PQsetNoticeReceiver(PGconn *conn, PQnoticeReceiver proc, void *arg);
159
163
 
160
164
  #else
161
165
  #define PGNOTIFY_EXTRA(notify) ((notify)->extra)
@@ -1,14 +1,25 @@
1
1
  require 'mkmf'
2
2
 
3
+ unless system("pg_config --bindir > /dev/null")
4
+ $stderr.write("ERROR: can't find pg_config.\n")
5
+ $stderr.write("HINT: Make sure pg_config is in your PATH\n")
6
+ exit 1
7
+ end
8
+
3
9
  # OS X compatibility
4
- if(PLATFORM =~ /darwin/) then
10
+ if(RUBY_PLATFORM =~ /darwin/) then
5
11
  # test if postgresql is probably universal
6
12
  bindir = (IO.popen("pg_config --bindir").readline.chomp rescue nil)
7
13
  filetype = (IO.popen("file #{bindir}/pg_config").
8
14
  readline.chomp rescue nil)
9
15
  # if it's not universal, ARCHFLAGS should be set
10
16
  if((filetype !~ /universal binary/) && ENV['ARCHFLAGS'].nil?) then
11
- arch = (IO.popen("uname -m").readline.chomp rescue nil)
17
+ arch_tmp = (IO.popen("uname -p").readline.chomp rescue nil)
18
+ if(arch_tmp == 'powerpc')
19
+ arch = 'ppc'
20
+ else
21
+ arch = 'i386'
22
+ end
12
23
  $stderr.write %{
13
24
  =========== WARNING ===========
14
25
 
@@ -32,13 +43,6 @@ if(PLATFORM =~ /darwin/) then
32
43
  end
33
44
  end
34
45
 
35
- # windows compatibility, need different library name
36
- if(PLATFORM =~ /mingw|mswin/) then
37
- $libname = '/ms/libpq'
38
- else
39
- $libname = 'pq'
40
- end
41
-
42
46
  if RUBY_VERSION < '1.8'
43
47
  puts 'This library is for ruby-1.8 or higher.'
44
48
  exit 1
@@ -53,10 +57,11 @@ def pg_config(type)
53
57
  end
54
58
 
55
59
  def have_build_env
56
- have_library($libname) && have_header('libpq-fe.h') && have_header('libpq/libpq-fs.h')
60
+ (have_library('pq') || have_library('libpq') || have_library('ms/libpq')) &&
61
+ have_header('libpq-fe.h') && have_header('libpq/libpq-fs.h')
57
62
  end
58
63
 
59
- dir_config('pgsql', config_value('include'), config_value('lib'))
64
+ dir_config('pg', config_value('include'), config_value('lib'))
60
65
 
61
66
  desired_functions = %w(
62
67
  PQconnectionUsedPassword
data/ext/pg.c CHANGED
@@ -9,7 +9,7 @@
9
9
  modified at: Wed Jan 20 16:41:51 1999
10
10
 
11
11
  $Author: jdavis $
12
- $Date: 2008-02-05 11:23:59 -0800 (Tue, 05 Feb 2008) $
12
+ $Date: 2008-03-18 09:44:07 -0700 (Tue, 18 Mar 2008) $
13
13
  ************************************************/
14
14
 
15
15
  #include "pg.h"
@@ -52,6 +52,9 @@ static VALUE pgconn_finish(VALUE self);
52
52
  static VALUE pgresult_clear(VALUE self);
53
53
  static VALUE pgresult_aref(VALUE self, VALUE index);
54
54
 
55
+ static PQnoticeReceiver default_notice_receiver = NULL;
56
+ static PQnoticeProcessor default_notice_processor = NULL;
57
+
55
58
  /*
56
59
  * Used to quote the values passed in a Hash to PGconn.init
57
60
  * when building the connection string.
@@ -108,13 +111,15 @@ value_as_cstring(VALUE in_str)
108
111
  static void
109
112
  free_pgconn(PGconn *conn)
110
113
  {
111
- PQfinish(conn);
114
+ if(conn != NULL)
115
+ PQfinish(conn);
112
116
  }
113
117
 
114
118
  static void
115
119
  free_pgresult(PGresult *result)
116
120
  {
117
- PQclear(result);
121
+ if(result != NULL)
122
+ PQclear(result);
118
123
  }
119
124
 
120
125
  static PGconn*
@@ -187,6 +192,45 @@ static VALUE yield_pgresult(VALUE rb_pgresult)
187
192
  return Qnil;
188
193
  }
189
194
 
195
+ static void
196
+ notice_receiver_proxy(void *arg, const PGresult *result)
197
+ {
198
+ VALUE proc;
199
+ VALUE self = (VALUE)arg;
200
+
201
+ if ((proc = rb_iv_get(self, "@notice_receiver")) != Qnil) {
202
+ rb_funcall(proc, rb_intern("call"), 1,
203
+ Data_Wrap_Struct(rb_cPGresult, NULL, NULL, (PGresult*)result));
204
+ }
205
+ return;
206
+ }
207
+
208
+ static void
209
+ notice_processor_proxy(void *arg, const char *message)
210
+ {
211
+ VALUE proc;
212
+ VALUE self = (VALUE)arg;
213
+
214
+ if ((proc = rb_iv_get(self, "@notice_processor")) != Qnil) {
215
+ rb_funcall(proc, rb_intern("call"), 1, rb_tainted_str_new2(message));
216
+ }
217
+ return;
218
+ }
219
+
220
+ /********************************************************************
221
+ *
222
+ * Document-class: PGError
223
+ *
224
+ * This is the exception class raised when an error is returned from
225
+ * a libpq API call.
226
+ *
227
+ * The attributes +connection+ and +result+ are set to the connection
228
+ * object and result set object, respectively.
229
+ *
230
+ * If the connection object or result set object is not available from
231
+ * the context in which the error was encountered, it is +nil+.
232
+ */
233
+
190
234
  /********************************************************************
191
235
  *
192
236
  * Document-class: PGconn
@@ -207,17 +251,13 @@ static VALUE yield_pgresult(VALUE rb_pgresult)
207
251
 
208
252
  #ifdef HAVE_RB_DEFINE_ALLOC_FUNC
209
253
  static VALUE
210
- pgconn_alloc(klass)
211
- VALUE klass;
254
+ pgconn_alloc(VALUE klass)
212
255
  {
213
256
  return Data_Wrap_Struct(klass, NULL, free_pgconn, NULL);
214
257
  }
215
258
  #else
216
259
  static VALUE
217
- pgconn_s_new(argc, argv, klass)
218
- int argc;
219
- VALUE *argv;
220
- VALUE klass;
260
+ pgconn_s_new(int argc, VALUE *argv, VALUE klass)
221
261
  {
222
262
  VALUE self = rb_obj_alloc(klass);
223
263
  rb_obj_call_init(self, argc, argv);
@@ -269,7 +309,6 @@ pgconn_init(argc, argv, self)
269
309
  char *conninfo = NULL;
270
310
  VALUE conninfo_rstr;
271
311
  VALUE error;
272
- VALUE temp;
273
312
  char *host, *port, *opt, *tty, *dbname, *login, *pwd;
274
313
  host=port=opt=tty=dbname=login=pwd=NULL;
275
314
 
@@ -332,6 +371,17 @@ pgconn_init(argc, argv, self)
332
371
  return self;
333
372
  }
334
373
 
374
+ /*TODO
375
+ * call-seq:
376
+ * PGconn.connect_start( ... ) -> PGconn
377
+ */
378
+ static VALUE
379
+ pgconn_s_connect_start(int argc, VALUE *argv, VALUE self)
380
+ {
381
+ rb_raise(rb_eStandardError, "PGconn.connect_start unimplemented.");
382
+ return Qnil;
383
+ }
384
+
335
385
  /*
336
386
  * call-seq:
337
387
  * PGconn.conndefaults() -> Array
@@ -422,6 +472,20 @@ pgconn_s_isthreadsafe(self)
422
472
  * PGconn INSTANCE METHODS
423
473
  **************************************************************************/
424
474
 
475
+ /*TODO
476
+ * call-seq:
477
+ * conn.connect_poll() -> Fixnum
478
+ *
479
+ *
480
+ */
481
+ static VALUE
482
+ pgconn_connect_poll(VALUE self)
483
+ {
484
+ PostgresPollingStatusType status;
485
+ status = PQconnectPoll(get_pgconn(self));
486
+ return INT2FIX((int)status);
487
+ }
488
+
425
489
  /*
426
490
  * call-seq:
427
491
  * conn.finish()
@@ -441,7 +505,8 @@ pgconn_finish(self)
441
505
  * call-seq:
442
506
  * conn.reset()
443
507
  *
444
- * Resets the backend connection. This method closes the backend connection and tries to re-connect.
508
+ * Resets the backend connection. This method closes the
509
+ * backend connection and tries to re-connect.
445
510
  */
446
511
  static VALUE
447
512
  pgconn_reset(self)
@@ -451,9 +516,39 @@ pgconn_reset(self)
451
516
  return self;
452
517
  }
453
518
 
454
- //TODO conn.reset_start
519
+ /*
520
+ * call-seq:
521
+ * conn.reset_start() -> nil
522
+ *
523
+ * Initiate a connection reset in a nonblocking manner.
524
+ * This will close the current connection and attempt to
525
+ * reconnect using the same connection parameters.
526
+ * Use PGconn#reset_poll to check the status of the
527
+ * connection reset.
528
+ */
529
+ static VALUE
530
+ pgconn_reset_start(VALUE self)
531
+ {
532
+ if(PQresetStart(get_pgconn(self)) == 0)
533
+ rb_raise(rb_ePGError, "reset has failed");
534
+ return Qnil;
535
+ }
455
536
 
456
- //TODO conn.reset_poll
537
+ /*
538
+ * call-seq:
539
+ * conn.reset_poll -> Fixnum
540
+ *
541
+ * Checks the status of a connection reset operation.
542
+ * See PGconn#connect_start and PGconn#connect_poll for
543
+ * usage information and return values.
544
+ */
545
+ static VALUE
546
+ pgconn_reset_poll(VALUE self)
547
+ {
548
+ PostgresPollingStatusType status;
549
+ status = PQresetPoll(get_pgconn(self));
550
+ return INT2FIX((int)status);
551
+ }
457
552
 
458
553
  /*
459
554
  * call-seq:
@@ -663,14 +758,20 @@ pgconn_error_message(self)
663
758
  return rb_tainted_str_new2(error);
664
759
  }
665
760
 
666
- //TODO PQsocket
667
761
  /*
668
762
  * call-seq:
669
- * conn.socket() -> TCPSocket
763
+ * conn.socket() -> Fixnum
670
764
  *
671
- * Returns the socket file descriptor of this
672
- * connection.
765
+ * Returns the socket's file descriptor for this connection.
673
766
  */
767
+ static VALUE
768
+ pgconn_socket(VALUE self)
769
+ {
770
+ int sd;
771
+ if( (sd = PQsocket(get_pgconn(self))) < 0)
772
+ rb_raise(rb_ePGError, "Can't get socket descriptor");
773
+ return INT2NUM(sd);
774
+ }
674
775
 
675
776
 
676
777
  /*
@@ -820,14 +921,19 @@ pgconn_exec(argc, argv, self)
820
921
  param_format = rb_hash_aref(param, sym_format);
821
922
  }
822
923
  else {
823
- param_type = INT2NUM(0);
924
+ param_type = Qnil;
824
925
  if(param == Qnil)
825
926
  param_value = param;
826
927
  else
827
928
  param_value = rb_obj_as_string(param);
828
- param_format = INT2NUM(0);
929
+ param_format = Qnil;
829
930
  }
830
- paramTypes[i] = NUM2INT(param_type);
931
+
932
+ if(param_type == Qnil)
933
+ paramTypes[i] = 0;
934
+ else
935
+ paramTypes[i] = NUM2INT(param_type);
936
+
831
937
  if(param_value == Qnil) {
832
938
  paramValues[i] = NULL;
833
939
  paramLengths[i] = 0;
@@ -835,9 +941,13 @@ pgconn_exec(argc, argv, self)
835
941
  else {
836
942
  Check_Type(param_value, T_STRING);
837
943
  paramValues[i] = StringValuePtr(param_value);
838
- paramLengths[i] = RSTRING_LEN(param_value) + 1;
944
+ paramLengths[i] = RSTRING_LEN(param_value);
839
945
  }
840
- paramFormats[i] = NUM2INT(param_format);
946
+
947
+ if(param_format == Qnil)
948
+ paramFormats[i] = 0;
949
+ else
950
+ paramFormats[i] = NUM2INT(param_format);
841
951
  }
842
952
 
843
953
  result = PQexecParams(conn, StringValuePtr(command), nParams, paramTypes,
@@ -903,7 +1013,10 @@ pgconn_prepare(argc, argv, self)
903
1013
  for(i = 0; i < nParams; i++) {
904
1014
  param = rb_ary_entry(in_paramtypes, i);
905
1015
  Check_Type(param, T_FIXNUM);
906
- paramTypes[i] = NUM2INT(param);
1016
+ if(param == Qnil)
1017
+ paramTypes[i] = 0;
1018
+ else
1019
+ paramTypes[i] = NUM2INT(param);
907
1020
  }
908
1021
  }
909
1022
  result = PQprepare(conn, StringValuePtr(name), StringValuePtr(command),
@@ -1009,9 +1122,13 @@ pgconn_exec_prepared(argc, argv, self)
1009
1122
  else {
1010
1123
  Check_Type(param_value, T_STRING);
1011
1124
  paramValues[i] = StringValuePtr(param_value);
1012
- paramLengths[i] = RSTRING_LEN(param_value) + 1;
1125
+ paramLengths[i] = RSTRING_LEN(param_value);
1013
1126
  }
1014
- paramFormats[i] = NUM2INT(param_format);
1127
+
1128
+ if(param_format == Qnil)
1129
+ paramFormats[i] = 0;
1130
+ else
1131
+ paramFormats[i] = NUM2INT(param_format);
1015
1132
  }
1016
1133
 
1017
1134
  result = PQexecPrepared(conn, StringValuePtr(name), nParams,
@@ -1342,7 +1459,12 @@ pgconn_send_query(argc, argv, self)
1342
1459
  param_value = rb_obj_as_string(param);
1343
1460
  param_format = INT2NUM(0);
1344
1461
  }
1345
- paramTypes[i] = NUM2INT(param_type);
1462
+
1463
+ if(param_type == Qnil)
1464
+ paramTypes[i] = 0;
1465
+ else
1466
+ paramTypes[i] = NUM2INT(param_type);
1467
+
1346
1468
  if(param_value == Qnil) {
1347
1469
  paramValues[i] = NULL;
1348
1470
  paramLengths[i] = 0;
@@ -1350,9 +1472,13 @@ pgconn_send_query(argc, argv, self)
1350
1472
  else {
1351
1473
  Check_Type(param_value, T_STRING);
1352
1474
  paramValues[i] = StringValuePtr(param_value);
1353
- paramLengths[i] = RSTRING_LEN(param_value) + 1;
1475
+ paramLengths[i] = RSTRING_LEN(param_value);
1354
1476
  }
1355
- paramFormats[i] = NUM2INT(param_format);
1477
+
1478
+ if(param_format == Qnil)
1479
+ paramFormats[i] = 0;
1480
+ else
1481
+ paramFormats[i] = NUM2INT(param_format);
1356
1482
  }
1357
1483
 
1358
1484
  result = PQsendQueryParams(conn, StringValuePtr(command), nParams, paramTypes,
@@ -1417,7 +1543,10 @@ pgconn_send_prepare(argc, argv, self)
1417
1543
  for(i = 0; i < nParams; i++) {
1418
1544
  param = rb_ary_entry(in_paramtypes, i);
1419
1545
  Check_Type(param, T_FIXNUM);
1420
- paramTypes[i] = NUM2INT(param);
1546
+ if(param == Qnil)
1547
+ paramTypes[i] = 0;
1548
+ else
1549
+ paramTypes[i] = NUM2INT(param);
1421
1550
  }
1422
1551
  }
1423
1552
  result = PQsendPrepare(conn, StringValuePtr(name), StringValuePtr(command),
@@ -1519,6 +1648,7 @@ pgconn_send_query_prepared(argc, argv, self)
1519
1648
  param_value = rb_obj_as_string(param);
1520
1649
  param_format = INT2NUM(0);
1521
1650
  }
1651
+
1522
1652
  if(param_value == Qnil) {
1523
1653
  paramValues[i] = NULL;
1524
1654
  paramLengths[i] = 0;
@@ -1526,9 +1656,13 @@ pgconn_send_query_prepared(argc, argv, self)
1526
1656
  else {
1527
1657
  Check_Type(param_value, T_STRING);
1528
1658
  paramValues[i] = StringValuePtr(param_value);
1529
- paramLengths[i] = RSTRING_LEN(param_value) + 1;
1659
+ paramLengths[i] = RSTRING_LEN(param_value);
1530
1660
  }
1531
- paramFormats[i] = NUM2INT(param_format);
1661
+
1662
+ if(param_format == Qnil)
1663
+ paramFormats[i] = 0;
1664
+ else
1665
+ paramFormats[i] = NUM2INT(param_format);
1532
1666
  }
1533
1667
 
1534
1668
  result = PQsendQueryPrepared(conn, StringValuePtr(name), nParams,
@@ -1911,31 +2045,54 @@ pgconn_set_error_verbosity(VALUE self, VALUE in_verbosity)
1911
2045
  return INT2FIX(PQsetErrorVerbosity(conn, verbosity));
1912
2046
  }
1913
2047
 
1914
- /*TODO
2048
+ /*
1915
2049
  * call-seq:
1916
- * conn.trace( port )
2050
+ * conn.trace( stream ) -> nil
1917
2051
  *
1918
- * Enables tracing message passing between backend.
1919
- * The trace message will be written to the _port_ object,
1920
- * which is an instance of the class +File+.
2052
+ * Enables tracing message passing between backend. The
2053
+ * trace message will be written to the stream _stream_,
2054
+ * which must implement a method +fileno+ that returns
2055
+ * a writable file descriptor.
1921
2056
  */
1922
2057
  static VALUE
1923
- pgconn_trace(self, port)
1924
- VALUE self, port;
2058
+ pgconn_trace(VALUE self, VALUE stream)
1925
2059
  {
1926
- //OpenFile* fp;
2060
+ FILE *fp;
2061
+ VALUE fileno;
2062
+ FILE *new_fp;
2063
+ int old_fd, new_fd;
2064
+ VALUE new_file;
1927
2065
 
1928
- Check_Type(port, T_FILE);
1929
- //GetOpenFile(port, fp);
2066
+ if(rb_respond_to(stream,rb_intern("fileno")) == Qfalse)
2067
+ rb_raise(rb_eArgError, "stream does not respond to method: fileno");
1930
2068
 
1931
- //PQtrace(get_pgconn(self), fp->f2?fp->f2:fp->f);
2069
+ fileno = rb_funcall(stream, rb_intern("fileno"), 0);
2070
+ if(fileno == Qnil)
2071
+ rb_raise(rb_eArgError, "can't get file descriptor from stream");
1932
2072
 
1933
- return self;
2073
+ /* Duplicate the file descriptor and re-open
2074
+ * it. Then, make it into a ruby File object
2075
+ * and assign it to an instance variable.
2076
+ * This prevents a problem when the File
2077
+ * object passed to this function is closed
2078
+ * before the connection object is. */
2079
+ old_fd = NUM2INT(fileno);
2080
+ new_fd = dup(old_fd);
2081
+ new_fp = fdopen(new_fd, "w");
2082
+
2083
+ if(new_fp == NULL)
2084
+ rb_raise(rb_eArgError, "stream is not writable");
2085
+
2086
+ new_file = rb_funcall(rb_cIO, rb_intern("new"), 1, INT2NUM(new_fd));
2087
+ rb_iv_set(self, "@trace_stream", new_file);
2088
+
2089
+ PQtrace(get_pgconn(self), new_fp);
2090
+ return Qnil;
1934
2091
  }
1935
2092
 
1936
2093
  /*
1937
2094
  * call-seq:
1938
- * conn.untrace()
2095
+ * conn.untrace() -> nil
1939
2096
  *
1940
2097
  * Disables the message tracing.
1941
2098
  */
@@ -1943,14 +2100,105 @@ static VALUE
1943
2100
  pgconn_untrace(self)
1944
2101
  VALUE self;
1945
2102
  {
1946
- PQuntrace(get_pgconn(self));
1947
- return self;
2103
+ VALUE trace_stream;
2104
+ PQuntrace(get_pgconn(self));
2105
+ trace_stream = rb_iv_get(self, "@trace_stream");
2106
+ rb_funcall(trace_stream, rb_intern("close"), 0);
2107
+ rb_iv_set(self, "@trace_stream", Qnil);
2108
+ return Qnil;
1948
2109
  }
1949
2110
 
1950
- //TODO set_notice_receiver
2111
+ /*
2112
+ * call-seq:
2113
+ * conn.set_notice_receiver {|result| ... } -> Proc
2114
+ *
2115
+ * Notice and warning messages generated by the server are not returned
2116
+ * by the query execution functions, since they do not imply failure of
2117
+ * the query. Instead they are passed to a notice handling function, and
2118
+ * execution continues normally after the handler returns. The default
2119
+ * notice handling function prints the message on <tt>stderr</tt>, but the
2120
+ * application can override this behavior by supplying its own handling
2121
+ * function.
2122
+ *
2123
+ * This function takes a new block to act as the handler, which should
2124
+ * accept a single parameter that will be a PGresult object, and returns
2125
+ * the Proc object previously set, or +nil+ if it was previously the default.
2126
+ *
2127
+ * If you pass no arguments, it will reset the handler to the default.
2128
+ */
2129
+ static VALUE
2130
+ pgconn_set_notice_receiver(VALUE self)
2131
+ {
2132
+ VALUE proc, old_proc;
2133
+ PGconn *conn = get_pgconn(self);
2134
+
2135
+ /* If default_notice_receiver is unset, assume that the current
2136
+ * notice receiver is the default, and save it to a global variable.
2137
+ * This should not be a problem because the default receiver is
2138
+ * always the same, so won't vary among connections.
2139
+ */
2140
+ if(default_notice_receiver == NULL)
2141
+ default_notice_receiver = PQsetNoticeReceiver(conn, NULL, NULL);
2142
+
2143
+ old_proc = rb_iv_get(self, "@notice_receiver");
2144
+ if( rb_block_given_p() ) {
2145
+ proc = rb_block_proc();
2146
+ PQsetNoticeReceiver(conn, notice_receiver_proxy, (void *)self);
2147
+ } else {
2148
+ /* if no block is given, set back to default */
2149
+ proc = Qnil;
2150
+ PQsetNoticeReceiver(conn, default_notice_receiver, NULL);
2151
+ }
1951
2152
 
1952
- //TODO set_notice_processor
2153
+ rb_iv_set(self, "@notice_receiver", proc);
2154
+ return old_proc;
2155
+ }
1953
2156
 
2157
+ /*
2158
+ * call-seq:
2159
+ * conn.set_notice_processor {|message| ... } -> Proc
2160
+ *
2161
+ * Notice and warning messages generated by the server are not returned
2162
+ * by the query execution functions, since they do not imply failure of
2163
+ * the query. Instead they are passed to a notice handling function, and
2164
+ * execution continues normally after the handler returns. The default
2165
+ * notice handling function prints the message on <tt>stderr</tt>, but the
2166
+ * application can override this behavior by supplying its own handling
2167
+ * function.
2168
+ *
2169
+ * This function takes a new block to act as the handler, which should
2170
+ * accept a single parameter that will be a PGresult object, and returns
2171
+ * the Proc object previously set, or +nil+ if it was previously the default.
2172
+ *
2173
+ * If you pass no arguments, it will reset the handler to the default.
2174
+ */
2175
+ static VALUE
2176
+ pgconn_set_notice_processor(VALUE self)
2177
+ {
2178
+ VALUE proc, old_proc;
2179
+ PGconn *conn = get_pgconn(self);
2180
+
2181
+ /* If default_notice_processor is unset, assume that the current
2182
+ * notice processor is the default, and save it to a global variable.
2183
+ * This should not be a problem because the default processor is
2184
+ * always the same, so won't vary among connections.
2185
+ */
2186
+ if(default_notice_processor == NULL)
2187
+ default_notice_processor = PQsetNoticeProcessor(conn, NULL, NULL);
2188
+
2189
+ old_proc = rb_iv_get(self, "@notice_processor");
2190
+ if( rb_block_given_p() ) {
2191
+ proc = rb_block_proc();
2192
+ PQsetNoticeProcessor(conn, notice_processor_proxy, (void *)self);
2193
+ } else {
2194
+ /* if no block is given, set back to default */
2195
+ proc = Qnil;
2196
+ PQsetNoticeProcessor(conn, default_notice_processor, NULL);
2197
+ }
2198
+
2199
+ rb_iv_set(self, "@notice_processor", proc);
2200
+ return old_proc;
2201
+ }
1954
2202
  /*
1955
2203
  * call-seq:
1956
2204
  * conn.get_client_encoding() -> String
@@ -2002,20 +2250,17 @@ pgconn_transaction(VALUE self)
2002
2250
  result = PQexec(conn, "BEGIN");
2003
2251
  rb_pgresult = new_pgresult(result);
2004
2252
  pgresult_check(self, rb_pgresult);
2005
- fprintf(stderr,"BEGIN\n");
2006
2253
  rb_protect(rb_yield, self, &status);
2007
2254
  if(status == 0) {
2008
2255
  result = PQexec(conn, "COMMIT");
2009
2256
  rb_pgresult = new_pgresult(result);
2010
2257
  pgresult_check(self, rb_pgresult);
2011
- fprintf(stderr,"COMMIT\n");
2012
2258
  }
2013
2259
  else {
2014
2260
  /* exception occurred, ROLLBACK and re-raise */
2015
2261
  result = PQexec(conn, "ROLLBACK");
2016
2262
  rb_pgresult = new_pgresult(result);
2017
2263
  pgresult_check(self, rb_pgresult);
2018
- fprintf(stderr,"ROLLBACK\n");
2019
2264
  rb_jump_tag(status);
2020
2265
  }
2021
2266
 
@@ -2055,7 +2300,7 @@ pgconn_s_quote_ident(VALUE self, VALUE in_str)
2055
2300
  /* result size at most NAMEDATALEN*2 plus surrounding
2056
2301
  * double-quotes. */
2057
2302
  char buffer[NAMEDATALEN*2+2];
2058
- int i=0,j=0;
2303
+ unsigned int i=0,j=0;
2059
2304
 
2060
2305
  if(strlen(str) >= NAMEDATALEN) {
2061
2306
  rb_raise(rb_eArgError,
@@ -2139,13 +2384,10 @@ static VALUE
2139
2384
  pgconn_get_last_result(VALUE self)
2140
2385
  {
2141
2386
  VALUE ret, result;
2142
- int result_found = 0;
2387
+ ret = Qnil;
2143
2388
  while((result = pgconn_get_result(self)) != Qnil) {
2144
2389
  ret = result;
2145
- result_found = 1;
2146
2390
  }
2147
- if(!result_found)
2148
- return Qnil;
2149
2391
  return ret;
2150
2392
  }
2151
2393
 
@@ -2168,45 +2410,6 @@ pgconn_async_exec(int argc, VALUE *argv, VALUE self)
2168
2410
  return pgconn_get_last_result(self);
2169
2411
  }
2170
2412
 
2171
- /*TODO */
2172
- static void
2173
- notice_proxy(self, message)
2174
- VALUE self;
2175
- const char *message;
2176
- {
2177
- VALUE block;
2178
- if ((block = rb_iv_get(self, "@on_notice")) != Qnil) {
2179
- rb_funcall(block, rb_intern("call"), 1, rb_str_new2(message));
2180
- }
2181
- }
2182
-
2183
- /*TODO
2184
- * call-seq:
2185
- * conn.on_notice {|message| ... }
2186
- *
2187
- * Notice and warning messages generated by the server are not returned
2188
- * by the query execution functions, since they do not imply failure of
2189
- * the query. Instead they are passed to a notice handling function, and
2190
- * execution continues normally after the handler returns. The default
2191
- * notice handling function prints the message on <tt>stderr</tt>, but the
2192
- * application can override this behavior by supplying its own handling
2193
- * function.
2194
- */
2195
- static VALUE
2196
- pgconn_set_notice_processor(self)
2197
- VALUE self;
2198
- {
2199
- VALUE block = rb_block_proc();
2200
- PGconn *conn = get_pgconn(self);
2201
- if (PQsetNoticeProcessor(conn, NULL, NULL) != notice_proxy) {
2202
- PQsetNoticeProcessor(conn, notice_proxy, (void *) self);
2203
- }
2204
- rb_iv_set(self, "@on_notice", block);
2205
- return self;
2206
- }
2207
-
2208
-
2209
-
2210
2413
  /**************************************************************************
2211
2414
  * LARGE OBJECT SUPPORT
2212
2415
  **************************************************************************/
@@ -2612,10 +2815,11 @@ pgresult_result_error_message(self)
2612
2815
  * * +PG_DIAG_SOURCE_FUNCTION+
2613
2816
  */
2614
2817
  static VALUE
2615
- pgresult_result_error_field(self)
2616
- VALUE self;
2818
+ pgresult_result_error_field(VALUE self, VALUE field)
2617
2819
  {
2618
- return rb_tainted_str_new2(PQresultErrorMessage(get_pgresult(self)));
2820
+ PGresult *result = get_pgresult(self);
2821
+ int fieldcode = NUM2INT(field);
2822
+ return rb_tainted_str_new2(PQresultErrorField(result,fieldcode));
2619
2823
  }
2620
2824
 
2621
2825
  /*
@@ -2629,7 +2833,7 @@ pgresult_clear(self)
2629
2833
  VALUE self;
2630
2834
  {
2631
2835
  PQclear(get_pgresult(self));
2632
- DATA_PTR(self) = 0;
2836
+ DATA_PTR(self) = NULL;
2633
2837
  return Qnil;
2634
2838
  }
2635
2839
 
@@ -2864,7 +3068,8 @@ pgresult_getvalue(self, tup_num, field_num)
2864
3068
  }
2865
3069
  if(PQgetisnull(result, i, j))
2866
3070
  return Qnil;
2867
- return rb_tainted_str_new2(PQgetvalue(result, i, j));
3071
+ return rb_tainted_str_new(PQgetvalue(result, i, j),
3072
+ PQgetlength(result, i, j));
2868
3073
  }
2869
3074
 
2870
3075
  /*
@@ -3032,7 +3237,8 @@ pgresult_aref(self, index)
3032
3237
  rb_hash_aset(tuple, fname, Qnil);
3033
3238
  }
3034
3239
  else {
3035
- val = rb_tainted_str_new2(PQgetvalue(result, tuple_num, field_num));
3240
+ val = rb_tainted_str_new(PQgetvalue(result, tuple_num, field_num),
3241
+ PQgetlength(result, tuple_num, field_num));
3036
3242
  rb_hash_aset(tuple, fname, val);
3037
3243
  }
3038
3244
  }
@@ -3119,6 +3325,7 @@ Init_pg()
3119
3325
  rb_define_singleton_method(rb_cPGconn, "isthreadsafe", pgconn_s_isthreadsafe, 0);
3120
3326
  rb_define_singleton_method(rb_cPGconn, "encrypt_password", pgconn_s_encrypt_password, 0);
3121
3327
  rb_define_singleton_method(rb_cPGconn, "quote_ident", pgconn_s_quote_ident, 1);
3328
+ rb_define_singleton_method(rb_cPGconn, "connect_start", pgconn_s_connect_start, -1);
3122
3329
  rb_define_singleton_method(rb_cPGconn, "conndefaults", pgconn_s_conndefaults, 0);
3123
3330
 
3124
3331
  /****** PGconn CLASS CONSTANTS: Connection Status ******/
@@ -3160,9 +3367,12 @@ Init_pg()
3160
3367
 
3161
3368
  /****** PGconn INSTANCE METHODS: Connection Control ******/
3162
3369
  rb_define_method(rb_cPGconn, "initialize", pgconn_init, -1);
3370
+ rb_define_method(rb_cPGconn, "connect_poll", pgconn_connect_poll, 0);
3371
+ rb_define_method(rb_cPGconn, "finish", pgconn_finish, 0);
3163
3372
  rb_define_method(rb_cPGconn, "reset", pgconn_reset, 0);
3373
+ rb_define_method(rb_cPGconn, "reset_start", pgconn_reset_start, 0);
3374
+ rb_define_method(rb_cPGconn, "reset_poll", pgconn_reset_poll, 0);
3164
3375
  rb_define_method(rb_cPGconn, "conndefaults", pgconn_s_conndefaults, 0);
3165
- rb_define_method(rb_cPGconn, "finish", pgconn_finish, 0);
3166
3376
  rb_define_alias(rb_cPGconn, "close", "finish");
3167
3377
 
3168
3378
  /****** PGconn INSTANCE METHODS: Connection Status ******/
@@ -3179,7 +3389,7 @@ Init_pg()
3179
3389
  rb_define_method(rb_cPGconn, "protocol_version", pgconn_protocol_version, 0);
3180
3390
  rb_define_method(rb_cPGconn, "server_version", pgconn_server_version, 0);
3181
3391
  rb_define_method(rb_cPGconn, "error_message", pgconn_error_message, 0);
3182
- //rb_define_method(rb_cPGconn, "socket", pgconn_socket, 0);
3392
+ rb_define_method(rb_cPGconn, "socket", pgconn_socket, 0);
3183
3393
  rb_define_method(rb_cPGconn, "backend_pid", pgconn_backend_pid, 0);
3184
3394
  rb_define_method(rb_cPGconn, "connection_needs_password", pgconn_connection_needs_password, 0);
3185
3395
  rb_define_method(rb_cPGconn, "connection_used_password", pgconn_connection_used_password, 0);
@@ -3230,7 +3440,7 @@ Init_pg()
3230
3440
  rb_define_method(rb_cPGconn, "untrace", pgconn_untrace, 0);
3231
3441
 
3232
3442
  /****** PGconn INSTANCE METHODS: Notice Processing ******/
3233
- //rb_define_method(rb_cPGconn, "set_notice_receiver", pgconn_set_notice_receiver, 0);
3443
+ rb_define_method(rb_cPGconn, "set_notice_receiver", pgconn_set_notice_receiver, 0);
3234
3444
  rb_define_method(rb_cPGconn, "set_notice_processor", pgconn_set_notice_processor, 0);
3235
3445
 
3236
3446
  /****** PGconn INSTANCE METHODS: Other ******/
@@ -3304,7 +3514,7 @@ Init_pg()
3304
3514
  rb_define_method(rb_cPGresult, "result_status", pgresult_result_status, 0);
3305
3515
  rb_define_method(rb_cPGresult, "res_status", pgresult_res_status, 1);
3306
3516
  rb_define_method(rb_cPGresult, "result_error_message", pgresult_result_error_message, 0);
3307
- rb_define_method(rb_cPGresult, "result_error_field", pgresult_result_error_field, 0);
3517
+ rb_define_method(rb_cPGresult, "result_error_field", pgresult_result_error_field, 1);
3308
3518
  rb_define_method(rb_cPGresult, "clear", pgresult_clear, 0);
3309
3519
  rb_define_method(rb_cPGresult, "ntuples", pgresult_ntuples, 0);
3310
3520
  rb_define_alias(rb_cPGresult, "num_tuples", "ntuples");
data/ext/pg.h CHANGED
@@ -1,7 +1,6 @@
1
1
  #include <stdio.h>
2
2
  #include <stdlib.h>
3
3
  #include <sys/types.h>
4
- #include <unistd.h>
5
4
 
6
5
  #include "ruby.h"
7
6
  #include "rubyio.h"
@@ -10,9 +9,9 @@
10
9
 
11
10
  #include "compat.h"
12
11
 
13
- #if RUBY_VERSION_CODE < 180
14
- #define rb_check_string_type(x) rb_check_convert_type(x, T_STRING, "String", "to_str")
15
- #endif /* RUBY_VERSION_CODE < 180 */
12
+ #if RUBY_VM != 1
13
+ #define RUBY_18_COMPAT
14
+ #endif
16
15
 
17
16
  #ifndef RARRAY_LEN
18
17
  #define RARRAY_LEN(x) RARRAY((x))->len
@@ -30,5 +29,9 @@
30
29
  #define StringValuePtr(x) STR2CSTR(x)
31
30
  #endif /* StringValuePtr */
32
31
 
32
+ #ifdef RUBY_18_COMPAT
33
+ #define rb_io_stdio_file GetWriteFile
34
+ #endif
35
+
33
36
  void Init_pg(void);
34
37
 
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.4
3
3
  specification_version: 1
4
4
  name: pg
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.7.9.2008.02.05
7
- date: 2008-02-05 00:00:00 -08:00
6
+ version: 0.7.9.2008.03.18
7
+ date: 2008-03-18 00:00:00 -07:00
8
8
  summary: Ruby extension library providing an API to PostgreSQL
9
9
  require_paths:
10
10
  - lib
@@ -33,12 +33,12 @@ authors:
33
33
  - Dave Lee
34
34
  - Jeff Davis
35
35
  files:
36
- - COPYING
36
+ - README
37
+ - LICENSE
37
38
  - COPYING.txt
38
39
  - Contributors
39
40
  - GPL
40
- - LICENSE
41
- - README
41
+ - BSD
42
42
  - ext/compat.c
43
43
  - ext/compat.h
44
44
  - ext/pg.h
data/COPYING DELETED
@@ -1,340 +0,0 @@
1
- GNU GENERAL PUBLIC LICENSE
2
- Version 2, June 1991
3
-
4
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
5
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
6
- Everyone is permitted to copy and distribute verbatim copies
7
- of this license document, but changing it is not allowed.
8
-
9
- Preamble
10
-
11
- The licenses for most software are designed to take away your
12
- freedom to share and change it. By contrast, the GNU General Public
13
- License is intended to guarantee your freedom to share and change free
14
- software--to make sure the software is free for all its users. This
15
- General Public License applies to most of the Free Software
16
- Foundation's software and to any other program whose authors commit to
17
- using it. (Some other Free Software Foundation software is covered by
18
- the GNU Library General Public License instead.) You can apply it to
19
- your programs, too.
20
-
21
- When we speak of free software, we are referring to freedom, not
22
- price. Our General Public Licenses are designed to make sure that you
23
- have the freedom to distribute copies of free software (and charge for
24
- this service if you wish), that you receive source code or can get it
25
- if you want it, that you can change the software or use pieces of it
26
- in new free programs; and that you know you can do these things.
27
-
28
- To protect your rights, we need to make restrictions that forbid
29
- anyone to deny you these rights or to ask you to surrender the rights.
30
- These restrictions translate to certain responsibilities for you if you
31
- distribute copies of the software, or if you modify it.
32
-
33
- For example, if you distribute copies of such a program, whether
34
- gratis or for a fee, you must give the recipients all the rights that
35
- you have. You must make sure that they, too, receive or can get the
36
- source code. And you must show them these terms so they know their
37
- rights.
38
-
39
- We protect your rights with two steps: (1) copyright the software, and
40
- (2) offer you this license which gives you legal permission to copy,
41
- distribute and/or modify the software.
42
-
43
- Also, for each author's protection and ours, we want to make certain
44
- that everyone understands that there is no warranty for this free
45
- software. If the software is modified by someone else and passed on, we
46
- want its recipients to know that what they have is not the original, so
47
- that any problems introduced by others will not reflect on the original
48
- authors' reputations.
49
-
50
- Finally, any free program is threatened constantly by software
51
- patents. We wish to avoid the danger that redistributors of a free
52
- program will individually obtain patent licenses, in effect making the
53
- program proprietary. To prevent this, we have made it clear that any
54
- patent must be licensed for everyone's free use or not licensed at all.
55
-
56
- The precise terms and conditions for copying, distribution and
57
- modification follow.
58
-
59
- GNU GENERAL PUBLIC LICENSE
60
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61
-
62
- 0. This License applies to any program or other work which contains
63
- a notice placed by the copyright holder saying it may be distributed
64
- under the terms of this General Public License. The "Program", below,
65
- refers to any such program or work, and a "work based on the Program"
66
- means either the Program or any derivative work under copyright law:
67
- that is to say, a work containing the Program or a portion of it,
68
- either verbatim or with modifications and/or translated into another
69
- language. (Hereinafter, translation is included without limitation in
70
- the term "modification".) Each licensee is addressed as "you".
71
-
72
- Activities other than copying, distribution and modification are not
73
- covered by this License; they are outside its scope. The act of
74
- running the Program is not restricted, and the output from the Program
75
- is covered only if its contents constitute a work based on the
76
- Program (independent of having been made by running the Program).
77
- Whether that is true depends on what the Program does.
78
-
79
- 1. You may copy and distribute verbatim copies of the Program's
80
- source code as you receive it, in any medium, provided that you
81
- conspicuously and appropriately publish on each copy an appropriate
82
- copyright notice and disclaimer of warranty; keep intact all the
83
- notices that refer to this License and to the absence of any warranty;
84
- and give any other recipients of the Program a copy of this License
85
- along with the Program.
86
-
87
- You may charge a fee for the physical act of transferring a copy, and
88
- you may at your option offer warranty protection in exchange for a fee.
89
-
90
- 2. You may modify your copy or copies of the Program or any portion
91
- of it, thus forming a work based on the Program, and copy and
92
- distribute such modifications or work under the terms of Section 1
93
- above, provided that you also meet all of these conditions:
94
-
95
- a) You must cause the modified files to carry prominent notices
96
- stating that you changed the files and the date of any change.
97
-
98
- b) You must cause any work that you distribute or publish, that in
99
- whole or in part contains or is derived from the Program or any
100
- part thereof, to be licensed as a whole at no charge to all third
101
- parties under the terms of this License.
102
-
103
- c) If the modified program normally reads commands interactively
104
- when run, you must cause it, when started running for such
105
- interactive use in the most ordinary way, to print or display an
106
- announcement including an appropriate copyright notice and a
107
- notice that there is no warranty (or else, saying that you provide
108
- a warranty) and that users may redistribute the program under
109
- these conditions, and telling the user how to view a copy of this
110
- License. (Exception: if the Program itself is interactive but
111
- does not normally print such an announcement, your work based on
112
- the Program is not required to print an announcement.)
113
-
114
- These requirements apply to the modified work as a whole. If
115
- identifiable sections of that work are not derived from the Program,
116
- and can be reasonably considered independent and separate works in
117
- themselves, then this License, and its terms, do not apply to those
118
- sections when you distribute them as separate works. But when you
119
- distribute the same sections as part of a whole which is a work based
120
- on the Program, the distribution of the whole must be on the terms of
121
- this License, whose permissions for other licensees extend to the
122
- entire whole, and thus to each and every part regardless of who wrote it.
123
-
124
- Thus, it is not the intent of this section to claim rights or contest
125
- your rights to work written entirely by you; rather, the intent is to
126
- exercise the right to control the distribution of derivative or
127
- collective works based on the Program.
128
-
129
- In addition, mere aggregation of another work not based on the Program
130
- with the Program (or with a work based on the Program) on a volume of
131
- a storage or distribution medium does not bring the other work under
132
- the scope of this License.
133
-
134
- 3. You may copy and distribute the Program (or a work based on it,
135
- under Section 2) in object code or executable form under the terms of
136
- Sections 1 and 2 above provided that you also do one of the following:
137
-
138
- a) Accompany it with the complete corresponding machine-readable
139
- source code, which must be distributed under the terms of Sections
140
- 1 and 2 above on a medium customarily used for software interchange; or,
141
-
142
- b) Accompany it with a written offer, valid for at least three
143
- years, to give any third party, for a charge no more than your
144
- cost of physically performing source distribution, a complete
145
- machine-readable copy of the corresponding source code, to be
146
- distributed under the terms of Sections 1 and 2 above on a medium
147
- customarily used for software interchange; or,
148
-
149
- c) Accompany it with the information you received as to the offer
150
- to distribute corresponding source code. (This alternative is
151
- allowed only for noncommercial distribution and only if you
152
- received the program in object code or executable form with such
153
- an offer, in accord with Subsection b above.)
154
-
155
- The source code for a work means the preferred form of the work for
156
- making modifications to it. For an executable work, complete source
157
- code means all the source code for all modules it contains, plus any
158
- associated interface definition files, plus the scripts used to
159
- control compilation and installation of the executable. However, as a
160
- special exception, the source code distributed need not include
161
- anything that is normally distributed (in either source or binary
162
- form) with the major components (compiler, kernel, and so on) of the
163
- operating system on which the executable runs, unless that component
164
- itself accompanies the executable.
165
-
166
- If distribution of executable or object code is made by offering
167
- access to copy from a designated place, then offering equivalent
168
- access to copy the source code from the same place counts as
169
- distribution of the source code, even though third parties are not
170
- compelled to copy the source along with the object code.
171
-
172
- 4. You may not copy, modify, sublicense, or distribute the Program
173
- except as expressly provided under this License. Any attempt
174
- otherwise to copy, modify, sublicense or distribute the Program is
175
- void, and will automatically terminate your rights under this License.
176
- However, parties who have received copies, or rights, from you under
177
- this License will not have their licenses terminated so long as such
178
- parties remain in full compliance.
179
-
180
- 5. You are not required to accept this License, since you have not
181
- signed it. However, nothing else grants you permission to modify or
182
- distribute the Program or its derivative works. These actions are
183
- prohibited by law if you do not accept this License. Therefore, by
184
- modifying or distributing the Program (or any work based on the
185
- Program), you indicate your acceptance of this License to do so, and
186
- all its terms and conditions for copying, distributing or modifying
187
- the Program or works based on it.
188
-
189
- 6. Each time you redistribute the Program (or any work based on the
190
- Program), the recipient automatically receives a license from the
191
- original licensor to copy, distribute or modify the Program subject to
192
- these terms and conditions. You may not impose any further
193
- restrictions on the recipients' exercise of the rights granted herein.
194
- You are not responsible for enforcing compliance by third parties to
195
- this License.
196
-
197
- 7. If, as a consequence of a court judgment or allegation of patent
198
- infringement or for any other reason (not limited to patent issues),
199
- conditions are imposed on you (whether by court order, agreement or
200
- otherwise) that contradict the conditions of this License, they do not
201
- excuse you from the conditions of this License. If you cannot
202
- distribute so as to satisfy simultaneously your obligations under this
203
- License and any other pertinent obligations, then as a consequence you
204
- may not distribute the Program at all. For example, if a patent
205
- license would not permit royalty-free redistribution of the Program by
206
- all those who receive copies directly or indirectly through you, then
207
- the only way you could satisfy both it and this License would be to
208
- refrain entirely from distribution of the Program.
209
-
210
- If any portion of this section is held invalid or unenforceable under
211
- any particular circumstance, the balance of the section is intended to
212
- apply and the section as a whole is intended to apply in other
213
- circumstances.
214
-
215
- It is not the purpose of this section to induce you to infringe any
216
- patents or other property right claims or to contest validity of any
217
- such claims; this section has the sole purpose of protecting the
218
- integrity of the free software distribution system, which is
219
- implemented by public license practices. Many people have made
220
- generous contributions to the wide range of software distributed
221
- through that system in reliance on consistent application of that
222
- system; it is up to the author/donor to decide if he or she is willing
223
- to distribute software through any other system and a licensee cannot
224
- impose that choice.
225
-
226
- This section is intended to make thoroughly clear what is believed to
227
- be a consequence of the rest of this License.
228
-
229
- 8. If the distribution and/or use of the Program is restricted in
230
- certain countries either by patents or by copyrighted interfaces, the
231
- original copyright holder who places the Program under this License
232
- may add an explicit geographical distribution limitation excluding
233
- those countries, so that distribution is permitted only in or among
234
- countries not thus excluded. In such case, this License incorporates
235
- the limitation as if written in the body of this License.
236
-
237
- 9. The Free Software Foundation may publish revised and/or new versions
238
- of the General Public License from time to time. Such new versions will
239
- be similar in spirit to the present version, but may differ in detail to
240
- address new problems or concerns.
241
-
242
- Each version is given a distinguishing version number. If the Program
243
- specifies a version number of this License which applies to it and "any
244
- later version", you have the option of following the terms and conditions
245
- either of that version or of any later version published by the Free
246
- Software Foundation. If the Program does not specify a version number of
247
- this License, you may choose any version ever published by the Free Software
248
- Foundation.
249
-
250
- 10. If you wish to incorporate parts of the Program into other free
251
- programs whose distribution conditions are different, write to the author
252
- to ask for permission. For software which is copyrighted by the Free
253
- Software Foundation, write to the Free Software Foundation; we sometimes
254
- make exceptions for this. Our decision will be guided by the two goals
255
- of preserving the free status of all derivatives of our free software and
256
- of promoting the sharing and reuse of software generally.
257
-
258
- NO WARRANTY
259
-
260
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261
- FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262
- OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263
- PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264
- OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265
- MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266
- TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267
- PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268
- REPAIR OR CORRECTION.
269
-
270
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271
- WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272
- REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273
- INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274
- OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275
- TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276
- YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277
- PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278
- POSSIBILITY OF SUCH DAMAGES.
279
-
280
- END OF TERMS AND CONDITIONS
281
-
282
- How to Apply These Terms to Your New Programs
283
-
284
- If you develop a new program, and you want it to be of the greatest
285
- possible use to the public, the best way to achieve this is to make it
286
- free software which everyone can redistribute and change under these terms.
287
-
288
- To do so, attach the following notices to the program. It is safest
289
- to attach them to the start of each source file to most effectively
290
- convey the exclusion of warranty; and each file should have at least
291
- the "copyright" line and a pointer to where the full notice is found.
292
-
293
- <one line to give the program's name and a brief idea of what it does.>
294
- Copyright (C) <year> <name of author>
295
-
296
- This program is free software; you can redistribute it and/or modify
297
- it under the terms of the GNU General Public License as published by
298
- the Free Software Foundation; either version 2 of the License, or
299
- (at your option) any later version.
300
-
301
- This program is distributed in the hope that it will be useful,
302
- but WITHOUT ANY WARRANTY; without even the implied warranty of
303
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304
- GNU General Public License for more details.
305
-
306
- You should have received a copy of the GNU General Public License
307
- along with this program; if not, write to the Free Software
308
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
309
-
310
-
311
- Also add information on how to contact you by electronic and paper mail.
312
-
313
- If the program is interactive, make it output a short notice like this
314
- when it starts in an interactive mode:
315
-
316
- Gnomovision version 69, Copyright (C) year name of author
317
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
318
- This is free software, and you are welcome to redistribute it
319
- under certain conditions; type `show c' for details.
320
-
321
- The hypothetical commands `show w' and `show c' should show the appropriate
322
- parts of the General Public License. Of course, the commands you use may
323
- be called something other than `show w' and `show c'; they could even be
324
- mouse-clicks or menu items--whatever suits your program.
325
-
326
- You should also get your employer (if you work as a programmer) or your
327
- school, if any, to sign a "copyright disclaimer" for the program, if
328
- necessary. Here is a sample; alter the names:
329
-
330
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
331
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
332
-
333
- <signature of Ty Coon>, 1 April 1989
334
- Ty Coon, President of Vice
335
-
336
- This General Public License does not permit incorporating your program into
337
- proprietary programs. If your program is a subroutine library, you may
338
- consider it more useful to permit linking proprietary applications with the
339
- library. If this is what you want to do, use the GNU Lesser General
340
- Public License instead of this License.