extralite-bundle 2.5 → 2.7
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/.gitignore +1 -0
- data/CHANGELOG.md +34 -13
- data/Gemfile +4 -0
- data/Gemfile-bundle +1 -1
- data/LICENSE +1 -1
- data/README.md +1059 -247
- data/Rakefile +18 -0
- data/TODO.md +0 -7
- data/examples/kv_store.rb +49 -0
- data/examples/multi_fiber.rb +16 -0
- data/examples/on_progress.rb +9 -0
- data/examples/pubsub_store_polyphony.rb +194 -0
- data/examples/pubsub_store_threads.rb +204 -0
- data/ext/extralite/changeset.c +463 -0
- data/ext/extralite/common.c +177 -91
- data/ext/extralite/database.c +745 -276
- data/ext/extralite/extconf-bundle.rb +10 -4
- data/ext/extralite/extconf.rb +34 -34
- data/ext/extralite/extralite.h +104 -47
- data/ext/extralite/extralite_ext.c +6 -0
- data/ext/extralite/iterator.c +14 -86
- data/ext/extralite/query.c +171 -264
- data/extralite-bundle.gemspec +1 -1
- data/extralite.gemspec +1 -1
- data/gemspec.rb +10 -11
- data/lib/extralite/version.rb +1 -1
- data/lib/extralite.rb +69 -10
- data/lib/sequel/adapters/extralite.rb +1 -1
- data/test/helper.rb +9 -1
- data/test/perf_argv_transform.rb +74 -0
- data/test/perf_ary.rb +14 -12
- data/test/perf_hash.rb +17 -15
- data/test/perf_hash_prepared.rb +58 -0
- data/test/perf_hash_transform.rb +66 -0
- data/test/perf_polyphony.rb +74 -0
- data/test/test_changeset.rb +161 -0
- data/test/test_database.rb +720 -104
- data/test/test_extralite.rb +2 -2
- data/test/test_iterator.rb +28 -13
- data/test/test_query.rb +352 -110
- data/test/test_sequel.rb +4 -4
- metadata +24 -16
- data/Gemfile.lock +0 -37
- data/test/perf_prepared.rb +0 -64
@@ -6,11 +6,17 @@ $CFLAGS << ' -Wno-undef'
|
|
6
6
|
$CFLAGS << ' -Wno-discarded-qualifiers'
|
7
7
|
$CFLAGS << ' -Wno-unused-function'
|
8
8
|
|
9
|
-
|
10
|
-
$defs <<
|
11
|
-
$defs <<
|
9
|
+
# enable the session extension
|
10
|
+
$defs << '-DSQLITE_ENABLE_SESSION'
|
11
|
+
$defs << '-DSQLITE_ENABLE_PREUPDATE_HOOK'
|
12
|
+
$defs << '-DEXTRALITE_ENABLE_CHANGESET'
|
12
13
|
|
13
|
-
|
14
|
+
$defs << '-DHAVE_SQLITE3_ENABLE_LOAD_EXTENSION'
|
15
|
+
$defs << '-DHAVE_SQLITE3_LOAD_EXTENSION'
|
16
|
+
$defs << '-DHAVE_SQLITE3_PREPARE_V2'
|
17
|
+
$defs << '-DHAVE_SQLITE3_ERROR_OFFSET'
|
18
|
+
$defs << '-DHAVE_SQLITE3SESSION_CHANGESET'
|
14
19
|
|
20
|
+
have_func('usleep')
|
15
21
|
dir_config('extralite_ext')
|
16
22
|
create_makefile('extralite_ext')
|
data/ext/extralite/extconf.rb
CHANGED
@@ -35,60 +35,60 @@ else
|
|
35
35
|
end
|
36
36
|
|
37
37
|
if with_config('sqlcipher')
|
38
|
-
pkg_config(
|
38
|
+
pkg_config('sqlcipher')
|
39
39
|
else
|
40
|
-
pkg_config(
|
40
|
+
pkg_config('sqlite3')
|
41
41
|
end
|
42
42
|
|
43
43
|
# --with-sqlite3-{dir,include,lib}
|
44
44
|
if with_config('sqlcipher')
|
45
45
|
$CFLAGS << ' -DUSING_SQLCIPHER'
|
46
|
-
dir_config(
|
46
|
+
dir_config('sqlcipher', cppflags, ldflags)
|
47
47
|
else
|
48
|
-
dir_config(
|
48
|
+
dir_config('sqlite3', cppflags, ldflags)
|
49
49
|
end
|
50
50
|
|
51
|
-
if RbConfig::CONFIG[
|
51
|
+
if RbConfig::CONFIG['host_os'] =~ /mswin/
|
52
52
|
$CFLAGS << ' -W3'
|
53
53
|
end
|
54
54
|
|
55
|
-
if RUBY_VERSION < '2.7'
|
56
|
-
$CFLAGS << ' -DTAINTING_SUPPORT'
|
57
|
-
end
|
58
|
-
|
59
55
|
# @!visibility private
|
60
56
|
def asplode missing
|
61
57
|
if RUBY_PLATFORM =~ /mingw|mswin/
|
62
|
-
abort "#{missing} is missing. Install SQLite3 from "
|
63
|
-
"http://www.sqlite.org/ first."
|
58
|
+
abort "#{missing} is missing. Install SQLite3 from http://www.sqlite.org/ first."
|
64
59
|
else
|
65
|
-
abort
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
end
|
60
|
+
abort <<~error
|
61
|
+
#{missing} is missing. Try 'brew install sqlite3',
|
62
|
+
'yum install sqlite-devel' or 'apt-get install libsqlite3-dev'
|
63
|
+
and check your shared library search path (the location where
|
64
|
+
your sqlite3 shared library is located).
|
65
|
+
error
|
72
66
|
end
|
67
|
+
end
|
73
68
|
|
74
|
-
|
75
|
-
|
69
|
+
asplode('sqlite3.h') unless find_header('sqlite3.h')
|
70
|
+
# find_library 'pthread', 'pthread_create' # 1.8 support. *shrug*
|
76
71
|
|
77
|
-
|
72
|
+
have_library 'dl' # for static builds
|
78
73
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
74
|
+
if with_config('sqlcipher')
|
75
|
+
asplode('sqlcipher') unless find_library 'sqlcipher', 'sqlite3_libversion_number'
|
76
|
+
else
|
77
|
+
asplode('sqlite3') unless find_library 'sqlite3', 'sqlite3_libversion_number'
|
78
|
+
end
|
84
79
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
80
|
+
have_func('sqlite3_enable_load_extension')
|
81
|
+
have_func('sqlite3_load_extension')
|
82
|
+
have_func('sqlite3_prepare_v2')
|
83
|
+
have_func('sqlite3_error_offset')
|
84
|
+
have_func('sqlite3session_changeset')
|
85
|
+
|
86
|
+
if have_type('sqlite3_session', 'sqlite.h')
|
87
|
+
$defs << '-DEXTRALITE_ENABLE_CHANGESET'
|
88
|
+
end
|
89
89
|
|
90
|
-
|
90
|
+
$defs << '-DEXTRALITE_NO_BUNDLE'
|
91
91
|
|
92
|
-
|
93
|
-
|
94
|
-
|
92
|
+
dir_config('extralite_ext')
|
93
|
+
create_makefile('extralite_ext')
|
94
|
+
end
|
data/ext/extralite/extralite.h
CHANGED
@@ -17,12 +17,15 @@
|
|
17
17
|
VALUE s = rb_funcall(obj, rb_intern("inspect"), 0); \
|
18
18
|
printf(": %s\n", StringValueCStr(s)); \
|
19
19
|
}
|
20
|
+
#define CALLER() rb_funcall(rb_mKernel, rb_intern("caller"), 0)
|
21
|
+
#define TRACE_CALLER() INSPECT("caller: ", CALLER())
|
20
22
|
|
21
23
|
#define SAFE(f) (VALUE (*)(VALUE))(f)
|
22
24
|
|
23
25
|
extern VALUE cDatabase;
|
24
26
|
extern VALUE cQuery;
|
25
27
|
extern VALUE cIterator;
|
28
|
+
extern VALUE cChangeset;
|
26
29
|
extern VALUE cBlob;
|
27
30
|
|
28
31
|
extern VALUE cError;
|
@@ -36,54 +39,95 @@ extern ID ID_each;
|
|
36
39
|
extern ID ID_keys;
|
37
40
|
extern ID ID_new;
|
38
41
|
extern ID ID_strip;
|
42
|
+
extern ID ID_to_s;
|
43
|
+
extern ID ID_track;
|
39
44
|
|
40
|
-
extern VALUE
|
45
|
+
extern VALUE SYM_argv;
|
41
46
|
extern VALUE SYM_ary;
|
42
|
-
extern VALUE
|
47
|
+
extern VALUE SYM_hash;
|
48
|
+
|
49
|
+
enum progress_handler_mode {
|
50
|
+
PROGRESS_NONE,
|
51
|
+
PROGRESS_NORMAL,
|
52
|
+
PROGRESS_ONCE,
|
53
|
+
PROGRESS_AT_LEAST_ONCE,
|
54
|
+
};
|
55
|
+
|
56
|
+
struct progress_handler {
|
57
|
+
enum progress_handler_mode mode;
|
58
|
+
VALUE proc;
|
59
|
+
int period;
|
60
|
+
int tick;
|
61
|
+
int tick_count;
|
62
|
+
int call_count;
|
63
|
+
};
|
43
64
|
|
44
65
|
typedef struct {
|
45
|
-
sqlite3
|
46
|
-
VALUE
|
47
|
-
int
|
66
|
+
sqlite3 *sqlite3_db;
|
67
|
+
VALUE trace_proc;
|
68
|
+
int gvl_release_threshold;
|
69
|
+
struct progress_handler progress_handler;
|
48
70
|
} Database_t;
|
49
71
|
|
72
|
+
enum query_mode {
|
73
|
+
QUERY_HASH,
|
74
|
+
QUERY_ARGV,
|
75
|
+
QUERY_ARY
|
76
|
+
};
|
77
|
+
|
50
78
|
typedef struct {
|
51
|
-
VALUE
|
52
|
-
VALUE
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
int
|
79
|
+
VALUE db;
|
80
|
+
VALUE sql;
|
81
|
+
VALUE transform_proc;
|
82
|
+
Database_t *db_struct;
|
83
|
+
sqlite3 *sqlite3_db;
|
84
|
+
sqlite3_stmt *stmt;
|
85
|
+
int eof;
|
86
|
+
int closed;
|
87
|
+
enum query_mode query_mode;
|
58
88
|
} Query_t;
|
59
89
|
|
60
90
|
enum iterator_mode {
|
61
91
|
ITERATOR_HASH,
|
92
|
+
ITERATOR_ARGV,
|
62
93
|
ITERATOR_ARY,
|
63
94
|
ITERATOR_SINGLE_COLUMN
|
64
95
|
};
|
65
96
|
|
66
97
|
typedef struct {
|
67
98
|
VALUE query;
|
68
|
-
enum iterator_mode mode;
|
69
99
|
} Iterator_t;
|
70
100
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
101
|
+
#ifdef EXTRALITE_ENABLE_CHANGESET
|
102
|
+
typedef struct {
|
103
|
+
int changeset_len;
|
104
|
+
void *changeset_ptr;
|
105
|
+
} Changeset_t;
|
106
|
+
#endif
|
107
|
+
|
108
|
+
enum row_mode {
|
109
|
+
ROW_YIELD,
|
110
|
+
ROW_MULTI,
|
111
|
+
ROW_SINGLE
|
75
112
|
};
|
76
113
|
|
77
114
|
typedef struct {
|
78
|
-
VALUE
|
79
|
-
|
80
|
-
|
81
|
-
VALUE
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
115
|
+
VALUE self;
|
116
|
+
VALUE sql;
|
117
|
+
VALUE params;
|
118
|
+
VALUE transform_proc;
|
119
|
+
|
120
|
+
Database_t *db;
|
121
|
+
sqlite3 *sqlite3_db;
|
122
|
+
sqlite3_stmt *stmt;
|
123
|
+
|
124
|
+
int gvl_release_threshold;
|
125
|
+
enum query_mode query_mode;
|
126
|
+
enum row_mode row_mode;
|
127
|
+
int max_rows;
|
128
|
+
|
129
|
+
int eof;
|
130
|
+
int step_count;
|
87
131
|
} query_ctx;
|
88
132
|
|
89
133
|
enum gvl_mode {
|
@@ -93,46 +137,59 @@ enum gvl_mode {
|
|
93
137
|
|
94
138
|
#define ALL_ROWS -1
|
95
139
|
#define SINGLE_ROW -2
|
96
|
-
#define
|
97
|
-
#define
|
98
|
-
#define QUERY_CTX(self, db, stmt, params,
|
99
|
-
|
140
|
+
#define ROW_YIELD_OR_MODE(default) (rb_block_given_p() ? ROW_YIELD : default)
|
141
|
+
#define ROW_MULTI_P(mode) (mode == ROW_MULTI)
|
142
|
+
#define QUERY_CTX(self, sql, db, stmt, params, transform_proc, query_mode, row_mode, max_rows) { \
|
143
|
+
self, \
|
144
|
+
sql, \
|
145
|
+
params, \
|
146
|
+
transform_proc, \
|
147
|
+
db, \
|
148
|
+
db->sqlite3_db, \
|
149
|
+
stmt, \
|
150
|
+
db->gvl_release_threshold, \
|
151
|
+
query_mode, \
|
152
|
+
row_mode, \
|
153
|
+
max_rows, \
|
154
|
+
0, \
|
155
|
+
0 \
|
156
|
+
}
|
157
|
+
|
100
158
|
#define DEFAULT_GVL_RELEASE_THRESHOLD 1000
|
159
|
+
#define DEFAULT_PROGRESS_HANDLER_PERIOD 1000
|
160
|
+
#define DEFAULT_PROGRESS_HANDLER_TICK 10
|
101
161
|
|
102
162
|
extern rb_encoding *UTF8_ENCODING;
|
103
163
|
|
164
|
+
typedef VALUE (*safe_query_impl)(query_ctx *);
|
165
|
+
|
104
166
|
VALUE safe_batch_execute(query_ctx *ctx);
|
105
167
|
VALUE safe_batch_query(query_ctx *ctx);
|
168
|
+
VALUE safe_batch_query_argv(query_ctx *ctx);
|
106
169
|
VALUE safe_batch_query_ary(query_ctx *ctx);
|
107
|
-
VALUE
|
170
|
+
VALUE safe_query_argv(query_ctx *ctx);
|
108
171
|
VALUE safe_query_ary(query_ctx *ctx);
|
109
172
|
VALUE safe_query_changes(query_ctx *ctx);
|
110
173
|
VALUE safe_query_columns(query_ctx *ctx);
|
111
174
|
VALUE safe_query_hash(query_ctx *ctx);
|
112
|
-
VALUE
|
113
|
-
VALUE
|
114
|
-
VALUE
|
115
|
-
|
116
|
-
VALUE Query_each_hash(VALUE self);
|
117
|
-
VALUE Query_each_ary(VALUE self);
|
118
|
-
VALUE Query_each_single_column(VALUE self);
|
119
|
-
|
120
|
-
VALUE Query_next_hash(int argc, VALUE *argv, VALUE self);
|
121
|
-
VALUE Query_next_ary(int argc, VALUE *argv, VALUE self);
|
122
|
-
VALUE Query_next_single_column(int argc, VALUE *argv, VALUE self);
|
175
|
+
VALUE safe_query_single_row_hash(query_ctx *ctx);
|
176
|
+
VALUE safe_query_single_row_argv(query_ctx *ctx);
|
177
|
+
VALUE safe_query_single_row_ary(query_ctx *ctx);
|
123
178
|
|
124
|
-
VALUE
|
125
|
-
VALUE
|
126
|
-
VALUE
|
179
|
+
VALUE Query_each(VALUE self);
|
180
|
+
VALUE Query_next(int argc, VALUE *argv, VALUE self);
|
181
|
+
VALUE Query_to_a(VALUE self);
|
127
182
|
|
128
|
-
void prepare_single_stmt(sqlite3 *db, sqlite3_stmt **stmt, VALUE sql);
|
129
|
-
void prepare_multi_stmt(sqlite3 *db, sqlite3_stmt **stmt, VALUE sql);
|
183
|
+
void prepare_single_stmt(enum gvl_mode mode, sqlite3 *db, sqlite3_stmt **stmt, VALUE sql);
|
184
|
+
void prepare_multi_stmt(enum gvl_mode mode, sqlite3 *db, sqlite3_stmt **stmt, VALUE sql);
|
130
185
|
void bind_all_parameters(sqlite3_stmt *stmt, int argc, VALUE *argv);
|
131
186
|
void bind_all_parameters_from_object(sqlite3_stmt *stmt, VALUE obj);
|
132
187
|
int stmt_iterate(query_ctx *ctx);
|
133
188
|
VALUE cleanup_stmt(query_ctx *ctx);
|
134
189
|
|
190
|
+
void Database_issue_query(Database_t *db, VALUE sql);
|
135
191
|
sqlite3 *Database_sqlite3_db(VALUE self);
|
192
|
+
enum gvl_mode Database_prepare_gvl_mode(Database_t *db);
|
136
193
|
Database_t *self_to_database(VALUE self);
|
137
194
|
|
138
195
|
void *gvl_call(enum gvl_mode mode, void *(*fn)(void *), void *data);
|
@@ -3,6 +3,9 @@
|
|
3
3
|
void Init_ExtraliteDatabase();
|
4
4
|
void Init_ExtraliteQuery();
|
5
5
|
void Init_ExtraliteIterator();
|
6
|
+
#ifdef EXTRALITE_ENABLE_CHANGESET
|
7
|
+
void Init_ExtraliteChangeset();
|
8
|
+
#endif
|
6
9
|
|
7
10
|
void Init_extralite_ext(void) {
|
8
11
|
rb_ext_ractor_safe(true);
|
@@ -10,4 +13,7 @@ void Init_extralite_ext(void) {
|
|
10
13
|
Init_ExtraliteDatabase();
|
11
14
|
Init_ExtraliteQuery();
|
12
15
|
Init_ExtraliteIterator();
|
16
|
+
#ifdef EXTRALITE_ENABLE_CHANGESET
|
17
|
+
Init_ExtraliteChangeset();
|
18
|
+
#endif
|
13
19
|
}
|
data/ext/extralite/iterator.c
CHANGED
@@ -9,23 +9,24 @@
|
|
9
9
|
|
10
10
|
VALUE cIterator;
|
11
11
|
|
12
|
-
VALUE SYM_hash;
|
13
|
-
VALUE SYM_ary;
|
14
|
-
VALUE SYM_single_column;
|
15
|
-
|
16
12
|
static size_t Iterator_size(const void *ptr) {
|
17
13
|
return sizeof(Iterator_t);
|
18
14
|
}
|
19
15
|
|
20
16
|
static void Iterator_mark(void *ptr) {
|
21
17
|
Iterator_t *iterator = ptr;
|
22
|
-
|
18
|
+
rb_gc_mark_movable(iterator->query);
|
19
|
+
}
|
20
|
+
|
21
|
+
static void Iterator_compact(void *ptr) {
|
22
|
+
Iterator_t *iterator = ptr;
|
23
|
+
iterator->query = rb_gc_location(iterator->query);
|
23
24
|
}
|
24
25
|
|
25
26
|
static const rb_data_type_t Iterator_type = {
|
26
27
|
"Iterator",
|
27
|
-
{Iterator_mark, free, Iterator_size,},
|
28
|
-
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
28
|
+
{Iterator_mark, free, Iterator_size, Iterator_compact},
|
29
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
|
29
30
|
};
|
30
31
|
|
31
32
|
static VALUE Iterator_allocate(VALUE klass) {
|
@@ -40,14 +41,6 @@ static inline Iterator_t *self_to_iterator(VALUE obj) {
|
|
40
41
|
return iterator;
|
41
42
|
}
|
42
43
|
|
43
|
-
static inline enum iterator_mode symbol_to_mode(VALUE sym) {
|
44
|
-
if (sym == SYM_hash) return ITERATOR_HASH;
|
45
|
-
if (sym == SYM_ary) return ITERATOR_ARY;
|
46
|
-
if (sym == SYM_single_column) return ITERATOR_SINGLE_COLUMN;
|
47
|
-
|
48
|
-
rb_raise(cError, "Invalid iterator mode");
|
49
|
-
}
|
50
|
-
|
51
44
|
/* Initializes an iterator using the given query object and iteration mode. The
|
52
45
|
* iteration mode is one of: `:hash`, `:ary`, or `:single_column`. An iterator
|
53
46
|
* is normally returned from one of the methods `Query#each`/`Query#each_hash`,
|
@@ -60,28 +53,12 @@ static inline enum iterator_mode symbol_to_mode(VALUE sym) {
|
|
60
53
|
* @param mode [Symbol] iteration mode
|
61
54
|
* @return [void]
|
62
55
|
*/
|
63
|
-
VALUE Iterator_initialize(VALUE self, VALUE query
|
56
|
+
VALUE Iterator_initialize(VALUE self, VALUE query) {
|
64
57
|
Iterator_t *iterator = self_to_iterator(self);
|
65
|
-
|
66
58
|
iterator->query = query;
|
67
|
-
iterator->mode = symbol_to_mode(mode);
|
68
|
-
|
69
59
|
return Qnil;
|
70
60
|
}
|
71
61
|
|
72
|
-
typedef VALUE (*each_method)(VALUE);
|
73
|
-
|
74
|
-
inline each_method mode_to_each_method(enum iterator_mode mode) {
|
75
|
-
switch (mode) {
|
76
|
-
case ITERATOR_ARY:
|
77
|
-
return Query_each_ary;
|
78
|
-
case ITERATOR_SINGLE_COLUMN:
|
79
|
-
return Query_each_single_column;
|
80
|
-
default:
|
81
|
-
return Query_each_hash;
|
82
|
-
}
|
83
|
-
}
|
84
|
-
|
85
62
|
/* Iterates through the associated query's result set using the iteration mode
|
86
63
|
* set when initialized. Each row would be passed to the given block according
|
87
64
|
* to the iteration mode, i.e. as a hash, an array, or a single value. In
|
@@ -93,26 +70,12 @@ inline each_method mode_to_each_method(enum iterator_mode mode) {
|
|
93
70
|
VALUE Iterator_each(VALUE self) {
|
94
71
|
if (rb_block_given_p()) {
|
95
72
|
Iterator_t *iterator = self_to_iterator(self);
|
96
|
-
|
97
|
-
method(iterator->query);
|
73
|
+
Query_each(iterator->query);
|
98
74
|
}
|
99
75
|
|
100
76
|
return self;
|
101
77
|
}
|
102
78
|
|
103
|
-
typedef VALUE (*next_method)(int, VALUE *, VALUE);
|
104
|
-
|
105
|
-
inline next_method mode_to_next_method(enum iterator_mode mode) {
|
106
|
-
switch (mode) {
|
107
|
-
case ITERATOR_ARY:
|
108
|
-
return Query_next_ary;
|
109
|
-
case ITERATOR_SINGLE_COLUMN:
|
110
|
-
return Query_next_single_column;
|
111
|
-
default:
|
112
|
-
return Query_next_hash;
|
113
|
-
}
|
114
|
-
}
|
115
|
-
|
116
79
|
/* Returns the next 1 or more rows from the associated query's result set
|
117
80
|
* according to the iteration mode, i.e. as a hash, an array or a single value.
|
118
81
|
*
|
@@ -131,25 +94,11 @@ inline next_method mode_to_next_method(enum iterator_mode mode) {
|
|
131
94
|
*/
|
132
95
|
VALUE Iterator_next(int argc, VALUE *argv, VALUE self) {
|
133
96
|
Iterator_t *iterator = self_to_iterator(self);
|
134
|
-
|
135
|
-
VALUE result = method(argc, argv, iterator->query);
|
97
|
+
VALUE result = Query_next(argc, argv, iterator->query);
|
136
98
|
|
137
99
|
return rb_block_given_p() ? self : result;
|
138
100
|
}
|
139
101
|
|
140
|
-
typedef VALUE (*to_a_method)(VALUE);
|
141
|
-
|
142
|
-
inline to_a_method mode_to_to_a_method(enum iterator_mode mode) {
|
143
|
-
switch (mode) {
|
144
|
-
case ITERATOR_ARY:
|
145
|
-
return Query_to_a_ary;
|
146
|
-
case ITERATOR_SINGLE_COLUMN:
|
147
|
-
return Query_to_a_single_column;
|
148
|
-
default:
|
149
|
-
return Query_to_a_hash;
|
150
|
-
}
|
151
|
-
}
|
152
|
-
|
153
102
|
/* Returns all rows from the associated query's result set according to the
|
154
103
|
* iteration mode, i.e. as a hash, an array or a single value.
|
155
104
|
*
|
@@ -157,19 +106,7 @@ inline to_a_method mode_to_to_a_method(enum iterator_mode mode) {
|
|
157
106
|
*/
|
158
107
|
VALUE Iterator_to_a(VALUE self) {
|
159
108
|
Iterator_t *iterator = self_to_iterator(self);
|
160
|
-
|
161
|
-
return method(iterator->query);
|
162
|
-
}
|
163
|
-
|
164
|
-
inline VALUE mode_to_symbol(Iterator_t *iterator) {
|
165
|
-
switch (iterator->mode) {
|
166
|
-
case ITERATOR_ARY:
|
167
|
-
return SYM_ary;
|
168
|
-
case ITERATOR_SINGLE_COLUMN:
|
169
|
-
return SYM_single_column;
|
170
|
-
default:
|
171
|
-
return SYM_hash;
|
172
|
-
}
|
109
|
+
return Query_to_a(iterator->query);
|
173
110
|
}
|
174
111
|
|
175
112
|
/* Returns a short string representation of the iterator instance, including the
|
@@ -179,9 +116,8 @@ inline VALUE mode_to_symbol(Iterator_t *iterator) {
|
|
179
116
|
*/
|
180
117
|
VALUE Iterator_inspect(VALUE self) {
|
181
118
|
VALUE cname = rb_class_name(CLASS_OF(self));
|
182
|
-
VALUE sym = mode_to_symbol(self_to_iterator(self));
|
183
119
|
|
184
|
-
return rb_sprintf("#<%"PRIsVALUE":%p
|
120
|
+
return rb_sprintf("#<%"PRIsVALUE":%p>", cname, (void*)self);
|
185
121
|
}
|
186
122
|
|
187
123
|
void Init_ExtraliteIterator(void) {
|
@@ -192,17 +128,9 @@ void Init_ExtraliteIterator(void) {
|
|
192
128
|
|
193
129
|
rb_include_module(cIterator, rb_mEnumerable);
|
194
130
|
|
195
|
-
rb_define_method(cIterator, "initialize", Iterator_initialize,
|
131
|
+
rb_define_method(cIterator, "initialize", Iterator_initialize, 1);
|
196
132
|
rb_define_method(cIterator, "each", Iterator_each, 0);
|
197
133
|
rb_define_method(cIterator, "inspect", Iterator_inspect, 0);
|
198
134
|
rb_define_method(cIterator, "next", Iterator_next, -1);
|
199
135
|
rb_define_method(cIterator, "to_a", Iterator_to_a, 0);
|
200
|
-
|
201
|
-
SYM_hash = ID2SYM(rb_intern("hash"));
|
202
|
-
SYM_ary = ID2SYM(rb_intern("ary"));
|
203
|
-
SYM_single_column = ID2SYM(rb_intern("single_column"));
|
204
|
-
|
205
|
-
rb_gc_register_mark_object(SYM_hash);
|
206
|
-
rb_gc_register_mark_object(SYM_ary);
|
207
|
-
rb_gc_register_mark_object(SYM_single_column);
|
208
136
|
}
|