sequel_pg 1.3.0 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +8 -0
- data/README.rdoc +33 -7
- data/ext/sequel_pg/extconf.rb +2 -0
- data/ext/sequel_pg/sequel_pg.c +245 -21
- data/lib/sequel_pg/streaming.rb +82 -0
- metadata +9 -8
data/CHANGELOG
CHANGED
@@ -1,5 +1,13 @@
|
|
1
|
+
=== 1.4.0 (2012-06-01)
|
2
|
+
|
3
|
+
* Add support for streaming on PostgreSQL 9.2 using PQsetRowProcessor (jeremyevans)
|
4
|
+
|
5
|
+
* Respect DEBUG environment variable when building (jeremyevans)
|
6
|
+
|
1
7
|
=== 1.3.0 (2012-04-02)
|
2
8
|
|
9
|
+
* Build Windows version against PostgreSQL 9.1.1, ruby 1.8.7, and ruby 1.9.2 (previously 9.0.1, 1.8.6, and 1.9.1) (jeremyevans)
|
10
|
+
|
3
11
|
* Add major speedup for new Sequel 3.34.0 methods Dataset#to_hash_groups and #select_hash_groups (jeremyevans)
|
4
12
|
|
5
13
|
* Handle infinite timestamp values using Database#convert_infinite_timestamps in Sequel 3.34.0 (jeremyevans)
|
data/README.rdoc
CHANGED
@@ -38,13 +38,13 @@ 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,
|
42
|
-
select_map, and select_order_map
|
43
|
-
default. It also has code to speed
|
44
|
-
which is off by default as it isn't
|
45
|
-
handle overriding Model.call,
|
46
|
-
Model#after_initialize, which may cause problems
|
47
|
-
following plugins that ship with Sequel:
|
41
|
+
sequel_pg also has code to speed up the map, to_hash, to_hash_groups,
|
42
|
+
select_hash, select_hash_groups, select_map, and select_order_map
|
43
|
+
Dataset methods, which is on by default. It also has code to speed
|
44
|
+
up the loading of model objects, which is off by default as it isn't
|
45
|
+
fully compatible. It doesn't handle overriding Model.call,
|
46
|
+
Model#set_values, or Model#after_initialize, which may cause problems
|
47
|
+
with the following plugins that ship with Sequel:
|
48
48
|
|
49
49
|
* class_table_inheritance
|
50
50
|
* force_encoding
|
@@ -63,6 +63,32 @@ enable the model optimization via:
|
|
63
63
|
# Specific dataset
|
64
64
|
Artist.dataset.optimize_model_load = true
|
65
65
|
|
66
|
+
== Streaming
|
67
|
+
|
68
|
+
If you are using PostgreSQL 9.2 or higher on the client, then sequel_pg
|
69
|
+
should enable streaming support. This allows you to stream returned
|
70
|
+
rows one at a time, instead of collecting the entire result set in
|
71
|
+
memory (which is how PostgreSQL works by default). You can check
|
72
|
+
if streaming is supported by:
|
73
|
+
|
74
|
+
Sequel::Postgres.supports_streaming?
|
75
|
+
|
76
|
+
If streaming is supported, you can load the streaming support into the
|
77
|
+
database:
|
78
|
+
|
79
|
+
require 'sequel_pg/streaming'
|
80
|
+
DB.extend Sequel::Postgres::Streaming
|
81
|
+
|
82
|
+
Then you can call the Dataset#stream method to have the dataset use
|
83
|
+
the streaming support:
|
84
|
+
|
85
|
+
DB[:table].stream.each{|row| ...}
|
86
|
+
|
87
|
+
If you want to enable streaming for all of a database's datasets, you
|
88
|
+
can do the following:
|
89
|
+
|
90
|
+
DB.extend_datasets Sequel::Postgres::Streaming::AllQueries
|
91
|
+
|
66
92
|
== Installing the gem
|
67
93
|
|
68
94
|
gem install sequel_pg
|
data/ext/sequel_pg/extconf.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'mkmf'
|
2
|
+
$CFLAGS << " -O0 -g -ggdb" if ENV['DEBUG']
|
2
3
|
$CFLAGS << " -Wall " unless RUBY_PLATFORM =~ /solaris/
|
3
4
|
dir_config('pg', ENV["POSTGRES_INCLUDE"] || (IO.popen("pg_config --includedir").readline.chomp rescue nil),
|
4
5
|
ENV["POSTGRES_LIB"] || (IO.popen("pg_config --libdir").readline.chomp rescue nil))
|
@@ -13,6 +14,7 @@ if enable_config("static-build")
|
|
13
14
|
end
|
14
15
|
|
15
16
|
if (have_library('pq') || have_library('libpq') || have_library('ms/libpq')) && have_header('libpq-fe.h')
|
17
|
+
have_func 'PQsetRowProcessor'
|
16
18
|
create_makefile("sequel_pg")
|
17
19
|
else
|
18
20
|
puts 'Could not find PostgreSQL build environment (libraries & headers): Makefile not created'
|
data/ext/sequel_pg/sequel_pg.c
CHANGED
@@ -41,11 +41,23 @@
|
|
41
41
|
#define SPG_YIELD_KMV_HASH_GROUPS 12
|
42
42
|
#define SPG_YIELD_MKMV_HASH_GROUPS 13
|
43
43
|
|
44
|
+
struct spg_row_proc_info {
|
45
|
+
VALUE dataset;
|
46
|
+
VALUE block;
|
47
|
+
VALUE model;
|
48
|
+
VALUE colsyms[SPG_MAX_FIELDS];
|
49
|
+
VALUE colconvert[SPG_MAX_FIELDS];
|
50
|
+
#if SPG_ENCODING
|
51
|
+
int enc_index;
|
52
|
+
#endif
|
53
|
+
};
|
54
|
+
|
44
55
|
static VALUE spg_Sequel;
|
45
56
|
static VALUE spg_Blob;
|
46
57
|
static VALUE spg_BigDecimal;
|
47
58
|
static VALUE spg_Date;
|
48
59
|
static VALUE spg_SQLTime;
|
60
|
+
static VALUE spg_PGError;
|
49
61
|
|
50
62
|
static VALUE spg_sym_utc;
|
51
63
|
static VALUE spg_sym_local;
|
@@ -399,32 +411,13 @@ static VALUE spg__field_ids(VALUE v, VALUE *colsyms, long nfields) {
|
|
399
411
|
return pg_columns;
|
400
412
|
}
|
401
413
|
|
402
|
-
static
|
403
|
-
PGresult *res;
|
404
|
-
VALUE colsyms[SPG_MAX_FIELDS];
|
405
|
-
VALUE colconvert[SPG_MAX_FIELDS];
|
406
|
-
long ntuples;
|
407
|
-
long nfields;
|
414
|
+
static void spg_set_column_info(VALUE self, PGresult *res, VALUE *colsyms, VALUE *colconvert) {
|
408
415
|
long i;
|
409
416
|
long j;
|
410
|
-
|
417
|
+
long nfields;
|
411
418
|
VALUE conv_procs = 0;
|
412
|
-
VALUE opts;
|
413
|
-
VALUE pg_type;
|
414
|
-
VALUE pg_value;
|
415
|
-
char type = SPG_YIELD_NORMAL;
|
416
419
|
|
417
|
-
#ifdef SPG_ENCODING
|
418
|
-
int enc_index;
|
419
|
-
enc_index = enc_get_index(rres);
|
420
|
-
#endif
|
421
|
-
|
422
|
-
Data_Get_Struct(rres, PGresult, res);
|
423
|
-
ntuples = PQntuples(res);
|
424
420
|
nfields = PQnfields(res);
|
425
|
-
if (nfields > SPG_MAX_FIELDS) {
|
426
|
-
rb_raise(rb_eRangeError, "more than %d columns in query", SPG_MAX_FIELDS);
|
427
|
-
}
|
428
421
|
|
429
422
|
for(j=0; j<nfields; j++) {
|
430
423
|
colsyms[j] = rb_funcall(self, spg_id_output_identifier, 1, rb_str_new2(PQfname(res, j)));
|
@@ -459,6 +452,36 @@ static VALUE spg_yield_hash_rows(VALUE self, VALUE rres, VALUE ignore) {
|
|
459
452
|
break;
|
460
453
|
}
|
461
454
|
}
|
455
|
+
}
|
456
|
+
|
457
|
+
static VALUE spg_yield_hash_rows(VALUE self, VALUE rres, VALUE ignore) {
|
458
|
+
PGresult *res;
|
459
|
+
VALUE colsyms[SPG_MAX_FIELDS];
|
460
|
+
VALUE colconvert[SPG_MAX_FIELDS];
|
461
|
+
long ntuples;
|
462
|
+
long nfields;
|
463
|
+
long i;
|
464
|
+
long j;
|
465
|
+
VALUE h;
|
466
|
+
VALUE opts;
|
467
|
+
VALUE pg_type;
|
468
|
+
VALUE pg_value;
|
469
|
+
char type = SPG_YIELD_NORMAL;
|
470
|
+
|
471
|
+
#ifdef SPG_ENCODING
|
472
|
+
int enc_index;
|
473
|
+
enc_index = enc_get_index(rres);
|
474
|
+
#endif
|
475
|
+
|
476
|
+
Data_Get_Struct(rres, PGresult, res);
|
477
|
+
ntuples = PQntuples(res);
|
478
|
+
nfields = PQnfields(res);
|
479
|
+
if (nfields > SPG_MAX_FIELDS) {
|
480
|
+
rb_raise(rb_eRangeError, "more than %d columns in query", SPG_MAX_FIELDS);
|
481
|
+
}
|
482
|
+
|
483
|
+
spg_set_column_info(self, res, colsyms, colconvert);
|
484
|
+
|
462
485
|
rb_ivar_set(self, spg_id_columns, rb_ary_new4(nfields, colsyms));
|
463
486
|
|
464
487
|
opts = rb_funcall(self, spg_id_opts, 0);
|
@@ -675,6 +698,199 @@ static VALUE spg_yield_hash_rows(VALUE self, VALUE rres, VALUE ignore) {
|
|
675
698
|
return self;
|
676
699
|
}
|
677
700
|
|
701
|
+
static VALUE spg_supports_streaming_p(VALUE self) {
|
702
|
+
return
|
703
|
+
#if HAVE_PQSETROWPROCESSOR
|
704
|
+
Qtrue;
|
705
|
+
#else
|
706
|
+
Qfalse;
|
707
|
+
#endif
|
708
|
+
}
|
709
|
+
|
710
|
+
#if HAVE_PQSETROWPROCESSOR
|
711
|
+
static VALUE spg__rp_value(VALUE self, PGresult* res, const PGdataValue* dvs, int j, VALUE* colconvert
|
712
|
+
#ifdef SPG_ENCODING
|
713
|
+
, int enc_index
|
714
|
+
#endif
|
715
|
+
) {
|
716
|
+
const char *v;
|
717
|
+
PGdataValue dv = dvs[j];
|
718
|
+
VALUE rv;
|
719
|
+
size_t l;
|
720
|
+
int len = dv.len;
|
721
|
+
|
722
|
+
if(len < 0) {
|
723
|
+
rv = Qnil;
|
724
|
+
} else {
|
725
|
+
v = dv.value;
|
726
|
+
|
727
|
+
switch(PQftype(res, j)) {
|
728
|
+
case 16: /* boolean */
|
729
|
+
rv = *v == 't' ? Qtrue : Qfalse;
|
730
|
+
break;
|
731
|
+
case 17: /* bytea */
|
732
|
+
v = PQunescapeBytea((unsigned char*)v, &l);
|
733
|
+
rv = rb_funcall(spg_Blob, spg_id_new, 1, rb_str_new(v, l));
|
734
|
+
PQfreemem((char *)v);
|
735
|
+
break;
|
736
|
+
case 20: /* integer */
|
737
|
+
case 21:
|
738
|
+
case 22:
|
739
|
+
case 23:
|
740
|
+
case 26:
|
741
|
+
rv = rb_str2inum(rb_str_new(v, len), 10);
|
742
|
+
break;
|
743
|
+
case 700: /* float */
|
744
|
+
case 701:
|
745
|
+
if (strncmp("NaN", v, 3) == 0) {
|
746
|
+
rv = spg_nan;
|
747
|
+
} else if (strncmp("Infinity", v, 8) == 0) {
|
748
|
+
rv = spg_pos_inf;
|
749
|
+
} else if (strncmp("-Infinity", v, 9) == 0) {
|
750
|
+
rv = spg_neg_inf;
|
751
|
+
} else {
|
752
|
+
rv = rb_float_new(rb_str_to_dbl(rb_str_new(v, len), Qfalse));
|
753
|
+
}
|
754
|
+
break;
|
755
|
+
case 790: /* numeric */
|
756
|
+
case 1700:
|
757
|
+
rv = rb_funcall(spg_BigDecimal, spg_id_new, 1, rb_str_new(v, len));
|
758
|
+
break;
|
759
|
+
case 1082: /* date */
|
760
|
+
rv = rb_str_new(v, len);
|
761
|
+
rv = spg_date(StringValuePtr(rv));
|
762
|
+
break;
|
763
|
+
case 1083: /* time */
|
764
|
+
case 1266:
|
765
|
+
rv = rb_str_new(v, len);
|
766
|
+
rv = spg_time(StringValuePtr(rv));
|
767
|
+
break;
|
768
|
+
case 1114: /* timestamp */
|
769
|
+
case 1184:
|
770
|
+
rv = rb_str_new(v, len);
|
771
|
+
rv = spg_timestamp(StringValuePtr(rv), self);
|
772
|
+
break;
|
773
|
+
case 18: /* char */
|
774
|
+
case 25: /* text */
|
775
|
+
case 1043: /* varchar*/
|
776
|
+
rv = rb_tainted_str_new(v, len);
|
777
|
+
#ifdef SPG_ENCODING
|
778
|
+
rb_enc_associate_index(rv, enc_index);
|
779
|
+
#endif
|
780
|
+
break;
|
781
|
+
default:
|
782
|
+
rv = rb_tainted_str_new(v, len);
|
783
|
+
#ifdef SPG_ENCODING
|
784
|
+
rb_enc_associate_index(rv, enc_index);
|
785
|
+
#endif
|
786
|
+
if (colconvert[j] != Qnil) {
|
787
|
+
rv = rb_funcall(colconvert[j], spg_id_call, 1, rv);
|
788
|
+
}
|
789
|
+
}
|
790
|
+
}
|
791
|
+
return rv;
|
792
|
+
}
|
793
|
+
|
794
|
+
static int spg_row_processor(PGresult *res, const PGdataValue *columns, const char **errmsgp, void *param) {
|
795
|
+
long nfields;
|
796
|
+
struct spg_row_proc_info *info;
|
797
|
+
info = (struct spg_row_proc_info *)param;
|
798
|
+
VALUE *colsyms = info->colsyms;
|
799
|
+
VALUE *colconvert = info->colconvert;
|
800
|
+
VALUE self = info->dataset;
|
801
|
+
|
802
|
+
switch (PQresultStatus(res))
|
803
|
+
{
|
804
|
+
case PGRES_TUPLES_OK:
|
805
|
+
case PGRES_COPY_OUT:
|
806
|
+
case PGRES_COPY_IN:
|
807
|
+
#ifdef HAVE_CONST_PGRES_COPY_BOTH
|
808
|
+
case PGRES_COPY_BOTH:
|
809
|
+
#endif
|
810
|
+
case PGRES_EMPTY_QUERY:
|
811
|
+
case PGRES_COMMAND_OK:
|
812
|
+
break;
|
813
|
+
case PGRES_BAD_RESPONSE:
|
814
|
+
case PGRES_FATAL_ERROR:
|
815
|
+
case PGRES_NONFATAL_ERROR:
|
816
|
+
rb_raise(spg_PGError, "error while streaming results");
|
817
|
+
default:
|
818
|
+
rb_raise(spg_PGError, "unexpected result status while streaming results");
|
819
|
+
}
|
820
|
+
|
821
|
+
nfields = PQnfields(res);
|
822
|
+
if(columns == NULL) {
|
823
|
+
spg_set_column_info(self, res, colsyms, colconvert);
|
824
|
+
rb_ivar_set(self, spg_id_columns, rb_ary_new4(nfields, colsyms));
|
825
|
+
} else {
|
826
|
+
long j;
|
827
|
+
VALUE h, m;
|
828
|
+
h = rb_hash_new();
|
829
|
+
|
830
|
+
for(j=0; j<nfields; j++) {
|
831
|
+
rb_hash_aset(h, colsyms[j], spg__rp_value(self, res, columns, j, colconvert
|
832
|
+
#ifdef SPG_ENCODING
|
833
|
+
, info->enc_index
|
834
|
+
#endif
|
835
|
+
));
|
836
|
+
}
|
837
|
+
|
838
|
+
/* optimize_model_load used, return model instance */
|
839
|
+
if ((m = info->model)) {
|
840
|
+
m = rb_obj_alloc(m);
|
841
|
+
rb_ivar_set(m, spg_id_values, h);
|
842
|
+
h = m;
|
843
|
+
}
|
844
|
+
|
845
|
+
rb_funcall(info->block, spg_id_call, 1, h);
|
846
|
+
}
|
847
|
+
return 1;
|
848
|
+
}
|
849
|
+
|
850
|
+
static VALUE spg_unset_row_processor(VALUE rconn) {
|
851
|
+
PGconn *conn;
|
852
|
+
Data_Get_Struct(rconn, PGconn, conn);
|
853
|
+
if ((PQskipResult(conn)) != NULL) {
|
854
|
+
/* Results remaining when row processor finished,
|
855
|
+
* either because an exception was raised or the iterator
|
856
|
+
* exited early, so skip all remaining rows. */
|
857
|
+
while(PQgetResult(conn) != NULL) {
|
858
|
+
/* Use a separate while loop as PQgetResult is faster than
|
859
|
+
* PQskipResult. */
|
860
|
+
}
|
861
|
+
}
|
862
|
+
PQsetRowProcessor(conn, NULL, NULL);
|
863
|
+
return Qnil;
|
864
|
+
}
|
865
|
+
|
866
|
+
static VALUE spg_with_row_processor(VALUE self, VALUE rconn, VALUE dataset, VALUE block) {
|
867
|
+
struct spg_row_proc_info info;
|
868
|
+
PGconn *conn;
|
869
|
+
Data_Get_Struct(rconn, PGconn, conn);
|
870
|
+
bzero(&info, sizeof(info));
|
871
|
+
|
872
|
+
info.dataset = dataset;
|
873
|
+
info.block = block;
|
874
|
+
info.model = 0;
|
875
|
+
#if SPG_ENCODING
|
876
|
+
info.enc_index = enc_get_index(rconn);
|
877
|
+
#endif
|
878
|
+
|
879
|
+
/* Abuse local variable, detect if optimize_model_load used */
|
880
|
+
block = rb_funcall(dataset, spg_id_opts, 0);
|
881
|
+
if (rb_type(block) == T_HASH && rb_hash_aref(block, spg_sym__sequel_pg_type) == spg_sym_model) {
|
882
|
+
block = rb_hash_aref(block, spg_sym__sequel_pg_value);
|
883
|
+
if (rb_type(block) == T_CLASS) {
|
884
|
+
info.model = block;
|
885
|
+
}
|
886
|
+
}
|
887
|
+
|
888
|
+
PQsetRowProcessor(conn, spg_row_processor, (void*)&info);
|
889
|
+
rb_ensure(rb_yield, Qnil, spg_unset_row_processor, rconn);
|
890
|
+
return Qnil;
|
891
|
+
}
|
892
|
+
#endif
|
893
|
+
|
678
894
|
void Init_sequel_pg(void) {
|
679
895
|
VALUE c, spg_Postgres;
|
680
896
|
ID cg;
|
@@ -725,6 +941,7 @@ void Init_sequel_pg(void) {
|
|
725
941
|
spg_BigDecimal = rb_funcall(rb_cObject, cg, 1, rb_str_new2("BigDecimal"));
|
726
942
|
spg_Date = rb_funcall(rb_cObject, cg, 1, rb_str_new2("Date"));
|
727
943
|
spg_Postgres = rb_funcall(spg_Sequel, cg, 1, rb_str_new2("Postgres"));
|
944
|
+
spg_PGError = rb_funcall(rb_cObject, cg, 1, rb_str_new2("PGError"));
|
728
945
|
|
729
946
|
spg_nan = rb_eval_string("0.0/0.0");
|
730
947
|
spg_pos_inf = rb_eval_string("1.0/0.0");
|
@@ -749,5 +966,12 @@ void Init_sequel_pg(void) {
|
|
749
966
|
rb_define_private_method(c, "yield_hash_rows", spg_yield_hash_rows, 2);
|
750
967
|
rb_define_private_method(c, "fetch_rows_set_cols", spg_fetch_rows_set_cols, 1);
|
751
968
|
|
969
|
+
rb_define_singleton_method(spg_Postgres, "supports_streaming?", spg_supports_streaming_p, 0);
|
970
|
+
|
971
|
+
#if HAVE_PQSETROWPROCESSOR
|
972
|
+
c = rb_funcall(spg_Postgres, cg, 1, rb_str_new2("Database"));
|
973
|
+
rb_define_private_method(c, "with_row_processor", spg_with_row_processor, 3);
|
974
|
+
#endif
|
975
|
+
|
752
976
|
rb_require("sequel_pg/sequel_pg");
|
753
977
|
}
|
@@ -0,0 +1,82 @@
|
|
1
|
+
unless Sequel::Postgres.respond_to?(:supports_streaming?)
|
2
|
+
raise LoadError, "either sequel_pg not loaded, or an old version of sequel_pg loaded"
|
3
|
+
end
|
4
|
+
unless Sequel::Postgres.supports_streaming?
|
5
|
+
raise LoadError, "streaming is not supported by the version of libpq in use"
|
6
|
+
end
|
7
|
+
|
8
|
+
# Database methods necessary to support streaming. You should extend your
|
9
|
+
# Database object with this:
|
10
|
+
#
|
11
|
+
# DB.extend Sequel::Postgres::Streaming
|
12
|
+
#
|
13
|
+
# Then you can call #stream on your datasets to use the streaming support:
|
14
|
+
#
|
15
|
+
# DB[:table].stream.each{|row| ...}
|
16
|
+
module Sequel::Postgres::Streaming
|
17
|
+
# Also extend the database's datasets to support streaming
|
18
|
+
def self.extended(db)
|
19
|
+
db.extend_datasets(DatasetMethods)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
# If streaming is requested, set a row processor while executing
|
25
|
+
# the query.
|
26
|
+
def _execute(conn, sql, opts={})
|
27
|
+
if stream = opts[:stream]
|
28
|
+
with_row_processor(conn, *stream){super}
|
29
|
+
else
|
30
|
+
super
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Dataset methods used to implement streaming.
|
35
|
+
module DatasetMethods
|
36
|
+
# If streaming has been requested and the current dataset
|
37
|
+
# can be streamed, request the database use streaming when
|
38
|
+
# executing this query.
|
39
|
+
def fetch_rows(sql, &block)
|
40
|
+
if stream_results?
|
41
|
+
execute(sql, :stream=>[self, block])
|
42
|
+
else
|
43
|
+
super
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Return a clone of the dataset that will use streaming to load
|
48
|
+
# rows.
|
49
|
+
def stream
|
50
|
+
clone(:stream=>true)
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
# Only stream results if streaming has been specifically requested
|
56
|
+
# and the query is streamable.
|
57
|
+
def stream_results?
|
58
|
+
@opts[:stream] && streamable?
|
59
|
+
end
|
60
|
+
|
61
|
+
# Queries using cursors are not streamable, and queries that use
|
62
|
+
# the map/select_map/to_hash/to_hash_groups optimizations are not
|
63
|
+
# streamable, but other queries are streamable.
|
64
|
+
def streamable?
|
65
|
+
spgt = (o = @opts)[:_sequel_pg_type]
|
66
|
+
(spgt.nil? || spgt == :model) && !o[:cursor]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Extend a database's datasets with this module to enable streaming
|
71
|
+
# on all streamable queries:
|
72
|
+
#
|
73
|
+
# DB.extend_datasets(Sequel::Postgres::Streaming::AllQueries)
|
74
|
+
module AllQueries
|
75
|
+
private
|
76
|
+
|
77
|
+
# Always stream results if the query is streamable.
|
78
|
+
def stream_results?
|
79
|
+
streamable?
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sequel_pg
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-06-01 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: pg
|
16
|
-
requirement: &
|
16
|
+
requirement: &4392569800 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,18 +21,18 @@ dependencies:
|
|
21
21
|
version: 0.8.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *4392569800
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: sequel
|
27
|
-
requirement: &
|
27
|
+
requirement: &4392569320 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: 3.
|
32
|
+
version: 3.36.0
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *4392569320
|
36
36
|
description: ! 'sequel_pg overwrites the inner loop of the Sequel postgres
|
37
37
|
|
38
38
|
adapter row fetching code with a C version. The C version
|
@@ -58,6 +58,7 @@ files:
|
|
58
58
|
- ext/sequel_pg/extconf.rb
|
59
59
|
- ext/sequel_pg/sequel_pg.c
|
60
60
|
- lib/sequel_pg/sequel_pg.rb
|
61
|
+
- lib/sequel_pg/streaming.rb
|
61
62
|
homepage: http://github.com/jeremyevans/sequel_pg
|
62
63
|
licenses: []
|
63
64
|
post_install_message:
|
@@ -76,7 +77,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
76
77
|
requirements:
|
77
78
|
- - ! '>='
|
78
79
|
- !ruby/object:Gem::Version
|
79
|
-
version: 1.8.
|
80
|
+
version: 1.8.7
|
80
81
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
82
|
none: false
|
82
83
|
requirements:
|