ext/oci8/oradate.c in ruby-oci8-1.0.7 vs ext/oci8/oradate.c in ruby-oci8-2.0.0

- old
+ new

@@ -1,18 +1,39 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ /* - oradate.c - part of ruby-oci8 - - Copyright (C) 2002 KUBO Takehiro <kubo@jiubao.org> - -=begin -== OraDate -date and time between 4712 B.C. and 9999 A.D. -=end -*/ + * oradate.c + * + * $Author: kubo $ + * $Date: 2009-01-04 01:58:01 +0900 (Sun, 04 Jan 2009) $ + * + * Copyright (C) 2002-2008 KUBO Takehiro <kubo@jiubao.org> + * + * date and time between 4712 B.C. and 9999 A.D. + */ #include "oci8.h" #include <time.h> +static VALUE cOraDate; + +/* + * Document-class: OraDate + * + * ruby class compatible with Oracle <tt>DATE</tt> data type. + * Date and time between 4712 B.C. and 9999 A.D. + * + */ +struct ora_date { + unsigned char century; + unsigned char year; + unsigned char month; + unsigned char day; + unsigned char hour; + unsigned char minute; + unsigned char second; +}; +typedef struct ora_date ora_date_t; + #define Set_year(od, y) (od)->century = y / 100 + 100, (od)->year = y % 100 + 100 #define Set_month(od, m) (od)->month = m #define Set_day(od, d) (od)->day = d #define Set_hour(od, h) (od)->hour = h + 1 #define Set_minute(od, m) (od)->minute = m + 1 @@ -24,403 +45,572 @@ #define Get_hour(od) ((od)->hour - 1) #define Get_minute(od) ((od)->minute - 1) #define Get_second(od) ((od)->second - 1) #define Check_year(year) \ - if (year < -4712 || 9999 < year) \ - rb_raise(rb_eRangeError, "Out of range for year %d (expect -4712 .. 9999)", year) + if (year < -4712 || 9999 < year) \ + rb_raise(rb_eRangeError, "Out of range for year %d (expect -4712 .. 9999)", year) #define Check_month(month) \ - if (month < 1 || 12 < month) \ - rb_raise(rb_eRangeError, "Out of range for month %d (expect 1 .. 12)", month) + if (month < 1 || 12 < month) \ + rb_raise(rb_eRangeError, "Out of range for month %d (expect 1 .. 12)", month) #define Check_day(day) \ - if (day < 1 || 31 < day) \ - rb_raise(rb_eRangeError, "Out of range for day %d (expect 1 .. 31)", day) + if (day < 1 || 31 < day) \ + rb_raise(rb_eRangeError, "Out of range for day %d (expect 1 .. 31)", day) #define Check_hour(hour) \ - if (hour < 0 || 23 < hour) \ - rb_raise(rb_eRangeError, "Out of range for hour %d (expect 0 .. 24)", hour) + if (hour < 0 || 23 < hour) \ + rb_raise(rb_eRangeError, "Out of range for hour %d (expect 0 .. 24)", hour) #define Check_minute(min) \ - if (min < 0 || 59 < min) \ - rb_raise(rb_eRangeError, "Out of range for minute %d (expect 0 .. 59)", min) + if (min < 0 || 59 < min) \ + rb_raise(rb_eRangeError, "Out of range for minute %d (expect 0 .. 59)", min) #define Check_second(sec) \ - if (sec < 0 || 59 < sec) \ - rb_raise(rb_eRangeError, "Out of range for second %d (expect 0 .. 59)", sec) + if (sec < 0 || 59 < sec) \ + rb_raise(rb_eRangeError, "Out of range for second %d (expect 0 .. 59)", sec) - -static VALUE ora_date_s_allocate(VALUE klass) +static void oci8_set_ora_date(ora_date_t *od, int year, int month, int day, int hour, int minute, int second) { - ora_date_t *od; - return Data_Make_Struct(klass, ora_date_t, NULL, xfree, od); + Set_year(od, year); + Set_month(od, month); + Set_day(od, day); + Set_hour(od, hour); + Set_minute(od, minute); + Set_second(od, second); } -#ifndef HAVE_RB_DEFINE_ALLOC_FUNC -/* ruby 1.6 */ -static VALUE ora_date_s_new(int argc, VALUE *argv, VALUE klass) +static VALUE ora_date_s_allocate(VALUE klass) { - VALUE obj = ora_date_s_allocate(klass); - rb_obj_call_init(obj, argc, argv); - return obj; + ora_date_t *od; + return Data_Make_Struct(klass, ora_date_t, NULL, xfree, od); } -#endif /* -=begin ---- OraDate.new([year [, month [, day [, hour [, min [,sec]]]]]]) -=end -*/ + * call-seq: + * OraDate.new(year = 1, month = 1, day = 1, hour = 0, min = 0, sec = 0) -> oradate + * + * Returns an <code>OraDate</code> object initialized to the specified date and time. + */ static VALUE ora_date_initialize(int argc, VALUE *argv, VALUE self) { - VALUE vyear, vmonth, vday, vhour, vmin, vsec; - ora_date_t *od; - int year, month, day, hour, min, sec; + VALUE vyear, vmonth, vday, vhour, vmin, vsec; + ora_date_t *od = DATA_PTR(self); + int year, month, day, hour, min, sec; - rb_scan_args(argc, argv, "06", &vyear, &vmonth, &vday, &vhour, &vmin, &vsec); - /* set year */ - if (argc > 0) { - year = NUM2INT(vyear); - Check_year(year); - } else { - year = 1; - } - /* set month */ - if (argc > 1) { - month = NUM2INT(vmonth); - Check_month(month); - } else { - month = 1; - } - /* set day */ - if (argc > 2) { - day = NUM2INT(vday); - Check_day(day); - } else { - day = 1; - } - /* set hour */ - if (argc > 3) { - hour = NUM2INT(vhour); - Check_hour(hour); - } else { - hour = 0; - } - /* set minute */ - if (argc > 4) { - min = NUM2INT(vmin); - Check_minute(min); - } else { - min = 0; - } - /* set second */ - if (argc > 5) { - sec = NUM2INT(vsec); - Check_second(sec); - } else { - sec = 0; - } + rb_scan_args(argc, argv, "06", &vyear, &vmonth, &vday, &vhour, &vmin, &vsec); + /* set year */ + if (argc > 0) { + year = NUM2INT(vyear); + Check_year(year); + } else { + year = 1; + } + /* set month */ + if (argc > 1) { + month = NUM2INT(vmonth); + Check_month(month); + } else { + month = 1; + } + /* set day */ + if (argc > 2) { + day = NUM2INT(vday); + Check_day(day); + } else { + day = 1; + } + /* set hour */ + if (argc > 3) { + hour = NUM2INT(vhour); + Check_hour(hour); + } else { + hour = 0; + } + /* set minute */ + if (argc > 4) { + min = NUM2INT(vmin); + Check_minute(min); + } else { + min = 0; + } + /* set second */ + if (argc > 5) { + sec = NUM2INT(vsec); + Check_second(sec); + } else { + sec = 0; + } - Data_Get_Struct(self, ora_date_t, od); - oci8_set_ora_date(od, year, month, day, hour, min, sec); - return Qnil; + oci8_set_ora_date(od, year, month, day, hour, min, sec); + return Qnil; } +/* :nodoc: */ static VALUE ora_date_initialize_copy(VALUE lhs, VALUE rhs) { - ora_date_t *l, *r; + ora_date_t *l, *r; -#ifdef HAVE_RB_DEFINE_ALLOC_FUNC - /* ruby 1.8 */ - rb_obj_init_copy(lhs, rhs); + rb_obj_init_copy(lhs, rhs); + Data_Get_Struct(lhs, ora_date_t, l); + Data_Get_Struct(rhs, ora_date_t, r); + memcpy(l, r, sizeof(ora_date_t)); + return lhs; +} + +/* + * call-seq: + * OraDate.now() -> oradate + * + * Returns an <code>OraDate</code> object initialized to the + * current local time. + */ +static VALUE ora_date_s_now(int argc, VALUE *argv, VALUE klass) +{ + VALUE obj = ora_date_s_allocate(klass); + ora_date_t *od = DATA_PTR(obj); + time_t tm = time(0); + int year, month, day, hour, min, sec; +#ifdef HAVE_LOCALTIME_R + struct tm t; + localtime_r(&tm, &t); +#define tp (&t) +#else + struct tm *tp; + tp = localtime(&tm); #endif - Data_Get_Struct(lhs, ora_date_t, l); - Data_Get_Struct(rhs, ora_date_t, r); - memcpy(l, r, sizeof(ora_date_t)); - return lhs; -} + year = tp->tm_year + 1900; + month = tp->tm_mon + 1; + day = tp->tm_mday; + hour = tp->tm_hour; + min = tp->tm_min; + sec = tp->tm_sec; -#ifndef HAVE_RB_DEFINE_ALLOC_FUNC -/* ruby 1.6 */ -static VALUE ora_date_clone(VALUE self) + oci8_set_ora_date(od, year, month, day, hour, min, sec); + return obj; +} + +/* + * call-seq: + * oradate.to_s -> string + * + * Returns a string representing <i>oradate</i>. + * The string format is 'yyyy/mm/dd hh:mi:ss'. + */ +static VALUE ora_date_to_s(VALUE self) { - VALUE obj = ora_date_s_allocate(CLASS_OF(self)); - return ora_date_initialize_copy(obj, self); + ora_date_t *od; + char buf[30]; + + Data_Get_Struct(self, ora_date_t, od); + sprintf(buf, "%04d/%02d/%02d %02d:%02d:%02d", Get_year(od), Get_month(od), + Get_day(od), Get_hour(od), Get_minute(od), Get_second(od)); + return rb_usascii_str_new_cstr(buf); } -#endif /* -=begin ---- OraDate.now() -=end -*/ -static VALUE ora_date_s_now(int argc, VALUE *argv) + * call-seq: + * oradate.to_a -> array + * + * Returns a 6-element <i>array</i> of values for <i>oradate</i>: + * {<code>[year, month, day, hour, minute, second]</code>}. + */ +static VALUE ora_date_to_a(VALUE self) { - ora_date_t *od; - VALUE obj; - int year, month, day, hour, min, sec; - time_t tm; - struct tm *tp; + ora_date_t *od; + VALUE ary[6]; - tm = time(0); - tp = localtime(&tm); - year = tp->tm_year + 1900; - month = tp->tm_mon + 1; - day = tp->tm_mday; - hour = tp->tm_hour; - min = tp->tm_min; - sec = tp->tm_sec; + Data_Get_Struct(self, ora_date_t, od); + ary[0] = INT2FIX(Get_year(od)); + ary[1] = INT2FIX(Get_month(od)); + ary[2] = INT2FIX(Get_day(od)); + ary[3] = INT2FIX(Get_hour(od)); + ary[4] = INT2FIX(Get_minute(od)); + ary[5] = INT2FIX(Get_second(od)); + return rb_ary_new4(6, ary); +} - obj = Data_Make_Struct(cOraDate, ora_date_t, NULL, xfree, od); - oci8_set_ora_date(od, year, month, day, hour, min, sec); - return obj; +/* + * call-seq: + * oradate.year -> fixnum + * + * Returns the year (-4712..9999) for <i>oradate</i>. + */ +static VALUE ora_date_year(VALUE self) +{ + ora_date_t *od; + + Data_Get_Struct(self, ora_date_t, od); + return INT2FIX(Get_year(od)); } /* -=begin ---- OraDate#to_s() -=end -*/ -static VALUE ora_date_to_s(VALUE self) + * call-seq: + * oradate.year = fixnum + * + * Sets the year (-4712..9999) for <i>oradate</i>. + */ +static VALUE ora_date_set_year(VALUE self, VALUE val) { - ora_date_t *od; - char buf[30]; - - Data_Get_Struct(self, ora_date_t, od); - sprintf(buf, "%04d/%02d/%02d %02d:%02d:%02d", Get_year(od), Get_month(od), - Get_day(od), Get_hour(od), Get_minute(od), Get_second(od)); - return rb_str_new2(buf); + ora_date_t *od; + int v; + + v = NUM2INT(val); + Check_year(v); + Data_Get_Struct(self, ora_date_t, od); + Set_year(od, v); + return self; } /* -=begin ---- OraDate#to_a() -=end -*/ -static VALUE ora_date_to_a(VALUE self) + * call-seq: + * oradate.month -> fixnum + * + * Returns the month of the year (1..12) for <i>oradate</i>. + */ +static VALUE ora_date_month(VALUE self) { - ora_date_t *od; - VALUE ary[6]; - - Data_Get_Struct(self, ora_date_t, od); - ary[0] = INT2FIX(Get_year(od)); - ary[1] = INT2FIX(Get_month(od)); - ary[2] = INT2FIX(Get_day(od)); - ary[3] = INT2FIX(Get_hour(od)); - ary[4] = INT2FIX(Get_minute(od)); - ary[5] = INT2FIX(Get_second(od)); - return rb_ary_new4(6, ary); + ora_date_t *od; + + Data_Get_Struct(self, ora_date_t, od); + return INT2FIX(Get_month(od)); } -#define DEFINE_GETTER_FUNC(where) \ -static VALUE ora_date_##where(VALUE self) \ -{ \ - ora_date_t *od; \ - \ - Data_Get_Struct(self, ora_date_t, od); \ - return INT2FIX(Get_##where(od)); \ +/* + * call-seq: + * oradate.month = fixnum + * + * Sets the month of the year (1..12) for <i>oradate</i>. + */ +static VALUE ora_date_set_month(VALUE self, VALUE val) +{ + ora_date_t *od; + int v; + + v = NUM2INT(val); + Check_month(v); + Data_Get_Struct(self, ora_date_t, od); + Set_month(od, v); + return self; } -#define DEFINE_SETTER_FUNC(where) \ -static VALUE ora_date_set_##where(VALUE self, VALUE val) \ -{ \ - ora_date_t *od; \ - int v; \ - \ - v = NUM2INT(val); \ - Check_##where(v); \ - Data_Get_Struct(self, ora_date_t, od); \ - Set_##where(od, v); \ - return self; \ +/* + * call-seq: + * oradate.day -> fixnum + * + * Returns the day of the month (1..31) for <i>oradate</i>. + */ +static VALUE ora_date_day(VALUE self) +{ + ora_date_t *od; + + Data_Get_Struct(self, ora_date_t, od); + return INT2FIX(Get_day(od)); } /* -=begin ---- OraDate#year -=end -*/ -DEFINE_GETTER_FUNC(year) -DEFINE_SETTER_FUNC(year) + * call-seq: + * oradate.day = fixnum + * + * Sets the day of the month (1..31) for <i>oradate</i>. + */ +static VALUE ora_date_set_day(VALUE self, VALUE val) +{ + ora_date_t *od; + int v; + v = NUM2INT(val); + Check_day(v); + Data_Get_Struct(self, ora_date_t, od); + Set_day(od, v); + return self; +} + /* -=begin ---- OraDate#month -=end -*/ -DEFINE_GETTER_FUNC(month) -DEFINE_SETTER_FUNC(month) + * call-seq: + * oradate.hour -> fixnum + * + * Returns the hour of the day (0..23) for <i>oradate</i>. + */ +static VALUE ora_date_hour(VALUE self) +{ + ora_date_t *od; + Data_Get_Struct(self, ora_date_t, od); + return INT2FIX(Get_hour(od)); +} + /* -=begin ---- OraDate#day -=end -*/ -DEFINE_GETTER_FUNC(day) -DEFINE_SETTER_FUNC(day) + * call-seq: + * oradate.hour = fixnum + * + * Sets the hour of the day (0..23) for <i>oradate</i>. + */ +static VALUE ora_date_set_hour(VALUE self, VALUE val) +{ + ora_date_t *od; + int v; + v = NUM2INT(val); + Check_hour(v); + Data_Get_Struct(self, ora_date_t, od); + Set_hour(od, v); + return self; +} + /* -=begin ---- OraDate#hour -=end -*/ -DEFINE_GETTER_FUNC(hour) -DEFINE_SETTER_FUNC(hour) + * call-seq: + * oradate.minute -> fixnum + * + * Returns the minute of the hour (0..59) for <i>oradate</i>. + */ +static VALUE ora_date_minute(VALUE self) +{ + ora_date_t *od; + Data_Get_Struct(self, ora_date_t, od); + return INT2FIX(Get_minute(od)); +} + /* -=begin ---- OraDate#minute -=end -*/ -DEFINE_GETTER_FUNC(minute) -DEFINE_SETTER_FUNC(minute) + * call-seq: + * oradate.minute = fixnum + * + * Sets the minute of the hour (0..59) for <i>oradate</i>. + */ +static VALUE ora_date_set_minute(VALUE self, VALUE val) +{ + ora_date_t *od; + int v; + v = NUM2INT(val); + Check_minute(v); + Data_Get_Struct(self, ora_date_t, od); + Set_minute(od, v); + return self; +} + /* -=begin ---- OraDate#second -=end -*/ -DEFINE_GETTER_FUNC(second) -DEFINE_SETTER_FUNC(second) + * call-seq: + * oradate.second -> fixnum + * + * Returns the second of the minute (0..59) for <i>oradate</i>. + */ +static VALUE ora_date_second(VALUE self) +{ + ora_date_t *od; + Data_Get_Struct(self, ora_date_t, od); + return INT2FIX(Get_second(od)); +} + /* -=begin ---- OraDate#trunc() -=end -*/ -static VALUE ora_date_trunc(VALUE self) + * call-seq: + * oradate.second = fixnum + * + * Sets the second of the minute (0..59) for <i>oradate</i>. + */ +static VALUE ora_date_set_second(VALUE self, VALUE val) { - ora_date_t *od; + ora_date_t *od; + int v; - Data_Get_Struct(self, ora_date_t, od); - od->hour = 1; - od->minute = 1; - od->second = 1; - return self; + v = NUM2INT(val); + Check_second(v); + Data_Get_Struct(self, ora_date_t, od); + Set_second(od, v); + return self; } -static VALUE ora_date_hash(VALUE self) +/* + * call-seq: + * oradate.trunc + * + * Truncates hour, minute and second to zero for <i>oradate</i>. + * + * oradate = OraDate.now # 2008/07/17 11:07:30 + * oradate.trunc # 2008/07/17 00:00:00 + */ +static VALUE ora_date_trunc(VALUE self) { - ora_date_t *od; - unsigned int v; + ora_date_t *od; - Data_Get_Struct(self, ora_date_t, od); - v = (od->century << 8) - + (od->year << 15) - + (od->month << 22) - + (od->day << 26) - + (od->hour << 12) - + (od->minute << 6) - + (od->second << 0); - return INT2FIX(v); + Data_Get_Struct(self, ora_date_t, od); + od->hour = 1; + od->minute = 1; + od->second = 1; + return self; } /* -=begin ---- OraDate#<=>(other) -=end -*/ + * call-seq: + * oradate1 <=> oradate2 -> -1, 0, +1 + * + * Comparison---Compares <i>oradate1</i> with <i>oradate2</i>. + * Other comparison operators are available because + * <code>Comparable</code> module is included. + */ static VALUE ora_date_cmp(VALUE self, VALUE val) { - ora_date_t *od1, *od2; - Data_Get_Struct(self, ora_date_t, od1); - Data_Get_Struct(val, ora_date_t, od2); - if (od1->century < od2->century) return INT2FIX(-1); - if (od1->century > od2->century) return INT2FIX(1); - if (od1->year < od2->year) return INT2FIX(-1); - if (od1->year > od2->year) return INT2FIX(1); - if (od1->month < od2->month) return INT2FIX(-1); - if (od1->month > od2->month) return INT2FIX(1); - if (od1->day < od2->day) return INT2FIX(-1); - if (od1->day > od2->day) return INT2FIX(1); - if (od1->hour < od2->hour) return INT2FIX(-1); - if (od1->hour > od2->hour) return INT2FIX(1); - if (od1->minute < od2->minute) return INT2FIX(-1); - if (od1->minute > od2->minute) return INT2FIX(1); - if (od1->second < od2->second) return INT2FIX(-1); - if (od1->second > od2->second) return INT2FIX(1); - return INT2FIX(0); + ora_date_t *od1, *od2; + Data_Get_Struct(self, ora_date_t, od1); + Check_Object(val, cOraDate); + Data_Get_Struct(val, ora_date_t, od2); + if (od1->century < od2->century) return INT2FIX(-1); + if (od1->century > od2->century) return INT2FIX(1); + if (od1->year < od2->year) return INT2FIX(-1); + if (od1->year > od2->year) return INT2FIX(1); + if (od1->month < od2->month) return INT2FIX(-1); + if (od1->month > od2->month) return INT2FIX(1); + if (od1->day < od2->day) return INT2FIX(-1); + if (od1->day > od2->day) return INT2FIX(1); + if (od1->hour < od2->hour) return INT2FIX(-1); + if (od1->hour > od2->hour) return INT2FIX(1); + if (od1->minute < od2->minute) return INT2FIX(-1); + if (od1->minute > od2->minute) return INT2FIX(1); + if (od1->second < od2->second) return INT2FIX(-1); + if (od1->second > od2->second) return INT2FIX(1); + return INT2FIX(0); } +/* :nodoc: */ +static VALUE ora_date_hash(VALUE self) +{ + ora_date_t *od; + unsigned int v; + + Data_Get_Struct(self, ora_date_t, od); + v = (od->century << 8) + + (od->year << 15) + + (od->month << 22) + + (od->day << 26) + + (od->hour << 12) + + (od->minute << 6) + + (od->second << 0); + return INT2FIX(v); +} + +/* + * call-seq: + * oradate._dump -> string + * + * Dumps <i>oradate</i> for marshaling. + */ static VALUE ora_date_dump(int argc, VALUE *argv, VALUE self) { - ora_date_t *od; - Data_Get_Struct(self, ora_date_t, od); - return rb_str_new((const char*)od, sizeof(ora_date_t)); -} + ora_date_t *od; + Data_Get_Struct(self, ora_date_t, od); + return rb_str_new((const char*)od, sizeof(ora_date_t)); /* ASCII-8BIT */ +} +/* + * call-seq: + * OraDate._load(string) -> oradate + * + * Unmarshals a dumped <code>OraDate</code> object. + */ static VALUE ora_date_s_load(VALUE klass, VALUE str) { - ora_date_t *od; - VALUE obj; + ora_date_t *od; + VALUE obj; - Check_Type(str, T_STRING); - if (RSTRING_LEN(str) != sizeof(ora_date_t)) { - rb_raise(rb_eTypeError, "marshaled OraDate format differ"); - } - obj = Data_Make_Struct(cOraDate, ora_date_t, NULL, xfree, od); - memcpy(od, RSTRING_PTR(str), sizeof(ora_date_t)); - return obj; -} + Check_Type(str, T_STRING); + if (RSTRING_LEN(str) != sizeof(ora_date_t)) { + rb_raise(rb_eTypeError, "marshaled OraDate format differ"); + } + obj = Data_Make_Struct(cOraDate, ora_date_t, NULL, xfree, od); + memcpy(od, RSTRING_PTR(str), sizeof(ora_date_t)); + return obj; +} -void Init_ora_date(void) +/* + * Document-class: OCI8::BindType::OraDate + * + * This is a helper class to bind OraDate as Oracle's <tt>DATE</tt> datatype. + * + */ +static VALUE bind_oradate_get(oci8_bind_t *obind, void *data, void *null_struct) { -#ifdef HAVE_RB_DEFINE_ALLOC_FUNC - /* ruby 1.8 */ - rb_define_alloc_func(cOraDate, RUBY_METHOD_FUNC(ora_date_s_allocate)); - rb_define_method(cOraDate, "initialize", ora_date_initialize, -1); - rb_define_method(cOraDate, "initialize_copy", ora_date_initialize_copy, 1); -#else - /* ruby 1.6 */ - rb_define_singleton_method(cOraDate, "new", ora_date_s_new, -1); - rb_define_method(cOraDate, "initialize", ora_date_initialize, -1); - rb_define_method(cOraDate, "clone", ora_date_clone, 0); - rb_define_method(cOraDate, "dup", ora_date_clone, 0); -#endif + ora_date_t *od; - rb_define_singleton_method(cOraDate, "now", ora_date_s_now, 0); - rb_define_method(cOraDate, "to_s", ora_date_to_s, 0); - rb_define_method(cOraDate, "to_a", ora_date_to_a, 0); + VALUE obj = Data_Make_Struct(cOraDate, ora_date_t, NULL, xfree, od); + memcpy(od, data, sizeof(ora_date_t)); + return obj; +} - rb_define_method(cOraDate, "year", ora_date_year, 0); - rb_define_method(cOraDate, "year=", ora_date_set_year, 1); +static void bind_oradate_set(oci8_bind_t *obind, void *data, void **null_structp, VALUE val) +{ + ora_date_t *od; - rb_define_method(cOraDate, "month", ora_date_month, 0); - rb_define_method(cOraDate, "month=", ora_date_set_month, 1); + Check_Object(val, cOraDate); + Data_Get_Struct(val, ora_date_t, od); + memcpy(data, od, sizeof(ora_date_t)); +} - rb_define_method(cOraDate, "day", ora_date_day, 0); - rb_define_method(cOraDate, "day=", ora_date_set_day, 1); +static void bind_oradate_init(oci8_bind_t *obind, VALUE svc, VALUE val, VALUE length) +{ + obind->value_sz = sizeof(ora_date_t); + obind->alloc_sz = sizeof(ora_date_t); +} - rb_define_method(cOraDate, "hour", ora_date_hour, 0); - rb_define_method(cOraDate, "hour=", ora_date_set_hour, 1); +static void bind_oradate_init_elem(oci8_bind_t *obind, VALUE svc) +{ + static const ora_date_t julian_day_0 = {100-47, 100-12, 1, 1, 1, 1, 1}; + ub4 idx = 0; + do { + memcpy((ora_date_t*)obind->valuep + idx, &julian_day_0, sizeof(ora_date_t)); + } while (++idx < obind->maxar_sz); +} - rb_define_method(cOraDate, "minute", ora_date_minute, 0); - rb_define_method(cOraDate, "minute=", ora_date_set_minute, 1); +static const oci8_bind_class_t bind_oradate_class = { + { + NULL, + oci8_bind_free, + sizeof(oci8_bind_t) + }, + bind_oradate_get, + bind_oradate_set, + bind_oradate_init, + bind_oradate_init_elem, + NULL, + NULL, + NULL, + SQLT_DAT, +}; - rb_define_method(cOraDate, "second", ora_date_second, 0); - rb_define_method(cOraDate, "second=", ora_date_set_second, 1); +void Init_ora_date(void) +{ + cOraDate = rb_define_class("OraDate", rb_cObject); - rb_define_method(cOraDate, "trunc", ora_date_trunc, 0); + rb_define_alloc_func(cOraDate, ora_date_s_allocate); + rb_define_method(cOraDate, "initialize", ora_date_initialize, -1); + rb_define_method(cOraDate, "initialize_copy", ora_date_initialize_copy, 1); + rb_define_singleton_method(cOraDate, "now", ora_date_s_now, 0); + rb_define_method(cOraDate, "to_s", ora_date_to_s, 0); + rb_define_method(cOraDate, "to_a", ora_date_to_a, 0); - rb_define_method(cOraDate, "<=>", ora_date_cmp, 1); - rb_include_module(cOraDate, rb_mComparable); + rb_define_method(cOraDate, "year", ora_date_year, 0); + rb_define_method(cOraDate, "year=", ora_date_set_year, 1); - rb_define_method(cOraDate, "hash", ora_date_hash, 0); + rb_define_method(cOraDate, "month", ora_date_month, 0); + rb_define_method(cOraDate, "month=", ora_date_set_month, 1); - rb_define_method(cOraDate, "_dump", ora_date_dump, -1); - rb_define_singleton_method(cOraDate, "_load", ora_date_s_load, 1); -} + rb_define_method(cOraDate, "day", ora_date_day, 0); + rb_define_method(cOraDate, "day=", ora_date_set_day, 1); -void oci8_set_ora_date(ora_date_t *od, int year, int month, int day, int hour, int minute, int second) -{ - Set_year(od, year); - Set_month(od, month); - Set_day(od, day); - Set_hour(od, hour); - Set_minute(od, minute); - Set_second(od, second); -} + rb_define_method(cOraDate, "hour", ora_date_hour, 0); + rb_define_method(cOraDate, "hour=", ora_date_set_hour, 1); -void oci8_get_ora_date(ora_date_t *od, int *year, int *month, int *day, int *hour, int *minute, int *second) -{ - *year = Get_year(od); - *month = Get_month(od); - *day = Get_day(od); - *hour = Get_hour(od); - *minute = Get_minute(od); - *second = Get_second(od); + rb_define_method(cOraDate, "minute", ora_date_minute, 0); + rb_define_method(cOraDate, "minute=", ora_date_set_minute, 1); + + rb_define_method(cOraDate, "second", ora_date_second, 0); + rb_define_method(cOraDate, "second=", ora_date_set_second, 1); + + rb_define_method(cOraDate, "trunc", ora_date_trunc, 0); + + rb_define_method(cOraDate, "<=>", ora_date_cmp, 1); + rb_include_module(cOraDate, rb_mComparable); + + rb_define_method(cOraDate, "hash", ora_date_hash, 0); + + rb_define_method(cOraDate, "_dump", ora_date_dump, -1); + rb_define_singleton_method(cOraDate, "_load", ora_date_s_load, 1); + + oci8_define_bind_class("OraDate", &bind_oradate_class); }