/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /************************************************************************* * * Effective License of whole file: * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License version 2.1, as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * * Parts "Copyright by Sun Microsystems, Inc" prior to August 2011: * * The Contents of this file are made available subject to the terms of * the GNU Lesser General Public License Version 2.1 * * Copyright: 2000 by Sun Microsystems, Inc. * * Contributor(s): Joerg Budischewski * * All parts contributed on or after August 2011: * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. *
************************************************************************/
using com::sun::star::sdbc::SQLException; using com::sun::star::sdbc::XStatement; using com::sun::star::sdbc::XConnection; using com::sun::star::sdbc::XPreparedStatement; using com::sun::star::sdbc::XParameters; using com::sun::star::sdbc::XResultSet; using com::sun::star::sdbc::XRow;
using com::sun::star::sdbcx::XColumnsSupplier;
using com::sun::star::uno::UNO_QUERY; using com::sun::star::uno::UNO_QUERY_THROW; using com::sun::star::uno::Reference; using com::sun::star::uno::Sequence; using com::sun::star::uno::XInterface; using com::sun::star::uno::Any;
using com::sun::star::container::XEnumeration; using com::sun::star::container::XEnumerationAccess;
namespace pq_sdbc_driver
{
OUString concatQualified( std::u16string_view a, std::u16string_view b)
{ return OUString::Concat(a) + "." + b;
}
OString y = iOUStringToOString( value, settings );
OStringBuffer strbuf( y.getLength() * 2 + 2 ); int error; int len = PQescapeStringConn(settings->pConnection, const_cast<char*>(strbuf.getStr()), y.getStr() , y.getLength(), &error ); if ( error )
{ char *errstr = PQerrorMessage(settings->pConnection); // As of PostgreSQL 9.1, the only possible errors "involve invalid multibyte encoding" // According to https://www2.opengroup.org/ogsys/jsp/publications/PublicationDetails.jsp?publicationid=11216 // (X/Open SQL CLI, March 1995, ISBN: 1-85912-081-4, X/Open Document Number: C451) // 22018 is for "Invalid character value" and seems to be the best match. // We have no good XInterface Reference to pass here, so just give NULL throw SQLException(OUString(errstr, strlen(errstr), ConnectionSettings::encoding),
nullptr,
u"22018"_ustr,
-1,
Any());
}
strbuf.setLength( len ); // Previously here RTL_TEXTENCODING_ASCII_US; as we set the PostgreSQL client_encoding to UTF8, // we get UTF8 here, too. I'm not sure why it worked well before...
buf.append( OStringToOUString( strbuf, RTL_TEXTENCODING_UTF8 ) );
}
TransactionGuard::~TransactionGuard()
{ try
{ if( ! m_commited )
m_stmt->executeUpdate( getStatics().ROLLBACK );
} catch( css::uno::Exception & )
{ // ignore, we are within a dtor
}
disposeNoThrow( m_stmt );
}
bool isWhitespace( sal_Unicode c )
{ return' ' == c || 9 == c || 10 == c || 13 == c;
}
OUString extractTableFromInsert( std::u16string_view sql )
{
OUString ret;
size_t i = 0; while (i < sql.size() && isWhitespace(sql[i])) { i++; }
if( o3tl::matchIgnoreAsciiCase(sql, u"insert", i) )
{
i += 6; while (i < sql.size() && isWhitespace(sql[i])) { i++; } if( o3tl::matchIgnoreAsciiCase(sql, u"into", i) )
{
i +=4; while (i < sql.size() && isWhitespace(sql[i])) { i++; } int start = i; bool quote = (sql[i] == '"'); for( i++ ; i < sql.size() ; i ++ )
{ if( quote && sql[i] == '"' )
{ while (i < sql.size() && isWhitespace(sql[i])) { i++; } if( '.' == sql[i] )
{ while (i < sql.size() && isWhitespace(sql[i])) { i++; } if( '"' == sql[i] )
{ // the second part of the table name does not use quotes // parse on
quote = false;
}
} else
{ // end quoted name, ok break;
}
} else
{ if( isWhitespace( sql[i] ) )
{ // found the end of an unquoted name break;
}
}
}
ret = o3tl::trim(sql.substr(start, i - start )); // printf( "pq_statement: parsed table name %s from insert\n" , // OUStringToOString( ret, RTL_TEXTENCODING_ASCII_US).getStr() );
}
} return ret;
}
OUString array2String( const css::uno::Sequence< Any > &seq )
{
OUStringBuffer buf(128); int len = seq.getLength();
buf.append( "{" ); for( int i = 0 ; i < len ; i ++ )
{
OUString element;
seq[i] >>= element;
if( i > 0 )
buf.append( "," ); int strLength = element.getLength();
buf.append( "\"" ); for( int j = 0 ; j < strLength ; j ++ )
{
sal_Unicode c = element[j]; if( c == '\\' || c == '"' || c == '{' || c == '}' )
{
buf.append( "\\" );
}
buf.append( c );
}
buf.append( "\"" );
}
buf.append( "}" ); return buf.makeStringAndClear();
}
std::vector< Any > parseArray( std::u16string_view str )
{
size_t len = str.size(); bool doubleQuote = false; int brackets = 0;
size_t i = 0;
OUStringBuffer current;
std::vector<Any> elements; bool doubleQuotedValue = false; while( i < len )
{
sal_Unicode c = str[i];
sal_Unicode cnext = str[i+1]; if( doubleQuote )
{ if( '\\' == c )
{
i ++;
current.append( cnext );
} elseif( '"' == c )
{
doubleQuote = false;
doubleQuotedValue = true; // signal, that there was an empty element
} else
{
current.append( c );
}
} elseif ( '{' == c )
{
brackets ++;
} elseif( '}' == c )
{
brackets --; if( brackets < 0 )
{ throw SQLException( "error during array parsing, didn't expect a } at position "
+ OUString::number(i) + " ('" + str + "')",
Reference< XInterface > (), OUString(), 1, Any() );
} if( brackets == 0 )
{ if( !current.isEmpty() || doubleQuotedValue )
elements.emplace_back( current.makeStringAndClear() );
} else
{
current.append( c );
}
} elseif( '"' == c )
{ // if( current.getLength() != 0 ) // { // OUStringBuffer buf; // buf.appendAscii( "error during array parsing, didn't expect a \" at position " ); // buf.append( i ); // buf.append( " ('" ); // buf.append( str ); // buf.append( "')" ); // throw SDBCException( // buf.makeStringAndClear(), // Reference< XInterface > (), 1, Any() ); // } // else // {
doubleQuote = true; // }
} elseif( ',' == c && brackets == 1)
{
doubleQuotedValue = false;
elements.emplace_back( current.makeStringAndClear() );
} elseif( isWhitespace( c ) )
{ // ignore whitespace without quotes
} else
{
current.append( c );
}
i++;
} return elements;
}
// copied from connectivity/source/dbtools, can't use the function directly bool implSetObject( const Reference< XParameters >& _rxParameters, const sal_Int32 _nColumnIndex, const Any& _rValue)
{ bool bSuccessfullyReRouted = true; switch (_rValue.getValueTypeClass())
{ case css::uno::TypeClass_HYPER:
{
_rxParameters->setLong( _nColumnIndex, sal_Int64(0) );
} break;
case css::uno::TypeClass_VOID:
_rxParameters->setNull(_nColumnIndex,css::sdbc::DataType::VARCHAR); break;
case css::uno::TypeClass_STRING:
_rxParameters->setString(_nColumnIndex, *o3tl::forceAccess<OUString>(_rValue)); break;
case css::uno::TypeClass_BOOLEAN:
_rxParameters->setBoolean(_nColumnIndex, *o3tl::forceAccess<bool>(_rValue)); break;
case css::uno::TypeClass_BYTE:
_rxParameters->setByte(_nColumnIndex, *o3tl::forceAccess<sal_Int8>(_rValue)); break;
case css::uno::TypeClass_UNSIGNED_SHORT: case css::uno::TypeClass_SHORT:
_rxParameters->setShort(_nColumnIndex, *o3tl::forceAccess<sal_Int16>(_rValue)); break;
case css::uno::TypeClass_CHAR:
_rxParameters->setString(_nColumnIndex, OUString(*o3tl::forceAccess<sal_Unicode>(_rValue))); break;
case css::uno::TypeClass_UNSIGNED_LONG: case css::uno::TypeClass_LONG:
_rxParameters->setInt(_nColumnIndex, *o3tl::forceAccess<sal_Int32>(_rValue)); break;
case css::uno::TypeClass_FLOAT:
_rxParameters->setFloat(_nColumnIndex, *o3tl::forceAccess<float>(_rValue)); break;
case css::uno::TypeClass_DOUBLE:
_rxParameters->setDouble(_nColumnIndex, *o3tl::forceAccess<double>(_rValue)); break;
case css::uno::TypeClass_SEQUENCE: if (auto s = o3tl::tryAccess<Sequence< sal_Int8 >>(_rValue))
{
_rxParameters->setBytes(_nColumnIndex, *s);
} else
bSuccessfullyReRouted = false; break; case css::uno::TypeClass_STRUCT: if (auto s1 = o3tl::tryAccess<css::util::DateTime>(_rValue))
_rxParameters->setTimestamp(_nColumnIndex, *s1); elseif (auto s2 = o3tl::tryAccess<css::util::Date>(_rValue))
_rxParameters->setDate(_nColumnIndex, *s2); elseif (auto s3 = o3tl::tryAccess<css::util::Time>(_rValue))
_rxParameters->setTime(_nColumnIndex, *s3); else
bSuccessfullyReRouted = false; break;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.