extralite 2.6 → 2.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -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`,
@@ -65,28 +53,12 @@ static inline enum iterator_mode symbol_to_mode(VALUE sym) {
65
53
  * @param mode [Symbol] iteration mode
66
54
  * @return [void]
67
55
  */
68
- VALUE Iterator_initialize(VALUE self, VALUE query, VALUE mode) {
56
+ VALUE Iterator_initialize(VALUE self, VALUE query) {
69
57
  Iterator_t *iterator = self_to_iterator(self);
70
-
71
58
  iterator->query = query;
72
- iterator->mode = symbol_to_mode(mode);
73
-
74
59
  return Qnil;
75
60
  }
76
61
 
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
62
  /* Iterates through the associated query's result set using the iteration mode
91
63
  * set when initialized. Each row would be passed to the given block according
92
64
  * to the iteration mode, i.e. as a hash, an array, or a single value. In
@@ -98,26 +70,12 @@ inline each_method mode_to_each_method(enum iterator_mode mode) {
98
70
  VALUE Iterator_each(VALUE self) {
99
71
  if (rb_block_given_p()) {
100
72
  Iterator_t *iterator = self_to_iterator(self);
101
- each_method method = mode_to_each_method(iterator->mode);
102
- method(iterator->query);
73
+ Query_each(iterator->query);
103
74
  }
104
75
 
105
76
  return self;
106
77
  }
107
78
 
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
79
  /* Returns the next 1 or more rows from the associated query's result set
122
80
  * according to the iteration mode, i.e. as a hash, an array or a single value.
123
81
  *
@@ -136,25 +94,11 @@ inline next_method mode_to_next_method(enum iterator_mode mode) {
136
94
  */
137
95
  VALUE Iterator_next(int argc, VALUE *argv, VALUE self) {
138
96
  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);
97
+ VALUE result = Query_next(argc, argv, iterator->query);
141
98
 
142
99
  return rb_block_given_p() ? self : result;
143
100
  }
144
101
 
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
102
  /* Returns all rows from the associated query's result set according to the
159
103
  * iteration mode, i.e. as a hash, an array or a single value.
160
104
  *
@@ -162,19 +106,7 @@ inline to_a_method mode_to_to_a_method(enum iterator_mode mode) {
162
106
  */
163
107
  VALUE Iterator_to_a(VALUE self) {
164
108
  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
- }
109
+ return Query_to_a(iterator->query);
178
110
  }
179
111
 
180
112
  /* Returns a short string representation of the iterator instance, including the
@@ -184,9 +116,8 @@ inline VALUE mode_to_symbol(Iterator_t *iterator) {
184
116
  */
185
117
  VALUE Iterator_inspect(VALUE self) {
186
118
  VALUE cname = rb_class_name(CLASS_OF(self));
187
- VALUE sym = mode_to_symbol(self_to_iterator(self));
188
119
 
189
- return rb_sprintf("#<%"PRIsVALUE":%p %"PRIsVALUE">", cname, (void*)self, sym);
120
+ return rb_sprintf("#<%"PRIsVALUE":%p>", cname, (void*)self);
190
121
  }
191
122
 
192
123
  void Init_ExtraliteIterator(void) {
@@ -197,17 +128,9 @@ void Init_ExtraliteIterator(void) {
197
128
 
198
129
  rb_include_module(cIterator, rb_mEnumerable);
199
130
 
200
- rb_define_method(cIterator, "initialize", Iterator_initialize, 2);
131
+ rb_define_method(cIterator, "initialize", Iterator_initialize, 1);
201
132
  rb_define_method(cIterator, "each", Iterator_each, 0);
202
133
  rb_define_method(cIterator, "inspect", Iterator_inspect, 0);
203
134
  rb_define_method(cIterator, "next", Iterator_next, -1);
204
135
  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
136
  }