Hanami uses Sequel as default ORM
There are different plugins for Sequel
Sometimes to use it you need to access to database connection object
For example to use PostgreSQL advisory locking for mutexes
There are such gems for this: sequel-advisory-locking, sequel-pg_advisory_lock
First, you should load an extension for Sequel::Database
instance
DB.extension(:advisory_locking)
Then use it in your app like this
DB.advisory_lock('my_key') do
# do stuff with lock
end
But there is problem to use such libraries with Hanami
There is no information about it in official guide
On database configuration page such info:
Hanami models use ROM as a low-level backend. This means that you can easily use any Sequel plugins in your app. For this you need to define a
gateway
block in your model configuration, add the extension by callingextension
ongateway.connection
and pass the extension name in:# config/environment.rb Hanami.configure do model do gateway do |g| g.connection.extension(:connection_validator) end end end
What I tried is define constant in this config
Hanami.configure do
model do
gateway do |g|
DB = g.connection
DB.extension(:connection_validator)
DB.extension(:advisory_locking)
end
end
end
And then use this DB
somewhere in the app, for example as DB.advisory_lock('my_key') { do_stuff_with_lock }
But such constants define within a block looks not good
How to get connection instance in Hanami app?
CodePudding user response:
There is config object in Hanami -- Hanami::Model.configuration
In fact it is the getter for @configuration
instance variable
It is instance of Hanami::Model::Configuration
and has such instance variables like @url
, @entities
, @logger
and others. So it's possible to call getters to get them
It also has connection
method. This method returns gateway.connection
And this gateway.connection
is just what is needed. This is exactly the instance of connection to the database, on which you can call methods
For example
Hanami::Model.configuration.connection.advisory_lock('my_lock') do
# do stuff with lock
end
I want to note that all these methods are indicated by the comment # @api private
. It means that their implementation may be changed in future versions.