1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_connectivity.hxx"
30 
31 
32 #include "flat/EDatabaseMetaData.hxx"
33 #include <com/sun/star/sdbc/DataType.hpp>
34 #include <com/sun/star/sdbc/ResultSetType.hpp>
35 #include <com/sun/star/sdbc/ColumnValue.hpp>
36 #include <com/sun/star/beans/XFastPropertySet.hpp>
37 #include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
38 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
39 #include <com/sun/star/sdbcx/XIndexesSupplier.hpp>
40 #include <tools/urlobj.hxx>
41 #include "FDatabaseMetaDataResultSet.hxx"
42 #include <com/sun/star/lang/XUnoTunnel.hpp>
43 #include <comphelper/extract.hxx>
44 #include <comphelper/types.hxx>
45 #include <rtl/logfile.hxx>
46 
47 using namespace ::comphelper;
48 
49 using namespace connectivity;
50 using namespace connectivity::flat;
51 //	using namespace connectivity::file;
52 using namespace ::com::sun::star::uno;
53 using namespace ::com::sun::star::beans;
54 using namespace ::com::sun::star::sdbcx;
55 using namespace ::com::sun::star::sdbc;
56 using namespace ::com::sun::star::container;
57 
58 
59 
60 OFlatDatabaseMetaData::OFlatDatabaseMetaData(::connectivity::file::OConnection* _pCon) 	:ODatabaseMetaData(_pCon)
61 {
62     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "flat", "Ocke.Janssen@sun.com", "OFlatDatabaseMetaData::OFlatDatabaseMetaData" );
63 }
64 // -------------------------------------------------------------------------
65 OFlatDatabaseMetaData::~OFlatDatabaseMetaData()
66 {
67     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "flat", "Ocke.Janssen@sun.com", "OFlatDatabaseMetaData::~OFlatDatabaseMetaData" );
68 }
69 // -------------------------------------------------------------------------
70 Reference< XResultSet > OFlatDatabaseMetaData::impl_getTypeInfo_throw(  )
71 {
72     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "flat", "Ocke.Janssen@sun.com", "OFlatDatabaseMetaData::impl_getTypeInfo_throw" );
73 	::osl::MutexGuard aGuard( m_aMutex );
74 
75     ::connectivity::ODatabaseMetaDataResultSet* pResult = new ::connectivity::ODatabaseMetaDataResultSet(::connectivity::ODatabaseMetaDataResultSet::eTypeInfo);
76     Reference< XResultSet > xRef = pResult;
77 
78 	static ODatabaseMetaDataResultSet::ORows aRows;
79 	if(aRows.empty())
80 	{
81 		ODatabaseMetaDataResultSet::ORow aRow;
82 
83 		aRow.push_back(ODatabaseMetaDataResultSet::getEmptyValue());
84 		aRow.push_back(new ORowSetValueDecorator(::rtl::OUString::createFromAscii("CHAR")));
85 		aRow.push_back(new ORowSetValueDecorator(DataType::CHAR));
86 		aRow.push_back(new ORowSetValueDecorator((sal_Int32)254));
87 		aRow.push_back(ODatabaseMetaDataResultSet::getQuoteValue());
88 		aRow.push_back(ODatabaseMetaDataResultSet::getQuoteValue());
89 		aRow.push_back(ODatabaseMetaDataResultSet::getEmptyValue());
90 		aRow.push_back(new ORowSetValueDecorator((sal_Int32)ColumnValue::NULLABLE));
91 		aRow.push_back(ODatabaseMetaDataResultSet::get1Value());
92 		aRow.push_back(new ORowSetValueDecorator((sal_Int32)ColumnSearch::CHAR));
93 		aRow.push_back(ODatabaseMetaDataResultSet::get1Value());
94 		aRow.push_back(ODatabaseMetaDataResultSet::get0Value());
95 		aRow.push_back(ODatabaseMetaDataResultSet::get0Value());
96 		aRow.push_back(ODatabaseMetaDataResultSet::getEmptyValue());
97 		aRow.push_back(ODatabaseMetaDataResultSet::get0Value());
98 		aRow.push_back(ODatabaseMetaDataResultSet::get0Value());
99 		aRow.push_back(ODatabaseMetaDataResultSet::getEmptyValue());
100 		aRow.push_back(ODatabaseMetaDataResultSet::getEmptyValue());
101 		aRow.push_back(new ORowSetValueDecorator((sal_Int32)10));
102 
103 		aRows.push_back(aRow);
104 
105 		aRow[1] = new ORowSetValueDecorator(::rtl::OUString::createFromAscii("VARCHAR"));
106 		aRow[2] = new ORowSetValueDecorator(DataType::VARCHAR);
107 		aRow[4] = ODatabaseMetaDataResultSet::getQuoteValue();
108 		aRow[5] = ODatabaseMetaDataResultSet::getQuoteValue();
109 		aRows.push_back(aRow);
110 
111 
112 		aRow[1] = new ORowSetValueDecorator(::rtl::OUString::createFromAscii("LONGVARCHAR"));
113 		aRow[2] = new ORowSetValueDecorator(DataType::LONGVARCHAR);
114 		aRow[3] = new ORowSetValueDecorator((sal_Int32)65535);
115 		aRow[4] = ODatabaseMetaDataResultSet::getQuoteValue();
116 		aRow[5] = ODatabaseMetaDataResultSet::getQuoteValue();
117 		aRows.push_back(aRow);
118 
119 		aRow[1] = new ORowSetValueDecorator(::rtl::OUString::createFromAscii("DATE"));
120 		aRow[2] = new ORowSetValueDecorator(DataType::DATE);
121 		aRow[3] = new ORowSetValueDecorator((sal_Int32)10);
122 		aRow[4] = ODatabaseMetaDataResultSet::getQuoteValue();
123 		aRow[5] = ODatabaseMetaDataResultSet::getQuoteValue();
124 		aRows.push_back(aRow);
125 
126 		aRow[1] = new ORowSetValueDecorator(::rtl::OUString::createFromAscii("TIME"));
127 		aRow[2] = new ORowSetValueDecorator(DataType::TIME);
128 		aRow[3] = new ORowSetValueDecorator((sal_Int32)8);
129 		aRow[4] = ODatabaseMetaDataResultSet::getQuoteValue();
130 		aRow[5] = ODatabaseMetaDataResultSet::getQuoteValue();
131 		aRows.push_back(aRow);
132 
133 		aRow[1] = new ORowSetValueDecorator(::rtl::OUString::createFromAscii("TIMESTAMP"));
134 		aRow[2] = new ORowSetValueDecorator(DataType::TIMESTAMP);
135 		aRow[3] = new ORowSetValueDecorator((sal_Int32)19);
136 		aRow[4] = ODatabaseMetaDataResultSet::getQuoteValue();
137 		aRow[5] = ODatabaseMetaDataResultSet::getQuoteValue();
138 		aRows.push_back(aRow);
139 
140 		aRow[1] = new ORowSetValueDecorator(::rtl::OUString::createFromAscii("BOOL"));
141 		aRow[2] = new ORowSetValueDecorator(DataType::BIT);
142 		aRow[3] = ODatabaseMetaDataResultSet::get1Value();
143 		aRow[9] = ODatabaseMetaDataResultSet::getBasicValue();
144 		aRows.push_back(aRow);
145 
146 		aRow[1] = new ORowSetValueDecorator(::rtl::OUString::createFromAscii("DECIMAL"));
147 		aRow[2] = new ORowSetValueDecorator(DataType::DECIMAL);
148 		aRow[3] = new ORowSetValueDecorator((sal_Int32)20);
149 		aRow[15] = new ORowSetValueDecorator((sal_Int32)15);
150 		aRows.push_back(aRow);
151 
152 		aRow[1] = new ORowSetValueDecorator(::rtl::OUString::createFromAscii("DOUBLE"));
153 		aRow[2] = new ORowSetValueDecorator(DataType::DOUBLE);
154 		aRow[3] = new ORowSetValueDecorator((sal_Int32)20);
155 		aRow[15] = ODatabaseMetaDataResultSet::get0Value();
156 		aRows.push_back(aRow);
157 
158 		aRow[1] = new ORowSetValueDecorator(::rtl::OUString::createFromAscii("NUMERIC"));
159 		aRow[2] = new ORowSetValueDecorator(DataType::NUMERIC);
160 		aRow[3] = new ORowSetValueDecorator((sal_Int32)20);
161 		aRow[15] = new ORowSetValueDecorator((sal_Int32)20);
162 		aRows.push_back(aRow);
163 	}
164 
165 	pResult->setRows(aRows);
166 	return xRef;
167 }
168 // -------------------------------------------------------------------------
169 Reference< XResultSet > SAL_CALL OFlatDatabaseMetaData::getColumns(
170 	const Any& /*catalog*/, const ::rtl::OUString& /*schemaPattern*/, const ::rtl::OUString& tableNamePattern,
171         const ::rtl::OUString& columnNamePattern ) throw(SQLException, RuntimeException)
172 {
173     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "flat", "Ocke.Janssen@sun.com", "OFlatDatabaseMetaData::getColumns" );
174 	::osl::MutexGuard aGuard( m_aMutex );
175 
176     Reference< XTablesSupplier > xTables = m_pConnection->createCatalog();
177 	if(!xTables.is())
178         throw SQLException();
179 
180 	Reference< XNameAccess> xNames = xTables->getTables();
181 	if(!xNames.is())
182 		throw SQLException();
183 
184 	ODatabaseMetaDataResultSet::ORows aRows;
185 	ODatabaseMetaDataResultSet::ORow aRow(19);
186 	aRow[10] = new ORowSetValueDecorator((sal_Int32)10);
187 	Sequence< ::rtl::OUString> aTabNames(xNames->getElementNames());
188 	const ::rtl::OUString* pTabBegin	= aTabNames.getConstArray();
189 	const ::rtl::OUString* pTabEnd		= pTabBegin + aTabNames.getLength();
190 	for(;pTabBegin != pTabEnd;++pTabBegin)
191 	{
192 		if(match(tableNamePattern,*pTabBegin,'\0'))
193 		{
194 			Reference< XColumnsSupplier> xTable;
195 			::cppu::extractInterface(xTable,xNames->getByName(*pTabBegin));
196 			aRow[3] = new ORowSetValueDecorator(*pTabBegin);
197 
198 			Reference< XNameAccess> xColumns = xTable->getColumns();
199 			if(!xColumns.is())
200 				throw SQLException();
201 
202 			Sequence< ::rtl::OUString> aColNames(xColumns->getElementNames());
203 
204 			const ::rtl::OUString* pBegin = aColNames.getConstArray();
205 			const ::rtl::OUString* pEnd = pBegin + aColNames.getLength();
206 			Reference< XPropertySet> xColumn;
207 			for(sal_Int32 i=1;pBegin != pEnd;++pBegin,++i)
208 			{
209 				if(match(columnNamePattern,*pBegin,'\0'))
210 				{
211 					aRow[4] = new ORowSetValueDecorator(*pBegin);
212 
213 					::cppu::extractInterface(xColumn,xColumns->getByName(*pBegin));
214 					OSL_ENSURE(xColumn.is(),"Columns contains a column who isn't a fastpropertyset!");
215 					aRow[5] = new ORowSetValueDecorator(getINT32(xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE))));
216 					aRow[6] = new ORowSetValueDecorator(getString(xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPENAME))));
217 					aRow[7] = new ORowSetValueDecorator(getINT32(xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PRECISION))));
218 					aRow[9] = new ORowSetValueDecorator(getINT32(xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_SCALE))));
219 					aRow[11] = new ORowSetValueDecorator(getINT32(xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISNULLABLE))));
220 					aRow[13] = new ORowSetValueDecorator(getString(xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DEFAULTVALUE))));
221 
222 					switch((sal_Int32)aRow[5]->getValue())
223 					{
224 					case DataType::CHAR:
225 					case DataType::VARCHAR:
226 						aRow[16] = new ORowSetValueDecorator((sal_Int32)254);
227 						break;
228 					case DataType::LONGVARCHAR:
229 						aRow[16] = new ORowSetValueDecorator((sal_Int32)65535);
230 						break;
231 					default:
232 						aRow[16] = new ORowSetValueDecorator((sal_Int32)0);
233 					}
234 					aRow[17] = new ORowSetValueDecorator(i);
235 					switch(sal_Int32(aRow[11]->getValue()))
236 					{
237 					case ColumnValue::NO_NULLS:
238 						aRow[18]  = new ORowSetValueDecorator(::rtl::OUString::createFromAscii("NO"));
239 						break;
240 					case ColumnValue::NULLABLE:
241 						aRow[18]  = new ORowSetValueDecorator(::rtl::OUString::createFromAscii("YES"));
242 						break;
243 					default:
244 						aRow[18]  = new ORowSetValueDecorator(::rtl::OUString());
245 					}
246 					aRows.push_back(aRow);
247 				}
248 			}
249 		}
250 	}
251 
252     ::connectivity::ODatabaseMetaDataResultSet* pResult = new ::connectivity::ODatabaseMetaDataResultSet(::connectivity::ODatabaseMetaDataResultSet::eColumns);
253 	Reference< XResultSet > xRef = pResult;
254 	pResult->setRows(aRows);
255 
256 	return xRef;
257 }
258 // -------------------------------------------------------------------------
259 ::rtl::OUString SAL_CALL OFlatDatabaseMetaData::getURL(  ) throw(SQLException, RuntimeException)
260 {
261     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "flat", "Ocke.Janssen@sun.com", "OFlatDatabaseMetaData::getURL" );
262 	::osl::MutexGuard aGuard( m_aMutex );
263 	return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("sdbc:flat:")) + m_pConnection->getURL();
264 }
265 // -----------------------------------------------------------------------------
266 
267 
268