swift 0.4.3 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/ext/pool.cc ADDED
@@ -0,0 +1,89 @@
1
+ #include "pool.h"
2
+
3
+ VALUE cSwiftPool;
4
+
5
+ static void pool_free(dbi::ConnectionPool *self) {
6
+ if (self) delete self;
7
+ }
8
+
9
+ VALUE pool_alloc(VALUE klass) {
10
+ dbi::ConnectionPool *pool = 0;
11
+ return Data_Wrap_Struct(klass, 0, pool_free, pool);
12
+ }
13
+
14
+ static dbi::ConnectionPool* pool_handle(VALUE self) {
15
+ dbi::ConnectionPool *pool;
16
+ Data_Get_Struct(self, dbi::ConnectionPool, pool);
17
+ if (!pool) rb_raise(eSwiftRuntimeError, "Invalid object, did you forget to call #super ?");
18
+ return pool;
19
+ }
20
+
21
+ // TODO: Remove unnecessary assignments. See Adapter.
22
+ VALUE pool_init(VALUE self, VALUE n, VALUE options) {
23
+ VALUE db = rb_hash_aref(options, ID2SYM(rb_intern("db")));
24
+ VALUE host = rb_hash_aref(options, ID2SYM(rb_intern("host")));
25
+ VALUE port = rb_hash_aref(options, ID2SYM(rb_intern("port")));
26
+ VALUE user = rb_hash_aref(options, ID2SYM(rb_intern("user")));
27
+ VALUE driver = rb_hash_aref(options, ID2SYM(rb_intern("driver")));
28
+ VALUE password = rb_hash_aref(options, ID2SYM(rb_intern("password")));
29
+ VALUE zone = rb_hash_aref(options, ID2SYM(rb_intern("timezone")));
30
+
31
+ if (NIL_P(db)) rb_raise(eSwiftArgumentError, "Pool#new called without :db");
32
+ if (NIL_P(driver)) rb_raise(eSwiftArgumentError, "#new called without :driver");
33
+
34
+ user = NIL_P(user) ? rb_str_new2(getlogin()) : user;
35
+ if (NUM2INT(n) < 1) rb_raise(eSwiftArgumentError, "Pool#new called with invalid pool size.");
36
+
37
+ try {
38
+ DATA_PTR(self) = new dbi::ConnectionPool(
39
+ NUM2INT(n),
40
+ CSTRING(driver),
41
+ CSTRING(user),
42
+ CSTRING(password),
43
+ CSTRING(db),
44
+ CSTRING(host),
45
+ CSTRING(port)
46
+ );
47
+ }
48
+ CATCH_DBI_EXCEPTIONS();
49
+ return Qnil;
50
+ }
51
+
52
+ void pool_callback(dbi::AbstractResultSet *result) {
53
+ VALUE callback = (VALUE)result->context;
54
+ // NOTE ResultSet will be free'd by the underlying connection pool dispatcher ib dbic++
55
+ if (!NIL_P(callback)) rb_proc_call(callback, rb_ary_new3(1, Data_Wrap_Struct(cSwiftResult, 0, 0, result)));
56
+ }
57
+
58
+ VALUE pool_execute(int argc, VALUE *argv, VALUE self) {
59
+ int n;
60
+ VALUE sql;
61
+ VALUE bind_values;
62
+ VALUE callback;
63
+ VALUE request = Qnil;
64
+
65
+ dbi::ConnectionPool *pool = pool_handle(self);
66
+ rb_scan_args(argc, argv, "1*&", &sql, &bind_values, &callback);
67
+
68
+ if (NIL_P(callback)) rb_raise(eSwiftArgumentError, "No block given in Pool#execute");
69
+
70
+ try {
71
+ Query query;
72
+ query_bind_values(&query, bind_values);
73
+ request = request_alloc(cSwiftRequest);
74
+ DATA_PTR(request) = pool->execute(CSTRING(sql), query.bind, pool_callback, (void*)callback);
75
+ return request;
76
+ }
77
+ CATCH_DBI_EXCEPTIONS();
78
+ }
79
+
80
+ void init_swift_pool() {
81
+ VALUE mSwift = rb_define_module("Swift");
82
+ VALUE mDB = rb_define_module_under(mSwift, "DB");
83
+ cSwiftPool = rb_define_class_under(mDB, "Pool", rb_cObject);
84
+
85
+ rb_define_alloc_func(cSwiftPool, pool_alloc);
86
+
87
+ rb_define_method(cSwiftPool, "initialize", RUBY_METHOD_FUNC(pool_init), 2);
88
+ rb_define_method(cSwiftPool, "execute", RUBY_METHOD_FUNC(pool_execute), -1);
89
+ }
data/ext/pool.h ADDED
@@ -0,0 +1,8 @@
1
+ #ifndef SWIFT_POOL_H
2
+ #define SWIFT_POOL_H
3
+
4
+ #include "swift.h"
5
+
6
+ void init_swift_pool();
7
+
8
+ #endif
data/ext/query.cc ADDED
@@ -0,0 +1,38 @@
1
+ #include "query.h"
2
+
3
+ VALUE query_execute(Query *query) {
4
+ return UINT2NUM(
5
+ query->bind.size() == 0
6
+ ? query->handle->conn()->execute(query->sql)
7
+ : query->handle->conn()->execute(query->sql, query->bind)
8
+ );
9
+ }
10
+
11
+ VALUE query_execute_statement(Query *query) {
12
+ return UINT2NUM(
13
+ query->bind.size() == 0
14
+ ? query->statement->execute()
15
+ : query->statement->execute(query->bind)
16
+ );
17
+ }
18
+
19
+ void query_bind_values(Query *query, VALUE bind_values) {
20
+ for (int i = 0; i < RARRAY_LEN(bind_values); i++) {
21
+ VALUE bind_value = rb_ary_entry(bind_values, i);
22
+
23
+ if (bind_value == Qnil) {
24
+ query->bind.push_back(dbi::PARAM(dbi::null()));
25
+ }
26
+ else if (rb_obj_is_kind_of(bind_value, rb_cIO) == Qtrue || rb_obj_is_kind_of(bind_value, cStringIO) == Qtrue) {
27
+ bind_value = rb_funcall(bind_value, rb_intern("read"), 0);
28
+ query->bind.push_back(dbi::PARAM_BINARY((unsigned char*)RSTRING_PTR(bind_value), RSTRING_LEN(bind_value)));
29
+ }
30
+ else {
31
+ bind_value = TO_S(bind_value);
32
+ if (strcmp(rb_enc_get(bind_value)->name, "UTF-8") != 0)
33
+ bind_value = rb_str_encode(bind_value, rb_str_new2("UTF-8"), 0, Qnil);
34
+ query->bind.push_back(dbi::PARAM((unsigned char*)RSTRING_PTR(bind_value), RSTRING_LEN(bind_value)));
35
+ }
36
+ }
37
+ }
38
+
data/ext/query.h ADDED
@@ -0,0 +1,17 @@
1
+ #ifndef SWIFT_QUERY_H
2
+ #define SWIFT_QUERY_H
3
+
4
+ #include "swift.h"
5
+
6
+ struct Query {
7
+ char *sql;
8
+ dbi::Handle *handle;
9
+ dbi::AbstractStatement *statement;
10
+ dbi::ResultRow bind;
11
+ };
12
+
13
+ VALUE query_execute(Query*);
14
+ VALUE query_execute_statement(Query*);
15
+ void query_bind_values(Query*, VALUE);
16
+
17
+ #endif
data/ext/request.cc ADDED
@@ -0,0 +1,44 @@
1
+ #include "request.h"
2
+
3
+ VALUE cSwiftRequest;
4
+
5
+ static void request_free(dbi::Request *request) {
6
+ if(request) delete request;
7
+ }
8
+
9
+ VALUE request_alloc(VALUE klass) {
10
+ dbi::Request *request = 0;
11
+ return Data_Wrap_Struct(klass, 0, request_free, request);
12
+ }
13
+
14
+ static dbi::Request* request_handle(VALUE self) {
15
+ dbi::Request *request;
16
+ Data_Get_Struct(self, dbi::Request, request);
17
+ if (!request) rb_raise(eSwiftRuntimeError, "Invalid object, did you forget to call #super ?");
18
+ return request;
19
+ }
20
+
21
+ VALUE request_socket(VALUE self) {
22
+ dbi::Request *request = request_handle(self);
23
+ try {
24
+ return INT2NUM(request->socket());
25
+ }
26
+ CATCH_DBI_EXCEPTIONS();
27
+ }
28
+
29
+ VALUE request_process(VALUE self) {
30
+ dbi::Request *request = request_handle(self);
31
+ try {
32
+ return request->process() ? Qtrue : Qfalse;
33
+ }
34
+ CATCH_DBI_EXCEPTIONS();
35
+ }
36
+
37
+ void init_swift_request() {
38
+ VALUE mSwift = rb_define_module("Swift");
39
+ cSwiftRequest = rb_define_class_under(mSwift, "Request", rb_cObject);
40
+
41
+ rb_define_alloc_func(cSwiftRequest, request_alloc);
42
+ rb_define_method(cSwiftRequest, "socket", RUBY_METHOD_FUNC(request_socket), 0);
43
+ rb_define_method(cSwiftRequest, "process", RUBY_METHOD_FUNC(request_process), 0);
44
+ }
data/ext/request.h ADDED
@@ -0,0 +1,10 @@
1
+ #ifndef SWIFT_REQUEST_H
2
+ #define SWIFT_REQUEST_H
3
+
4
+ #include "swift.h"
5
+
6
+ extern VALUE cSwiftRequest;
7
+ VALUE request_alloc(VALUE klass);
8
+ void init_swift_request();
9
+
10
+ #endif
data/ext/result.cc ADDED
@@ -0,0 +1,246 @@
1
+ #include "result.h"
2
+
3
+ VALUE cSwiftResult;
4
+ VALUE cDateTime;
5
+ VALUE cStringIO;
6
+ VALUE cBigDecimal;
7
+
8
+ VALUE fNew, fNewBang;
9
+
10
+ uint64_t epoch_ajd_n, epoch_ajd_d;
11
+ VALUE daysecs, sg;
12
+
13
+ void result_free(dbi::AbstractResultSet *result) {
14
+ if (result) {
15
+ result->cleanup();
16
+ delete result;
17
+ }
18
+ }
19
+
20
+ VALUE result_alloc(VALUE klass) {
21
+ dbi::AbstractResultSet *result = 0;
22
+ return Data_Wrap_Struct(klass, 0, result_free, result);
23
+ }
24
+
25
+ // TODO:
26
+ static VALUE result_clone(VALUE self) {
27
+ rb_raise(eSwiftRuntimeError, "clone is not allowed.");
28
+ }
29
+
30
+ // TODO:
31
+ static VALUE result_dup(VALUE self) {
32
+ rb_raise(eSwiftRuntimeError, "dup is not allowed.");
33
+ }
34
+
35
+ VALUE result_each(VALUE self) {
36
+ uint64_t length;
37
+ const char *data;
38
+
39
+ dbi::AbstractResultSet *result = result_handle(self);
40
+ VALUE scheme = rb_iv_get(self, "@scheme");
41
+
42
+ try {
43
+ VALUE fields = rb_ary_new();
44
+ std::vector<string> result_fields = result->fields();
45
+ std::vector<int> result_types = result->types();
46
+ for (uint32_t i = 0; i < result_fields.size(); i++) {
47
+ rb_ary_push(fields, ID2SYM(rb_intern(result_fields[i].c_str())));
48
+ }
49
+
50
+ result->seek(0);
51
+ for (uint32_t row = 0; row < result->rows(); row++) {
52
+ VALUE tuple = rb_hash_new();
53
+ for (uint32_t column = 0; column < result->columns(); column++) {
54
+ data = (const char*)result->read(row, column, &length);
55
+ if (data) {
56
+ rb_hash_aset(
57
+ tuple,
58
+ rb_ary_entry(fields, column),
59
+ typecast_field(result_types[column], data, length)
60
+ );
61
+ }
62
+ else {
63
+ rb_hash_aset(tuple, rb_ary_entry(fields, column), Qnil);
64
+ }
65
+ } // column loop
66
+ NIL_P(scheme) ? rb_yield(tuple) : rb_yield(rb_funcall(scheme, rb_intern("load"), 1, tuple));
67
+ } // row loop
68
+ }
69
+ CATCH_DBI_EXCEPTIONS();
70
+
71
+ return Qnil;
72
+ }
73
+
74
+ dbi::AbstractResultSet* result_handle(VALUE self) {
75
+ dbi::AbstractResultSet *result;
76
+ Data_Get_Struct(self, dbi::AbstractResultSet, result);
77
+ if (!result) rb_raise(eSwiftRuntimeError, "Invalid object, did you forget to call #super?");
78
+
79
+ return result;
80
+ }
81
+
82
+ static VALUE result_finish(VALUE self) {
83
+ dbi::AbstractResultSet *result = result_handle(self);
84
+ try {
85
+ result->finish();
86
+ }
87
+ CATCH_DBI_EXCEPTIONS();
88
+ }
89
+
90
+ // Calculates local offset at a given time, including dst.
91
+ size_t client_tzoffset(uint64_t local, int isdst) {
92
+ struct tm tm;
93
+ gmtime_r((const time_t*)&local, &tm);
94
+ return local + (isdst ? 3600 : 0) - mktime(&tm);
95
+ }
96
+
97
+ // pinched from do_postgres
98
+ static void reduce(uint64_t *numerator, uint64_t *denominator) {
99
+ uint64_t a, b, c;
100
+ a = *numerator;
101
+ b = *denominator;
102
+ while (a) {
103
+ c = a; a = b % a; b = c;
104
+ }
105
+ *numerator = *numerator / b;
106
+ *denominator = *denominator / b;
107
+ }
108
+
109
+ VALUE typecast_datetime(const char *data, uint64_t len) {
110
+ struct tm tm;
111
+ uint64_t epoch, adjust, offset;
112
+
113
+ double usec = 0;
114
+ char tzsign = 0;
115
+ int tzhour = 0, tzmin = 0;
116
+
117
+ memset(&tm, 0, sizeof(struct tm));
118
+ if (strchr(data, '.')) {
119
+ sscanf(data, "%04d-%02d-%02d %02d:%02d:%02d%lf%c%02d:%02d",
120
+ &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec,
121
+ &usec, &tzsign, &tzhour, &tzmin);
122
+ }
123
+ else {
124
+ sscanf(data, "%04d-%02d-%02d %02d:%02d:%02d%c%02d:%02d",
125
+ &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec,
126
+ &tzsign, &tzhour, &tzmin);
127
+ }
128
+
129
+ tm.tm_year -= 1900;
130
+ tm.tm_mon -= 1;
131
+ tm.tm_isdst = -1;
132
+ if (tm.tm_mday > 0) {
133
+ epoch = mktime(&tm);
134
+ adjust = client_tzoffset(epoch, tm.tm_isdst);
135
+ offset = adjust;
136
+
137
+ if (tzsign == '+' || tzsign == '-') {
138
+ offset = tzsign == '+'
139
+ ? (time_t)tzhour * 3600 + (time_t)tzmin * 60
140
+ : (time_t)tzhour * -3600 + (time_t)tzmin * -60;
141
+ }
142
+
143
+ // 32bit platforms are for weenies
144
+ uint64_t ajd_n = (epoch + adjust - offset), ajd_d = 86400L;
145
+ reduce(&ajd_n, &ajd_d);
146
+ ajd_n = epoch_ajd_n*ajd_d + ajd_n*epoch_ajd_d;
147
+ ajd_d = epoch_ajd_d*ajd_d;
148
+ reduce(&ajd_n, &ajd_d);
149
+
150
+ VALUE ajd = rb_rational_new(SIZET2NUM(ajd_n), SIZET2NUM(ajd_d));
151
+ return rb_funcall(cDateTime, fNewBang, 3, ajd, rb_rational_new(INT2FIX(offset), daysecs), sg);
152
+ }
153
+
154
+ // TODO: throw a warning ?
155
+ return rb_str_new(data, len);
156
+ }
157
+
158
+ VALUE typecast_field(int type, const char *data, uint64_t length) {
159
+ switch(type) {
160
+ case DBI_TYPE_BOOLEAN:
161
+ return strcmp(data, "t") == 0 || strcmp(data, "1") == 0 ? Qtrue : Qfalse;
162
+ case DBI_TYPE_INT:
163
+ return rb_cstr2inum(data, 10);
164
+ case DBI_TYPE_BLOB:
165
+ return rb_funcall(cStringIO, fNew, 1, rb_str_new(data, length));
166
+ case DBI_TYPE_TEXT:
167
+ return rb_enc_str_new(data, length, rb_utf8_encoding());
168
+ case DBI_TYPE_TIME:
169
+ return typecast_datetime(data, length);
170
+ case DBI_TYPE_NUMERIC:
171
+ return rb_funcall(cBigDecimal, fNew, 1, rb_str_new2(data));
172
+ case DBI_TYPE_FLOAT:
173
+ return rb_float_new(atof(data));
174
+ }
175
+ }
176
+
177
+ VALUE result_insert_id(VALUE self) {
178
+ dbi::AbstractResultSet *result = result_handle(self);
179
+ try {
180
+ return SIZET2NUM(result->lastInsertID());
181
+ }
182
+ CATCH_DBI_EXCEPTIONS();
183
+ return Qnil;
184
+ }
185
+
186
+ VALUE result_rows(VALUE self) {
187
+ dbi::AbstractResultSet *result = result_handle(self);
188
+ try {
189
+ return SIZET2NUM(result->rows());
190
+ }
191
+ CATCH_DBI_EXCEPTIONS();
192
+ }
193
+
194
+ VALUE result_columns(VALUE self) {
195
+ dbi::AbstractResultSet *result = result_handle(self);
196
+ try {
197
+ return SIZET2NUM(result->columns());
198
+ }
199
+ CATCH_DBI_EXCEPTIONS();
200
+ }
201
+
202
+ VALUE result_fields(VALUE self) {
203
+ dbi::AbstractResultSet *result = result_handle(self);
204
+ try {
205
+ std::vector<string> result_fields = result->fields();
206
+ VALUE fields = rb_ary_new();
207
+ for (int i = 0; i < result_fields.size(); i++)
208
+ rb_ary_push(fields, rb_str_new2(result_fields[i].c_str()));
209
+ return fields;
210
+ }
211
+ CATCH_DBI_EXCEPTIONS();
212
+ }
213
+
214
+ void init_swift_result() {
215
+ rb_require("bigdecimal");
216
+ rb_require("stringio");
217
+ rb_require("date");
218
+
219
+ VALUE mSwift = rb_define_module("Swift");
220
+ cSwiftResult = rb_define_class_under(mSwift, "Result", rb_cObject);
221
+ cDateTime = CONST_GET(rb_mKernel, "DateTime");
222
+ cStringIO = CONST_GET(rb_mKernel, "StringIO");
223
+ cBigDecimal = CONST_GET(rb_mKernel, "BigDecimal");
224
+
225
+ fNew = rb_intern("new");
226
+ fNewBang = rb_intern("new!");
227
+
228
+ rb_define_alloc_func(cSwiftResult, result_alloc);
229
+ rb_include_module(cSwiftResult, CONST_GET(rb_mKernel, "Enumerable"));
230
+
231
+ rb_define_method(cSwiftResult, "clone", RUBY_METHOD_FUNC(result_clone), 0);
232
+ rb_define_method(cSwiftResult, "dup", RUBY_METHOD_FUNC(result_dup), 0);
233
+ rb_define_method(cSwiftResult, "each", RUBY_METHOD_FUNC(result_each), 0);
234
+ rb_define_method(cSwiftResult, "finish", RUBY_METHOD_FUNC(result_finish), 0);
235
+ rb_define_method(cSwiftResult, "insert_id", RUBY_METHOD_FUNC(result_insert_id), 0);
236
+ rb_define_method(cSwiftResult, "rows", RUBY_METHOD_FUNC(result_rows), 0);
237
+ rb_define_method(cSwiftResult, "columns", RUBY_METHOD_FUNC(result_columns), 0);
238
+ rb_define_method(cSwiftResult, "fields", RUBY_METHOD_FUNC(result_fields), 0);
239
+
240
+ // typecast_datetime setup.
241
+ epoch_ajd_d = 2;
242
+ epoch_ajd_n = 4881175L; // 1970-01-01 00:00:00 is 2440587.5 in ajd
243
+ daysecs = SIZET2NUM(86400L);
244
+ sg = SIZET2NUM(2299161L); // day of calendar reform Date::ITALY
245
+ }
246
+
data/ext/result.h ADDED
@@ -0,0 +1,17 @@
1
+ #ifndef SWIFT_RESULT_H
2
+ #define SWIFT_RESULT_H
3
+
4
+ #include "swift.h"
5
+
6
+ extern VALUE cSwiftResult;
7
+ extern VALUE cStringIO;
8
+
9
+ void init_swift_result();
10
+ void result_free(dbi::AbstractResultSet*);
11
+ VALUE result_each(VALUE);
12
+ dbi::AbstractResultSet* result_handle(VALUE);
13
+
14
+ VALUE typecast_field(int, const char*, uint64_t);
15
+ VALUE typecast_datetime(const char*, uint64_t);
16
+
17
+ #endif
data/ext/statement.cc ADDED
@@ -0,0 +1,87 @@
1
+ #include "statement.h"
2
+ #include "adapter.h"
3
+ #include "result.h"
4
+ #include "query.h"
5
+
6
+ VALUE cSwiftStatement;
7
+
8
+ void statement_free(dbi::AbstractStatement *statement) {
9
+ if (statement) {
10
+ statement->cleanup();
11
+ delete statement;
12
+ }
13
+ }
14
+
15
+ VALUE statement_alloc(VALUE klass) {
16
+ dbi::AbstractStatement *statement = 0;
17
+ return Data_Wrap_Struct(klass, 0, statement_free, statement);
18
+ }
19
+
20
+ dbi::AbstractStatement* statement_handle(VALUE self) {
21
+ dbi::AbstractStatement *handle;
22
+ Data_Get_Struct(self, dbi::AbstractStatement, handle);
23
+ if (!handle) rb_raise(eSwiftRuntimeError, "Invalid object, did you forget to call #super?");
24
+
25
+ return handle;
26
+ }
27
+
28
+ // TODO: Change bind_values to an array in the interface? Avoid array -> splat -> array.
29
+ static VALUE statement_execute(int argc, VALUE *argv, VALUE self) {
30
+ VALUE bind_values, block;
31
+ rb_scan_args(argc, argv, "0*&", &bind_values, &block);
32
+
33
+ dbi::AbstractStatement *statement = (dbi::AbstractStatement*)statement_handle(self);
34
+ try {
35
+ Query query;
36
+ query.statement = statement;
37
+ if (RARRAY_LEN(bind_values) > 0) query_bind_values(&query, bind_values);
38
+ if (dbi::_trace) dbi::logMessage(dbi::_trace_fd, dbi::formatParams(statement->command(), query.bind));
39
+
40
+ // TODO: http://redmine.ruby-lang.org/issues/show/3762
41
+ // rb_thread_blocking_region and C++ exceptions don't mix in 1.9.2.
42
+ // rb_thread_blocking_region(((VALUE (*)(void*))query_execute_statement), &query, RUBY_UBF_IO, 0);
43
+ query_execute_statement(&query);
44
+ }
45
+ CATCH_DBI_EXCEPTIONS();
46
+
47
+ if (rb_block_given_p()) return result_each(self);
48
+ return self;
49
+ }
50
+
51
+ VALUE statement_initialize(VALUE self, VALUE adapter, VALUE sql) {
52
+ dbi::Handle *handle = adapter_handle(adapter);
53
+
54
+ if (NIL_P(adapter)) rb_raise(eSwiftArgumentError, "Statement#new called without an Adapter instance.");
55
+ if (NIL_P(sql)) rb_raise(eSwiftArgumentError, "Statement#new called without a command.");
56
+
57
+ try {
58
+ DATA_PTR(self) = handle->conn()->prepare(CSTRING(sql));
59
+ }
60
+ CATCH_DBI_EXCEPTIONS();
61
+
62
+ return Qnil;
63
+ }
64
+
65
+ void init_swift_statement() {
66
+ VALUE mSwift = rb_define_module("Swift");
67
+
68
+ /*
69
+ TODO Inheritance confusion.
70
+
71
+ dbic++ has this,
72
+ dbi::Statement < dbi::AbstractStatement
73
+ dbi::AbstractStatement < dbi::AbstractResult
74
+
75
+ Swift has this,
76
+ Statement < Result
77
+
78
+ Not sure if this hierarchy is correct or perfect. I reckon Statement should not
79
+ inherit Result and just return a Result on execute() - maybe cleaner but very
80
+ inefficient when doing tons on non-select style queries.
81
+ */
82
+
83
+ cSwiftStatement = rb_define_class_under(mSwift, "Statement", cSwiftResult);
84
+ rb_define_method(cSwiftStatement, "execute", RUBY_METHOD_FUNC(statement_execute), -1);
85
+ rb_define_method(cSwiftStatement, "initialize", RUBY_METHOD_FUNC(statement_initialize), 2);
86
+ rb_define_alloc_func(cSwiftStatement, statement_alloc);
87
+ }
data/ext/statement.h ADDED
@@ -0,0 +1,12 @@
1
+ #ifndef SWIFT_STATEMENT_H
2
+ #define SWIFT_STATEMENT_H
3
+
4
+ #include "swift.h"
5
+
6
+ extern VALUE cSwiftStatement;
7
+
8
+ void init_swift_statement();
9
+ void statement_free(dbi::AbstractStatement*);
10
+
11
+ #endif
12
+