midori-contrib 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|