sequel_pg 1.17.2 → 1.18.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 61a49fada0595f92d8452ff231ff0d44ffadf59a887671c9d86178d957f95f44
4
- data.tar.gz: 8969b6f0b9492e2f9edb087b57ef7b13993d61eeaabb9a0291478c1a227448ff
3
+ metadata.gz: 9d497c75bd5ace025a1696d5b5df76116dd54495afee2178872f8f19f06b9257
4
+ data.tar.gz: 24a06481753cb39885de374dfca9e3adcc041e7b0c42550d3406513f79b41ba9
5
5
  SHA512:
6
- metadata.gz: 7d5f69fd6e5f2a7dd3b067ca423c85ed2d9fc2f3af9ae191a19507ac3635e654699e5dac6c90ba1f910d5619cf8242a039e07752bfccbfed8c2a57a280fe0bb3
7
- data.tar.gz: 899259457171fafd01c689f234da55255a06a4408ab7e58bcbdf8df94a409884a46ce3e613a2faabe9fbec350b65188d3d8a3e1821832b74d7ff9d145bbb16ef
6
+ metadata.gz: ddf3c461fd892e80c199f7f5f37cf65a46f14a6a41285e7eec0fdb6ec0da5d4cfa9c74a866f1d3f7da5d8ef1a967ca713da3b12f167b82c2ee0b53bafbcd1bf3
7
+ data.tar.gz: c656f25a3ab3aa13286db0586d843b690c864fc219210de328edbca195b501c874046f96e098b8e3adcc549f11c052615c62ecec03f6821e6ebeab2dff6e874a
data/CHANGELOG CHANGED
@@ -1,3 +1,19 @@
1
+ === 1.18.0 (2025-12-01)
2
+
3
+ * Optimize Dataset#all and #with_sql_all (jeremyevans)
4
+
5
+ * Fix runtime warnings when using Dataset#as_hash and #to_hash_groups with invalid columns (jeremyevans)
6
+
7
+ * Fix Dataset#map return value when the null_dataset extension is used (jeremyevans)
8
+
9
+ * Further optimize Dataset#as_set and #select_set on Ruby 4+ using core Set C-API (jeremyevans)
10
+
11
+ * Use rb_hash_new_capa if available to avoid unnecessary hash resizing (jeremyevans)
12
+
13
+ * Further optimize Dataset#map and #select_map by populating array in C instead of yielding to Ruby (jeremyevans)
14
+
15
+ * Optimize Dataset#as_set and #select_set in Sequel 5.99+ (jeremyevans)
16
+
1
17
  === 1.17.2 (2025-03-14)
2
18
 
