Skip to content

Commit

Permalink
Merge pull request #345 from rom-rb/infer-schema
Browse files Browse the repository at this point in the history
Support automatic schema inferring
  • Loading branch information
flash-gordon committed May 22, 2016
2 parents 61f3d47 + c66b6ec commit 4d1e959
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 14 deletions.
1 change: 0 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ group :test do
gem 'anima', '~> 0.2.0'
gem 'minitest'
gem 'thread_safe'
gem 'activesupport'
gem 'inflecto', '~> 0.0', '>= 0.0.2'

platforms :rbx do
Expand Down
12 changes: 8 additions & 4 deletions lib/rom/relation/class_interface.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,11 @@ def inherited(klass)
klass.class_eval do
use :registry_reader

defines :gateway, :dataset, :dataset_proc, :register_as, :schema_dsl
defines :gateway, :dataset, :dataset_proc, :register_as, :schema_dsl, :schema_inferrer

gateway :default
schema_dsl Schema::DSL
schema_inferrer nil

dataset default_name

Expand Down Expand Up @@ -146,13 +147,16 @@ def [](adapter)
# @return [Schema]
#
# @param [Symbol] dataset An optional dataset name
# @param [Boolean] infer Whether to do an automatic schema inferring
#
# @api public
def schema(dataset = nil, &block)
def schema(dataset = nil, infer: false, &block)
if defined?(@schema)
@schema
elsif block
@schema = schema_dsl.new(dataset || self.dataset, &block).call
elsif block || infer
@schema = schema_dsl.new(dataset || self.dataset,
inferrer: infer ? schema_inferrer : nil,
&block).call

if dataset
self.dataset(dataset)
Expand Down
39 changes: 30 additions & 9 deletions lib/rom/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,27 @@ module ROM
#
# @api public
class Schema
include Dry::Equalizer(:dataset, :attributes, :meta)
include Dry::Equalizer(:dataset, :attributes, :inferrer)
include Enumerable

attr_reader :dataset, :attributes, :meta
attr_reader :dataset, :attributes, :inferrer

# @api public
class DSL < BasicObject
attr_reader :dataset, :attributes
attr_reader :dataset, :attributes, :inferrer

# @api private
def initialize(dataset = nil, &block)
@attributes = {}
def initialize(dataset = nil, inferrer: nil, &block)
@attributes = nil
@dataset = dataset
instance_exec(&block)
@inferrer = inferrer

if block
instance_exec(&block)
elsif inferrer.nil?
raise ArgumentError,
'You must pass a block to define a schema or set an inferrer for automatic inferring'
end
end

# Defines a relation attribute with its type
Expand All @@ -28,6 +35,7 @@ def initialize(dataset = nil, &block)
#
# @api public
def attribute(name, type)
@attributes ||= {}
@attributes[name] = type.meta(name: name)
end

Expand All @@ -43,15 +51,17 @@ def primary_key(*names)

# @api private
def call
Schema.new(dataset, attributes)
Schema.new(dataset, attributes, inferrer: inferrer && inferrer.new(self))
end
end

# @api private
def initialize(dataset, attributes)
def initialize(dataset, attributes, inferrer: nil)
@dataset = dataset
@attributes = attributes
freeze
@inferrer = inferrer

freeze if self.defined?
end

# Iterate over schema's attributes
Expand Down Expand Up @@ -79,5 +89,16 @@ def primary_key
def foreign_key(relation)
detect { |attr| attr.meta[:foreign_key] && attr.meta[:relation] == relation }
end

# @api public
def defined?
!@attributes.nil?
end

# @api private
def infer!(gateway)
@attributes = inferrer.call(dataset, gateway)
freeze
end
end
end
4 changes: 4 additions & 0 deletions lib/rom/setup/finalize/finalize_relations.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ def run!
# where klass' gateway points to non-existant repo
gateway = @gateways.fetch(klass.gateway)
ds_proc = klass.dataset_proc || -> _ { self }

if klass.schema && !klass.schema.defined?
klass.schema.infer!(gateway)
end
dataset = gateway.dataset(klass.dataset).instance_exec(klass, &ds_proc)

relation = klass.new(dataset, __registry__: registry)
Expand Down

0 comments on commit 4d1e959

Please sign in to comment.