Completed
Push — test ( 5bf343...41c779 )
by Temitope
03:44
created

DatabaseHandler   A

Complexity

Total Complexity 34

Size/Duplication

Total Lines 281
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 1
Bugs 1 Features 0
Metric Value
wmc 34
lcom 1
cbo 4
dl 0
loc 281
rs 9.2
c 1
b 1
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 12 2
A create() 0 20 3
B insertRecord() 0 24 3
B update() 0 41 6
B read() 0 24 4
A delete() 0 17 3
A filterClassAttributes() 0 13 3
A prepareUpdateQuery() 0 11 1
B findAndWhere() 0 24 6
A getColumnNames() 0 23 3
1
<?php
2
3
/**
4
 * @package  Laztopaz\potato-ORM
5
 * @author   Temitope Olotin <[email protected]>
6
 * @license  <https://opensource.org/license/MIT> MIT
7
 */
8
9
namespace Laztopaz\PotatoORM;
10
11
use PDO;
12
use Laztopaz\PotatoORM\DatabaseHelper;
13
use Laztopaz\PotatoORM\TableFieldUndefinedException;
14
use Laztopaz\PotatoORM\EmptyArrayException;
15
use Laztopaz\PotatoORM\NoRecordDeletionException;
16
use Laztopaz\PotatoORM\NoRecordInsertionException;
17
use Laztopaz\PotatoORM\NoRecordUpdateException;
18
19
class DatabaseHandler {
20
21
    private $tableFields;
0 ignored issues
show
Unused Code introduced by
The property $tableFields is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
22
    private $dbHelperInstance;
0 ignored issues
show
Unused Code introduced by
The property $dbHelperInstance is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
23
    private $dbConnection;
24
    private $model;
25
    
26
    /**
27
     * This is a constructor; a default method  that will be called automatically during class instantiation
28
     */
29
    public function __construct($modelClassName, $dbConn = Null) 
30
    {
31
        if (is_null($dbConn)) {
32
            $this->dbConnection = new DatabaseConnection();
33
34
        } else {
35
            $this->dbConnection = $dbConn;
36
37
        }
38
        
39
        $this->model = $modelClassName;
40
     }
41
     
42
    /**
43
     * This method create a record and store it in a table row
44
     * @params associative array, string tablename
45
     * @return boolean true or false
46
     */
47
    public function create($associative1DArray, $tableName, $dbConn = Null) 
48
    {
49
        $tableFields = $this->getColumnNames($this->model, $this->dbConnection);
50
51
        $unexpectedFields = self::filterClassAttributes($tableFields, $associative1DArray);
52
      
53
        if (count($unexpectedFields) > 0) {
54
            throw TableFieldUndefinedException::create($unexpectedFields,"needs to be created as a table field");
55
        }
56
57
        unset($associative1DArray[0]);
58
59
        if (is_null($dbConn)) {
60
            $dbConn = $this->dbConnection;
61
62
        }
63
64
        return $this->insertRecord($dbConn, $tableName, $associative1DArray);
65
66
    }
67
    
68
    /**
69
     * This method runs the insertion query
70
     * @param  $dbConn           
71
     * @param  $tableName          
72
     * @param  $associative1DArray 
73
     * @return boolean true         
74
     */
75
    private function  insertRecord($dbConn, $tableName, $associative1DArray) 
76
    {
77
        $insertQuery = 'INSERT INTO '.$tableName;
78
79
        $TableValues = implode(',',array_keys($associative1DArray));
80
81
        foreach ($associative1DArray as $field => $value) {
82
            $FormValues[] = "'".trim(addslashes($value))."'";
0 ignored issues
show
Coding Style Comprehensibility introduced by
$FormValues was never initialized. Although not strictly required by PHP, it is generally a good practice to add $FormValues = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
83
        }
84
85
        $splittedTableValues = implode(',', $FormValues);
0 ignored issues
show
Bug introduced by
The variable $FormValues does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
86
87
        $insertQuery.= ' ('.$TableValues.')';
88
        $insertQuery.= ' VALUES ('.$splittedTableValues.')';
89
90
        $executeQuery = $dbConn->exec($insertQuery);
91
92
        if ($executeQuery) {
93
            return true;
94
        }
95
96
        return false;
97
98
      }
99
100
    /**
101
     * This method updates any table by supplying 3 parameter
102
     * @params: $updateParams, $tableName, $associative1DArray
103
     * @return boolean true or false
104
     */
105
    public function update(array $updateParams, $tableName, $associative1DArray, $dbConn = null)
106
    {
107
        $sql = "";
108
109
        if (is_null($dbConn)) {
110
            $dbConn = $this->dbConnection;
111
112
        }
113
114
        $updateSql = "UPDATE `$tableName` SET ";
115
116
        unset($associative1DArray['id']);
117
118
        $unexpectedFields = self::filterClassAttributes($this->getColumnNames($this->model, $this->dbConnection), $associative1DArray);
119
120
        if (count($unexpectedFields) > 0) {
121
            throw TableFieldUndefinedException::create($unexpectedFields, "needs to be created as a table field");
122
        }
123
124
        foreach ($associative1DArray as $field => $value) {
125
            $sql .= "`$field` = '$value'".",";
126
        }
127
128
        $updateSql .= $this->prepareUpdateQuery($sql);
129
130
        foreach ($updateParams as $key => $val) {
131
            $updateSql .= " WHERE $key = $val";
132
        }
133
134
        $stmt = $dbConn->prepare($updateSql);
135
136
        $boolResponse = $stmt->execute();
137
138
        if ($boolResponse) {
139
            return true;
140
141
        }
142
143
        return false;
144
145
    }
146
    
147
  /**
148
   * This method retrieves record from a table
149
   * @params int id, string tableName
150
   * @return array
151
   */
152
   public static function read($id, $tableName, $dbConn = null)
153
   {
154
       $tableData = [];
155
156
       if (is_null($dbConn)) {
157
           $dbConn = new DatabaseConnection();
158
       }
159
160
       $sql = $id ? 'SELECT * FROM '.$tableName.' WHERE id = '.$id : 'SELECT * FROM '.$tableName;
161
162
       $stmt = $dbConn->prepare($sql);
163
       $stmt->bindValue(':table', $tableName);
164
       $stmt->bindValue(':id', $id);
165
       $stmt->execute();
166
167
       $results = $stmt->fetchAll(PDO::FETCH_ASSOC);
168
169
       foreach ($results as $result) {
170
           array_push($tableData, $result);
171
       }
172
173
       return $tableData;
174
175
   }
176
   
177
  /**
178
   * This method deletes a record  from a table row
179
   * @params int id, string tableName
180
   * @return boolean true or false
181
   */
182
  public static function delete($id, $tableName, $dbConn = null)
183
  {
184
      if (is_null($dbConn)) {
185
          $dbConn = new DatabaseConnection();
186
      }
187
188
      $sql = 'DELETE FROM '.$tableName.' WHERE id = '.$id;
189
190
      $boolResponse = $dbConn->exec($sql);
191
192
      if ($boolResponse) {
193
          return true;
194
195
      }
196
197
      throw NoRecordDeletionException::create("Record deletion unsuccessful because id does not match any record");
198
  }
199
  
200
  /**
201
   * This method checks if the magic setters array is the same as the table columns
202
   * @param array $tableColumn
203
   * @param array $userSetterArray
204
   * @return array $unexpectedFields
205
   */
206
  public static function filterClassAttributes(array $tableColumn, array $userSetterArray)
207
  {
208
      $unexpectedFields = [];
209
210
      foreach ($userSetterArray as $key => $val) {
211
          if (! in_array($key, $tableColumn)) {
212
              $unexpectedFields[] = $key;
213
          }
214
      }
215
216
      return $unexpectedFields;
217
218
  }
219
  
220
  /**
221
   * This method returns sql query
222
   * @param $sql
223
   * @return string
224
   */
225
  public function prepareUpdateQuery($sql)
226
  {
227
      $splittedQuery = explode(",",$sql);
228
229
      array_pop($splittedQuery);
230
231
      $mergeData = implode(",",$splittedQuery);
232
233
      return $mergeData;
234
235
  }
236
  
237
  /**
238
   * @param array $params
239
   * @param $tableName
240
   * @param $dbConn
241
   * @return bool
242
   * @throws EmptyArrayException
243
   */
244
  public function findAndWhere($params, $tableName, $dbConn = null)
245
  {
246
      if (is_null($dbConn)) {
247
          $dbConn = $this->dbConnection;
248
      }
249
250
      if (is_array($params) && !empty($params)) {
251
          $sql = "SELECT * FROM ".$tableName;
252
253
          foreach ($params as $key => $val) {
254
              $sql .= " WHERE `$key` = '$val'";
255
          }
256
257
          $statement = $dbConn->prepare($sql);
258
          $statement->execute();
259
260
          $returnedRowNumbers = $statement->rowCount();
261
          
262
          return $returnedRowNumbers ? true : false;
263
264
      }
265
266
      throw EmptyArrayException::create("Array Expected: parameter passed to this function is not an array");
267
  }
268
  
269
  /**
270
   * This method returns column fields of a particular table
271
   * @param $table
272
   * @param $conn
273
   * @return array
274
   */
275
  public function getColumnNames($table, $dbConn = null) 
276
  {
277
      $tableFields = [];
278
     
279
      if (is_null($dbConn)) {
280
         $dbConn = $this->dbConnection;
281
      }
282
283
      $sql = "SHOW COLUMNS FROM ".$table;
284
     
285
      $stmt = $dbConn->prepare($sql);
286
      $stmt->bindValue(':table', $table, PDO::PARAM_STR);
287
      $stmt->execute();
288
289
      $results = $stmt->fetchAll(PDO::FETCH_ASSOC);
290
     
291
      foreach ($results as $result) {
292
          array_push($tableFields, $result['Field']);
293
      }
294
295
      return $tableFields;
296
     
297
  }
298
299
}
300