Verzeichnisstruktur phpBB-3.0.0
- Veröffentlicht
- 12.12.2007
So funktioniert es
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
mssql_odbc.php
001 <?php
002 /**
003 *
004 * @package dbal
005 * @version $Id$
006 * @copyright (c) 2005 phpBB Group
007 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
008 *
009 */
010
011 /**
012 * @ignore
013 */
014 if (!defined('IN_PHPBB'))
015 {
016 exit;
017 }
018
019 include_once($phpbb_root_path . 'includes/db/dbal.' . $phpEx);
020
021 /**
022 * Unified ODBC functions
023 * Unified ODBC functions support any database having ODBC driver, for example Adabas D, IBM DB2, iODBC, Solid, Sybase SQL Anywhere...
024 * Here we only support MSSQL Server 2000+ because of the provided schema
025 *
026 * @note number of bytes returned for returning data depends on odbc.defaultlrl php.ini setting.
027 * If it is limited to 4K for example only 4K of data is returned max, resulting in incomplete theme data for example.
028 * @note odbc.defaultbinmode may affect UTF8 characters
029 *
030 * @package dbal
031 */
032 class dbal_mssql_odbc extends dbal
033 {
034 var $last_query_text = '';
035
036 /**
037 * Connect to server
038 */
039 function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false)
040 {
041 $this->persistency = $persistency;
042 $this->user = $sqluser;
043 $this->server = $sqlserver . (($port) ? ':' . $port : '');
044 $this->dbname = $database;
045
046 $max_size = @ini_get('odbc.defaultlrl');
047 if (!empty($max_size))
048 {
049 $unit = strtolower(substr($max_size, -1, 1));
050 $max_size = (int) $max_size;
051
052 if ($unit == 'k')
053 {
054 $max_size = floor($max_size / 1024);
055 }
056 else if ($unit == 'g')
057 {
058 $max_size *= 1024;
059 }
060 else if (is_numeric($unit))
061 {
062 $max_size = floor((int) ($max_size . $unit) / 1048576);
063 }
064 $max_size = max(8, $max_size) . 'M';
065
066 @ini_set('odbc.defaultlrl', $max_size);
067 }
068
069 $this->db_connect_id = ($this->persistency) ? @odbc_pconnect($this->server, $this->user, $sqlpassword) : @odbc_connect($this->server, $this->user, $sqlpassword);
070
071 return ($this->db_connect_id) ? $this->db_connect_id : $this->sql_error('');
072 }
073
074 /**
075 * Version information about used database
076 */
077 function sql_server_info()
078 {
079 $result_id = @odbc_exec($this->db_connect_id, "SELECT SERVERPROPERTY('productversion'), SERVERPROPERTY('productlevel'), SERVERPROPERTY('edition')");
080
081 $row = false;
082 if ($result_id)
083 {
084 $row = @odbc_fetch_array($result_id);
085 @odbc_free_result($result_id);
086 }
087
088 if ($row)
089 {
090 return 'MSSQL (ODBC)<br />' . implode(' ', $row);
091 }
092
093 return 'MSSQL (ODBC)';
094 }
095
096 /**
097 * SQL Transaction
098 * @access private
099 */
100 function _sql_transaction($status = 'begin')
101 {
102 switch ($status)
103 {
104 case 'begin':
105 return @odbc_exec($this->db_connect_id, 'BEGIN TRANSACTION');
106 break;
107
108 case 'commit':
109 return @odbc_exec($this->db_connect_id, 'COMMIT TRANSACTION');
110 break;
111
112 case 'rollback':
113 return @odbc_exec($this->db_connect_id, 'ROLLBACK TRANSACTION');
114 break;
115 }
116
117 return true;
118 }
119
120 /**
121 * Base query method
122 *
123 * @param string $query Contains the SQL query which shall be executed
124 * @param int $cache_ttl Either 0 to avoid caching or the time in seconds which the result shall be kept in cache
125 * @return mixed When casted to bool the returned value returns true on success and false on failure
126 *
127 * @access public
128 */
129 function sql_query($query = '', $cache_ttl = 0)
130 {
131 if ($query != '')
132 {
133 global $cache;
134
135 // EXPLAIN only in extra debug mode
136 if (defined('DEBUG_EXTRA'))
137 {
138 $this->sql_report('start', $query);
139 }
140
141 $this->last_query_text = $query;
142 $this->query_result = ($cache_ttl && method_exists($cache, 'sql_load')) ? $cache->sql_load($query) : false;
143 $this->sql_add_num_queries($this->query_result);
144
145 if ($this->query_result === false)
146 {
147 if (($this->query_result = @odbc_exec($this->db_connect_id, $query)) === false)
148 {
149 $this->sql_error($query);
150 }
151
152 if (defined('DEBUG_EXTRA'))
153 {
154 $this->sql_report('stop', $query);
155 }
156
157 if ($cache_ttl && method_exists($cache, 'sql_save'))
158 {
159 $this->open_queries[(int) $this->query_result] = $this->query_result;
160 $cache->sql_save($query, $this->query_result, $cache_ttl);
161 }
162 else if (strpos($query, 'SELECT') === 0 && $this->query_result)
163 {
164 $this->open_queries[(int) $this->query_result] = $this->query_result;
165 }
166 }
167 else if (defined('DEBUG_EXTRA'))
168 {
169 $this->sql_report('fromcache', $query);
170 }
171 }
172 else
173 {
174 return false;
175 }
176
177 return ($this->query_result) ? $this->query_result : false;
178 }
179
180 /**
181 * Build LIMIT query
182 */
183 function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0)
184 {
185 $this->query_result = false;
186
187 // Since TOP is only returning a set number of rows we won't need it if total is set to 0 (return all rows)
188 if ($total)
189 {
190 // We need to grab the total number of rows + the offset number of rows to get the correct result
191 if (strpos($query, 'SELECT DISTINCT') === 0)
192 {
193 $query = 'SELECT DISTINCT TOP ' . ($total + $offset) . ' ' . substr($query, 15);
194 }
195 else
196 {
197 $query = 'SELECT TOP ' . ($total + $offset) . ' ' . substr($query, 6);
198 }
199 }
200
201 $result = $this->sql_query($query, $cache_ttl);
202
203 // Seek by $offset rows
204 if ($offset)
205 {
206 $this->sql_rowseek($offset, $result);
207 }
208
209 return $result;
210 }
211
212 /**
213 * Return number of affected rows
214 */
215 function sql_affectedrows()
216 {
217 return ($this->db_connect_id) ? @odbc_num_rows($this->query_result) : false;
218 }
219
220 /**
221 * Fetch current row
222 * @note number of bytes returned depends on odbc.defaultlrl php.ini setting. If it is limited to 4K for example only 4K of data is returned max.
223 */
224 function sql_fetchrow($query_id = false, $debug = false)
225 {
226 global $cache;
227
228 if ($query_id === false)
229 {
230 $query_id = $this->query_result;
231 }
232
233 if (isset($cache->sql_rowset[$query_id]))
234 {
235 return $cache->sql_fetchrow($query_id);
236 }
237
238 return ($query_id !== false) ? @odbc_fetch_array($query_id) : false;
239 }
240
241 /**
242 * Seek to given row number
243 * rownum is zero-based
244 */
245 function sql_rowseek($rownum, &$query_id)
246 {
247 global $cache;
248
249 if ($query_id === false)
250 {
251 $query_id = $this->query_result;
252 }
253
254 if (isset($cache->sql_rowset[$query_id]))
255 {
256 return $cache->sql_rowseek($rownum, $query_id);
257 }
258
259 if ($query_id === false)
260 {
261 return false;
262 }
263
264 $this->sql_freeresult($query_id);
265 $query_id = $this->sql_query($this->last_query_text);
266
267 if ($query_id === false)
268 {
269 return false;
270 }
271
272 // We do not fetch the row for rownum == 0 because then the next resultset would be the second row
273 for ($i = 0; $i < $rownum; $i++)
274 {
275 if (!$this->sql_fetchrow($query_id))
276 {
277 return false;
278 }
279 }
280
281 return true;
282 }
283
284 /**
285 * Get last inserted id after insert statement
286 */
287 function sql_nextid()
288 {
289 $result_id = @odbc_exec($this->db_connect_id, 'SELECT @@IDENTITY');
290
291 if ($result_id)
292 {
293 if (@odbc_fetch_array($result_id))
294 {
295 $id = @odbc_result($result_id, 1);
296 @odbc_free_result($result_id);
297 return $id;
298 }
299 @odbc_free_result($result_id);
300 }
301
302 return false;
303 }
304
305 /**
306 * Free sql result
307 */
308 function sql_freeresult($query_id = false)
309 {
310 global $cache;
311
312 if ($query_id === false)
313 {
314 $query_id = $this->query_result;
315 }
316
317 if (isset($cache->sql_rowset[$query_id]))
318 {
319 return $cache->sql_freeresult($query_id);
320 }
321
322 if (isset($this->open_queries[(int) $query_id]))
323 {
324 unset($this->open_queries[(int) $query_id]);
325 return @odbc_free_result($query_id);
326 }
327
328 return false;
329 }
330
331 /**
332 * Escape string used in sql query
333 */
334 function sql_escape($msg)
335 {
336 return str_replace("'", "''", $msg);
337 }
338
339 /**
340 * Build LIKE expression
341 * @access private
342 */
343 function _sql_like_expression($expression)
344 {
345 return $expression . " ESCAPE '\\'";
346 }
347
348 /**
349 * Build db-specific query data
350 * @access private
351 */
352 function _sql_custom_build($stage, $data)
353 {
354 return $data;
355 }
356
357 /**
358 * return sql error array
359 * @access private
360 */
361 function _sql_error()
362 {
363 return array(
364 'message' => @odbc_errormsg(),
365 'code' => @odbc_error()
366 );
367 }
368
369 /**
370 * Close sql connection
371 * @access private
372 */
373 function _sql_close()
374 {
375 return @odbc_close($this->db_connect_id);
376 }
377
378 /**
379 * Build db-specific report
380 * @access private
381 */
382 function _sql_report($mode, $query = '')
383 {
384 switch ($mode)
385 {
386 case 'start':
387 break;
388
389 case 'fromcache':
390 $endtime = explode(' ', microtime());
391 $endtime = $endtime[0] + $endtime[1];
392
393 $result = @odbc_exec($this->db_connect_id, $query);
394 while ($void = @odbc_fetch_array($result))
395 {
396 // Take the time spent on parsing rows into account
397 }
398 @odbc_free_result($result);
399
400 $splittime = explode(' ', microtime());
401 $splittime = $splittime[0] + $splittime[1];
402
403 $this->sql_report('record_fromcache', $query, $endtime, $splittime);
404
405 break;
406 }
407 }
408 }
409
410 ?>