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 
21 #include <connectivity/PColumn.hxx>
22 #include <connectivity/dbtools.hxx>
23 #include <TConnection.hxx>
24 
25 #include <comphelper/types.hxx>
26 #include <tools/diagnose_ex.h>
27 
28 #include <com/sun/star/sdbc/XResultSetMetaData.hpp>
29 #include <com/sun/star/beans/PropertyAttribute.hpp>
30 
31 using namespace ::comphelper;
32 using namespace connectivity;
33 using namespace dbtools;
34 using namespace connectivity::parse;
35 using namespace ::com::sun::star::uno;
36 using namespace ::com::sun::star::sdbc;
37 using namespace ::com::sun::star::beans;
38 using namespace ::com::sun::star::container;
39 
40 
OParseColumn(const Reference<XPropertySet> & _xColumn,bool _bCase)41 OParseColumn::OParseColumn(const Reference<XPropertySet>& _xColumn, bool _bCase)
42     : connectivity::sdbcx::OColumn( getString(_xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME)))
43                                 ,   getString(_xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPENAME)))
44                                 ,   getString(_xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DEFAULTVALUE)))
45                                 ,   getString(_xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DESCRIPTION)))
46                                 ,   getINT32(_xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISNULLABLE)))
47                                 ,   getINT32(_xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PRECISION)))
48                                 ,   getINT32(_xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_SCALE)))
49                                 ,   getINT32(_xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE)))
50                                 ,   getBOOL(_xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISAUTOINCREMENT)))
51                                 ,   false
52                                 ,   getBOOL(_xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISCURRENCY)))
53                                 ,   _bCase
54                                 ,   getString(_xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_CATALOGNAME)))
55                                 ,   getString(_xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_SCHEMANAME)))
56                                 ,   getString(_xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TABLENAME)))
57                                 )
58     , m_bFunction(false)
59     , m_bDbasePrecisionChanged(false)
60     , m_bAggregateFunction(false)
61     , m_bIsSearchable( true )
62 {
63     construct();
64 }
65 
66 
OParseColumn(const OUString & Name,const OUString & TypeName,const OUString & DefaultValue,const OUString & Description,sal_Int32 IsNullable,sal_Int32 Precision,sal_Int32 Scale,sal_Int32 Type,bool IsAutoIncrement,bool IsCurrency,bool _bCase,const OUString & CatalogName,const OUString & SchemaName,const OUString & TableName)67 OParseColumn::OParseColumn( const OUString& Name,
68                     const OUString& TypeName,
69                     const OUString& DefaultValue,
70                     const OUString& Description,
71                     sal_Int32       IsNullable,
72                     sal_Int32       Precision,
73                     sal_Int32       Scale,
74                     sal_Int32       Type,
75                     bool            IsAutoIncrement,
76                     bool            IsCurrency,
77                     bool            _bCase,
78                     const OUString& CatalogName,
79                     const OUString& SchemaName,
80                     const OUString& TableName
81                 ) : connectivity::sdbcx::OColumn(Name,
82                                   TypeName,
83                                   DefaultValue,
84                                   Description,
85                                   IsNullable,
86                                   Precision,
87                                   Scale,
88                                   Type,
89                                   IsAutoIncrement,
90                                   false,
91                                   IsCurrency,
92                                   _bCase,
93                                   CatalogName,
94                                   SchemaName,
95                                   TableName)
96     , m_bFunction(false)
97     , m_bDbasePrecisionChanged(false)
98     , m_bAggregateFunction(false)
99     , m_bIsSearchable( true )
100 {
101     construct();
102 }
103 
104 
createColumnsForResultSet(const Reference<XResultSetMetaData> & _rxResMetaData,const Reference<XDatabaseMetaData> & _rxDBMetaData,const Reference<XNameAccess> & i_xQueryColumns)105 ::rtl::Reference< OSQLColumns > OParseColumn::createColumnsForResultSet( const Reference< XResultSetMetaData >& _rxResMetaData,
106     const Reference< XDatabaseMetaData >& _rxDBMetaData,const Reference< XNameAccess>& i_xQueryColumns )
107 {
108     sal_Int32 nColumnCount = _rxResMetaData->getColumnCount();
109     ::rtl::Reference aReturn( new OSQLColumns ); aReturn->get().reserve( nColumnCount );
110 
111     StringMap aColumnMap;
112     for ( sal_Int32 i = 1; i <= nColumnCount; ++i )
113     {
114         OParseColumn* pColumn = createColumnForResultSet( _rxResMetaData, _rxDBMetaData, i,aColumnMap );
115         aReturn->get().push_back( pColumn );
116         if ( i_xQueryColumns.is() && i_xQueryColumns->hasByName(pColumn->getRealName()) )
117         {
118             Reference<XPropertySet> xColumn(i_xQueryColumns->getByName(pColumn->getRealName()),UNO_QUERY_THROW);
119             OUString sLabel;
120             xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_LABEL)) >>= sLabel;
121             if ( !sLabel.isEmpty() )
122                 pColumn->setLabel(sLabel);
123         }
124     }
125 
126     return aReturn;
127 }
128 
129 
createColumnForResultSet(const Reference<XResultSetMetaData> & _rxResMetaData,const Reference<XDatabaseMetaData> & _rxDBMetaData,sal_Int32 _nColumnPos,StringMap & _rColumns)130 OParseColumn* OParseColumn::createColumnForResultSet( const Reference< XResultSetMetaData >& _rxResMetaData,
131     const Reference< XDatabaseMetaData >& _rxDBMetaData, sal_Int32 _nColumnPos, StringMap& _rColumns )
132 {
133     OUString sLabel = _rxResMetaData->getColumnLabel( _nColumnPos );
134     // retrieve the name of the column
135     // check for duplicate entries
136     if(_rColumns.find(sLabel) != _rColumns.end())
137     {
138         OUString sAlias(sLabel);
139         sal_Int32 searchIndex=1;
140         while(_rColumns.find(sAlias) != _rColumns.end())
141         {
142             sAlias = sLabel + OUString::number(searchIndex++);
143         }
144         sLabel = sAlias;
145     }
146     _rColumns.emplace(sLabel,0);
147     OParseColumn* pColumn = new OParseColumn(
148         sLabel,
149         _rxResMetaData->getColumnTypeName( _nColumnPos ),
150         OUString(),
151         OUString(),
152         _rxResMetaData->isNullable( _nColumnPos ),
153         _rxResMetaData->getPrecision( _nColumnPos ),
154         _rxResMetaData->getScale( _nColumnPos ),
155         _rxResMetaData->getColumnType( _nColumnPos ),
156         _rxResMetaData->isAutoIncrement( _nColumnPos ),
157         _rxResMetaData->isCurrency( _nColumnPos ),
158         _rxDBMetaData->supportsMixedCaseQuotedIdentifiers(),
159         _rxResMetaData->getCatalogName( _nColumnPos ),
160         _rxResMetaData->getSchemaName( _nColumnPos ),
161         _rxResMetaData->getTableName( _nColumnPos )
162     );
163     pColumn->setIsSearchable( _rxResMetaData->isSearchable( _nColumnPos ) );
164     pColumn->setRealName(_rxResMetaData->getColumnName( _nColumnPos ));
165     pColumn->setLabel(sLabel);
166     return pColumn;
167 }
168 
169 
~OParseColumn()170 OParseColumn::~OParseColumn()
171 {
172 }
173 
construct()174 void OParseColumn::construct()
175 {
176     registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FUNCTION),                PROPERTY_ID_FUNCTION,               0,  &m_bFunction,               cppu::UnoType<decltype(m_bFunction)>::get());
177     registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_AGGREGATEFUNCTION),       PROPERTY_ID_AGGREGATEFUNCTION,      0,  &m_bAggregateFunction,      cppu::UnoType<decltype(m_bAggregateFunction)>::get());
178     registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_REALNAME),                PROPERTY_ID_REALNAME,               0,  &m_aRealName,               cppu::UnoType<decltype(m_aRealName)>::get());
179     registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DBASEPRECISIONCHANGED),   PROPERTY_ID_DBASEPRECISIONCHANGED,  0,  &m_bDbasePrecisionChanged,  cppu::UnoType<decltype(m_bDbasePrecisionChanged)>::get());
180     registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISSEARCHABLE),            PROPERTY_ID_ISSEARCHABLE,           0,  &m_bIsSearchable,           cppu::UnoType<decltype(m_bIsSearchable)>::get());
181     registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_LABEL),                   PROPERTY_ID_LABEL,                  0,  &m_sLabel,                  cppu::UnoType<decltype(m_sLabel)>::get());
182 }
183 
createArrayHelper() const184 ::cppu::IPropertyArrayHelper* OParseColumn::createArrayHelper() const
185 {
186     return doCreateArrayHelper();
187 }
188 
getInfoHelper()189 ::cppu::IPropertyArrayHelper & SAL_CALL OParseColumn::getInfoHelper()
190 {
191     OSL_ENSURE( !isNew(), "OParseColumn::getInfoHelper: a *new* ParseColumn?" );
192     return *OParseColumn_PROP::getArrayHelper();
193 }
194 
195 
OOrderColumn(const Reference<XPropertySet> & _xColumn,const OUString & i_rOriginatingTableName,bool _bCase,bool _bAscending)196 OOrderColumn::OOrderColumn( const Reference<XPropertySet>& _xColumn, const OUString& i_rOriginatingTableName,
197                             bool _bCase, bool _bAscending )
198     : connectivity::sdbcx::OColumn(
199         getString(_xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME))),
200         getString(_xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPENAME))),
201         getString(_xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DEFAULTVALUE))),
202         getString(_xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DESCRIPTION))),
203         getINT32(_xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISNULLABLE))),
204         getINT32(_xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PRECISION))),
205         getINT32(_xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_SCALE))),
206         getINT32(_xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE))),
207         getBOOL(_xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISAUTOINCREMENT))),
208         false,
209         getBOOL(_xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISCURRENCY))),
210         _bCase,
211         getString(_xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_CATALOGNAME))),
212         getString(_xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_SCHEMANAME))),
213         i_rOriginatingTableName
214     )
215     ,m_bAscending(_bAscending)
216 {
217     construct();
218 }
219 
220 
OOrderColumn(const Reference<XPropertySet> & _xColumn,bool _bCase,bool _bAscending)221 OOrderColumn::OOrderColumn( const Reference<XPropertySet>& _xColumn, bool _bCase, bool _bAscending )
222     : connectivity::sdbcx::OColumn(
223         getString(_xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME))),
224         getString(_xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPENAME))),
225         getString(_xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DEFAULTVALUE))),
226         getString(_xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DESCRIPTION))),
227         getINT32(_xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISNULLABLE))),
228         getINT32(_xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PRECISION))),
229         getINT32(_xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_SCALE))),
230         getINT32(_xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE))),
231         getBOOL(_xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISAUTOINCREMENT))),
232         false,
233         getBOOL(_xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISCURRENCY))),
234         _bCase,
235         getString(_xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_CATALOGNAME))),
236         getString(_xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_SCHEMANAME))),
237         getString(_xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TABLENAME)))
238     )
239     ,m_bAscending(_bAscending)
240 {
241     construct();
242 }
243 
244 
~OOrderColumn()245 OOrderColumn::~OOrderColumn()
246 {
247 }
248 
249 
construct()250 void OOrderColumn::construct()
251 {
252     registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISASCENDING), PROPERTY_ID_ISASCENDING,
253         PropertyAttribute::READONLY,  const_cast< bool* >( &m_bAscending ),    cppu::UnoType<decltype(m_bAscending)>::get() );
254 }
255 
createArrayHelper() const256 ::cppu::IPropertyArrayHelper* OOrderColumn::createArrayHelper() const
257 {
258     return doCreateArrayHelper();
259 }
260 
getInfoHelper()261 ::cppu::IPropertyArrayHelper & SAL_CALL OOrderColumn::getInfoHelper()
262 {
263     OSL_ENSURE( !isNew(), "OOrderColumn::getInfoHelper: a *new* OrderColumn?" );
264     return *OOrderColumn_PROP::getArrayHelper();
265 }
266 
getSupportedServiceNames()267 css::uno::Sequence< OUString > SAL_CALL OOrderColumn::getSupportedServiceNames(  )
268 {
269     css::uno::Sequence< OUString > aSupported { "com.sun.star.sdb.OrderColumn" };
270 
271     return aSupported;
272 }
273 
274 
275 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
276