Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "dbase/DDatabaseMetaData.hxx"
21 : #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
22 : #include <com/sun/star/sdbc/DataType.hpp>
23 : #include <com/sun/star/sdbc/ResultSetType.hpp>
24 : #include <com/sun/star/sdbc/ColumnValue.hpp>
25 : #include <com/sun/star/beans/XPropertySet.hpp>
26 : #include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
27 : #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
28 : #include <com/sun/star/sdbcx/XIndexesSupplier.hpp>
29 : #include "FDatabaseMetaDataResultSet.hxx"
30 : #include <com/sun/star/lang/XUnoTunnel.hpp>
31 : #include "dbase/DIndex.hxx"
32 : #include <connectivity/FValue.hxx>
33 : #include <comphelper/processfactory.hxx>
34 : #include <comphelper/types.hxx>
35 : #include <ucbhelper/content.hxx>
36 :
37 : using namespace ::comphelper;
38 : using namespace connectivity::dbase;
39 : using namespace connectivity;
40 : using namespace ::com::sun::star::uno;
41 : using namespace ::com::sun::star::beans;
42 : using namespace ::com::sun::star::sdbcx;
43 : using namespace ::com::sun::star::sdbc;
44 : using namespace ::com::sun::star::container;
45 : using namespace ::com::sun::star::ucb;
46 : using namespace ::com::sun::star::lang;
47 :
48 58 : ODbaseDatabaseMetaData::ODbaseDatabaseMetaData(::connectivity::file::OConnection* _pCon) :ODatabaseMetaData(_pCon)
49 : {
50 58 : }
51 :
52 116 : ODbaseDatabaseMetaData::~ODbaseDatabaseMetaData()
53 : {
54 116 : }
55 :
56 2 : Reference< XResultSet > ODbaseDatabaseMetaData::impl_getTypeInfo_throw( )
57 : {
58 2 : ::osl::MutexGuard aGuard( m_aMutex );
59 :
60 2 : ::connectivity::ODatabaseMetaDataResultSet* pResult = new ::connectivity::ODatabaseMetaDataResultSet(::connectivity::ODatabaseMetaDataResultSet::eTypeInfo);
61 2 : Reference< XResultSet > xRef = pResult;
62 :
63 2 : static ODatabaseMetaDataResultSet::ORows aRows;
64 2 : if(aRows.empty())
65 : {
66 2 : ODatabaseMetaDataResultSet::ORow aRow;
67 2 : aRow.reserve(19);
68 :
69 2 : aRow.push_back(ODatabaseMetaDataResultSet::getEmptyValue());
70 2 : aRow.push_back(new ORowSetValueDecorator(OUString("VARCHAR")));
71 2 : aRow.push_back(new ORowSetValueDecorator(DataType::VARCHAR));
72 2 : aRow.push_back(new ORowSetValueDecorator((sal_Int32)254));
73 2 : aRow.push_back(ODatabaseMetaDataResultSet::getQuoteValue());
74 2 : aRow.push_back(ODatabaseMetaDataResultSet::getQuoteValue());
75 2 : aRow.push_back(new ORowSetValueDecorator(OUString("length")));
76 2 : aRow.push_back(new ORowSetValueDecorator((sal_Int32)ColumnValue::NULLABLE));
77 2 : aRow.push_back(ODatabaseMetaDataResultSet::get1Value());
78 2 : aRow.push_back(new ORowSetValueDecorator((sal_Int32)ColumnSearch::FULL));
79 2 : aRow.push_back(ODatabaseMetaDataResultSet::get1Value());
80 2 : aRow.push_back(ODatabaseMetaDataResultSet::get0Value());
81 2 : aRow.push_back(ODatabaseMetaDataResultSet::get0Value());
82 2 : aRow.push_back(new ORowSetValueDecorator(OUString("C")));
83 2 : aRow.push_back(ODatabaseMetaDataResultSet::get0Value());
84 2 : aRow.push_back(ODatabaseMetaDataResultSet::get0Value());
85 2 : aRow.push_back(ODatabaseMetaDataResultSet::getEmptyValue());
86 2 : aRow.push_back(ODatabaseMetaDataResultSet::getEmptyValue());
87 2 : aRow.push_back(new ORowSetValueDecorator((sal_Int32)10));
88 :
89 2 : aRows.push_back(aRow);
90 :
91 2 : aRow[1] = new ORowSetValueDecorator(OUString("LONGVARCHAR"));
92 2 : aRow[2] = new ORowSetValueDecorator(DataType::LONGVARCHAR);
93 2 : aRow[3] = new ORowSetValueDecorator((sal_Int32)2147483647);
94 2 : aRow[6] = new ORowSetValueDecorator();
95 2 : aRow[13] = new ORowSetValueDecorator(OUString("M"));
96 2 : aRows.push_back(aRow);
97 :
98 2 : aRow[1] = new ORowSetValueDecorator(OUString("DATE"));
99 2 : aRow[2] = new ORowSetValueDecorator(DataType::DATE);
100 2 : aRow[3] = new ORowSetValueDecorator((sal_Int32)10);
101 2 : aRow[13] = new ORowSetValueDecorator(OUString("D"));
102 2 : aRows.push_back(aRow);
103 :
104 2 : aRow[1] = new ORowSetValueDecorator(OUString("BOOLEAN"));
105 2 : aRow[2] = new ORowSetValueDecorator(DataType::BIT);
106 2 : aRow[3] = ODatabaseMetaDataResultSet::get1Value();
107 2 : aRow[4] = ODatabaseMetaDataResultSet::getEmptyValue();
108 2 : aRow[5] = ODatabaseMetaDataResultSet::getEmptyValue();
109 2 : aRow[6] = new ORowSetValueDecorator(OUString());
110 2 : aRow[9] = ODatabaseMetaDataResultSet::getBasicValue();
111 2 : aRow[13] = new ORowSetValueDecorator(OUString("L"));
112 2 : aRows.push_back(aRow);
113 :
114 2 : aRow[1] = new ORowSetValueDecorator(OUString("DOUBLE"));
115 2 : aRow[2] = new ORowSetValueDecorator(DataType::DOUBLE);
116 2 : aRow[3] = new ORowSetValueDecorator((sal_Int32)8);
117 2 : aRow[13] = new ORowSetValueDecorator(OUString("B"));
118 2 : aRows.push_back(aRow);
119 :
120 2 : aRow[11] = new ORowSetValueDecorator(sal_True);
121 2 : aRow[13] = new ORowSetValueDecorator(OUString("Y"));
122 2 : aRows.push_back(aRow);
123 :
124 2 : aRow[1] = new ORowSetValueDecorator(OUString("TIMESTAMP"));
125 2 : aRow[2] = new ORowSetValueDecorator(DataType::TIMESTAMP);
126 2 : aRow[11] = new ORowSetValueDecorator(sal_False);
127 2 : aRow[13] = new ORowSetValueDecorator(OUString("T"));
128 2 : aRows.push_back(aRow);
129 :
130 2 : aRow[1] = new ORowSetValueDecorator(OUString("INTEGER"));
131 2 : aRow[2] = new ORowSetValueDecorator(DataType::INTEGER);
132 2 : aRow[3] = new ORowSetValueDecorator((sal_Int32)10);
133 2 : aRow[13] = new ORowSetValueDecorator(OUString("I"));
134 2 : aRows.push_back(aRow);
135 :
136 2 : aRow[1] = new ORowSetValueDecorator(OUString("DECIMAL"));
137 2 : aRow[2] = new ORowSetValueDecorator(DataType::DECIMAL);
138 2 : aRow[3] = new ORowSetValueDecorator((sal_Int32)20);
139 2 : aRow[6] = new ORowSetValueDecorator(OUString("length,scale"));
140 2 : aRow[13] = new ORowSetValueDecorator(OUString("F"));
141 2 : aRows.push_back(aRow);
142 :
143 2 : aRow[1] = new ORowSetValueDecorator(OUString("NUMERIC"));
144 2 : aRow[2] = new ORowSetValueDecorator(DataType::DECIMAL);
145 2 : aRow[3] = new ORowSetValueDecorator((sal_Int32)16);
146 2 : aRow[13] = new ORowSetValueDecorator(OUString("N"));
147 2 : aRow[15] = new ORowSetValueDecorator((sal_Int32)16);
148 2 : aRows.push_back(aRow);
149 : }
150 :
151 2 : pResult->setRows(aRows);
152 2 : return xRef;
153 : }
154 :
155 0 : Reference< XResultSet > SAL_CALL ODbaseDatabaseMetaData::getColumns(
156 : const Any& /*catalog*/, const OUString& /*schemaPattern*/, const OUString& tableNamePattern,
157 : const OUString& columnNamePattern ) throw(SQLException, RuntimeException, std::exception)
158 : {
159 0 : ::osl::MutexGuard aGuard( m_aMutex );
160 :
161 0 : Reference< XTablesSupplier > xTables = m_pConnection->createCatalog();
162 0 : if(!xTables.is())
163 0 : throw SQLException();
164 :
165 0 : Reference< XNameAccess> xNames = xTables->getTables();
166 0 : if(!xNames.is())
167 0 : throw SQLException();
168 :
169 0 : ODatabaseMetaDataResultSet::ORows aRows;
170 0 : ODatabaseMetaDataResultSet::ORow aRow(19);
171 :
172 : try
173 : {
174 0 : aRow[10] = new ORowSetValueDecorator((sal_Int32)10);
175 0 : Sequence< OUString> aTabNames(xNames->getElementNames());
176 0 : const OUString* pTabBegin = aTabNames.getConstArray();
177 0 : const OUString* pTabEnd = pTabBegin + aTabNames.getLength();
178 0 : for(;pTabBegin != pTabEnd;++pTabBegin)
179 : {
180 0 : if(match(tableNamePattern,*pTabBegin,'\0'))
181 : {
182 : Reference< XColumnsSupplier> xTable(
183 0 : xNames->getByName(*pTabBegin), css::uno::UNO_QUERY);
184 : OSL_ENSURE(xTable.is(),"Table not found! Normally a exception had to be thrown here!");
185 0 : aRow[3] = new ORowSetValueDecorator(*pTabBegin);
186 :
187 0 : Reference< XNameAccess> xColumns = xTable->getColumns();
188 0 : if(!xColumns.is())
189 0 : throw SQLException();
190 :
191 0 : Sequence< OUString> aColNames(xColumns->getElementNames());
192 :
193 0 : const OUString* pBegin = aColNames.getConstArray();
194 0 : const OUString* pEnd = pBegin + aColNames.getLength();
195 0 : Reference< XPropertySet> xColumn;
196 0 : for(sal_Int32 i=1;pBegin != pEnd;++pBegin,++i)
197 : {
198 0 : if(match(columnNamePattern,*pBegin,'\0'))
199 : {
200 0 : aRow[4] = new ORowSetValueDecorator(*pBegin);
201 :
202 : xColumn.set(
203 0 : xColumns->getByName(*pBegin), css::uno::UNO_QUERY);
204 : OSL_ENSURE(xColumn.is(),"Columns contains a column who isn't a fastpropertyset!");
205 0 : aRow[5] = new ORowSetValueDecorator(getINT32(xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE))));
206 0 : aRow[6] = new ORowSetValueDecorator(getString(xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPENAME))));
207 0 : aRow[7] = new ORowSetValueDecorator(getINT32(xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PRECISION))));
208 0 : aRow[9] = new ORowSetValueDecorator(getINT32(xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_SCALE))));
209 0 : aRow[11] = new ORowSetValueDecorator(getINT32(xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISNULLABLE))));
210 0 : aRow[13] = new ORowSetValueDecorator(getString(xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DEFAULTVALUE))));
211 0 : switch((sal_Int32)aRow[5]->getValue())
212 : {
213 : case DataType::CHAR:
214 : case DataType::VARCHAR:
215 0 : aRow[16] = new ORowSetValueDecorator((sal_Int32)254);
216 0 : break;
217 : case DataType::LONGVARCHAR:
218 0 : aRow[16] = new ORowSetValueDecorator((sal_Int32)65535);
219 0 : break;
220 : default:
221 0 : aRow[16] = new ORowSetValueDecorator((sal_Int32)0);
222 : }
223 0 : aRow[17] = new ORowSetValueDecorator(i);
224 0 : switch(sal_Int32(aRow[11]->getValue()))
225 : {
226 : case ColumnValue::NO_NULLS:
227 0 : aRow[18] = new ORowSetValueDecorator(OUString("NO"));
228 0 : break;
229 : case ColumnValue::NULLABLE:
230 0 : aRow[18] = new ORowSetValueDecorator(OUString("YES"));
231 0 : break;
232 : default:
233 0 : aRow[18] = new ORowSetValueDecorator(OUString());
234 : }
235 0 : aRows.push_back(aRow);
236 : }
237 0 : }
238 : }
239 0 : }
240 : }
241 0 : catch (const WrappedTargetException& e)
242 : {
243 0 : SQLException aSql;
244 0 : if (e.TargetException >>= aSql)
245 0 : throw aSql;
246 0 : throw WrappedTargetRuntimeException(e.Message, e.Context, e.TargetException);
247 : }
248 0 : ::connectivity::ODatabaseMetaDataResultSet* pResult = new ::connectivity::ODatabaseMetaDataResultSet(::connectivity::ODatabaseMetaDataResultSet::eColumns);
249 0 : Reference< XResultSet > xRef = pResult;
250 0 : pResult->setRows(aRows);
251 :
252 0 : return xRef;
253 : }
254 :
255 0 : Reference< XResultSet > SAL_CALL ODbaseDatabaseMetaData::getIndexInfo(
256 : const Any& /*catalog*/, const OUString& /*schema*/, const OUString& table,
257 : sal_Bool unique, sal_Bool /*approximate*/ ) throw(SQLException, RuntimeException, std::exception)
258 : {
259 0 : ::osl::MutexGuard aGuard( m_aMutex );
260 :
261 0 : Reference< XTablesSupplier > xTables = m_pConnection->createCatalog();
262 0 : if(!xTables.is())
263 0 : throw SQLException();
264 :
265 0 : Reference< XNameAccess> xNames = xTables->getTables();
266 0 : if(!xNames.is())
267 0 : throw SQLException();
268 :
269 0 : ODatabaseMetaDataResultSet::ORows aRows;
270 0 : ODatabaseMetaDataResultSet::ORow aRow(14);
271 :
272 0 : aRow[5] = new ORowSetValueDecorator(OUString());
273 0 : aRow[10] = new ORowSetValueDecorator(OUString("A"));
274 :
275 : Reference< XIndexesSupplier> xTable(
276 0 : xNames->getByName(table), css::uno::UNO_QUERY);
277 0 : aRow[3] = new ORowSetValueDecorator(table);
278 0 : aRow[7] = new ORowSetValueDecorator((sal_Int32)3);
279 :
280 0 : Reference< XNameAccess> xIndexes = xTable->getIndexes();
281 0 : if(!xIndexes.is())
282 0 : throw SQLException();
283 :
284 0 : Sequence< OUString> aIdxNames(xIndexes->getElementNames());
285 :
286 0 : const OUString* pBegin = aIdxNames.getConstArray();
287 0 : const OUString* pEnd = pBegin + aIdxNames.getLength();
288 0 : Reference< XPropertySet> xIndex;
289 0 : for(;pBegin != pEnd;++pBegin)
290 : {
291 0 : xIndex.set(xIndexes->getByName(*pBegin), css::uno::UNO_QUERY);
292 : OSL_ENSURE(xIndex.is(),"Indexes contains a column who isn't a fastpropertyset!");
293 :
294 0 : if(unique && !getBOOL(xIndex->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISUNIQUE))))
295 0 : continue;
296 0 : aRow[4] = new ORowSetValueDecorator(getBOOL(xIndex->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISUNIQUE))));
297 0 : aRow[6] = new ORowSetValueDecorator(*pBegin);
298 :
299 0 : Reference< XUnoTunnel> xTunnel(xIndex,UNO_QUERY);
300 0 : if(xTunnel.is())
301 : {
302 0 : ODbaseIndex* pIndex = reinterpret_cast< ODbaseIndex* >( xTunnel->getSomething(ODbaseIndex::getUnoTunnelImplementationId()) );
303 0 : if(pIndex)
304 : {
305 0 : aRow[11] = new ORowSetValueDecorator((sal_Int32)pIndex->getHeader().db_maxkeys);
306 0 : aRow[12] = new ORowSetValueDecorator((sal_Int32)pIndex->getHeader().db_pagecount);
307 : }
308 : }
309 :
310 0 : Reference<XColumnsSupplier> xColumnsSup(xIndex,UNO_QUERY);
311 0 : Reference< XNameAccess> xColumns = xColumnsSup->getColumns();
312 0 : Sequence< OUString> aColNames(xColumns->getElementNames());
313 :
314 0 : const OUString* pColBegin = aColNames.getConstArray();
315 0 : const OUString* pColEnd = pColBegin + aColNames.getLength();
316 0 : Reference< XPropertySet> xColumn;
317 0 : for(sal_Int32 j=1;pColBegin != pColEnd;++pColBegin,++j)
318 : {
319 0 : aRow[8] = new ORowSetValueDecorator(j);
320 0 : aRow[9] = new ORowSetValueDecorator(*pColBegin);
321 0 : aRows.push_back(aRow);
322 : }
323 0 : }
324 :
325 0 : ::connectivity::ODatabaseMetaDataResultSet* pResult = new ::connectivity::ODatabaseMetaDataResultSet(::connectivity::ODatabaseMetaDataResultSet::eIndexInfo);
326 0 : Reference< XResultSet > xRef = pResult;
327 0 : pResult->setRows(aRows);
328 0 : return xRef;
329 : }
330 :
331 58 : OUString SAL_CALL ODbaseDatabaseMetaData::getURL( ) throw(SQLException, RuntimeException, std::exception)
332 : {
333 58 : ::osl::MutexGuard aGuard( m_aMutex );
334 58 : return OUString("sdbc:dbase:") + m_pConnection->getURL();
335 : }
336 :
337 0 : sal_Int32 SAL_CALL ODbaseDatabaseMetaData::getMaxBinaryLiteralLength( ) throw(SQLException, RuntimeException, std::exception)
338 : {
339 0 : return SAL_MAX_INT32;
340 : }
341 :
342 0 : sal_Int32 SAL_CALL ODbaseDatabaseMetaData::getMaxCharLiteralLength( ) throw(SQLException, RuntimeException, std::exception)
343 : {
344 0 : return 254;
345 : }
346 :
347 0 : sal_Int32 SAL_CALL ODbaseDatabaseMetaData::getMaxColumnNameLength( ) throw(SQLException, RuntimeException, std::exception)
348 : {
349 0 : return 10;
350 : }
351 :
352 0 : sal_Int32 SAL_CALL ODbaseDatabaseMetaData::getMaxColumnsInIndex( ) throw(SQLException, RuntimeException, std::exception)
353 : {
354 0 : return 1;
355 : }
356 :
357 0 : sal_Int32 SAL_CALL ODbaseDatabaseMetaData::getMaxColumnsInTable( ) throw(SQLException, RuntimeException, std::exception)
358 : {
359 0 : return 128;
360 : }
361 :
362 30 : sal_Bool SAL_CALL ODbaseDatabaseMetaData::supportsAlterTableWithAddColumn( ) throw(SQLException, RuntimeException, std::exception)
363 : {
364 30 : return sal_True;
365 : }
366 :
367 30 : sal_Bool SAL_CALL ODbaseDatabaseMetaData::supportsAlterTableWithDropColumn( ) throw(SQLException, RuntimeException, std::exception)
368 : {
369 30 : return sal_False;
370 : }
371 :
372 0 : sal_Bool SAL_CALL ODbaseDatabaseMetaData::isReadOnly( ) throw(SQLException, RuntimeException, std::exception)
373 : {
374 0 : ::osl::MutexGuard aGuard( m_aMutex );
375 :
376 0 : bool bReadOnly = false;
377 0 : static OUString sReadOnly( "IsReadOnly" );
378 0 : ::ucbhelper::Content aFile(m_pConnection->getContent(),Reference< XCommandEnvironment >(), comphelper::getProcessComponentContext());
379 0 : aFile.getPropertyValue(sReadOnly) >>= bReadOnly;
380 :
381 0 : return bReadOnly;
382 : }
383 :
384 0 : bool ODbaseDatabaseMetaData::impl_storesMixedCaseQuotedIdentifiers_throw( )
385 : {
386 0 : return true;
387 : }
388 :
389 58 : bool ODbaseDatabaseMetaData::impl_supportsMixedCaseQuotedIdentifiers_throw( )
390 : {
391 58 : return true;
392 : }
393 :
394 :
395 :
396 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|