Completed
Push — master ( d942bb...bdf8d4 )
by Michael
63:24 queued 38:29
created

InsertOnDuplicateKeyBuilder::__invoke()   D

Complexity

Conditions 13
Paths 1

Size

Total Lines 131
Code Lines 52

Duplication

Lines 30
Ratio 22.9 %

Importance

Changes 0
Metric Value
dl 30
loc 131
rs 4.9922
c 0
b 0
f 0
cc 13
eloc 52
nc 1
nop 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Napp\Core\Dbal\Builder;
4
5
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
6
use Illuminate\Database\Query\Builder;
7
use Illuminate\Support\Arr;
8
9
class InsertOnDuplicateKeyBuilder
10
{
11
    function __invoke ()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
12
    {
13
        /**
14
         * Run an insert ignore statement against the database.
15
         *
16
         * @param  array $values
17
         * @return bool
18
         */
19
        Builder::macro('insertIgnore', function (array $values) {
20
            return $this->insertOnDuplicateKey($values, null, 'ignore');
0 ignored issues
show
Bug introduced by
The method insertOnDuplicateKey() does not seem to exist on object<Napp\Core\Dbal\Bu...tOnDuplicateKeyBuilder>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
21
        });
22
23
        /**
24
         * Run an insert on duplicate key update statement against the database.
25
         *
26
         * @param  array $values
27
         * @param  array $columnsToUpdate
28
         * @param  string $type
29
         * @return bool
30
         */
31
        Builder::macro('insertOnDuplicateKey', function (
32
            array $values,
33
            array $columnsToUpdate = null,
34
            $type = 'on duplicate key'
35
        ) {
36
            // Since every insert gets treated like a batch insert, we will make sure the
37
            // bindings are structured in a way that is convenient for building these
38
            // inserts statements by verifying the elements are actually an array.
39
            if (empty($values)) {
40
                return true;
41
            }
42
43 View Code Duplication
            if (! \is_array(reset($values))) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
44
                $values = [$values];
45
            }
46
47
            // Here, we will sort the insert keys for every record so that each insert is
48
            // in the same order for the record. We need to make sure this is the case
49
            // so there are not any errors or problems when inserting these records.
50
            else {
51
                foreach ($values as $key => $value) {
52
                    ksort($value);
53
                    $values[$key] = $value;
54
                }
55
            }
56
            // Finally, we will run this query against the database connection and return
57
            // the results. We will need to also flatten these bindings before running
58
            // the query so they are all in one huge, flattened array for execution.
59
            $bindings = $this->cleanBindings(Arr::flatten($values, 1));
0 ignored issues
show
Bug introduced by
The method cleanBindings() does not seem to exist on object<Napp\Core\Dbal\Bu...tOnDuplicateKeyBuilder>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
60
            // Essentially we will force every insert to be treated as a batch insert which
61
            // simply makes creating the SQL easier for us since we can utilize the same
62
            // basic routine regardless of an amount of records given to us to insert.
63
            $table = $this->grammar->wrapTable($this->from);
0 ignored issues
show
Bug introduced by
The property grammar does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
Bug introduced by
The property from does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
64
65
            $columns = array_keys(reset($values));
66
67
            $columnsString = $this->grammar->columnize($columns);
68
69
            // We need to build a list of parameter place-holders of values that are bound
70
            // to the query. Each insert should have the exact same amount of parameter
71
            // bindings so we will loop through the record and parameterize them all.
72
            $parameters = collect($values)->map(function ($record) {
73
                return '(' . $this->grammar->parameterize($record) . ')';
74
            })->implode(', ');
75
76
            $sql = 'insert ' . ($type === 'ignore' ? 'ignore ' : '') . "into $table ($columnsString) values $parameters";
77
78
            if ($type === 'ignore') {
79
                return $this->connection->insert($sql, $bindings);
0 ignored issues
show
Bug introduced by
The property connection does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
80
            }
81
82
            $sql .= ' on duplicate key update ';
83
84
            // We will update all the columns specified in $values by default.
85
            if ($columnsToUpdate === null) {
86
                $columnsToUpdate = $columns;
87
            }
88
89
            foreach ($columnsToUpdate as $key => $value) {
90
                $column = is_int($key) ? $value : $key;
91
                $column = $this->grammar->wrap($column);
92
                $sql .= "$column = ";
93
                if (is_int($key)) {
94
                    $sql .= "VALUES($column)";
95
                } else {
96
                    if ($this->grammar->isExpression($value)) {
97
                        $sql .= $value->getValue();
98
                    } else {
99
                        $sql .= '?';
100
                        $bindings[] = $value;
101
                    }
102
                }
103
                $sql .= ',';
104
            }
105
106
            return $this->connection->insert(rtrim($sql, ','), $bindings);
107
        });
108
109
        /**
110
         * Attach models to the parent ignoring existing associations.
111
         *
112
         * @param  mixed $id
113
         * @param  array $attributes
114
         * @return void
115
         */
116 View Code Duplication
        BelongsToMany::macro('attachIgnore', function ($id, array $attributes = [], $touch = true) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
117
            $this->newPivotStatement()->insertIgnore($this->formatAttachRecords(
0 ignored issues
show
Bug introduced by
The method newPivotStatement() does not seem to exist on object<Napp\Core\Dbal\Bu...tOnDuplicateKeyBuilder>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
Bug introduced by
The method formatAttachRecords() does not seem to exist on object<Napp\Core\Dbal\Bu...tOnDuplicateKeyBuilder>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
118
                $this->parseIds($id), $attributes
0 ignored issues
show
Bug introduced by
The method parseIds() does not seem to exist on object<Napp\Core\Dbal\Bu...tOnDuplicateKeyBuilder>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
119
            ));
120
            if ($touch) {
121
                $this->touchIfTouching();
0 ignored issues
show
Bug introduced by
The method touchIfTouching() does not seem to exist on object<Napp\Core\Dbal\Bu...tOnDuplicateKeyBuilder>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
122
            }
123
        });
124
125
        /**
126
         * Attach models to the parent updating existing associations.
127
         *
128
         * @param  mixed $id
129
         * @param  array $attributes
130
         * @return void
131
         */
132 View Code Duplication
        BelongsToMany::macro('attachOnDuplicateKey', function ($id, array $attributes = [], $touch = true) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
133
            $this->newPivotStatement()->insertOnDuplicateKey($this->formatAttachRecords(
0 ignored issues
show
Bug introduced by
The method newPivotStatement() does not seem to exist on object<Napp\Core\Dbal\Bu...tOnDuplicateKeyBuilder>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
Bug introduced by
The method formatAttachRecords() does not seem to exist on object<Napp\Core\Dbal\Bu...tOnDuplicateKeyBuilder>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
134
                $this->parseIds($id), $attributes
0 ignored issues
show
Bug introduced by
The method parseIds() does not seem to exist on object<Napp\Core\Dbal\Bu...tOnDuplicateKeyBuilder>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
135
            ));
136
137
            if ($touch) {
138
                $this->touchIfTouching();
0 ignored issues
show
Bug introduced by
The method touchIfTouching() does not seem to exist on object<Napp\Core\Dbal\Bu...tOnDuplicateKeyBuilder>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
139
            }
140
        });
141
    }
142
}