Version 4.5.0

This commit is contained in:
Neo committed 2025-12-19 05:51:58 -08:00
1 parent 1a0c7fd3c2
commit f79dcf067a
3791 files changed
+248032 -76372

No files matched your search

+56 -71
View File
@@ -11,7 +11,7 @@
namespace IPS\Db;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -46,7 +46,7 @@ class _Select implements \Iterator, \Countable
* @brief The statement
*/
protected $stmt;
/**
* @brief If TRUE, will return the result as a multidimensional array, with each joined table separately
*/
@@ -85,6 +85,16 @@ class _Select implements \Iterator, \Countable
{
return $this->query;
}
/**
* Return the query
*
* @return string
*/
public function returnFullQuery()
{
return \IPS\Db::_replaceBinds( $this->query, array_merge( $this->joinBinds, $this->binds ) );
}
/**
* Force an index
@@ -152,7 +162,7 @@ class _Select implements \Iterator, \Countable
$query .= "( {$tableQuery} ) AS `{$matches[1]}`";
}
}
elseif ( is_array( $table ) )
elseif ( \is_array( $table ) )
{
if ( \substr( $table[0], 0, 1 ) === '(' )
{
@@ -177,11 +187,11 @@ class _Select implements \Iterator, \Countable
return '`' . $col . '`';
}, $on ) ) . ' ) ';
}
else if ( is_array( $on ) AND isset($on[1]) and $on[1] instanceof \IPS\Db\Select )
else if ( \is_array( $on ) AND isset($on[1]) and $on[1] instanceof \IPS\Db\Select )
{
$query .= ' ON ' . $on[0] . '=(' . $on[1]->query . ')';
if( count( $on[1]->binds ) )
if( \count( $on[1]->binds ) )
{
foreach ( $on[1]->binds as $bind )
{
@@ -256,12 +266,7 @@ class _Select implements \Iterator, \Countable
* @brief Value Table
*/
protected $valueTable = NULL;
/**
* @brief Are we at the beginning?
*/
protected $rewound = FALSE;
/**
* Set key field
*
@@ -276,18 +281,18 @@ class _Select implements \Iterator, \Countable
$this->runQuery();
}
if ( is_string( $column ) )
if ( \is_string( $column ) )
{
if ( $this->multiDimensional )
{
if ( !isset( $this->columns[ $table ] ) or !in_array( $column, $this->columns[ $table ] ) )
if ( !isset( $this->columns[ $table ] ) or !\in_array( $column, $this->columns[ $table ] ) )
{
throw new \InvalidArgumentException;
}
}
else
{
if ( !in_array( $column, $this->columns ) )
if ( !\in_array( $column, $this->columns ) )
{
throw new \InvalidArgumentException;
}
@@ -314,18 +319,18 @@ class _Select implements \Iterator, \Countable
$this->runQuery();
}
if ( is_string( $column ) )
if ( \is_string( $column ) )
{
if ( $this->multiDimensional )
{
if ( !isset( $this->columns[ $table ] ) or !in_array( $column, $this->columns[ $table ] ) )
if ( !isset( $this->columns[ $table ] ) or !\in_array( $column, $this->columns[ $table ] ) )
{
throw new \InvalidArgumentException;
}
}
else
{
if ( !in_array( $column, $this->columns ) )
if ( !\in_array( $column, $this->columns ) )
{
throw new \InvalidArgumentException;
}
@@ -355,11 +360,11 @@ class _Select implements \Iterator, \Countable
* @throws \UnderflowException
*/
public function first()
{
if ( !$this->rewound )
{
$this->rewind();
}
{
/* Move to the first result */
$this->rewind();
/* Return it */
if ( !$this->valid() )
{
throw new \UnderflowException;
@@ -384,7 +389,7 @@ class _Select implements \Iterator, \Countable
if ( !$meta )
{
throw new \IPS\Db\Exception( "No result metadata - possible table crash", -1, NULL, $this->query, array_merge( $this->joinBinds, $this->binds ) );
throw new \IPS\Db\Exception( $this->db->errno ? $this->db->error : "No result metadata - possible table crash", $this->db->errno ?: -1, NULL, $this->query, array_merge( $this->joinBinds, $this->binds ) );
}
while ( $field = $meta->fetch_field() )
@@ -413,18 +418,14 @@ class _Select implements \Iterator, \Countable
$this->columns = array_keys( $this->row );
}
call_user_func_array( array( $this->stmt, 'bind_result' ), $params );
$stmtReference = $this->stmt;
$stmtReference->bind_result( ...$params );
/* Set counts */
if ( mb_strpos( $this->query, 'SQL_CALC_FOUND_ROWS' ) !== FALSE )
{
$count = $this->db->query( 'SELECT FOUND_ROWS() AS count;', TRUE, TRUE )->fetch_assoc();
$this->totalCount = $count['count'];
}
$this->count = $this->stmt->num_rows;
/* Note that the query has just been ran */
$this->rewound = TRUE;
/* Set the key to -1 (i.e. we haven't fetched any row yet) */
$this->key = -1;
}
/**
@@ -433,16 +434,18 @@ class _Select implements \Iterator, \Countable
* @return void
*/
public function rewind()
{
/* Run the query */
if ( !$this->rewound )
{
$this->runQuery();
}
/* Get the first result */
$this->key = -1;
$this->next();
{
/* If we haven't run the query yet, or we have already traversed the result set beyond the first result, (re-)run the query */
if ( !$this->stmt or $this->key > 0 )
{
$this->runQuery();
}
/* Move to the first result if we haven't already */
if ( $this->key === -1 )
{
$this->next();
}
}
/**
@@ -454,9 +457,10 @@ class _Select implements \Iterator, \Countable
{
if ( $this->valueField )
{
if ( !is_string( $this->valueField ) and is_callable( $this->valueField ) )
if ( !\is_string( $this->valueField ) and \is_callable( $this->valueField ) )
{
return call_user_func( $this->valueField, $this->row );
$valueField = $this->valueField;
return $valueField( $this->row );
}
else
{
@@ -470,7 +474,7 @@ class _Select implements \Iterator, \Countable
}
}
}
elseif ( count( $this->row ) === 1 )
elseif ( \count( $this->row ) === 1 )
{
foreach ( $this->row as $v )
{
@@ -482,7 +486,7 @@ class _Select implements \Iterator, \Countable
$row = array();
foreach ( $this->row as $k => $v )
{
if ( is_array( $v ) )
if ( \is_array( $v ) )
{
foreach ( $v as $k2 => $v2 )
{
@@ -507,7 +511,7 @@ class _Select implements \Iterator, \Countable
{
if ( $this->keyField )
{
if ( is_string( $this->keyField ) )
if ( \is_string( $this->keyField ) )
{
if ( $this->keyTable )
{
@@ -520,7 +524,8 @@ class _Select implements \Iterator, \Countable
}
else
{
return call_user_func( $this->keyField, $this->row );
$keyField = $this->keyField;
return $keyField( $this->row );
}
}
else
@@ -535,9 +540,7 @@ class _Select implements \Iterator, \Countable
* @return void
*/
public function next()
{
$this->rewound = FALSE;
{
$fetch = $this->stmt->fetch();
if ( $fetch === NULL )
{
@@ -561,37 +564,19 @@ class _Select implements \Iterator, \Countable
* @brief Number of rows in this set
*/
protected $count;
/**
* @brief Number of rows in total, ignoring LIMIT
*/
protected $totalCount;
/**
* [Countable] Get number of rows
*
* @param bool $allRows If TRUE, will get the number of rows ignoring the limit. In order for this to work, the query must have been ran with SQL_CALC_FOUND_ROWS
* @return int
*/
public function count( $allRows = FALSE )
public function count()
{
if ( !$this->stmt )
{
$this->runQuery();
$this->rewound = FALSE;
}
if ( $allRows )
{
if ( $this->totalCount === NULL )
{
throw new \IPS\Db\Exception( "Total count attempted on a query not ran with SQL_CALC_FOUND_ROWS", -100, NULL, $this->query, array_merge( $this->joinBinds, $this->binds ) );
}
return $this->totalCount;
}
else
{
return $this->count;
}
return $this->count;
}
}