sequel_pg 1.15.0 → 1.16.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 41aa757cb6f4ca6f56ca26044517a47a68731dd7d51335451f6da2e5b5b34d6f
4
- data.tar.gz: ec43d49fd7b4b8821ecbb813f6244aaf46f69866e84b94df96a3c52ef3a6fd41
3
+ metadata.gz: e7bcc241985851b36df5d4e199e1edc08626fa8dcd23065aefd13b4cafd135a9
4
+ data.tar.gz: 8816059db9824f1396cb9d734c1b12f1c4ccb38c13ebc4a9c953a78cfff90fdd
5
5
  SHA512:
6
- metadata.gz: 2a2578bec8fed224dcd3c1263cb86a4729cf11318f80d6cdb03366ae7dae6e68995447db06a1105d1ecda50222d2ff6258079fb7395d3f262094e1e05502fd48
7
- data.tar.gz: 26a470d0e7d8290cade76b07cecd972be840c838492607a5649c0fd803de2ca7ea2e34b0c77fddcaff734a2a875b1f26ce8d5b03ec0fe0ab887ae3045ffa10e0
6
+ metadata.gz: 2220c53c58d8bd549f66849529584dcf836495f0f55dc5819bd01841131e213f24cdcda089ae63a9703ae08c6c5ae5514160b1ce1f181e1277d099765d2f683b
7
+ data.tar.gz: 6ac01c39dddb568d29100e9bcd3a326d8bcc1b0cd4a54a4c507793fd0817d0709bfabbe6252873c7b422e8ed68f8a6b6d8f77f13b69d1012965b314611734a9c
data/CHANGELOG CHANGED
@@ -1,3 +1,11 @@
1
+ === 1.16.0 (2022-08-16)
2
+
3
+ * Fix memory leak when using streaming with 1.3.4+ (jeremyevans) (#48)
4
+
5
+ * Modify LDFLAGS when building on MacOS arm64 to allow undefined functions (maxsz) (#46)
6
+
7
+ * Adjust many internal C types to fix compilation warnings (jeremyevans)
8
+
1
9
  === 1.15.0 (2022-03-16)
2
10
 
3
11
  * Avoid deprecation warning in the pg_streaming extension on pg 1.3+ when streaming a query with bound parameters (jeremyevans)
data/README.rdoc CHANGED
@@ -77,9 +77,16 @@ variables to specify the shared library and header directories.
77
77
 
78
78
  == Running the specs
79
79
 
80
- sequel_pg doesn't ship with it's own specs. It's designed to
81
- replace a part of Sequel, so it just uses Sequel's specs.
82
- Specifically, the spec_postgres rake task from Sequel.
80
+ sequel_pg is designed to replace a part of Sequel, so it shold be tested
81
+ using Sequel's specs (the spec_postgres rake task). There is a spec_cov
82
+ task that assumes you have Sequel checked out at ../sequel, and uses a
83
+ small spec suite for parts of sequel_pg not covered by Sequel's specs.
84
+ It sets the SEQUEL_PG_STREAM environment variable when running Sequel's
85
+ specs, make sure that spec/spec_config.rb in Sequel is set to connect
86
+ to PostgreSQL and use the following additional settings:
87
+
88
+ DB.extension(:pg_streaming)
89
+ DB.stream_all_queries = true
83
90
 
84
91
  == Reporting issues/bugs
85
92
 
data/Rakefile CHANGED
@@ -1,7 +1,6 @@
1
- require "rake"
2
1
  require "rake/clean"
3
2
 
4
- CLEAN.include %w'**.rbc rdoc'
3
+ CLEAN.include %w'**.rbc rdoc coverage'
5
4
 
6
5
  desc "Do a full cleaning"
7
6
  task :distclean do
@@ -19,3 +18,25 @@ begin
19
18
  Rake::ExtensionTask.new('sequel_pg')
20
19
  rescue LoadError
21
20
  end
21
+
22
+ # This assumes you have sequel checked out in ../sequel, and that
23
+ # spec_postgres is setup to run Sequel's PostgreSQL specs.
24
+ desc "Run tests with coverage"
25
+ task :spec_cov=>:compile do
26
+ ENV['RUBYLIB'] = "#{__dir__}/lib:#{ENV['RUBYLIB']}"
27
+ ENV['RUBYOPT'] = "-r #{__dir__}/spec/coverage_helper.rb #{ENV['RUBYOPT']}"
28
+ ENV['SIMPLECOV_COMMAND_NAME'] = "sequel_pg"
29
+ sh %'#{FileUtils::RUBY} -I ../sequel/lib spec/sequel_pg_spec.rb'
30
+
31
+ ENV['RUBYOPT'] = "-I lib -r sequel -r sequel/extensions/pg_array #{ENV['RUBYOPT']}"
32
+ ENV['SEQUEL_PG_STREAM'] = "1"
33
+ ENV['SIMPLECOV_COMMAND_NAME'] = "sequel"
34
+ sh %'cd ../sequel && #{FileUtils::RUBY} spec/adapter_spec.rb postgres'
35
+ end
36
+
37
+ desc "Run CI tests"
38
+ task :spec_ci=>:compile do
39
+ ENV['SEQUEL_PG_SPEC_URL'] = ENV['SEQUEL_POSTGRES_URL'] = "postgres://localhost/?user=postgres&password=postgres"
40
+ sh %'#{FileUtils::RUBY} -I lib -I sequel/lib spec/sequel_pg_spec.rb'
41
+ sh %'cd sequel && #{FileUtils::RUBY} -I lib -I ../lib spec/adapter_spec.rb postgres'
42
+ end
@@ -2,6 +2,7 @@ require 'mkmf'
2
2
  $CFLAGS << " -O0 -g" if ENV['DEBUG']
3
3
  $CFLAGS << " -Drb_tainted_str_new=rb_str_new -DNO_TAINT" if RUBY_VERSION >= '2.7'
4
4
  $CFLAGS << " -Wall " unless RUBY_PLATFORM =~ /solaris/
5
+ $LDFLAGS += " -Wl,-U,_pg_get_pgconn -Wl,-U,_pg_get_result_enc_idx -Wl,-U,_pgresult_get -Wl,-U,_pgresult_stream_any " if RUBY_PLATFORM =~ /arm64-darwin/
5
6
  dir_config('pg', ENV["POSTGRES_INCLUDE"] || (IO.popen("pg_config --includedir").readline.chomp rescue nil),
6
7
  ENV["POSTGRES_LIB"] || (IO.popen("pg_config --libdir").readline.chomp rescue nil))
7
8
 
@@ -1,4 +1,4 @@
1
- #define SEQUEL_PG_VERSION_INTEGER 11500
1
+ #define SEQUEL_PG_VERSION_INTEGER 11600
2
2
 
3
3
  #include <string.h>
4
4
  #include <stdio.h>
@@ -199,10 +199,10 @@ static int enc_get_index(VALUE val) {
199
199
  } while(0)
200
200
 
201
201
  static VALUE
202
- pg_text_dec_integer(char *val, int len)
202
+ pg_text_dec_integer(char *val, size_t len)
203
203
  {
204
204
  long i;
205
- int max_len;
205
+ size_t max_len;
206
206
 
207
207
  if( sizeof(i) >= 8 && FIXNUM_MAX >= 1000000000000000000LL ){
208
208
  /* 64 bit system can safely handle all numbers up to 18 digits as Fixnum */
@@ -257,7 +257,7 @@ pg_text_dec_integer(char *val, int len)
257
257
 
258
258
  static VALUE spg__array_col_value(char *v, size_t length, VALUE converter, int enc_index, int oid, VALUE db);
259
259
 
260
- static VALUE read_array(int *index, char *c_pg_array_string, int array_string_length, VALUE buf, VALUE converter, int enc_index, int oid, VALUE db) {
260
+ static VALUE read_array(int *index, char *c_pg_array_string, long array_string_length, VALUE buf, VALUE converter, int enc_index, int oid, VALUE db) {
261
261
  int word_index = 0;
262
262
  char *word = RSTRING_PTR(buf);
263
263
 
@@ -353,7 +353,7 @@ static VALUE read_array(int *index, char *c_pg_array_string, int array_string_le
353
353
  return array;
354
354
  }
355
355
 
356
- static VALUE check_pg_array(int* index, char *c_pg_array_string, int array_string_length) {
356
+ static VALUE check_pg_array(int* index, char *c_pg_array_string, long array_string_length) {
357
357
  if (array_string_length == 0) {
358
358
  rb_raise(rb_eArgError, "unexpected PostgreSQL array format, empty");
359
359
  } else if (array_string_length == 2 && c_pg_array_string[0] == '{' && c_pg_array_string[0] == '}') {
@@ -384,7 +384,7 @@ static VALUE parse_pg_array(VALUE self, VALUE pg_array_string, VALUE converter)
384
384
  /* convert to c-string, create additional ruby string buffer of
385
385
  * the same length, as that will be the worst case. */
386
386
  char *c_pg_array_string = StringValueCStr(pg_array_string);
387
- int array_string_length = RSTRING_LEN(pg_array_string);
387
+ long array_string_length = RSTRING_LEN(pg_array_string);
388
388
  int index = 1;
389
389
  VALUE ary;
390
390
 
@@ -1012,12 +1012,12 @@ static int spg_timestamp_info_bitmask(VALUE self) {
1012
1012
  return tz;
1013
1013
  }
1014
1014
 
1015
- static VALUE spg__col_value(VALUE self, PGresult *res, long i, long j, VALUE* colconvert, int enc_index) {
1015
+ static VALUE spg__col_value(VALUE self, PGresult *res, int i, int j, VALUE* colconvert, int enc_index) {
1016
1016
  char *v;
1017
1017
  VALUE rv;
1018
1018
  int ftype = PQftype(res, j);
1019
1019
  VALUE array_type;
1020
- VALUE scalar_oid;
1020
+ int scalar_oid;
1021
1021
  struct spg_blob_initialization bi;
1022
1022
 
1023
1023
  if(PQgetisnull(res, i, j)) {
@@ -1251,20 +1251,20 @@ static VALUE spg__col_value(VALUE self, PGresult *res, long i, long j, VALUE* co
1251
1251
  return rv;
1252
1252
  }
1253
1253
 
1254
- static VALUE spg__col_values(VALUE self, VALUE v, VALUE *colsyms, long nfields, PGresult *res, long i, VALUE *colconvert, int enc_index) {
1254
+ static VALUE spg__col_values(VALUE self, VALUE v, VALUE *colsyms, long nfields, PGresult *res, int i, VALUE *colconvert, int enc_index) {
1255
1255
  long j;
1256
1256
  VALUE cur;
1257
1257
  long len = RARRAY_LEN(v);
1258
1258
  VALUE a = rb_ary_new2(len);
1259
1259
  for (j=0; j<len; j++) {
1260
1260
  cur = rb_ary_entry(v, j);
1261
- rb_ary_store(a, j, cur == Qnil ? Qnil : spg__col_value(self, res, i, NUM2LONG(cur), colconvert, enc_index));
1261
+ rb_ary_store(a, j, cur == Qnil ? Qnil : spg__col_value(self, res, i, NUM2INT(cur), colconvert, enc_index));
1262
1262
  }
1263
1263
  return a;
1264
1264
  }
1265
1265
 
1266
- static long spg__field_id(VALUE v, VALUE *colsyms, long nfields) {
1267
- long j;
1266
+ static int spg__field_id(VALUE v, VALUE *colsyms, long nfields) {
1267
+ int j;
1268
1268
  for (j=0; j<nfields; j++) {
1269
1269
  if (colsyms[j] == v) {
1270
1270
  return j;
@@ -1275,7 +1275,7 @@ static long spg__field_id(VALUE v, VALUE *colsyms, long nfields) {
1275
1275
 
1276
1276
  static VALUE spg__field_ids(VALUE v, VALUE *colsyms, long nfields) {
1277
1277
  long i;
1278
- long j;
1278
+ int j;
1279
1279
  VALUE cur;
1280
1280
  long len = RARRAY_LEN(v);
1281
1281
  VALUE pg_columns = rb_ary_new2(len);
@@ -1288,9 +1288,9 @@ static VALUE spg__field_ids(VALUE v, VALUE *colsyms, long nfields) {
1288
1288
  }
1289
1289
 
1290
1290
  static void spg_set_column_info(VALUE self, PGresult *res, VALUE *colsyms, VALUE *colconvert, int enc_index) {
1291
- long i;
1292
- long j;
1293
- long nfields;
1291
+ int i;
1292
+ int j;
1293
+ int nfields;
1294
1294
  int timestamp_info = 0;
1295
1295
  int time_info = 0;
1296
1296
  VALUE conv_procs = 0;
@@ -1380,10 +1380,10 @@ static void spg_set_column_info(VALUE self, PGresult *res, VALUE *colsyms, VALUE
1380
1380
  }
1381
1381
 
1382
1382
  static VALUE spg_yield_hash_rows_internal(VALUE self, PGresult *res, int enc_index, VALUE* colsyms, VALUE* colconvert) {
1383
- long ntuples;
1384
- long nfields;
1385
- long i;
1386
- long j;
1383
+ int ntuples;
1384
+ int nfields;
1385
+ int i;
1386
+ int j;
1387
1387
  VALUE h;
1388
1388
  VALUE opts;
1389
1389
  VALUE pg_type;
@@ -1483,7 +1483,7 @@ static VALUE spg_yield_hash_rows_internal(VALUE self, PGresult *res, int enc_ind
1483
1483
  case SPG_YIELD_KV_HASH_GROUPS:
1484
1484
  /* Hash with single key and single value */
1485
1485
  {
1486
- VALUE k, v;
1486
+ int k, v;
1487
1487
  h = rb_hash_new();
1488
1488
  k = spg__field_id(rb_ary_entry(pg_value, 0), colsyms, nfields);
1489
1489
  v = spg__field_id(rb_ary_entry(pg_value, 1), colsyms, nfields);
@@ -1511,7 +1511,8 @@ static VALUE spg_yield_hash_rows_internal(VALUE self, PGresult *res, int enc_ind
1511
1511
  case SPG_YIELD_MKV_HASH_GROUPS:
1512
1512
  /* Hash with array of keys and single value */
1513
1513
  {
1514
- VALUE k, v;
1514
+ VALUE k;
1515
+ int v;
1515
1516
  h = rb_hash_new();
1516
1517
  k = spg__field_ids(rb_ary_entry(pg_value, 0), colsyms, nfields);
1517
1518
  v = spg__field_id(rb_ary_entry(pg_value, 1), colsyms, nfields);
@@ -1539,7 +1540,8 @@ static VALUE spg_yield_hash_rows_internal(VALUE self, PGresult *res, int enc_ind
1539
1540
  case SPG_YIELD_KMV_HASH_GROUPS:
1540
1541
  /* Hash with single keys and array of values */
1541
1542
  {
1542
- VALUE k, v;
1543
+ VALUE v;
1544
+ int k;
1543
1545
  h = rb_hash_new();
1544
1546
  k = spg__field_id(rb_ary_entry(pg_value, 0), colsyms, nfields);
1545
1547
  v = spg__field_ids(rb_ary_entry(pg_value, 1), colsyms, nfields);
@@ -1621,7 +1623,7 @@ def_spg_yield_hash_rows(1664)
1621
1623
 
1622
1624
  static VALUE spg_yield_hash_rows(VALUE self, VALUE rres, VALUE ignore) {
1623
1625
  PGresult *res;
1624
- long nfields;
1626
+ int nfields;
1625
1627
  int enc_index;
1626
1628
 
1627
1629
  if (!RTEST(rres)) {
@@ -1636,7 +1638,7 @@ static VALUE spg_yield_hash_rows(VALUE self, VALUE rres, VALUE ignore) {
1636
1638
  else if (nfields <= 64) return spg_yield_hash_rows_64(self, res, enc_index);
1637
1639
  else if (nfields <= 256) return spg_yield_hash_rows_256(self, res, enc_index);
1638
1640
  else if (nfields <= 1664) return spg_yield_hash_rows_1664(self, res, enc_index);
1639
- else rb_raise(rb_eRangeError, "more than 1664 columns in query (%ld columns detected)", nfields);
1641
+ else rb_raise(rb_eRangeError, "more than 1664 columns in query (%d columns detected)", nfields);
1640
1642
 
1641
1643
  /* UNREACHABLE */
1642
1644
  return self;
@@ -1678,7 +1680,7 @@ static void spg__yield_each_row_stream(VALUE rres, int ntuples, int nfields, voi
1678
1680
  VALUE *colconvert= data->colconvert;
1679
1681
  PGresult *res = pgresult_get(rres);
1680
1682
  int enc_index = data->enc_index;
1681
- long j;
1683
+ int j;
1682
1684
 
1683
1685
  for(j=0; j<nfields; j++) {
1684
1686
  rb_hash_aset(h, colsyms[j], spg__col_value(self, res, 0, j, colconvert , enc_index));
@@ -1691,11 +1693,12 @@ static void spg__yield_each_row_stream(VALUE rres, int ntuples, int nfields, voi
1691
1693
  } else {
1692
1694
  rb_yield(h);
1693
1695
  }
1696
+ PQclear(res);
1694
1697
  }
1695
1698
 
1696
1699
  static VALUE spg__yield_each_row_internal(VALUE self, VALUE rconn, VALUE rres, PGresult *res, int enc_index, VALUE *colsyms, VALUE *colconvert) {
1697
- long nfields;
1698
- long j;
1700
+ int nfields;
1701
+ int j;
1699
1702
  VALUE h;
1700
1703
  VALUE opts;
1701
1704
  VALUE pg_type;
@@ -1776,7 +1779,7 @@ static VALUE spg__yield_each_row(VALUE self) {
1776
1779
  VALUE rres;
1777
1780
  VALUE rconn;
1778
1781
  int enc_index;
1779
- long nfields;
1782
+ int nfields;
1780
1783
 
1781
1784
  rconn = rb_ary_entry(self, 1);
1782
1785
  self = rb_ary_entry(self, 0);
@@ -1797,7 +1800,7 @@ static VALUE spg__yield_each_row(VALUE self) {
1797
1800
  else if (nfields <= 1664) return spg__yield_each_row_1664(self, rconn, rres, res, enc_index);
1798
1801
  else {
1799
1802
  rb_funcall(rres, spg_id_clear, 0);
1800
- rb_raise(rb_eRangeError, "more than 1664 columns in query (%ld columns detected)", nfields);
1803
+ rb_raise(rb_eRangeError, "more than 1664 columns in query (%d columns detected)", nfields);
1801
1804
  }
1802
1805
 
1803
1806
  /* UNREACHABLE */
@@ -1,9 +1,11 @@
1
+ # :nocov:
1
2
  unless Sequel::Postgres.respond_to?(:supports_streaming?)
2
3
  raise LoadError, "either sequel_pg not loaded, or an old version of sequel_pg loaded"
3
4
  end
4
5
  unless Sequel::Postgres.supports_streaming?
5
6
  raise LoadError, "streaming is not supported by the version of libpq in use"
6
7
  end
8
+ # :nocov:
7
9
 
8
10
  # Database methods necessary to support streaming. You should load this extension
9
11
  # into your database object:
@@ -73,11 +75,13 @@ module Sequel::Postgres::Streaming
73
75
 
74
76
  private
75
77
 
78
+ # :nocov:
76
79
  unless Sequel::Postgres::Adapter.method_defined?(:send_query_params)
77
80
  def send_query_params(*args)
78
81
  send_query(*args)
79
82
  end
80
83
  end
84
+ # :nocov:
81
85
 
82
86
  if Sequel::Database.instance_methods.map(&:to_s).include?('log_connection_yield')
83
87
  # If using single row mode, send the query instead of executing it.
@@ -93,6 +97,7 @@ module Sequel::Postgres::Streaming
93
97
  end
94
98
  end
95
99
  else
100
+ # :nocov:
96
101
  def execute_query(sql, args)
97
102
  if @single_row_mode
98
103
  @single_row_mode = false
@@ -104,6 +109,7 @@ module Sequel::Postgres::Streaming
104
109
  super
105
110
  end
106
111
  end
112
+ # :nocov:
107
113
  end
108
114
  end
109
115
 
@@ -53,11 +53,13 @@ class Sequel::Postgres::Dataset
53
53
  end
54
54
  end
55
55
 
56
+ # :nocov:
56
57
  unless Sequel::Dataset.method_defined?(:as_hash)
57
58
  # Handle previous versions of Sequel that use to_hash instead of as_hash
58
59
  alias to_hash as_hash
59
60
  remove_method :as_hash
60
61
  end
62
+ # :nocov:
61
63
 
62
64
  # In the case where both arguments given, use an optimized version.
63
65
  def to_hash_groups(key_column, value_column = nil, opts = Sequel::OPTS)
@@ -120,8 +122,10 @@ if defined?(Sequel::Postgres::PGArray)
120
122
  # pg_array extension previously loaded
121
123
 
122
124
  class Sequel::Postgres::PGArray::Creator
125
+ # :nocov:
123
126
  # Avoid method redefined verbose warning
124
127
  alias call call if method_defined?(:call)
128
+ # :nocov:
125
129
 
126
130
  # Override Creator to use sequel_pg's C-based parser instead of the pure ruby parser.
127
131
  def call(string)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequel_pg
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.15.0
4
+ version: 1.16.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Evans
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-03-16 00:00:00.000000000 Z
11
+ date: 2022-08-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pg