swift 0.8.1 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
data/API.rdoc CHANGED
@@ -16,15 +16,15 @@ Public API minus the optional stuff like Pool, IdentityMap, Migrations etc.
16
16
  #all #=> Result
17
17
  #begin #=> Adapter
18
18
  #commit
19
- #create #=> Scheme
20
- #destroy #=> Result
19
+ #create #=> Scheme or Result
20
+ #destroy #=> Scheme or Result
21
21
  #execute #=> Result
22
22
  #first #=> Scheme
23
23
  #get #=> Scheme
24
24
  #prepare #=> Statement
25
25
  #rollback
26
26
  #transaction #=> Adapter
27
- #update #=> Result
27
+ #update #=> Scheme or Result
28
28
  #reconnect
29
29
  #delete #=> Result
30
30
 
@@ -50,7 +50,7 @@ Public API minus the optional stuff like Pool, IdentityMap, Migrations etc.
50
50
  Scheme
51
51
  .all #=> Result
52
52
  .attribute #=> Type
53
- .create #=> Scheme
53
+ .create #=> Scheme or Result
54
54
  .first #=> Scheme
55
55
  .get #=> Scheme
56
56
  .header #=> Header
@@ -58,9 +58,9 @@ Public API minus the optional stuff like Pool, IdentityMap, Migrations etc.
58
58
  .new #=> Scheme
59
59
  .scheme #=> Alias for self.class
60
60
  .store #=> Symbol
61
- #destroy #=> Result
61
+ #destroy #=> Scheme or Result
62
62
  #tuple #=> Hash
63
- #update #=> Result
63
+ #update #=> Scheme or Result
64
64
 
65
65
  # Enumerable collection of Types for Scheme
66
66
  Header
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.8.1
1
+ 0.9.0
data/ext/result.cc CHANGED
@@ -158,7 +158,7 @@ VALUE typecast_timestamp(const char *data, uint64_t len, const char *zone) {
158
158
  lastmatch++;
159
159
  }
160
160
  subsec[idx] = 0;
161
- usec = atoll(subsec);
161
+ usec = round(atoll(subsec) * (1000000 / pow(10, idx)));
162
162
  }
163
163
 
164
164
  tm.tm_year -= 1900;
data/lib/swift/adapter.rb CHANGED
@@ -25,8 +25,8 @@ module Swift
25
25
  #--
26
26
  # NOTE: Not significantly shorter than Scheme.db.first(User, 'id = ?', 12)
27
27
  def get scheme, keys
28
- relation = scheme.new(keys)
29
- prepare_get(scheme).execute(*relation.tuple.values_at(*scheme.header.keys)).first
28
+ resource = scheme.new(keys)
29
+ prepare_get(scheme).execute(*resource.tuple.values_at(*scheme.header.keys)).first
30
30
  end
31
31
 
32
32
  # Select one or more.
@@ -73,32 +73,58 @@ module Swift
73
73
  prepare(scheme, "select * from #{scheme.store} #{where} limit 1").execute(*binds, &block).first
74
74
  end
75
75
 
76
+ # Delete one or more.
77
+ #
78
+ # The SQL condition form of Swift::Adapter.destroy.
79
+ #
80
+ # @example All.
81
+ # Swift.db.delete(User)
82
+ # @example All with conditions and binds.
83
+ # Swift.db.delete(User, ':name = ? and :age > ?', 'Apple Arthurton', 32)
84
+ #
85
+ # @param [Swift::Scheme] scheme Concrete scheme subclass
86
+ # @param [String] conditions Optional SQL 'where' fragment.
87
+ # @param [Object, ...] *binds Optional bind values that accompany conditions SQL fragment.
88
+ # @return [Swift::Result]
89
+ def delete scheme, conditions = '', *binds
90
+ sql = "delete from #{scheme.store}"
91
+ sql += " where #{exchange_names(scheme, conditions)}" unless conditions.empty?
92
+ execute(sql, *binds)
93
+ end
94
+
76
95
  # Create one or more.
77
96
  #
78
97
  # @example Scheme.
79
98
  # user = User.new(name: 'Apply Arthurton', age: 32)
80
99
  # Swift.db.create(User, user)
100
+ # #=> Swift::Scheme
81
101
  # @example Coerce hash to scheme.
82
102
  # Swif.db.create(User, name: 'Apple Arthurton', age: 32)
83
- # @example Multiple relations.
103
+ # #=> Swift::Scheme
104
+ # @example Multiple resources.
84
105
  # apple = User.new(name: 'Apple Arthurton', age: 32)
85
106
  # benny = User.new(name: 'Benny Arthurton', age: 30)
