types::Variant execute( const types::Variant& i) const { const CustomDataValue* cv = i.customref(); const CustomDataType* dt = cv->type(); CustomDataType::CustomDataValueMethod method = dt->getMethod( m_name); if (!method) throw std::logic_error( "internal: calling undefined method"); return method( *cv, m_arg); }
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( ) ) + "'" ); } }