static void set_sqlite3_func_result(sqlite3_context * ctx, VALUE result) { switch(TYPE(result)) { case T_NIL: sqlite3_result_null(ctx); break; case T_FIXNUM: sqlite3_result_int64(ctx, (sqlite3_int64)FIX2LONG(result)); break; case T_BIGNUM: { #if SIZEOF_LONG < 8 sqlite3_int64 num64; if (bignum_to_int64(result, &num64)) { sqlite3_result_int64(ctx, num64); break; } #endif } case T_FLOAT: sqlite3_result_double(ctx, NUM2DBL(result)); break; case T_STRING: if(CLASS_OF(result) == cSqlite3Blob #ifdef HAVE_RUBY_ENCODING_H || rb_enc_get_index(result) == rb_ascii8bit_encindex() #endif ) { sqlite3_result_blob( ctx, (const void *)StringValuePtr(result), (int)RSTRING_LEN(result), SQLITE_TRANSIENT ); } else { sqlite3_result_text( ctx, (const char *)StringValuePtr(result), (int)RSTRING_LEN(result), SQLITE_TRANSIENT ); } break; default: rb_raise(rb_eRuntimeError, "can't return %s", rb_class2name(CLASS_OF(result))); } }
/* call-seq: stmt.bind_param(key, value) * * Binds value to the named (or positional) placeholder. If +param+ is a * Fixnum, it is treated as an index for a positional placeholder. * Otherwise it is used as the name of the placeholder to bind to. * * See also #bind_params. */ static VALUE bind_param(VALUE self, VALUE key, VALUE value) { sqlite3StmtRubyPtr ctx; int status; int index; Data_Get_Struct(self, sqlite3StmtRuby, ctx); REQUIRE_OPEN_STMT(ctx); switch(TYPE(key)) { case T_SYMBOL: key = rb_funcall(key, rb_intern("to_s"), 0); case T_STRING: if(RSTRING_PTR(key)[0] != ':') key = rb_str_plus(rb_str_new2(":"), key); index = sqlite3_bind_parameter_index(ctx->st, StringValuePtr(key)); break; default: index = (int)NUM2INT(key); } if(index == 0) rb_raise(rb_path2class("SQLite3::Exception"), "no such bind parameter"); switch(TYPE(value)) { case T_STRING: if(CLASS_OF(value) == cSqlite3Blob || rb_enc_get_index(value) == rb_ascii8bit_encindex() ) { status = sqlite3_bind_blob( ctx->st, index, (const char *)StringValuePtr(value), (int)RSTRING_LEN(value), SQLITE_TRANSIENT ); } else { if (UTF16_LE_P(value) || UTF16_BE_P(value)) { status = sqlite3_bind_text16( ctx->st, index, (const char *)StringValuePtr(value), (int)RSTRING_LEN(value), SQLITE_TRANSIENT ); } else { if (!UTF8_P(value) || !USASCII_P(value)) { value = rb_str_encode(value, rb_enc_from_encoding(rb_utf8_encoding()), 0, Qnil); } status = sqlite3_bind_text( ctx->st, index, (const char *)StringValuePtr(value), (int)RSTRING_LEN(value), SQLITE_TRANSIENT ); } } break; case T_BIGNUM: { sqlite3_int64 num64; if (bignum_to_int64(value, &num64)) { status = sqlite3_bind_int64(ctx->st, index, num64); break; } } case T_FLOAT: status = sqlite3_bind_double(ctx->st, index, NUM2DBL(value)); break; case T_FIXNUM: status = sqlite3_bind_int64(ctx->st, index, (sqlite3_int64)FIX2LONG(value)); break; case T_NIL: status = sqlite3_bind_null(ctx->st, index); break; default: rb_raise(rb_eRuntimeError, "can't prepare %s", rb_class2name(CLASS_OF(value))); break; } CHECK(sqlite3_db_handle(ctx->st), status); return self; }