1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
|
#include <sqlite3_ruby.h>
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));
}
|