mysql_isolated_server 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c86a7be139488f4c7980f150cb2df8d998730c3a
4
- data.tar.gz: d90947e7b2e7bc90083bf7f63c93a00c56bfb661
3
+ metadata.gz: 5d8abd30d623ca6de6dc2bffdbda2a4a7b0bbbb5
4
+ data.tar.gz: 390239042496260846019bf0ee3ca7289b8c293c
5
5
  SHA512:
6
- metadata.gz: e15d257eab67513a552482f2b58eb86ad89a65f1dff1032d1b40a2108db393dc4f8fc0be8dee8c8f0a2f2c0045cb2d983bdac0a424cb7a40a0fd7cd2c6a7d154
7
- data.tar.gz: e15e5009dc2a940b3c547cfcb6bc817787d1d4b130c26f9510d3aa634c220efb5cfb41dedb95749bc95e6952c1806d8ceff6406c0a2cdbbb162f265147d445a5
6
+ metadata.gz: 14b04cc5b22b42c6b9020a3d991483871a67b19e4339ae71762e278e751352432080afce395f722ebbb639edd19f55c93d8dae7e18d5a2ff7de3bd11f6963aef
7
+ data.tar.gz: dc810674507fa907e24595314a238a150e7c05906c2d1a5d2b684e0c415170bf400f73d9df927ad948a81c43330962c1928db7b44f3e8330d4b2b2b59b15560e
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/ruby
2
+ require 'rubygems'
3
+ $LOAD_PATH << File.dirname(__FILE__) + "/../lib"
4
+ require 'mysql_isolated_server'
5
+ require 'getoptlong'
6
+
7
+ $stderr.puts ENV.inspect
8
+ opts = GetoptLong.new(
9
+ [ '--log-bin', GetoptLong::REQUIRED_ARGUMENT ],
10
+ [ '--pid', GetoptLong::REQUIRED_ARGUMENT ]
11
+ )
12
+
13
+ options = {}
14
+ opts.each do |opt, arg|
15
+ case opt
16
+ when '--log-bin'
17
+ options[:log_bin] = arg
18
+ when '--pid'
19
+ options[:pid] = arg.to_i
20
+ end
21
+ end
22
+
23
+ options[:params] = ARGV.join(' ')
24
+
25
+ mysql_isolated_server = MysqlIsolatedServer.new(options)
26
+ mysql_isolated_server.boot!
27
+
28
+ puts "dir: " + mysql_isolated_server.base
29
+ puts "port: " + mysql_isolated_server.port.to_s
30
+ STDOUT.flush
@@ -1,23 +1,56 @@
1
1
  require 'tmpdir'
2
2
  require 'socket'
3
- require 'mysql2'
3
+
4
+ if RUBY_PLATFORM == "java"
5
+ require 'mysql_isolated_server/jdbc_connection'
6
+ else
7
+ require 'mysql_isolated_server/mysql2_connection'
8
+ end
4
9
 
5
10
  class MysqlIsolatedServer
11
+ include DBConnection
6
12
  attr_reader :pid, :base, :port
7
13
  attr_accessor :params
8
14
  MYSQL_BASE_DIR="/usr"
9
15
 
10
16
  def initialize(options = {})
11
- @base = Dir.mktmpdir("mysql_isolated", "/tmp")
17
+ @base = options[:base] || Dir.mktmpdir("mysql_isolated", "/tmp")
12
18
  @mysql_data_dir="#{@base}/mysqld"
13
19
  @mysql_socket="#{@mysql_data_dir}/mysqld.sock"
14
20
  @params = options[:params]
15
21
  @load_data_path = options[:data_path]
16
22
  @port = options[:port]
17
23
  @allow_output = options[:allow_output]
24
+ @log_bin = options[:log_bin] || "--log-bin"
25
+ @parent_pid = options[:pid]
18
26
  @server_id = rand(2**31)
19
27
  end
20
28
 
