// ------------------------------------------------------------------------------------------------ #include "Statement.hpp" #include "Connection.hpp" #include "ResultSet.hpp" // ------------------------------------------------------------------------------------------------ #include #include // ------------------------------------------------------------------------------------------------ namespace SqMod { // ------------------------------------------------------------------------------------------------ SQInteger Statement::Typename(HSQUIRRELVM vm) { static const SQChar name[] = _SC("SqMySQLStatement"); sq_pushstring(vm, name, sizeof(name)); return 1; } // ------------------------------------------------------------------------------------------------ Int32 Statement::Cmp(const Statement & o) const { if (m_Handle == o.m_Handle) { return 0; } else if (m_Handle.HndPtr() > o.m_Handle.HndPtr()) { return 1; } else { return -1; } } // ------------------------------------------------------------------------------------------------ CSStr Statement::ToString() const { // Do we have a valid handle? if (m_Handle) { m_Handle->mQuery.c_str(); } // Default to an empty string return _SC(""); } // ------------------------------------------------------------------------------------------------ Statement::Statement() : m_Handle() { } // ------------------------------------------------------------------------------------------------ Statement::Statement(const ConnHnd & connection, CSStr query) : m_Handle(connection, query) { } // ------------------------------------------------------------------------------------------------ Statement::Statement(const Connection & connection, CSStr query) : m_Handle(connection.GetHnd(), query) { } // ------------------------------------------------------------------------------------------------ Connection Statement::GetConnection() const { // Validate the managed handle m_Handle.Validate(); // Return the requested information return Connection(m_Handle->mConnection); } // ------------------------------------------------------------------------------------------------ void Statement::SetConnection(const Connection & conn) { // Validate the managed handle m_Handle.Validate(); // Perform the requested operation m_Handle->mConnection = conn.GetHnd(); } // ------------------------------------------------------------------------------------------------ Int32 Statement::Execute() { // Validate the managed handle m_Handle.Validate(); // Attempt to bind the parameters if (mysql_stmt_bind_param(m_Handle, m_Handle->mMyBinds)) { THROW_CURRENT(m_Handle, "Cannot bind statement parameters"); } // Attempt to execute the statement else if (mysql_stmt_execute(m_Handle)) { THROW_CURRENT(m_Handle, "Cannot execute statement"); } // Return the number of rows affected by this query return mysql_stmt_affected_rows(m_Handle); } // ------------------------------------------------------------------------------------------------ Uint32 Statement::Insert() { // Validate the managed handle m_Handle.Validate(); // Attempt to bind the parameters if (mysql_stmt_bind_param(m_Handle, m_Handle->mMyBinds)) { THROW_CURRENT(m_Handle, "Cannot bind statement parameters"); } // Attempt to execute the statement else if (mysql_stmt_execute(m_Handle)) { THROW_CURRENT(m_Handle, "Cannot execute statement"); } // Return the identifier of the inserted row return mysql_stmt_insert_id(m_Handle); } // ------------------------------------------------------------------------------------------------ ResultSet Statement::Query() { // Validate the managed handle m_Handle.Validate(); // Attempt to bind the parameters if (mysql_stmt_bind_param(m_Handle, m_Handle->mMyBinds)) { THROW_CURRENT(m_Handle, "Cannot bind statement parameters"); } // Attempt to execute the statement else if (mysql_stmt_execute(m_Handle)) { THROW_CURRENT(m_Handle, "Cannot execute statement"); } // Return the results of this query return ResultSet(ResHnd(m_Handle)); } // ------------------------------------------------------------------------------------------------ void Statement::SetInt8(Uint32 idx, SQInteger val) const { // Validate the managed handle and specified index m_Handle.ValidateIndex(idx); // Attempt to set the input value m_Handle->mBinds[idx].SetInput(MYSQL_TYPE_TINY, &(m_Handle->mMyBinds[idx])); // Assign the value to the input m_Handle->mBinds[idx].mInt64 = ConvTo< Int8 >::From(val); } // ------------------------------------------------------------------------------------------------ void Statement::SetUint8(Uint32 idx, SQInteger val) const { // Validate the managed handle and specified index m_Handle.ValidateIndex(idx); // Attempt to set the input value m_Handle->mBinds[idx].SetInput(MYSQL_TYPE_TINY, &(m_Handle->mMyBinds[idx])); // Assign the value to the input m_Handle->mBinds[idx].mUint64 = ConvTo< Uint8 >::From(val); // Specify that this value is unsigned m_Handle->mMyBinds[idx].is_unsigned = true; } // ------------------------------------------------------------------------------------------------ void Statement::SetInt16(Uint32 idx, SQInteger val) const { // Validate the managed handle and specified index m_Handle.ValidateIndex(idx); // Attempt to set the input value m_Handle->mBinds[idx].SetInput(MYSQL_TYPE_SHORT, &(m_Handle->mMyBinds[idx])); // Assign the value to the input m_Handle->mBinds[idx].mInt64 = ConvTo< Int16 >::From(val); } // ------------------------------------------------------------------------------------------------ void Statement::SetUint16(Uint32 idx, SQInteger val) const { // Validate the managed handle and specified index m_Handle.ValidateIndex(idx); // Attempt to set the input value m_Handle->mBinds[idx].SetInput(MYSQL_TYPE_SHORT, &(m_Handle->mMyBinds[idx])); // Assign the value to the input m_Handle->mBinds[idx].mUint64 = ConvTo< Uint16 >::From(val); // Specify that this value is unsigned m_Handle->mMyBinds[idx].is_unsigned = true; } // ------------------------------------------------------------------------------------------------ void Statement::SetInt32(Uint32 idx, SQInteger val) const { // Validate the managed handle and specified index m_Handle.ValidateIndex(idx); // Attempt to set the input value m_Handle->mBinds[idx].SetInput(MYSQL_TYPE_LONG, &(m_Handle->mMyBinds[idx])); // Assign the value to the input m_Handle->mBinds[idx].mInt64 = ConvTo< Int32 >::From(val); } // ------------------------------------------------------------------------------------------------ void Statement::SetUint32(Uint32 idx, SQInteger val) const { // Validate the managed handle and specified index m_Handle.ValidateIndex(idx); // Attempt to set the input value m_Handle->mBinds[idx].SetInput(MYSQL_TYPE_LONG, &(m_Handle->mMyBinds[idx])); // Assign the value to the input m_Handle->mBinds[idx].mUint64 = ConvTo< Uint32 >::From(val); // Specify that this value is unsigned m_Handle->mMyBinds[idx].is_unsigned = true; } // ------------------------------------------------------------------------------------------------ void Statement::SetInt64(Uint32 idx, SQInteger val) const { // Validate the managed handle and specified index m_Handle.ValidateIndex(idx); // Attempt to set the input value m_Handle->mBinds[idx].SetInput(MYSQL_TYPE_LONGLONG, &(m_Handle->mMyBinds[idx])); // Assign the value to the input m_Handle->mBinds[idx].mInt64 = ConvTo< Int64 >::From(val); } // ------------------------------------------------------------------------------------------------ void Statement::SetUint64(Uint32 idx, SQInteger val) const { // Validate the managed handle and specified index m_Handle.ValidateIndex(idx); // Attempt to set the input value m_Handle->mBinds[idx].SetInput(MYSQL_TYPE_LONGLONG, &(m_Handle->mMyBinds[idx])); // Assign the value to the input m_Handle->mBinds[idx].mUint64 = ConvTo< Uint64 >::From(val); // Specify that this value is unsigned m_Handle->mMyBinds[idx].is_unsigned = true; } // ------------------------------------------------------------------------------------------------ void Statement::SetSLongInt(Uint32 idx, Object & val) const { // Validate the managed handle and specified index m_Handle.ValidateIndex(idx); // Attempt to set the input value m_Handle->mBinds[idx].SetInput(MYSQL_TYPE_LONGLONG, &(m_Handle->mMyBinds[idx])); // Obtain the initial stack size const StackGuard sg; // Push the specified object onto the stack Var< Object >::push(_SqVM, val); // Attempt to get the numeric value inside the specified object if (SQ_FAILED(_SqMod->GetSLongValue(_SqVM, -1, &(m_Handle->mBinds[idx].mInt64)))) { STHROWF("Invalid long integer specified"); } } // ------------------------------------------------------------------------------------------------ void Statement::SetULongInt(Uint32 idx, Object & val) const { // Validate the managed handle and specified index m_Handle.ValidateIndex(idx); // Attempt to set the input value m_Handle->mBinds[idx].SetInput(MYSQL_TYPE_LONGLONG, &(m_Handle->mMyBinds[idx])); // Specify that this value is unsigned m_Handle->mMyBinds[idx].is_unsigned = true; // Obtain the initial stack size const StackGuard sg; // Push the specified object onto the stack Var< Object >::push(_SqVM, val); // Attempt to get the numeric value inside the specified object if (SQ_FAILED(_SqMod->GetULongValue(_SqVM, -1, &(m_Handle->mBinds[idx].mUint64)))) { STHROWF("Invalid long integer specified"); } } // ------------------------------------------------------------------------------------------------ void Statement::SetInteger(Uint32 idx, SQInteger val) const { #ifdef _SQ64 SetInt64(idx, val); #else SetInt32(idx, val); #endif // _SQ64 } // ------------------------------------------------------------------------------------------------ void Statement::SetFloat32(Uint32 idx, SQFloat val) const { // Validate the managed handle and specified index m_Handle.ValidateIndex(idx); // Attempt to set the input value m_Handle->mBinds[idx].SetInput(MYSQL_TYPE_FLOAT, &(m_Handle->mMyBinds[idx])); // Assign the value to the input m_Handle->mBinds[idx].mFloat32[0] = ConvTo< Float32 >::From(val); } // ------------------------------------------------------------------------------------------------ void Statement::SetFloat64(Uint32 idx, SQFloat val) const { // Validate the managed handle and specified index m_Handle.ValidateIndex(idx); // Attempt to set the input value m_Handle->mBinds[idx].SetInput(MYSQL_TYPE_DOUBLE, &(m_Handle->mMyBinds[idx])); // Assign the value to the input m_Handle->mBinds[idx].mFloat64 = ConvTo< Float64 >::From(val); } // ------------------------------------------------------------------------------------------------ void Statement::SetFloat(Uint32 idx, SQFloat val) const { #ifdef SQUSEDOUBLE SetFloat64(idx, val); #else SetFloat32(idx, val); #endif // SQUSEDOUBLE } // ------------------------------------------------------------------------------------------------ void Statement::SetBoolean(Uint32 idx, bool val) const { // Validate the managed handle and specified index m_Handle.ValidateIndex(idx); // Attempt to set the input value m_Handle->mBinds[idx].SetInput(MYSQL_TYPE_TINY, &(m_Handle->mMyBinds[idx])); // Assign the value to the input m_Handle->mBinds[idx].mUint64 = val; } // ------------------------------------------------------------------------------------------------ void Statement::SetDate(Uint32 idx, Object & val) const { // Validate the managed handle and specified index m_Handle.ValidateIndex(idx); // Attempt to set the input value m_Handle->mBinds[idx].SetInput(MYSQL_TYPE_DATE, &(m_Handle->mMyBinds[idx])); // Assign the value to the input SqDateToMySQLTime(val, m_Handle->mBinds[idx].mTime); } // ------------------------------------------------------------------------------------------------ void Statement::SetTime(Uint32 idx, Object & val) const { // Validate the managed handle and specified index m_Handle.ValidateIndex(idx); // Attempt to set the input value m_Handle->mBinds[idx].SetInput(MYSQL_TYPE_TIME, &(m_Handle->mMyBinds[idx])); // Assign the value to the input SqTimeToMySQLTime(val, m_Handle->mBinds[idx].mTime); } // ------------------------------------------------------------------------------------------------ void Statement::SetDatetime(Uint32 idx, Object & val) const { // Validate the managed handle and specified index m_Handle.ValidateIndex(idx); // Attempt to set the input value m_Handle->mBinds[idx].SetInput(MYSQL_TYPE_DATETIME, &(m_Handle->mMyBinds[idx])); // Assign the value to the input SqDatetimeToMySQLTime(val, m_Handle->mBinds[idx].mTime); } // ------------------------------------------------------------------------------------------------ void Statement::SetString(Uint32 idx, CSStr val) const { // Validate the managed handle and specified index m_Handle.ValidateIndex(idx); // Attempt to set the input value m_Handle->mBinds[idx].SetInput(MYSQL_TYPE_STRING, &(m_Handle->mMyBinds[idx]), val, std::strlen(val)); } // ------------------------------------------------------------------------------------------------ void Statement::SetEnum(Uint32 idx, CSStr val) const { // Validate the managed handle and specified index m_Handle.ValidateIndex(idx); // Attempt to set the input value m_Handle->mBinds[idx].SetInput(MYSQL_TYPE_ENUM, &(m_Handle->mMyBinds[idx]), val, std::strlen(val)); } // ------------------------------------------------------------------------------------------------ void Statement::SetSet(Uint32 idx, CSStr val) const { // Validate the managed handle and specified index m_Handle.ValidateIndex(idx); // Attempt to set the input value m_Handle->mBinds[idx].SetInput(MYSQL_TYPE_SET, &(m_Handle->mMyBinds[idx]), val, std::strlen(val)); } // ------------------------------------------------------------------------------------------------ void Statement::SetBlob(Uint32 /*idx*/, Object & /*val*/) const { // TODO... } // ------------------------------------------------------------------------------------------------ void Statement::SetData(Uint32 /*idx*/, Object & /*val*/) const { // TODO... } // ------------------------------------------------------------------------------------------------ void Statement::SetNull(Uint32 idx) const { // Validate the managed handle and specified index m_Handle.ValidateIndex(idx); // Attempt to set the input value m_Handle->mBinds[idx].SetInput(MYSQL_TYPE_NULL, &(m_Handle->mMyBinds[idx])); } } // Namespace:: SqMod