swift 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -264,11 +264,11 @@ which implicitly uses `rb_thread_wait_fd`
264
264
  or use the `swift/eventmachine` api.
265
265
 
266
266
  ```ruby
267
- require 'swift/eventmachine'
268
- require 'swift/adapter/postgres'
267
+ require 'swift'
268
+ require 'swift/adapter/em/postgres'
269
269
 
270
270
  EM.run do
271
- pool = 3.times.map { Swift.setup(:default, Swift::Adapter::Postgres, db: "swift") }
271
+ pool = 3.times.map { Swift.setup(:default, Swift::Adapter::EM::Postgres, db: "swift") }
272
272
 
273
273
  3.times.each do |n|
274
274
  defer = pool[n].execute("select pg_sleep(3 - #{n}), #{n + 1} as qid")
@@ -287,13 +287,13 @@ or use the `swift/eventmachine` api.
287
287
  or use the `em-synchrony` api for `swift`
288
288
 
289
289
  ```ruby
290
- require 'swift/synchrony'
291
- require 'swift/adapter/postgres'
290
+ require 'swift'
291
+ require 'swift/adapter/synchrony/postgres'
292
292
 
293
293
  EM.run do
294
294
  3.times.each do |n|
295
295
  EM.synchrony do
296
- db = Swift.setup(:default, Swift::Adapter::Postgres, db: "swift")
296
+ db = Swift.setup(:default, Swift::Adapter::Synchrony::Postgres, db: "swift")
297
297
  result = db.execute("select pg_sleep(3 - #{n}), #{n + 1} as qid")
298
298
 
299
299
  p result.first
@@ -312,7 +312,7 @@ require 'swift/fiber_connection_pool'
312
312
 
313
313
  EM.run do
314
314
  Swift.setup(:default) do
315
- Swift::FiberConnectionPool.new(size: 5) {Swift::Adapter::Postgres.new(db: 'swift')}
315
+ Swift::FiberConnectionPool.new(size: 5) {Swift::Adapter::Synchrony::Postgres.new(db: 'swift')}
316
316
  end
317
317
 
