Enable the cursor and returns a statement object to allow using fetch() on it

@author Housseyn Guettaf <ghoucine@gmail.com>

@link   http://phiber.myjetbrains.com/youtrack/issue/core-35

@return \PDOStatement
@throws \Exception
347192
public function cursor()
    {
        static $stmt;
        if (!$stmt) {
            $this->setPrepareParams(array(\PDO::ATTR_CURSOR => \PDO::CURSOR_SCROLL));
            $this->prepFetch();
            $stmt = $this->oosql_stmt;
        }

        return $stmt;
    }
986565
public function execute()
	{
		$pdoStatement = $this->pdo->prepare((string) $this);

		foreach ($this->bindings as $clause => $predicate) {
			foreach ($predicate as $key => $value) {
				$pdoStatement->bindValue(sprintf(':%s%d', $clause, $key + 1), $value, $this->getPdoDataType($value));
			}
		}

		$pdoStatement->execute();

		return new QueryResult($pdoStatement);
	}
850588
public function execute(PDO $pdo)
    {
        try {
            $stmt = $pdo->prepare($this->getSql());
            $this->statementExecute($stmt, $this->getWhereData());
            $this->checkAffected($stmt, new NoRecordsAffectedSelectException());
            $data = $this->fetchData(
                $stmt,
                $this->getFetchFlat(),
                $this->getFetchStyle()
            );
            $this->setData($data ?: $this->getDefaultValue());
            return $this->getData();
        } catch (NoRecordsAffectedException $exc) {
            throw $exc;
        } catch (\Exception $exc) {
            throw new ExecutionErrorException($exc->getMessage());
        }
    }
376212
public function compile()
    {
        // check for the bare minimum
        if ($this->table === false || $this->type === false) {
            throw (new \Exception('Query compilation failure: missing table or type'));
        }
        switch ($this->type) {
            case 'UPDATE':
                return $this->generateUPDATEStatement();
            case 'INSERT':
                return $this->generateINSERTStatement();
            case 'DELETE':
                return $this->generateDELETEStatement();
            default:
                return $this->generateSELECTStatement();
        }
    }
712674
public function fetch(int $fetch_style = \PDO::FETCH_ASSOC, int $cursor_orientation = null, int $cursor_offset = null)
    {
        $this->execute();
        
        return $this->stmt->fetch($fetch_style, $cursor_orientation, $cursor_offset);
    }
98020
public function query() {
    $adapter = $this->getAdapter();
    $sql = $this->getSql();
    // always update offset, since it's most likely not contained in the cache id
    $sql = preg_replace('/OFFSET\s+[0-9]+/i', 'OFFSET '.$this->getRawState(Select::OFFSET), $sql);
    $stmt = $adapter->getDriver()->getConnection()->prepare($sql);
    if (self::$logger->isDebugEnabled()) {
      self::$logger->debug("Execute statement: ".$sql);
      self::$logger->debug($this->getParameters(true));
    }
    return $stmt->execute($this->getParameters(true))->getResource();
  }
818678
public function execute() {
		
		// build the query
		$this->buildQuery();

		// prepare the statement
		$this->Prepared = \Polyfony\Database::handle()->prepare($this->Query);
		
		// marker start (after preparation, otherwise we would not be able to read the query, it wouldn't exist yet!)
		$id_marker = Profiler::setMarker(null, 'database', ['Query'=>$this]);

		// if prepare failed
		if(!$this->Prepared) {
			// throw an exception
			$this->throwExceptionOn('prepare');
		}
		
		// execute the statement
		$this->Success = $this->Prepared->execute($this->Values);
		
		// if execution failed
		if($this->Success === false) {
			// throw an exception
			$this->throwExceptionOn('execute');
		}

		// if a forced type of object has been defined
		$this->Object = $this->Object && $this->Object != 'Record' ? 
			'\Models\\'.$this->Object : 
			'\Models\\'.$this->Table;

		// temporary fix, if we don't have an object class at all
		if($this->Object == '\Models\\') {
			$this->Object = '\Polyfony\\Record';
		}

		// tweak for Microsoft SQL Server and MySQL
		$this->Object = str_replace('"','', $this->Object);
		
		// fetch all results as objects
		$this->Result = $this->Prepared->fetchAll(PDO::FETCH_CLASS, $this->Object);

		// format the result
		$this->formatSelectResult();
		$this->formatUpdateOrDeleteResult();
		$this->formatInsertResult();

		// marker end, release after all manipulation has been done
		Profiler::releaseMarker($id_marker);

		// return whatever result we got
		return $this->Result;
	}
