summaryrefslogtreecommitdiffstats
path: root/vendor/ipl/sql/src/Insert.php
blob: 738a842f71f5d5fac3604f8d66354f55ac2c785c (plain)
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
<?php

namespace ipl\Sql;

use InvalidArgumentException;

use function ipl\Stdlib\arrayval;

/**
 * SQL INSERT query
 */
class Insert implements CommonTableExpressionInterface
{
    use CommonTableExpression;

    /** @var string|null The table for the INSERT INTO query */
    protected $into;

    /** @var array|null The columns for which the query provides values */
    protected $columns;

    /** @var array|null The values to insert */
    protected $values;

    /** @var Select|null The select query for INSERT INTO ... SELECT queries */
    protected $select;

    /**
     * Get the table for the INSERT INTo query
     *
     * @return string|null
     */
    public function getInto()
    {
        return $this->into;
    }

    /**
     * Set the table for the INSERT INTO query
     *
     * Note that this method does NOT quote the table you specify for the INSERT INTO.
     * If you allow user input here, you must protected yourself against SQL injection using
     * {@link Connection::quoteIdentifier()} for the table name passed to this method.
     * If you are using special table names, e.g. reserved keywords for your DBMS, you are required to use
     * {@link Connection::quoteIdentifier()} as well.
     *
     * @param string $table The table to insert data into. The table specification must be in one of the following
     *                      formats: 'table' or 'schema.table'
     *
     * @return $this
     */
    public function into($table)
    {
        $this->into = $table;

        return $this;
    }

    /**
     * Get the columns for which the statement provides values
     *
     * @return array
     */
    public function getColumns()
    {
        if (! empty($this->columns)) {
            return array_keys($this->columns);
        }

        if (! empty($this->values)) {
            return array_keys($this->values);
        }

        return [];
    }

    /**
     * Set the columns for which the query provides values
     *
     * Note that this method does NOT quote the columns you specify for the INSERT INTO.
     * If you allow user input here, you must protected yourself against SQL injection using
     * {@link Connection::quoteIdentifier()} for the column names passed to this method.
     * If you are using special column names, e.g. reserved keywords for your DBMS, you are required to use
     * {@link Connection::quoteIdentifier()} as well.
     *
     * If you do not set the columns for which the query provides values using this method, you must pass the values to
     * {@link values()} in terms of column-value pairs in order to provide the column names.
     *
     * @param array $columns
     *
     * @return $this
     */
    public function columns(array $columns)
    {
        $this->columns = array_flip($columns);

        return $this;
    }

    /**
     * Get the values to insert
     *
     * @return array
     */
    public function getValues()
    {
        return array_values($this->values ?: []);
    }

    /**
     * Set the values to INSERT INTO - either plain values or expressions or scalar subqueries
     *
     * If you do not set the columns for which the query provides values using {@link columns()}, you must specify
     * the values in terms of column-value pairs in order to provide the column names. Please note that the same
     * restriction regarding quoting applies here. If you use {@link columns()} to set the columns and specify the
     * values in terms of column-value pairs, the columns from {@link columns()} will be used nonetheless.
     *
     * @param iterable $values List of values or associative set of column-value pairs
     *
     * @return $this
     *
     * @throws InvalidArgumentException If values type is invalid
     */
    public function values($values)
    {
        $this->values = arrayval($values);

        return $this;
    }

    /**
     * Create a INSERT INTO ... SELECT statement
     *
     * @param Select $select
     *
     * @return $this
     */
    public function select(Select $select)
    {
        $this->select = $select;

        return $this;
    }

    /**
     * Get the select query for the INSERT INTO ... SELECT statement
     *
     * @return Select|null
     */
    public function getSelect()
    {
        return $this->select;
    }

    public function __clone()
    {
        $this->cloneCte();

        if ($this->values !== null) {
            foreach ($this->values as &$value) {
                if ($value instanceof ExpressionInterface || $value instanceof Select) {
                    $value = clone $value;
                }
            }
            unset($value);
        }

        if ($this->select !== null) {
            $this->select = clone $this->select;
        }
    }
}