Database: handle more possible datatype exceptions
Fixes https://gitlab.com/kicad/code/kicad/-/issues/16090
This commit is contained in:
parent
35edd84269
commit
44374c661f
|
@ -444,7 +444,16 @@ bool DATABASE_CONNECTION::SelectOne( const std::string& aTable,
|
||||||
case SQL_DECIMAL:
|
case SQL_DECIMAL:
|
||||||
case SQL_NUMERIC:
|
case SQL_NUMERIC:
|
||||||
{
|
{
|
||||||
aResult[column] = fmt::format( "{:G}", results.get<double>( i ) );
|
try
|
||||||
|
{
|
||||||
|
aResult[column] = fmt::format( "{:G}", results.get<double>( i ) );
|
||||||
|
}
|
||||||
|
catch( nanodbc::null_access_error& e )
|
||||||
|
{
|
||||||
|
// Column was empty (null)
|
||||||
|
aResult[column] = std::string();
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -540,43 +549,92 @@ bool DATABASE_CONNECTION::SelectAll( const std::string& aTable, const std::strin
|
||||||
|
|
||||||
timer.Stop();
|
timer.Stop();
|
||||||
|
|
||||||
try
|
auto handleException =
|
||||||
{
|
[&]( std::runtime_error& aException, const std::string& aExtraContext = "" )
|
||||||
while( results.next() )
|
|
||||||
{
|
|
||||||
ROW result;
|
|
||||||
|
|
||||||
for( short j = 0; j < results.columns(); ++j )
|
|
||||||
{
|
{
|
||||||
std::string column = toUTF8( results.column_name( j ) );
|
m_lastError = aException.what();
|
||||||
|
std::string extra = aExtraContext.empty() ? "" : ": " + aExtraContext;
|
||||||
|
wxLogTrace( traceDatabase,
|
||||||
|
wxT( "Exception while parsing result %d from SelectAll: %s%s" ),
|
||||||
|
aResults.size(), m_lastError, extra );
|
||||||
|
};
|
||||||
|
|
||||||
switch( results.column_datatype( j ) )
|
while( results.next() )
|
||||||
{
|
{
|
||||||
case SQL_DOUBLE:
|
short columnCount = 0;
|
||||||
case SQL_FLOAT:
|
ROW result;
|
||||||
case SQL_REAL:
|
|
||||||
case SQL_DECIMAL:
|
try
|
||||||
case SQL_NUMERIC:
|
{
|
||||||
|
columnCount = results.columns();
|
||||||
|
}
|
||||||
|
catch( nanodbc::database_error& e )
|
||||||
|
{
|
||||||
|
handleException( e );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for( short j = 0; j < columnCount; ++j )
|
||||||
|
{
|
||||||
|
std::string column;
|
||||||
|
std::string columnExtraDbgInfo;
|
||||||
|
int datatype = SQL_UNKNOWN_TYPE;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
column = toUTF8( results.column_name( j ) );
|
||||||
|
datatype = results.column_datatype( j );
|
||||||
|
columnExtraDbgInfo = fmt::format( "column index {}, name '{}', type {}", j, column,
|
||||||
|
datatype );
|
||||||
|
}
|
||||||
|
catch( nanodbc::index_range_error& e )
|
||||||
|
{
|
||||||
|
handleException( e, columnExtraDbgInfo );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch( datatype )
|
||||||
|
{
|
||||||
|
case SQL_DOUBLE:
|
||||||
|
case SQL_FLOAT:
|
||||||
|
case SQL_REAL:
|
||||||
|
case SQL_DECIMAL:
|
||||||
|
case SQL_NUMERIC:
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
result[column] = fmt::format( "{:G}", results.get<double>( j ) );
|
result[column] = fmt::format( "{:G}", results.get<double>( j ) );
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
catch( nanodbc::null_access_error& e )
|
||||||
|
{
|
||||||
|
// Column was empty (null)
|
||||||
|
result[column] = std::string();
|
||||||
|
}
|
||||||
|
catch( std::runtime_error& e )
|
||||||
|
{
|
||||||
|
handleException( e, columnExtraDbgInfo );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
result[column] = toUTF8( results.get<nanodbc::string>( j,
|
result[column] = toUTF8( results.get<nanodbc::string>( j,
|
||||||
NANODBC_TEXT( "" ) ) );
|
NANODBC_TEXT( "" ) ) );
|
||||||
}
|
}
|
||||||
|
catch( std::runtime_error& e )
|
||||||
|
{
|
||||||
|
handleException( e, columnExtraDbgInfo );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
aResults.emplace_back( std::move( result ) );
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
catch( nanodbc::database_error& e )
|
aResults.emplace_back( std::move( result ) );
|
||||||
{
|
|
||||||
m_lastError = e.what();
|
|
||||||
wxLogTrace( traceDatabase, wxT( "Exception while parsing results from SelectAll: %s" ),
|
|
||||||
m_lastError );
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wxLogTrace( traceDatabase, wxT( "SelectAll from %s completed in %0.1f ms" ), aTable,
|
wxLogTrace( traceDatabase, wxT( "SelectAll from %s completed in %0.1f ms" ), aTable,
|
||||||
|
|
|
@ -551,8 +551,17 @@ LIB_SYMBOL* SCH_DATABASE_PLUGIN::loadSymbolFromRow( const wxString& aSymbolName,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString value( std::any_cast<std::string>( aRow.at( mapping.column ) ).c_str(),
|
std:: string strValue;
|
||||||
wxConvUTF8 );
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
strValue = std::any_cast<std::string>( aRow.at( mapping.column ) );
|
||||||
|
}
|
||||||
|
catch( std::bad_any_cast& e )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
wxString value( strValue.c_str(), wxConvUTF8 );
|
||||||
|
|
||||||
if( mapping.name == wxT( "Value" ) )
|
if( mapping.name == wxT( "Value" ) )
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue