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.
- data/API.rdoc +14 -14
- data/README.md +110 -61
- data/Rakefile +2 -5
- data/VERSION +1 -1
- data/lib/swift/adapter/mysql.rb +30 -0
- data/lib/swift/adapter/postgres.rb +27 -0
- data/lib/swift/adapter/sql.rb +23 -29
- data/lib/swift/adapter/sqlite3.rb +59 -0
- data/lib/swift/adapter.rb +129 -70
- data/lib/swift/attribute.rb +19 -8
- data/lib/swift/eventmachine.rb +49 -0
- data/lib/swift/identity_map.rb +7 -7
- data/lib/swift/migrations.rb +12 -12
- data/lib/swift/{scheme.rb → record.rb} +16 -17
- data/lib/swift/result.rb +24 -0
- data/lib/swift/statement.rb +25 -0
- data/lib/swift/synchrony.rb +38 -0
- data/lib/swift/validations.rb +2 -2
- data/lib/swift.rb +8 -6
- data/swift.gemspec +19 -31
- data/test/helper.rb +11 -6
- data/test/test_adapter.rb +11 -25
- data/test/test_async.rb +9 -12
- data/test/test_encoding.rb +2 -2
- data/test/test_error.rb +8 -8
- data/test/test_io.rb +2 -2
- data/test/{test_scheme.rb → test_record.rb} +6 -6
- data/test/test_swift.rb +9 -51
- data/test/test_timestamps.rb +1 -1
- data/test/test_transactions.rb +2 -2
- data/test/test_types.rb +3 -3
- data/test/test_validations.rb +2 -2
- metadata +20 -27
- data/ext/adapter.cc +0 -479
- data/ext/adapter.h +0 -13
- data/ext/adapter_io.cc +0 -62
- data/ext/adapter_io.h +0 -24
- data/ext/attribute.cc +0 -22
- data/ext/attribute.h +0 -8
- data/ext/datetime.cc +0 -96
- data/ext/datetime.h +0 -12
- data/ext/extconf.rb +0 -61
- data/ext/query.cc +0 -104
- data/ext/query.h +0 -20
- data/ext/result.cc +0 -229
- data/ext/result.h +0 -27
- data/ext/statement.cc +0 -116
- data/ext/statement.h +0 -22
- data/ext/swift.cc +0 -114
- data/ext/swift.h +0 -60
- data/lib/swift/db.rb +0 -89
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: swift
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,11 +10,11 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2012-
|
13
|
+
date: 2012-08-01 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: minitest
|
17
|
-
requirement:
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
18
|
none: false
|
19
19
|
requirements:
|
20
20
|
- - ! '>='
|
@@ -22,14 +22,18 @@ dependencies:
|
|
22
22
|
version: 1.7.0
|
23
23
|
type: :development
|
24
24
|
prerelease: false
|
25
|
-
version_requirements:
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ! '>='
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: 1.7.0
|
26
31
|
description: A rational rudimentary database abstraction.
|
27
32
|
email:
|
28
33
|
- shane.hanna@gmail.com
|
29
34
|
- deepfryed@gmail.com
|
30
35
|
executables: []
|
31
|
-
extensions:
|
32
|
-
- ext/extconf.rb
|
36
|
+
extensions: []
|
33
37
|
extra_rdoc_files:
|
34
38
|
- LICENSE
|
35
39
|
- README.md
|
@@ -39,32 +43,21 @@ files:
|
|
39
43
|
- README.md
|
40
44
|
- Rakefile
|
41
45
|
- VERSION
|
42
|
-
- ext/adapter.cc
|
43
|
-
- ext/adapter.h
|
44
|
-
- ext/adapter_io.cc
|
45
|
-
- ext/adapter_io.h
|
46
|
-
- ext/attribute.cc
|
47
|
-
- ext/attribute.h
|
48
|
-
- ext/datetime.cc
|
49
|
-
- ext/datetime.h
|
50
|
-
- ext/extconf.rb
|
51
|
-
- ext/query.cc
|
52
|
-
- ext/query.h
|
53
|
-
- ext/result.cc
|
54
|
-
- ext/result.h
|
55
|
-
- ext/statement.cc
|
56
|
-
- ext/statement.h
|
57
|
-
- ext/swift.cc
|
58
|
-
- ext/swift.h
|
59
46
|
- lib/swift.rb
|
60
47
|
- lib/swift/adapter.rb
|
48
|
+
- lib/swift/adapter/mysql.rb
|
49
|
+
- lib/swift/adapter/postgres.rb
|
61
50
|
- lib/swift/adapter/sql.rb
|
51
|
+
- lib/swift/adapter/sqlite3.rb
|
62
52
|
- lib/swift/attribute.rb
|
63
|
-
- lib/swift/
|
53
|
+
- lib/swift/eventmachine.rb
|
64
54
|
- lib/swift/header.rb
|
65
55
|
- lib/swift/identity_map.rb
|
66
56
|
- lib/swift/migrations.rb
|
67
|
-
- lib/swift/
|
57
|
+
- lib/swift/record.rb
|
58
|
+
- lib/swift/result.rb
|
59
|
+
- lib/swift/statement.rb
|
60
|
+
- lib/swift/synchrony.rb
|
68
61
|
- lib/swift/type.rb
|
69
62
|
- lib/swift/validations.rb
|
70
63
|
- swift.gemspec
|
@@ -78,7 +71,7 @@ files:
|
|
78
71
|
- test/test_error.rb
|
79
72
|
- test/test_identity_map.rb
|
80
73
|
- test/test_io.rb
|
81
|
-
- test/
|
74
|
+
- test/test_record.rb
|
82
75
|
- test/test_swift.rb
|
83
76
|
- test/test_timestamps.rb
|
84
77
|
- test/test_transactions.rb
|
@@ -104,7 +97,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
104
97
|
version: '0'
|
105
98
|
requirements: []
|
106
99
|
rubyforge_project:
|
107
|
-
rubygems_version: 1.8.
|
100
|
+
rubygems_version: 1.8.23
|
108
101
|
signing_key:
|
109
102
|
specification_version: 3
|
110
103
|
summary: A rational rudimentary database abstraction.
|
data/ext/adapter.cc
DELETED
@@ -1,479 +0,0 @@
|
|
1
|
-
// vim:ts=2:sts=2:sw=2:expandtab
|
2
|
-
|
3
|
-
#include "adapter.h"
|
4
|
-
#include "sys/select.h"
|
5
|
-
|
6
|
-
// Extend the default dbi::FieldSet class with some ruby love.
|
7
|
-
class Fields : public dbi::FieldSet {
|
8
|
-
public:
|
9
|
-
Fields() : dbi::FieldSet(0) {}
|
10
|
-
|
11
|
-
void operator<<(VALUE v) {
|
12
|
-
VALUE name = TO_S(v);
|
13
|
-
fields.push_back(std::string(RSTRING_PTR(name), RSTRING_LEN(name)));
|
14
|
-
}
|
15
|
-
};
|
16
|
-
|
17
|
-
static VALUE cSwiftAdapter;
|
18
|
-
|
19
|
-
void build_extra_options_string(VALUE key, VALUE value, VALUE ptr) {
|
20
|
-
std::string *optstring = (std::string *)ptr;
|
21
|
-
*optstring += CSTRING(key) + std::string("=") + CSTRING(value) + std::string(";");
|
22
|
-
}
|
23
|
-
|
24
|
-
std::string parse_extra_options(VALUE options) {
|
25
|
-
std::string optstring = "";
|
26
|
-
if (!NIL_P(options))
|
27
|
-
rb_hash_foreach(options, RUBY_STATIC_FUNC(build_extra_options_string), (VALUE)&optstring);
|
28
|
-
return optstring;
|
29
|
-
}
|
30
|
-
|
31
|
-
static void adapter_free(dbi::Handle *handle) {
|
32
|
-
if (handle) {
|
33
|
-
handle->conn()->cleanup();
|
34
|
-
delete handle;
|
35
|
-
}
|
36
|
-
}
|
37
|
-
|
38
|
-
VALUE adapter_alloc(VALUE klass) {
|
39
|
-
dbi::Handle *handle = 0;
|
40
|
-
return Data_Wrap_Struct(klass, 0, adapter_free, handle);
|
41
|
-
}
|
42
|
-
|
43
|
-
dbi::Handle* adapter_handle(VALUE self) {
|
44
|
-
dbi::Handle *handle;
|
45
|
-
Data_Get_Struct(self, dbi::Handle, handle);
|
46
|
-
if (!handle) rb_raise(eSwiftRuntimeError, "Invalid object, did you forget to call #super?");
|
47
|
-
|
48
|
-
return handle;
|
49
|
-
}
|
50
|
-
|
51
|
-
/*
|
52
|
-
Begin a transaction (unit of work).
|
53
|
-
|
54
|
-
@overload commit(name = nil)
|
55
|
-
@param [Symbol, String] name Optional transaction name.
|
56
|
-
|
57
|
-
@see Swift::Adapter#transaction
|
58
|
-
*/
|
59
|
-
static VALUE adapter_begin(int argc, VALUE *argv, VALUE self) {
|
60
|
-
VALUE save_point;
|
61
|
-
rb_scan_args(argc, argv, "01", &save_point);
|
62
|
-
|
63
|
-
dbi::Handle *handle = adapter_handle(self);
|
64
|
-
try {
|
65
|
-
NIL_P(save_point) ? handle->begin() : handle->begin(CSTRING(save_point));
|
66
|
-
}
|
67
|
-
CATCH_DBI_EXCEPTIONS();
|
68
|
-
return Qtrue;
|
69
|
-
}
|
70
|
-
|
71
|
-
/*
|
72
|
-
Close the connection.
|
73
|
-
*/
|
74
|
-
static VALUE adapter_close(VALUE self) {
|
75
|
-
dbi::Handle *handle = adapter_handle(self);
|
76
|
-
try { handle->close(); } CATCH_DBI_EXCEPTIONS();
|
77
|
-
rb_iv_set(self, "@closed", true);
|
78
|
-
return Qtrue;
|
79
|
-
}
|
80
|
-
|
81
|
-
|
82
|
-
/*
|
83
|
-
Check if connection is closed.
|
84
|
-
*/
|
85
|
-
static VALUE adapter_closed(VALUE self) {
|
86
|
-
return rb_iv_get(self, "@closed");
|
87
|
-
}
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
/*
|
93
|
-
Shallow copy of adapter.
|
94
|
-
|
95
|
-
@note Currently not allowed.
|
96
|
-
@see Object.clone
|
97
|
-
*/
|
98
|
-
static VALUE adapter_clone(VALUE self) {
|
99
|
-
rb_raise(eSwiftRuntimeError, "clone is not allowed.");
|
100
|
-
}
|
101
|
-
|
102
|
-
/*
|
103
|
-
Commit a transaction (unit of work).
|
104
|
-
|
105
|
-
@overload commit(name = nil)
|
106
|
-
@param [Symbol, String] name Optional transaction name.
|
107
|
-
*/
|
108
|
-
static VALUE adapter_commit(int argc, VALUE *argv, VALUE self) {
|
109
|
-
VALUE save_point;
|
110
|
-
rb_scan_args(argc, argv, "01", &save_point);
|
111
|
-
dbi::Handle *handle = adapter_handle(self);
|
112
|
-
|
113
|
-
try {
|
114
|
-
NIL_P(save_point) ? handle->commit() : handle->commit(CSTRING(save_point));
|
115
|
-
}
|
116
|
-
CATCH_DBI_EXCEPTIONS();
|
117
|
-
return Qtrue;
|
118
|
-
}
|
119
|
-
|
120
|
-
/*
|
121
|
-
Shallow copy of adapter.
|
122
|
-
|
123
|
-
@note Currently not allowed.
|
124
|
-
@see Object.dup
|
125
|
-
*/
|
126
|
-
static VALUE adapter_dup(VALUE self) {
|
127
|
-
rb_raise(eSwiftRuntimeError, "dup is not allowed.");
|
128
|
-
}
|
129
|
-
|
130
|
-
/*
|
131
|
-
Escape a string.
|
132
|
-
|
133
|
-
@note Bind values do not need to be escaped.
|
134
|
-
|
135
|
-
@overload escape(value)
|
136
|
-
@param [String] value String to be escaped.
|
137
|
-
@return [String]
|
138
|
-
*/
|
139
|
-
static VALUE adapter_escape(VALUE self, VALUE value) {
|
140
|
-
if (TYPE(value) != T_STRING)
|
141
|
-
value = TO_S(value);
|
142
|
-
|
143
|
-
dbi::Handle *handle = adapter_handle(self);
|
144
|
-
try {
|
145
|
-
std::string safe = handle->escape(std::string(RSTRING_PTR(value), RSTRING_LEN(value)));
|
146
|
-
return rb_str_new(safe.data(), safe.length());
|
147
|
-
}
|
148
|
-
CATCH_DBI_EXCEPTIONS();
|
149
|
-
}
|
150
|
-
|
151
|
-
/*
|
152
|
-
Execute a single statement.
|
153
|
-
|
154
|
-
@example
|
155
|
-
result = User.execute("select * from #{User} where #{User.name} = ?", 'apple')
|
156
|
-
result.first # User object.
|
157
|
-
|
158
|
-
@overload execute(statement = '', *binds, &block)
|
159
|
-
@param [String] statement Query statement.
|
160
|
-
@param [*Object] binds Bind values.
|
161
|
-
@yield [Swift::Result]
|
162
|
-
@return [Swift::Result]
|
163
|
-
*/
|
164
|
-
static VALUE adapter_execute(int argc, VALUE *argv, VALUE self) {
|
165
|
-
VALUE statement, bind_values, block, rows, scheme = Qnil;
|
166
|
-
|
167
|
-
dbi::Handle *handle = adapter_handle(self);
|
168
|
-
rb_scan_args(argc, argv, "1*&", &statement, &bind_values, &block);
|
169
|
-
|
170
|
-
if (TYPE(statement) == T_CLASS) {
|
171
|
-
scheme = statement;
|
172
|
-
statement = rb_ary_shift(bind_values);
|
173
|
-
}
|
174
|
-
|
175
|
-
try {
|
176
|
-
Query query;
|
177
|
-
query.sql = CSTRING(statement);
|
178
|
-
query.handle = handle;
|
179
|
-
|
180
|
-
if (RARRAY_LEN(bind_values) > 0) query_bind_values(&query, bind_values);
|
181
|
-
if (dbi::_trace) dbi::logMessage(dbi::_trace_fd, dbi::formatParams(query.sql, query.bind));
|
182
|
-
|
183
|
-
if ((rows = rb_thread_blocking_region(((VALUE (*)(void*))query_execute), &query, RUBY_UBF_IO, 0)) == Qfalse)
|
184
|
-
rb_raise(query.error_klass, "%s", query.error_message);
|
185
|
-
|
186
|
-
VALUE result = result_wrap_handle(cSwiftResult, self, handle->conn()->result(), true);
|
187
|
-
if (!NIL_P(scheme))
|
188
|
-
rb_iv_set(result, "@scheme", scheme);
|
189
|
-
return rb_block_given_p() ? result_each(result) : result;
|
190
|
-
}
|
191
|
-
CATCH_DBI_EXCEPTIONS();
|
192
|
-
}
|
193
|
-
|
194
|
-
/*
|
195
|
-
Reestablish a connection.
|
196
|
-
*/
|
197
|
-
static VALUE adapter_reconnect(VALUE self) {
|
198
|
-
dbi::Handle *handle = adapter_handle(self);
|
199
|
-
try {
|
200
|
-
handle->reconnect();
|
201
|
-
rb_iv_set(self, "@closed", false);
|
202
|
-
}
|
203
|
-
CATCH_DBI_EXCEPTIONS();
|
204
|
-
return Qtrue;
|
205
|
-
}
|
206
|
-
|
207
|
-
/*
|
208
|
-
Setup a new DB connection.
|
209
|
-
|
210
|
-
You almost certainly want to setup a <tt>:default</tt> named adapter. The <tt>:default</tt> scope will be used
|
211
|
-
for unscoped calls to <tt>Swift.db</tt>.
|
212
|
-
|
213
|
-
@example
|
214
|
-
Swift.setup :default, Swift::DB::Postgres, db: 'db1'
|
215
|
-
Swift.setup :other, Swift::DB::Postgres, db: 'db2'
|
216
|
-
|
217
|
-
@overload new(options = {})
|
218
|
-
@param [Hash] options Connection options
|
219
|
-
@option options [String] :db Name.
|
220
|
-
@option options [String] :user (*nix login user)
|
221
|
-
@option options [String] :password ('')
|
222
|
-
@option options [String] :host ('localhost')
|
223
|
-
@option options [Integer] :port (DB default)
|
224
|
-
@return [Swift::Adapter]
|
225
|
-
|
226
|
-
@see Swift::DB
|
227
|
-
@see Swift::Adapter
|
228
|
-
*/
|
229
|
-
static VALUE adapter_initialize(VALUE self, VALUE options) {
|
230
|
-
VALUE db = rb_hash_aref(options, ID2SYM(rb_intern("db")));
|
231
|
-
VALUE driver = rb_hash_aref(options, ID2SYM(rb_intern("driver")));
|
232
|
-
VALUE user = rb_hash_aref(options, ID2SYM(rb_intern("user")));
|
233
|
-
|
234
|
-
if (NIL_P(db)) rb_raise(eSwiftArgumentError, "Adapter#new called without :db");
|
235
|
-
if (NIL_P(driver)) rb_raise(eSwiftArgumentError, "Adapter#new called without :driver");
|
236
|
-
|
237
|
-
user = NIL_P(user) ? current_user() : user;
|
238
|
-
VALUE extra = rb_hash_dup(options);
|
239
|
-
|
240
|
-
rb_hash_delete(extra, ID2SYM(rb_intern("db")));
|
241
|
-
rb_hash_delete(extra, ID2SYM(rb_intern("driver")));
|
242
|
-
rb_hash_delete(extra, ID2SYM(rb_intern("user")));
|
243
|
-
rb_hash_delete(extra, ID2SYM(rb_intern("password")));
|
244
|
-
rb_hash_delete(extra, ID2SYM(rb_intern("host")));
|
245
|
-
rb_hash_delete(extra, ID2SYM(rb_intern("port")));
|
246
|
-
|
247
|
-
std::string extra_options_string = parse_extra_options(extra);
|
248
|
-
|
249
|
-
try {
|
250
|
-
DATA_PTR(self) = new dbi::Handle(
|
251
|
-
CSTRING(driver),
|
252
|
-
CSTRING(user),
|
253
|
-
CSTRING(rb_hash_aref(options, ID2SYM(rb_intern("password")))),
|
254
|
-
CSTRING(db),
|
255
|
-
CSTRING(rb_hash_aref(options, ID2SYM(rb_intern("host")))),
|
256
|
-
CSTRING(rb_hash_aref(options, ID2SYM(rb_intern("port")))),
|
257
|
-
extra_options_string.size() > 0 ? (char*)extra_options_string.c_str() : 0
|
258
|
-
);
|
259
|
-
}
|
260
|
-
CATCH_DBI_EXCEPTIONS();
|
261
|
-
|
262
|
-
rb_iv_set(self, "@options", options);
|
263
|
-
|
264
|
-
return Qnil;
|
265
|
-
}
|
266
|
-
|
267
|
-
/*
|
268
|
-
Prepare a statement for on or more executions.
|
269
|
-
|
270
|
-
@example
|
271
|
-
sth = User.prepare("select * from #{User} where #{User.name} = ?")
|
272
|
-
sth.execute('apple') #=> Result
|
273
|
-
sth.execute('benny') #=> Result
|
274
|
-
|
275
|
-
@overload prepare(statement, &block)
|
276
|
-
@param [String] statement Query statement.
|
277
|
-
@return [Swift::Statement]
|
278
|
-
*/
|
279
|
-
static VALUE adapter_prepare(int argc, VALUE *argv, VALUE self) {
|
280
|
-
VALUE sql, scheme, prepared;
|
281
|
-
dbi::AbstractStatement *statement;
|
282
|
-
|
283
|
-
rb_scan_args(argc, argv, "11", &scheme, &sql);
|
284
|
-
if (TYPE(scheme) != T_CLASS) {
|
285
|
-
sql = scheme;
|
286
|
-
scheme = Qnil;
|
287
|
-
}
|
288
|
-
|
289
|
-
dbi::Handle *handle = adapter_handle(self);
|
290
|
-
try {
|
291
|
-
// TODO: Move to statement_* constructor.
|
292
|
-
statement = handle->conn()->prepare(CSTRING(sql));
|
293
|
-
prepared = statement_wrap_handle(cSwiftStatement, self, statement);
|
294
|
-
rb_iv_set(prepared, "@scheme", scheme);
|
295
|
-
rb_iv_set(prepared, "@sql", sql);
|
296
|
-
return prepared;
|
297
|
-
}
|
298
|
-
CATCH_DBI_EXCEPTIONS();
|
299
|
-
}
|
300
|
-
|
301
|
-
/*
|
302
|
-
Rollback the current transaction.
|
303
|
-
|
304
|
-
@overload rollback(name = nil)
|
305
|
-
@param [Symbol, String] name Optional transaction name.
|
306
|
-
*/
|
307
|
-
static VALUE adapter_rollback(int argc, VALUE *argv, VALUE self) {
|
308
|
-
VALUE save_point;
|
309
|
-
dbi::Handle *handle = adapter_handle(self);
|
310
|
-
rb_scan_args(argc, argv, "01", &save_point);
|
311
|
-
|
312
|
-
try {
|
313
|
-
NIL_P(save_point) ? handle->rollback() : handle->rollback(CSTRING(save_point));
|
314
|
-
}
|
315
|
-
CATCH_DBI_EXCEPTIONS();
|
316
|
-
return Qtrue;
|
317
|
-
}
|
318
|
-
|
319
|
-
/*
|
320
|
-
Block form transaction sugar.
|
321
|
-
|
322
|
-
@overload transaction(name = nil, &block)
|
323
|
-
@param [Symbol, String] name Optional transaction name.
|
324
|
-
*/
|
325
|
-
static VALUE adapter_transaction(int argc, VALUE *argv, VALUE self) {
|
326
|
-
int status;
|
327
|
-
VALUE sp, block, block_result = Qnil;
|
328
|
-
dbi::Handle *handle = adapter_handle(self);
|
329
|
-
rb_scan_args(argc, argv, "01&", &sp, &block);
|
330
|
-
|
331
|
-
if (NIL_P(block)) rb_raise(eSwiftArgumentError, "Transaction called without a block.");
|
332
|
-
std::string save_point = NIL_P(sp) ? "SP" + dbi::generateCompactUUID() : CSTRING(sp);
|
333
|
-
|
334
|
-
try {
|
335
|
-
handle->begin(save_point);
|
336
|
-
block_result = rb_protect(rb_yield, self, &status);
|
337
|
-
if (!status && handle->transactions().size() > 0) {
|
338
|
-
handle->commit(save_point);
|
339
|
-
}
|
340
|
-
else if (status && handle->transactions().size() > 0) {
|
341
|
-
handle->rollback(save_point);
|
342
|
-
rb_jump_tag(status);
|
343
|
-
}
|
344
|
-
}
|
345
|
-
CATCH_DBI_EXCEPTIONS();
|
346
|
-
|
347
|
-
return block_result;
|
348
|
-
}
|
349
|
-
|
350
|
-
/*
|
351
|
-
Bulk insert resources.
|
352
|
-
|
353
|
-
@overload write(store, fields, stream)
|
354
|
-
@param [Swift::Scheme, String] store Write to store.
|
355
|
-
@param [Array<Swift::Attribute, String>] fields Write to fields in store.
|
356
|
-
@param [IO] stream IO to read from.
|
357
|
-
|
358
|
-
@note The format of the stream and bulk write performance are entirely down to each adapter.
|
359
|
-
*/
|
360
|
-
static VALUE adapter_write(int argc, VALUE *argv, VALUE self) {
|
361
|
-
uint64_t rows = 0;
|
362
|
-
VALUE stream, table, fields;
|
363
|
-
dbi::Handle *handle = adapter_handle(self);
|
364
|
-
|
365
|
-
rb_scan_args(argc, argv, "30", &table, &fields, &stream);
|
366
|
-
if (TYPE(stream) != T_STRING && !rb_respond_to(stream, rb_intern("read")))
|
367
|
-
rb_raise(eSwiftArgumentError, "Stream must be a String or IO object.");
|
368
|
-
if (TYPE(fields) != T_ARRAY)
|
369
|
-
rb_raise(eSwiftArgumentError, "Fields must be an Array.");
|
370
|
-
|
371
|
-
try {
|
372
|
-
Fields write_fields;
|
373
|
-
for (int i = 0; i < RARRAY_LEN(fields); i++)
|
374
|
-
write_fields << rb_ary_entry(fields, i);
|
375
|
-
|
376
|
-
/*
|
377
|
-
TODO: Adapter specific code is balls.
|
378
|
-
This is just for the friggin mysql support - mysql does not like a statement close command being send on a
|
379
|
-
handle when the writing has started.
|
380
|
-
*/
|
381
|
-
rb_gc();
|
382
|
-
|
383
|
-
if (TYPE(stream) == T_STRING) {
|
384
|
-
dbi::StringIO io(RSTRING_PTR(stream), RSTRING_LEN(stream));
|
385
|
-
rows = handle->write(RSTRING_PTR(TO_S(table)), write_fields, &io);
|
386
|
-
}
|
387
|
-
else {
|
388
|
-
AdapterIO io(stream);
|
389
|
-
rows = handle->write(RSTRING_PTR(TO_S(table)), write_fields, &io);
|
390
|
-
}
|
391
|
-
return SIZET2NUM(rows);
|
392
|
-
}
|
393
|
-
CATCH_DBI_EXCEPTIONS();
|
394
|
-
}
|
395
|
-
|
396
|
-
/*
|
397
|
-
Returns the socket fileno for the connection.
|
398
|
-
|
399
|
-
@overload fileno()
|
400
|
-
@return [Fixnum]
|
401
|
-
*/
|
402
|
-
VALUE adapter_fileno(VALUE self) {
|
403
|
-
dbi::Handle *handle = adapter_handle(self);
|
404
|
-
return INT2NUM(handle->conn()->socket());
|
405
|
-
}
|
406
|
-
|
407
|
-
/*
|
408
|
-
Executes a query asynchronously and returns the result instance.
|
409
|
-
|
410
|
-
@example
|
411
|
-
|
412
|
-
@overload async_execute(statement = '', *binds, &block)
|
413
|
-
@param [String] statement Query statement.
|
414
|
-
@param [*Object] binds Bind values.
|
415
|
-
@return [Swift::Result]
|
416
|
-
*/
|
417
|
-
VALUE adapter_async_execute(int argc, VALUE *argv, VALUE self) {
|
418
|
-
VALUE statement, bind_values, block, scheme = Qnil, result;
|
419
|
-
|
420
|
-
dbi::Handle *handle = adapter_handle(self);
|
421
|
-
rb_scan_args(argc, argv, "1*&", &statement, &bind_values, &block);
|
422
|
-
|
423
|
-
if (TYPE(statement) == T_CLASS) {
|
424
|
-
scheme = statement;
|
425
|
-
statement = rb_ary_shift(bind_values);
|
426
|
-
}
|
427
|
-
|
428
|
-
try {
|
429
|
-
dbi::AbstractResult *dbi_result;
|
430
|
-
if (RARRAY_LEN(bind_values) > 0) {
|
431
|
-
Query query;
|
432
|
-
query_bind_values(&query, bind_values);
|
433
|
-
dbi_result = handle->conn()->aexecute(CSTRING(statement), query.bind);
|
434
|
-
}
|
435
|
-
else
|
436
|
-
dbi_result = handle->conn()->aexecute(CSTRING(statement));
|
437
|
-
|
438
|
-
result = result_wrap_handle(cSwiftResult, self, dbi_result, true);
|
439
|
-
if (!NIL_P(scheme))
|
440
|
-
rb_iv_set(result, "@scheme", scheme);
|
441
|
-
|
442
|
-
// if block given, just use rb_thread_select
|
443
|
-
if (rb_block_given_p()) {
|
444
|
-
rb_thread_wait_fd(handle->socket());
|
445
|
-
while (dbi_result->consumeResult());
|
446
|
-
dbi_result->prepareResult();
|
447
|
-
}
|
448
|
-
}
|
449
|
-
CATCH_DBI_EXCEPTIONS();
|
450
|
-
|
451
|
-
return rb_block_given_p() ? result_each(result) : result;
|
452
|
-
}
|
453
|
-
|
454
|
-
void init_swift_adapter() {
|
455
|
-
VALUE mSwift = rb_define_module("Swift");
|
456
|
-
cSwiftAdapter = rb_define_class_under(mSwift, "Adapter", rb_cObject);
|
457
|
-
|
458
|
-
rb_define_method(cSwiftAdapter, "begin", RUBY_METHOD_FUNC(adapter_begin), -1);
|
459
|
-
rb_define_method(cSwiftAdapter, "clone", RUBY_METHOD_FUNC(adapter_clone), 0);
|
460
|
-
rb_define_method(cSwiftAdapter, "close", RUBY_METHOD_FUNC(adapter_close), 0);
|
461
|
-
rb_define_method(cSwiftAdapter, "closed?", RUBY_METHOD_FUNC(adapter_closed), 0);
|
462
|
-
rb_define_method(cSwiftAdapter, "commit", RUBY_METHOD_FUNC(adapter_commit), -1);
|
463
|
-
rb_define_method(cSwiftAdapter, "dup", RUBY_METHOD_FUNC(adapter_dup), 0);
|
464
|
-
rb_define_method(cSwiftAdapter, "escape", RUBY_METHOD_FUNC(adapter_escape), 1);
|
465
|
-
rb_define_method(cSwiftAdapter, "execute", RUBY_METHOD_FUNC(adapter_execute), -1);
|
466
|
-
rb_define_method(cSwiftAdapter, "initialize", RUBY_METHOD_FUNC(adapter_initialize), 1);
|
467
|
-
rb_define_method(cSwiftAdapter, "prepare", RUBY_METHOD_FUNC(adapter_prepare), -1);
|
468
|
-
rb_define_method(cSwiftAdapter, "rollback", RUBY_METHOD_FUNC(adapter_rollback), -1);
|
469
|
-
rb_define_method(cSwiftAdapter, "transaction", RUBY_METHOD_FUNC(adapter_transaction), -1);
|
470
|
-
rb_define_method(cSwiftAdapter, "write", RUBY_METHOD_FUNC(adapter_write), -1);
|
471
|
-
rb_define_method(cSwiftAdapter, "reconnect", RUBY_METHOD_FUNC(adapter_reconnect), 0);
|
472
|
-
|
473
|
-
// stuff you need for async
|
474
|
-
rb_define_method(cSwiftAdapter, "fileno", RUBY_METHOD_FUNC(adapter_fileno), 0);
|
475
|
-
rb_define_method(cSwiftAdapter, "async_execute", RUBY_METHOD_FUNC(adapter_async_execute), -1);
|
476
|
-
|
477
|
-
rb_define_alloc_func(cSwiftAdapter, adapter_alloc);
|
478
|
-
}
|
479
|
-
|
data/ext/adapter.h
DELETED
data/ext/adapter_io.cc
DELETED
@@ -1,62 +0,0 @@
|
|
1
|
-
#include "adapter_io.h"
|
2
|
-
|
3
|
-
AdapterIO::AdapterIO(VALUE s) {
|
4
|
-
stream = s;
|
5
|
-
}
|
6
|
-
|
7
|
-
std::string& AdapterIO::read() {
|
8
|
-
VALUE response = rb_funcall(stream, rb_intern("read"), 0);
|
9
|
-
if (response == Qnil) {
|
10
|
-
return empty;
|
11
|
-
}
|
12
|
-
else {
|
13
|
-
// Attempt TO_S first before complaining?
|
14
|
-
if (TYPE(response) != T_STRING) {
|
15
|
-
rb_raise(
|
16
|
-
CONST_GET(rb_mKernel, "ArgumentError"),
|
17
|
-
"Write can only process string data. You need to stringify values returned in the callback."
|
18
|
-
);
|
19
|
-
}
|
20
|
-
stringdata = std::string(RSTRING_PTR(response), RSTRING_LEN(response));
|
21
|
-
return stringdata;
|
22
|
-
}
|
23
|
-
}
|
24
|
-
|
25
|
-
uint32_t AdapterIO::read(char *buffer, uint32_t length) {
|
26
|
-
VALUE response = rb_funcall(stream, rb_intern("read"), 1, INT2NUM(length));
|
27
|
-
if (response == Qnil) {
|
28
|
-
return 0;
|
29
|
-
}
|
30
|
-
else {
|
31
|
-
length = length < RSTRING_LEN(response) ? length : RSTRING_LEN(response);
|
32
|
-
memcpy(buffer, RSTRING_PTR(response), length);
|
33
|
-
return length;
|
34
|
-
}
|
35
|
-
}
|
36
|
-
|
37
|
-
void AdapterIO::write(const char *str) {
|
38
|
-
rb_funcall(stream, rb_intern("write"), 1, rb_str_new2(str));
|
39
|
-
}
|
40
|
-
|
41
|
-
void AdapterIO::write(const char *str, uint64_t l) {
|
42
|
-
rb_funcall(stream, rb_intern("write"), 1, rb_str_new(str, l));
|
43
|
-
}
|
44
|
-
|
45
|
-
bool AdapterIO::readline(std::string &line) {
|
46
|
-
VALUE response = rb_funcall(stream, rb_intern("gets"), 0);
|
47
|
-
if (response == Qnil) {
|
48
|
-
return false;
|
49
|
-
}
|
50
|
-
else {
|
51
|
-
line = std::string(RSTRING_PTR(response), RSTRING_LEN(response));
|
52
|
-
return true;
|
53
|
-
}
|
54
|
-
}
|
55
|
-
|
56
|
-
char* AdapterIO::readline() {
|
57
|
-
return readline(stringdata) ? (char*)stringdata.c_str() : 0;
|
58
|
-
}
|
59
|
-
|
60
|
-
void AdapterIO::truncate() {
|
61
|
-
rb_funcall(stream, rb_intern("truncate"), 0);
|
62
|
-
}
|
data/ext/adapter_io.h
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
#ifndef SWIFT_ADAPTER_IO_H
|
2
|
-
#define SWIFT_ADAPTER_IO_H
|
3
|
-
|
4
|
-
#include "swift.h"
|
5
|
-
|
6
|
-
class AdapterIO : public dbi::IO {
|
7
|
-
private:
|
8
|
-
VALUE stream;
|
9
|
-
std::string stringdata, empty;
|
10
|
-
public:
|
11
|
-
AdapterIO(VALUE);
|
12
|
-
std::string& read();
|
13
|
-
uint32_t read(char *, uint32_t);
|
14
|
-
|
15
|
-
void write(const char *);
|
16
|
-
void write(const char *, uint64_t);
|
17
|
-
|
18
|
-
void truncate();
|
19
|
-
|
20
|
-
bool readline(string&);
|
21
|
-
char* readline();
|
22
|
-
};
|
23
|
-
|
24
|
-
#endif
|
data/ext/attribute.cc
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
#include "attribute.h"
|
2
|
-
|
3
|
-
ID fcall;
|
4
|
-
|
5
|
-
VALUE attribute_default(VALUE self) {
|
6
|
-
VALUE value = rb_iv_get(self, "@default");
|
7
|
-
|
8
|
-
if (NIL_P(value) || rb_obj_is_kind_of(value, rb_cNumeric) || rb_special_const_p(value))
|
9
|
-
return value;
|
10
|
-
else if (rb_respond_to(value, fcall))
|
11
|
-
return rb_funcall(value, fcall, 0);
|
12
|
-
else
|
13
|
-
return rb_obj_dup(value);
|
14
|
-
}
|
15
|
-
|
16
|
-
void init_swift_attribute() {
|
17
|
-
VALUE mSwift = rb_define_module("Swift");
|
18
|
-
VALUE cSwiftAttribute = rb_define_class_under(mSwift, "Attribute", rb_cObject);
|
19
|
-
|
20
|
-
fcall = rb_intern("call");
|
21
|
-
rb_define_method(cSwiftAttribute, "default", RUBY_METHOD_FUNC(attribute_default), 0);
|
22
|
-
}
|