Completed
Push — master ( 195cac...2c4aac )
by Nazar
05:02
created

SQLite::tables()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 23
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 7.6085

Importance

Changes 0
Metric Value
cc 4
eloc 9
nc 4
nop 1
dl 0
loc 23
ccs 9
cts 23
cp 0.3913
crap 7.6085
rs 8.7972
c 0
b 0
f 0
1
<?php
2
/**
3
 * @package   CleverStyle Framework
4
 * @author    Nazar Mokrynskyi <[email protected]>
5
 * @copyright Copyright (c) 2016-2017, 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 32
	public function __construct ($database, $user = '', $password = '', $host = '', $prefix = '') {
25 32
		if (!$host) {
26 1
			return;
27
		}
28 32
		$start = microtime(true);
29
		try {
30 32
			$this->instance        = new \SQLite3($host);
31 32
			$this->database        = $database;
32 32
			$this->connected       = true;
33 32
			$this->connecting_time = microtime(true) - $start;
34 32
			$this->db_type         = 'sqlite';
35 32
			$this->prefix          = $prefix;
36
		} catch (\Exception $e) {
37
		}
38 32
	}
39
	/**
40
	 * @inheritdoc
41
	 */
42 32
	public function q ($query, ...$params) {
43 32
		return parent::q(
44 32
			$this->convert_sql($query),
45 32
			...$params
46
		);
47
	}
48
	/**
49
	 * Convert small subset of MySQL queries into SQLite-compatible syntax
50
	 *
51
	 * @param string $query
52
	 *
53
	 * @return string
54
	 */
55 32
	protected function convert_sql ($query) {
56 32
		return str_replace('INSERT IGNORE', 'INSERT OR IGNORE', $query);
57
	}
58
	/**
59
	 * @inheritdoc
60
	 *
61
	 * @return false|SQLite3Result
62
	 */
63 32
	protected function q_internal ($query, $parameters = []) {
64 32
		if (!$query) {
65 1
			return false;
66
		}
67 32
		if ($parameters) {
68 27
			$stmt = $this->instance->prepare($query);
69 27
			if (!$stmt) {
70
				return false;
71
			}
72
			// Allows to provide more parameters for prepared statements than needed
73 27
			$local_parameters = array_slice($parameters, 0, substr_count($query, '?'));
74 27
			foreach ($local_parameters as $index => $parameter) {
75 27
				$stmt->bindValue($index + 1, $parameter);
76
			}
77 27
			return $stmt->execute();
78
		}
79 32
		return $this->instance->query($query);
80
	}
81
	/**
82
	 * @inheritdoc
83
	 *
84
	 * @param false|SQLite3Result $query_result
85
	 */
86 32
	public function f ($query_result, $single_column = false, $array = false, $indexed = false) {
87 32
		if (!($query_result instanceof SQLite3Result)) {
88 1
			return false;
89
		}
90 32
		$result_type = $single_column || $indexed ? SQLITE3_NUM : SQLITE3_ASSOC;
91 32
		if ($array) {
92 27
			$result = [];
93 27
			while ($current = $query_result->fetchArray($result_type)) {
94 26
				$result[] = $single_column ? $current[0] : $current;
95
			}
96 27
			$this->free($query_result);
97 27
			return $result;
98
		}
99 30
		$result = $query_result->fetchArray($result_type);
100 30
		return $single_column && $result ? $result[0] : $result;
101
	}
102
	/**
103
	 * @inheritdoc
104
	 */
105 24
	public function id () {
106 24
		return $this->instance->lastInsertRowID();
107
	}
108
	/**
109
	 * @inheritdoc
110
	 */
111 1
	public function affected () {
112 1
		return $this->instance->changes();
113
	}
114
	/**
115
	 * @inheritdoc
116
	 *
117
	 * @param false|SQLite3Result $query_result
118
	 */
119 27
	public function free ($query_result) {
120 27
		if ($query_result instanceof SQLite3Result) {
121 27
			return $query_result->finalize();
122
		}
123 1
		return true;
124
	}
125
	/**
126
	 * @inheritdoc
127
	 */
128 3
	public function columns ($table, $like = false) {
129 3
		if (!$table) {
130 1
			return false;
131
		}
132 3
		$columns = $this->qfa("PRAGMA table_info(`$table`)") ?: [];
133 3
		foreach ($columns as &$column) {
134 3
			$column = $column['name'];
135
		}
136
		/**
137
		 * Only support the most common cases
138
		 */
139 3
		if ($like) {
140 1
			if (substr($like, -1) == '%') {
141 1
				$like = substr($like, 0, -1);
142 1
				return array_values(
143
					array_filter(
144
						$columns,
145 1
						function ($column) use ($like) {
146 1
							return strpos($column, $like) === 0;
147 1
						}
148
					)
149
				);
150 1
			} elseif (strpos($like, '%') === false) {
151 1
				return in_array($like, $columns) ? [$like] : [];
152
			} else {
153 1
				trigger_error("Can't get columns like $like, SQLite driver doesn't support such conditions", E_USER_WARNING);
154 1
				return [];
155
			}
156
		}
157 3
		return $columns;
158
	}
159
	/**
160
	 * @inheritdoc
161
	 */
162 1
	public function tables ($like = false) {
163 1
		if ($like) {
164 1
			$like = $this->s($like);
165 1
			return $this->qfas(
166
				"SELECT `name`
167
				FROM `sqlite_master`
168
				WHERE
169
					`type` = 'table' AND
170
					`name` != 'sqlite_sequence' AND
171 1
					`name` LIKE $like
172
				ORDER BY `name` ASC"
173 1
			) ?: [];
174
		} else {
175 1
			return $this->qfas(
176 1
				"SELECT `name`
177
				FROM `sqlite_master`
178
				WHERE
179
					`type` = 'table' AND
180
					`name` != 'sqlite_sequence'
181
				ORDER BY `name` ASC"
182 1
			) ?: [];
183
		}
184
	}
185
	/**
186
	 * @inheritdoc
187
	 */
188 29
	protected function s_internal ($string, $single_quotes_around) {
189 29
		$return = \SQLite3::escapeString($string);
190 29
		return $single_quotes_around ? "'$return'" : $return;
191
	}
192
	/**
193
	 * @inheritdoc
194
	 */
195 1
	public function server () {
196 1
		return \SQLite3::version()['versionString'];
197
	}
198
	/**
199
	 * @inheritdoc
200
	 */
201 1
	public function __destruct () {
202 1
		if ($this->connected && is_object($this->instance)) {
203 1
			$this->instance->close();
204 1
			$this->connected = false;
205
		}
206 1
	}
207
}
208