virtual types::Variant execute( const types::Variant& i) const
         {return types::Variant( i.todouble());}
void Object::constructor( const types::Variant& val)
{
	switch (val.type())
	{
		case types::Variant::Custom:
		{
			types::Variant baseval;
			try
			{
				if (val.customref()->getBaseTypeValue( baseval)
				&&  baseval.type() != types::Variant::Custom)
				{
					constructor( baseval);
					break;
				}
			}
			catch (const std::runtime_error& e)
			{
				throw std::runtime_error( std::string("cannot convert value to base type for binding: ") + e.what());
			}
			constructor( val.tostring());
		}
		case types::Variant::Timestamp:
		{
			types::DateTime dt( val.totimestamp());
			if (dt.subtype() == types::DateTime::YYYYMMDD)
			{
				m_obj = PyDate_FromDate( dt.year(), dt.month(), dt.day());
				if (!m_obj) THROW_ON_ERROR( "failed to convert to python Date");
			}
			else
			{
				m_obj = PyDateTime_FromDateAndTime( dt.year(), dt.month(), dt.day(), dt.hour(), dt.minute(), dt.second(), dt.usecond());
				if (!m_obj) THROW_ON_ERROR( "failed to convert to python DateTime");
			}
			break;
		}
		case types::Variant::BigNumber:
		{
			std::string strval = val.tostring();
			if (val.bignumref()->scale() <= 0)
			{
				char* end = 0;
				m_obj = PyLong_FromString( const_cast<char*>(strval.c_str()), &end, 10);
				if (!m_obj) THROW_ON_ERROR( "failed to convert to big number (Long)");
				else if (end != strval.c_str()+strval.size())
				{
					Py_DECREF( m_obj);
					throw std::runtime_error( "superfluous characters at end of big number string");
				}
			}
			else
			{
				m_obj = PyBytes_FromStringAndSize( strval.c_str(), strval.size());
				if (!m_obj) THROW_ON_ERROR( "failed to convert to big number (fixed point number) as string");
			}
			break;
		}
		case types::Variant::Null:
			m_obj = Py_None;
			Py_INCREF( m_obj);
		break;
		case types::Variant::Int:
			m_obj = PyLong_FromLong( val.toint());
			if (!m_obj) THROW_ON_ERROR( "failed to convert to python long integer");
		break;
		case types::Variant::UInt:
			m_obj = PyLong_FromUnsignedLong( val.touint());
			if (!m_obj) THROW_ON_ERROR( "failed to convert to python unsigned long integer");
		break;
		case types::Variant::Bool:
			m_obj = PyBool_FromLong( val.tobool()?1:0);
		break;
		case types::Variant::Double:
			m_obj = PyFloat_FromDouble( val.todouble());
			if (!m_obj) THROW_ON_ERROR( "failed to convert to python double precision floating point value");
		break;
		case types::Variant::String:
			m_obj = PyUnicode_FromStringAndSize( val.charptr(), val.charsize());
			if (!m_obj) THROW_ON_ERROR( "failed to convert to python unicode string");
		break;
		default:
			throw std::runtime_error("try to get object for non atomic value");
	}
}
void SQLiteStatement::bindVariant( const unsigned int idx, const types::Variant &value )
{
	switch (value.type())
	{
		case types::Variant::Null:
			m_rc = wrap_sqlite3_bind_null( m_stm, (int)idx);
			break;
			
		case types::Variant::Bool:
			m_rc = wrap_sqlite3_bind_int( m_stm, (int)idx, value.tobool());
			break;
			
		case types::Variant::Int:
			if( value.data( ).value.Int <= std::numeric_limits<signed int>::max( ) && value.data( ).value.Int >= std::numeric_limits<signed int>::min( ) ) {
				m_rc = wrap_sqlite3_bind_int( m_stm, (int)idx, (signed int)value.toint());
			} else {
				m_rc = wrap_sqlite3_bind_int64( m_stm, (int)idx, value.toint());
			}
			break;
			
		case types::Variant::UInt:
			if( value.data( ).value.UInt <= (unsigned int)std::numeric_limits<signed int>::max( ) ) {
				m_rc = wrap_sqlite3_bind_int( m_stm, (int)idx, (signed int)value.toint());
			} else if ( value.data( ).value.UInt <= (_WOLFRAME_UINTEGER)std::numeric_limits<sqlite3_int64>::max( ) ) {
				m_rc = wrap_sqlite3_bind_int64( m_stm, (int)idx, value.toint());
			} else {
				m_data.push_back( value.tostring());
				m_rc = wrap_sqlite3_bind_text( m_stm, (int)idx, m_data.back().c_str(), m_data.back().size(), SQLITE_STATIC);
			}
			break;
			
		case types::Variant::Double:
			m_rc = wrap_sqlite3_bind_double( m_stm, (int)idx, value.todouble());
			break;
			
		case types::Variant::String:
			m_rc = wrap_sqlite3_bind_text( m_stm, (int)idx, value.charptr(), value.charsize(), SQLITE_STATIC);
			break;
			
		case types::Variant::Timestamp:
		{
			m_data.push_back( types::DateTime( value.totimestamp()).tostring( types::DateTime::StringFormat::ExtendedISOdateTime));
			m_rc = wrap_sqlite3_bind_text( m_stm, (int)idx, m_data.back().c_str(), m_data.back().size(), SQLITE_STATIC);
			break;
		}
		case types::Variant::BigNumber:
		{
			m_data.push_back( value.tostring());
			m_rc = wrap_sqlite3_bind_text( m_stm, (int)idx, m_data.back().c_str(), m_data.back().size(), SQLITE_STATIC);
			break;
		}
		case types::Variant::Custom:
		{
			types::Variant baseval;
			try
			{
				if (value.customref()->getBaseTypeValue( baseval)
				&&  baseval.type() != types::Variant::Custom)
				{
					bindVariant( idx, baseval);
					break;
				}
			}
			catch (const std::runtime_error& e)
			{
				throw std::runtime_error( std::string("cannot convert value to base type for binding: ") + e.what());
			}
			bindVariant( idx, value.tostring());
			break;
		}
		default:
			throw std::logic_error( "Binding unknown type '" + std::string( value.typeName( ) ) + "'" );
	}
}