Method: TinyBackup#restore_db

Defined in:
lib/tiny_backup.rb

#restore_db(version_number, just_temporary = true, with_backup = true) ⇒ Object

Change the database to match the selected integer version_number.

Parameters:

  • version_number (Integer or Symbol)

    can be :all to restore all backup data or 0 to restore only the data collected in the .zip file

  • just_temporary (Boolean) (defaults to: true)

    if is false, the unused version files will be deleted and the latest backup version will be synchronized with the database data.

  • with_backup (Boolean) (defaults to: true)

    if is false, the attempt to backup not saved data is canceled



220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
# File 'lib/tiny_backup.rb', line 220

def restore_db version_number, just_temporary=true, with_backup=true
  # do this before deleting the database and lose data
  backup_now if just_temporary && with_backup

  lock # if the resource is locked, we skip to ensure block
  locked_by_this_method = true

  tmp_files = []

  if just_temporary && version_number != :all
    puts "you want to restore just temporary: DO NOT start a backup BEFORE calling TinyBackup.restore_db(:all)\n" if !config.silent
  end

  version_files = Dir.glob("#{config.backup_folder}/#{config.version_prefix}*")
  if version_number == :all
    version_count = version_files.length
  else
    good_versions = version_files.find_all { |i| i.gsub("#{config.backup_folder}/#{config.version_prefix}", "").split("_").first.to_i <= version_number.to_i }
    version_count = good_versions.length
    tmp_files += version_files - good_versions if !just_temporary
  end

  tmp_origin_zip = compact_original version_count
  tmp_files << "#{config.backup_folder}/#{tmp_origin_zip}"
  tmp_files << "#{config.backup_folder}/schema_tmp.rb"

  db_name = Rails.configuration.database_configuration[Rails.env]["database"]
  db_collation = ActiveRecord::Base.connection.collation
  ActiveRecord::Base.connection.drop_database   db_name
  ActiveRecord::Base.connection.create_database db_name, collation: db_collation
  ActiveRecord::Base.connection.reconnect!

  # prepare the structure
  ZIPLIB.open("#{config.backup_folder}/#{tmp_origin_zip}") do |zf|
    zf.entries.each do |zf_entry|
      if zf_entry.name == "schema.rb"
        File.open("#{config.backup_folder}/schema_tmp.rb", "wb") { |f| f.write zf.read(zf_entry.name) }
        break
      end
    end
  end
  schema_verbose = ActiveRecord::Schema.verbose
  ActiveRecord::Schema.verbose = !config.silent
  ActiveRecord::Schema.load("#{config.backup_folder}/schema_tmp.rb")
  ActiveRecord::Schema.verbose = schema_verbose

  # add the data
  ZIPLIB.open("#{config.backup_folder}/#{tmp_origin_zip}") do |zf|
    zf.entries.each do |zf_entry|
      next if zf_entry.name == "schema.rb"
      table_rows = zf.read(zf_entry.name).split("\n")
      table_header = table_rows.shift
      table_name = zf_entry.name.split(".").first

      t_benchmark = Benchmark.ms do
        table_rows.in_groups_of(config.per_page, false) do |tr_group|
          ActiveRecord::Base.connection.execute insert_row(table_name, table_header, tr_group)
        end
      end
      puts "-- insert_data(\"#{table_name}\")\n   -> #{'%.4f' % (t_benchmark/1000)}s\n" if !config.silent
    end
  end

  # delete temporary files before method exit
  rescue => e
    @method_error = e
  ensure
    unlock if locked_by_this_method
    tmp_files.each { |i| File.delete(i) rescue nil } if tmp_files.present?
    raise @method_error if @method_error.present?
    return true
end