Exponential 6.0.13 Exponential Enterprise Open Source CMS - PHP Class Reference

ezsqlite3db.php
Go to the documentation of this file.
1 <?php
2
3 class eZSQLite3DB extends eZDBInterface
4 {
5 function __construct( $parameters )
6 {
7 parent::__construct( $parameters );
8
9 if ( !extension_loaded( 'sqlite3' ) )
10 {
11 if ( function_exists( 'eZAppendWarningItem' ) )
12 {
13 eZAppendWarningItem( array( 'error' => array( 'type' => 'ezdb',
14 'number' => eZDBInterface::ERROR_MISSING_EXTENSION ),
15 'text' => 'SQLite3 extension was not found, the DB handler will not be initialized.' ) );
16 $this->IsConnected = false;
17 }
18 eZDebug::writeError( 'SQLite3 extension was not found, the DB handler will not be initialized.', 'eZSQLite3DB' );
19 return;
20 }
21
22 if ( $this->DBConnection === false && $this->DB !== null )
23 {
24 $this->DBConnection = $this->connect( $this->DB );
25 }
26
27
28 // WAL mode has better control over concurrency.
29 // Source: https://www.sqlite.org/wal.html
30 $this->query('PRAGMA journal_mode = wal;');
31
32 // Initialize TempTableList
33 $this->TempTableList = array();
34
35 eZDebug::createAccumulatorGroup( 'sqlite3_total', 'SQLite3 Total' );
36 }
37
42 private function connect( $fileName )
43 {
44 /*
45 print( $sql . PHP_EOL . PHP_EOL );
46
47 $backtrace = debug_backtrace();
48 $cleanedBackTrace = array();
49 foreach ( $backtrace as $call )
50 {
51 $item = '';
52 if ( isset( $call['class'] ) )
53 {
54 $item .= $call['class'];
55 }
56
57 if ( isset( $call['type'] ) )
58 {
59 $item .= $call['type'];
60 }
61
62 $item .= $call['function'] . " in file " . $call['file'] . " line " . $call['line'];
63
64 //$item .= var_export( $call['args'], true );
65 $cleanedBacktrace[] = $item;
66 }
67
68 print( implode( PHP_EOL, $cleanedBacktrace ) . PHP_EOL . PHP_EOL );
69 */
70 $connection = false;
71 $error = 0;
72
73 $maxAttempts = $this->connectRetryCount() + 1;
74 $waitTime = $this->connectRetryWaitTime();
75 $numAttempts = 1;
76 while ( ( $connection == false || $error !== 0 ) && $numAttempts <= $maxAttempts )
77 {
78 $directoryPath = 'var/storage/sqlite3';
79 $fullPath = $fileName == ':memory:' ? $fileName : eZDir::path( array( $directoryPath, $fileName ) );
80
81 if( !file_exists( $directoryPath ) )
82 mkdir( $directoryPath, 0775 );
83 // var_dump( $fullPath ); echo '<hr>'; // die();
84 if( !file_exists( $fullPath ) )
85 $fh = fopen($fullPath, 'w') or eZDebug::writeError( "Connection error: Couldn't create database file. Please try again later or inform the system administrator.", "eZSQLite3DB" );
86 $connection = new SQLite3( $fullPath );
87 eZDebug::writeDebug( $connection );
88
89 if ( $connection )
90 {
91 $error = $connection->lastErrorCode();
92 eZDebug::writeDebug( gettype( $error ) . '(' . ( $error ? 'true' : 'false' ) . ')' );
93 }
94 $numAttempts++;
95 }
96
97 if ( $error !== 0 )
98 {
99 $this->ErrorNumber = $error;
100 $this->ErrorMessage = $connection->lastErrorMsg();
101 eZDebug::writeError( "Connection error: Couldn't connect to database. Please try again later or inform the system administrator.", "eZSQLite3DB" );
102 $this->IsConnected = false;
103 }
104 else
105 {
106 $connection->createFunction( 'md5', array( $this, 'md5UDF' ) );
107 $this->IsConnected = true;
108 }
109
110 return $connection;
111 }
112
116 function databaseName()
117 {
118 return 'sqlite';
119 }
120
124 function bindingType( )
125 {
126 return eZDBInterface::BINDING_NO;
127 }
128
132 function bindVariable( $value, $fieldDef = false )
133 {
134 return $value;
135 }
136
137 /*
138 */
139 function checkCharset( $charset, &$currentCharset )
140 {
141 return true;
142 }
143
147 function query( $sql, $server = false )
148 {
149 if ( $this->IsConnected )
150 {
151 if ( $this->OutputSQL )
152 {
153 eZDebug::accumulatorStart( 'sqlite3_query', 'sqlite3_total', 'sqlite3_queries' );
154 $this->startTimer();
155 }
156
157 $result = $this->DBConnection->exec( $sql );
158 if ( $this->OutputSQL )
159 {
160 $this->endTimer();
161
162 if ( $this->timeTaken() > $this->SlowSQLTimeout )
163 {
164 eZDebug::accumulatorStop( 'sqlite3_query' );
165 $this->reportQuery( 'SQLite3DB', $sql, false, $this->timeTaken() );
166 }
167 }
168
169 if ( !$result )
170 {
171 $this->setError();
172
173 eZDebug::writeError( "Error: error when executing query: $sql", "eZSQLite3DB" );
174 $this->reportError();
175 }
176 else
177 {
178 return true;
179 }
180 }
181 else
182 {
183 eZDebug::writeError( "Trying to do a query without being connected to a database!", "eZSQLite3DB" );
184 }
185
186 return false;
187 }
188
192 function arrayQuery( $sql, $params = array(), $server = false )
193 {
194 /*
195 print( $sql . PHP_EOL . PHP_EOL );
196
197 $backtrace = debug_backtrace();
198 $cleanedBackTrace = array();
199 foreach ( $backtrace as $call )
200 {
201 $item = '';
202 if ( isset( $call['class'] ) )
203 {
204 $item .= $call['class'];
205 }
206
207 if ( isset( $call['type'] ) )
208 {
209 $item .= $call['type'];
210 }
211
212 $item .= $call['function'] . " in file " . $call['file'] . " line " . $call['line'];
213
214 //$item .= var_export( $call['args'], true );
215 $cleanedBacktrace[] = $item;
216 }
217
218 print( implode( PHP_EOL, $cleanedBacktrace ) . PHP_EOL . PHP_EOL );
219 / */
220
221 $retArray = array();
222 if ( $this->IsConnected )
223 {
224 $limit = false;
225 $offset = 0;
226 $column = false;
227 // check for array parameters
228 if ( is_array( $params ) )
229 {
230 if ( isset( $params["limit"] ) and is_numeric( $params["limit"] ) )
231 $limit = $params["limit"];
232
233 if ( isset( $params["offset"] ) and is_numeric( $params["offset"] ) )
234 $offset = $params["offset"];
235
236 if ( isset( $params["column"] ) and ( is_numeric( $params["column"] ) or is_string( $params["column"] ) ) )
237 $column = $params["column"];
238 }
239
240 if ( $limit !== false and is_numeric( $limit ) )
241 {
242 $sql .= "\nLIMIT $offset, $limit ";
243 }
244 else if ( $offset !== false and is_numeric( $offset ) and $offset > 0 )
245 {
246 $sql .= "\nLIMIT $offset, 18446744073709551615"; // 2^64-1
247 }
248
249 if ( $this->OutputSQL )
250 {
251 eZDebug::accumulatorStart( 'sqlite3_query', 'sqlite3_total', 'sqlite3_queries' );
252 $this->startTimer();
253 }
254
255 $results = $this->DBConnection->query( $sql );
256
257 if ( $this->OutputSQL )
258 {
259 $this->endTimer();
260
261 if ( $this->timeTaken() > $this->SlowSQLTimeout )
262 {
263 eZDebug::accumulatorStop( 'sqlite3_query' );
264 $this->reportQuery( 'SQLite3DB', $sql, false, $this->timeTaken() );
265 }
266 }
267
268 if ( $results === false )
269 {
270 $this->setError();
271 eZDebug::writeError( "Error: error executing query: $sql", "eZSQLite3DB" );
272 $this->reportError();
273
274 return false;
275 }
276
277 $i = 0;
278 while ( $row = $results->fetchArray( SQLITE3_ASSOC ) )
279 {
280 eZDebug::accumulatorStart( 'sqlite3_loop', 'sqlite3_total', 'Looping result' );
281
282 // SQLite sometimes gives back column names prefixed with the table name
283 // we need to transform the row so that there are no table names
284 $transformedRow = array();
285 foreach ( $row as $identifier => $value )
286 {
287 if ( strpos( $identifier, '.' ) !== false )
288 {
289 $parts = explode( '.', $identifier );
290 $newIdentifier = array_pop( $parts );
291 }
292 else
293 {
294 $newIdentifier = $identifier;
295 }
296
297 $transformedRow[$newIdentifier] = $value;
298 }
299
300 $retArray[$i + $offset] = is_string( $column ) ? $transformedRow[$column] : $transformedRow;
301 $i++;
302 eZDebug::accumulatorStop( 'sqlite3_loop' );
303 }
304
305 $results->finalize();
306 }
307 return $retArray;
308 }
309
310 function subString( $string, $from, $len = null )
311 {
312 if ( $len == null )
313 {
314 return " substr( $string, $from, length( $string ) - $from ) ";
315 }
316 else
317 {
318 return " substr( $string, $from, $len ) ";
319 }
320 }
321
322 function concatString( $strings = array() )
323 {
324 return implode( " || " , $strings );
325 }
326
327 function md5( $str )
328 {
329 return " MD5( $str ) ";
330 }
331
332 function md5UDF( $str )
333 {
334 return md5( $str );
335 }
336
337 function bitAnd( $arg1, $arg2 )
338 {
339 return '(' . $arg1 . ' & ' . $arg2 . ' ) ';
340 }
341
342 function bitOr( $arg1, $arg2 )
343 {
344 return '( ' . $arg1 . ' | ' . $arg2 . ' ) ';
345 }
346
351 function beginQuery()
352 {
353 return $this->query( "BEGIN" );
354 }
355
360 function commitQuery()
361 {
362 return $this->query( "COMMIT" );
363 }
364
369 function rollbackQuery()
370 {
371 return $this->query( "ROLLBACK" );
372 }
373
377 function lastSerialID( $table = false, $column = false )
378 {
379 if ( $this->IsConnected )
380 {
381 $id = $this->DBConnection->lastInsertRowID();
382
383 // if the primary key consists of more than one field
384 // then we can not rely on the auto increment functionality of SQLite,
386 // so we need to check if the autoincrement field matches the rowid
387 // if not, we'll update it
388 $result = $this->arrayQuery( "SELECT $column FROM $table WHERE rowid=$id" );
389 if ( $result[0][$column] != $id )
390 {
391 // we use the maximum + 1 instead of the rowid, because some autoincrement fields
392 // in the standard data do not follow up each other
393 // so for the standard data the autoincrement column might not match the rowid
394 // and query errors will appear when we add new data because of unique key violations
395 $max = $this->arrayQuery( "SELECT MAX($column) AS maximum FROM $table" );
396
397 $newID = $max['0']['maximum'] + 1;
398
399 $this->query( "UPDATE $table SET $column=$newID WHERE rowid=$id" );
400
401 return $newID;
402 }
403 else
404 {
405 return $id;
406 }
407 }
408 else
409 {
410 return false;
411 }
412 }
413
417 function escapeString( $str )
418 {
419 if ( $this->IsConnected )
420 {
421 return $this->DBConnection->escapeString( $str );
422 }
423 else
424 {
425 return $str;
426 }
427 }
428
432 function close()
433 {
434 if ( $this->IsConnected )
435 {
436 $this->DBConnection->close();
437 $this->IsConnected = false;
438 }
439 }
440
441 function __destruct()
442 {
443 $this->close();
444 }
445
449 function createDatabase( $dbName )
450 {
451 // useless in the contect of SQLite
452 }
453
457 function setError()
458 {
459 if ( $this->DBConnection )
460 {
461 $this->ErrorNumber = $this->DBConnection->lastErrorCode();
462 $this->ErrorMessage = $this->DBConnection->lastErrorMsg();
463 }
464 }
465
469 function availableDatabases()
470 {
471 $returnFiles = array();
472 if ( $handle = @opendir( 'var/storage/sqlite3' ) )
473 {
474 while ( ( $file = readdir( $handle ) ) !== false )
475 {
476 if ( ( $file == "." ) || ( $file == ".." ) )
477 {
478 continue;
479 }
480
481 if ( is_file( 'var/storage/sqlite3/' . $file ) )
482 {
483 $returnFiles[] = $file;
484 }
485 }
486 @closedir( $handle );
487 }
488 return $returnFiles;
489 }
490
494 function databaseServerVersion()
495 {
496 // no server, so returning client version
497 //return $this->databaseClientVersion();
498 //setup require string instead of array
499 $versionInfo = SQLite3::version();
500 $versionString = $versionInfo['versionString'];
501 return array( 'string' => $versionString, 'values' => $versionString );
502 }
503
507 function databaseClientVersion()
508 {
509 $versionInfo = SQLite3::version();
510 $versionString = $versionInfo['versionString'];
511
512 $versionArray = explode( '.', $versionString );
513
514 return array( 'string' => $versionInfo,
515 'values' => $versionArray );
516 }
517
521 function isCharsetSupported( $charset )
522 {
523 return true;
524 }
525
526 function eZTableList( $server = eZDBInterface::SERVER_MASTER )
527 {
528 $tables = array();
529 if ( $this->IsConnected )
530 {
531 $sql = "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name";
532 $results = $this->arrayQuery( $sql );
533
534 foreach ( $results as $entry )
535 {
536 $tableName = $entry['name'];
537 if ( substr( $tableName, 0, 2 ) == 'ez' )
538 {
539 $tables[$tableName] = eZDBInterface::RELATION_TABLE;
540 }
541 }
542 }
543 return $tables;
544 }
545
549 function supportedRelationTypes()
550 {
551 return array( eZDBInterface::RELATION_TABLE );
552 }
553
554 function relationList( $relationType = eZDBInterface::RELATION_TABLE )
555 {
556 if ( $relationType != eZDBInterface::RELATION_TABLE )
557 {
558 eZDebug::writeError( "Unsupported relation type '$relationType'", 'eZSQLite3DB::relationList' );
559 return false;
560 }
561
562 $tables = array_keys( $this->eZTableList() );
563 return $tables;
564 }
565
569 function removeRelation( $relationName, $relationType )
570 {
571 $relationTypeName = $this->relationName( $relationType );
572 if ( !$relationTypeName )
573 {
574 eZDebug::writeError( "Unknown relation type '$relationType'", 'eZSQLite3DB::removeRelation' );
575 return false;
576 }
577
578 if ( $this->IsConnected )
579 {
580 $sql = "DROP $relationTypeName $relationName";
581 return $this->query( $sql );
582 }
583 return false;
584 }
585
586 public $TempTableList;
587 }
588
589 ?>
eZDBInterface
Definition: ezdbinterface.php:20
eZDBInterface\startTimer
startTimer()
Definition: ezdbinterface.php:380
eZDBInterface\reportQuery
reportQuery( $class, $sql, $numRows, $timeTaken, $asDebug=false)
Definition: ezdbinterface.php:353
eZDBInterface\BINDING_NO
const BINDING_NO
Definition: ezdbinterface.php:21
eZDBInterface\reportError
reportError()
Definition: ezdbinterface.php:1042
eZDBInterface\connectRetryCount
connectRetryCount()
Definition: ezdbinterface.php:458
eZDBInterface\SERVER_MASTER
const SERVER_MASTER
Definition: ezdbinterface.php:42
eZDBInterface\RELATION_TABLE
const RELATION_TABLE
Definition: ezdbinterface.php:25
eZDBInterface\ERROR_MISSING_EXTENSION
const ERROR_MISSING_EXTENSION
Definition: ezdbinterface.php:40
eZDBInterface\connectRetryWaitTime
connectRetryWaitTime()
Definition: ezdbinterface.php:468
eZDBInterface\timeTaken
timeTaken()
Definition: ezdbinterface.php:426
eZDBInterface\endTimer
endTimer()
Definition: ezdbinterface.php:390
eZDBInterface\relationName
relationName( $relationType)
Definition: ezdbinterface.php:1206
eZDebug\writeError
static writeError( $string, $label="", $backgroundClass="")
Definition: ezdebug.php:545
eZDebug\writeDebug
static writeDebug( $string, $label="", $backgroundClass="")
Definition: ezdebug.php:588
eZDebug\createAccumulatorGroup
static createAccumulatorGroup( $key, $name=false)
Definition: ezdebug.php:1314
eZDebug\accumulatorStart
static accumulatorStart( $key, $inGroup=false, $name=false, $recursive=false)
Definition: ezdebug.php:1361
eZDebug\accumulatorStop
static accumulatorStop( $key, $recursive=false)
Definition: ezdebug.php:1389
eZDir\path
static path( $names, $includeEndSeparator=false, $type=self::SEPARATOR_UNIX)
Definition: ezdir.php:237
eZSQLite3DB
Definition: ezsqlite3db.php:4
eZSQLite3DB\__construct
__construct( $parameters)
Definition: ezsqlite3db.php:5
eZSQLite3DB\eZTableList
eZTableList( $server=eZDBInterface::SERVER_MASTER)
Definition: ezsqlite3db.php:526
eZSQLite3DB\connect
connect( $fileName)
Definition: ezsqlite3db.php:42
eZSQLite3DB\subString
subString( $string, $from, $len=null)
Definition: ezsqlite3db.php:310
eZSQLite3DB\$TempTableList
$TempTableList
Definition: ezsqlite3db.php:586
eZSQLite3DB\databaseName
databaseName()
Definition: ezsqlite3db.php:116
eZSQLite3DB\bindingType
bindingType()
Definition: ezsqlite3db.php:124
eZSQLite3DB\databaseServerVersion
databaseServerVersion()
Definition: ezsqlite3db.php:494
eZSQLite3DB\lastSerialID
lastSerialID( $table=false, $column=false)
Definition: ezsqlite3db.php:377
eZSQLite3DB\bindVariable
bindVariable( $value, $fieldDef=false)
Definition: ezsqlite3db.php:132
eZSQLite3DB\escapeString
escapeString( $str)
Definition: ezsqlite3db.php:417
eZSQLite3DB\relationList
relationList( $relationType=eZDBInterface::RELATION_TABLE)
Definition: ezsqlite3db.php:554
eZSQLite3DB\md5UDF
md5UDF( $str)
Definition: ezsqlite3db.php:332
eZSQLite3DB\bitAnd
bitAnd( $arg1, $arg2)
Definition: ezsqlite3db.php:337
eZSQLite3DB\availableDatabases
availableDatabases()
Definition: ezsqlite3db.php:469
eZSQLite3DB\createDatabase
createDatabase( $dbName)
Definition: ezsqlite3db.php:449
eZSQLite3DB\commitQuery
commitQuery()
Definition: ezsqlite3db.php:360
eZSQLite3DB\close
close()
Definition: ezsqlite3db.php:432
eZSQLite3DB\checkCharset
checkCharset( $charset, &$currentCharset)
Definition: ezsqlite3db.php:139
eZSQLite3DB\isCharsetSupported
isCharsetSupported( $charset)
Definition: ezsqlite3db.php:521
eZSQLite3DB\databaseClientVersion
databaseClientVersion()
Definition: ezsqlite3db.php:507
eZSQLite3DB\md5
md5( $str)
Definition: ezsqlite3db.php:327
eZSQLite3DB\bitOr
bitOr( $arg1, $arg2)
Definition: ezsqlite3db.php:342
eZSQLite3DB\beginQuery
beginQuery()
Definition: ezsqlite3db.php:351
eZSQLite3DB\arrayQuery
arrayQuery( $sql, $params=array(), $server=false)
Definition: ezsqlite3db.php:192
eZSQLite3DB\concatString
concatString( $strings=array())
Definition: ezsqlite3db.php:322
eZSQLite3DB\removeRelation
removeRelation( $relationName, $relationType)
Definition: ezsqlite3db.php:569
eZSQLite3DB\query
query( $sql, $server=false)
Definition: ezsqlite3db.php:147
eZSQLite3DB\rollbackQuery
rollbackQuery()
Definition: ezsqlite3db.php:369
eZSQLite3DB\supportedRelationTypes
supportedRelationTypes()
Definition: ezsqlite3db.php:549
eZSQLite3DB\setError
setError()
Definition: ezsqlite3db.php:457
eZSQLite3DB\__destruct
__destruct()
Definition: ezsqlite3db.php:441
Copyright © 1998 – 2026 7x. All rights reserved. Licensed under the GNU GPLv2+.