<commit_before>/*-------------------------------------------------------------------------
 *
 *   FILE
 *	pqxx/result.hxx
 *
 *   DESCRIPTION
 *      definitions for the pqxx::result class and support classes.
 *   pqxx::result represents the set of result tuples from a database query
 *   DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/result instead.
 *
 * Copyright (c) 2001-2009, <NAME> <<EMAIL>>
 *
 * See COPYING for copyright license.  If you did not receive a file called
 * COPYING with this source code, please notify the distributor of this mistake,
 * or contact the author.
 *
 *-------------------------------------------------------------------------
 */
#ifndef PQXX_H_RESULT
#define PQXX_H_RESULT

#include "pqxx/compiler-public.hxx"
#include "pqxx/compiler-internal-pre.hxx"

#ifdef PQXX_HAVE_IOS
#include <ios>
#endif

#include <stdexcept>

#include "pqxx/except"
#include "pqxx/strconv"
#include "pqxx/util"

/* Methods tested in eg. self-test program test001 are marked with "//[t1]"
 */

// TODO: Support SQL arrays

namespace pqxx
{
class result;

namespace internal
{
class sql_cursor;

/// Information shared between all copies of a result set
struct PQXX_PRIVATE result_data
{
  /// Underlying libpq-managed result set
  /** @warning This member is duplicated in the result object as a performance
   * shortcut.
   */
  pqxx::internal::pq::PGresult *data;

  /// Frontend/backend protocol version
  int protocol;

  /// Query string that yielded this result
  PGSTD::string query;

  int encoding_code;

  // TODO: Locking for result copy-construction etc. also goes here