86
- # Swift.db.create(User, apple, benny)
87
- # @example Coerce multiple relations.
88
- # Swift.db.create(User, {name: 'Apple Arthurton', age: 32}, {name: 'Benny Arthurton', age: 30})
107
+ # Swift.db.create(User, [apple, benny])
108
+ # #=> Array<Swift::Scheme>
109
+ # @example Coerce multiple resources.
110
+ # Swift.db.create(User, [{name: 'Apple Arthurton', age: 32}, {name: 'Benny Arthurton', age: 30}])
111
+ # #=> Array<Swift::Scheme>
89
112
  #
90
- # @param [Swift::Scheme] scheme Concrete scheme subclass to load.
91
- # @param [Swift::Scheme, Hash> *relations Scheme or tuple hash. Hashes will be coerced into scheme via Swift::Scheme#new
92
- # @return [Array<Swift::Scheme>]
113
+ # @param [Swift::Scheme] scheme Concrete scheme subclass to load.
114
+ # @param [Swift::Scheme, Hash, Array<Swift::Scheme, Hash>] resources The resources to be saved.
115
+ # @return [Swift::Scheme, Array<Swift::Scheme>]
116
+ # @note Hashes will be coerced into a Swift::Scheme resource via Swift::Scheme#new
117
+ # @note Passing a scalar will result in a scalar.
93
118
  # @see Swift::Scheme.create
94
- def create scheme, *relations
119
+ def create scheme, resources
95
120
  statement = prepare_create(scheme)
96
- relations.map do |relation|
97
- relation = scheme.new(relation) unless relation.kind_of?(scheme)
98
- result = statement.execute(*relation.tuple.values_at(*scheme.header.insertable))
99
- relation.tuple[scheme.header.serial] = result.insert_id if scheme.header.serial
100
- relation
121
+ result = [resources].flatten.map do |resource|
122
+ resource = scheme.new(resource) unless resource.kind_of?(scheme)
123
+ result = statement.execute(*resource.tuple.values_at(*scheme.header.insertable))
124
+ resource.tuple[scheme.header.serial] = result.insert_id if scheme.header.serial
125
+ resource
101
126
  end
127
+ resources.kind_of?(Enumerable) ? result : result.first
102
128
  end
103
129
 
104
130
  # Update one or more.
@@ -107,32 +133,43 @@ module Swift
107
133
  # user = Swift.db.create(User, name: 'Apply Arthurton', age: 32)
108
134
  # user.name = 'Arthur Appleton'
109
135
  # Swift.db.update(User, user)
136
+ # #=> Swift::Scheme
110
137
  # @example Coerce hash to scheme.
111
138
  # user = Swift.db.create(User, name: 'Apply Arthurton', age: 32)
112
139
  # user.name = 'Arthur Appleton'
113
140
  # Swif.db.update(User, user.tuple)
114
- # @example Multiple relations.
141
+ # #=> Swift::Scheme
142
+ # @example Multiple resources.
115
143
  # apple = Swift.db.create(User, name: 'Apple Arthurton', age: 32)
116
144
  # benny = Swift.db.create(User, name: 'Benny Arthurton', age: 30)
117
- # Swift.db.update(User, apple, benny)
118
- # @example Coerce multiple relations.
145
+ # Swift.db.update(User, [apple, benny])
146
+ # #=> Array<Swift::Scheme>
147
+ # @example Coerce multiple resources.
119
148
  # apple = Swift.db.create(User, name: 'Apple Arthurton', age: 32)
120
149
  # benny = Swift.db.create(User, name: 'Benny Arthurton', age: 30)
121
- # Swift.db.update(User, apple.tuple, benny.tuple)
150
+ # Swift.db.update(User, [apple.tuple, benny.tuple])
151
+ # #=> Array<Swift::Scheme>
122
152
  #
123
- # @param [Swift::Scheme] scheme Concrete scheme subclass to load.
124
- # @param [Swift::Scheme, Hash> *relations Scheme or tuple hash. Hashes will be coerced into scheme via Swift::Scheme#new
125
- # @return [Array<Swift::Scheme>]
153
+ # @param [Swift::Scheme] scheme Concrete scheme subclass to load.
154
+ # @param [Swift::Scheme, Hash, Array<Swift::Scheme, Hash>] resources The resources to be updated.
155
+ # @return [Swift::Scheme, Swift::Result<Swift::Scheme>]
156
+ # @note Hashes will be coerced into a Swift::Scheme resource via Swift::Scheme#new
157
+ # @note Passing a scalar will result in a scalar.
126
158
  # @see Swift::Scheme#update
127
- def update scheme, *relations
159
+ def update scheme, resources
128
160
  statement = prepare_update(scheme)
