Override of parent query() to watch for "MySQL went away" errors

@param String $sqlStatement
@param array  $bindParams
@param array  $bindTypes

@return boolean
495804
public function query($sqlStatement, $bindParams=null, $bindTypes=null) {
		try {
			$results = $this->callParentQuery($sqlStatement, $bindParams, $bindTypes);
            $results->setFetchMode(Db::FETCH_ASSOC);
            return $results;
		} catch(\PDOException $e) {
			if($e->getCode() === self::MYSQL_WENT_AWAY_CODE || $e->getMessage() === 'SQLSTATE[HY000]: General error: 2006 MySQL server has gone away') {
				$this->connect($this->_descriptor);
				return $this->callParentQuery($sqlStatement, $bindParams, $bindTypes);
			} else {
				throw $e;
			}
		}
	}
1365287
protected function bind(Statement $preparedStatement, $query)
    {
        foreach ($this->values as $placeholder => $value) {
            if (strpos($query, $placeholder) !== false) {
                $preparedStatement->bindValue($placeholder, $value[0], $value[1]);
            }
        }

        foreach ($this->variables as $placeholder => $value) {
            if (strpos($query, $placeholder) !== false) {
                $variable = & $value[0];
                $preparedStatement->bindParam($placeholder, $variable, $value[1]);
            }
        }

        foreach ($this->arrays as $placeholder => $values) {
            $count = count($values);
            for ($i = 0; $i < $count; $i++) {
                $value = $values[$i];
                $nextPlaceholder = $placeholder . $i;
                if (is_null($value)) {
                    $preparedStatement->bindValue($nextPlaceholder, $value, \PDO::PARAM_NULL);
                } elseif (is_int($value)) {
                    $preparedStatement->bindValue($nextPlaceholder, $value, \PDO::PARAM_INT);
                } else {
                    $preparedStatement->bindValue($nextPlaceholder, $value, \PDO::PARAM_STR);
                }
            }
        }
    }
1359238
public function prepareAndExecuteSql($sql, $binds = [])
    {
        $prepare = $this->prepareSQL($sql, $binds);

        return $this->executePrepared($prepare);
    }
860259
protected function __execute(array $inputParameters = null)
    {
        $params = $this->getExecuteParams($inputParameters);
        $result = $this->statement->execute($params);
        yield $result;
        $result = yield;
        $this->binds = [];
        if(false === $result)
        {
            throw new DbException('sql query error: [' . $this->errorCode() . '] ' . $this->errorInfo() . ' sql: ' . $this->getSql());
        }
        else
        {
            $this->data = $result;
            $this->cursor = 0;
            return true;
        }
    }
1158740
protected function executeUpdate($sql,$bindparams=NULL) {
		$result = $this->db->handle->prepare($sql);
		$result->execute($bindparams);
		if ($result->errorCode() == '00000') {
			return true;
		} 
		$this->logStatementError($result->errorInfo(),$sql);
		return false;
	}
335367
protected function _run(string $type, string $table, string $sql=NULL, array $vals=NULL, bool $reset=TRUE): PDOStatement
	{
		if ($sql === NULL)
		{
			$sql = $this->_compile($type, $table);
		}

		if ($vals === NULL)
		{
			$vals = array_merge($this->state->getValues(), $this->state->getWhereValues());
		}

		$startTime = microtime(TRUE);

		$res = empty($vals)
			? $this->driver->query($sql)
			: $this->driver->prepareExecute($sql, $vals);

		$endTime = microtime(TRUE);
		$totalTime = number_format($endTime - $startTime, 5);

		// Add this query to the list of executed queries
		$this->_appendQuery($vals, $sql, (int) $totalTime);

		// Reset class state for next query
		if ($reset)
		{
			$this->resetQuery();
		}

		return $res;
	}
1030245
public int bindStatement(PreparedStatement stmt, Query query, ClassDescriptor cld, int param) throws SQLException
    {
        int result;

        result = bindStatement(stmt, query.getCriteria(), cld, param);
        result = bindStatement(stmt, query.getHavingCriteria(), cld, result);

        return result;
    }
510259
public function execute($params = null)
    {
        if (is_array($params)) {
            $hasZeroIndex = array_key_exists(0, $params);

            foreach ($params as $key => $val) {
                if ($hasZeroIndex && is_int($key)) {
                    $this->bindValue($key + 1, $val);
                } else {
                    $this->bindValue($key, $val);
                }
            }
        }

        if (! sasql_stmt_execute($this->stmt)) {
            throw SQLAnywhereException::fromSQLAnywhereError($this->conn, $this->stmt);
        }

        $this->result = sasql_stmt_result_metadata($this->stmt);

        return true;
    }
