Methods

Included Modules

Class Index [+]

Quicksearch

Sequel::Dataset

Dataset class for MySQL datasets accessed via the native driver.


Dataset class for PostgreSQL datasets that use the pg, postgres, or postgres-pr driver.


A dataset represents an SQL query, or more generally, an abstract set of rows in the database. Datasets can be used to create, retrieve, update and delete records.

Query results are always retrieved on demand, so a dataset can be kept around and reused indefinitely (datasets never cache results):

  my_posts = DB[:posts].filter(:author => 'david') # no records are retrieved
  my_posts.all # records are retrieved
  my_posts.all # records are retrieved again

Most dataset methods return modified copies of the dataset (functional style), so you can reuse different datasets to access data:

  posts = DB[:posts]
  davids_posts = posts.filter(:author => 'david')
  old_posts = posts.filter('stamp < ?', Date.today - 7)
  davids_old_posts = davids_posts.filter('stamp < ?', Date.today - 7)

Datasets are Enumerable objects, so they can be manipulated using any of the Enumerable methods, such as map, inject, etc.

For more information, see the "Dataset Basics" guide.

Constants

DatasetClass
DatasetClass
PREPARED_ARG_PLACEHOLDER
DatasetClass
APOS
PREPARED_ARG_PLACEHOLDER
ACTION_METHODS

Action methods defined by Sequel that execute code on the database.

NOTIMPL_MSG
ARRAY_ACCESS_ERROR_MSG
ARG_BLOCK_ERROR_MSG
IMPORT_ERROR_MSG
PREPARED_ARG_PLACEHOLDER
COLUMN_CHANGE_OPTS

The dataset options that require the removal of cached columns if changed.

NON_SQL_OPTIONS

Which options don’t affect the SQL generation. Used by simple_select_all? to determine if this is a simple SELECT * FROM table.

CONDITIONED_JOIN_TYPES

These symbols have _join methods created (e.g. inner_join) that call join_table with the symbol, passing along the arguments and block from the method call.

UNCONDITIONED_JOIN_TYPES

These symbols have _join methods created (e.g. natural_join) that call join_table with the symbol. They only accept a single table argument which is passed to join_table, and they raise an error if called with a block.

JOIN_METHODS

All methods that return modified datasets with a joined table added.

QUERY_METHODS

Methods that return modified datasets

WILDCARD
ALL
AND_SEPARATOR
APOS
APOS_RE
ARRAY_EMPTY
AS
ASC
BOOL_FALSE
BOOL_TRUE
BRACKET_CLOSE
BRACKET_OPEN
CASE_ELSE
CASE_END
CASE_OPEN
CASE_THEN
CASE_WHEN
CAST_OPEN
COLUMN_REF_RE1
COLUMN_REF_RE2
COLUMN_REF_RE3
COMMA
COMMA_SEPARATOR
CONDITION_FALSE
CONDITION_TRUE
COUNT_FROM_SELF_OPTS
COUNT_OF_ALL_AS_COUNT
DATASET_ALIAS_BASE_NAME
DEFAULT
DEFAULT_VALUES
DELETE
DELETE_CLAUSE_METHODS
DESC
DISTINCT
DOT
DOUBLE_APOS
DOUBLE_QUOTE
EQUAL
EXTRACT
EXISTS
FOR_UPDATE
FORMAT_DATE
FORMAT_DATE_STANDARD
FORMAT_OFFSET
FORMAT_TIMESTAMP_RE
FORMAT_TIMESTAMP_USEC
FORMAT_USEC
FRAME_ALL
FRAME_ROWS
FROM
FUNCTION_EMPTY
GROUP_BY
HAVING
INSERT
INSERT_CLAUSE_METHODS
INTO
IS_LITERALS
IS_OPERATORS
LIMIT
N_ARITY_OPERATORS
NOT_SPACE
NULL
NULLS_FIRST
NULLS_LAST
OFFSET
ON
ON_PAREN
ORDER_BY
ORDER_BY_NS
OVER
PAREN_CLOSE
PAREN_OPEN
PAREN_SPACE_OPEN
PARTITION_BY
QUALIFY_KEYS
QUESTION_MARK
QUESTION_MARK_RE
QUOTE
QUOTE_RE
RETURNING
SELECT
SELECT_CLAUSE_METHODS
SET
SPACE
SQL_WITH
SPACE_WITH
TILDE
TIMESTAMP_FORMAT
STANDARD_TIMESTAMP_FORMAT
TWO_ARITY_OPERATORS
UNDERSCORE
UPDATE
UPDATE_CLAUSE_METHODS
USING
VALUES
V190
WHERE
PUBLIC_APPEND_METHODS
PRIVATE_APPEND_METHODS
MUTATION_METHODS

All methods that should have a ! method added that modifies the receiver.

Attributes

db[RW]

The database related to this dataset. This is the Database instance that will execute all of this dataset’s queries.

opts[RW]

The hash of options for this dataset, keys are symbols.

identifier_input_method[W]

Set the method to call on identifiers going into the database for this dataset

identifier_output_method[W]

Set the method to call on identifiers coming the database for this dataset

quote_identifiers[W]

Whether to quote identifiers for this dataset

row_proc[RW]

The row_proc for this database, should be any object that responds to call with a single hash argument and returns the object you want # to return.

Public Class Methods

clause_methods(type, clauses) click to toggle source

Given a type (e.g. select) and an array of clauses, return an array of methods to call to build the SQL string.

     # File lib/sequel/dataset/sql.rb, line 181
181:     def self.clause_methods(type, clauses)
182:       clauses.map{|clause| :"#{type}_#{clause}_sql"}.freeze
183:     end
def_append_methods(meths) click to toggle source
     # File lib/sequel/dataset/sql.rb, line 326
