swift 0.10.0 → 0.11.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 +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
|