Completed
Push — master ( 727d34...2d2ccc )
by Fabrice
06:07
created

DbLoader   A

Complexity

Total Complexity 6

Size/Duplication

Total Lines 84
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Importance

Changes 0
Metric Value
wmc 6
lcom 1
cbo 0
dl 0
loc 84
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 2
A setLoadQuery() 0 6 1
A setWhereFields() 0 6 1
A exec() 0 19 2
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\YaEtl\LoaderAbstract;
13
use Illuminate\Database\Query\Builder;
14
15
/**
16
 * Class DbLoader
17
 */
18
class DbLoader extends LoaderAbstract
19
{
20
    /**
21
     * array of fields used in the where clause (select and update)
22
     *
23
     * @var array
24
     */
25
    protected $whereFields;
26
27
    /**
28
     * query object
29
     *
30
     * @var Builder
31
     */
32
    protected $loadQuery;
33
34
    /**
35
     * @var mixed
36
     */
37
    protected $record;
38
39
    /**
40
     * @param Builder|null $loadQuery
41
     */
42
    public function __construct(Builder $loadQuery = null)
43
    {
44
        if ($loadQuery !== null) {
45
            $this->setLoadQuery($loadQuery);
46
        }
47
    }
48
49
    /**
50
     * @param Builder $loadQuery
51
     *
52
     * @return $this
53
     */
54
    public function setLoadQuery(Builder $loadQuery)
55
    {
56
        $this->loadQuery = $loadQuery;
57
58
        return $this;
59
    }
60
61
    /**
62
     * @param array $whereFields
63
     *
64
     * @return $this
65
     */
66
    public function setWhereFields(array $whereFields)
67
    {
68
        $this->whereFields = $whereFields;
69
70
        return $this;
71
    }
72
73
    /**
74
     * This method does not implement multi inserts and will
75
     * perform one query per record, which is also why flush
76
     * is left alone
77
     * We assume here that transformed data is a name/value pair
78
     * array of fields to update/insert
79
     *
80
     * @param array $record
81
     */
82
    public function exec($record)
83
    {
84
        // clone query object in order to prevent where clause stacking
85
        $loadQuery   = clone $this->loadQuery;
86
        $whereClause = \array_intersect_key($record, \array_flip($this->whereFields));
87
88
        // let's be atomic while we're at it (and where applicable ...)
89
        // btw, multi insert are not necessarily that faster in real world
90
        // situation where there is a lot of updates and you need ot keep
91
        // atomicity using transactions
92
        DB::transaction(function () use ($loadQuery, $whereClause, $record) {
93
            if ($loadQuery->where($whereClause)->sharedLock()->exists()) {
94
                $update = \array_diff_key($record, $whereClause);
95
                $loadQuery->update($update);
96
            } else {
97
                $loadQuery->insert($record);
98
            }
99
        });
100
    }
101
}
102