sqlite3-static 3.12.2
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 +7 -0
- data/API_CHANGES.rdoc +50 -0
- data/CHANGELOG.rdoc +287 -0
- data/Manifest.txt +52 -0
- data/README.rdoc +100 -0
- data/ext/sqlite3/backup.c +168 -0
- data/ext/sqlite3/backup.h +15 -0
- data/ext/sqlite3/database.c +888 -0
- data/ext/sqlite3/database.h +15 -0
- data/ext/sqlite3/exception.c +94 -0
- data/ext/sqlite3/exception.h +8 -0
- data/ext/sqlite3/extconf.rb +33 -0
- data/ext/sqlite3/sqlite3.c +143 -0
- data/ext/sqlite3/sqlite3.h +8733 -0
- data/ext/sqlite3/sqlite3_core.c +189319 -0
- data/ext/sqlite3/sqlite3_ruby.h +52 -0
- data/ext/sqlite3/statement.c +447 -0
- data/ext/sqlite3/statement.h +16 -0
- data/lib/sqlite3.rb +15 -0
- data/lib/sqlite3/constants.rb +49 -0
- data/lib/sqlite3/database.rb +600 -0
- data/lib/sqlite3/errors.rb +44 -0
- data/lib/sqlite3/pragmas.rb +597 -0
- data/lib/sqlite3/resultset.rb +195 -0
- data/lib/sqlite3/statement.rb +144 -0
- data/lib/sqlite3/translator.rb +118 -0
- data/lib/sqlite3/value.rb +57 -0
- data/lib/sqlite3/version.rb +25 -0
- metadata +80 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#ifndef SQLITE3_RUBY
|
|
2
|
+
#define SQLITE3_RUBY
|
|
3
|
+
|
|
4
|
+
#include <ruby.h>
|
|
5
|
+
|
|
6
|
+
#ifdef UNUSED
|
|
7
|
+
#elif defined(__GNUC__)
|
|
8
|
+
# define UNUSED(x) UNUSED_ ## x __attribute__((unused))
|
|
9
|
+
#elif defined(__LCLINT__)
|
|
10
|
+
# define UNUSED(x) /*@unused@*/ x
|
|
11
|
+
#else
|
|
12
|
+
# define UNUSED(x) x
|
|
13
|
+
#endif
|
|
14
|
+
|
|
15
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
|
16
|
+
#include <ruby/encoding.h>
|
|
17
|
+
|
|
18
|
+
#define USASCII_P(_obj) (rb_enc_get_index(_obj) == rb_usascii_encindex())
|
|
19
|
+
#define UTF8_P(_obj) (rb_enc_get_index(_obj) == rb_utf8_encindex())
|
|
20
|
+
#define UTF16_LE_P(_obj) (rb_enc_get_index(_obj) == rb_enc_find_index("UTF-16LE"))
|
|
21
|
+
#define UTF16_BE_P(_obj) (rb_enc_get_index(_obj) == rb_enc_find_index("UTF-16BE"))
|
|
22
|
+
#define SQLITE3_UTF8_STR_NEW2(_obj) \
|
|
23
|
+
(rb_enc_associate_index(rb_str_new2(_obj), rb_utf8_encindex()))
|
|
24
|
+
|
|
25
|
+
#else
|
|
26
|
+
|
|
27
|
+
#define SQLITE3_UTF8_STR_NEW2(_obj) (rb_str_new2(_obj))
|
|
28
|
+
|
|
29
|
+
#endif
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
#include "sqlite3.h"
|
|
33
|
+
|
|
34
|
+
#ifndef HAVE_TYPE_SQLITE3_INT64
|
|
35
|
+
typedef sqlite_int64 sqlite3_int64;
|
|
36
|
+
#endif
|
|
37
|
+
|
|
38
|
+
#ifndef HAVE_TYPE_SQLITE3_UINT64
|
|
39
|
+
typedef sqlite_uint64 sqlite3_uint64;
|
|
40
|
+
#endif
|
|
41
|
+
|
|
42
|
+
extern VALUE mSqlite3;
|
|
43
|
+
extern VALUE cSqlite3Blob;
|
|
44
|
+
|
|
45
|
+
#include <database.h>
|
|
46
|
+
#include <statement.h>
|
|
47
|
+
#include <exception.h>
|
|
48
|
+
#include <backup.h>
|
|
49
|
+
|
|
50
|
+
int bignum_to_int64(VALUE big, sqlite3_int64 *result);
|
|
51
|
+
|
|
52
|
+
#endif
|
|
@@ -0,0 +1,447 @@
|
|
|
1
|
+
#include <sqlite3_ruby.h>
|
|
2
|
+
|
|
3
|
+
#define REQUIRE_OPEN_STMT(_ctxt) \
|
|
4
|
+
if(!_ctxt->st) \
|
|
5
|
+
rb_raise(rb_path2class("SQLite3::Exception"), "cannot use a closed statement");
|
|
6
|
+
|
|
7
|
+
VALUE cSqlite3Statement;
|
|
8
|
+
|
|
9
|
+
static void deallocate(void * ctx)
|
|
10
|
+
{
|
|
11
|
+
sqlite3StmtRubyPtr c = (sqlite3StmtRubyPtr)ctx;
|
|
12
|
+
xfree(c);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
static VALUE allocate(VALUE klass)
|
|
16
|
+
{
|
|
17
|
+
sqlite3StmtRubyPtr ctx = xcalloc((size_t)1, sizeof(sqlite3StmtRuby));
|
|
18
|
+
ctx->st = NULL;
|
|
19
|
+
ctx->done_p = 0;
|
|
20
|
+
|
|
21
|
+
return Data_Wrap_Struct(klass, NULL, deallocate, ctx);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/* call-seq: SQLite3::Statement.new(db, sql)
|
|
25
|
+
*
|
|
26
|
+
* Create a new statement attached to the given Database instance, and which
|
|
27
|
+
* encapsulates the given SQL text. If the text contains more than one
|
|
28
|
+
* statement (i.e., separated by semicolons), then the #remainder property
|
|
29
|
+
* will be set to the trailing text.
|
|
30
|
+
*/
|
|
31
|
+
static VALUE initialize(VALUE self, VALUE db, VALUE sql)
|
|
32
|
+
{
|
|
33
|
+
sqlite3RubyPtr db_ctx;
|
|
34
|
+
sqlite3StmtRubyPtr ctx;
|
|
35
|
+
const char *tail = NULL;
|
|
36
|
+
int status;
|
|
37
|
+
|
|
38
|
+
StringValue(sql);
|
|
39
|
+
|
|
40
|
+
Data_Get_Struct(db, sqlite3Ruby, db_ctx);
|
|
41
|
+
Data_Get_Struct(self, sqlite3StmtRuby, ctx);
|
|
42
|
+
|
|
43
|
+
if(!db_ctx->db)
|
|
44
|
+
rb_raise(rb_eArgError, "prepare called on a closed database");
|
|
45
|
+
|
|
46
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
|
47
|
+
if(!UTF8_P(sql)) {
|
|
48
|
+
sql = rb_str_export_to_enc(sql, rb_utf8_encoding());
|
|
49
|
+
}
|
|
50
|
+
#endif
|
|
51
|
+
|
|
52
|
+
#ifdef HAVE_SQLITE3_PREPARE_V2
|
|
53
|
+
status = sqlite3_prepare_v2(
|
|
54
|
+
#else
|
|
55
|
+
status = sqlite3_prepare(
|
|
56
|
+
#endif
|
|
57
|
+
db_ctx->db,
|
|
58
|
+
(const char *)StringValuePtr(sql),
|
|
59
|
+
(int)RSTRING_LEN(sql),
|
|
60
|
+
&ctx->st,
|
|
61
|
+
&tail
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
CHECK(db_ctx->db, status);
|
|
65
|
+
|
|
66
|
+
rb_iv_set(self, "@connection", db);
|
|
67
|
+
rb_iv_set(self, "@remainder", rb_str_new2(tail));
|
|
68
|
+
rb_iv_set(self, "@columns", Qnil);
|
|
69
|
+
rb_iv_set(self, "@types", Qnil);
|
|
70
|
+
|
|
71
|
+
return self;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/* call-seq: stmt.close
|
|
75
|
+
*
|
|
76
|
+
* Closes the statement by finalizing the underlying statement
|
|
77
|
+
* handle. The statement must not be used after being closed.
|
|
78
|
+
*/
|
|
79
|
+
static VALUE sqlite3_rb_close(VALUE self)
|
|
80
|
+
{
|
|
81
|
+
sqlite3StmtRubyPtr ctx;
|
|
82
|
+
|
|
83
|
+
Data_Get_Struct(self, sqlite3StmtRuby, ctx);
|
|
84
|
+
|
|
85
|
+
REQUIRE_OPEN_STMT(ctx);
|
|
86
|
+
|
|
87
|
+
sqlite3_finalize(ctx->st);
|
|
88
|
+
ctx->st = NULL;
|
|
89
|
+
|
|
90
|
+
return self;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/* call-seq: stmt.closed?
|
|
94
|
+
*
|
|
95
|
+
* Returns true if the statement has been closed.
|
|
96
|
+
*/
|
|
97
|
+
static VALUE closed_p(VALUE self)
|
|
98
|
+
{
|
|
99
|
+
sqlite3StmtRubyPtr ctx;
|
|
100
|
+
Data_Get_Struct(self, sqlite3StmtRuby, ctx);
|
|
101
|
+
|
|
102
|
+
if(!ctx->st) return Qtrue;
|
|
103
|
+
|
|
104
|
+
return Qfalse;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
static VALUE step(VALUE self)
|
|
108
|
+
{
|
|
109
|
+
sqlite3StmtRubyPtr ctx;
|
|
110
|
+
sqlite3_stmt *stmt;
|
|
111
|
+
int value, length;
|
|
112
|
+
VALUE list;
|
|
113
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
|
114
|
+
rb_encoding * internal_encoding;
|
|
115
|
+
#endif
|
|
116
|
+
|
|
117
|
+
Data_Get_Struct(self, sqlite3StmtRuby, ctx);
|
|
118
|
+
|
|
119
|
+
REQUIRE_OPEN_STMT(ctx);
|
|
120
|
+
|
|
121
|
+
if(ctx->done_p) return Qnil;
|
|
122
|
+
|
|
123
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
|
124
|
+
{
|
|
125
|
+
VALUE db = rb_iv_get(self, "@connection");
|
|
126
|
+
rb_funcall(db, rb_intern("encoding"), 0);
|
|
127
|
+
internal_encoding = rb_default_internal_encoding();
|
|
128
|
+
}
|
|
129
|
+
#endif
|
|
130
|
+
|
|
131
|
+
stmt = ctx->st;
|
|
132
|
+
|
|
133
|
+
value = sqlite3_step(stmt);
|
|
134
|
+
length = sqlite3_column_count(stmt);
|
|
135
|
+
list = rb_ary_new2((long)length);
|
|
136
|
+
|
|
137
|
+
switch(value) {
|
|
138
|
+
case SQLITE_ROW:
|
|
139
|
+
{
|
|
140
|
+
int i;
|
|
141
|
+
for(i = 0; i < length; i++) {
|
|
142
|
+
switch(sqlite3_column_type(stmt, i)) {
|
|
143
|
+
case SQLITE_INTEGER:
|
|
144
|
+
rb_ary_push(list, LL2NUM(sqlite3_column_int64(stmt, i)));
|
|
145
|
+
break;
|
|
146
|
+
case SQLITE_FLOAT:
|
|
147
|
+
rb_ary_push(list, rb_float_new(sqlite3_column_double(stmt, i)));
|
|
148
|
+
break;
|
|
149
|
+
case SQLITE_TEXT:
|
|
150
|
+
{
|
|
151
|
+
VALUE str = rb_tainted_str_new(
|
|
152
|
+
(const char *)sqlite3_column_text(stmt, i),
|
|
153
|
+
(long)sqlite3_column_bytes(stmt, i)
|
|
154
|
+
);
|
|
155
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
|
156
|
+
rb_enc_associate_index(str, rb_utf8_encindex());
|
|
157
|
+
if(internal_encoding)
|
|
158
|
+
str = rb_str_export_to_enc(str, internal_encoding);
|
|
159
|
+
#endif
|
|
160
|
+
rb_ary_push(list, str);
|
|
161
|
+
}
|
|
162
|
+
break;
|
|
163
|
+
case SQLITE_BLOB:
|
|
164
|
+
{
|
|
165
|
+
VALUE str = rb_tainted_str_new(
|
|
166
|
+
(const char *)sqlite3_column_blob(stmt, i),
|
|
167
|
+
(long)sqlite3_column_bytes(stmt, i)
|
|
168
|
+
);
|
|
169
|
+
rb_ary_push(list, str);
|
|
170
|
+
}
|
|
171
|
+
break;
|
|
172
|
+
case SQLITE_NULL:
|
|
173
|
+
rb_ary_push(list, Qnil);
|
|
174
|
+
break;
|
|
175
|
+
default:
|
|
176
|
+
rb_raise(rb_eRuntimeError, "bad type");
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
break;
|
|
181
|
+
case SQLITE_DONE:
|
|
182
|
+
ctx->done_p = 1;
|
|
183
|
+
return Qnil;
|
|
184
|
+
break;
|
|
185
|
+
default:
|
|
186
|
+
sqlite3_reset(stmt);
|
|
187
|
+
ctx->done_p = 0;
|
|
188
|
+
CHECK(sqlite3_db_handle(ctx->st), value);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
return list;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/* call-seq: stmt.bind_param(key, value)
|
|
195
|
+
*
|
|
196
|
+
* Binds value to the named (or positional) placeholder. If +param+ is a
|
|
197
|
+
* Fixnum, it is treated as an index for a positional placeholder.
|
|
198
|
+
* Otherwise it is used as the name of the placeholder to bind to.
|
|
199
|
+
*
|
|
200
|
+
* See also #bind_params.
|
|
201
|
+
*/
|
|
202
|
+
static VALUE bind_param(VALUE self, VALUE key, VALUE value)
|
|
203
|
+
{
|
|
204
|
+
sqlite3StmtRubyPtr ctx;
|
|
205
|
+
int status;
|
|
206
|
+
int index;
|
|
207
|
+
|
|
208
|
+
Data_Get_Struct(self, sqlite3StmtRuby, ctx);
|
|
209
|
+
REQUIRE_OPEN_STMT(ctx);
|
|
210
|
+
|
|
211
|
+
switch(TYPE(key)) {
|
|
212
|
+
case T_SYMBOL:
|
|
213
|
+
key = rb_funcall(key, rb_intern("to_s"), 0);
|
|
214
|
+
case T_STRING:
|
|
215
|
+
if(RSTRING_PTR(key)[0] != ':') key = rb_str_plus(rb_str_new2(":"), key);
|
|
216
|
+
index = sqlite3_bind_parameter_index(ctx->st, StringValuePtr(key));
|
|
217
|
+
break;
|
|
218
|
+
default:
|
|
219
|
+
index = (int)NUM2INT(key);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
if(index == 0)
|
|
223
|
+
rb_raise(rb_path2class("SQLite3::Exception"), "no such bind parameter");
|
|
224
|
+
|
|
225
|
+
switch(TYPE(value)) {
|
|
226
|
+
case T_STRING:
|
|
227
|
+
if(CLASS_OF(value) == cSqlite3Blob
|
|
228
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
|
229
|
+
|| rb_enc_get_index(value) == rb_ascii8bit_encindex()
|
|
230
|
+
#endif
|
|
231
|
+
) {
|
|
232
|
+
status = sqlite3_bind_blob(
|
|
233
|
+
ctx->st,
|
|
234
|
+
index,
|
|
235
|
+
(const char *)StringValuePtr(value),
|
|
236
|
+
(int)RSTRING_LEN(value),
|
|
237
|
+
SQLITE_TRANSIENT
|
|
238
|
+
);
|
|
239
|
+
} else {
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
|
243
|
+
if (UTF16_LE_P(value) || UTF16_BE_P(value)) {
|
|
244
|
+
status = sqlite3_bind_text16(
|
|
245
|
+
ctx->st,
|
|
246
|
+
index,
|
|
247
|
+
(const char *)StringValuePtr(value),
|
|
248
|
+
(int)RSTRING_LEN(value),
|
|
249
|
+
SQLITE_TRANSIENT
|
|
250
|
+
);
|
|
251
|
+
} else {
|
|
252
|
+
if (!UTF8_P(value) || !USASCII_P(value)) {
|
|
253
|
+
value = rb_str_encode(value, rb_enc_from_encoding(rb_utf8_encoding()), 0, Qnil);
|
|
254
|
+
}
|
|
255
|
+
#endif
|
|
256
|
+
status = sqlite3_bind_text(
|
|
257
|
+
ctx->st,
|
|
258
|
+
index,
|
|
259
|
+
(const char *)StringValuePtr(value),
|
|
260
|
+
(int)RSTRING_LEN(value),
|
|
261
|
+
SQLITE_TRANSIENT
|
|
262
|
+
);
|
|
263
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
|
264
|
+
}
|
|
265
|
+
#endif
|
|
266
|
+
}
|
|
267
|
+
break;
|
|
268
|
+
case T_BIGNUM: {
|
|
269
|
+
sqlite3_int64 num64;
|
|
270
|
+
if (bignum_to_int64(value, &num64)) {
|
|
271
|
+
status = sqlite3_bind_int64(ctx->st, index, num64);
|
|
272
|
+
break;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
case T_FLOAT:
|
|
276
|
+
status = sqlite3_bind_double(ctx->st, index, NUM2DBL(value));
|
|
277
|
+
break;
|
|
278
|
+
case T_FIXNUM:
|
|
279
|
+
status = sqlite3_bind_int64(ctx->st, index, (sqlite3_int64)FIX2LONG(value));
|
|
280
|
+
break;
|
|
281
|
+
case T_NIL:
|
|
282
|
+
status = sqlite3_bind_null(ctx->st, index);
|
|
283
|
+
break;
|
|
284
|
+
default:
|
|
285
|
+
rb_raise(rb_eRuntimeError, "can't prepare %s",
|
|
286
|
+
rb_class2name(CLASS_OF(value)));
|
|
287
|
+
break;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
CHECK(sqlite3_db_handle(ctx->st), status);
|
|
291
|
+
|
|
292
|
+
return self;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/* call-seq: stmt.reset!
|
|
296
|
+
*
|
|
297
|
+
* Resets the statement. This is typically done internally, though it might
|
|
298
|
+
* occassionally be necessary to manually reset the statement.
|
|
299
|
+
*/
|
|
300
|
+
static VALUE reset_bang(VALUE self)
|
|
301
|
+
{
|
|
302
|
+
sqlite3StmtRubyPtr ctx;
|
|
303
|
+
|
|
304
|
+
Data_Get_Struct(self, sqlite3StmtRuby, ctx);
|
|
305
|
+
REQUIRE_OPEN_STMT(ctx);
|
|
306
|
+
|
|
307
|
+
sqlite3_reset(ctx->st);
|
|
308
|
+
|
|
309
|
+
ctx->done_p = 0;
|
|
310
|
+
|
|
311
|
+
return self;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/* call-seq: stmt.clear_bindings!
|
|
315
|
+
*
|
|
316
|
+
* Resets the statement. This is typically done internally, though it might
|
|
317
|
+
* occassionally be necessary to manually reset the statement.
|
|
318
|
+
*/
|
|
319
|
+
static VALUE clear_bindings(VALUE self)
|
|
320
|
+
{
|
|
321
|
+
sqlite3StmtRubyPtr ctx;
|
|
322
|
+
|
|
323
|
+
Data_Get_Struct(self, sqlite3StmtRuby, ctx);
|
|
324
|
+
REQUIRE_OPEN_STMT(ctx);
|
|
325
|
+
|
|
326
|
+
sqlite3_clear_bindings(ctx->st);
|
|
327
|
+
|
|
328
|
+
ctx->done_p = 0;
|
|
329
|
+
|
|
330
|
+
return self;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/* call-seq: stmt.done?
|
|
334
|
+
*
|
|
335
|
+
* returns true if all rows have been returned.
|
|
336
|
+
*/
|
|
337
|
+
static VALUE done_p(VALUE self)
|
|
338
|
+
{
|
|
339
|
+
sqlite3StmtRubyPtr ctx;
|
|
340
|
+
Data_Get_Struct(self, sqlite3StmtRuby, ctx);
|
|
341
|
+
|
|
342
|
+
if(ctx->done_p) return Qtrue;
|
|
343
|
+
return Qfalse;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/* call-seq: stmt.column_count
|
|
347
|
+
*
|
|
348
|
+
* Returns the number of columns to be returned for this statement
|
|
349
|
+
*/
|
|
350
|
+
static VALUE column_count(VALUE self)
|
|
351
|
+
{
|
|
352
|
+
sqlite3StmtRubyPtr ctx;
|
|
353
|
+
Data_Get_Struct(self, sqlite3StmtRuby, ctx);
|
|
354
|
+
REQUIRE_OPEN_STMT(ctx);
|
|
355
|
+
|
|
356
|
+
return INT2NUM((long)sqlite3_column_count(ctx->st));
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/* call-seq: stmt.column_name(index)
|
|
360
|
+
*
|
|
361
|
+
* Get the column name at +index+. 0 based.
|
|
362
|
+
*/
|
|
363
|
+
static VALUE column_name(VALUE self, VALUE index)
|
|
364
|
+
{
|
|
365
|
+
sqlite3StmtRubyPtr ctx;
|
|
366
|
+
const char * name;
|
|
367
|
+
|
|
368
|
+
Data_Get_Struct(self, sqlite3StmtRuby, ctx);
|
|
369
|
+
REQUIRE_OPEN_STMT(ctx);
|
|
370
|
+
|
|
371
|
+
name = sqlite3_column_name(ctx->st, (int)NUM2INT(index));
|
|
372
|
+
|
|
373
|
+
if(name) return SQLITE3_UTF8_STR_NEW2(name);
|
|
374
|
+
return Qnil;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/* call-seq: stmt.column_decltype(index)
|
|
378
|
+
*
|
|
379
|
+
* Get the column type at +index+. 0 based.
|
|
380
|
+
*/
|
|
381
|
+
static VALUE column_decltype(VALUE self, VALUE index)
|
|
382
|
+
{
|
|
383
|
+
sqlite3StmtRubyPtr ctx;
|
|
384
|
+
const char * name;
|
|
385
|
+
|
|
386
|
+
Data_Get_Struct(self, sqlite3StmtRuby, ctx);
|
|
387
|
+
REQUIRE_OPEN_STMT(ctx);
|
|
388
|
+
|
|
389
|
+
name = sqlite3_column_decltype(ctx->st, (int)NUM2INT(index));
|
|
390
|
+
|
|
391
|
+
if(name) return rb_str_new2(name);
|
|
392
|
+
return Qnil;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/* call-seq: stmt.bind_parameter_count
|
|
396
|
+
*
|
|
397
|
+
* Return the number of bind parameters
|
|
398
|
+
*/
|
|
399
|
+
static VALUE bind_parameter_count(VALUE self)
|
|
400
|
+
{
|
|
401
|
+
sqlite3StmtRubyPtr ctx;
|
|
402
|
+
Data_Get_Struct(self, sqlite3StmtRuby, ctx);
|
|
403
|
+
REQUIRE_OPEN_STMT(ctx);
|
|
404
|
+
|
|
405
|
+
return INT2NUM((long)sqlite3_bind_parameter_count(ctx->st));
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
#ifdef HAVE_SQLITE3_COLUMN_DATABASE_NAME
|
|
409
|
+
|
|
410
|
+
/* call-seq: stmt.database_name(column_index)
|
|
411
|
+
*
|
|
412
|
+
* Return the database name for the column at +column_index+
|
|
413
|
+
*/
|
|
414
|
+
static VALUE database_name(VALUE self, VALUE index)
|
|
415
|
+
{
|
|
416
|
+
sqlite3StmtRubyPtr ctx;
|
|
417
|
+
Data_Get_Struct(self, sqlite3StmtRuby, ctx);
|
|
418
|
+
REQUIRE_OPEN_STMT(ctx);
|
|
419
|
+
|
|
420
|
+
return SQLITE3_UTF8_STR_NEW2(
|
|
421
|
+
sqlite3_column_database_name(ctx->st, NUM2INT(index)));
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
#endif
|
|
425
|
+
|
|
426
|
+
void init_sqlite3_statement()
|
|
427
|
+
{
|
|
428
|
+
cSqlite3Statement = rb_define_class_under(mSqlite3, "Statement", rb_cObject);
|
|
429
|
+
|
|
430
|
+
rb_define_alloc_func(cSqlite3Statement, allocate);
|
|
431
|
+
rb_define_method(cSqlite3Statement, "initialize", initialize, 2);
|
|
432
|
+
rb_define_method(cSqlite3Statement, "close", sqlite3_rb_close, 0);
|
|
433
|
+
rb_define_method(cSqlite3Statement, "closed?", closed_p, 0);
|
|
434
|
+
rb_define_method(cSqlite3Statement, "bind_param", bind_param, 2);
|
|
435
|
+
rb_define_method(cSqlite3Statement, "reset!", reset_bang, 0);
|
|
436
|
+
rb_define_method(cSqlite3Statement, "clear_bindings!", clear_bindings, 0);
|
|
437
|
+
rb_define_method(cSqlite3Statement, "step", step, 0);
|
|
438
|
+
rb_define_method(cSqlite3Statement, "done?", done_p, 0);
|
|
439
|
+
rb_define_method(cSqlite3Statement, "column_count", column_count, 0);
|
|
440
|
+
rb_define_method(cSqlite3Statement, "column_name", column_name, 1);
|
|
441
|
+
rb_define_method(cSqlite3Statement, "column_decltype", column_decltype, 1);
|
|
442
|
+
rb_define_method(cSqlite3Statement, "bind_parameter_count", bind_parameter_count, 0);
|
|
443
|
+
|
|
444
|
+
#ifdef HAVE_SQLITE3_COLUMN_DATABASE_NAME
|
|
445
|
+
rb_define_method(cSqlite3Statement, "database_name", database_name, 1);
|
|
446
|
+
#endif
|
|
447
|
+
}
|