#include "swift.h" static VALUE mSwift; VALUE eSwiftError; VALUE eSwiftArgumentError; VALUE eSwiftRuntimeError; VALUE eSwiftConnectionError; VALUE swift_init(VALUE self, VALUE path) { try { dbi::dbiInitialize(CSTRING(path)); } CATCH_DBI_EXCEPTIONS(); return Qtrue; } VALUE swift_trace(int argc, VALUE *argv, VALUE self) { VALUE flag, io; rb_io_t *fptr; int fd = 2; // defaults to stderr rb_scan_args(argc, argv, "11", &flag, &io); if (TYPE(flag) != T_TRUE && TYPE(flag) != T_FALSE) rb_raise(eSwiftArgumentError, "Swift#trace expects a boolean flag, got %s", CSTRING(flag)); if (!NIL_P(io)) { GetOpenFile(rb_convert_type(io, T_FILE, "IO", "to_io"), fptr); fd = fptr->fd; } dbi::trace(flag == Qtrue ? true : false, fd); return flag; } VALUE atexit_gc(...) { rb_gc(); return Qnil; } void atexit_caller(VALUE data) { rb_proc_call(data, rb_ary_new()); } extern "C" { void Init_swift(void) { mSwift = rb_define_module("Swift"); eSwiftError = rb_define_class("SwiftError", CONST_GET(rb_mKernel, "StandardError")); eSwiftArgumentError = rb_define_class("SwiftArgumentError", eSwiftError); eSwiftRuntimeError = rb_define_class("SwiftRuntimeError", eSwiftError); eSwiftConnectionError = rb_define_class("SwiftConnectionError", eSwiftError); init_swift_adapter(); init_swift_attribute(); init_swift_pool(); init_swift_request(); init_swift_result(); init_swift_statement(); init_swift_query(); rb_define_module_function(mSwift, "init", RUBY_METHOD_FUNC(swift_init), 1); rb_define_module_function(mSwift, "trace", RUBY_METHOD_FUNC(swift_trace), -1); // NOTE // Swift adapter and statement objects need to be deallocated or garbage collected in the reverse // allocation order. rb_gc() does that but gc at exit time seems to do it in allocation order which // stuffs up dbic++ destructors. rb_set_end_proc(atexit_caller, rb_proc_new(atexit_gc, mSwift)); } }