diff --git a/src/onedb/onedb b/src/onedb/onedb index 7afbb3b160..3112854b01 100755 --- a/src/onedb/onedb +++ b/src/onedb/onedb @@ -356,4 +356,24 @@ cmd=CommandParser::CmdParser.new(ARGV) do end end + ########################################################################### + # Migrate SQLite to MySQL + ########################################################################### + sqlite2mysql_desc = <<-EOT.unindent + Migrates a SQLite OpenNebula Database to MySQL + EOT + + command :sqlite2mysql , sqlite2mysql_desc, :options=>[BACKUP, FORCE] do + begin + options[:backend] = :sqlite + sqlite = OneDB.new(options) + + options[:backend] = :mysql + mysql = OneDB.new(options) + + mysql.sqlite2mysql(options, sqlite) + rescue Exception => e + [-1, e.message] + end + end end diff --git a/src/onedb/onedb.rb b/src/onedb/onedb.rb index 6df4b658a2..aed9f983b7 100644 --- a/src/onedb/onedb.rb +++ b/src/onedb/onedb.rb @@ -20,6 +20,8 @@ require 'onedb_backend' LOG_TIME = false class OneDB + attr_accessor :backend + def initialize(ops) if ops[:backend] == :sqlite begin @@ -519,6 +521,40 @@ is preserved. end end + def sqlite2mysql(options, sqlite) + one_not_running() + + sqlite_v = sqlite.backend.read_db_version + mysql_v = @backend.read_db_version + + if !options[:force] + match = true + match = false if sqlite_v[:version] != mysql_v[:version] + match = false if sqlite_v[:local_version] != mysql_v[:local_version] + + if !match + err_msg = "SQLite version: #{sqlite_v[:version]}\n" + err_msg << "SQLite local version: #{sqlite_v[:local_version]}\n" + err_msg << "MySQL version: #{mysql_v[:version]}\n" + err_msg << "MySQL local version: #{mysql_v[:local_version]}\n" + err_msg << "The MySQL and SQLite versions do not match. Please run " + err_msg << "'onedb -i' in order to bootstrap a blank OpenNebula DB." + + raise err_msg + end + end + + backup(options[:backup], options) + + file = "#{RUBY_LIB_LOCATION}/onedb/sqlite2mysql.rb" + load(file) + @backend.extend Sqlite2MySQL + + @backend.convert(sqlite.backend.db) + + return 0 + end + private def one_not_running() diff --git a/src/onedb/onedb_backend.rb b/src/onedb/onedb_backend.rb index e2970692a8..a689db5a44 100644 --- a/src/onedb/onedb_backend.rb +++ b/src/onedb/onedb_backend.rb @@ -286,7 +286,11 @@ class BackEndSQLite < OneDBBacKEnd require 'fileutils' def initialize(file) - @sqlite_file = file + if !file.nil? + @sqlite_file = file + else + raise "SQLite database path not supplied." + end end def bck_file diff --git a/src/onedb/sqlite2mysql.rb b/src/onedb/sqlite2mysql.rb new file mode 100644 index 0000000000..3b5ec585a4 --- /dev/null +++ b/src/onedb/sqlite2mysql.rb @@ -0,0 +1,33 @@ +module Sqlite2MySQL + + PROGRESS = 1000 + + def convert(sqlite_db) + puts "Starting migration from SQLite to MySQL\n" + + sqlite_db.tables.each do |table| + @db[table].delete + + records = sqlite_db[table].count + puts "> #{table} (#{records} records)" + + i=0 + sqlite_db[table].each do |row| + @db[table].insert(row) + + i+=1 + if i % PROGRESS == 0 + if i < PROGRESS+1 + print " #{i}" + else + print "...#{i}" + end + end + end + + puts if i > PROGRESS-1 + end + + puts "\nMigration successful." + end +end