129
- relations.map do |relation|
130
- relation = scheme.new(relation) unless relation.kind_of?(scheme)
131
- keys = relation.tuple.values_at(*scheme.header.keys)
132
- raise ArgumentError, "relation has incomplete key : #{relation.inspect}" unless keys.select(&:nil?).empty?
133
- statement.execute(*relation.tuple.values_at(*scheme.header.updatable), *keys)
134
- relation
161
+ result = [resources].flatten.map do |resource|
162
+ resource = scheme.new(resource) unless resource.kind_of?(scheme)
163
+ keys = resource.tuple.values_at(*scheme.header.keys)
164
+
165
+ # TODO: Name the key field(s) missing.
166
+ raise ArgumentError, "#{scheme} resource has incomplete key: #{resource.inspect}" \
167
+ unless keys.select(&:nil?).empty?
168
+
169
+ statement.execute(*resource.tuple.values_at(*scheme.header.updatable), *keys)
170
+ resource
135
171
  end
172
+ resources.kind_of?(Enumerable) ? result : result.first
136
173
  end
137
174
 
138
175
  # Destroy one or more.
@@ -145,49 +182,40 @@ module Swift
145
182
  # user = Swift.db.create(User, name: 'Apply Arthurton', age: 32)
146
183
  # user.name = 'Arthur Appleton'
147
184
  # Swif.db.destroy(User, user.tuple)
148
- # @example Multiple relations.
185
+ # @example Multiple resources.
149
186
  # apple = Swift.db.create(User, name: 'Apple Arthurton', age: 32)
150
187
  # benny = Swift.db.create(User, name: 'Benny Arthurton', age: 30)
151
- # Swift.db.destroy(User, apple, benny)
152
- # @example Coerce multiple relations.
188
+ # Swift.db.destroy(User, [apple, benny])
189
+ # @example Coerce multiple resources.
153
190
  # apple = Swift.db.create(User, name: 'Apple Arthurton', age: 32)
154
191
  # benny = Swift.db.create(User, name: 'Benny Arthurton', age: 30)
155
- # Swift.db.destroy(User, apple.tuple, benny.tuple)
192
+ # Swift.db.destroy(User, [apple.tuple, benny.tuple])
156
193
  #
157
- # @param [Swift::Scheme] scheme Concrete scheme subclass to load.
158
- # @param [Swift::Scheme, Hash] *relations Scheme or tuple hash. Hashes will be coerced into scheme via Swift::Scheme#new
194
+ # @param [Swift::Scheme] scheme Concrete scheme subclass to load.
195
+ # @param [Swift::Scheme, Hash, Array<Swift::Scheme, Hash>] resources The resources to be destroyed.
196
+ # @return [Swift::Scheme, Array<Swift::Scheme>]
197
+ # @note Hashes will be coerced into a Swift::Scheme resource via Swift::Scheme#new
198
+ # @note Passing a scalar will result in a scalar.
159
199
  # @see Swift::Scheme#destroy
160
- def destroy scheme, *relations
200
+ def destroy scheme, resources
161
201
  statement = prepare_destroy(scheme)
162
- relations.map do |relation|
163
- relation = scheme.new(relation) unless relation.kind_of?(scheme)
164
- keys = relation.tuple.values_at(*scheme.header.keys)
165
- raise ArgumentError, "relation has incomplete key : #{relation.inspect}" unless keys.select(&:nil?).empty?
202
+ result = [resources].flatten.map do |resource|
203
+ resource = scheme.new(resource) unless resource.kind_of?(scheme)
204
+ keys = resource.tuple.values_at(*scheme.header.keys)
205
+
206
+ # TODO: Name the key field(s) missing.
207
+ raise ArgumentError, "#{scheme} resource has incomplete key: #{resource.inspect}" \
208
+ unless keys.select(&:nil?).empty?
209
+
166
210
  if result = statement.execute(*keys)
167
- relation.freeze
211
+ resource.freeze
168
212
  end
169
213
  result
170
214
  end
215
+ resources.kind_of?(Enumerable) ? result : result.first
171
216
  end
172
217
 
173
218
 
174
- # Delete one or more rows
175
- #
176
- # @example All.
177
- # Swift.db.delete(User)
178
- # @example All with conditions and binds.
179
- # Swift.db.delete(User, ':name = ? and :age > ?', 'Apple Arthurton', 32)
180
- #
181
- # @param [Swift::Scheme] scheme Concrete scheme subclass
182
- # @param [String] conditions Optional SQL 'where' fragment.
183
- # @param [Object, ...] *binds Optional bind values that accompany conditions SQL fragment.
184
- # @return [Swift::Result]
185
- def delete scheme, conditions = '', *binds
186
- sql = "delete from #{scheme.store}"
187
- sql += " where #{exchange_names(scheme, conditions)}" unless conditions.empty?
188
- execute(sql, *binds)
189
- end
190
-
191
219
  def migrate! scheme