209726
public function fetch()
        {
            try {
                if ($this->values = $this->statement->fetch(\PDO::FETCH_ASSOC)) {
                    return $this->values;
                } else {
                    return false;
                }
            } catch (\PDOException $e) {
                throw new Exception('An error occured while trying to fetch the result: "' . $e->getMessage() . '"');
            }
        }
486440
public function fetch()
    {
        $this->throwIfContextInvalid();

        $this->reloadQueryAdapter();
        $results = $this->activeQuery->fetch();

        $this->resetCurrentQuery();

        if (!is_array($results) && get_class($results) === "WP_Error") {
            throw new Exception(json_encode($results));
        }

        return $this->wrapInEntities($results);
    }
749389
protected function getParser()
    {
        $driver = strtolower(DB::getDriverName());

        if (!in_array($driver, $this->drivers)) {
            throw new Exception('The database driver user is not supported!');
        }

        $class = sprintf('CrestApps\CodeGenerator\DatabaseParsers\%sParser', ucfirst($driver));

        return new $class($this->getTableName(), $this->getDatabaseName(), $this->getLanguages());
    }
159369
public function cursor()
    {
        if (is_null($this->columns)) {
            $this->columns = ['*'];
        }

        $result = $this->connection->query(
            $this->toSql(),
            $this->getBindings()
        );

        while ($row = $result->unbuffered_row()) {
            yield $row;
        }
    }
996236
public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEXT, $cursorOffset = 0)
    {
        // do not try fetching from the statement if it's not expected to contain result
        // in order to prevent exceptional situation
        if ($this->stmt === null || ! $this->result) {
            return false;
        }

        $args      = func_get_args();
        $fetchMode = $fetchMode ?: $this->defaultFetchMode;

        if ($fetchMode === FetchMode::COLUMN) {
            return $this->fetchColumn();
        }

        if (isset(self::$fetchMap[$fetchMode])) {
            return sqlsrv_fetch_array($this->stmt, self::$fetchMap[$fetchMode]) ?: false;
        }

        if (in_array($fetchMode, [FetchMode::STANDARD_OBJECT, FetchMode::CUSTOM_OBJECT], true)) {
            $className = $this->defaultFetchClass;
            $ctorArgs  = $this->defaultFetchClassCtorArgs;

            if (count($args) >= 2) {
                $className = $args[1];
                $ctorArgs  = $args[2] ?? [];
            }

            return sqlsrv_fetch_object($this->stmt, $className, $ctorArgs) ?: false;
        }

        throw new SQLSrvException('Fetch mode is not supported!');
    }
610485
public function getStatementDay()
    {
        if (null === $this->n) {
            $this->n = 1;
        }

        $date = new \DateTime($this->d, new \DateTimeZone('UTC'));

        $date->sub(new \DateInterval(sprintf('P%dD', ($this->p * $this->n) - 1)));
        $start_date = $date->format('Y-m-j');

        $date->add(new \DateInterval(sprintf('P%dD', $this->n)));
        $end_date = $date->format('Y-m-j');

        if (is_array($this->select)) {
            $query = sprintf('%s WHERE %s BETWEEN %s AND %s', $this->select[0], $this->c, $start_date, $end_date);
            $adt = $this->sql->getAdapter();
            $statement = $adt->query($query, $adt::QUERY_MODE_PREPARE);
        } else {
            $select = clone $this->select;
            $select->where(new Between($this->c, $start_date, $end_date));

            $statement = $this->sql->prepareStatementForSqlObject($select);
        }

        return $statement;
    }
