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