green-em-pg 0.1.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/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source "http://rubygems.org"
2
+
3
+ group :test do
4
+ gem "sequel"
5
+ gem "minitest"
6
+ gem "minitest-reporters"
7
+ gem "debugger"
8
+ end
9
+
10
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,51 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ green-em-pg (0.1.0)
5
+ em-pg (>= 0.1)
6
+ eventmachine (>= 0.12)
7
+ green (>= 0.1.1)
8
+ pg (>= 0.14)
9
+
10
+ GEM
11
+ remote: http://rubygems.org/
12
+ specs:
13
+ ansi (1.4.3)
14
+ builder (3.1.4)
15
+ columnize (0.3.6)
16
+ debugger (1.3.0)
17
+ columnize (>= 0.3.1)
18
+ debugger-linecache (~> 1.1.1)
19
+ debugger-ruby_core_source (~> 1.1.7)
20
+ debugger-linecache (1.1.2)
21
+ debugger-ruby_core_source (>= 1.1.1)
22
+ debugger-ruby_core_source (1.1.7)
23
+ em-pg (0.1.1)
24
+ eventmachine (>= 0.12)
25
+ pg (>= 0.14)
26
+ eventmachine (1.0.0)
27
+ green (0.1.1)
28
+ kgio (= 2.7.4)
29
+ hashie (1.2.0)
30
+ kgio (2.7.4)
31
+ minitest (4.5.0)
32
+ minitest-reporters (0.14.7)
33
+ ansi
34
+ builder
35
+ minitest (>= 2.12, < 5.0)
36
+ powerbar
37
+ pg (0.14.1)
38
+ powerbar (1.0.11)
39
+ ansi (~> 1.4.0)
40
+ hashie (>= 1.1.0)
41
+ sequel (3.43.0)
42
+
43
+ PLATFORMS
44
+ ruby
45
+
46
+ DEPENDENCIES
47
+ debugger
48
+ green-em-pg!
49
+ minitest
50
+ minitest-reporters
51
+ sequel
data/README.md ADDED
@@ -0,0 +1,36 @@
1
+ green-em-pg
2
+ ===========
3
+
4
+ Simple wrapper around [em-pg](https://github.com/prepor/em-pg) for [Green](https://github.com/prepor/green). And [Sequel](http://sequel.rubyforge.org/) adapter.
5
+
6
+ Usage
7
+ -----
8
+
9
+ ```ruby
10
+ gem "green-em-pg"
11
+ ```
12
+
13
+ ```ruby
14
+ require "green-em/pg"
15
+
16
+ db = Green::EM::PG.new host: "localhost",
17
+ port: 5432,
18
+ dbname: "test",
19
+ user: "postgres",
20
+ password: "postgres"
21
+
22
+ res = db.send_qeury "select * from test"
23
+
24
+ puts res.inspect
25
+ ```
26
+
27
+ Sequel
28
+ ------
29
+
30
+ ```ruby
31
+ require "green-em/pg/sequal"
32
+ url = "postgres://postgres:postgres@localhost:5432/test"
33
+ db = Sequel.connect(url, pool_class: Green::EM::PG::Sequel::ConnectionPool)
34
+
35
+ puts db[:test].all.inspect
36
+ ```
data/Rakefile ADDED
@@ -0,0 +1,121 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'date'
4
+
5
+ #############################################################################
6
+ #
7
+ # Helper functions
8
+ #
9
+ #############################################################################
10
+
11
+ def name
12
+ @name ||= Dir['*.gemspec'].first.split('.').first
13
+ end
14
+
15
+ def version
16
+ line = File.read("lib/green-em/pg.rb")[/^\s*VERSION\s*=\s*.*/]
17
+ line.match(/.*VERSION\s*=\s*['"](.*)['"]/)[1]
18
+ end
19
+
20
+ def date
21
+ Date.today.to_s
22
+ end
23
+
24
+ def rubyforge_project
25
+ name
26
+ end
27
+
28
+ def gemspec_file
29
+ "#{name}.gemspec"
30
+ end
31
+
32
+ def gem_file
33
+ "#{name}-#{version}.gem"
34
+ end
35
+
36
+ def replace_header(head, header_name)
37
+ head.sub!(/(\.#{header_name}\s*= ').*'/) { "#{$1}#{send(header_name)}'"}
38
+ end
39
+
40
+ #############################################################################
41
+ #
42
+ # Standard tasks
43
+ #
44
+ #############################################################################
45
+
46
+ task :default => :spec
47
+
48
+ require 'rake/testtask'
49
+ Rake::TestTask.new(:spec) do |test|
50
+ test.libs << 'lib' << 'spec'
51
+ test.pattern = 'spec/**/*_spec.rb'
52
+ test.verbose = true
53
+ end
54
+
55
+ desc "Open an irb session preloaded with this library"
56
+ task :console do
57
+ sh "irb -rubygems -r ./lib/#{name}.rb"
58
+ end
59
+
60
+ #############################################################################
61
+ #
62
+ # Custom tasks (add your own tasks here)
63
+ #
64
+ #############################################################################
65
+
66
+
67
+
68
+ #############################################################################
69
+ #
70
+ # Packaging tasks
71
+ #
72
+ #############################################################################
73
+
74
+ desc "Create tag v#{version} and build and push #{gem_file} to Rubygems"
75
+ task :release => :build do
76
+ unless `git branch` =~ /^\* master$/
77
+ puts "You must be on the master branch to release!"
78
+ exit!
79
+ end
80
+ sh "git commit --allow-empty -a -m 'Release #{version}'"
81
+ sh "git tag v#{version}"
82
+ sh "git push origin master"
83
+ sh "git push origin v#{version}"
84
+ sh "gem push pkg/#{name}-#{version}.gem"
85
+ end
86
+
87
+ desc "Build #{gem_file} into the pkg directory"
88
+ task :build => :gemspec do
89
+ sh "mkdir -p pkg"
90
+ sh "gem build #{gemspec_file}"
91
+ sh "mv #{gem_file} pkg"
92
+ end
93
+
94
+ desc "Generate #{gemspec_file}"
95
+ task :gemspec do
96
+ # read spec file and split out manifest section
97
+ spec = File.read(gemspec_file)
98
+ head, manifest, tail = spec.split(" # = MANIFEST =\n")
99
+
100
+ # replace name version and date
101
+ replace_header(head, :name)
102
+ replace_header(head, :version)
103
+ replace_header(head, :date)
104
+ #comment this out if your rubyforge_project has a different name
105
+ replace_header(head, :rubyforge_project)
106
+
107
+ # determine file list from git ls-files
108
+ files = `git ls-files`.
109
+ split("\n").
110
+ sort.
111
+ reject { |file| file =~ /^\./ }.
112
+ reject { |file| file =~ /^(rdoc|pkg)/ }.
113
+ map { |file| " #{file}" }.
114
+ join("\n")
115
+
116
+ # piece file back together and write
117
+ manifest = " s.files = %w[\n#{files}\n ]\n"
118
+ spec = [head, manifest, tail].join(" # = MANIFEST =\n")
119
+ File.open(gemspec_file, 'w') { |io| io.write(spec) }
120
+ puts "Updated #{gemspec_file}"
121
+ end
@@ -0,0 +1,30 @@
1
+ spec = Gem::Specification.new do |s|
2
+ s.name = 'green-em-pg'
3
+ s.version = '0.1.0'
4
+ s.date = '2013-01-28'
5
+ s.summary = 'Async PostgreSQL client API for Ruby/EventMachine'
6
+ s.email = "ceo@prepor.ru"
7
+ s.homepage = "http://github.com/prepor/em-postgres"
8
+ s.description = 'Async PostgreSQL client API for Ruby/EventMachine'
9
+ s.has_rdoc = false
10
+ s.authors = ["Andrew Rudenko"]
11
+ s.add_dependency('eventmachine', '>= 0.12')
12
+ s.add_dependency('pg', '>= 0.14')
13
+ s.add_dependency('green', '>= 0.1.1')
14
+ s.add_dependency('em-pg', '>= 0.1')
15
+
16
+ # = MANIFEST =
17
+ s.files = %w[
18
+ Gemfile
19
+ Gemfile.lock
20
+ README.md
21
+ Rakefile
22
+ green-em-pg.gemspec
23
+ lib/green-em/pg.rb
24
+ lib/green-em/pg/sequel.rb
25
+ spec/green-em/pg/sequel_spec.rb
26
+ spec/green-em/pg_spec.rb
27
+ spec/spec_helper.rb
28
+ ]
29
+ # = MANIFEST =
30
+ end
@@ -0,0 +1,24 @@
1
+ require 'green-em'
2
+ require 'em/pg'
3
+ class Green
4
+ module EM
5
+ class PG < ::EM::PG
6
+ VERSION = "0.1.0"
7
+ def self.new(*args)
8
+ Green.hub # ensure started green hub
9
+ db = allocate
10
+ db.instance_eval do
11
+ initialize(*args)
12
+ end
13
+ Green::EM.sync db
14
+ db
15
+ end
16
+
17
+ [:send_query, :send_prepare, :send_query_prepared, :send_describe_prepared, :send_describe_portal].each do |m|
18
+ define_method(m) do |*args|
19
+ Green::EM.sync super(*args)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,72 @@
1
+ require 'pg'
2
+ require 'forwardable'
3
+ require 'green-em/pg'
4
+ require 'sequel'
5
+ require 'green/connection_pool'
6
+ class Green
7
+ module EM
8
+ class PG
9
+ class Sequel
10
+ class ConnectionPool < ::Sequel::ConnectionPool
11
+ DEFAULT_SIZE = 4
12
+ attr_accessor :pool
13
+ def initialize(db, opts = {})
14
+ super
15
+ @pool = Green::ConnectionPool.new size: opts[:max_connection] || DEFAULT_SIZE,
16
+ disconnect_class: ::Sequel::DatabaseDisconnectError do
17
+ make_new(DEFAULT_SERVER)
18
+ end
19
+ end
20
+
21
+ def size
22
+ @pool.available.size
23
+ end
24
+
25
+ def hold(server = nil, &blk)
26
+ @pool.execute(&blk)
27
+ end
28
+
29
+ def disconnect(server = nil)
30
+ @pool.available.each{ |conn| db.disconnect_connection(conn) }
31
+ @pool.available.clear
32
+ end
33
+ end
34
+ end
35
+
36
+ class PGconn < Green::EM::PG
37
+ extend Forwardable
38
+
39
+ def_delegators :@pg, :status, :escape_string, :escape_bytea
40
+
41
+ class << self
42
+ alias :connect :new
43
+ end
44
+
45
+ { async_exec: :send_query,
46
+ prepare: :send_prepare,
47
+ exec_prepared: :send_query_prepared,
48
+ finish: :close }.each do |from, to|
49
+ define_method from do |*args|
50
+ send(to, *args)
51
+ end
52
+ end
53
+ # alias :async_exec :send_query
54
+ # alias :prepare :send_prepare
55
+ # alias :exec_prepared :send_query_prepared
56
+ # alias :finish :close
57
+
58
+ [:get_copy_data, :put_copy_data, :put_copy_end, :get_result, :wait_for_notify].each do |m|
59
+ define_method(m) do |*args|
60
+ raise "Unimplemented method #{m} in green postgres adapter"
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
67
+
68
+ PGconn = Green::EM::PG::PGconn
69
+
70
+ require 'sequel/adapters/postgres'
71
+
72
+ Sequel::Postgres::CONVERTED_EXCEPTIONS << ::EM::PG::Error
@@ -0,0 +1,64 @@
1
+ require 'spec_helper'
2
+ require 'green-em/pg/sequel'
3
+ require 'green/group'
4
+
5
+ describe Green::EM::PG do
6
+ DELAY = 1
7
+ QUERY = "select pg_sleep(#{DELAY})"
8
+
9
+
10
+ let(:url) { DB_URL }
11
+ let(:size) { 1 }
12
+ let(:db) { Sequel.connect(url, max_connection: size, pool_class: Green::EM::PG::Sequel::ConnectionPool, db_logger: Logger.new(nil)) }
13
+ let(:test) { db[:test] }
14
+
15
+ before do
16
+ db.create_table!(:test) do
17
+ text :name
18
+ integer :value, index: true
19
+ end
20
+ end
21
+
22
+ after do
23
+ db.drop_table?(:test)
24
+ end
25
+
26
+ it "should connect and execute query" do
27
+ test.insert name: "andrew", value: 42
28
+ test.where(name: "andrew").first[:value].must_equal 42
29
+ end
30
+
31
+
32
+ describe "pool size is exceeded" do
33
+ let(:size) { 1 }
34
+ it "should queue requests" do
35
+ start = Time.now.to_f
36
+
37
+ g = Green::Group.new
38
+ res = []
39
+ g.spawn { res << db[QUERY].all }
40
+ g.spawn { res << db[QUERY].all }
41
+ g.join
42
+ (Time.now.to_f - start.to_f).must_be_within_delta DELAY * 2, DELAY * 2 * 0.15
43
+ res.size.must_equal 2
44
+ end
45
+ end
46
+
47
+ describe "pool size is enough" do
48
+ let(:size) { 2 }
49
+ it "should parallel requests" do
50
+ start = Time.now.to_f
51
+
52
+ g = Green::Group.new
53
+ res = []
54
+ g.spawn { res << db[QUERY].all }
55
+ g.spawn { res << db[QUERY].all }
56
+ g.join
57
+
58
+ (Time.now.to_f - start.to_f).must_be_within_delta DELAY, DELAY * 0.30
59
+ res.size.must_equal 2
60
+ end
61
+ end
62
+
63
+
64
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe Green::EM::PG do
4
+ let(:db) { Green::EM::PG.new DB_CONFIG }
5
+ it "should execute query" do
6
+ res = db.send_query "select 1;"
7
+ res.first["?column?"].must_equal "1"
8
+ end
9
+ end
@@ -0,0 +1,26 @@
1
+ ENV['BUNDLE_GEMFILE'] = File.expand_path('../../Gemfile', __FILE__)
2
+
3
+ ENV['GREEN_HUB'] = 'EM'
4
+ require 'bundler/setup'
5
+
6
+ require 'green-em/pg'
7
+
8
+ require 'minitest/spec'
9
+ require 'minitest/autorun'
10
+ require 'minitest/reporters'
11
+
12
+ logger = Logger.new nil
13
+
14
+ DB_CONFIG = {
15
+ host: "localhost",
16
+ port: 5432,
17
+ dbname: "test",
18
+ user: "postgres",
19
+ password: "postgres",
20
+ }
21
+
22
+ EM::PG.logger = logger
23
+
24
+ DB_URL = "postgres://%s:%s@%s:%d/%s" % [DB_CONFIG[:user], DB_CONFIG[:password], DB_CONFIG[:host], DB_CONFIG[:port], DB_CONFIG[:dbname]]
25
+
26
+ MiniTest::Reporters.use! MiniTest::Reporters::SpecReporter.new
metadata ADDED
@@ -0,0 +1,118 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: green-em-pg
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Andrew Rudenko
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-01-28 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: eventmachine
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0.12'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0.12'
30
+ - !ruby/object:Gem::Dependency
31
+ name: pg
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0.14'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0.14'
46
+ - !ruby/object:Gem::Dependency
47
+ name: green
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: 0.1.1
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: 0.1.1
62
+ - !ruby/object:Gem::Dependency
63
+ name: em-pg
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0.1'
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0.1'
78
+ description: Async PostgreSQL client API for Ruby/EventMachine
79
+ email: ceo@prepor.ru
80
+ executables: []
81
+ extensions: []
82
+ extra_rdoc_files: []
83
+ files:
84
+ - Gemfile
85
+ - Gemfile.lock
86
+ - README.md
87
+ - Rakefile
88
+ - green-em-pg.gemspec
89
+ - lib/green-em/pg.rb
90
+ - lib/green-em/pg/sequel.rb
91
+ - spec/green-em/pg/sequel_spec.rb
92
+ - spec/green-em/pg_spec.rb
93
+ - spec/spec_helper.rb
94
+ homepage: http://github.com/prepor/em-postgres
95
+ licenses: []
96
+ post_install_message:
97
+ rdoc_options: []
98
+ require_paths:
99
+ - lib
100
+ required_ruby_version: !ruby/object:Gem::Requirement
101
+ none: false
102
+ requirements:
103
+ - - ! '>='
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ required_rubygems_version: !ruby/object:Gem::Requirement
107
+ none: false
108
+ requirements:
109
+ - - ! '>='
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ requirements: []
113
+ rubyforge_project:
114
+ rubygems_version: 1.8.24
115
+ signing_key:
116
+ specification_version: 3
117
+ summary: Async PostgreSQL client API for Ruby/EventMachine
118
+ test_files: []