summaryrefslogtreecommitdiff
path: root/connectivity
diff options
context:
space:
mode:
authorAndrzej J.R. Hunt <andrzej@ahunt.org>2013-09-05 08:20:43 +0100
committerAndrzej J.R. Hunt <andrzej@ahunt.org>2013-09-06 13:46:49 +0100
commit17a2a19ca23c0e3acf6dadc5ccdad054395738ef (patch)
tree549f0f0670272b365bc735993a222b9a07d2885b /connectivity
parentb10afb26296e33c77e94a6eda3f2c36c4d34c2aa (diff)
Implement getIndexInfo. (firebird-sdbc)
Change-Id: I8c3393fbc7c4fb418f31a80b23360c6c7bf21a25
Diffstat (limited to 'connectivity')
-rw-r--r--connectivity/source/drivers/firebird/DatabaseMetaData.cxx101
1 files changed, 92 insertions, 9 deletions
diff --git a/connectivity/source/drivers/firebird/DatabaseMetaData.cxx b/connectivity/source/drivers/firebird/DatabaseMetaData.cxx
index 2eabddff0866..ddb9ea45984c 100644
--- a/connectivity/source/drivers/firebird/DatabaseMetaData.cxx
+++ b/connectivity/source/drivers/firebird/DatabaseMetaData.cxx
@@ -26,6 +26,7 @@
#include <com/sun/star/sdbc/ColumnValue.hpp>
#include <com/sun/star/sdbc/DataType.hpp>
+#include <com/sun/star/sdbc/IndexType.hpp>
#include <com/sun/star/sdbc/ResultSetType.hpp>
#include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
#include <com/sun/star/sdbc/TransactionIsolation.hpp>
@@ -1548,17 +1549,99 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getPrimaryKeys(
return xResultSet;
}
-// -------------------------------------------------------------------------
+
uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getIndexInfo(
- const Any& catalog, const OUString& schema, const OUString& table,
- sal_Bool unique, sal_Bool approximate ) throw(SQLException, RuntimeException)
+ const Any& aCatalog, const OUString& sSchema, const OUString& sTable,
+ sal_Bool bIsUnique, sal_Bool bIsApproximate)
+ throw(SQLException, RuntimeException)
{
- (void) catalog;
- (void) schema;
- (void) table;
- (void) unique;
- (void) approximate;
- return NULL;
+ (void) aCatalog;
+ (void) sSchema;
+
+ // Apparently this method can also return a "tableIndexStatistic"
+ // However this is only mentioned in XDatabaseMetaData.idl (whose comments
+ // are duplicated in the postgresql driver), and is otherwise undocumented.
+
+ SAL_INFO("connectivity.firebird", "getPrimaryKeys() with "
+ "Table: " << sTable);
+
+ OUStringBuffer aQueryBuf("SELECT "
+ "indices.RDB$RELATION_NAME, " // 1. Table Name
+ "index_segments.RDB$FIELD_NAME, " // 2. Column Name
+ "index_segments.RDB$FIELD_POSITION, " // 3. Sequence Number
+ "indices.RDB$INDEX_NAME, " // 4. Index name
+ "indices.RDB$UNIQUE_FLAG, " // 5. Unique Flag
+ "indices.RDB$INDEX_TYPE " // 6. Index Type
+ "FROM RDB$INDICES indices "
+ "JOIN RDB$INDEX_SEGMENTS index_segments "
+ "on (indices.RDB$INDEX_NAME = index_segments.RDB$INDEX_NAME) "
+ "WHERE (indices.RDB$SYSTEM_FLAG = 0) ");
+ // Not sure whether we should exclude system indices, but otoh. we never
+ // actually deal with system tables (system indices only apply to system
+ // tables) within the GUI.
+
+ // Only filter if true (according to the docs), i.e.:
+ // If false we return all indices, if true we return only unique indices
+ if (bIsUnique)
+ aQueryBuf.append("AND (indices.RDB$UNIQUE_FLAG = 1) ");
+
+ // TODO: what is bIsApproximate?
+ (void) bIsApproximate;
+
+ OUString sQuery = aQueryBuf.makeStringAndClear();
+
+ uno::Reference< XStatement > xStatement = m_pConnection->createStatement();
+ uno::Reference< XResultSet > xRs = xStatement->executeQuery(sQuery);
+ uno::Reference< XRow > xRow( xRs, UNO_QUERY_THROW );
+
+ ODatabaseMetaDataResultSet::ORows aResults;
+ ODatabaseMetaDataResultSet::ORow aCurrentRow(14);
+
+ aCurrentRow[0] = new ORowSetValueDecorator(); // Unused -- numbering starts from 0
+ aCurrentRow[1] = new ORowSetValueDecorator(); // Catalog - can be null
+ aCurrentRow[2] = new ORowSetValueDecorator(); // Schema - can be null
+ aCurrentRow[5] = new ORowSetValueDecorator(); // Index Catalog -- can be null
+ // According to wikipedia firebird uses clustered indices.
+ // The documentation does not specifically seem to specify this.
+ aCurrentRow[7] = new ORowSetValueDecorator(IndexType::CLUSTERED); // 7. INDEX TYPE
+ aCurrentRow[13] = new ORowSetValueDecorator(); // Filter Condition -- can be null
+
+ while(xRs->next())
+ {
+ // 3. Table Name
+ if (xRs->getRow() == 1) // Table name doesn't change, so only retrieve once
+ {
+ aCurrentRow[3] = new ORowSetValueDecorator(sanitizeIdentifier(xRow->getString(1)));
+ }
+
+ // 4. NON_UNIQUE -- i.e. specifically negate here.
+ aCurrentRow[4] = new ORowSetValueDecorator(!xRow->getBoolean(5));
+ // 6. INDEX NAME
+ aCurrentRow[6] = new ORowSetValueDecorator(sanitizeIdentifier(xRow->getString(4)));
+
+ // 8. ORDINAL POSITION
+ aCurrentRow[8] = new ORowSetValueDecorator(xRow->getShort(3));
+ // 9. COLUMN NAME
+ aCurrentRow[9] = new ORowSetValueDecorator(sanitizeIdentifier(xRow->getString(2)));
+ // 10. ASC(ending)/DESC(ending)
+ if (xRow->getShort(6) == 1)
+ aCurrentRow[10] = new ORowSetValueDecorator(OUString("D"));
+ else
+ aCurrentRow[10] = new ORowSetValueDecorator(OUString("A"));
+ // TODO: double check this^^^, doesn't seem to be officially documented anywhere.
+ // 11. CARDINALITY
+ aCurrentRow[11] = new ORowSetValueDecorator((sal_Int32)0); // TODO: determine how to do this
+ // 12. PAGES
+ aCurrentRow[12] = new ORowSetValueDecorator((sal_Int32)0); // TODO: determine how to do this
+
+ aResults.push_back(aCurrentRow);
+ }
+ ODatabaseMetaDataResultSet* pResultSet = new
+ ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::ePrimaryKeys);
+ uno::Reference< XResultSet > xResultSet = pResultSet;
+ pResultSet->setRows( aResults );
+
+ return xResultSet;
}
// -------------------------------------------------------------------------
uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getBestRowIdentifier(