44#include <rtl/strbuf.hxx>
45#include <rtl/ustrbuf.hxx>
50#include <com/sun/star/sdbc/DataType.hpp>
51#include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
52#include <com/sun/star/sdbc/ResultSetType.hpp>
53#include <com/sun/star/sdbc/SQLException.hpp>
65using com::sun::star::uno::Any;
66using com::sun::star::uno::Type;
69using com::sun::star::uno::UNO_QUERY;
71using com::sun::star::lang::IllegalArgumentException;
73using com::sun::star::sdbc::XCloseable;
74using com::sun::star::sdbc::XResultSet;
75using com::sun::star::sdbc::XRef;
76using com::sun::star::sdbc::XBlob;
77using com::sun::star::sdbc::XClob;
78using com::sun::star::sdbc::XArray;
79using com::sun::star::sdbc::XConnection;
80using com::sun::star::sdbc::SQLException;
82using com::sun::star::beans::Property;
83using com::sun::star::beans::XPropertySetInfo;
91 static ::cppu::OPropertyArrayHelper arrayHelper(
97 "EscapeProcessing", 1,
115 "ResultSetConcurrency", 7,
121 static ::cppu::IPropertyArrayHelper *pArrayHelper = &arrayHelper;
123 return *pArrayHelper;
128 static const char *
const operators =
"<>=()!/&%.,;";
130 const char *
w = operators;
131 while (*
w && *
w != c)
140 return o[
index] ==
':' && (
146 return str[0] ==
'"' || str[0] ==
'\'';
150 const ::rtl::Reference< comphelper::RefCountedMutex > & refMutex,
157 , m_pSettings(pSettings)
158 , m_stmt(
std::move(stmt))
160 , m_multipleResultAvailable(false)
161 , m_multipleResultUpdateCount(0)
162 , m_lastOidInserted( InvalidOid )
167 css::sdbc::ResultSetConcurrency::READ_ONLY;
169 css::sdbc::ResultSetType::SCROLL_INSENSITIVE;
184 if( str[
index] ==
'?' ||
193 m_vars = std::vector< OString >( elements );
205 "pq_preparedstatement: parameter index out of range (expected 1 to "
206 + OUString::number(
m_vars.size() )
207 +
", got " + OUString::number( parameterIndex )
210 *
this, OUString(), 1,
Any () );
217 "pq_driver: PreparedStatement or connection has already been closed !",
218 *
this, OUString(),1,
Any());
223 Any aRet = PreparedStatement_BASE::queryInterface(rType);
224 return aRet.hasValue() ? aRet : OPropertySetHelper::queryInterface(rType);
231 ::comphelper::concatSequences(
232 OPropertySetHelper::getTypes(),
233 PreparedStatement_BASE::getTypes()));
240 return css::uno::Sequence<sal_Int8>();
249 MutexGuard guard(
m_xMutex->GetMutex() );
265 OUStringBuffer buf(128);
266 buf.append(
"pq_driver: "
268 +
" (caused by statement '" );
271 OUString error = buf.makeStringAndClear();
272 SAL_WARN(
"connectivity.postgresql", error);
273 throw SQLException( error, *
this, OUString(), 1,
Any() );
296 osl::MutexGuard guard(
m_xMutex->GetMutex() );
298 OStringBuffer buf(
m_stmt.getLength() *2 );
300 std::vector< OString >::size_type vars = 0;
318 if( str[
index] ==
'?' )
321 buf.append(
m_vars[vars] );
330 buf.append(
m_vars[vars] );
333 while (
index < str.getLength()
354 if( lastResultSet.is() )
355 lastResultSet->close();
380 MutexGuard guard(
m_xMutex->GetMutex() );
390 MutexGuard guard(
m_xMutex->GetMutex() );
393 m_vars[parameterIndex-1] = OString(
"NULL" );
397 sal_Int32 parameterIndex, sal_Int32,
const OUString& )
399 MutexGuard guard(
m_xMutex->GetMutex() );
402 m_vars[parameterIndex-1] = OString(
"NULL" );
408 MutexGuard guard(
m_xMutex->GetMutex() );
412 m_vars[parameterIndex-1] = OString(
"'t'" );
414 m_vars[parameterIndex-1] = OString(
"'f'" );
430 MutexGuard guard(
m_xMutex->GetMutex() );
433 m_vars[parameterIndex-1] =
"'" + OString::number(
x) +
"'";
438 MutexGuard guard(
m_xMutex->GetMutex() );
441 m_vars[parameterIndex-1] =
"'" + OString::number(
x) +
"'";
446 MutexGuard guard(
m_xMutex->GetMutex() );
449 m_vars[parameterIndex-1] =
"'" + OString::number(
x) +
"'";
454 MutexGuard guard(
m_xMutex->GetMutex() );
457 m_vars[parameterIndex-1] =
"'" + OString::number(
x) +
"'";
464 MutexGuard guard(
m_xMutex->GetMutex() );
467 OStringBuffer buf( 20 );
470 buf.ensureCapacity(
y.getLength() * 2 + 2 );
471 int len = PQescapeString(
const_cast<char*
>(buf.getStr())+1,
y.getStr() ,
y.getLength() );
472 buf.setLength( 1 + len );
474 m_vars[parameterIndex-1] = buf.makeStringAndClear();
480 MutexGuard guard(
m_xMutex->GetMutex() );
484 const std::unique_ptr<unsigned char, deleter_from_fn<PQfreemem>> escapedString(
485 PQescapeBytea(
reinterpret_cast<unsigned char const *
>(
x.getConstArray()),
x.getLength(), &len));
486 if( ! escapedString )
489 "pq_preparedstatement.setBytes: Error during converting bytesequence to an SQL conform string",
490 *
this, OUString(), 1,
Any() );
493 = OString::Concat(
"'") + std::string_view(
reinterpret_cast<char *
>(escapedString.get()), len -1) +
"'";
508 sal_Int32 parameterIndex,
const css::util::DateTime& x )
519 "pq_preparedstatement: setBinaryStream not implemented",
520 *
this, OUString(), 1,
Any () );
529 "pq_preparedstatement: setCharacterStream not implemented",
530 *
this, OUString(), 1,
Any () );
538 "pq_preparedstatement::setObject: can't convert value of type " +
x.getValueTypeName(),
539 *
this, OUString(), 1,
Any () );
544 sal_Int32 parameterIndex,
546 sal_Int32 targetSqlType,
549 if( css::sdbc::DataType::DECIMAL == targetSqlType ||
550 css::sdbc::DataType::NUMERIC == targetSqlType )
552 double myDouble = 0.0;
556 myString = OUString::number( myDouble );
562 if( myString.isEmpty() )
565 "pq_preparedstatement::setObjectWithInfo: can't convert value of type "
566 +
x.getValueTypeName() +
" to type DECIMAL or NUMERIC",
567 *
this, OUString(), 1,
Any () );
584 "pq_preparedstatement: setRef not implemented",
585 *
this, OUString(), 1,
Any () );
593 "pq_preparedstatement: setBlob not implemented",
594 *
this, OUString(), 1,
Any () );
602 "pq_preparedstatement: setClob not implemented",
603 *
this, OUString(), 1,
Any () );
607 sal_Int32 parameterIndex,
615 MutexGuard guard(
m_xMutex->GetMutex() );
633 ret = supplier->getMetaData();
644 Any & rConvertedValue, Any & rOldValue, sal_Int32 nHandle,
const Any& rValue )
653 bRet = ( rValue >>= val );
654 rConvertedValue <<= val;
660 bRet = ( rValue >>= val );
661 rConvertedValue <<= val;
673 bRet = ( rValue >>= val );
674 rConvertedValue <<= val;
679 throw IllegalArgumentException(
680 "pq_statement: Invalid property handle ("
681 + OUString::number(
nHandle ) +
")",
690 sal_Int32 nHandle,
const Any& rValue )
722 if( lastResultSet.is() )
723 lastResultSet->close();
730 osl::MutexGuard guard(
m_xMutex->GetMutex() );
virtual void SAL_CALL setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const css::uno::Any &rValue) override
virtual void SAL_CALL setTimestamp(sal_Int32 parameterIndex, const css::util::DateTime &x) override
virtual void SAL_CALL setInt(sal_Int32 parameterIndex, sal_Int32 x) override
virtual css::uno::Reference< css::sdbc::XConnection > SAL_CALL getConnection() override
virtual void SAL_CALL setFloat(sal_Int32 parameterIndex, float x) override
virtual void SAL_CALL setDouble(sal_Int32 parameterIndex, double x) override
virtual void SAL_CALL setNull(sal_Int32 parameterIndex, sal_Int32 sqlType) override
css::uno::Reference< css::sdbc::XConnection > m_connection
sal_Int32 m_lastOidInserted
virtual css::uno::Reference< css::sdbc::XResultSet > SAL_CALL getGeneratedValues() override
virtual void SAL_CALL close() override
virtual cppu::IPropertyArrayHelper &SAL_CALL getInfoHelper() override
virtual sal_Bool SAL_CALL execute() override
void checkColumnIndex(sal_Int32 parameterIndex)
virtual void SAL_CALL disposing() override
virtual void SAL_CALL setLong(sal_Int32 parameterIndex, sal_Int64 x) override
css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override
virtual sal_Int32 SAL_CALL executeUpdate() override
virtual void SAL_CALL setClob(sal_Int32 parameterIndex, const css::uno::Reference< css::sdbc::XClob > &x) override
virtual css::uno::Reference< css::sdbc::XResultSet > SAL_CALL executeQuery() override
virtual sal_Int32 SAL_CALL getUpdateCount() override
virtual void SAL_CALL setObject(sal_Int32 parameterIndex, const css::uno::Any &x) override
virtual void SAL_CALL setBinaryStream(sal_Int32 parameterIndex, const css::uno::Reference< css::io::XInputStream > &x, sal_Int32 length) override
virtual void SAL_CALL setString(sal_Int32 parameterIndex, const OUString &x) override
virtual void SAL_CALL setCharacterStream(sal_Int32 parameterIndex, const css::uno::Reference< css::io::XInputStream > &x, sal_Int32 length) override
virtual void SAL_CALL setRef(sal_Int32 parameterIndex, const css::uno::Reference< css::sdbc::XRef > &x) override
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &reqType) override
sal_Int32 m_multipleResultUpdateCount
virtual void SAL_CALL setObjectWithInfo(sal_Int32 parameterIndex, const css::uno::Any &x, sal_Int32 targetSqlType, sal_Int32 scale) override
virtual sal_Bool SAL_CALL convertFastPropertyValue(css::uno::Any &rConvertedValue, css::uno::Any &rOldValue, sal_Int32 nHandle, const css::uno::Any &rValue) override
virtual css::uno::Reference< css::sdbc::XResultSet > SAL_CALL getResultSet() override
ConnectionSettings * m_pSettings
css::uno::Reference< css::sdbc::XCloseable > m_lastResultset
::rtl::Reference< comphelper::RefCountedMutex > m_xMutex
virtual void SAL_CALL setBoolean(sal_Int32 parameterIndex, sal_Bool x) override
virtual void SAL_CALL clearParameters() override
virtual css::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() override
virtual sal_Bool SAL_CALL getMoreResults() override
virtual void SAL_CALL setTime(sal_Int32 parameterIndex, const css::util::Time &x) override
bool m_multipleResultAvailable
std::vector< OString > m_vars
virtual void SAL_CALL setObjectNull(sal_Int32 parameterIndex, sal_Int32 sqlType, const OUString &typeName) override
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
virtual ~PreparedStatement() override
std::vector< OString > m_splittedStatement
virtual void SAL_CALL setBytes(sal_Int32 parameterIndex, const css::uno::Sequence< sal_Int8 > &x) override
virtual void SAL_CALL setByte(sal_Int32 parameterIndex, sal_Int8 x) override
virtual void SAL_CALL clearWarnings() override
virtual void SAL_CALL setArray(sal_Int32 parameterIndex, const css::uno::Reference< css::sdbc::XArray > &x) override
css::uno::Any m_props[PREPARED_STATEMENT_SIZE]
void SAL_CALL getFastPropertyValue(css::uno::Any &rValue, sal_Int32 nHandle) const override
virtual void SAL_CALL setShort(sal_Int32 parameterIndex, sal_Int16 x) override
virtual css::uno::Any SAL_CALL getWarnings() override
virtual void SAL_CALL setDate(sal_Int32 parameterIndex, const css::util::Date &x) override
OUString m_lastTableInserted
virtual css::uno::Reference< css::sdbc::XResultSetMetaData > SAL_CALL getMetaData() override
OString m_executedStatement
PreparedStatement(const rtl::Reference< comphelper::RefCountedMutex > &refMutex, const css::uno::Reference< css::sdbc::XConnection > &con, struct ConnectionSettings *pSettings, OString stmt)
void raiseSQLException(const char *errorMsg)
virtual void SAL_CALL setBlob(sal_Int32 parameterIndex, const css::uno::Reference< css::sdbc::XBlob > &x) override
#define SAL_WARN(area, stream)
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
const sal_Int32 PREPARED_STATEMENT_FETCH_DIRECTION
bool implSetObject(const Reference< XParameters > &_rxParameters, const sal_Int32 _nColumnIndex, const Any &_rValue)
bool isWhitespace(sal_Unicode c)
const sal_Int32 PREPARED_STATEMENT_MAX_FIELD_SIZE
const sal_Int32 PREPARED_STATEMENT_RESULT_SET_TYPE
OUString array2String(const css::uno::Sequence< Any > &seq)
sal_Int32 extractIntProperty(const Reference< XPropertySet > &descriptor, const OUString &name)
const sal_Int32 PREPARED_STATEMENT_QUERY_TIME_OUT
static bool isQuoted(std::string_view str)
const sal_Int32 PREPARED_STATEMENT_ESCAPE_PROCESSING
static bool isNamedParameterStart(std::string_view o, int index)
::cppu::WeakComponentImplHelper< css::sdbc::XPreparedStatement, css::sdbc::XParameters, css::sdbc::XCloseable, css::sdbc::XWarningsSupplier, css::sdbc::XMultipleResults, css::sdbc::XGeneratedResultSet, css::sdbc::XResultSetMetaDataSupplier > PreparedStatement_BASE
::cppu::IPropertyArrayHelper & getPreparedStatementPropertyArrayHelper()
const sal_Int32 PREPARED_STATEMENT_FETCH_SIZE
static bool isOperator(char c)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
const sal_Int32 PREPARED_STATEMENT_RESULT_SET_CONCURRENCY
const sal_Int32 PREPARED_STATEMENT_CURSOR_NAME
Reference< XResultSet > getGeneratedValuesFromLastInsert(ConnectionSettings *pConnectionSettings, const Reference< XConnection > &connection, sal_Int32 nLastOid, std::u16string_view lastTableInserted, const OString &lastQuery)
bool executePostgresCommand(const OString &cmd, struct CommandData *data)
const sal_Int32 PREPARED_STATEMENT_MAX_ROWS
void splitSQL(const OString &sql, std::vector< OString > &vec)
OUString * pLastTableInserted
css::uno::Reference< css::uno::XInterface > owner
sal_Int32 * pMultipleResultUpdateCount
css::uno::Reference< css::sdbc::XCloseable > * pLastResultset
sal_Int32 * pLastOidInserted
::rtl::Reference< comphelper::RefCountedMutex > refMutex
bool * pMultipleResultAvailable
ConnectionSettings ** ppSettings
css::uno::Reference< css::sdbcx::XTablesSupplier > tableSupplier
static const rtl_TextEncoding encoding