# File lib/pghero.rb, line 157 def primary_database databases.values.first end
module PgHero
Constants
- MUTEX
- VERSION
Attributes
cache_hit_rate_threshold[RW]
config_path[RW]
env[RW]
explain_timeout_sec[RW]
filter_data[RW]
long_running_query_sec[RW]
show_migrations[RW]
slow_query_calls[RW]
slow_query_ms[RW]
total_connections_threshold[RW]
Public Class Methods
analyze_all(**options)
click to toggle source
# File lib/pghero.rb, line 176 def analyze_all(**options) each_database do |database| next if database.replica? database.analyze_tables(**options) end end
autoindex_all(create: false, verbose: true)
click to toggle source
# File lib/pghero.rb, line 183 def autoindex_all(create: false, verbose: true) each_database do |database| puts "Autoindexing #{database.id}..." if verbose database.autoindex(create: create) end end
capture_query_stats(verbose: false)
click to toggle source
# File lib/pghero.rb, line 161 def capture_query_stats(verbose: false) each_database do |database| next unless database.capture_query_stats? puts "Capturing query stats for #{database.id}..." if verbose database.capture_query_stats(raise_errors: true) end end
capture_space_stats(verbose: false)
click to toggle source
# File lib/pghero.rb, line 169 def capture_space_stats(verbose: false) each_database do |database| puts "Capturing space stats for #{database.id}..." if verbose database.capture_space_stats end end
clean_query_stats()
click to toggle source
delete previous stats go database by database to use an index stats for old databases are not cleaned up since we can't use an index
# File lib/pghero.rb, line 197 def clean_query_stats each_database do |database| database.clean_query_stats end end
clean_space_stats()
click to toggle source
# File lib/pghero.rb, line 203 def clean_space_stats each_database do |database| database.clean_space_stats end end
config()
click to toggle source
# File lib/pghero.rb, line 93 def config @config ||= begin require "erb" require "yaml" path = config_path config_file_exists = File.exist?(path) config = YAML.load(ERB.new(File.read(path)).result) if config_file_exists config ||= {} if config[env] config[env] elsif config["databases"] # preferred format config elsif config_file_exists raise "Invalid config file" else databases = {} if !ENV["PGHERO_DATABASE_URL"] && spec_supported? ActiveRecord::Base.configurations.configs_for(env_name: env, include_replicas: true).each do |db| databases[db.send(spec_name_key)] = {"spec" => db.send(spec_name_key)} end end if databases.empty? databases["primary"] = { "url" => ENV["PGHERO_DATABASE_URL"] || connection_config(ActiveRecord::Base) } end if databases.size == 1 databases.values.first.merge!( "db_instance_identifier" => ENV["PGHERO_DB_INSTANCE_IDENTIFIER"], "gcp_database_id" => ENV["PGHERO_GCP_DATABASE_ID"], "azure_resource_id" => ENV["PGHERO_AZURE_RESOURCE_ID"] ) end { "databases" => databases } end end end
connection_config(model)
click to toggle source
private
# File lib/pghero.rb, line 215 def connection_config(model) ActiveRecord::VERSION::STRING.to_f >= 6.1 ? model.connection_db_config.configuration_hash : model.connection_config end
databases()
click to toggle source
ensure we only have one copy of databases so there's only one connection pool per database
# File lib/pghero.rb, line 143 def databases unless defined?(@databases) # only use mutex on initialization MUTEX.synchronize do # return if another process initialized while we were waiting return @databases if defined?(@databases) @databases = config["databases"].map { |id, c| [id.to_sym, Database.new(id, c)] }.to_h end end @databases end
password()
click to toggle source
use method instead of attr_accessor to ensure this works if variable set after PgHero
is loaded
# File lib/pghero.rb, line 85 def password @password ||= config["password"] || ENV["PGHERO_PASSWORD"] end
pretty_size(value)
click to toggle source
# File lib/pghero.rb, line 190 def pretty_size(value) ActiveSupport::NumberHelper.number_to_human_size(value, precision: 3) end
primary_database()
click to toggle source
spec_name_key()
click to toggle source
private Rails 6.1 deprecate `spec_name` and use `name` for configurations github.com/rails/rails/pull/38536
# File lib/pghero.rb, line 222 def spec_name_key ActiveRecord::VERSION::STRING.to_f >= 6.1 ? :name : :spec_name end
spec_supported?()
click to toggle source
private
# File lib/pghero.rb, line 210 def spec_supported? ActiveRecord::VERSION::MAJOR >= 6 end
stats_database_url()
click to toggle source
# File lib/pghero.rb, line 89 def stats_database_url @stats_database_url ||= config["stats_database_url"] || ENV["PGHERO_STATS_DATABASE_URL"] end
time_zone()
click to toggle source
# File lib/pghero.rb, line 73 def time_zone @time_zone || Time.zone end
time_zone=(time_zone)
click to toggle source
# File lib/pghero.rb, line 69 def time_zone=(time_zone) @time_zone = time_zone.is_a?(ActiveSupport::TimeZone) ? time_zone : ActiveSupport::TimeZone[time_zone.to_s] end
username()
click to toggle source
use method instead of attr_accessor to ensure this works if variable set after PgHero
is loaded
# File lib/pghero.rb, line 79 def username @username ||= config["username"] || ENV["PGHERO_USERNAME"] end
Private Class Methods
each_database() { |database| ... }
click to toggle source
# File lib/pghero.rb, line 228 def each_database first_error = nil databases.each do |_, database| begin yield database rescue => e puts "#{e.class.name}: #{e.message}" puts first_error ||= e end end raise first_error if first_error true end