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 +4 -4
- data/CHANGELOG +16 -0
- data/README.rdoc +14 -1
- data/ext/sequel_pg/extconf.rb +2 -0
- data/ext/sequel_pg/sequel_pg.c +220 -21
- data/lib/sequel_pg/model.rb +48 -0
- data/lib/sequel_pg/sequel_pg.rb +85 -29
- metadata +5 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9d497c75bd5ace025a1696d5b5df76116dd54495afee2178872f8f19f06b9257
|
|
4
|
+
data.tar.gz: 24a06481753cb39885de374dfca9e3adcc041e7b0c42550d3406513f79b41ba9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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', :
|
|
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
|
data/ext/sequel_pg/extconf.rb
CHANGED
|
@@ -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")
|
data/ext/sequel_pg/sequel_pg.c
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#define SEQUEL_PG_VERSION_INTEGER
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
data/lib/sequel_pg/sequel_pg.rb
CHANGED
|
@@ -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
|
-
|
|
31
|
-
|
|
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
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
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
|
-
|
|
93
|
-
|
|
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
|
-
|
|
100
|
-
|
|
101
|
-
rows
|
|
127
|
+
clone(:_sequel_pg_type=>:first_array).fetch_rows(sql){|a| return a}
|
|
128
|
+
[]
|
|
102
129
|
end
|
|
103
130
|
|
|
104
|
-
|
|
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
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
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.
|
|
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:
|
|
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.
|
|
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: []
|