318
318
  5.times do
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.1.0
1
+ 1.2.0
@@ -0,0 +1,11 @@
1
+ require 'swift/adapter/mysql'
2
+ require 'swift/adapter/eventmachine'
3
+
4
+ # TODO: use Module#prepend when backported
5
+ module Swift
6
+ class Adapter
7
+ class Eventmachine::Mysql < Mysql
8
+ include Eventmachine
9
+ end # Eventmachine::Mysql
10
+ end # Adapter
11
+ end # Swift
@@ -0,0 +1,11 @@
1
+ require 'swift/adapter/postgres'
2
+ require 'swift/adapter/eventmachine'
3
+
4
+ # TODO: use Module#prepend when backported
5
+ module Swift
6
+ class Adapter
7
+ class Eventmachine::Postgres < Postgres
8
+ include Eventmachine
9
+ end # Eventmachine::Postgres
10
+ end # Adapter
11
+ end # Swift
@@ -0,0 +1,62 @@
1
+ require 'eventmachine'
2
+ require 'swift'
3
+
4
+ module Swift
5
+ # Eventmachine Adapter Extensions.
6
+ #
7
+ # This replaces the Adapter#execute method with a non-blocking asynchronous version.
8
+ class Adapter
9
+ module Eventmachine
10
+ class Handler < EM::Connection
11
+ def initialize adapter, record, defer
12
+ @started = Time.now
13
+ @adapter = adapter
14
+ @record = record
15
+ @defer = defer
16
+ end
17
+
18
+ def notify_readable
19
+ detach
20
+ start, command, bind = @adapter.pending.shift
21
+ @adapter.log_command(start, command, bind) if @adapter.trace?
22
+
23
+ begin
24
+ @defer.succeed(@record ? Result.new(@record, @adapter.result) : @adapter.result)
25
+ rescue Exception => e
26
+ @defer.fail(e)
27
+ end
28
+ end
29
+ end # Handler
30
+
31
+ # Execute a command asynchronously.
32
+ #
33
+ # @example
34
+ # defer = Swift.db.execute(User, "select * from users where id = ?", 1)
35
+ # defer.callback do |user|
36
+ # p user.id
37
+ # end
38
+ # defer.errback do |error|
39
+ # p error
40
+ # end
41
+ #
42
+ # @see [Swift::Adapter]
43
+ def execute command, *bind
44
+ raise RuntimeError, 'Command already in progress' unless pending.empty?
45
+
46
+ record, command = command, bind.shift if command.kind_of?(Class) && command < Record
47
+ pending << [Time.now, command, bind]
48
+ query(command, *bind)
49
+
50
+ ::EM::DefaultDeferrable.new.tap do |defer|
51
+ ::EM.watch(fileno, Handler, self, record, defer) {|c| c.notify_readable = true}
52
+ end
53
+ end
54
+
55
+ def pending
56
+ @pending ||= []
57
+ end
58
+ end # Eventmachine
59
+
60
+ EM = Eventmachine
61
+ end # Adapter
62
+ end # Swift
@@ -0,0 +1,48 @@
1
+ require 'em-synchrony'
2
+
3
+ module Swift
4
+ # em-synchrony support for Swift::Adapter
5
+ #
6
+ class Adapter
7
+ module Synchrony
8
+ # Execute a command asynchronously and pause the Fiber until the command finishes.
9
+ #
10
+ # @example
11
+ # EM.run do
12
+ # 3.times.each do |n|
13
+ # EM.synchrony do
14
+ # db = Swift.setup(:default, Swift::Adapter::Synchrony::Postgres, db: "swift_test")
15
+ # result = db.execute("select pg_sleep(3 - #{n}), #{n + 1} as qid")
16
+ #
17
+ # p result.first
18
+ # EM.stop if n == 0
19
+ # end
20
+ # end
21
+ # end
22
+ #
23
+ # @see [Swift::Adapter]
24
+ def execute *args
25
+ res = ::EM::Synchrony.sync super(*args)
26
+ if res.kind_of?(Error)
27
+ res.set_backtrace caller.reject {|subject| subject =~ %r{swift/fiber_connection_pool}}
28
+ raise res
29
+ end
30
+ yield res if block_given?
31
+ res
32
+ end
33
+
34
+ def transaction &block
35
+ Swift.scopes.push(self)
36
+ execute('begin')
37
+ res = yield(self)
38
+ execute('commit')
39
+ res
40
+ rescue => e
41
+ execute('rollback')
42
+ raise e
43
+ ensure
44
+ Swift.scopes.pop
45
+ end
46
+ end # Synchrony
47
+ end # Adapter
48
+ end # Swift
@@ -0,0 +1,12 @@
1
+ require 'swift/adapter/synchrony'
2
+ require 'swift/adapter/em/mysql'
3
+
4
+ module Swift
5
+ # em-synchrony support for Swift::Adapter
6
+ #
7
+ class Adapter
8
+ class Synchrony::Mysql < EM::Mysql
9
+ include Synchrony
10
+ end # Synchrony::Mysql
11
+ end # Adapter
12
+ end # Swift
@@ -0,0 +1,12 @@
1
+ require 'swift/adapter/synchrony'
2
+ require 'swift/adapter/em/postgres'
3
+
4
+ module Swift
5
+ # em-synchrony support for Swift::Adapter
6
+ #
7
+ class Adapter
8
+ class Synchrony::Postgres < EM::Postgres
9
+ include Synchrony
10
+ end # Synchrony::Postgres
11
+ end # Adapter
12
+ end # Swift
@@ -1,7 +1,5 @@
1
1
  # Based on EM::Synchrony::ConnectionPool
2
2
 
3
- require 'swift/synchrony'
4
-
5
3
  module Swift
6
4
  class FiberConnectionPool
7
5
 
@@ -76,19 +74,4 @@ module Swift
76
74
  end
77
75
  end
78
76
  end # FiberConnectionPool
79
-
80
- class Adapter::Sql
81
- def serialized_transaction &block
82
- Swift.scopes.push(self)
83
- execute('begin')
84
- res = yield(self)
85
- execute('commit')
86
- res
87
- rescue => e
88
- execute('rollback')
89
- raise e
90
- ensure
91
- Swift.scopes.pop
92
- end
93
- end # Adapter::Sql
94
77
  end # Swift
data/swift.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "swift"
8
- s.version = "1.1.0"
8
+ s.version = "1.2.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 = "2013-02-18"
12
+ s.date = "2013-03-10"
13
13
  s.description = "A rational rudimentary database abstraction."
14
14
  s.email = ["shane.hanna@gmail.com", "deepfryed@gmail.com"]
