sequel_pg 1.1.1-x86-mingw32 → 1.2.0-x86-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +12 -0
- data/README.rdoc +25 -0
- data/Rakefile +1 -1
- data/ext/sequel_pg/sequel_pg.c +303 -71
- data/lib/1.8/sequel_pg.so +0 -0
- data/lib/1.9/sequel_pg.so +0 -0
- data/lib/sequel_pg/sequel_pg.rb +76 -0
- metadata +9 -8
data/CHANGELOG
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
=== 1.2.0 (2011-11-01)
|
2
|
+
|
3
|
+
* Add optimize_model_load setting to speedup loading of model objects, off by default (jeremyevans)
|
4
|
+
|
5
|
+
* Add major speedup to Dataset#map, #to_hash, #select_map, #select_order_map, and #select_hash (jeremyevans)
|
6
|
+
|
7
|
+
* Work with the new Database#timezone setting in Sequel 3.29.0 (jeremyevans)
|
8
|
+
|
9
|
+
=== 1.1.1 (2011-09-01)
|
10
|
+
|
11
|
+
* Work with new Sequel::SQLTime for time columns in Sequel 3.27.0 (jeremyevans)
|
12
|
+
|
1
13
|
=== 1.1.0 (2011-06-01)
|
2
14
|
|
3
15
|
* Work with new Database#conversion_procs method in Sequel 3.24.0 (jeremyevans)
|
data/README.rdoc
CHANGED
@@ -38,6 +38,31 @@ Here's an example that uses a modified version of swift's benchmarks
|
|
38
38
|
sequel #select 0.090000 2.020000 2.110000 2.246688 46.54m
|
39
39
|
sequel_pg #select 0.000000 0.250000 0.250000 0.361999 7.33m
|
40
40
|
|
41
|
+
sequel_pg also has code to speed up the map, to_hash, select_hash,
|
42
|
+
select_map, and select_order_map Dataset methods, which is on by
|
43
|
+
default. It also has code to speed up the loading of model objects,
|
44
|
+
which is off by default as it isn't fully compatible. It doesn't
|
45
|
+
handle overriding Model.call, Model#set_values, or
|
46
|
+
Model#after_initialize, which may cause problems with the
|
47
|
+
following plugins that ship with Sequel:
|
48
|
+
|
49
|
+
* class_table_inheritance
|
50
|
+
* force_encoding
|
51
|
+
* serializiation
|
52
|
+
* single_table_interitance
|
53
|
+
* typecast_on_load
|
54
|
+
* update_primary_key
|
55
|
+
|
56
|
+
If you want to extract that last ounce of performance when loading
|
57
|
+
model objects and you can live with the limitations, you can
|
58
|
+
enable the model optimization via:
|
59
|
+
|
60
|
+
# All datasets
|
61
|
+
DB.optimize_model_load = true
|
62
|
+
|
63
|
+
# Specific dataset
|
64
|
+
Artist.dataset.optimize_model_load = true
|
65
|
+
|
41
66
|
== Installing the gem
|
42
67
|
|
43
68
|
gem install sequel_pg
|
data/Rakefile
CHANGED
data/ext/sequel_pg/sequel_pg.c
CHANGED
@@ -7,6 +7,9 @@
|
|
7
7
|
#if defined(HAVE_RUBY_ENCODING_H) && HAVE_RUBY_ENCODING_H
|
8
8
|
#define SPG_ENCODING 1
|
9
9
|
#include <ruby/encoding.h>
|
10
|
+
#define ENC_INDEX ,enc_index
|
11
|
+
#else
|
12
|
+
#define ENC_INDEX
|
10
13
|
#endif
|
11
14
|
|
12
15
|
#define SPG_MAX_FIELDS 256
|
@@ -22,6 +25,17 @@
|
|
22
25
|
#define SPG_APP_LOCAL 4
|
23
26
|
#define SPG_APP_UTC 8
|
24
27
|
|
28
|
+
#define SPG_YIELD_NORMAL 0
|
29
|
+
#define SPG_YIELD_COLUMN 1
|
30
|
+
#define SPG_YIELD_COLUMNS 2
|
31
|
+
#define SPG_YIELD_FIRST 3
|
32
|
+
#define SPG_YIELD_ARRAY 4
|
33
|
+
#define SPG_YIELD_KV_HASH 5
|
34
|
+
#define SPG_YIELD_MKV_HASH 6
|
35
|
+
#define SPG_YIELD_KMV_HASH 7
|
36
|
+
#define SPG_YIELD_MKMV_HASH 8
|
37
|
+
#define SPG_YIELD_MODEL 9
|
38
|
+
|
25
39
|
static VALUE spg_Sequel;
|
26
40
|
static VALUE spg_Blob;
|
27
41
|
static VALUE spg_BigDecimal;
|
@@ -30,6 +44,13 @@ static VALUE spg_SQLTime;
|
|
30
44
|
|
31
45
|
static VALUE spg_sym_utc;
|
32
46
|
static VALUE spg_sym_local;
|
47
|
+
static VALUE spg_sym_map;
|
48
|
+
static VALUE spg_sym_first;
|
49
|
+
static VALUE spg_sym_array;
|
50
|
+
static VALUE spg_sym_hash;
|
51
|
+
static VALUE spg_sym_model;
|
52
|
+
static VALUE spg_sym__sequel_pg_type;
|
53
|
+
static VALUE spg_sym__sequel_pg_value;
|
33
54
|
|
34
55
|
static ID spg_id_new;
|
35
56
|
static ID spg_id_local;
|
@@ -39,7 +60,7 @@ static ID spg_id_day;
|
|
39
60
|
static ID spg_id_output_identifier;
|
40
61
|
static ID spg_id_datetime_class;
|
41
62
|
static ID spg_id_application_timezone;
|
42
|
-
static ID
|
63
|
+
static ID spg_id_timezone;
|
43
64
|
static ID spg_id_op_plus;
|
44
65
|
static ID spg_id_utc;
|
45
66
|
static ID spg_id_utc_offset;
|
@@ -48,12 +69,14 @@ static ID spg_id_new_offset;
|
|
48
69
|
|
49
70
|
static ID spg_id_call;
|
50
71
|
static ID spg_id_get;
|
72
|
+
static ID spg_id_opts;
|
51
73
|
|
52
74
|
static ID spg_id_db;
|
53
75
|
static ID spg_id_conversion_procs;
|
54
76
|
|
55
77
|
static ID spg_id_columns;
|
56
78
|
static ID spg_id_encoding;
|
79
|
+
static ID spg_id_values;
|
57
80
|
|
58
81
|
#if SPG_ENCODING
|
59
82
|
static int enc_get_index(VALUE val)
|
@@ -94,7 +117,7 @@ static VALUE spg_date(const char *s) {
|
|
94
117
|
return rb_funcall(spg_Date, spg_id_new, 3, INT2NUM(year), INT2NUM(month), INT2NUM(day));
|
95
118
|
}
|
96
119
|
|
97
|
-
static VALUE spg_timestamp(const char *s) {
|
120
|
+
static VALUE spg_timestamp(const char *s, VALUE self) {
|
98
121
|
VALUE dtc, dt, rtz;
|
99
122
|
int tz = SPG_NO_TZ;
|
100
123
|
int year, month, day, hour, min, sec, usec, tokens, utc_offset;
|
@@ -135,7 +158,7 @@ static VALUE spg_timestamp(const char *s) {
|
|
135
158
|
|
136
159
|
/* Get values of datetime_class, database_timezone, and application_timezone */
|
137
160
|
dtc = rb_funcall(spg_Sequel, spg_id_datetime_class, 0);
|
138
|
-
rtz = rb_funcall(
|
161
|
+
rtz = rb_funcall(rb_funcall(self, spg_id_db, 0), spg_id_timezone, 0);
|
139
162
|
if (rtz == spg_sym_local) {
|
140
163
|
tz += SPG_DB_LOCAL;
|
141
164
|
} else if (rtz == spg_sym_utc) {
|
@@ -234,6 +257,116 @@ static VALUE spg_fetch_rows_set_cols(VALUE self, VALUE ignore) {
|
|
234
257
|
return self;
|
235
258
|
}
|
236
259
|
|
260
|
+
static VALUE spg__col_value(VALUE self, PGresult *res, long i, long j, VALUE* colconvert
|
261
|
+
#ifdef SPG_ENCODING
|
262
|
+
, int enc_index
|
263
|
+
#endif
|
264
|
+
) {
|
265
|
+
char *v;
|
266
|
+
VALUE rv;
|
267
|
+
size_t l;
|
268
|
+
|
269
|
+
if(PQgetisnull(res, i, j)) {
|
270
|
+
rv = Qnil;
|
271
|
+
} else {
|
272
|
+
v = PQgetvalue(res, i, j);
|
273
|
+
|
274
|
+
switch(PQftype(res, j)) {
|
275
|
+
case 16: /* boolean */
|
276
|
+
rv = *v == 't' ? Qtrue : Qfalse;
|
277
|
+
break;
|
278
|
+
case 17: /* bytea */
|
279
|
+
v = (char *)PQunescapeBytea((unsigned char*)v, &l);
|
280
|
+
rv = rb_funcall(spg_Blob, spg_id_new, 1, rb_str_new(v, l));
|
281
|
+
PQfreemem(v);
|
282
|
+
break;
|
283
|
+
case 20: /* integer */
|
284
|
+
case 21:
|
285
|
+
case 22:
|
286
|
+
case 23:
|
287
|
+
case 26:
|
288
|
+
rv = rb_cstr2inum(v, 10);
|
289
|
+
break;
|
290
|
+
case 700: /* float */
|
291
|
+
case 701:
|
292
|
+
rv = rb_float_new(rb_cstr_to_dbl(v, Qfalse));
|
293
|
+
break;
|
294
|
+
case 790: /* numeric */
|
295
|
+
case 1700:
|
296
|
+
rv = rb_funcall(spg_BigDecimal, spg_id_new, 1, rb_str_new(v, PQgetlength(res, i, j)));
|
297
|
+
break;
|
298
|
+
case 1082: /* date */
|
299
|
+
rv = spg_date(v);
|
300
|
+
break;
|
301
|
+
case 1083: /* time */
|
302
|
+
case 1266:
|
303
|
+
rv = spg_time(v);
|
304
|
+
break;
|
305
|
+
case 1114: /* timestamp */
|
306
|
+
case 1184:
|
307
|
+
rv = spg_timestamp(v, self);
|
308
|
+
break;
|
309
|
+
case 18: /* char */
|
310
|
+
case 25: /* text */
|
311
|
+
case 1043: /* varchar*/
|
312
|
+
rv = rb_tainted_str_new(v, PQgetlength(res, i, j));
|
313
|
+
#ifdef SPG_ENCODING
|
314
|
+
rb_enc_associate_index(rv, enc_index);
|
315
|
+
#endif
|
316
|
+
break;
|
317
|
+
default:
|
318
|
+
rv = rb_tainted_str_new(v, PQgetlength(res, i, j));
|
319
|
+
#ifdef SPG_ENCODING
|
320
|
+
rb_enc_associate_index(rv, enc_index);
|
321
|
+
#endif
|
322
|
+
if (colconvert[j] != Qnil) {
|
323
|
+
rv = rb_funcall(colconvert[j], spg_id_call, 1, rv);
|
324
|
+
}
|
325
|
+
}
|
326
|
+
}
|
327
|
+
return rv;
|
328
|
+
}
|
329
|
+
|
330
|
+
static VALUE spg__col_values(VALUE self, VALUE v, VALUE *colsyms, long nfields, PGresult *res, long i, VALUE *colconvert
|
331
|
+
#ifdef SPG_ENCODING
|
332
|
+
, int enc_index
|
333
|
+
#endif
|
334
|
+
) {
|
335
|
+
long j;
|
336
|
+
VALUE cur;
|
337
|
+
long len = RARRAY_LEN(v);
|
338
|
+
VALUE a = rb_ary_new2(len);
|
339
|
+
for (j=0; j<len; j++) {
|
340
|
+
cur = rb_ary_entry(v, j);
|
341
|
+
rb_ary_store(a, j, cur == Qnil ? Qnil : spg__col_value(self, res, i, NUM2LONG(cur), colconvert ENC_INDEX));
|
342
|
+
}
|
343
|
+
return a;
|
344
|
+
}
|
345
|
+
|
346
|
+
static long spg__field_id(VALUE v, VALUE *colsyms, long nfields) {
|
347
|
+
long j;
|
348
|
+
for (j=0; j<nfields; j++) {
|
349
|
+
if (colsyms[j] == v) {
|
350
|
+
return j;
|
351
|
+
}
|
352
|
+
}
|
353
|
+
return -1;
|
354
|
+
}
|
355
|
+
|
356
|
+
static VALUE spg__field_ids(VALUE v, VALUE *colsyms, long nfields) {
|
357
|
+
long i;
|
358
|
+
long j;
|
359
|
+
VALUE cur;
|
360
|
+
long len = RARRAY_LEN(v);
|
361
|
+
VALUE pg_columns = rb_ary_new2(len);
|
362
|
+
for (i=0; i<len; i++) {
|
363
|
+
cur = rb_ary_entry(v, i);
|
364
|
+
j = spg__field_id(cur, colsyms, nfields);
|
365
|
+
rb_ary_store(pg_columns, i, j == -1 ? Qnil : LONG2NUM(j));
|
366
|
+
}
|
367
|
+
return pg_columns;
|
368
|
+
}
|
369
|
+
|
237
370
|
static VALUE spg_yield_hash_rows(VALUE self, VALUE rres, VALUE ignore) {
|
238
371
|
PGresult *res;
|
239
372
|
VALUE colsyms[SPG_MAX_FIELDS];
|
@@ -242,10 +375,12 @@ static VALUE spg_yield_hash_rows(VALUE self, VALUE rres, VALUE ignore) {
|
|
242
375
|
long nfields;
|
243
376
|
long i;
|
244
377
|
long j;
|
245
|
-
VALUE h
|
246
|
-
|
247
|
-
|
248
|
-
VALUE
|
378
|
+
VALUE h;
|
379
|
+
VALUE conv_procs = 0;
|
380
|
+
VALUE opts;
|
381
|
+
VALUE pg_type;
|
382
|
+
VALUE pg_value;
|
383
|
+
char type = SPG_YIELD_NORMAL;
|
249
384
|
|
250
385
|
#ifdef SPG_ENCODING
|
251
386
|
int enc_index;
|
@@ -285,7 +420,7 @@ static VALUE spg_yield_hash_rows(VALUE self, VALUE rres, VALUE ignore) {
|
|
285
420
|
colconvert[j] = Qnil;
|
286
421
|
break;
|
287
422
|
default:
|
288
|
-
if (conv_procs ==
|
423
|
+
if (conv_procs == 0) {
|
289
424
|
conv_procs = rb_funcall(rb_funcall(self, spg_id_db, 0), spg_id_conversion_procs, 0);
|
290
425
|
}
|
291
426
|
colconvert[j] = rb_funcall(conv_procs, spg_id_get, 1, INT2NUM(i));
|
@@ -294,72 +429,157 @@ static VALUE spg_yield_hash_rows(VALUE self, VALUE rres, VALUE ignore) {
|
|
294
429
|
}
|
295
430
|
rb_ivar_set(self, spg_id_columns, rb_ary_new4(nfields, colsyms));
|
296
431
|
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
break;
|
329
|
-
case 1082: /* date */
|
330
|
-
rv = spg_date(v);
|
331
|
-
break;
|
332
|
-
case 1083: /* time */
|
333
|
-
case 1266:
|
334
|
-
rv = spg_time(v);
|
335
|
-
break;
|
336
|
-
case 1114: /* timestamp */
|
337
|
-
case 1184:
|
338
|
-
rv = spg_timestamp(v);
|
339
|
-
break;
|
340
|
-
case 18: /* char */
|
341
|
-
case 25: /* text */
|
342
|
-
case 1043: /* varchar*/
|
343
|
-
rv = rb_tainted_str_new(v, PQgetlength(res, i, j));
|
344
|
-
#ifdef SPG_ENCODING
|
345
|
-
rb_enc_associate_index(rv, enc_index);
|
346
|
-
#endif
|
347
|
-
break;
|
348
|
-
default:
|
349
|
-
rv = rb_tainted_str_new(v, PQgetlength(res, i, j));
|
350
|
-
#ifdef SPG_ENCODING
|
351
|
-
rb_enc_associate_index(rv, enc_index);
|
352
|
-
#endif
|
353
|
-
if (colconvert[j] != Qnil) {
|
354
|
-
rv = rb_funcall(colconvert[j], spg_id_call, 1, rv);
|
355
|
-
}
|
432
|
+
opts = rb_funcall(self, spg_id_opts, 0);
|
433
|
+
if (rb_type(opts) == T_HASH) {
|
434
|
+
pg_type = rb_hash_aref(opts, spg_sym__sequel_pg_type);
|
435
|
+
pg_value = rb_hash_aref(opts, spg_sym__sequel_pg_value);
|
436
|
+
if (SYMBOL_P(pg_type)) {
|
437
|
+
if (pg_type == spg_sym_map) {
|
438
|
+
if (SYMBOL_P(pg_value)) {
|
439
|
+
type = SPG_YIELD_COLUMN;
|
440
|
+
} else if (rb_type(pg_value) == T_ARRAY) {
|
441
|
+
type = SPG_YIELD_COLUMNS;
|
442
|
+
}
|
443
|
+
} else if (pg_type == spg_sym_first) {
|
444
|
+
type = SPG_YIELD_FIRST;
|
445
|
+
} else if (pg_type == spg_sym_array) {
|
446
|
+
type = SPG_YIELD_ARRAY;
|
447
|
+
} else if (pg_type == spg_sym_hash && rb_type(pg_value) == T_ARRAY) {
|
448
|
+
VALUE pg_value_key, pg_value_value;
|
449
|
+
pg_value_key = rb_ary_entry(pg_value, 0);
|
450
|
+
pg_value_value = rb_ary_entry(pg_value, 1);
|
451
|
+
if (SYMBOL_P(pg_value_key)) {
|
452
|
+
if (SYMBOL_P(pg_value_value)) {
|
453
|
+
type = SPG_YIELD_KV_HASH;
|
454
|
+
} else if (rb_type(pg_value_value) == T_ARRAY) {
|
455
|
+
type = SPG_YIELD_KMV_HASH;
|
456
|
+
}
|
457
|
+
} else if (rb_type(pg_value_key) == T_ARRAY) {
|
458
|
+
if (SYMBOL_P(pg_value_value)) {
|
459
|
+
type = SPG_YIELD_MKV_HASH;
|
460
|
+
} else if (rb_type(pg_value_value) == T_ARRAY) {
|
461
|
+
type = SPG_YIELD_MKMV_HASH;
|
462
|
+
}
|
356
463
|
}
|
464
|
+
} else if (pg_type == spg_sym_model && rb_type(pg_value) == T_CLASS) {
|
465
|
+
type = SPG_YIELD_MODEL;
|
357
466
|
}
|
358
|
-
rb_hash_aset(h, colsyms[j], rv);
|
359
467
|
}
|
360
|
-
rb_yield(h);
|
361
468
|
}
|
362
|
-
|
469
|
+
|
470
|
+
switch(type) {
|
471
|
+
case SPG_YIELD_NORMAL:
|
472
|
+
/* Normal, hash for entire row */
|
473
|
+
for(i=0; i<ntuples; i++) {
|
474
|
+
h = rb_hash_new();
|
475
|
+
for(j=0; j<nfields; j++) {
|
476
|
+
rb_hash_aset(h, colsyms[j], spg__col_value(self, res, i, j, colconvert ENC_INDEX));
|
477
|
+
}
|
478
|
+
rb_yield(h);
|
479
|
+
}
|
480
|
+
break;
|
481
|
+
case SPG_YIELD_COLUMN:
|
482
|
+
/* Single column */
|
483
|
+
j = spg__field_id(pg_value, colsyms, nfields);
|
484
|
+
if (j == -1) {
|
485
|
+
for(i=0; i<ntuples; i++) {
|
486
|
+
rb_yield(Qnil);
|
487
|
+
}
|
488
|
+
} else {
|
489
|
+
for(i=0; i<ntuples; i++) {
|
490
|
+
rb_yield(spg__col_value(self, res, i, j, colconvert ENC_INDEX));
|
491
|
+
}
|
492
|
+
}
|
493
|
+
break;
|
494
|
+
case SPG_YIELD_COLUMNS:
|
495
|
+
/* Multiple columns as an array */
|
496
|
+
h = spg__field_ids(pg_value, colsyms, nfields);
|
497
|
+
for(i=0; i<ntuples; i++) {
|
498
|
+
rb_yield(spg__col_values(self, h, colsyms, nfields, res, i, colconvert ENC_INDEX));
|
499
|
+
}
|
500
|
+
break;
|
501
|
+
case SPG_YIELD_FIRST:
|
502
|
+
/* First column */
|
503
|
+
for(i=0; i<ntuples; i++) {
|
504
|
+
rb_yield(spg__col_value(self, res, i, 0, colconvert ENC_INDEX));
|
505
|
+
}
|
506
|
+
break;
|
507
|
+
case SPG_YIELD_ARRAY:
|
508
|
+
/* Array of all columns */
|
509
|
+
for(i=0; i<ntuples; i++) {
|
510
|
+
h = rb_ary_new2(nfields);
|
511
|
+
for(j=0; j<nfields; j++) {
|
512
|
+
rb_ary_store(h, j, spg__col_value(self, res, i, j, colconvert ENC_INDEX));
|
513
|
+
}
|
514
|
+
rb_yield(h);
|
515
|
+
}
|
516
|
+
break;
|
517
|
+
case SPG_YIELD_KV_HASH:
|
518
|
+
/* Hash with single key and single value */
|
519
|
+
{
|
520
|
+
VALUE k, v;
|
521
|
+
h = rb_hash_new();
|
522
|
+
k = spg__field_id(rb_ary_entry(pg_value, 0), colsyms, nfields);
|
523
|
+
v = spg__field_id(rb_ary_entry(pg_value, 1), colsyms, nfields);
|
524
|
+
for(i=0; i<ntuples; i++) {
|
525
|
+
rb_hash_aset(h, spg__col_value(self, res, i, k, colconvert ENC_INDEX), spg__col_value(self, res, i, v, colconvert ENC_INDEX));
|
526
|
+
}
|
527
|
+
rb_yield(h);
|
528
|
+
}
|
529
|
+
break;
|
530
|
+
case SPG_YIELD_MKV_HASH:
|
531
|
+
/* Hash with array of keys and single value */
|
532
|
+
{
|
533
|
+
VALUE k, v;
|
534
|
+
h = rb_hash_new();
|
535
|
+
k = spg__field_ids(rb_ary_entry(pg_value, 0), colsyms, nfields);
|
536
|
+
v = spg__field_id(rb_ary_entry(pg_value, 1), colsyms, nfields);
|
537
|
+
for(i=0; i<ntuples; i++) {
|
538
|
+
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));
|
539
|
+
}
|
540
|
+
rb_yield(h);
|
541
|
+
}
|
542
|
+
break;
|
543
|
+
case SPG_YIELD_KMV_HASH:
|
544
|
+
/* Hash with single keys and array of values */
|
545
|
+
{
|
546
|
+
VALUE k, v;
|
547
|
+
h = rb_hash_new();
|
548
|
+
k = spg__field_id(rb_ary_entry(pg_value, 0), colsyms, nfields);
|
549
|
+
v = spg__field_ids(rb_ary_entry(pg_value, 1), colsyms, nfields);
|
550
|
+
for(i=0; i<ntuples; i++) {
|
551
|
+
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));
|
552
|
+
}
|
553
|
+
rb_yield(h);
|
554
|
+
}
|
555
|
+
break;
|
556
|
+
case SPG_YIELD_MKMV_HASH:
|
557
|
+
/* Hash with array of keys and array of values */
|
558
|
+
{
|
559
|
+
VALUE k, v;
|
560
|
+
h = rb_hash_new();
|
561
|
+
k = spg__field_ids(rb_ary_entry(pg_value, 0), colsyms, nfields);
|
562
|
+
v = spg__field_ids(rb_ary_entry(pg_value, 1), colsyms, nfields);
|
563
|
+
for(i=0; i<ntuples; i++) {
|
564
|
+
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));
|
565
|
+
}
|
566
|
+
rb_yield(h);
|
567
|
+
}
|
568
|
+
break;
|
569
|
+
case SPG_YIELD_MODEL:
|
570
|
+
/* Model object for entire row */
|
571
|
+
for(i=0; i<ntuples; i++) {
|
572
|
+
h = rb_hash_new();
|
573
|
+
for(j=0; j<nfields; j++) {
|
574
|
+
rb_hash_aset(h, colsyms[j], spg__col_value(self, res, i, j, colconvert ENC_INDEX));
|
575
|
+
}
|
576
|
+
/* Abuse local variable */
|
577
|
+
pg_type = rb_obj_alloc(pg_value);
|
578
|
+
rb_ivar_set(pg_type, spg_id_values, h);
|
579
|
+
rb_yield(pg_type);
|
580
|
+
}
|
581
|
+
break;
|
582
|
+
}
|
363
583
|
return self;
|
364
584
|
}
|
365
585
|
|
@@ -375,7 +595,7 @@ void Init_sequel_pg(void) {
|
|
375
595
|
spg_id_output_identifier = rb_intern("output_identifier");
|
376
596
|
spg_id_datetime_class = rb_intern("datetime_class");
|
377
597
|
spg_id_application_timezone = rb_intern("application_timezone");
|
378
|
-
|
598
|
+
spg_id_timezone = rb_intern("timezone");
|
379
599
|
spg_id_op_plus = rb_intern("+");
|
380
600
|
spg_id_utc = rb_intern("utc");
|
381
601
|
spg_id_utc_offset = rb_intern("utc_offset");
|
@@ -385,14 +605,24 @@ void Init_sequel_pg(void) {
|
|
385
605
|
spg_id_call = rb_intern("call");
|
386
606
|
spg_id_get = rb_intern("[]");
|
387
607
|
|
608
|
+
spg_id_opts = rb_intern("opts");
|
609
|
+
|
388
610
|
spg_id_db = rb_intern("db");
|
389
611
|
spg_id_conversion_procs = rb_intern("conversion_procs");
|
390
612
|
|
391
613
|
spg_id_columns = rb_intern("@columns");
|
392
614
|
spg_id_encoding = rb_intern("@encoding");
|
615
|
+
spg_id_values = rb_intern("@values");
|
393
616
|
|
394
617
|
spg_sym_utc = ID2SYM(rb_intern("utc"));
|
395
618
|
spg_sym_local = ID2SYM(rb_intern("local"));
|
619
|
+
spg_sym_map = ID2SYM(rb_intern("map"));
|
620
|
+
spg_sym_first = ID2SYM(rb_intern("first"));
|
621
|
+
spg_sym_array = ID2SYM(rb_intern("array"));
|
622
|
+
spg_sym_hash = ID2SYM(rb_intern("hash"));
|
623
|
+
spg_sym_model = ID2SYM(rb_intern("model"));
|
624
|
+
spg_sym__sequel_pg_type = ID2SYM(rb_intern("_sequel_pg_type"));
|
625
|
+
spg_sym__sequel_pg_value = ID2SYM(rb_intern("_sequel_pg_value"));
|
396
626
|
|
397
627
|
spg_Sequel = rb_funcall(rb_cObject, cg, 1, rb_str_new2("Sequel"));
|
398
628
|
spg_Blob = rb_funcall(rb_funcall(spg_Sequel, cg, 1, rb_str_new2("SQL")), cg, 1, rb_str_new2("Blob"));
|
@@ -409,4 +639,6 @@ void Init_sequel_pg(void) {
|
|
409
639
|
c = rb_funcall(spg_Postgres, cg, 1, rb_str_new2("Dataset"));
|
410
640
|
rb_define_private_method(c, "yield_hash_rows", spg_yield_hash_rows, 2);
|
411
641
|
rb_define_private_method(c, "fetch_rows_set_cols", spg_fetch_rows_set_cols, 1);
|
642
|
+
|
643
|
+
rb_require("sequel_pg/sequel_pg");
|
412
644
|
}
|
data/lib/1.8/sequel_pg.so
CHANGED
Binary file
|
data/lib/1.9/sequel_pg.so
CHANGED
Binary file
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# Add speedup for model class creation from dataset
|
2
|
+
class Sequel::Postgres::Database
|
3
|
+
# Whether to optimize loads for all model datasets created from this dataset.
|
4
|
+
# Has certain limitations, see the README for details.
|
5
|
+
attr_accessor :optimize_model_load
|
6
|
+
end
|
7
|
+
|
8
|
+
# Add faster versions of Dataset#map, #to_hash, #select_map, #select_order_map, and #select_hash
|
9
|
+
class Sequel::Postgres::Dataset
|
10
|
+
# Set whether to enable optimized model loading for this dataset.
|
11
|
+
attr_writer :optimize_model_load
|
12
|
+
|
13
|
+
# In the case where an argument is given, use an optimized version.
|
14
|
+
def map(sym=nil)
|
15
|
+
if sym
|
16
|
+
if block_given?
|
17
|
+
super
|
18
|
+
else
|
19
|
+
rows = []
|
20
|
+
clone(:_sequel_pg_type=>:map, :_sequel_pg_value=>sym).fetch_rows(sql){|s| rows << s}
|
21
|
+
rows
|
22
|
+
end
|
23
|
+
else
|
24
|
+
super
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# If this dataset has turned model loading on or off, use the default value from
|
29
|
+
# the Database object.
|
30
|
+
def optimize_model_load
|
31
|
+
defined?(@optimize_model_load) ? @optimize_model_load : db.optimize_model_load
|
32
|
+
end
|
33
|
+
|
34
|
+
# In the case where both arguments given, use an optimized version.
|
35
|
+
def to_hash(key_column, value_column = nil)
|
36
|
+
if value_column
|
37
|
+
clone(:_sequel_pg_type=>:hash, :_sequel_pg_value=>[key_column, value_column]).fetch_rows(sql){|s| return s}
|
38
|
+
else
|
39
|
+
super
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# If model loads are being optimized and this is a model load, use the optimized
|
44
|
+
# version.
|
45
|
+
def each
|
46
|
+
if (rp = row_proc) && optimize_model_load?
|
47
|
+
clone(:_sequel_pg_type=>:model, :_sequel_pg_value=>rp).fetch_rows(sql, &Proc.new)
|
48
|
+
else
|
49
|
+
super
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
protected
|
54
|
+
|
55
|
+
# Always use optimized version
|
56
|
+
def _select_map_multiple(ret_cols)
|
57
|
+
rows = []
|
58
|
+
clone(:_sequel_pg_type=>:array).fetch_rows(sql){|s| rows << s}
|
59
|
+
rows
|
60
|
+
end
|
61
|
+
|
62
|
+
# Always use optimized version
|
63
|
+
def _select_map_single
|
64
|
+
rows = []
|
65
|
+
clone(:_sequel_pg_type=>:first).fetch_rows(sql){|s| rows << s}
|
66
|
+
rows
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
# The model load can only be optimized if it's for a model and it's not a graphed dataset
|
72
|
+
# or using a cursor.
|
73
|
+
def optimize_model_load?
|
74
|
+
(rp = row_proc).is_a?(Class) && (rp < Sequel::Model) && optimize_model_load && !opts[:use_cursor] && !opts[:graph]
|
75
|
+
end
|
76
|
+
end
|
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
|
-
hash:
|
4
|
+
hash: 31
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 1
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 1.
|
8
|
+
- 2
|
9
|
+
- 0
|
10
|
+
version: 1.2.0
|
11
11
|
platform: x86-mingw32
|
12
12
|
authors:
|
13
13
|
- Jeremy Evans
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-10-31 00:00:00 -07:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -42,12 +42,12 @@ dependencies:
|
|
42
42
|
requirements:
|
43
43
|
- - ">="
|
44
44
|
- !ruby/object:Gem::Version
|
45
|
-
hash:
|
45
|
+
hash: 115
|
46
46
|
segments:
|
47
47
|
- 3
|
48
|
-
-
|
48
|
+
- 29
|
49
49
|
- 0
|
50
|
-
version: 3.
|
50
|
+
version: 3.29.0
|
51
51
|
type: :runtime
|
52
52
|
version_requirements: *id002
|
53
53
|
description: |
|
@@ -72,6 +72,7 @@ files:
|
|
72
72
|
- Rakefile
|
73
73
|
- ext/sequel_pg/extconf.rb
|
74
74
|
- ext/sequel_pg/sequel_pg.c
|
75
|
+
- lib/sequel_pg/sequel_pg.rb
|
75
76
|
- lib/1.8/sequel_pg.so
|
76
77
|
- lib/1.9/sequel_pg.so
|
77
78
|
has_rdoc: true
|