bootstrap-db 0.0.3 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ NjVjNjYxOTZmYzUzMzM2MzNiOWM2M2ZmYjgwNzNiYWE3Nzk2MmY3OA==
5
+ data.tar.gz: !binary |-
6
+ Y2FjNWM5MzgxNTg4N2M4MDk4ZmNjNmM5MmYzMTIxODIzNWQ3MDIxNw==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ OWZlNDgxOTAyMjU5ZDAwZjY1MmExOGRmZGMxMGM2MGMzMWE0NzE5NTBmMGIz
10
+ N2Q2ZDRhNTUzOTcwNjNlZDllNjBmNmUyYWFjNDA0Zjg3NzE4MzVjOWZmOGFk
11
+ ZmIxNzk5NWY1ZTc1NWI0YjJiOTY4YThlNWJhZGNhYzVkZjliMGE=
12
+ data.tar.gz: !binary |-
13
+ YzkyODRkMjEyZjViOWIyZjY4Yzc0NDNmYzJjN2QyMThkNmU3NWIzOTA5ZTJm
14
+ ZGIxYWM0NGIzYTEwZTgwY2YwYWE1MDJjNDRkN2EzZTA5NmNkNWVjMWI2YzYx
15
+ OTMxOGFmY2EwY2QzZGUyYWNlYTk5MDgxOGM5OWZhYTZiZjljN2U=
data/README.md CHANGED
@@ -2,8 +2,14 @@
2
2
 
3
3
  ## Purpose
4
4
 
5
- Collection of rake tasks for speeding up the capture and load of database snapshots (dumps).
6
- Currently accepting MySQL & Postgres databases and specifically gear to Rails applications.
5
+ To be able to load and dump a database as quickly as possible.
6
+ Primary use is to load a large dataset quickly, with practical applications for running
7
+ test suites (with extensive seed data).
8
+
9
+ Some projects require extensive seed data, with many complex values, which can take excessive time to generate. The idea of this project is to create a 'snapshot' in time of this generated seed data, and be able to load almost instantly. With the time rebase task, this can also have the time and dates rebased to the current time, allowing relative time tests to work.
10
+
11
+ For example:
12
+ * Running a project with multiple customer types and scenarios, with complex underlying data. This takes around ~55 seconds to generate. You don't want to run this for *every single test* you run. So on change of the data, recreate the dump, and set the test suite to load. Now it will take ~1 second.
7
13
 
8
14
  ## Add this line to your application's Gemfile:
9
15
 
@@ -17,8 +23,8 @@ Currently accepting MySQL & Postgres databases and specifically gear to Rails ap
17
23
 
18
24
  ```
19
25
  rake bootstrap:db:dump #Dump default to db/bootstrap/bootstrap_data.sql
20
- rake bootstrap:db:dump Rails.env=production #Dump specific Rails environment using database.yml
21
- rake bootstrap:db:dump FILE=db/bootstrap/live_database.dump #Dump to specific location
26
+ rake bootstrap:db:dump RAILS_ENV=production #Dump specific Rails environment using database.yml
27
+ rake bootstrap:db:dump BOOTSTRAP_DIR=db/my_bootstraps/ #Dump to specific directory
22
28
  rake bootstrap:db:dump FILE_NAME=live_database.dump #Dump specific file to default bootstrap location
23
29
  ```
24
30
 
@@ -29,14 +35,22 @@ Currently accepting MySQL & Postgres databases and specifically gear to Rails ap
29
35
  rake bootstrap:db:dump IGNORE_TABLES='messages,incidents'
30
36
  ```
31
37
 
38
+ ### Database Rebuild and Dump
39
+
40
+ Recreate the database from scratch, seed and then dump.
41
+
42
+ ```
43
+ rake bootstrap:db:recreate #Dump default to db/bootstrap/bootstrap_data.sql
44
+ ```
45
+
32
46
  ### Database Load
33
47
 
34
48
  Load, and overwrite, current database environment with a passed file name.
35
49
 
36
50
  ```
