-
Notifications
You must be signed in to change notification settings - Fork 64
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Removes the need for pg client tools #942
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,18 +34,6 @@ Spec.before_each do | |
Fiber.current.query_cache = LuckyCache::NullStore.new | ||
end | ||
|
||
class SampleBackupDatabase < Avram::Database | ||
end | ||
|
||
SampleBackupDatabase.configure do |settings| | ||
Comment on lines
-37
to
-40
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I moved this to |
||
settings.credentials = Avram::Credentials.parse?(ENV["BACKUP_DATABASE_URL"]?) || Avram::Credentials.new( | ||
hostname: "db", | ||
database: "sample_backup", | ||
username: "lucky", | ||
password: "developer" | ||
) | ||
end | ||
|
||
Lucky::Session.configure do |settings| | ||
settings.key = "_app_session" | ||
end | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,17 @@ | ||
# Handles the connection to the DB. | ||
class Avram::Connection | ||
private getter db : DB::Database? = nil | ||
|
||
def initialize(@connection_string : String, @database_class : Avram::Database.class) | ||
end | ||
|
||
def open : DB::Database | ||
try_connection! | ||
@db = try_connection! | ||
end | ||
|
||
def close | ||
@db.try(&.close) | ||
@db = nil | ||
end | ||
Comment on lines
8
to
15
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't really understand this. We've never had a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sounds like a plausible explanation. That would solve the bulk of the use cases and the stuff that did generate errors would just get dismissed by restarting the container. I think this is 👍 |
||
|
||
def connect_listen(*channels : String, &block : PQ::Notification ->) : Nil | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -80,6 +80,17 @@ class Avram::Credentials | |
@query.try(&.strip).presence | ||
end | ||
|
||
# This is the full connection string used | ||
# to connect to the PostgreSQL server. | ||
def connection_string : String | ||
String.build do |io| | ||
Comment on lines
+85
to
+86
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In order to run SQL before a database exists, we need the connection string There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What do you mean? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, I was just saying that I moved this logic out so I can differentiate between
and
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oh I get it. I thought you were saying that you were filling in some sample connection string details for type safety .... o_O I was way off... |
||
set_url_protocol(io) | ||
set_url_creds(io) | ||
set_url_host(io) | ||
set_url_port(io) | ||
end | ||
end | ||
|
||
# Returns the postgres connection string without | ||
# any query params. | ||
def url_without_query_params : String | ||
|
@@ -88,10 +99,7 @@ class Avram::Credentials | |
|
||
private def build_url | ||
String.build do |io| | ||
set_url_protocol(io) | ||
set_url_creds(io) | ||
set_url_host(io) | ||
set_url_port(io) | ||
io << connection_string | ||
set_url_db(io) | ||
set_url_query(io) | ||
end | ||
|
Original file line number | Diff line number | Diff line change | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -48,33 +48,35 @@ class Avram::Migrator::Runner | |||||||||||||
end | ||||||||||||||
|
||||||||||||||
def self.drop_db(quiet? : Bool = false) | ||||||||||||||
run "dropdb #{cmd_args}" | ||||||||||||||
DB.connect(credentials.connection_string) do |db| | ||||||||||||||
db.exec "DROP DATABASE IF EXISTS #{db_name}" | ||||||||||||||
end | ||||||||||||||
jwoertink marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||
unless quiet? | ||||||||||||||
puts "Done dropping #{Avram::Migrator::Runner.db_name.colorize(:green)}" | ||||||||||||||
end | ||||||||||||||
rescue e : Exception | ||||||||||||||
if (message = e.message) && message.includes?(%("#{self.db_name}" does not exist)) | ||||||||||||||
unless quiet? | ||||||||||||||
puts "Already dropped #{self.db_name.colorize(:green)}" | ||||||||||||||
end | ||||||||||||||
else | ||||||||||||||
raise e | ||||||||||||||
end | ||||||||||||||
end | ||||||||||||||
|
||||||||||||||
def self.create_db(quiet? : Bool = false) | ||||||||||||||
run "createdb #{cmd_args}" | ||||||||||||||
DB.connect(credentials.connection_string) do |db| | ||||||||||||||
db.exec "CREATE DATABASE #{db_name} WITH OWNER DEFAULT" | ||||||||||||||
end | ||||||||||||||
unless quiet? | ||||||||||||||
puts "Done creating #{Avram::Migrator::Runner.db_name.colorize(:green)}" | ||||||||||||||
puts "Done creating #{db_name.colorize(:green)}" | ||||||||||||||
end | ||||||||||||||
rescue e : DB::ConnectionRefused | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure what level the issue is at, but when you can't connect, a |
||||||||||||||
message = e.message.to_s | ||||||||||||||
if message.blank? | ||||||||||||||
raise ConnectionError.new(URI.parse(credentials.url_without_query_params), Avram.settings.database_to_migrate) | ||||||||||||||
else | ||||||||||||||
raise e | ||||||||||||||
end | ||||||||||||||
rescue e : Exception | ||||||||||||||
if (message = e.message) && message.includes?(%("#{self.db_name}" already exists)) | ||||||||||||||
message = e.message.to_s | ||||||||||||||
if message.includes?(%("#{self.db_name}" already exists)) | ||||||||||||||
unless quiet? | ||||||||||||||
puts "Already created #{self.db_name.colorize(:green)}" | ||||||||||||||
end | ||||||||||||||
elsif (message = e.message) && (message.includes?("createdb: not found") || message.includes?("No command 'createdb' found")) | ||||||||||||||
raise PGClientNotInstalledError.new(message) | ||||||||||||||
elsif (message = e.message) && message.includes?("could not connect to database template") | ||||||||||||||
elsif message.includes?("Cannot establish connection") | ||||||||||||||
raise PGNotRunningError.new(message) | ||||||||||||||
Comment on lines
+79
to
80
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I actually think this won't ever get here now... I'll have to double check, but I believe this is the same as above. It raises a DB::ConnectionRefused error with no message, and then in the stack trace there's a "Caused by..." There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This whole exception logic could use a refactor. For example, matching on exception message text is probably not necessary at all if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Totally. This definitely needs a refactor. The main idea here is that the error coming form postgres is generally not too helpful. I find myself usually having to google why I'm getting "could not connect to template1" and other weird errors. So in this case, we catch those, and re-raise a new helpful error that gives you a list of things to look for as to why it failed. I'll think about this a bit more and circle back. Lines 94 to 99 in 376379a
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, there's no reason it needs to be addressed in your pull here, it's out of scope. |
||||||||||||||
else | ||||||||||||||
raise e | ||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This fully closes the DB connection when the block ends allowing me to drop the DB.