midori-contrib 0.0.1
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.
- checksums.yaml +7 -0
- data/.editorconfig +9 -0
- data/Gemfile.lock +77 -0
- data/lib/midori-contrib/file.rb +51 -0
- data/lib/midori-contrib/net.rb +42 -0
- data/lib/midori-contrib/redic.rb +99 -0
- data/lib/midori-contrib/sequel/mysql2.rb +111 -0
- data/lib/midori-contrib/sequel/postgres.rb +45 -0
- data/lib/midori-contrib.rb +5 -0
- data/midori-contrib.gemspec +19 -0
- metadata +67 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 393f08c7ad62a5acac4c3ff58767946de3440d2f
|
4
|
+
data.tar.gz: 4bb1e8b95c10350a57d42761f2818353920be756
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3709e3e7f72a1794af4822273402728780cd3a83cf6eff11a9b3159338ff665c6c07c385cd3661cd1a96ea15cadfcdb5f6b95200ad21c3fcdaf11fd9a30947b0
|
7
|
+
data.tar.gz: c11f2937a9deb52f787e25bdad8c6a1e209364e1df19f9e21d200fc26ba0d5f83ccf875f78249ccebcf51504c14469c95649c988b057086611cc5db52f366e48
|
data/.editorconfig
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
midori-contrib (0.0.1)
|
5
|
+
em-midori (~> 0.3)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
codeclimate-test-reporter (1.0.7)
|
11
|
+
simplecov
|
12
|
+
diff-lcs (1.3)
|
13
|
+
docile (1.1.5)
|
14
|
+
em-midori (0.3.0)
|
15
|
+
midori_http_parser (~> 0.6.1)
|
16
|
+
mustermann (~> 1.0)
|
17
|
+
nio4r (~> 2.0)
|
18
|
+
hiredis (0.6.1)
|
19
|
+
json (2.1.0)
|
20
|
+
kramdown (1.13.2)
|
21
|
+
midori_http_parser (0.6.1.3)
|
22
|
+
mustermann (1.0.0)
|
23
|
+
mysql2 (0.4.6)
|
24
|
+
nest (3.1.1)
|
25
|
+
redic
|
26
|
+
nio4r (2.1.0)
|
27
|
+
ohm (3.1.1)
|
28
|
+
nest (~> 3)
|
29
|
+
redic (~> 1.5.0)
|
30
|
+
stal
|
31
|
+
pg (0.21.0)
|
32
|
+
rake (12.0.0)
|
33
|
+
redic (1.5.0)
|
34
|
+
hiredis
|
35
|
+
rspec (3.6.0)
|
36
|
+
rspec-core (~> 3.6.0)
|
37
|
+
rspec-expectations (~> 3.6.0)
|
38
|
+
rspec-mocks (~> 3.6.0)
|
39
|
+
rspec-core (3.6.0)
|
40
|
+
rspec-support (~> 3.6.0)
|
41
|
+
rspec-expectations (3.6.0)
|
42
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
43
|
+
rspec-support (~> 3.6.0)
|
44
|
+
rspec-mocks (3.6.0)
|
45
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
46
|
+
rspec-support (~> 3.6.0)
|
47
|
+
rspec-support (3.6.0)
|
48
|
+
sequel (4.47.0)
|
49
|
+
simplecov (0.14.1)
|
50
|
+
docile (~> 1.1.0)
|
51
|
+
json (>= 1.8, < 3)
|
52
|
+
simplecov-html (~> 0.10.0)
|
53
|
+
simplecov-html (0.10.1)
|
54
|
+
stal (0.3.0)
|
55
|
+
redic (~> 1.5)
|
56
|
+
yard (0.9.9)
|
57
|
+
|
58
|
+
PLATFORMS
|
59
|
+
ruby
|
60
|
+
|
61
|
+
DEPENDENCIES
|
62
|
+
bundler (~> 1.0)
|
63
|
+
codeclimate-test-reporter (~> 1.0)
|
64
|
+
hiredis (~> 0.6.0)
|
65
|
+
kramdown (~> 1.13)
|
66
|
+
midori-contrib!
|
67
|
+
mysql2 (~> 0.4)
|
68
|
+
ohm (~> 3.0)
|
69
|
+
pg (~> 0.17)
|
70
|
+
rake (~> 12.0)
|
71
|
+
rspec (~> 3.0)
|
72
|
+
sequel (~> 4.40)
|
73
|
+
simplecov (~> 0.14)
|
74
|
+
yard (~> 0.9)
|
75
|
+
|
76
|
+
BUNDLED WITH
|
77
|
+
1.14.6
|
@@ -0,0 +1,51 @@
|
|
1
|
+
##
|
2
|
+
# Midori Extension of File reading and writing
|
3
|
+
class MidoriContrib::File
|
4
|
+
# Init File object
|
5
|
+
# @param [Array] args same args like File.new
|
6
|
+
def initialize(*args)
|
7
|
+
@file = File.new(*args)
|
8
|
+
end
|
9
|
+
|
10
|
+
# read file
|
11
|
+
# @return [String] string readed
|
12
|
+
def read
|
13
|
+
await(Promise.new do |resolve|
|
14
|
+
data = ''
|
15
|
+
EventLoop.register(@file, :r) do
|
16
|
+
if @file.eof?
|
17
|
+
EventLoop.deregister(@file)
|
18
|
+
resolve.call(data)
|
19
|
+
else
|
20
|
+
data << @file.read_nonblock(16384)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end)
|
24
|
+
end
|
25
|
+
|
26
|
+
# write file
|
27
|
+
# @param [String] data string to be written
|
28
|
+
def write(data)
|
29
|
+
await(Promise.new do |resolve|
|
30
|
+
written = 0
|
31
|
+
EventLoop.register(@file, :w) do
|
32
|
+
written += @file.write_nonblock(data[written..-1])
|
33
|
+
if written == data.size
|
34
|
+
EventLoop.deregister(@file)
|
35
|
+
resolve.call(written)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end)
|
39
|
+
end
|
40
|
+
|
41
|
+
# raw file object
|
42
|
+
# @return [File] file
|
43
|
+
def raw
|
44
|
+
@file
|
45
|
+
end
|
46
|
+
|
47
|
+
# Close the file
|
48
|
+
def close
|
49
|
+
@file.close
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'net/protocol'
|
2
|
+
|
3
|
+
##
|
4
|
+
# Meta programming Net class for async HTTP and FTP connection
|
5
|
+
class Net::BufferedIO
|
6
|
+
# Wait till io finishes
|
7
|
+
# @param [Symbol] interest
|
8
|
+
def wait_io(interest)
|
9
|
+
await(Promise.new do |resolve|
|
10
|
+
io = @io.to_io
|
11
|
+
EventLoop.register(io, interest) do
|
12
|
+
EventLoop.deregister(io)
|
13
|
+
resolve.call(self)
|
14
|
+
end
|
15
|
+
end)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Fill until the operation finishes
|
19
|
+
def rbuf_fill
|
20
|
+
loop do
|
21
|
+
case rv = @io.read_nonblock(BUFSIZE, exception: false)
|
22
|
+
when String
|
23
|
+
return @rbuf << rv
|
24
|
+
when :wait_readable
|
25
|
+
wait_io(:r)
|
26
|
+
# @io.to_io.wait_readable(@read_timeout) or raise Net::ReadTimeout
|
27
|
+
# continue looping
|
28
|
+
when :wait_writable
|
29
|
+
# OpenSSL::Buffering#read_nonblock may fail with IO::WaitWritable.
|
30
|
+
# http://www.openssl.org/support/faq.html#PROG10
|
31
|
+
# :nocov:
|
32
|
+
wait_io(:w)
|
33
|
+
# @io.to_io.wait_writable(@read_timeout) or raise Net::ReadTimeout
|
34
|
+
# continue looping
|
35
|
+
when nil
|
36
|
+
# callers do not care about backtrace, so avoid allocating for it
|
37
|
+
raise EOFError, 'end of file reached', []
|
38
|
+
# :nocov:
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
##
|
2
|
+
# Meta-programming hiredis for redis async extension
|
3
|
+
module Hiredis
|
4
|
+
require 'hiredis/connection'
|
5
|
+
# Overwrite with ruby implementation to hook IO
|
6
|
+
require 'hiredis/ruby/connection'
|
7
|
+
require 'hiredis/ruby/reader'
|
8
|
+
# Redis Connection
|
9
|
+
Connection = Ruby::Connection
|
10
|
+
# Redis Result Reader
|
11
|
+
Reader = Ruby::Reader
|
12
|
+
|
13
|
+
##
|
14
|
+
# Meta-programming hiredis for redis async extension
|
15
|
+
module Ruby
|
16
|
+
##
|
17
|
+
# Meta-programming hiredis for redis async extension
|
18
|
+
class Connection
|
19
|
+
# Do redis query
|
20
|
+
# @param [Array] args equal to Hiredis write args
|
21
|
+
def query(args)
|
22
|
+
await(Promise.new do |resolve|
|
23
|
+
read_flag = false
|
24
|
+
data = pre_write(args)
|
25
|
+
written = 0
|
26
|
+
EventLoop.register(@sock, :rw) do |monitor|
|
27
|
+
if read_flag && monitor.readable?
|
28
|
+
# Reading
|
29
|
+
_read(resolve, @sock)
|
30
|
+
end
|
31
|
+
if !read_flag && monitor.writable?
|
32
|
+
# Writing
|
33
|
+
written += @sock.write_nonblock(data[written..-1])
|
34
|
+
read_flag = true if written == string_size(data)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end)
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
def pre_write(args)
|
42
|
+
command = []
|
43
|
+
command << "*#{args.size}"
|
44
|
+
args.each do |arg|
|
45
|
+
arg = arg.to_s
|
46
|
+
command << "$#{string_size arg}"
|
47
|
+
command << arg
|
48
|
+
end
|
49
|
+
data = command.join(COMMAND_DELIMITER) + COMMAND_DELIMITER
|
50
|
+
data.force_encoding('binary') if data.respond_to?(:force_encoding)
|
51
|
+
data
|
52
|
+
end
|
53
|
+
|
54
|
+
def _read(resolve, sock)
|
55
|
+
@reader.feed @sock.read_nonblock(1024)
|
56
|
+
reply = @reader.gets
|
57
|
+
if reply
|
58
|
+
EventLoop.deregister(sock)
|
59
|
+
resolve.call(reply)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
require 'redic'
|
67
|
+
|
68
|
+
##
|
69
|
+
# Meta-programming Redic for redis async extension
|
70
|
+
class Redic
|
71
|
+
# Meta-programming Redic for redis async extension
|
72
|
+
class Client
|
73
|
+
# Connect redis, yield optional
|
74
|
+
def connect
|
75
|
+
establish_connection unless connected?
|
76
|
+
if block_given?
|
77
|
+
# Redic default yield
|
78
|
+
# :nocov:
|
79
|
+
@semaphore.synchronize do
|
80
|
+
yield
|
81
|
+
end
|
82
|
+
# :nocov:
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# Call without thread lock
|
87
|
+
# @param [Array] args same params as Redic
|
88
|
+
def call(*args)
|
89
|
+
@connection.query(*args)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# Call without thread lock
|
94
|
+
# @param [Array] args same params as Redic
|
95
|
+
def call(*args)
|
96
|
+
@client.connect
|
97
|
+
@client.call(args)
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
require 'sequel'
|
2
|
+
require 'sequel/adapters/mysql2'
|
3
|
+
|
4
|
+
# Management of MySQL Sockets
|
5
|
+
MYSQL_SOCKETS = {}
|
6
|
+
|
7
|
+
##
|
8
|
+
# Meta-programming Sequel for async extensions
|
9
|
+
module Sequel
|
10
|
+
# Midori Extension of sequel MySQL through meta programming
|
11
|
+
module Mysql2
|
12
|
+
# Midori Extension of sequel MySQL through meta programming
|
13
|
+
class Database
|
14
|
+
# Execute the given SQL on the given connection. If the :type
|
15
|
+
# option is :select, yield the result of the query, otherwise
|
16
|
+
# yield the connection if a block is given.
|
17
|
+
# @param [Mysql2::Client] conn connection to database
|
18
|
+
# @param [String] sql sql query
|
19
|
+
# @param [Hash] opts optional options
|
20
|
+
# @return [Mysql2::Result] MySQL results
|
21
|
+
def _execute(conn, sql, opts) # rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity
|
22
|
+
begin
|
23
|
+
# :nocov:
|
24
|
+
stream = opts[:stream]
|
25
|
+
if NativePreparedStatements
|
26
|
+
if (args = opts[:arguments])
|
27
|
+
args = args.map{|arg| bound_variable_value(arg)}
|
28
|
+
end
|
29
|
+
|
30
|
+
case sql
|
31
|
+
when ::Mysql2::Statement
|
32
|
+
stmt = sql
|
33
|
+
when Dataset
|
34
|
+
sql = sql.sql
|
35
|
+
close_stmt = true
|
36
|
+
stmt = conn.prepare(sql)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
r = log_connection_yield((log_sql = opts[:log_sql]) ? sql + log_sql : sql, conn, args) do
|
41
|
+
if stmt
|
42
|
+
conn.query_options.merge!(cache_rows: true,
|
43
|
+
database_timezone: timezone,
|
44
|
+
application_timezone: Sequel.application_timezone,
|
45
|
+
stream: stream,
|
46
|
+
cast_booleans: convert_tinyint_to_bool)
|
47
|
+
stmt.execute(*args)
|
48
|
+
# :nocov:
|
49
|
+
else
|
50
|
+
if MYSQL_SOCKETS[conn.socket].nil?
|
51
|
+
MYSQL_SOCKETS[conn.socket] = IO::open(conn.socket)
|
52
|
+
end
|
53
|
+
socket = MYSQL_SOCKETS[conn.socket]
|
54
|
+
await(Promise.new do |resolve|
|
55
|
+
count = 0
|
56
|
+
EventLoop.register(socket, :rw) do
|
57
|
+
if (count == 0)
|
58
|
+
# Writable
|
59
|
+
count += 1
|
60
|
+
conn.query(sql,
|
61
|
+
database_timezone: timezone,
|
62
|
+
application_timezone: Sequel.application_timezone,
|
63
|
+
stream: stream,
|
64
|
+
async: true)
|
65
|
+
else
|
66
|
+
# Readable
|
67
|
+
begin
|
68
|
+
EventLoop.deregister(socket)
|
69
|
+
resolve.call(conn.async_result)
|
70
|
+
rescue ::Mysql2::Error => e
|
71
|
+
resolve.call(PromiseException.new(e))
|
72
|
+
next
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# :nocov:
|
81
|
+
if opts[:type] == :select
|
82
|
+
if r
|
83
|
+
if stream
|
84
|
+
begin
|
85
|
+
r2 = yield r
|
86
|
+
ensure
|
87
|
+
# If r2 is nil, it means the block did not exit normally,
|
88
|
+
# so the rest of the results must be drained to prevent
|
89
|
+
# "commands out of sync" errors.
|
90
|
+
r.each{} unless r2
|
91
|
+
end
|
92
|
+
else
|
93
|
+
yield r
|
94
|
+
end
|
95
|
+
end
|
96
|
+
elsif block_given?
|
97
|
+
yield conn
|
98
|
+
end
|
99
|
+
rescue ::Mysql2::Error => e
|
100
|
+
raise_error(e)
|
101
|
+
ensure
|
102
|
+
if stmt
|
103
|
+
conn.query_options.replace(conn.instance_variable_get(:@sequel_default_query_options))
|
104
|
+
stmt.close if close_stmt
|
105
|
+
end
|
106
|
+
# :nocov:
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'sequel'
|
2
|
+
require 'sequel/adapters/postgres'
|
3
|
+
|
4
|
+
# Management of Postgres Sockets
|
5
|
+
POSTGRES_SOCKETS = {}
|
6
|
+
|
7
|
+
##
|
8
|
+
# Midori Extension of sequel postgres through meta programming
|
9
|
+
class Sequel::Postgres::Adapter
|
10
|
+
# Call a sql request asynchronously
|
11
|
+
# @param [String] sql sql request
|
12
|
+
# @param [Array] args args to send
|
13
|
+
# @return [Array] sql query result
|
14
|
+
def execute_query(sql, args)
|
15
|
+
@db.log_connection_yield(sql, self, args) do
|
16
|
+
if POSTGRES_SOCKETS[self].nil?
|
17
|
+
POSTGRES_SOCKETS[self] = IO::open(socket)
|
18
|
+
end
|
19
|
+
socket_object = POSTGRES_SOCKETS[self]
|
20
|
+
await(Promise.new do |resolve|
|
21
|
+
count = 0
|
22
|
+
EventLoop.register(socket_object, :rw) do
|
23
|
+
begin
|
24
|
+
if (count == 0)
|
25
|
+
# Writable
|
26
|
+
unless is_busy
|
27
|
+
send_query(sql)
|
28
|
+
count += 1
|
29
|
+
end
|
30
|
+
else
|
31
|
+
# Readable
|
32
|
+
EventLoop.deregister(socket_object)
|
33
|
+
resolve.call(get_result)
|
34
|
+
end
|
35
|
+
# For extra errors
|
36
|
+
# :nocov:
|
37
|
+
rescue => e
|
38
|
+
resolve.call(PromiseException.new(e))
|
39
|
+
# :nocov:
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require './lib/midori-contrib'
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = 'midori-contrib'
|
5
|
+
s.version = MidoriContrib::VERSION
|
6
|
+
s.required_ruby_version = '>=2.2.6'
|
7
|
+
s.date = Time.now.strftime('%Y-%m-%d')
|
8
|
+
s.summary = 'Various extensions for midori'
|
9
|
+
s.description = 'Various extensions officially supported for midori'
|
10
|
+
s.authors = ['HeckPsi Lab']
|
11
|
+
s.email = 'business@heckpsi.com'
|
12
|
+
s.require_paths = ['lib']
|
13
|
+
s.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(spec|.resources)/}) } \
|
14
|
+
- %w(README.md CONTRIBUTOR_COVENANT_CODE_OF_CONDUCT.md Gemfile Rakefile em-midori.gemspec .gitignore .rspec .codeclimate.yml .rubocop.yml .travis.yml logo.png Rakefile Gemfile)
|
15
|
+
s.homepage = 'https://github.com/heckpsi-lab/midori-contrib'
|
16
|
+
s.metadata = { 'issue_tracker' => 'https://github.com/heckpsi-lab/midori-contrib/issues' }
|
17
|
+
s.license = 'MIT'
|
18
|
+
s.add_runtime_dependency 'em-midori', '~> 0.3'
|
19
|
+
end
|
metadata
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: midori-contrib
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- HeckPsi Lab
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-06-15 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: em-midori
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.3'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.3'
|
27
|
+
description: Various extensions officially supported for midori
|
28
|
+
email: business@heckpsi.com
|
29
|
+
executables: []
|
30
|
+
extensions: []
|
31
|
+
extra_rdoc_files: []
|
32
|
+
files:
|
33
|
+
- ".editorconfig"
|
34
|
+
- Gemfile.lock
|
35
|
+
- lib/midori-contrib.rb
|
36
|
+
- lib/midori-contrib/file.rb
|
37
|
+
- lib/midori-contrib/net.rb
|
38
|
+
- lib/midori-contrib/redic.rb
|
39
|
+
- lib/midori-contrib/sequel/mysql2.rb
|
40
|
+
- lib/midori-contrib/sequel/postgres.rb
|
41
|
+
- midori-contrib.gemspec
|
42
|
+
homepage: https://github.com/heckpsi-lab/midori-contrib
|
43
|
+
licenses:
|
44
|
+
- MIT
|
45
|
+
metadata:
|
46
|
+
issue_tracker: https://github.com/heckpsi-lab/midori-contrib/issues
|
47
|
+
post_install_message:
|
48
|
+
rdoc_options: []
|
49
|
+
require_paths:
|
50
|
+
- lib
|
51
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: 2.2.6
|
56
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
requirements: []
|
62
|
+
rubyforge_project:
|
63
|
+
rubygems_version: 2.6.10
|
64
|
+
signing_key:
|
65
|
+
specification_version: 4
|
66
|
+
summary: Various extensions for midori
|
67
|
+
test_files: []
|