  result_data();
  result_data(pqxx::internal::pq::PGresult *,
		int protocol,
		const PGSTD::string &,
		int encoding_code);
  ~result_data();
};

void PQXX_LIBEXPORT freemem_result_data(const result_data *) throw ();
} // namespace internal


namespace internal
{
namespace gate
{
class result_connection;
class result_creation;
class result_sql_cursor;
} // namespace internal::gate
} // namespace internal


/// Query or command result set.
/** This behaves as a container (as defined by the C++ standard library) and
 * provides random access const iterators to iterate over its tuples.  A tuple
 * can also be accessed by indexing a result R by the tuple's zero-based
 * number:
 *
 * @code
 *	for (result::size_type i=0; i < R.size(); ++i) Process(R[i]);
 * @endcode
 *
 * Result sets in libpqxx are lightweight, reference-counted wrapper objects
 * (following the Proxy design pattern) that are small and cheap to copy.  Think
 * of a result object as a "smart pointer" to an underlying result set.
 *
 * @warning The result set that a result object points to is not thread-safe.
 * If you copy a result object, it still refers to the same underlying result
 * set.  So never copy, destroy, query, or otherwise access a result while
 * another thread may be copying, destroying, querying, or otherwise accessing
 * the same result set--even if it is doing so through a different result
 * object!
 */
class PQXX_LIBEXPORT result :
  private internal::PQAlloc<
	const internal::result_data, internal::freemem_result_data>
{
  typedef internal::PQAlloc<
	const internal::result_data, internal::freemem_result_data> super;
public:
  class const_iterator;
  class const_fielditerator;
  class const_reverse_fielditerator;
  class tuple;
  class field;
  typedef unsigned long size_type;
  typedef signed long difference_type;
  typedef tuple reference;
  typedef const_iterator pointer;

  /// Reference to one row in a result.
  /** A tuple represents one row (also called a tuple) in a query result set.
   * It also acts as a container mapping column numbers or names to field
   * values (see below):
   *
   * @code
   *	cout << tuple["date"].c_str() << ": " << tuple["name"].c_str() << endl;
   * @endcode
   *
   * The tuple itself acts like a (non-modifyable) container, complete with its
   * own const_iterator and const_reverse_iterator.
   */
  class PQXX_LIBEXPORT tuple
  {
  public:
    typedef unsigned int size_type;
    typedef signed int difference_type;
    typedef const_fielditerator const_iterator;
    typedef const_iterator iterator;
    typedef field reference;
    typedef const_fielditerator pointer;
    typedef const_reverse_fielditerator const_reverse_iterator;
    typedef const_reverse_iterator reverse_iterator;

    tuple(const result *r, result::size_type i) throw () :
      m_Home(r), m_Index(i), m_Begin(0), m_End(r ? r->columns() : 0) {}
    ~tuple() throw () {} // Yes <NAME>, you're absolutely right[1]

    /**
     * @name Comparison
     */
    //@{
    bool operator==(const tuple &) const throw ();			//[t75]
    bool operator!=(const tuple &rhs) const throw ()			//[t75]
	{ return !operator==(rhs); }
    //@}

    const_iterator begin() const throw ()				//[t82]
	{ return const_iterator(*this, m_Begin); }
    const_iterator end() const throw ()					//[t82]
	{ return const_iterator(*this, m_End); }

    /**
     * @name Field access
     */
    //@{
    reference front() const throw () { return field(*this, m_Begin); }	//[t74]
    reference back() const throw () { return field(*this, m_End-1); }	//[t75]

    const_reverse_fielditerator rbegin() const;				//[t82]
    const_reverse_fielditerator rend() const;				//[t82]

    reference operator[](size_type i) const throw ()			//[t11]
	{ return field(*this, m_Begin+i); }
    reference operator[](int i) const throw ()				//[t2]
	{ return operator[](size_type(i)); }
    reference operator[](const char f[]) const				//[t11]
	{ return at(f); }
    reference operator[](const PGSTD::string &s) const			//[t11]
	{ return operator[](s.c_str()); }
    reference at(size_type) const throw (range_error);			//[t11]
    reference at(int i) const throw (range_error)			//[t11]
	{ return at(size_type(i)); }
    reference at(const char[]) const;					//[t11]
    reference at(const PGSTD::string &s) const				//[t11]
	{ return at(s.c_str()); }
    //@}

    size_type size() const throw () { return m_End-m_Begin; }	       	//[t11]

    void swap(tuple &) throw ();					//[t11]

    result::size_type rownumber() const throw () { return m_Index; }	//[t11]

    /**
     * @name Column information
     */
    //@{
    /// Number of given column (throws exception if it doesn't exist)
    size_type column_number(const PGSTD::string &ColName) const		//[t30]
	{ return column_number(ColName.c_str()); }

    /// Number of given column (throws exception if it doesn't exist)
    size_type column_number(const char[]) const;       			//[t30]

    /// Type of given column
    oid column_type(size_type ColNum) const				//[t7]
	{ return m_Home->column_type(m_Begin+ColNum); }

    /// Type of given column
    oid column_type(int ColNum) const					//[t7]
	{ return column_type(size_type(ColNum)); }

    /// Type of given column
    oid column_type(const PGSTD::string &ColName) const			//[t7]
	{ return column_type(column_number(ColName)); }

    /// Type of given column
    oid column_type(const char ColName[]) const				//[t7]
	{ return column_type(column_number(ColName)); }

    /// What table did this column come from?  Requires PostgreSQL 7.4 C API.
    /** Only defined if the libpqxx library was compiled against a libpq
     * version that supports the @c PQftable function.
     *
     * If you get a link error saying this function is undefined, that must be
     * because libpqxx was compiled against an older version of libpq.  The
     * @c PQftable function first became available in PostgreSQL 7.4.
     */
    oid column_table(size_type ColNum) const				//[t2]
	{ return m_Home->column_table(m_Begin+ColNum); }
    /// What table did this column come from?  Requires PostgreSQL 7.4 C API.
    /** Only defined if the libpqxx library was compiled against a libpq
     * version that supports the @c PQftable function.
     *
     * If you get a link error saying this function is undefined, that must be
     * because libpqxx was compiled against an older version of libpq.  The
     * @c PQftable function first became available in PostgreSQL 7.4.
     */
    oid column_table(int ColNum) const					//[t2]
	{ return column_table(size_type(ColNum)); }
    /// What table did this column come from?  Requires PostgreSQL 7.4 C API.
    /** Only defined if the libpqxx library was compiled against a libpq
     * version that supports the @c PQftable function.
     *
     * If you get a link error saying this function is undefined, that must be
     * because libpqxx was compiled against an older version of libpq.  The
     * @c PQftable function first became available in PostgreSQL 7.4.
     */
    oid column_table(const PGSTD::string &ColName) const		//[t2]
	{ return column_table(column_number(ColName)); }

    /// What column number in its table did this result column come from?
    /** A meaningful answer can be given only if the column in question comes
     * directly from a column in a table.  If the column is computed in any
     * other way, a logic_error will be thrown.
     *
     * @param ColNum a zero-based column number in this result set
     * @return a zero-based column number in originating table
     *
     * Requires libpq from PostgreSQL 7.4 or better, as well as a server version
     * of at least 7.4.
     */
    size_type table_column(size_type ColNum) const			//[t93]
	{ return m_Home->table_column(m_Begin+ColNum); }

    /// What column number in its table did this result column come from?
    size_type table_column(int ColNum) const				//[t93]
	{ return table_column(size_type(ColNum)); }

    /// What column number in its table did this result column come from?
    size_type table_column(const PGSTD::string &ColName) const		//[t93]
	{ return table_column(column_number(ColName)); }
    //@}

    result::size_type num() const { return rownumber(); }		//[t1]

    tuple slice(size_type Begin, size_type End) const;
    tuple slice(int Begin, int End) const
	{ return slice(size_type(Begin), size_type(End)); }

  protected:
    friend class field;<commit_msg>Don't need slice(int, int) after all.  Thanks <NAME>.<commit_after>/*-------------------------------------------------------------------------
 *
 *   FILE
 *	pqxx/result.hxx
 *
 *   DESCRIPTION
 *      definitions for the pqxx::result class and support classes.
 *   pqxx::result represents the set of result tuples from a database query
 *   DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/result instead.
 *
 * Copyright (c) 2001-2009, <NAME> <<EMAIL>>
 *
 * See COPYING for copyright license.  If you did not receive a file called
 * COPYING with this source code, please notify the distributor of this mistake,
 * or contact the author.
 *
 *-------------------------------------------------------------------------
 */
#ifndef PQXX_H_RESULT
#define PQXX_H_RESULT

#include "pqxx/compiler-public.hxx"
#include "pqxx/compiler-internal-pre.hxx"

#ifdef PQXX_HAVE_IOS
#include <ios>
#endif

#include <stdexcept>

#include "pqxx/except"
#include "pqxx/strconv"
#include "pqxx/util"

/* Methods tested in eg. self-test program test001 are marked with "//[t1]"
 */

// TODO: Support SQL arrays

namespace pqxx
{
class result;

namespace internal
{
class sql_cursor;

/// Information shared between all copies of a result set
struct PQXX_PRIVATE result_data
{
  /// Underlying libpq-managed result set
  /** @warning This member is duplicated in the result object as a performance
   * shortcut.
   */
  pqxx::internal::pq::PGresult *data;

  /// Frontend/backend protocol version
  int protocol;

  /// Query string that yielded this result
  PGSTD::string query;

  int encoding_code;

  // TODO: Locking for result copy-construction etc. also goes here

  result_data();
  result_data(pqxx::internal::pq::PGresult *,
		int protocol,
		const PGSTD::string &,
		int encoding_code);
  ~result_data();
};

void PQXX_LIBEXPORT freemem_result_data(const result_data *) throw ();
} // namespace internal


namespace internal
{
namespace gate
{
class result_connection;
class result_creation;
class result_sql_cursor;
} // namespace internal::gate
} // namespace internal


/// Query or command result set.
/** This behaves as a container (as defined by the C++ standard library) and
 * provides random access const iterators to iterate over its tuples.  A tuple
 * can also be accessed by indexing a result R by the tuple's zero-based
 * number:
 *
 * @code
 *	for (result::size_type i=0; i < R.size(); ++i) Process(R[i]);
 * @endcode
 *
 * Result sets in libpqxx are lightweight, reference-counted wrapper objects
 * (following the Proxy design pattern) that are small and cheap to copy.  Think
 * of a result object as a "smart pointer" to an underlying result set.
 *
 * @warning The result set that a result object points to is not thread-safe.
 * If you copy a result object, it still refers to the same underlying result
 * set.  So never copy, destroy, query, or otherwise access a result while
 * another thread may be copying, destroying, querying, or otherwise accessing
 * the same result set--even if it is doing so through a different result
 * object!
 */
class PQXX_LIBEXPORT result :
  private internal::PQAlloc<
	const internal::result_data, internal::freemem_result_data>
{
  typedef internal::PQAlloc<
	const internal::result_data, internal::freemem_result_data> super;
public:
  class const_iterator;
  class const_fielditerator;
  class const_reverse_fielditerator;
  class tuple;
  class field;
  typedef unsigned long size_type;
  typedef signed long difference_type;
  typedef tuple reference;
  typedef const_iterator pointer;

  /// Reference to one row in a result.
  /** A tuple represents one row (also called a tuple) in a query result set.
   * It also acts as a container mapping column numbers or names to field
   * values (see below):
   *
   * @code
   *	cout << tuple["date"].c_str() << ": " << tuple["name"].c_str() << endl;
   * @endcode
   *
   * The tuple itself acts like a (non-modifyable) container, complete with its
   * own const_iterator and const_reverse_iterator.
   */
  class PQXX_LIBEXPORT tuple
  {
  public:
    typedef unsigned int size_type;
    typedef signed int difference_type;
    typedef const_fielditerator const_iterator;
    typedef const_iterator iterator;
    typedef field reference;
    typedef const_fielditerator pointer;
    typedef const_reverse_fielditerator const_reverse_iterator;
    typedef const_reverse_iterator reverse_iterator;

    tuple(const result *r, result::size_type i) throw () :
      m_Home(r), m_Index(i), m_Begin(0), m_End(r ? r->columns() : 0) {}
    ~tuple() throw () {} // Yes Scott Meyers, you're absolutely right[1]

    /**
     * @name Comparison
     */
    //@{
    bool operator==(const tuple &) const throw ();			//[t75]
    bool operator!=(const tuple &rhs) const throw ()			//[t75]
	{ return !operator==(rhs); }
    //@}

    const_iterator begin() const throw ()				//[t82]
	{ return const_iterator(*this, m_Begin); }
    const_iterator end() const throw ()					//[t82]
	{ return const_iterator(*this, m_End); }

    /**
     * @name Field access
     */
    //@{
    reference front() const throw () { return field(*this, m_Begin); }	//[t74]
    reference back() const throw () { return field(*this, m_End-1); }	//[t75]

    const_reverse_fielditerator rbegin() const;				//[t82]
    const_reverse_fielditerator rend() const;				//[t82]

    reference operator[](size_type i) const throw ()			//[t11]
	{ return field(*this, m_Begin+i); }
    reference operator[](int i) const throw ()				//[t2]
	{ return operator[](size_type(i)); }
    reference operator[](const char f[]) const				//[t11]
	{ return at(f); }
    reference operator[](const PGSTD::string &s) const			//[t11]
	{ return operator[](s.c_str()); }
    reference at(size_type) const throw (range_error);			//[t11]
    reference at(int i) const throw (range_error)			//[t11]
	{ return at(size_type(i)); }
    reference at(const char[]) const;					//[t11]
    reference at(const PGSTD::string &s) const				//[t11]
	{ return at(s.c_str()); }
    //@}

    size_type size() const throw () { return m_End-m_Begin; }	       	//[t11]

    void swap(tuple &) throw ();					//[t11]

    result::size_type rownumber() const throw () { return m_Index; }	//[t11]

    /**
     * @name Column information
     */
    //@{
    /// Number of given column (throws exception if it doesn't exist)
    size_type column_number(const PGSTD::string &ColName) const		//[t30]
	{ return column_number(ColName.c_str()); }

    /// Number of given column (throws exception if it doesn't exist)
    size_type column_number(const char[]) const;       			//[t30]

    /// Type of given column
    oid column_type(size_type ColNum) const				//[t7]
	{ return m_Home->column_type(m_Begin+ColNum); }

    /// Type of given column
    oid column_type(int ColNum) const					//[t7]
	{ return column_type(size_type(ColNum)); }

    /// Type of given column
    oid column_type(const PGSTD::string &ColName) const			//[t7]
	{ return column_type(column_number(ColName)); }

    /// Type of given column
    oid column_type(const char ColName[]) const				//[t7]
	{ return column_type(column_number(ColName)); }

    /// What table did this column come from?  Requires PostgreSQL 7.4 C API.
    /** Only defined if the libpqxx library was compiled against a libpq
     * version that supports the @c PQftable function.
     *
     * If you get a link error saying this function is undefined, that must be
     * because libpqxx was compiled against an older version of libpq.  The
     * @c PQftable function first became available in PostgreSQL 7.4.
     */
    oid column_table(size_type ColNum) const				//[t2]
	{ return m_Home->column_table(m_Begin+ColNum); }
    /// What table did this column come from?  Requires PostgreSQL 7.4 C API.
    /** Only defined if the libpqxx library was compiled against a libpq
     * version that supports the @c PQftable function.
     *
     * If you get a link error saying this function is undefined, that must be
     * because libpqxx was compiled against an older version of libpq.  The
     * @c PQftable function first became available in PostgreSQL 7.4.
     */
    oid column_table(int ColNum) const					//[t2]
	{ return column_table(size_type(ColNum)); }
    /// What table did this column come from?  Requires PostgreSQL 7.4 C API.
    /** Only defined if the libpqxx library was compiled against a libpq
     * version that supports the @c PQftable function.
     *
     * If you get a link error saying this function is undefined, that must be
     * because libpqxx was compiled against an older version of libpq.  The
     * @c PQftable function first became available in PostgreSQL 7.4.
     */
    oid column_table(const PGSTD::string &ColName) const		//[t2]
	{ return column_table(column_number(ColName)); }

    /// What column number in its table did this result column come from?
    /** A meaningful answer can be given only if the column in question comes
     * directly from a column in a table.  If the column is computed in any
     * other way, a logic_error will be thrown.
     *
     * @param ColNum a zero-based column number in this result set
     * @return a zero-based column number in originating table
     *
     * Requires libpq from PostgreSQL 7.4 or better, as well as a server version
     * of at least 7.4.
     */
    size_type table_column(size_type ColNum) const			//[t93]
	{ return m_Home->table_column(m_Begin+ColNum); }

    /// What column number in its table did this result column come from?
    size_type table_column(int ColNum) const				//[t93]
	{ return table_column(size_type(ColNum)); }

    /// What column number in its table did this result column come from?
    size_type table_column(const PGSTD::string &ColName) const		//[t93]
	{ return table_column(column_number(ColName)); }
    //@}

    result::size_type num() const { return rownumber(); }		//[t1]

    tuple slice(size_type Begin, size_type End) const;

  protected:
    friend class field;
{'fraction_non_alphanumeric': 0.11894405279736013, 'fraction_numerical': 0.0087995600219989, 'mean_word_length': 3.0837076357697017, 'pattern_counts': {'":': 2, '<': 37, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3358947', 'n_tokens_mistral': 6350, 'n_tokens_neox': 5975, 'n_words': 2156}