diff --git a/src/Dibi/Bridges/Nette/DibiExtension22.php b/src/Dibi/Bridges/Nette/DibiExtension22.php index c07c56e9..2c5edd4d 100644 --- a/src/Dibi/Bridges/Nette/DibiExtension22.php +++ b/src/Dibi/Bridges/Nette/DibiExtension22.php @@ -55,6 +55,7 @@ class DibiExtension22 extends Nette\DI\CompilerExtension foreach ((array) $config['flags'] as $flag) { $flags |= constant($flag); } + $config['flags'] = $flags; } @@ -68,6 +69,7 @@ class DibiExtension22 extends Nette\DI\CompilerExtension [[Dibi\Bridges\Tracy\Panel::class, 'renderException']] ); } + if ($useProfiler) { $panel = $container->addDefinition($this->prefix('panel')) ->setFactory(Dibi\Bridges\Tracy\Panel::class, [ diff --git a/src/Dibi/Bridges/Tracy/Panel.php b/src/Dibi/Bridges/Tracy/Panel.php index a0b2e2ff..2e92ac81 100644 --- a/src/Dibi/Bridges/Tracy/Panel.php +++ b/src/Dibi/Bridges/Tracy/Panel.php @@ -58,6 +58,7 @@ class Panel implements Tracy\IBarPanel if (($event->type & $this->filter) === 0) { return; } + $this->events[] = $event; } @@ -88,6 +89,7 @@ class Panel implements Tracy\IBarPanel foreach ($this->events as $event) { $totalTime += $event->time; } + return '' . $count . "\u{a0}queries" . ($totalTime ? ' / ' . number_format($totalTime * 1000, 1, '.', "\u{202f}") . "\u{202f}ms" : '') @@ -128,6 +130,7 @@ class Panel implements Tracy\IBarPanel $explain = @Helpers::dump($connection->nativeQuery("$cmd $event->sql"), true); } catch (Dibi\Exception $e) { } + [$connection->onEvent, \dibi::$numOfQueries, \dibi::$totalTime] = $backup; } @@ -142,6 +145,7 @@ class Panel implements Tracy\IBarPanel if ($explain) { $s .= "
{$explain}
"; } + if ($event->source) { $s .= Tracy\Helpers::editorLink($event->source[0], $event->source[1]); //->class('tracy-DibiProfiler-source'); } diff --git a/src/Dibi/Connection.php b/src/Dibi/Connection.php index 1088af4b..cdb57752 100644 --- a/src/Dibi/Connection.php +++ b/src/Dibi/Connection.php @@ -150,16 +150,17 @@ class Connection implements IConnection if ($event) { $this->onEvent($event->done()); } + if (isset($this->config['onConnect'])) { foreach ($this->config['onConnect'] as $sql) { $this->query($sql); } } - } catch (DriverException $e) { if ($event) { $this->onEvent($event->done($e)); } + throw $e; } } @@ -207,6 +208,7 @@ class Connection implements IConnection if (!$this->driver) { $this->connect(); } + return $this->driver; } @@ -232,6 +234,7 @@ class Connection implements IConnection if (!$this->driver) { $this->connect(); } + return (clone $this->translator)->translate($args); } @@ -252,6 +255,7 @@ class Connection implements IConnection } else { echo get_class($e) . ': ' . $e->getMessage() . (PHP_SAPI === 'cli' ? "\n" : '
'); } + return false; } } @@ -287,6 +291,7 @@ class Connection implements IConnection if ($event) { $this->onEvent($event->done($e)); } + throw $e; } @@ -294,6 +299,7 @@ class Connection implements IConnection if ($event) { $this->onEvent($event->done($res)); } + return $res; } @@ -307,10 +313,12 @@ class Connection implements IConnection if (!$this->driver) { $this->connect(); } + $rows = $this->driver->getAffectedRows(); if ($rows === null || $rows < 0) { throw new Exception('Cannot retrieve number of affected rows.'); } + return $rows; } @@ -324,10 +332,12 @@ class Connection implements IConnection if (!$this->driver) { $this->connect(); } + $id = $this->driver->getInsertId($sequence); if ($id === null) { throw new Exception('Cannot retrieve last generated ID.'); } + return $id; } @@ -344,17 +354,18 @@ class Connection implements IConnection if (!$this->driver) { $this->connect(); } + $event = $this->onEvent ? new Event($this, Event::BEGIN, $savepoint) : null; try { $this->driver->begin($savepoint); if ($event) { $this->onEvent($event->done()); } - } catch (DriverException $e) { if ($event) { $this->onEvent($event->done($e)); } + throw $e; } } @@ -372,17 +383,18 @@ class Connection implements IConnection if (!$this->driver) { $this->connect(); } + $event = $this->onEvent ? new Event($this, Event::COMMIT, $savepoint) : null; try { $this->driver->commit($savepoint); if ($event) { $this->onEvent($event->done()); } - } catch (DriverException $e) { if ($event) { $this->onEvent($event->done($e)); } + throw $e; } } @@ -400,17 +412,18 @@ class Connection implements IConnection if (!$this->driver) { $this->connect(); } + $event = $this->onEvent ? new Event($this, Event::ROLLBACK, $savepoint) : null; try { $this->driver->rollback($savepoint); if ($event) { $this->onEvent($event->done()); } - } catch (DriverException $e) { if ($event) { $this->onEvent($event->done($e)); } + throw $e; } } @@ -433,6 +446,7 @@ class Connection implements IConnection if ($this->transactionDepth === 0) { $this->rollback(); } + throw $e; } @@ -484,6 +498,7 @@ class Connection implements IConnection if ($args instanceof Traversable) { $args = iterator_to_array($args); } + return $this->command()->insert() ->into('%n', $table, '(%n)', array_keys($args))->values('%l', $args); } @@ -601,6 +616,7 @@ class Connection implements IConnection if (!$this->driver) { $this->connect(); } + return new Reflection\Database($this->driver->getReflector(), $this->config['database'] ?? null); } diff --git a/src/Dibi/DataSource.php b/src/Dibi/DataSource.php index 26b63301..40dbaa37 100644 --- a/src/Dibi/DataSource.php +++ b/src/Dibi/DataSource.php @@ -72,6 +72,7 @@ class DataSource implements IDataSource } else { $this->cols[$col] = $as; } + $this->result = null; return $this; } @@ -101,6 +102,7 @@ class DataSource implements IDataSource } else { $this->sorting[$row] = $direction; } + $this->result = null; return $this; } @@ -135,6 +137,7 @@ class DataSource implements IDataSource if ($this->result === null) { $this->result = $this->connection->nativeQuery($this->__toString()); } + return $this->result; } @@ -262,6 +265,7 @@ class DataSource implements IDataSource )->fetchSingle()) : $this->getTotalCount(); } + return $this->count; } @@ -276,6 +280,7 @@ class DataSource implements IDataSource 'SELECT COUNT(*) FROM ' . $this->sql )->fetchSingle()); } + return $this->totalCount; } } diff --git a/src/Dibi/Drivers/FirebirdDriver.php b/src/Dibi/Drivers/FirebirdDriver.php index e1f8c69f..d24fd704 100644 --- a/src/Dibi/Drivers/FirebirdDriver.php +++ b/src/Dibi/Drivers/FirebirdDriver.php @@ -101,10 +101,10 @@ class FirebirdDriver implements Dibi\Driver } else { throw new Dibi\DriverException(ibase_errmsg(), ibase_errcode(), $sql); } - } elseif (is_resource($res)) { return $this->createResultDriver($res); } + return null; } @@ -136,6 +136,7 @@ class FirebirdDriver implements Dibi\Driver if ($savepoint !== null) { throw new Dibi\NotSupportedException('Savepoints are not supported in Firebird/Interbase.'); } + $this->transaction = ibase_trans($this->getResource()); $this->inTransaction = true; } diff --git a/src/Dibi/Drivers/FirebirdReflector.php b/src/Dibi/Drivers/FirebirdReflector.php index db1ddf81..d13f3810 100644 --- a/src/Dibi/Drivers/FirebirdReflector.php +++ b/src/Dibi/Drivers/FirebirdReflector.php @@ -47,6 +47,7 @@ class FirebirdReflector implements Dibi\Reflector 'view' => $row[1] === 'TRUE', ]; } + return $tables; } @@ -99,6 +100,7 @@ class FirebirdReflector implements Dibi\Reflector 'autoincrement' => false, ]; } + return $columns; } @@ -131,6 +133,7 @@ class FirebirdReflector implements Dibi\Reflector $indexes[$key]['table'] = $table; $indexes[$key]['columns'][$row['FIELD_POSITION']] = $row['FIELD_NAME']; } + return $indexes; } @@ -159,6 +162,7 @@ class FirebirdReflector implements Dibi\Reflector 'table' => $table, ]; } + return $keys; } @@ -179,6 +183,7 @@ class FirebirdReflector implements Dibi\Reflector while ($row = $res->fetch(false)) { $indices[] = $row[0]; } + return $indices; } @@ -201,6 +206,7 @@ class FirebirdReflector implements Dibi\Reflector while ($row = $res->fetch(false)) { $constraints[] = $row[0]; } + return $constraints; } @@ -248,6 +254,7 @@ class FirebirdReflector implements Dibi\Reflector 'enabled' => trim($row['TRIGGER_ENABLED']) === 'TRUE', ]; } + return $triggers; } @@ -270,6 +277,7 @@ class FirebirdReflector implements Dibi\Reflector while ($row = $res->fetch(false)) { $triggers[] = $row[0]; } + return $triggers; } @@ -321,6 +329,7 @@ class FirebirdReflector implements Dibi\Reflector $procedures[$key]['params'][$io][$num]['type'] = trim($row['FIELD_TYPE']); $procedures[$key]['params'][$io][$num]['size'] = $row['FIELD_LENGTH']; } + return $procedures; } @@ -338,6 +347,7 @@ class FirebirdReflector implements Dibi\Reflector while ($row = $res->fetch(false)) { $procedures[] = $row[0]; } + return $procedures; } @@ -356,6 +366,7 @@ class FirebirdReflector implements Dibi\Reflector while ($row = $res->fetch(false)) { $generators[] = $row[0]; } + return $generators; } @@ -374,6 +385,7 @@ class FirebirdReflector implements Dibi\Reflector while ($row = $res->fetch(false)) { $functions[] = $row[0]; } + return $functions; } } diff --git a/src/Dibi/Drivers/FirebirdResult.php b/src/Dibi/Drivers/FirebirdResult.php index be998208..a597f741 100644 --- a/src/Dibi/Drivers/FirebirdResult.php +++ b/src/Dibi/Drivers/FirebirdResult.php @@ -126,6 +126,7 @@ class FirebirdResult implements Dibi\ResultDriver 'nativetype' => $row['type'], ]; } + return $columns; } diff --git a/src/Dibi/Drivers/MySqlReflector.php b/src/Dibi/Drivers/MySqlReflector.php index bed173c2..336baaae 100644 --- a/src/Dibi/Drivers/MySqlReflector.php +++ b/src/Dibi/Drivers/MySqlReflector.php @@ -43,6 +43,7 @@ class MySqlReflector implements Dibi\Reflector 'view' => isset($row[1]) && $row[1] === 'VIEW', ]; } + return $tables; } @@ -67,6 +68,7 @@ class MySqlReflector implements Dibi\Reflector 'vendor' => $row, ]; } + return $columns; } @@ -84,6 +86,7 @@ class MySqlReflector implements Dibi\Reflector $indexes[$row['Key_name']]['primary'] = $row['Key_name'] === 'PRIMARY'; $indexes[$row['Key_name']]['columns'][$row['Seq_in_index'] - 1] = $row['Column_name']; } + return array_values($indexes); } @@ -123,6 +126,7 @@ class MySqlReflector implements Dibi\Reflector $foreignKeys[$keyName]['onDelete'] = $row['DELETE_RULE']; $foreignKeys[$keyName]['onUpdate'] = $row['UPDATE_RULE']; } + return array_values($foreignKeys); } } diff --git a/src/Dibi/Drivers/MySqliDriver.php b/src/Dibi/Drivers/MySqliDriver.php index d9dede68..e1cc4985 100644 --- a/src/Dibi/Drivers/MySqliDriver.php +++ b/src/Dibi/Drivers/MySqliDriver.php @@ -88,6 +88,7 @@ class MySqliDriver implements Dibi\Driver $this->connection->options($key, $value); } } + @$this->connection->real_connect( // intentionally @ (empty($config['persistent']) ? '' : 'p:') . $config['host'], $config['username'], @@ -153,6 +154,7 @@ class MySqliDriver implements Dibi\Driver } elseif ($res instanceof \mysqli_result) { return $this->createResultDriver($res); } + return null; } @@ -191,6 +193,7 @@ class MySqliDriver implements Dibi\Driver foreach ($matches as $m) { $res[$m[1]] = (int) $m[2]; } + return $res; } @@ -319,6 +322,7 @@ class MySqliDriver implements Dibi\Driver if ($value->y || $value->m || $value->d) { throw new Dibi\NotSupportedException('Only time interval is supported.'); } + return $value->format("'%r%H:%I:%S.%f'"); } diff --git a/src/Dibi/Drivers/MySqliResult.php b/src/Dibi/Drivers/MySqliResult.php index 67a5a86e..fde57880 100644 --- a/src/Dibi/Drivers/MySqliResult.php +++ b/src/Dibi/Drivers/MySqliResult.php @@ -55,6 +55,7 @@ class MySqliResult implements Dibi\ResultDriver if (!$this->buffered) { throw new Dibi\NotSupportedException('Row count is not available for unbuffered queries.'); } + return $this->resultSet->num_rows; } @@ -80,6 +81,7 @@ class MySqliResult implements Dibi\ResultDriver if (!$this->buffered) { throw new Dibi\NotSupportedException('Cannot seek an unbuffered result set.'); } + return $this->resultSet->data_seek($row); } @@ -107,6 +109,7 @@ class MySqliResult implements Dibi\ResultDriver $types[$value] = substr($key, 12); } } + $types[MYSQLI_TYPE_TINY] = $types[MYSQLI_TYPE_SHORT] = $types[MYSQLI_TYPE_LONG] = 'INT'; } @@ -123,6 +126,7 @@ class MySqliResult implements Dibi\ResultDriver 'vendor' => $row, ]; } + return $columns; } diff --git a/src/Dibi/Drivers/OdbcDriver.php b/src/Dibi/Drivers/OdbcDriver.php index bbcbccb7..f7776594 100644 --- a/src/Dibi/Drivers/OdbcDriver.php +++ b/src/Dibi/Drivers/OdbcDriver.php @@ -96,6 +96,7 @@ class OdbcDriver implements Dibi\Driver ? $this->createResultDriver($res) : null; } + return null; } @@ -139,6 +140,7 @@ class OdbcDriver implements Dibi\Driver if (!odbc_commit($this->connection)) { throw new Dibi\DriverException(odbc_errormsg($this->connection) . ' ' . odbc_error($this->connection)); } + odbc_autocommit($this->connection, PHP_VERSION_ID < 80000 ? 1 : true); } @@ -152,6 +154,7 @@ class OdbcDriver implements Dibi\Driver if (!odbc_rollback($this->connection)) { throw new Dibi\DriverException(odbc_errormsg($this->connection) . ' ' . odbc_error($this->connection)); } + odbc_autocommit($this->connection, PHP_VERSION_ID < 80000 ? 1 : true); } diff --git a/src/Dibi/Drivers/OdbcReflector.php b/src/Dibi/Drivers/OdbcReflector.php index 0b53294b..d59dccb0 100644 --- a/src/Dibi/Drivers/OdbcReflector.php +++ b/src/Dibi/Drivers/OdbcReflector.php @@ -44,6 +44,7 @@ class OdbcReflector implements Dibi\Reflector ]; } } + odbc_free_result($res); return $tables; } @@ -68,6 +69,7 @@ class OdbcReflector implements Dibi\Reflector ]; } } + odbc_free_result($res); return $columns; } diff --git a/src/Dibi/Drivers/OdbcResult.php b/src/Dibi/Drivers/OdbcResult.php index 45b9fac5..57657405 100644 --- a/src/Dibi/Drivers/OdbcResult.php +++ b/src/Dibi/Drivers/OdbcResult.php @@ -72,11 +72,13 @@ class OdbcResult implements Dibi\ResultDriver if (!odbc_fetch_row($set, ++$this->row)) { return null; } + $count = odbc_num_fields($set); $cols = []; for ($i = 1; $i <= $count; $i++) { $cols[] = odbc_result($set, $i); } + return $cols; } } @@ -116,6 +118,7 @@ class OdbcResult implements Dibi\ResultDriver 'nativetype' => odbc_field_type($this->resultSet, $i), ]; } + return $columns; } diff --git a/src/Dibi/Drivers/OracleDriver.php b/src/Dibi/Drivers/OracleDriver.php index 4b02f213..a63b21eb 100644 --- a/src/Dibi/Drivers/OracleDriver.php +++ b/src/Dibi/Drivers/OracleDriver.php @@ -104,6 +104,7 @@ class OracleDriver implements Dibi\Driver $err = oci_error($this->connection); throw new Dibi\DriverException($err['message'], $err['code'], $sql); } + return null; } @@ -163,6 +164,7 @@ class OracleDriver implements Dibi\Driver $err = oci_error($this->connection); throw new Dibi\DriverException($err['message'], $err['code']); } + $this->autocommit = true; } @@ -177,6 +179,7 @@ class OracleDriver implements Dibi\Driver $err = oci_error($this->connection); throw new Dibi\DriverException($err['message'], $err['code']); } + $this->autocommit = true; } diff --git a/src/Dibi/Drivers/OracleReflector.php b/src/Dibi/Drivers/OracleReflector.php index 0598a5e4..90609ec2 100644 --- a/src/Dibi/Drivers/OracleReflector.php +++ b/src/Dibi/Drivers/OracleReflector.php @@ -44,6 +44,7 @@ class OracleReflector implements Dibi\Reflector ]; } } + return $tables; } @@ -66,6 +67,7 @@ class OracleReflector implements Dibi\Reflector 'vendor' => $row, ]; } + return $columns; } diff --git a/src/Dibi/Drivers/OracleResult.php b/src/Dibi/Drivers/OracleResult.php index 65b90a5c..78a3028b 100644 --- a/src/Dibi/Drivers/OracleResult.php +++ b/src/Dibi/Drivers/OracleResult.php @@ -100,6 +100,7 @@ class OracleResult implements Dibi\ResultDriver 'nativetype' => $type === 'NUMBER' && oci_field_scale($this->resultSet, $i) === 0 ? 'INTEGER' : $type, ]; } + return $columns; } diff --git a/src/Dibi/Drivers/PdoDriver.php b/src/Dibi/Drivers/PdoDriver.php index 4b4b54c8..62697d92 100644 --- a/src/Dibi/Drivers/PdoDriver.php +++ b/src/Dibi/Drivers/PdoDriver.php @@ -60,7 +60,6 @@ class PdoDriver implements Dibi\Driver if ($this->connection->getAttribute(PDO::ATTR_ERRMODE) !== PDO::ERRMODE_SILENT) { throw new Dibi\DriverException('PDO connection in exception or warning error mode is not supported.'); } - } else { try { $this->connection = new PDO($config['dsn'], $config['username'], $config['password'], $config['options']); @@ -69,6 +68,7 @@ class PdoDriver implements Dibi\Driver if ($e->getMessage() === 'could not find driver') { throw new Dibi\NotSupportedException('PHP extension for PDO is not loaded.'); } + throw new Dibi\DriverException($e->getMessage(), $e->getCode()); } } @@ -366,15 +366,18 @@ class PdoDriver implements Dibi\Driver $sql .= ' LIMIT ' . ($limit ?? '18446744073709551615') . ($offset ? ' OFFSET ' . $offset : ''); } + break; case 'pgsql': if ($limit !== null) { $sql .= ' LIMIT ' . $limit; } + if ($offset) { $sql .= ' OFFSET ' . $offset; } + break; case 'sqlite': @@ -382,6 +385,7 @@ class PdoDriver implements Dibi\Driver $sql .= ' LIMIT ' . ($limit ?? '-1') . ($offset ? ' OFFSET ' . $offset : ''); } + break; case 'oci': @@ -394,6 +398,7 @@ class PdoDriver implements Dibi\Driver } elseif ($limit !== null) { $sql = 'SELECT * FROM (' . $sql . ') WHERE ROWNUM <= ' . $limit; } + break; case 'mssql': @@ -406,10 +411,10 @@ class PdoDriver implements Dibi\Driver } elseif ($offset) { $sql = sprintf('%s OFFSET %d ROWS', rtrim($sql), $offset); } + break; } // break omitted - case 'odbc': if ($offset) { throw new Dibi\NotSupportedException('Offset is not supported by this database.'); @@ -419,7 +424,6 @@ class PdoDriver implements Dibi\Driver break; } // break omitted - default: throw new Dibi\NotSupportedException('PDO or driver does not support applying limit or offset.'); } diff --git a/src/Dibi/Drivers/PdoResult.php b/src/Dibi/Drivers/PdoResult.php index 012f4a44..73bad23c 100644 --- a/src/Dibi/Drivers/PdoResult.php +++ b/src/Dibi/Drivers/PdoResult.php @@ -85,6 +85,7 @@ class PdoResult implements Dibi\ResultDriver if ($row === false) { throw new Dibi\NotSupportedException('Driver does not support meta data.'); } + $row += [ 'table' => null, 'native_type' => 'VAR_STRING', @@ -99,6 +100,7 @@ class PdoResult implements Dibi\ResultDriver 'vendor' => $row, ]; } + return $columns; } diff --git a/src/Dibi/Drivers/PostgreDriver.php b/src/Dibi/Drivers/PostgreDriver.php index 8c43dbfa..b92ff4f4 100644 --- a/src/Dibi/Drivers/PostgreDriver.php +++ b/src/Dibi/Drivers/PostgreDriver.php @@ -64,6 +64,7 @@ class PostgreDriver implements Dibi\Driver } } } + $connectType = $config['connect_type'] ?? PGSQL_CONNECT_FORCE_NEW; set_error_handler(function (int $severity, string $message) use (&$error) { @@ -127,6 +128,7 @@ class PostgreDriver implements Dibi\Driver return $this->createResultDriver($res); } } + return null; } @@ -264,6 +266,7 @@ class PostgreDriver implements Dibi\Driver if (!$this->getResource()) { throw new Dibi\Exception('Lost connection to server.'); } + return "'" . pg_escape_string($this->connection, $value) . "'"; } @@ -273,6 +276,7 @@ class PostgreDriver implements Dibi\Driver if (!$this->getResource()) { throw new Dibi\Exception('Lost connection to server.'); } + return "'" . pg_escape_bytea($this->connection, $value) . "'"; } @@ -328,9 +332,11 @@ class PostgreDriver implements Dibi\Driver if ($limit < 0 || $offset < 0) { throw new Dibi\NotSupportedException('Negative offset or limit.'); } + if ($limit !== null) { $sql .= ' LIMIT ' . $limit; } + if ($offset) { $sql .= ' OFFSET ' . $offset; } diff --git a/src/Dibi/Drivers/PostgreReflector.php b/src/Dibi/Drivers/PostgreReflector.php index bc7fafbb..d7bcb15b 100644 --- a/src/Dibi/Drivers/PostgreReflector.php +++ b/src/Dibi/Drivers/PostgreReflector.php @@ -66,6 +66,7 @@ class PostgreReflector implements Dibi\Reflector while ($row = $res->fetch(true)) { $tables[] = $row; } + return $tables; } @@ -131,6 +132,7 @@ class PostgreReflector implements Dibi\Reflector 'vendor' => $row, ]; } + return $columns; } @@ -180,6 +182,7 @@ class PostgreReflector implements Dibi\Reflector } } } + return array_values($indexes); } diff --git a/src/Dibi/Drivers/PostgreResult.php b/src/Dibi/Drivers/PostgreResult.php index 62c54832..cc0358ef 100644 --- a/src/Dibi/Drivers/PostgreResult.php +++ b/src/Dibi/Drivers/PostgreResult.php @@ -103,6 +103,7 @@ class PostgreResult implements Dibi\ResultDriver : $row['name']; $columns[] = $row; } + return $columns; } diff --git a/src/Dibi/Drivers/SqliteDriver.php b/src/Dibi/Drivers/SqliteDriver.php index cdeb9fa7..2e215b8d 100644 --- a/src/Dibi/Drivers/SqliteDriver.php +++ b/src/Dibi/Drivers/SqliteDriver.php @@ -92,6 +92,7 @@ class SqliteDriver implements Dibi\Driver } elseif ($res instanceof \SQLite3Result && $res->numColumns()) { return $this->createResultDriver($res); } + return null; } diff --git a/src/Dibi/Drivers/SqliteReflector.php b/src/Dibi/Drivers/SqliteReflector.php index db1a37b7..da2a36f4 100644 --- a/src/Dibi/Drivers/SqliteReflector.php +++ b/src/Dibi/Drivers/SqliteReflector.php @@ -44,6 +44,7 @@ class SqliteReflector implements Dibi\Reflector while ($row = $res->fetch(true)) { $tables[] = $row; } + return $tables; } @@ -70,6 +71,7 @@ class SqliteReflector implements Dibi\Reflector 'vendor' => $row, ]; } + return $columns; } @@ -103,8 +105,10 @@ class SqliteReflector implements Dibi\Reflector break; } } + $indexes[$index]['primary'] = (bool) $primary; } + if (!$indexes) { // @see http://www.sqlite.org/lang_createtable.html#rowid foreach ($columns as $column) { if ($column['vendor']['pk']) { @@ -142,6 +146,7 @@ class SqliteReflector implements Dibi\Reflector $keys[$row['id']]['foreign'] = null; } } + return array_values($keys); } } diff --git a/src/Dibi/Drivers/SqliteResult.php b/src/Dibi/Drivers/SqliteResult.php index 4f31b90e..686d8b00 100644 --- a/src/Dibi/Drivers/SqliteResult.php +++ b/src/Dibi/Drivers/SqliteResult.php @@ -99,6 +99,7 @@ class SqliteResult implements Dibi\ResultDriver 'nativetype' => $types[$this->resultSet->columnType($i)] ?? null, // buggy in PHP 7.4.4 & 7.3.16, bug 79414 ]; } + return $columns; } diff --git a/src/Dibi/Drivers/SqlsrvDriver.php b/src/Dibi/Drivers/SqlsrvDriver.php index 98287fbd..9801d911 100644 --- a/src/Dibi/Drivers/SqlsrvDriver.php +++ b/src/Dibi/Drivers/SqlsrvDriver.php @@ -56,7 +56,6 @@ class SqlsrvDriver implements Dibi\Driver if (!is_resource($this->connection)) { throw new \InvalidArgumentException("Configuration option 'resource' is not resource."); } - } else { $options = $config['options']; @@ -72,6 +71,7 @@ class SqlsrvDriver implements Dibi\Driver $info = sqlsrv_errors(SQLSRV_ERR_ERRORS); throw new Dibi\DriverException($info[0]['message'], $info[0]['code']); } + sqlsrv_configure('WarningsReturnAsErrors', 1); } @@ -107,6 +107,7 @@ class SqlsrvDriver implements Dibi\Driver ? $this->createResultDriver($res) : null; } + return null; } @@ -130,6 +131,7 @@ class SqlsrvDriver implements Dibi\Driver $row = sqlsrv_fetch_array($res, SQLSRV_FETCH_NUMERIC); return Dibi\Helpers::intVal($row[0]); } + return null; } @@ -267,7 +269,6 @@ class SqlsrvDriver implements Dibi\Driver } elseif ($limit !== null) { $sql = sprintf('SELECT TOP (%d) * FROM (%s) t', $limit, $sql); } - } elseif ($limit !== null) { // requires ORDER BY, see https://technet.microsoft.com/en-us/library/gg699618(v=sql.110).aspx $sql = sprintf('%s OFFSET %d ROWS FETCH NEXT %d ROWS ONLY', rtrim($sql), $offset, $limit); diff --git a/src/Dibi/Drivers/SqlsrvReflector.php b/src/Dibi/Drivers/SqlsrvReflector.php index 28049537..b7b78f46 100644 --- a/src/Dibi/Drivers/SqlsrvReflector.php +++ b/src/Dibi/Drivers/SqlsrvReflector.php @@ -42,6 +42,7 @@ class SqlsrvReflector implements Dibi\Reflector 'view' => isset($row[1]) && $row[1] === 'VIEW', ]; } + return $tables; } @@ -91,6 +92,7 @@ class SqlsrvReflector implements Dibi\Reflector 'vendor' => $row, ]; } + return $columns; } @@ -114,6 +116,7 @@ class SqlsrvReflector implements Dibi\Reflector $indexes[$row['name']]['primary'] = $row['is_primary_key'] === 1; $indexes[$row['name']]['columns'] = $keyUsages[$row['name']] ?? []; } + return array_values($indexes); } diff --git a/src/Dibi/Drivers/SqlsrvResult.php b/src/Dibi/Drivers/SqlsrvResult.php index 1b5a50cf..ef6ffcf8 100644 --- a/src/Dibi/Drivers/SqlsrvResult.php +++ b/src/Dibi/Drivers/SqlsrvResult.php @@ -96,6 +96,7 @@ class SqlsrvResult implements Dibi\ResultDriver 'nativetype' => $fieldMetadata['Type'], ]; } + return $columns; } diff --git a/src/Dibi/Fluent.php b/src/Dibi/Fluent.php index e505aecd..e905e3e0 100644 --- a/src/Dibi/Fluent.php +++ b/src/Dibi/Fluent.php @@ -136,6 +136,7 @@ class Fluent implements IDataSource if (isset(self::$masks[$clause])) { $this->clauses = array_fill_keys(self::$masks[$clause], null); } + $this->cursor = &$this->clauses[$clause]; $this->cursor = []; $this->command = $clause; @@ -165,7 +166,6 @@ class Fluent implements IDataSource $this->cursor[] = $sep; } } - } else { // append to currect flow if ($args === [self::REMOVE]) { @@ -203,6 +203,7 @@ class Fluent implements IDataSource if ($arg instanceof self) { $arg = new Literal("($arg)"); } + $this->cursor[] = $arg; } @@ -245,6 +246,7 @@ class Fluent implements IDataSource } else { unset($this->flags[$flag]); } + return $this; } @@ -390,6 +392,7 @@ class Fluent implements IDataSource $method = array_shift($setup); $res->$method(...$setup); } + return $res; } @@ -428,7 +431,6 @@ class Fluent implements IDataSource $args = array_merge(['%lmt %ofs', $data['LIMIT'][0] ?? null, $data['OFFSET'][0] ?? null], $args); unset($data['LIMIT'], $data['OFFSET']); } - } else { $clause = self::$normalizer->$clause; if (array_key_exists($clause, $this->clauses)) { @@ -444,6 +446,7 @@ class Fluent implements IDataSource if ($clause === $this->command && $this->flags) { $args[] = implode(' ', array_keys($this->flags)); } + foreach ($statement as $arg) { $args[] = $arg; } @@ -464,6 +467,7 @@ class Fluent implements IDataSource $s .= 'By'; trigger_error("Did you mean '$s'?", E_USER_NOTICE); } + return strtoupper(preg_replace('#[a-z](?=[A-Z])#', '$0 ', $s)); } @@ -475,6 +479,7 @@ class Fluent implements IDataSource $this->clauses[$clause] = &$val; unset($val); } + $this->cursor = &$foo; } } diff --git a/src/Dibi/HashMap.php b/src/Dibi/HashMap.php index 7fa558c1..0f3b426a 100644 --- a/src/Dibi/HashMap.php +++ b/src/Dibi/HashMap.php @@ -50,6 +50,7 @@ final class HashMap extends HashMapBase if ($nm === '') { $nm = "\xFF"; } + $this->$nm = $val; } diff --git a/src/Dibi/Helpers.php b/src/Dibi/Helpers.php index 8c86ae68..7e3e9caf 100644 --- a/src/Dibi/Helpers.php +++ b/src/Dibi/Helpers.php @@ -41,6 +41,7 @@ class Helpers $spaces = $maxLen - mb_strlen($col) + 2; echo "$col" . str_repeat(' ', $spaces) . "$val\n"; } + echo "\n"; } @@ -53,6 +54,7 @@ class Helpers foreach ($row as $col => $foo) { echo "\t\t" . htmlspecialchars((string) $col) . "\n"; } + echo "\t\n\n\n"; } @@ -60,6 +62,7 @@ class Helpers foreach ($row as $col) { echo "\t\t", htmlspecialchars((string) $col), "\n"; } + echo "\t\n"; } @@ -104,6 +107,7 @@ class Helpers } }, $sql); } + echo trim($sql) . "\n\n"; } else { @@ -150,6 +154,7 @@ class Helpers $best = $item; } } + return $best; } @@ -198,6 +203,7 @@ class Helpers return $val; } } + return null; } @@ -208,6 +214,7 @@ class Helpers if (self::$types === null) { self::$types = new HashMap([self::class, 'detectType']); } + return self::$types; } @@ -260,7 +267,6 @@ class Helpers if ($onProgress) { $onProgress($count, isset($stat['size']) ? $size * 100 / $stat['size'] : null); } - } else { $sql .= $s; } @@ -273,6 +279,7 @@ class Helpers $onProgress($count, isset($stat['size']) ? 100 : null); } } + fclose($handle); return $count; } @@ -294,6 +301,7 @@ class Helpers if (is_float($value * 1)) { throw new Exception("Number $value is greater than integer."); } + return (int) $value; } else { throw new Exception("Expected number, '$value' given."); diff --git a/src/Dibi/Loggers/FileLogger.php b/src/Dibi/Loggers/FileLogger.php index f35e0ee0..8268234d 100644 --- a/src/Dibi/Loggers/FileLogger.php +++ b/src/Dibi/Loggers/FileLogger.php @@ -54,6 +54,7 @@ class FileLogger if ($code = $event->result->getCode()) { $message = "[$code] $message"; } + $this->writeToFile( $event, "ERROR: $message" diff --git a/src/Dibi/Reflection/Column.php b/src/Dibi/Reflection/Column.php index 3d7ed23d..b5b92c20 100644 --- a/src/Dibi/Reflection/Column.php +++ b/src/Dibi/Reflection/Column.php @@ -66,6 +66,7 @@ class Column if (empty($this->info['table']) || !$this->reflector) { throw new Dibi\Exception('Table is unknown or not available.'); } + return new Table($this->reflector, ['name' => $this->info['table']]); } diff --git a/src/Dibi/Reflection/Database.php b/src/Dibi/Reflection/Database.php index 8c6e11ed..a271acd2 100644 --- a/src/Dibi/Reflection/Database.php +++ b/src/Dibi/Reflection/Database.php @@ -62,6 +62,7 @@ class Database foreach ($this->tables as $table) { $res[] = $table->getName(); } + return $res; } diff --git a/src/Dibi/Reflection/Result.php b/src/Dibi/Reflection/Result.php index 2d8f92aa..a843de50 100644 --- a/src/Dibi/Reflection/Result.php +++ b/src/Dibi/Reflection/Result.php @@ -54,6 +54,7 @@ class Result foreach ($this->columns as $column) { $res[] = $fullNames ? $column->getFullName() : $column->getName(); } + return $res; } diff --git a/src/Dibi/Reflection/Table.php b/src/Dibi/Reflection/Table.php index f79802df..a0e28f8e 100644 --- a/src/Dibi/Reflection/Table.php +++ b/src/Dibi/Reflection/Table.php @@ -85,6 +85,7 @@ class Table foreach ($this->columns as $column) { $res[] = $column->getName(); } + return $res; } @@ -152,6 +153,7 @@ class Table foreach ($info['columns'] as $key => $name) { $info['columns'][$key] = $this->columns[strtolower($name)]; } + $this->indexes[strtolower($info['name'])] = new Index($info); if (!empty($info['primary'])) { $this->primaryKey = $this->indexes[strtolower($info['name'])]; diff --git a/src/Dibi/Result.php b/src/Dibi/Result.php index 6c2714c3..56a114d9 100644 --- a/src/Dibi/Result.php +++ b/src/Dibi/Result.php @@ -170,6 +170,7 @@ class Result implements IDataSource if ($row === null) { return null; } + $this->fetched = true; $this->normalize($row); if ($this->rowFactory) { @@ -177,6 +178,7 @@ class Result implements IDataSource } elseif ($this->rowClass) { return new $this->rowClass($row); } + return $row; } @@ -191,6 +193,7 @@ class Result implements IDataSource if ($row === null) { return null; } + $this->fetched = true; $this->normalize($row); return reset($row); @@ -215,6 +218,7 @@ class Result implements IDataSource if ($limit === 0) { break; } + $limit--; $data[] = $row; } while ($row = $this->fetch()); @@ -287,7 +291,6 @@ class Result implements IDataSource } else { $x = &$x->{$assoc[$i + 1]}; } - } elseif ($as !== '|') { // associative-array node $x = &$x[(string) $row->$as]; } @@ -345,7 +348,6 @@ class Result implements IDataSource } else { $x = &$x[$assoc[$i + 1]]; } - } elseif ($as === '@') { // "object" node if ($x === null) { $x = clone $row; @@ -354,7 +356,6 @@ class Result implements IDataSource } else { $x = &$x->{$assoc[$i + 1]}; } - } else { // associative-array node $x = &$x[(string) $row->$as]; } @@ -398,6 +399,7 @@ class Result implements IDataSource do { $data[] = $row[$key]; } while ($row = $this->fetch()); + return $data; } @@ -412,6 +414,7 @@ class Result implements IDataSource do { $data[] = $row[$value]; } while ($row = $this->fetch()); + return $data; } @@ -455,6 +458,7 @@ class Result implements IDataSource if (!isset($row[$key])) { // null continue; } + $value = $row[$key]; $format = $this->formats[$type] ?? null; @@ -478,9 +482,11 @@ class Result implements IDataSource } elseif ($p !== false && $e !== false) { $value = rtrim($value, '.'); } + if ($value === '' || $value[0] === '.') { $value = '0' . $value; } + $row[$key] = $value === str_replace(',', '.', (string) ($float = (float) $value)) ? $float : $value; @@ -495,7 +501,6 @@ class Result implements IDataSource } else { $row[$key] = null; } - } elseif ($type === Type::TIME_INTERVAL) { preg_match('#^(-?)(\d+)\D(\d+)\D(\d+)\z#', $value, $m); $value = new \DateInterval("PT$m[2]H$m[3]M$m[4]S"); @@ -513,7 +518,6 @@ class Result implements IDataSource } else { $row[$key] = json_decode($value, $format === 'array'); } - } else { throw new \RuntimeException('Unexpected type ' . $type); } @@ -590,6 +594,7 @@ class Result implements IDataSource if ($this->meta === null) { $this->meta = new Reflection\Result($this->getResultDriver()); } + return $this->meta; } diff --git a/src/Dibi/Row.php b/src/Dibi/Row.php index 78eae4d0..c0bb7118 100644 --- a/src/Dibi/Row.php +++ b/src/Dibi/Row.php @@ -40,8 +40,10 @@ class Row implements \ArrayAccess, \IteratorAggregate, \Countable if (!$time || substr((string) $time, 0, 7) === '0000-00') { // '', null, false, '0000-00-00', ... return null; } + $time = new DateTime($time); } + return $format === null ? $time : $time->format($format); } diff --git a/src/Dibi/Strict.php b/src/Dibi/Strict.php index f3386c5b..17804f50 100644 --- a/src/Dibi/Strict.php +++ b/src/Dibi/Strict.php @@ -67,6 +67,7 @@ trait Strict $ret = $this->$m(); return $ret; } + $rc = new ReflectionClass($this); $items = array_filter($rc->getProperties(ReflectionProperty::IS_PUBLIC), function ($p) { return !$p->isStatic(); }); $items = array_map(function ($item) { return $item->getName(); }, $items); diff --git a/src/Dibi/Translator.php b/src/Dibi/Translator.php index 1a7852e0..2188e896 100644 --- a/src/Dibi/Translator.php +++ b/src/Dibi/Translator.php @@ -69,6 +69,7 @@ final class Translator while (count($args) === 1 && is_array($args[0])) { // implicit array expansion $args = array_values($args[0]); } + $this->args = $args; $this->errors = []; @@ -116,6 +117,7 @@ XX throw new PcreException; } } + continue; } @@ -138,8 +140,10 @@ XX if ($lastArr === $cursor - 1) { $sql[] = ','; } + $sql[] = $this->formatValue($arg, $commandIns ? 'l' : 'a'); } + $lastArr = $cursor; continue; } @@ -148,7 +152,6 @@ XX $sql[] = $this->formatValue($arg, null); } // while - if ($comment) { $sql[] = '*/'; } @@ -214,13 +217,14 @@ XX } else { $op = '= '; } + $vx[] = $k . $op . $v; } - } else { $vx[] = $this->formatValue($v, 'ex'); } } + return '(' . implode(') ' . strtoupper($modifier) . ' (', $vx) . ')'; case 'n': // key, key, ... identifier names @@ -232,6 +236,7 @@ XX $vx[] = $this->identifiers->{$pair[0]}; } } + return implode(', ', $vx); @@ -241,6 +246,7 @@ XX $vx[] = $this->identifiers->{$pair[0]} . '=' . $this->formatValue($v, $pair[1] ?? (is_array($v) ? 'ex!' : null)); } + return implode(', ', $vx); @@ -250,6 +256,7 @@ XX $pair = explode('%', (string) $k, 2); // split into identifier & modifier $vx[] = $this->formatValue($v, $pair[1] ?? (is_array($v) ? 'ex!' : null)); } + return '(' . (($vx || $modifier === 'l') ? implode(', ', $vx) : 'NULL') . ')'; @@ -259,6 +266,7 @@ XX $kx[] = $this->identifiers->{$pair[0]}; $vx[] = $this->formatValue($v, $pair[1] ?? (is_array($v) ? 'ex!' : null)); } + return '(' . implode(', ', $kx) . ') VALUES (' . implode(', ', $vx) . ')'; case 'm': // (key, key, ...) VALUES (val, val, ...), (val, val, ...), ... @@ -281,9 +289,11 @@ XX $vx[$k2][] = $this->formatValue($v2, $pair[1] ?? (is_array($v2) ? 'ex!' : null)); } } + foreach ($vx as $k => $v) { $vx[$k] = '(' . implode(', ', $v) . ')'; } + return '(' . implode(', ', $kx) . ') VALUES ' . implode(', ', $vx); case 'by': // key ASC, key DESC @@ -297,6 +307,7 @@ XX $vx[] = $this->identifiers->$v; } } + return implode(', ', $vx); case 'ex!': @@ -310,11 +321,11 @@ XX foreach ($value as $v) { $vx[] = $this->formatValue($v, $modifier); } + return implode(', ', $vx); } } - // with modifier procession if ($modifier) { if ($value !== null && !is_scalar($value)) { // array is already processed @@ -400,6 +411,7 @@ XX } elseif (!$value instanceof \DateTimeInterface) { $value = new DateTime($value); } + return $modifier === 'd' ? $this->driver->escapeDate($value) : $this->driver->escapeDateTime($value); @@ -439,6 +451,7 @@ XX throw new PcreException; } } + return $value; case 'SQL': // preserve as real SQL (TODO: rename to %sql) @@ -469,7 +482,6 @@ XX } } - // without modifier procession if (is_string($value)) { return $this->driver->escapeText($value); @@ -551,6 +563,7 @@ XX $this->comment = true; return '/*'; } + return ''; } elseif ($mod === 'else') { @@ -563,7 +576,6 @@ XX $this->comment = true; return '/*'; } - } elseif ($mod === 'end') { $this->ifLevel--; if ($this->ifLevelStart === $this->ifLevel + 1) { @@ -572,6 +584,7 @@ XX $this->comment = false; return '*/'; } + return ''; } elseif ($mod === 'ex') { // array expansion @@ -586,6 +599,7 @@ XX } else { $this->limit = Helpers::intVal($arg); } + return ''; } elseif ($mod === 'ofs') { // apply offset @@ -596,6 +610,7 @@ XX } else { $this->offset = Helpers::intVal($arg); } + return ''; } else { // default processing @@ -649,6 +664,7 @@ XX $v = $this->driver->escapeIdentifier($v); } } + return implode('.', $parts); } } diff --git a/tests/dibi/PdoDriver.providedConnection.phpt b/tests/dibi/PdoDriver.providedConnection.phpt index 81d999c2..dfec0a74 100644 --- a/tests/dibi/PdoDriver.providedConnection.phpt +++ b/tests/dibi/PdoDriver.providedConnection.phpt @@ -13,6 +13,7 @@ function buildPdoDriver(?int $errorMode) if ($errorMode !== null) { $pdo->setAttribute(PDO::ATTR_ERRMODE, $errorMode); } + new Dibi\Drivers\PdoDriver(['resource' => $pdo]); }