001/*
002// This software is subject to the terms of the Eclipse Public License v1.0
003// Agreement, available at the following URL:
004// http://www.eclipse.org/legal/epl-v10.html.
005// You must accept the terms of that agreement to use this software.
006//
007// Copyright (C) 2007-2011 Pentaho
008// All Rights Reserved.
009*/
010package mondrian.olap4j;
011
012import mondrian.olap.Util;
013import mondrian.rolap.RolapConnection;
014import mondrian.xmla.XmlaUtil;
015
016import org.olap4j.*;
017import org.olap4j.metadata.*;
018
019import java.sql.ResultSet;
020import java.sql.SQLException;
021import java.util.*;
022
023/**
024 * Implementation of {@link org.olap4j.OlapDatabaseMetaData}
025 * for the Mondrian OLAP engine.
026 *
027 * <p>This class has sub-classes which implement JDBC 3.0 and JDBC 4.0 APIs;
028 * it is instantiated using {@link Factory#newDatabaseMetaData}.</p>
029 *
030 * @author jhyde
031 * @since May 23, 2007
032 */
033abstract class MondrianOlap4jDatabaseMetaData implements OlapDatabaseMetaData {
034    final MondrianOlap4jConnection olap4jConnection;
035
036    private static final Comparator<Catalog> CATALOG_COMP =
037        new Comparator<Catalog>() {
038            public int compare(Catalog o1, Catalog o2) {
039                return o1.getName().compareTo(o2.getName());
040            }
041        };
042
043    private static final Comparator<Schema> SCHEMA_COMP =
044        new Comparator<Schema>() {
045            public int compare(Schema o1, Schema o2) {
046                return o1.getName().compareTo(o2.getName());
047            }
048        };
049
050    /**
051     * Creates a MondrianOlap4jDatabaseMetaData.
052     *
053     * @param olap4jConnection Connection
054     * @param mondrianConnection Mondrian connection
055     */
056    MondrianOlap4jDatabaseMetaData(
057        MondrianOlap4jConnection olap4jConnection,
058        RolapConnection mondrianConnection)
059    {
060        this.olap4jConnection = olap4jConnection;
061    }
062
063    // helpers
064
065    /**
066     * Executes a metadata query and returns the result as a JDBC
067     * {@link ResultSet}.
068     *
069     * <p>The XMLA specification usually specifies that the returned list is
070     * ordered by particular attributes. XMLA notwithstanding, the result from
071     * this method is always ordered.
072     *
073     * @param methodName Name of the metadata request. Corresponds to the XMLA
074     * method name, e.g. "MDSCHEMA_CUBES"
075     *
076     * @param patternValues Array of alternating parameter name and value
077     * pairs. If the parameter value is null, it is ignored.
078     *
079     * @return Result set of metadata
080     *
081     * @throws org.olap4j.OlapException on error
082     */
083    private ResultSet getMetadata(
084        String methodName,
085        Object... patternValues)
086        throws OlapException
087    {
088        Map<String, Object> restrictionMap =
089            new HashMap<String, Object>();
090        assert patternValues.length % 2 == 0;
091        for (int i = 0; i < patternValues.length / 2; ++i) {
092            final String key = (String) patternValues[i * 2];
093            Object value = patternValues[i * 2 + 1];
094            if (value != null) {
095                if (value instanceof String) {
096                    value = Collections.singletonList((String) value);
097                }
098                restrictionMap.put(key, value);
099            }
100        }
101        XmlaUtil.MetadataRowset rowset =
102            XmlaUtil.getMetadataRowset(
103                olap4jConnection,
104                methodName,
105                restrictionMap);
106        return olap4jConnection.factory.newFixedResultSet(
107            olap4jConnection, rowset.headerList, rowset.rowList);
108    }
109
110    /**
111     * Wraps a string in an object that indicates that it is to be treated as
112     * a wildcard pattern, not a literal match.
113     *
114     * @param pattern Pattern
115     * @return Wildcard, or null if pattern is null
116     */
117    private XmlaUtil.Wildcard wildcard(String pattern) {
118        return pattern == null
119            ? null
120            : new XmlaUtil.Wildcard(pattern);
121    }
122
123    // implement DatabaseMetaData
124
125    public boolean allProceduresAreCallable() throws SQLException {
126        throw new UnsupportedOperationException();
127    }
128
129    public boolean allTablesAreSelectable() throws SQLException {
130        throw new UnsupportedOperationException();
131    }
132
133    public String getURL() throws SQLException {
134        return olap4jConnection.getMondrianConnection().getConnectString();
135    }
136
137    public String getUserName() throws SQLException {
138        // mondrian does not support a user name property
139        return null;
140    }
141
142    public boolean isReadOnly() throws SQLException {
143        // all mondrian databases are read-only
144        return true;
145    }
146
147    public boolean nullsAreSortedHigh() throws SQLException {
148        throw new UnsupportedOperationException();
149    }
150
151    public boolean nullsAreSortedLow() throws SQLException {
152        throw new UnsupportedOperationException();
153    }
154
155    public boolean nullsAreSortedAtStart() throws SQLException {
156        throw new UnsupportedOperationException();
157    }
158
159    public boolean nullsAreSortedAtEnd() throws SQLException {
160        throw new UnsupportedOperationException();
161    }
162
163    public String getDatabaseProductName() throws SQLException {
164        return olap4jConnection.mondrianServer.getVersion().getProductName();
165    }
166
167    public String getDatabaseProductVersion() throws SQLException {
168        return olap4jConnection.mondrianServer.getVersion().getVersionString();
169    }
170
171    public String getDriverName() throws SQLException {
172        return olap4jConnection.driver.getName();
173    }
174
175    public String getDriverVersion() throws SQLException {
176        return olap4jConnection.driver.getVersion();
177    }
178
179    public int getDriverMajorVersion() {
180        return olap4jConnection.driver.getMajorVersion();
181    }
182
183    public int getDriverMinorVersion() {
184        return olap4jConnection.driver.getMinorVersion();
185    }
186
187    public boolean usesLocalFiles() throws SQLException {
188        throw new UnsupportedOperationException();
189    }
190
191    public boolean usesLocalFilePerTable() throws SQLException {
192        throw new UnsupportedOperationException();
193    }
194
195    public boolean supportsMixedCaseIdentifiers() throws SQLException {
196        throw new UnsupportedOperationException();
197    }
198
199    public boolean storesUpperCaseIdentifiers() throws SQLException {
200        throw new UnsupportedOperationException();
201    }
202
203    public boolean storesLowerCaseIdentifiers() throws SQLException {
204        throw new UnsupportedOperationException();
205    }
206
207    public boolean storesMixedCaseIdentifiers() throws SQLException {
208        throw new UnsupportedOperationException();
209    }
210
211    public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException {
212        throw new UnsupportedOperationException();
213    }
214
215    public boolean storesUpperCaseQuotedIdentifiers() throws SQLException {
216        throw new UnsupportedOperationException();
217    }
218
219    public boolean storesLowerCaseQuotedIdentifiers() throws SQLException {
220        throw new UnsupportedOperationException();
221    }
222
223    public boolean storesMixedCaseQuotedIdentifiers() throws SQLException {
224        throw new UnsupportedOperationException();
225    }
226
227    public String getIdentifierQuoteString() throws SQLException {
228        throw new UnsupportedOperationException();
229    }
230
231    public String getSQLKeywords() throws SQLException {
232        throw new UnsupportedOperationException();
233    }
234
235    public String getNumericFunctions() throws SQLException {
236        throw new UnsupportedOperationException();
237    }
238
239    public String getStringFunctions() throws SQLException {
240        throw new UnsupportedOperationException();
241    }
242
243    public String getSystemFunctions() throws SQLException {
244        throw new UnsupportedOperationException();
245    }
246
247    public String getTimeDateFunctions() throws SQLException {
248        throw new UnsupportedOperationException();
249    }
250
251    public String getSearchStringEscape() throws SQLException {
252        throw new UnsupportedOperationException();
253    }
254
255    public String getExtraNameCharacters() throws SQLException {
256        throw new UnsupportedOperationException();
257    }
258
259    public boolean supportsAlterTableWithAddColumn() throws SQLException {
260        throw new UnsupportedOperationException();
261    }
262
263    public boolean supportsAlterTableWithDropColumn() throws SQLException {
264        throw new UnsupportedOperationException();
265    }
266
267    public boolean supportsColumnAliasing() throws SQLException {
268        throw new UnsupportedOperationException();
269    }
270
271    public boolean nullPlusNonNullIsNull() throws SQLException {
272        throw new UnsupportedOperationException();
273    }
274
275    public boolean supportsConvert() throws SQLException {
276        throw new UnsupportedOperationException();
277    }
278
279    public boolean supportsConvert(
280        int fromType, int toType) throws SQLException
281    {
282        throw new UnsupportedOperationException();
283    }
284
285    public boolean supportsTableCorrelationNames() throws SQLException {
286        throw new UnsupportedOperationException();
287    }
288
289    public boolean supportsDifferentTableCorrelationNames()
290        throws SQLException
291    {
292        throw new UnsupportedOperationException();
293    }
294
295    public boolean supportsExpressionsInOrderBy() throws SQLException {
296        throw new UnsupportedOperationException();
297    }
298
299    public boolean supportsOrderByUnrelated() throws SQLException {
300        throw new UnsupportedOperationException();
301    }
302
303    public boolean supportsGroupBy() throws SQLException {
304        throw new UnsupportedOperationException();
305    }
306
307    public boolean supportsGroupByUnrelated() throws SQLException {
308        throw new UnsupportedOperationException();
309    }
310
311    public boolean supportsGroupByBeyondSelect() throws SQLException {
312        throw new UnsupportedOperationException();
313    }
314
315    public boolean supportsLikeEscapeClause() throws SQLException {
316        throw new UnsupportedOperationException();
317    }
318
319    public boolean supportsMultipleResultSets() throws SQLException {
320        throw new UnsupportedOperationException();
321    }
322
323    public boolean supportsMultipleTransactions() throws SQLException {
324        throw new UnsupportedOperationException();
325    }
326
327    public boolean supportsNonNullableColumns() throws SQLException {
328        throw new UnsupportedOperationException();
329    }
330
331    public boolean supportsMinimumSQLGrammar() throws SQLException {
332        throw new UnsupportedOperationException();
333    }
334
335    public boolean supportsCoreSQLGrammar() throws SQLException {
336        throw new UnsupportedOperationException();
337    }
338
339    public boolean supportsExtendedSQLGrammar() throws SQLException {
340        throw new UnsupportedOperationException();
341    }
342
343    public boolean supportsANSI92EntryLevelSQL() throws SQLException {
344        throw new UnsupportedOperationException();
345    }
346
347    public boolean supportsANSI92IntermediateSQL() throws SQLException {
348        throw new UnsupportedOperationException();
349    }
350
351    public boolean supportsANSI92FullSQL() throws SQLException {
352        throw new UnsupportedOperationException();
353    }
354
355    public boolean supportsIntegrityEnhancementFacility() throws SQLException {
356        throw new UnsupportedOperationException();
357    }
358
359    public boolean supportsOuterJoins() throws SQLException {
360        throw new UnsupportedOperationException();
361    }
362
363    public boolean supportsFullOuterJoins() throws SQLException {
364        throw new UnsupportedOperationException();
365    }
366
367    public boolean supportsLimitedOuterJoins() throws SQLException {
368        throw new UnsupportedOperationException();
369    }
370
371    public String getSchemaTerm() throws SQLException {
372        throw new UnsupportedOperationException();
373    }
374
375    public String getProcedureTerm() throws SQLException {
376        throw new UnsupportedOperationException();
377    }
378
379    public String getCatalogTerm() throws SQLException {
380        throw new UnsupportedOperationException();
381    }
382
383    public boolean isCatalogAtStart() throws SQLException {
384        throw new UnsupportedOperationException();
385    }
386
387    public String getCatalogSeparator() throws SQLException {
388        throw new UnsupportedOperationException();
389    }
390
391    public boolean supportsSchemasInDataManipulation() throws SQLException {
392        throw new UnsupportedOperationException();
393    }
394
395    public boolean supportsSchemasInProcedureCalls() throws SQLException {
396        throw new UnsupportedOperationException();
397    }
398
399    public boolean supportsSchemasInTableDefinitions() throws SQLException {
400        throw new UnsupportedOperationException();
401    }
402
403    public boolean supportsSchemasInIndexDefinitions() throws SQLException {
404        throw new UnsupportedOperationException();
405    }
406
407    public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException {
408        throw new UnsupportedOperationException();
409    }
410
411    public boolean supportsCatalogsInDataManipulation() throws SQLException {
412        throw new UnsupportedOperationException();
413    }
414
415    public boolean supportsCatalogsInProcedureCalls() throws SQLException {
416        throw new UnsupportedOperationException();
417    }
418
419    public boolean supportsCatalogsInTableDefinitions() throws SQLException {
420        throw new UnsupportedOperationException();
421    }
422
423    public boolean supportsCatalogsInIndexDefinitions() throws SQLException {
424        throw new UnsupportedOperationException();
425    }
426
427    public boolean supportsCatalogsInPrivilegeDefinitions()
428        throws SQLException
429    {
430        throw new UnsupportedOperationException();
431    }
432
433    public boolean supportsPositionedDelete() throws SQLException {
434        throw new UnsupportedOperationException();
435    }
436
437    public boolean supportsPositionedUpdate() throws SQLException {
438        throw new UnsupportedOperationException();
439    }
440
441    public boolean supportsSelectForUpdate() throws SQLException {
442        throw new UnsupportedOperationException();
443    }
444
445    public boolean supportsStoredProcedures() throws SQLException {
446        throw new UnsupportedOperationException();
447    }
448
449    public boolean supportsSubqueriesInComparisons() throws SQLException {
450        throw new UnsupportedOperationException();
451    }
452
453    public boolean supportsSubqueriesInExists() throws SQLException {
454        throw new UnsupportedOperationException();
455    }
456
457    public boolean supportsSubqueriesInIns() throws SQLException {
458        throw new UnsupportedOperationException();
459    }
460
461    public boolean supportsSubqueriesInQuantifieds() throws SQLException {
462        throw new UnsupportedOperationException();
463    }
464
465    public boolean supportsCorrelatedSubqueries() throws SQLException {
466        throw new UnsupportedOperationException();
467    }
468
469    public boolean supportsUnion() throws SQLException {
470        throw new UnsupportedOperationException();
471    }
472
473    public boolean supportsUnionAll() throws SQLException {
474        throw new UnsupportedOperationException();
475    }
476
477    public boolean supportsOpenCursorsAcrossCommit() throws SQLException {
478        throw new UnsupportedOperationException();
479    }
480
481    public boolean supportsOpenCursorsAcrossRollback() throws SQLException {
482        throw new UnsupportedOperationException();
483    }
484
485    public boolean supportsOpenStatementsAcrossCommit() throws SQLException {
486        throw new UnsupportedOperationException();
487    }
488
489    public boolean supportsOpenStatementsAcrossRollback() throws SQLException {
490        throw new UnsupportedOperationException();
491    }
492
493    public int getMaxBinaryLiteralLength() throws SQLException {
494        throw new UnsupportedOperationException();
495    }
496
497    public int getMaxCharLiteralLength() throws SQLException {
498        throw new UnsupportedOperationException();
499    }
500
501    public int getMaxColumnNameLength() throws SQLException {
502        throw new UnsupportedOperationException();
503    }
504
505    public int getMaxColumnsInGroupBy() throws SQLException {
506        throw new UnsupportedOperationException();
507    }
508
509    public int getMaxColumnsInIndex() throws SQLException {
510        throw new UnsupportedOperationException();
511    }
512
513    public int getMaxColumnsInOrderBy() throws SQLException {
514        throw new UnsupportedOperationException();
515    }
516
517    public int getMaxColumnsInSelect() throws SQLException {
518        throw new UnsupportedOperationException();
519    }
520
521    public int getMaxColumnsInTable() throws SQLException {
522        throw new UnsupportedOperationException();
523    }
524
525    public int getMaxConnections() throws SQLException {
526        throw new UnsupportedOperationException();
527    }
528
529    public int getMaxCursorNameLength() throws SQLException {
530        throw new UnsupportedOperationException();
531    }
532
533    public int getMaxIndexLength() throws SQLException {
534        throw new UnsupportedOperationException();
535    }
536
537    public int getMaxSchemaNameLength() throws SQLException {
538        throw new UnsupportedOperationException();
539    }
540
541    public int getMaxProcedureNameLength() throws SQLException {
542        throw new UnsupportedOperationException();
543    }
544
545    public int getMaxCatalogNameLength() throws SQLException {
546        throw new UnsupportedOperationException();
547    }
548
549    public int getMaxRowSize() throws SQLException {
550        throw new UnsupportedOperationException();
551    }
552
553    public boolean doesMaxRowSizeIncludeBlobs() throws SQLException {
554        throw new UnsupportedOperationException();
555    }
556
557    public int getMaxStatementLength() throws SQLException {
558        throw new UnsupportedOperationException();
559    }
560
561    public int getMaxStatements() throws SQLException {
562        throw new UnsupportedOperationException();
563    }
564
565    public int getMaxTableNameLength() throws SQLException {
566        throw new UnsupportedOperationException();
567    }
568
569    public int getMaxTablesInSelect() throws SQLException {
570        throw new UnsupportedOperationException();
571    }
572
573    public int getMaxUserNameLength() throws SQLException {
574        throw new UnsupportedOperationException();
575    }
576
577    public int getDefaultTransactionIsolation() throws SQLException {
578        throw new UnsupportedOperationException();
579    }
580
581    public boolean supportsTransactions() throws SQLException {
582        throw new UnsupportedOperationException();
583    }
584
585    public boolean supportsTransactionIsolationLevel(int level)
586        throws SQLException
587    {
588        throw new UnsupportedOperationException();
589    }
590
591    public boolean supportsDataDefinitionAndDataManipulationTransactions()
592        throws SQLException
593    {
594        throw new UnsupportedOperationException();
595    }
596
597    public boolean supportsDataManipulationTransactionsOnly()
598        throws SQLException
599    {
600        throw new UnsupportedOperationException();
601    }
602
603    public boolean dataDefinitionCausesTransactionCommit() throws SQLException {
604        throw new UnsupportedOperationException();
605    }
606
607    public boolean dataDefinitionIgnoredInTransactions() throws SQLException {
608        throw new UnsupportedOperationException();
609    }
610
611    public ResultSet getProcedures(
612        String catalog,
613        String schemaPattern,
614        String procedureNamePattern) throws SQLException
615    {
616        throw new UnsupportedOperationException();
617    }
618
619    public ResultSet getProcedureColumns(
620        String catalog,
621        String schemaPattern,
622        String procedureNamePattern,
623        String columnNamePattern) throws SQLException
624    {
625        throw new UnsupportedOperationException();
626    }
627
628    public ResultSet getTables(
629        String catalog,
630        String schemaPattern,
631        String tableNamePattern,
632        String types[]) throws SQLException
633    {
634        throw new UnsupportedOperationException();
635    }
636
637    public ResultSet getSchemas() throws OlapException {
638        if (false) {
639            // Do not use DBSCHEMA_SCHEMATA: it has different columns than the
640            // JDBC spec requires
641            return getMetadata("DBSCHEMA_SCHEMATA");
642        }
643        List<String> headerList =
644            Arrays.asList("TABLE_SCHEM", "TABLE_CAT");
645        List<List<Object>> rowList = new ArrayList<List<Object>>();
646        for (Catalog catalog
647                : Util.sort(
648                    olap4jConnection.getOlapCatalogs(),
649                    CATALOG_COMP))
650        {
651            for (Schema schema
652                    : Util.sort(
653                        catalog.getSchemas(),
654                        SCHEMA_COMP))
655            {
656                rowList.add(
657                    Arrays.<Object>asList(
658                        schema.getName(),
659                        catalog.getName()));
660            }
661        }
662        return olap4jConnection.factory.newFixedResultSet(
663            olap4jConnection, headerList, rowList);
664    }
665
666    public ResultSet getCatalogs() throws OlapException {
667        if (false) {
668            // Do not use DBSCHEMA_CATALOGS: it has different columns than the
669            // JDBC spec requires
670            return getMetadata("DBSCHEMA_CATALOGS");
671        }
672
673        List<String> headerList =
674            Arrays.asList("TABLE_CAT");
675        List<List<Object>> rowList = new ArrayList<List<Object>>();
676        for (Catalog catalog
677                : Util.sort(
678                    olap4jConnection.getOlapCatalogs(),
679                    CATALOG_COMP))
680        {
681            rowList.add(
682                Collections.<Object>singletonList(catalog.getName()));
683        }
684        return olap4jConnection.factory.newFixedResultSet(
685            olap4jConnection, headerList, rowList);
686    }
687
688    public ResultSet getTableTypes() throws SQLException {
689        throw new UnsupportedOperationException();
690    }
691
692    public ResultSet getColumns(
693        String catalog,
694        String schemaPattern,
695        String tableNamePattern,
696        String columnNamePattern) throws SQLException
697    {
698        throw new UnsupportedOperationException();
699    }
700
701    public ResultSet getColumnPrivileges(
702        String catalog,
703        String schema,
704        String table,
705        String columnNamePattern) throws SQLException
706    {
707        throw new UnsupportedOperationException();
708    }
709
710    public ResultSet getTablePrivileges(
711        String catalog,
712        String schemaPattern,
713        String tableNamePattern) throws SQLException
714    {
715        throw new UnsupportedOperationException();
716    }
717
718    public ResultSet getBestRowIdentifier(
719        String catalog,
720        String schema,
721        String table,
722        int scope,
723        boolean nullable) throws SQLException
724    {
725        throw new UnsupportedOperationException();
726    }
727
728    public ResultSet getVersionColumns(
729        String catalog, String schema, String table) throws SQLException
730    {
731        throw new UnsupportedOperationException();
732    }
733
734    public ResultSet getPrimaryKeys(
735        String catalog, String schema, String table) throws SQLException
736    {
737        throw new UnsupportedOperationException();
738    }
739
740    public ResultSet getImportedKeys(
741        String catalog, String schema, String table) throws SQLException
742    {
743        throw new UnsupportedOperationException();
744    }
745
746    public ResultSet getExportedKeys(
747        String catalog, String schema, String table) throws SQLException
748    {
749        throw new UnsupportedOperationException();
750    }
751
752    public ResultSet getCrossReference(
753        String parentCatalog,
754        String parentSchema,
755        String parentTable,
756        String foreignCatalog,
757        String foreignSchema,
758        String foreignTable) throws SQLException
759    {
760        throw new UnsupportedOperationException();
761    }
762
763    public ResultSet getTypeInfo() throws SQLException {
764        throw new UnsupportedOperationException();
765    }
766
767    public ResultSet getIndexInfo(
768        String catalog,
769        String schema,
770        String table,
771        boolean unique,
772        boolean approximate) throws SQLException
773    {
774        throw new UnsupportedOperationException();
775    }
776
777    public boolean supportsResultSetType(int type) throws SQLException {
778        throw new UnsupportedOperationException();
779    }
780
781    public boolean supportsResultSetConcurrency(
782        int type, int concurrency) throws SQLException
783    {
784        throw new UnsupportedOperationException();
785    }
786
787    public boolean ownUpdatesAreVisible(int type) throws SQLException {
788        throw new UnsupportedOperationException();
789    }
790
791    public boolean ownDeletesAreVisible(int type) throws SQLException {
792        throw new UnsupportedOperationException();
793    }
794
795    public boolean ownInsertsAreVisible(int type) throws SQLException {
796        throw new UnsupportedOperationException();
797    }
798
799    public boolean othersUpdatesAreVisible(int type) throws SQLException {
800        throw new UnsupportedOperationException();
801    }
802
803    public boolean othersDeletesAreVisible(int type) throws SQLException {
804        throw new UnsupportedOperationException();
805    }
806
807    public boolean othersInsertsAreVisible(int type) throws SQLException {
808        throw new UnsupportedOperationException();
809    }
810
811    public boolean updatesAreDetected(int type) throws SQLException {
812        throw new UnsupportedOperationException();
813    }
814
815    public boolean deletesAreDetected(int type) throws SQLException {
816        throw new UnsupportedOperationException();
817    }
818
819    public boolean insertsAreDetected(int type) throws SQLException {
820        throw new UnsupportedOperationException();
821    }
822
823    public boolean supportsBatchUpdates() throws SQLException {
824        throw new UnsupportedOperationException();
825    }
826
827    public ResultSet getUDTs(
828        String catalog,
829        String schemaPattern,
830        String typeNamePattern,
831        int[] types) throws SQLException
832    {
833        throw new UnsupportedOperationException();
834    }
835
836    public OlapConnection getConnection() {
837        return olap4jConnection;
838    }
839
840    public boolean supportsSavepoints() throws SQLException {
841        throw new UnsupportedOperationException();
842    }
843
844    public boolean supportsNamedParameters() throws SQLException {
845        throw new UnsupportedOperationException();
846    }
847
848    public boolean supportsMultipleOpenResults() throws SQLException {
849        throw new UnsupportedOperationException();
850    }
851
852    public boolean supportsGetGeneratedKeys() throws SQLException {
853        throw new UnsupportedOperationException();
854    }
855
856    public ResultSet getSuperTypes(
857        String catalog,
858        String schemaPattern,
859        String typeNamePattern) throws SQLException
860    {
861        throw new UnsupportedOperationException();
862    }
863
864    public ResultSet getSuperTables(
865        String catalog,
866        String schemaPattern,
867        String tableNamePattern) throws SQLException
868    {
869        throw new UnsupportedOperationException();
870    }
871
872    public ResultSet getAttributes(
873        String catalog,
874        String schemaPattern,
875        String typeNamePattern,
876        String attributeNamePattern) throws SQLException
877    {
878        throw new UnsupportedOperationException();
879    }
880
881    public boolean supportsResultSetHoldability(int holdability)
882        throws SQLException
883    {
884        throw new UnsupportedOperationException();
885    }
886
887    public int getResultSetHoldability() throws SQLException {
888        throw new UnsupportedOperationException();
889    }
890
891    public int getDatabaseMajorVersion() throws SQLException {
892        return olap4jConnection.mondrianServer.getVersion().getMajorVersion();
893    }
894
895    public int getDatabaseMinorVersion() throws SQLException {
896        return olap4jConnection.mondrianServer.getVersion().getMinorVersion();
897    }
898
899    public int getJDBCMajorVersion() throws SQLException {
900        // mondrian olap4j supports jdbc 4.0
901        return 4;
902    }
903
904    public int getJDBCMinorVersion() throws SQLException {
905        // mondrian olap4j supports jdbc 4.0
906        return 0;
907    }
908
909    public int getSQLStateType() throws SQLException {
910        throw new UnsupportedOperationException();
911    }
912
913    public boolean locatorsUpdateCopy() throws SQLException {
914        throw new UnsupportedOperationException();
915    }
916
917    public boolean supportsStatementPooling() throws SQLException {
918        throw new UnsupportedOperationException();
919    }
920
921    // implement java.sql.Wrapper
922
923    // straightforward implementation of unwrap and isWrapperFor, since this
924    // class already implements the interface they most likely require:
925    // DatabaseMetaData and OlapDatabaseMetaData
926
927    public <T> T unwrap(Class<T> iface) throws SQLException {
928        if (iface.isInstance(this)) {
929            return iface.cast(this);
930        }
931        throw olap4jConnection.helper.createException(
932            "does not implement '" + iface + "'");
933    }
934
935    public boolean isWrapperFor(Class<?> iface) throws SQLException {
936        return iface.isInstance(this);
937    }
938
939    // implement OlapDatabaseMetaData
940
941    public Set<CellSetListener.Granularity>
942    getSupportedCellSetListenerGranularities()
943        throws OlapException
944    {
945        // Cell set listener API not supported in this version of mondrian.
946        return Collections.emptySet();
947    }
948
949    public ResultSet getActions(
950        String catalog,
951        String schemaPattern,
952        String cubeNamePattern,
953        String actionNamePattern) throws OlapException
954    {
955        return getMetadata(
956            "MDSCHEMA_ACTIONS",
957            "SCHEMA_NAME", wildcard(schemaPattern),
958            "CUBE_NAME", wildcard(cubeNamePattern),
959            "ACTION_NAME", wildcard(actionNamePattern));
960    }
961
962    public ResultSet getDatabases() throws OlapException {
963        return getMetadata("DISCOVER_DATASOURCES");
964    }
965
966    public ResultSet getLiterals() throws OlapException {
967        return getMetadata("DISCOVER_LITERALS");
968    }
969
970    public ResultSet getDatabaseProperties(
971        String dataSourceName,
972        String propertyNamePattern) throws OlapException
973    {
974        return getMetadata("DISCOVER_PROPERTIES");
975    }
976
977    public ResultSet getProperties(
978        String catalog,
979        String schemaPattern,
980        String cubeNamePattern,
981        String dimensionUniqueName,
982        String hierarchyUniqueName,
983        String levelUniqueName,
984        String memberUniqueName,
985        String propertyNamePattern) throws OlapException
986    {
987        return getMetadata(
988            "MDSCHEMA_PROPERTIES",
989            "CATALOG_NAME", catalog,
990            "SCHEMA_NAME", wildcard(schemaPattern),
991            "CUBE_NAME", wildcard(cubeNamePattern),
992            "DIMENSION_UNIQUE_NAME", dimensionUniqueName,
993            "HIERARCHY_UNIQUE_NAME", hierarchyUniqueName,
994            "LEVEL_UNIQUE_NAME", levelUniqueName,
995            "MEMBER_UNIQUE_NAME", memberUniqueName,
996            "PROPERTY_NAME", wildcard(propertyNamePattern));
997    }
998
999    public String getMdxKeywords() throws OlapException {
1000        StringBuilder buf = new StringBuilder();
1001        for (String keyword : olap4jConnection.mondrianServer.getKeywords()) {
1002            if (buf.length() > 0) {
1003                buf.append(',');
1004            }
1005            buf.append(keyword);
1006        }
1007        return buf.toString();
1008    }
1009
1010    public ResultSet getCubes(
1011        String catalog,
1012        String schemaPattern,
1013        String cubeNamePattern)
1014        throws OlapException
1015    {
1016        return getMetadata(
1017            "MDSCHEMA_CUBES",
1018            "CATALOG_NAME", catalog,
1019            "SCHEMA_NAME", wildcard(schemaPattern),
1020            "CUBE_NAME", wildcard(cubeNamePattern));
1021    }
1022
1023    public ResultSet getDimensions(
1024        String catalog,
1025        String schemaPattern,
1026        String cubeNamePattern,
1027        String dimensionNamePattern)
1028        throws OlapException
1029    {
1030        return getMetadata(
1031            "MDSCHEMA_DIMENSIONS",
1032            "SCHEMA_NAME", wildcard(schemaPattern),
1033            "CUBE_NAME", wildcard(cubeNamePattern),
1034            "DIMENSION_NAME", wildcard(dimensionNamePattern));
1035    }
1036
1037    public ResultSet getOlapFunctions(
1038        String functionNamePattern) throws OlapException
1039    {
1040        return getMetadata(
1041            "MDSCHEMA_FUNCTIONS",
1042            "FUNCTION_NAME", wildcard(functionNamePattern));
1043    }
1044
1045    public ResultSet getHierarchies(
1046        String catalog,
1047        String schemaPattern,
1048        String cubeNamePattern,
1049        String dimensionUniqueName,
1050        String hierarchyNamePattern)
1051        throws OlapException
1052    {
1053        return getMetadata(
1054            "MDSCHEMA_HIERARCHIES",
1055            "CATALOG_NAME", catalog,
1056            "SCHEMA_NAME", wildcard(schemaPattern),
1057            "CUBE_NAME", wildcard(cubeNamePattern),
1058            "DIMENSION_UNIQUE_NAME", dimensionUniqueName,
1059            "HIERARCHY_NAME", wildcard(hierarchyNamePattern));
1060    }
1061
1062    public ResultSet getMeasures(
1063        String catalog,
1064        String schemaPattern,
1065        String cubeNamePattern,
1066        String measureNamePattern,
1067        String measureUniqueName) throws OlapException
1068    {
1069        return getMetadata(
1070            "MDSCHEMA_MEASURES",
1071            "CATALOG_NAME", catalog,
1072            "SCHEMA_NAME", wildcard(schemaPattern),
1073            "CUBE_NAME", wildcard(cubeNamePattern),
1074            "MEASURE_NAME", wildcard(measureNamePattern),
1075            "MEASURE_UNIQUE_NAME", measureUniqueName);
1076    }
1077
1078    public ResultSet getMembers(
1079        String catalog,
1080        String schemaPattern,
1081        String cubeNamePattern,
1082        String dimensionUniqueName,
1083        String hierarchyUniqueName,
1084        String levelUniqueName,
1085        String memberUniqueName,
1086        Set<Member.TreeOp> treeOps) throws OlapException
1087    {
1088        String treeOpString;
1089        if (treeOps != null) {
1090            final int mask =
1091                Member.TreeOp.getDictionary().toMask(treeOps);
1092            treeOpString = String.valueOf(mask);
1093        } else {
1094            treeOpString = null;
1095        }
1096        return getMetadata(
1097            "MDSCHEMA_MEMBERS",
1098            "CATALOG_NAME", catalog,
1099            "SCHEMA_NAME", wildcard(schemaPattern),
1100            "CUBE_NAME", wildcard(cubeNamePattern),
1101            "DIMENSION_UNIQUE_NAME", dimensionUniqueName,
1102            "HIERARCHY_UNIQUE_NAME", hierarchyUniqueName,
1103            "LEVEL_UNIQUE_NAME", levelUniqueName,
1104            "MEMBER_UNIQUE_NAME", memberUniqueName,
1105            "TREE_OP", treeOpString);
1106    }
1107
1108    public ResultSet getLevels(
1109        String catalog,
1110        String schemaPattern,
1111        String cubeNamePattern,
1112        String dimensionUniqueName,
1113        String hierarchyUniqueName,
1114        String levelNamePattern) throws OlapException
1115    {
1116        return getMetadata(
1117            "MDSCHEMA_LEVELS",
1118            "CATALOG_NAME", catalog,
1119            "SCHEMA_NAME", wildcard(schemaPattern),
1120            "CUBE_NAME", wildcard(cubeNamePattern),
1121            "DIMENSION_UNIQUE_NAME", dimensionUniqueName,
1122            "HIERARCHY_UNIQUE_NAME", hierarchyUniqueName,
1123            "LEVEL_NAME", wildcard(levelNamePattern));
1124    }
1125
1126    public ResultSet getSets(
1127        String catalog,
1128        String schemaPattern,
1129        String cubeNamePattern,
1130        String setNamePattern) throws OlapException
1131    {
1132        return getMetadata(
1133            "MDSCHEMA_SETS",
1134            "CATALOG_NAME", catalog,
1135            "SCHEMA_NAME", wildcard(schemaPattern),
1136            "CUBE_NAME", wildcard(cubeNamePattern),
1137            "SET_NAME", wildcard(setNamePattern));
1138    }
1139}
1140
1141// End MondrianOlap4jDatabaseMetaData.java