extralite 2.6 → 2.7.1

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.
@@ -35,28 +35,27 @@ else
35
35
  end
36
36
 
37
37
  if with_config('sqlcipher')
38
- pkg_config("sqlcipher")
38
+ pkg_config('sqlcipher')
39
39
  else
40
- pkg_config("sqlite3")
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("sqlcipher", cppflags, ldflags)
46
+ dir_config('sqlcipher', cppflags, ldflags)
47
47
  else
48
- dir_config("sqlite3", cppflags, ldflags)
48
+ dir_config('sqlite3', cppflags, ldflags)
49
49
  end
50
50
 
51
- if RbConfig::CONFIG["host_os"] =~ /mswin/
51
+ if RbConfig::CONFIG['host_os'] =~ /mswin/
52
52
  $CFLAGS << ' -W3'
53
53
  end
54
54
 
55
55
  # @!visibility private
56
56
  def asplode missing
57
57
  if RUBY_PLATFORM =~ /mingw|mswin/
58
- abort "#{missing} is missing. Install SQLite3 from " +
59
- "http://www.sqlite.org/ first."
58
+ abort "#{missing} is missing. Install SQLite3 from http://www.sqlite.org/ first."
60
59
  else
61
60
  abort <<~error
62
61
  #{missing} is missing. Try 'brew install sqlite3',
@@ -87,11 +86,8 @@ else
87
86
  if have_type('sqlite3_session', 'sqlite.h')
88
87
  $defs << '-DEXTRALITE_ENABLE_CHANGESET'
89
88
  end
90
- # have_macro('__SQLITESESSION_H_')
91
- # have_macro('SQLITE3_H')
92
89
 
93
-
94
- $defs << "-DEXTRALITE_NO_BUNDLE"
90
+ $defs << '-DEXTRALITE_NO_BUNDLE'
95
91
 
96
92
  dir_config('extralite_ext')
97
93
  create_makefile('extralite_ext')
@@ -17,6 +17,8 @@
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
 
@@ -40,36 +42,60 @@ extern ID ID_strip;
40
42
  extern ID ID_to_s;
41
43
  extern ID ID_track;
42
44
 
45
+ extern VALUE SYM_argv;
43
46
  extern VALUE SYM_ary;
44
47
  extern VALUE SYM_hash;
45
- extern VALUE SYM_single_column;
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
+ };
46
64
 
47
65
  typedef struct {
48
- sqlite3 *sqlite3_db;
49
- VALUE trace_proc;
50
- VALUE progress_handler_proc;
51
- int gvl_release_threshold;
66
+ sqlite3 *sqlite3_db;
67
+ VALUE trace_proc;
68
+ int gvl_release_threshold;
69
+ struct progress_handler progress_handler;
52
70
  } Database_t;
53
71
 
72
+ enum query_mode {
73
+ QUERY_HASH,
74
+ QUERY_ARGV,
75
+ QUERY_ARY
76
+ };
77
+
54
78
  typedef struct {
55
- VALUE db;
56
- VALUE sql;
57
- Database_t *db_struct;
58
- sqlite3 *sqlite3_db;
59
- sqlite3_stmt *stmt;
60
- int eof;
61
- int closed;
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;
62
88
  } Query_t;
63
89
 
64
90
  enum iterator_mode {
65
91
  ITERATOR_HASH,
92
+ ITERATOR_ARGV,
66
93
  ITERATOR_ARY,
67
94
  ITERATOR_SINGLE_COLUMN
68
95
  };
69
96
 
70
97
  typedef struct {
71
98
  VALUE query;
72
- enum iterator_mode mode;
73
99
  } Iterator_t;
74
100
 
75
101
  #ifdef EXTRALITE_ENABLE_CHANGESET
@@ -79,22 +105,29 @@ typedef struct {
79
105
  } Changeset_t;
80
106
  #endif
81
107
 
