ext/statement.cc in swift-0.6.1 vs ext/statement.cc in swift-0.7.0
- old
+ new
@@ -3,28 +3,49 @@
#include "result.h"
#include "query.h"
VALUE cSwiftStatement;
-void statement_free(dbi::AbstractStatement *statement) {
- if (statement) {
- statement->cleanup();
- delete statement;
+void statement_mark(StatementWrapper *handle) {
+ if (handle)
+ rb_gc_mark(handle->adapter);
+}
+
+void statement_free(StatementWrapper *handle) {
+ if (handle) {
+ if (handle->free) {
+ handle->statement->cleanup();
+ delete handle->statement;
+ }
+ delete handle;
}
}
VALUE statement_alloc(VALUE klass) {
- dbi::AbstractStatement *statement = 0;
- return Data_Wrap_Struct(klass, 0, statement_free, statement);
+ StatementWrapper *handle = 0;
+ return Data_Wrap_Struct(klass, statement_mark, statement_free, handle);
}
+VALUE statement_wrap_handle(VALUE klass, VALUE adapter, dbi::AbstractStatement *statement) {
+ StatementWrapper *handle = new StatementWrapper;
+ handle->statement = statement;
+ handle->adapter = adapter;
+ handle->free = true;
+
+ VALUE obj = Data_Wrap_Struct(klass, statement_mark, statement_free, handle);
+ if (!NIL_P(adapter))
+ rb_iv_set(obj, "@timezone", rb_iv_get(adapter, "@timezone"));
+
+ return obj;
+}
+
dbi::AbstractStatement* statement_handle(VALUE self) {
- dbi::AbstractStatement *handle;
- Data_Get_Struct(self, dbi::AbstractStatement, handle);
+ StatementWrapper *handle;
+ Data_Get_Struct(self, StatementWrapper, handle);
if (!handle) rb_raise(eSwiftRuntimeError, "Invalid object, did you forget to call #super?");
- return handle;
+ return handle->statement;
}
// TODO: Change bind_values to an array in the interface? Avoid array -> splat -> array.
static VALUE statement_execute(int argc, VALUE *argv, VALUE self) {
VALUE bind_values, block;
@@ -32,11 +53,11 @@
dbi::AbstractStatement *statement = (dbi::AbstractStatement*)statement_handle(self);
try {
Query query;
query.statement = statement;
- if (RARRAY_LEN(bind_values) > 0) query_bind_values(&query, bind_values);
+ if (RARRAY_LEN(bind_values) > 0) query_bind_values(&query, bind_values, statement->driver());
if (dbi::_trace) dbi::logMessage(dbi::_trace_fd, dbi::formatParams(statement->command(), query.bind));
if (rb_thread_blocking_region(((VALUE (*)(void*))query_execute_statement), &query, RUBY_UBF_IO, 0) == Qfalse)
rb_raise(eSwiftRuntimeError, "%s", query.error);
}
@@ -51,10 +72,16 @@
if (NIL_P(adapter)) rb_raise(eSwiftArgumentError, "Statement#new called without an Adapter instance.");
if (NIL_P(sql)) rb_raise(eSwiftArgumentError, "Statement#new called without a command.");
try {
- DATA_PTR(self) = handle->conn()->prepare(CSTRING(sql));
+ // needs to happen before wrapping in case it raises errors.
+ dbi::AbstractStatement *statement = handle->conn()->prepare(CSTRING(sql));
+ StatementWrapper *statement_handle = new StatementWrapper;
+ statement_handle->statement = statement;
+ statement_handle->adapter = adapter;
+ statement_handle->free = true;
+ DATA_PTR(self) = statement_handle;
}
CATCH_DBI_EXCEPTIONS();
return Qnil;
}