Move all of the reasonable DatabaseBase methods to Database class
[lhc/web/wiklou.git] / includes / db / Database.php
1 <?php
2 /**
3 * @defgroup Database Database
4 *
5 * This file deals with database interface functions
6 * and query specifics/optimisations.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 * http://www.gnu.org/copyleft/gpl.html
22 *
23 * @file
24 * @ingroup Database
25 */
26
27 /**
28 * Database abstraction object
29 * @ingroup Database
30 */
31 abstract class DatabaseBase extends Database {
32 /**
33 * Boolean, controls output of large amounts of debug information.
34 * @param bool|null $debug
35 * - true to enable debugging
36 * - false to disable debugging
37 * - omitted or null to do nothing
38 *
39 * @return bool Previous value of the flag
40 * @deprecated since 1.28; use setFlag()
41 */
42 public function debug( $debug = null ) {
43 $res = $this->getFlag( DBO_DEBUG );
44 if ( $debug !== null ) {
45 $debug ? $this->setFlag( DBO_DEBUG ) : $this->clearFlag( DBO_DEBUG );
46 }
47
48 return $res;
49 }
50
51 /**
52 * @return string Command delimiter used by this database engine
53 */
54 public function getDelimiter() {
55 return $this->delimiter;
56 }
57
58 /**
59 * Returns true if this database supports (and uses) cascading deletes
60 *
61 * @return bool
62 */
63 public function cascadingDeletes() {
64 return false;
65 }
66 /**
67 * Returns true if this database supports (and uses) triggers (e.g. on the page table)
68 *
69 * @return bool
70 */
71 public function cleanupTriggers() {
72 return false;
73 }
74 /**
75 * Returns true if this database is strict about what can be put into an IP field.
76 * Specifically, it uses a NULL value instead of an empty string.
77 *
78 * @return bool
79 */
80 public function strictIPs() {
81 return false;
82 }
83
84 /**
85 * Returns true if this database can do a native search on IP columns
86 * e.g. this works as expected: .. WHERE rc_ip = '127.42.12.102/32';
87 *
88 * @return bool
89 */
90 public function searchableIPs() {
91 return false;
92 }
93
94 /**
95 * Returns true if this database uses timestamps rather than integers
96 *
97 * @return bool
98 */
99 public function realTimestamps() {
100 return false;
101 }
102
103 /**
104 * Returns true if this database can use functional indexes
105 *
106 * @return bool
107 */
108 public function functionalIndexes() {
109 return false;
110 }
111
112 /**
113 * Intended to be compatible with the PEAR::DB wrapper functions.
114 * http://pear.php.net/manual/en/package.database.db.intro-execute.php
115 *
116 * ? = scalar value, quoted as necessary
117 * ! = raw SQL bit (a function for instance)
118 * & = filename; reads the file and inserts as a blob
119 * (we don't use this though...)
120 *
121 * @param string $sql
122 * @param string $func
123 *
124 * @return array
125 */
126 protected function prepare( $sql, $func = __METHOD__ ) {
127 /* MySQL doesn't support prepared statements (yet), so just
128 * pack up the query for reference. We'll manually replace
129 * the bits later.
130 */
131 return [ 'query' => $sql, 'func' => $func ];
132 }
133
134 /**
135 * Free a prepared query, generated by prepare().
136 * @param string $prepared
137 */
138 protected function freePrepared( $prepared ) {
139 /* No-op by default */
140 }
141
142 /**
143 * Execute a prepared query with the various arguments
144 * @param string $prepared The prepared sql
145 * @param mixed $args Either an array here, or put scalars as varargs
146 *
147 * @return ResultWrapper
148 */
149 public function execute( $prepared, $args = null ) {
150 if ( !is_array( $args ) ) {
151 # Pull the var args
152 $args = func_get_args();
153 array_shift( $args );
154 }
155
156 $sql = $this->fillPrepared( $prepared['query'], $args );
157
158 return $this->query( $sql, $prepared['func'] );
159 }
160
161 /**
162 * For faking prepared SQL statements on DBs that don't support it directly.
163 *
164 * @param string $preparedQuery A 'preparable' SQL statement
165 * @param array $args Array of Arguments to fill it with
166 * @return string Executable SQL
167 */
168 public function fillPrepared( $preparedQuery, $args ) {
169 reset( $args );
170 $this->preparedArgs =& $args;
171
172 return preg_replace_callback( '/(\\\\[?!&]|[?!&])/',
173 [ &$this, 'fillPreparedArg' ], $preparedQuery );
174 }
175
176 /**
177 * preg_callback func for fillPrepared()
178 * The arguments should be in $this->preparedArgs and must not be touched
179 * while we're doing this.
180 *
181 * @param array $matches
182 * @throws DBUnexpectedError
183 * @return string
184 */
185 protected function fillPreparedArg( $matches ) {
186 switch ( $matches[1] ) {
187 case '\\?':
188 return '?';
189 case '\\!':
190 return '!';
191 case '\\&':
192 return '&';
193 }
194
195 list( /* $n */, $arg ) = each( $this->preparedArgs );
196
197 switch ( $matches[1] ) {
198 case '?':
199 return $this->addQuotes( $arg );
200 case '!':
201 return $arg;
202 case '&':
203 # return $this->addQuotes( file_get_contents( $arg ) );
204 throw new DBUnexpectedError(
205 $this,
206 '& mode is not implemented. If it\'s really needed, uncomment the line above.'
207 );
208 default:
209 throw new DBUnexpectedError(
210 $this,
211 'Received invalid match. This should never happen!'
212 );
213 }
214 }
215
216 /**
217 * Get search engine class. All subclasses of this need to implement this
218 * if they wish to use searching.
219 *
220 * @return string
221 */
222 public function getSearchEngine() {
223 return 'SearchEngineDummy';
224 }
225 }