3
19
  * Add explicit arguments to PQfreemem casts to avoid compilation issues when using the C23 standard (jeremyevans) (#59)
data/README.rdoc CHANGED
@@ -127,13 +127,26 @@ requirements:
127
127
  PostgreSQL defaulting to ISO, Sequel also manually sets the
128
128
  date format to ISO by default, so unless you are overriding that
129
129
  setting (via DB.use_iso_date_format = false), you should be OK.
130
+
130
131
  * Adding your own type conversion procs only has an effect if those
131
132
  types are not handled by default.
133
+
132
134
  * You do not need to require the library, the sequel postgres adapter
133
135
  will require it automatically. If you are using bundler, you
134
136
  should add it to your Gemfile like so:
135
137
 
136
- gem 'sequel_pg', :require=>'sequel'
138
+ gem 'sequel_pg', require: 'sequel'
139
+
140
+ * Using a precompiled pg gem can cause issues in certain cases,
141
+ since it statically links a libpq that could differ from the system
142
+ libpq dynamically linked to the sequel_pg gem. You can work around
143
+ the issue by forcing the ruby platform for the pg gem:
144
+
145
+ # Manual install
146
+ gem install pg --platform ruby
147
+
148
+ # Gemfile
149
+ gem 'pg', force_ruby_platform: true
137
150
 
138
151
  * sequel_pg currently calls functions defined in the pg gem, which
139
152
  does not work on Windows and does not work in some unix-like
@@ -7,6 +7,8 @@ dir_config('pg', ENV["POSTGRES_INCLUDE"] || (IO.popen("pg_config --includedir").
7
7
  ENV["POSTGRES_LIB"] || (IO.popen("pg_config --libdir").readline.chomp rescue nil))
8
8
 
9
9
  if (have_library('pq') || have_library('libpq') || have_library('ms/libpq')) && have_header('libpq-fe.h')
10
+ have_func 'rb_hash_new_capa'
11
+ have_func 'rb_set_new_capa'
10
12
  have_func 'PQsetSingleRowMode'
11
13
  have_func 'timegm'
12
14
  create_makefile("sequel_pg")
@@ -1,4 +1,4 @@
1
- #define SEQUEL_PG_VERSION_INTEGER 11702
1
+ #define SEQUEL_PG_VERSION_INTEGER 11800
2
2
 
3
3
  #include <string.h>
4
4
  #include <stdio.h>
@@ -24,6 +24,10 @@
24
24
  #define RARRAY_AREF(a, i) (RARRAY_PTR(a)[i])
25
25
  #endif
26
26
 
27
+ #if !HAVE_RB_HASH_NEW_CAPA
28
+ #define rb_hash_new_capa(_) rb_hash_new()
29
+ #endif
30
+
27
31
  #define ntohll(c) ((uint64_t)( \
28
32
  (((uint64_t)(*((unsigned char*)(c)+0)))<<56LL) | \
29
33
  (((uint64_t)(*((unsigned char*)(c)+1)))<<48LL) | \
@@ -65,6 +69,16 @@
65
69
  #define SPG_YIELD_MKV_HASH_GROUPS 11
66
70
  #define SPG_YIELD_KMV_HASH_GROUPS 12
67
71
  #define SPG_YIELD_MKMV_HASH_GROUPS 13
72
+ #define SPG_YIELD_COLUMN_ARRAY 14
73
+ #define SPG_YIELD_COLUMNS_ARRAY 15
74
+ #define SPG_YIELD_FIRST_ARRAY 16
75
+ #define SPG_YIELD_ARRAY_ARRAY 17
76
+ #define SPG_YIELD_COLUMN_SET 18
77
+ #define SPG_YIELD_COLUMNS_SET 19
78
+ #define SPG_YIELD_FIRST_SET 20
79
+ #define SPG_YIELD_ARRAY_SET 21
80
+ #define SPG_YIELD_ALL 22
81
+ #define SPG_YIELD_ALL_MODEL 23
68
82
 
69
83
  /* External functions defined by ruby-pg */
70
84
  PGconn* pg_get_pgconn(VALUE);
@@ -91,11 +105,19 @@ static VALUE spg_vmasks6;
91
105
  static VALUE spg_sym_utc;
92
106
  static VALUE spg_sym_local;
93
107
  static VALUE spg_sym_map;
108
+ static VALUE spg_sym_map_array;
109
+ static VALUE spg_sym_map_set;
94
110
  static VALUE spg_sym_first;
111
+ static VALUE spg_sym_first_array;
112
+ static VALUE spg_sym_first_set;
95
113
  static VALUE spg_sym_array;
114
+ static VALUE spg_sym_array_array;
115
+ static VALUE spg_sym_array_set;
96
116
  static VALUE spg_sym_hash;
97
117
  static VALUE spg_sym_hash_groups;
98
118
  static VALUE spg_sym_model;
119
+ static VALUE spg_sym_all;
120
+ static VALUE spg_sym_all_model;
99
121
  static VALUE spg_sym__sequel_pg_type;
100
122
  static VALUE spg_sym__sequel_pg_value;
101
123
 
@@ -1405,10 +1427,34 @@ static VALUE spg_yield_hash_rows_internal(VALUE self, PGresult *res, int enc_ind
1405
1427
  } else if (rb_type(pg_value) == T_ARRAY) {
1406
1428
  type = SPG_YIELD_COLUMNS;
1407
1429
  }
1430
+ } else if (pg_type == spg_sym_map_array) {
1431
+ if (SYMBOL_P(pg_value)) {
1432
+ type = SPG_YIELD_COLUMN_ARRAY;
1433
+ } else if (rb_type(pg_value) == T_ARRAY) {
1434
+ type = SPG_YIELD_COLUMNS_ARRAY;
1435
+ }
1436
+ #if HAVE_RB_SET_NEW_CAPA
1437
+ } else if (pg_type == spg_sym_map_set) {
1438
+ if (SYMBOL_P(pg_value)) {
1439
+ type = SPG_YIELD_COLUMN_SET;
1440
+ } else if (rb_type(pg_value) == T_ARRAY) {
1441
+ type = SPG_YIELD_COLUMNS_SET;
1442
+ }
1443
+ #endif
1408
1444
  } else if (pg_type == spg_sym_first) {
1409
1445
  type = SPG_YIELD_FIRST;
1410
1446
  } else if (pg_type == spg_sym_array) {
1411
1447
  type = SPG_YIELD_ARRAY;
1448
+ } else if (pg_type == spg_sym_first_array) {
1449
+ type = SPG_YIELD_FIRST_ARRAY;
1450
+ } else if (pg_type == spg_sym_array_array) {
1451
+ type = SPG_YIELD_ARRAY_ARRAY;
1452
+ #if HAVE_RB_SET_NEW_CAPA
1453
+ } else if (pg_type == spg_sym_first_set) {
1454
+ type = SPG_YIELD_FIRST_SET;
1455
+ } else if (pg_type == spg_sym_array_set) {
1456
+ type = SPG_YIELD_ARRAY_SET;
1457
+ #endif
1412
1458
  } else if ((pg_type == spg_sym_hash || pg_type == spg_sym_hash_groups) && rb_type(pg_value) == T_ARRAY) {
1413
1459
  VALUE pg_value_key, pg_value_value;
1414
1460
  pg_value_key = rb_ary_entry(pg_value, 0);
@@ -1428,6 +1474,10 @@ static VALUE spg_yield_hash_rows_internal(VALUE self, PGresult *res, int enc_ind
1428
1474
  }
1429
1475
  } else if (pg_type == spg_sym_model && rb_type(pg_value) == T_CLASS) {
1430
1476
  type = SPG_YIELD_MODEL;
1477
+ } else if (pg_type == spg_sym_all_model && rb_type(pg_value) == T_CLASS) {
1478
+ type = SPG_YIELD_ALL_MODEL;
1479
+ } else if (pg_type == spg_sym_all) {
1480
+ type = SPG_YIELD_ALL;
1431
1481
  }
1432
1482
  }