29
+ def self.thread_boot(*params)
30
+ bin = File.dirname(__FILE__) + "/../bin/boot_isolated_server"
31
+ mysql_dir, mysql_port = nil, nil
32
+ restore_env = {}
33
+
34
+ Thread.abort_on_exception = true
35
+ Thread.new do
36
+ ENV.keys.grep(/GEM|BUNDLE|RUBYOPT/).each do |k|
37
+ restore_env[k] = ENV.delete(k)
38
+ end
39
+ params = ["--pid", $$.to_s] + params
40
+
41
+ pipe = IO.popen(["#{bin}"].concat(params), "r") do |pipe|
42
+ mysql_dir = pipe.readline.split(' ').last
43
+ mysql_port = pipe.readline.split(' ').last.to_i
44
+ sleep
45
+ end
46
+ end
47
+
48
+ while mysql_port.nil?
49
+ sleep 1
50
+ end
51
+ new(:port => mysql_port, :base => mysql_dir)
52
+ end
53
+
21
54
  def make_slave_of(master)
22
55
  master_binlog_info = master.connection.query("show master status").first
23
56
  connection.query(<<-EOL
@@ -32,10 +65,6 @@ class MysqlIsolatedServer
32
65
  connection.query("SET GLOBAL READ_ONLY=1")
33
66
  end
34
67
 
35
- def connection
36
- @cx ||= Mysql2::Client.new(:host => "127.0.0.1", :port => @port, :username => "root", :password => "", :database => "mysql")
37
- end
38
-
39
68
  def set_rw(rw)
40
69
  ro = rw ? 0 : 1
41
70
  connection.query("SET GLOBAL READ_ONLY=#{ro}")
@@ -54,7 +83,7 @@ class MysqlIsolatedServer
54
83
  exec_server <<-EOL
55
84
  #{mysqld} --no-defaults --default-storage-engine=innodb \
56
85
  --datadir=#{@mysql_data_dir} --pid-file=#{@base}/mysqld.pid --port=#{@port} \
57
- #{@params} --socket=#{@mysql_data_dir}/mysql.sock --log-bin --log-slave-updates
86
+ #{@params} --socket=#{@mysql_data_dir}/mysql.sock #{@log_bin} --log-slave-updates
58
87
  EOL
59
88
 
60
89
  while !system("mysql -h127.0.0.1 --port=#{@port} --database=mysql -u root -e 'select 1' >/dev/null 2>&1")
@@ -85,6 +114,19 @@ class MysqlIsolatedServer
85
114
  system("cp #{File.expand_path(File.dirname(__FILE__))}/tables/user.* #{@mysql_data_dir}/mysql")
86
115
  end
87
116
 
117
+ if !@log_bin
118
+ @log_bin = "--log-bin"
119
+ else
120
+ if @log_bin[0] != '/'
121
+ binlog_dir = "#{@mysql_data_dir}/#{@log_bin}"
122
+ else
123
+ binlog_dir = @log_bin
124
+ end
125
+
126
+ system("mkdir -p #{binlog_dir}")
127
+ @log_bin = "--log-bin=#{binlog_dir}"
128
+ end
129
+
88
130
  up!
89
131
 
90
132
  tzinfo_to_sql = locate_executable("mysql_tzinfo_to_sql5", "mysql_tzinfo_to_sql")
@@ -100,7 +142,7 @@ class MysqlIsolatedServer
100
142
 
101
143
  begin
102
144
  socket = Socket.new(:INET, :STREAM, 0)
103
- socket.bind(Addrinfo.tcp("127.0.0.1", candidate))
145
+ socket.bind(Socket.pack_sockaddr_in(candidate, '127.0.0.1'))
104
146
  socket.close
105
147
  return candidate
106
148
  rescue Exception => e
@@ -117,9 +159,10 @@ class MysqlIsolatedServer
117
159
  system("mkdir -p #{base}/tmp")
118
160
  system("chmod 0777 #{base}/tmp")
119
161
 
120
- original_pid = $$
162
+ parent_pid = @parent_pid || $$
121
163
  mysql_pid = nil
122
164
 
165
+ $stderr.puts cmd
123
166
  middle_pid = fork do
124
167
  mysql_pid = fork do
125
168
  ENV["TMPDIR"] = "#{base}/tmp"
@@ -134,15 +177,18 @@ class MysqlIsolatedServer
134
177
  # begin waiting for the parent (or mysql) to die; at_exit is hard to control when interacting with test/unit
135
178
  # we can also be killed by our parent with down! and up!
136
179
  #
137
- trap("TERM") do
138
- Process.kill("KILL", mysql_pid) rescue nil
139
- cleanup!
140
- exit!
180
+ ["TERM", "INT"].each do |sig|
181
+ trap(sig) do
182
+ Process.kill("KILL", mysql_pid) rescue nil
183
+ cleanup!
184
+ exit!
185
+ end
141
186
  end
142
187
 
188
+
143
189
  while true
144
190
  begin
145
- Process.kill(0, original_pid)
191
+ Process.kill(0, parent_pid)
146
192
  Process.kill(0, mysql_pid)
147
193
  rescue Exception => e
148
194
  Process.kill("KILL", mysql_pid) rescue nil
@@ -0,0 +1,49 @@
1
+ require "java"
2
+ java_import "java.sql.DriverManager"
3
+ java_import "org.apache.commons.lang.StringEscapeUtils"
4
+
5
+ class MysqlIsolatedServer
6
+ class WrappedJDBCConnection
7
+ def initialize(port)
8
+ @cx ||= DriverManager.get_connection("jdbc:mysql://127.0.0.1:#{port}/mysql", "root", "")
9
+ end
10
+
11
+ def query(sql)
12
+ stmt = @cx.create_statement
13
+ if sql !~ /^select/i && sql !~ /^show/i
14
+ return stmt.execute(sql)
15
+ end
16
+
17
+ rs = stmt.execute_query(sql)
18
+ while (rs.next)
19
+ rows = []
20
+ meta_data = rs.get_meta_data
21
+ num_cols = meta_data.get_column_count
22
+
23
+ row = {}
24
+ 1.upto(num_cols) do |col|
25
+ col_name = meta_data.get_column_label(col)
26
+ col_value = rs.get_object(col) # of meta_data.get_column_type(col)
27
+
28
+ row[col_name] = col_value if col_value # skip if nil
29
+ end
30
+
31
+ rows << row
32
+ end
33
+ rows
34
+ ensure
35
+ stmt.close if stmt
36
+ rs.close if rs
37
+ end
38
+
39
+ def escape(str)
40
+ StringEscapeUtils.escapeSql(str)
41
+ end
42
+ end
43
+
44
+ module DBConnection
45
+ def connection
46
+ @connection ||= WrappedJDBCConnection.new(@port)
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,8 @@
1
+ class MysqlIsolatedServer
2
+ module DBConnection
3
+ def connection
4
+ require 'mysql2'
5
+ @cx ||= Mysql2::Client.new(:host => "127.0.0.1", :port => @port, :username => "root", :password => "", :database => "mysql")
6
+ end
7
+ end
8
+ end
@@ -1,3 +1,3 @@
1
1
  class MysqlIsolatedServer
2
- VERSION = "0.2.2"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -15,6 +15,5 @@ Gem::Specification.new do |gem|
15
15
  gem.files = `git ls-files`.split($/)
16
16
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
17
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
- gem.add_dependency "mysql2"
19
18
  gem.require_paths = ["lib"]
20
19
  end
metadata CHANGED
@@ -1,34 +1,21 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mysql_isolated_server
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Osheroff
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-22 00:00:00.000000000 Z
12
- dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: mysql2
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '0'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: '0'
11
+ date: 2014-06-16 00:00:00.000000000 Z
12
+ dependencies: []
27
13
  description: A small library that allows you to easily spin up new local mysql servers
28
14
  for testing purposes.
29
15
  email:
30
16
  - ben@zendesk.com
31
- executables: []
17
+ executables:
18
+ - boot_isolated_server
32
19
  extensions: []
33
20
  extra_rdoc_files: []
34
21
  files:
@@ -37,7 +24,10 @@ files:
37
24
  - LICENSE.txt
38
25
  - README.md
39
26
  - Rakefile
27
+ - bin/boot_isolated_server
40
28
  - lib/mysql_isolated_server.rb
29
+ - lib/mysql_isolated_server/jdbc_connection.rb
30
+ - lib/mysql_isolated_server/mysql2_connection.rb
41
31
  - lib/mysql_isolated_server/version.rb
42
32
  - lib/tables/user.MYD
43
33
  - lib/tables/user.MYI