82
- enum query_mode {
83
- QUERY_YIELD,
84
- QUERY_MULTI_ROW,
85
- QUERY_SINGLE_ROW
108
+ enum row_mode {
109
+ ROW_YIELD,
110
+ ROW_MULTI,
111
+ ROW_SINGLE
86
112
  };
87
113
 
88
114
  typedef struct {
89
- VALUE self;
90
- sqlite3 *sqlite3_db;
91
- sqlite3_stmt *stmt;
92
- VALUE params;
93
- enum query_mode mode;
94
- int max_rows;
95
- int eof;
96
- int gvl_release_threshold;
97
- int step_count;
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;
98
131
  } query_ctx;
99
132
 
100
133
  enum gvl_mode {
@@ -104,41 +137,48 @@ enum gvl_mode {
104
137
 
105
138
  #define ALL_ROWS -1
106
139
  #define SINGLE_ROW -2
107
- #define QUERY_MODE(default) (rb_block_given_p() ? QUERY_YIELD : default)
108
- #define MULTI_ROW_P(mode) (mode == QUERY_MULTI_ROW)
109
- #define QUERY_CTX(self, db, stmt, params, mode, max_rows) \
110
- { self, db->sqlite3_db, stmt, params, mode, max_rows, 0, db->gvl_release_threshold, 0 }
111
- #define TRACE_SQL(db, sql) \
112
- if (db->trace_proc != Qnil) rb_funcall(db->trace_proc, ID_call, 1, sql);
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
+ }
113
157
 
114
158
  #define DEFAULT_GVL_RELEASE_THRESHOLD 1000
115
-
159
+ #define DEFAULT_PROGRESS_HANDLER_PERIOD 1000
160
+ #define DEFAULT_PROGRESS_HANDLER_TICK 10
116
161
 
117
162
  extern rb_encoding *UTF8_ENCODING;
118
163
 
164
+ typedef VALUE (*safe_query_impl)(query_ctx *);
165
+
119
166
  VALUE safe_batch_execute(query_ctx *ctx);
120
167
  VALUE safe_batch_query(query_ctx *ctx);
168
+ VALUE safe_batch_query_argv(query_ctx *ctx);
121
169
  VALUE safe_batch_query_ary(query_ctx *ctx);
122
- VALUE safe_batch_query_single_column(query_ctx *ctx);
170
+ VALUE safe_query_argv(query_ctx *ctx);
123
171
  VALUE safe_query_ary(query_ctx *ctx);
124
172
  VALUE safe_query_changes(query_ctx *ctx);
125
173
  VALUE safe_query_columns(query_ctx *ctx);
126
174
  VALUE safe_query_hash(query_ctx *ctx);
127
- VALUE safe_query_single_column(query_ctx *ctx);
128
- VALUE safe_query_single_row(query_ctx *ctx);
129
- VALUE safe_query_single_value(query_ctx *ctx);
130
-
131
- VALUE Query_each_hash(VALUE self);
132
- VALUE Query_each_ary(VALUE self);
133
- VALUE Query_each_single_column(VALUE self);
134
-
135
- VALUE Query_next_hash(int argc, VALUE *argv, VALUE self);
136
- VALUE Query_next_ary(int argc, VALUE *argv, VALUE self);
137
- 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);
138
178
 
139
- VALUE Query_to_a_hash(VALUE self);
140
- VALUE Query_to_a_ary(VALUE self);
141
- VALUE Query_to_a_single_column(VALUE self);
179
+ VALUE Query_each(VALUE self);
180
+ VALUE Query_next(int argc, VALUE *argv, VALUE self);
181
+ VALUE Query_to_a(VALUE self);
142
182
 
143
183
  void prepare_single_stmt(enum gvl_mode mode, sqlite3 *db, sqlite3_stmt **stmt, VALUE sql);
144
184
  void prepare_multi_stmt(enum gvl_mode mode, sqlite3 *db, sqlite3_stmt **stmt, VALUE sql);
@@ -147,6 +187,7 @@ void bind_all_parameters_from_object(sqlite3_stmt *stmt, VALUE obj);
147
187
  int stmt_iterate(query_ctx *ctx);
148
188
  VALUE cleanup_stmt(query_ctx *ctx);
149
189
 
190
+ void Database_issue_query(Database_t *db, VALUE sql);
150
191
  sqlite3 *Database_sqlite3_db(VALUE self);
151
192
  enum gvl_mode Database_prepare_gvl_mode(Database_t *db);
152
193
  Database_t *self_to_database(VALUE self);
@@ -9,10 +9,6 @@
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
  }
