swift 0.14.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
-