···11-## Rubywarden
22-33-### Migrating From `bitwarden-ruby` to Rubywarden and ActiveRecord
44-55-If you've used this application before it switched to using ActiveRecord
66-(when it was called `bitwarden-ruby`), you need to do the following steps to
77-migrate the data and generate the new table structures.
88-99-Even though the migration script will import to a new database file at a
1010-different path, it is probably best to create a backup yourself.
1111-You can also copy the `db/production.sqlite3` to your local machine and do the
1212-migration there.
1313-After a successful migration you'd have to copy the updated database file back
1414-to the production machine.
1515-1616-First make sure you have the latest code:
1717-1818- git pull
1919-2020-Then checkout to a specific revision where the migration was made:
2121-2222- git checkout 40044728d
2323-2424-Run `bundle` to add some required libraries for the migration:
2525-2626- bundle --with migrate
2727-2828-Now you are ready to do the migration:
2929-3030- bundle exec ruby tools/migrate_to_ar.rb -e production
3131-3232-The `-e` switch allows you to select the correct database environment from
3333-`db/config.yml`.
3434-3535-The migration script will:
3636-3737- - dump the contents of the old database (most likely at
3838- `db/production.sqlite`) to a temporary YAML file
3939- - create the new database at `db/production/production.sqlite3` using
4040- ActiveRecord migrations
4141- - import the contents from the dump file
4242- - remove the dump file
4343-4444-Now your data is completely migrated into a new database at the new recommended
4545-path, and the library will now use ActiveRecord to handle anything database
4646-related.
4747-4848-It is recommended to follow the
4949-[initial installation instructions](https://github.com/jcs/rubywarden#manual-setup)
5050-to create a new, unprivileged user to own the new `db/production/` database
5151-and run the server.
5252-5353-Lastly, update to the current code:
5454-5555- git checkout master
5656-5757-And then follow the
5858-[update instructions](https://github.com/jcs/rubywarden#updating)
5959-to bring your database up to date with the latest migrations.
···9999100100### Updating
101101102102-If you've previously used Rubywarden before July 30, 2018 when it was called
103103-`bitwarden-ruby`, when it did not use ActiveRecord, you should instead
104104-[migrate](AR-MIGRATE.md)
105105-your existing database.
106106-107102To update your instance of Rubywarden, fetch the latest code:
108103109104 cd /path/to/your/rubywarden
-88
tools/migrate_to_ar.rb
···11-# see https://github.com/jcs/rubywarden/blob/master/AR-MIGRATE.md
22-33-require "fileutils"
44-require "getoptlong"
55-require "tempfile"
66-require "yaml_db"
77-88-def usage
99- puts "usage: #{$PROGRAM_NAME} -e development"
1010- exit 1
1111-end
1212-1313-environment = nil
1414-begin
1515- GetoptLong.new(
1616- ['--environment', '-e', GetoptLong::REQUIRED_ARGUMENT]
1717- ).each do |opt, arg|
1818- case opt
1919- when '--environment'
2020- environment = arg
2121- end
2222- end
2323-rescue GetoptLong::InvalidOption
2424- usage
2525-end
2626-2727-usage unless environment
2828-2929-require File.realpath(File.dirname(__FILE__) + "/../lib/rubywarden.rb")
3030-3131-ActiveRecord::Base.remove_connection
3232-3333-dbconfig = YAML.load(File.read(File.realpath(__dir__ + "/../db/config.yml")))
3434-3535-# if a file exists at the new path, some kind of migration has already been
3636-# done so bail out
3737-newdb = dbconfig[environment]["database"]
3838-if File.exists?(newdb)
3939- raise "a file already exists at #{newdb}, has a migration already taken place?"
4040-end
4141-4242-olddb = File.realpath(__dir__ + "/../db/production.sqlite3")
4343-if !olddb || !File.exists?(olddb)
4444- raise "no file at #{olddb} to migrate"
4545-end
4646-4747-# point a temporary config at the old db path so we can dump it
4848-tmpconfig = dbconfig[environment].dup
4949-tmpconfig["database"] = olddb
5050-ActiveRecord::Base.establish_connection tmpconfig
5151-5252-# select only tables for defined models
5353-class YamlDb::SerializationHelper::Dump
5454- def self.tables
5555- ObjectSpace.each_object(Class).select{|k| k < DBModel}.map{|k| k.table_name }
5656- end
5757-end
5858-5959-dump_file = Tempfile.new("rubywarden-migrate")
6060-6161-puts "dumping old database to #{dump_file.path}"
6262-YamlDb::SerializationHelper::Base.new(YamlDb::Helper).dump(dump_file.path)
6363-ActiveRecord::Base.remove_connection
6464-6565-puts "creating new database at #{dbconfig[environment]["database"]}"
6666-system("rake", "db:migrate", "RUBYWARDEN_ENV=#{environment}")
6767-6868-puts "importing old database dump"
6969-ActiveRecord::Base.establish_connection dbconfig[environment]
7070-YamlDb::SerializationHelper::Base.new(YamlDb::Helper).load(dump_file.path)
7171-7272-puts "deleting dump file"
7373-dump_file.unlink
7474-7575-# reset created_at / updated_at from seconds since epoch to actual datetime for ar magic
7676-DBModel.record_timestamps = false
7777-ObjectSpace.each_object(Class).select {|k| k < DBModel}.each do |k|
7878- k.all.each do |i|
7979- i.update created_at: Time.at(i.created_at), updated_at: Time.at(i.updated_at)
8080- end
8181-end
8282-DBModel.record_timestamps = true
8383-8484-newdb = File.realpath(__dir__ + "/../" + dbconfig[environment]["database"])
8585-puts "you may wish to delete the old database at #{newdb}"
8686-8787-puts "you may also wish to create a new, unprivileged user to run the"
8888-puts "rubywarden server and own the db/production/ directory"