swift 0.14.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/API.rdoc +14 -14
  2. data/README.md +110 -61
  3. data/Rakefile +2 -5
  4. data/VERSION +1 -1
  5. data/lib/swift/adapter/mysql.rb +30 -0
  6. data/lib/swift/adapter/postgres.rb +27 -0
  7. data/lib/swift/adapter/sql.rb +23 -29
  8. data/lib/swift/adapter/sqlite3.rb +59 -0
  9. data/lib/swift/adapter.rb +129 -70
  10. data/lib/swift/attribute.rb +19 -8
  11. data/lib/swift/eventmachine.rb +49 -0
  12. data/lib/swift/identity_map.rb +7 -7
  13. data/lib/swift/migrations.rb +12 -12
  14. data/lib/swift/{scheme.rb → record.rb} +16 -17
  15. data/lib/swift/result.rb +24 -0
  16. data/lib/swift/statement.rb +25 -0
  17. data/lib/swift/synchrony.rb +38 -0
  18. data/lib/swift/validations.rb +2 -2
  19. data/lib/swift.rb +8 -6
  20. data/swift.gemspec +19 -31
  21. data/test/helper.rb +11 -6
  22. data/test/test_adapter.rb +11 -25
  23. data/test/test_async.rb +9 -12
  24. data/test/test_encoding.rb +2 -2
  25. data/test/test_error.rb +8 -8
  26. data/test/test_io.rb +2 -2
  27. data/test/{test_scheme.rb → test_record.rb} +6 -6
  28. data/test/test_swift.rb +9 -51
  29. data/test/test_timestamps.rb +1 -1
  30. data/test/test_transactions.rb +2 -2
  31. data/test/test_types.rb +3 -3
  32. data/test/test_validations.rb +2 -2
  33. metadata +20 -27
  34. data/ext/adapter.cc +0 -479
  35. data/ext/adapter.h +0 -13
  36. data/ext/adapter_io.cc +0 -62
  37. data/ext/adapter_io.h +0 -24
  38. data/ext/attribute.cc +0 -22
  39. data/ext/attribute.h +0 -8
  40. data/ext/datetime.cc +0 -96
  41. data/ext/datetime.h +0 -12
  42. data/ext/extconf.rb +0 -61
  43. data/ext/query.cc +0 -104
  44. data/ext/query.h +0 -20
  45. data/ext/result.cc +0 -229
  46. data/ext/result.h +0 -27
  47. data/ext/statement.cc +0 -116
  48. data/ext/statement.h +0 -22
  49. data/ext/swift.cc +0 -114
  50. data/ext/swift.h +0 -60
  51. data/lib/swift/db.rb +0 -89
