trilogy-libraries / trilogy

Trilogy is a client library for MySQL-compatible database servers, designed for performance, flexibility, and ease of embedding.
MIT License
697 stars 68 forks source link

`Trilogy.connect` not working in Staging and Production environments. #149

Open joshuapinter opened 7 months ago

joshuapinter commented 7 months ago

In Staging and Production

config = Rails.configuration.database_configuration[ Rails.env ]
connection = Trilogy.new( config )
#=> .../trilogy-2.6.1/lib/trilogy.rb:18:in `_connect': No such file or directory - trilogy_connect - unable to connect to /tmp/mysql.sock (Trilogy::SyscallError::ENOENT)

In Development

config = Rails.configuration.database_configuration[ Rails.env ]
connection = Trilogy.new( config )
#=> <Trilogy:0x000000013a9de1e0

The configs between the environments are similar with just different database, username, password and host values.

Moreover, the actual Rails application (i.e. ActiveRecord) works just fine in all environments using Trilogy.

Any thoughts on this?

Thanks!

bensheldon commented 7 months ago

Is your production database available via a socket file on that same host? unable to connect to /tmp/mysql.sock (Trilogy::SyscallError::ENOENT)

It looks like your configuration may still have Trilogy connecting via a file-based socket rather than remotely over the network and/or port 3306.

joshuapinter commented 7 months ago

Thanks for the reply @bensheldon.

I don't think that's it because the actual app works just fine. As an example here is my staging environment config:

staging:
  database:  redacted
  username:  redacted
  password:  redacted
  adapter:   trilogy
  host:      redacted
  port:      3306

Is there something special with Trilogy.connect that we need to do to force it to use the host and port instead of a socket file?

joshuapinter commented 7 months ago

Okay, I narrowed it down a bit. It looks like the config Hash is being completely ignored when passed to Trilogy.new, which looks like it is expecting named parameters.

That explains why it works in Development, because in Development, you don't need to pass the config and it'll still connect:

config = Rails.configuration.database_configuration[ Rails.env ]
Trilogy.new( config )
#=> <Trilogy:0x000000013a9de1e0
Trilogy.new
=> #<Trilogy:0x0000000139ef01e8

If I supply the named parameters manually it works:

Trilogy.new( host: redacted, port: 3306, username: redacted, password: redacted )
=> #<Trilogy:0x00007f676bbf79d8

I tried using splat (**) to convert the config to named parameters but that doesn't seem to work:

Trilogy.new( **config )
.../trilogy-2.6.1/lib/trilogy.rb:18:in `_connect': No such file or directory - trilogy_connect - unable to connect to /tmp/mysql.sock (Trilogy::SyscallError::ENOENT)

Any idea how to pass the config Hash to Trilogy.new?

joshuapinter commented 7 months ago

Okay, figured it out. config is by default set with keys that are Strings wherease Trilogy.new is expecting Symbols.

This ended up working:

Trilogy.new( config.symbolize_keys )
#=> #<Trilogy:0x00007f676ba2a790

Is this something you can or want to handle in the library itself so it treats Strings and Symbols the same in the initialization config?

bensheldon commented 7 months ago

Oh! Nice find! I'd like that configuration to be more permissive and less surprising. It looks like we're already duping the connection options during initialization, so maybe that could do the symbolize keys too (with some slight reordering):

https://github.com/trilogy-libraries/trilogy/blob/90d81d2a7e457435224232539470b7bd383a82f4/contrib/ruby/lib/trilogy.rb#L10-L23

Edit: I misunderstood what we're doing with #connection_options. I think doing a symbolize_keys or equivalent still would be ok.

joshuapinter commented 7 months ago

Yup, I would just symbolize the keys for options right at the start. Because this is just ruby I don't think we can use rails methods so I think options.transform_keys(&:to_sym) should do the trick.

Do you want to handle it or do you want me to submit a PR?

bensheldon commented 7 months ago

@joshuapinter if you could submit a PR, I can take it from there 👍🏻

joshuapinter commented 7 months ago

@bensheldon There ya go! https://github.com/trilogy-libraries/trilogy/pull/151

Thanks.