33#include <com/sun/star/sdbc/DriverManager.hpp>
34#include <com/sun/star/uno/XComponentContext.hpp>
50OUString getJavaDriverClass(css::uno::Sequence<css::beans::PropertyValue>
const& info)
53 OUString(
"com.mysql.jdbc.Driver"));
63ODriverDelegator::~ODriverDelegator()
67 ::comphelper::disposeComponent(m_xODBCDriver);
68 ::comphelper::disposeComponent(m_xNativeDriver);
69 for (
auto& rEntry : m_aJdbcDrivers)
70 ::comphelper::disposeComponent(rEntry.second);
72 catch (
const Exception&)
77void ODriverDelegator::disposing()
79 ::osl::MutexGuard aGuard(m_aMutex);
81 for (
auto const& connection : m_aConnections)
83 Reference<XInterface> xTemp = connection.first.get();
84 ::comphelper::disposeComponent(xTemp);
86 m_aConnections.clear();
89 ODriverDelegator_BASE::disposing();
94enum class T_DRIVERTYPE
101bool isOdbcUrl(std::u16string_view _sUrl) {
return o3tl::starts_with(_sUrl, u
"sdbc:mysql:odbc:"); }
103bool isNativeUrl(std::u16string_view _sUrl)
108T_DRIVERTYPE lcl_getDriverType(std::u16string_view _sUrl)
110 T_DRIVERTYPE eRet = T_DRIVERTYPE::Jdbc;
111 if (isOdbcUrl(_sUrl))
112 eRet = T_DRIVERTYPE::Odbc;
113 else if (isNativeUrl(_sUrl))
114 eRet = T_DRIVERTYPE::Native;
118OUString transformUrl(std::u16string_view _sUrl)
120 OUString sNewUrl(_sUrl.substr(11));
121 if (isOdbcUrl(_sUrl))
122 sNewUrl =
"sdbc:" + sNewUrl;
123 else if (isNativeUrl(_sUrl))
124 sNewUrl =
"sdbc:" + sNewUrl;
127 sNewUrl = OUString::Concat(
"jdbc:mysql://") + sNewUrl.subView(5);
132Reference<XDriver> lcl_loadDriver(
const Reference<XComponentContext>& _rxContext,
133 const OUString& _sUrl)
135 Reference<XDriverManager2> xDriverAccess = DriverManager::create(_rxContext);
136 Reference<XDriver> xDriver = xDriverAccess->getDriverByURL(_sUrl);
140Sequence<PropertyValue> lcl_convertProperties(T_DRIVERTYPE _eType,
141 const Sequence<PropertyValue>& info,
142 const OUString& _sUrl)
144 std::vector<PropertyValue> aProps;
145 const PropertyValue* pSupported = info.getConstArray();
146 const PropertyValue* pEnd = pSupported + info.getLength();
148 aProps.reserve(info.getLength() + 5);
150 for (; pSupported != pEnd; ++pSupported)
152 aProps.push_back(*pSupported);
153 if (pSupported->Name ==
"JavaDriverClass")
159 if (_eType == T_DRIVERTYPE::Odbc)
161 aProps.push_back(PropertyValue(
"Silent", 0,
Any(
true), PropertyState_DIRECT_VALUE));
163 PropertyValue(
"PreventGetVersionColumns", 0,
Any(
true), PropertyState_DIRECT_VALUE));
165 else if (_eType == T_DRIVERTYPE::Jdbc)
169 aProps.push_back(PropertyValue(
"JavaDriverClass", 0,
170 Any(OUString(
"com.mysql.jdbc.Driver")),
171 PropertyState_DIRECT_VALUE));
177 PropertyValue(
"PublicConnectionURL", 0,
Any(_sUrl), PropertyState_DIRECT_VALUE));
180 PropertyValue(
"IsAutoRetrievingEnabled", 0,
Any(
true), PropertyState_DIRECT_VALUE));
181 aProps.push_back(PropertyValue(
"AutoRetrievingStatement", 0,
182 Any(OUString(
"SELECT LAST_INSERT_ID()")),
183 PropertyState_DIRECT_VALUE));
185 PropertyValue(
"ParameterNameSubstitution", 0,
Any(
true), PropertyState_DIRECT_VALUE));
186 return Sequence<PropertyValue>(aProps.data(), aProps.size());
190Reference<XDriver> ODriverDelegator::loadDriver(std::u16string_view url,
191 const Sequence<PropertyValue>& info)
193 Reference<XDriver> xDriver;
194 const OUString sCuttedUrl = transformUrl(url);
195 const T_DRIVERTYPE
eType = lcl_getDriverType(url);
196 if (eType == T_DRIVERTYPE::Odbc)
198 if (!m_xODBCDriver.is())
199 m_xODBCDriver = lcl_loadDriver(m_xContext, sCuttedUrl);
200 xDriver = m_xODBCDriver;
202 else if (eType == T_DRIVERTYPE::Native)
204 if (!m_xNativeDriver.is())
205 m_xNativeDriver = lcl_loadDriver(m_xContext, sCuttedUrl);
206 xDriver = m_xNativeDriver;
210 OUString sDriverClass(getJavaDriverClass(info));
211 TJDBCDrivers::iterator aFind = m_aJdbcDrivers.find(sDriverClass);
212 if (aFind == m_aJdbcDrivers.end())
213 aFind = m_aJdbcDrivers.emplace(sDriverClass, lcl_loadDriver(m_xContext, sCuttedUrl))
215 xDriver = aFind->second;
221Reference<XConnection> SAL_CALL ODriverDelegator::connect(
const OUString& url,
222 const Sequence<PropertyValue>& info)
224 Reference<XConnection> xConnection;
227 Reference<XDriver> xDriver = loadDriver(url, info);
230 OUString sCuttedUrl = transformUrl(url);
231 const T_DRIVERTYPE
eType = lcl_getDriverType(url);
232 Sequence<PropertyValue> aConvertedProperties = lcl_convertProperties(eType, info, url);
233 if (eType == T_DRIVERTYPE::Jdbc)
236 info, u
"CharSet", OUString());
237 if (!sIanaName.isEmpty())
242 if (aLookup != aLookupIanaName.
end())
245 if (RTL_TEXTENCODING_UTF8 == (*aLookup).getEncoding())
247 static constexpr OUStringLiteral s_sCharSetOp =
u"useUnicode=true&";
248 if (!sCuttedUrl.matchIgnoreAsciiCase(s_sCharSetOp))
253 if (sCuttedUrl.indexOf(
'?') == -1)
257 sCuttedUrl += sAdd +
"characterEncoding=" + sIanaName;
262 xConnection = xDriver->connect(sCuttedUrl, aConvertedProperties);
263 if (xConnection.is())
266 auto pMetaConnection = comphelper::getFromUnoTunnel<OMetaConnection>(xConnection);
268 pMetaConnection->setURL(url);
269 m_aConnections.push_back(
270 TWeakPair(WeakReferenceHelper(xConnection),
278sal_Bool SAL_CALL ODriverDelegator::acceptsURL(
const OUString& url)
280 Sequence<PropertyValue> info;
282 bool bOK = url.startsWith(
"sdbc:mysql:odbc:") || url.startsWith(
"sdbc:mysql:jdbc:")
283 || (url.startsWith(
"sdbc:mysql:mysqlc:") && loadDriver(url, info).is());
287Sequence<DriverPropertyInfo> SAL_CALL
288ODriverDelegator::getPropertyInfo(
const OUString& url,
const Sequence<PropertyValue>& info)
290 if (!acceptsURL(url))
291 return Sequence<DriverPropertyInfo>();
293 Sequence<OUString> aBoolean{
"0",
"1" };
295 std::vector<DriverPropertyInfo> aDriverInfo{
296 {
"CharSet",
"CharSet of the database.",
false, {}, {} },
297 {
"SuppressVersionColumns",
"Display version columns (when available).",
false,
"0",
300 const T_DRIVERTYPE
eType = lcl_getDriverType(url);
301 if (eType == T_DRIVERTYPE::Jdbc)
303 aDriverInfo.push_back(DriverPropertyInfo(
"JavaDriverClass",
"The JDBC driver class name.",
304 true, getJavaDriverClass(info),
305 Sequence<OUString>()));
307 else if (eType == T_DRIVERTYPE::Native)
309 aDriverInfo.push_back(DriverPropertyInfo(
310 "LocalSocket",
"The file path of a socket to connect to a local MySQL server.",
false,
311 OUString(), Sequence<OUString>()));
312 aDriverInfo.push_back(DriverPropertyInfo(
313 "NamedPipe",
"The name of a pipe to connect to a local MySQL server.",
false,
314 OUString(), Sequence<OUString>()));
317 return Sequence<DriverPropertyInfo>(aDriverInfo.data(), aDriverInfo.size());
320sal_Int32 SAL_CALL ODriverDelegator::getMajorVersion() {
return 1; }
322sal_Int32 SAL_CALL ODriverDelegator::getMinorVersion() {
return 0; }
324Reference<XTablesSupplier> SAL_CALL
325ODriverDelegator::getDataDefinitionByConnection(
const Reference<XConnection>& connection)
327 ::osl::MutexGuard aGuard(m_aMutex);
330 Reference<XTablesSupplier> xTab;
331 auto pConnection = comphelper::getFromUnoTunnel<OMetaConnection>(connection);
334 TWeakPairVector::iterator
i
335 = std::find_if(m_aConnections.begin(), m_aConnections.end(),
336 [&pConnection](
const TWeakPairVector::value_type& rConnection) {
337 return rConnection.second.second == pConnection;
339 if (i != m_aConnections.end())
341 xTab.set(
i->second.first.get(), UNO_QUERY);
344 xTab =
new OMySQLCatalog(connection);
345 i->second.first = WeakReferenceHelper(xTab);
351 TWeakPairVector::iterator
i
352 = std::find_if(m_aConnections.begin(), m_aConnections.end(),
353 [&connection](
const TWeakPairVector::value_type& rConnection) {
354 Reference<XConnection> xTemp(rConnection.first.get(), UNO_QUERY);
355 return xTemp == connection;
357 if (i != m_aConnections.end())
359 xTab.set(
i->second.first.get(), UNO_QUERY);
362 xTab =
new OMySQLCatalog(connection);
363 i->second.first = WeakReferenceHelper(xTab);
370Reference<XTablesSupplier> SAL_CALL
371ODriverDelegator::getDataDefinitionByURL(
const OUString& url,
const Sequence<PropertyValue>& info)
373 if (!acceptsURL(url))
380 return getDataDefinitionByConnection(connect(url, info));
385OUString SAL_CALL ODriverDelegator::getImplementationName()
387 return "org.openoffice.comp.drivers.MySQL.Driver";
390sal_Bool SAL_CALL ODriverDelegator::supportsService(
const OUString& _rServiceName)
395Sequence<OUString> SAL_CALL ODriverDelegator::getSupportedServiceNames()
397 return {
"com.sun.star.sdbc.Driver",
"com.sun.star.sdbcx.Driver" };
402extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
404 css::uno::Sequence<css::uno::Any>
const&)
Reference< XComponentContext > m_xContext
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * connectivity_mysql_ODriverDelegator_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &)
VALUE_TYPE getOrDefault(const OUString &_rValueName, const VALUE_TYPE &_rDefault) const
helper class for accessing resources shared by different libraries in the connectivity module
OUString getResourceString(TranslateId pResId) const
loads a string from the shared resource file
delegates all calls to the original driver and extend the existing one with the SDBCX layer.
ODriverDelegator(const css::uno::Reference< css::uno::XComponentContext > &_rxContext)
creates a new delegator for a HSQLDB driver
std::pair< css::uno::WeakReferenceHelper, TWeakConnectionPair > TWeakPair
std::pair< OUString,TWeakRefPair > TWeakConnectionPair
::cppu::WeakComponentImplHelper< css::sdbc::XDriver, css::sdbcx::XDataDefinitionSupplier, css::lang::XServiceInfo, css::sdbcx::XCreateCatalog, css::embed::XTransactionListener > ODriverDelegator_BASE
std::vector< TWeakPair > TWeakPairVector
void checkDisposed(bool _bThrow)
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
constexpr bool starts_with(std::basic_string_view< charT, traits > sv, std::basic_string_view< charT, traits > x) noexcept