Skip to content

Commit

Permalink
Implementing MRI support via C exts
Browse files Browse the repository at this point in the history
  • Loading branch information
Alex Jokela committed Jun 27, 2012
1 parent fecddf9 commit a0b99ee
Show file tree
Hide file tree
Showing 9 changed files with 210 additions and 307 deletions.
7 changes: 5 additions & 2 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@ source :rubygems
gem 'mysql-pr', :git => 'git://github.com/ajokela/mysql-pr.git'
gem 'postgres-pr'

gem 'activerecord'

platforms :jruby do
gem 'activerecord'
gem 'jdbc-postgres'
gem 'activerecord-jdbc-adapter'
gem 'activerecord-jdbcpostgresql-adapter'
end

platforms :mri_19 do
gem 'pg'
end

gem 'test-unit'
32 changes: 27 additions & 5 deletions bin/mysql-to-postgres
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,46 @@ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')

require 'rubygems'
require 'bundler/setup'
require 'active_record'


if RUBY_PLATFORM == 'java'
require 'active_record'
require 'postgres-pr/postgres-compat'
else
require 'pg_ext'
require 'pg/exceptions'
require 'pg/constants'
require 'pg/connection'
require 'pg/result'
require 'pg'
end

require '../lib/mysql2psql'

CONFIG_FILE = File.expand_path(File.expand_path(File.dirname(__FILE__)) + "/../config/database.yml")

if FileTest.exist?(CONFIG_FILE)
if FileTest.exist?(CONFIG_FILE) or (ARGV.length > 0 and FileTest.exist?(File.expand_path(ARGV[0])))

db_yaml = YAML::load_file CONFIG_FILE
if ARGV.length > 0
file = ARGV[0]
else
file = CONFIG_FILE
end

base_name = File.basename(file)

db_yaml = YAML::load_file file

if db_yaml.has_key?('mysql2psql')
# puts db_yaml["mysql2psql"].to_s
Mysql2psql.new(db_yaml["mysql2psql"]).convert
else
# Oh Noes! There is no key in the hash...
raise "database.yml does not contain a configuration directive for mysql -> postgres"
raise "#{base_name} does not contain a configuration directive for mysql -> postgres"
end


else
raise "#{base_name} does not exist"
end

# exit Mysql2psql.new(yaml).convert
3 changes: 3 additions & 0 deletions config/default.database.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,6 @@ mysql2psql:

preserve_order: true

remove_dump_file: true

report_status: json # false, json, xml
10 changes: 6 additions & 4 deletions lib/mysql2psql.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
require 'mysql2psql/writer'
require 'mysql2psql/postgres_writer'
require 'mysql2psql/postgres_file_writer.rb'
require 'mysql2psql/postgres_activerecord_writer.rb'
require 'mysql2psql/postgres_db_writer.rb'

class Mysql2psql

Expand All @@ -33,13 +33,15 @@ def convert

tag = Time.new.to_s.gsub(/((\-)|( )|(:))+/, '')

filename = tag + '_output.sql'
filename = File.expand_path('./' + tag + '_output.sql')

@writer = PostgresActiveRecordWriter.new(filename, options)
@writer = PostgresDbWriter.new(filename, options)

Converter.new(reader, writer, options).convert

writer.inload
if options.config['remove_dump_file']
File.delete filename if File::exists?( filename )
end

end

Expand Down
133 changes: 133 additions & 0 deletions lib/mysql2psql/connection.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@

class Mysql2psql

class Connection

attr_reader :conn, :adapter, :hostname, :login, :password, :database, :schema, :port, :environment, :jruby, :copy_manager, :stream, :is_copying

def initialize(options)

# Rails-centric stuffs
@environment = ENV['RAILS_ENV'].nil? ? 'development' : ENV['RAILS_ENV']

if options.has_key?('config') and options['config'].has_key?('destination') and options['config']['destination'].has_key?(environment)

pg_options = Config.new(YAML::load(options['config']['destination'][environment].to_yaml))
@hostname, @login, @password, @database, @port = pg_options.hostname('localhost'), pg_options.username, pg_options.password, pg_options.database, pg_options.port(5432).to_s
@database, @schema = database.split(":")

@adapter = pg_options.adapter("jdbcpostgresql")

else
raise "Unable to locate PostgreSQL destination environment in the configuration file"
end

if RUBY_PLATFORM == 'jruby'
@jruby = true

ActiveRecord::Base.establish_connection(
:adapter => adapter,
:database => database,
:username => login,
:password => password,
:host => hostname,
:port => port)

@conn = ActiveRecord::Base.connection_pool.checkout

unless conn.nil?
raw_connection = conn.raw_connection
@copy_manager = org.postgresql.copy.CopyManager.new(raw_connection.connection)
else
raise_nil_connection
end

else
@jruby = false

@conn = PG.connect( dbname: database, user: login, password: password, host: hostname, port: port )

unless conn.nil?

else
raise_nil_connection
end

end

@is_copying = false

end

def execute(sql)

if sql.match(/^COPY /) and ! is_copying
sql.chomp! # cHomp! cHomp!

if jruby
@stream = copy_manager.copy_in(sql)
else
conn.exec( sql )
end

@is_copying = true

elsif sql.match(/^TRUNCATE /) and ! is_copying

$stderr.puts "===> ERR: TRUNCATE is not implemented!"

elsif sql.match(/^ALTER /) and ! is_copying

$stderr.puts "===> ERR: ALTER is not implemented!"

elsif is_copying

if sql.match(/^\\\./)

@is_copying = false

if jruby
stream.end_copy
else
conn.put_copy_end
end

else

if jruby
begin
row = sql.to_java_bytes
stream.write_to_copy(row, 0, row.length)
rescue Exception => e
stream.cancel_copy
raise e
end
else

begin

until conn.put_copy_data( sql )
$stderr.puts " waiting for connection to be writable..."
sleep 0.1
end

rescue Exception => e
$stderr.puts e
raise e
end

end

end

end

end

def raise_nil_connection
raise "No Connection"
end

end

end
22 changes: 18 additions & 4 deletions lib/mysql2psql/converter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,24 @@ def convert
writer.write_table(table)
end unless @suppress_ddl

tables.each do |table|
writer.truncate(table) if force_truncate && suppress_ddl
writer.write_contents(table, reader)
end unless @suppress_data
# tables.each do |table|
# writer.truncate(table) if force_truncate && suppress_ddl
# writer.write_contents(table, reader)
# end unless @suppress_data

unless @suppress_data

tables.each do |table|
writer.truncate(table) if force_truncate and suppress_ddl
end

tables.each do |table|
writer.write_contents(table, reader)
end

writer.inload

end

tables.each do |table|
writer.write_indexes(table)
Expand Down
110 changes: 0 additions & 110 deletions lib/mysql2psql/postgres_activerecord_writer.rb

This file was deleted.

Loading

0 comments on commit a0b99ee

Please sign in to comment.