431436
public function prepare()
    {
        if (null === $this->statement) {
            $this->statement = $this->db->prepare($this->getSql());
        }

        return $this;
    }
1087612
public final function open() : Connection
   {

      if ( $this->isOpen() )
      {
         return $this;
      }

      $attrSupport       = $this->_driver->getAttributeSupport();
      $definedAttributes = $this->_driver->getDefinedAttributes();


      $dsn  = $this->_driver->getType() . ':';
      $dsnC = 0;
      $user = null;
      $pass = null;
      $sql  = [];
      $opts = [];

      foreach( $definedAttributes as $attrName => $attrValue )
      {

         $attrDesc = $attrSupport->get( $attrName );

         if ( null === $attrDesc ) { continue; }

         switch ( $attrDesc->getType() )
         {

            case Type::DSN_PART:
               if ( $dsnC < 1 )
               {
                  $dsnC++;
               }
               else
               {
                  $dsn .= $attrSupport->getDSNAttributeSeparator();
               }
               if ( $attrDesc->useNameInDSN() )
               {
                  $dsn .= $attrName . $attrSupport->getDSNKeyValueSeparator();
               }
               $dsn .= $attrValue;
               break;

            case Type::USERNAME_PARAM:
               $user = $attrValue;
               break;

            case Type::PASSWORD_PARAM:
               $pass = $attrValue;
               break;

            case Type::OPTION_PARAM:
               $opts[ $attrName ] = $attrValue;
               break;

            #case Type::INIT_SQL:
            default:
               if ( 'charset' === $attrName )
               {
                  $sql[] = 'SET NAMES ' . $attrValue;
                  break;
               }
               $sql[] = $attrValue;
               break;

         }

      }

      try
      {
         if ( ! isset( $opts[ \PDO::ATTR_ERRMODE ] ) )
         {
            $opts[ \PDO::ATTR_ERRMODE ] = \PDO::ERRMODE_EXCEPTION;
         }
         if ( $this->_driver->getType() === 'sqlite' || ( null === $user && null === $pass ) )
         {
            $this->_pdo = new \PDO( $dsn, null, null, $opts );
         }
         else
         {
            $this->_pdo = new \PDO( $dsn, $user, $pass, $opts );
         }
      }
      catch ( \Throwable $ex )
      {
         throw new ConnectionException( $this->_driver, 'Connection init fails!', 256, $ex );
      }

      if ( 0 < \count( $sql ) )
      {

         foreach ( $sql as $sqlString )
         {
            try { $this->_pdo->exec( $sqlString ); }
            catch ( \Throwable $ex )
            {
               throw new QueryException(
                  $this->_driver, $sqlString, [], 'Can not call the initial query!', 256, $ex
               );
            }
         }

      }

      return $this;

   }
747657
public function selectOne()
    {
        $this->setLimit(1);

        $query = 'SELECT ' . $this->getQueryFields() . ' FROM ' . $this->getTable() . ' ' . $this->getQueryWhere() . ' ' . $this->getQueryOrderBy() . ' ' . $this->getQueryLimit();

        $statement = $this->db->prepare($query);
        $statement->execute($this->binds);

        $this->clear();

        if ($statement->rowCount() === 0) {
            throw new ExceptionNoData('No data for current query! (query: ' . $query . ', bind: ' . json_encode($this->binds) . ')', 10001);
        }

        //~ Create new object, set data & save it in cache
        return $this->newDataInstance($statement->fetchObject(), true);
    }
1248338
public function query($statement, ...$fetch): PDOStatement
    {
        $this->connect();

        $statement = DBHelper::replaceTablePrefix($statement, $this->tablePrefix, $this->prefixPlaceholder);

        // trigger before event
        $this->fire(self::BEFORE_EXECUTE, [$statement]);

        $sth = $this->pdo->query($statement, ...$fetch);

        // trigger after event
        $this->fire(self::AFTER_EXECUTE, [$statement]);

        return $sth;
    }