Builder   A
last analyzed

Complexity

Total Complexity 17

Size/Duplication

Total Lines 121
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 43
c 1
b 0
f 0
dl 0
loc 121
ccs 46
cts 46
cp 1
rs 10
wmc 17

5 Methods

Rating   Name   Duplication   Size   Complexity  
A upsert() 0 28 4
A insertIgnore() 0 11 2
A __construct() 0 6 3
A getQueryGrammar() 0 16 5
A prepareValuesForInsert() 0 13 3
1
<?php
2
3
namespace Staudenmeir\LaravelUpsert\Query;
4
5
use Illuminate\Database\Connection;
6
use Illuminate\Database\Query\Builder as Base;
7
use Illuminate\Database\Query\Grammars\Grammar;
8
use Illuminate\Database\Query\Processors\Processor;
9
use Illuminate\Support\Arr;
10
use RuntimeException;
11
use Staudenmeir\LaravelUpsert\Query\Grammars\MySqlGrammar;
12
use Staudenmeir\LaravelUpsert\Query\Grammars\PostgresGrammar;
13
use Staudenmeir\LaravelUpsert\Query\Grammars\SQLiteGrammar;
14
use Staudenmeir\LaravelUpsert\Query\Grammars\SqlServerGrammar;
15
16
class Builder extends Base
17
{
18
    /**
19
     * Create a new query builder instance.
20
     *
21
     * @param \Illuminate\Database\Connection $connection
22
     * @param \Illuminate\Database\Query\Grammars\Grammar|null $grammar
23
     * @param \Illuminate\Database\Query\Processors\Processor|null $processor
24
     * @return void
25
     */
26 68
    public function __construct(Connection $connection, Grammar $grammar = null, Processor $processor = null)
27
    {
28 68
        $grammar = $grammar ?: $connection->withTablePrefix($this->getQueryGrammar($connection));
29 68
        $processor = $processor ?: $connection->getPostProcessor();
30
31 68
        parent::__construct($connection, $grammar, $processor);
32 68
    }
33
34
    /**
35
     * Get the query grammar.
36
     *
37
     * @param \Illuminate\Database\Connection $connection
38
     * @return \Illuminate\Database\Query\Grammars\Grammar
39
     */
40 68
    protected function getQueryGrammar(Connection $connection)
41
    {
42 68
        $driver = $connection->getDriverName();
43
44 68
        switch ($driver) {
45 68
            case 'mysql':
46 17
                return new MySqlGrammar;
47 51
            case 'pgsql':
48 17
                return new PostgresGrammar;
49 34
            case 'sqlite':
50 17
                return new SQLiteGrammar;
51 17
            case 'sqlsrv':
52 17
                return new SqlServerGrammar;
53
        }
54
55
        throw new RuntimeException('This database is not supported.'); // @codeCoverageIgnore
56
    }
57
58
    /**
59
     * Insert new records or update the existing ones.
60
     *
61
     * @param array $values
62
     * @param array|string $target
63
     * @param array|null $update
64
     * @return int
65
     */
66 40
    public function upsert(array $values, $target, array $update = null)
67
    {
68 40
        if (empty($values)) {
69 4
            return 0;
70
        }
71
72 36
        if ($update === []) {
73 4
            return (int) $this->insert($values);
74
        }
75
76 32
        $values = $this->prepareValuesForInsert($values);
77
78 32
        if (is_null($update)) {
79 4
            $update = array_keys(reset($values));
80
        }
81
82 32
        $bindings = $this->cleanBindings(
83 32
            array_merge(
84 32
                Arr::flatten($values, 1),
85 32
                collect($update)->reject(function ($value, $key) {
86 32
                    return is_int($key);
87 32
                })->all()
88
            )
89
        );
90
91 32
        return $this->connection->affectingStatement(
92 32
            $this->grammar->compileUpsert($this, $values, (array) $target, $update),
93
            $bindings
94
        );
95
    }
96
97
    /**
98
     * Insert a new record into the database and ignore duplicate-key errors.
99
     *
100
     * @param array $values
101
     * @param array|string|null $target
102
     * @return int
103
     */
104 20
    public function insertIgnore(array $values, $target = null)
105
    {
106 20
        if (empty($values)) {
107 4
            return 0;
108
        }
109
110 16
        $values = $this->prepareValuesForInsert($values);
111
112 16
        return $this->connection->affectingStatement(
113 16
            $this->grammar->compileInsertIgnore($this, $values, (array) $target),
114 16
            $this->cleanBindings(Arr::flatten($values, 1))
115
        );
116
    }
117
118
    /**
119
     * Prepare the values for an "insert" statement.
120
     *
121
     * @param array $values
122
     * @return array
123
     */
124 48
    protected function prepareValuesForInsert(array $values)
125
    {
126 48
        if (!is_array(reset($values))) {
127 4
            return [$values];
128
        }
129
130 44
        foreach ($values as $key => $value) {
131 44
            ksort($value);
132
133 44
            $values[$key] = $value;
134
        }
135
136 44
        return $values;
137
    }
138
}
139