lib/rom/sql/relation.rb in rom-sql-0.7.0 vs lib/rom/sql/relation.rb in rom-sql-0.8.0
- old
+ new
@@ -1,21 +1,30 @@
require 'rom/sql/header'
+require 'rom/sql/types'
+require 'rom/sql/schema'
+
require 'rom/sql/relation/reading'
require 'rom/sql/relation/writing'
require 'rom/plugins/relation/view'
require 'rom/plugins/relation/key_inference'
require 'rom/plugins/relation/sql/base_view'
require 'rom/plugins/relation/sql/auto_combine'
require 'rom/plugins/relation/sql/auto_wrap'
+require 'rom/support/deprecations'
+require 'rom/support/constants'
+
module ROM
module SQL
# Sequel-specific relation extensions
#
+ # @api public
class Relation < ROM::Relation
+ include SQL
+
adapter :sql
use :key_inference
use :view
use :base_view
@@ -23,74 +32,116 @@
use :auto_wrap
include Writing
include Reading
- # @attr_reader [Header] header Internal lazy-initialized header
- attr_reader :header
-
- # Name of the table used in FROM clause
- #
- # @attr_reader [Symbol] table
- attr_reader :table
-
# Set default dataset for a relation sub-class
#
# @api private
def self.inherited(klass)
super
klass.class_eval do
+ schema_dsl SQL::Schema::DSL
+ schema_inferrer ROM::SQL::Schema::Inferrer
+
dataset do
table = opts[:from].first
if db.table_exists?(table)
- # quick fix for dbs w/o primary_key inference
- #
- # TODO: add a way of setting a pk explicitly on a relation
- pk =
- if db.respond_to?(:primary_key)
- Array(db.primary_key(table))
- else
- [:id]
- end.map { |name| :"#{table}__#{name}" }
-
- select(*columns).order(*pk)
+ pk_header = klass.primary_key_header(db, table)
+ select(*columns).order(*pk_header.qualified)
else
self
end
end
+
+ # @!method by_pk(pk)
+ # Return a relation restricted by its primary key
+ # @param [Object] pk The primary key value
+ # @return [SQL::Relation]
+ # @api public
+ view(:by_pk, attributes[:base]) do |pk|
+ where(primary_key => pk)
+ end
end
end
+ # @api private
+ def self.associations
+ schema.associations
+ end
+
+ # @api private
+ def self.primary_key_header(db, table)
+ names =
+ if schema
+ schema.primary_key_names
+ elsif db.respond_to?(:primary_key)
+ Array(db.primary_key(table))
+ else
+ [:id]
+ end
+ Header.new(names, table)
+ end
+
+ # Set primary key
+ #
+ # @deprecated
+ #
+ # @api public
def self.primary_key(value)
+ Deprecations.announce(
+ :primary_key, "use schema definition to configure primary key"
+ )
option :primary_key, reader: true, default: value
end
- primary_key :id
+ option :primary_key, reader: true, default: -> rel {
+ rel.schema? ? rel.schema.primary_key_name : :id
+ }
+ # Return table name from relation's sql statement
+ #
+ # This value is used by `header` for prefixing column names
+ #
+ # @return [Symbol]
+ #
# @api private
- def initialize(dataset, registry = {})
- super
- @table = dataset.opts[:from].first
+ def table
+ @table ||= dataset.opts[:from].first
end
# Return a header for this relation
#
# @return [Header]
#
# @api private
def header
- @header ||= Header.new(dataset.opts[:select] || dataset.columns, table)
+ @header ||= Header.new(selected_columns, table)
end
# Return raw column names
#
# @return [Array<Symbol>]
#
# @api private
def columns
- dataset.columns
+ @columns ||= dataset.columns
+ end
+
+ protected
+
+ # Return a list of columns from *the sql select* statement or default to
+ # dataset columns
+ #
+ # This is used to construct relation's header
+ #
+ # @return [Array<Symbol>]
+ #
+ # @api private
+ def selected_columns
+ @selected_columns ||= dataset.opts.fetch(:select, columns)
end
end
end
end