Completed
Pull Request — development (#3098)
by John
09:23
created

DbSearch_PostgreSQL   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 199
Duplicated Lines 4.02 %

Coupling/Cohesion

Components 2
Dependencies 2

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 16
lcom 2
cbo 2
dl 8
loc 199
ccs 0
cts 128
cp 0
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A search_support() 0 6 1
A search_query() 0 56 4
A skip_next_error() 0 4 1
B membersTableInfo() 8 56 7
A create_word_search() 0 18 1
A db_search() 0 8 2

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
3
/**
4
 * This class handles database search. (PostgreSQL)
5
 *
6
 * @name      ElkArte Forum
7
 * @copyright ElkArte Forum contributors
8
 * @license   BSD http://opensource.org/licenses/BSD-3-Clause
9
 *
10
 * @version 2.0 dev
11
 *
12
 */
13
14
/**
15
 * PostgreSQL implementation of DbSearch
16
 */
17
class DbSearch_PostgreSQL implements DbSearch
18
{
19
	/**
20
	 * This instance of the search
21
	 * @var DbSearch_PostgreSQL
22
	 */
23
	private static $_search = null;
24
25
	/**
26
	 * The way to skip a database error
27
	 * @var boolean
28
	 */
29
	protected $_skip_error = false;
30
31
	/**
32
	 * This function will tell you whether this database type supports this search type.
33
	 *
34
	 * @param string $search_type
35
	 *
36
	 * @return bool
37
	 */
38
	public function search_support($search_type)
39
	{
40
		$supported_types = array('custom');
41
42
		return in_array($search_type, $supported_types);
43
	}
44
45
	/**
46
	 * Compute and execute the correct query for search.
47
	 * Returns the result of executing the query.
48
	 *
49
	 * @param string $identifier
50
	 * @param string $db_string
51
	 * @param mixed[] $db_values default array()
52
	 * @param resource|null $connection
53
	 */
54
	public function search_query($identifier, $db_string, $db_values = array(), $connection = null)
55
	{
56
		$db = database();
57
58
		$replacements = array(
59
			'create_tmp_log_search_topics' => array(
60
				'~mediumint\(\d\)~i' => 'int',
61
				'~unsigned~i' => '',
62
				'~ENGINE=MEMORY~i' => '',
63
			),
64
			'create_tmp_log_search_messages' => array(
65
				'~mediumint\(\d\)~i' => 'int',
66
				'~unsigned~i' => '',
67
				'~ENGINE=MEMORY~i' => '',
68
			),
69
			'drop_tmp_log_search_topics' => array(
70
				'~IF\sEXISTS~i' => '',
71
			),
72
			'drop_tmp_log_search_messages' => array(
73
				'~IF\sEXISTS~i' => '',
74
			),
75
			'insert_into_log_messages_fulltext' => array(
76
				'~LIKE~i' => 'iLIKE',
77
				'~NOT\sLIKE~i' => '~NOT iLIKE',
78
				'~NOT\sRLIKE~i' => '!~*',
79
				'~RLIKE~i' => '~*',
80
			),
81
			'insert_log_search_results_subject' => array(
82
				'~LIKE~i' => 'iLIKE',
83
				'~NOT\sLIKE~i' => 'NOT iLIKE',
84
				'~NOT\sRLIKE~i' => '!~*',
85
				'~RLIKE~i' => '~*',
86
			),
87
		);
88
89
		if (isset($replacements[$identifier]))
90
			$db_string = preg_replace(array_keys($replacements[$identifier]), array_values($replacements[$identifier]), $db_string);
91
		elseif (preg_match('~^\s*INSERT\sIGNORE~i', $db_string) != 0)
92
		{
93
			$db_string = preg_replace('~^\s*INSERT\sIGNORE~i', 'INSERT', $db_string);
94
			// Don't error on multi-insert.
95
			$this->_skip_error = true;
96
		}
97
98
		if ($this->_skip_error === true)
99
		{
100
			$db->skip_next_error();
101
			$this->_skip_error = false;
102
		}
103
104
		$return = $db->query('', $db_string,
105
			$db_values, $connection
106
		);
107
108
		return $return;
109
	}
110
111
	/**
112
	 * {@inheritDoc}
113
	 */
114
	public function skip_next_error()
115
	{
116
		$this->_skip_error = true;
117
	}
118
119
	/**
120
	 * Returns some basic info about the {db_prefix}messages table
121
	 * Used in ManageSearch.controller.php in the page to select the index method
122
	 */
123
	public function membersTableInfo()
124
	{
125
		global $db_prefix, $txt;
126
127
		$db = database();
128
		$db_table = db_table();
129
130
		$table_info = array();
131
132
		// In order to report the sizes correctly we need to perform vacuum (optimize) on the tables we will be using.
133
		$db_table->optimize('{db_prefix}messages');
134
		if ($db_table->table_exists('{db_prefix}log_search_words'))
135
			$db_table->optimize('{db_prefix}log_search_words');
136
137
		// PostGreSql has some hidden sizes.
138
		$request = $db->query('', '
139
			SELECT relname, relpages * 8 *1024 AS "KB" FROM pg_class
140
			WHERE relname = {string:messages} OR relname = {string:log_search_words}
141
			ORDER BY relpages DESC',
142
			array(
143
				'messages' => $db_prefix . 'messages',
144
				'log_search_words' => $db_prefix . 'log_search_words',
145
			)
146
		);
147
148
		if ($request !== false && $db->num_rows($request) > 0)
149
		{
150
			while ($row = $db->fetch_assoc($request))
151
			{
152
				if ($row['relname'] == $db_prefix . 'messages')
153
				{
154
					$table_info['data_length'] = (int) $row['KB'];
155
					$table_info['index_length'] = (int) $row['KB'];
156
157
					// Doesn't support fulltext
158
					$table_info['fulltext_length'] = $txt['not_applicable'];
159
				}
160
				elseif ($row['relname'] == $db_prefix . 'log_search_words')
161
				{
162
					$table_info['index_length'] = (int) $row['KB'];
163
					$table_info['custom_index_length'] = (int) $row['KB'];
164
				}
165
			}
166
			$db->free_result($request);
167
		}
168 View Code Duplication
		else
169
			// Didn't work for some reason...
170
			$table_info = array(
171
				'data_length' => $txt['not_applicable'],
172
				'index_length' => $txt['not_applicable'],
173
				'fulltext_length' => $txt['not_applicable'],
174
				'custom_index_length' => $txt['not_applicable'],
175
			);
176
177
		return $table_info;
178
	}
179
180
	/**
181
	 * Make a custom word index.
182
	 *
183
	 * @param string $size
184
	 */
185
	public function create_word_search($size)
186
	{
187
		$db = database();
188
189
		$size = 'int';
190
191
		$db->query('', '
192
			CREATE TABLE {db_prefix}log_search_words (
193
				id_word {raw:size} NOT NULL default {string:string_zero},
194
				id_msg int NOT NULL default {string:string_zero},
195
				PRIMARY KEY (id_word, id_msg)
196
			)',
197
			array(
198
				'size' => $size,
199
				'string_zero' => '0',
200
			)
201
		);
202
	}
203
204
	/**
205
	 * Static method that allows to retrieve or create an instance of this class.
206
	 */
207
	public static function db_search()
208
	{
209
		if (is_null(self::$_search))
210
		{
211
			self::$_search = new self();
212
		}
213
		return self::$_search;
214
	}
215
}