#include VALUE mSqlite3; VALUE cSqlite3Blob; int bignum_to_int64(VALUE value, sqlite3_int64 *result) { #ifdef HAVE_RB_INTEGER_PACK const int nails = 0; int t = rb_integer_pack(value, result, 1, sizeof(*result), nails, INTEGER_PACK_NATIVE_BYTE_ORDER| INTEGER_PACK_2COMP); switch (t) { case -2: case +2: return 0; case +1: if (!nails) { if (*result < 0) return 0; } break; case -1: if (!nails) { if (*result >= 0) return 0; } else { *result += INT64_MIN; } break; } return 1; #else # ifndef RBIGNUM_LEN # define RBIGNUM_LEN(x) RBIGNUM(x)->len # endif const long len = RBIGNUM_LEN(value); if (len == 0) { *result = 0; return 1; } if (len > 63 / (SIZEOF_BDIGITS * CHAR_BIT) + 1) return 0; if (len == 63 / (SIZEOF_BDIGITS * CHAR_BIT) + 1) { const BDIGIT *digits = RBIGNUM_DIGITS(value); BDIGIT blast = digits[len-1]; BDIGIT bmax = (BDIGIT)1UL << (63 % (CHAR_BIT * SIZEOF_BDIGITS)); if (blast > bmax) return 0; if (blast == bmax) { if (RBIGNUM_POSITIVE_P(value)) { return 0; } else { long i = len-1; while (i) { if (digits[--i]) return 0; } } } } *result = (sqlite3_int64)NUM2LL(value); return 1; #endif } static VALUE libversion(VALUE UNUSED(klass)) { return INT2NUM(sqlite3_libversion_number()); } void Init_sqlite3_native() { /* * SQLite3 is a wrapper around the popular database * sqlite[http://sqlite.org]. * * For an example of usage, see SQLite3::Database. */ mSqlite3 = rb_define_module("SQLite3"); /* A class for differentiating between strings and blobs, when binding them * into statements. */ cSqlite3Blob = rb_define_class_under(mSqlite3, "Blob", rb_cString); /* Initialize the sqlite3 library */ #ifdef HAVE_SQLITE3_INITIALIZE sqlite3_initialize(); #endif init_sqlite3_database(); init_sqlite3_statement(); #ifdef HAVE_SQLITE3_BACKUP_INIT init_sqlite3_backup(); #endif rb_define_singleton_method(mSqlite3, "libversion", libversion, 0); rb_define_const(mSqlite3, "SQLITE_VERSION", rb_str_new2(SQLITE_VERSION)); rb_define_const(mSqlite3, "SQLITE_VERSION_NUMBER", INT2FIX(SQLITE_VERSION_NUMBER)); }