#ifndef _SQSQLITE_PARAMETER_HPP_ #define _SQSQLITE_PARAMETER_HPP_ // ------------------------------------------------------------------------------------------------ #include "Handle/Statement.hpp" // ------------------------------------------------------------------------------------------------ #include // ------------------------------------------------------------------------------------------------ namespace SqMod { /* ------------------------------------------------------------------------------------------------ * Used to manage and interact with parameters from a database statement. */ class Parameter { // -------------------------------------------------------------------------------------------- friend class Statement; private: // -------------------------------------------------------------------------------------------- Int32 m_Index; // The index of the managed parameter. StmtRef m_Handle; // Reference to the managed statement. protected: /* -------------------------------------------------------------------------------------------- * Validate the managed statement handle and throw an error if invalid. */ #if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC) void Validate(CCStr file, Int32 line) const; #else void Validate() const; #endif // _DEBUG /* -------------------------------------------------------------------------------------------- * Validate the managed statement handle and throw an error if invalid. */ #if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC) void ValidateCreated(CCStr file, Int32 line) const; #else void ValidateCreated() const; #endif // _DEBUG /* -------------------------------------------------------------------------------------------- * Validate the managed statement handle and throw an error if invalid. */ #if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC) const StmtRef & GetValid(CCStr file, Int32 line) const; #else const StmtRef & GetValid() const; #endif // _DEBUG /* -------------------------------------------------------------------------------------------- * Validate the managed statement handle and throw an error if invalid. */ #if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC) const StmtRef & GetCreated(CCStr file, Int32 line) const; #else const StmtRef & GetCreated() const; #endif // _DEBUG /* -------------------------------------------------------------------------------------------- * Validate the statement reference and parameter index, and throw an error if they're invalid. */ #if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC) void ValidateParam(Int32 idx, CCStr file, Int32 line) const; #else void ValidateParam(Int32 idx) const; #endif // _DEBUG /* -------------------------------------------------------------------------------------------- * Modify the index to the specified value. */ void SetIndex(Int32 idx) { // Assign the index with a failsafe to invalid on error AutoAssign< Int32 > aa(m_Index, -1, idx); // Validate the obtained parameter index SQMOD_VALIDATE_PARAM(*this, idx); // Don't fall back to the invalid index anymore aa.Set(idx); } /* -------------------------------------------------------------------------------------------- * Modify the index to the specified value. */ void SetIndex(CSStr name) { SetIndex(sqlite3_bind_parameter_index(SQMOD_GET_CREATED(*this)->mPtr, name)); } /* -------------------------------------------------------------------------------------------- * Modify the index to the specified value. */ void SetIndex(const Object & param); public: /* -------------------------------------------------------------------------------------------- * Default constructor (null). */ Parameter() : m_Index(0), m_Handle() { /* ... */ } /* -------------------------------------------------------------------------------------------- * No parameter constructor. */ Parameter(const StmtRef & stmt) : m_Index(0), m_Handle(stmt) { /* ... */ } /* -------------------------------------------------------------------------------------------- * Index constructor. */ Parameter(const StmtRef & stmt, Int32 idx) : m_Index(idx), m_Handle(stmt) { SQMOD_VALIDATE_PARAM(*this, m_Index); } /* -------------------------------------------------------------------------------------------- * Name constructor. */ Parameter(const StmtRef & stmt, CSStr name) : m_Index(stmt ? sqlite3_bind_parameter_index(stmt->mPtr, name) : 0), m_Handle(stmt) { SQMOD_VALIDATE_PARAM(*this, m_Index); } /* -------------------------------------------------------------------------------------------- * Dynamic constructor. */ Parameter(const StmtRef & stmt, const Object & param) : m_Index(0), m_Handle(stmt) { if (!m_Handle) { STHROWF("Invalid SQLite statement reference"); } // Extract the index SetIndex(param); } /* -------------------------------------------------------------------------------------------- * Copy constructor. */ Parameter(const Parameter & o) = default; /* -------------------------------------------------------------------------------------------- * Move constructor. */ Parameter(Parameter && o) = default; /* -------------------------------------------------------------------------------------------- * Copy assignment operator. */ Parameter & operator = (const Parameter & o) = default; /* -------------------------------------------------------------------------------------------- * Move assignment operator. */ Parameter & operator = (Parameter && o) = default; /* -------------------------------------------------------------------------------------------- * Perform an equality comparison between two parameter indexes. */ bool operator == (const Parameter & o) const { return (m_Index == o.m_Index); } /* -------------------------------------------------------------------------------------------- * Perform an inequality comparison between two parameter indexes. */ bool operator != (const Parameter & o) const { return (m_Index != o.m_Index); } /* -------------------------------------------------------------------------------------------- * Implicit conversion to boolean for use in boolean operations. */ operator bool () const { return m_Index >= 0; } /* -------------------------------------------------------------------------------------------- * Used by the script engine to compare two instances of this type. */ Int32 Cmp(const Parameter & o) const { if (m_Index == o.m_Index) { return 0; } else if (m_Index > o.m_Index) { return 1; } else { return -1; } } /* -------------------------------------------------------------------------------------------- * Used by the script engine to convert an instance of this type to a string. */ CSStr ToString() const { CSStr val = nullptr; // Can we attempt to return the parameter name? if (m_Handle && m_Index) { val = sqlite3_bind_parameter_name(m_Handle->mPtr, m_Index); } else { val = ToStrF(_SC("%d"), m_Index); } // Return the value if valid return val ? val : _SC(""); } /* -------------------------------------------------------------------------------------------- * Used by the script engine to retrieve the name from instances of this type. */ static SQInteger Typename(HSQUIRRELVM vm); /* -------------------------------------------------------------------------------------------- * See whether this statement is valid. */ bool IsValid() const { return m_Handle; // An invalid statement means an invalid parameter } /* -------------------------------------------------------------------------------------------- * Return the number of active references to this statement handle. */ Uint32 GetRefCount() const { return m_Handle.Count(); } /* -------------------------------------------------------------------------------------------- * Retrieve the associated parameter index. */ Int32 GetIndex() const { return m_Index; } /* -------------------------------------------------------------------------------------------- * Retrieve the associated database statement. */ Object GetStatement() const; /* -------------------------------------------------------------------------------------------- * Retrieve the associated database connection. */ Object GetConnection() const; /* -------------------------------------------------------------------------------------------- * Retrieve the name of the referenced parameter. */ CSStr GetName() const { return sqlite3_bind_parameter_name(SQMOD_GET_CREATED(*this)->mPtr, m_Index); } /* -------------------------------------------------------------------------------------------- * Release the reference to the associated database statement and parameter index. */ void Release() { m_Handle.Reset(); m_Index = 0; } /* -------------------------------------------------------------------------------------------- * Attempt to bind a dynamic value at the referenced parameter index. */ void SetValue(const Object & value); /* -------------------------------------------------------------------------------------------- * Attempt to bind a boolean value at the referenced parameter index. */ void SetBool(bool value); /* -------------------------------------------------------------------------------------------- * Attempt to bind a character value at the referenced parameter index. */ void SetChar(SQInteger value); /* -------------------------------------------------------------------------------------------- * Attempt to bind a native integer value at the referenced parameter index. */ void SetInteger(SQInteger value); /* -------------------------------------------------------------------------------------------- * Attempt to bind a signed 8 bit integer value at the referenced parameter index. */ void SetInt8(SQInteger value); /* -------------------------------------------------------------------------------------------- * Attempt to bind an unsigned 8 bit integer value at the referenced parameter index. */ void SetUint8(SQInteger value); /* -------------------------------------------------------------------------------------------- * Attempt to bind a signed 16 bit integer value at the referenced parameter index. */ void SetInt16(SQInteger value); /* -------------------------------------------------------------------------------------------- * Attempt to bind an unsigned 16 bit integer value at the referenced parameter index. */ void SetUint16(SQInteger value); /* -------------------------------------------------------------------------------------------- * Attempt to bind a signed 32 bit integer value at the referenced parameter index. */ void SetInt32(SQInteger value); /* -------------------------------------------------------------------------------------------- * Attempt to bind an unsigned 32 bit integer value at the referenced parameter index. */ void SetUint32(SQInteger value); /* -------------------------------------------------------------------------------------------- * Attempt to bind a signed 64 bit integer value at the referenced parameter index. */ void SetInt64(const Object & value); /* -------------------------------------------------------------------------------------------- * Attempt to bind an unsigned 64 bit integer value at the referenced parameter index. */ void SetUint64(const Object & value); /* -------------------------------------------------------------------------------------------- * Attempt to bind a native floating point value at the referenced parameter index. */ void SetFloat(SQFloat value); /* -------------------------------------------------------------------------------------------- * Attempt to bind a 32 bit floating point value at the referenced parameter index. */ void SetFloat32(SQFloat value); /* -------------------------------------------------------------------------------------------- * Attempt to bind a 64 bit floating point value at the referenced parameter index. */ void SetFloat64(SQFloat value); /* -------------------------------------------------------------------------------------------- * Attempt to bind a string value at the referenced parameter index. */ void SetString(CSStr value); /* -------------------------------------------------------------------------------------------- * Attempt to bind a string value at the referenced parameter index. */ void SetStringEx(CSStr value, Int32 length); /* -------------------------------------------------------------------------------------------- * Attempt to bind a zeroed blob value at the referenced parameter index. */ void SetZeroBlob(SQInteger size); /* -------------------------------------------------------------------------------------------- * Attempt to bind a blob value at the referenced parameter index. */ void SetBlob(const Object & value); /* -------------------------------------------------------------------------------------------- * Attempt to bind a buffer value at the referenced parameter index. */ void SetData(const Object & value); /* -------------------------------------------------------------------------------------------- * Attempt to bind a date value at the referenced parameter index. */ void SetDate(const Object & value); /* -------------------------------------------------------------------------------------------- * Attempt to bind a date value at the referenced parameter index. */ void SetDateEx(SQInteger year, SQInteger month, SQInteger day); /* -------------------------------------------------------------------------------------------- * Attempt to bind a time value at the referenced parameter index. */ void SetTime(const Object & value); /* -------------------------------------------------------------------------------------------- * Attempt to bind a time value at the referenced parameter index. */ void SetTimeEx(SQInteger hour, SQInteger minute, SQInteger second); /* -------------------------------------------------------------------------------------------- * Attempt to bind a date-time value at the referenced parameter index. */ void SetDatetime(const Object & value); /* -------------------------------------------------------------------------------------------- * Attempt to bind a date-time value at the referenced parameter index. */ void SetDatetimeEx(SQInteger year, SQInteger month, SQInteger day, SQInteger hour, SQInteger minute, SQInteger second); /* -------------------------------------------------------------------------------------------- * Attempt to bind the current timestamp at the referenced parameter index. */ void SetNow(); /* -------------------------------------------------------------------------------------------- * Attempt to bind a null value at the referenced parameter index. */ void SetNull(); /* -------------------------------------------------------------------------------------------- * Attempt to bind a string value at the referenced parameter index. */ static SQInteger SetStringF(HSQUIRRELVM vm); }; } // Namespace:: SqMod #endif // _SQSQLITE_PARAMETER_HPP_