Advertisement
Guest User

Untitled

a guest
Feb 13th, 2017
111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.81 KB | None | 0 0
  1. # Add to `spec/support/database_state_loader.rb`
  2.  
  3. class DatabaseStateLoader
  4. class EnvironmentError < RuntimeError; end
  5.  
  6. def self.load(path)
  7. new(path).load
  8. end
  9.  
  10. def initialize(path)
  11. @path = path
  12. end
  13.  
  14. def load
  15. # Just double check we're in the right environment
  16. raise EnvironmentError.new("This can only be run in development") if not Rails.env.development?
  17.  
  18. puts "Loading #{@path}"
  19. data = JSON.parse(File.read(@path))
  20.  
  21. created_database_config = create_and_switch_to_temporary_database
  22. insert_data(data)
  23.  
  24. username = created_database_config['username']
  25. password = created_database_config['password']
  26. host = created_database_config['host'] || "127.0.0.1"
  27. port = created_database_config['port'] || "5432"
  28. name = created_database_config['database']
  29. database_url = "postgres://#{username}:#{password}@#{host}:#{port}/#{name}"
  30.  
  31. puts ""
  32. puts "State data was succesfully inserted into database: #{name} 👍"
  33. puts ""
  34. puts "You can startup a console to access this database by running:"
  35. puts ""
  36. puts " DATABASE_URL=#{database_url} DISABLE_SPRING=1 rails console"
  37. puts ""
  38. puts "When you're done, you can remove the database by running:"
  39. puts ""
  40. puts " dropdb #{name}"
  41. puts ""
  42. end
  43.  
  44. private
  45.  
  46. def create_and_switch_to_temporary_database
  47. # Parse and load database.yml
  48. database_yml_path = Rails.root.join("config", "database.yml")
  49. parsed_database_yml = ERB.new(database_yml_path.read).result
  50. database_config = YAML.load(parsed_database_yml)
  51. test_database_config = database_config['test']
  52.  
  53. # Create a new database for this state
  54. puts "Creating state database..."
  55. state_database_name = "#{test_database_config['database']}_state_#{Time.now.to_i}"
  56. ActiveRecord::Base.connection.create_database(state_database_name)
  57.  
  58. # Connect to the jdatabase and recreate structure
  59. puts "Connecting `#{state_database_name}`"
  60. state_database_config = test_database_config.merge("database" => state_database_name, "pool" => 30)
  61. ActiveRecord::Base.establish_connection state_database_config
  62. ActiveRecord::Base.connection.execute(Rails.root.join("db/structure.sql").read)
  63.  
  64. state_database_config
  65. end
  66.  
  67. def insert_data(data)
  68. puts "Inserting data into database..."
  69.  
  70. ActiveRecord::Base.transaction do
  71. data.each do |(table, rows)|
  72. rows.each do |row|
  73. columns = []
  74. values = []
  75.  
  76. row.each do |(key, value)|
  77. columns << key
  78. values << begin
  79. case value
  80. when nil
  81. "null"
  82. when Hash
  83. case connection.columns(table).find { |column| column.name == key }.sql_type
  84. when "hstore"
  85. connection.quote connection.lookup_cast_type("hstore").serialize(value)
  86. when "json"
  87. connection.quote connection.lookup_cast_type("json").serialize(value)
  88. else
  89. raise "Not sure how to insert: (#{key}: #{value.inspect})"
  90. end
  91. when Array
  92. if value.empty?
  93. "null"
  94. else
  95. "(#{value.map { |v| connection.quote(v) }.join(", ")})"
  96. end
  97. else
  98. connection.quote value
  99. end
  100. end
  101. end
  102.  
  103. connection.execute(<<~SQL)
  104. INSERT INTO #{quote_table_name(table)} (#{columns.map { |column| quote_column_name(column) }.join(", ")})
  105. VALUES (#{values.join(", ")})
  106. SQL
  107. end
  108. end
  109. end
  110. end
  111.  
  112. delegate :connection, to: "ActiveRecord::Base"
  113. delegate :quote_table_name, :quote_column_name, to: :connection
  114. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement