Completed
Push — master ( 20ce86...00401a )
by Chris
02:49
created

MySql::identifier()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 17
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 17
rs 9.2
cc 4
eloc 9
nc 4
nop 1
1
<?php
2
namespace Darya\Database\Query\Translator;
3
4
use Darya\Database\Query\AbstractSqlTranslator;
5
6
/**
7
 * Darya's MySQL query translator.
8
 * 
9
 * @author Chris Andrew <[email protected]>
10
 */
11
class MySql extends AbstractSqlTranslator {
12
	
13
	/**
14
	 * Resolve the given value as an identifier.
15
	 * 
16
	 * @param mixed $identifier
17
	 * @return mixed
18
	 */
19
	protected function resolveIdentifier($identifier) {
20
		if (!is_string($identifier)) {
21
			return $identifier;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $identifier; (object|integer|double|null|array|boolean) is incompatible with the return type declared by the abstract method Darya\Database\Query\Abs...ator::resolveIdentifier of type string.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
22
		}
23
		
24
		$split = explode('.', $identifier, 2);
25
		
26
		foreach ($split as $index => $value) {
27
			$split[$index] = $value !== '*' ? '`' . $value . '`' : $value;
28
		}
29
		
30
		return implode('.', $split);
31
	}
32
	
33
	/**
34
	 * Prepare a LIMIT clause using the given limit and offset.
35
	 * 
36
	 * @param int $limit  [optional]
37
	 * @param int $offset [optional]
38
	 * @return string
39
	 */
40
	protected function prepareLimit($limit = 0, $offset = 0) {
41
		if (!static::limitIsUseful($limit, $offset)) {
42
			return null;
43
		}
44
		
45
		$limit = (int) $limit;
46
		$offset = (int) $offset;
47
		
48
		$query = 'LIMIT ';
49
		
50
		if ($offset > 0) {
51
			$query .= "$offset, ";
52
		}
53
		
54
		return $query . $limit;
55
	}
56
	
57
	/**
58
	 * Prepare a SELECT statement using the given columns, table, clauses and
59
	 * options.
60
	 * 
61
	 * @param string       $table
62
	 * @param array|string $columns
63
	 * @param string       $joins    [optional]
64
	 * @param string       $where    [optional]
65
	 * @param string       $order    [optional]
66
	 * @param string       $limit    [optional]
67
	 * @param bool         $distinct [optional]
68
	 * @return string
69
	 */
70 View Code Duplication
	protected function prepareSelect($table, $columns, $joins = null, $where = null, $order = null, $limit = null, $distinct = false) {
0 ignored issues
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...
71
		$table = $this->identifier($table);
72
		
73
		$distinct = $distinct ? 'DISTINCT' : '';
74
		
75
		return static::concatenate(array('SELECT', $distinct, $columns, 'FROM', $table, $joins, $where, $order, $limit));
76
	}
77
	
78
	/**
79
	 * Prepare an UPDATE statement with the given table, data and clauses.
80
	 * 
81
	 * @param string $table
82
	 * @param array  $data
83
	 * @param string $where [optional]
84
	 * @param string $limit [optional]
85
	 * @return string
86
	 */
87 View Code Duplication
	protected function prepareUpdate($table, $data, $where = null, $limit = null) {
0 ignored issues
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...
88
		$table = $this->identifier($table);
89
		
90
		foreach ($data as $key => $value) {
91
			$column = $this->identifier($key);
92
			$value = $this->value($value);
93
			$data[$key] = "$column = $value";
94
		}
95
		
96
		$values = implode(', ', $data);
97
		
98
		return static::concatenate(array('UPDATE', $table, 'SET', $values, $where, $limit));
99
	}
100
	
101
	/**
102
	 * Prepare a DELETE statement with the given table and clauses.
103
	 * 
104
	 * @param string $table
105
	 * @param string $where [optional]
106
	 * @param string $limit [optional]
107
	 * @return string
108
	 */
109 View Code Duplication
	protected function prepareDelete($table, $where = null, $limit = null) {
0 ignored issues
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...
110
		$table = $this->identifier($table);
111
		
112
		if ($table == '*' || !$table || !$where) {
113
			return null;
114
		}
115
		
116
		return static::concatenate(array('DELETE FROM', $table, $where, $limit));
117
	}
118
	
119
}
120