56311
public function execXMLStoredProcedure($conn, $sql, $bindArray)
    {

        $internalKey = $bindArray['internalKey'];
        $controlKey = $bindArray['controlKey'];
        $inputXml = $bindArray['inputXml'];
        $outputXml = $bindArray['outputXml'];

        // @todo see why error doesn't properly bubble up to top level.
        $crsr = @db2_prepare($conn, $sql);
        if (!$crsr) {
            $this->setStmtError();
            return false;
        }

        // stored procedure takes four parameters. Each 'name' will be bound to a real PHP variable
        $params = array(
            array('position' => 1, 'name' => "internalKey", 'inout' => DB2_PARAM_IN),
            array('position' => 2, 'name' => "controlKey",  'inout' => DB2_PARAM_IN),
            array('position' => 3, 'name' => "inputXml",    'inout' => DB2_PARAM_IN),
            array('position' => 4, 'name' => "outputXml",   'inout' => DB2_PARAM_OUT),
        );
        
        // bind the four parameters
        foreach ($params as $param) {
            $ret = db2_bind_param ($crsr, $param['position'], $param['name'], $param['inout']);
            if (!$ret) {
                // unable to bind a param. Set error and exit
                $this->setStmtError($crsr);
                return false;
            }
        }

        $ret = @db2_execute($crsr);
        if (!$ret) {
            // execution of XMLSERVICE stored procedure failed.
            $this->setStmtError($crsr);
            return false;
        }

        return $outputXml;
    }
1082652
private function binding(\PDOStatement $sql, array $bindings = []): \PDOStatement
    {
        foreach ($bindings as $binding=>$value) {
            if (!is_array($value)) {
                $sql->bindValue($binding, $value);
            } else {
                switch(strtolower($value[1])) {
                    case 'date':
                        $sql->bindValue($binding, $this->time($value[0], 'Y-m-d'), \PDO::PARAM_STR);
                        break;
                    case 'time':
                        $sql->bindValue($binding, $this->time($value[0], 'Y-m-d H:i:s.u'), \PDO::PARAM_STR);
                        break;
                    case 'bool':
                    case 'boolean':
                        $sql->bindValue($binding, boolval($value[0]), \PDO::PARAM_BOOL);
                        break;
                    case 'null':
                        $sql->bindValue($binding, NULL, \PDO::PARAM_NULL);
                        break;
                    case 'int':
                    case 'integer':
                    case 'number':
                    case 'limit':
                    case 'offset':
                        $sql->bindValue($binding, intval($value[0]), \PDO::PARAM_INT);
                        break;
                    case 'str':
                    case 'string':
                    case 'text':
                    case 'float':
                    case 'varchar':
                    case 'varchar2':
                        $sql->bindValue($binding, strval($value[0]), \PDO::PARAM_STR);
                        break;
                    case 'lob':
                    case 'large':
                    case 'object':
                    case 'blob':
                        $sql->bindParam($binding, $value[0], \PDO::PARAM_LOB, strlen($value[0]));
                        break;
                    case 'like':
                        $sql->bindValue($binding, '%'.$value[0].'%', \PDO::PARAM_STR);
                        break;
                    default:
                        if (is_int($value[1])) {
                            $sql->bindValue($binding, $value[0], $value[1]);
                        } else {
                            $sql->bindValue($binding, strval($value[0]), \PDO::PARAM_STR);
                        }
                }
            }
        }
        return $sql;
    }
699244
public function query(string $sql, $bind = []): Statement
    {
        $this->operation = 'query';
        $this->params = $bind;
        $this->sql = $sql;
        return $this;
    }
408585
public function bind_and_run( $query, $bindings = [] )
	{
		$new_query = $this->bind_params( $query, $bindings );

		$result = $this->db->query( $new_query );

		if ( $result === false || $this->db->last_error ) {
			throw new QueryException( $new_query, $bindings, new \Exception( $this->db->last_error ) );
		}

		return (array) $result;
	}
239648
public function statement($sql, $bindings = array())
		{
			list($statement, $result) = $this->execute($sql, $bindings);
			return $result;
		}
750472
public function write($query, array $bindings=[], $returnAffected=null)
    {
        $returnAffected = $returnAffected !== null
                          ? $returnAffected
                          : $this->getOption(static::RETURN_LAST_AFFECTED);

        $this->callBeforeListeners('write',[$query, $bindings]);

        if (!$bindings) {
            $rows = $this->writeUnprepared($query);
            $this->callAfterListeners('write',[$query, $bindings]);
            return $returnAffected ? $rows : null;
        }

        $statement = $this->runPrepared($query, $bindings);

        $this->callAfterListeners('write',[$query, $bindings]);

        return $returnAffected ? $statement->rowCount() : null;
    }