37
51
  rake bootstrap:db:load #Load default from db/bootstrap/bootstrap_data.sql
38
- rake bootstrap:db:load Rails.env=production #Load specific Rails environment using database.yml
39
- rake bootstrap:db:load FILE=db/bootstrap/live_database_dump.sql #Load from specific dump
52
+ rake bootstrap:db:load RAILS_ENV=production #Load specific Rails environment using database.yml
53
+ rake bootstrap:db:load BOOTSTRAP_DIR=db/custom_dir/ #Load from specific dump directory
40
54
  rake bootstrap:db:load FILE_NAME=live_database_dump.sql #Load specific file from default bootstrap location
41
55
  ```
42
56
 
@@ -56,6 +70,20 @@ Pass 'VERBOSE=true' if you'd like to see more information. For example:
56
70
  rake bootstrap:db:dump VERBOSE=true
57
71
  ```
58
72
 
73
+ ### Database Time Rebaser
74
+
75
+ Load, and overwrite, current database environment with a passed snapshot. Then 'rebase' all date and time values from the generated snapshot point in time to 'now'.
76
+
77
+ Working example:
78
+ * A customer may have an activity feed with a variety of tests to check date ranges of results. With the `time rebaser` task, this will actively loop over every date or time value in a db and `rebase` the time to a new point (comparing it to the generated time).
79
+ * For this to work, you can only use *relative* time tests (1.week.ago, 4.months.ago, 5.years.from.now), as the rebaser doesn't know what should be fixed and not. You cannot generate data (and snapshot the dump) with data like `Time.zone.today.beginning_of_year` and expect the test to find the data. *All* date and time fields will be shifted based on the difference between when the data was generated and the load time.
80
+
81
+
82
+ *all the same options as `bootstrap:db:load` apply here too*
83
+ ```
84
+ rake bootstrap:db:load_and_rebase #Load default from db/bootstrap/bootstrap_data.sql and rebase all time and date values
85
+ ```
86
+
59
87
  ## Requirements
60
88
 
61
89
  * Rails
@@ -64,11 +92,12 @@ Pass 'VERBOSE=true' if you'd like to see more information. For example:
64
92
  * mysql/postgresql
65
93
 
66
94
 
