Completed
Push — master ( 3c979b...679720 )
by Rasmus
02:21
created

InsertQuery   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 115
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 92.31%

Importance

Changes 4
Bugs 1 Features 0
Metric Value
wmc 9
c 4
b 1
f 0
lcom 1
cbo 4
dl 0
loc 115
ccs 36
cts 39
cp 0.9231
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
B __construct() 0 25 3
B add() 0 28 4
A getSQL() 0 20 2
1
<?php
2
3
namespace mindplay\sql\model;
4
5
use mindplay\sql\framework\Driver;
6
use mindplay\sql\framework\Query;
7
use mindplay\sql\framework\TypeProvider;
8
use RuntimeException;
9
10
/**
11
 * This class represents an INSERT query.
12
 */
13
class InsertQuery extends Query
14
{
15
    /**
16
     * @var Driver
17
     */
18
    private $driver;
19
20
    /**
21
     * @var Table
22
     */
23
    private $table;
24
25
    /**
26
     * @var Column[]
27
     */
28
    private $columns;
29
30
    /**
31
     * @var string[] list of tuple expressions
32
     */
33
    private $tuples = [];
34
35
    /**
36
     * @param Driver                 $driver
37
     * @param TypeProvider           $types
38
     * @param Table                  $table  Table to INSERT into
39
     * @param mixed[]|mixed[][]|null $record optional record map (or list of record maps) where Column name => value
40
     */
41 1
    public function __construct(Driver $driver, TypeProvider $types, Table $table, array $record = null)
42
    {
43 1
        parent::__construct($types);
44
45 1
        if ($table->getAlias()) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $table->getAlias() of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
46
            throw new RuntimeException("can't insert into a Table instance with an alias");
47
        }
48
49 1
        $this->driver = $driver;
50
51 1
        $this->table = $table;
52
53 1
        $this->columns = array_filter(
54 1
            $table->listColumns(),
55
            function (Column $column) {
56 1
                return $column->isAuto() === false;
57 1
            }
58
        );
59
60 1
        if ($record !== null) {
61 1
            $this->add($record);
62
        }
63
64 1
        return $this;
0 ignored issues
show
Bug introduced by
Constructors do not have meaningful return values, anything that is returned from here is discarded. Are you sure this is correct?
Loading history...
65
    }
66
67
68
    /**
69
     * Add a record to this INSERT query.
70
     *
71
     * @param array $record record map (where Column name => value)
72
     *
73
     * @return $this
74
     */
75 1
    public function add(array $record)
76
    {
77 1
        $placeholders = [];
78
79 1
        $tuple_num = count($this->tuples);
80
81 1
        foreach ($this->columns as $col_index => $column) {
82 1
            $name = $column->getName();
83
84 1
            if (array_key_exists($name, $record)) {
85 1
                $value = $record[$name];
86 1
            } elseif ($column->isRequired() === false) {
87
                $value = $column->getDefault();
88
            } else {
89 1
                throw new RuntimeException("required value '{$name}' missing from tuple # {$tuple_num}");
90
            }
91
92 1
            $placeholder = "c{$tuple_num}_{$col_index}";
93
94 1
            $placeholders[] = ":{$placeholder}";
95
96 1
            $this->bind($placeholder, $value, $column->getType());
97
        }
98
99 1
        $this->tuples[] = "(" . implode(", ", $placeholders) . ")";
100
101 1
        return $this;
102
    }
103
104
    /**
105
     * @inheritdoc
106
     */
107 1
    public function getSQL()
108
    {
109 1
        if (count($this->tuples) === 0) {
110
            throw new RuntimeException("no records added to this query");
111
        }
112
113 1
        $table = "{$this->table}";
114
115 1
        $quoted_column_names = implode(
116 1
            ", ",
117
            array_map(
118 1
                function (Column $column) {
119 1
                    return $this->driver->quoteName($column->getName());
120 1
                },
121 1
                $this->columns
122
            )
123
        );
124
125 1
        return "INSERT INTO {$table} ({$quoted_column_names}) VALUES\n" . implode(",\n", $this->tuples);
126
    }
127
}
128