@@ -45,14 +41,6 @@ static inline Iterator_t *self_to_iterator(VALUE obj) {
45
41
  return iterator;
46
42
  }
47
43
 
48
- static inline enum iterator_mode symbol_to_mode(VALUE sym) {
49
- if (sym == SYM_hash) return ITERATOR_HASH;
50
- if (sym == SYM_ary) return ITERATOR_ARY;
51
- if (sym == SYM_single_column) return ITERATOR_SINGLE_COLUMN;
52
-
53
- rb_raise(cError, "Invalid iterator mode");
54
- }
55
-
56
44
  /* Initializes an iterator using the given query object and iteration mode. The
57
45
  * iteration mode is one of: `:hash`, `:ary`, or `:single_column`. An iterator
58
46
  * is normally returned from one of the methods `Query#each`/`Query#each_hash`,
@@ -62,31 +50,14 @@ static inline enum iterator_mode symbol_to_mode(VALUE sym) {
62
50
  * ...
63
51
  *
64
52
  * @param query [Extralite::Query] associated query
65
- * @param mode [Symbol] iteration mode
66
53
  * @return [void]
67
54
  */
68
- VALUE Iterator_initialize(VALUE self, VALUE query, VALUE mode) {
55
+ VALUE Iterator_initialize(VALUE self, VALUE query) {
69
56
  Iterator_t *iterator = self_to_iterator(self);
70
-
71
57
  iterator->query = query;
72
- iterator->mode = symbol_to_mode(mode);
73
-
74
58
  return Qnil;
75
59
  }
76
60
 
77
- typedef VALUE (*each_method)(VALUE);
78
-
79
- inline each_method mode_to_each_method(enum iterator_mode mode) {
80
- switch (mode) {
81
- case ITERATOR_ARY:
82
- return Query_each_ary;
83
- case ITERATOR_SINGLE_COLUMN:
84
- return Query_each_single_column;
85
- default:
86
- return Query_each_hash;
87
- }
88
- }
89
-
90
61
  /* Iterates through the associated query's result set using the iteration mode
91
62
  * set when initialized. Each row would be passed to the given block according
92
63
  * to the iteration mode, i.e. as a hash, an array, or a single value. In
@@ -98,26 +69,12 @@ inline each_method mode_to_each_method(enum iterator_mode mode) {
98
69
  VALUE Iterator_each(VALUE self) {
99
70
  if (rb_block_given_p()) {
100
71
  Iterator_t *iterator = self_to_iterator(self);
101
- each_method method = mode_to_each_method(iterator->mode);
102
- method(iterator->query);
72
+ Query_each(iterator->query);
103
73
  }
104
74
 
105
75
  return self;
106
76
  }
107
77
 
108
- typedef VALUE (*next_method)(int, VALUE *, VALUE);
109
-
110
- inline next_method mode_to_next_method(enum iterator_mode mode) {
111
- switch (mode) {
112
- case ITERATOR_ARY:
113
- return Query_next_ary;
114
- case ITERATOR_SINGLE_COLUMN:
115
- return Query_next_single_column;
116
- default:
117
- return Query_next_hash;
118
- }
119
- }
120
-
121
78
  /* Returns the next 1 or more rows from the associated query's result set
122
79
  * according to the iteration mode, i.e. as a hash, an array or a single value.
123
80
  *
@@ -136,25 +93,11 @@ inline next_method mode_to_next_method(enum iterator_mode mode) {
136
93
  */
137
94
  VALUE Iterator_next(int argc, VALUE *argv, VALUE self) {
138
95
  Iterator_t *iterator = self_to_iterator(self);
139
- next_method method = mode_to_next_method(iterator->mode);
140
- VALUE result = method(argc, argv, iterator->query);
96
+ VALUE result = Query_next(argc, argv, iterator->query);
141
97
 
142
98
  return rb_block_given_p() ? self : result;
143
99
  }
144
100
 
145
- typedef VALUE (*to_a_method)(VALUE);
146
-
147
- inline to_a_method mode_to_to_a_method(enum iterator_mode mode) {
148
- switch (mode) {
149
- case ITERATOR_ARY:
150
- return Query_to_a_ary;
151
- case ITERATOR_SINGLE_COLUMN:
152
- return Query_to_a_single_column;
153
- default:
154
- return Query_to_a_hash;
155
- }
156
- }
157
-
158
101
  /* Returns all rows from the associated query's result set according to the
159
102
  * iteration mode, i.e. as a hash, an array or a single value.
160
103
  *
@@ -162,19 +105,7 @@ inline to_a_method mode_to_to_a_method(enum iterator_mode mode) {
162
105
  */
163
106
  VALUE Iterator_to_a(VALUE self) {
164
107
  Iterator_t *iterator = self_to_iterator(self);
165
- to_a_method method = mode_to_to_a_method(iterator->mode);
166
- return method(iterator->query);
167
- }
168
-
169
- inline VALUE mode_to_symbol(Iterator_t *iterator) {
170
- switch (iterator->mode) {
171
- case ITERATOR_ARY:
172
- return SYM_ary;
173
- case ITERATOR_SINGLE_COLUMN:
174
- return SYM_single_column;
175
- default:
176
- return SYM_hash;
177
- }
108
+ return Query_to_a(iterator->query);
178
109
  }
179
110
 
180
111
  /* Returns a short string representation of the iterator instance, including the
@@ -184,9 +115,8 @@ inline VALUE mode_to_symbol(Iterator_t *iterator) {
184
115
  */
185
116
  VALUE Iterator_inspect(VALUE self) {
186
117
  VALUE cname = rb_class_name(CLASS_OF(self));
187
- VALUE sym = mode_to_symbol(self_to_iterator(self));
188
118
 
189
- return rb_sprintf("#<%"PRIsVALUE":%p %"PRIsVALUE">", cname, (void*)self, sym);
119
+ return rb_sprintf("#<%"PRIsVALUE":%p>", cname, (void*)self);
190
120
  }
191
121
 
192
122
  void Init_ExtraliteIterator(void) {
@@ -197,17 +127,9 @@ void Init_ExtraliteIterator(void) {
197
127
 
198
128
  rb_include_module(cIterator, rb_mEnumerable);
199
129
 
200
- rb_define_method(cIterator, "initialize", Iterator_initialize, 2);
130
+ rb_define_method(cIterator, "initialize", Iterator_initialize, 1);
201
131
  rb_define_method(cIterator, "each", Iterator_each, 0);
202
132
  rb_define_method(cIterator, "inspect", Iterator_inspect, 0);
203
133
  rb_define_method(cIterator, "next", Iterator_next, -1);
204
134
  rb_define_method(cIterator, "to_a", Iterator_to_a, 0);
205
-
206
- SYM_hash = ID2SYM(rb_intern("hash"));
207
- SYM_ary = ID2SYM(rb_intern("ary"));
208
- SYM_single_column = ID2SYM(rb_intern("single_column"));
209
-
210
- rb_gc_register_mark_object(SYM_hash);
211
- rb_gc_register_mark_object(SYM_ary);
212
- rb_gc_register_mark_object(SYM_single_column);
213
135
  }