Completed
Push — master ( f5e696...7c0e7c )
by Rasmus
03:36
created

InsertQuery   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 108
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 86.84%

Importance

Changes 0
Metric Value
wmc 8
lcom 1
cbo 4
dl 0
loc 108
ccs 33
cts 38
cp 0.8684
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 19 2
B add() 0 28 4
A getSQL() 0 20 2
1
<?php
2
3
namespace mindplay\sql\model\query;
4
5
use mindplay\sql\model\Driver;
6
use mindplay\sql\model\schema\Column;
7
use mindplay\sql\model\schema\Table;
8
use mindplay\sql\model\TypeProvider;
9
use RuntimeException;
10
11
/**
12
 * This class represents an INSERT query.
13
 */
14
class InsertQuery extends Query
15
{
16
    /**
17
     * @var Driver
18
     */
19
    private $driver;
20
21
    /**
22
     * @var Table
23
     */
24
    private $table;
25
26
    /**
27
     * @var Column[]
28
     */
29
    private $columns;
30
31
    /**
32
     * @var string[] list of tuple expressions
33
     */
34
    private $tuples = [];
35
36
    /**
37
     * @param Driver       $driver
38
     * @param TypeProvider $types
39
     * @param Table        $table Table to INSERT into
40
     */
41 1
    public function __construct(Driver $driver, TypeProvider $types, Table $table)
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 1
    }
60
61
62
    /**
63
     * Add a record to this INSERT query.
64
     *
65
     * @param array $record record map (where Column name => value)
66
     *
67
     * @return $this
68
     */
69 1
    public function add(array $record)
70
    {
71 1
        $placeholders = [];
72
73 1
        $tuple_num = count($this->tuples);
74
75 1
        foreach ($this->columns as $col_index => $column) {
76 1
            $name = $column->getName();
77
78 1
            if (array_key_exists($name, $record)) {
79 1
                $value = $record[$name];
80
            } elseif ($column->isRequired() === false) {
81
                $value = $column->getDefault();
82
            } else {
83
                throw new RuntimeException("required value '{$name}' missing from tuple # {$tuple_num}");
84
            }
85
86 1
            $placeholder = "c{$tuple_num}_{$col_index}";
87
88 1
            $placeholders[] = ":{$placeholder}";
89
90 1
            $this->bind($placeholder, $value, $column->getType());
91
        }
92
93 1
        $this->tuples[] = "(" . implode(", ", $placeholders) . ")";
94
95 1
        return $this;
96
    }
97
98
    /**
99
     * @inheritdoc
100
     */
101 1
    public function getSQL()
102
    {
103 1
        if (count($this->tuples) === 0) {
104
            throw new RuntimeException("no records added to this query");
105
        }
106
107 1
        $table = "{$this->table}";
108
109 1
        $quoted_column_names = implode(
110 1
            ", ",
111 1
            array_map(
112 1
                function (Column $column) {
113 1
                    return $this->driver->quoteName($column->getName());
114 1
                },
115 1
                $this->columns
116
            )
117
        );
118
119 1
        return "INSERT INTO {$table} ({$quoted_column_names}) VALUES\n" . implode(",\n", $this->tuples);
120
    }
121
}
122