Permalink
Browse files

Improve how adapters are initialized

This commit inverts dependency between the Adapter class and the
specific implementations. Every adapter should now register itself by
calling Adapter.register(self). They should also implement the .schemes
method that return a list of schemes the adapter works with.

A Adapter.[] method was also added. This method looks up Adapter classes
based on a given scheme.

 #55
  • Loading branch information...
abernardes committed Nov 2, 2014
1 parent ab8c4cf commit 5567e12413987d62570e5763318ae10e90a97ae0
View
@@ -27,6 +27,10 @@ def self.setup(options, &block)
require 'rom/reader'
require 'rom/adapter'
require 'rom/adapter/memory'
require 'rom/adapter/sequel'
require 'rom/adapter/mongo'
require 'rom/repository'
require 'rom/env'
View
@@ -1,29 +1,29 @@
require 'addressable/uri'
require 'rom/adapter/memory'
require 'rom/adapter/sequel'
require 'rom/adapter/mongo'
module ROM
class Adapter
@adapters = []
attr_reader :uri
def self.setup(uri_string)
uri = Addressable::URI.parse(uri_string)
adapter =
case uri.scheme
when 'sqlite', 'jdbc' then Adapter::Sequel
when 'memory' then Adapter::Memory
when 'mongo' then Adapter::Mongo
else
raise ArgumentError, "#{uri_string.inspect} uri is not supported"
end
unless adapter = self[uri.scheme]
raise ArgumentError, "#{uri_string.inspect} uri is not supported"
end
adapter.new(uri)
end
def self.register(adapter)
@adapters << adapter
end
def self.[](scheme)
@adapters.detect { |adapter| adapter.schemes.include?(scheme.to_sym) }
end
def initialize(uri)
@uri = uri
@@ -4,6 +4,10 @@ class Adapter
class Memory < Adapter
attr_reader :connection
def self.schemes
[:memory]
end
class Storage
attr_reader :data
@@ -26,6 +30,7 @@ def [](name)
connection[name]
end
Adapter.register(self)
end
end
View
@@ -6,6 +6,10 @@ class Adapter
class Mongo < Adapter
attr_reader :connection
def self.schemes
[:mongo]
end
class Dataset
include Charlatan.new(:collection, kind: Moped::Query)
end
@@ -24,6 +28,7 @@ def schema
[]
end
Adapter.register(self)
end
end
@@ -8,6 +8,10 @@ class Adapter
class Sequel < Adapter
attr_reader :connection
def self.schemes
[:sqlite, :jdbc]
end
def initialize(*args)
super
@connection = ::Sequel.connect(uri.to_s)
@@ -46,6 +50,8 @@ def map_attribute_types(attrs)
def map_schema_type(type)
connection.class::SCHEMA_TYPE_CLASSES.fetch(type)
end
Adapter.register(self)
end
end
@@ -0,0 +1,15 @@
require 'spec_helper'
describe Adapter::Sequel do
describe ".initialize" do
it "sets up a connection based on the URI" do
connection = Adapter::Sequel.new(SEQUEL_TEST_DB_URI).connection
if USING_JRUBY
expect(connection).to be_instance_of(Sequel::JDBC::Database)
else
expect(connection).to be_instance_of(Sequel::SQLite::Database)
end
end
end
end
@@ -1,16 +1,33 @@
require 'spec_helper'
class TestAdapter < Adapter
def self.schemes
[:test_scheme]
end
def initialize(uri); end
Adapter.register(self)
end
describe Adapter do
describe '.setup' do
it 'sets up connection based on a uri' do
connection = Adapter.setup(SEQUEL_TEST_DB_URI).connection
adapter = Adapter.setup("test_scheme::memory")
if USING_JRUBY
expect(connection).to be_instance_of(Sequel::JDBC::Database)
else
expect(connection).to be_instance_of(Sequel::SQLite::Database)
end
expect(adapter).to be_instance_of(TestAdapter)
end
it 'raises an exception if the scheme is not supported' do
expect {
Adapter.setup("bogus:///non-existent")
}.to raise_error(ArgumentError, '"bogus:///non-existent" uri is not supported')
end
end
describe '.[]' do
it "looks up and return the adapter class for the given schema" do
expect(Adapter[:test_scheme]).to eq TestAdapter
end
end
end

0 comments on commit 5567e12

Please sign in to comment.