PrimaryKey   A
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 180
Duplicated Lines 5 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 94%

Importance

Changes 3
Bugs 0 Features 0
Metric Value
wmc 14
c 3
b 0
f 0
lcom 1
cbo 3
dl 9
loc 180
ccs 47
cts 50
cp 0.94
rs 10

8 Methods

Rating   Name   Duplication   Size   Complexity  
A setPrimaryKeyFields() 0 4 1
A checkColumnExistsInSchema() 0 7 2
A csvDataForPrimaryKeyColumn() 0 5 1
A getPrimaryKeyDataForRow() 0 10 2
A createHash() 0 4 1
A isHashUnique() 0 4 1
B validate() 0 32 5
A handleDuplicateHash() 9 9 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
namespace JsonTable\Analyse;
3
4
/**
5
 * Perform primary key analysis.
6
 *
7
 * @package JsonTable
8
 */
9
class PrimaryKey extends Analyse implements AnalyseInterface
10
{
11
    /**
12
     * @var string The description for fields with duplicated primary keys.
13
     */
14
    const ERROR_DUPLICATE_PRIMARY_KEY = 'There are <strong>%d</strong> rows that have duplicated primary keys:';
15
16
    /**
17
     * @var array   The current CSV row being analysed.
18
     */
19
    private $currentCsvRow;
20
21
    /**
22
     * @var int The position of the current CSV row row in the CSV file.
23
     */
24
    private $rowNumber;
25
26
    /**
27
     * @var array   The primary keys for every row in the file.
28
     */
29
    private $fileKeys;
30
31
    /**
32
     * @var array   The primary key parts for the current row.
33
     */
34
    private $rowKeyParts;
35
36
    /**
37
     * @var array   The primary key fields.
38
     */
39
    private $primaryKeyFields;
40
41
    /**
42
     * @var string  The name of the primary key field currently being analysed.
43
     */
44
    private $primaryKeyFieldName;
45
46
    /**
47
     * @var string  The hash of the data taken from the primary key fields in the current CSV row.
48
     */
49
    private $hash;
50
51
52
    /**
53
     * Validate that any specified primary key constraints have been met.
54
     *
55
     * @return  boolean Does the data meet the primary key constraints.
56
     *
57
     *
58
     */
59 74
    public function validate()
60
    {
61 74
        if (false === property_exists(parent::$schemaJson, 'primaryKey')) {
62 1
            return true;
63
        }
64
65 73
        $this->setPrimaryKeyFields();
66 73
        $this->fileKeys = [];
67
68 73
        self::rewindFilePointerToFirstData();
69
70 73
        $this->rowNumber= 1;
71
72 73
        while ($currentCsvRow = parent::loopThroughFileRows()) {
73 73
            $this->currentCsvRow = $currentCsvRow;
74 73
            $this->getPrimaryKeyDataForRow();
75 73
            $this->createHash();
76
77 73
            if ($existingKey = $this->isHashUnique()) {
78 1
                $this->handleDuplicateHash($existingKey);
79
80 1
                if ($this->stopIfInvalid) {
81
                    return false;
82
                }
83 1
            }
84
85 73
            $this->fileKeys[$this->rowNumber] = $this->hash;
86 73
            $this->rowNumber++;
87 73
        }
88
89 73
        return true;
90
    }
91
92
93
    /**
94
     * Set the primary key fields.
95
     *
96
     * @return  void
97
     */
98 73
    private function setPrimaryKeyFields()
99
    {
100 73
        $this->primaryKeyFields = (array) parent::$schemaJson->primaryKey;
101 73
    }
102
103
104
    /**
105
     * Check that there is a column in the JSON table schema file for the current primary key field.
106
     *
107
     * @return  void
108
     *
109
     * @throws  \Exception if the primary key was not in the schema file.
110
     */
111 73
    private function checkColumnExistsInSchema()
112
    {
113 73
        if (false === $this->getSchemaKeyFromName($this->primaryKeyFieldName)) {
114
            throw new \Exception("The primary key &quot;$this->primaryKeyFieldName&quot; was not in the file.
115
                    Primary key columns should be set as required.");
116
        }
117 73
    }
118
119
120
    /**
121
     * Get the data in the CSV column for the current primary key column.
122
     *
123
     * @return  string  The data in the column.
124
     */
125 73
    private function csvDataForPrimaryKeyColumn()
126
    {
127 73
        $csvPosition = $this->getCsvPositionFromName($this->primaryKeyFieldName);
128 73
        return $this->currentCsvRow[$csvPosition];
129
    }
130
131
132
    /**
133
     * Get the data in the primary key columns for the current CSV row.
134
     *
135
     * @return  void
136
     */
137 73
    private function getPrimaryKeyDataForRow()
138
    {
139 73
        $this->rowKeyParts = [];
140
141 73
        foreach ($this->primaryKeyFields as $fieldName) {
142 73
            $this->primaryKeyFieldName = strtolower($fieldName);
143 73
            $this->checkColumnExistsInSchema();
144 73
            $this->rowKeyParts[] = $this->csvDataForPrimaryKeyColumn();
145 73
        }
146 73
    }
147
148
149
    /**
150
     * Create a hash of the data taken from the primary key fields in the current CSV row.
151
     *
152
     * @return  void
153
     */
154 73
    private function createHash()
155
    {
156 73
        $this->hash = implode(', ', $this->rowKeyParts);
157 73
    }
158
159
160
    /**
161
     * Check whether the current hash has already been created for this file.
162
     *
163
     * @return  boolean|int False if this row's primary key hash is unique
164
     *                      or the number of the row with the same hash if it's not.
165
     */
166 73
    private function isHashUnique()
167
    {
168 73
        return array_search($this->hash, $this->fileKeys);
169
    }
170
171
172
    /**
173
     * Handle the current hash not being unique.
174
     *
175
     * @param   int $existingKey    The number of the row with the same hash.
176
     *
177
     * @return  void
178
     */
179 1 View Code Duplication
    private function handleDuplicateHash($existingKey)
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in 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...
180
    {
181 1
        $primaryKeyColumns = implode(', ', $this->primaryKeyFields);
182
        $errorMessage = "The data in columns &quot;$primaryKeyColumns&quot; should be unique,
183 1
                but rows $existingKey &amp; $this->rowNumber have the same values of &quot;$this->hash&quot;";
184
185 1
        $this->error->setError(self::ERROR_DUPLICATE_PRIMARY_KEY, $errorMessage);
186 1
        $this->statistics->setErrorRow($this->rowNumber);
187
    }
188
}