DbLoader::__construct()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 3
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 7
rs 10
1
<?php
2
3
/*
4
 * This file is part of YaEtl
5
 *     (c) Fabrice de Stefanis / https://github.com/fab2s/YaEtl
6
 * This source file is licensed under the MIT license which you will
7
 * find in the LICENSE file or at https://opensource.org/licenses/MIT
8
 */
9
10
namespace fab2s\YaEtl\Laravel\Loaders;
11
12
use fab2s\NodalFlow\NodalFlowException;
13
use fab2s\YaEtl\Loaders\LoaderAbstract;
14
use Illuminate\Database\Query\Builder;
15
use Illuminate\Support\Facades\DB;
16
17
/**
18
 * Class DbLoader
19
 */
20
class DbLoader extends LoaderAbstract
21
{
22
    /**
23
     * Array of fields used in the where clause (select and update)
24
     *
25
     * @var array
26
     */
27
    protected $whereFields;
28
29
    /**
30
     * The query object
31
     *
32
     * @var Builder
33
     */
34
    protected $loadQuery;
35
36
    /**
37
     * Instantiate the DbLoader
38
     *
39
     * @param Builder|null $loadQuery
40
     *
41
     * @throws NodalFlowException
42
     */
43
    public function __construct(?Builder $loadQuery = null)
44
    {
45
        if ($loadQuery !== null) {
46
            $this->setLoadQuery($loadQuery);
47
        }
48
49
        parent::__construct();
50
    }
51
52
    /**
53
     * Set the Load query
54
     *
55
     * @param Builder $loadQuery
56
     *
57
     * @return static
58
     */
59
    public function setLoadQuery(Builder $loadQuery): self
60
    {
61
        $this->loadQuery = $loadQuery;
62
63
        return $this;
64
    }
65
66
    /**
67
     * Set proper WHERE fields
68
     *
69
     * @param array $whereFields
70
     *
71
     * @return static
72
     */
73
    public function setWhereFields(array $whereFields): self
74
    {
75
        $this->whereFields = $whereFields;
76
77
        return $this;
78
    }
79
80
    /**
81
     * This method does not implement multi inserts and will
82
     * perform one query per record, which is also why flush
83
     * is left alone
84
     * We assume here that transformed data is a name/value pair
85
     * array of fields to update/insert
86
     *
87
     * @param array $param The record to load
88
     *
89
     * @return mixed|void
90
     */
91
    public function exec($param = null)
92
    {
93
        // clone query object in order to prevent where clause stacking
94
        $loadQuery   = clone $this->loadQuery;
95
        $whereClause = \array_intersect_key($param, \array_flip((array) $this->whereFields));
0 ignored issues
show
Bug introduced by
It seems like $param can also be of type null; however, parameter $array1 of array_intersect_key() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

95
        $whereClause = \array_intersect_key(/** @scrutinizer ignore-type */ $param, \array_flip((array) $this->whereFields));
Loading history...
96
97
        // let's be atomic while we're at it (and where applicable ...)
98
        // btw, multi insert are not necessarily that faster in real world
99
        // situation where there is a lot of updates and you need ot keep
100
        // atomicity using transactions
101
        DB::transaction(function () use ($loadQuery, $whereClause, $param) {
102
            if (!empty($whereClause) && $loadQuery->where($whereClause)->sharedLock()->exists()) {
103
                $update = \array_diff_key($param, $whereClause);
0 ignored issues
show
Bug introduced by
It seems like $param can also be of type null; however, parameter $array1 of array_diff_key() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

103
                $update = \array_diff_key(/** @scrutinizer ignore-type */ $param, $whereClause);
Loading history...
104
                $loadQuery->update($update);
105
            } else {
106
                $loadQuery->insert($param);
0 ignored issues
show
Bug introduced by
It seems like $param can also be of type null; however, parameter $values of Illuminate\Database\Query\Builder::insert() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

106
                $loadQuery->insert(/** @scrutinizer ignore-type */ $param);
Loading history...
107
            }
108
        });
109
    }
110
}
111