#ifndef _SQMYSQL_HANDLE_RESULTSET_HPP_ #define _SQMYSQL_HANDLE_RESULTSET_HPP_ // ------------------------------------------------------------------------------------------------ #include "Handle/Statement.hpp" #include "Base/Buffer.hpp" // ------------------------------------------------------------------------------------------------ #include // ------------------------------------------------------------------------------------------------ namespace SqMod { /* ------------------------------------------------------------------------------------------------ * The structure that holds the data associated with a certain field. */ struct ResBind { public: // -------------------------------------------------------------------------------------------- typedef MYSQL_RES Type; // The managed type. // -------------------------------------------------------------------------------------------- typedef Type* Pointer; // Pointer to the managed type. typedef const Type* ConstPtr; // Constant pointer to the managed type. // -------------------------------------------------------------------------------------------- typedef Type& Reference; // Reference to the managed type. typedef const Type& ConstRef; // Constant reference to the managed type. // -------------------------------------------------------------------------------------------- typedef MYSQL_FIELD FieldType; // Database field type. typedef MYSQL_BIND BindType; // Database bind type. typedef MYSQL_TIME TimeType; // Database time type. typedef MYSQL_ROW RowType; // Database row type. typedef my_bool BoolType; // Database boolean type. // -------------------------------------------------------------------------------------------- typedef std::unordered_map< String, Uint32 > IndexMap; public: // -------------------------------------------------------------------------------------------- BoolType mIsNull; // Allows the database to specify if the field is null. BoolType mError; // Allows the database if errors occured on this field. Buffer mData; // Buffer to store non fundamental data for the field. BindType * mBind; // The associated database bind point handle. TimeType mTime; // Structure used to retrieve time data from database. // -------------------------------------------------------------------------------------------- union { Uint64 mUint64; // Retrieve unsigned integer values from a field. Int64 mInt64; // Retrieve signed integer values from a field. Int32 mInt32[2]; // Retrieve 32 bit signed integer values from a field. Float64 mFloat64; // Retrieve 32 bit floating point values from a field. Float32 mFloat32[2]; // Retrieve 64 bit floating point values from the field. }; public: /* -------------------------------------------------------------------------------------------- * Default constructor. */ ResBind() : mIsNull(0), mError(0), mData(), mBind(nullptr), mTime(), mUint64(0) { /* ... */ } /* -------------------------------------------------------------------------------------------- * Copy constructor. (disabled) */ ResBind(const ResBind & o) = delete; /* -------------------------------------------------------------------------------------------- * Move constructor. (disabled) */ ResBind(ResBind && o) = delete; /* -------------------------------------------------------------------------------------------- * Copy assignment operator. (disabled) */ ResBind & operator = (const ResBind & o) = delete; /* -------------------------------------------------------------------------------------------- * Move assignment operator. (disabled) */ ResBind & operator = (ResBind && o) = delete; /* -------------------------------------------------------------------------------------------- * Retrieve the used buffer. */ CStr GetBuffer() { return mData ? mData.Data() : reinterpret_cast< CStr >(&mUint64); } /* -------------------------------------------------------------------------------------------- * Retrieve the buffer length. */ Ulong GetLength() const { return mBind == nullptr ? 0 : mBind->buffer_length; } /* -------------------------------------------------------------------------------------------- * Configure the output to match the requirements of a certain field. */ void SetOutput(const FieldType & field, BindType * bind); }; /* ------------------------------------------------------------------------------------------------ * The structure that holds the data associated with a certain result-set handle. */ struct ResHnd { public: // -------------------------------------------------------------------------------------------- typedef MYSQL_RES Type; // The managed type. // -------------------------------------------------------------------------------------------- typedef Type* Pointer; // Pointer to the managed type. typedef const Type* ConstPtr; // Constant pointer to the managed type. // -------------------------------------------------------------------------------------------- typedef Type& Reference; // Reference to the managed type. typedef const Type& ConstRef; // Constant reference to the managed type. // -------------------------------------------------------------------------------------------- typedef MYSQL_FIELD FieldType; // Database field type. typedef MYSQL_BIND BindType; // Database bind type. typedef MYSQL_TIME TimeType; // Database time type. typedef MYSQL_ROW RowType; // Database row type. typedef my_bool BoolType; // Database boolean type. // -------------------------------------------------------------------------------------------- typedef std::unordered_map< String, Uint32 > IndexMap; // Name to index association of fields. public: // -------------------------------------------------------------------------------------------- Pointer mPtr; // The managed result-set handle. // -------------------------------------------------------------------------------------------- Uint32 mFieldCount; // Number of fields in the result-set. Ulong * mLengths; // Data length when the result-set came from a connection. FieldType * mFields; // Fields in the results set. ResBind * mBinds; // Bind wrappers. BindType * mMyBinds; // Bind points. RowType mRow; // Row data. // -------------------------------------------------------------------------------------------- ConnRef mConnection; // Associated connection. StmtRef mStatement; // Associated statement. IndexMap mIndexes; // Field names and their associated index. public: /* -------------------------------------------------------------------------------------------- * Default constructor. */ ResHnd(); /* -------------------------------------------------------------------------------------------- * Destructor. */ ~ResHnd(); /* -------------------------------------------------------------------------------------------- * Grab the current error in the associated statement or connection handle. */ void GrabCurrent(); /* -------------------------------------------------------------------------------------------- * Grab the current error in the associated statement or connection handle and throw it. */ #if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC) void ThrowCurrent(CCStr act, CCStr file, Int32 line); #else void ThrowCurrent(CCStr act); #endif // _DEBUG /* -------------------------------------------------------------------------------------------- * Validate the statement handle and field index and throw an error if invalid. */ #if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC) void ValidateField(Uint32 idx, CCStr file, Int32 line) const; #else void ValidateField(Uint32 idx) const; #endif // _DEBUG /* -------------------------------------------------------------------------------------------- * Create the result-set from a Connection. */ void Create(const ConnRef & conn); /* -------------------------------------------------------------------------------------------- * Create the result-set from a Statement. */ void Create(const StmtRef & stmt); /* -------------------------------------------------------------------------------------------- * Returns the current position of the row cursor for the last Next(). */ Uint64 RowIndex() const; /* -------------------------------------------------------------------------------------------- * Returns the number of rows in the result set. */ Uint64 RowCount() const; /* -------------------------------------------------------------------------------------------- * Retrieve the next row from the query. */ bool Next(); /* -------------------------------------------------------------------------------------------- * Seeks to an arbitrary row in a query result set. */ bool SetRowIndex(Uint64 index); }; } // Namespace:: SqMod #endif // _SQMYSQL_HANDLE_RESULTSET_HPP_