192
220
  keys = scheme.header.keys
193
221
  fields = scheme.header.map{|p| field_definition(p)}.join(', ')
data/lib/swift/scheme.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  module Swift
2
2
 
3
- # A relation (instance) definition.
3
+ # A resource (instance) definition.
4
4
  #
5
5
  # @example A user scheme.
6
6
  # class User < Swift::Scheme
@@ -10,8 +10,6 @@ module Swift
10
10
  # attribute :email, Swift::Type::String
11
11
  # attribute :updated_at, Swift::Type::Time
12
12
  # end # User
13
- #
14
- # @todo Tuple should be renamed tuples (plural?)
15
13
  class Scheme
16
14
  attr_accessor :tuple
17
15
  alias_method :scheme, :class
@@ -22,7 +20,7 @@ module Swift
22
20
  # email: 'apple@arthurton.local',
23
21
  # updated_at: Time.now
24
22
  # )
25
- # @param [Hash] options Create relation and set attributes. <tt>{name: value}</tt>
23
+ # @param [Hash] options Create resource and set attributes. <tt>{name: value}</tt>
26
24
  def initialize options = {}
27
25
  @tuple = scheme.header.new_tuple
28
26
  options.each{|k, v| send(:"#{k}=", v)}
@@ -49,8 +47,8 @@ module Swift
49
47
  # updated_at: Time.now
50
48
  # )
51
49
  # apple.destroy
52
- def destroy
53
- Swift.db.destroy(scheme, self)
50
+ def destroy resources = self
51
+ Swift.db.destroy(scheme, resources)
54
52
  end
55
53
 
56
54
  class << self
@@ -62,6 +60,7 @@ module Swift
62
60
  def inherited klass
63
61
  klass.header = Header.new
64
62
  klass.header.push(*header) if header
63
+ klass.store store if store
65
64
  Swift.schema.push(klass) if klass.name
66
65
  end
67
66
 
@@ -96,9 +95,9 @@ module Swift
96
95
  # updated_at: Time.now
97
96
  # )
98
97
  #
99
- # @param [Hash] options Create with attributes. <tt>{name: value}</tt>
100
- def create options = {}
101
- Swift.db.create(self, options)
98
+ # @param [Hash, Array<Hash>] options Create with attributes. <tt>{name: value}</tt>
99
+ def create resources = {}
100
+ Swift.db.create(self, resources)
102
101
  end
103
102
 
104
103
  # Select by id(s).
data/swift.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{swift}
8
- s.version = "0.8.1"
8
+ s.version = "0.9.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{2011-01-19}
12
+ s.date = %q{2011-02-10}
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"]
data/test/test_scheme.rb CHANGED
@@ -78,7 +78,7 @@ describe 'scheme' do
78
78
  end
79
79
 
80
80
  it 'adapter should delete only relevant rows given condition & scheme' do
81
- Swift.db.create(@user, {name: 'dave'}, {name: 'mike'})
81
+ Swift.db.create(@user, [{name: 'dave'}, {name: 'mike'}])
82
82
  assert_equal 2, @user.all.rows
83
83
 
84
84
  Swift.db.delete @user, ':name = ?', 'dave'
data/test/test_types.rb CHANGED
@@ -26,7 +26,7 @@ describe 'Adapter' do
26
26
 
27
27
  it 'query result is typecast correctly' do
28
28
  dt = '2010-01-01 23:22:21'
29
- bind = [ 1, 'jim', 32, 178.71, true, false, '2010-01-02', "#{dt}.012345+11:00" ]
29
+ bind = [ 1, 'jim', 32, 178.71, true, false, '2010-01-02', "#{dt}.065+11:00" ]
30
30
  @db.execute %q{insert into users values(?, ?, ?, ?, ?, ?, ?, ?)}, *bind
31
31
 
32
32
  result = @db.prepare(%q{select * from users limit 1}).execute.first
@@ -40,7 +40,7 @@ describe 'Adapter' do
40
40
  assert_kind_of Time, result[:updated]
41
41
 
42
42
  assert_equal dt, result[:updated].strftime('%F %T')
43
- assert_equal 12345, result[:updated].usec unless @db.kind_of?(Swift::DB::Mysql)
43
+ assert_equal 65000, result[:updated].usec unless @db.kind_of?(Swift::DB::Mysql)
44
44
  end
45
45
  end
46
46
  end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 8
8
- - 1
9
- version: 0.8.1
7
+ - 9
8
+ - 0
9
+ version: 0.9.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Shane Hanna
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-01-19 00:00:00 +11:00
18
+ date: 2011-02-10 00:00:00 +11:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency