Completed
Pull Request — master (#49)
by Thomas
16:34
created

BulkInsert::limit()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 5
ccs 0
cts 0
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 2
1
<?php
2
3
namespace ORM;
4
5
use ORM\Dbal\Dbal;
6
use ORM\Exception\InvalidArgument;
7
8
class BulkInsert
9
{
10
    /** @var string */
11
    protected $class;
12
13
    /** @var Dbal */
14
    protected $dbal;
15
16
    /** @var int */
17
    protected $limit;
18
19
    /** @var callable */
20
    protected $onSync;
21
22
    /** @var bool */
23
    protected $useAutoIncrement = true;
24
25
    /** @var bool */
26
    protected $update = true;
27
28
    /** @var Entity[] */
29
    protected $new = [];
30
31
    /** @var Entity[] */
32
    protected $synced = [];
33
34
    /**
35
     * BulkInsert constructor.
36
     *
37
     * @param string $class
38
     * @param Dbal $dbal
39
     * @param int $limit
40
     */
41 13
    public function __construct(Dbal $dbal, $class, $limit = 20)
42
    {
43 13
        $this->class = $class;
44 13
        $this->dbal = $dbal;
45 13
        $this->limit = $limit;
46 13
    }
47
48
    /**
49
     * Add an entity to the bulk insert.
50
     *
51
     * @param Entity ...$entities
52
     * @throws InvalidArgument
53
     */
54 6
    public function add(Entity ...$entities)
55
    {
56 6
        foreach ($entities as $entity) {
57 6
            if (!$entity instanceof $this->class) {
58 6
                throw new InvalidArgument('Only entities from type ' . $this->class . ' can be added');
59
            }
60
        }
61
62 5
        array_push($this->new, ...$entities);
63 5
        while (count($this->new) >= $this->limit) {
64 4
            $this->execute();
65
        }
66 5
    }
67
68
    /**
69
     * Insert the outstanding entities and return all synced objects.
70
     *
71
     * @return Entity[]
72
     */
73 3
    public function finish()
74
    {
75 3
        if (!empty($this->new)) {
76 1
            $this->execute();
77
        }
78 3
        return $this->synced;
79
    }
80
81
    /**
82
     * Executes the bulk insert.
83
     */
84 5
    protected function execute()
85
    {
86 5
        $new = array_splice($this->new, 0, $this->limit);
87 5
        if ($this->dbal->bulkInsert($new, $this->update, $this->useAutoIncrement)) {
88 5
            array_push($this->synced, ...$new);
89 5
            !$this->onSync || call_user_func($this->onSync, $new);
90
        }
91 5
    }
92
93
    /** @return int
94
     * @codeCoverageIgnore trivial */
95
    public function getLimit()
96
    {
97
        return $this->limit;
98
    }
99
100
    /**
101
     * Limit the amount of entities inserted at once.
102
     *
103
     * @param int $limit
104
     * @return $this
105
     * @codeCoverageIgnore trivial
106
     */
107
    public function limit($limit)
108
    {
109
        $this->limit = $limit;
110
        return $this;
111
    }
112
113
    /**
114
     * Enable updating the primary keys from autoincrement
115
     *
116
     * **Caution**: Your db access layer (DBAL) may not support this feature.
117
     *
118
     * @return $this
119
     * @codeCoverageIgnore trivial
120
     */
121
    public function useAutoincrement()
122
    {
123
        $this->useAutoIncrement = true;
124
        return $this;
125
    }
126
127
    /**
128
     * Disable updating the primary key by auto increment.
129
     *
130
     * **Caution**: If this is disabled updating could cause a IncompletePrimaryKey exception.
131
     *
132
     * @return $this
133
     * @codeCoverageIgnore trivial
134
     */
135
    public function noAutoincrement()
136
    {
137
        $this->useAutoIncrement = false;
138
        return $this;
139
    }
140
141
    /**
142
     * Executes $callback after insert
143
     *
144
     * Provides an array of the just inserted entities in first argument.
145
     *
146
     * @param callable $callback
147
     * @return $this
148
     * @codeCoverageIgnore trivial
149
     */
150
    public function onSync(callable $callback)
151
    {
152
        $this->onSync = $callback;
153
        return $this;
154
    }
155
156
    /**
157
     * Disable updating entities after insert
158
     *
159
     * @return $this
160
     * @codeCoverageIgnore trivial
161
     */
162
    public function noUpdates()
163
    {
164
        $this->update = false;
165
        return $this;
166
    }
167
168
    /**
169
     * Enable updating entities after insert
170
     *
171
     * **Caution**: This option will need to update the primary key by autoincrement which maybe is not supported
172
     * by your db access layer (DBAL).
173
     *
174
     * @return $this
175
     * @codeCoverageIgnore trivial
176
     */
177
    public function updateEntities()
178
    {
179
        $this->update = true;
180
        return $this;
181
    }
182
}
183