File: insert_returning_select.rb

package info (click to toggle)
ruby-sequel 5.63.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 10,408 kB
  • sloc: ruby: 113,747; makefile: 3
file content (72 lines) | stat: -rw-r--r-- 2,361 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# frozen-string-literal: true

module Sequel
  module Plugins
    # If the model's dataset selects explicit columns and the
    # database supports it, the insert_returning_select plugin will
    # automatically set the RETURNING clause on the dataset used to
    # insert rows to the columns selected, which allows the default model
    # support to run the insert and refresh of the data in a single
    # query, instead of two separate queries.  This is Sequel's default
    # behavior when the model does not select explicit columns.
    #
    # Usage:
    #
    #   # Make all model subclasses automatically setup insert returning clauses
    #   Sequel::Model.plugin :insert_returning_select
    #
    #   # Make the Album class automatically setup insert returning clauses
    #   Album.plugin :insert_returning_select
    module InsertReturningSelect
      # Modify the current model's dataset selection, if the model
      # has a dataset.
      def self.configure(model)
        model.instance_exec do
          self.dataset = dataset if @dataset && @dataset.opts[:select]
        end
      end

      module ClassMethods
        # The dataset to use to insert new rows.  For internal use only.
        attr_reader :instance_insert_dataset

        private

        # When reseting the instance dataset, also reset the instance_insert_dataset.
        def reset_instance_dataset
          ret = super
          return unless ds = @instance_dataset

          if columns = insert_returning_columns(ds)
            ds = ds.returning(*columns)
          end
          @instance_insert_dataset = ds

          ret
        end

        # Determine the columns to use for the returning clause, or return nil
        # if they can't be determined and a returning clause should not be
        # added automatically.
        def insert_returning_columns(ds)
          return unless ds.supports_returning?(:insert)
          return unless values = ds.opts[:select]

          values = values.map{|v| ds.unqualified_column_for(v)}
          if values.all?
            values
          end
        end
      end
      
      module InstanceMethods
        private

        # Use the instance_insert_dataset as the base dataset for the insert.
        def _insert_dataset
          use_server(model.instance_insert_dataset)
        end
      end
    end
  end
end