67
- ## TODO (if we end up using this more)
95
+ ## TODO
96
+ * Write extensive readme examples
68
97
  * This has been quickly rebuilt from a ridiculously old project of mine (http://github.com/tommeier/bootstrap). This should be refactored into proper objects and expose classes as well as rake tasks. Fully tested.
69
- * Proper mapping of parameter for dumping (eg. --username) to database config
70
98
  * List required attributes for each database (like `host` and raise on missing)
71
- * Load config once, and apply a bunch of custom items. For instance, mysql default bootstrap should be a *.sql file and the default for postgres should be *.dump for faster loads
99
+ * Clearly list options available to Rake tasks
100
+ * Convert rake tasks to script tasks (if 'load_config' can be loaded)
72
101
 
73
102
  ## Contributing
74
103
 
data/lib/bootstrap/db.rb CHANGED
@@ -2,10 +2,18 @@ require 'bootstrap/db/version'
2
2
 
3
3
  module Bootstrap
4
4
  module Db
5
+
6
+ # Error when unable to find '.bootstrap' file when required
7
+ class MissingSettingsFileError < StandardError; end
5
8
  end
6
9
  end
7
10
 
8
11
  require 'bootstrap/db/config'
9
12
  require 'bootstrap/db/railtie'
13
+ require 'bootstrap/db/log'
14
+ require 'bootstrap/db/command'
15
+ require 'bootstrap/db/adapter'
16
+ require 'bootstrap/db/adapter/mysql'
17
+ require 'bootstrap/db/adapter/postgres'
10
18
 
11
19
 
@@ -0,0 +1,50 @@
1
+ module Bootstrap
2
+ module Db
3
+ class Adapter
4
+ include Bootstrap::Db::Command
5
+
6
+ attr_reader :config, :file_name, :file_path
7
+
8
+ def initialize(config)
9
+ @config = config
10
+
11
+ @file_name = ENV['FILE_NAME'] || default_file_name
12
+ @file_path = File.expand_path(File.join(config.bootstrap_dir, file_name))
13
+ end
14
+
15
+ # implemented by adapters
16
+ def command_string
17
+ raise NotImplementedError
18
+ end
19
+
20
+ # implemented by adapters
21
+ def default_file_name
22
+ raise NotImplementedError
23
+ end
24
+
25
+ def ignore_tables
26
+ @ignore_tables ||= begin
27
+ ENV['IGNORE_TABLES'].split(',') if ENV['IGNORE_TABLES']
28
+ end
29
+ end
30
+
31
+ def additional_parameters
32
+ @optional_parameters ||= begin
33
+ ENV['ADDITIONAL_PARAMS'].split(',') if ENV['ADDITIONAL_PARAMS']
34
+ end
35
+ end
36
+
37
+ def current_db_time
38
+ if Time.respond_to?(:zone)
39
+ #Handle custom timezones
40
+ if time_zone = (ENV['TZ'] || ENV['ZONEBIE_TZ'])
41
+ Time.zone ||= time_zone
42
+ end
43
+ Time.zone.now
44
+ else
45
+ Time.now
46
+ end.to_formatted_s(:db)
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,68 @@
1
+ module Bootstrap
2
+ module Db
3
+ class Mysql < Adapter
4
+ # Config -> command line parameter
5
+ CONNECTION_MAP = {
6
+ :username => :u,
7
+ :password => :p,
8
+ :host => :h
9
+ }
10
+
11
+ # Compile connection string
12
+ def connection_string
13
+ @connection_string ||= begin
14
+ CONNECTION_MAP.inject([]) do |result, (config_name, command_name)|
15
+ config_value = config.settings[config_name.to_s]
16
+ result << "-#{command_name} '#{config_value}'" if config_value
17
+ result
18
+ end.join(' ')
19
+ end
20
+ end
21
+
22
+ def dump!
23
+ #mysqldump --help
24
+ dump_command = [
25
+ "mysqldump",
26
+ "-q --add-drop-table --add-locks",
27
+ "--extended-insert --lock-tables",
28
+ "--single-transaction",
29
+ connection_string
30
+ ]
31
+
32
+ if ignore_tables.present?
33
+ ignore_tables.each do |table_name|
34
+ dump_command << "--ignore-table='#{config.settings["database"]}.#{table_name.strip}'"
35
+ end
36
+ end
37
+
38
+ if additional_parameters.present?
39
+ additional_parameters.each do |param|
40
+ dump_command << param
41
+ end
42
+ end
43
+
44
+ dump_command << "#{config.settings['database']} > #{file_path}"
45
+
46
+ display_and_execute(dump_command.join(' '))
47
+ end
48
+
49
+ def load!
50
+ #mysql --help
51
+ load_command = [
52
+ "mysql",
53
+ "-f",
54
+ connection_string,
55
+ "#{config.settings["database"]} < #{file_path}"
56
+ ]
57
+
58
+ display_and_execute(load_command.join(' '))
59
+ end
60
+
61
+ private
62
+
63
+ def default_file_name
64
+ 'bootstrap_data.sql'
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,149 @@
1
+ require 'yaml'
2
+
3
+ module Bootstrap
4
+ module Db
5
+ class Postgres < Adapter
6
+ LOAD_COMMAND = "pg_restore"
7
+
8
+ CONNECTION_PARAMS = [ :username, :password, :host, :port ]
9
+ CONFIG_DEFAULTS = {
10
+ :port => 5423
11
+ }
12
+
13
+ # Compile connection string
14
+ def connection_string
15
+ @connection_string ||= begin
16
+ CONNECTION_PARAMS.inject([]) do |result, element|
17
+ config_value = config.settings[element.to_s] || CONFIG_DEFAULTS[element]
18
+ result << "--#{element}='#{config_value}'" if config_value
19
+ result
20
+ end.join(' ')
21
+ end
22
+ end
23
+
24
+ def dump!
25
+ #pg_dump --help
26
+ dump_command = [
27
+ "pg_dump",
28
+ "--create --format=c",
29
+ "--file=#{file_path}",
30
+ connection_string
31
+ ]
32
+
33
+ if ignore_tables.present?
34
+ ignore_tables.each do |table_name|
35
+ dump_command << "--exclude-table='#{config.settings["database"]}.#{table_name.strip}'"
36
+ end
37
+ end
38
+
39
+ if additional_parameters.present?
40
+ additional_parameters.each do |param|
41
+ dump_command << param
42
+ end
43
+ end
44
+
45
+ dump_command << config.settings['database']
46
+
47
+ result = display_and_execute(dump_command.join(' '))
48
+
49
+ save_generated_time!
50
+
51
+ result
52
+ end
53
+
54
+ def load!
55
+ #pg_restore --help
56
+ load_command = [
57
+ "pg_restore",
58
+ "--single-transaction --format=c",
59
+ "--dbname='#{config.settings["database"]}'",
60
+ connection_string,
61
+ file_path
62
+ ]
63
+
64
+ display_and_execute(load_command.join(' '))
65
+ end
66
+
67
+ def rebase!
68
+ generated_time = load_generated_time!
69
+
70
+ load_rebase_functions!
71
+
72
+ start_point = generated_time
73
+ rebase_to = current_db_time
74
+
75
+ rebase_cmd = "SELECT rebase_db_time('#{start_point}'::timestamp, '#{rebase_to}'::timestamp);"
76
+ result = display_and_execute("#{psql_execute} --command=#{rebase_cmd.shellescape}")
77
+ log(result.inspect)
78
+ end
79
+
80
+ private
81
+
82
+ def psql_execute
83
+ @psql_execute ||= begin
84
+ [
85
+ 'psql',
86
+ connection_string,
87
+ "--dbname='#{config.settings['database']}'"
88
+ ].join(' ')
89
+ end
90
+ end
91
+
92
+ def load_rebase_functions!
93
+ function_sql_path = File.expand_path('../../sql/rebase_time.sql', __FILE__)
94
+ display_and_execute("#{psql_execute} --file='#{function_sql_path}'")
95
+ end
96
+
97
+ def default_file_name
98
+ 'bootstrap_data.dump' #Custom format 'c'
99
+ end
100
+
101
+ def load_generated_time!
102
+ settings = current_settings
103
+
104
+ generated_times = settings[:generated_on]
105
+ generated_time = generated_times && generated_times[file_path]
106
+
107
+ unless generated_time
108
+ error_message =<<-ERR
109
+ Error - Cannot find generated time. Please recreate dump.
110
+ A generated time is required to know how to rebase time correctly.
111
+ Looking in: #{settings_path}
112
+ ERR
113
+ raise MissingSettingsFileError.new(error_message)
114
+ end
115
+
116
+ generated_time
117
+ end
118
+
119
+ # Save and track generated time of bootstrap
120
+ def save_generated_time!
121
+ settings = current_settings
122
+ settings[:generated_on] ||= {}
123
+
124
+ #Clear any bootstraps that may have been removed
125
+ settings[:generated_on].each do |file, generated_time|
126
+ settings[:generated_on].delete(file) unless File.exists?(file)
127
+ end
128
+
129
+ #Set current bootstrap generated time
130
+ settings[:generated_on][file_path] = current_db_time
131
+ puts settings.inspect
132
+
133
+ #Save settings file
134
+ File.open(settings_path, "w") do |file|
135
+ file.write settings.to_yaml
136
+ end
137
+ end
138
+
139
+ def current_settings
140
+ return {} unless File.exists?(settings_path)
141
+ YAML::load_file(settings_path) || {}
142
+ end
143
+
144
+ def settings_path
145
+ @settings_path ||= File.expand_path(File.join(config.bootstrap_dir, '.bootstrap'))
146
+ end
147
+ end
148
+ end
149
+ end
@@ -1,10 +1,6 @@
1
1
  module Bootstrap
2
2
  module Db
3
- module RakeHelper
4
-
5
- def log(output)
6
- STDERR.puts "[bootstrap-db] #{output}"
7
- end
3
+ module Command
8
4
 
9
5
  def display_and_execute(command)
10
6
  log(command) if ENV['VERBOSE'] == 'true'
@@ -3,15 +3,15 @@ module Bootstrap
3
3
  class Config
4
4
  DB_CONFIG_PATH = 'config/database.yml'
5
5
 
6
- attr_accessor :settings, :adapter, :dump_name, :dump_path, :dump_dir
6
+ attr_accessor :settings, :adapter, :bootstrap_dir
7
7
 
8
- def initialize(settings)
9
- self.settings = settings
10
- self.adapter = settings[Rails.env]["adapter"].to_sym
8
+ def initialize(loaded_settings)
9
+ self.settings = loaded_settings[Rails.env]
10
+ self.adapter = self.settings["adapter"].to_sym
11
11
 
12
- self.dump_path = ENV['FILE'] || File.join(default_dump_path, ENV['FILE_NAME'] || default_dump_name)
13
- self.dump_name = File.basename(self.dump_path)
14
- self.dump_dir = File.dirname(self.dump_path)
12
+ self.bootstrap_dir = ENV['BOOTSTRAP_DIR'] || default_directory
13
+
14
+ ensure_bootstrap_dir_exists!
15
15
  end
16
16
 
17
17
  def self.load!(configuration_path = File.join(Rails.root, DB_CONFIG_PATH))
@@ -30,17 +30,13 @@ module Bootstrap
30
30
 
31
31
  private
32
32
 
33
- def default_dump_path
34
- @default_dump_path ||= File.join(Rails.root, 'db', 'bootstrap')
33
+ def default_directory
34
+ @default_directory ||= File.join(Rails.root, 'db', 'bootstrap')
35
35
  end
36
36
 
37
- def default_dump_name
38
- @default_dump_name ||= case self.adapter
39
- when :postgresql
40
- 'bootstrap_data.dump' #Custom format 'c'
41
- else
42
- 'bootstrap_data.sql' #MySQL
43
- end
37
+ def ensure_bootstrap_dir_exists!
38
+ #Create directories if they don't exist
39
+ Dir.mkdir bootstrap_dir unless File.exists?(bootstrap_dir)
44
40
  end
45
41
  end
46
42
  end
@@ -0,0 +1,11 @@
1
+ module Bootstrap
2
+ module Db
3
+ module Log
4
+
5
+ def log(output)
6
+ STDERR.puts "[bootstrap-db] #{output}"
7
+ end
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,108 @@
1
+ -- Setup functions for being able to rebase time + date values
2
+ -- from a point the db data was generated to a new point.
3
+
4
+ -- Rebase time values to a fixed point
5
+ CREATE OR REPLACE FUNCTION rebase_time(
6
+ fixed_point timestamp,
7
+ new_point timestamp,
8
+ original_time timestamp)
9
+ RETURNS timestamp AS
10
+ $$
11
+ DECLARE
12
+ result timestamp := new_point;
13
+ BEGIN
14
+ IF (original_time = fixed_point) THEN
15
+ result := new_point;
16
+ ELSIF (original_time < fixed_point) THEN
17
+ -- Original time was set in the past
18
+ result := (new_point - (fixed_point - original_time));
19
+ ELSIF (original_time > fixed_point) THEN
20
+ -- Original time was set in the future
21
+ result := (new_point + (original_time - fixed_point));
22
+ END IF;
23
+ --RAISE NOTICE 'Original: %, New: %', original_time, result;
24
+ RETURN result;
25
+ END;
26
+ $$
27
+ LANGUAGE 'plpgsql' STABLE;
28
+
29
+ --Rebase date values to a fixed point
30
+ CREATE OR REPLACE FUNCTION rebase_date(
31
+ fixed_point date,
32
+ new_point date,
33
+ original date)
34
+ RETURNS date AS
35
+ $$
36
+ DECLARE
37
+ result date := new_point;
38
+ BEGIN
39
+ IF (original = fixed_point) THEN
40
+ result := new_point;
41
+ ELSIF (original < fixed_point) THEN
42
+ -- Original was set in the past
43
+ result := (new_point - (fixed_point - original));
44
+ ELSE
45
+ -- Original was set in the future
46
+ result := (new_point + (original - fixed_point));
47
+ END IF;
48
+ RETURN result;
49
+ END;
50
+ $$
51
+ LANGUAGE 'plpgsql' STABLE;
52
+
53
+ --Rebase all date/timestamp values in db to a fixed point
54
+ --Returns the number of rows affected
55
+ CREATE OR REPLACE FUNCTION rebase_db_time(
56
+ fixed_point timestamp,
57
+ new_point timestamp
58
+ )
59
+ RETURNS integer AS
60
+ $$
61
+ DECLARE
62
+ column_data record;
63
+ update_command varchar := '';
64
+ function_name varchar := '';
65
+ fixed_point_type varchar := '';
66
+ update_result integer := 0;
67
+ result integer := 0;
68
+ BEGIN
69
+ FOR column_data IN (
70
+ SELECT table_name, column_name, data_type
71
+ FROM information_schema.columns
72
+ WHERE
73
+ table_schema = 'public'
74
+ AND data_type IN
75
+ ('timestamp without time zone',
76
+ 'timestamp with time zone',
77
+ 'date')
78
+ ORDER BY table_name DESC ) LOOP
79
+ --'date'
80
+ IF column_data.data_type = 'date' THEN
81
+ function_name := 'rebase_date';
82
+ ELSE
83
+ function_name := 'rebase_time';
84
+ END IF;
85
+
86
+ update_command := format('UPDATE %s SET %I = %s(%L::%s, %L::%s, %s.%s::%s);',
87
+ column_data.table_name,
88
+ column_data.column_name,
89
+ function_name,
90
+ fixed_point,
91
+ column_data.data_type,
92
+ new_point,
93
+ column_data.data_type,
94
+ column_data.table_name,
95
+ column_data.column_name,
96
+ column_data.data_type);
97
+
98
+ --RAISE EXCEPTION '%', update_command;
99
+ EXECUTE update_command;
100
+
101
+ GET DIAGNOSTICS update_result := ROW_COUNT;
102
+ result := result + update_result;
103
+ END LOOP;
104
+ --RAISE EXCEPTION '%', result;
105
+ RETURN result;
106
+ END;
107
+ $$
108
+ LANGUAGE 'plpgsql' VOLATILE;
@@ -1,88 +1,76 @@
1
- require File.join(File.dirname(__FILE__), '../rake_helper')
2
-
3
1
  namespace :bootstrap do
4
2
  namespace :db do
5
- include Bootstrap::Db::RakeHelper
3
+ include Bootstrap::Db::Log
4
+
5
+ desc "Recreate bootstrap (drop, create + seed)"
6
+ task :recreate => ['db:drop', 'db:setup', :dump]
6
7
 
7
8
  desc "Dump the current database to a SQL file"
8
- task :dump => :environment do
9
+ task :dump => ['db:load_config'] do
9
10
  config = Bootstrap::Db::Config.load!
10
11
 
11
- settings = config.settings[Rails.env]
12
- ignore_tables = ENV['IGNORE_TABLES'].split(',') if ENV['IGNORE_TABLES']
13
- passed_params = ENV['ADDITIONAL_PARAMS'].split(',') if ENV['ADDITIONAL_PARAMS']
12
+ bootstrap = case config.adapter
13
+ when :mysql
14
+ Bootstrap::Db::Mysql.new(config)
15
+ when :postgresql
16
+ Bootstrap::Db::Postgres.new(config)
17
+ else
18
+ raise "Error : Task not supported by '#{config.adapter}'"
19
+ end
14
20
 
15
- #Create directories if they don't exist
16
- Dir.mkdir config.dump_dir unless File.exists?(config.dump_dir)
21
+ log "Generating dump of database: '#{bootstrap.file_name}'"
17
22
 
18
- log "Generating dump of database: '#{config.dump_name}'"
23
+ bootstrap.dump!
19
24
 
20
- case config.adapter
21
- when :mysql
22
- #mysqldump --help
23
- default_sql_attrs = "-q --add-drop-table --add-locks --extended-insert --lock-tables --single-transaction"
24
- if ignore_tables
25
- ignore_tables.each do |table_name|
26
- default_sql_attrs += " --ignore-table=#{settings["database"]}.#{table_name.strip}"
27
- end
28
- end
29
-
30
- if passed_params
31
- passed_params.each do |param|
32
- default_sql_attrs += " #{param}"
33
- end
34
- end
35
-
36
- password_attrs = " -p#{settings["password"]}" if settings["password"]
37
- #--all-tablespaces
38
- display_and_execute("mysqldump #{default_sql_attrs} -h #{settings["host"]} -u #{settings["username"]}#{password_attrs} #{settings["database"]} > #{config.dump_path}")
25
+ log "Dump completed --> '#{bootstrap.file_path}'"
26
+ end
27
+
28
+ desc "Load a SQL dump into the current environment"
29
+ task :load => ['db:load_config'] do
30
+ config = Bootstrap::Db::Config.load!
39
31
 
32
+ bootstrap = case config.adapter
33
+ when :mysql
34
+ Bootstrap::Db::Mysql.new(config)
40
35
  when :postgresql
41
- #pg_dump --help
42
- default_sql_attrs = "--clean --create --format=c"
36
+ Bootstrap::Db::Postgres.new(config)
37
+ else
38
+ raise "Task not supported by '#{config.adapter}'"
39
+ end
43
40
 
44
- if ignore_tables.present?
45
- ignore_tables.each do |table_name|
46
- default_sql_attrs += " --exclude-table=#{settings["database"]}.#{table_name.strip}"
47
- end
48
- end
41
+ unless File.exists?(bootstrap.file_path)
42
+ raise "Unable to find dump at location - '#{bootstrap.file_path}'"
43
+ end
49
44
 
50
- if passed_params.present?
51
- passed_params.each do |param|
52
- default_sql_attrs += " #{param}"
53
- end
54
- end
45
+ log "Loading dump: '#{bootstrap.file_name}'"
55
46
 
56
- user_attribute = " --username=#{settings["username"]}" if settings['username']
47
+ bootstrap.load!
57
48
 
58
- display_and_execute("pg_dump #{default_sql_attrs} --host=#{settings["host"]} --port=#{settings["port"] || 5432}#{user_attribute} --file=#{config.dump_path} #{settings["database"]}")
59
- else
60
- raise "Error : Task not supported by '#{settings['adapter']}'"
61
- end
62
- log "Dump completed --> '#{config.dump_path}'"
49
+ log "Database load completed..."
63
50
  end
64
51
 
65
- desc "Load a SQL dump into the current environment"
66
- task :load => :environment do
52
+ desc "Load a SQL dump and rebase the time to this point in time"
53
+ task :load_and_rebase => ['db:load_config', :load] do
67
54
  config = Bootstrap::Db::Config.load!
68
- settings = config.settings[Rails.env]
69
- raise "Unable to find dump at location - '#{config.dump_path}'" unless File.exists?(config.dump_path)
70
55
 
71
- log "Loading dump: '#{config.dump_name}'"
72
-
73
- case config.adapter
56
+ bootstrap = case config.adapter
74
57
  when :mysql
75
- password_attrs = " -p#{settings["password"]}" if settings["password"]
76
- display_and_execute("mysql -f -h #{settings["host"]} -u #{settings["username"]}#{password_attrs.to_s} #{settings["database"]} < #{config.dump_path}")
58
+ raise "Not supported yet. Sorry"
77
59
  when :postgresql
78
- default_sql_attrs = "--clean --single-transaction --format=c"
79
- user_attribute = " --username=#{settings["username"]}" if settings['username']
80
- display_and_execute("pg_restore #{default_sql_attrs} --host=#{settings["host"]} --port=#{settings["port"] || 5432} --dbname=#{settings["database"]}#{user_attribute} #{config.dump_path}")
60
+ Bootstrap::Db::Postgres.new(config)
81
61
  else
82
- raise "Task not supported by '#{settings['adapter']}'"
62
+ raise "Task not supported by '#{config.adapter}'"
83
63
  end
84
64
 
85
- log "Database load completed..."
65
+ unless File.exists?(bootstrap.file_path)
66
+ raise "Unable to find dump at location - '#{bootstrap.file_path}'"
67
+ end
68
+
69
+ log "Rebasing database time relative to now..."
70
+
71
+ bootstrap.rebase!
72
+
73
+ log "Database rebase completed..."
86
74
  end
87
75
  end
88
76
  end
@@ -1,5 +1,5 @@
1
1
  module Bootstrap
2
2
  module Db
3
- VERSION = "0.0.3"
3
+ VERSION = "0.1.3"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,20 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bootstrap-db
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
5
- prerelease:
4
+ version: 0.1.3
6
5
  platform: ruby
7
6
  authors:
8
7
  - Tom Meier
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-07-07 00:00:00.000000000 Z
11
+ date: 2013-08-23 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: railties
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
17
  - - ! '>='
20
18
  - !ruby/object:Gem::Version
@@ -22,7 +20,6 @@ dependencies:
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
24
  - - ! '>='
28
25
  - !ruby/object:Gem::Version
@@ -30,7 +27,6 @@ dependencies:
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: bundler
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
31
  - - ~>
36
32
  - !ruby/object:Gem::Version
@@ -38,7 +34,6 @@ dependencies:
38
34
  type: :development
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
38
  - - ~>
44
39
  - !ruby/object:Gem::Version
@@ -46,7 +41,6 @@ dependencies:
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: rake
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
45
  - - ! '>='
52
46
  - !ruby/object:Gem::Version
@@ -54,7 +48,6 @@ dependencies:
54
48
  type: :development
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
52
  - - ! '>='
60
53
  - !ruby/object:Gem::Version
@@ -73,34 +66,38 @@ files:
73
66
  - Rakefile
74
67
  - bootstrap-db.gemspec
75
68
  - lib/bootstrap/db.rb
69
+ - lib/bootstrap/db/adapter.rb
70
+ - lib/bootstrap/db/adapter/mysql.rb
71
+ - lib/bootstrap/db/adapter/postgres.rb
72
+ - lib/bootstrap/db/command.rb
76
73
  - lib/bootstrap/db/config.rb
74
+ - lib/bootstrap/db/log.rb
77
75
  - lib/bootstrap/db/railtie.rb
78
- - lib/bootstrap/db/rake_helper.rb
76
+ - lib/bootstrap/db/sql/rebase_time.sql
79
77
  - lib/bootstrap/db/tasks/bootstrap-db.rake
80
78
  - lib/bootstrap/db/version.rb
81
79
  homepage: http://github.com/tommeier/bootstrap-db
82
80
  licenses:
83
81
  - MIT
82
+ metadata: {}
84
83
  post_install_message:
85
84
  rdoc_options: []
86
85
  require_paths:
87
86
  - lib
88
87
  required_ruby_version: !ruby/object:Gem::Requirement
89
- none: false
90
88
  requirements:
91
89
  - - ! '>='
92
90
  - !ruby/object:Gem::Version
93
91
  version: '0'
94
92
  required_rubygems_version: !ruby/object:Gem::Requirement
95
- none: false
96
93
  requirements:
97
94
  - - ! '>='
98
95
  - !ruby/object:Gem::Version
99
96
  version: '0'
100
97
  requirements: []
101
98
  rubyforge_project:
102
- rubygems_version: 1.8.23
99
+ rubygems_version: 2.0.7
103
100
  signing_key:
104
- specification_version: 3
101
+ specification_version: 4
105
102
  summary: Database dump and loader
106
103
  test_files: []