Class: Squcumber::Postgres::Mock::Database

Inherits:
Object
  • Object
show all
Defined in:
lib/squcumber-postgres/mock/database.rb

Constant Summary collapse

DELETE_DB_WHEN_FINISHED =
ENV['KEEP_TEST_DB'].to_i == 1 ? false : true
TEST_DB_NAME_OVERRIDE =
ENV.fetch('TEST_DB_NAME_OVERRIDE', '')

Instance Method Summary collapse

Constructor Details

#initialize(production_database) ⇒ Database

Returns a new instance of Database.



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/squcumber-postgres/mock/database.rb', line 10

def initialize(production_database)
  @production_database = production_database or raise ArgumentError, 'No production database provided'

  test_db_name_postfix = TEST_DB_NAME_OVERRIDE.empty? ? rand(10000..99999) : TEST_DB_NAME_OVERRIDE
  @test_db_name = "test_env_#{test_db_name_postfix}"

  if @production_database.exec("select datname from pg_database where datname like '%#{@test_db_name}%'").num_tuples != 0
    @production_database.exec("drop database #{@test_db_name}")
  end
  @production_database.exec("create database #{@test_db_name}")

  @testing_database = PG.connect(
    host: ENV['DB_HOST'],
    port: ENV['DB_PORT'],
    dbname: @test_db_name,
    user: ENV['DB_USER'],
    password: ENV['DB_PASSWORD']
  )
end

Instance Method Details

#copy_table_def_from_prod(schema, table) ⇒ Object

Redshift does not allow to copy a table schema to another database, i.e. ‘create table some_db.some_table (like another_db.some_table)` cannot be used.



56
57
58
59
# File 'lib/squcumber-postgres/mock/database.rb', line 56

def copy_table_def_from_prod(schema, table)
  create_table_statement = _get_create_table_statement(schema, table)
  exec(create_table_statement)
end

#copy_table_defs_from_prod(tables) ⇒ Object



61
62
63
64
65
# File 'lib/squcumber-postgres/mock/database.rb', line 61

def copy_table_defs_from_prod(tables)
  tables.each do |obj|
    obj.each { |schema, table| copy_table_def_from_prod(schema, table) }
  end
end

#destroyObject



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/squcumber-postgres/mock/database.rb', line 87

def destroy
  @testing_database.close()

  if DELETE_DB_WHEN_FINISHED
    attempts = 0
    begin
      attempts += 1
      @production_database.exec("drop database #{@test_db_name}")
    rescue PG::ObjectInUse
      sleep 5
      retry unless attempts >= 3
    end
  else
    puts "\nTest database has been kept alive: #{@test_db_name}"
  end

  @production_database.close()
end

#exec(statement) ⇒ Object Also known as: query



44
45
46
# File 'lib/squcumber-postgres/mock/database.rb', line 44

def exec(statement)
  @testing_database.exec(statement)
end

#exec_file(path) ⇒ Object Also known as: query_file



49
50
51
# File 'lib/squcumber-postgres/mock/database.rb', line 49

def exec_file(path)
  exec(File.read("#{path}"))
end

#insert_mock_values(schema_and_table, mock) ⇒ Object



74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/squcumber-postgres/mock/database.rb', line 74

def insert_mock_values(schema_and_table, mock)
  schema, table = schema_and_table.split('.')
  keys = []
  vals = []
  mock.each do |key, value|
    unless value.nil?
      keys << key
      vals << (value.is_a?(String) ? "'#{value}'" : value)
    end
  end
  exec("insert into #{schema}.#{table} (#{keys.join(',')}) values (#{vals.join(',')})") unless vals.empty?
end

#mock(mock) ⇒ Object



67
68
69
70
71
72
# File 'lib/squcumber-postgres/mock/database.rb', line 67

def mock(mock)
  mock.each do |schema_and_table, data|
    raise "Mock data for #{schema_and_table} is not correctly formatted: must be Array but was #{data.class}" unless data.is_a?(Array)
    data.each { |datum| insert_mock_values(schema_and_table, datum) }
  end
end

#setup(schemas) ⇒ Object



30
31
32
33
34
35
# File 'lib/squcumber-postgres/mock/database.rb', line 30

def setup(schemas)
  schemas.each do |schema|
    exec("drop schema if exists #{schema} cascade")
    exec("create schema #{schema}")
  end
end

#truncate_all_tablesObject



37
38
39
40
41
42
# File 'lib/squcumber-postgres/mock/database.rb', line 37

def truncate_all_tables
  @testing_database
    .exec("select schemaname || '.' || tablename as schema_and_table from pg_tables where tableowner = '#{ENV['DB_USER']}' and schemaname not in ('pg_catalog', 'information_schema')")
    .map { |row| row['schema_and_table'] }
    .each { |schema_and_table| exec("truncate table #{schema_and_table}") }
end