sqlite3 1.7.3-x64-mingw32 → 2.0.1-x64-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +160 -0
- data/CONTRIBUTING.md +23 -1
- data/FAQ.md +0 -43
- data/INSTALLATION.md +13 -5
- data/LICENSE +18 -22
- data/README.md +75 -4
- data/dependencies.yml +10 -11
- data/ext/sqlite3/aggregator.c +142 -145
- data/ext/sqlite3/aggregator.h +2 -4
- data/ext/sqlite3/backup.c +74 -65
- data/ext/sqlite3/backup.h +2 -2
- data/ext/sqlite3/database.c +535 -482
- data/ext/sqlite3/database.h +7 -4
- data/ext/sqlite3/exception.c +111 -92
- data/ext/sqlite3/exception.h +3 -1
- data/ext/sqlite3/extconf.rb +21 -22
- data/ext/sqlite3/sqlite3.c +159 -115
- data/ext/sqlite3/sqlite3_ruby.h +2 -2
- data/ext/sqlite3/statement.c +516 -300
- data/ext/sqlite3/statement.h +3 -3
- data/ext/sqlite3/timespec.h +20 -0
- data/lib/sqlite3/3.0/sqlite3_native.so +0 -0
- data/lib/sqlite3/constants.rb +171 -47
- data/lib/sqlite3/database.rb +106 -166
- data/lib/sqlite3/errors.rb +26 -1
- data/lib/sqlite3/pragmas.rb +126 -136
- data/lib/sqlite3/resultset.rb +14 -97
- data/lib/sqlite3/statement.rb +58 -13
- data/lib/sqlite3/value.rb +17 -20
- data/lib/sqlite3/version.rb +1 -21
- data/lib/sqlite3.rb +6 -4
- metadata +3 -28
- data/API_CHANGES.md +0 -49
- data/ChangeLog.cvs +0 -88
- data/Gemfile +0 -10
- data/LICENSE-DEPENDENCIES +0 -20
- data/lib/sqlite3/translator.rb +0 -117
- data/test/helper.rb +0 -27
- data/test/test_backup.rb +0 -33
- data/test/test_collation.rb +0 -82
- data/test/test_database.rb +0 -668
- data/test/test_database_flags.rb +0 -95
- data/test/test_database_readonly.rb +0 -36
- data/test/test_database_readwrite.rb +0 -41
- data/test/test_deprecated.rb +0 -49
- data/test/test_encoding.rb +0 -165
- data/test/test_integration.rb +0 -507
- data/test/test_integration_aggregate.rb +0 -336
- data/test/test_integration_open_close.rb +0 -30
- data/test/test_integration_pending.rb +0 -115
- data/test/test_integration_resultset.rb +0 -142
- data/test/test_integration_statement.rb +0 -194
- data/test/test_pragmas.rb +0 -22
- data/test/test_result_set.rb +0 -47
- data/test/test_sqlite3.rb +0 -30
- data/test/test_statement.rb +0 -290
- data/test/test_statement_execute.rb +0 -39
data/ext/sqlite3/aggregator.c
CHANGED
@@ -31,20 +31,20 @@ typedef struct rb_sqlite3_protected_funcall_args {
|
|
31
31
|
static VALUE
|
32
32
|
rb_sqlite3_protected_funcall_body(VALUE protected_funcall_args_ptr)
|
33
33
|
{
|
34
|
-
|
35
|
-
|
34
|
+
protected_funcall_args_t *args =
|
35
|
+
(protected_funcall_args_t *)protected_funcall_args_ptr;
|
36
36
|
|
37
|
-
|
37
|
+
return rb_funcall2(args->self, args->method, args->argc, args->params);
|
38
38
|
}
|
39
39
|
|
40
40
|
static VALUE
|
41
41
|
rb_sqlite3_protected_funcall(VALUE self, ID method, int argc, VALUE *params,
|
42
|
-
int*
|
42
|
+
int *exc_status)
|
43
43
|
{
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
44
|
+
protected_funcall_args_t args = {
|
45
|
+
.self = self, .method = method, .argc = argc, .params = params
|
46
|
+
};
|
47
|
+
return rb_protect(rb_sqlite3_protected_funcall_body, (VALUE)(&args), exc_status);
|
48
48
|
}
|
49
49
|
|
50
50
|
/* called in rb_sqlite3_aggregator_step and rb_sqlite3_aggregator_final. It
|
@@ -54,36 +54,36 @@ rb_sqlite3_protected_funcall(VALUE self, ID method, int argc, VALUE *params,
|
|
54
54
|
static VALUE
|
55
55
|
rb_sqlite3_aggregate_instance(sqlite3_context *ctx)
|
56
56
|
{
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
57
|
+
VALUE aw = (VALUE) sqlite3_user_data(ctx);
|
58
|
+
VALUE handler_klass = rb_iv_get(aw, "-handler_klass");
|
59
|
+
VALUE inst;
|
60
|
+
VALUE *inst_ptr = sqlite3_aggregate_context(ctx, (int)sizeof(VALUE));
|
61
61
|
|
62
|
-
|
63
|
-
|
64
|
-
|
62
|
+
if (!inst_ptr) {
|
63
|
+
rb_fatal("SQLite is out-of-merory");
|
64
|
+
}
|
65
65
|
|
66
|
-
|
66
|
+
inst = *inst_ptr;
|
67
67
|
|
68
|
-
|
69
|
-
|
70
|
-
|
68
|
+
if (inst == Qfalse) { /* Qfalse == 0 */
|
69
|
+
VALUE instances = rb_iv_get(aw, "-instances");
|
70
|
+
int exc_status;
|
71
71
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
72
|
+
inst = rb_class_new_instance(0, NULL, cAggregatorInstance);
|
73
|
+
rb_iv_set(inst, "-handler_instance", rb_sqlite3_protected_funcall(
|
74
|
+
handler_klass, rb_intern("new"), 0, NULL, &exc_status));
|
75
|
+
rb_iv_set(inst, "-exc_status", INT2NUM(exc_status));
|
76
76
|
|
77
|
-
|
77
|
+
rb_ary_push(instances, inst);
|
78
78
|
|
79
|
-
|
80
|
-
|
79
|
+
*inst_ptr = inst;
|
80
|
+
}
|
81
81
|
|
82
|
-
|
83
|
-
|
84
|
-
|
82
|
+
if (inst == Qnil) {
|
83
|
+
rb_fatal("SQLite called us back on an already destroyed aggregate instance");
|
84
|
+
}
|
85
85
|
|
86
|
-
|
86
|
+
return inst;
|
87
87
|
}
|
88
88
|
|
89
89
|
/* called by rb_sqlite3_aggregator_final. Unlinks and frees the
|
@@ -92,84 +92,84 @@ rb_sqlite3_aggregate_instance(sqlite3_context *ctx)
|
|
92
92
|
static void
|
93
93
|
rb_sqlite3_aggregate_instance_destroy(sqlite3_context *ctx)
|
94
94
|
{
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
95
|
+
VALUE aw = (VALUE) sqlite3_user_data(ctx);
|
96
|
+
VALUE instances = rb_iv_get(aw, "-instances");
|
97
|
+
VALUE *inst_ptr = sqlite3_aggregate_context(ctx, 0);
|
98
|
+
VALUE inst;
|
99
99
|
|
100
|
-
|
101
|
-
|
102
|
-
|
100
|
+
if (!inst_ptr || (inst = *inst_ptr)) {
|
101
|
+
return;
|
102
|
+
}
|
103
103
|
|
104
|
-
|
105
|
-
|
106
|
-
|
104
|
+
if (inst == Qnil) {
|
105
|
+
rb_fatal("attempt to destroy aggregate instance twice");
|
106
|
+
}
|
107
107
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
108
|
+
rb_iv_set(inst, "-handler_instance", Qnil); // may catch use-after-free
|
109
|
+
if (rb_ary_delete(instances, inst) == Qnil) {
|
110
|
+
rb_fatal("must be in instances at that point");
|
111
|
+
}
|
112
112
|
|
113
|
-
|
113
|
+
*inst_ptr = Qnil;
|
114
114
|
}
|
115
115
|
|
116
116
|
static void
|
117
|
-
rb_sqlite3_aggregator_step(sqlite3_context *
|
117
|
+
rb_sqlite3_aggregator_step(sqlite3_context *ctx, int argc, sqlite3_value **argv)
|
118
118
|
{
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
}
|
134
|
-
if (argc > 1) {
|
135
|
-
params = xcalloc((size_t)argc, sizeof(VALUE));
|
136
|
-
for(i = 0; i < argc; i++) {
|
137
|
-
params[i] = sqlite3val2rb(argv[i]);
|
119
|
+
VALUE inst = rb_sqlite3_aggregate_instance(ctx);
|
120
|
+
VALUE handler_instance = rb_iv_get(inst, "-handler_instance");
|
121
|
+
VALUE *params = NULL;
|
122
|
+
VALUE one_param;
|
123
|
+
int exc_status = NUM2INT(rb_iv_get(inst, "-exc_status"));
|
124
|
+
int i;
|
125
|
+
|
126
|
+
if (exc_status) {
|
127
|
+
return;
|
128
|
+
}
|
129
|
+
|
130
|
+
if (argc == 1) {
|
131
|
+
one_param = sqlite3val2rb(argv[0]);
|
132
|
+
params = &one_param;
|
138
133
|
}
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
134
|
+
if (argc > 1) {
|
135
|
+
params = xcalloc((size_t)argc, sizeof(VALUE));
|
136
|
+
for (i = 0; i < argc; i++) {
|
137
|
+
params[i] = sqlite3val2rb(argv[i]);
|
138
|
+
}
|
139
|
+
}
|
140
|
+
rb_sqlite3_protected_funcall(
|
141
|
+
handler_instance, rb_intern("step"), argc, params, &exc_status);
|
142
|
+
if (argc > 1) {
|
143
|
+
xfree(params);
|
144
|
+
}
|
145
|
+
|
146
|
+
rb_iv_set(inst, "-exc_status", INT2NUM(exc_status));
|
147
147
|
}
|
148
148
|
|
149
149
|
/* we assume that this function is only called once per execution context */
|
150
150
|
static void
|
151
|
-
rb_sqlite3_aggregator_final(sqlite3_context *
|
151
|
+
rb_sqlite3_aggregator_final(sqlite3_context *ctx)
|
152
152
|
{
|
153
|
-
|
154
|
-
|
155
|
-
|
153
|
+
VALUE inst = rb_sqlite3_aggregate_instance(ctx);
|
154
|
+
VALUE handler_instance = rb_iv_get(inst, "-handler_instance");
|
155
|
+
int exc_status = NUM2INT(rb_iv_get(inst, "-exc_status"));
|
156
156
|
|
157
|
-
if (!exc_status) {
|
158
|
-
VALUE result = rb_sqlite3_protected_funcall(
|
159
|
-
handler_instance, rb_intern("finalize"), 0, NULL, &exc_status);
|
160
157
|
if (!exc_status) {
|
161
|
-
|
158
|
+
VALUE result = rb_sqlite3_protected_funcall(
|
159
|
+
handler_instance, rb_intern("finalize"), 0, NULL, &exc_status);
|
160
|
+
if (!exc_status) {
|
161
|
+
set_sqlite3_func_result(ctx, result);
|
162
|
+
}
|
162
163
|
}
|
163
|
-
}
|
164
164
|
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
165
|
+
if (exc_status) {
|
166
|
+
/* the user should never see this, as Statement.step() will pick up the
|
167
|
+
* outstanding exception and raise it instead of generating a new one
|
168
|
+
* for SQLITE_ERROR with message "Ruby Exception occurred" */
|
169
|
+
sqlite3_result_error(ctx, "Ruby Exception occurred", -1);
|
170
|
+
}
|
171
171
|
|
172
|
-
|
172
|
+
rb_sqlite3_aggregate_instance_destroy(ctx);
|
173
173
|
}
|
174
174
|
|
175
175
|
/* call-seq: define_aggregator2(aggregator)
|
@@ -205,69 +205,66 @@ rb_sqlite3_aggregator_final(sqlite3_context * ctx)
|
|
205
205
|
VALUE
|
206
206
|
rb_sqlite3_define_aggregator2(VALUE self, VALUE aggregator, VALUE ruby_name)
|
207
207
|
{
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
208
|
+
/* define_aggregator is added as a method to SQLite3::Database in database.c */
|
209
|
+
sqlite3RubyPtr ctx = sqlite3_database_unwrap(self);
|
210
|
+
int arity, status;
|
211
|
+
VALUE aw;
|
212
|
+
VALUE aggregators;
|
213
|
+
|
214
|
+
if (!ctx->db) {
|
215
|
+
rb_raise(rb_path2class("SQLite3::Exception"), "cannot use a closed database");
|
216
|
+
}
|
217
|
+
|
218
|
+
if (rb_respond_to(aggregator, rb_intern("arity"))) {
|
219
|
+
VALUE ruby_arity = rb_funcall(aggregator, rb_intern("arity"), 0);
|
220
|
+
arity = NUM2INT(ruby_arity);
|
221
|
+
} else {
|
222
|
+
arity = -1;
|
223
|
+
}
|
224
|
+
|
225
|
+
if (arity < -1 || arity > 127) {
|
226
226
|
#ifdef PRIsVALUE
|
227
|
-
|
228
|
-
|
227
|
+
rb_raise(rb_eArgError, "%"PRIsVALUE" arity=%d out of range -1..127",
|
228
|
+
self, arity);
|
229
229
|
#else
|
230
|
-
|
230
|
+
rb_raise(rb_eArgError, "Aggregator arity=%d out of range -1..127", arity);
|
231
231
|
#endif
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
rb_ary_push(aggregators, aw);
|
260
|
-
|
261
|
-
return self;
|
232
|
+
}
|
233
|
+
|
234
|
+
if (!rb_ivar_defined(self, rb_intern("-aggregators"))) {
|
235
|
+
rb_iv_set(self, "-aggregators", rb_ary_new());
|
236
|
+
}
|
237
|
+
aggregators = rb_iv_get(self, "-aggregators");
|
238
|
+
|
239
|
+
aw = rb_class_new_instance(0, NULL, cAggregatorWrapper);
|
240
|
+
rb_iv_set(aw, "-handler_klass", aggregator);
|
241
|
+
rb_iv_set(aw, "-instances", rb_ary_new());
|
242
|
+
|
243
|
+
status = sqlite3_create_function(
|
244
|
+
ctx->db,
|
245
|
+
StringValueCStr(ruby_name),
|
246
|
+
arity,
|
247
|
+
SQLITE_UTF8,
|
248
|
+
(void *)aw,
|
249
|
+
NULL,
|
250
|
+
rb_sqlite3_aggregator_step,
|
251
|
+
rb_sqlite3_aggregator_final
|
252
|
+
);
|
253
|
+
|
254
|
+
CHECK(ctx->db, status);
|
255
|
+
|
256
|
+
rb_ary_push(aggregators, aw);
|
257
|
+
|
258
|
+
return self;
|
262
259
|
}
|
263
260
|
|
264
261
|
void
|
265
262
|
rb_sqlite3_aggregator_init(void)
|
266
263
|
{
|
267
|
-
|
268
|
-
|
269
|
-
|
264
|
+
/* rb_class_new generatos class with undefined allocator in ruby 1.9 */
|
265
|
+
cAggregatorWrapper = rb_funcall(rb_cClass, rb_intern("new"), 0);
|
266
|
+
rb_gc_register_mark_object(cAggregatorWrapper);
|
270
267
|
|
271
|
-
|
272
|
-
|
268
|
+
cAggregatorInstance = rb_funcall(rb_cClass, rb_intern("new"), 0);
|
269
|
+
rb_gc_register_mark_object(cAggregatorInstance);
|
273
270
|
}
|
data/ext/sqlite3/aggregator.h
CHANGED
@@ -3,10 +3,8 @@
|
|
3
3
|
|
4
4
|
#include <sqlite3_ruby.h>
|
5
5
|
|
6
|
-
VALUE
|
7
|
-
rb_sqlite3_define_aggregator2(VALUE self, VALUE aggregator, VALUE ruby_name);
|
6
|
+
VALUE rb_sqlite3_define_aggregator2(VALUE self, VALUE aggregator, VALUE ruby_name);
|
8
7
|
|
9
|
-
void
|
10
|
-
rb_sqlite3_aggregator_init(void);
|
8
|
+
void rb_sqlite3_aggregator_init(void);
|
11
9
|
|
12
10
|
#endif
|
data/ext/sqlite3/backup.c
CHANGED
@@ -8,11 +8,12 @@
|
|
8
8
|
|
9
9
|
VALUE cSqlite3Backup;
|
10
10
|
|
11
|
-
static size_t
|
11
|
+
static size_t
|
12
|
+
backup_memsize(const void *data)
|
12
13
|
{
|
13
|
-
|
14
|
-
|
15
|
-
|
14
|
+
sqlite3BackupRubyPtr ctx = (sqlite3BackupRubyPtr)data;
|
15
|
+
// NB: can't account for ctx->p because the type is incomplete.
|
16
|
+
return sizeof(*ctx);
|
16
17
|
}
|
17
18
|
|
18
19
|
static const rb_data_type_t backup_type = {
|
@@ -27,10 +28,11 @@ static const rb_data_type_t backup_type = {
|
|
27
28
|
RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
|
28
29
|
};
|
29
30
|
|
30
|
-
static VALUE
|
31
|
+
static VALUE
|
32
|
+
allocate(VALUE klass)
|
31
33
|
{
|
32
|
-
|
33
|
-
|
34
|
+
sqlite3BackupRubyPtr ctx;
|
35
|
+
return TypedData_Make_Struct(klass, sqlite3BackupRuby, &backup_type, ctx);
|
34
36
|
}
|
35
37
|
|
36
38
|
/* call-seq: SQLite3::Backup.new(dstdb, dstname, srcdb, srcname)
|
@@ -69,31 +71,33 @@ static VALUE allocate(VALUE klass)
|
|
69
71
|
* b.finish
|
70
72
|
*
|
71
73
|
*/
|
72
|
-
static VALUE
|
74
|
+
static VALUE
|
75
|
+
initialize(VALUE self, VALUE dstdb, VALUE dstname, VALUE srcdb, VALUE srcname)
|
73
76
|
{
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
77
|
+
sqlite3BackupRubyPtr ctx;
|
78
|
+
sqlite3RubyPtr ddb_ctx, sdb_ctx;
|
79
|
+
sqlite3_backup *pBackup;
|
80
|
+
|
81
|
+
TypedData_Get_Struct(self, sqlite3BackupRuby, &backup_type, ctx);
|
82
|
+
ddb_ctx = sqlite3_database_unwrap(dstdb);
|
83
|
+
sdb_ctx = sqlite3_database_unwrap(srcdb);
|
84
|
+
|
85
|
+
if (!sdb_ctx->db) {
|
86
|
+
rb_raise(rb_eArgError, "cannot backup from a closed database");
|
87
|
+
}
|
88
|
+
if (!ddb_ctx->db) {
|
89
|
+
rb_raise(rb_eArgError, "cannot backup to a closed database");
|
90
|
+
}
|
91
|
+
|
92
|
+
pBackup = sqlite3_backup_init(ddb_ctx->db, StringValuePtr(dstname),
|
93
|
+
sdb_ctx->db, StringValuePtr(srcname));
|
94
|
+
if (pBackup) {
|
95
|
+
ctx->p = pBackup;
|
96
|
+
} else {
|
97
|
+
CHECK(ddb_ctx->db, sqlite3_errcode(ddb_ctx->db));
|
98
|
+
}
|
99
|
+
|
100
|
+
return self;
|
97
101
|
}
|
98
102
|
|
99
103
|
/* call-seq: SQLite3::Backup#step(nPage)
|
@@ -105,30 +109,32 @@ static VALUE initialize(VALUE self, VALUE dstdb, VALUE dstname, VALUE srcdb, VAL
|
|
105
109
|
* When coping is not done, it returns SQLite3::Constants::ErrorCode::OK.
|
106
110
|
* When some errors occur, it returns the error code.
|
107
111
|
*/
|
108
|
-
static VALUE
|
112
|
+
static VALUE
|
113
|
+
step(VALUE self, VALUE nPage)
|
109
114
|
{
|
110
|
-
|
111
|
-
|
115
|
+
sqlite3BackupRubyPtr ctx;
|
116
|
+
int status;
|
112
117
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
118
|
+
TypedData_Get_Struct(self, sqlite3BackupRuby, &backup_type, ctx);
|
119
|
+
REQUIRE_OPEN_BACKUP(ctx);
|
120
|
+
status = sqlite3_backup_step(ctx->p, NUM2INT(nPage));
|
121
|
+
return INT2NUM(status);
|
117
122
|
}
|
118
123
|
|
119
124
|
/* call-seq: SQLite3::Backup#finish
|
120
125
|
*
|
121
126
|
* Destroy the backup object.
|
122
127
|
*/
|
123
|
-
static VALUE
|
128
|
+
static VALUE
|
129
|
+
finish(VALUE self)
|
124
130
|
{
|
125
|
-
|
131
|
+
sqlite3BackupRubyPtr ctx;
|
126
132
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
133
|
+
TypedData_Get_Struct(self, sqlite3BackupRuby, &backup_type, ctx);
|
134
|
+
REQUIRE_OPEN_BACKUP(ctx);
|
135
|
+
(void)sqlite3_backup_finish(ctx->p);
|
136
|
+
ctx->p = NULL;
|
137
|
+
return Qnil;
|
132
138
|
}
|
133
139
|
|
134
140
|
/* call-seq: SQLite3::Backup#remaining
|
@@ -138,13 +144,14 @@ static VALUE finish(VALUE self)
|
|
138
144
|
* Note that the value is only updated after step() is called,
|
139
145
|
* so before calling step() returned value is invalid.
|
140
146
|
*/
|
141
|
-
static VALUE
|
147
|
+
static VALUE
|
148
|
+
remaining(VALUE self)
|
142
149
|
{
|
143
|
-
|
150
|
+
sqlite3BackupRubyPtr ctx;
|
144
151
|
|
145
|
-
|
146
|
-
|
147
|
-
|
152
|
+
TypedData_Get_Struct(self, sqlite3BackupRuby, &backup_type, ctx);
|
153
|
+
REQUIRE_OPEN_BACKUP(ctx);
|
154
|
+
return INT2NUM(sqlite3_backup_remaining(ctx->p));
|
148
155
|
}
|
149
156
|
|
150
157
|
/* call-seq: SQLite3::Backup#pagecount
|
@@ -154,28 +161,30 @@ static VALUE remaining(VALUE self)
|
|
154
161
|
* Note that the value is only updated after step() is called,
|
155
162
|
* so before calling step() returned value is invalid.
|
156
163
|
*/
|
157
|
-
static VALUE
|
164
|
+
static VALUE
|
165
|
+
pagecount(VALUE self)
|
158
166
|
{
|
159
|
-
|
167
|
+
sqlite3BackupRubyPtr ctx;
|
160
168
|
|
161
|
-
|
162
|
-
|
163
|
-
|
169
|
+
TypedData_Get_Struct(self, sqlite3BackupRuby, &backup_type, ctx);
|
170
|
+
REQUIRE_OPEN_BACKUP(ctx);
|
171
|
+
return INT2NUM(sqlite3_backup_pagecount(ctx->p));
|
164
172
|
}
|
165
173
|
|
166
|
-
void
|
174
|
+
void
|
175
|
+
init_sqlite3_backup(void)
|
167
176
|
{
|
168
177
|
#if 0
|
169
|
-
|
178
|
+
VALUE mSqlite3 = rb_define_module("SQLite3");
|
170
179
|
#endif
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
180
|
+
cSqlite3Backup = rb_define_class_under(mSqlite3, "Backup", rb_cObject);
|
181
|
+
|
182
|
+
rb_define_alloc_func(cSqlite3Backup, allocate);
|
183
|
+
rb_define_method(cSqlite3Backup, "initialize", initialize, 4);
|
184
|
+
rb_define_method(cSqlite3Backup, "step", step, 1);
|
185
|
+
rb_define_method(cSqlite3Backup, "finish", finish, 0);
|
186
|
+
rb_define_method(cSqlite3Backup, "remaining", remaining, 0);
|
187
|
+
rb_define_method(cSqlite3Backup, "pagecount", pagecount, 0);
|
179
188
|
}
|
180
189
|
|
181
190
|
#endif
|
data/ext/sqlite3/backup.h
CHANGED
@@ -4,11 +4,11 @@
|
|
4
4
|
#include <sqlite3_ruby.h>
|
5
5
|
|
6
6
|
struct _sqlite3BackupRuby {
|
7
|
-
|
7
|
+
sqlite3_backup *p;
|
8
8
|
};
|
9
9
|
|
10
10
|
typedef struct _sqlite3BackupRuby sqlite3BackupRuby;
|
11
|
-
typedef sqlite3BackupRuby *
|
11
|
+
typedef sqlite3BackupRuby *sqlite3BackupRubyPtr;
|
12
12
|
|
13
13
|
void init_sqlite3_backup();
|
14
14
|
|