swift 0.5.1 → 0.6.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.
@@ -71,7 +71,7 @@ primitive Ruby type conversion.
71
71
  attribute :id, Swift::Type::Integer, serial: true, key: true
72
72
  attribute :name, Swift::Type::String
73
73
  attribute :email, Swift::Type::String
74
- attribute :updated_at, Swift::Type::Time
74
+ attribute :updated_at, Swift::Type::DateTime
75
75
  end # User
76
76
 
77
77
  Swift.db do |db|
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.1
1
+ 0.6.0
@@ -9,12 +9,12 @@ require 'swift/validations'
9
9
 
10
10
  class User < Swift::Scheme
11
11
  store :users
12
- attribute :id, Swift::Type::Integer, serial: true, key: true
12
+ attribute :id, Swift::Type::Integer, serial: true, key: true
13
13
  attribute :name, Swift::Type::String
14
14
  attribute :email, Swift::Type::String
15
15
  attribute :active, Swift::Type::Boolean
16
- attribute :created, Swift::Type::Time, default: proc { Time.now }
17
- attribute :optional, Swift::Type::String, default: 'woot'
16
+ attribute :created, Swift::Type::DateTime, default: proc { Time.now }
17
+ attribute :optional, Swift::Type::String, default: 'woot'
18
18
 
19
19
  validations do |errors|
20
20
  errors << [:name, 'is blank'] if name.to_s.empty?
@@ -86,10 +86,9 @@ static VALUE adapter_execute(int argc, VALUE *argv, VALUE self) {
86
86
  if (RARRAY_LEN(bind_values) > 0) query_bind_values(&query, bind_values);
87
87
  if (dbi::_trace) dbi::logMessage(dbi::_trace_fd, dbi::formatParams(query.sql, query.bind));
88
88
 
89
- // TODO: http://redmine.ruby-lang.org/issues/show/3762
90
- // rb_thread_blocking_region and C++ exceptions don't mix in 1.9.2.
91
- // rows = rb_thread_blocking_region(((VALUE (*)(void*))query_execute), &query, RUBY_UBF_IO, 0);
92
- rows = query_execute(&query);
89
+ if ((rows = rb_thread_blocking_region(((VALUE (*)(void*))query_execute), &query, RUBY_UBF_IO, 0)) == Qfalse)
90
+ rb_raise(eSwiftRuntimeError, "%s", query.error);
91
+
93
92
  if (rb_block_given_p()) {
94
93
  dbi::AbstractResultSet *result = handle->results();
95
94
  return result_each(Data_Wrap_Struct(cSwiftResult, 0, result_free, result));
@@ -55,6 +55,6 @@ exit 1 unless library_installed? 'pcrecpp', apt_install_hint('libpcre3-dev')
55
55
  exit 1 unless library_installed? 'uuid', apt_install_hint('uuid-dev')
56
56
  exit 1 unless library_installed? 'dbic++', apt_install_hint('dbic++-dev')
57
57
 
58
- assert_dbicpp_version '0.3.0'
58
+ assert_dbicpp_version '0.3.1'
59
59
 
60
60
  create_makefile 'swift'
@@ -1,19 +1,31 @@
1
1
  #include "query.h"
2
2
 
3
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
- );
4
+ try {
5
+ return UINT2NUM(
6
+ query->bind.size() == 0
7
+ ? query->handle->conn()->execute(query->sql)
8
+ : query->handle->conn()->execute(query->sql, query->bind)
9
+ );
10
+ }
11
+ catch (dbi::Error &e) {
12
+ query->error = e.what();
13
+ return Qfalse;
14
+ }
9
15
  }
10
16
 
11
17
  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
- );
18
+ try {
19
+ return UINT2NUM(
20
+ query->bind.size() == 0
21
+ ? query->statement->execute()
22
+ : query->statement->execute(query->bind)
23
+ );
24
+ }
25
+ catch (dbi::Error &e) {
26
+ query->error = e.what();
27
+ return Qfalse;
28
+ }
17
29
  }
