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 <sal/config.h>
21
22 #include <string_view>
23
24 #include <ado/ADatabaseMetaData.hxx>
25 #include <ado/ADatabaseMetaDataResultSetMetaData.hxx>
26 #include <ado/Awrapado.hxx>
27 #include <ado/AGroup.hxx>
28 #include <ado/adoimp.hxx>
29 #include <ado/AIndex.hxx>
30 #include <ado/AKey.hxx>
31 #include <ado/ATable.hxx>
32 #include <com/sun/star/sdbc/DataType.hpp>
33 #include <com/sun/star/sdbc/ProcedureResult.hpp>
34 #include <com/sun/star/sdbc/ColumnValue.hpp>
35 #ifdef DELETE
36 #undef DELETE
37 #endif
38 #include <com/sun/star/sdbcx/Privilege.hpp>
39 #include <com/sun/star/sdbcx/PrivilegeObject.hpp>
40 #include <com/sun/star/sdbc/KeyRule.hpp>
41 #include <com/sun/star/sdbcx/KeyType.hpp>
42
43 using namespace connectivity::ado;
44 using namespace ::com::sun::star::sdbc;
45 using namespace ::com::sun::star::sdbcx;
46 using namespace ::com::sun::star::uno;
47
48
fillLiterals()49 void ODatabaseMetaData::fillLiterals()
50 {
51 ADORecordset *pRecordset = nullptr;
52 OLEVariant vtEmpty;
53 vtEmpty.setNoArg();
54 m_pADOConnection->OpenSchema(adSchemaDBInfoLiterals,vtEmpty,vtEmpty,&pRecordset);
55
56 ADOS::ThrowException(*m_pADOConnection,*this);
57
58 OSL_ENSURE(pRecordset,"fillLiterals: no resultset!");
59 if ( pRecordset )
60 {
61 WpADORecordset aRecordset(pRecordset);
62
63 aRecordset.MoveFirst();
64 OLEVariant aValue;
65 LiteralInfo aInfo;
66 while(!aRecordset.IsAtEOF())
67 {
68 WpOLEAppendCollection<ADOFields, ADOField, WpADOField> aFields(aRecordset.GetFields());
69 WpADOField aField(aFields.GetItem(1));
70 aInfo.pwszLiteralValue = aField.get_Value().getString();
71 aField = aFields.GetItem(5);
72 aInfo.fSupported = aField.get_Value().getBool();
73 aField = aFields.GetItem(6);
74 aInfo.cchMaxLen = aField.get_Value().getUInt32();
75
76 aField = aFields.GetItem(4);
77 sal_uInt32 nId = aField.get_Value().getUInt32();
78 m_aLiteralInfo[nId] = aInfo;
79
80 aRecordset.MoveNext();
81 }
82 aRecordset.Close();
83 }
84 }
85
getMaxSize(sal_uInt32 _nId)86 sal_Int32 ODatabaseMetaData::getMaxSize(sal_uInt32 _nId)
87 {
88 if(m_aLiteralInfo.empty())
89 fillLiterals();
90
91 sal_Int32 nSize = 0;
92 std::map<sal_uInt32,LiteralInfo>::const_iterator aIter = m_aLiteralInfo.find(_nId);
93 if(aIter != m_aLiteralInfo.end() && (*aIter).second.fSupported)
94 nSize = (static_cast<sal_Int32>((*aIter).second.cchMaxLen) == -1) ? 0 : (*aIter).second.cchMaxLen;
95 return nSize;
96 }
97
isCapable(sal_uInt32 _nId)98 bool ODatabaseMetaData::isCapable(sal_uInt32 _nId)
99 {
100 if(m_aLiteralInfo.empty())
101 fillLiterals();
102 bool bSupported = false;
103 std::map<sal_uInt32,LiteralInfo>::const_iterator aIter = m_aLiteralInfo.find(_nId);
104 if(aIter != m_aLiteralInfo.end())
105 bSupported = (*aIter).second.fSupported;
106 return bSupported;
107 }
108
109
getLiteral(sal_uInt32 _nId)110 OUString ODatabaseMetaData::getLiteral(sal_uInt32 _nId)
111 {
112 if(m_aLiteralInfo.empty())
113 fillLiterals();
114 OUString sStr;
115 std::map<sal_uInt32,LiteralInfo>::const_iterator aIter = m_aLiteralInfo.find(_nId);
116 if(aIter != m_aLiteralInfo.end() && (*aIter).second.fSupported)
117 sStr = (*aIter).second.pwszLiteralValue;
118 return sStr;
119 }
120
121
setColumnPrivilegesMap()122 void ODatabaseMetaDataResultSetMetaData::setColumnPrivilegesMap()
123 {
124 m_mColumns[8] = OColumn(OUString(),"IS_GRANTABLE",
125 ColumnValue::NULLABLE,
126 3,3,0,
127 DataType::VARCHAR);
128 }
129
setColumnsMap()130 void ODatabaseMetaDataResultSetMetaData::setColumnsMap()
131 {
132 m_mColumns[6] = OColumn(OUString(),"TYPE_NAME",
133 ColumnValue::NO_NULLS,
134 0,0,0,
135 DataType::VARCHAR);
136 m_mColumns[11] = OColumn(OUString(),"NULLABLE",
137 ColumnValue::NO_NULLS,
138 1,1,0,
139 DataType::INTEGER);
140 m_mColumns[12] = OColumn(OUString(),"REMARKS",
141 ColumnValue::NULLABLE,
142 0,0,0,
143 DataType::VARCHAR);
144 m_mColumns[13] = OColumn(OUString(),"COLUMN_DEF",
145 ColumnValue::NULLABLE,
146 0,0,0,
147 DataType::VARCHAR);
148 m_mColumns[14] = OColumn(OUString(),"SQL_DATA_TYPE",
149 ColumnValue::NO_NULLS,
150 1,1,0,
151 DataType::INTEGER);
152 m_mColumns[15] = OColumn(OUString(),"SQL_DATETIME_SUB",
153 ColumnValue::NO_NULLS,
154 1,1,0,
155 DataType::INTEGER);
156 m_mColumns[16] = OColumn(OUString(),"CHAR_OCTET_LENGTH",
157 ColumnValue::NO_NULLS,
158 1,1,0,
159 DataType::INTEGER);
160 }
161
setTablesMap()162 void ODatabaseMetaDataResultSetMetaData::setTablesMap()
163 {
164 m_mColumns[5] = OColumn(OUString(),"REMARKS",
165 ColumnValue::NULLABLE,
166 0,0,0,
167 DataType::VARCHAR);
168 }
169
setProcedureColumnsMap()170 void ODatabaseMetaDataResultSetMetaData::setProcedureColumnsMap()
171 {
172 m_mColumns[12] = OColumn(OUString(),"NULLABLE",
173 ColumnValue::NO_NULLS,
174 1,1,0,
175 DataType::INTEGER);
176 }
177
setPrimaryKeysMap()178 void ODatabaseMetaDataResultSetMetaData::setPrimaryKeysMap()
179 {
180 m_mColumns[5] = OColumn(OUString(),"KEY_SEQ",
181 ColumnValue::NO_NULLS,
182 1,1,0,
183 DataType::INTEGER);
184 m_mColumns[6] = OColumn(OUString(),"PK_NAME",
185 ColumnValue::NULLABLE,
186 0,0,0,
187 DataType::VARCHAR);
188 }
189
setIndexInfoMap()190 void ODatabaseMetaDataResultSetMetaData::setIndexInfoMap()
191 {
192 m_mColumns[4] = OColumn(OUString(),"NON_UNIQUE",
193 ColumnValue::NO_NULLS,
194 1,1,0,
195 DataType::BIT);
196 m_mColumns[5] = OColumn(OUString(),"INDEX_QUALIFIER",
197 ColumnValue::NULLABLE,
198 0,0,0,
199 DataType::VARCHAR);
200 m_mColumns[10] = OColumn(OUString(),"ASC_OR_DESC",
201 ColumnValue::NULLABLE,
202 0,0,0,
203 DataType::VARCHAR);
204 }
205
setTablePrivilegesMap()206 void ODatabaseMetaDataResultSetMetaData::setTablePrivilegesMap()
207 {
208 m_mColumns[6] = OColumn(OUString(),"PRIVILEGE",
209 ColumnValue::NULLABLE,
210 0,0,0,
211 DataType::VARCHAR);
212 m_mColumns[7] = OColumn(OUString(),"IS_GRANTABLE",
213 ColumnValue::NULLABLE,
214 0,0,0,
215 DataType::VARCHAR);
216 }
217
setCrossReferenceMap()218 void ODatabaseMetaDataResultSetMetaData::setCrossReferenceMap()
219 {
220 m_mColumns[9] = OColumn(OUString(),"KEY_SEQ",
221 ColumnValue::NO_NULLS,
222 1,1,0,
223 DataType::INTEGER);
224 }
225
setTypeInfoMap()226 void ODatabaseMetaDataResultSetMetaData::setTypeInfoMap()
227 {
228 m_mColumns[3] = OColumn(OUString(),"PRECISION",
229 ColumnValue::NO_NULLS,
230 1,1,0,
231 DataType::INTEGER);
232 m_mColumns[7] = OColumn(OUString(),"NULLABLE",
233 ColumnValue::NO_NULLS,
234 1,1,0,
235 DataType::INTEGER);
236 m_mColumns[12] = OColumn(OUString(),"AUTO_INCREMENT",
237 ColumnValue::NO_NULLS,
238 1,1,0,
239 DataType::BIT);
240 m_mColumns[16] = OColumn(OUString(),"SQL_DATA_TYPE",
241 ColumnValue::NO_NULLS,
242 1,1,0,
243 DataType::INTEGER);
244 m_mColumns[17] = OColumn(OUString(),"SQL_DATETIME_SUB",
245 ColumnValue::NO_NULLS,
246 1,1,0,
247 DataType::INTEGER);
248 m_mColumns[18] = OColumn(OUString(),"NUM_PREC_RADIX",
249 ColumnValue::NO_NULLS,
250 1,1,0,
251 DataType::INTEGER);
252 }
253
setProceduresMap()254 void ODatabaseMetaDataResultSetMetaData::setProceduresMap()
255 {
256 m_mColumns[7] = OColumn(OUString(),"REMARKS",
257 ColumnValue::NULLABLE,
258 0,0,0,
259 DataType::VARCHAR);
260 }
261
isSearchable(sal_Int32 column)262 sal_Bool SAL_CALL ODatabaseMetaDataResultSetMetaData::isSearchable( sal_Int32 column )
263 {
264 if(!m_mColumns.empty() && (m_mColumnsIter = m_mColumns.find(column)) != m_mColumns.end())
265 return (*m_mColumnsIter).second.isSearchable();
266 return true;
267 }
268
isAutoIncrement(sal_Int32 column)269 sal_Bool SAL_CALL ODatabaseMetaDataResultSetMetaData::isAutoIncrement( sal_Int32 column )
270 {
271 if(!m_mColumns.empty() && (m_mColumnsIter = m_mColumns.find(column)) != m_mColumns.end())
272 return (*m_mColumnsIter).second.isAutoIncrement();
273 return false;
274 }
275
getColumnServiceName(sal_Int32)276 OUString SAL_CALL ODatabaseMetaDataResultSetMetaData::getColumnServiceName( sal_Int32 /*column*/ )
277 {
278 return OUString();
279 }
280
getTableName(sal_Int32 column)281 OUString SAL_CALL ODatabaseMetaDataResultSetMetaData::getTableName( sal_Int32 column )
282 {
283 if(!m_mColumns.empty() && (m_mColumnsIter = m_mColumns.find(column)) != m_mColumns.end())
284 return (*m_mColumnsIter).second.getTableName();
285 return OUString();
286 }
287
getCatalogName(sal_Int32)288 OUString SAL_CALL ODatabaseMetaDataResultSetMetaData::getCatalogName( sal_Int32 /*column*/ )
289 {
290 return OUString();
291 }
292
getColumnTypeName(sal_Int32)293 OUString SAL_CALL ODatabaseMetaDataResultSetMetaData::getColumnTypeName( sal_Int32 /*column*/ )
294 {
295 return OUString();
296 }
297
298
isCaseSensitive(sal_Int32 column)299 sal_Bool SAL_CALL ODatabaseMetaDataResultSetMetaData::isCaseSensitive( sal_Int32 column )
300 {
301 if(!m_mColumns.empty() && (m_mColumnsIter = m_mColumns.find(column)) != m_mColumns.end())
302 return (*m_mColumnsIter).second.isCaseSensitive();
303 return true;
304 }
305
306
getSchemaName(sal_Int32)307 OUString SAL_CALL ODatabaseMetaDataResultSetMetaData::getSchemaName( sal_Int32 /*column*/ )
308 {
309 return OUString();
310 }
311
312
MapObjectType(sal_Int32 ObjType)313 ObjectTypeEnum OAdoGroup::MapObjectType(sal_Int32 ObjType)
314 {
315 ObjectTypeEnum eNumType= adPermObjTable;
316 switch(ObjType)
317 {
318 case PrivilegeObject::TABLE:
319 break;
320 case PrivilegeObject::VIEW:
321 eNumType = adPermObjView;
322 break;
323 case PrivilegeObject::COLUMN:
324 eNumType = adPermObjColumn;
325 break;
326 }
327 return eNumType;
328 }
329
MapRight(RightsEnum _eNum)330 sal_Int32 OAdoGroup::MapRight(RightsEnum _eNum)
331 {
332 sal_Int32 nRight = 0;
333 if(_eNum & adRightRead)
334 nRight |= Privilege::SELECT;
335 if(_eNum & adRightInsert)
336 nRight |= Privilege::INSERT;
337 if(_eNum & adRightUpdate)
338 nRight |= Privilege::UPDATE;
339 if(_eNum & adRightDelete)
340 nRight |= Privilege::DELETE;
341 if(_eNum & adRightReadDesign)
342 nRight |= Privilege::READ;
343 if(_eNum & adRightCreate)
344 nRight |= Privilege::CREATE;
345 if(_eNum & adRightWriteDesign)
346 nRight |= Privilege::ALTER;
347 if(_eNum & adRightReference)
348 nRight |= Privilege::REFERENCE;
349 if(_eNum & adRightDrop)
350 nRight |= Privilege::DROP;
351
352 return nRight;
353 }
354
Map2Right(sal_Int32 _eNum)355 RightsEnum OAdoGroup::Map2Right(sal_Int32 _eNum)
356 {
357 sal_Int32 nRight = adRightNone;
358 if(_eNum & Privilege::SELECT)
359 nRight |= adRightRead;
360
361 if(_eNum & Privilege::INSERT)
362 nRight |= adRightInsert;
363
364 if(_eNum & Privilege::UPDATE)
365 nRight |= adRightUpdate;
366
367 if(_eNum & Privilege::DELETE)
368 nRight |= adRightDelete;
369
370 if(_eNum & Privilege::READ)
371 nRight |= adRightReadDesign;
372
373 if(_eNum & Privilege::CREATE)
374 nRight |= adRightCreate;
375
376 if(_eNum & Privilege::ALTER)
377 nRight |= adRightWriteDesign;
378
379 if(_eNum & Privilege::REFERENCE)
380 nRight |= adRightReference;
381
382 if(_eNum & Privilege::DROP)
383 nRight |= adRightDrop;
384
385 return static_cast<RightsEnum>(nRight);
386 }
387
Create()388 void WpADOIndex::Create()
389 {
390 _ADOIndex* pIndex = nullptr;
391 HRESULT hr = CoCreateInstance(ADOS::CLSID_ADOINDEX_25,
392 nullptr,
393 CLSCTX_INPROC_SERVER,
394 ADOS::IID_ADOINDEX_25,
395 reinterpret_cast<void**>(&pIndex) );
396
397
398 if( !FAILED( hr ) )
399 {
400 operator=( pIndex );
401 pIndex->Release();
402 }
403 }
404
fillPropertyValues()405 void OAdoIndex::fillPropertyValues()
406 {
407 if(m_aIndex.IsValid())
408 {
409 m_Name = m_aIndex.get_Name();
410 m_IsUnique = m_aIndex.get_Unique();
411 m_IsPrimaryKeyIndex = m_aIndex.get_PrimaryKey();
412 m_IsClustered = m_aIndex.get_Clustered();
413 }
414 }
415
Create()416 void WpADOKey::Create()
417 {
418 _ADOKey* pKey = nullptr;
419 HRESULT hr = CoCreateInstance(ADOS::CLSID_ADOKEY_25,
420 nullptr,
421 CLSCTX_INPROC_SERVER,
422 ADOS::IID_ADOKEY_25,
423 reinterpret_cast<void**>(&pKey) );
424
425
426 if( !FAILED( hr ) )
427 {
428 operator=( pKey );
429 pKey->Release();
430 }
431 }
432
fillPropertyValues()433 void OAdoKey::fillPropertyValues()
434 {
435 if(m_aKey.IsValid())
436 {
437 m_aProps->m_Type = MapKeyRule(m_aKey.get_Type());
438 m_Name = m_aKey.get_Name();
439 m_aProps->m_ReferencedTable = m_aKey.get_RelatedTable();
440 m_aProps->m_UpdateRule = MapRule(m_aKey.get_UpdateRule());
441 m_aProps->m_DeleteRule = MapRule(m_aKey.get_DeleteRule());
442 }
443 }
444
MapRule(const RuleEnum & _eNum)445 sal_Int32 OAdoKey::MapRule(const RuleEnum& _eNum)
446 {
447 sal_Int32 eNum = KeyRule::NO_ACTION;
448 switch(_eNum)
449 {
450 case adRICascade:
451 eNum = KeyRule::CASCADE;
452 break;
453 case adRISetNull:
454 eNum = KeyRule::SET_NULL;
455 break;
456 case adRINone:
457 eNum = KeyRule::NO_ACTION;
458 break;
459 case adRISetDefault:
460 eNum = KeyRule::SET_DEFAULT;
461 break;
462 }
463 return eNum;
464 }
465
Map2Rule(sal_Int32 _eNum)466 RuleEnum OAdoKey::Map2Rule(sal_Int32 _eNum)
467 {
468 RuleEnum eNum = adRINone;
469 switch(_eNum)
470 {
471 case KeyRule::CASCADE:
472 eNum = adRICascade;
473 break;
474 case KeyRule::SET_NULL:
475 eNum = adRISetNull;
476 break;
477 case KeyRule::NO_ACTION:
478 eNum = adRINone;
479 break;
480 case KeyRule::SET_DEFAULT:
481 eNum = adRISetDefault;
482 break;
483 }
484 return eNum;
485 }
486
MapKeyRule(const KeyTypeEnum & _eNum)487 sal_Int32 OAdoKey::MapKeyRule(const KeyTypeEnum& _eNum)
488 {
489 sal_Int32 nKeyType = KeyType::PRIMARY;
490 switch(_eNum)
491 {
492 case adKeyPrimary:
493 nKeyType = KeyType::PRIMARY;
494 break;
495 case adKeyForeign:
496 nKeyType = KeyType::FOREIGN;
497 break;
498 case adKeyUnique:
499 nKeyType = KeyType::UNIQUE;
500 break;
501 }
502 return nKeyType;
503 }
504
Map2KeyRule(sal_Int32 _eNum)505 KeyTypeEnum OAdoKey::Map2KeyRule(sal_Int32 _eNum)
506 {
507 KeyTypeEnum eNum( adKeyPrimary );
508 switch(_eNum)
509 {
510 case KeyType::PRIMARY:
511 eNum = adKeyPrimary;
512 break;
513 case KeyType::FOREIGN:
514 eNum = adKeyForeign;
515 break;
516 case KeyType::UNIQUE:
517 eNum = adKeyUnique;
518 break;
519 default:
520 OSL_FAIL( "OAdoKey::Map2KeyRule: invalid key type!" );
521 }
522 return eNum;
523 }
524
Create()525 void WpADOTable::Create()
526 {
527 _ADOTable* pTable = nullptr;
528 HRESULT hr = CoCreateInstance(ADOS::CLSID_ADOTABLE_25,
529 nullptr,
530 CLSCTX_INPROC_SERVER,
531 ADOS::IID_ADOTABLE_25,
532 reinterpret_cast<void**>(&pTable) );
533
534
535 if( !FAILED( hr ) )
536 {
537 operator=( pTable );
538 pTable->Release();
539 }
540 }
541
GetObjectOwner(std::u16string_view _rName,ObjectTypeEnum _eNum)542 OUString WpADOCatalog::GetObjectOwner(std::u16string_view _rName, ObjectTypeEnum _eNum)
543 {
544 OLEVariant _rVar;
545 _rVar.setNoArg();
546 OLEString aBSTR;
547 OLEString sStr1(_rName);
548 pInterface->GetObjectOwner(sStr1.asBSTR(),_eNum,_rVar,aBSTR.getAddress());
549 return aBSTR.asOUString();
550 }
551
fillPropertyValues()552 void OAdoTable::fillPropertyValues()
553 {
554 if(m_aTable.IsValid())
555 {
556 m_Name = m_aTable.get_Name();
557 m_Type = m_aTable.get_Type();
558 {
559 WpADOCatalog aCat(m_aTable.get_ParentCatalog());
560 if(aCat.IsValid())
561 m_CatalogName = aCat.GetObjectOwner(m_aTable.get_Name(),adPermObjTable);
562 }
563 {
564 WpADOProperties aProps = m_aTable.get_Properties();
565 if(aProps.IsValid())
566 m_Description
567 = OTools::getValue(aProps, std::u16string_view(u"Description")).getString();
568 }
569 }
570 }
571
Create()572 void WpADOUser::Create()
573 {
574 _ADOUser* pUser = nullptr;
575 HRESULT hr = CoCreateInstance(ADOS::CLSID_ADOUSER_25,
576 nullptr,
577 CLSCTX_INPROC_SERVER,
578 ADOS::IID_ADOUSER_25,
579 reinterpret_cast<void**>(&pUser) );
580
581
582 if( !FAILED( hr ) )
583 {
584 operator=( pUser );
585 pUser->Release();
586 }
587 }
588
589
590 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
591