lib/rom/sql/relation.rb in rom-sql-0.6.0.beta1 vs lib/rom/sql/relation.rb in rom-sql-0.6.0.rc1
- old
+ new
@@ -1,8 +1,10 @@
require 'rom/sql/header'
require 'rom/sql/relation/class_methods'
+require 'rom/sql/relation/reading'
+require 'rom/sql/relation/writing'
require 'rom/sql/relation/inspection'
require 'rom/sql/relation/associations'
module ROM
module SQL
@@ -13,10 +15,12 @@
extend ClassMethods
include Inspection
include Associations
+ include Writing
+ include Reading
# @attr_reader [Header] header Internal lazy-initialized header
attr_reader :header
# Name of the table used in FROM clause
@@ -26,386 +30,9 @@
# @api private
def initialize(dataset, registry = {})
super
@table = dataset.opts[:from].first
- end
-
- # Project a relation
- #
- # This method is intended to be used internally within a relation object
- #
- # @example
- # rom.relation(:users) { |r| r.project(:id, :name) }
- #
- # @param [Symbol] names A list of symbol column names
- #
- # @return [Relation]
- #
- # @api public
- def project(*names)
- select(*header.project(*names))
- end
-
- # Rename columns in a relation
- #
- # This method is intended to be used internally within a relation object
- #
- # @example
- # rom.relation(:users) { |r| r.rename(name: :user_name) }
- #
- # @param [Hash] options A name => new_name map
- #
- # @return [Relation]
- #
- # @api public
- def rename(options)
- select(*header.rename(options))
- end
-
- # Prefix all columns in a relation
- #
- # This method is intended to be used internally within a relation object
- #
- # @example
- # rom.relation(:users) { |r| r.prefix(:user) }
- #
- # @param [Symbol] name The prefix
- #
- # @return [Relation]
- #
- # @api public
- def prefix(name = Inflector.singularize(table))
- rename(header.prefix(name).to_h)
- end
-
- # Qualifies all columns in a relation
- #
- # This method is intended to be used internally within a relation object
- #
- # @example
- # rom.relation(:users) { |r| r.qualified }
- #
- # @return [Relation]
- #
- # @api public
- def qualified
- select(*qualified_columns)
- end
-
- # Return a list of qualified column names
- #
- # This method is intended to be used internally within a relation object
- #
- # @return [Relation]
- #
- # @api public
- def qualified_columns
- header.qualified.to_a
- end
-
- # Get first tuple from the relation
- #
- # @example
- # users.first
- #
- # @return [Relation]
- #
- # @api public
- def first
- dataset.first
- end
-
- # Get last tuple from the relation
- #
- # @example
- # users.last
- #
- # @return [Relation]
- #
- # @api public
- def last
- dataset.last
- end
-
- # Return relation count
- #
- # @example
- # users.count # => 12
- #
- # @return [Relation]
- #
- # @api public
- def count
- dataset.count
- end
-
- # Select specific columns for select clause
- #
- # @example
- # users.select(:id, :name)
- #
- # @return [Relation]
- #
- # @api public
- def select(*args, &block)
- __new__(dataset.__send__(__method__, *args, &block))
- end
-
- # Append specific columns to select clause
- #
- # @example
- # users.select(:id, :name).select_append(:email)
- #
- # @return [Relation]
- #
- # @api public
- def select_append(*args, &block)
- __new__(dataset.__send__(__method__, *args, &block))
- end
-
- # Returns a copy of the relation with a SQL DISTINCT clause.
- #
- # @example
- # users.distinct(:country)
- #
- # @return [Relation]
- #
- # @api public
- def distinct(*args, &block)
- __new__(dataset.__send__(__method__, *args, &block))
- end
-
- # Restrict a relation to match criteria
- #
- # @example
- # users.where(name: 'Jane')
- #
- # @return [Relation]
- #
- # @api public
- def where(*args, &block)
- __new__(dataset.__send__(__method__, *args, &block))
- end
-
- # Restrict a relation to not match criteria
- #
- # @example
- # users.exclude(name: 'Jane')
- #
- # @return [Relation]
- #
- # @api public
- def exclude(*args, &block)
- __new__(dataset.__send__(__method__, *args, &block))
- end
-
- # Inverts a request
- #
- # @example
- # users.exclude(name: 'Jane').invert
- #
- # # this is the same as:
- # users.where(name: 'Jane')
- #
- # @return [Relation]
- #
- # @api public
- def invert(*args, &block)
- __new__(dataset.__send__(__method__, *args, &block))
- end
-
- # Set order for the relation
- #
- # @example
- # users.order(:name)
- #
- # @return [Relation]
- #
- # @api public
- def order(*args, &block)
- __new__(dataset.__send__(__method__, *args, &block))
- end
-
- # Reverse the order of the relation
- #
- # @example
- # users.order(:name).reverse
- #
- # @return [Relation]
- #
- # @api public
- def reverse(*args, &block)
- __new__(dataset.__send__(__method__, *args, &block))
- end
-
- # Limit a relation to a specific number of tuples
- #
- # @example
- # users.limit(1)
- #
- # @return [Relation]
- #
- # @api public
- def limit(*args, &block)
- __new__(dataset.__send__(__method__, *args, &block))
- end
-
- # Set offset for the relation
- #
- # @example
- # users.limit(10).offset(2)
- #
- # @return [Relation]
- #
- # @api public
- def offset(*args, &block)
- __new__(dataset.__send__(__method__, *args, &block))
- end
-
- # Map tuples from the relation
- #
- # @example
- # users.map { |user| ... }
- #
- # @api public
- def map(&block)
- to_enum.map(&block)
- end
-
- # Join other relation using inner join
- #
- # @param [Symbol] relation name
- # @param [Hash] join keys
- #
- # @return [Relation]
- #
- # @api public
- def inner_join(*args, &block)
- __new__(dataset.__send__(__method__, *args, &block))
- end
-
- # Join other relation using left outer join
- #
- # @param [Symbol] relation name
- # @param [Hash] join keys
- #
- # @return [Relation]
- #
- # @api public
- def left_join(*args, &block)
- __new__(dataset.__send__(__method__, *args, &block))
- end
-
- # Group by specific columns
- #
- # @example
- # tasks.group(:user_id)
- #
- # @return [Relation]
- #
- # @api public
- def group(*args, &block)
- __new__(dataset.__send__(__method__, *args, &block))
- end
-
- # Group by specific columns and count by group
- #
- # @example
- # tasks.group_and_count(:user_id)
- # # => [{ user_id: 1, count: 2 }, { user_id: 2, count: 3 }]
- #
- # @return [Relation]
- #
- # @api public
- def group_and_count(*args, &block)
- __new__(dataset.__send__(__method__, *args, &block))
- end
-
- # Select and group by specific columns
- #
- # @example
- # tasks.select_group(:user_id)
- # # => [{ user_id: 1 }, { user_id: 2 }]
- #
- # @return [Relation]
- #
- # @api public
- def select_group(*args, &block)
- __new__(dataset.__send__(__method__, *args, &block))
- end
-
- # Insert tuple into relation
- #
- # @example
- # users.insert(name: 'Jane')
- #
- # @param [Hash] tuple
- #
- # @return [Relation]
- #
- # @api public
- def insert(*args, &block)
- dataset.insert(*args, &block)
- end
-
- # Multi insert tuples into relation
- #
- # @example
- # users.multi_insert([{name: 'Jane'}, {name: 'Jack'}])
- #
- # @param [Array] tuples
- #
- # @return [Relation]
- #
- # @api public
- def multi_insert(*args, &block)
- dataset.multi_insert(*args, &block)
- end
-
- # Update tuples in the relation
- #
- # @example
- # users.update(name: 'Jane')
- # users.where(name: 'Jane').update(name: 'Jane Doe')
- #
- # @return [Relation]
- #
- # @api public
- def update(*args, &block)
- dataset.update(*args, &block)
- end
-
- # Delete tuples from the relation
- #
- # @example
- # users.delete # deletes all
- # users.where(name: 'Jane').delete # delete tuples
- # from restricted relation
- #
- # @return [Relation]
- #
- # @api public
- def delete(*args, &block)
- dataset.delete(*args, &block)
- end
-
- # Return if a restricted relation has 0 tuples
- #
- # @example
- # users.unique?(email: 'jane@doe.org') # true
- #
- # users.insert(email: 'jane@doe.org')
- #
- # users.unique?(email: 'jane@doe.org') # false
- #
- # @param [Hash] criteria hash for the where clause
- #
- # @return [Relation]
- #
- # @api public
- def unique?(criteria)
- where(criteria).count.zero?
end
# Return a header for this relation
#
# @return [Header]