Module: ROM::SQL::Relation::Reading
- Included in:
- ROM::SQL::Relation
- Defined in:
- lib/rom/sql/relation/reading.rb
Overview
Query API for SQL::Relation
Constant Summary collapse
- ROW_LOCK_MODES =
Row-level lock modes
Hash.new(update: 'FOR UPDATE'.freeze).update( # https://www.postgresql.org/docs/current/static/sql-select.html#SQL-FOR-UPDATE-SHARE postgres: { update: 'FOR UPDATE'.freeze, no_key_update: 'FOR NO KEY UPDATE'.freeze, share: 'FOR SHARE'.freeze, key_share: 'FOR KEY SHARE'.freeze }, # https://dev.mysql.com/doc/refman/5.7/en/innodb-locking-reads.html mysql: { update: 'FOR UPDATE'.freeze, share: 'LOCK IN SHARE MODE'.freeze } ).freeze
Instance Method Summary collapse
-
#avg(*args) ⇒ Object
Returns a result of SQL AVG clause.
-
#count ⇒ Relation
Return relation count.
-
#distinct(*args, &block) ⇒ Relation
Returns a copy of the relation with a SQL DISTINCT clause.
-
#each_batch(size: 1000) {|| ... } ⇒ Object
Process the dataset in batches.
-
#exclude(*args, &block) ⇒ Relation
Restrict a relation to not match criteria.
-
#exist?(*args, &block) ⇒ TrueClass, FalseClass
Checks whether a relation has at least one tuple.
-
#exists(other, condition = nil) ⇒ SQL::Relation
Restrict with rows from another relation.
-
#fetch(pk) ⇒ Relation
Fetch a tuple identified by the pk.
-
#first ⇒ Hash
Get first tuple from the relation.
-
#group(*args, &block) ⇒ Relation
Group by specific columns.
-
#group_and_count(*args, &block) ⇒ Relation
Group by specific columns and count by group.
-
#group_append(*args, &block) ⇒ Relation
Group by more columns.
-
#having(*args, &block) ⇒ Relation
Restrict a relation to match grouping criteria.
-
#invert ⇒ Relation
Inverts the current WHERE and HAVING clauses.
-
#join(*args, &block) ⇒ Relation
(also: #inner_join)
Join with another relation using INNER JOIN.
-
#last ⇒ Hash
Get last tuple from the relation.
-
#left_join(*args, &block) ⇒ Relation
Join with another relation using LEFT OUTER JOIN.
-
#limit(*args) ⇒ Relation
Limit a relation to a specific number of tuples.
-
#lock(options = EMPTY_HASH, &block) ⇒ Object
Lock rows with in the specified mode.
-
#map(key = nil, &block) ⇒ Object
Map tuples from the relation.
-
#max(*args) ⇒ Object
Returns a result of SQL MAX clause.
-
#min(*args) ⇒ Object
Returns a result of SQL MIN clause.
-
#offset(num) ⇒ Relation
Set offset for the relation.
-
#order(*args, &block) ⇒ Relation
Set order for the relation.
-
#pluck(name) ⇒ Array
Pluck values from a specific column.
-
#prefix(name = Dry::Core::Inflector.singularize(schema.name.dataset)) ⇒ Relation
Prefix all columns in a relation.
-
#qualified(table_alias = nil) ⇒ Relation
Qualifies all columns in a relation.
-
#qualified_columns ⇒ Array<Symbol>
Return a list of qualified column names.
-
#read(sql) ⇒ SQL::Relation
Return a new relation from a raw SQL string.
-
#rename(options) ⇒ Relation
Rename columns in a relation.
-
#reverse(*args, &block) ⇒ Relation
Reverse the order of the relation.
-
#right_join(*args, &block) ⇒ Relation
Join with another relation using RIGHT JOIN.
-
#select(*args, &block) ⇒ Relation
(also: #project)
Select specific columns for select clause.
-
#select_append(*args, &block) ⇒ Relation
Append specific columns to select clause.
-
#select_group(*args, &block) ⇒ Relation
Select and group by specific columns.
-
#sum(*args) ⇒ Integer
Returns a result of SQL SUM clause.
-
#union(relation, options = EMPTY_HASH, &block) ⇒ Object
Adds a UNION clause for relation dataset using second relation dataset.
-
#unique?(criteria) ⇒ TrueClass, FalseClass
Return if a restricted relation has 0 tuples.
-
#where(*args, &block) ⇒ Relation
Restrict a relation to match criteria.
Instance Method Details
#avg(*args) ⇒ Object
Returns a result of SQL AVG clause.
323 324 325 |
# File 'lib/rom/sql/relation/reading.rb', line 323 def avg(*args) dataset.__send__(__method__, *args) end |
#count ⇒ Relation
Return relation count
50 51 52 |
# File 'lib/rom/sql/relation/reading.rb', line 50 def count dataset.count end |
#distinct(*columns) ⇒ Relation #distinct(&block) ⇒ Relation
Returns a copy of the relation with a SQL DISTINCT clause.
267 268 269 |
# File 'lib/rom/sql/relation/reading.rb', line 267 def distinct(*args, &block) new(dataset.__send__(__method__, *args, &block)) end |
#each_batch(size: 1000) {|| ... } ⇒ Object
Process the dataset in batches. The method yields a relation restricted by a primary key value. This means it discards any order internally and uses the PK sort. Currently, works only with a single-column primary key.
899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 |
# File 'lib/rom/sql/relation/reading.rb', line 899 def each_batch(size: 1000) pks = schema.primary_key if pks.size > 1 raise ArgumentError, 'Composite primary keys are not supported yet' end source = order(pks[0]).limit(size) rel = source loop do ids = rel.pluck(primary_key) break if ids.empty? yield(rel) break if ids.size < size rel = source.where(pks[0] > ids.last) end end |
#exclude(*args, &block) ⇒ Relation
Restrict a relation to not match criteria
377 378 379 |
# File 'lib/rom/sql/relation/reading.rb', line 377 def exclude(*args, &block) new(dataset.__send__(__method__, *args, &block)) end |
#exist?(*args, &block) ⇒ TrueClass, FalseClass
Checks whether a relation has at least one tuple
@example
users.where(name: 'John').exist? # => true
users.exist?(name: 'Klaus') # => false
users.exist? { name.is('klaus') } # => false
@param [Array<Object>] args Optional restrictions to filter the relation
@yield An optional block filters the relation using `where DSL`
793 794 795 |
# File 'lib/rom/sql/relation/reading.rb', line 793 def exist?(*args, &block) !where(*args, &block).limit(1).count.zero? end |
#exists(other, condition = nil) ⇒ SQL::Relation
Restrict with rows from another relation. Accepts only SQL relations and uses the EXISTS clause under the hood
878 879 880 881 |
# File 'lib/rom/sql/relation/reading.rb', line 878 def exists(other, condition = nil) join_condition = condition || associations[other.name].join_keys where(other.where(join_condition).dataset.exists) end |
#fetch(pk) ⇒ Relation
Fetch a tuple identified by the pk
37 38 39 |
# File 'lib/rom/sql/relation/reading.rb', line 37 def fetch(pk) by_pk(pk).one! end |
#first ⇒ Hash
Get first tuple from the relation
63 64 65 |
# File 'lib/rom/sql/relation/reading.rb', line 63 def first limit(1).to_a.first end |
#group(*columns) ⇒ Relation #group(*attributes) ⇒ Relation #group(*attributes, &block) ⇒ Relation
Group by specific columns
676 677 678 679 680 681 682 683 684 685 686 |
# File 'lib/rom/sql/relation/reading.rb', line 676 def group(*args, &block) if block if args.size > 0 group(*args).group_append(&block) else new(dataset.__send__(__method__, *schema.canonical.group(&block))) end else new(dataset.__send__(__method__, *schema.canonical.project(*args))) end end |
#group_and_count(*args, &block) ⇒ Relation
Group by specific columns and count by group
738 739 740 |
# File 'lib/rom/sql/relation/reading.rb', line 738 def group_and_count(*args, &block) new(dataset.__send__(__method__, *args, &block)) end |
#group_append(*columns) ⇒ Relation #group_append(*attributes) ⇒ Relation #group_append(*attributes, &block) ⇒ Relation
Group by more columns
715 716 717 718 719 720 721 722 723 724 725 |
# File 'lib/rom/sql/relation/reading.rb', line 715 def group_append(*args, &block) if block if args.size > 0 group_append(*args).group_append(&block) else new(dataset.group_append(*schema.canonical.group(&block))) end else new(dataset.group_append(*args)) end end |
#having(conditions) ⇒ Relation #having(&block) ⇒ Relation
Restrict a relation to match grouping criteria
414 415 416 417 418 419 420 |
# File 'lib/rom/sql/relation/reading.rb', line 414 def having(*args, &block) if block new(dataset.having(*args, *schema.canonical.restriction(&block))) else new(dataset.__send__(__method__, *args)) end end |
#invert ⇒ Relation
Inverts the current WHERE and HAVING clauses. If there is neither a WHERE or HAVING clause, adds a WHERE clause that is always false.
434 435 436 |
# File 'lib/rom/sql/relation/reading.rb', line 434 def invert new(dataset.invert) end |
#join(dataset, join_conditions) ⇒ Relation #join(dataset, join_conditions, options) ⇒ Relation #join(relation) ⇒ Relation Also known as: inner_join
Join with another relation using INNER JOIN
564 565 566 |
# File 'lib/rom/sql/relation/reading.rb', line 564 def join(*args, &block) __join__(__method__, *args, &block) end |
#last ⇒ Hash
Get last tuple from the relation
76 77 78 |
# File 'lib/rom/sql/relation/reading.rb', line 76 def last reverse.limit(1).first end |
#left_join(dataset, left_join_conditions) ⇒ Relation #left_join(dataset, left_join_conditions, options) ⇒ Relation #left_join(relation) ⇒ Relation
Join with another relation using LEFT OUTER JOIN
604 605 606 |
# File 'lib/rom/sql/relation/reading.rb', line 604 def left_join(*args, &block) __join__(__method__, *args, &block) end |
#limit(num) ⇒ Relation #limit(num, offset) ⇒ Relation
Limit a relation to a specific number of tuples
511 512 513 |
# File 'lib/rom/sql/relation/reading.rb', line 511 def limit(*args) new(dataset.__send__(__method__, *args)) end |
#lock(options) ⇒ SQL::Relation #lock(options) {|relation| ... } ⇒ Object
Lock rows with in the specified mode. Check out ROW_LOCK_MODES for the list of supported modes, keep in mind available lock modes heavily depend on the database type+version you’re running on.
850 851 852 853 854 855 856 857 858 859 860 |
# File 'lib/rom/sql/relation/reading.rb', line 850 def lock( = EMPTY_HASH, &block) clause = lock_clause() if block transaction do block.call(dataset.lock_style(clause).to_a) end else new(dataset.lock_style(clause)) end end |
#map(key = nil, &block) ⇒ Object
Map tuples from the relation
140 141 142 143 144 145 146 |
# File 'lib/rom/sql/relation/reading.rb', line 140 def map(key = nil, &block) if key dataset.map(key, &block) else dataset.map(&block) end end |
#max(*args) ⇒ Object
Returns a result of SQL MAX clause.
309 310 311 |
# File 'lib/rom/sql/relation/reading.rb', line 309 def max(*args) dataset.__send__(__method__, *args) end |
#min(*args) ⇒ Object
Returns a result of SQL MIN clause.
295 296 297 |
# File 'lib/rom/sql/relation/reading.rb', line 295 def min(*args) dataset.__send__(__method__, *args) end |
#offset(num) ⇒ Relation
Set offset for the relation
525 526 527 |
# File 'lib/rom/sql/relation/reading.rb', line 525 def offset(num) new(dataset.__send__(__method__, num)) end |
#order(*columns) ⇒ Relation #order(*attributes) ⇒ Relation #order(&block) ⇒ Relation
Set order for the relation
469 470 471 472 473 474 475 |
# File 'lib/rom/sql/relation/reading.rb', line 469 def order(*args, &block) if block new(dataset.order(*args, *schema.canonical.order(&block))) else new(dataset.__send__(__method__, *args, &block)) end end |
#pluck(name) ⇒ Array
Pluck values from a specific column
157 158 159 |
# File 'lib/rom/sql/relation/reading.rb', line 157 def pluck(name) map(name) end |
#prefix(name = Dry::Core::Inflector.singularize(schema.name.dataset)) ⇒ Relation
Prefix all columns in a relation
This method is intended to be used internally within a relation object
93 94 95 |
# File 'lib/rom/sql/relation/reading.rb', line 93 def prefix(name = Dry::Core::Inflector.singularize(schema.name.dataset)) schema.prefix(name).(self) end |
#qualified(table_alias = nil) ⇒ Relation
Qualifies all columns in a relation
This method is intended to be used internally within a relation object
108 109 110 |
# File 'lib/rom/sql/relation/reading.rb', line 108 def qualified(table_alias = nil) schema.qualified(table_alias).(self) end |
#qualified_columns ⇒ Array<Symbol>
Return a list of qualified column names
This method is intended to be used internally within a relation object
123 124 125 |
# File 'lib/rom/sql/relation/reading.rb', line 123 def qualified_columns schema.qualified.map(&:to_sql_name) end |
#read(sql) ⇒ SQL::Relation
Return a new relation from a raw SQL string
825 826 827 |
# File 'lib/rom/sql/relation/reading.rb', line 825 def read(sql) new(dataset.db[sql], schema: schema.empty) end |
#rename(options) ⇒ Relation
Rename columns in a relation
This method is intended to be used internally within a relation object
174 175 176 |
# File 'lib/rom/sql/relation/reading.rb', line 174 def rename() schema.rename().(self) end |
#reverse(*args, &block) ⇒ Relation
Reverse the order of the relation
485 486 487 |
# File 'lib/rom/sql/relation/reading.rb', line 485 def reverse(*args, &block) new(dataset.__send__(__method__, *args, &block)) end |
#right_join(dataset, right_join_conditions) ⇒ Relation #right_join(dataset, right_join_conditions, options) ⇒ Relation #right_join(relation) ⇒ Relation
Join with another relation using RIGHT JOIN
643 644 645 |
# File 'lib/rom/sql/relation/reading.rb', line 643 def right_join(*args, &block) __join__(__method__, *args, &block) end |
#select(*columns) ⇒ Relation #select(*attributes) ⇒ Relation #select(&block) ⇒ Relation #select(*columns, &block) ⇒ Relation Also known as: project
Select specific columns for select clause
231 232 233 |
# File 'lib/rom/sql/relation/reading.rb', line 231 def select(*args, &block) schema.project(*args, &block).(self) end |
#select_append(*args, &block) ⇒ Relation
Append specific columns to select clause
243 244 245 |
# File 'lib/rom/sql/relation/reading.rb', line 243 def select_append(*args, &block) schema.merge(schema.canonical.project(*args, &block)).(self) end |
#select_group(*args, &block) ⇒ Relation
Select and group by specific columns
753 754 755 756 |
# File 'lib/rom/sql/relation/reading.rb', line 753 def select_group(*args, &block) new_schema = schema.project(*args, &block) new_schema.(self).group(*new_schema) end |
#sum(*args) ⇒ Integer
Returns a result of SQL SUM clause.
281 282 283 |
# File 'lib/rom/sql/relation/reading.rb', line 281 def sum(*args) dataset.__send__(__method__, *args) end |
#union(relation, options = EMPTY_HASH, &block) ⇒ Object
Adds a UNION clause for relation dataset using second relation dataset
@returRelation]
774 775 776 |
# File 'lib/rom/sql/relation/reading.rb', line 774 def union(relation, = EMPTY_HASH, &block) new(dataset.__send__(__method__, relation.dataset, , &block)) end |
#unique?(criteria) ⇒ TrueClass, FalseClass
Return if a restricted relation has 0 tuples
811 812 813 |
# File 'lib/rom/sql/relation/reading.rb', line 811 def unique?(criteria) !exist?(criteria) end |
#where(conditions) ⇒ Relation #where(conditions, &block) ⇒ Relation #where(&block) ⇒ Relation
Restrict a relation to match criteria
355 356 357 358 359 360 361 362 363 364 365 |
# File 'lib/rom/sql/relation/reading.rb', line 355 def where(*args, &block) if block where(*args).where(schema.canonical.restriction(&block)) elsif args.size == 1 && args[0].is_a?(Hash) new(dataset.where(coerce_conditions(args[0]))) elsif !args.empty? new(dataset.where(*args)) else self end end |