Example #1
0
/* call-seq: SQLite3::Database.new(file, options = {})
 *
 * Create a new Database object that opens the given file. If utf16
 * is +true+, the filename is interpreted as a UTF-16 encoded string.
 *
 * By default, the new database will return result rows as arrays
 * (#results_as_hash) and has type translation disabled (#type_translation=).
 */
static VALUE initialize(int argc, VALUE *argv, VALUE self)
{
  sqlite3RubyPtr ctx;
  VALUE file;
  VALUE opts;
  VALUE zvfs;
  int status;

  Data_Get_Struct(self, sqlite3Ruby, ctx);

  rb_scan_args(argc, argv, "12", &file, &opts, &zvfs);
  if(NIL_P(opts)) opts = rb_hash_new();

#ifdef HAVE_RUBY_ENCODING_H
  if(UTF16_LE_P(file)) {
    status = sqlite3_open16(utf16_string_value_ptr(file), &ctx->db);
  } else {
#endif

    if(Qtrue == rb_hash_aref(opts, sym_utf16)) {
      status = sqlite3_open16(utf16_string_value_ptr(file), &ctx->db);
    } else {

#ifdef HAVE_RUBY_ENCODING_H
      if(!UTF8_P(file)) {
        file = rb_str_export_to_enc(file, rb_utf8_encoding());
      }
#endif

      status = sqlite3_open_v2(
          StringValuePtr(file),
          &ctx->db,
          SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
          NIL_P(zvfs) ? NULL : StringValuePtr(zvfs)
      );
    }

#ifdef HAVE_RUBY_ENCODING_H
  }
#endif

  CHECK(ctx->db, status)

  rb_iv_set(self, "@tracefunc", Qnil);
  rb_iv_set(self, "@authorizer", Qnil);
  rb_iv_set(self, "@encoding", Qnil);
  rb_iv_set(self, "@busy_handler", Qnil);
  rb_iv_set(self, "@results_as_hash", rb_hash_aref(opts, sym_results_as_hash));
  rb_iv_set(self, "@type_translation", rb_hash_aref(opts, sym_type_translation));

  if(rb_block_given_p()) {
    rb_yield(self);
    rb_funcall(self, rb_intern("close"), 0);
  }

  return self;
}
Example #2
0
/* 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;
}
Example #3
0
/* call-seq: SQLite3::Database.new(file, options = {})
 *
 * Create a new Database object that opens the given file. If utf16
 * is +true+, the filename is interpreted as a UTF-16 encoded string.
 *
 * By default, the new database will return result rows as arrays
 * (#results_as_hash) and has type translation disabled (#type_translation=).
 */
static VALUE initialize(int argc, VALUE *argv, VALUE self)
{
  sqlite3RubyPtr ctx;
  VALUE file;
  VALUE opts;
  VALUE zvfs;
#ifdef HAVE_SQLITE3_OPEN_V2
  int mode = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
#endif
  int status;

  Data_Get_Struct(self, sqlite3Ruby, ctx);

  rb_scan_args(argc, argv, "12", &file, &opts, &zvfs);
#if defined StringValueCStr
  StringValuePtr(file);
  rb_check_safe_obj(file);
#else
  Check_SafeStr(file);
#endif
  if(NIL_P(opts)) opts = rb_hash_new();
  else Check_Type(opts, T_HASH);

#ifdef HAVE_RUBY_ENCODING_H
  if(UTF16_LE_P(file) || UTF16_BE_P(file)) {
    status = sqlite3_open16(utf16_string_value_ptr(file), &ctx->db);
  } else {
#endif

    if(Qtrue == rb_hash_aref(opts, sym_utf16)) {
      status = sqlite3_open16(utf16_string_value_ptr(file), &ctx->db);
    } else {

#ifdef HAVE_RUBY_ENCODING_H
      if(!UTF8_P(file)) {
        file = rb_str_export_to_enc(file, rb_utf8_encoding());
      }
#endif

      if (Qtrue == rb_hash_aref(opts, ID2SYM(rb_intern("readonly")))) {
#ifdef HAVE_SQLITE3_OPEN_V2
        mode = SQLITE_OPEN_READONLY;
#else
        rb_raise(rb_eNotImpError, "sqlite3-ruby was compiled against a version of sqlite that does not support readonly databases");
#endif
      }
#ifdef HAVE_SQLITE3_OPEN_V2
      status = sqlite3_open_v2(
          StringValuePtr(file),
          &ctx->db,
          mode,
          NIL_P(zvfs) ? NULL : StringValuePtr(zvfs)
      );
#else
      status = sqlite3_open(
          StringValuePtr(file),
          &ctx->db
      );
#endif
    }

#ifdef HAVE_RUBY_ENCODING_H
  }
#endif

  CHECK(ctx->db, status)

  rb_iv_set(self, "@tracefunc", Qnil);
  rb_iv_set(self, "@authorizer", Qnil);
  rb_iv_set(self, "@encoding", Qnil);
  rb_iv_set(self, "@busy_handler", Qnil);
  rb_iv_set(self, "@collations", rb_hash_new());
  rb_iv_set(self, "@functions", rb_hash_new());
  rb_iv_set(self, "@results_as_hash", rb_hash_aref(opts, sym_results_as_hash));
  rb_iv_set(self, "@type_translation", rb_hash_aref(opts, sym_type_translation));
#ifdef HAVE_SQLITE3_OPEN_V2
  rb_iv_set(self, "@readonly", mode == SQLITE_OPEN_READONLY ? Qtrue : Qfalse);
#else
  rb_iv_set(self, "@readonly", Qfalse);
#endif

  if(rb_block_given_p()) {
    rb_ensure(rb_yield, self, sqlite3_rb_close, self);
  }

  return self;
}