Completed
Push — master ( a2c8d4...3a88fc )
by Nazar
07:08
created

SQLite   B

Complexity

Total Complexity 40

Size/Duplication

Total Lines 184
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 65.32%

Importance

Changes 0
Metric Value
dl 0
loc 184
rs 8.2608
c 0
b 0
f 0
ccs 81
cts 124
cp 0.6532
wmc 40
lcom 1
cbo 1

13 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 16 3
A q() 0 5 1
A q_internal() 0 6 2
A q_multi_internal() 0 7 3
B f() 0 16 9
A id() 0 3 1
A affected() 0 3 1
A free() 0 6 2
C columns() 0 31 8
B tables() 0 23 4
A s_internal() 0 4 2
A server() 0 3 1
A __destruct() 0 6 3

How to fix   Complexity   

Complex Class

Complex classes like SQLite often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use SQLite, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * @package   CleverStyle Framework
4
 * @author    Nazar Mokrynskyi <[email protected]>
5
 * @copyright Copyright (c) 2016, Nazar Mokrynskyi
6
 * @license   MIT License, see license.txt
7
 */
8
namespace cs\DB;
9
use
10
	SQLite3Result;
11
12
class SQLite extends _Abstract {
13
	/**
14
	 * @var \SQLite3 Instance of DB connection
15
	 */
16
	protected $instance;
17
	/**
18
	 * @param string $database Ignored for SQLite
19
	 * @param string $user     Ignored for SQLite
20
	 * @param string $password Ignored for SQLite
21
	 * @param string $host     Path to database file, relatively to website root or absolute
22
	 * @param string $prefix
23
	 */
24 22
	function __construct ($database, $user = '', $password = '', $host = '', $prefix = '') {
25
		// Hack for HHVM: https://github.com/facebook/hhvm/issues/7225
26 22
		if (!$host) {
27 1
			return;
28
		}
29 22
		$start = microtime(true);
30
		try {
31 22
			$this->instance        = new \SQLite3($host);
32 22
			$this->database        = $database;
33 22
			$this->connected       = true;
34 22
			$this->connecting_time = microtime(true) - $start;
35 22
			$this->db_type         = 'sqlite';
36 22
			$this->prefix          = $prefix;
37
		} catch (\Exception $e) {
38
		}
39 22
	}
40
	/**
41
	 * @inheritdoc
42
	 */
43 22
	function q ($query, $params = [], ...$param) {
44
		// Hack to convert small subset of MySQL queries into SQLite-compatible syntax
45 22
		$query = str_replace('INSERT IGNORE', 'INSERT OR IGNORE', $query);
46 22
		return parent::q(...([$query] + func_get_args()));
47
	}
48
	/**
49
	 * @inheritdoc
50
	 *
51
	 * @return false|SQLite3Result
52
	 */
53 22
	protected function q_internal ($query) {
54 22
		if (!$query) {
55 1
			return false;
56
		}
57 22
		return $this->instance->query($query);
58
	}
59
	/**
60
	 * @inheritdoc
61
	 */
62 6
	protected function q_multi_internal ($query) {
63 6
		$result = true;
64 6
		foreach ($query as $q) {
65 6
			$result = $result && $this->q_internal($q);
66
		}
67 6
		return $result;
68
	}
69
	/**
70
	 * @inheritdoc
71
	 *
72
	 * @param false|SQLite3Result $query_result
73
	 */
74 21
	function f ($query_result, $single_column = false, $array = false, $indexed = false) {
75 21
		if (!($query_result instanceof SQLite3Result)) {
76 1
			return false;
77
		}
78 21
		$result_type = $single_column || $indexed ? SQLITE3_NUM : SQLITE3_ASSOC;
79 21
		if ($array) {
80 18
			$result = [];
81 18
			while ($current = $query_result->fetchArray($result_type)) {
82 18
				$result[] = $single_column ? $current[0] : $current;
83
			}
84 18
			$this->free($query_result);
85 18
			return $result;
86
		}
87 20
		$result = $query_result->fetchArray($result_type);
88 20
		return $single_column && $result ? $result[0] : $result;
89
	}
90
	/**
91
	 * @inheritdoc
92
	 */
93 15
	function id () {
94 15
		return $this->instance->lastInsertRowID();
95
	}
96
	/**
97
	 * @inheritdoc
98
	 */
99 1
	function affected () {
100 1
		return $this->instance->changes();
101
	}
102
	/**
103
	 * @inheritdoc
104
	 *
105
	 * @param false|SQLite3Result $query_result
106
	 */
107 18
	function free ($query_result) {
108 18
		if ($query_result instanceof SQLite3Result) {
109 18
			return $query_result->finalize();
110
		}
111 1
		return true;
112
	}
113
	/**
114
	 * @inheritdoc
115
	 */
116 2
	function columns ($table, $like = false) {
117 2
		if (!$table) {
118 1
			return false;
119
		}
120 2
		$columns = $this->qfa("PRAGMA table_info(`$table`)") ?: [];
121 2
		foreach ($columns as &$column) {
122 2
			$column = $column['name'];
123
		}
124
		/**
125
		 * Only support the most common cases
126
		 */
127 2
		if ($like) {
128 1
			if (substr($like, -1) == '%') {
129 1
				$like = substr($like, 0, -1);
130 1
				return array_values(
131
					array_filter(
132
						$columns,
133 1
						function ($column) use ($like) {
134 1
							return strpos($column, $like) === 0;
135 1
						}
136
					)
137
				);
138 1
			} elseif (strpos($like, '%') === false) {
139 1
				return in_array($like, $columns) ? [$like] : [];
140
			} else {
141 1
				trigger_error("Can't get columns like $like, SQLite engine doesn't support such conditions", E_USER_WARNING);
142 1
				return [];
143
			}
144
		}
145 2
		return $columns;
146
	}
147
	/**
148
	 * @inheritdoc
149
	 */
150 1
	function tables ($like = false) {
151 1
		if ($like) {
152 1
			$like = $this->s($like);
153 1
			return $this->qfas(
154
				"SELECT `name`
155
				FROM `sqlite_master`
156
				WHERE
157
					`type` = 'table' AND
158
					`name` != 'sqlite_sequence' AND
159 1
					`name` LIKE $like
160 1
				ORDER BY `name` ASC"
161 1
			) ?: [];
162
		} else {
163 1
			return $this->qfas(
164
				"SELECT `name`
165
				FROM `sqlite_master`
166
				WHERE
167
					`type` = 'table' AND
168
					`name` != 'sqlite_sequence'
169 1
				ORDER BY `name` ASC"
170 1
			) ?: [];
171
		}
172
	}
173
	/**
174
	 * @inheritdoc
175
	 */
176 22
	protected function s_internal ($string, $single_quotes_around) {
177 22
		$return = \SQLite3::escapeString($string);
178 22
		return $single_quotes_around ? "'$return'" : $return;
179
	}
180
	/**
181
	 * @inheritdoc
182
	 */
183 1
	function server () {
184 1
		return \SQLite3::version()['versionString'];
185
	}
186
	/**
187
	 * @inheritdoc
188
	 */
189 2
	function __destruct () {
190 2
		if ($this->connected && is_object($this->instance)) {
191 2
			$this->instance->close();
192 2
			$this->connected = false;
193
		}
194 2
	}
195
}
196