326:     def self.def_append_methods(meths)
327:       meths.each do |meth|
328:         class_eval(          def #{meth}(*args, &block)            s = ''            #{meth}_append(s, *args, &block)            s          end, __FILE__, __LINE__ + 1)
329:       end
330:     end
def_mutation_method(*meths) click to toggle source

Setup mutation (e.g. filter!) methods. These operate the same as the non-! methods, but replace the options of the current dataset with the options of the resulting dataset.

    # File lib/sequel/dataset/mutation.rb, line 14
14:     def self.def_mutation_method(*meths)
15:       meths.each do |meth|
16:         class_eval("def #{meth}!(*args, &block); mutation_method(:#{meth}, *args, &block) end", __FILE__, __LINE__)
17:       end
18:     end
introspect_all_columns() click to toggle source

Enable column introspection for every dataset.

    # File lib/sequel/extensions/columns_introspection.rb, line 56
56:     def self.introspect_all_columns
57:       include ColumnsIntrospection
58:       remove_method(:columns) if instance_methods(false).map{|x| x.to_s}.include?('columns')
59:     end
new(db, opts = nil) click to toggle source

Constructs a new Dataset instance with an associated database and options. Datasets are usually constructed by invoking the Database#[] method:

  DB[:posts]

Sequel::Dataset is an abstract class that is not useful by itself. Each database adapter provides a subclass of Sequel::Dataset, and has the Database#dataset method return an instance of that subclass.

    # File lib/sequel/dataset/misc.rb, line 28
28:     def initialize(db, opts = nil)
29:       @db = db
30:       @opts = opts || {}
31:     end

Public Instance Methods

<<(arg) click to toggle source

Inserts the given argument into the database. Returns self so it can be used safely when chaining:

  DB[:items] << {:id=>0, :name=>'Zero'} << DB[:old_items].select(:id, name)
    # File lib/sequel/dataset/actions.rb, line 22
22:     def <<(arg)
23:       insert(arg)
24:       self
25:     end
==(o) click to toggle source

Define a hash value such that datasets with the same DB, opts, and SQL will be consider equal.

    # File lib/sequel/dataset/misc.rb, line 35
35:     def ==(o)
36:       o.is_a?(self.class) && db == o.db  && opts == o.opts && sql == o.sql
37:     end
[](*conditions) click to toggle source

Returns the first record matching the conditions. Examples:

  DB[:table][:id=>1] # SELECT * FROM table WHERE (id = 1) LIMIT 1
  # => {:id=1}
    # File lib/sequel/dataset/actions.rb, line 31
31:     def [](*conditions)
32:       raise(Error, ARRAY_ACCESS_ERROR_MSG) if (conditions.length == 1 and conditions.first.is_a?(Integer)) or conditions.length == 0
33:       first(*conditions)
34:     end
[]=(conditions, values) click to toggle source

Update all records matching the conditions with the values specified. Returns the number of rows affected.

  DB[:table][:id=>1] = {:id=>2} # UPDATE table SET id = 2 WHERE id = 1
  # => 1 # number of rows affected
    # File lib/sequel/dataset/actions.rb, line 41
41:     def []=(conditions, values)
42:       filter(conditions).update(values)
43:     end
add_graph_aliases(graph_aliases) click to toggle source

Adds the given graph aliases to the list of graph aliases to use, unlike set_graph_aliases, which replaces the list (the equivalent of select_more when graphing). See set_graph_aliases.

  DB[:table].add_graph_aliases(:some_alias=>[:table, :column])
  # SELECT ..., table.column AS some_alias
  # => {:table=>{:column=>some_alias_value, ...}, ...}
    # File lib/sequel/dataset/graph.rb, line 17
17:     def add_graph_aliases(graph_aliases)
18:       columns, graph_aliases = graph_alias_columns(graph_aliases)
19:       ds = select_more(*columns)
20:       ds.opts[:graph_aliases] = (ds.opts[:graph_aliases] || (ds.opts[:graph][:column_aliases] rescue {}) || {}).merge(graph_aliases)
21:       ds
22:     end
aliased_expression_sql_append(sql, ae) click to toggle source

SQL fragment for AliasedExpression

     # File lib/sequel/dataset/sql.rb, line 341
341:     def aliased_expression_sql_append(sql, ae)
342:       literal_append(sql, ae.expression)
343:       as_sql_append(sql, ae.aliaz)
344:     end
all(&block) click to toggle source

Returns an array with all records in the dataset. If a block is given, the array is iterated over after all items have been loaded.

  DB[:table].all # SELECT * FROM table
  # => [{:id=>1, ...}, {:id=>2, ...}, ...]

  # Iterate over all rows in the table
  DB[:table].all{|row| p row}
    # File lib/sequel/dataset/actions.rb, line 53
53:     def all(&block)
54:       a = []
55:       each{|r| a << r}
56:       post_load(a)
57:       a.each(&block) if block
58:       a
59:     end
and(*cond, &block) click to toggle source

Adds an further filter to an existing filter using AND. If no filter exists an error is raised. This method is identical to # except it expects an existing filter.

  DB[:table].filter(:a).and(:b) # SELECT * FROM table WHERE a AND b
    # File lib/sequel/dataset/query.rb, line 45
45:     def and(*cond, &block)
46:       raise(InvalidOperation, "No existing filter found.") unless @opts[:having] || @opts[:where]
47:       filter(*cond, &block)
48:     end
array_sql_append(sql, a) click to toggle source

SQL fragment for Array

     # File lib/sequel/dataset/sql.rb, line 347
347:     def array_sql_append(sql, a)
348:       if a.empty?
349:         sql << ARRAY_EMPTY
350:       else
351:         sql << PAREN_OPEN
352:         expression_list_append(sql, a)
353:         sql << PAREN_CLOSE
354:       end
355:     end
avg(column) click to toggle source

Returns the average value for the given column.

  DB[:table].avg(:number) # SELECT avg(number) FROM table LIMIT 1
  # => 3
    # File lib/sequel/dataset/actions.rb, line 65
65:     def avg(column)
66:       aggregate_dataset.get{avg(column)}
67:     end
bind(bind_vars={}) click to toggle source

Set the bind variables to use for the call. If bind variables have already been set for this dataset, they are updated with the contents of bind_vars.

  DB[:table].filter(:id=>:$id).bind(:id=>1).call(:first)
  # SELECT * FROM table WHERE id = ? LIMIT 1 -- (1)
  # => {:id=>1}
     # File lib/sequel/dataset/prepared_statements.rb, line 217
217:     def bind(bind_vars={})
218:       clone(:bind_vars=>@opts[:bind_vars] ? @opts[:bind_vars].merge(bind_vars) : bind_vars)
219:     end
boolean_constant_sql_append(sql, constant) click to toggle source

SQL fragment for BooleanConstants

     # File lib/sequel/dataset/sql.rb, line 358
358:     def boolean_constant_sql_append(sql, constant)
359:       if (constant == true || constant == false) && !supports_where_true?
360:         sql << (constant == true ? CONDITION_TRUE : CONDITION_FALSE)
361:       else
362:         literal_append(sql, constant)
363:       end
364:     end
call(type, bind_variables={}, *values, &block) click to toggle source

For the given type (:select, :first, :insert, :insert_select, :update, or :delete), run the sql with the bind variables specified in the hash. values is a hash passed to insert or update (if one of those types is used), which may contain placeholders.

  DB[:table].filter(:id=>:$id).call(:first, :id=>1)
  # SELECT * FROM table WHERE id = ? LIMIT 1 -- (1)
  # => {:id=>1}
     # File lib/sequel/dataset/prepared_statements.rb, line 228
228:     def call(type, bind_variables={}, *values, &block)
229:       prepare(type, nil, *values).call(bind_variables, &block)
230:     end
call(type, bind_vars={}, *values, &block) click to toggle source

Execute the given type of statement with the hash of values.

     # File lib/sequel/adapters/postgres.rb, line 673
673:         def call(type, bind_vars={}, *values, &block)
674:           ps = to_prepared_statement(type, values)
675:           ps.extend(BindArgumentMethods)
676:           ps.call(bind_vars, &block)
677:         end
call(type, bind_vars={}, *values, &block) click to toggle source

Execute the given type of statement with the hash of values.

     # File lib/sequel/adapters/oracle.rb, line 367
367:       def call(type, bind_vars={}, *values, &block)
368:         ps = to_prepared_statement(type, values)
369:         ps.extend(BindArgumentMethods)
370:         ps.call(bind_vars, &block)
371:       end
case_expression_sql_append(sql, ce) click to toggle source

SQL fragment for CaseExpression

     # File lib/sequel/dataset/sql.rb, line 367
367:     def case_expression_sql_append(sql, ce)
368:       sql << CASE_OPEN
369:       if ce.expression?
370:         sql << SPACE
371:         literal_append(sql, ce.expression)
372:       end
373:       w = CASE_WHEN
374:       t = CASE_THEN
375:       ce.conditions.each do |c,r|
376:         sql << w
377:         literal_append(sql, c)
378:         sql << t
379:         literal_append(sql, r)
380:       end
381:       sql << CASE_ELSE
382:       literal_append(sql, ce.default)
383:       sql << CASE_END
384:     end
cast_sql_append(sql, expr, type) click to toggle source

SQL fragment for the SQL CAST expression

     # File lib/sequel/dataset/sql.rb, line 387
387:     def cast_sql_append(sql, expr, type)
388:       sql << CAST_OPEN
389:       literal_append(sql, expr)
390:       sql << AS << db.cast_type_literal(type).to_s
391:       sql << PAREN_CLOSE
392:     end
clone(opts = {}) click to toggle source

Returns a new clone of the dataset with with the given options merged. If the options changed include options in COLUMN_CHANGE_OPTS, the cached columns are deleted. This method should generally not be called directly by user code.

    # File lib/sequel/dataset/query.rb, line 54
54:     def clone(opts = {})
55:       c = super()
56:       c.opts = @opts.merge(opts)
57:       c.instance_variable_set(:@columns, nil) if opts.keys.any?{|o| COLUMN_CHANGE_OPTS.include?(o)}
58:       c
59:     end
column_all_sql_append(sql, ca) click to toggle source

SQL fragment for specifying all columns in a given table

     # File lib/sequel/dataset/sql.rb, line 395
395:     def column_all_sql_append(sql, ca)
396:       qualified_identifier_sql_append(sql, ca.table, WILDCARD)
397:     end
columns() click to toggle source

Returns the columns in the result set in order as an array of symbols. If the columns are currently cached, returns the cached value. Otherwise, a SELECT query is performed to retrieve a single row in order to get the columns.

If you are looking for all columns for a single table and maybe some information about each column (e.g. database type), see Database#schema.

  DB[:table].columns
  # => [:id, :name]
    # File lib/sequel/dataset/actions.rb, line 78
78:     def columns
79:       return @columns if @columns
80:       ds = unfiltered.unordered.clone(:distinct => nil, :limit => 1, :offset=>nil)
81:       ds.each{break}
82:       @columns = ds.instance_variable_get(:@columns)
83:       @columns || []
84:     end
columns!() click to toggle source

Ignore any cached column information and perform a query to retrieve a row in order to get the columns.

  DB[:table].columns!
  # => [:id, :name]
    # File lib/sequel/dataset/actions.rb, line 91
91:     def columns!
92:       @columns = nil
93:       columns
94:     end
columns_without_introspection() click to toggle source
Alias for: columns
complex_expression_sql_append(sql, op, args) click to toggle source

SQL fragment for the complex expression.

     # File lib/sequel/dataset/sql.rb, line 400
400:     def complex_expression_sql_append(sql, op, args)
401:       case op
402:       when *IS_OPERATORS
403:         r = args.at(1)
404:         if r.nil? || supports_is_true?
405:           raise(InvalidOperation, 'Invalid argument used for IS operator') unless v = IS_LITERALS[r]
406:           sql << PAREN_OPEN
407:           literal_append(sql, args.at(0))
408:           sql << SPACE << op.to_s << SPACE
409:           sql << v << PAREN_CLOSE
410:         elsif op == :IS
411:           complex_expression_sql_append(sql, :"=", args)
412:         else
413:           complex_expression_sql_append(sql, :OR, [SQL::BooleanExpression.new(:"!=", *args), SQL::BooleanExpression.new(:IS, args.at(0), nil)])
414:         end
415:       when :IN, :"NOT IN"
416:         cols = args.at(0)
417:         vals = args.at(1)
418:         col_array = true if cols.is_a?(Array)
419:         if vals.is_a?(Array)
420:           val_array = true
421:           empty_val_array = vals == []
422:         end
423:         if empty_val_array
424:           literal_append(sql, empty_array_value(op, cols))
425:         elsif col_array
426:           if !supports_multiple_column_in?
427:             if val_array
428:               expr = SQL::BooleanExpression.new(:OR, *vals.to_a.map{|vs| SQL::BooleanExpression.from_value_pairs(cols.to_a.zip(vs).map{|c, v| [c, v]})})
429:               literal_append(sql, op == :IN ? expr : ~expr)
430:             else
431:               old_vals = vals
432:               vals = vals.naked if vals.is_a?(Sequel::Dataset)
433:               vals = vals.to_a
434:               val_cols = old_vals.columns
435:               complex_expression_sql_append(sql, op, [cols, vals.map!{|x| x.values_at(*val_cols)}])
436:             end
437:           else
438:             # If the columns and values are both arrays, use array_sql instead of
439:             # literal so that if values is an array of two element arrays, it
440:             # will be treated as a value list instead of a condition specifier.
441:             sql << PAREN_OPEN
442:             literal_append(sql, cols)
443:             sql << SPACE << op.to_s << SPACE
444:             if val_array
445:               array_sql_append(sql, vals)
446:             else
447:               literal_append(sql, vals)
448:             end
449:             sql << PAREN_CLOSE
450:           end
451:         else
452:           sql << PAREN_OPEN
453:           literal_append(sql, cols)
454:           sql << SPACE << op.to_s << SPACE
455:           literal_append(sql, vals)
456:           sql << PAREN_CLOSE
457:         end
458:       when *TWO_ARITY_OPERATORS
459:         sql << PAREN_OPEN
460:         literal_append(sql, args.at(0))
461:         sql << SPACE << op.to_s << SPACE
462:         literal_append(sql, args.at(1))
463:         sql << PAREN_CLOSE
464:       when *N_ARITY_OPERATORS
465:         sql << PAREN_OPEN
466:         c = false
467:         op_str = " #{op} "
468:         args.each do |a|
469:           sql << op_str if c
470:           literal_append(sql, a)
471:           c ||= true
472:         end
473:         sql << PAREN_CLOSE
474:       when :NOT
475:         sql << NOT_SPACE
476:         literal_append(sql, args.at(0))
477:       when :NOOP
478:         literal_append(sql, args.at(0))
479:       when :'B~'
480:         sql << TILDE
481:         literal_append(sql, args.at(0))
482:       when :extract
483:         sql << EXTRACT << args.at(0).to_s << FROM
484:         literal_append(sql, args.at(1))
485:         sql << PAREN_CLOSE
486:       else
487:         raise(InvalidOperation, "invalid operator #{op}")
488:       end
489:     end
constant_sql_append(sql, constant) click to toggle source

SQL fragment for constants

     # File lib/sequel/dataset/sql.rb, line 492
492:     def constant_sql_append(sql, constant)
493:       sql << constant.to_s
494:     end
count() click to toggle source

Returns the number of records in the dataset.

  DB[:table].count # SELECT COUNT(*) AS count FROM table LIMIT 1
  # => 3
     # File lib/sequel/dataset/actions.rb, line 100
100:     def count
101:       aggregate_dataset.get{COUNT(:*){}.as(count)}.to_i
102:     end
def_mutation_method(*meths) click to toggle source

Add a mutation method to this dataset instance.

    # File lib/sequel/dataset/mutation.rb, line 37
37:     def def_mutation_method(*meths)
38:       meths.each do |meth|
39:         instance_eval("def #{meth}!(*args, &block); mutation_method(:#{meth}, *args, &block) end", __FILE__, __LINE__)
40:       end
41:     end
delete(&block) click to toggle source

Deletes the records in the dataset. The returned value should be number of records deleted, but that is adapter dependent.

  DB[:table].delete # DELETE * FROM table
  # => 3
     # File lib/sequel/dataset/actions.rb, line 109
109:     def delete(&block)
110:       sql = delete_sql
111:       if uses_returning?(:delete)
112:         returning_fetch_rows(sql, &block)
113:       else
114:         execute_dui(sql)
115:       end
116:     end
delete_sql() click to toggle source

Returns a DELETE SQL query string. See delete.

  dataset.filter{|o| o.price >= 100}.delete_sql
  # => "DELETE FROM items WHERE (price >= 100)"
    # File lib/sequel/dataset/sql.rb, line 12
12:     def delete_sql
13:       return static_sql(opts[:sql]) if opts[:sql]
14:       check_modification_allowed!
15:       clause_sql(:delete)
16:     end
distinct(*args) click to toggle source

Returns a copy of the dataset with the SQL DISTINCT clause. The DISTINCT clause is used to remove duplicate rows from the output. If arguments are provided, uses a DISTINCT ON clause, in which case it will only be distinct on those columns, instead of all returned columns. Raises an error if arguments are given and DISTINCT ON is not supported.

 DB[:items].distinct # SQL: SELECT DISTINCT * FROM items
 DB[:items].order(:id).distinct(:id) # SQL: SELECT DISTINCT ON (id) * FROM items ORDER BY id
    # File lib/sequel/dataset/query.rb, line 70
70:     def distinct(*args)
71:       raise(InvalidOperation, "DISTINCT ON not supported") if !args.empty? && !supports_distinct_on?
72:       clone(:distinct => args)
73:     end
each() click to toggle source

Iterates over the records in the dataset as they are yielded from the database adapter, and returns self.

  DB[:table].each{|row| p row} # SELECT * FROM table

Note that this method is not safe to use on many adapters if you are running additional queries inside the provided block. If you are running queries inside the block, you should use all instead of each for the outer queries, or use a separate thread or shard inside each:

     # File lib/sequel/dataset/actions.rb, line 127
127:     def each
128:       if @opts[:graph]
129:         graph_each{|r| yield r}
130:       elsif row_proc = @row_proc
131:         fetch_rows(select_sql){|r| yield row_proc.call(r)}
132:       else
133:         fetch_rows(select_sql){|r| yield r}
134:       end
135:       self
136:     end
each_page(page_size) click to toggle source

Yields a paginated dataset for each page and returns the receiver. Does a count to find the total number of records for this dataset.

    # File lib/sequel/extensions/pagination.rb, line 20
20:     def each_page(page_size)
21:       raise(Error, "You cannot paginate a dataset that already has a limit") if @opts[:limit]
22:       record_count = count
23:       total_pages = (record_count / page_size.to_f).ceil
24:       (1..total_pages).each{|page_no| yield paginate(page_no, page_size, record_count)}
25:       self
26:     end
each_server() click to toggle source

Yield a dataset for each server in the connection pool that is tied to that server. Intended for use in sharded environments where all servers need to be modified with the same data:

  DB[:configs].where(:key=>'setting').each_server{|ds| ds.update(:value=>'new_value')}
    # File lib/sequel/dataset/misc.rb, line 49
49:     def each_server
50:       db.servers.each{|s| yield server(s)}
51:     end
empty?() click to toggle source

Returns true if no records exist in the dataset, false otherwise

  DB[:table].empty? # SELECT 1 AS one FROM table LIMIT 1
  # => false
     # File lib/sequel/dataset/actions.rb, line 142
142:     def empty?
143:       get(Sequel::SQL::AliasedExpression.new(1, :one)).nil?
144:     end
eql?(o) click to toggle source

Alias for ==

    # File lib/sequel/dataset/misc.rb, line 40
40:     def eql?(o)
41:       self == o
42:     end
except(dataset, opts={}) click to toggle source

Adds an EXCEPT clause using a second dataset object. An EXCEPT compound dataset returns all rows in the current dataset that are not in the given dataset. Raises an InvalidOperation if the operation is not supported. Options:

:alias

Use the given value as the from_self alias

:all

Set to true to use EXCEPT ALL instead of EXCEPT, so duplicate rows can occur

:from_self

Set to false to not wrap the returned dataset in a from_self, use with care.

  DB[:items].except(DB[:other_items])
  # SELECT * FROM (SELECT * FROM items EXCEPT SELECT * FROM other_items) AS t1

  DB[:items].except(DB[:other_items], :all=>true, :from_self=>false)
  # SELECT * FROM items EXCEPT ALL SELECT * FROM other_items

  DB[:items].except(DB[:other_items], :alias=>:i)
  # SELECT * FROM (SELECT * FROM items EXCEPT SELECT * FROM other_items) AS i
    # File lib/sequel/dataset/query.rb, line 92
92:     def except(dataset, opts={})
93:       opts = {:all=>opts} unless opts.is_a?(Hash)
94:       raise(InvalidOperation, "EXCEPT not supported") unless supports_intersect_except?
95:       raise(InvalidOperation, "EXCEPT ALL not supported") if opts[:all] && !supports_intersect_except_all?
96:       compound_clone(:except, dataset, opts)
97:     end
exclude(*cond, &block) click to toggle source

Performs the inverse of Dataset#filter. Note that if you have multiple filter conditions, this is not the same as a negation of all conditions.

  DB[:items].exclude(:category => 'software')
  # SELECT * FROM items WHERE (category != 'software')
  
  DB[:items].exclude(:category => 'software', :id=>3)
  # SELECT * FROM items WHERE ((category != 'software') OR (id != 3))
     # File lib/sequel/dataset/query.rb, line 107
107:     def exclude(*cond, &block)
108:       _filter_or_exclude(true, @opts[:having] ? :having : :where, *cond, &block)
109:     end
exclude_having(*cond, &block) click to toggle source

Inverts the given conditions and adds them to the HAVING clause.

  DB[:items].select_group(:name).exclude_having{count(name) < 2}
  # SELECT name FROM items GROUP BY name HAVING (count(name) >= 2)
     # File lib/sequel/dataset/query.rb, line 115
115:     def exclude_having(*cond, &block)
116:       _filter_or_exclude(true, :having, *cond, &block)
117:     end
exclude_where(*cond, &block) click to toggle source

Inverts the given conditions and adds them to the WHERE clause.

  DB[:items].select_group(:name).exclude_where(:category => 'software')
  # SELECT * FROM items WHERE (category != 'software')

  DB[:items].select_group(:name).
    exclude_having{count(name) < 2}.
    exclude_where(:category => 'software')
  # SELECT name FROM items WHERE (category != 'software')
  # GROUP BY name HAVING (count(name) >= 2)
     # File lib/sequel/dataset/query.rb, line 129
129:     def exclude_where(*cond, &block)
130:       _filter_or_exclude(true, :where, *cond, &block)
131:     end
exists() click to toggle source

Returns an EXISTS clause for the dataset as a LiteralString.

  DB.select(1).where(DB[:items].exists)
  # SELECT 1 WHERE (EXISTS (SELECT * FROM items))
    # File lib/sequel/dataset/sql.rb, line 22
22:     def exists
23:       SQL::PlaceholderLiteralString.new(EXISTS, [self], true)
24:     end
fetch_rows(sql) click to toggle source

Yield all rows matching this dataset. If the dataset is set to split multiple statements, yield arrays of hashes one per statement instead of yielding results for all statements as hashes.

     # File lib/sequel/adapters/mysql.rb, line 295
295:       def fetch_rows(sql)
296:         execute(sql) do |r|
297:           i = 1
298:           cps = db.conversion_procs
299:           cols = r.fetch_fields.map do |f| 
300:             # Pretend tinyint is another integer type if its length is not 1, to
301:             # avoid casting to boolean if Sequel::MySQL.convert_tinyint_to_bool
302:             # is set.
303:             type_proc = f.type == 1 && f.length != 1 ? cps[2] : cps[f.type]
304:             [output_identifier(f.name), type_proc, i+=1]
305:           end
306:           @columns = cols.map{|c| c.first}
307:           if opts[:split_multiple_result_sets]
308:             s = []
309:             yield_rows(r, cols){|h| s << h}
310:             yield s
311:           else
312:             yield_rows(r, cols){|h| yield h}
313:           end
314:         end
315:         self
316:       end
fetch_rows(sql) click to toggle source

Executes a select query and fetches records, yielding each record to the supplied block. The yielded records should be hashes with symbol keys. This method should probably should not be called by user code, use each instead.

     # File lib/sequel/dataset/actions.rb, line 150
150:     def fetch_rows(sql)
151:       raise NotImplemented, NOTIMPL_MSG
152:     end
fetch_rows(sql) click to toggle source
     # File lib/sequel/adapters/oracle.rb, line 373
373:       def fetch_rows(sql)
374:         execute(sql) do |cursor|
375:           offset = @opts[:offset]
376:           rn = row_number_column
377:           cps = db.conversion_procs
378:           cols = columns = cursor.get_col_names.map{|c| output_identifier(c)}
379:           metadata = cursor.column_metadata
380:           cm = cols.zip(metadata).map{|c, m| [c, cps[m.data_type]]}
381:           columns = cols.reject{|x| x == rn} if offset
382:           @columns = columns
383:           while r = cursor.fetch
384:             row = {}
385:             r.zip(cm).each{|v, (c, cp)| row[c] = ((v && cp) ? cp.call(v) : v)}
386:             row.delete(rn) if offset
387:             yield row
388:           end
389:         end
390:         self
391:       end
fetch_rows(sql) click to toggle source

Yield all rows returned by executing the given SQL and converting the types.

     # File lib/sequel/adapters/postgres.rb, line 564
564:       def fetch_rows(sql)
565:         return cursor_fetch_rows(sql){|h| yield h} if @opts[:cursor]
566:         execute(sql){|res| yield_hash_rows(res, fetch_rows_set_cols(res)){|h| yield h}}
567:       end
filter(*cond, &block) click to toggle source

Returns a copy of the dataset with the given conditions imposed upon it. If the query already has a HAVING clause, then the conditions are imposed in the HAVING clause. If not, then they are imposed in the WHERE clause.

filter accepts the following argument types:

  • Hash - list of equality/inclusion expressions

  • Array - depends:

    • If first member is a string, assumes the rest of the arguments are parameters and interpolates them into the string.

    • If all members are arrays of length two, treats the same way as a hash, except it allows for duplicate keys to be specified.

    • Otherwise, treats each argument as a separate condition.

  • String - taken literally

  • Symbol - taken as a boolean column argument (e.g. WHERE active)

  • Sequel::SQL::BooleanExpression - an existing condition expression, probably created using the Sequel expression filter DSL.

filter also takes a block, which should return one of the above argument types, and is treated the same way. This block yields a virtual row object, which is easy to use to create identifiers and functions. For more details on the virtual row support, see the "Virtual Rows" guide

If both a block and regular argument are provided, they get ANDed together.

Examples:

  DB[:items].filter(:id => 3)
  # SELECT * FROM items WHERE (id = 3)

  DB[:items].filter('price < ?', 100)
  # SELECT * FROM items WHERE price < 100

  DB[:items].filter([[:id, [1,2,3]], [:id, 0..10]])
  # SELECT * FROM items WHERE ((id IN (1, 2, 3)) AND ((id >= 0) AND (id <= 10)))

  DB[:items].filter('price < 100')
  # SELECT * FROM items WHERE price < 100

  DB[:items].filter(:active)
  # SELECT * FROM items WHERE :active

  DB[:items].filter{price < 100}
  # SELECT * FROM items WHERE (price < 100)

Multiple filter calls can be chained for scoping:

  software = dataset.filter(:category => 'software').filter{price < 100}
  # SELECT * FROM items WHERE ((category = 'software') AND (price < 100))

See the the "Dataset Filtering" guide for more examples and details.

     # File lib/sequel/dataset/query.rb, line 185
185:     def filter(*cond, &block)
186:       _filter(@opts[:having] ? :having : :where, *cond, &block)
187:     end
first(*args, &block) click to toggle source

If a integer argument is given, it is interpreted as a limit, and then returns all matching records up to that limit. If no argument is passed, it returns the first matching record. If any other type of argument(s) is passed, it is given to filter and the first matching record is returned. If a block is given, it is used to filter the dataset before returning anything. Examples:

  DB[:table].first # SELECT * FROM table LIMIT 1
  # => {:id=>7}

  DB[:table].first(2) # SELECT * FROM table LIMIT 2
  # => [{:id=>6}, {:id=>4}]

  DB[:table].first(:id=>2) # SELECT * FROM table WHERE (id = 2) LIMIT 1
  # => {:id=>2}

  DB[:table].first("id = 3") # SELECT * FROM table WHERE (id = 3) LIMIT 1
  # => {:id=>3}

  DB[:table].first("id = ?", 4) # SELECT * FROM table WHERE (id = 4) LIMIT 1
  # => {:id=>4}

  DB[:table].first{id > 2} # SELECT * FROM table WHERE (id > 2) LIMIT 1
  # => {:id=>5}

  DB[:table].first("id > ?", 4){id < 6} # SELECT * FROM table WHERE ((id > 4) AND (id < 6)) LIMIT 1
  # => {:id=>5}

  DB[:table].first(2){id < 2} # SELECT * FROM table WHERE (id < 2) LIMIT 2
  # => [{:id=>1}]
     # File lib/sequel/dataset/actions.rb, line 184
184:     def first(*args, &block)
185:       ds = block ? filter(&block) : self
186: 
187:       if args.empty?
188:         ds.single_record
189:       else
190:         args = (args.size == 1) ? args.first : args
191:         if Integer === args
192:           ds.limit(args).all
193:         else
194:           ds.filter(args).single_record
195:         end
196:       end
197:     end
first_source() click to toggle source

Alias of first_source_alias

    # File lib/sequel/dataset/misc.rb, line 54
54:     def first_source
55:       first_source_alias
56:     end
first_source_alias() click to toggle source

The first source (primary table) for this dataset. If the dataset doesn’t have a table, raises an Error. If the table is aliased, returns the aliased name.

  DB[:table].first_source_alias
  # => :table

  DB[:table___t].first_source_alias
  # => :t
    # File lib/sequel/dataset/misc.rb, line 66
66:     def first_source_alias
67:       source = @opts[:from]
68:       if source.nil? || source.empty?
69:         raise Error, 'No source specified for query'
70:       end
71:       case s = source.first
72:       when SQL::AliasedExpression
73:         s.aliaz
74:       when Symbol
75:         sch, table, aliaz = split_symbol(s)
76:         aliaz ? aliaz.to_sym : s
77:       else
78:         s
79:       end
80:     end
first_source_table() click to toggle source

The first source (primary table) for this dataset. If the dataset doesn’t have a table, raises an error. If the table is aliased, returns the original table, not the alias

  DB[:table].first_source_table
  # => :table

  DB[:table___t].first_source_table
  # => :table
     # File lib/sequel/dataset/misc.rb, line 91
 91:     def first_source_table
 92:       source = @opts[:from]
 93:       if source.nil? || source.empty?
 94:         raise Error, 'No source specified for query'
 95:       end
 96:       case s = source.first
 97:       when SQL::AliasedExpression
 98:         s.expression
 99:       when Symbol
100:         sch, table, aliaz = split_symbol(s)
101:         aliaz ? (sch ? SQL::QualifiedIdentifier.new(sch, table) : table.to_sym) : s
102:       else
103:         s
104:       end
105:     end
for_update() click to toggle source

Returns a cloned dataset with a :update lock style.

  DB[:table].for_update # SELECT * FROM table FOR UPDATE
     # File lib/sequel/dataset/query.rb, line 192
192:     def for_update
193:       lock_style(:update)
194:     end
from(*source) click to toggle source

Returns a copy of the dataset with the source changed. If no source is given, removes all tables. If multiple sources are given, it is the same as using a CROSS JOIN (cartesian product) between all tables.

  DB[:items].from # SQL: SELECT *
  DB[:items].from(:blah) # SQL: SELECT * FROM blah
  DB[:items].from(:blah, :foo) # SQL: SELECT * FROM blah, foo
     # File lib/sequel/dataset/query.rb, line 203
203:     def from(*source)
204:       table_alias_num = 0
205:       sources = []
206:       ctes = nil
207:       source.each do |s|
208:         case s
209:         when Hash
210:           s.each{|k,v| sources << SQL::AliasedExpression.new(k,v)}
211:         when Dataset
212:           if hoist_cte?(s)
213:             ctes ||= []
214:             ctes += s.opts[:with]
215:             s = s.clone(:with=>nil)
216:           end
217:           sources << SQL::AliasedExpression.new(s, dataset_alias(table_alias_num+=1))
218:         when Symbol
219:           sch, table, aliaz = split_symbol(s)
220:           if aliaz
221:             s = sch ? SQL::QualifiedIdentifier.new(sch, table) : SQL::Identifier.new(table)
222:             sources << SQL::AliasedExpression.new(s, aliaz.to_sym)
223:           else
224:             sources << s
225:           end
226:         else
227:           sources << s
228:         end
229:       end
230:       o = {:from=>sources.empty? ? nil : sources}
231:       o[:with] = (opts[:with] || []) + ctes if ctes
232:       o[:num_dataset_sources] = table_alias_num if table_alias_num > 0
233:       clone(o)
234:     end
from_self(opts={}) click to toggle source

Returns a dataset selecting from the current dataset. Supplying the :alias option controls the alias of the result.

  ds = DB[:items].order(:name).select(:id, :name)
  # SELECT id,name FROM items ORDER BY name

  ds.from_self
  # SELECT * FROM (SELECT id, name FROM items ORDER BY name) AS t1

  ds.from_self(:alias=>:foo)
  # SELECT * FROM (SELECT id, name FROM items ORDER BY name) AS foo
     # File lib/sequel/dataset/query.rb, line 247
247:     def from_self(opts={})
248:       fs = {}
249:       @opts.keys.each{|k| fs[k] = nil unless NON_SQL_OPTIONS.include?(k)}
250:       clone(fs).from(opts[:alias] ? as(opts[:alias]) : self)
251:     end
function_sql_append(sql, f) click to toggle source

SQL fragment specifying an SQL function call

     # File lib/sequel/dataset/sql.rb, line 497
497:     def function_sql_append(sql, f)
498:       sql << f.f.to_s
499:       args = f.args
500:       if args.empty?
501:         sql << FUNCTION_EMPTY
502:       else
503:         literal_append(sql, args)
504:       end
505:     end
get(column=(no_arg=true; click to toggle source

Return the column value for the first matching record in the dataset. Raises an error if both an argument and block is given.

  DB[:table].get(:id) # SELECT id FROM table LIMIT 1
  # => 3

  ds.get{sum(id)} # SELECT sum(id) FROM table LIMIT 1
  # => 6
     # File lib/sequel/dataset/actions.rb, line 207
207:     def get(column=(no_arg=true; nil), &block)
208:       if block
209:         raise(Error, ARG_BLOCK_ERROR_MSG) unless no_arg
210:         select(&block).single_value
211:       else
212:         select(column).single_value
213:       end
214:     end
graph(dataset, join_conditions = nil, options = {}, &block) click to toggle source

Allows you to join multiple datasets/tables and have the result set split into component tables.

This differs from the usual usage of join, which returns the result set as a single hash. For example:

  # CREATE TABLE artists (id INTEGER, name TEXT);
  # CREATE TABLE albums (id INTEGER, name TEXT, artist_id INTEGER);

  DB[:artists].left_outer_join(:albums, :artist_id=>:id).first
  #=> {:id=>albums.id, :name=>albums.name, :artist_id=>albums.artist_id}

  DB[:artists].graph(:albums, :artist_id=>:id).first
  #=> {:artists=>{:id=>artists.id, :name=>artists.name}, :albums=>{:id=>albums.id, :name=>albums.name, :artist_id=>albums.artist_id}}

Using a join such as left_outer_join, the attribute names that are shared between the tables are combined in the single return hash. You can get around that by using select with correct aliases for all of the columns, but it is simpler to use graph and have the result set split for you. In addition, graph respects any row_proc of the current dataset and the datasets you use with graph.

If you are graphing a table and all columns for that table are nil, this indicates that no matching rows existed in the table, so graph will return nil instead of a hash with all nil values:

  # If the artist doesn't have any albums
  DB[:artists].graph(:albums, :artist_id=>:id).first
  => {:artists=>{:id=>artists.id, :name=>artists.name}, :albums=>nil}

Arguments:

dataset

Can be a symbol (specifying a table), another dataset, or an object that responds to dataset and returns a symbol or a dataset

join_conditions

Any condition(s) allowed by join_table.

block

A block that is passed to join_table.

Options:

:from_self_alias

The alias to use when the receiver is not a graphed dataset but it contains multiple FROM tables or a JOIN. In this case, the receiver is wrapped in a from_self before graphing, and this option determines the alias to use.

:implicit_qualifier

The qualifier of implicit conditions, see #.

:join_type

The type of join to use (passed to join_table). Defaults to :left_outer.

:select

An array of columns to select. When not used, selects all columns in the given dataset. When set to false, selects no columns and is like simply joining the tables, though graph keeps some metadata about the join that makes it important to use graph instead of join_table.

:table_alias

The alias to use for the table. If not specified, doesn’t alias the table. You will get an error if the the alias (or table) name is used more than once.

     # File lib/sequel/dataset/graph.rb, line 74
 74:     def graph(dataset, join_conditions = nil, options = {}, &block)
 75:       # Allow the use of a model, dataset, or symbol as the first argument
 76:       # Find the table name/dataset based on the argument
 77:       dataset = dataset.dataset if dataset.respond_to?(:dataset)
 78:       table_alias = options[:table_alias]
 79:       case dataset
 80:       when Symbol
 81:         table = dataset
 82:         dataset = @db[dataset]
 83:         table_alias ||= table
 84:       when ::Sequel::Dataset
 85:         if dataset.simple_select_all?
 86:           table = dataset.opts[:from].first
 87:           table_alias ||= table
 88:         else
 89:           table = dataset
 90:           table_alias ||= dataset_alias((@opts[:num_dataset_sources] || 0)+1)
 91:         end
 92:       else
 93:         raise Error, "The dataset argument should be a symbol, dataset, or model"
 94:       end
 95: 
 96:       # Raise Sequel::Error with explanation that the table alias has been used
 97:       raise_alias_error = lambda do
 98:         raise(Error, "this #{options[:table_alias] ? 'alias' : 'table'} has already been been used, please specify "            "#{options[:table_alias] ? 'a different alias' : 'an alias via the :table_alias option'}") 
 99:       end
100: 
101:       # Only allow table aliases that haven't been used
102:       raise_alias_error.call if @opts[:graph] && @opts[:graph][:table_aliases] && @opts[:graph][:table_aliases].include?(table_alias)
103:       
104:       # Use a from_self if this is already a joined table
105:       ds = (!@opts[:graph] && (@opts[:from].length > 1 || @opts[:join])) ? from_self(:alias=>options[:from_self_alias] || first_source) : self
106:       
107:       # Join the table early in order to avoid cloning the dataset twice
108:       ds = ds.join_table(options[:join_type] || :left_outer, table, join_conditions, :table_alias=>table_alias, :implicit_qualifier=>options[:implicit_qualifier], &block)
109:       opts = ds.opts
110: 
111:       # Whether to include the table in the result set
112:       add_table = options[:select] == false ? false : true
113:       # Whether to add the columns to the list of column aliases
114:       add_columns = !ds.opts.include?(:graph_aliases)
115: 
116:       # Setup the initial graph data structure if it doesn't exist
117:       if graph = opts[:graph]
118:         opts[:graph] = graph = graph.dup
119:         select = opts[:select].dup
120:         [:column_aliases, :table_aliases, :column_alias_num].each{|k| graph[k] = graph[k].dup}
121:       else
122:         master = alias_symbol(ds.first_source_alias)
123:         raise_alias_error.call if master == table_alias
124:         # Master hash storing all .graph related information
125:         graph = opts[:graph] = {}
126:         # Associates column aliases back to tables and columns
127:         column_aliases = graph[:column_aliases] = {}
128:         # Associates table alias (the master is never aliased)
129:         table_aliases = graph[:table_aliases] = {master=>self}
130:         # Keep track of the alias numbers used
131:         ca_num = graph[:column_alias_num] = Hash.new(0)
132:         # All columns in the master table are never
133:         # aliased, but are not included if set_graph_aliases
134:         # has been used.
135:         if add_columns
136:           if (select = @opts[:select]) && !select.empty? && !(select.length == 1 && (select.first.is_a?(SQL::ColumnAll)))
137:             select = select.each do |sel|
138:               column = case sel
139:               when Symbol
140:                 _, c, a = split_symbol(sel)
141:                 (a || c).to_sym
142:               when SQL::Identifier
143:                 sel.value.to_sym
144:               when SQL::QualifiedIdentifier
145:                 column = sel.column
146:                 column = column.value if column.is_a?(SQL::Identifier)
147:                 column.to_sym
148:               when SQL::AliasedExpression
149:                 column = sel.aliaz
150:                 column = column.value if column.is_a?(SQL::Identifier)
151:                 column.to_sym
152:               else
153:                 raise Error, "can't figure out alias to use for graphing for #{sel.inspect}"
154:               end
155:               column_aliases[column] = [master, column]
156:             end
157:             select = qualified_expression(select, master)
158:           else
159:             select = columns.map do |column|
160:               column_aliases[column] = [master, column]
161:               SQL::QualifiedIdentifier.new(master, column)
162:             end
163:           end
164:         end
165:       end
166: 
167:       # Add the table alias to the list of aliases
168:       # Even if it isn't been used in the result set,
169:       # we add a key for it with a nil value so we can check if it
170:       # is used more than once
171:       table_aliases = graph[:table_aliases]
172:       table_aliases[table_alias] = add_table ? dataset : nil
173: 
174:       # Add the columns to the selection unless we are ignoring them
175:       if add_table && add_columns
176:         column_aliases = graph[:column_aliases]
177:         ca_num = graph[:column_alias_num]
178:         # Which columns to add to the result set
179:         cols = options[:select] || dataset.columns
180:         # If the column hasn't been used yet, don't alias it.
181:         # If it has been used, try table_column.
182:         # If that has been used, try table_column_N 
183:         # using the next value of N that we know hasn't been
184:         # used
185:         cols.each do |column|
186:           col_alias, identifier = if column_aliases[column]
187:             column_alias = :"#{table_alias}_#{column}"
188:             if column_aliases[column_alias]
189:               column_alias_num = ca_num[column_alias]
190:               column_alias = :"#{column_alias}_#{column_alias_num}" 
191:               ca_num[column_alias] += 1
192:             end
193:             [column_alias, SQL::AliasedExpression.new(SQL::QualifiedIdentifier.new(table_alias, column), column_alias)]
194:           else
195:             ident = SQL::QualifiedIdentifier.new(table_alias, column)
196:             [column, ident]
197:           end
198:           column_aliases[col_alias] = [table_alias, column]
199:           select.push(identifier)
200:         end
201:       end
202:       add_columns ? ds.select(*select) : ds
203:     end
graph(*) click to toggle source

Don’t allow graphing a dataset that splits multiple statements

     # File lib/sequel/adapters/mysql.rb, line 319
319:       def graph(*)
320:         raise(Error, "Can't graph a dataset that splits multiple result sets") if opts[:split_multiple_result_sets]
321:         super
322:       end
grep(columns, patterns, opts={}) click to toggle source

Match any of the columns to any of the patterns. The terms can be strings (which use LIKE) or regular expressions (which are only supported on MySQL and PostgreSQL). Note that the total number of pattern matches will be Array(columns).length * Array(terms).length, which could cause performance issues.

Options (all are boolean):

:all_columns

All columns must be matched to any of the given patterns.

:all_patterns

All patterns must match at least one of the columns.

:case_insensitive

Use a case insensitive pattern match (the default is case sensitive if the database supports it).

If both :all_columns and :all_patterns are true, all columns must match all patterns.

Examples:

  dataset.grep(:a, '%test%')
  # SELECT * FROM items WHERE (a LIKE '%test%')

  dataset.grep([:a, :b], %w'%test% foo')
  # SELECT * FROM items WHERE ((a LIKE '%test%') OR (a LIKE 'foo') OR (b LIKE '%test%') OR (b LIKE 'foo'))

  dataset.grep([:a, :b], %w'%foo% %bar%', :all_patterns=>true)
  # SELECT * FROM a WHERE (((a LIKE '%foo%') OR (b LIKE '%foo%')) AND ((a LIKE '%bar%') OR (b LIKE '%bar%')))

  dataset.grep([:a, :b], %w'%foo% %bar%', :all_columns=>true)
  # SELECT * FROM a WHERE (((a LIKE '%foo%') OR (a LIKE '%bar%')) AND ((b LIKE '%foo%') OR (b LIKE '%bar%')))

  dataset.grep([:a, :b], %w'%foo% %bar%', :all_patterns=>true, :all_columns=>true)
  # SELECT * FROM a WHERE ((a LIKE '%foo%') AND (b LIKE '%foo%') AND (a LIKE '%bar%') AND (b LIKE '%bar%'))
     # File lib/sequel/dataset/query.rb, line 284
284:     def grep(columns, patterns, opts={})
285:       if opts[:all_patterns]
286:         conds = Array(patterns).map do |pat|
287:           SQL::BooleanExpression.new(opts[:all_columns] ? :AND : :OR, *Array(columns).map{|c| SQL::StringExpression.like(c, pat, opts)})
288:         end
289:         filter(SQL::BooleanExpression.new(opts[:all_patterns] ? :AND : :OR, *conds))
290:       else
291:         conds = Array(columns).map do |c|
292:           SQL::BooleanExpression.new(:OR, *Array(patterns).map{|pat| SQL::StringExpression.like(c, pat, opts)})
293:         end
294:         filter(SQL::BooleanExpression.new(opts[:all_columns] ? :AND : :OR, *conds))
295:       end
296:     end
group(*columns, &block) click to toggle source

Returns a copy of the dataset with the results grouped by the value of the given columns. If a block is given, it is treated as a virtual row block, similar to filter.

  DB[:items].group(:id) # SELECT * FROM items GROUP BY id
  DB[:items].group(:id, :name) # SELECT * FROM items GROUP BY id, name
  DB[:items].group{[a, sum(b)]} # SELECT * FROM items GROUP BY a, sum(b)
     # File lib/sequel/dataset/query.rb, line 305
305:     def group(*columns, &block)
306:       virtual_row_columns(columns, block)
307:       clone(:group => (columns.compact.empty? ? nil : columns))
308:     end
group_and_count(*columns, &block) click to toggle source

Returns a dataset grouped by the given column with count by group. Column aliases may be supplied, and will be included in the select clause. If a block is given, it is treated as a virtual row block, similar to filter.

Examples:

  DB[:items].group_and_count(:name).all
  # SELECT name, count(*) AS count FROM items GROUP BY name 
  # => [{:name=>'a', :count=>1}, ...]

  DB[:items].group_and_count(:first_name, :last_name).all
  # SELECT first_name, last_name, count(*) AS count FROM items GROUP BY first_name, last_name
  # => [{:first_name=>'a', :last_name=>'b', :count=>1}, ...]

  DB[:items].group_and_count(:first_name___name).all
  # SELECT first_name AS name, count(*) AS count FROM items GROUP BY first_name
  # => [{:name=>'a', :count=>1}, ...]

  DB[:items].group_and_count{substr(first_name, 1, 1).as(initial)}.all
  # SELECT substr(first_name, 1, 1) AS initial, count(*) AS count FROM items GROUP BY substr(first_name, 1, 1)
  # => [{:initial=>'a', :count=>1}, ...]
     # File lib/sequel/dataset/query.rb, line 336
336:     def group_and_count(*columns, &block)
337:       select_group(*columns, &block).select_more(COUNT_OF_ALL_AS_COUNT)
338:     end
group_by(*columns, &block) click to toggle source

Alias of group

     # File lib/sequel/dataset/query.rb, line 311
311:     def group_by(*columns, &block)
312:       group(*columns, &block)
313:     end
group_cube() click to toggle source

Adds the appropriate CUBE syntax to GROUP BY.

     # File lib/sequel/dataset/query.rb, line 341
341:     def group_cube
342:       raise Error, "GROUP BY CUBE not supported on #{db.database_type}" unless supports_group_cube?
343:       clone(:group_options=>:cube)
344:     end
group_rollup() click to toggle source

Adds the appropriate ROLLUP syntax to GROUP BY.

     # File lib/sequel/dataset/query.rb, line 347
347:     def group_rollup
348:       raise Error, "GROUP BY ROLLUP not supported on #{db.database_type}" unless supports_group_rollup?
349:       clone(:group_options=>:rollup)
350:     end
hash() click to toggle source

Define a hash value such that datasets with the same DB, opts, and SQL will have the same hash value

     # File lib/sequel/dataset/misc.rb, line 109
109:     def hash
110:       [db, opts.sort_by{|k, v| k.to_s}, sql].hash
111:     end
having(*cond, &block) click to toggle source

Returns a copy of the dataset with the HAVING conditions changed. See # for argument types.

  DB[:items].group(:sum).having(:sum=>10)
  # SELECT * FROM items GROUP BY sum HAVING (sum = 10)
     # File lib/sequel/dataset/query.rb, line 356
356:     def having(*cond, &block)
357:       _filter(:having, *cond, &block)
358:     end
identifier_input_method() click to toggle source

The String instance method to call on identifiers before sending them to the database.

     # File lib/sequel/dataset/misc.rb, line 115
115:     def identifier_input_method
116:       if defined?(@identifier_input_method)
117:         @identifier_input_method
118:       elsif db.respond_to?(:identifier_input_method)
119:         @identifier_input_method = db.identifier_input_method
120:       else
121:         @identifier_input_method = nil
122:       end
123:     end
identifier_output_method() click to toggle source

The String instance method to call on identifiers before sending them to the database.

     # File lib/sequel/dataset/misc.rb, line 127
127:     def identifier_output_method
128:       if defined?(@identifier_output_method)
129:         @identifier_output_method
130:       elsif db.respond_to?(:identifier_output_method)
131:         @identifier_output_method = db.identifier_output_method
132:       else
133:         @identifier_output_method = nil
134:       end
135:     end
import(columns, values, opts={}) click to toggle source

Inserts multiple records into the associated table. This method can be used to efficiently insert a large number of records into a table in a single query if the database supports it. Inserts are automatically wrapped in a transaction.

This method is called with a columns array and an array of value arrays:

  DB[:table].import([:x, :y], [[1, 2], [3, 4]])
  # INSERT INTO table (x, y) VALUES (1, 2) 
  # INSERT INTO table (x, y) VALUES (3, 4) 

This method also accepts a dataset instead of an array of value arrays:

  DB[:table].import([:x, :y], DB[:table2].select(:a, :b))
  # INSERT INTO table (x, y) SELECT a, b FROM table2 

Options:

:commit_every

Open a new transaction for every given number of records. For example, if you provide a value of 50, will commit after every 50 records.

:server

Set the server/shard to use for the transaction and insert queries.

:slice

Same as :commit_every, :commit_every takes precedence.

     # File lib/sequel/dataset/actions.rb, line 239
239:     def import(columns, values, opts={})
240:       return @db.transaction{insert(columns, values)} if values.is_a?(Dataset)
241: 
242:       return if values.empty?
243:       raise(Error, IMPORT_ERROR_MSG) if columns.empty?
244:       ds = opts[:server] ? server(opts[:server]) : self
245:       
246:       if slice_size = opts[:commit_every] || opts[:slice]
247:         offset = 0
248:         rows = []
249:         while offset < values.length
250:           rows << ds._import(columns, values[offset, slice_size], opts)
251:           offset += slice_size
252:         end
253:         rows.flatten
254:       else
255:         ds._import(columns, values, opts)
256:       end
257:     end
insert(*values, &block) click to toggle source

Inserts values into the associated table. The returned value is generally the value of the primary key for the inserted row, but that is adapter dependent.

insert handles a number of different argument formats:

no arguments or single empty hash

Uses DEFAULT VALUES

single hash

Most common format, treats keys as columns an values as values

single array

Treats entries as values, with no columns

two arrays

Treats first array as columns, second array as values

single Dataset

Treats as an insert based on a selection from the dataset given, with no columns

array and dataset

Treats as an insert based on a selection from the dataset given, with the columns given by the array.

Examples:

  DB[:items].insert
  # INSERT INTO items DEFAULT VALUES

  DB[:items].insert({})
  # INSERT INTO items DEFAULT VALUES

  DB[:items].insert([1,2,3])
  # INSERT INTO items VALUES (1, 2, 3)

  DB[:items].insert([:a, :b], [1,2])
  # INSERT INTO items (a, b) VALUES (1, 2)

  DB[:items].insert(:a => 1, :b => 2)
  # INSERT INTO items (a, b) VALUES (1, 2)

  DB[:items].insert(DB[:old_items])
  # INSERT INTO items SELECT * FROM old_items

  DB[:items].insert([:a, :b], DB[:old_items])
  # INSERT INTO items (a, b) SELECT * FROM old_items
     # File lib/sequel/dataset/actions.rb, line 294
294:     def insert(*values, &block)
295:       sql = insert_sql(*values)
296:       if uses_returning?(:insert)
297:         returning_fetch_rows(sql, &block)
298:       else
299:         execute_insert(sql)
300:       end
301:     end
insert_multiple(array, &block) click to toggle source

Inserts multiple values. If a block is given it is invoked for each item in the given array before inserting it. See multi_insert as a possibly faster version that may be able to insert multiple records in one SQL statement (if supported by the database). Returns an array of primary keys of inserted rows.

  DB[:table].insert_multiple([{:x=>1}, {:x=>2}])
  # => [4, 5]
  # INSERT INTO table (x) VALUES (1)
  # INSERT INTO table (x) VALUES (2)

  DB[:table].insert_multiple([{:x=>1}, {:x=>2}]){|row| row[:y] = row[:x] * 2}
  # => [6, 7]
  # INSERT INTO table (x, y) VALUES (1, 2)
  # INSERT INTO table (x, y) VALUES (2, 4)
     # File lib/sequel/dataset/actions.rb, line 318
318:     def insert_multiple(array, &block)
319:       if block
320:         array.map{|i| insert(block.call(i))}
321:       else
322:         array.map{|i| insert(i)}
323:       end
324:     end
insert_sql(*values) click to toggle source

Returns an INSERT SQL query string. See insert.

  DB[:items].insert_sql(:a=>1)
  # => "INSERT INTO items (a) VALUES (1)"
    # File lib/sequel/dataset/sql.rb, line 30
30:     def insert_sql(*values)
31:       return static_sql(@opts[:sql]) if @opts[:sql]
32: 
33:       check_modification_allowed!
34: 
35:       columns = []
36: 
37:       case values.size
38:       when 0
39:         return insert_sql({})
40:       when 1
41:         case vals = values.at(0)
42:         when Hash
43:           vals = @opts[:defaults].merge(vals) if @opts[:defaults]
44:           vals = vals.merge(@opts[:overrides]) if @opts[:overrides]
45:           values = []
46:           vals.each do |k,v| 
47:             columns << k
48:             values << v
49:           end
50:         when Dataset, Array, LiteralString
51:           values = vals
52:         else
53:           if vals.respond_to?(:values) && (v = vals.values).is_a?(Hash)
54:             return insert_sql(v) 
55:           end
56:         end
57:       when 2
58:         if (v0 = values.at(0)).is_a?(Array) && ((v1 = values.at(1)).is_a?(Array) || v1.is_a?(Dataset) || v1.is_a?(LiteralString))
59:           columns, values = v0, v1
60:           raise(Error, "Different number of values and columns given to insert_sql") if values.is_a?(Array) and columns.length != values.length
61:         end
62:       end
63: 
64:       if values.is_a?(Array) && values.empty? && !insert_supports_empty_values? 
65:         columns = [columns().last]
66:         values = [DEFAULT]
67:       end
68:       clone(:columns=>columns, :values=>values)._insert_sql
69:     end
inspect() click to toggle source

Returns a string representation of the dataset including the class name and the corresponding SQL select statement.

     # File lib/sequel/dataset/misc.rb, line 139
139:     def inspect
140:       c = self.class
141:       c = c.superclass while c.name.nil? || c.name == ''
142:       "#<#{c.name}: #{sql.inspect}>"
143:     end
intersect(dataset, opts={}) click to toggle source

Adds an INTERSECT clause using a second dataset object. An INTERSECT compound dataset returns all rows in both the current dataset and the given dataset. Raises an InvalidOperation if the operation is not supported. Options:

:alias

Use the given value as the from_self alias

:all

Set to true to use INTERSECT ALL instead of INTERSECT, so duplicate rows can occur

:from_self

Set to false to not wrap the returned dataset in a from_self, use with care.

  DB[:items].intersect(DB[:other_items])
  # SELECT * FROM (SELECT * FROM items INTERSECT SELECT * FROM other_items) AS t1

  DB[:items].intersect(DB[:other_items], :all=>true, :from_self=>false)
  # SELECT * FROM items INTERSECT ALL SELECT * FROM other_items

  DB[:items].intersect(DB[:other_items], :alias=>:i)
  # SELECT * FROM (SELECT * FROM items INTERSECT SELECT * FROM other_items) AS i
     # File lib/sequel/dataset/query.rb, line 377
377:     def intersect(dataset, opts={})
378:       opts = {:all=>opts} unless opts.is_a?(Hash)
379:       raise(InvalidOperation, "INTERSECT not supported") unless supports_intersect_except?
380:       raise(InvalidOperation, "INTERSECT ALL not supported") if opts[:all] && !supports_intersect_except_all?
381:       compound_clone(:intersect, dataset, opts)
382:     end
interval(column) click to toggle source

Returns the interval between minimum and maximum values for the given column.

  DB[:table].interval(:id) # SELECT (max(id) - min(id)) FROM table LIMIT 1
  # => 6
     # File lib/sequel/dataset/actions.rb, line 331
331:     def interval(column)
332:       aggregate_dataset.get{max(column) - min(column)}
333:     end
invert() click to toggle source

Inverts the current filter.

  DB[:items].filter(:category => 'software').invert
  # SELECT * FROM items WHERE (category != 'software')

  DB[:items].filter(:category => 'software', :id=>3).invert
  # SELECT * FROM items WHERE ((category != 'software') OR (id != 3))
     # File lib/sequel/dataset/query.rb, line 391
391:     def invert
392:       having, where = @opts[:having], @opts[:where]
393:       raise(Error, "No current filter") unless having || where
394:       o = {}
395:       o[:having] = SQL::BooleanExpression.invert(having) if having
396:       o[:where] = SQL::BooleanExpression.invert(where) if where
397:       clone(o)
398:     end
join(*args, &block) click to toggle source

Alias of inner_join

     # File lib/sequel/dataset/query.rb, line 401
401:     def join(*args, &block)
402:       inner_join(*args, &block)
403:     end
join_clause_sql_append(sql, jc) click to toggle source

SQL fragment specifying a JOIN clause without ON or USING.

     # File lib/sequel/dataset/sql.rb, line 508
508:     def join_clause_sql_append(sql, jc)
509:       table = jc.table
510:       table_alias = jc.table_alias
511:       table_alias = nil if table == table_alias
512:       sql << SPACE << join_type_sql(jc.join_type) << SPACE
513:       identifier_append(sql, table)
514:       as_sql_append(sql, table_alias) if table_alias
515:     end
join_on_clause_sql_append(sql, jc) click to toggle source

SQL fragment specifying a JOIN clause with ON.

     # File lib/sequel/dataset/sql.rb, line 518
518:     def join_on_clause_sql_append(sql, jc)
519:       join_clause_sql_append(sql, jc)
520:       sql << ON
521:       literal_append(sql, filter_expr(jc.on))
522:     end
join_table(type, table, expr=nil, options={}, &block) click to toggle source

Returns a joined dataset. Not usually called directly, users should use the appropriate join method (e.g. join, left_join, natural_join, cross_join) which fills in the type argument.

Takes the following arguments:

  • type - The type of join to do (e.g. :inner)

  • table - Depends on type:

    • Dataset - a subselect is performed with an alias of tN for some value of N

    • Model (or anything responding to :table_name) - table.table_name

  • expr - specifies conditions, depends on type:

    • Hash, Array of two element arrays - Assumes key (1st arg) is column of joined table (unless already qualified), and value (2nd arg) is column of the last joined or primary table (or the :implicit_qualifier option). To specify multiple conditions on a single joined table column, you must use an array. Uses a JOIN with an ON clause.

    • Array - If all members of the array are symbols, considers them as columns and uses a JOIN with a USING clause. Most databases will remove duplicate columns from the result set if this is used.

    • nil - If a block is not given, doesn’t use ON or USING, so the JOIN should be a NATURAL or CROSS join. If a block is given, uses an ON clause based on the block, see below.

    • Everything else - pretty much the same as a using the argument in a call to filter, so strings are considered literal, symbols specify boolean columns, and Sequel expressions can be used. Uses a JOIN with an ON clause.

  • options - a hash of options, with any of the following keys:

    • :table_alias - the name of the table’s alias when joining, necessary for joining to the same table more than once. No alias is used by default.

    • :implicit_qualifier - The name to use for qualifying implicit conditions. By default, the last joined or primary table is used.

  • block - The block argument should only be given if a JOIN with an ON clause is used, in which case it yields the table alias/name for the table currently being joined, the table alias/name for the last joined (or first table), and an array of previous SQL::JoinClause. Unlike filter, this block is not treated as a virtual row block.

Examples:

  DB[:a].join_table(:cross, :b)
  # SELECT * FROM a CROSS JOIN b

  DB[:a].join_table(:inner, DB[:b], :c=>d)
  # SELECT * FROM a INNER JOIN (SELECT * FROM b) AS t1 ON (t1.c = a.d)

  DB[:a].join_table(:left, :b___c, [:d])
  # SELECT * FROM a LEFT JOIN b AS c USING (d)

  DB[:a].natural_join(:b).join_table(:inner, :c) do |ta, jta, js|
    (:d.qualify(ta) > :e.qualify(jta)) & {:f.qualify(ta)=>DB.from(js.first.table).select(:g)}
  end
  # SELECT * FROM a NATURAL JOIN b INNER JOIN c
  #   ON ((c.d > b.e) AND (c.f IN (SELECT g FROM b)))
     # File lib/sequel/dataset/query.rb, line 456
456:     def join_table(type, table, expr=nil, options={}, &block)
457:       if hoist_cte?(table)
458:         s, ds = hoist_cte(table)
459:         return s.join_table(type, ds, expr, options, &block)
460:       end
461: 
462:       using_join = expr.is_a?(Array) && !expr.empty? && expr.all?{|x| x.is_a?(Symbol)}
463:       if using_join && !supports_join_using?
464:         h = {}
465:         expr.each{|s| h[s] = s}
466:         return join_table(type, table, h, options)
467:       end
468: 
469:       case options
470:       when Hash
471:         table_alias = options[:table_alias]
472:         last_alias = options[:implicit_qualifier]
473:       when Symbol, String, SQL::Identifier
474:         table_alias = options
475:         last_alias = nil 
476:       else
477:         raise Error, "invalid options format for join_table: #{options.inspect}"
478:       end
479: 
480:       if Dataset === table
481:         if table_alias.nil?
482:           table_alias_num = (@opts[:num_dataset_sources] || 0) + 1
483:           table_alias = dataset_alias(table_alias_num)
484:         end
485:         table_name = table_alias
486:       else
487:         table = table.table_name if table.respond_to?(:table_name)
488:         table, implicit_table_alias = split_alias(table)
489:         table_alias ||= implicit_table_alias
490:         table_name = table_alias || table
491:       end
492: 
493:       join = if expr.nil? and !block
494:         SQL::JoinClause.new(type, table, table_alias)
495:       elsif using_join
496:         raise(Sequel::Error, "can't use a block if providing an array of symbols as expr") if block
497:         SQL::JoinUsingClause.new(expr, type, table, table_alias)
498:       else
499:         last_alias ||= @opts[:last_joined_table] || first_source_alias
500:         if Sequel.condition_specifier?(expr)
501:           expr = expr.collect do |k, v|
502:             k = qualified_column_name(k, table_name) if k.is_a?(Symbol)
503:             v = qualified_column_name(v, last_alias) if v.is_a?(Symbol)
504:             [k,v]
505:           end
506:           expr = SQL::BooleanExpression.from_value_pairs(expr)
507:         end
508:         if block
509:           expr2 = yield(table_name, last_alias, @opts[:join] || [])
510:           expr = expr ? SQL::BooleanExpression.new(:AND, expr, expr2) : expr2
511:         end
512:         SQL::JoinOnClause.new(expr, type, table, table_alias)
513:       end
514: 
515:       opts = {:join => (@opts[:join] || []) + [join], :last_joined_table => table_name}
516:       opts[:num_dataset_sources] = table_alias_num if table_alias_num
517:       clone(opts)
518:     end
join_using_clause_sql_append(sql, jc) click to toggle source

SQL fragment specifying a JOIN clause with USING.

     # File lib/sequel/dataset/sql.rb, line 525
525:     def join_using_clause_sql_append(sql, jc)
526:       join_clause_sql_append(sql, jc)
527:       sql << USING
528:       column_list_append(sql, jc.using)
529:       sql << PAREN_CLOSE
530:     end
last(*args, &block) click to toggle source

Reverses the order and then runs # with the given arguments and block. Note that this will not necessarily give you the last record in the dataset, unless you have an unambiguous order. If there is not currently an order for this dataset, raises an Error.

  DB[:table].order(:id).last # SELECT * FROM table ORDER BY id DESC LIMIT 1
  # => {:id=>10}

  DB[:table].order(:id.desc).last(2) # SELECT * FROM table ORDER BY id ASC LIMIT 2
  # => [{:id=>1}, {:id=>2}]
     # File lib/sequel/dataset/actions.rb, line 345
345:     def last(*args, &block)
346:       raise(Error, 'No order specified') unless @opts[:order]
347:       reverse.first(*args, &block)
348:     end
limit(l, o = nil) click to toggle source

If given an integer, the dataset will contain only the first l results. If given a range, it will contain only those at offsets within that range. If a second argument is given, it is used as an offset. To use an offset without a limit, pass nil as the first argument.

  DB[:items].limit(10) # SELECT * FROM items LIMIT 10
  DB[:items].limit(10, 20) # SELECT * FROM items LIMIT 10 OFFSET 20
  DB[:items].limit(10...20) # SELECT * FROM items LIMIT 10 OFFSET 10
  DB[:items].limit(10..20) # SELECT * FROM items LIMIT 11 OFFSET 10
  DB[:items].limit(nil, 20) # SELECT * FROM items OFFSET 20
     # File lib/sequel/dataset/query.rb, line 537
537:     def limit(l, o = nil)
538:       return from_self.limit(l, o) if @opts[:sql]
539: 
540:       if Range === l
541:         o = l.first
542:         l = l.last - l.first + (l.exclude_end? ? 0 : 1)
543:       end
544:       l = l.to_i if l.is_a?(String) && !l.is_a?(LiteralString)
545:       if l.is_a?(Integer)
546:         raise(Error, 'Limits must be greater than or equal to 1') unless l >= 1
547:       end
548:       opts = {:limit => l}
549:       if o
550:         o = o.to_i if o.is_a?(String) && !o.is_a?(LiteralString)
551:         if o.is_a?(Integer)
552:           raise(Error, 'Offsets must be greater than or equal to 0') unless o >= 0
553:         end
554:         opts[:offset] = o
555:       end
556:       clone(opts)
557:     end
literal_append(sql, v) click to toggle source

Returns a literal representation of a value to be used as part of an SQL expression.

  DB[:items].literal("abc'def\\") #=> "'abc''def\\\\'"
  DB[:items].literal(:items__id) #=> "items.id"
  DB[:items].literal([1, 2, 3]) => "(1, 2, 3)"
  DB[:items].literal(DB[:items]) => "(SELECT * FROM items)"
  DB[:items].literal(:x + 1 > :y) => "((x + 1) > y)"

If an unsupported object is given, an Error is raised.

     # File lib/sequel/dataset/sql.rb, line 81
 81:     def literal_append(sql, v)
 82:       case v
 83:       when Symbol
 84:         literal_symbol_append(sql, v)
 85:       when String
 86:         case v
 87:         when LiteralString
 88:           sql << v
 89:         when SQL::Blob
 90:           literal_blob_append(sql, v)
 91:         else
 92:           literal_string_append(sql, v)
 93:         end
 94:       when Integer
 95:         sql << literal_integer(v)
 96:       when Hash
 97:         literal_hash_append(sql, v)
 98:       when SQL::Expression
 99:         literal_expression_append(sql, v)
100:       when Float
101:         sql << literal_float(v)
102:       when BigDecimal
103:         sql << literal_big_decimal(v)
104:       when NilClass
105:         sql << literal_nil
106:       when TrueClass
107:         sql << literal_true
108:       when FalseClass
109:         sql << literal_false
110:       when Array
111:         literal_array_append(sql, v)
112:       when Time
113:         sql << (v.is_a?(SQLTime) ? literal_sqltime(v) : literal_time(v))
114:       when DateTime
115:         sql << literal_datetime(v)
116:       when Date
117:         sql << literal_date(v)
118:       when Dataset
119:         literal_dataset_append(sql, v)
120:       else
121:         literal_other_append(sql, v)
122:       end
123:     end
lock_style(style) click to toggle source

Returns a cloned dataset with the given lock style. If style is a string, it will be used directly. Otherwise, a symbol may be used for database independent locking. Currently :update is respected by most databases, and :share is supported by some.

  DB[:items].lock_style('FOR SHARE') # SELECT * FROM items FOR SHARE
     # File lib/sequel/dataset/query.rb, line 565
565:     def lock_style(style)
566:       clone(:lock => style)
567:     end
map(column=nil, &block) click to toggle source

Maps column values for each record in the dataset (if a column name is given), or performs the stock mapping functionality of Enumerable otherwise. Raises an Error if both an argument and block are given.

  DB[:table].map(:id) # SELECT * FROM table
  # => [1, 2, 3, ...]

  DB[:table].map{|r| r[:id] * 2} # SELECT * FROM table
  # => [2, 4, 6, ...]

You can also provide an array of column names:

  DB[:table].map([:id, :name]) # SELECT * FROM table
  # => [[1, 'A'], [2, 'B'], [3, 'C'], ...]
     # File lib/sequel/dataset/actions.rb, line 364
364:     def map(column=nil, &block)
365:       if column
366:         raise(Error, ARG_BLOCK_ERROR_MSG) if block
367:         return naked.map(column) if row_proc
368:         if column.is_a?(Array)
369:           super(){|r| r.values_at(*column)}
370:         else
371:           super(){|r| r[column]}
372:         end
373:       else
374:         super(&block)
375:       end
376:     end
max(column) click to toggle source

Returns the maximum value for the given column.

  DB[:table].max(:id) # SELECT max(id) FROM table LIMIT 1
  # => 10
     # File lib/sequel/dataset/actions.rb, line 382
382:     def max(column)
383:       aggregate_dataset.get{max(column)}
384:     end
min(column) click to toggle source

Returns the minimum value for the given column.

  DB[:table].min(:id) # SELECT min(id) FROM table LIMIT 1
  # => 1
     # File lib/sequel/dataset/actions.rb, line 390
390:     def min(column)
391:       aggregate_dataset.get{min(column)}
392:     end
multi_insert(hashes, opts={}) click to toggle source

This is a front end for import that allows you to submit an array of hashes instead of arrays of columns and values:

  DB[:table].multi_insert([{:x => 1}, {:x => 2}])
  # INSERT INTO table (x) VALUES (1)
  # INSERT INTO table (x) VALUES (2)

Be aware that all hashes should have the same keys if you use this calling method, otherwise some columns could be missed or set to null instead of to default values.

This respects the same options as #.

     # File lib/sequel/dataset/actions.rb, line 406
406:     def multi_insert(hashes, opts={})
407:       return if hashes.empty?
408:       columns = hashes.first.keys
409:       import(columns, hashes.map{|h| columns.map{|c| h[c]}}, opts)
410:     end
multi_insert_sql(columns, values) click to toggle source

Returns an array of insert statements for inserting multiple records. This method is used by multi_insert to format insert statements and expects a keys array and and an array of value arrays.

This method should be overridden by descendants if the support inserting multiple records in a single SQL statement.

     # File lib/sequel/dataset/sql.rb, line 131
131:     def multi_insert_sql(columns, values)
132:       values.map{|r| insert_sql(columns, r)}
133:     end
naked() click to toggle source

Returns a cloned dataset without a row_proc.

  ds = DB[:items]
  ds.row_proc = proc{|r| r.invert}
  ds.all # => [{2=>:id}]
  ds.naked.all # => [{:id=>2}]
     # File lib/sequel/dataset/query.rb, line 575
575:     def naked
576:       ds = clone
577:       ds.row_proc = nil
578:       ds
579:     end
naked!() click to toggle source

Remove the row_proc from the current dataset.

    # File lib/sequel/dataset/mutation.rb, line 44
44:     def naked!
45:       self.row_proc = nil
46:       self
47:     end
negative_boolean_constant_sql_append(sql, constant) click to toggle source

SQL fragment for NegativeBooleanConstants

     # File lib/sequel/dataset/sql.rb, line 533
533:     def negative_boolean_constant_sql_append(sql, constant)
534:       sql << NOT_SPACE
535:       boolean_constant_sql_append(sql, constant)
536:     end
nullify() click to toggle source

Return a cloned nullified dataset.

    # File lib/sequel/extensions/null_dataset.rb, line 81
81:     def nullify
82:       clone.nullify!
83:     end
nullify!() click to toggle source

Nullify the current dataset

    # File lib/sequel/extensions/null_dataset.rb, line 86
86:     def nullify!
87:       extend NullDataset
88:     end
or(*cond, &block) click to toggle source

Adds an alternate filter to an existing filter using OR. If no filter exists an Error is raised.

  DB[:items].filter(:a).or(:b) # SELECT * FROM items WHERE a OR b
     # File lib/sequel/dataset/query.rb, line 585
585:     def or(*cond, &block)
586:       clause = (@opts[:having] ? :having : :where)
587:       raise(InvalidOperation, "No existing filter found.") unless @opts[clause]
588:       cond = cond.first if cond.size == 1
589:       clone(clause => SQL::BooleanExpression.new(:OR, @opts[clause], filter_expr(cond, &block)))
590:     end
order(*columns, &block) click to toggle source

Returns a copy of the dataset with the order changed. If the dataset has an existing order, it is ignored and overwritten with this order. If a nil is given the returned dataset has no order. This can accept multiple arguments of varying kinds, such as SQL functions. If a block is given, it is treated as a virtual row block, similar to filter.

  DB[:items].order(:name) # SELECT * FROM items ORDER BY name
  DB[:items].order(:a, :b) # SELECT * FROM items ORDER BY a, b
  DB[:items].order('a + b'.lit) # SELECT * FROM items ORDER BY a + b
  DB[:items].order(:a + :b) # SELECT * FROM items ORDER BY (a + b)
  DB[:items].order(:name.desc) # SELECT * FROM items ORDER BY name DESC
  DB[:items].order(:name.asc(:nulls=>:last)) # SELECT * FROM items ORDER BY name ASC NULLS LAST
  DB[:items].order{sum(name).desc} # SELECT * FROM items ORDER BY sum(name) DESC
  DB[:items].order(nil) # SELECT * FROM items
     # File lib/sequel/dataset/query.rb, line 606
606:     def order(*columns, &block)
607:       virtual_row_columns(columns, block)
608:       clone(:order => (columns.compact.empty?) ? nil : columns)
609:     end
order_append(*columns, &block) click to toggle source

Alias of order_more, for naming consistency with order_prepend.

     # File lib/sequel/dataset/query.rb, line 612
612:     def order_append(*columns, &block)
613:       order_more(*columns, &block)
614:     end
order_by(*columns, &block) click to toggle source

Alias of order

     # File lib/sequel/dataset/query.rb, line 617
617:     def order_by(*columns, &block)
618:       order(*columns, &block)
619:     end
order_more(*columns, &block) click to toggle source

Returns a copy of the dataset with the order columns added to the end of the existing order.

  DB[:items].order(:a).order(:b) # SELECT * FROM items ORDER BY b
  DB[:items].order(:a).order_more(:b) # SELECT * FROM items ORDER BY a, b
     # File lib/sequel/dataset/query.rb, line 626
626:     def order_more(*columns, &block)
627:       columns = @opts[:order] + columns if @opts[:order]
628:       order(*columns, &block)
629:     end
order_prepend(*columns, &block) click to toggle source

Returns a copy of the dataset with the order columns added to the beginning of the existing order.

  DB[:items].order(:a).order(:b) # SELECT * FROM items ORDER BY b
  DB[:items].order(:a).order_prepend(:b) # SELECT * FROM items ORDER BY b, a
     # File lib/sequel/dataset/query.rb, line 636
636:     def order_prepend(*columns, &block)
637:       ds = order(*columns, &block)
638:       @opts[:order] ? ds.order_more(*@opts[:order]) : ds
639:     end
ordered_expression_sql_append(sql, oe) click to toggle source

SQL fragment for the ordered expression, used in the ORDER BY clause.

     # File lib/sequel/dataset/sql.rb, line 540
540:     def ordered_expression_sql_append(sql, oe)
541:       literal_append(sql, oe.expression)
542:       sql << (oe.descending ? DESC : ASC)
543:       case oe.nulls
544:       when :first
545:         sql << NULLS_FIRST
546:       when :last
547:         sql << NULLS_LAST
548:       end
549:     end
paginate(page_no, page_size, record_count=nil) click to toggle source

Returns a paginated dataset. The returned dataset is limited to the page size at the correct offset, and extended with the Pagination module. If a record count is not provided, does a count of total number of records for this dataset.

    # File lib/sequel/extensions/pagination.rb, line 11
11:     def paginate(page_no, page_size, record_count=nil)
12:       raise(Error, "You cannot paginate a dataset that already has a limit") if @opts[:limit]
13:       paginated = limit(page_size, (page_no - 1) * page_size)
14:       paginated.extend(Pagination)
15:       paginated.set_pagination_info(page_no, page_size, record_count || count)
16:     end
placeholder_literal_string_sql_append(sql, pls) click to toggle source

SQL fragment for a literal string with placeholders

     # File lib/sequel/dataset/sql.rb, line 552
552:     def placeholder_literal_string_sql_append(sql, pls)
553:       args = pls.args
554:       str = pls.str
555:       sql << PAREN_OPEN if pls.parens
556:       if args.is_a?(Hash)
557:         re = /:(#{args.keys.map{|k| Regexp.escape(k.to_s)}.join('|')})\b/
558:         loop do
559:           previous, q, str = str.partition(re)
560:           sql << previous
561:           literal_append(sql, args[($1||q[1..1].to_s).to_sym]) unless q.empty?
562:           break if str.empty?
563:         end
564:       elsif str.is_a?(Array)
565:         len = args.length
566:         str.each_with_index do |s, i|
567:           sql << s
568:           literal_append(sql, args[i]) unless i == len
569:         end
570:       else
571:         i = 1
572:         loop do
573:           previous, q, str = str.partition(QUESTION_MARK)
574:           sql << previous
575:            literal_append(sql, args.at(i+=1)) unless q.empty?
576:           break if str.empty?
577:         end
578:       end
579:       sql << PAREN_CLOSE if pls.parens
580:     end
prepare(type, name=nil, *values) click to toggle source

Prepare the given type of statement with the given name, and store it in the database to be called later.

     # File lib/sequel/adapters/postgres.rb, line 681
681:         def prepare(type, name=nil, *values)
682:           ps = to_prepared_statement(type, values)
683:           ps.extend(PreparedStatementMethods)
684:           if name
685:             ps.prepared_statement_name = name
686:             db.set_prepared_statement(name, ps)
687:           end
688:           ps
689:         end
prepare(type, name=nil, *values) click to toggle source

Prepare the given type of query with the given name and store it in the database. Note that a new native prepared statement is created on each call to this prepared statement.

     # File lib/sequel/adapters/oracle.rb, line 396
396:       def prepare(type, name=nil, *values)
397:         ps = to_prepared_statement(type, values)
398:         ps.extend(PreparedStatementMethods)
399:         if name
400:           ps.prepared_statement_name = name
401:           db.set_prepared_statement(name, ps)
402:         end
403:         ps
404:       end
prepare(type, name=nil, *values) click to toggle source

Prepare an SQL statement for later execution. Takes a type similar to #, and the name symbol of the prepared statement. While name defaults to nil, it should always be provided as a symbol for the name of the prepared statement, as some databases require that prepared statements have names.

This returns a clone of the dataset extended with PreparedStatementMethods, which you can call with the hash of bind variables to use. The prepared statement is also stored in the associated database, where it can be called by name. The following usage is identical:

  ps = DB[:table].filter(:name=>:$name).prepare(:first, :select_by_name)

  ps.call(:name=>'Blah')
  # SELECT * FROM table WHERE name = ? -- ('Blah')
  # => {:id=>1, :name=>'Blah'}

  DB.call(:select_by_name, :name=>'Blah') # Same thing
     # File lib/sequel/dataset/prepared_statements.rb, line 250
250:     def prepare(type, name=nil, *values)
251:       ps = to_prepared_statement(type, values)
252:       db.set_prepared_statement(name, ps) if name
253:       ps
254:     end
prepared_arg_placeholder() click to toggle source

PostgreSQL uses $N for placeholders instead of ?, so use a $ as the placeholder.

     # File lib/sequel/adapters/postgres.rb, line 695
695:         def prepared_arg_placeholder
696:           PREPARED_ARG_PLACEHOLDER
697:         end
provides_accurate_rows_matched?() click to toggle source

Whether this dataset will provide accurate number of rows matched for delete and update statements. Accurate in this case is the number of rows matched by the dataset’s filter.

    # File lib/sequel/dataset/features.rb, line 23
23:     def provides_accurate_rows_matched?
24:       true
25:     end
qualified_identifier_sql_append(sql, table, column=(c = table.column; click to toggle source

SQL fragment for the qualifed identifier, specifying a table and a column (or schema and table). If 3 arguments are given, the 2nd should be the table/qualifier and the third should be column/qualified. If 2 arguments are given, the 2nd should be an SQL::QualifiedIdentifier.

     # File lib/sequel/dataset/sql.rb, line 586
586:     def qualified_identifier_sql_append(sql, table, column=(c = table.column; table = table.table; c))
587:       identifier_append(sql, table)
588:       sql << DOT
589:       identifier_append(sql, column)
590:     end
qualify(table=first_source) click to toggle source

Qualify to the given table, or first source if no table is given.

  DB[:items].filter(:id=>1).qualify
  # SELECT items.* FROM items WHERE (items.id = 1)

  DB[:items].filter(:id=>1).qualify(:i)
  # SELECT i.* FROM items WHERE (i.id = 1)
     # File lib/sequel/dataset/query.rb, line 648
648:     def qualify(table=first_source)
649:       qualify_to(table)
650:     end
qualify_to(table) click to toggle source

Return a copy of the dataset with unqualified identifiers in the SELECT, WHERE, GROUP, HAVING, and ORDER clauses qualified by the given table. If no columns are currently selected, select all columns of the given table.

  DB[:items].filter(:id=>1).qualify_to(:i)
  # SELECT i.* FROM items WHERE (i.id = 1)
     # File lib/sequel/dataset/query.rb, line 659
659:     def qualify_to(table)
660:       o = @opts
661:       return clone if o[:sql]
662:       h = {}
663:       (o.keys & QUALIFY_KEYS).each do |k|
664:         h[k] = qualified_expression(o[k], table)
665:       end
666:       h[:select] = [SQL::ColumnAll.new(table)] if !o[:select] || o[:select].empty?
667:       clone(h)
668:     end
qualify_to_first_source() click to toggle source

Qualify the dataset to its current first source. This is useful if you have unqualified identifiers in the query that all refer to the first source, and you want to join to another table which has columns with the same name as columns in the current dataset. See qualify_to.

  DB[:items].filter(:id=>1).qualify_to_first_source
  # SELECT items.* FROM items WHERE (items.id = 1)
     # File lib/sequel/dataset/query.rb, line 678
678:     def qualify_to_first_source
679:       qualify_to(first_source)
680:     end
query(&block) click to toggle source

Translates a query block into a dataset. Query blocks can be useful when expressing complex SELECT statements, e.g.:

  dataset = DB[:items].query do
    select :x, :y, :z
    filter{|o| (o.x > 1) & (o.y > 2)}
    order :z.desc
  end

Which is the same as:

 dataset = DB[:items].select(:x, :y, :z).filter{|o| (o.x > 1) & (o.y > 2)}.order(:z.desc)

Note that inside a call to query, you cannot call each, insert, update, or delete (or any method that calls those), or Sequel will raise an error.

    # File lib/sequel/extensions/query.rb, line 30
30:     def query(&block)
31:       copy = clone({})
32:       copy.extend(QueryBlockCopy)
33:       copy.instance_eval(&block)
34:       clone(copy.opts)
35:     end
quote_identifier_append(sql, name) click to toggle source

Adds quoting to identifiers (columns and tables). If identifiers are not being quoted, returns name as a string. If identifiers are being quoted quote the name with quoted_identifier.

     # File lib/sequel/dataset/sql.rb, line 595
595:     def quote_identifier_append(sql, name)
596:       if name.is_a?(LiteralString)
597:         sql << name
598:       else
599:         name = name.value if name.is_a?(SQL::Identifier)
600:         name = input_identifier(name)
601:         if quote_identifiers?
602:           quoted_identifier_append(sql, name)
603:         else
604:           sql << name
605:         end
606:       end
607:     end
quote_identifiers?() click to toggle source

Whether this dataset quotes identifiers.

    # File lib/sequel/dataset/features.rb, line 10
10:     def quote_identifiers?
11:       if defined?(@quote_identifiers)
12:         @quote_identifiers
13:       elsif db.respond_to?(:quote_identifiers?)
14:         @quote_identifiers = db.quote_identifiers?
15:       else
16:         @quote_identifiers = false
17:       end
18:     end
quote_schema_table_append(sql, table) click to toggle source

Separates the schema from the table and returns a string with them quoted (if quoting identifiers)

     # File lib/sequel/dataset/sql.rb, line 611
611:     def quote_schema_table_append(sql, table)
612:       schema, table = schema_and_table(table)
613:       if schema
614:         quote_identifier_append(sql, schema)
615:         sql << DOT
616:       end
617:       quote_identifier_append(sql, table)
618:     end
quoted_identifier_append(sql, name) click to toggle source

This method quotes the given name with the SQL standard double quote. should be overridden by subclasses to provide quoting not matching the SQL standard, such as backtick (used by MySQL and SQLite).

     # File lib/sequel/dataset/sql.rb, line 623
623:     def quoted_identifier_append(sql, name)
624:       sql << QUOTE << name.to_s.gsub(QUOTE_RE, DOUBLE_QUOTE) << QUOTE
625:     end
range(column) click to toggle source

Returns a Range instance made from the minimum and maximum values for the given column.

  DB[:table].range(:id) # SELECT max(id) AS v1, min(id) AS v2 FROM table LIMIT 1
  # => 1..10
     # File lib/sequel/dataset/actions.rb, line 417
417:     def range(column)
418:       if r = aggregate_dataset.select{[min(column).as(v1), max(column).as(v2)]}.first
419:         (r[:v1]..r[:v2])
420:       end
421:     end
recursive_cte_requires_column_aliases?() click to toggle source

Whether you must use a column alias list for recursive CTEs (false by default).

    # File lib/sequel/dataset/features.rb, line 29
29:     def recursive_cte_requires_column_aliases?
30:       false
31:     end
requires_placeholder_type_specifiers?() click to toggle source

Whether type specifiers are required for prepared statement/bound variable argument placeholders (i.e. :bv__integer)

    # File lib/sequel/dataset/features.rb, line 41
41:     def requires_placeholder_type_specifiers?
42:       false
43:     end
requires_placeholder_type_specifiers?() click to toggle source

Oracle requires type specifiers for placeholders, at least if you ever want to use a nil/NULL value as the value for the placeholder.

     # File lib/sequel/adapters/oracle.rb, line 409
409:       def requires_placeholder_type_specifiers?
410:         true
411:       end
requires_sql_standard_datetimes?() click to toggle source

Whether the dataset requires SQL standard datetimes (false by default, as most allow strings with ISO 8601 format).

    # File lib/sequel/dataset/features.rb, line 35
35:     def requires_sql_standard_datetimes?
36:       false
37:     end
returning(*values) click to toggle source

Modify the RETURNING clause, only supported on a few databases. If returning is used, instead of insert returning the autogenerated primary key or update/delete returning the number of modified rows, results are returned using fetch_rows.

  DB[:items].returning # RETURNING *
  DB[:items].returning(nil) # RETURNING NULL
  DB[:items].returning(:id, :name) # RETURNING id, name
     # File lib/sequel/dataset/query.rb, line 690
690:     def returning(*values)
691:       clone(:returning=>values)
692:     end
reverse(*order) click to toggle source

Returns a copy of the dataset with the order reversed. If no order is given, the existing order is inverted.

  DB[:items].reverse(:id) # SELECT * FROM items ORDER BY id DESC
  DB[:items].order(:id).reverse # SELECT * FROM items ORDER BY id DESC
  DB[:items].order(:id).reverse(:name.asc) # SELECT * FROM items ORDER BY name ASC
     # File lib/sequel/dataset/query.rb, line 700
700:     def reverse(*order)
701:       order(*invert_order(order.empty? ? @opts[:order] : order))
702:     end
reverse_order(*order) click to toggle source

Alias of reverse

     # File lib/sequel/dataset/query.rb, line 705
705:     def reverse_order(*order)
706:       reverse(*order)
707:     end
row_number_column() click to toggle source

The alias to use for the row_number column, used when emulating OFFSET support and for eager limit strategies

     # File lib/sequel/dataset/misc.rb, line 147
147:     def row_number_column
148:       :x_sequel_row_number_x
149:     end
schema_and_table(table_name) click to toggle source

Split the schema information from the table

     # File lib/sequel/dataset/sql.rb, line 628
628:     def schema_and_table(table_name)
629:       sch = db.default_schema if db
630:       case table_name
631:       when Symbol
632:         s, t, a = split_symbol(table_name)
633:         [s||sch, t]
634:       when SQL::QualifiedIdentifier
635:         [table_name.table, table_name.column]
636:       when SQL::Identifier
637:         [sch, table_name.value]
638:       when String
639:         [sch, table_name]
640:       else
641:         raise Error, 'table_name should be a Symbol, SQL::QualifiedIdentifier, SQL::Identifier, or String'
642:       end
643:     end
select(*columns, &block) click to toggle source

Returns a copy of the dataset with the columns selected changed to the given columns. This also takes a virtual row block, similar to filter.

  DB[:items].select(:a) # SELECT a FROM items
  DB[:items].select(:a, :b) # SELECT a, b FROM items
  DB[:items].select{[a, sum(b)]} # SELECT a, sum(b) FROM items
     # File lib/sequel/dataset/query.rb, line 716
716:     def select(*columns, &block)
717:       virtual_row_columns(columns, block)
718:       m = []
719:       columns.each do |i|
720:         i.is_a?(Hash) ? m.concat(i.map{|k, v| SQL::AliasedExpression.new(k,v)}) : m << i
721:       end
722:       clone(:select => m)
723:     end
select_all(*tables) click to toggle source

Returns a copy of the dataset selecting the wildcard if no arguments are given. If arguments are given, treat them as tables and select all columns (using the wildcard) from each table.

  DB[:items].select(:a).select_all # SELECT * FROM items
  DB[:items].select_all(:items) # SELECT items.* FROM items
  DB[:items].select_all(:items, :foo) # SELECT items.*, foo.* FROM items
     # File lib/sequel/dataset/query.rb, line 732
732:     def select_all(*tables)
733:       if tables.empty?
734:         clone(:select => nil)
735:       else
736:         select(*tables.map{|t| i, a = split_alias(t); a || i}.map{|t| SQL::ColumnAll.new(t)})
737:       end
738:     end
select_append(*columns, &block) click to toggle source

Returns a copy of the dataset with the given columns added to the existing selected columns. If no columns are currently selected, it will select the columns given in addition to *.

  DB[:items].select(:a).select(:b) # SELECT b FROM items
  DB[:items].select(:a).select_append(:b) # SELECT a, b FROM items
  DB[:items].select_append(:b) # SELECT *, b FROM items
     # File lib/sequel/dataset/query.rb, line 747
747:     def select_append(*columns, &block)
748:       cur_sel = @opts[:select]
749:       if !cur_sel || cur_sel.empty?
750:         unless supports_select_all_and_column?
751:           return select_all(*(Array(@opts[:from]) + Array(@opts[:join]))).select_more(*columns, &block)
752:         end
753:         cur_sel = [WILDCARD]
754:       end
755:       select(*(cur_sel + columns), &block)
756:     end
select_group(*columns, &block) click to toggle source

Set both the select and group clauses with the given columns. Column aliases may be supplied, and will be included in the select clause. This also takes a virtual row block similar to filter.

  DB[:items].select_group(:a, :b)
  # SELECT a, b FROM items GROUP BY a, b

  DB[:items].select_group(:c___a){f(c2)}
  # SELECT c AS a, f(c2) FROM items GROUP BY c, f(c2)
     # File lib/sequel/dataset/query.rb, line 767
767:     def select_group(*columns, &block)
768:       virtual_row_columns(columns, block)
769:       select(*columns).group(*columns.map{|c| unaliased_identifier(c)})
770:     end
select_hash(key_column, value_column) click to toggle source

Returns a hash with key_column values as keys and value_column values as values. Similar to to_hash, but only selects the columns given.

  DB[:table].select_hash(:id, :name) # SELECT id, name FROM table
  # => {1=>'a', 2=>'b', ...}

You can also provide an array of column names for either the key_column, the value column, or both:

  DB[:table].select_hash([:id, :foo], [:name, :bar]) # SELECT * FROM table
  # {[1, 3]=>['a', 'c'], [2, 4]=>['b', 'd'], ...}

When using this method, you must be sure that each expression has an alias that Sequel can determine. Usually you can do this by calling the # method on the expression and providing an alias.

     # File lib/sequel/dataset/actions.rb, line 438
438:     def select_hash(key_column, value_column)
439:       _select_hash(:to_hash, key_column, value_column)
440:     end
select_hash_groups(key_column, value_column) click to toggle source

Returns a hash with key_column values as keys and an array of value_column values. Similar to to_hash_groups, but only selects the columns given.

  DB[:table].select_hash(:name, :id) # SELECT id, name FROM table
  # => {'a'=>[1, 4, ...], 'b'=>[2, ...], ...}

You can also provide an array of column names for either the key_column, the value column, or both:

  DB[:table].select_hash([:first, :middle], [:last, :id]) # SELECT * FROM table
  # {['a', 'b']=>[['c', 1], ['d', 2], ...], ...}

When using this method, you must be sure that each expression has an alias that Sequel can determine. Usually you can do this by calling the # method on the expression and providing an alias.

     # File lib/sequel/dataset/actions.rb, line 457
457:     def select_hash_groups(key_column, value_column)
458:       _select_hash(:to_hash_groups, key_column, value_column)
459:     end
select_map(column=nil, &block) click to toggle source

Selects the column given (either as an argument or as a block), and returns an array of all values of that column in the dataset. If you give a block argument that returns an array with multiple entries, the contents of the resulting array are undefined. Raises an Error if called with both an argument and a block.

  DB[:table].select_map(:id) # SELECT id FROM table
  # => [3, 5, 8, 1, ...]

  DB[:table].select_map{id * 2} # SELECT (id * 2) FROM table
  # => [6, 10, 16, 2, ...]

You can also provide an array of column names:

  DB[:table].select_map([:id, :name]) # SELECT id, name FROM table
  # => [[1, 'A'], [2, 'B'], [3, 'C'], ...]

If you provide an array of expressions, you must be sure that each entry in the array has an alias that Sequel can determine. Usually you can do this by calling the # method on the expression and providing an alias.

     # File lib/sequel/dataset/actions.rb, line 481
481:     def select_map(column=nil, &block)
482:       _select_map(column, false, &block)
483:     end
select_more(*columns, &block) click to toggle source

Returns a copy of the dataset with the given columns added to the existing selected columns. If no columns are currently selected it will just select the columns given.

  DB[:items].select(:a).select(:b) # SELECT b FROM items
  DB[:items].select(:a).select_more(:b) # SELECT a, b FROM items
  DB[:items].select_more(:b) # SELECT b FROM items
     # File lib/sequel/dataset/query.rb, line 779
779:     def select_more(*columns, &block)
780:       columns = @opts[:select] + columns if @opts[:select]
781:       select(*columns, &block)
782:     end
select_order_map(column=nil, &block) click to toggle source

The same as select_map, but in addition orders the array by the column.

  DB[:table].select_order_map(:id) # SELECT id FROM table ORDER BY id
  # => [1, 2, 3, 4, ...]

  DB[:table].select_order_map{id * 2} # SELECT (id * 2) FROM table ORDER BY (id * 2)
  # => [2, 4, 6, 8, ...]

You can also provide an array of column names:

  DB[:table].select_order_map([:id, :name]) # SELECT id, name FROM table ORDER BY id, name
  # => [[1, 'A'], [2, 'B'], [3, 'C'], ...]

If you provide an array of expressions, you must be sure that each entry in the array has an alias that Sequel can determine. Usually you can do this by calling the # method on the expression and providing an alias.

     # File lib/sequel/dataset/actions.rb, line 501
501:     def select_order_map(column=nil, &block)
502:       _select_map(column, true, &block)
503:     end
select_remove(*cols) click to toggle source

Remove columns from the list of selected columns. If any of the currently selected columns use expressions/aliases, this will remove selected columns with the given aliases. It will also remove entries from the selection that match exactly:

  # Assume columns a, b, and c in items table
  DB[:items] # SELECT * FROM items
  DB[:items].select_remove(:c) # SELECT a, b FROM items
  DB[:items].select(:a, :b___c, :c___b).select_remove(:c) # SELECT a, c AS b FROM items
  DB[:items].select(:a, :b___c, :c___b).select_remove(:c___b) # SELECT a, b AS c FROM items

Note that there are a few cases where this method may not work correctly:

  • This dataset joins multiple tables and does not have an existing explicit selection. In this case, the code will currently use unqualified column names for all columns the dataset returns, except for the columns given.

  • This dataset has an existing explicit selection containing an item that returns multiple database columns (e.g. :table.*, ‘column1, column2’.lit). In this case, the behavior is undefined and this method should not be used.

There may be other cases where this method does not work correctly, use it with caution.

    # File lib/sequel/extensions/select_remove.rb, line 27
27:     def select_remove(*cols)
28:       if (sel = @opts[:select]) && !sel.empty?
29:         select(*(columns.zip(sel).reject{|c, s| cols.include?(c)}.map{|c, s| s} - cols))
30:       else
31:         select(*(columns - cols))
32:       end
33:     end
select_sql() click to toggle source

Returns a SELECT SQL query string.

  dataset.select_sql # => "SELECT * FROM items"
     # File lib/sequel/dataset/sql.rb, line 138
138:     def select_sql
139:       return static_sql(@opts[:sql]) if @opts[:sql]
140:       clause_sql(:select)
141:     end
server(servr) click to toggle source

Set the server for this dataset to use. Used to pick a specific database shard to run a query against, or to override the default (where SELECT uses :read_only database and all other queries use the :default database). This method is always available but is only useful when database sharding is being used.

  DB[:items].all # Uses the :read_only or :default server 
  DB[:items].delete # Uses the :default server
  DB[:items].server(:blah).delete # Uses the :blah server
     # File lib/sequel/dataset/query.rb, line 793
793:     def server(servr)
794:       clone(:server=>servr)
795:     end
set(*args) click to toggle source

Alias for update, but not aliased directly so subclasses don’t have to override both methods.

     # File lib/sequel/dataset/actions.rb, line 507
507:     def set(*args)
508:       update(*args)
509:     end
set_defaults(hash) click to toggle source

Set the default values for insert and update statements. The values hash passed to insert or update are merged into this hash, so any values in the hash passed to insert or update will override values passed to this method.

  DB[:items].set_defaults(:a=>'a', :c=>'c').insert(:a=>'d', :b=>'b')
  # INSERT INTO items (a, c, b) VALUES ('d', 'c', 'b')
     # File lib/sequel/dataset/query.rb, line 803
803:     def set_defaults(hash)
804:       clone(:defaults=>(@opts[:defaults]||{}).merge(hash))
805:     end
set_graph_aliases(graph_aliases) click to toggle source

This allows you to manually specify the graph aliases to use when using graph. You can use it to only select certain columns, and have those columns mapped to specific aliases in the result set. This is the equivalent of select for a graphed dataset, and must be used instead of select whenever graphing is used.

graph_aliases

Should be a hash with keys being symbols of column aliases, and values being either symbols or arrays with one to three elements. If the value is a symbol, it is assumed to be the same as a one element array containing that symbol. The first element of the array should be the table alias symbol. The second should be the actual column name symbol. If the array only has a single element the column name symbol will be assumed to be the same as the corresponding hash key. If the array has a third element, it is used as the value returned, instead of table_alias.column_name.

  DB[:artists].graph(:albums, :artist_id=>:id).
    set_graph_aliases(:name=>:artists,
                      :album_name=>[:albums, :name],
                      :forty_two=>[:albums, :fourtwo, 42]).first
  # SELECT artists.name, albums.name AS album_name, 42 AS forty_two ...
  # => {:artists=>{:name=>artists.name}, :albums=>{:name=>albums.name, :fourtwo=>42}}
     # File lib/sequel/dataset/graph.rb, line 230
230:     def set_graph_aliases(graph_aliases)
231:       columns, graph_aliases = graph_alias_columns(graph_aliases)
232:       ds = select(*columns)
233:       ds.opts[:graph_aliases] = graph_aliases
234:       ds
235:     end
set_overrides(hash) click to toggle source

Set values that override hash arguments given to insert and update statements. This hash is merged into the hash provided to insert or update, so values will override any values given in the insert/update hashes.

  DB[:items].set_overrides(:a=>'a', :c=>'c').insert(:a=>'d', :b=>'b')
  # INSERT INTO items (a, c, b) VALUES ('a', 'c', 'b')
     # File lib/sequel/dataset/query.rb, line 813
813:     def set_overrides(hash)
814:       clone(:overrides=>hash.merge(@opts[:overrides]||{}))
815:     end
single_record() click to toggle source

Returns the first record in the dataset, or nil if the dataset has no records. Users should probably use first instead of this method.

     # File lib/sequel/dataset/actions.rb, line 514
514:     def single_record
515:       clone(:limit=>1).each{|r| return r}
516:       nil
517:     end
single_value() click to toggle source

Returns the first value of the first record in the dataset. Returns nil if dataset is empty. Users should generally use get instead of this method.

     # File lib/sequel/dataset/actions.rb, line 522
522:     def single_value
523:       if r = naked.ungraphed.single_record
524:         r.values.first
525:       end
526:     end
split_alias(c) click to toggle source

Splits a possible implicit alias in c, handling both SQL::AliasedExpressions and Symbols. Returns an array of two elements, with the first being the main expression, and the second being the alias.

     # File lib/sequel/dataset/misc.rb, line 154
154:     def split_alias(c)
155:       case c
156:       when Symbol
157:         c_table, column, aliaz = split_symbol(c)
158:         [c_table ? SQL::QualifiedIdentifier.new(c_table, column.to_sym) : column.to_sym, aliaz]
159:       when SQL::AliasedExpression
160:         [c.expression, c.aliaz]
161:       when SQL::JoinClause
162:         [c.table, c.table_alias]
163:       else
164:         [c, nil]
165:       end
166:     end
split_multiple_result_sets() click to toggle source

Makes each yield arrays of rows, with each array containing the rows for a given result set. Does not work with graphing. So you can submit SQL with multiple statements and easily determine which statement returned which results.

Modifies the row_proc of the returned dataset so that it still works as expected (running on the hashes instead of on the arrays of hashes). If you modify the row_proc afterward, note that it will receive an array of hashes instead of a hash.

     # File lib/sequel/adapters/mysql.rb, line 333
333:       def split_multiple_result_sets
334:         raise(Error, "Can't split multiple statements on a graphed dataset") if opts[:graph]
335:         ds = clone(:split_multiple_result_sets=>true)
336:         ds.row_proc = proc{|x| x.map{|h| row_proc.call(h)}} if row_proc
337:         ds
338:       end
sql() click to toggle source

Same as select_sql, not aliased directly to make subclassing simpler.

     # File lib/sequel/dataset/sql.rb, line 144
144:     def sql
145:       select_sql
146:     end
subscript_sql_append(sql, s) click to toggle source

SQL fragment for specifying subscripts (SQL array accesses)

     # File lib/sequel/dataset/sql.rb, line 646
646:     def subscript_sql_append(sql, s)
647:       literal_append(sql, s.f)
648:       sql << BRACKET_OPEN
649:       expression_list_append(sql, s.sub)
650:       sql << BRACKET_CLOSE
651:     end
sum(column) click to toggle source

Returns the sum for the given column.

  DB[:table].sum(:id) # SELECT sum(id) FROM table LIMIT 1
  # => 55
     # File lib/sequel/dataset/actions.rb, line 532
532:     def sum(column)
533:       aggregate_dataset.get{sum(column)}
534:     end
supports_cte?(type=:select) click to toggle source

Whether the dataset supports common table expressions (the WITH clause). If given, type can be :select, :insert, :update, or :delete, in which case it determines whether WITH is supported for the respective statement type.

    # File lib/sequel/dataset/features.rb, line 48
48:     def supports_cte?(type=:select)
49:       send(:"#{type}_clause_methods").include?(:"#{type}_with_sql")
50:     end
supports_cte_in_subqueries?() click to toggle source

Whether the dataset supports common table expressions (the WITH clause) in subqueries. If false, applies the WITH clause to the main query, which can cause issues if multiple WITH clauses use the same name.

    # File lib/sequel/dataset/features.rb, line 55
55:     def supports_cte_in_subqueries?
56:       false
57:     end
supports_distinct_on?() click to toggle source

Whether the dataset supports or can emulate the DISTINCT ON clause, false by default.

    # File lib/sequel/dataset/features.rb, line 60
60:     def supports_distinct_on?
61:       false
62:     end
supports_group_cube?() click to toggle source

Whether the dataset supports CUBE with GROUP BY.

    # File lib/sequel/dataset/features.rb, line 65
65:     def supports_group_cube?
66:       false
67:     end
supports_group_rollup?() click to toggle source

Whether the dataset supports ROLLUP with GROUP BY.

    # File lib/sequel/dataset/features.rb, line 70
70:     def supports_group_rollup?
71:       false
72:     end
supports_insert_select?() click to toggle source

Whether this dataset supports the insert_select method for returning all columns values directly from an insert query.

    # File lib/sequel/dataset/features.rb, line 76
76:     def supports_insert_select?
77:       supports_returning?(:insert)
78:     end
supports_intersect_except?() click to toggle source

Whether the dataset supports the INTERSECT and EXCEPT compound operations, true by default.

    # File lib/sequel/dataset/features.rb, line 81
81:     def supports_intersect_except?
82:       true
83:     end
supports_intersect_except_all?() click to toggle source

Whether the dataset supports the INTERSECT ALL and EXCEPT ALL compound operations, true by default.

    # File lib/sequel/dataset/features.rb, line 86
86:     def supports_intersect_except_all?
87:       true
88:     end
supports_is_true?() click to toggle source

Whether the dataset supports the IS TRUE syntax.

    # File lib/sequel/dataset/features.rb, line 91
91:     def supports_is_true?
92:       true
93:     end
supports_join_using?() click to toggle source

Whether the dataset supports the JOIN table USING (column1, …) syntax.

    # File lib/sequel/dataset/features.rb, line 96
96:     def supports_join_using?
97:       true
98:     end
supports_modifying_joins?() click to toggle source

Whether modifying joined datasets is supported.

     # File lib/sequel/dataset/features.rb, line 101
101:     def supports_modifying_joins?
102:       false
103:     end
supports_multiple_column_in?() click to toggle source

Whether the IN/NOT IN operators support multiple columns when an array of values is given.

     # File lib/sequel/dataset/features.rb, line 107
107:     def supports_multiple_column_in?
108:       true
109:     end
supports_ordered_distinct_on?() click to toggle source

Whether the dataset supports or can fully emulate the DISTINCT ON clause, including respecting the ORDER BY clause, false by default

     # File lib/sequel/dataset/features.rb, line 113
113:     def supports_ordered_distinct_on?
114:       supports_distinct_on?
115:     end
supports_returning?(type) click to toggle source

Whether the RETURNING clause is supported for the given type of query. type can be :insert, :update, or :delete.

     # File lib/sequel/dataset/features.rb, line 119
119:     def supports_returning?(type)
120:       send(:"#{type}_clause_methods").include?(:"#{type}_returning_sql")
121:     end
supports_select_all_and_column?() click to toggle source

Whether the database supports SELECT *, column FROM table

     # File lib/sequel/dataset/features.rb, line 124
124:     def supports_select_all_and_column?
125:       true
126:     end
supports_timestamp_timezones?() click to toggle source

Whether the dataset supports timezones in literal timestamps

     # File lib/sequel/dataset/features.rb, line 129
129:     def supports_timestamp_timezones?
130:       false
131:     end
supports_timestamp_usecs?() click to toggle source

Whether the dataset supports fractional seconds in literal timestamps

     # File lib/sequel/dataset/features.rb, line 134
134:     def supports_timestamp_usecs?
135:       true
136:     end
supports_where_true?() click to toggle source

Whether the dataset supports WHERE TRUE (or WHERE 1 for databases that that use 1 for true).

     # File lib/sequel/dataset/features.rb, line 145
145:     def supports_where_true?
146:       true
147:     end
supports_window_functions?() click to toggle source

Whether the dataset supports window functions.

     # File lib/sequel/dataset/features.rb, line 139
139:     def supports_window_functions?
140:       false
141:     end
to_csv(include_column_titles = true) click to toggle source

Returns a string in CSV format containing the dataset records. By default the CSV representation includes the column titles in the first line. You can turn that off by passing false as the include_column_titles argument.

This does not use a CSV library or handle quoting of values in any way. If any values in any of the rows could include commas or line endings, you shouldn’t use this.

  puts DB[:table].to_csv # SELECT * FROM table
  # id,name
  # 1,Jim
  # 2,Bob
     # File lib/sequel/dataset/actions.rb, line 549
549:     def to_csv(include_column_titles = true)
550:       n = naked
551:       cols = n.columns
552:       csv = ''
553:       csv << "#{cols.join(COMMA_SEPARATOR)}\r\n" if include_column_titles
554:       n.each{|r| csv << "#{cols.collect{|c| r[c]}.join(COMMA_SEPARATOR)}\r\n"}
555:       csv
556:     end
to_dot() click to toggle source

Return a string that can be processed by the dot program (included with graphviz) in order to see a visualization of the dataset’s abstract syntax tree.

     # File lib/sequel/extensions/to_dot.rb, line 145
145:     def to_dot
146:       ToDot.output(self)
147:     end
to_hash(key_column, value_column = nil) click to toggle source

Returns a hash with one column used as key and another used as value. If rows have duplicate values for the key column, the latter row(s) will overwrite the value of the previous row(s). If the value_column is not given or nil, uses the entire hash as the value.

  DB[:table].to_hash(:id, :name) # SELECT * FROM table
  # {1=>'Jim', 2=>'Bob', ...}

  DB[:table].to_hash(:id) # SELECT * FROM table
  # {1=>{:id=>1, :name=>'Jim'}, 2=>{:id=>2, :name=>'Bob'}, ...}

You can also provide an array of column names for either the key_column, the value column, or both:

  DB[:table].to_hash([:id, :foo], [:name, :bar]) # SELECT * FROM table
  # {[1, 3]=>['Jim', 'bo'], [2, 4]=>['Bob', 'be'], ...}

  DB[:table].to_hash([:id, :name]) # SELECT * FROM table
  # {[1, 'Jim']=>{:id=>1, :name=>'Jim'}, [2, 'Bob'=>{:id=>2, :name=>'Bob'}, ...}
     # File lib/sequel/dataset/actions.rb, line 577
577:     def to_hash(key_column, value_column = nil)
578:       h = {}
579:       if value_column
580:         return naked.to_hash(key_column, value_column) if row_proc
581:         if value_column.is_a?(Array)
582:           if key_column.is_a?(Array)
583:             each{|r| h[r.values_at(*key_column)] = r.values_at(*value_column)}
584:           else
585:             each{|r| h[r[key_column]] = r.values_at(*value_column)}
586:           end
587:         else
588:           if key_column.is_a?(Array)
589:             each{|r| h[r.values_at(*key_column)] = r[value_column]}
590:           else
591:             each{|r| h[r[key_column]] = r[value_column]}
592:           end
593:         end
594:       elsif key_column.is_a?(Array)
595:         each{|r| h[r.values_at(*key_column)] = r}
596:       else
597:         each{|r| h[r[key_column]] = r}
598:       end
599:       h
600:     end
to_hash_groups(key_column, value_column = nil) click to toggle source

Returns a hash with one column used as key and the values being an array of column values. If the value_column is not given or nil, uses the entire hash as the value.

  DB[:table].to_hash(:name, :id) # SELECT * FROM table
  # {'Jim'=>[1, 4, 16, ...], 'Bob'=>[2], ...}

  DB[:table].to_hash(:name) # SELECT * FROM table
  # {'Jim'=>[{:id=>1, :name=>'Jim'}, {:id=>4, :name=>'Jim'}, ...], 'Bob'=>[{:id=>2, :name=>'Bob'}], ...}

You can also provide an array of column names for either the key_column, the value column, or both:

  DB[:table].to_hash([:first, :middle], [:last, :id]) # SELECT * FROM table
  # {['Jim', 'Bob']=>[['Smith', 1], ['Jackson', 4], ...], ...}

  DB[:table].to_hash([:first, :middle]) # SELECT * FROM table
  # {['Jim', 'Bob']=>[{:id=>1, :first=>'Jim', :middle=>'Bob', :last=>'Smith'}, ...], ...}
     # File lib/sequel/dataset/actions.rb, line 620
620:     def to_hash_groups(key_column, value_column = nil)
621:       h = {}
622:       if value_column
623:         return naked.to_hash_groups(key_column, value_column) if row_proc
624:         if value_column.is_a?(Array)
625:           if key_column.is_a?(Array)
626:             each{|r| (h[r.values_at(*key_column)] ||= []) << r.values_at(*value_column)}
627:           else
628:             each{|r| (h[r[key_column]] ||= []) << r.values_at(*value_column)}
629:           end
630:         else
631:           if key_column.is_a?(Array)
632:             each{|r| (h[r.values_at(*key_column)] ||= []) << r[value_column]}
633:           else
634:             each{|r| (h[r[key_column]] ||= []) << r[value_column]}
635:           end
636:         end
637:       elsif key_column.is_a?(Array)
638:         each{|r| (h[r.values_at(*key_column)] ||= []) << r}
639:       else
640:         each{|r| (h[r[key_column]] ||= []) << r}
641:       end
642:       h
643:     end
truncate() click to toggle source

Truncates the dataset. Returns nil.

  DB[:table].truncate # TRUNCATE table
  # => nil
     # File lib/sequel/dataset/actions.rb, line 649
649:     def truncate
650:       execute_ddl(truncate_sql)
651:     end
truncate_sql() click to toggle source

Returns a TRUNCATE SQL query string. See truncate

  DB[:items].truncate_sql # => 'TRUNCATE items'
     # File lib/sequel/dataset/sql.rb, line 151
151:     def truncate_sql
152:       if opts[:sql]
153:         static_sql(opts[:sql])
154:       else
155:         check_truncation_allowed!
156:         raise(InvalidOperation, "Can't truncate filtered datasets") if opts[:where] || opts[:having]
157:         _truncate_sql(source_list(opts[:from]))
158:       end
159:     end
unbind() click to toggle source

Unbind bound variables from this dataset’s filter and return an array of two objects. The first object is a modified dataset where the filter has been replaced with one that uses bound variable placeholders. The second object is the hash of unbound variables. You can then prepare and execute (or just call) the dataset with the bound variables to get results.

  ds, bv = DB[:items].filter(:a=>1).unbind
  ds # SELECT * FROM items WHERE (a = $a)
  bv #  {:a => 1}
  ds.call(:select, bv)
     # File lib/sequel/dataset/query.rb, line 827
827:     def unbind
828:       u = Unbinder.new
829:       ds = clone(:where=>u.transform(opts[:where]), :join=>u.transform(opts[:join]))
830:       [ds, u.binds]
831:     end
unfiltered() click to toggle source

Returns a copy of the dataset with no filters (HAVING or WHERE clause) applied.

  DB[:items].group(:a).having(:a=>1).where(:b).unfiltered
  # SELECT * FROM items GROUP BY a
     # File lib/sequel/dataset/query.rb, line 837
837:     def unfiltered
838:       clone(:where => nil, :having => nil)
839:     end
ungraphed() click to toggle source

Remove the splitting of results into subhashes, and all metadata related to the current graph (if any).

     # File lib/sequel/dataset/graph.rb, line 239
239:     def ungraphed
240:       clone(:graph=>nil, :graph_aliases=>nil)
241:     end
ungrouped() click to toggle source

Returns a copy of the dataset with no grouping (GROUP or HAVING clause) applied.

  DB[:items].group(:a).having(:a=>1).where(:b).ungrouped
  # SELECT * FROM items WHERE b
     # File lib/sequel/dataset/query.rb, line 845
845:     def ungrouped
846:       clone(:group => nil, :having => nil)
847:     end
union(dataset, opts={}) click to toggle source

Adds a UNION clause using a second dataset object. A UNION compound dataset returns all rows in either the current dataset or the given dataset. Options:

:alias

Use the given value as the from_self alias

:all

Set to true to use UNION ALL instead of UNION, so duplicate rows can occur

:from_self

Set to false to not wrap the returned dataset in a from_self, use with care.

  DB[:items].union(DB[:other_items])
  # SELECT * FROM (SELECT * FROM items UNION SELECT * FROM other_items) AS t1

  DB[:items].union(DB[:other_items], :all=>true, :from_self=>false)
  # SELECT * FROM items UNION ALL SELECT * FROM other_items

  DB[:items].union(DB[:other_items], :alias=>:i)
  # SELECT * FROM (SELECT * FROM items UNION SELECT * FROM other_items) AS i
     # File lib/sequel/dataset/query.rb, line 865
865:     def union(dataset, opts={})
866:       opts = {:all=>opts} unless opts.is_a?(Hash)
867:       compound_clone(:union, dataset, opts)
868:     end
unlimited() click to toggle source

Returns a copy of the dataset with no limit or offset.

  DB[:items].limit(10, 20).unlimited # SELECT * FROM items
     # File lib/sequel/dataset/query.rb, line 873
873:     def unlimited
874:       clone(:limit=>nil, :offset=>nil)
875:     end
unordered() click to toggle source

Returns a copy of the dataset with no order.

  DB[:items].order(:a).unordered # SELECT * FROM items
     # File lib/sequel/dataset/query.rb, line 880
880:     def unordered
881:       order(nil)
882:     end
unused_table_alias(table_alias, used_aliases = []) click to toggle source

Creates a unique table alias that hasn’t already been used in the dataset. table_alias can be any type of object accepted by alias_symbol. The symbol returned will be the implicit alias in the argument, possibly appended with “_N” if the implicit alias has already been used, where N is an integer starting at 0 and increasing until an unused one is found.

You can provide a second addition array argument containing symbols that should not be considered valid table aliases. The current aliases for the FROM and JOIN tables are automatically included in this array.

  DB[:table].unused_table_alias(:t)
  # => :t

  DB[:table].unused_table_alias(:table)
  # => :table_0

  DB[:table, :table_0].unused_table_alias(:table)
  # => :table_1

  DB[:table, :table_0].unused_table_alias(:table, [:table_1, :table_2])
  # => :table_3
     # File lib/sequel/dataset/misc.rb, line 190
190:     def unused_table_alias(table_alias, used_aliases = [])
191:       table_alias = alias_symbol(table_alias)
192:       used_aliases += opts[:from].map{|t| alias_symbol(t)} if opts[:from]
193:       used_aliases += opts[:join].map{|j| j.table_alias ? alias_alias_symbol(j.table_alias) : alias_symbol(j.table)} if opts[:join]
194:       if used_aliases.include?(table_alias)
195:         i = 0
196:         loop do
197:           ta = :"#{table_alias}_#{i}"
198:           return ta unless used_aliases.include?(ta)
199:           i += 1 
200:         end
201:       else
202:         table_alias
203:       end
204:     end
update(values={}, &block) click to toggle source

Updates values for the dataset. The returned value is generally the number of rows updated, but that is adapter dependent. values should a hash where the keys are columns to set and values are the values to which to set the columns.

  DB[:table].update(:x=>nil) # UPDATE table SET x = NULL
  # => 10

  DB[:table].update(:x=>:x+1, :y=>0) # UPDATE table SET x = (x + 1), y = 0
  # => 10
     # File lib/sequel/dataset/actions.rb, line 663
663:     def update(values={}, &block)
664:       sql = update_sql(values)
665:       if uses_returning?(:update)
666:         returning_fetch_rows(sql, &block)
667:       else
668:         execute_dui(sql)
669:       end
670:     end
update_sql(values = {}) click to toggle source

Formats an UPDATE statement using the given values. See update.

  DB[:items].update_sql(:price => 100, :category => 'software')
  # => "UPDATE items SET price = 100, category = 'software'

Raises an Error if the dataset is grouped or includes more than one table.

     # File lib/sequel/dataset/sql.rb, line 168
168:     def update_sql(values = {})
169:       return static_sql(opts[:sql]) if opts[:sql]
170:       check_modification_allowed!
171:       clone(:values=>values)._update_sql
172:     end
use_cursor(opts={}) click to toggle source

Uses a cursor for fetching records, instead of fetching the entire result set at once. Can be used to process large datasets without holding all rows in memory (which is what the underlying drivers do by default). Options:

  • :rows_per_fetch - the number of rows per fetch (default 1000). Higher numbers result in fewer queries but greater memory use.

Usage:

  DB[:huge_table].use_cursor.each{|row| p row}
  DB[:huge_table].use_cursor(:rows_per_fetch=>10000).each{|row| p row}

This is untested with the prepared statement/bound variable support, and unlikely to work with either.

     # File lib/sequel/adapters/postgres.rb, line 584
584:       def use_cursor(opts={})
585:         clone(:cursor=>{:rows_per_fetch=>1000}.merge(opts))
586:       end
where(*cond, &block) click to toggle source

Add a condition to the WHERE clause. See filter for argument types.

  DB[:items].group(:a).having(:a).filter(:b)
  # SELECT * FROM items GROUP BY a HAVING a AND b

  DB[:items].group(:a).having(:a).where(:b)
  # SELECT * FROM items WHERE b GROUP BY a HAVING a
     # File lib/sequel/dataset/query.rb, line 891
891:     def where(*cond, &block)
892:       _filter(:where, *cond, &block)
893:     end
window_function_sql_append(sql, function, window) click to toggle source

The SQL fragment for the given window function’s function and window.

     # File lib/sequel/dataset/sql.rb, line 695
695:     def window_function_sql_append(sql, function, window)
696:       literal_append(sql, function)
697:       sql << OVER
698:       literal_append(sql, window)
699:     end
window_sql_append(sql, opts) click to toggle source

The SQL fragment for the given window’s options.

     # File lib/sequel/dataset/sql.rb, line 654
654:     def window_sql_append(sql, opts)
655:       raise(Error, 'This dataset does not support window functions') unless supports_window_functions?
656:       sql << PAREN_OPEN
657:       window, part, order, frame = opts.values_at(:window, :partition, :order, :frame)
658:       space = false
659:       space_s = SPACE
660:       if window
661:         literal_append(sql, window)
662:         space = true
663:       end
664:       if part
665:         sql << space_s if space
666:         sql << PARTITION_BY
667:         expression_list_append(sql, Array(part))
668:         space = true
669:       end
670:       if order
671:         sql << space_s if space
672:         sql << ORDER_BY_NS
673:         expression_list_append(sql, Array(order))
674:         space = true
675:       end
676:       case frame
677:         when nil
678:           # nothing
679:         when :all
680:           sql << space_s if space
681:           sql << FRAME_ALL
682:         when :rows
683:           sql << space_s if space
684:           sql << FRAME_ROWS
685:         when String
686:           sql << space_s if space
687:           sql << frame
688:         else
689:           raise Error, "invalid window frame clause, should be :all, :rows, a string, or nil"
690:       end
691:       sql << PAREN_CLOSE
692:     end
with(name, dataset, opts={}) click to toggle source

Add a common table expression (CTE) with the given name and a dataset that defines the CTE. A common table expression acts as an inline view for the query. Options:

:args

Specify the arguments/columns for the CTE, should be an array of symbols.

:recursive

Specify that this is a recursive CTE

  DB[:items].with(:items, DB[:syx].filter(:name.like('A%')))
  # WITH items AS (SELECT * FROM syx WHERE (name LIKE 'A%')) SELECT * FROM items
     # File lib/sequel/dataset/query.rb, line 903
903:     def with(name, dataset, opts={})
904:       raise(Error, 'This datatset does not support common table expressions') unless supports_cte?
905:       if hoist_cte?(dataset)
906:         s, ds = hoist_cte(dataset)
907:         s.with(name, ds, opts)
908:       else
909:         clone(:with=>(@opts[:with]||[]) + [opts.merge(:name=>name, :dataset=>dataset)])
910:       end
911:     end
with_recursive(name, nonrecursive, recursive, opts={}) click to toggle source

Add a recursive common table expression (CTE) with the given name, a dataset that defines the nonrecursive part of the CTE, and a dataset that defines the recursive part of the CTE. Options:

:args

Specify the arguments/columns for the CTE, should be an array of symbols.

:union_all

Set to false to use UNION instead of UNION ALL combining the nonrecursive and recursive parts.

  DB[:t].select(:i___id, :pi___parent_id).
   with_recursive(:t,
                  DB[:i1].filter(:parent_id=>nil),
                  DB[:t].join(:t, :i=>:parent_id).select(:i1__id, :i1__parent_id),
                  :args=>[:i, :pi])
  # WITH RECURSIVE t(i, pi) AS (
  #   SELECT * FROM i1 WHERE (parent_id IS NULL)
  #   UNION ALL
  #   SELECT i1.id, i1.parent_id FROM t INNER JOIN t ON (t.i = t.parent_id)
  # )
  # SELECT i AS id, pi AS parent_id FROM t
     # File lib/sequel/dataset/query.rb, line 930
930:     def with_recursive(name, nonrecursive, recursive, opts={})
931:       raise(Error, 'This datatset does not support common table expressions') unless supports_cte?
932:       if hoist_cte?(nonrecursive)
933:         s, ds = hoist_cte(nonrecursive)
934:         s.with_recursive(name, ds, recursive, opts)
935:       elsif hoist_cte?(recursive)
936:         s, ds = hoist_cte(recursive)
937:         s.with_recursive(name, nonrecursive, ds, opts)
938:       else
939:         clone(:with=>(@opts[:with]||[]) + [opts.merge(:recursive=>true, :name=>name, :dataset=>nonrecursive.union(recursive, {:all=>opts[:union_all] != false, :from_self=>false}))])
940:       end
941:     end
with_sql(sql, *args) click to toggle source

Returns a copy of the dataset with the static SQL used. This is useful if you want to keep the same row_proc/graph, but change the SQL used to custom SQL.

  DB[:items].with_sql('SELECT * FROM foo') # SELECT * FROM foo

You can use placeholders in your SQL and provide arguments for those placeholders:

  DB[:items].with_sql('SELECT ? FROM foo', 1) # SELECT 1 FROM foo

You can also provide a method name and arguments to call to get the SQL:

  DB[:items].with_sql(:insert_sql, :b=>1) # INSERT INTO items (b) VALUES (1)
     # File lib/sequel/dataset/query.rb, line 955
955:     def with_sql(sql, *args)
956:       if sql.is_a?(Symbol)
957:         sql = send(sql, *args)
958:       else
959:         sql = SQL::PlaceholderLiteralString.new(sql, args) unless args.empty?
960:       end
961:       clone(:sql=>sql)
962:     end
with_sql_delete(sql) click to toggle source

Execute the given SQL and return the number of rows deleted. This exists solely as an optimization, replacing with_sql(sql).delete. It’s significantly faster as it does not require cloning the current dataset.

     # File lib/sequel/dataset/actions.rb, line 675
675:     def with_sql_delete(sql)
676:       execute_dui(sql)
677:     end

Protected Instance Methods

_import(columns, values, opts) click to toggle source

Internals of #. If primary key values are requested, use separate insert commands for each row. Otherwise, call # and execute each statement it gives separately.

     # File lib/sequel/dataset/actions.rb, line 684
684:     def _import(columns, values, opts)
685:       trans_opts = opts.merge(:server=>@opts[:server])
686:       if opts[:return] == :primary_key
687:         @db.transaction(trans_opts){values.map{|v| insert(columns, v)}}
688:       else
689:         stmts = multi_insert_sql(columns, values)
690:         @db.transaction(trans_opts){stmts.each{|st| execute_dui(st)}}
691:       end
692:     end
_insert_sql() click to toggle source

Formats in INSERT statement using the stored columns and values.

     # File lib/sequel/dataset/sql.rb, line 704
704:     def _insert_sql
705:       clause_sql(:insert)
706:     end
_select_map_multiple(ret_cols) click to toggle source

Return an array of arrays of values given by the symbols in ret_cols.

     # File lib/sequel/dataset/actions.rb, line 695
695:     def _select_map_multiple(ret_cols)
696:       map{|r| r.values_at(*ret_cols)}
697:     end
_select_map_single() click to toggle source

Returns an array of the first value in each row.

     # File lib/sequel/dataset/actions.rb, line 700
700:     def _select_map_single
701:       map{|r| r.values.first}
702:     end
_update_sql() click to toggle source

Formats an UPDATE statement using the stored values.

     # File lib/sequel/dataset/sql.rb, line 709
709:     def _update_sql
710:       clause_sql(:update)
711:     end
compound_clone(type, dataset, opts) click to toggle source

Add the dataset to the list of compounds

     # File lib/sequel/dataset/query.rb, line 967
967:     def compound_clone(type, dataset, opts)
968:       if hoist_cte?(dataset)
969:         s, ds = hoist_cte(dataset)
970:         return s.compound_clone(type, ds, opts)
971:       end
972:       ds = compound_from_self.clone(:compounds=>Array(@opts[:compounds]).map{|x| x.dup} + [[type, dataset.compound_from_self, opts[:all]]])
973:       opts[:from_self] == false ? ds : ds.from_self(opts)
974:     end
compound_from_self() click to toggle source

Return a from_self dataset if an order or limit is specified, so it works as expected with UNION, EXCEPT, and INTERSECT clauses.

     # File lib/sequel/dataset/sql.rb, line 715
715:     def compound_from_self
716:       (@opts[:limit] || @opts[:order]) ? from_self : self
717:     end
options_overlap(opts) click to toggle source

Return true if the dataset has a non-nil value for any key in opts.

     # File lib/sequel/dataset/query.rb, line 977
977:     def options_overlap(opts)
978:       !(@opts.collect{|k,v| k unless v.nil?}.compact & opts).empty?
979:     end
simple_select_all?() click to toggle source

Whether this dataset is a simple SELECT * FROM table.

     # File lib/sequel/dataset/query.rb, line 982
982:     def simple_select_all?
983:       o = @opts.reject{|k,v| v.nil? || NON_SQL_OPTIONS.include?(k)}
984:       o.length == 1 && (f = o[:from]) && f.length == 1 && (f.first.is_a?(Symbol) || f.first.is_a?(SQL::AliasedExpression))
985:     end
to_prepared_statement(type, values=nil) click to toggle source

Return a cloned copy of the current dataset extended with PreparedStatementMethods, setting the type and modify values.

     # File lib/sequel/dataset/prepared_statements.rb, line 260
260:     def to_prepared_statement(type, values=nil)
261:       ps = bind
262:       ps.extend(PreparedStatementMethods)
263:       ps.orig_dataset = self
264:       ps.prepared_type = type
265:       ps.prepared_modify_values = values
266:       ps
267:     end

Private Instance Methods

_filter(clause, *cond, &block) click to toggle source

Internal filter method so it works on either the having or where clauses.

      # File lib/sequel/dataset/query.rb, line 1003
1003:     def _filter(clause, *cond, &block)
1004:       _filter_or_exclude(false, clause, *cond, &block)
1005:     end
_filter_or_exclude(invert, clause, *cond, &block) click to toggle source

Internal filter/exclude method so it works on either the having or where clauses.

      # File lib/sequel/dataset/query.rb, line 990
 990:     def _filter_or_exclude(invert, clause, *cond, &block)
 991:       cond = cond.first if cond.size == 1
 992:       if cond.respond_to?(:empty?) && cond.empty? && !block
 993:         clone
 994:       else
 995:         cond = filter_expr(cond, &block)
 996:         cond = SQL::BooleanExpression.invert(cond) if invert
 997:         cond = SQL::BooleanExpression.new(:AND, @opts[clause], cond) if @opts[clause]
 998:         clone(clause => cond)
 999:       end
1000:     end
_select_hash(meth, key_column, value_column) click to toggle source

Internals of select_hash and select_hash_groups

     # File lib/sequel/dataset/actions.rb, line 707
707:     def _select_hash(meth, key_column, value_column)
708:       if key_column.is_a?(Array)
709:         if value_column.is_a?(Array)
710:           select(*(key_column + value_column)).send(meth, key_column.map{|c| hash_key_symbol(c)}, value_column.map{|c| hash_key_symbol(c)})
711:         else
712:           select(*(key_column + [value_column])).send(meth, key_column.map{|c| hash_key_symbol(c)}, hash_key_symbol(value_column))
713:         end
714:       elsif value_column.is_a?(Array)
715:         select(key_column, *value_column).send(meth, hash_key_symbol(key_column), value_column.map{|c| hash_key_symbol(c)})
716:       else
717:         select(key_column, value_column).send(meth, hash_key_symbol(key_column), hash_key_symbol(value_column))
718:       end
719:     end
_select_map(column, order, &block) click to toggle source

Internals of select_map and select_order_map

     # File lib/sequel/dataset/actions.rb, line 722
722:     def _select_map(column, order, &block)
723:       ds = naked.ungraphed
724:       columns = Array(column)
725:       virtual_row_columns(columns, block)
726:       select_cols = order ? columns.map{|c| c.is_a?(SQL::OrderedExpression) ? c.expression : c} : columns
727:       ds = ds.select(*select_cols)
728:       ds = ds.order(*columns.map{|c| unaliased_identifier(c)}) if order
729:       if column.is_a?(Array) || (columns.length > 1)
730:         ds._select_map_multiple(select_cols.map{|c| hash_key_symbol(c)})
731:       else
732:         ds._select_map_single
733:       end
734:     end
_truncate_sql(table) click to toggle source

Formats the truncate statement. Assumes the table given has already been literalized.

     # File lib/sequel/dataset/sql.rb, line 723
723:     def _truncate_sql(table)
724:       "TRUNCATE TABLE #{table}"
725:     end
aggregate_dataset() click to toggle source

Clone of this dataset usable in aggregate operations. Does a from_self if dataset contains any parameters that would affect normal aggregation, or just removes an existing order if not.

     # File lib/sequel/dataset/sql.rb, line 766
766:     def aggregate_dataset
767:       options_overlap(COUNT_FROM_SELF_OPTS) ? from_self : unordered
768:     end
alias_alias_symbol(s) click to toggle source

Returns an appropriate symbol for the alias represented by s.

     # File lib/sequel/dataset/sql.rb, line 728
728:     def alias_alias_symbol(s)
729:       case s
730:       when Symbol
731:         s
732:       when String
733:         s.to_sym
734:       when SQL::Identifier
735:         s.value.to_s.to_sym
736:       else
737:         raise Error, "Invalid alias for alias_alias_symbol: #{s.inspect}"
738:       end
739:     end
alias_symbol(sym) click to toggle source

Returns an appropriate alias symbol for the given object, which can be a Symbol, String, SQL::Identifier, SQL::QualifiedIdentifier, or SQL::AliasedExpression.

     # File lib/sequel/dataset/sql.rb, line 744
744:     def alias_symbol(sym)
745:       case sym
746:       when Symbol
747:         s, t, a = split_symbol(sym)
748:         a || s ? (a || t).to_sym : sym
749:       when String
750:         sym.to_sym
751:       when SQL::Identifier
752:         sym.value.to_s.to_sym
753:       when SQL::QualifiedIdentifier
754:         alias_symbol(sym.column)
755:       when SQL::AliasedExpression
756:         alias_alias_symbol(sym.aliaz)
757:       else
758:         raise Error, "Invalid alias for alias_symbol: #{sym.inspect}"
759:       end
760:     end
argument_list_append(sql, args) click to toggle source
     # File lib/sequel/dataset/sql.rb, line 770
770:     def argument_list_append(sql, args)
771:       c = false
772:       comma = COMMA
773:       args.each do |a|
774:         sql << comma if c
775:         sql << a.to_s
776:         c ||= true
777:       end
778:     end
as_sql_append(sql, aliaz) click to toggle source

SQL fragment for specifying an alias. expression should already be literalized.

     # File lib/sequel/dataset/sql.rb, line 781
781:     def as_sql_append(sql, aliaz)
782:       sql << AS
783:       quote_identifier_append(sql, aliaz)
784:     end
check_modification_allowed!() click to toggle source

Raise an InvalidOperation exception if deletion is not allowed for this dataset

     # File lib/sequel/dataset/sql.rb, line 788
788:     def check_modification_allowed!
789:       raise(InvalidOperation, "Grouped datasets cannot be modified") if opts[:group]
790:       raise(InvalidOperation, "Joined datasets cannot be modified") if !supports_modifying_joins? && joined_dataset?
791:     end
check_truncation_allowed!() click to toggle source

Alias of check_modification_allowed!

     # File lib/sequel/dataset/sql.rb, line 794
794:     def check_truncation_allowed!
795:       check_modification_allowed!
796:     end
clause_sql(type) click to toggle source

Prepare an SQL statement by calling all clause methods for the given statement type.

     # File lib/sequel/dataset/sql.rb, line 799
799:     def clause_sql(type)
800:       sql = @opts[:append_sql] || sql_string_origin
801:       send("#{type}_clause_methods").each{|x| send(x, sql)}
802:       sql
803:     end
column_list_append(sql, columns) click to toggle source

Converts an array of column names into a comma seperated string of column names. If the array is empty, a wildcard (*) is returned.

     # File lib/sequel/dataset/sql.rb, line 807
807:     def column_list_append(sql, columns)
808:       if (columns.nil? || columns.empty?)
809:         sql << WILDCARD
810:       else
811:         expression_list_append(sql, columns)
812:       end
813:     end
complex_expression_arg_pairs(args) click to toggle source

Yield each two pair of arguments to the block, which should return a string representing the SQL code for those two arguments. If more than 2 arguments are provided, all calls to the block # after the first will have a LiteralString as the first argument, representing the application of the block to the previous arguments.

     # File lib/sequel/dataset/sql.rb, line 821
821:     def complex_expression_arg_pairs(args)
822:       case args.length
823:       when 1
824:         literal(args.at(0))
825:       when 2
826:         yield args.at(0), args.at(1)
827:       else
828:         args.inject{|m, a| LiteralString.new(yield(m, a))}
829:       end
830:     end
compound_dataset_sql_append(sql, ds) click to toggle source

The SQL to use for the dataset used in a UNION/INTERSECT/EXCEPT clause.

     # File lib/sequel/dataset/sql.rb, line 833
833:     def compound_dataset_sql_append(sql, ds)
834:       subselect_sql_append(sql, ds)
835:     end
cursor_fetch_rows(sql) click to toggle source

Use a cursor to fetch groups of records at a time, yielding them to the block.

     # File lib/sequel/adapters/postgres.rb, line 703
703:       def cursor_fetch_rows(sql)
704:         server_opts = {:server=>@opts[:server] || :read_only}
705:         db.transaction(server_opts) do 
706:           begin
707:             execute_ddl("DECLARE sequel_cursor NO SCROLL CURSOR WITHOUT HOLD FOR #{sql}", server_opts)
708:             rows_per_fetch = @opts[:cursor][:rows_per_fetch].to_i
709:             rows_per_fetch = 1000 if rows_per_fetch <= 0
710:             fetch_sql = "FETCH FORWARD #{rows_per_fetch} FROM sequel_cursor"
711:             cols = nil
712:             # Load columns only in the first fetch, so subsequent fetches are faster
713:             execute(fetch_sql) do |res|
714:               cols = fetch_rows_set_cols(res)
715:               yield_hash_rows(res, cols){|h| yield h}
716:               return if res.ntuples < rows_per_fetch
717:             end
718:             loop do
719:               execute(fetch_sql) do |res|
720:                 yield_hash_rows(res, cols){|h| yield h}
721:                 return if res.ntuples < rows_per_fetch
722:               end
723:             end
724:           ensure
725:             execute_ddl("CLOSE sequel_cursor", server_opts)
726:           end
727:         end
728:       end
dataset_alias(number) click to toggle source

The alias to use for datasets, takes a number to make sure the name is unique.

     # File lib/sequel/dataset/sql.rb, line 838
838:     def dataset_alias(number)
839:       :"#{DATASET_ALIAS_BASE_NAME}#{number}"
840:     end
default_server() click to toggle source

Return self if the dataset already has a server, or a cloned dataset with the default server otherwise.

      # File lib/sequel/dataset/query.rb, line 1079
1079:     def default_server
1080:       @opts[:server] ? self : clone(:server=>:default)
1081:     end
default_server_opts(opts) click to toggle source

Set the server to use to :default unless it is already set in the passed opts

     # File lib/sequel/dataset/actions.rb, line 737
737:     def default_server_opts(opts)
738:       {:server=>@opts[:server] || :default}.merge(opts)
739:     end
default_timestamp_format() click to toggle source

The strftime format to use when literalizing the time.

     # File lib/sequel/dataset/sql.rb, line 843
843:     def default_timestamp_format
844:       requires_sql_standard_datetimes? ? STANDARD_TIMESTAMP_FORMAT : TIMESTAMP_FORMAT
845:     end
delete_clause_methods() click to toggle source

The order of methods to call to build the DELETE SQL statement

     # File lib/sequel/dataset/sql.rb, line 848
848:     def delete_clause_methods
849:       DELETE_CLAUSE_METHODS
850:     end
delete_delete_sql(sql) click to toggle source
     # File lib/sequel/dataset/sql.rb, line 852
852:     def delete_delete_sql(sql)
853:       sql << DELETE
854:     end
delete_from_sql(sql) click to toggle source
Alias for: select_from_sql
delete_order_sql(sql) click to toggle source
Alias for: select_order_sql
delete_returning_sql(sql) click to toggle source
delete_where_sql(sql) click to toggle source
Alias for: select_where_sql
delete_with_sql(sql) click to toggle source
Alias for: select_with_sql
empty_array_value(op, cols) click to toggle source
     # File lib/sequel/dataset/sql.rb, line 868
868:     def empty_array_value(op, cols)
869:       if Sequel.empty_array_handle_nulls
870:         c = Array(cols)
871:         SQL::BooleanExpression.from_value_pairs(c.zip(c), :AND, op == :IN)
872:       else
873:         {1 => ((op == :IN) ? 0 : 1)}
874:       end
875:     end
execute(sql, opts={}, &block) click to toggle source

Execute the given select SQL on the database using execute. Use the :read_only server unless a specific server is set.

     # File lib/sequel/dataset/actions.rb, line 743
743:     def execute(sql, opts={}, &block)
744:       @db.execute(sql, {:server=>@opts[:server] || :read_only}.merge(opts), &block)
745:     end
execute(sql, opts={}, &block) click to toggle source

Set the :type option to :select if it hasn’t been set.

     # File lib/sequel/adapters/mysql.rb, line 343
343:       def execute(sql, opts={}, &block)
344:         super(sql, {:type=>:select}.merge(opts), &block)
345:       end
execute_ddl(sql, opts={}, &block) click to toggle source

Execute the given SQL on the database using execute_ddl.

     # File lib/sequel/dataset/actions.rb, line 748
748:     def execute_ddl(sql, opts={}, &block)
749:       @db.execute_ddl(sql, default_server_opts(opts), &block)
750:       nil
751:     end
execute_dui(sql, opts={}, &block) click to toggle source

Execute the given SQL on the database using execute_dui.

     # File lib/sequel/dataset/actions.rb, line 754
754:     def execute_dui(sql, opts={}, &block)
755:       @db.execute_dui(sql, default_server_opts(opts), &block)
756:     end
execute_insert(sql, opts={}, &block) click to toggle source

Execute the given SQL on the database using execute_insert.

     # File lib/sequel/dataset/actions.rb, line 759
759:     def execute_insert(sql, opts={}, &block)
760:       @db.execute_insert(sql, default_server_opts(opts), &block)
761:     end
expression_list_append(sql, columns) click to toggle source

Converts an array of expressions into a comma separated string of expressions.

     # File lib/sequel/dataset/sql.rb, line 858
858:     def expression_list_append(sql, columns)
859:       c = false
860:       co = COMMA
861:       columns.each do |col|
862:         sql << co if c
863:         literal_append(sql, col)
864:         c ||= true
865:       end
866:     end
fetch_rows_set_cols(res) click to toggle source

Set the @columns based on the result set, and return the array of field numers, type conversion procs, and name symbol arrays.

     # File lib/sequel/adapters/postgres.rb, line 732
732:       def fetch_rows_set_cols(res)
733:         cols = []
734:         procs = db.conversion_procs
735:         res.nfields.times do |fieldnum|
736:           cols << [fieldnum, procs[res.ftype(fieldnum)], output_identifier(res.fname(fieldnum))]
737:         end
738:         @columns = cols.map{|c| c.at(2)}
739:         cols
740:       end
filter_expr(expr = nil, &block) click to toggle source

SQL expression object based on the expr type. See filter.

      # File lib/sequel/dataset/query.rb, line 1008
1008:     def filter_expr(expr = nil, &block)
1009:       expr = nil if expr == []
1010:       if expr && block
1011:         return SQL::BooleanExpression.new(:AND, filter_expr(expr), filter_expr(block))
1012:       elsif block
1013:         expr = block
1014:       end
1015:       case expr
1016:       when Hash
1017:         SQL::BooleanExpression.from_value_pairs(expr)
1018:       when Array
1019:         if (sexpr = expr.at(0)).is_a?(String)
1020:           SQL::PlaceholderLiteralString.new(sexpr, expr[1..1], true)
1021:         elsif Sequel.condition_specifier?(expr)
1022:           SQL::BooleanExpression.from_value_pairs(expr)
1023:         else
1024:           SQL::BooleanExpression.new(:AND, *expr.map{|x| filter_expr(x)})
1025:         end
1026:       when Proc
1027:         filter_expr(Sequel.virtual_row(&expr))
1028:       when SQL::NumericExpression, SQL::StringExpression
1029:         raise(Error, "Invalid SQL Expression type: #{expr.inspect}") 
1030:       when Symbol, SQL::Expression
1031:         expr
1032:       when TrueClass, FalseClass
1033:         if supports_where_true?
1034:           SQL::BooleanExpression.new(:NOOP, expr)
1035:         elsif expr
1036:           SQL::Constants::SQLTRUE
1037:         else
1038:           SQL::Constants::SQLFALSE
1039:         end
1040:       when String
1041:         LiteralString.new("(#{expr})")
1042:       else
1043:         raise(Error, 'Invalid filter argument')
1044:       end
1045:     end
format_timestamp(v) click to toggle source

Format the timestamp based on the default_timestamp_format, with a couple of modifiers. First, allow %N to be used for fractions seconds (if the database supports them), and override %z to always use a numeric offset of hours and minutes.

     # File lib/sequel/dataset/sql.rb, line 881
881:     def format_timestamp(v)
882:       v2 = db.from_application_timestamp(v)
883:       fmt = default_timestamp_format.gsub(FORMAT_TIMESTAMP_RE) do |m|
884:         if m == FORMAT_USEC
885:           format_timestamp_usec(v.is_a?(DateTime) ? v.sec_fraction*(RUBY_VERSION < V190 ? 86400000000 : 1000000) : v.usec) if supports_timestamp_usecs?
886:         else
887:           if supports_timestamp_timezones?
888:             # Would like to just use %z format, but it doesn't appear to work on Windows
889:             # Instead, the offset fragment is constructed manually
890:             minutes = (v2.is_a?(DateTime) ? v2.offset * 1440 : v2.utc_offset/60).to_i
891:             format_timestamp_offset(*minutes.divmod(60))
892:           end
893:         end
894:       end
895:       v2.strftime(fmt)
896:     end
format_timestamp_offset(hour, minute) click to toggle source

Return the SQL timestamp fragment to use for the timezone offset.

     # File lib/sequel/dataset/sql.rb, line 899
899:     def format_timestamp_offset(hour, minute)
900:       sprintf(FORMAT_OFFSET, hour, minute)
901:     end
format_timestamp_usec(usec) click to toggle source

Return the SQL timestamp fragment to use for the fractional time part. Should start with the decimal point. Uses 6 decimal places by default.

     # File lib/sequel/dataset/sql.rb, line 905
905:     def format_timestamp_usec(usec)
906:       sprintf(FORMAT_TIMESTAMP_USEC, usec)
907:     end
graph_alias_columns(graph_aliases) click to toggle source

Transform the hash of graph aliases and return a two element array where the first element is an array of identifiers suitable to pass to a select method, and the second is a new hash of preprocessed graph aliases.

     # File lib/sequel/dataset/graph.rb, line 248
248:     def graph_alias_columns(graph_aliases)
249:       gas = {}
250:       identifiers = graph_aliases.collect do |col_alias, tc| 
251:         table, column, value = Array(tc)
252:         column ||= col_alias
253:         gas[col_alias] = [table, column]
254:         identifier = value || SQL::QualifiedIdentifier.new(table, column)
255:         identifier = SQL::AliasedExpression.new(identifier, col_alias) if value || column != col_alias
256:         identifier
257:       end
258:       [identifiers, gas]
259:     end
graph_each() click to toggle source

Fetch the rows, split them into component table parts, tranform and run the row_proc on each part (if applicable), and yield a hash of the parts.

     # File lib/sequel/dataset/graph.rb, line 264
264:     def graph_each
265:       # Reject tables with nil datasets, as they are excluded from
266:       # the result set
267:       datasets = @opts[:graph][:table_aliases].to_a.reject{|ta,ds| ds.nil?}
268:       # Get just the list of table aliases into a local variable, for speed
269:       table_aliases = datasets.collect{|ta,ds| ta}
270:       # Get an array of arrays, one for each dataset, with
271:       # the necessary information about each dataset, for speed
272:       datasets = datasets.collect{|ta, ds| [ta, ds, ds.row_proc]}
273:       # Use the manually set graph aliases, if any, otherwise
274:       # use the ones automatically created by .graph
275:       column_aliases = @opts[:graph_aliases] || @opts[:graph][:column_aliases]
276:       fetch_rows(select_sql) do |r|
277:         graph = {}
278:         # Create the sub hashes, one per table
279:         table_aliases.each{|ta| graph[ta]={}}
280:         # Split the result set based on the column aliases
281:         # If there are columns in the result set that are
282:         # not in column_aliases, they are ignored
283:         column_aliases.each do |col_alias, tc|
284:           ta, column = tc
285:           graph[ta][column] = r[col_alias]
286:         end
287:         # For each dataset run the row_proc if applicable
288:         datasets.each do |ta,ds,rp|
289:           g = graph[ta]
290:           graph[ta] = if g.values.any?{|x| !x.nil?}
291:             rp ? rp.call(g) : g
292:           else
293:             nil
294:           end
295:         end
296: 
297:         yield graph
298:       end
299:       self
300:     end
hash_key_symbol(s) click to toggle source

Return a plain symbol given a potentially qualified or aliased symbol, specifying the symbol that is likely to be used as the hash key for the column when records are returned.

     # File lib/sequel/dataset/actions.rb, line 766
766:     def hash_key_symbol(s)
767:       case s
768:       when Symbol
769:         _, c, a = split_symbol(s)
770:         (a || c).to_sym
771:       when SQL::Identifier
772:         hash_key_symbol(s.value)
773:       when SQL::QualifiedIdentifier
774:         hash_key_symbol(s.column)
775:       when SQL::AliasedExpression
776:         hash_key_symbol(s.aliaz)
777:       when String
778:         s.to_sym
779:       else
780:         raise(Error, "#{s.inspect} is not supported, should be a Symbol, String, SQL::Identifier, SQL::QualifiedIdentifier, or SQL::AliasedExpression") 
781:       end
782:     end
hoist_cte(ds) click to toggle source

Return two datasets, the first a clone of the receiver with the WITH clause from the given dataset added to it, and the second a clone of the given dataset with the WITH clause removed.

      # File lib/sequel/dataset/query.rb, line 1050
1050:     def hoist_cte(ds)
1051:       [clone(:with => (opts[:with] || []) + ds.opts[:with]), ds.clone(:with => nil)]
1052:     end
hoist_cte?(ds) click to toggle source

Whether CTEs need to be hoisted from the given ds into the current ds.

      # File lib/sequel/dataset/query.rb, line 1055
1055:     def hoist_cte?(ds)
1056:       ds.is_a?(Dataset) && ds.opts[:with] && !supports_cte_in_subqueries?
1057:     end
identifier_append(sql, v) click to toggle source

Append the value, but special case regular (non-literal, non-blob) strings so that they are considered as identifiers and not SQL strings.

     # File lib/sequel/dataset/sql.rb, line 911
911:     def identifier_append(sql, v)
912:       if v.is_a?(String)
913:         case v
914:         when LiteralString
915:           sql << v
916:         when SQL::Blob
917:           literal_append(sql, v)
918:         else
919:           quote_identifier_append(sql, v)
920:         end
921:       else
922:         literal_append(sql, v)
923:       end
924:     end
Also aliased as: table_ref_append
input_identifier(v) click to toggle source

Modify the identifier returned from the database based on the identifier_output_method.

     # File lib/sequel/dataset/sql.rb, line 929
929:     def input_identifier(v)
930:       (i = identifier_input_method) ? v.to_s.send(i) : v.to_s
931:     end
insert_clause_methods() click to toggle source

The order of methods to call to build the INSERT SQL statement

     # File lib/sequel/dataset/sql.rb, line 940
940:     def insert_clause_methods
941:       INSERT_CLAUSE_METHODS
942:     end
insert_columns_sql(sql) click to toggle source

SQL fragment specifying the columns to insert into

     # File lib/sequel/dataset/sql.rb, line 945
945:     def insert_columns_sql(sql)
946:       columns = opts[:columns]
947:       if columns && !columns.empty?
948:         sql << PAREN_SPACE_OPEN
949:         c = false
950:         co = COMMA
951:         columns.each do |col|
952:           sql << co if c
953:           identifier_append(sql, col)
954:           c ||= true
955:         end
956:         sql << PAREN_CLOSE
957:       end 
958:     end
insert_insert_sql(sql) click to toggle source
     # File lib/sequel/dataset/sql.rb, line 960
960:     def insert_insert_sql(sql)
961:       sql << INSERT
962:     end
insert_into_sql(sql) click to toggle source

SQL fragment specifying the table to insert INTO

     # File lib/sequel/dataset/sql.rb, line 934
934:     def insert_into_sql(sql)
935:       sql << INTO
936:       source_list_append(sql, @opts[:from])
937:     end
insert_returning_sql(sql) click to toggle source

SQL fragment specifying the values to return.

     # File lib/sequel/dataset/sql.rb, line 985
985:     def insert_returning_sql(sql)
986:       if opts.has_key?(:returning)
987:         sql << RETURNING
988:         column_list_append(sql, Array(opts[:returning]))
989:       end
990:     end
insert_supports_empty_values?() click to toggle source

Whether insert(nil) or insert({}) must be emulated by using at least one value, false by default.

     # File lib/sequel/dataset/features.rb, line 153
153:     def insert_supports_empty_values?
154:       true
155:     end
insert_values_sql(sql) click to toggle source

SQL fragment specifying the values to insert.

     # File lib/sequel/dataset/sql.rb, line 965
965:     def insert_values_sql(sql)
966:       case values = opts[:values]
967:       when Array
968:         if values.empty?
969:           sql << DEFAULT_VALUES
970:         else
971:           sql << VALUES
972:           literal_append(sql, values)
973:         end
974:       when Dataset
975:         sql << SPACE
976:         subselect_sql_append(sql, values)
977:       when LiteralString
978:         sql << SPACE << values
979:       else
980:         raise Error, "Unsupported INSERT values type, should be an Array or Dataset: #{values.inspect}"
981:       end
982:     end
insert_with_sql(sql) click to toggle source
Alias for: select_with_sql
invert_order(order) click to toggle source

Inverts the given order by breaking it into a list of column references and inverting them.

  DB[:items].invert_order([:id.desc]]) #=> [:id]
  DB[:items].invert_order(:category, :price.desc]) #=> [:category.desc, :price]
      # File lib/sequel/dataset/query.rb, line 1064
1064:     def invert_order(order)
1065:       return nil unless order
1066:       new_order = []
1067:       order.map do |f|
1068:         case f
1069:         when SQL::OrderedExpression
1070:           f.invert
1071:         else
1072:           SQL::OrderedExpression.new(f)
1073:         end
1074:       end
1075:     end
join_type_sql(join_type) click to toggle source

SQL fragment specifying a JOIN type, converts underscores to spaces and upcases.

     # File lib/sequel/dataset/sql.rb, line 996
996:     def join_type_sql(join_type)
997:       "#{join_type.to_s.gsub(UNDERSCORE, SPACE).upcase} JOIN"
998:     end
joined_dataset?() click to toggle source

Whether this dataset is a joined dataset

      # File lib/sequel/dataset/sql.rb, line 1001
1001:     def joined_dataset?
1002:      (opts[:from].is_a?(Array) && opts[:from].size > 1) || opts[:join]
1003:     end
literal_array_append(sql, v) click to toggle source

SQL fragment for Array. Treats as an expression if an array of all two pairs, or as a SQL array otherwise.

      # File lib/sequel/dataset/sql.rb, line 1006
1006:     def literal_array_append(sql, v)
1007:       if Sequel.condition_specifier?(v)
1008:         literal_expression_append(sql, SQL::BooleanExpression.from_value_pairs(v))
1009:       else
1010:         array_sql_append(sql, v)
1011:       end
1012:     end
literal_big_decimal(v) click to toggle source

SQL fragment for BigDecimal

      # File lib/sequel/dataset/sql.rb, line 1015
1015:     def literal_big_decimal(v)
1016:       d = v.to_s("F")
1017:       v.nan? || v.infinite? ?  "'#{d}'" : d
1018:     end
literal_blob_append(sql, v) click to toggle source

SQL fragment for SQL::Blob

      # File lib/sequel/dataset/sql.rb, line 1021
1021:     def literal_blob_append(sql, v)
1022:       literal_string_append(sql, v)
1023:     end
literal_blob_append(sql, v) click to toggle source

Use the driver’s escape_bytea

     # File lib/sequel/adapters/postgres.rb, line 743
743:       def literal_blob_append(sql, v)
744:         sql << APOS << db.synchronize{|c| c.escape_bytea(v)} << APOS
745:       end
literal_dataset_append(sql, v) click to toggle source

SQL fragment for Dataset. Does a subselect inside parantheses.

      # File lib/sequel/dataset/sql.rb, line 1026
1026:     def literal_dataset_append(sql, v)
1027:       sql << PAREN_OPEN
1028:       subselect_sql_append(sql, v)
1029:       sql << PAREN_CLOSE
1030:     end
literal_date(v) click to toggle source

SQL fragment for Date, using the ISO8601 format.

      # File lib/sequel/dataset/sql.rb, line 1033
1033:     def literal_date(v)
1034:       if requires_sql_standard_datetimes?
1035:         v.strftime(FORMAT_DATE_STANDARD)
1036:       else
1037:         v.strftime(FORMAT_DATE)
1038:       end
1039:     end
literal_datetime(v) click to toggle source

SQL fragment for DateTime

      # File lib/sequel/dataset/sql.rb, line 1042
1042:     def literal_datetime(v)
1043:       format_timestamp(v)
1044:     end
literal_expression_append(sql, v) click to toggle source

SQL fragment for SQL::Expression, result depends on the specific type of expression.

      # File lib/sequel/dataset/sql.rb, line 1047
1047:     def literal_expression_append(sql, v)
1048:       v.to_s_append(self, sql)
1049:     end
literal_false() click to toggle source

SQL fragment for false

      # File lib/sequel/dataset/sql.rb, line 1052
1052:     def literal_false
1053:       BOOL_FALSE
1054:     end
literal_float(v) click to toggle source

SQL fragment for Float

      # File lib/sequel/dataset/sql.rb, line 1057
1057:     def literal_float(v)
1058:       v.to_s
1059:     end
literal_hash_append(sql, v) click to toggle source

SQL fragment for Hash, treated as an expression

      # File lib/sequel/dataset/sql.rb, line 1062
1062:     def literal_hash_append(sql, v)
1063:       literal_expression_append(sql, SQL::BooleanExpression.from_value_pairs(v))
1064:     end
literal_integer(v) click to toggle source

SQL fragment for Integer

      # File lib/sequel/dataset/sql.rb, line 1067
1067:     def literal_integer(v)
1068:       v.to_s
1069:     end
literal_nil() click to toggle source

SQL fragment for nil

      # File lib/sequel/dataset/sql.rb, line 1072
1072:     def literal_nil
1073:       NULL
1074:     end
literal_other_append(sql, v) click to toggle source

SQL fragment for a type of object not handled by Dataset#literal. Calls sql_literal if object responds to it, otherwise raises an error. Classes implementing sql_literal should call a class-specific method on the dataset provided and should add that method to Sequel::Dataset, allowing for adapters to provide customized literalizations. If a database specific type is allowed, this should be overriden in a subclass.

      # File lib/sequel/dataset/sql.rb, line 1082
1082:     def literal_other_append(sql, v)
1083:       if v.respond_to?(:sql_literal_append)
1084:         v.sql_literal_append(self, sql)
1085:       elsif v.respond_to?(:sql_literal)
1086:         sql << v.sql_literal(self)
1087:       else
1088:         raise Error, "can't express #{v.inspect} as a SQL literal"
1089:       end
1090:     end
literal_other_append(sql, v) click to toggle source
     # File lib/sequel/adapters/oracle.rb, line 415
415:       def literal_other_append(sql, v)
416:         case v
417:         when OraDate
418:           literal_append(sql, db.to_application_timestamp(v))
419:         when OCI8::CLOB
420:           v.rewind
421:           literal_append(sql, v.read)
422:         else
423:           super
424:         end
425:       end
literal_sqltime(v) click to toggle source

SQL fragment for Sequel::SQLTime, containing just the time part

      # File lib/sequel/dataset/sql.rb, line 1093
1093:     def literal_sqltime(v)
1094:       v.strftime("'%H:%M:%S#{format_timestamp_usec(v.usec) if supports_timestamp_usecs?}'")
1095:     end
literal_string_append(sql, v) click to toggle source

Use the driver’s escape_string

     # File lib/sequel/adapters/postgres.rb, line 748
748:       def literal_string_append(sql, v)
749:         sql << APOS << db.synchronize{|c| c.escape_string(v)} << APOS
750:       end
literal_string_append(sql, v) click to toggle source

SQL fragment for String. Doubles \ and ’ by default.

      # File lib/sequel/dataset/sql.rb, line 1098
1098:     def literal_string_append(sql, v)
1099:       sql << APOS << v.gsub(APOS_RE, DOUBLE_APOS) << APOS
1100:     end
literal_string_append(sql, v) click to toggle source

Handle correct quoting of strings using ::MySQL.quote.

     # File lib/sequel/adapters/mysql.rb, line 348
348:       def literal_string_append(sql, v)
349:         sql << "'"
350:         sql << ::Mysql.quote(v)
351:         sql << "'"
352:       end
literal_symbol_append(sql, v) click to toggle source

Converts a symbol into a column name. This method supports underscore notation in order to express qualified (two underscores) and aliased (three underscores) columns:

  dataset.literal(:abc) #=> "abc"
  dataset.literal(:abc___a) #=> "abc AS a"
  dataset.literal(:items__abc) #=> "items.abc"
  dataset.literal(:items__abc___a) #=> "items.abc AS a"
      # File lib/sequel/dataset/sql.rb, line 1110
1110:     def literal_symbol_append(sql, v)
1111:       c_table, column, c_alias = split_symbol(v)
1112:       if c_table
1113:         quote_identifier_append(sql, c_table)
1114:         sql << DOT
1115:       end
1116:       quote_identifier_append(sql, column)
1117:       as_sql_append(sql, c_alias) if c_alias
1118:     end
literal_time(v) click to toggle source

SQL fragment for Time

      # File lib/sequel/dataset/sql.rb, line 1121
1121:     def literal_time(v)
1122:       format_timestamp(v)
1123:     end
literal_true() click to toggle source

SQL fragment for true

      # File lib/sequel/dataset/sql.rb, line 1126
1126:     def literal_true
1127:       BOOL_TRUE
1128:     end
mutation_method(meth, *args, &block) click to toggle source

Modify the receiver with the results of sending the meth, args, and block to the receiver and merging the options of the resulting dataset into the receiver’s options.

    # File lib/sequel/dataset/mutation.rb, line 54
54:     def mutation_method(meth, *args, &block)
55:       copy = send(meth, *args, &block)
56:       @opts.merge!(copy.opts)
57:       self
58:     end
offset_returns_row_number_column?() click to toggle source

Whether using an offset returns an extra row number column that should be eliminated, false by default.

     # File lib/sequel/dataset/features.rb, line 159
159:     def offset_returns_row_number_column?
160:       false
161:     end
output_identifier(v) click to toggle source

Modify the identifier returned from the database based on the identifier_output_method.

     # File lib/sequel/dataset/actions.rb, line 786
786:     def output_identifier(v)
787:       v = 'untitled' if v == ''
788:       (i = identifier_output_method) ? v.to_s.send(i).to_sym : v.to_sym
789:     end
post_load(all_records) click to toggle source

This is run inside .all, after all of the records have been loaded via .each, but before any block passed to all is called. It is called with a single argument, an array of all returned records. Does nothing by default, added to make the model eager loading code simpler.

     # File lib/sequel/dataset/actions.rb, line 795
795:     def post_load(all_records)
796:     end
prepared_arg_placeholder() click to toggle source
     # File lib/sequel/adapters/oracle.rb, line 427
427:       def prepared_arg_placeholder
428:         PREPARED_ARG_PLACEHOLDER
429:       end
prepared_arg_placeholder() click to toggle source

The argument placeholder. Most databases used unnumbered arguments with question marks, so that is the default.

     # File lib/sequel/dataset/prepared_statements.rb, line 273
273:     def prepared_arg_placeholder
274:       PREPARED_ARG_PLACEHOLDER
275:     end
qualified_column_name(column, table) click to toggle source

Returns a qualified column name (including a table name) if the column name isn’t already qualified.

      # File lib/sequel/dataset/sql.rb, line 1132
1132:     def qualified_column_name(column, table)
1133:       if Symbol === column 
1134:         c_table, column, c_alias = split_symbol(column)
1135:         unless c_table
1136:           case table
1137:           when Symbol
1138:             schema, table, t_alias = split_symbol(table)
1139:             t_alias ||= Sequel::SQL::QualifiedIdentifier.new(schema, table) if schema
1140:           when Sequel::SQL::AliasedExpression
1141:             t_alias = table.aliaz
1142:           end
1143:           c_table = t_alias || table
1144:         end
1145:         ::Sequel::SQL::QualifiedIdentifier.new(c_table, column)
1146:       else
1147:         column
1148:       end
1149:     end
qualified_expression(e, table) click to toggle source

Qualify the given expression e to the given table.

      # File lib/sequel/dataset/sql.rb, line 1152
1152:     def qualified_expression(e, table)
1153:       Qualifier.new(self, table).transform(e)
1154:     end
returning_fetch_rows(sql, &block) click to toggle source

Called by insert/update/delete when returning is used. Yields each row as a plain hash to the block if one is given, or returns an array of plain hashes for all rows if a block is not given

     # File lib/sequel/dataset/actions.rb, line 801
801:     def returning_fetch_rows(sql, &block)
802:       if block
803:         default_server.fetch_rows(sql, &block)
804:         nil
805:       else
806:         rows = []
807:         default_server.fetch_rows(sql){|r| rows << r}
808:         rows
809:       end
810:     end
select_clause_methods() click to toggle source

The order of methods to call to build the SELECT SQL statement

      # File lib/sequel/dataset/sql.rb, line 1157
1157:     def select_clause_methods
1158:       SELECT_CLAUSE_METHODS
1159:     end
select_columns_sql(sql) click to toggle source

Modify the sql to add the columns selected

      # File lib/sequel/dataset/sql.rb, line 1162
1162:     def select_columns_sql(sql)
1163:       sql << SPACE
1164:       column_list_append(sql, @opts[:select])
1165:     end
select_compounds_sql(sql) click to toggle source

Modify the sql to add a dataset to the via an EXCEPT, INTERSECT, or UNION clause. This uses a subselect for the compound datasets used, because using parantheses doesn’t work on all databases. I consider this an ugly hack, but can’t I think of a better default.

      # File lib/sequel/dataset/sql.rb, line 1182
1182:     def select_compounds_sql(sql)
1183:       return unless c = @opts[:compounds]
1184:       c.each do |type, dataset, all|
1185:         sql << SPACE << type.to_s.upcase
1186:         sql << ALL if all
1187:         sql << SPACE
1188:         compound_dataset_sql_append(sql, dataset)
1189:       end
1190:     end
select_distinct_sql(sql) click to toggle source

Modify the sql to add the DISTINCT modifier

      # File lib/sequel/dataset/sql.rb, line 1168
1168:     def select_distinct_sql(sql)
1169:       if distinct = @opts[:distinct]
1170:         sql << DISTINCT
1171:         unless distinct.empty?
1172:           sql << ON_PAREN
1173:           expression_list_append(sql, distinct)
1174:           sql << PAREN_CLOSE
1175:         end
1176:       end
1177:     end
select_from_sql(sql) click to toggle source

Modify the sql to add the list of tables to select FROM

      # File lib/sequel/dataset/sql.rb, line 1193
1193:     def select_from_sql(sql)
1194:       if f = @opts[:from]
1195:         sql << FROM
1196:         source_list_append(sql, f)
1197:       end
1198:     end
Also aliased as: delete_from_sql
select_group_sql(sql) click to toggle source

Modify the sql to add the expressions to GROUP BY

      # File lib/sequel/dataset/sql.rb, line 1202
1202:     def select_group_sql(sql)
1203:       if group = @opts[:group]
1204:         sql << GROUP_BY
1205:         if go = @opts[:group_options]
1206:           if uses_with_rollup?
1207:             expression_list_append(sql, group)
1208:             sql << SPACE_WITH << go.to_s.upcase
1209:           else
1210:             sql << go.to_s.upcase << PAREN_OPEN
1211:             expression_list_append(sql, group)
1212:             sql << PAREN_CLOSE
1213:           end
1214:         else
1215:           expression_list_append(sql, group)
1216:         end
1217:       end
1218:     end
select_having_sql(sql) click to toggle source

Modify the sql to add the filter criteria in the HAVING clause

      # File lib/sequel/dataset/sql.rb, line 1221
1221:     def select_having_sql(sql)
1222:       if having = @opts[:having]
1223:         sql << HAVING
1224:         literal_append(sql, having)
1225:       end
1226:     end
select_join_sql(sql) click to toggle source

Modify the sql to add the list of tables to JOIN to

      # File lib/sequel/dataset/sql.rb, line 1229
1229:     def select_join_sql(sql)
1230:       if js = @opts[:join]
1231:         js.each{|j| literal_append(sql, j)}
1232:       end
1233:     end
select_limit_sql(sql) click to toggle source

Modify the sql to limit the number of rows returned and offset

      # File lib/sequel/dataset/sql.rb, line 1236
1236:     def select_limit_sql(sql)
1237:       if l = @opts[:limit]
1238:         sql << LIMIT
1239:         literal_append(sql, l)
1240:       end
1241:       if o = @opts[:offset]
1242:         sql << OFFSET
1243:         literal_append(sql, o)
1244:       end
1245:     end
select_lock_sql(sql) click to toggle source

Modify the sql to support the different types of locking modes.

      # File lib/sequel/dataset/sql.rb, line 1248
1248:     def select_lock_sql(sql)
1249:       case l = @opts[:lock]
1250:       when :update
1251:         sql << FOR_UPDATE
1252:       when String
1253:         sql << SPACE << l
1254:       end
1255:     end
select_order_sql(sql) click to toggle source

Modify the sql to add the expressions to ORDER BY

      # File lib/sequel/dataset/sql.rb, line 1258
1258:     def select_order_sql(sql)
1259:       if o = @opts[:order]
1260:         sql << ORDER_BY
1261:         expression_list_append(sql, o)
1262:       end
1263:     end
select_select_sql(sql) click to toggle source
      # File lib/sequel/dataset/sql.rb, line 1267
1267:     def select_select_sql(sql)
1268:       sql << SELECT
1269:     end
select_where_sql(sql) click to toggle source

Modify the sql to add the filter criteria in the WHERE clause

      # File lib/sequel/dataset/sql.rb, line 1272
1272:     def select_where_sql(sql)
1273:       if w = @opts[:where]
1274:         sql << WHERE
1275:         literal_append(sql, w)
1276:       end
1277:     end
select_with_sql(sql) click to toggle source

SQL Fragment specifying the WITH clause

      # File lib/sequel/dataset/sql.rb, line 1282
1282:     def select_with_sql(sql)
1283:       ws = opts[:with]
1284:       return if !ws || ws.empty?
1285:       sql << select_with_sql_base
1286:       c = false
1287:       comma = COMMA
1288:       ws.each do |w|
1289:         sql << comma if c
1290:         quote_identifier_append(sql, w[:name])
1291:         if args = w[:args]
1292:          sql << PAREN_OPEN
1293:          argument_list_append(sql, args)
1294:          sql << PAREN_CLOSE
1295:         end
1296:         sql << AS
1297:         literal_dataset_append(sql, w[:dataset])
1298:         c ||= true
1299:       end
1300:       sql << SPACE
1301:     end
select_with_sql_base() click to toggle source

The base keyword to use for the SQL WITH clause

      # File lib/sequel/dataset/sql.rb, line 1307
1307:     def select_with_sql_base
1308:       SQL_WITH
1309:     end
source_list_append(sql, sources) click to toggle source

Converts an array of source names into into a comma separated list.

      # File lib/sequel/dataset/sql.rb, line 1312
1312:     def source_list_append(sql, sources)
1313:       raise(Error, 'No source specified for query') if sources.nil? || sources == []
1314:       c = false
1315:       co = COMMA
1316:       sources.each do |s|
1317:         sql << co if c
1318:         identifier_append(sql, s)
1319:         c ||= true
1320:       end
1321:     end
split_symbol(sym) click to toggle source

Splits the symbol into three parts. Each part will either be a string or nil.

For columns, these parts are the table, column, and alias. For tables, these parts are the schema, table, and alias.

      # File lib/sequel/dataset/sql.rb, line 1328
1328:     def split_symbol(sym)
1329:       case s = sym.to_s
1330:       when COLUMN_REF_RE1
1331:         [$1, $2, $3]
1332:       when COLUMN_REF_RE2
1333:         [nil, $1, $2]
1334:       when COLUMN_REF_RE3
1335:         [$1, $2, nil]
1336:       else
1337:         [nil, s, nil]
1338:       end
1339:     end
sql_string_origin() click to toggle source

The string that is appended to to create the SQL query, the empty string by default

      # File lib/sequel/dataset/sql.rb, line 1343
1343:     def sql_string_origin
1344:       ''
1345:     end
static_sql(sql) click to toggle source

SQL to use if this dataset uses static SQL. Since static SQL can be a PlaceholderLiteralString in addition to a String, we literalize nonstrings.

      # File lib/sequel/dataset/sql.rb, line 1350
1350:     def static_sql(sql)
1351:       if append_sql = @opts[:append_sql]
1352:         if sql.is_a?(String)
1353:           append_sql << sql
1354:         else
1355:           literal_append(append_sql, sql)
1356:         end
1357:       else
1358:         if sql.is_a?(String)
1359:           sql
1360:         else
1361:           literal(sql)
1362:         end
1363:       end
1364:     end
subselect_sql_append(sql, ds) click to toggle source

SQL fragment for a subselect using the given database’s SQL.

      # File lib/sequel/dataset/sql.rb, line 1367
1367:     def subselect_sql_append(sql, ds)
1368:       ds.clone(:append_sql=>sql).sql
1369:     end
table_ref_append(sql, v) click to toggle source
Alias for: identifier_append
unaliased_identifier(c) click to toggle source

Return the unaliased part of the identifier. Handles both implicit aliases in symbols, as well as SQL::AliasedExpression objects. Other objects are returned as is.

     # File lib/sequel/dataset/actions.rb, line 815
815:     def unaliased_identifier(c)
816:       case c
817:       when Symbol
818:         c_table, column, _ = split_symbol(c)
819:         c_table ? SQL::QualifiedIdentifier.new(c_table, column.to_sym) : column.to_sym
820:       when SQL::AliasedExpression
821:         c.expression
822:       when SQL::OrderedExpression
823:         expr = c.expression
824:         if expr.is_a?(Symbol)
825:           expr = unaliased_identifier(expr)
826:           SQL::OrderedExpression.new(unaliased_identifier(c.expression), c.descending, :nulls=>c.nulls)
827:         else
828:           c
829:         end
830:       else
831:         c
832:       end
833:     end
update_clause_methods() click to toggle source

The order of methods to call to build the UPDATE SQL statement

      # File lib/sequel/dataset/sql.rb, line 1372
1372:     def update_clause_methods
1373:       UPDATE_CLAUSE_METHODS
1374:     end
update_order_sql(sql) click to toggle source
Alias for: select_order_sql
update_returning_sql(sql) click to toggle source
update_set_sql(sql) click to toggle source

The SQL fragment specifying the columns and values to SET.

      # File lib/sequel/dataset/sql.rb, line 1385
1385:     def update_set_sql(sql)
1386:       values = opts[:values]
1387:       sql << SET
1388:       if values.is_a?(Hash)
1389:         values = opts[:defaults].merge(values) if opts[:defaults]
1390:         values = values.merge(opts[:overrides]) if opts[:overrides]
1391:         c = false
1392:         eq = EQUAL
1393:         values.each do |k, v|
1394:           sql << COMMA if c
1395:           if k.is_a?(String) && !k.is_a?(LiteralString)
1396:             quote_identifier_append(sql, k)
1397:           else
1398:             literal_append(sql, k)
1399:           end
1400:           sql << eq
1401:           literal_append(sql, v)
1402:           c ||= true
1403:         end
1404:       else
1405:         sql << values
1406:       end
1407:     end
update_table_sql(sql) click to toggle source

SQL fragment specifying the tables from with to delete. Includes join table if modifying joins is allowed.

      # File lib/sequel/dataset/sql.rb, line 1378
1378:     def update_table_sql(sql)
1379:       sql << SPACE
1380:       source_list_append(sql, @opts[:from])
1381:       select_join_sql(sql) if supports_modifying_joins?
1382:     end
update_update_sql(sql) click to toggle source
      # File lib/sequel/dataset/sql.rb, line 1409
1409:     def update_update_sql(sql)
1410:       sql << UPDATE
1411:     end
update_where_sql(sql) click to toggle source
Alias for: select_where_sql
update_with_sql(sql) click to toggle source
Alias for: select_with_sql
uses_returning?(type) click to toggle source

Whether the RETURNING clause is used for the given dataset. type can be :insert, :update, or :delete.

     # File lib/sequel/dataset/features.rb, line 165
165:     def uses_returning?(type)
166:       opts[:returning] && !@opts[:sql] && supports_returning?(type)
167:     end
uses_with_rollup?() click to toggle source

Whether the dataset uses WITH ROLLUP/CUBE instead of ROLLUP()/CUBE().

     # File lib/sequel/dataset/features.rb, line 170
170:     def uses_with_rollup?
171:       false
172:     end
virtual_row_columns(columns, block) click to toggle source

Treat the block as a virtual_row block if not nil and add the resulting columns to the columns array (modifies columns).

      # File lib/sequel/dataset/query.rb, line 1085
1085:     def virtual_row_columns(columns, block)
1086:       columns.concat(Array(Sequel.virtual_row(&block))) if block
1087:     end
yield_hash_rows(res, cols) click to toggle source

For each row in the result set, yield a hash with column name symbol keys and typecasted values.

     # File lib/sequel/adapters/postgres.rb, line 754
754:       def yield_hash_rows(res, cols)
755:         res.ntuples.times do |recnum|
756:           converted_rec = {}
757:           cols.each do |fieldnum, type_proc, fieldsym|
758:             value = res.getvalue(recnum, fieldnum)
759:             converted_rec[fieldsym] = (value && type_proc) ? type_proc.call(value) : value
760:           end
761:           yield converted_rec
762:         end
763:       end
yield_rows(r, cols) click to toggle source

Yield each row of the given result set r with columns cols as a hash with symbol keys

     # File lib/sequel/adapters/mysql.rb, line 356
356:       def yield_rows(r, cols)
357:         while row = r.fetch_row
358:           h = {}
359:           cols.each{|n, p, i| v = row[i]; h[n] = (v && p) ? p.call(v) : v}
360:           yield h
361:         end
362:       end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.