Completed
Pull Request — master (#23)
by
unknown
02:00
created

fulltext_support::is_postgres()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
/**
3
 *
4
 * Precise Similar Topics
5
 *
6
 * @copyright (c) 2014 Matt Friedman
7
 * @license GNU General Public License, version 2 (GPL-2.0)
8
 *
9
 */
10
11
namespace vse\similartopics\core;
12
13
class fulltext_support
14
{
15
	/** @var \phpbb\db\driver\driver_interface */
16
	protected $db;
17
18
	/** @var string */
19
	protected $engine;
20
21
	/**
22
	 * Constructor
23
	 *
24
	 * @access public
25
	 * @param  \phpbb\db\driver\driver_interface
26
	 */
27
	public function __construct(\phpbb\db\driver\driver_interface $db)
28
	{
29
		$this->db = $db;
30
	}
31
32
	/**
33
	 * Check if the database is using MySQL
34
	 *
35
	 * @access public
36
	 * @return bool True if is mysql, false otherwise
37
	 */
38
	public function is_mysql()
39
	{
40
		return ($this->db->get_sql_layer() === 'mysql4' || $this->db->get_sql_layer() === 'mysqli');
41
	}
42
43
	/**
44
	 * Check if the database is using PostgreSQL
45
	 *
46
	 * @access public
47
	 * @return bool True if is postgresql, false otherwise
48
	 */
49
	public function is_postgres()
50
	{
51
		return ($this->db->get_sql_layer() === 'postgres');
52
	}
53
54
	/**
55
	 * Check for FULLTEXT index support
56
	 *
57
	 * @access public
58
	 * @return bool True if FULLTEXT is supported, false otherwise
59
	 */
60
	public function is_supported()
61
	{
62
		// FULLTEXT is supported on InnoDB since MySQL 5.6.4 according to
63
		// http://dev.mysql.com/doc/refman/5.6/en/innodb-storage-engine.html
64
		return ($this->is_postgres() || $this->get_engine() === 'myisam' || ($this->get_engine() === 'innodb' && phpbb_version_compare($this->db->sql_server_info(true), '5.6.4', '>=')));
65
	}
66
67
	/**
68
	 * Get the database storage engine name
69
	 *
70
	 * @access public
71
	 * @return string The storage engine name
72
	 */
73
	public function get_engine()
74
	{
75
		return isset($this->engine) ? $this->engine : $this->set_engine();
76
	}
77
78
	/**
79
	 * Set the database storage engine name
80
	 *
81
	 * @access public
82
	 * @return string The storage engine name
83
	 */
84
	public function set_engine()
85
	{
86
		$this->engine = '';
87
88
		if ($this->is_mysql())
89
		{
90
			$info = $this->get_table_info();
91
92
			// Modern MySQL uses 'Engine', but older may still use 'Type'
93
			foreach (array('Engine', 'Type') as $name)
94
			{
95
				if (isset($info[$name]))
96
				{
97
					$this->engine = strtolower($info[$name]);
98
					break;
99
				}
100
			}
101
		}
102
103
		return $this->engine;
104
	}
105
106
	/**
107
	 * Check if a field is a FULLTEXT index
108
	 *
109
	 * @access public
110
	 * @param string $field name of a field
111
	 * @return bool True if field is a FULLTEXT index, false otherwise
112
	 */
113
	public function is_index($field = 'topic_title')
114
	{
115
		$is_index = false;
116
117
		if ($this->is_mysql())
118
		{
119
			$sql = 'SHOW INDEX
120
				FROM ' . TOPICS_TABLE;
121
			$result = $this->db->sql_query($sql);
122
123
			while ($row = $this->db->sql_fetchrow($result))
124
			{
125
				// Older MySQL versions didn't use Index_type, so fallback to Comment
126
				$index_type = isset($row['Index_type']) ? $row['Index_type'] : $row['Comment'];
127
128
				if ($index_type === 'FULLTEXT' && $row['Key_name'] === $field)
129
				{
130
					$is_index = true;
131
					break;
132
				}
133
			}
134
135
			$this->db->sql_freeresult($result);
136
		}
137
		else if ($this->is_postgres())
138
		{
139
			global $config;
140
			$ts_name = $config['similar_topics_postgres_ts_name'];
141
			foreach ($this->get_pg_indexes($field) AS $index)
142
			{
143
				if ($index == TOPICS_TABLE . '_' . $ts_name . '_' .$field)
144
				{
145
					$is_index = true;
146
					break;
147
				}
148
			}
149
		}
150
151
		return $is_index;
152
	}
153
154
	/**
155
	 * Get topics table information
156
	 *
157
	 * @access protected
158
	 * @return mixed Array with the table info, false if the table does not exist
159
	 */
160
	protected function get_table_info()
161
	{
162
		$result = $this->db->sql_query('SHOW TABLE STATUS LIKE \'' . TOPICS_TABLE . '\'');
163
		$info = $this->db->sql_fetchrow($result);
164
		$this->db->sql_freeresult($result);
165
166
		return $info;
167
	}
168
	/**
169
	 * get all PostgreSQL FULLTEXT indexes on field in topics table
170
	 *
171
	 * @access public
172
	 * @param string $field name of a field
173
	 * @return array contains index names
174
	 */
175
	public function get_pg_indexes($field = 'topic_title')
176
	{
177
		$indexes = array();
178
		if (!$this->is_postgres())
179
		{
180
			return $indexes;
181
		}
182
		
183
		$sql = "SELECT c2.relname
184
		FROM pg_catalog.pg_class c1, pg_catalog.pg_index i, pg_catalog.pg_class c2, pg_catalog.pg_get_indexdef(i.indexrelid, 0, true) indexdef
185
		WHERE c1.relname = '" . TOPICS_TABLE . "'
186
				AND position('to_tsvector' in indexdef) > 0
187
				AND pg_catalog.pg_table_is_visible(c1.oid)
188
				AND c1.oid = i.indrelid
189
				AND i.indexrelid = c2.oid;";
190
		$result = $this->db->sql_query($sql);
191
		
192
		while ($row = $this->db->sql_fetchrow($result))
193
		{
194
			if (strpos($row['relname'], $field) !== false)
195
			{
196
				$indexes[] = $row['relname'];
197
			}
198
			
199
		}
200
		$this->db->sql_freeresult($result);
201
		
202
		return $indexes;
203
	}
204
}
205