1433
1483
  }
@@ -1436,7 +1486,7 @@ static VALUE spg_yield_hash_rows_internal(VALUE self, PGresult *res, int enc_ind
1436
1486
  case SPG_YIELD_NORMAL:
1437
1487
  /* Normal, hash for entire row */
1438
1488
  for(i=0; i<ntuples; i++) {
1439
- h = rb_hash_new();
1489
+ h = rb_hash_new_capa(nfields);
1440
1490
  for(j=0; j<nfields; j++) {
1441
1491
  rb_hash_aset(h, colsyms[j], spg__col_value(self, res, i, j, colconvert, enc_index));
1442
1492
  }
@@ -1463,6 +1513,63 @@ static VALUE spg_yield_hash_rows_internal(VALUE self, PGresult *res, int enc_ind
1463
1513
  rb_yield(spg__col_values(self, h, colsyms, nfields, res, i, colconvert, enc_index));
1464
1514
  }
1465
1515
  break;
1516
+ case SPG_YIELD_COLUMN_ARRAY:
1517
+ /* Array containing single column */
1518
+ {
1519
+ VALUE ary = rb_ary_new2(ntuples);
1520
+ j = spg__field_id(pg_value, colsyms, nfields);
1521
+ if (j == -1) {
1522
+ for(i=0; i<ntuples; i++) {
1523
+ rb_ary_store(ary, i, Qnil);
1524
+ }
1525
+ }
1526
+ else {
1527
+ for(i=0; i<ntuples; i++) {
1528
+ rb_ary_store(ary, i, spg__col_value(self, res, i, j, colconvert, enc_index));
1529
+ }
1530
+ }
1531
+ rb_yield(ary);
1532
+ }
1533
+ break;
1534
+ case SPG_YIELD_COLUMNS_ARRAY:
1535
+ /* Array containing arrays of columns */
1536
+ {
1537
+ VALUE ary = rb_ary_new2(ntuples);
1538
+ h = spg__field_ids(pg_value, colsyms, nfields);
1539
+ for(i=0; i<ntuples; i++) {
1540
+ rb_ary_store(ary, i, spg__col_values(self, h, colsyms, nfields, res, i, colconvert, enc_index));
1541
+ }
1542
+ rb_yield(ary);
1543
+ }
1544
+ break;
1545
+ #if HAVE_RB_SET_NEW_CAPA
1546
+ case SPG_YIELD_COLUMN_SET:
1547
+ /* Set containing single column */
1548
+ {
1549
+ VALUE set = rb_set_new_capa(ntuples);
1550
+ j = spg__field_id(pg_value, colsyms, nfields);
1551
+ if (j == -1) {
1552
+ rb_set_add(set, Qnil);
1553
+ } else {
1554
+ for(i=0; i<ntuples; i++) {
1555
+ rb_set_add(set, spg__col_value(self, res, i, j, colconvert, enc_index));
1556
+ }
1557
+ }
1558
+ rb_yield(set);
1559
+ }
1560
+ break;
1561
+ case SPG_YIELD_COLUMNS_SET:
1562
+ /* Set containing arrays of columns */
1563
+ {
1564
+ VALUE set = rb_set_new_capa(ntuples);
1565
+ h = spg__field_ids(pg_value, colsyms, nfields);
1566
+ for(i=0; i<ntuples; i++) {
1567
+ rb_set_add(set, spg__col_values(self, h, colsyms, nfields, res, i, colconvert, enc_index));
1568
+ }
1569
+ rb_yield(set);
1570
+ }
1571
+ break;
1572
+ #endif
1466
1573
  case SPG_YIELD_FIRST:
1467
1574
  /* First column */
1468
1575
  for(i=0; i<ntuples; i++) {
@@ -1479,23 +1586,73 @@ static VALUE spg_yield_hash_rows_internal(VALUE self, PGresult *res, int enc_ind
1479
1586
  rb_yield(h);
1480
1587
  }
1481
1588
  break;
1589
+ case SPG_YIELD_FIRST_ARRAY:
1590
+ /* Array of first column */
1591
+ h = rb_ary_new2(ntuples);
1592
+ for(i=0; i<ntuples; i++) {
1593
+ rb_ary_store(h, i, spg__col_value(self, res, i, 0, colconvert, enc_index));
1594
+ }
1595
+ rb_yield(h);
1596
+ break;
1597
+ case SPG_YIELD_ARRAY_ARRAY:
1598
+ /* Array of arrays of all columns */
1599
+ {
1600
+ VALUE ary = rb_ary_new2(ntuples);
1601
+ for(i=0; i<ntuples; i++) {
1602
+ h = rb_ary_new2(nfields);
1603
+ for(j=0; j<nfields; j++) {
1604
+ rb_ary_store(h, j, spg__col_value(self, res, i, j, colconvert, enc_index));
1605
+ }
1606
+ rb_ary_store(ary, i, h);
1607
+ }
1608
+ rb_yield(ary);
1609
+ }
1610
+ break;
1611
+ #if HAVE_RB_SET_NEW_CAPA
1612
+ case SPG_YIELD_FIRST_SET:
1613
+ /* Array of first column */
1614
+ h = rb_set_new_capa(ntuples);
1615
+ for(i=0; i<ntuples; i++) {
1616
+ rb_set_add(h, spg__col_value(self, res, i, 0, colconvert, enc_index));
1617
+ }
1618
+ rb_yield(h);
1619
+ break;
1620
+ case SPG_YIELD_ARRAY_SET:
1621
+ /* Array of arrays of all columns */
1622
+ {
1623
+ VALUE set = rb_set_new_capa(ntuples);
1624
+ for(i=0; i<ntuples; i++) {
1625
+ h = rb_ary_new2(nfields);
1626
+ for(j=0; j<nfields; j++) {
1627
+ rb_ary_store(h, j, spg__col_value(self, res, i, j, colconvert, enc_index));
1628
+ }
1629
+ rb_set_add(set, h);
1630
+ }
1631
+ rb_yield(set);
1632
+ }
1633
+ break;
1634
+ #endif
1482
1635
  case SPG_YIELD_KV_HASH:
1483
1636
  case SPG_YIELD_KV_HASH_GROUPS:
1484
1637
  /* Hash with single key and single value */
1485
1638
  {
1486
1639
  int k, v;
1487
- h = rb_hash_new();
1640
+ VALUE kv, vv;
1488
1641
  k = spg__field_id(rb_ary_entry(pg_value, 0), colsyms, nfields);
1489
1642
  v = spg__field_id(rb_ary_entry(pg_value, 1), colsyms, nfields);
1490
1643
  if(type == SPG_YIELD_KV_HASH) {
1644
+ h = rb_hash_new_capa(ntuples);
1491
1645
  for(i=0; i<ntuples; i++) {
1492
- rb_hash_aset(h, spg__col_value(self, res, i, k, colconvert, enc_index), spg__col_value(self, res, i, v, colconvert, enc_index));
1646
+ kv = k == -1 ? Qnil : spg__col_value(self, res, i, k, colconvert, enc_index);
1647
+ vv = v == -1 ? Qnil : spg__col_value(self, res, i, v, colconvert, enc_index);
1648
+ rb_hash_aset(h, kv, vv);
1493
1649
  }
1494
1650
  } else {
1495
- VALUE kv, vv, a;
1651
+ VALUE a;
1652
+ h = rb_hash_new();
1496
1653
  for(i=0; i<ntuples; i++) {
1497
- kv = spg__col_value(self, res, i, k, colconvert, enc_index);
1498
- vv = spg__col_value(self, res, i, v, colconvert, enc_index);
1654
+ kv = k == -1 ? Qnil : spg__col_value(self, res, i, k, colconvert, enc_index);
1655
+ vv = v == -1 ? Qnil : spg__col_value(self, res, i, v, colconvert, enc_index);
1499
1656
  a = rb_hash_lookup(h, kv);
1500
1657
  if(!RTEST(a)) {
1501
1658
  rb_hash_aset(h, kv, rb_ary_new3(1, vv));
@@ -1511,20 +1668,22 @@ static VALUE spg_yield_hash_rows_internal(VALUE self, PGresult *res, int enc_ind
1511
1668
  case SPG_YIELD_MKV_HASH_GROUPS:
1512
1669
  /* Hash with array of keys and single value */
1513
1670
  {
1514
- VALUE k;
1671
+ VALUE k, vv;
1515
1672
  int v;
1516
- h = rb_hash_new();
1517
1673
  k = spg__field_ids(rb_ary_entry(pg_value, 0), colsyms, nfields);
1518
1674
  v = spg__field_id(rb_ary_entry(pg_value, 1), colsyms, nfields);
1519
1675
  if(type == SPG_YIELD_MKV_HASH) {
1676
+ h = rb_hash_new_capa(ntuples);
1520
1677
  for(i=0; i<ntuples; i++) {
1521
- rb_hash_aset(h, spg__col_values(self, k, colsyms, nfields, res, i, colconvert, enc_index), spg__col_value(self, res, i, v, colconvert, enc_index));
1678
+ vv = v == -1 ? Qnil : spg__col_value(self, res, i, v, colconvert, enc_index);
1679
+ rb_hash_aset(h, spg__col_values(self, k, colsyms, nfields, res, i, colconvert, enc_index), vv);
1522
1680
  }
1523
1681
  } else {
1524
- VALUE kv, vv, a;
1682
+ VALUE kv, a;
1683
+ h = rb_hash_new();
1525
1684
  for(i=0; i<ntuples; i++) {
1526
1685
  kv = spg__col_values(self, k, colsyms, nfields, res, i, colconvert, enc_index);
1527
- vv = spg__col_value(self, res, i, v, colconvert, enc_index);
1686
+ vv = v == -1 ? Qnil : spg__col_value(self, res, i, v, colconvert, enc_index);
1528
1687
  a = rb_hash_lookup(h, kv);
1529
1688
  if(!RTEST(a)) {
1530
1689
  rb_hash_aset(h, kv, rb_ary_new3(1, vv));
@@ -1540,19 +1699,21 @@ static VALUE spg_yield_hash_rows_internal(VALUE self, PGresult *res, int enc_ind
1540
1699
  case SPG_YIELD_KMV_HASH_GROUPS:
1541
1700
  /* Hash with single keys and array of values */
1542
1701
  {
1543
- VALUE v;
1702
+ VALUE v, kv;
1544
1703
  int k;
1545
- h = rb_hash_new();
1546
1704
  k = spg__field_id(rb_ary_entry(pg_value, 0), colsyms, nfields);
1547
1705
  v = spg__field_ids(rb_ary_entry(pg_value, 1), colsyms, nfields);
1548
1706
  if(type == SPG_YIELD_KMV_HASH) {
1707
+ h = rb_hash_new_capa(ntuples);
1549
1708
  for(i=0; i<ntuples; i++) {
1550
- rb_hash_aset(h, spg__col_value(self, res, i, k, colconvert, enc_index), spg__col_values(self, v, colsyms, nfields, res, i, colconvert, enc_index));
1709
+ kv = k == -1 ? Qnil : spg__col_value(self, res, i, k, colconvert, enc_index);
1710
+ rb_hash_aset(h, kv, spg__col_values(self, v, colsyms, nfields, res, i, colconvert, enc_index));
1551
1711
  }
1552
1712
  } else {
1553
- VALUE kv, vv, a;
1713
+ VALUE vv, a;
1714
+ h = rb_hash_new();
1554
1715
  for(i=0; i<ntuples; i++) {
1555
- kv = spg__col_value(self, res, i, k, colconvert, enc_index);
1716
+ kv = k == -1 ? Qnil : spg__col_value(self, res, i, k, colconvert, enc_index);
1556
1717
  vv = spg__col_values(self, v, colsyms, nfields, res, i, colconvert, enc_index);
1557
1718
  a = rb_hash_lookup(h, kv);
1558
1719
  if(!RTEST(a)) {
@@ -1570,15 +1731,16 @@ static VALUE spg_yield_hash_rows_internal(VALUE self, PGresult *res, int enc_ind
1570
1731
  /* Hash with array of keys and array of values */
1571
1732
  {
1572
1733
  VALUE k, v;
1573
- h = rb_hash_new();
1574
1734
  k = spg__field_ids(rb_ary_entry(pg_value, 0), colsyms, nfields);
1575
1735
  v = spg__field_ids(rb_ary_entry(pg_value, 1), colsyms, nfields);
1576
1736
  if(type == SPG_YIELD_MKMV_HASH) {
1737
+ h = rb_hash_new_capa(ntuples);
1577
1738
  for(i=0; i<ntuples; i++) {
1578
1739
  rb_hash_aset(h, spg__col_values(self, k, colsyms, nfields, res, i, colconvert, enc_index), spg__col_values(self, v, colsyms, nfields, res, i, colconvert, enc_index));
1579
1740
  }
1580
1741
  } else {
1581
1742
  VALUE kv, vv, a;
1743
+ h = rb_hash_new();
1582
1744
  for(i=0; i<ntuples; i++) {
1583
1745
  kv = spg__col_values(self, k, colsyms, nfields, res, i, colconvert, enc_index);
1584
1746
  vv = spg__col_values(self, v, colsyms, nfields, res, i, colconvert, enc_index);
@@ -1596,7 +1758,7 @@ static VALUE spg_yield_hash_rows_internal(VALUE self, PGresult *res, int enc_ind
1596
1758
  case SPG_YIELD_MODEL:
1597
1759
  /* Model object for entire row */
1598
1760
  for(i=0; i<ntuples; i++) {
1599
- h = rb_hash_new();
1761
+ h = rb_hash_new_capa(nfields);
1600
1762
  for(j=0; j<nfields; j++) {
1601
1763
  rb_hash_aset(h, colsyms[j], spg__col_value(self, res, i, j, colconvert, enc_index));
1602
1764
  }
@@ -1606,6 +1768,35 @@ static VALUE spg_yield_hash_rows_internal(VALUE self, PGresult *res, int enc_ind
1606
1768
  rb_yield(pg_type);
1607
1769
  }
1608
1770
  break;
1771
+ case SPG_YIELD_ALL_MODEL:
1772
+ {
1773
+ VALUE ary = rb_ary_new2(ntuples);
1774
+ VALUE obj;
1775
+ for(i=0; i<ntuples; i++) {
1776
+ h = rb_hash_new_capa(nfields);
1777
+ for(j=0; j<nfields; j++) {
1778
+ rb_hash_aset(h, colsyms[j], spg__col_value(self, res, i, j, colconvert, enc_index));
1779
+ }
1780
+ obj = rb_obj_alloc(pg_value);
1781
+ rb_ivar_set(obj, spg_id_values, h);
1782
+ rb_ary_store(ary, i, obj);
1783
+ }
1784
+ rb_yield(ary);
1785
+ }
1786
+ break;
1787
+ case SPG_YIELD_ALL:
1788
+ {
1789
+ VALUE ary = rb_ary_new2(ntuples);
1790
+ for(i=0; i<ntuples; i++) {
1791
+ h = rb_hash_new_capa(nfields);
1792
+ for(j=0; j<nfields; j++) {
1793
+ rb_hash_aset(h, colsyms[j], spg__col_value(self, res, i, j, colconvert, enc_index));
1794
+ }
1795
+ rb_ary_store(ary, i, h);
1796
+ }
1797
+ rb_yield(ary);
1798
+ }
1799
+ break;
1609
1800
  }
1610
1801
  return self;
1611
1802
  }
@@ -1674,7 +1865,7 @@ struct spg__yield_each_row_stream_data {
1674
1865
 
1675
1866
  static int spg__yield_each_row_stream(VALUE rres, int ntuples, int nfields, void *rdata) {
1676
1867
  struct spg__yield_each_row_stream_data* data = (struct spg__yield_each_row_stream_data *)rdata;
1677
- VALUE h = rb_hash_new();
1868
+ VALUE h = rb_hash_new_capa(nfields);
1678
1869
  VALUE self = data->self;
1679
1870
  VALUE *colsyms = data->colsyms;
1680
1871
  VALUE *colconvert= data->colconvert;
@@ -1735,7 +1926,7 @@ static VALUE spg__yield_each_row_internal(VALUE self, VALUE rconn, VALUE rres, P
1735
1926
  }
1736
1927
 
1737
1928
  while (PQntuples(res) != 0) {
1738
- h = rb_hash_new();
1929
+ h = rb_hash_new_capa(nfields);
1739
1930
  for(j=0; j<nfields; j++) {
1740
1931
  rb_hash_aset(h, colsyms[j], spg__col_value(self, res, 0, j, colconvert , enc_index));
1741
1932
  }
@@ -1918,11 +2109,19 @@ void Init_sequel_pg(void) {
1918
2109
  spg_sym_utc = ID2SYM(rb_intern("utc"));
1919
2110
  spg_sym_local = ID2SYM(rb_intern("local"));
1920
2111
  spg_sym_map = ID2SYM(rb_intern("map"));
2112
+ spg_sym_map_array = ID2SYM(rb_intern("map_array"));
2113
+ spg_sym_map_set = ID2SYM(rb_intern("map_set"));
1921
2114
  spg_sym_first = ID2SYM(rb_intern("first"));
1922
2115
  spg_sym_array = ID2SYM(rb_intern("array"));
2116
+ spg_sym_first_array = ID2SYM(rb_intern("first_array"));
2117
+ spg_sym_array_array = ID2SYM(rb_intern("array_array"));
2118
+ spg_sym_first_set = ID2SYM(rb_intern("first_set"));
2119
+ spg_sym_array_set = ID2SYM(rb_intern("array_set"));
1923
2120
  spg_sym_hash = ID2SYM(rb_intern("hash"));
1924
2121
  spg_sym_hash_groups = ID2SYM(rb_intern("hash_groups"));
1925
2122
  spg_sym_model = ID2SYM(rb_intern("model"));
2123
+ spg_sym_all = ID2SYM(rb_intern("all"));
2124
+ spg_sym_all_model = ID2SYM(rb_intern("all_model"));
1926
2125
  spg_sym__sequel_pg_type = ID2SYM(rb_intern("_sequel_pg_type"));
1927
2126
  spg_sym__sequel_pg_value = ID2SYM(rb_intern("_sequel_pg_value"));
1928
2127
 
@@ -0,0 +1,48 @@
1
+ class Sequel::Postgres::Dataset
2
+ # If model loads are being optimized and this is a model load, use the optimized
3
+ # version.
4
+ def each(&block)
5
+ rp = row_proc
6
+ return super unless allow_sequel_pg_optimization? && optimize_model_load?(rp)
7
+ clone(:_sequel_pg_type=>:model, :_sequel_pg_value=>rp).fetch_rows(sql, &block)
8
+ end
9
+
10
+ # Avoid duplicate method warning
11
+ alias with_sql_all with_sql_all
12
+
13
+ # Always use optimized version
14
+ def with_sql_all(sql, &block)
15
+ rp = row_proc
16
+ return super unless allow_sequel_pg_optimization?
17
+
18
+ if optimize_model_load?(rp)
19
+ clone(:_sequel_pg_type=>:all_model, :_sequel_pg_value=>row_proc).fetch_rows(sql) do |array|
20
+ post_load(array)
21
+ array.each(&block) if block
22
+ return array
23
+ end
24
+ []
25
+ else
26
+ clone(:_sequel_pg_type=>:all).fetch_rows(sql) do |array|
27
+ if rp = row_proc
28
+ array.map!{|h| rp.call(h)}
29
+ end
30
+ post_load(array)
31
+ array.each(&block) if block
32
+ return array
33
+ end
34
+ []
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ # The model load can only be optimized if it's for a model and it's not a graphed dataset
41
+ # or using a cursor.
42
+ def optimize_model_load?(rp)
43
+ rp.is_a?(Class) &&
44
+ rp < Sequel::Model &&
45
+ rp.method(:call).owner == Sequel::Model::ClassMethods &&
46
+ opts[:optimize_model_load] != false
47
+ end
48
+ end
@@ -21,15 +21,33 @@ class Sequel::Postgres::Dataset
21
21
  opts.has_key?(:optimize_model_load) ? opts[:optimize_model_load] : true
22
22
  end
23
23
 
24
+ # :nocov:
25
+ if method_defined?(:as_set)
26
+ # :nocov:
27
+ if RUBY_VERSION > '4'
28
+ def as_set(column)
29
+ clone(:_sequel_pg_type=>:map_set, :_sequel_pg_value=>column).fetch_rows(sql){return it}
30
+ Set.new
31
+ end
32
+ # :nocov:
33
+ else
34
+ def as_set(column)
35
+ rows = Set.new
36
+ clone(:_sequel_pg_type=>:map, :_sequel_pg_value=>column).fetch_rows(sql){|s| rows.add(s)}
37
+ rows
38
+ end
39
+ end
40
+ # :nocov:
41
+ end
42
+
24
43
  # In the case where an argument is given, use an optimized version.
25
44
  def map(sym=nil)
26
45
  if sym
27
46
  if block_given?
28
47
  super
29
48
  else
30
- rows = []
31
- clone(:_sequel_pg_type=>:map, :_sequel_pg_value=>sym).fetch_rows(sql){|s| rows << s}
32
- rows
49
+ clone(:_sequel_pg_type=>:map_array, :_sequel_pg_value=>sym).fetch_rows(sql){|a| return a}
50
+ []
33
51
  end
34
52
  else
35
53
  super
@@ -73,48 +91,86 @@ class Sequel::Postgres::Dataset
73
91
  end
74
92
  end
75
93
 
76
- if defined?(Sequel::Model::ClassMethods)
77
- # If model loads are being optimized and this is a model load, use the optimized
78
- # version.
79
- def each(&block)
80
- if optimize_model_load?
81
- clone(:_sequel_pg_type=>:model, :_sequel_pg_value=>row_proc).fetch_rows(sql, &block)
82
- else
83
- super
94
+ # Delegate to with_sql_all using the default SQL
95
+ def all(&block)
96
+ with_sql_all(sql, &block)
97
+ end
98
+
99
+ # :nocov:
100
+ # Generally overridden by the model support, only used if the model
101
+ # support is not used.
102
+ def with_sql_all(sql, &block)
103
+ return super unless allow_sequel_pg_optimization?
104
+
105
+ clone(:_sequel_pg_type=>:all).fetch_rows(sql) do |array|
106
+ if rp = row_proc
107
+ array.map!{|h| rp.call(h)}
84
108
  end
109
+ post_load(array)
110
+ array.each(&block) if block
111
+ return array
85
112
  end
113
+ []
86
114
  end
115
+ # :nocov:
87
116
 
88
117
  protected
89
118
 
90
119
  # Always use optimized version
91
120
  def _select_map_multiple(ret_cols)
92
- rows = []
93
- clone(:_sequel_pg_type=>:array).fetch_rows(sql){|s| rows << s}
94
- rows
121
+ clone(:_sequel_pg_type=>:array_array).fetch_rows(sql){|a| return a}
122
+ []
95
123
  end
96
124
 
97
125
  # Always use optimized version
98
126
  def _select_map_single
99
- rows = []
100
- clone(:_sequel_pg_type=>:first).fetch_rows(sql){|s| rows << s}
101
- rows
127
+ clone(:_sequel_pg_type=>:first_array).fetch_rows(sql){|a| return a}
128
+ []
102
129
  end
103
130
 
104
- private
131
+ # :nocov:
132
+ if method_defined?(:_select_set_multiple)
133
+ # :nocov:
134
+ if RUBY_VERSION > '4'
135
+ # Always use optimized version
136
+ def _select_set_multiple(ret_cols)
137
+ clone(:_sequel_pg_type=>:array_set).fetch_rows(sql){return it}
138
+ Set.new
139
+ end
105
140
 
106
- if defined?(Sequel::Model::ClassMethods)
107
- # The model load can only be optimized if it's for a model and it's not a graphed dataset
108
- # or using a cursor.
109
- def optimize_model_load?
110
- (rp = row_proc) &&
111
- rp.is_a?(Class) &&
112
- rp < Sequel::Model &&
113
- rp.method(:call).owner == Sequel::Model::ClassMethods &&
114
- opts[:optimize_model_load] != false &&
115
- !opts[:use_cursor] &&
116
- !opts[:graph]
141
+ # Always use optimized version
142
+ def _select_set_single
143
+ clone(:_sequel_pg_type=>:first_set).fetch_rows(sql){return it}
144
+ Set.new
145
+ end
146
+ # :nocov:
147
+ else
148
+ # Always use optimized version
149
+ def _select_set_multiple(ret_cols)
150
+ set = Set.new
151
+ clone(:_sequel_pg_type=>:array).fetch_rows(sql){|s| set.add s}
152
+ set
153
+ end
154
+
155
+ # Always use optimized version
156
+ def _select_set_single
157
+ set = Set.new
158
+ clone(:_sequel_pg_type=>:first).fetch_rows(sql){|s| set.add s}
159
+ set
160
+ end
117
161
  end
162
+ # :nocov:
163
+ end
164
+
165
+ if defined?(Sequel::Model::ClassMethods)
166
+ require_relative 'model'
167
+ end
168
+
169
+ private
170
+
171
+ # Whether to allow sequel_pg to optimize the each/all/with_sql_all call.
172
+ def allow_sequel_pg_optimization?
173
+ (!opts[:graph] || opts[:eager_graph]) && !opts[:cursor]
118
174
  end
119
175
  end
120
176
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequel_pg
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.17.2
4
+ version: 1.18.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Evans
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-03-14 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: pg
@@ -57,9 +57,9 @@ executables: []
57
57
  extensions:
58
58
  - ext/sequel_pg/extconf.rb
59
59
  extra_rdoc_files:
60
- - README.rdoc
61
60
  - CHANGELOG
62
61
  - MIT-LICENSE
62
+ - README.rdoc
63
63
  files:
64
64
  - CHANGELOG
65
65
  - MIT-LICENSE
@@ -68,6 +68,7 @@ files:
68
68
  - ext/sequel_pg/extconf.rb
69
69
  - ext/sequel_pg/sequel_pg.c
70
70
  - lib/sequel/extensions/pg_streaming.rb
71
+ - lib/sequel_pg/model.rb
71
72
  - lib/sequel_pg/sequel_pg.rb
72
73
  homepage: http://github.com/jeremyevans/sequel_pg
73
74
  licenses:
@@ -99,7 +100,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
99
100
  - !ruby/object:Gem::Version
100
101
  version: '0'
101
102
  requirements: []
102
- rubygems_version: 3.6.2
103
+ rubygems_version: 3.6.9
103
104
  specification_version: 4
104
105
  summary: Faster SELECTs when using Sequel with pg
105
106
  test_files: []