Class: Baza::Driver::Pg::Database

Inherits:
Baza::Database show all
Defined in:
lib/baza/driver/pg/database.rb

Constant Summary collapse

CREATE_ALLOWED_KEYS =
[:columns, :indexes, :temp, :return_sql].freeze

Instance Attribute Summary

Attributes inherited from Baza::Database

#db, #driver, #name

Instance Method Summary collapse

Methods inherited from Baza::Database

#import_file!, #initialize, #name_changed?, #name_was, #table_exists?, #to_param

Methods included from Baza::DatabaseModelFunctionality

#model_name, #to_model

Constructor Details

This class inherits a constructor from Baza::Database

Instance Method Details

#create_table(table_name, data, args = nil) ⇒ Object

Creates a new table by the given name and data.



58
59
60
61
62
# File 'lib/baza/driver/pg/database.rb', line 58

def create_table(table_name, data, args = nil)
  use do
    db.tables.create(table_name, data, args)
  end
end

#dropObject



7
8
9
10
11
12
13
14
# File 'lib/baza/driver/pg/database.rb', line 7

def drop
  with_cloned_conn_and_terminated_connections do |cloned_conn|
    # Drop the database
    cloned_conn.query("DROP DATABASE #{db.sep_database}#{db.escape_database(name)}#{db.sep_database}")
  end

  self
end

#rename(new_name) ⇒ Object



64
65
66
67
68
69
70
71
# File 'lib/baza/driver/pg/database.rb', line 64

def rename(new_name)
  with_cloned_conn_and_terminated_connections do |cloned_conn|
    cloned_conn.query("ALTER DATABASE #{db.sep_database}#{db.escape_database(name_was)}#{db.sep_database} RENAME TO #{db.sep_database}#{db.escape_database(new_name)}#{db.sep_database}")
  end

  @name = new_name.to_s
  self
end

#save!Object



2
3
4
5
# File 'lib/baza/driver/pg/database.rb', line 2

def save!
  rename(name) unless name.to_s == name_was
  self
end

#table(table_name) ⇒ Object



16
17
18
19
20
# File 'lib/baza/driver/pg/database.rb', line 16

def table(table_name)
  table = tables(name: table_name).first
  raise Baza::Errors::TableNotFound unless table
  table
end

#tables(args = {}) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/baza/driver/pg/database.rb', line 22

def tables(args = {})
  tables_list = [] unless block_given?

  where_args = {
    table_catalog: name,
    table_schema: "public"
  }
  where_args[:table_name] = args.fetch(:name) if args[:name]

  use do
    db.select([:information_schema, :tables], where_args, orderby: :table_name) do |table_data|
      table = Baza::Driver::Pg::Table.new(
        driver: db.driver,
        data: table_data
      )

      next if table.native?

      if tables_list
        tables_list << table
      else
        yield table
      end
    end
  end

  tables_list
end

#use(&blk) ⇒ Object



51
52
53
54
# File 'lib/baza/driver/pg/database.rb', line 51

def use(&blk)
  db.with_database(name, &blk)
  self
end

#with_cloned_conn_and_terminated_connectionsObject



73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/baza/driver/pg/database.rb', line 73

def with_cloned_conn_and_terminated_connections
  other_db = db.databases.list.find { |database| database.name != @db.current_database && database.name != "template0" }

  # Drop database through a cloned connection, because Postgres might bug up if dropping the current
  db.clone_conn(db: other_db.name) do |cloned_conn|
    # Close existing connections to avoid 'is being accessed by other users' errors
    cloned_conn.query("REVOKE CONNECT ON DATABASE #{db.sep_database}#{db.escape_database(name)}#{db.sep_database} FROM public") unless name_changed?
    cloned_conn.query("SELECT pid, pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = #{db.sep_val}#{@db.esc(name)}#{db.sep_val} AND pid != pg_backend_pid()")

    yield cloned_conn
  end
end