data/ext/attribute.h DELETED
@@ -1,8 +0,0 @@
1
- #ifndef SWIFT_ATTRIBUTE_H
2
- #define SWIFT_ATTRIBUTE_H
3
-
4
- #include "swift.h"
5
-
6
- void init_swift_attribute();
7
-
8
- #endif
data/ext/datetime.cc DELETED
@@ -1,96 +0,0 @@
1
- #include "datetime.h"
2
-
3
- extern VALUE dtformat;
4
-
5
- VALUE cSwiftDateTime, day_seconds;
6
- ID fcivil, fparse, fstrptime;
7
-
8
- // NOTE: only parses '%F %T.%N %z' format and falls back to the built-in DateTime#parse
9
- // and is almost 2x faster than doing:
10
- //
11
- // rb_funcall(klass, fstrptime, 2, rb_str_new(data, size), dtformat);
12
- //
13
- VALUE datetime_parse(VALUE klass, const char *data, uint64_t size) {
14
- struct tm tm;
15
- double seconds;
16
- const char *ptr;
17
- char tzsign = 0, fraction[32];
18
- int tzhour = 0, tzmin = 0, lastmatch = -1, offset = 0, idx;
19
-
20
- memset(&tm, 0, sizeof(struct tm));
21
- sscanf(data, "%04d-%02d-%02d %02d:%02d:%02d%n",
22
- &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec, &lastmatch);
23
-
24
- // fallback to default datetime parser, this is more expensive.
25
- if (tm.tm_mday == 0)
26
- return Qnil;
27
-
28
- seconds = tm.tm_sec;
29
-
30
- // parse millisecs if any -- tad faster than using %lf in sscanf above.
31
- if (lastmatch > 0 && lastmatch < size && *(data + lastmatch) == '.') {
32
- idx = 0;
33
- ptr = data + ++lastmatch;
34
- while (*ptr && isdigit(*ptr) && idx < 31) {
35
- lastmatch++;
36
- fraction[idx++] = *ptr++;
37
- }
38
-
39
- fraction[idx] = 0;
40
- seconds += (double)atoll(fraction) / pow(10, idx);
41
- }
42
-
43
- // parse timezone offsets if any - matches +HH:MM +HH MM +HHMM
44
- if (lastmatch > 0 && lastmatch < size) {
45
- const char *ptr = data + lastmatch;
46
- while(*ptr && *ptr != '+' && *ptr != '-') ptr++;
47
- tzsign = *ptr++;
48
- if (*ptr && isdigit(*ptr)) {
49
- tzhour = *ptr++ - '0';
50
- if (*ptr && isdigit(*ptr)) tzhour = tzhour * 10 + *ptr++ - '0';
51
- while(*ptr && !isdigit(*ptr)) ptr++;
52
- if (*ptr) {
53
- tzmin = *ptr++ - '0';
54
- if (*ptr && isdigit(*ptr)) tzmin = tzmin * 10 + *ptr++ - '0';
55
- }
56
- }
57
- }
58
-
59
- if (tzsign) {
60
- offset = tzsign == '+'
61
- ? (time_t)tzhour * 3600 + (time_t)tzmin * 60
62
- : (time_t)tzhour * -3600 + (time_t)tzmin * -60;
63
- }
64
-
65
- return rb_funcall(klass, fcivil, 7,
66
- INT2FIX(tm.tm_year), INT2FIX(tm.tm_mon), INT2FIX(tm.tm_mday),
67
- INT2FIX(tm.tm_hour), INT2FIX(tm.tm_min), DBL2NUM(seconds),
68
- offset == 0 ? INT2FIX(0) : rb_Rational(INT2FIX(offset), day_seconds)
69
- );
70
- }
71
-
72
- VALUE rb_datetime_parse(VALUE self, VALUE string) {
73
- const char *data = CSTRING(string);
74
- int size = TYPE(string) == T_STRING ? RSTRING_LEN(string) : strlen(data);
75
-
76
- if (NIL_P(string))
77
- return Qnil;
78
-
79
- VALUE datetime = datetime_parse(self, data, size);
80
- return NIL_P(datetime) ? rb_call_super(1, &string) : datetime;
81
- }
82
-
83
- void init_swift_datetime() {
84
- rb_require("date");
85
-
86
- VALUE mSwift = rb_define_module("Swift");
87
- VALUE cDateTime = CONST_GET(rb_mKernel, "DateTime");
88
- cSwiftDateTime = rb_define_class_under(mSwift, "DateTime", cDateTime);
89
- fcivil = rb_intern("civil");
90
- fparse = rb_intern("parse");
91
- fstrptime = rb_intern("strptime");
92
- day_seconds = INT2FIX(86400);
93
-
94
- rb_global_variable(&day_seconds);
95
- rb_define_singleton_method(cSwiftDateTime, "parse", RUBY_METHOD_FUNC(rb_datetime_parse), 1);
96
- }
data/ext/datetime.h DELETED
@@ -1,12 +0,0 @@
1
- #ifndef SWIFT_DATETIME_H
2
- #define SWIFT_DATETIME_H
3
-
4
- #include "swift.h"
5
- #include <math.h>
6
-
7
- void init_swift_datetime();
8
- VALUE datetime_parse(VALUE klass, const char *data, uint64_t size);
9
-
10
- extern VALUE cSwiftDateTime;
11
-
12
- #endif
data/ext/extconf.rb DELETED
@@ -1,61 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require 'mkmf'
3
-
4
- ConfigClass = defined?(RbConfig) ? RbConfig : Config
5
-
6
- ConfigClass::CONFIG['CC'] = 'g++'
7
- ConfigClass::CONFIG['CPP'] = 'g++'
8
-
9
- $CFLAGS = '-fPIC -Os -I/usr/include -I/opt/local/include -I/usr/local/include'
10
-
11
- def apt_install_hint pkg
12
- "sudo apt-get install #{pkg}"
13
- end
14
-
15
- def library_installed? name, hint
16
- if find_library(name, 'main', *%w(/usr/lib /usr/local/lib /opt/lib /opt/local/lib /sw/lib))
17
- true
18
- else
19
- $stderr.puts <<-ERROR
20
-
21
- Unable to find required library: #{name}.
22
- On debian systems, it can be installed as,
23
-
24
- #{hint}
25
-
26
- You may have to add the following ppa to your sources,
27
-
28
- sudo add-apt-repository ppa:deepfryed
29
-
30
- to install dbic++-dev and associated drivers dbic++-mysql or dbic++-pg
31
-
32
- ERROR
33
- false
34
- end
35
- end
36
-
37
- def assert_dbicpp_version ver
38
- passed = false
39
- header = '/usr/include/dbic++.h'
40
- message = "Swift needs dbic++ >= #{ver}. Please update your dbic++ installation."
41
-
42
- if File.exists?(header) && match = File.read(header).match(/DBI_VERSION\s+(.*?)\n/mi)
43
- rmajor, rminor, rbuild = ver.strip.split(/\./).map(&:to_i)
44
- imajor, iminor, ibuild = match.captures.first.strip.split(/\./).map(&:to_i)
45
- passed = (imajor > rmajor) ||
46
- (imajor == rmajor && iminor > rminor) ||
47
- (imajor == rmajor && iminor == rminor && ibuild >= rbuild)
48
- else
49
- message = "Cannot find #{header} or version number. You need to install dbic++ >= #{ver}"
50
- passed = false
51
- end
52
-
53
- raise message unless passed
54
- end
55
-
56
- exit 1 unless library_installed? 'pcrecpp', apt_install_hint('libpcre3-dev')
57
- exit 1 unless library_installed? 'uuid', apt_install_hint('uuid-dev')
58
- exit 1 unless library_installed? 'dbic++', apt_install_hint('dbic++-dev')
59
-
60
- assert_dbicpp_version '0.6.0'
61
- create_makefile 'swift'
data/ext/query.cc DELETED
@@ -1,104 +0,0 @@
1
- #include "query.h"
2
- #include <math.h>
3
-
4
- ID fstrftime;
5
- VALUE dtformat, utf8;
6
- VALUE cDateTime;
7
-
8
- VALUE query_execute(Query *query) {
9
- try {
10
- return UINT2NUM(
11
- query->bind.size() == 0
12
- ? query->handle->conn()->execute(query->sql)
13
- : query->handle->conn()->execute(query->sql, query->bind)
14
- );
15
- }
16
- catch (dbi::ConnectionError &e) {
17
- query->error_klass = eSwiftConnectionError;
18
- snprintf(query->error_message, 8192, "%s", e.what());
19
- }
20
- catch (dbi::Error &e) {
21
- query->error_klass = eSwiftRuntimeError;
22
- snprintf(query->error_message, 8192, "%s", e.what());
23
- }
24
- catch (std::bad_alloc &e) {
25
- query->error_klass = rb_eNoMemError;
26
- snprintf(query->error_message, 8192, "%s", e.what());
27
- }
28
- catch (std::exception &e) {
29
- query->error_klass = rb_eRuntimeError;
30
- snprintf(query->error_message, 8192, "%s", e.what());
31
- }
32
-
33
- return Qfalse;
34
- }
35
-
36
- VALUE query_execute_statement(Query *query) {
37
- try {
38
- return UINT2NUM(
39
- query->bind.size() == 0
40
- ? query->statement->execute()
41
- : query->statement->execute(query->bind)
42
- );
43
- }
44
- catch (dbi::ConnectionError &e) {
45
- query->error_klass = eSwiftConnectionError;
46
- snprintf(query->error_message, 8192, "%s", e.what());
47
- }
48
- catch (dbi::Error &e) {
49
- query->error_klass = eSwiftRuntimeError;
50
- snprintf(query->error_message, 8192, "%s", e.what());
51
- }
52
- catch (std::bad_alloc &e) {
53
- query->error_klass = rb_eNoMemError;
54
- snprintf(query->error_message, 8192, "%s", e.what());
55
- }
56
- catch (std::exception &e) {
57
- query->error_klass = rb_eRuntimeError;
58
- snprintf(query->error_message, 8192, "%s", e.what());
59
- }
60
-
61
- return Qfalse;
62
- }
63
-
64
- void query_bind_values(Query *query, VALUE bind_values) {
65
- for (int i = 0; i < RARRAY_LEN(bind_values); i++) {
66
- VALUE bind_value = rb_ary_entry(bind_values, i);
67
-
68
- if (bind_value == Qnil) {
69
- query->bind.push_back(dbi::PARAM(dbi::null()));
70
- }
71
- else if (bind_value == Qtrue) {
72
- query->bind.push_back(dbi::PARAM("1"));
73
- }
74
- else if (bind_value == Qfalse) {
75
- query->bind.push_back(dbi::PARAM("0"));
76
- }
77
- else if (rb_obj_is_kind_of(bind_value, rb_cIO) == Qtrue || rb_obj_is_kind_of(bind_value, cStringIO) == Qtrue) {
78
- bind_value = rb_funcall(bind_value, rb_intern("read"), 0);
79
- query->bind.push_back(dbi::PARAM_BINARY((unsigned char*)RSTRING_PTR(bind_value), RSTRING_LEN(bind_value)));
80
- }
81
- else if (rb_obj_is_kind_of(bind_value, rb_cTime) || rb_obj_is_kind_of(bind_value, cDateTime)) {
82
- std::string timestamp = RSTRING_PTR(rb_funcall(bind_value, fstrftime, 1, dtformat));
83
- query->bind.push_back(dbi::PARAM(timestamp));
84
- }
85
- else {
86
- bind_value = TO_S(bind_value);
87
- if (strcmp(rb_enc_get(bind_value)->name, "UTF-8") != 0)
88
- bind_value = rb_str_encode(bind_value, utf8, 0, Qnil);
89
- query->bind.push_back(dbi::PARAM((unsigned char*)RSTRING_PTR(bind_value), RSTRING_LEN(bind_value)));
90
- }
91
- }
92
- }
93
-
94
- void init_swift_query() {
95
- rb_require("date");
96
-
97
- utf8 = rb_str_new2("UTF-8");
98
- fstrftime = rb_intern("strftime");
99
- dtformat = rb_str_new2("%F %T.%N %z");
100
- cDateTime = CONST_GET(rb_mKernel, "DateTime");
101
-
102
- rb_global_variable(&utf8);
103
- rb_global_variable(&dtformat);
104
- }
data/ext/query.h DELETED
@@ -1,20 +0,0 @@
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
- std::vector<dbi::Param> bind;
11
- char error_message[8192];
12
- VALUE error_klass;
13
- };
14
-
15
- VALUE query_execute(Query*);
16
- VALUE query_execute_statement(Query*);
17
- void query_bind_values(Query*, VALUE);
18
- void init_swift_query();
19
-
20
- #endif
data/ext/result.cc DELETED
@@ -1,229 +0,0 @@
1
- #include "result.h"
2
- #include "datetime.h"
3
- #include <math.h>
4
-
5
- #define date_parse(klass, data,len) rb_funcall(datetime_parse(klass, data, len), fto_date, 0)
6
-
7
- VALUE cBigDecimal, cStringIO, cSwiftResult;
8
- ID fnew, fload, fto_date;
9
-
10
- void result_mark(ResultWrapper *handle) {
11
- if (handle)
12
- rb_gc_mark(handle->adapter);
13
- }
14
-
15
- void result_free(ResultWrapper *handle) {
16
- if (handle) {
17
- if (handle->free) delete handle->result;
18
- delete handle;
19
- }
20
- }
21
-
22
- VALUE result_alloc(VALUE klass) {
23
- ResultWrapper *handle = 0;
24
- return Data_Wrap_Struct(klass, result_mark, result_free, handle);
25
- }
26
-
27
- VALUE result_wrap_handle(VALUE klass, VALUE adapter, dbi::AbstractResult *result, bool free) {
28
- ResultWrapper *handle = new ResultWrapper;
29
- handle->result = result;
30
- handle->adapter = adapter;
31
- handle->free = free;
32
-
33
- VALUE obj = Data_Wrap_Struct(klass, result_mark, result_free, handle);
34
- if (!NIL_P(adapter))
35
- rb_iv_set(obj, "@timezone", rb_iv_get(adapter, "@timezone"));
36
-
37
- return obj;
38
- }
39
-
40
- dbi::AbstractResult* result_handle(VALUE self) {
41
- ResultWrapper *handle;
42
- Data_Get_Struct(self, ResultWrapper, handle);
43
- if (!handle) rb_raise(eSwiftRuntimeError, "Invalid object, did you forget to call #super?");
44
-
45
- return handle->result;
46
- }
47
-
48
- // NOTE clone and dup cannot be allowed since the underlying c++ object needs to be cloned, which
49
- // frankly is too much work :)
50
- static VALUE result_clone(VALUE self) {
51
- rb_raise(eSwiftRuntimeError, "clone is not allowed.");
52
- }
53
-
54
- static VALUE result_dup(VALUE self) {
55
- rb_raise(eSwiftRuntimeError, "dup is not allowed.");
56
- }
57
-
58
- VALUE result_each(VALUE self) {
59
- uint64_t length;
60
- const char *data;
61
-
62
- dbi::AbstractResult *result = result_handle(self);
63
- VALUE scheme = rb_iv_get(self, "@scheme");
64
-
65
- try {
66
- std::vector<string> result_fields = result->fields();
67
- std::vector<int> result_types = result->types();
68
- std::vector<VALUE> fields;
69
- for (uint32_t i = 0; i < result_fields.size(); i++)
70
- fields.push_back(ID2SYM(rb_intern(result_fields[i].c_str())));
71
-
72
- result->seek(0);
73
- for (uint32_t row = 0; row < result->rows(); row++) {
74
- VALUE tuple = rb_hash_new();
75
- for (uint32_t column = 0; column < result->columns(); column++) {
76
- data = (const char*)result->read(row, column, &length);
77
- if (data) {
78
- rb_hash_aset(
79
- tuple,
80
- fields[column],
81
- typecast_field(result_types[column], data, length)
82
- );
83
- }
84
- else {
85
- rb_hash_aset(tuple, fields[column], Qnil);
86
- }
87
- } // column loop
88
- NIL_P(scheme) ? rb_yield(tuple) : rb_yield(rb_funcall(scheme, fload, 1, tuple));
89
- } // row loop
90
- }
91
- CATCH_DBI_EXCEPTIONS();
92
-
93
- return Qnil;
94
- }
95
-
96
- VALUE typecast_field(int type, const char *data, uint64_t length) {
97
- switch(type) {
98
- case DBI_TYPE_BOOLEAN:
99
- return (data && (data[0] =='t' || data[0] == '1')) ? Qtrue : Qfalse;
100
- case DBI_TYPE_INT:
101
- return rb_cstr2inum(data, 10);
102
- case DBI_TYPE_BLOB:
103
- return rb_funcall(cStringIO, fnew, 1, rb_str_new(data, length));
104
- case DBI_TYPE_TIMESTAMP:
105
- return datetime_parse(cSwiftDateTime, data, length);
106
- case DBI_TYPE_DATE:
107
- return date_parse(cSwiftDateTime, data, length);
108
- case DBI_TYPE_NUMERIC:
109
- return rb_funcall(cBigDecimal, fnew, 1, rb_str_new2(data));
110
- case DBI_TYPE_FLOAT:
111
- return rb_float_new(atof(data));
112
-
113
- // DBI_TYPE_TIME
114
- // DBI_TYPE_TEXT
115
- default:
116
- return rb_enc_str_new(data, length, rb_utf8_encoding());
117
- }
118
- }
119
-
120
- VALUE result_insert_id(VALUE self) {
121
- dbi::AbstractResult *result = result_handle(self);
122
- try {
123
- return SIZET2NUM(result->lastInsertID());
124
- }
125
- CATCH_DBI_EXCEPTIONS();
126
- return Qnil;
127
- }
128
-
129
- VALUE result_rows(VALUE self) {
130
- dbi::AbstractResult *result = result_handle(self);
131
- try {
132
- return SIZET2NUM(result->rows());
133
- }
134
- CATCH_DBI_EXCEPTIONS();
135
- }
136
-
137
- VALUE result_columns(VALUE self) {
138
- dbi::AbstractResult *result = result_handle(self);
139
- try {
140
- return SIZET2NUM(result->columns());
141
- }
142
- CATCH_DBI_EXCEPTIONS();
143
- }
144
-
145
- VALUE result_fields(VALUE self) {
146
- dbi::AbstractResult *result = result_handle(self);
147
- try {
148
- std::vector<string> result_fields = result->fields();
149
- VALUE fields = rb_ary_new();
150
- for (int i = 0; i < result_fields.size(); i++)
151
- rb_ary_push(fields, ID2SYM(rb_intern(result_fields[i].c_str())));
152
- return fields;
153
- }
154
- CATCH_DBI_EXCEPTIONS();
155
- }
156
-
157
- VALUE result_field_types(VALUE self) {
158
- dbi::AbstractResult *result = result_handle(self);
159
- std::vector<int> result_types = result->types();
160
-
161
- VALUE types = rb_ary_new();
162
- for (std::vector<int>::iterator it = result_types.begin(); it != result_types.end(); it++) {
163
- switch(*it) {
164
- case DBI_TYPE_BOOLEAN:
165
- rb_ary_push(types, rb_str_new2("boolean"));
166
- break;
167
- case DBI_TYPE_INT:
168
- rb_ary_push(types, rb_str_new2("integer"));
169
- break;
170
- case DBI_TYPE_BLOB:
171
- rb_ary_push(types, rb_str_new2("blob"));
172
- break;
173
- case DBI_TYPE_TIMESTAMP:
174
- rb_ary_push(types, rb_str_new2("timestamp"));
175
- break;
176
- case DBI_TYPE_DATE:
177
- rb_ary_push(types, rb_str_new2("date"));
178
- break;
179
- case DBI_TYPE_NUMERIC:
180
- rb_ary_push(types, rb_str_new2("numeric"));
181
- break;
182
- case DBI_TYPE_FLOAT:
183
- rb_ary_push(types, rb_str_new2("float"));
184
- break;
185
- case DBI_TYPE_TIME:
186
- rb_ary_push(types, rb_str_new2("time"));
187
- break;
188
- default:
189
- rb_ary_push(types, rb_str_new2("text"));
190
- }
191
- }
192
-
193
- return types;
194
- }
195
-
196
- VALUE result_retrieve(VALUE self) {
197
- dbi::AbstractResult *result = result_handle(self);
198
- while (result->consumeResult());
199
- result->prepareResult();
200
- return true;
201
- }
202
-
203
- void init_swift_result() {
204
- rb_require("bigdecimal");
205
- rb_require("stringio");
206
-
207
- VALUE mSwift = rb_define_module("Swift");
208
- cSwiftResult = rb_define_class_under(mSwift, "Result", rb_cObject);
209
- cStringIO = CONST_GET(rb_mKernel, "StringIO");
210
- cBigDecimal = CONST_GET(rb_mKernel, "BigDecimal");
211
-
212
- fto_date = rb_intern("to_date");
213
- fnew = rb_intern("new");
214
- fload = rb_intern("load");
215
-
216
- rb_define_alloc_func(cSwiftResult, result_alloc);
217
- rb_include_module(cSwiftResult, CONST_GET(rb_mKernel, "Enumerable"));
218
-
219
- rb_define_method(cSwiftResult, "retrieve", RUBY_METHOD_FUNC(result_retrieve), 0);
220
- rb_define_method(cSwiftResult, "clone", RUBY_METHOD_FUNC(result_clone), 0);
221
- rb_define_method(cSwiftResult, "dup", RUBY_METHOD_FUNC(result_dup), 0);
222
- rb_define_method(cSwiftResult, "each", RUBY_METHOD_FUNC(result_each), 0);
223
- rb_define_method(cSwiftResult, "insert_id", RUBY_METHOD_FUNC(result_insert_id), 0);
224
- rb_define_method(cSwiftResult, "rows", RUBY_METHOD_FUNC(result_rows), 0);
225
- rb_define_method(cSwiftResult, "columns", RUBY_METHOD_FUNC(result_columns), 0);
226
- rb_define_method(cSwiftResult, "fields", RUBY_METHOD_FUNC(result_fields), 0);
227
- rb_define_method(cSwiftResult, "field_types", RUBY_METHOD_FUNC(result_field_types), 0);
228
- }
229
-
data/ext/result.h DELETED
@@ -1,27 +0,0 @@
1
- #ifndef SWIFT_RESULT_H
2
- #define SWIFT_RESULT_H
3
-
4
- #include "swift.h"
5
-
6
- struct ResultWrapper {
7
- dbi::AbstractResult *result;
8
- VALUE adapter;
9
- bool free;
10
- };
11
-
12
- extern VALUE cSwiftResult;
13
- extern VALUE cStringIO;
14
-
15
- void init_swift_result();
16
-
17
- void result_free(ResultWrapper *);
18
- void result_mark(ResultWrapper *);
19
-
20
- VALUE result_wrap_handle(VALUE, VALUE, dbi::AbstractResult *, bool free);
21
- dbi::AbstractResult* result_handle(VALUE);
22
-
23
- VALUE result_each(VALUE);
24
-
25
- VALUE typecast_field(int, const char*, uint64_t);
26
-
27
- #endif
data/ext/statement.cc DELETED
@@ -1,116 +0,0 @@
1
- #include "statement.h"
2
- #include "adapter.h"
3
- #include "result.h"
4
- #include "query.h"
5
-
6
- VALUE cSwiftStatement;
7
-
8
- void statement_mark(StatementWrapper *handle) {
9
- if (handle)
10
- rb_gc_mark(handle->adapter);
11
- }
12
-
13
- void statement_free(StatementWrapper *handle) {
14
- if (handle) {
15
- if (handle->free) delete handle->statement;
16
- delete handle;
17
- }
18
- }
19
-
20
- VALUE statement_alloc(VALUE klass) {
21
- StatementWrapper *handle = 0;
22
- return Data_Wrap_Struct(klass, statement_mark, statement_free, handle);
23
- }
24
-
25
- VALUE statement_wrap_handle(VALUE klass, VALUE adapter, dbi::AbstractStatement *statement) {
26
- StatementWrapper *handle = new StatementWrapper;
27
- handle->statement = statement;
28
- handle->adapter = adapter;
29
- handle->free = true;
30
-
31
- VALUE obj = Data_Wrap_Struct(klass, statement_mark, statement_free, handle);
32
- if (!NIL_P(adapter))
33
- rb_iv_set(obj, "@timezone", rb_iv_get(adapter, "@timezone"));
34
-
35
- return obj;
36
- }
37
-
38
- dbi::AbstractStatement* statement_handle(VALUE self) {
39
- StatementWrapper *handle;
40
- Data_Get_Struct(self, StatementWrapper, handle);
41
- if (!handle) rb_raise(eSwiftRuntimeError, "Invalid object, did you forget to call #super?");
42
-
43
- return handle->statement;
44
- }
45
-
46
- // array -> splat -> array is an overhead, but it reads nicer.
47
- static VALUE statement_execute(int argc, VALUE *argv, VALUE self) {
48
- VALUE bind_values, block;
49
- rb_scan_args(argc, argv, "0*&", &bind_values, &block);
50
-
51
- dbi::AbstractStatement *statement = (dbi::AbstractStatement*)statement_handle(self);
52
- try {
53
- Query query;
54
- query.statement = statement;
55
- if (RARRAY_LEN(bind_values) > 0) query_bind_values(&query, bind_values);
56
- if (dbi::_trace) dbi::logMessage(dbi::_trace_fd, dbi::formatParams(statement->command(), query.bind));
57
-
58
- if (rb_thread_blocking_region(((VALUE (*)(void*))query_execute_statement), &query, RUBY_UBF_IO, 0) == Qfalse)
59
- rb_raise(query.error_klass, "%s", query.error_message);
60
- }
61
- CATCH_DBI_EXCEPTIONS();
62
-
63
- StatementWrapper *handle;
64
- Data_Get_Struct(self, StatementWrapper, handle);
65
-
66
- VALUE result = result_wrap_handle(cSwiftResult, handle->adapter, statement->result(), true);
67
- rb_iv_set(result, "@scheme", rb_iv_get(self, "@scheme"));
68
-
69
- return rb_block_given_p() ? result_each(result) : result;
70
- }
71
-
72
- VALUE statement_insert_id(VALUE self) {
73
- dbi::AbstractStatement *statement = statement_handle(self);
74
- try {
75
- return SIZET2NUM(statement->lastInsertID());
76
- }
77
- CATCH_DBI_EXCEPTIONS();
78
- return Qnil;
79
- }
80
-
81
- VALUE statement_initialize(VALUE self, VALUE adapter, VALUE sql) {
82
- dbi::Handle *handle = adapter_handle(adapter);
83
-
84
- if (NIL_P(adapter)) rb_raise(eSwiftArgumentError, "Statement#new called without an Adapter instance.");
85
- if (NIL_P(sql)) rb_raise(eSwiftArgumentError, "Statement#new called without a command.");
86
-
87
- try {
88
- // needs to happen before wrapping in case it raises errors.
89
- dbi::AbstractStatement *statement = handle->conn()->prepare(CSTRING(sql));
90
- StatementWrapper *statement_handle = new StatementWrapper;
91
- statement_handle->statement = statement;
92
- statement_handle->adapter = adapter;
93
- statement_handle->free = true;
94
- DATA_PTR(self) = statement_handle;
95
- }
96
- CATCH_DBI_EXCEPTIONS();
97
-
98
- return Qnil;
99
- }
100
-
101
- VALUE statement_command(VALUE self) {
102
- return rb_iv_get(self, "@sql");
103
- }
104
-
105
- void init_swift_statement() {
106
- VALUE mSwift = rb_define_module("Swift");
107
-
108
- cSwiftStatement = rb_define_class_under(mSwift, "Statement", rb_cObject);
109
- rb_define_method(cSwiftStatement, "execute", RUBY_METHOD_FUNC(statement_execute), -1);
110
- rb_define_method(cSwiftStatement, "initialize", RUBY_METHOD_FUNC(statement_initialize), 2);
111
- rb_define_method(cSwiftStatement, "insert_id", RUBY_METHOD_FUNC(statement_insert_id), 0);
112
- rb_define_method(cSwiftStatement, "command", RUBY_METHOD_FUNC(statement_command), 0);
113
-
114
- rb_define_alias(cSwiftStatement, "to_s", "command");
115
- rb_define_alloc_func(cSwiftStatement, statement_alloc);
116
- }
data/ext/statement.h DELETED
@@ -1,22 +0,0 @@
1
- #ifndef SWIFT_STATEMENT_H
2
- #define SWIFT_STATEMENT_H
3
-
4
- #include "swift.h"
5
-
6
- struct StatementWrapper {
7
- dbi::AbstractStatement *statement;
8
- VALUE adapter;
9
- bool free;
10
- };
11
-
12
- extern VALUE cSwiftStatement;
13
-
14
- void init_swift_statement();
15
- void statement_free(StatementWrapper *);
16
- void statement_mark(StatementWrapper *);
17
-
18
- VALUE statement_wrap_handle(VALUE, VALUE, dbi::AbstractStatement *);
19
- dbi::AbstractStatement* statement_handle(VALUE);
20
-
21
- #endif
22
-