sqlite3 1.7.3-arm64-darwin → 2.0.0-arm64-darwin
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/CHANGELOG.md +152 -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.bundle +0 -0
- data/lib/sqlite3/3.1/sqlite3_native.bundle +0 -0
- data/lib/sqlite3/3.2/sqlite3_native.bundle +0 -0
- data/lib/sqlite3/3.3/sqlite3_native.bundle +0 -0
- data/lib/sqlite3/constants.rb +171 -47
- data/lib/sqlite3/database.rb +105 -165
- 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 |  |