18
30
 
19
31
  void query_bind_values(Query *query, VALUE bind_values) {
@@ -23,6 +35,12 @@ void query_bind_values(Query *query, VALUE bind_values) {
23
35
  if (bind_value == Qnil) {
24
36
  query->bind.push_back(dbi::PARAM(dbi::null()));
25
37
  }
38
+ else if (bind_value == Qtrue) {
39
+ query->bind.push_back(dbi::PARAM("1"));
40
+ }
41
+ else if (bind_value == Qfalse) {
42
+ query->bind.push_back(dbi::PARAM("0"));
43
+ }
26
44
  else if (rb_obj_is_kind_of(bind_value, rb_cIO) == Qtrue || rb_obj_is_kind_of(bind_value, cStringIO) == Qtrue) {
27
45
  bind_value = rb_funcall(bind_value, rb_intern("read"), 0);
28
46
  query->bind.push_back(dbi::PARAM_BINARY((unsigned char*)RSTRING_PTR(bind_value), RSTRING_LEN(bind_value)));
@@ -8,6 +8,7 @@ struct Query {
8
8
  dbi::Handle *handle;
9
9
  dbi::AbstractStatement *statement;
10
10
  dbi::ResultRow bind;
11
+ const char *error;
11
12
  };
12
13
 
13
14
  VALUE query_execute(Query*);
@@ -1,9 +1,10 @@
1
1
  #include "result.h"
2
2
 
3
- VALUE cSwiftResult;
3
+ VALUE cBigDecimal;
4
+ VALUE cDate;
4
5
  VALUE cDateTime;
5
6
  VALUE cStringIO;
6
- VALUE cBigDecimal;
7
+ VALUE cSwiftResult;
7
8
 
8
9
  VALUE fNew, fNewBang;
9
10
 
@@ -91,6 +92,7 @@ static VALUE result_finish(VALUE self) {
91
92
  int64_t client_tzoffset(int64_t local, int isdst) {
92
93
  struct tm tm;
93
94
  gmtime_r((const time_t*)&local, &tm);
95
+ // TODO: This won't work in Lord Howe Island, Australia which uses half hour shift.
94
96
  return (int64_t)(local + (isdst ? 3600 : 0) - mktime(&tm));
95
97
  }
96
98
 
@@ -106,7 +108,7 @@ static void reduce(uint64_t *numerator, uint64_t *denominator) {
106
108
  *denominator = *denominator / b;
107
109
  }
108
110
 
109
- VALUE typecast_datetime(const char *data, uint64_t len) {
111
+ VALUE typecast_timestamp(VALUE klass, const char *data, uint64_t len) {
110
112
  struct tm tm;
111
113
  int64_t epoch, adjust, offset;
112
114
 
@@ -141,24 +143,27 @@ VALUE typecast_datetime(const char *data, uint64_t len) {
141
143
  }
142
144
 
143
145
  // 32bit platforms are for weenies
144
- uint64_t ajd_n = (epoch + adjust - offset), ajd_d = 86400L;
146
+ uint64_t ajd_n = (epoch + adjust - offset)*1000000 + usec*1000000, ajd_d = DAYMICROSECS;
145
147
  reduce(&ajd_n, &ajd_d);
146
148
  ajd_n = epoch_ajd_n*ajd_d + ajd_n*epoch_ajd_d;
147
149
  ajd_d = epoch_ajd_d*ajd_d;
148
150
  reduce(&ajd_n, &ajd_d);
149
151
 
150
152
  VALUE ajd = rb_rational_new(SIZET2NUM(ajd_n), SIZET2NUM(ajd_d));
151
- return rb_funcall(cDateTime, fNewBang, 3, ajd, rb_rational_new(INT2FIX(adjust), daysecs), sg);
153
+ return rb_funcall(klass, fNewBang, 3, ajd, rb_rational_new(INT2FIX(adjust), daysecs), sg);
152
154
  }
153
155
 
154
156
  // TODO: throw a warning ?
155
157
  return rb_str_new(data, len);
156
158
  }
157
159
 
160
+ #define typecast_datetime(data,len) typecast_timestamp(cDateTime, data, len)
161
+ #define typecast_date(data,len) typecast_timestamp(cDate, data, len)
162
+
158
163
  VALUE typecast_field(int type, const char *data, uint64_t length) {
159
164
  switch(type) {
160
165
  case DBI_TYPE_BOOLEAN:
161
- return strcmp(data, "t") == 0 || strcmp(data, "1") == 0 ? Qtrue : Qfalse;
166
+ return (data && (data[0] =='t' || data[0] == '1')) ? Qtrue : Qfalse;
162
167
  case DBI_TYPE_INT:
163
168
  return rb_cstr2inum(data, 10);
164
169
  case DBI_TYPE_BLOB:
@@ -167,6 +172,8 @@ VALUE typecast_field(int type, const char *data, uint64_t length) {
167
172
  return rb_enc_str_new(data, length, rb_utf8_encoding());
168
173
  case DBI_TYPE_TIME:
169
174
  return typecast_datetime(data, length);
175
+ case DBI_TYPE_DATE:
176
+ return typecast_date(data, length);
170
177
  case DBI_TYPE_NUMERIC:
171
178
  return rb_funcall(cBigDecimal, fNew, 1, rb_str_new2(data));
172
179
  case DBI_TYPE_FLOAT:
@@ -219,6 +226,7 @@ void init_swift_result() {
219
226
  VALUE mSwift = rb_define_module("Swift");
220
227
  cSwiftResult = rb_define_class_under(mSwift, "Result", rb_cObject);
221
228
  cDateTime = CONST_GET(rb_mKernel, "DateTime");
229
+ cDate = CONST_GET(rb_mKernel, "Date");
222
230
  cStringIO = CONST_GET(rb_mKernel, "StringIO");
223
231
  cBigDecimal = CONST_GET(rb_mKernel, "BigDecimal");
224
232
 
@@ -37,10 +37,8 @@ static VALUE statement_execute(int argc, VALUE *argv, VALUE self) {
37
37
  if (RARRAY_LEN(bind_values) > 0) query_bind_values(&query, bind_values);
38
38
  if (dbi::_trace) dbi::logMessage(dbi::_trace_fd, dbi::formatParams(statement->command(), query.bind));
39
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);
40
+ if (rb_thread_blocking_region(((VALUE (*)(void*))query_execute_statement), &query, RUBY_UBF_IO, 0) == Qfalse)
41
+ rb_raise(eSwiftRuntimeError, "%s", query.error);
44
42
  }
45
43
  CATCH_DBI_EXCEPTIONS();
46
44
 
@@ -17,10 +17,10 @@ extern VALUE eSwiftConnectionError;
17
17
 
18
18
  #define CATCH_DBI_EXCEPTIONS() \
19
19
  catch (dbi::ConnectionError &error) { \
20
- rb_raise(eSwiftConnectionError, "%s", CSTRING(rb_str_new2(error.what()))); \
20
+ rb_raise(eSwiftConnectionError, "%s", error.what()); \
21
21
  } \
22
22
  catch (dbi::Error &error) { \
23
- rb_raise(eSwiftRuntimeError, "%s", CSTRING(rb_str_new2(error.what()))); \
23
+ rb_raise(eSwiftRuntimeError, "%s", error.what()); \
24
24
  }
25
25
 
26
26
  #include "adapter.h"
@@ -31,5 +31,13 @@ extern VALUE eSwiftConnectionError;
31
31
  #include "request.h"
32
32
  #include "pool.h"
33
33
 
34
+ #undef SIZET2NUM
35
+ #ifdef HAVE_LONG_LONG
36
+ #define SIZET2NUM(x) ULL2NUM(x)
37
+ #define DAYMICROSECS 86400000000LL
38
+ #else
39
+ #define SIZET2NUM(x) ULONG2NUM(x)
40
+ #define DAYMICROSECS 86400000000L
34
41
  #endif
35
42
 
43
+ #endif
@@ -107,7 +107,7 @@ module Swift
107
107
  when Type::Integer then attribute.serial ? 'serial' : 'integer'
108
108
  when Type::Float then 'float'
109
109
  when Type::BigDecimal then 'numeric'
110
- when Type::Time then 'timestamp'
110
+ when Type::DateTime then 'timestamp'
111
111
  when Type::Boolean then 'boolean'
112
112
  when Type::IO then 'blob'
113
113
  else 'text'
@@ -2,11 +2,12 @@ module Swift
2
2
  module Type
3
3
  class BigDecimal < Attribute; end
4
4
  class Boolean < Attribute; end
5
+ class Date < Attribute; end
6
+ class DateTime < Attribute; end
5
7
  class Float < Attribute; end
6
8
  class Integer < Attribute; end
7
9
  class IO < Attribute; end
8
10
  class String < Attribute; end
9
- class Time < Attribute; end
10
11
  end # Type
11
12
  end # Swift
12
13
 
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{swift}
8
- s.version = "0.5.1"
8
+ s.version = "0.6.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Shane Hanna", "Bharanee 'Barney' Rathna"]
12
- s.date = %q{2010-08-30}
12
+ s.date = %q{2010-09-02}
13
13
  s.description = %q{A rational rudimentary database abstraction.}
14
14
  s.email = ["shane.hanna@gmail.com", "deepfryed@gmail.com"]
15
15
  s.extensions = ["ext/extconf.rb"]
@@ -63,12 +63,13 @@ Gem::Specification.new do |s|
63
63
  "test/test_scheme.rb",
64
64
  "test/test_timestamps.rb",
65
65
  "test/test_transactions.rb",
66
+ "test/test_types.rb",
66
67
  "test/test_validations.rb"
67
68
  ]
68
69
  s.homepage = %q{http://github.com/shanna/swift}
69
70
  s.rdoc_options = ["--charset=UTF-8"]
70
71
  s.require_paths = ["lib"]
71
- s.rubygems_version = %q{1.3.7}
72
+ s.rubygems_version = %q{1.3.6}
72
73
  s.summary = %q{A rational rudimentary database abstraction.}
73
74
  s.test_files = [
74
75
  "test/test_pool.rb",
@@ -82,6 +83,7 @@ Gem::Specification.new do |s|
82
83
  "test/test_encoding.rb",
83
84
  "test/test_timestamps.rb",
84
85
  "test/test_scheme.rb",
86
+ "test/test_types.rb",
85
87
  "examples/scheme.rb",
86
88
  "examples/async.rb",
87
89
  "examples/db.rb"
@@ -91,7 +93,7 @@ Gem::Specification.new do |s|
91
93
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
92
94
  s.specification_version = 3
93
95
 
94
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
96
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
95
97
  s.add_development_dependency(%q<minitest>, [">= 1.7.0"])
96
98
  s.add_development_dependency(%q<eventmachine>, [">= 0"])
97
99
  else
@@ -4,12 +4,12 @@ describe 'scheme' do
4
4
  before do
5
5
  @user = Class.new(Swift::Scheme) do
6
6
  store :users
7
- attribute :id, Swift::Type::Integer, serial: true, key: true
8
- attribute :name, Swift::Type::String, default: "dave"
9
- attribute :age, Swift::Type::Integer, default: 18
7
+ attribute :id, Swift::Type::Integer, serial: true, key: true
8
+ attribute :name, Swift::Type::String, default: "dave"
9
+ attribute :age, Swift::Type::Integer, default: 18
10
10
  attribute :email, Swift::Type::String
11
- attribute :verified, Swift::Type::Boolean, default: false
12
- attribute :created_at, Swift::Type::Time, default: proc { Time.now }
11
+ attribute :verified, Swift::Type::Boolean, default: false
12
+ attribute :created_at, Swift::Type::DateTime, default: proc { Time.now }
13
13
  end
14
14
  end
15
15
 
@@ -0,0 +1,29 @@
1
+ require_relative 'helper'
2
+
3
+ describe 'Adapter' do
4
+ supported_by Swift::DB::Postgres, Swift::DB::Mysql do
5
+ describe 'typecasting' do
6
+ before do
7
+ @db = Swift.db
8
+ @db.execute %q{drop table if exists users}
9
+ @db.execute %q{
10
+ create table users(id serial, name text, age integer, height float, hacker bool, slacker bool, created date)
11
+ }
12
+ end
13
+
14
+ it 'query result is typecast correctly' do
15
+ bind = [ 'jim', 32, 178.71, true, false ]
16
+ @db.execute %q{insert into users(name,age,height,hacker,slacker, created) values(?, ?, ?, ?, ?, now())}, *bind
17
+
18
+ result = @db.prepare(%q{select * from users limit 1}).execute.first
19
+ assert_kind_of Integer, result[:id]
20
+ assert_kind_of String, result[:name]
21
+ assert_kind_of Integer, result[:age]
22
+ assert_kind_of Float, result[:height]
23
+ assert_kind_of TrueClass, result[:hacker]
24
+ assert_kind_of FalseClass, result[:slacker]
25
+ assert_kind_of Date, result[:created]
26
+ end
27
+ end
28
+ end
29
+ end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 5
8
- - 1
9
- version: 0.5.1
7
+ - 6
8
+ - 0
9
+ version: 0.6.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Shane Hanna
@@ -15,14 +15,13 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-08-30 00:00:00 +10:00
18
+ date: 2010-09-02 00:00:00 +10:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
22
  name: minitest
23
23
  prerelease: false
24
24
  requirement: &id001 !ruby/object:Gem::Requirement
25
- none: false
26
25
  requirements:
27
26
  - - ">="
28
27
  - !ruby/object:Gem::Version
@@ -37,7 +36,6 @@ dependencies:
37
36
  name: eventmachine
38
37
  prerelease: false
39
38
  requirement: &id002 !ruby/object:Gem::Requirement
40
- none: false
41
39
  requirements:
42
40
  - - ">="
43
41
  - !ruby/object:Gem::Version
@@ -103,10 +101,8 @@ files:
103
101
  - test/test_scheme.rb
104
102
  - test/test_timestamps.rb
105
103
  - test/test_transactions.rb
104
+ - test/test_types.rb
106
105
  - test/test_validations.rb
107
- - examples/scheme.rb
108
- - examples/async.rb
109
- - examples/db.rb
110
106
  has_rdoc: true
111
107
  homepage: http://github.com/shanna/swift
112
108
  licenses: []
@@ -117,7 +113,6 @@ rdoc_options:
117
113
  require_paths:
118
114
  - lib
119
115
  required_ruby_version: !ruby/object:Gem::Requirement
120
- none: false
121
116
  requirements:
122
117
  - - ">="
123
118
  - !ruby/object:Gem::Version
@@ -125,7 +120,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
125
120
  - 0
126
121
  version: "0"
127
122
  required_rubygems_version: !ruby/object:Gem::Requirement
128
- none: false
129
123
  requirements:
130
124
  - - ">="
131
125
  - !ruby/object:Gem::Version
@@ -135,7 +129,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
135
129
  requirements: []
136
130
 
137
131
  rubyforge_project:
138
- rubygems_version: 1.3.7
132
+ rubygems_version: 1.3.6
139
133
  signing_key:
140
134
  specification_version: 3
141
135
  summary: A rational rudimentary database abstraction.
@@ -151,6 +145,7 @@ test_files:
151
145
  - test/test_encoding.rb
152
146
  - test/test_timestamps.rb
153
147
  - test/test_scheme.rb
148
+ - test/test_types.rb
154
149
  - examples/scheme.rb
155
150
  - examples/async.rb
156
151
  - examples/db.rb