1184546
public function pdoQuery($sql = '', $bindWhereParam = [])
    {
        // Check empty query
        if (empty($sql)) {
            self::error('Query is empty..');
        }

        // clean query from white space
        $sql = trim($sql);
        // get operation type
        $operation = explode(' ', $sql);
        // make first word in uppercase
        $operation[0] = strtoupper($operation[0]);

        // set class property with pass value
        $this->sql = $sql;
        // set class statement handler
        $this->STH = $this->prepare($this->sql);

        // check valid sql operation statement
        if (!in_array($operation[0], $this->validOperation)) {
            self::error('invalid operation called in query. use only ' . implode(', ',
                    $this->validOperation) . ' You can have NO SPACE be between ' . implode(', ',
                    $this->validOperation) . ' AND parms');
        }

        // sql query pass with no bind param
        if (count($bindWhereParam) <= 0) {

            // try catch block start
            try {
                // execute pdo statement
                if ($this->STH->execute()) {
                    // get affected rows and set it to class property
                    $this->affectedRows = $this->STH->rowCount();
                    // set pdo result array with class property
                    $this->results = $this->STH->fetchAll();
                    // close pdo cursor
                    $this->STH->closeCursor();
                    // return pdo result
                    return $this;
                } else {
                    self::error($this->STH->errorInfo()); // if not run pdo statement sed error
                }
            } catch (\PDOException $e) {
                self::error($e->getMessage() . ': ' . __LINE__);
            } // end try catch block
        } elseif (count($bindWhereParam) > 0) {  // if query pass with bind param

            $this->data = $bindWhereParam;
            // start binding fields
            // bind pdo param
            $this->_bindPdoParam($bindWhereParam);
            // use try catch block to get pdo error
            try {
                // run pdo statement with bind param
                if ($this->STH->execute()) {
                    // check operation type
                    switch ($operation[0]) {
                        case 'SELECT':
                            // get affected rows by select statement
                            $this->affectedRows = $this->STH->rowCount();
                            // get pdo result array
                            $this->results = $this->STH->fetchAll();
                            // return PDO instance
                            return $this;
                            break;
                        case 'INSERT':
                            // return last insert id
                            $this->lastId = $this->lastInsertId();
                            // return PDO instance
                            return $this;
                            break;
                        case 'UPDATE':
                            // get affected rows
                            $this->affectedRows = $this->STH->rowCount();
                            // return PDO instance
                            return $this;
                            break;
                        case 'DELETE':
                            // get affected rows
                            $this->affectedRows = $this->STH->rowCount();
                            // return PDO instance
                            return $this;
                            break;
                    }
                    // close pdo cursor
                    $this->STH->closeCursor();
                } else {
                    self::error($this->STH->errorInfo());
                }
            } catch (\PDOException $e) {
                self::error($e->getMessage() . ': ' . __LINE__);
            } // end try catch block to get pdo error
        } else {
            self::error('Error Query');
        }
    }
336123
protected function bindParams($query, $sqlParams)
    {
        if (empty($sqlParams)) {
            $sqlParams = [];
        } 
        uksort(
            $sqlParams,
            function ($k1, $k2) {
                return strlen($k1) < strlen($k2);
            }
        );
        foreach ($sqlParams as $key=>$value) {
            if (gettype($value)==="array") {
                $value = array_map(
                    function ($v) {
                        return $this->escape($v);
                    },
                    $value
                );
                $value = "(".implode(",", $value).")";
                $query = str_replace($key, $value, $query);
            } else {
                $query = str_replace($key, $this->escape($value), $query);
            }
        }
        return $query;
    }
332161
function bindAndExecute() {
		$conn = $this->connection;

		if ($conn === null) {
			throw new RuntimeException('bindAndExecute cannot be called on a QueryStatement without a connection.');
		}
		if ($conn instanceof DBMSSQL && $conn->getDriver() === 'dblib' && function_exists('mb_detect_encoding')) {
			return $conn->query($this->__toString());
		}
		if ($conn instanceof DBSQLite) {
			return $conn->query($this->__toString());
		}

		$string = self::embedIdentifiers($this->getString(), array_values($this->identifiers), $conn);

		$result = $conn->prepare($string);
		foreach ($this->getParams() as $key => $value) {
			$pdo_type = PDO::PARAM_STR;
			if (is_int($value)) {
				$pdo_type = PDO::PARAM_INT;
			} elseif (is_null($value)) {
				$pdo_type = PDO::PARAM_NULL;
			} elseif (is_bool($value)) {
				$value = $value ? 1 : 0;
				$pdo_type = PDO::PARAM_INT;
			}
			$result->bindValue($key + 1, $value, $pdo_type);
		}
		$result->execute();
		return $result;
	}