15
15
  s.extra_rdoc_files = [
@@ -24,12 +24,17 @@ Gem::Specification.new do |s|
24
24
  "VERSION",
25
25
  "lib/swift.rb",
26
26
  "lib/swift/adapter.rb",
27
+ "lib/swift/adapter/em/mysql.rb",
28
+ "lib/swift/adapter/em/postgres.rb",
29
+ "lib/swift/adapter/eventmachine.rb",
27
30
  "lib/swift/adapter/mysql.rb",
28
31
  "lib/swift/adapter/postgres.rb",
29
32
  "lib/swift/adapter/sql.rb",
30
33
  "lib/swift/adapter/sqlite3.rb",
34
+ "lib/swift/adapter/synchrony.rb",
35
+ "lib/swift/adapter/synchrony/mysql.rb",
36
+ "lib/swift/adapter/synchrony/postgres.rb",
31
37
  "lib/swift/attribute.rb",
32
- "lib/swift/eventmachine.rb",
33
38
  "lib/swift/fiber_connection_pool.rb",
34
39
  "lib/swift/header.rb",
35
40
  "lib/swift/identity_map.rb",
@@ -37,7 +42,6 @@ Gem::Specification.new do |s|
37
42
  "lib/swift/record.rb",
38
43
  "lib/swift/result.rb",
39
44
  "lib/swift/statement.rb",
40
- "lib/swift/synchrony.rb",
41
45
  "lib/swift/type.rb",
42
46
  "lib/swift/validations.rb",
43
47
  "swift.gemspec",
data/test/helper.rb CHANGED
@@ -18,9 +18,6 @@ class MiniTest::Spec
18
18
  connection_defaults = { db: 'swift_test', user: Etc.getlogin, host: '127.0.0.1' }
19
19
  adapters.each do |adapter|
20
20
  begin
21
- #next if Swift::Adapter::Sqlite3 == adapter
22
- #next if Swift::Adapter::Mysql == adapter
23
- #next if Swift::Adapter::Postgres == adapter
24
21
  Swift.setup :default, adapter, connection_defaults.merge(adapter_defaults.fetch(adapter, {}))
25
22
  rescue => error
26
23
  warn "Unable to setup 'swift_test' db for #{adapter}, #{error.message}. Skipping..."
@@ -1,10 +1,10 @@
1
1
  require 'helper'
2
+ require 'swift/fiber_connection_pool'
3
+ require 'swift/adapter/synchrony/postgres'
2
4
 
3
5
  describe 'fiber connection pool' do
4
6
  before do
5
- skip 'swift/synchrony re-defines Adapter#execute' unless ENV['TEST_SWIFT_SYNCHRONY']
6
7
 
7
- require 'swift/fiber_connection_pool'
8
8
  EM.synchrony do
9
9
  Swift.setup(:default, Swift::Adapter::Postgres, db: 'swift_test')
10
10
  Swift.db.execute('drop table if exists users')
@@ -17,21 +17,25 @@ describe 'fiber connection pool' do
17
17
  end
18
18
 
19
19
  10.times { @user.create(name: 'test') }
20
+
21
+ # async on from now on
22
+ Swift.setup(:default) do
23
+ Swift::FiberConnectionPool.new(size: 2) do
24
+ Swift::Adapter::Synchrony::Postgres.new(db: 'swift_test')
25
+ end
26
+ end
20
27
  EM.stop
21
28
  end
22
29
  end
23
30
 
24
31
  it 'can synchronize queries across fibers' do
25
32
  EM.run do
26
- Swift.setup(:default) { Swift::FiberConnectionPool.new(size: 2) {Swift::Adapter::Postgres.new(db: 'swift_test')}}
27
-
28
33
  @counts = []
29
34
  5.times do
30
35
  EM.synchrony do
31
36
  @counts << @user.execute('select * from users').selected_rows
32
37
  end
33
38
  end
34
-
35
39
  EM.add_timer(0.2) { EM.stop }
36
40
  end
37
41
 
@@ -42,7 +46,6 @@ describe 'fiber connection pool' do
42
46
  it 'sets appropriate backtrace for errors' do
43
47
  EM.synchrony do
44
48
  error = nil
45
- Swift.setup(:default) { Swift::FiberConnectionPool.new(size: 2) {Swift::Adapter::Postgres.new(db: 'swift_test')}}
46
49
 
47
50
  begin
48
51
  Swift.db.execute 'foo bar baz'
@@ -51,7 +54,7 @@ describe 'fiber connection pool' do
51
54
  end
52
55
 
53
56
  assert error
54
- assert_match %r{test/test_synchrony.rb:48}, error.backtrace.first
57
+ assert_match %r{test/test_synchrony.rb}, error.backtrace[0]
55
58
  EM.stop
56
59
  end
57
60
  end
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: 1.1.0
4
+ version: 1.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-02-18 00:00:00.000000000 Z
13
+ date: 2013-03-10 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  requirement: !ruby/object:Gem::Requirement
@@ -45,12 +45,17 @@ files:
45
45
  - VERSION
46
46
  - lib/swift.rb
47
47
  - lib/swift/adapter.rb
48
+ - lib/swift/adapter/em/mysql.rb
49
+ - lib/swift/adapter/em/postgres.rb
50
+ - lib/swift/adapter/eventmachine.rb
48
51
  - lib/swift/adapter/mysql.rb
49
52
  - lib/swift/adapter/postgres.rb
50
53
  - lib/swift/adapter/sql.rb
51
54
  - lib/swift/adapter/sqlite3.rb
55
+ - lib/swift/adapter/synchrony.rb
56
+ - lib/swift/adapter/synchrony/mysql.rb
57
+ - lib/swift/adapter/synchrony/postgres.rb
52
58
  - lib/swift/attribute.rb
53
- - lib/swift/eventmachine.rb
54
59
  - lib/swift/fiber_connection_pool.rb
55
60
  - lib/swift/header.rb
56
61
  - lib/swift/identity_map.rb
@@ -58,7 +63,6 @@ files:
58
63
  - lib/swift/record.rb
59
64
  - lib/swift/result.rb
60
65
  - lib/swift/statement.rb
61
- - lib/swift/synchrony.rb
62
66
  - lib/swift/type.rb
63
67
  - lib/swift/validations.rb
64
68
  - swift.gemspec
@@ -89,7 +93,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
89
93
  requirements:
90
94
  - - ! '>='
91
95
  - !ruby/object:Gem::Version
92
- hash: -3874151873791212661
96
+ hash: -4534175981099401006
93
97
  version: '0'
94
98
  segments:
95
99
  - 0
@@ -1,61 +0,0 @@
1
- require 'eventmachine'
2
- require 'swift'
3
-
4
- module Swift
5
- # Eventmachine Adapter Extensions.
6
- #
7
- # This replaces the Adapter#execute method with a non-blocking asynchronous version.
8
- class Adapter
9
- alias :blocking_execute :execute
10
-
11
- class EMHandler < EM::Connection
12
- def initialize adapter, record, defer
13
- @started = Time.now
14
- @adapter = adapter
15
- @record = record
16
- @defer = defer
17
- end
18
-
19
- def notify_readable
20
- detach
21
- start, command, bind = @adapter.pending.shift
22
- @adapter.log_command(start, command, bind) if @adapter.trace?
23
-
24
- begin
25
- @defer.succeed(@record ? Result.new(@record, @adapter.result) : @adapter.result)
26
- rescue Exception => e
27
- @defer.fail(e)
28
- end
29
- end
30
- end
31
-
32
- # Execute a command asynchronously.
33
- #
34
- # @example
35
- # defer = Swift.db.execute(User, "select * from users where id = ?", 1)
36
- # defer.callback do |user|
37
- # p user.id
38
- # end
39
- # defer.errback do |error|
40
- # p error
41
- # end
42
- #
43
- # @see [Swift::Adapter]
44
- def execute command, *bind
45
- raise RuntimeError, 'Command already in progress' unless pending.empty?
46
-
47
- start = Time.now
48
- record, command = command, bind.shift if command.kind_of?(Class) && command < Record
49
- pending << [start, command, bind]
50
- query(command, *bind)
51
-
52
- EM::DefaultDeferrable.new.tap do |defer|
53
- EM.watch(fileno, EMHandler, self, record, defer) {|c| c.notify_readable = true }
54
- end
55
- end
56
-
57
- def pending
58
- @pending ||= []
59
- end
60
- end
61
- end
@@ -1,38 +0,0 @@
1
- require 'em-synchrony'
2
- require 'swift/eventmachine'
3
-
4
- module Swift
5
- # em-synchrony support for Swift::Adapter
6
- #
7
- # This replaces the default Adapter#execute with a version that uses EM::Synchrony.sync to wait for the
8
- # defered command to complete. It assumes that the execute method is called inside a em-synchrony Fiber.
9
- class Adapter
10
- alias :aexecute :execute
11
-
12
- # Execute a command asynchronously and pause the Fiber until the command finishes.
13
- #
14
- # @example
15
- # EM.run do
16
- # 3.times.each do |n|
17
- # EM.synchrony do
18
- # db = Swift.setup(:default, Swift::Adapter::Postgres, db: "swift_test")
19
- # result = db.execute("select pg_sleep(3 - #{n}), #{n + 1} as qid")
20
- #
21
- # p result.first
22
- # EM.stop if n == 0
23
- # end
24
- # end
25
- # end
26
- #
27
- # @see [Swift::Adapter]
28
- def execute *args
29
- res = EM::Synchrony.sync aexecute(*args)
30
- if res.kind_of?(Error)
31
- res.set_backtrace caller.reject {|subject| subject =~ %r{swift/fiber_connection_pool}}
32
- raise res
33
- end
34
- yield res if block_given?
35
- res
36
- end
37
- end
38
- end