views:

130

answers:

2

I'm converting a part of a rails application to its own sinatra application. It has some beefy work to do and rather than have a million helps in app.rb, I've separated some of it out into classes. Without access to rails I'm rewriting finder several methods and needing access to the database inside of my class. What's the best way to share a database connection between your application and a class? Or would you recommend pushing all database work into its own class and only having the connection established there?

Here is what I have in in app.rb

require 'lib/myclass'

configure :production do
  MysqlDB = Sequel.connect('mysql://user:password@host:port/db_name')
end

I want to access it in lib/myclass.rb

class Myclass
  def self.find_by_domain_and_stub(domain, stub)
    # want to do a query here
  end
end

I've tried several things but nothing that seems to work well enough to even include as an example.

+1  A: 

Assuming you're not doing any threading, just set up the connection as a global var.

require 'lib/myclass'

before do
  $MysqlDB = Sequel.connect('mysql://user:password@host:port/db_name')
end

class Myclass
  def self.find_by_domain_and_stub(domain, stub)
    # use $MysqlDB here
  end
end

Might be wise to check the connection timeout settings, or explicitly disconnect from the server. If you're handling a lot of requests, you could run out of connections before they time out.

Tim Rosenblatt
perfect, exactly what I needed
imightbeinatree at Cloudspace
A: 

Tim Rosenblatt's answer will reconnect on every request. It's better to do the following in your Sinatra app:

require 'sequel'
DB = Sequel.connect('mysql://user:password@host:port/db_name')
require 'lib/myclass'

It's better to use a constant than a global variable in this case.

Jeremy Evans
would you change your mind if i told you that the application will only serve for a single api call that is expected to do a single request and close the connection right afterwards?
imightbeinatree at Cloudspace
The Sequel solution to that would be call connect with a block, which I would do in the actual Sinatra action, not in the before. get('...') do Sequel.connect('mysql://user:password@host:port/db_name') do |db| ... end end
Jeremy Evans
just realized i wasn't very clear in my comment to your answer. the single api call still has to execute quite a few queries and jump through some complex hoops before it returns the result. I had understood you to mean that the db will reconnect on every request (as in page load). Is this what you meant or did you perhaps mean that the db connection will be re-established everytime I call the global variable in my code?
imightbeinatree at Cloudspace