Completed
Push — master ( 08bc8c...ed20a5 )
by Markus
11s
created

PdoWriter   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 90
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 94.59%

Importance

Changes 0
Metric Value
wmc 10
lcom 1
cbo 1
dl 0
loc 90
ccs 35
cts 37
cp 0.9459
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 2
A prepare() 0 5 1
A writeItem() 0 17 3
A finish() 0 6 1
A flush() 0 16 3
1
<?php
2
3
namespace Port\Pdo;
4
5
use Port\Exception\WriterException;
6
use Port\Writer;
7
use Port\Writer\FlushableWriter;
8
9
/**
10
 * Write data into a specific database table using a PDO instance.
11
 *
12
 * IMPORTANT: If your PDO instance does not have ERRMODE_EXCEPTION any write failure will be silent or logged to
13
 * stderr only. It is strongly recomended you enable Exceptions with:
14
 *
15
 *     $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
16
 *
17
 * @author Stefan Warman
18
 */
19
class PdoWriter implements Writer, FlushableWriter
20
{
21
    /**
22
     * @var \PDO
23
     */
24
    protected $pdo;
25
26
    /**
27
     * @var string
28
     */
29
    protected $tableName;
30
31
    /**
32
     * @var \PDOStatement
33
     */
34
    protected $statement;
35
36
    /**
37
     * @var array
38
     */
39
    private $stack;
40
41
    /**
42
     * Note if your table name is a reserved word for your target DB you should quote it in the appropriate way e.g.
43
     * for MySQL enclose the name in `backticks`.
44
     *
45
     * @param \PDO   $pdo
46
     * @param string $tableName
47
     */
48 6
    public function __construct(\PDO $pdo, $tableName)
49
    {
50 6
        $this->pdo = $pdo;
51 6
        $this->tableName = $tableName;
52
53 6
        if (\PDO::ERRMODE_EXCEPTION !== $this->pdo->getAttribute(\PDO::ATTR_ERRMODE)) {
54 2
            throw new WriterException('Please set the pdo error mode to PDO::ERRMODE_EXCEPTION');
55
        }
56 4
    }
57
58 4
    public function prepare()
59
    {
60 4
        $this->stack = [];
61 4
        $this->statement = null;
62 4
    }
63
64
    /**
65
     * {@inheritdoc}
66
     */
67 4
    public function writeItem(array $item)
68
    {
69 4
        if (null === $this->statement) {
70
            try {
71 4
                $this->statement = $this->pdo->prepare(sprintf(
72 4
                    'INSERT INTO %s (%s) VALUES (%s)',
73 4
                    $this->tableName,
74 4
                    implode(',', array_keys($item)),
75 4
                    substr(str_repeat('?,', count($item)), 0, -1)
76 4
                ));
77 4
            } catch (\PDOException $e) {
78 2
                throw new WriterException('Failed to send query', null, $e);
79
            }
80 2
        }
81
82 2
        $this->stack[] = array_values($item);
83 2
    }
84
85 2
    public function finish()
86
    {
87 2
        $this->flush();
88
89 2
        return $this;
90
    }
91
92 2
    public function flush()
93
    {
94 2
        $this->pdo->beginTransaction();
95
96
        try {
97 2
            foreach ($this->stack as $data) {
98 2
                $this->statement->execute($data);
99 2
            }
100 2
            $this->stack = [];
101
102 2
            $this->pdo->commit();
103 2
        } catch (\PDOException $e) {
104
            $this->pdo->rollBack();
105
            throw new WriterException('Failed to write to database', null, $e);
106
        }
107 2
    }
108
}
109