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