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 "DatabaseMetaData.hxx"
21 : #include "Util.hxx"
22 :
23 : #include <ibase.h>
24 : #include <rtl/ustrbuf.hxx>
25 : #include <FDatabaseMetaDataResultSet.hxx>
26 :
27 : #include <com/sun/star/sdbc/ColumnValue.hpp>
28 : #include <com/sun/star/sdbc/DataType.hpp>
29 : #include <com/sun/star/sdbc/IndexType.hpp>
30 : #include <com/sun/star/sdbc/ResultSetType.hpp>
31 : #include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
32 : #include <com/sun/star/sdbc/TransactionIsolation.hpp>
33 : #include <com/sun/star/sdbc/XParameters.hpp>
34 : #include <com/sun/star/sdbc/XRow.hpp>
35 :
36 : using namespace connectivity::firebird;
37 :
38 : using namespace ::rtl;
39 :
40 : using namespace com::sun::star;
41 : using namespace com::sun::star::uno;
42 : using namespace com::sun::star::lang;
43 : using namespace com::sun::star::beans;
44 : using namespace com::sun::star::sdbc;
45 :
46 0 : ODatabaseMetaData::ODatabaseMetaData(Connection* _pCon)
47 0 : : m_pConnection(_pCon)
48 : {
49 : OSL_ENSURE(m_pConnection,"ODatabaseMetaData::ODatabaseMetaData: No connection set!");
50 0 : }
51 :
52 0 : ODatabaseMetaData::~ODatabaseMetaData()
53 : {
54 0 : }
55 :
56 : //----- Catalog Info -- UNSUPPORTED -------------------------------------------
57 0 : OUString SAL_CALL ODatabaseMetaData::getCatalogSeparator() throw(SQLException, RuntimeException, std::exception)
58 : {
59 0 : return OUString();
60 : }
61 :
62 0 : sal_Int32 SAL_CALL ODatabaseMetaData::getMaxCatalogNameLength() throw(SQLException, RuntimeException, std::exception)
63 : {
64 0 : return -1;
65 : }
66 :
67 0 : OUString SAL_CALL ODatabaseMetaData::getCatalogTerm() throw(SQLException, RuntimeException, std::exception)
68 : {
69 0 : return OUString();
70 : }
71 :
72 0 : sal_Bool SAL_CALL ODatabaseMetaData::isCatalogAtStart() throw(SQLException, RuntimeException, std::exception)
73 : {
74 0 : return sal_False;
75 : }
76 :
77 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsCatalogsInTableDefinitions() throw(SQLException, RuntimeException, std::exception)
78 : {
79 0 : return sal_False;
80 : }
81 :
82 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsCatalogsInIndexDefinitions() throw(SQLException, RuntimeException, std::exception)
83 : {
84 0 : return sal_False;
85 : }
86 :
87 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsCatalogsInDataManipulation( ) throw(SQLException, RuntimeException, std::exception)
88 : {
89 0 : return sal_False;
90 : }
91 :
92 0 : uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getCatalogs() throw(SQLException, RuntimeException, std::exception)
93 : {
94 : OSL_FAIL("Not implemented yet!");
95 : // TODO implement
96 0 : return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eCatalogs);
97 : }
98 :
99 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsCatalogsInProcedureCalls() throw(SQLException, RuntimeException, std::exception)
100 : {
101 0 : return sal_False;
102 : }
103 :
104 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsCatalogsInPrivilegeDefinitions() throw(SQLException, RuntimeException, std::exception)
105 : {
106 0 : return sal_False;
107 : }
108 :
109 : //----- Schema Info -- UNSUPPORTED --------------------------------------------
110 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsSchemasInProcedureCalls()
111 : throw(SQLException, RuntimeException, std::exception)
112 : {
113 0 : return sal_False;
114 : }
115 :
116 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsSchemasInPrivilegeDefinitions()
117 : throw(SQLException, RuntimeException, std::exception)
118 : {
119 0 : return sal_False;
120 : }
121 :
122 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsSchemasInDataManipulation()
123 : throw(SQLException, RuntimeException, std::exception)
124 : {
125 0 : return sal_False;
126 : }
127 :
128 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsSchemasInIndexDefinitions()
129 : throw(SQLException, RuntimeException, std::exception)
130 : {
131 0 : return sal_False;
132 : }
133 :
134 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsSchemasInTableDefinitions()
135 : throw(SQLException, RuntimeException, std::exception)
136 : {
137 0 : return sal_False;
138 : }
139 :
140 0 : sal_Int32 SAL_CALL ODatabaseMetaData::getMaxSchemaNameLength()
141 : throw(SQLException, RuntimeException, std::exception)
142 : {
143 0 : return -1;
144 : }
145 :
146 0 : OUString SAL_CALL ODatabaseMetaData::getSchemaTerm()
147 : throw(SQLException, RuntimeException, std::exception)
148 : {
149 0 : return OUString();
150 : }
151 :
152 0 : uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getSchemas()
153 : throw(SQLException, RuntimeException, std::exception)
154 : {
155 : OSL_FAIL("Not implemented yet!");
156 : // TODO implement
157 0 : return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eSchemas);
158 : }
159 :
160 : //----- Max Sizes/Lengths -----------------------------------------------------
161 0 : sal_Int32 SAL_CALL ODatabaseMetaData::getMaxBinaryLiteralLength() throw(SQLException, RuntimeException, std::exception)
162 : {
163 0 : return 32767;
164 : }
165 :
166 0 : sal_Int32 SAL_CALL ODatabaseMetaData::getMaxRowSize() throw(SQLException, RuntimeException, std::exception)
167 : {
168 0 : return 32767;
169 : }
170 :
171 0 : sal_Int32 SAL_CALL ODatabaseMetaData::getMaxCharLiteralLength() throw(SQLException, RuntimeException, std::exception)
172 : {
173 0 : return 32767;
174 : }
175 :
176 0 : sal_Int32 SAL_CALL ODatabaseMetaData::getMaxColumnNameLength() throw(SQLException, RuntimeException, std::exception)
177 : {
178 0 : return 31;
179 : }
180 :
181 0 : sal_Int32 SAL_CALL ODatabaseMetaData::getMaxColumnsInIndex() throw(SQLException, RuntimeException, std::exception)
182 : {
183 : // TODO: No idea.
184 : // See: http://www.firebirdsql.org/en/firebird-technical-specifications/
185 0 : return 16;
186 : }
187 :
188 0 : sal_Int32 SAL_CALL ODatabaseMetaData::getMaxCursorNameLength() throw(SQLException, RuntimeException, std::exception)
189 : {
190 0 : return 32;
191 : }
192 :
193 0 : sal_Int32 SAL_CALL ODatabaseMetaData::getMaxConnections() throw(SQLException, RuntimeException, std::exception)
194 : {
195 0 : return 100; // Arbitrary
196 : }
197 :
198 0 : sal_Int32 SAL_CALL ODatabaseMetaData::getMaxColumnsInTable() throw(SQLException, RuntimeException, std::exception)
199 : {
200 : // May however be smaller.
201 : // See: http://www.firebirdsql.org/en/firebird-technical-specifications/
202 0 : return 32767;
203 : }
204 :
205 0 : sal_Int32 SAL_CALL ODatabaseMetaData::getMaxStatementLength() throw(SQLException, RuntimeException, std::exception)
206 : {
207 0 : return 32767;
208 : }
209 :
210 0 : sal_Int32 SAL_CALL ODatabaseMetaData::getMaxTableNameLength() throw(SQLException, RuntimeException, std::exception)
211 : {
212 0 : return 31;
213 : }
214 :
215 0 : sal_Int32 SAL_CALL ODatabaseMetaData::getMaxTablesInSelect( ) throw(SQLException, RuntimeException, std::exception)
216 : {
217 0 : sal_Int32 nValue = 0; // 0 means no limit
218 0 : return nValue;
219 : }
220 :
221 :
222 0 : sal_Bool SAL_CALL ODatabaseMetaData::doesMaxRowSizeIncludeBlobs( ) throw(SQLException, RuntimeException, std::exception)
223 : {
224 0 : return sal_False;
225 : }
226 :
227 : // ---- Identifiers -----------------------------------------------------------
228 : // Only quoted identifiers are case sensitive, unquoted are case insensitive
229 0 : OUString SAL_CALL ODatabaseMetaData::getIdentifierQuoteString()
230 : throw(SQLException, RuntimeException, std::exception)
231 : {
232 0 : OUString aVal('"');
233 0 : return aVal;
234 : }
235 :
236 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsMixedCaseQuotedIdentifiers( ) throw(SQLException, RuntimeException, std::exception)
237 : {
238 0 : return sal_True;
239 : }
240 :
241 0 : sal_Bool SAL_CALL ODatabaseMetaData::storesLowerCaseQuotedIdentifiers()
242 : throw(SQLException, RuntimeException, std::exception)
243 : {
244 0 : return sal_False;
245 : }
246 :
247 0 : sal_Bool SAL_CALL ODatabaseMetaData::storesMixedCaseQuotedIdentifiers()
248 : throw(SQLException, RuntimeException, std::exception)
249 : {
250 : // TODO: confirm this -- the documentation is highly ambiguous
251 : // However it seems this should be true as quoted identifiers ARE
252 : // stored mixed case.
253 0 : return sal_True;
254 : }
255 :
256 0 : sal_Bool SAL_CALL ODatabaseMetaData::storesUpperCaseQuotedIdentifiers()
257 : throw(SQLException, RuntimeException, std::exception)
258 : {
259 0 : return sal_False;
260 : }
261 :
262 : // ---- Unquoted Identifiers -------------------------------------------------
263 : // All unquoted identifers are stored upper case.
264 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsMixedCaseIdentifiers()
265 : throw(SQLException, RuntimeException, std::exception)
266 : {
267 0 : return sal_False;
268 : }
269 :
270 0 : sal_Bool SAL_CALL ODatabaseMetaData::storesLowerCaseIdentifiers()
271 : throw(SQLException, RuntimeException, std::exception)
272 : {
273 0 : return sal_False;
274 : }
275 :
276 0 : sal_Bool SAL_CALL ODatabaseMetaData::storesMixedCaseIdentifiers()
277 : throw(SQLException, RuntimeException, std::exception)
278 : {
279 0 : return sal_False;
280 : }
281 :
282 0 : sal_Bool SAL_CALL ODatabaseMetaData::storesUpperCaseIdentifiers()
283 : throw(SQLException, RuntimeException, std::exception)
284 : {
285 0 : return sal_True;
286 : }
287 :
288 : // ---- SQL Feature Support ---------------------------------------------------
289 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsCoreSQLGrammar()
290 : throw(SQLException, RuntimeException, std::exception)
291 : {
292 0 : return sal_True;
293 : }
294 :
295 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsMinimumSQLGrammar()
296 : throw(SQLException, RuntimeException, std::exception)
297 : {
298 0 : return sal_True;
299 : }
300 :
301 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsAlterTableWithAddColumn()
302 : throw(SQLException, RuntimeException, std::exception)
303 : {
304 0 : return sal_True;
305 : }
306 :
307 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsAlterTableWithDropColumn()
308 : throw(SQLException, RuntimeException, std::exception)
309 : {
310 0 : return sal_True;
311 : }
312 :
313 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsPositionedDelete()
314 : throw(SQLException, RuntimeException, std::exception)
315 : {
316 0 : return sal_True;
317 : }
318 :
319 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsPositionedUpdate()
320 : throw(SQLException, RuntimeException, std::exception)
321 : {
322 0 : return sal_True;
323 : }
324 :
325 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsOuterJoins()
326 : throw(SQLException, RuntimeException, std::exception)
327 : {
328 0 : return sal_True;
329 : }
330 :
331 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsSelectForUpdate()
332 : throw(SQLException, RuntimeException, std::exception)
333 : {
334 0 : return sal_True;
335 : }
336 :
337 0 : sal_Bool SAL_CALL ODatabaseMetaData::allTablesAreSelectable()
338 : throw(SQLException, RuntimeException, std::exception)
339 : {
340 : // TODO: true if embedded, but unsure about remote server
341 0 : return sal_True;
342 : }
343 :
344 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsConvert(sal_Int32 fromType,
345 : sal_Int32 toType)
346 : throw(SQLException, RuntimeException, std::exception)
347 : {
348 : (void) fromType;
349 : (void) toType;
350 0 : return sal_False;
351 : }
352 :
353 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsTypeConversion()
354 : throw(SQLException, RuntimeException, std::exception)
355 : {
356 0 : return sal_False;
357 : }
358 :
359 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsColumnAliasing()
360 : throw(SQLException, RuntimeException, std::exception)
361 : {
362 0 : return sal_True;
363 : }
364 :
365 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsTableCorrelationNames()
366 : throw(SQLException, RuntimeException, std::exception)
367 : {
368 0 : return sal_True;
369 : }
370 :
371 0 : sal_Int32 SAL_CALL ODatabaseMetaData::getMaxIndexLength( ) throw(SQLException, RuntimeException, std::exception)
372 : {
373 0 : sal_Int32 nValue = 0; // 0 means no limit
374 0 : return nValue;
375 : }
376 :
377 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsNonNullableColumns( ) throw(SQLException, RuntimeException, std::exception)
378 : {
379 0 : return sal_True;
380 : }
381 :
382 0 : OUString SAL_CALL ODatabaseMetaData::getExtraNameCharacters( ) throw(SQLException, RuntimeException, std::exception)
383 : {
384 0 : OUString aVal;
385 0 : return aVal;
386 : }
387 :
388 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsDifferentTableCorrelationNames( ) throw(SQLException, RuntimeException, std::exception)
389 : {
390 0 : return sal_False;
391 : }
392 : // ---- Data definition stuff -------------------------------------------------
393 0 : sal_Bool SAL_CALL ODatabaseMetaData::dataDefinitionIgnoredInTransactions()
394 : throw(SQLException, RuntimeException, std::exception)
395 : {
396 0 : return sal_False;
397 : }
398 :
399 0 : sal_Bool SAL_CALL ODatabaseMetaData::dataDefinitionCausesTransactionCommit()
400 : throw(SQLException, RuntimeException, std::exception)
401 : {
402 0 : return sal_True;
403 : }
404 :
405 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsDataManipulationTransactionsOnly()
406 : throw(SQLException, RuntimeException, std::exception)
407 : {
408 0 : return sal_True;
409 : }
410 :
411 0 : sal_Bool SAL_CALL ODatabaseMetaData::
412 : supportsDataDefinitionAndDataManipulationTransactions()
413 : throw(SQLException, RuntimeException, std::exception)
414 : {
415 0 : return sal_False;
416 : }
417 : //----- Transaction Support --------------------------------------------------
418 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsTransactions()
419 : throw(SQLException, RuntimeException, std::exception)
420 : {
421 0 : return sal_True;
422 : }
423 :
424 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsOpenStatementsAcrossRollback()
425 : throw(SQLException, RuntimeException, std::exception)
426 : {
427 0 : return sal_False;
428 : }
429 :
430 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsOpenStatementsAcrossCommit()
431 : throw(SQLException, RuntimeException, std::exception)
432 : {
433 0 : return sal_False;
434 : }
435 :
436 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsOpenCursorsAcrossCommit()
437 : throw(SQLException, RuntimeException, std::exception)
438 : {
439 0 : return sal_False;
440 : }
441 :
442 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsOpenCursorsAcrossRollback()
443 : throw(SQLException, RuntimeException, std::exception)
444 : {
445 0 : return sal_False;
446 : }
447 :
448 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsMultipleTransactions()
449 : throw(SQLException, RuntimeException, std::exception)
450 : {
451 0 : return sal_True;
452 : }
453 :
454 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsTransactionIsolationLevel(
455 : sal_Int32 aLevel)
456 : throw(SQLException, RuntimeException, std::exception)
457 : {
458 : return aLevel == TransactionIsolation::READ_UNCOMMITTED
459 0 : || aLevel == TransactionIsolation::READ_COMMITTED
460 0 : || aLevel == TransactionIsolation::REPEATABLE_READ
461 0 : || aLevel == TransactionIsolation::SERIALIZABLE;
462 : }
463 :
464 0 : sal_Int32 SAL_CALL ODatabaseMetaData::getDefaultTransactionIsolation()
465 : throw(SQLException, RuntimeException, std::exception)
466 : {
467 0 : return TransactionIsolation::REPEATABLE_READ;
468 : }
469 :
470 :
471 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsANSI92FullSQL( ) throw(SQLException, RuntimeException, std::exception)
472 : {
473 0 : return sal_False;
474 : }
475 :
476 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsANSI92EntryLevelSQL( ) throw(SQLException, RuntimeException, std::exception)
477 : {
478 0 : return sal_True; // should be supported at least
479 : }
480 :
481 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsIntegrityEnhancementFacility( ) throw(SQLException, RuntimeException, std::exception)
482 : {
483 0 : return sal_False;
484 : }
485 :
486 0 : sal_Int32 SAL_CALL ODatabaseMetaData::getMaxStatements( ) throw(SQLException, RuntimeException, std::exception)
487 : {
488 0 : sal_Int32 nValue = 0; // 0 means no limit
489 0 : return nValue;
490 : }
491 :
492 0 : sal_Int32 SAL_CALL ODatabaseMetaData::getMaxProcedureNameLength( ) throw(SQLException, RuntimeException, std::exception)
493 : {
494 0 : sal_Int32 nValue = 31; // TODO: confirm
495 0 : return nValue;
496 : }
497 :
498 0 : sal_Bool SAL_CALL ODatabaseMetaData::allProceduresAreCallable( ) throw(SQLException, RuntimeException, std::exception)
499 : {
500 0 : return sal_False;
501 : }
502 :
503 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsStoredProcedures( ) throw(SQLException, RuntimeException, std::exception)
504 : {
505 0 : return sal_True;
506 : }
507 :
508 0 : sal_Bool SAL_CALL ODatabaseMetaData::isReadOnly( ) throw(SQLException, RuntimeException, std::exception)
509 : {
510 0 : return m_pConnection->isReadOnly();
511 : }
512 :
513 0 : sal_Bool SAL_CALL ODatabaseMetaData::usesLocalFiles( ) throw(SQLException, RuntimeException, std::exception)
514 : {
515 0 : return m_pConnection->isEmbedded();
516 : }
517 :
518 0 : sal_Bool SAL_CALL ODatabaseMetaData::usesLocalFilePerTable( ) throw(SQLException, RuntimeException, std::exception)
519 : {
520 0 : return sal_False;
521 : }
522 :
523 0 : sal_Bool SAL_CALL ODatabaseMetaData::nullPlusNonNullIsNull( ) throw(SQLException, RuntimeException, std::exception)
524 : {
525 0 : return sal_False;
526 : }
527 :
528 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsExpressionsInOrderBy( ) throw(SQLException, RuntimeException, std::exception)
529 : {
530 0 : return sal_False;
531 : }
532 :
533 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsGroupBy( ) throw(SQLException, RuntimeException, std::exception)
534 : {
535 0 : return sal_True;
536 : }
537 :
538 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsGroupByBeyondSelect( ) throw(SQLException, RuntimeException, std::exception)
539 : {
540 : // Unsure
541 0 : return sal_True;
542 : }
543 :
544 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsGroupByUnrelated( ) throw(SQLException, RuntimeException, std::exception)
545 : {
546 : // Unsure
547 0 : return sal_False;
548 : }
549 :
550 :
551 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsMultipleResultSets( ) throw(SQLException, RuntimeException, std::exception)
552 : {
553 0 : return sal_False;
554 : }
555 :
556 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsLikeEscapeClause( ) throw(SQLException, RuntimeException, std::exception)
557 : {
558 0 : return sal_False;
559 : }
560 :
561 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsOrderByUnrelated( ) throw(SQLException, RuntimeException, std::exception)
562 : {
563 0 : return sal_False;
564 : }
565 :
566 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsUnion( ) throw(SQLException, RuntimeException, std::exception)
567 : {
568 0 : return sal_True;
569 : }
570 :
571 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsUnionAll( ) throw(SQLException, RuntimeException, std::exception)
572 : {
573 0 : return sal_True;
574 : }
575 :
576 0 : sal_Bool SAL_CALL ODatabaseMetaData::nullsAreSortedAtEnd( ) throw(SQLException, RuntimeException, std::exception)
577 : {
578 0 : return sal_False;
579 : }
580 :
581 0 : sal_Bool SAL_CALL ODatabaseMetaData::nullsAreSortedAtStart( ) throw(SQLException, RuntimeException, std::exception)
582 : {
583 0 : return sal_False;
584 : }
585 :
586 0 : sal_Bool SAL_CALL ODatabaseMetaData::nullsAreSortedHigh( ) throw(SQLException, RuntimeException, std::exception)
587 : {
588 0 : return sal_False;
589 : }
590 :
591 0 : sal_Bool SAL_CALL ODatabaseMetaData::nullsAreSortedLow( ) throw(SQLException, RuntimeException, std::exception)
592 : {
593 0 : return sal_False;
594 : }
595 :
596 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsCorrelatedSubqueries( ) throw(SQLException, RuntimeException, std::exception)
597 : {
598 0 : return sal_False;
599 : }
600 :
601 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsSubqueriesInComparisons( ) throw(SQLException, RuntimeException, std::exception)
602 : {
603 0 : return sal_False;
604 : }
605 :
606 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsSubqueriesInExists( ) throw(SQLException, RuntimeException, std::exception)
607 : {
608 0 : return sal_False;
609 : }
610 :
611 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsSubqueriesInIns( ) throw(SQLException, RuntimeException, std::exception)
612 : {
613 0 : return sal_False;
614 : }
615 :
616 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsSubqueriesInQuantifieds( ) throw(SQLException, RuntimeException, std::exception)
617 : {
618 0 : return sal_False;
619 : }
620 :
621 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsANSI92IntermediateSQL( ) throw(SQLException, RuntimeException, std::exception)
622 : {
623 0 : return sal_False;
624 : }
625 :
626 0 : OUString SAL_CALL ODatabaseMetaData::getURL() throw(SQLException, RuntimeException, std::exception)
627 : {
628 0 : return m_pConnection->getConnectionURL();
629 : }
630 :
631 0 : OUString SAL_CALL ODatabaseMetaData::getUserName( ) throw(SQLException, RuntimeException, std::exception)
632 : {
633 0 : OUString aValue;
634 0 : return aValue;
635 : }
636 :
637 0 : OUString SAL_CALL ODatabaseMetaData::getDriverName( ) throw(SQLException, RuntimeException, std::exception)
638 : {
639 0 : OUString aValue;
640 0 : return aValue;
641 : }
642 :
643 0 : OUString SAL_CALL ODatabaseMetaData::getDriverVersion() throw(SQLException, RuntimeException, std::exception)
644 : {
645 0 : OUString aValue;
646 0 : return aValue;
647 : }
648 :
649 0 : OUString SAL_CALL ODatabaseMetaData::getDatabaseProductVersion( ) throw(SQLException, RuntimeException, std::exception)
650 : {
651 0 : OUString aValue;
652 0 : return aValue;
653 : }
654 :
655 0 : OUString SAL_CALL ODatabaseMetaData::getDatabaseProductName( ) throw(SQLException, RuntimeException, std::exception)
656 : {
657 0 : OUString aValue;
658 0 : return aValue;
659 : }
660 :
661 0 : OUString SAL_CALL ODatabaseMetaData::getProcedureTerm( ) throw(SQLException, RuntimeException, std::exception)
662 : {
663 0 : OUString aValue;
664 0 : return aValue;
665 : }
666 :
667 0 : sal_Int32 SAL_CALL ODatabaseMetaData::getDriverMajorVersion( ) throw(RuntimeException, std::exception)
668 : {
669 0 : return 1;
670 : }
671 :
672 0 : sal_Int32 SAL_CALL ODatabaseMetaData::getDriverMinorVersion( ) throw(RuntimeException, std::exception)
673 : {
674 0 : return 0;
675 : }
676 :
677 0 : OUString SAL_CALL ODatabaseMetaData::getSQLKeywords( ) throw(SQLException, RuntimeException, std::exception)
678 : {
679 0 : OUString aValue;
680 0 : return aValue;
681 : }
682 :
683 0 : OUString SAL_CALL ODatabaseMetaData::getSearchStringEscape( ) throw(SQLException, RuntimeException, std::exception)
684 : {
685 0 : OUString aValue;
686 0 : return aValue;
687 : }
688 :
689 0 : OUString SAL_CALL ODatabaseMetaData::getStringFunctions( ) throw(SQLException, RuntimeException, std::exception)
690 : {
691 0 : return OUString();
692 : }
693 :
694 0 : OUString SAL_CALL ODatabaseMetaData::getTimeDateFunctions( ) throw(SQLException, RuntimeException, std::exception)
695 : {
696 0 : return OUString();
697 : }
698 :
699 0 : OUString SAL_CALL ODatabaseMetaData::getSystemFunctions( ) throw(SQLException, RuntimeException, std::exception)
700 : {
701 0 : return OUString();
702 : }
703 :
704 0 : OUString SAL_CALL ODatabaseMetaData::getNumericFunctions( ) throw(SQLException, RuntimeException, std::exception)
705 : {
706 0 : return OUString();
707 : }
708 :
709 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsExtendedSQLGrammar( ) throw(SQLException, RuntimeException, std::exception)
710 : {
711 0 : return sal_False;
712 : }
713 :
714 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsFullOuterJoins( ) throw(SQLException, RuntimeException, std::exception)
715 : {
716 0 : return sal_False;
717 : }
718 :
719 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsLimitedOuterJoins( ) throw(SQLException, RuntimeException, std::exception)
720 : {
721 0 : return sal_False;
722 : }
723 :
724 0 : sal_Int32 SAL_CALL ODatabaseMetaData::getMaxColumnsInGroupBy( ) throw(SQLException, RuntimeException, std::exception)
725 : {
726 0 : sal_Int32 nValue = 0; // 0 means no limit
727 0 : return nValue;
728 : }
729 :
730 0 : sal_Int32 SAL_CALL ODatabaseMetaData::getMaxColumnsInOrderBy( ) throw(SQLException, RuntimeException, std::exception)
731 : {
732 0 : sal_Int32 nValue = 0; // 0 means no limit
733 0 : return nValue;
734 : }
735 :
736 0 : sal_Int32 SAL_CALL ODatabaseMetaData::getMaxColumnsInSelect( ) throw(SQLException, RuntimeException, std::exception)
737 : {
738 0 : sal_Int32 nValue = 0; // 0 means no limit
739 0 : return nValue;
740 : }
741 :
742 0 : sal_Int32 SAL_CALL ODatabaseMetaData::getMaxUserNameLength( ) throw(SQLException, RuntimeException, std::exception)
743 : {
744 0 : return 31;
745 : }
746 :
747 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsResultSetType(sal_Int32 setType)
748 : throw(SQLException, RuntimeException, std::exception)
749 : {
750 0 : switch (setType)
751 : {
752 : case ResultSetType::FORWARD_ONLY:
753 0 : return sal_True;
754 : default:
755 0 : return sal_False;
756 : }
757 : }
758 :
759 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsResultSetConcurrency(
760 : sal_Int32 aResultSetType,
761 : sal_Int32 aConcurrency)
762 : throw(SQLException, RuntimeException, std::exception)
763 : {
764 0 : if (aResultSetType == ResultSetType::FORWARD_ONLY
765 0 : && aConcurrency == ResultSetConcurrency::READ_ONLY)
766 0 : return sal_True;
767 : else
768 0 : return sal_False;
769 : }
770 :
771 0 : sal_Bool SAL_CALL ODatabaseMetaData::ownUpdatesAreVisible( sal_Int32 setType ) throw(SQLException, RuntimeException, std::exception)
772 : {
773 : (void) setType;
774 0 : return sal_False;
775 : }
776 :
777 0 : sal_Bool SAL_CALL ODatabaseMetaData::ownDeletesAreVisible( sal_Int32 setType ) throw(SQLException, RuntimeException, std::exception)
778 : {
779 : (void) setType;
780 0 : return sal_False;
781 : }
782 :
783 0 : sal_Bool SAL_CALL ODatabaseMetaData::ownInsertsAreVisible( sal_Int32 setType ) throw(SQLException, RuntimeException, std::exception)
784 : {
785 : (void) setType;
786 0 : return sal_False;
787 : }
788 :
789 0 : sal_Bool SAL_CALL ODatabaseMetaData::othersUpdatesAreVisible( sal_Int32 setType ) throw(SQLException, RuntimeException, std::exception)
790 : {
791 : (void) setType;
792 0 : return sal_False;
793 : }
794 :
795 0 : sal_Bool SAL_CALL ODatabaseMetaData::othersDeletesAreVisible( sal_Int32 setType ) throw(SQLException, RuntimeException, std::exception)
796 : {
797 : (void) setType;
798 0 : return sal_False;
799 : }
800 :
801 0 : sal_Bool SAL_CALL ODatabaseMetaData::othersInsertsAreVisible( sal_Int32 setType ) throw(SQLException, RuntimeException, std::exception)
802 : {
803 : (void) setType;
804 0 : return sal_False;
805 : }
806 :
807 0 : sal_Bool SAL_CALL ODatabaseMetaData::updatesAreDetected( sal_Int32 setType ) throw(SQLException, RuntimeException, std::exception)
808 : {
809 : (void) setType;
810 0 : return sal_False;
811 : }
812 :
813 0 : sal_Bool SAL_CALL ODatabaseMetaData::deletesAreDetected( sal_Int32 setType ) throw(SQLException, RuntimeException, std::exception)
814 : {
815 : (void) setType;
816 0 : return sal_False;
817 : }
818 :
819 0 : sal_Bool SAL_CALL ODatabaseMetaData::insertsAreDetected( sal_Int32 setType ) throw(SQLException, RuntimeException, std::exception)
820 : {
821 : (void) setType;
822 0 : return sal_False;
823 : }
824 :
825 0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsBatchUpdates()
826 : throw(SQLException, RuntimeException, std::exception)
827 : {
828 : // No batch support in firebird
829 0 : return sal_False;
830 : }
831 :
832 0 : uno::Reference< XConnection > SAL_CALL ODatabaseMetaData::getConnection()
833 : throw(SQLException, RuntimeException, std::exception)
834 : {
835 0 : return (uno::Reference< XConnection >) m_pConnection;
836 : }
837 :
838 : // here follow all methods which return a resultset
839 : // the first methods is an example implementation how to use this resultset
840 : // of course you could implement it on your and you should do this because
841 : // the general way is more memory expensive
842 :
843 0 : uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTableTypes( ) throw(SQLException, RuntimeException, std::exception)
844 : {
845 : OSL_FAIL("Not implemented yet!");
846 : // TODO implement
847 0 : return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eTableTypes);
848 : }
849 :
850 0 : uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTypeInfo()
851 : throw(SQLException, RuntimeException, std::exception)
852 : {
853 : SAL_INFO("connectivity.firebird", "getTypeInfo()");
854 :
855 : // this returns an empty resultset where the column-names are already set
856 : // in special the metadata of the resultset already returns the right columns
857 : ODatabaseMetaDataResultSet* pResultSet =
858 0 : new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eTypeInfo);
859 0 : uno::Reference< XResultSet > xResultSet = pResultSet;
860 0 : static ODatabaseMetaDataResultSet::ORows aResults;
861 :
862 0 : if(aResults.empty())
863 : {
864 0 : ODatabaseMetaDataResultSet::ORow aRow(19);
865 :
866 : // Common data
867 0 : aRow[4] = ODatabaseMetaDataResultSet::getQuoteValue(); // Literal quote marks
868 0 : aRow[5] = ODatabaseMetaDataResultSet::getQuoteValue(); // Literal quote marks
869 0 : aRow[7] = new ORowSetValueDecorator(sal_True); // Nullable
870 0 : aRow[8] = new ORowSetValueDecorator(sal_True); // Case sensitive
871 0 : aRow[10] = new ORowSetValueDecorator(sal_False); // Is unsigned
872 : // FIXED_PREC_SCALE: docs state "can it be a money value? " however
873 : // in reality this causes Base to treat all numbers as money formatted
874 : // by default which is wrong (and formatting as money value is still
875 : // possible for all values).
876 0 : aRow[11] = new ORowSetValueDecorator(sal_False);
877 : // Localised Type Name -- TODO: implement (but can be null):
878 0 : aRow[13] = new ORowSetValueDecorator();
879 0 : aRow[16] = new ORowSetValueDecorator(); // Unused
880 0 : aRow[17] = new ORowSetValueDecorator(); // Unused
881 0 : aRow[18] = new ORowSetValueDecorator(sal_Int16(10));// Radix
882 :
883 : // SQL_TEXT
884 0 : aRow[1] = new ORowSetValueDecorator(OUString("CHAR"));
885 0 : aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_TEXT));
886 0 : aRow[3] = new ORowSetValueDecorator(sal_Int16(32767)); // Prevision = max length
887 0 : aRow[6] = new ORowSetValueDecorator(OUString("length")); // Create Params
888 0 : aRow[9] = new ORowSetValueDecorator(
889 0 : sal_Int16(ColumnSearch::FULL)); // Searchable
890 0 : aRow[12] = new ORowSetValueDecorator(sal_False); // Autoincrement
891 0 : aRow[14] = ODatabaseMetaDataResultSet::get0Value(); // Minimum scale
892 0 : aRow[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale
893 0 : aResults.push_back(aRow);
894 :
895 : // SQL_VARYING
896 0 : aRow[1] = new ORowSetValueDecorator(OUString("VARCHAR"));
897 0 : aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_VARYING));
898 0 : aRow[3] = new ORowSetValueDecorator(sal_Int16(32767)); // Prevision = max length
899 0 : aRow[6] = new ORowSetValueDecorator(OUString("length")); // Create Params
900 0 : aRow[9] = new ORowSetValueDecorator(
901 0 : sal_Int16(ColumnSearch::FULL)); // Searchable
902 0 : aRow[12] = new ORowSetValueDecorator(sal_False); // Autoincrement
903 0 : aRow[14] = ODatabaseMetaDataResultSet::get0Value(); // Minimum scale
904 0 : aRow[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale
905 0 : aResults.push_back(aRow);
906 :
907 : // Integer Types common
908 : {
909 0 : aRow[6] = new ORowSetValueDecorator(); // Create Params
910 0 : aRow[9] = new ORowSetValueDecorator(
911 0 : sal_Int16(ColumnSearch::FULL)); // Searchable
912 0 : aRow[12] = new ORowSetValueDecorator(sal_True); // Autoincrement
913 0 : aRow[14] = ODatabaseMetaDataResultSet::get0Value(); // Minimum scale
914 0 : aRow[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale
915 : }
916 : // SQL_SHORT
917 0 : aRow[1] = new ORowSetValueDecorator(OUString("SMALLINT"));
918 0 : aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_SHORT));
919 0 : aRow[3] = new ORowSetValueDecorator(sal_Int16(5)); // Prevision
920 0 : aResults.push_back(aRow);
921 : // SQL_LONG
922 0 : aRow[1] = new ORowSetValueDecorator(OUString("INTEGER"));
923 0 : aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_LONG));
924 0 : aRow[3] = new ORowSetValueDecorator(sal_Int16(10)); // Precision
925 0 : aResults.push_back(aRow);
926 : // SQL_INT64
927 0 : aRow[1] = new ORowSetValueDecorator(OUString("BIGINT"));
928 0 : aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_INT64));
929 0 : aRow[3] = new ORowSetValueDecorator(sal_Int16(20)); // Precision
930 0 : aResults.push_back(aRow);
931 :
932 : // Decimal Types common
933 : {
934 0 : aRow[6] = new ORowSetValueDecorator(); // Create Params
935 0 : aRow[9] = new ORowSetValueDecorator(
936 0 : sal_Int16(ColumnSearch::FULL)); // Searchable
937 0 : aRow[12] = new ORowSetValueDecorator(sal_True); // Autoincrement
938 : }
939 : // SQL_FLOAT
940 0 : aRow[1] = new ORowSetValueDecorator(OUString("FLOAT"));
941 0 : aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_FLOAT));
942 0 : aRow[3] = new ORowSetValueDecorator(sal_Int16(7)); // Precision
943 0 : aRow[14] = new ORowSetValueDecorator(sal_Int16(1)); // Minimum scale
944 0 : aRow[15] = new ORowSetValueDecorator(sal_Int16(7)); // Max scale
945 0 : aResults.push_back(aRow);
946 : // SQL_DOUBLE
947 0 : aRow[1] = new ORowSetValueDecorator(OUString("DOUBLE PRECISION"));
948 0 : aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_DOUBLE));
949 0 : aRow[3] = new ORowSetValueDecorator(sal_Int16(15)); // Precision
950 0 : aRow[14] = new ORowSetValueDecorator(sal_Int16(1)); // Minimum scale
951 0 : aRow[15] = new ORowSetValueDecorator(sal_Int16(15)); // Max scale
952 0 : aResults.push_back(aRow);
953 : // // SQL_D_FLOAT
954 : // aRow[1] = new ORowSetValueDecorator(getColumnTypeNameFromFBType(SQL_D_FLOAT));
955 : // aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_D_FLOAT));
956 : // aRow[3] = new ORowSetValueDecorator(sal_Int16(15)); // Precision
957 : // aRow[14] = new ORowSetValueDecorator(sal_Int16(1)); // Minimum scale
958 : // aRow[15] = new ORowSetValueDecorator(sal_Int16(15)); // Max scale
959 : // aResults.push_back(aRow);
960 : // TODO: no idea whether D_FLOAT corresponds to an sql type
961 :
962 : // SQL_TIMESTAMP
963 : // TODO: precision?
964 0 : aRow[1] = new ORowSetValueDecorator(OUString("TIMESTAMP"));
965 0 : aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_TIMESTAMP));
966 0 : aRow[3] = new ORowSetValueDecorator(sal_Int32(8)); // Prevision = max length
967 0 : aRow[6] = new ORowSetValueDecorator(); // Create Params
968 0 : aRow[9] = new ORowSetValueDecorator(
969 0 : sal_Int16(ColumnSearch::FULL)); // Searchable
970 0 : aRow[12] = new ORowSetValueDecorator(sal_False); // Autoincrement
971 0 : aRow[14] = ODatabaseMetaDataResultSet::get0Value(); // Minimum scale
972 0 : aRow[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale
973 0 : aResults.push_back(aRow);
974 :
975 : // SQL_TYPE_TIME
976 : // TODO: precision?
977 0 : aRow[1] = new ORowSetValueDecorator(OUString("TIME"));
978 0 : aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_TYPE_TIME));
979 0 : aRow[3] = new ORowSetValueDecorator(sal_Int32(8)); // Prevision = max length
980 0 : aRow[6] = new ORowSetValueDecorator(); // Create Params
981 0 : aRow[9] = new ORowSetValueDecorator(
982 0 : sal_Int16(ColumnSearch::FULL)); // Searchable
983 0 : aRow[12] = new ORowSetValueDecorator(sal_False); // Autoincrement
984 0 : aRow[14] = ODatabaseMetaDataResultSet::get0Value(); // Minimum scale
985 0 : aRow[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale
986 0 : aResults.push_back(aRow);
987 :
988 : // SQL_TYPE_DATE
989 : // TODO: precision?
990 0 : aRow[1] = new ORowSetValueDecorator(OUString("DATE"));
991 0 : aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_TYPE_DATE));
992 0 : aRow[3] = new ORowSetValueDecorator(sal_Int32(8)); // Prevision = max length
993 0 : aRow[6] = new ORowSetValueDecorator(); // Create Params
994 0 : aRow[9] = new ORowSetValueDecorator(
995 0 : sal_Int16(ColumnSearch::FULL)); // Searchable
996 0 : aRow[12] = new ORowSetValueDecorator(sal_False); // Autoincrement
997 0 : aRow[14] = ODatabaseMetaDataResultSet::get0Value(); // Minimum scale
998 0 : aRow[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale
999 0 : aResults.push_back(aRow);
1000 :
1001 : // SQL_BLOB
1002 : // TODO: precision?
1003 0 : aRow[1] = new ORowSetValueDecorator(OUString("BLOB"));
1004 0 : aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_BLOB));
1005 0 : aRow[3] = new ORowSetValueDecorator(sal_Int32(0)); // Prevision = max length
1006 0 : aRow[6] = new ORowSetValueDecorator(); // Create Params
1007 0 : aRow[9] = new ORowSetValueDecorator(
1008 0 : sal_Int16(ColumnSearch::NONE)); // Searchable
1009 0 : aRow[12] = new ORowSetValueDecorator(sal_False); // Autoincrement
1010 0 : aRow[14] = ODatabaseMetaDataResultSet::get0Value(); // Minimum scale
1011 0 : aRow[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale
1012 0 : aResults.push_back(aRow);
1013 :
1014 : // TODO: complete
1015 : // case SQL_ARRAY:
1016 : // case SQL_NULL:
1017 : // case SQL_QUAD: // Is a "Blob ID" according to the docs
1018 : }
1019 0 : pResultSet->setRows(aResults);
1020 0 : return xResultSet;
1021 : }
1022 :
1023 0 : uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getColumnPrivileges(
1024 : const Any& /*aCatalog*/,
1025 : const OUString& /*sSchema*/,
1026 : const OUString& sTable,
1027 : const OUString& sColumnNamePattern)
1028 : throw(SQLException, RuntimeException, std::exception)
1029 : {
1030 : SAL_INFO("connectivity.firebird", "getColumnPrivileges() with "
1031 : "Table: " << sTable
1032 : << " & ColumnNamePattern: " << sColumnNamePattern);
1033 :
1034 : ODatabaseMetaDataResultSet* pResultSet = new
1035 0 : ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eColumnPrivileges);
1036 0 : uno::Reference< XResultSet > xResultSet = pResultSet;
1037 0 : uno::Reference< XStatement > statement = m_pConnection->createStatement();
1038 :
1039 0 : static const OUString wld("%");
1040 : OUStringBuffer queryBuf(
1041 : "SELECT "
1042 : "priv.RDB$RELATION_NAME, " // 1 Table name
1043 : "priv.RDB$GRANTOR," // 2
1044 : "priv.RDB$USER, " // 3 Grantee
1045 : "priv.RDB$PRIVILEGE, " // 4
1046 : "priv.RDB$GRANT_OPTION, " // 5 is Grantable
1047 : "priv.RDB$FIELD_NAME " // 6 Column name
1048 0 : "FROM RDB$USER_PRIVILEGES priv ");
1049 :
1050 : {
1051 0 : OUString sAppend = "WHERE priv.RDB$RELATION_NAME = '%' ";
1052 0 : queryBuf.append(sAppend.replaceAll("%", sTable));
1053 : }
1054 0 : if (!sColumnNamePattern.isEmpty())
1055 : {
1056 0 : OUString sAppend;
1057 0 : if (sColumnNamePattern.match(wld))
1058 0 : sAppend = "AND priv.RDB$FIELD_NAME LIKE '%' ";
1059 : else
1060 0 : sAppend = "AND priv.RDB$FIELD_NAME = '%' ";
1061 :
1062 0 : queryBuf.append(sAppend.replaceAll(wld, sColumnNamePattern));
1063 : }
1064 :
1065 : queryBuf.append(" ORDER BY priv.RDB$FIELD, "
1066 0 : "priv.RDB$PRIVILEGE");
1067 :
1068 0 : OUString query = queryBuf.makeStringAndClear();
1069 :
1070 0 : uno::Reference< XResultSet > rs = statement->executeQuery(query.getStr());
1071 0 : uno::Reference< XRow > xRow( rs, UNO_QUERY_THROW );
1072 0 : ODatabaseMetaDataResultSet::ORows aResults;
1073 :
1074 0 : ODatabaseMetaDataResultSet::ORow aCurrentRow(8);
1075 0 : aCurrentRow[0] = new ORowSetValueDecorator(); // Unused
1076 0 : aCurrentRow[1] = new ORowSetValueDecorator(); // 1. TABLE_CAT Unsupported
1077 0 : aCurrentRow[2] = new ORowSetValueDecorator(); // 1. TABLE_SCHEM Unsupported
1078 :
1079 0 : while( rs->next() )
1080 : {
1081 : // 3. TABLE_NAME
1082 0 : aCurrentRow[3] = new ORowSetValueDecorator(sanitizeIdentifier(xRow->getString(1)));
1083 : // 4. COLUMN_NAME
1084 0 : aCurrentRow[4] = new ORowSetValueDecorator(sanitizeIdentifier(xRow->getString(6)));
1085 0 : aCurrentRow[5] = new ORowSetValueDecorator(xRow->getString(2)); // 5. GRANTOR
1086 0 : aCurrentRow[6] = new ORowSetValueDecorator(xRow->getString(3)); // 6. GRANTEE
1087 0 : aCurrentRow[7] = new ORowSetValueDecorator(xRow->getString(4)); // 7. Privilege
1088 0 : aCurrentRow[7] = new ORowSetValueDecorator(xRow->getBoolean(5)); // 8. Grantable
1089 :
1090 0 : aResults.push_back(aCurrentRow);
1091 : }
1092 :
1093 0 : pResultSet->setRows( aResults );
1094 :
1095 0 : return xResultSet;
1096 : }
1097 :
1098 0 : uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getColumns(
1099 : const Any& /*catalog*/,
1100 : const OUString& /*schemaPattern*/,
1101 : const OUString& tableNamePattern,
1102 : const OUString& columnNamePattern)
1103 : throw(SQLException, RuntimeException, std::exception)
1104 : {
1105 : SAL_INFO("connectivity.firebird", "getColumns() with "
1106 : "TableNamePattern: " << tableNamePattern <<
1107 : " & ColumnNamePattern: " << columnNamePattern);
1108 :
1109 : OUStringBuffer queryBuf("SELECT "
1110 : "relfields.RDB$RELATION_NAME, " // 1
1111 : "relfields.RDB$FIELD_NAME, " // 2
1112 : "relfields.RDB$DESCRIPTION," // 3
1113 : "relfields.RDB$DEFAULT_VALUE, " // 4
1114 : "relfields.RDB$FIELD_POSITION, "// 5
1115 : "fields.RDB$FIELD_TYPE, " // 6
1116 : "fields.RDB$FIELD_LENGTH, " // 7
1117 : "fields.RDB$FIELD_PRECISION, " // 8
1118 : // Specifically use relfields null flag -- the one in fields is used
1119 : // for domains, whether a specific field is nullable is set in relfields,
1120 : // this is also the one we manually fiddle when changin NULL/NOT NULL
1121 : // (see Table.cxx)
1122 : "relfields.RDB$NULL_FLAG " // 9
1123 : "FROM RDB$RELATION_FIELDS relfields "
1124 : "JOIN RDB$FIELDS fields "
1125 : "on (fields.RDB$FIELD_NAME = relfields.RDB$FIELD_SOURCE) "
1126 0 : "WHERE (1 = 1) ");
1127 :
1128 0 : if (!tableNamePattern.isEmpty())
1129 : {
1130 0 : OUString sAppend;
1131 0 : if (tableNamePattern.match("%"))
1132 0 : sAppend = "AND relfields.RDB$RELATION_NAME LIKE '%' ";
1133 : else
1134 0 : sAppend = "AND relfields.RDB$RELATION_NAME = '%' ";
1135 :
1136 0 : queryBuf.append(sAppend.replaceAll("%", tableNamePattern));
1137 : }
1138 :
1139 0 : if (!columnNamePattern.isEmpty())
1140 : {
1141 0 : OUString sAppend;
1142 0 : if (columnNamePattern.match("%"))
1143 0 : sAppend = "AND relfields.RDB$FIELD_NAME LIKE '%' ";
1144 : else
1145 0 : sAppend = "AND relfields.RDB$FIELD_NAME = '%' ";
1146 :
1147 0 : queryBuf.append(sAppend.replaceAll("%", columnNamePattern));
1148 : }
1149 :
1150 0 : OUString query = queryBuf.makeStringAndClear();
1151 :
1152 0 : uno::Reference< XStatement > statement = m_pConnection->createStatement();
1153 0 : uno::Reference< XResultSet > rs = statement->executeQuery(query.getStr());
1154 0 : uno::Reference< XRow > xRow( rs, UNO_QUERY_THROW );
1155 :
1156 0 : ODatabaseMetaDataResultSet::ORows aResults;
1157 0 : ODatabaseMetaDataResultSet::ORow aCurrentRow(19);
1158 :
1159 0 : aCurrentRow[0] = new ORowSetValueDecorator(); // Unused -- numbering starts from 0
1160 0 : aCurrentRow[1] = new ORowSetValueDecorator(); // Catalog - can be null
1161 0 : aCurrentRow[2] = new ORowSetValueDecorator(); // Schema - can be null
1162 0 : aCurrentRow[8] = new ORowSetValueDecorator(); // Unused
1163 0 : aCurrentRow[10] = new ORowSetValueDecorator(sal_Int32(10)); // Radix: fixed in FB
1164 0 : aCurrentRow[14] = new ORowSetValueDecorator(); // Unused
1165 0 : aCurrentRow[15] = new ORowSetValueDecorator(); // Unused
1166 :
1167 0 : while( rs->next() )
1168 : {
1169 : // 3. TABLE_NAME
1170 0 : aCurrentRow[3] = new ORowSetValueDecorator(sanitizeIdentifier(xRow->getString(1)));
1171 : // 4. Column Name
1172 0 : aCurrentRow[4] = new ORowSetValueDecorator(sanitizeIdentifier(xRow->getString(2)));
1173 : // 5. Datatype
1174 0 : short aType = getFBTypeFromBlrType(xRow->getShort(6));
1175 0 : aCurrentRow[5] = new ORowSetValueDecorator(getColumnTypeFromFBType(aType));
1176 : // 6. Typename (SQL_*)
1177 0 : aCurrentRow[6] = new ORowSetValueDecorator(getColumnTypeNameFromFBType(aType));
1178 :
1179 : // 7. Column Sizes
1180 : {
1181 0 : sal_Int32 aColumnSize = 0;
1182 0 : switch (aType)
1183 : {
1184 : case SQL_TEXT:
1185 : case SQL_VARYING:
1186 0 : aColumnSize = xRow->getShort(7);
1187 0 : break;
1188 : case SQL_SHORT:
1189 : case SQL_LONG:
1190 : case SQL_FLOAT:
1191 : case SQL_DOUBLE:
1192 : case SQL_D_FLOAT:
1193 : case SQL_INT64:
1194 : case SQL_QUAD:
1195 0 : aColumnSize = xRow->getShort(8);
1196 0 : break;
1197 : case SQL_TIMESTAMP:
1198 : case SQL_BLOB:
1199 : case SQL_ARRAY:
1200 : case SQL_TYPE_TIME:
1201 : case SQL_TYPE_DATE:
1202 : case SQL_NULL:
1203 : // TODO: implement.
1204 0 : break;
1205 : }
1206 0 : aCurrentRow[7] = new ORowSetValueDecorator(aColumnSize);
1207 : }
1208 :
1209 : // 9. Decimal Digits
1210 : // TODO: implement
1211 0 : aCurrentRow[9] = new ORowSetValueDecorator(sal_Int32(0));
1212 :
1213 : // 11. Nullable
1214 0 : if (xRow->getShort(9))
1215 : {
1216 0 : aCurrentRow[11] = new ORowSetValueDecorator(ColumnValue::NO_NULLS);
1217 : }
1218 : else
1219 : {
1220 0 : aCurrentRow[11] = new ORowSetValueDecorator(ColumnValue::NULLABLE);
1221 : }
1222 : // 12. Comments -- may be omitted
1223 : {
1224 0 : OUString aDescription;
1225 0 : uno::Reference< XBlob > xDescriptionBlob = xRow->getBlob(3);
1226 0 : if (xDescriptionBlob.is())
1227 : {
1228 0 : sal_Int32 aBlobLength = (sal_Int32) xDescriptionBlob->length();
1229 0 : aDescription = OUString((char*) xDescriptionBlob->getBytes(0, aBlobLength).getArray(),
1230 : aBlobLength,
1231 0 : RTL_TEXTENCODING_UTF8);
1232 : }
1233 0 : aCurrentRow[12] = new ORowSetValueDecorator(aDescription);
1234 : }
1235 : // 13. Default -- may be omitted.
1236 : {
1237 0 : uno::Reference< XBlob > xDefaultValueBlob = xRow->getBlob(4);
1238 0 : if (xDefaultValueBlob.is())
1239 : {
1240 : // TODO: Implement
1241 : }
1242 0 : aCurrentRow[13] = new ORowSetValueDecorator();
1243 : }
1244 :
1245 : // 16. Bytes in Column for char
1246 0 : if (aType == SQL_TEXT)
1247 : {
1248 0 : aCurrentRow[16] = new ORowSetValueDecorator(xRow->getShort(7));
1249 : }
1250 0 : else if (aType == SQL_VARYING)
1251 : {
1252 0 : aCurrentRow[16] = new ORowSetValueDecorator(sal_Int32(32767));
1253 : }
1254 : else
1255 : {
1256 0 : aCurrentRow[16] = new ORowSetValueDecorator(sal_Int32(0));
1257 : }
1258 : // 17. Index of column
1259 : {
1260 0 : short nColumnNumber = xRow->getShort(5);
1261 : // Firebird stores column numbers beginning with 0 internally
1262 : // SDBC expects column numbering to begin with 1.
1263 0 : aCurrentRow[17] = new ORowSetValueDecorator(sal_Int32(nColumnNumber + 1));
1264 : }
1265 : // 18. Is nullable
1266 0 : if (xRow->getShort(9))
1267 : {
1268 0 : aCurrentRow[18] = new ORowSetValueDecorator(OUString("NO"));
1269 : }
1270 : else
1271 : {
1272 0 : aCurrentRow[18] = new ORowSetValueDecorator(OUString("YES"));
1273 : }
1274 :
1275 0 : aResults.push_back(aCurrentRow);
1276 : }
1277 : ODatabaseMetaDataResultSet* pResultSet = new
1278 0 : ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eColumns);
1279 0 : uno::Reference< XResultSet > xResultSet = pResultSet;
1280 0 : pResultSet->setRows( aResults );
1281 :
1282 0 : return xResultSet;
1283 : }
1284 :
1285 0 : uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTables(
1286 : const Any& /*catalog*/,
1287 : const OUString& /*schemaPattern*/,
1288 : const OUString& tableNamePattern,
1289 : const Sequence< OUString >& types)
1290 : throw(SQLException, RuntimeException, std::exception)
1291 : {
1292 : SAL_INFO("connectivity.firebird", "getTables() with "
1293 : "TableNamePattern: " << tableNamePattern);
1294 :
1295 : ODatabaseMetaDataResultSet* pResultSet = new
1296 0 : ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eTables);
1297 0 : uno::Reference< XResultSet > xResultSet = pResultSet;
1298 0 : uno::Reference< XStatement > statement = m_pConnection->createStatement();
1299 :
1300 0 : static const OUString wld("%");
1301 : OUStringBuffer queryBuf(
1302 : "SELECT "
1303 : "RDB$RELATION_NAME, "
1304 : "RDB$SYSTEM_FLAG, "
1305 : "RDB$RELATION_TYPE, "
1306 : "RDB$DESCRIPTION, "
1307 : "RDB$VIEW_BLR "
1308 : "FROM RDB$RELATIONS "
1309 0 : "WHERE ");
1310 :
1311 : // TODO: GLOBAL TEMPORARY, LOCAL TEMPORARY, ALIAS, SYNONYM
1312 0 : if ((types.getLength() == 0) || (types.getLength() == 1 && types[0].match(wld)))
1313 : {
1314 : // All table types? I.e. includes system tables.
1315 0 : queryBuf.append("(RDB$RELATION_TYPE = 0 OR RDB$RELATION_TYPE = 1) ");
1316 : }
1317 : else
1318 : {
1319 0 : queryBuf.append("( (0 = 1) ");
1320 0 : for (int i = 0; i < types.getLength(); i++)
1321 : {
1322 0 : if (types[i] == "SYSTEM TABLE")
1323 0 : queryBuf.append("OR (RDB$SYSTEM_FLAG = 1 AND RDB$VIEW_BLR IS NULL) ");
1324 0 : else if (types[i] == "TABLE")
1325 0 : queryBuf.append("OR (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG = 0 AND RDB$VIEW_BLR IS NULL) ");
1326 0 : else if (types[i] == "VIEW")
1327 0 : queryBuf.append("OR (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG = 0 AND RDB$VIEW_BLR IS NOT NULL) ");
1328 : else
1329 0 : throw SQLException(); // TODO: implement other types, see above.
1330 : }
1331 0 : queryBuf.append(") ");
1332 : }
1333 :
1334 0 : if (!tableNamePattern.isEmpty())
1335 : {
1336 0 : OUString sAppend;
1337 0 : if (tableNamePattern.match(wld))
1338 0 : sAppend = "AND RDB$RELATION_NAME LIKE '%' ";
1339 : else
1340 0 : sAppend = "AND RDB$RELATION_NAME = '%' ";
1341 :
1342 0 : queryBuf.append(sAppend.replaceAll(wld, tableNamePattern));
1343 : }
1344 :
1345 0 : queryBuf.append(" ORDER BY RDB$RELATION_TYPE, RDB$RELATION_NAME");
1346 :
1347 0 : OUString query = queryBuf.makeStringAndClear();
1348 :
1349 0 : uno::Reference< XResultSet > rs = statement->executeQuery(query.getStr());
1350 0 : uno::Reference< XRow > xRow( rs, UNO_QUERY_THROW );
1351 0 : ODatabaseMetaDataResultSet::ORows aResults;
1352 :
1353 0 : ODatabaseMetaDataResultSet::ORow aCurrentRow(6);
1354 0 : aCurrentRow[0] = new ORowSetValueDecorator(); // 0. Unused
1355 0 : aCurrentRow[1] = new ORowSetValueDecorator(); // 1. Table_Cat Unsupported
1356 0 : aCurrentRow[2] = new ORowSetValueDecorator(); // 2. Table_Schem Unsupported
1357 :
1358 0 : while( rs->next() )
1359 : {
1360 : // 3. TABLE_NAME
1361 0 : aCurrentRow[3] = new ORowSetValueDecorator(sanitizeIdentifier(xRow->getString(1)));
1362 : // 4. TABLE_TYPE
1363 : {
1364 : // TODO: check this as the docs are a bit unclear.
1365 0 : sal_Int16 nSystemFlag = xRow->getShort(2);
1366 0 : sal_Int16 nTableType = xRow->getShort(3);
1367 0 : xRow->getBlob(5); // We have to retrieve a column to verify it is null.
1368 0 : sal_Bool aIsView = !xRow->wasNull();
1369 0 : OUString sTableType;
1370 :
1371 0 : if (nSystemFlag == 1)
1372 : {
1373 0 : sTableType = "SYSTEM TABLE";
1374 : }
1375 0 : else if (aIsView)
1376 : {
1377 0 : sTableType = "VIEW";
1378 : }
1379 : else
1380 : {
1381 0 : if (nTableType == 0)
1382 0 : sTableType = "TABLE";
1383 : }
1384 :
1385 0 : aCurrentRow[4] = new ORowSetValueDecorator(sTableType);
1386 : }
1387 : // 5. REMARKS
1388 : {
1389 0 : uno::Reference< XBlob > xBlob = xRow->getBlob(4);
1390 0 : OUString sDescription;
1391 :
1392 0 : if (xBlob.is())
1393 : {
1394 : // TODO: we should actually be using CLOB here instead.
1395 : // However we haven't implemented CLOB yet, so use BLOB.
1396 0 : sal_Int32 aBlobLength = (sal_Int32) xBlob->length();
1397 0 : sDescription = OUString((char*) xBlob->getBytes(0, aBlobLength).getArray(),
1398 : aBlobLength,
1399 0 : RTL_TEXTENCODING_UTF8);
1400 : }
1401 :
1402 0 : aCurrentRow[5] = new ORowSetValueDecorator(sDescription);
1403 : }
1404 :
1405 0 : aResults.push_back(aCurrentRow);
1406 : }
1407 :
1408 0 : pResultSet->setRows( aResults );
1409 :
1410 0 : return xResultSet;
1411 : }
1412 :
1413 0 : uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getProcedureColumns(
1414 : const Any& catalog, const OUString& schemaPattern,
1415 : const OUString& procedureNamePattern, const OUString& columnNamePattern ) throw(SQLException, RuntimeException, std::exception)
1416 : {
1417 : SAL_WARN("connectivity.firebird", "Not yet implemented");
1418 : (void) catalog;
1419 : (void) schemaPattern;
1420 : (void) procedureNamePattern;
1421 : (void) columnNamePattern;
1422 : OSL_FAIL("Not implemented yet!");
1423 : // TODO implement
1424 0 : return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eProcedureColumns);
1425 : }
1426 :
1427 0 : uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getProcedures(
1428 : const Any& catalog, const OUString& schemaPattern,
1429 : const OUString& procedureNamePattern ) throw(SQLException, RuntimeException, std::exception)
1430 : {
1431 : SAL_WARN("connectivity.firebird", "Not yet implemented");
1432 : (void) catalog;
1433 : (void) schemaPattern;
1434 : (void) procedureNamePattern;
1435 : OSL_FAIL("Not implemented yet!");
1436 : // TODO implement
1437 0 : return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eProcedures);
1438 : }
1439 :
1440 0 : uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getVersionColumns(
1441 : const Any& catalog, const OUString& schema, const OUString& table ) throw(SQLException, RuntimeException, std::exception)
1442 : {
1443 : SAL_WARN("connectivity.firebird", "Not yet implemented");
1444 : (void) catalog;
1445 : (void) schema;
1446 : (void) table;
1447 : OSL_FAIL("Not implemented yet!");
1448 : // TODO implement
1449 0 : return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eVersionColumns);
1450 : }
1451 :
1452 0 : uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getExportedKeys(
1453 : const Any& catalog, const OUString& schema, const OUString& table ) throw(SQLException, RuntimeException, std::exception)
1454 : {
1455 : // List the columns in a table which are foreign keys. This is actually
1456 : // never used anywhere in the LO codebase currently. Retrieval from firebird
1457 : // requires using a 5-table join.
1458 : SAL_WARN("connectivity.firebird", "Not yet implemented");
1459 : (void) catalog;
1460 : (void) schema;
1461 : (void) table;
1462 : OSL_FAIL("Not implemented yet!");
1463 : // TODO implement
1464 0 : return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eExportedKeys);
1465 : }
1466 :
1467 0 : uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getImportedKeys(
1468 : const Any& catalog, const OUString& schema, const OUString& table ) throw(SQLException, RuntimeException, std::exception)
1469 : {
1470 : // List the columns in a table (which must be primary key, or possibly just
1471 : // unique) that are referred to in other foreign keys. Will have a similar
1472 : // 5-table or so join as in getExportedKeys.
1473 : SAL_WARN("connectivity.firebird", "Not yet implemented");
1474 : (void) catalog;
1475 : (void) schema;
1476 : (void) table;
1477 : OSL_FAIL("Not implemented yet!");
1478 : // TODO implement
1479 0 : return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eImportedKeys);
1480 : }
1481 :
1482 0 : uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getPrimaryKeys(
1483 : const Any& /*aCatalog*/,
1484 : const OUString& /*sSchema*/,
1485 : const OUString& sTable)
1486 : throw(SQLException, RuntimeException, std::exception)
1487 : {
1488 : SAL_INFO("connectivity.firebird", "getPrimaryKeys() with "
1489 : "Table: " << sTable);
1490 :
1491 : OUStringBuffer aQueryBuf("SELECT "
1492 : "constr.RDB$RELATION_NAME, " // 1. Table Name
1493 : "inds.RDB$FIELD_NAME, " // 2. Column Name
1494 : "inds.RDB$FIELD_POSITION, " // 3. Sequence Number
1495 : "constr.RDB$CONSTRAINT_NAME " // 4 Constraint name
1496 : "FROM RDB$RELATION_CONSTRAINTS constr "
1497 : "JOIN RDB$INDEX_SEGMENTS inds "
1498 0 : "on (constr.RDB$INDEX_NAME = inds.RDB$INDEX_NAME) ");
1499 :
1500 0 : OUString sAppend = "WHERE constr.RDB$RELATION_NAME = '%' ";
1501 0 : aQueryBuf.append(sAppend.replaceAll("%", sTable));
1502 :
1503 : aQueryBuf.append("AND constr.RDB$CONSTRAINT_TYPE = 'PRIMARY KEY' "
1504 0 : "ORDER BY inds.RDB$FIELD_NAME");
1505 :
1506 0 : OUString sQuery = aQueryBuf.makeStringAndClear();
1507 :
1508 0 : uno::Reference< XStatement > xStatement = m_pConnection->createStatement();
1509 0 : uno::Reference< XResultSet > xRs = xStatement->executeQuery(sQuery);
1510 0 : uno::Reference< XRow > xRow( xRs, UNO_QUERY_THROW );
1511 :
1512 0 : ODatabaseMetaDataResultSet::ORows aResults;
1513 0 : ODatabaseMetaDataResultSet::ORow aCurrentRow(7);
1514 :
1515 0 : aCurrentRow[0] = new ORowSetValueDecorator(); // Unused -- numbering starts from 0
1516 0 : aCurrentRow[1] = new ORowSetValueDecorator(); // Catalog - can be null
1517 0 : aCurrentRow[2] = new ORowSetValueDecorator(); // Schema - can be null
1518 :
1519 0 : while(xRs->next())
1520 : {
1521 : // 3. Table Name
1522 0 : if (xRs->getRow() == 1) // Table name doesn't change, so only retrieve once
1523 : {
1524 0 : aCurrentRow[3] = new ORowSetValueDecorator(sanitizeIdentifier(xRow->getString(1)));
1525 : }
1526 : // 4. Column Name
1527 0 : aCurrentRow[4] = new ORowSetValueDecorator(sanitizeIdentifier(xRow->getString(2)));
1528 : // 5. KEY_SEQ (which key in the sequence)
1529 0 : aCurrentRow[5] = new ORowSetValueDecorator(xRow->getShort(3));
1530 : // 6. Primary Key Name
1531 0 : aCurrentRow[6] = new ORowSetValueDecorator(sanitizeIdentifier(xRow->getString(4)));
1532 :
1533 0 : aResults.push_back(aCurrentRow);
1534 : }
1535 : ODatabaseMetaDataResultSet* pResultSet = new
1536 0 : ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::ePrimaryKeys);
1537 0 : uno::Reference< XResultSet > xResultSet = pResultSet;
1538 0 : pResultSet->setRows( aResults );
1539 :
1540 0 : return xResultSet;
1541 : }
1542 :
1543 0 : uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getIndexInfo(
1544 : const Any& /*aCatalog*/,
1545 : const OUString& /*sSchema*/,
1546 : const OUString& sTable,
1547 : sal_Bool bIsUnique,
1548 : sal_Bool bIsApproximate)
1549 : throw(SQLException, RuntimeException, std::exception)
1550 : {
1551 : // Apparently this method can also return a "tableIndexStatistic"
1552 : // However this is only mentioned in XDatabaseMetaData.idl (whose comments
1553 : // are duplicated in the postgresql driver), and is otherwise undocumented.
1554 : SAL_INFO("connectivity.firebird", "getPrimaryKeys() with "
1555 : "Table: " << sTable);
1556 :
1557 : OUStringBuffer aQueryBuf("SELECT "
1558 : "indices.RDB$RELATION_NAME, " // 1. Table Name
1559 : "index_segments.RDB$FIELD_NAME, " // 2. Column Name
1560 : "index_segments.RDB$FIELD_POSITION, " // 3. Sequence Number
1561 : "indices.RDB$INDEX_NAME, " // 4. Index name
1562 : "indices.RDB$UNIQUE_FLAG, " // 5. Unique Flag
1563 : "indices.RDB$INDEX_TYPE " // 6. Index Type
1564 : "FROM RDB$INDICES indices "
1565 : "JOIN RDB$INDEX_SEGMENTS index_segments "
1566 : "on (indices.RDB$INDEX_NAME = index_segments.RDB$INDEX_NAME) "
1567 0 : "WHERE indices.RDB$RELATION_NAME = '" + sTable + "' "
1568 0 : "AND (indices.RDB$SYSTEM_FLAG = 0) ");
1569 : // Not sure whether we should exclude system indices, but otoh. we never
1570 : // actually deal with system tables (system indices only apply to system
1571 : // tables) within the GUI.
1572 :
1573 : // Only filter if true (according to the docs), i.e.:
1574 : // If false we return all indices, if true we return only unique indices
1575 0 : if (bIsUnique)
1576 0 : aQueryBuf.append("AND (indices.RDB$UNIQUE_FLAG = 1) ");
1577 :
1578 : // TODO: what is bIsApproximate?
1579 : (void) bIsApproximate;
1580 :
1581 0 : OUString sQuery = aQueryBuf.makeStringAndClear();
1582 :
1583 0 : uno::Reference< XStatement > xStatement = m_pConnection->createStatement();
1584 0 : uno::Reference< XResultSet > xRs = xStatement->executeQuery(sQuery);
1585 0 : uno::Reference< XRow > xRow( xRs, UNO_QUERY_THROW );
1586 :
1587 0 : ODatabaseMetaDataResultSet::ORows aResults;
1588 0 : ODatabaseMetaDataResultSet::ORow aCurrentRow(14);
1589 :
1590 0 : aCurrentRow[0] = new ORowSetValueDecorator(); // Unused -- numbering starts from 0
1591 0 : aCurrentRow[1] = new ORowSetValueDecorator(); // Catalog - can be null
1592 0 : aCurrentRow[2] = new ORowSetValueDecorator(); // Schema - can be null
1593 0 : aCurrentRow[5] = new ORowSetValueDecorator(); // Index Catalog -- can be null
1594 : // According to wikipedia firebird uses clustered indices.
1595 : // The documentation does not specifically seem to specify this.
1596 0 : aCurrentRow[7] = new ORowSetValueDecorator(IndexType::CLUSTERED); // 7. INDEX TYPE
1597 0 : aCurrentRow[13] = new ORowSetValueDecorator(); // Filter Condition -- can be null
1598 :
1599 0 : while(xRs->next())
1600 : {
1601 : // 3. Table Name
1602 0 : if (xRs->getRow() == 1) // Table name doesn't change, so only retrieve once
1603 : {
1604 0 : aCurrentRow[3] = new ORowSetValueDecorator(sanitizeIdentifier(xRow->getString(1)));
1605 : }
1606 :
1607 : // 4. NON_UNIQUE -- i.e. specifically negate here.
1608 0 : aCurrentRow[4] = new ORowSetValueDecorator(!xRow->getBoolean(5));
1609 : // 6. INDEX NAME
1610 0 : aCurrentRow[6] = new ORowSetValueDecorator(sanitizeIdentifier(xRow->getString(4)));
1611 :
1612 : // 8. ORDINAL POSITION
1613 0 : aCurrentRow[8] = new ORowSetValueDecorator(xRow->getShort(3));
1614 : // 9. COLUMN NAME
1615 0 : aCurrentRow[9] = new ORowSetValueDecorator(sanitizeIdentifier(xRow->getString(2)));
1616 : // 10. ASC(ending)/DESC(ending)
1617 0 : if (xRow->getShort(6) == 1)
1618 0 : aCurrentRow[10] = new ORowSetValueDecorator(OUString("D"));
1619 : else
1620 0 : aCurrentRow[10] = new ORowSetValueDecorator(OUString("A"));
1621 : // TODO: double check this^^^, doesn't seem to be officially documented anywhere.
1622 : // 11. CARDINALITY
1623 0 : aCurrentRow[11] = new ORowSetValueDecorator((sal_Int32)0); // TODO: determine how to do this
1624 : // 12. PAGES
1625 0 : aCurrentRow[12] = new ORowSetValueDecorator((sal_Int32)0); // TODO: determine how to do this
1626 :
1627 0 : aResults.push_back(aCurrentRow);
1628 : }
1629 : ODatabaseMetaDataResultSet* pResultSet = new
1630 0 : ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::ePrimaryKeys);
1631 0 : uno::Reference< XResultSet > xResultSet = pResultSet;
1632 0 : pResultSet->setRows( aResults );
1633 :
1634 0 : return xResultSet;
1635 : }
1636 :
1637 0 : uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getBestRowIdentifier(
1638 : const Any& catalog, const OUString& schema, const OUString& table, sal_Int32 scope,
1639 : sal_Bool nullable ) throw(SQLException, RuntimeException, std::exception)
1640 : {
1641 : (void) catalog;
1642 : (void) schema;
1643 : (void) table;
1644 : (void) scope;
1645 : (void) nullable;
1646 : OSL_FAIL("Not implemented yet!");
1647 : // TODO implement
1648 0 : return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eBestRowIdentifier);
1649 : }
1650 :
1651 0 : uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTablePrivileges(
1652 : const Any& /*aCatalog*/,
1653 : const OUString& /*sSchemaPattern*/,
1654 : const OUString& sTableNamePattern)
1655 : throw(SQLException, RuntimeException, std::exception)
1656 : {
1657 : SAL_INFO("connectivity.firebird", "getTablePrivileges() with "
1658 : "TableNamePattern: " << sTableNamePattern);
1659 :
1660 : ODatabaseMetaDataResultSet* pResultSet = new
1661 0 : ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eTablePrivileges);
1662 0 : uno::Reference< XResultSet > xResultSet = pResultSet;
1663 0 : uno::Reference< XStatement > statement = m_pConnection->createStatement();
1664 :
1665 : // TODO: column specific privileges are included, we may need
1666 : // to have WHERE RDB$FIELD_NAME = NULL or similar.
1667 0 : static const OUString wld("%");
1668 : OUStringBuffer queryBuf(
1669 : "SELECT "
1670 : "priv.RDB$RELATION_NAME, " // 1
1671 : "priv.RDB$GRANTOR," // 2
1672 : "priv.RDB$USER, " // 3 Grantee
1673 : "priv.RDB$PRIVILEGE, " // 4
1674 : "priv.RDB$GRANT_OPTION " // 5 is Grantable
1675 0 : "FROM RDB$USER_PRIVILEGES priv ");
1676 :
1677 0 : if (!sTableNamePattern.isEmpty())
1678 : {
1679 0 : OUString sAppend;
1680 0 : if (sTableNamePattern.match(wld))
1681 0 : sAppend = "WHERE priv.RDB$RELATION_NAME LIKE '%' ";
1682 : else
1683 0 : sAppend = "WHERE priv.RDB$RELATION_NAME = '%' ";
1684 :
1685 0 : queryBuf.append(sAppend.replaceAll(wld, sTableNamePattern));
1686 : }
1687 : queryBuf.append(" ORDER BY priv.RDB$RELATION_TYPE, "
1688 : "priv.RDB$RELATION_NAME, "
1689 0 : "priv.RDB$PRIVILEGE");
1690 :
1691 0 : OUString query = queryBuf.makeStringAndClear();
1692 :
1693 0 : uno::Reference< XResultSet > rs = statement->executeQuery(query.getStr());
1694 0 : uno::Reference< XRow > xRow( rs, UNO_QUERY_THROW );
1695 0 : ODatabaseMetaDataResultSet::ORows aResults;
1696 :
1697 0 : ODatabaseMetaDataResultSet::ORow aRow(8);
1698 0 : aRow[0] = new ORowSetValueDecorator(); // Unused
1699 0 : aRow[1] = new ORowSetValueDecorator(); // TABLE_CAT unsupported
1700 0 : aRow[2] = new ORowSetValueDecorator(); // TABLE_SCHEM unussported.
1701 :
1702 0 : while( rs->next() )
1703 : {
1704 : // 3. TABLE_NAME
1705 0 : aRow[3] = new ORowSetValueDecorator(sanitizeIdentifier(xRow->getString(1)));
1706 0 : aRow[4] = new ORowSetValueDecorator(xRow->getString(2)); // 4. GRANTOR
1707 0 : aRow[5] = new ORowSetValueDecorator(xRow->getString(3)); // 5. GRANTEE
1708 0 : aRow[6] = new ORowSetValueDecorator(xRow->getString(4)); // 6. Privilege
1709 0 : aRow[7] = new ORowSetValueDecorator(xRow->getBoolean(5)); // 7. Is Grantable
1710 :
1711 0 : aResults.push_back(aRow);
1712 : }
1713 :
1714 0 : pResultSet->setRows( aResults );
1715 :
1716 0 : return xResultSet;
1717 : }
1718 :
1719 0 : uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getCrossReference(
1720 : const Any& primaryCatalog, const OUString& primarySchema,
1721 : const OUString& primaryTable, const Any& foreignCatalog,
1722 : const OUString& foreignSchema, const OUString& foreignTable ) throw(SQLException, RuntimeException, std::exception)
1723 : {
1724 : (void) primaryCatalog;
1725 : (void) primarySchema;
1726 : (void) primaryTable;
1727 : (void) foreignCatalog;
1728 : (void) foreignSchema;
1729 : (void) foreignTable;
1730 : OSL_FAIL("Not implemented yet!");
1731 : // TODO implement
1732 0 : return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eCrossReference);
1733 : }
1734 :
1735 0 : uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getUDTs( const Any& catalog, const OUString& schemaPattern, const OUString& typeNamePattern, const Sequence< sal_Int32 >& types ) throw(SQLException, RuntimeException, std::exception)
1736 : {
1737 : (void) catalog;
1738 : (void) schemaPattern;
1739 : (void) typeNamePattern;
1740 : (void) types;
1741 : OSL_FAIL("Not implemented yet!");
1742 : // TODO implement
1743 0 : return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eUDTs);
1744 : }
1745 :
1746 :
1747 :
1748 :
1749 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|