swift 0.10.0 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- data/API.rdoc +9 -16
- data/README.rdoc +10 -7
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/ext/adapter.cc +155 -25
- data/ext/extconf.rb +3 -3
- data/ext/pool.cc +1 -1
- data/ext/result.cc +2 -2
- data/ext/statement.cc +1 -1
- data/ext/swift.cc +49 -4
- data/ext/swift.h +2 -1
- data/lib/swift/adapter/sql.rb +69 -0
- data/lib/swift/adapter.rb +15 -136
- data/lib/swift/attribute.rb +7 -0
- data/lib/swift/db.rb +5 -3
- data/lib/swift/migrations.rb +51 -8
- data/lib/swift/scheme.rb +32 -36
- data/lib/swift.rb +2 -1
- data/swift.gemspec +10 -25
- data/test/helper.rb +6 -0
- data/test/minitest_teardown_hack.rb +20 -0
- data/test/test_scheme.rb +17 -22
- data/test/test_swift.rb +71 -0
- metadata +42 -78
- data/examples/async.rb +0 -65
- data/examples/db.rb +0 -44
- data/examples/scheme.rb +0 -54
data/lib/swift/adapter.rb
CHANGED
@@ -4,10 +4,6 @@ module Swift
|
|
4
4
|
#
|
5
5
|
# @abstract
|
6
6
|
# @see Swift::DB See Swift::DB for concrete adapters.
|
7
|
-
# @todo For the time being all adapters are SQL and DBIC++ centric. It would be super easy to abstract though I
|
8
|
-
# don't know if you would be better off doing it at the Ruby or DBIC++ level (or both).
|
9
|
-
#--
|
10
|
-
# TODO: Extension methods are undocumented.
|
11
7
|
class Adapter
|
12
8
|
attr_reader :options
|
13
9
|
|
@@ -29,69 +25,6 @@ module Swift
|
|
29
25
|
prepare_get(scheme).execute(*resource.tuple.values_at(*scheme.header.keys)).first
|
30
26
|
end
|
31
27
|
|
32
|
-
# Select one or more.
|
33
|
-
#
|
34
|
-
# @example All.
|
35
|
-
# Swif.db.all(User)
|
36
|
-
# @example All with conditions and binds.
|
37
|
-
# Swift.db.all(User, ':name = ? and :age > ?', 'Apple Arthurton', 32)
|
38
|
-
# @example Block form iterator.
|
39
|
-
# Swift.db.all(User, ':age > ?', 32) do |user|
|
40
|
-
# puts user.name
|
41
|
-
# end
|
42
|
-
#
|
43
|
-
# @param [Swift::Scheme] scheme Concrete scheme subclass to load.
|
44
|
-
# @param [String] conditions Optional SQL 'where' fragment.
|
45
|
-
# @param [Object, ...] *binds Optional bind values that accompany conditions SQL fragment.
|
46
|
-
# @param [Proc] &block Optional 'each' iterator block.
|
47
|
-
# @return [Swift::Result]
|
48
|
-
# @see Swift::Scheme.all
|
49
|
-
def all scheme, conditions = '', *binds, &block
|
50
|
-
where = "where #{exchange_names(scheme, conditions)}" unless conditions.empty?
|
51
|
-
prepare(scheme, "select * from #{scheme.store} #{where}").execute(*binds, &block)
|
52
|
-
end
|
53
|
-
|
54
|
-
# Select one.
|
55
|
-
#
|
56
|
-
# @example First.
|
57
|
-
# Swif.db.first(User)
|
58
|
-
# @example First with conditions and binds.
|
59
|
-
# Swift.db.first(User, ':name = ? and :age > ?', 'Apple Arthurton', 32)
|
60
|
-
# @example Block form iterator.
|
61
|
-
# Swift.db.first(User, ':age > ?', 32) do |user|
|
62
|
-
# puts user.name
|
63
|
-
# end
|
64
|
-
#
|
65
|
-
# @param [Swift::Scheme] scheme Concrete scheme subclass to load.
|
66
|
-
# @param [String] conditions Optional SQL 'where' fragment.
|
67
|
-
# @param [Object, ...] *binds Optional bind values that accompany conditions SQL fragment.
|
68
|
-
# @param [Proc] &block Optional 'each' iterator block.
|
69
|
-
# @return [Swift::Scheme, nil]
|
70
|
-
# @see Swift::Scheme.first
|
71
|
-
def first scheme, conditions = '', *binds, &block
|
72
|
-
where = "where #{exchange_names(scheme, conditions)}" unless conditions.empty?
|
73
|
-
prepare(scheme, "select * from #{scheme.store} #{where} limit 1").execute(*binds, &block).first
|
74
|
-
end
|
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
|
-
|
95
28
|
# Create one or more.
|
96
29
|
#
|
97
30
|
# @example Scheme.
|
@@ -152,7 +85,7 @@ module Swift
|
|
152
85
|
#
|
153
86
|
# @param [Swift::Scheme] scheme Concrete scheme subclass to load.
|
154
87
|
# @param [Swift::Scheme, Hash, Array<Swift::Scheme, Hash>] resources The resources to be updated.
|
155
|
-
# @return [Swift::Scheme, Swift::Result
|
88
|
+
# @return [Swift::Scheme, Swift::Result]
|
156
89
|
# @note Hashes will be coerced into a Swift::Scheme resource via Swift::Scheme#new
|
157
90
|
# @note Passing a scalar will result in a scalar.
|
158
91
|
# @see Swift::Scheme#update
|
@@ -172,33 +105,33 @@ module Swift
|
|
172
105
|
resources.kind_of?(Array) ? result : result.first
|
173
106
|
end
|
174
107
|
|
175
|
-
#
|
108
|
+
# Delete one or more.
|
176
109
|
#
|
177
110
|
# @example Scheme.
|
178
111
|
# user = Swift.db.create(User, name: 'Apply Arthurton', age: 32)
|
179
112
|
# user.name = 'Arthur Appleton'
|
180
|
-
# Swift.db.
|
113
|
+
# Swift.db.delete(User, user)
|
181
114
|
# @example Coerce hash to scheme.
|
182
115
|
# user = Swift.db.create(User, name: 'Apply Arthurton', age: 32)
|
183
116
|
# user.name = 'Arthur Appleton'
|
184
|
-
# Swif.db.
|
117
|
+
# Swif.db.delete(User, user.tuple)
|
185
118
|
# @example Multiple resources.
|
186
119
|
# apple = Swift.db.create(User, name: 'Apple Arthurton', age: 32)
|
187
120
|
# benny = Swift.db.create(User, name: 'Benny Arthurton', age: 30)
|
188
|
-
# Swift.db.
|
121
|
+
# Swift.db.delete(User, [apple, benny])
|
189
122
|
# @example Coerce multiple resources.
|
190
123
|
# apple = Swift.db.create(User, name: 'Apple Arthurton', age: 32)
|
191
124
|
# benny = Swift.db.create(User, name: 'Benny Arthurton', age: 30)
|
192
|
-
# Swift.db.
|
125
|
+
# Swift.db.delete(User, [apple.tuple, benny.tuple])
|
193
126
|
#
|
194
127
|
# @param [Swift::Scheme] scheme Concrete scheme subclass to load.
|
195
|
-
# @param [Swift::Scheme, Hash, Array<Swift::Scheme, Hash>] resources The resources to be
|
128
|
+
# @param [Swift::Scheme, Hash, Array<Swift::Scheme, Hash>] resources The resources to be deleteed.
|
196
129
|
# @return [Swift::Scheme, Array<Swift::Scheme>]
|
197
130
|
# @note Hashes will be coerced into a Swift::Scheme resource via Swift::Scheme#new
|
198
131
|
# @note Passing a scalar will result in a scalar.
|
199
|
-
# @see Swift::Scheme#
|
200
|
-
def
|
201
|
-
statement =
|
132
|
+
# @see Swift::Scheme#delete
|
133
|
+
def delete scheme, resources
|
134
|
+
statement = prepare_delete(scheme)
|
202
135
|
result = [resources].flatten.map do |resource|
|
203
136
|
resource = scheme.new(resource) unless resource.kind_of?(scheme)
|
204
137
|
keys = resource.tuple.values_at(*scheme.header.keys)
|
@@ -215,76 +148,22 @@ module Swift
|
|
215
148
|
resources.kind_of?(Array) ? result : result.first
|
216
149
|
end
|
217
150
|
|
218
|
-
|
219
|
-
def migrate! scheme
|
220
|
-
keys = scheme.header.keys
|
221
|
-
fields = scheme.header.map{|p| field_definition(p)}.join(', ')
|
222
|
-
fields += ", primary key (#{keys.join(', ')})" unless keys.empty?
|
223
|
-
|
224
|
-
execute("drop table if exists #{scheme.store} cascade")
|
225
|
-
execute("create table #{scheme.store} (#{fields})")
|
226
|
-
end
|
227
|
-
|
228
151
|
protected
|
229
|
-
def exchange_names scheme, query
|
230
|
-
query.gsub(/:(\w+)/){ scheme.send($1.to_sym).field }
|
231
|
-
end
|
232
|
-
|
233
|
-
def returning?
|
234
|
-
raise NotImplementedError
|
235
|
-
end
|
236
|
-
|
237
|
-
def prepare_cached scheme, name, &block
|
238
|
-
@prepared ||= Hash.new{|h,k| h[k] = Hash.new} # Autovivification please Matz!
|
239
|
-
@prepared[scheme][name] ||= prepare(scheme, yield)
|
240
|
-
end
|
241
|
-
|
242
152
|
def prepare_get scheme
|
243
|
-
|
244
|
-
where = scheme.header.keys.map{|key| "#{key} = ?"}.join(' and ')
|
245
|
-
"select * from #{scheme.store} where #{where} limit 1"
|
246
|
-
end
|
153
|
+
raise NotImplementedError
|
247
154
|
end
|
248
155
|
|
249
156
|
def prepare_create scheme
|
250
|
-
|
251
|
-
values = (['?'] * scheme.header.insertable.size).join(', ')
|
252
|
-
returning = "returning #{scheme.header.serial}" if scheme.header.serial and returning?
|
253
|
-
"insert into #{scheme.store} (#{scheme.header.insertable.join(', ')}) values (#{values}) #{returning}"
|
254
|
-
end
|
157
|
+
raise NotImplementedError
|
255
158
|
end
|
256
159
|
|
257
160
|
def prepare_update scheme
|
258
|
-
|
259
|
-
set = scheme.header.updatable.map{|field| "#{field} = ?"}.join(', ')
|
260
|
-
where = scheme.header.keys.map{|key| "#{key} = ?"}.join(' and ')
|
261
|
-
"update #{scheme.store} set #{set} where #{where}"
|
262
|
-
end
|
263
|
-
end
|
264
|
-
|
265
|
-
def prepare_destroy scheme
|
266
|
-
prepare_cached(scheme, :destroy) do
|
267
|
-
where = scheme.header.keys.map{|key| "#{key} = ?"}.join(' and ')
|
268
|
-
"delete from #{scheme.store} where #{where}"
|
269
|
-
end
|
161
|
+
raise NotImplementedError
|
270
162
|
end
|
271
163
|
|
272
|
-
def
|
273
|
-
|
164
|
+
def prepare_delete scheme
|
165
|
+
raise NotImplementedError
|
274
166
|
end
|
275
167
|
|
276
|
-
def field_type attribute
|
277
|
-
case attribute
|
278
|
-
when Type::String then 'text'
|
279
|
-
when Type::Integer then attribute.serial ? 'serial' : 'integer'
|
280
|
-
when Type::Float then 'float'
|
281
|
-
when Type::BigDecimal then 'numeric'
|
282
|
-
when Type::Time then 'timestamp'
|
283
|
-
when Type::Date then 'date'
|
284
|
-
when Type::Boolean then 'boolean'
|
285
|
-
when Type::IO then 'blob'
|
286
|
-
else 'text'
|
287
|
-
end
|
288
|
-
end
|
289
168
|
end # Adapter
|
290
169
|
end # Swift
|
data/lib/swift/attribute.rb
CHANGED
@@ -29,6 +29,13 @@ module Swift
|
|
29
29
|
define_scheme_methods(scheme)
|
30
30
|
end
|
31
31
|
|
32
|
+
# The attributes field.
|
33
|
+
#
|
34
|
+
# @return [String]
|
35
|
+
def to_s
|
36
|
+
field.to_s
|
37
|
+
end
|
38
|
+
|
32
39
|
# Evals attribute accessors for this attribute into the scheme.
|
33
40
|
def define_scheme_methods scheme
|
34
41
|
scheme.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
data/lib/swift/db.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
+
require 'swift/adapter/sql'
|
2
|
+
|
1
3
|
module Swift
|
2
4
|
module DB
|
3
|
-
class Mysql < Adapter
|
5
|
+
class Mysql < Adapter::Sql
|
4
6
|
def initialize options = {}
|
5
7
|
super options.update(driver: 'mysql')
|
6
8
|
end
|
@@ -20,7 +22,7 @@ module Swift
|
|
20
22
|
end
|
21
23
|
end # Mysql
|
22
24
|
|
23
|
-
class Sqlite3 < Adapter
|
25
|
+
class Sqlite3 < Adapter::Sql
|
24
26
|
def initialize options = {}
|
25
27
|
super options.update(driver: 'sqlite3')
|
26
28
|
end
|
@@ -54,7 +56,7 @@ module Swift
|
|
54
56
|
end
|
55
57
|
end # Sqlite3
|
56
58
|
|
57
|
-
class Postgres < Adapter
|
59
|
+
class Postgres < Adapter::Sql
|
58
60
|
def initialize options = {}
|
59
61
|
super options.update(driver: 'postgresql')
|
60
62
|
end
|
data/lib/swift/migrations.rb
CHANGED
@@ -1,15 +1,58 @@
|
|
1
1
|
module Swift
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
2
|
+
module Migrations
|
3
|
+
module ClassMethods
|
4
|
+
# @example
|
5
|
+
# class User < Swift::Scheme
|
6
|
+
# migrations do |db|
|
7
|
+
# db.execute %q{create table users(id serial, name text, age int)}
|
8
|
+
# end
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
# @param [Proc] &migrations
|
12
|
+
#
|
13
|
+
# @see Swift::Scheme
|
14
|
+
def migrations &migrations
|
15
|
+
define_singleton_method(:migrate!, lambda{|db = Swift.db| migrations.call(db)})
|
16
|
+
end
|
17
|
+
|
18
|
+
# @example
|
19
|
+
# User.migrate!
|
20
|
+
#
|
21
|
+
# @param [Swift::Adapter] db
|
22
|
+
#
|
23
|
+
# @see Swift::Scheme
|
24
|
+
def migrate! db = Swift.db
|
25
|
+
db.migrate! self
|
26
|
+
end
|
27
|
+
end # ClassMethods
|
6
28
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
29
|
+
module InstanceMethods
|
30
|
+
# @example
|
31
|
+
# db.migrate! User
|
32
|
+
#
|
33
|
+
# @param [Swift::Scheme] scheme
|
34
|
+
#
|
35
|
+
# @see Swift::Adapter::Sql
|
36
|
+
def migrate! scheme
|
37
|
+
keys = scheme.header.keys
|
38
|
+
fields = scheme.header.map{|p| field_definition(p)}.join(', ')
|
39
|
+
fields += ", primary key (#{keys.join(', ')})" unless keys.empty?
|
40
|
+
|
41
|
+
execute("drop table if exists #{scheme.store} cascade")
|
42
|
+
execute("create table #{scheme.store} (#{fields})")
|
43
|
+
end
|
44
|
+
end # InstanceMethods
|
45
|
+
end # Migrations
|
11
46
|
|
12
47
|
def self.migrate! name = nil
|
13
48
|
schema.each{|scheme| scheme.migrate!(db(name)) }
|
14
49
|
end
|
50
|
+
|
51
|
+
class Scheme
|
52
|
+
extend Migrations::ClassMethods
|
53
|
+
end
|
54
|
+
|
55
|
+
class Adapter::Sql
|
56
|
+
include Migrations::InstanceMethods
|
57
|
+
end
|
15
58
|
end # Swift
|
data/lib/swift/scheme.rb
CHANGED
@@ -23,7 +23,7 @@ module Swift
|
|
23
23
|
# @param [Hash] options Create resource and set attributes. <tt>{name: value}</tt>
|
24
24
|
def initialize options = {}
|
25
25
|
@tuple = scheme.header.new_tuple
|
26
|
-
options.each{|k, v|
|
26
|
+
options.each{|k, v| public_send(:"#{k}=", v)}
|
27
27
|
end
|
28
28
|
|
29
29
|
# @example
|
@@ -36,7 +36,7 @@ module Swift
|
|
36
36
|
#
|
37
37
|
# @param [Hash] options Update attributes. <tt>{name: value}</tt>
|
38
38
|
def update options = {}
|
39
|
-
options.each{|k, v|
|
39
|
+
options.each{|k, v| public_send(:"#{k}=", v)}
|
40
40
|
Swift.db.update(scheme, self)
|
41
41
|
end
|
42
42
|
|
@@ -46,9 +46,9 @@ module Swift
|
|
46
46
|
# email: 'apple@arthurton.local',
|
47
47
|
# updated_at: Time.now
|
48
48
|
# )
|
49
|
-
# apple.
|
50
|
-
def
|
51
|
-
Swift.db.
|
49
|
+
# apple.delete
|
50
|
+
def delete resources = self
|
51
|
+
Swift.db.delete(scheme, resources)
|
52
52
|
end
|
53
53
|
|
54
54
|
class << self
|
@@ -75,7 +75,7 @@ module Swift
|
|
75
75
|
# @see Swift::Attribute#new
|
76
76
|
def attribute name, type, options = {}
|
77
77
|
header.push(attribute = type.new(self, name, options))
|
78
|
-
(
|
78
|
+
define_singleton_method(name, lambda{ attribute })
|
79
79
|
end
|
80
80
|
|
81
81
|
# Define the store (table).
|
@@ -86,6 +86,13 @@ module Swift
|
|
86
86
|
name ? @store = name : @store
|
87
87
|
end
|
88
88
|
|
89
|
+
# Store (table) name.
|
90
|
+
#
|
91
|
+
# @return [String]
|
92
|
+
def to_s
|
93
|
+
store.to_s
|
94
|
+
end
|
95
|
+
|
89
96
|
# Create (insert).
|
90
97
|
#
|
91
98
|
# @example
|
@@ -113,42 +120,31 @@ module Swift
|
|
113
120
|
Swift.db.get(self, keys)
|
114
121
|
end
|
115
122
|
|
116
|
-
#
|
123
|
+
# Prepare a statement for on or more executions.
|
117
124
|
#
|
118
|
-
# @example
|
119
|
-
# User.
|
120
|
-
#
|
121
|
-
#
|
122
|
-
# @example Block form iterator.
|
123
|
-
# User.all(':age > ?', 32) do |user|
|
124
|
-
# puts user.name
|
125
|
-
# end
|
125
|
+
# @example
|
126
|
+
# sth = User.prepare("select * from #{User} where #{User.name} = ?")
|
127
|
+
# sth.execute('apple') #=> Result
|
128
|
+
# sth.execute('benny') #=> Result
|
126
129
|
#
|
127
|
-
# @param [String]
|
128
|
-
# @
|
129
|
-
|
130
|
-
|
131
|
-
def all conditions = '', *binds, &block
|
132
|
-
Swift.db.all(self, conditions, *binds, &block)
|
130
|
+
# @param [String] statement Query statement.
|
131
|
+
# @return [Swift::Statement]
|
132
|
+
def prepare statement = ''
|
133
|
+
Swift.db.prepare(self, statement)
|
133
134
|
end
|
134
135
|
|
135
|
-
#
|
136
|
+
# Execute a single statement.
|
136
137
|
#
|
137
|
-
# @example
|
138
|
-
# User.
|
139
|
-
#
|
140
|
-
# User.first(':name = ? and :age > ?', 'Apple Arthurton', 32)
|
141
|
-
# @example Block form iterator.
|
142
|
-
# User.first(User, 'age > ?', 32) do |user|
|
143
|
-
# puts user.name
|
144
|
-
# end
|
138
|
+
# @example
|
139
|
+
# result = User.execute("select * from #{User} where #{User.name} = ?", 'apple')
|
140
|
+
# sth.first # User object.
|
145
141
|
#
|
146
|
-
# @param [String]
|
147
|
-
# @param [Object
|
148
|
-
# @
|
149
|
-
# @return [Swift::
|
150
|
-
def
|
151
|
-
Swift.db.
|
142
|
+
# @param [String] statement Query statement.
|
143
|
+
# @param [*Object] binds Bind values.
|
144
|
+
# @yield [Swift::Result]
|
145
|
+
# @return [Swift::Result]
|
146
|
+
def execute statement = '', *binds, &block
|
147
|
+
Swift.db.execute(self, statement, *binds, &block)
|
152
148
|
end
|
153
149
|
end
|
154
150
|
end # Scheme
|
data/lib/swift.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# Extension.
|
2
2
|
require_relative '../ext/swift'
|
3
3
|
require_relative 'swift/adapter'
|
4
|
+
require_relative 'swift/adapter/sql'
|
4
5
|
require_relative 'swift/attribute'
|
5
6
|
require_relative 'swift/db'
|
6
7
|
require_relative 'swift/header'
|
@@ -40,7 +41,7 @@ require_relative 'swift/type'
|
|
40
41
|
# user.update
|
41
42
|
#
|
42
43
|
# # Destroy
|
43
|
-
# user.
|
44
|
+
# user.delete
|
44
45
|
#
|
45
46
|
# == See
|
46
47
|
# * README.rdoc has more usage examples.
|
data/swift.gemspec
CHANGED
@@ -5,14 +5,14 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{swift}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.11.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
-
s.authors = [
|
12
|
-
s.date = %q{2011-
|
11
|
+
s.authors = [%q{Shane Hanna}, %q{Bharanee 'Barney' Rathna}]
|
12
|
+
s.date = %q{2011-09-30}
|
13
13
|
s.description = %q{A rational rudimentary database abstraction.}
|
14
|
-
s.email = [
|
15
|
-
s.extensions = [
|
14
|
+
s.email = [%q{shane.hanna@gmail.com}, %q{deepfryed@gmail.com}]
|
15
|
+
s.extensions = [%q{ext/extconf.rb}]
|
16
16
|
s.extra_rdoc_files = [
|
17
17
|
"LICENSE",
|
18
18
|
"README.rdoc"
|
@@ -44,6 +44,7 @@ Gem::Specification.new do |s|
|
|
44
44
|
"ext/swift.h",
|
45
45
|
"lib/swift.rb",
|
46
46
|
"lib/swift/adapter.rb",
|
47
|
+
"lib/swift/adapter/sql.rb",
|
47
48
|
"lib/swift/attribute.rb",
|
48
49
|
"lib/swift/db.rb",
|
49
50
|
"lib/swift/header.rb",
|
@@ -56,6 +57,7 @@ Gem::Specification.new do |s|
|
|
56
57
|
"swift.gemspec",
|
57
58
|
"test/helper.rb",
|
58
59
|
"test/house-explode.jpg",
|
60
|
+
"test/minitest_teardown_hack.rb",
|
59
61
|
"test/test_adapter.rb",
|
60
62
|
"test/test_encoding.rb",
|
61
63
|
"test/test_error.rb",
|
@@ -63,35 +65,18 @@ Gem::Specification.new do |s|
|
|
63
65
|
"test/test_io.rb",
|
64
66
|
"test/test_pool.rb",
|
65
67
|
"test/test_scheme.rb",
|
68
|
+
"test/test_swift.rb",
|
66
69
|
"test/test_timestamps.rb",
|
67
70
|
"test/test_transactions.rb",
|
68
71
|
"test/test_types.rb",
|
69
72
|
"test/test_validations.rb"
|
70
73
|
]
|
71
74
|
s.homepage = %q{http://github.com/shanna/swift}
|
72
|
-
s.require_paths = [
|
73
|
-
s.rubygems_version = %q{1.
|
75
|
+
s.require_paths = [%q{lib}]
|
76
|
+
s.rubygems_version = %q{1.8.5}
|
74
77
|
s.summary = %q{A rational rudimentary database abstraction.}
|
75
|
-
s.test_files = [
|
76
|
-
"examples/async.rb",
|
77
|
-
"examples/db.rb",
|
78
|
-
"examples/scheme.rb",
|
79
|
-
"test/helper.rb",
|
80
|
-
"test/test_adapter.rb",
|
81
|
-
"test/test_encoding.rb",
|
82
|
-
"test/test_error.rb",
|
83
|
-
"test/test_identity_map.rb",
|
84
|
-
"test/test_io.rb",
|
85
|
-
"test/test_pool.rb",
|
86
|
-
"test/test_scheme.rb",
|
87
|
-
"test/test_timestamps.rb",
|
88
|
-
"test/test_transactions.rb",
|
89
|
-
"test/test_types.rb",
|
90
|
-
"test/test_validations.rb"
|
91
|
-
]
|
92
78
|
|
93
79
|
if s.respond_to? :specification_version then
|
94
|
-
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
95
80
|
s.specification_version = 3
|
96
81
|
|
97
82
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
data/test/helper.rb
CHANGED
@@ -1,8 +1,11 @@
|
|
1
1
|
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
$:.unshift(File.join(File.dirname(__FILE__), '..', 'test'))
|
2
3
|
|
3
4
|
require 'minitest/spec'
|
4
5
|
require 'minitest/unit'
|
6
|
+
require 'minitest_teardown_hack'
|
5
7
|
require 'swift'
|
8
|
+
require 'swift/migrations'
|
6
9
|
require 'etc'
|
7
10
|
|
8
11
|
class MiniTest::Spec
|
@@ -21,6 +24,9 @@ class MiniTest::Spec
|
|
21
24
|
before do
|
22
25
|
Swift.setup :default, adapter, connection_defaults.merge(adapter_defaults.fetch(adapter, {}))
|
23
26
|
end
|
27
|
+
after do
|
28
|
+
Swift.db.close
|
29
|
+
end
|
24
30
|
block.call(adapter)
|
25
31
|
end
|
26
32
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# TODO remove this once the patch gets applied to stock ruby 1.9
|
2
|
+
class MiniTest::Spec < MiniTest::Unit::TestCase
|
3
|
+
|
4
|
+
def self.define_inheritable_method name, &block # :nodoc:
|
5
|
+
super_method = self.superclass.instance_method name
|
6
|
+
|
7
|
+
case name
|
8
|
+
when :teardown
|
9
|
+
define_method(name) do
|
10
|
+
instance_eval(&block)
|
11
|
+
super_method.bind(self).call if super_method
|
12
|
+
end
|
13
|
+
else
|
14
|
+
define_method(name) do
|
15
|
+
super_method.bind(self).call if super_method
|
16
|
+
instance_eval(&block)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/test/test_scheme.rb
CHANGED
@@ -11,6 +11,12 @@ describe 'scheme' do
|
|
11
11
|
attribute :email, Swift::Type::String
|
12
12
|
attribute :verified, Swift::Type::Boolean, default: false
|
13
13
|
attribute :created_at, Swift::Type::Time, default: proc { Time.now }
|
14
|
+
|
15
|
+
migrations do |db|
|
16
|
+
db.execute %q{
|
17
|
+
create users(id serial, name text, age int, height real, email text, verified bool, created_at timestamp)
|
18
|
+
}
|
19
|
+
end
|
14
20
|
end
|
15
21
|
end
|
16
22
|
|
@@ -62,33 +68,16 @@ describe 'scheme' do
|
|
62
68
|
assert_equal 1, Swift.db.execute(@user, 'select * from users').first.id
|
63
69
|
end
|
64
70
|
|
65
|
-
it 'adapter should
|
71
|
+
it 'adapter should delete valid instance' do
|
66
72
|
user = @user.create
|
67
73
|
assert_equal 1, user.id
|
68
74
|
|
69
|
-
assert Swift.db.
|
75
|
+
assert Swift.db.delete @user, user
|
70
76
|
assert_nil @user.get(id: 1)
|
71
77
|
end
|
72
78
|
|
73
|
-
it 'adapter should barf when trying to
|
74
|
-
assert_raises(ArgumentError) { Swift.db.
|
75
|
-
end
|
76
|
-
|
77
|
-
it 'adapter should delete all rows given scheme' do
|
78
|
-
user = @user.create
|
79
|
-
assert_equal 1, user.id
|
80
|
-
|
81
|
-
Swift.db.delete @user
|
82
|
-
assert_nil @user.get(id: 1)
|
83
|
-
end
|
84
|
-
|
85
|
-
it 'adapter should delete only relevant rows given condition & scheme' do
|
86
|
-
Swift.db.create(@user, [{name: 'dave'}, {name: 'mike'}])
|
87
|
-
assert_equal 2, @user.all.rows
|
88
|
-
|
89
|
-
Swift.db.delete @user, ':name = ?', 'dave'
|
90
|
-
assert_nil @user.first ':name = ?', 'dave'
|
91
|
-
assert @user.first ':name = ?', 'mike'
|
79
|
+
it 'adapter should barf when trying to delete an invalid instance' do
|
80
|
+
assert_raises(ArgumentError) { Swift.db.delete @user, {id: nil, name: 'foo'} }
|
92
81
|
end
|
93
82
|
|
94
83
|
it 'should not update without valid keys' do
|
@@ -99,7 +88,13 @@ describe 'scheme' do
|
|
99
88
|
it 'should update with valid keys' do
|
100
89
|
user = @user.create
|
101
90
|
assert user.update(name: 'dave')
|
102
|
-
assert_equal 'dave', @user.first.name
|
91
|
+
assert_equal 'dave', @user.execute("select * from #{@user}").first.name
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'should destroy' do
|
95
|
+
user = @user.create
|
96
|
+
assert user.update(name: 'dave')
|
97
|
+
assert user.delete
|
103
98
|
end
|
104
99
|
end
|
105
100
|
end
|