1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.jdbc4olap.jdbc;
23
24 import java.sql.Connection;
25 import java.sql.DatabaseMetaData;
26 import java.sql.ResultSet;
27 import java.sql.SQLException;
28 import java.sql.Types;
29 import java.util.ArrayList;
30 import java.util.List;
31 import java.util.HashMap;
32
33 import org.jdbc4olap.xmla.XmlaConn;
34 import org.jdbc4olap.xmla.XmlaHelper;
35 import org.w3c.dom.NodeList;
36 import org.w3c.dom.Node;
37
38
39
40
41
42 class OlapDatabaseMetaData implements DatabaseMetaData {
43
44 private final OlapConnection olapConn;
45 private final XmlaConn xmlaConn;
46 private ArrayList<String[]> catalogsCache;
47 private ArrayList<String[]> schemasCache;
48
49 OlapDatabaseMetaData(final OlapConnection conn) {
50 this.olapConn = conn;
51 this.xmlaConn = olapConn.getXmlaConn();
52 }
53
54 public boolean allProceduresAreCallable() throws SQLException {
55 return false;
56 }
57
58 public boolean allTablesAreSelectable() throws SQLException {
59 return true;
60 }
61
62 public boolean dataDefinitionCausesTransactionCommit() throws SQLException {
63 return false;
64 }
65
66 public boolean dataDefinitionIgnoredInTransactions() throws SQLException {
67 return true;
68 }
69
70 public boolean deletesAreDetected(final int arg0) throws SQLException {
71 return false;
72 }
73
74 public boolean doesMaxRowSizeIncludeBlobs() throws SQLException {
75 return true;
76 }
77
78 public ResultSet getAttributes(final String arg0, final String arg1, final String arg2,
79 final String arg3) throws SQLException {
80 return OlapResultSet.createEmptyResultSet();
81 }
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103 static final String[] ROW_ID_NAMES = new String[]{
104 "SCOPE",
105 "COLUMN_NAME",
106 "DATA_TYPE",
107 "TYPE_NAME",
108 "COLUMN_SIZE",
109 "BUFFER_LENGTH",
110 "DECIMAL_DIGITS",
111 "PSEUDO_COLUMN"
112 };
113 private static final int[] ROW_ID_TYPES = new int[]{
114 Types.INTEGER,
115 Types.VARCHAR,
116 Types.INTEGER,
117 Types.VARCHAR,
118 Types.INTEGER,
119 Types.INTEGER,
120 Types.INTEGER,
121 Types.INTEGER,
122 };
123
124 public ResultSet getBestRowIdentifier(final String arg0, final String arg1,
125 final String arg2, final int arg3, final boolean arg4) throws SQLException {
126 final OlapResultSet rs = new OlapResultSet();
127 OlapResultSetMetaData.setMetaData(rs, ROW_ID_NAMES, ROW_ID_TYPES);
128 return rs;
129 }
130
131 public ResultSet getCatalogs() throws SQLException {
132
133 final OlapResultSet rsCatalogsCache = new OlapResultSet();
134 for (String[] cat : getCatalogsCache()) {
135 rsCatalogsCache.add(cat);
136 }
137 OlapResultSetMetaData.setMetaDataStringCols(rsCatalogsCache, new String[]{"TABLE_CAT"});
138 return rsCatalogsCache;
139 }
140
141 static final String CATALOG_SEPARATOR = ".";
142
143 public String getCatalogSeparator() throws SQLException {
144 return CATALOG_SEPARATOR;
145 }
146
147 public String getCatalogTerm() throws SQLException {
148 return "catalog";
149 }
150
151
152
153
154
155
156
157
158
159
160
161 static final String[] COL_PRIV_NAMES = new String[]{
162 "TABLE_CAT",
163 "TABLE_SCHEM",
164 "TABLE_NAME",
165 "COLUMN_NAME",
166 "GRANTOR",
167 "GRANTEE",
168 "PRIVILEGE",
169 "IS_GRANTABLE"
170 };
171
172 public ResultSet getColumnPrivileges(final String arg0, final String arg1, final String arg2,
173 final String arg3) throws SQLException {
174 final OlapResultSet rs = new OlapResultSet();
175 OlapResultSetMetaData.setMetaDataStringCols(rs, COL_PRIV_NAMES);
176 return rs;
177 }
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218 static final String[] COLUMN_NAMES = new String[]{
219 "TABLE_CAT",
220 "TABLE_SCHEM",
221 "TABLE_NAME",
222 "COLUMN_NAME",
223 "DATA_TYPE",
224 "TYPE_NAME",
225 "COLUMN_SIZE",
226 "BUFFER_LENGTH",
227 "DECIMAL_DIGITS",
228 "NUM_PREC_RADIX",
229 "NULLABLE",
230 "REMARKS",
231 "COLUMN_DEF",
232 "SQL_DATA_TYPE",
233 "SQL_DATETIME_SUB",
234 "CHAR_OCTET_LENGTH",
235 "ORDINAL_POSITION",
236 "IS_NULLABLE",
237 "SCOPE_CATLOG",
238 "SCOPE_SCHEMA",
239 "SCOPE_TABLE",
240 "SOURCE_DATA_TYPE"
241 };
242 static final int[] COLUMN_TYPES = new int[]{
243 Types.VARCHAR,
244 Types.VARCHAR,
245 Types.VARCHAR,
246 Types.VARCHAR,
247 Types.INTEGER,
248 Types.VARCHAR,
249 Types.INTEGER,
250 Types.INTEGER,
251 Types.INTEGER,
252 Types.INTEGER,
253 Types.INTEGER,
254 Types.VARCHAR,
255 Types.VARCHAR,
256 Types.INTEGER,
257 Types.INTEGER,
258 Types.INTEGER,
259 Types.INTEGER,
260 Types.VARCHAR,
261 Types.VARCHAR,
262 Types.VARCHAR,
263 Types.VARCHAR,
264 Types.INTEGER
265 };
266
267 public ResultSet getColumns(final String catalog, String schemaPattern, String tableNamePattern,
268 String columnNamePattern) throws SQLException {
269
270 final OlapResultSet resRS = new OlapResultSet();
271 OlapResultSetMetaData.setMetaData(resRS, COLUMN_NAMES, COLUMN_TYPES);
272 if (("".equals(catalog)) || ("".equals(schemaPattern)) || ("".equals(tableNamePattern)) || ("".equals(columnNamePattern))) {
273 return resRS;
274 }
275
276 schemaPattern = translatePattern(schemaPattern);
277 tableNamePattern = translatePattern(tableNamePattern);
278 columnNamePattern = translatePattern(columnNamePattern);
279
280 final List<String> catalogs = getCatalogsByName(catalog);
281 XmlaHelper helper = new XmlaHelper();
282 for (String cat : catalogs) {
283 if (catalog == null || catalog.equals(cat)) {
284 final String measureName = xmlaConn.getMeasureName(cat, schemaPattern);
285 if (measureName != null && measureName.equals(tableNamePattern)) {
286 final NodeList measures = xmlaConn.getMembersNodeList(cat, schemaPattern, measureName, null, columnNamePattern);
287
288 final List<String> cubesPked = new ArrayList<String>();
289
290 for (int i = 0; i < measures.getLength(); i++) {
291 final Node item = measures.item(i);
292 String cube = "";
293 String measure = "";
294 String desc = "";
295
296 NodeList nl = item.getChildNodes();
297 for (int j = 0; j < nl.getLength(); j++) {
298 org.w3c.dom.Node node = nl.item(j);
299 final String nodeName = node.getNodeName();
300 final String nodeTextContent = helper.getTextContent(node);
301
302 if (nodeName.equals("CUBE_NAME")) {
303 cube = nodeTextContent;
304 } else if (nodeName.equals("MEMBER_UNIQUE_NAME")) {
305 measure = nodeTextContent;
306 } else if (nodeName.equals("MEMBER_CAPTION")) {
307 desc = nodeTextContent;
308 }
309 }
310
311
312 if (!cubesPked.contains(cube)) {
313 ResultSet lRS = getPrimaryKeys(cat, cube, measureName);
314 lRS.beforeFirst();
315 while (lRS.next()) {
316 addColumnTuple(resRS,
317 lRS.getString(1), lRS.getString(2), lRS.getString(3), lRS.getString(4),
318
319 Types.VARCHAR,
320 null);
321 }
322 lRS = getImportedKeys(cat, cube, measureName);
323 lRS.beforeFirst();
324 while (lRS.next()) {
325 addColumnTuple(resRS,
326 lRS.getString(5), lRS.getString(6), lRS.getString(7), lRS.getString(8),
327
328 Types.VARCHAR,
329 null);
330 }
331 cubesPked.add(cube);
332 }
333
334 addColumnTuple(resRS,
335 cat, cube, measureName, measure,
336 Types.NUMERIC,
337 desc);
338 }
339
340 } else {
341
342 final HashMap<String, List<String>> cubesPked = new HashMap<String, List<String>>();
343 List<String> tablesPked;
344
345 final NodeList levels = xmlaConn.getLevelsNodeList(cat, schemaPattern, tableNamePattern, columnNamePattern);
346
347 for (int i = 0; i < levels.getLength(); i++) {
348 final Node item = levels.item(i);
349 String cube = "";
350 String table = "";
351 String level = "";
352 String desc = "";
353
354 final NodeList nl = item.getChildNodes();
355 for (int j = 0; j < nl.getLength(); j++) {
356 org.w3c.dom.Node node = nl.item(j);
357 final String nodeName = node.getNodeName();
358 final String nodeTextContent = helper.getTextContent(node);
359
360 if (nodeName.equals("CUBE_NAME")) {
361 cube = nodeTextContent;
362 } else if (nodeName.equals(xmlaConn.getTableUniqueNameProperty())) {
363 table = nodeTextContent;
364 } else if (nodeName.equals("LEVEL_UNIQUE_NAME")) {
365 level = nodeTextContent;
366 } else if (nodeName.equals("LEVEL_CAPTION")) {
367 desc = nodeTextContent;
368 }
369 }
370
371
372 tablesPked = cubesPked.get(cube);
373 if (tablesPked == null) {
374 tablesPked = new ArrayList<String>();
375 }
376 if (!tablesPked.contains(table)) {
377 final ResultSet lRS = getPrimaryKeys(cat, cube, table);
378 lRS.beforeFirst();
379 while (lRS.next()) {
380 addColumnTuple(resRS,
381 lRS.getString(1), lRS.getString(2), lRS.getString(3), lRS.getString(4),
382
383 Types.VARCHAR,
384 null);
385 }
386 tablesPked.add(table);
387 cubesPked.put(cube, tablesPked);
388 }
389
390 addColumnTuple(resRS,
391 cat, cube, table, level, Types.VARCHAR, desc);
392 }
393 }
394 }
395 }
396 return resRS;
397 }
398
399 List<String> getCatalogsByName(final String namedCatalog) throws SQLException {
400 final List<String> catalogs = new ArrayList<String>();
401 if (namedCatalog == null) {
402
403 for (String[] cachedCatalog : getCatalogsCache()) {
404 catalogs.add(cachedCatalog[0]);
405 }
406
407 } else {
408 catalogs.add(namedCatalog);
409 }
410 return catalogs;
411 }
412
413 static void addColumnTuple(final OlapResultSet resRS,
414 final String tableCatalog, final String tableSchema, final String tableName,
415 final String columnName, final int dataType,
416 final String remarks) {
417
418
419 final Object[] val = new Object[22];
420 val[0] = tableCatalog;
421 val[1] = tableSchema;
422 val[2] = tableName;
423 val[3] = columnName;
424
425 val[4] = dataType;
426
427 val[5] = OlapResultSetMetaData.TYPE_NAME_MAP.get(dataType);
428
429 val[6] = -1;
430 val[7] = -1;
431 val[8] = -1;
432 val[9] = -1;
433
434 val[10] = DatabaseMetaData.columnNoNulls;
435
436 val[11] = remarks;
437
438 val[13] = dataType;
439
440 val[14] = -1;
441 val[15] = -1;
442 val[16] = -1;
443
444
445 val[17] = "YES";
446
447 val[21] = dataType;
448
449
450 resRS.add(val);
451 }
452
453 public Connection getConnection() throws SQLException {
454 return olapConn;
455 }
456
457 public ResultSet getCrossReference(final String arg0, final String arg1, final String arg2,
458 final String arg3, final String arg4, final String arg5) throws SQLException {
459 return OlapResultSet.createEmptyResultSet();
460 }
461
462 public int getDatabaseMajorVersion() throws SQLException {
463 return 0;
464 }
465
466 public int getDatabaseMinorVersion() throws SQLException {
467 return 0;
468 }
469
470 public String getDatabaseProductName() throws SQLException {
471 return xmlaConn.getDatabaseProductName();
472 }
473
474 public String getDatabaseProductVersion() throws SQLException {
475 return xmlaConn.getDatabaseProductVersion();
476 }
477
478 public int getDefaultTransactionIsolation() throws SQLException {
479 return Connection.TRANSACTION_NONE;
480 }
481
482 public int getDriverMajorVersion() {
483 return 1;
484 }
485
486 public int getDriverMinorVersion() {
487 return 0;
488 }
489
490 public String getDriverName() throws SQLException {
491 return "jdbc4olap Driver";
492 }
493
494 public String getDriverVersion() throws SQLException {
495 return "1.0";
496 }
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547 static final String[] EXPORTED_KEYS_NAMES = new String[]{
548 "PKTABLE_CAT",
549 "PKTABLE_SCHEM",
550 "PKTABLE_NAME",
551 "PKCOLUMN_NAME",
552 "FKTABLE_CAT",
553 "FKTABLE_SCHEM",
554 "FKTABLE_NAME",
555 "FKCOLUMN_NAME",
556 "KEY_SEQ",
557 "UPDATE_RULE",
558 "DELETE_RULE",
559 "FK_NAME",
560 "PK_NAME",
561 "DEFERRABILITY"
562 };
563 private static final int[] EXPORTED_KEYS_TYPES = new int[]{
564 Types.VARCHAR,
565 Types.VARCHAR,
566 Types.VARCHAR,
567 Types.VARCHAR,
568 Types.VARCHAR,
569 Types.VARCHAR,
570 Types.VARCHAR,
571 Types.VARCHAR,
572 Types.INTEGER,
573 Types.INTEGER,
574 Types.INTEGER,
575 Types.VARCHAR,
576 Types.VARCHAR,
577 Types.INTEGER
578 };
579
580 public ResultSet getExportedKeys(final String arg0, final String arg1, final String arg2)
581 throws SQLException {
582 final OlapResultSet rs = new OlapResultSet();
583 OlapResultSetMetaData.setMetaData(rs, EXPORTED_KEYS_NAMES, EXPORTED_KEYS_TYPES);
584 return rs;
585 }
586
587 public String getExtraNameCharacters() throws SQLException {
588 return null;
589 }
590
591 public String getIdentifierQuoteString() throws SQLException {
592 return "\"";
593 }
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645 static final String[] IMPORTED_KEYS_NAMES = new String[]{
646 "PKTABLE_CAT",
647 "PKTABLE_SCHEM",
648 "PKTABLE_NAME",
649 "PKCOLUMN_NAME",
650 "FKTABLE_CAT",
651 "FKTABLE_SCHEM",
652 "FKTABLE_NAME",
653 "FKCOLUMN_NAME",
654 "KEY_SEQ",
655 "UPDATE_RULE",
656 "DELETE_RULE",
657 "FK_NAME",
658 "PK_NAME",
659 "DEFERRABILITY"
660 };
661 private static final int[] IMPORTED_KEYS_TYPES = new int[]{
662 Types.VARCHAR,
663 Types.VARCHAR,
664 Types.VARCHAR,
665 Types.VARCHAR,
666 Types.VARCHAR,
667 Types.VARCHAR,
668 Types.VARCHAR,
669 Types.VARCHAR,
670 Types.INTEGER,
671 Types.INTEGER,
672 Types.INTEGER,
673 Types.VARCHAR,
674 Types.VARCHAR,
675 Types.INTEGER
676 };
677
678 public ResultSet getImportedKeys(final String catalog, final String schema, final String table)
679 throws SQLException {
680
681 final OlapResultSet resRS = new OlapResultSet();
682 OlapResultSetMetaData.setMetaData(resRS, IMPORTED_KEYS_NAMES, IMPORTED_KEYS_TYPES);
683
684 if (table == null) {
685 return resRS;
686 }
687
688 final List<String> catalogs = new ArrayList<String>();
689 ResultSet lRS;
690 if (catalog == null) {
691 lRS = getCatalogs();
692 lRS.beforeFirst();
693 while (lRS.next()) {
694 catalogs.add(lRS.getString(1));
695 }
696 } else {
697 catalogs.add(catalog);
698 }
699
700 String tableTag = xmlaConn.getTableUniqueNameProperty();
701 XmlaHelper helper = new XmlaHelper();
702 for (String cat : catalogs) {
703 if ((catalog == null || catalog.equals(cat)) && table.equals(xmlaConn.getMeasureName(cat, schema))) {
704 final NodeList rows = xmlaConn.getTablesNodeList(cat, schema, null);
705
706 for (int i = 0; i < rows.getLength(); i++) {
707 final Node item = rows.item(i);
708 String cube = "";
709 String tableName = "";
710 final NodeList nl = item.getChildNodes();
711 for (int j = 0; j < nl.getLength(); j++) {
712 final Node node = nl.item(j);
713 final String nodeName = node.getNodeName();
714 final String nodeTextContent = helper.getTextContent(node);
715 if (nodeName.equals("CUBE_NAME")) {
716 cube = nodeTextContent;
717 } else if (nodeName.equals(tableTag)) {
718 tableName = nodeTextContent;
719 }
720 }
721 if (!table.equals(tableName)) {
722 lRS = getPrimaryKeys(cat, cube, tableName);
723 lRS.beforeFirst();
724 while (lRS.next()) {
725 final Object[] val = new Object[14];
726 val[0] = cat;
727 val[1] = cube;
728 val[2] = tableName;
729 val[3] = lRS.getString(4);
730 val[4] = cat;
731 val[5] = cube;
732 val[6] = table;
733 val[7] = lRS.getString(4);
734 val[8] = lRS.getInt(5);
735 val[9] = DatabaseMetaData.importedKeyNoAction;
736 val[10] = DatabaseMetaData.importedKeyNoAction;
737 val[11] = null;
738 val[12] = null;
739 val[13] = DatabaseMetaData.importedKeyNotDeferrable;
740 resRS.add(val);
741 }
742 }
743 }
744 }
745 }
746 return resRS;
747 }
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781 static final String[] INDEX_INFO_NAMES = new String[]{
782 "TABLE_CAT",
783 "TABLE_SCHEM",
784 "TABLE_NAME",
785 "NON_UNIQUE",
786 "INDEX_QUALIFIER",
787 "INDEX_NAME",
788 "TYPE",
789 "ORDINAL_POSITION",
790 "COLUMN_NAME",
791 "ASC_OR_DESC",
792 "CARDINALITY",
793 "PAGES",
794 "FILTER_CONDITION"
795 };
796 private static final int[] INDEX_INFO_TYPES = new int[]{
797 Types.VARCHAR,
798 Types.VARCHAR,
799 Types.VARCHAR,
800 Types.BOOLEAN,
801 Types.VARCHAR,
802 Types.VARCHAR,
803 Types.INTEGER,
804 Types.INTEGER,
805 Types.VARCHAR,
806 Types.VARCHAR,
807 Types.INTEGER,
808 Types.INTEGER,
809 Types.VARCHAR
810 };
811
812 public ResultSet getIndexInfo(final String arg0, final String arg1, final String arg2,
813 final boolean arg3, final boolean arg4) throws SQLException {
814 final OlapResultSet rs = new OlapResultSet();
815 OlapResultSetMetaData.setMetaData(rs, INDEX_INFO_NAMES, INDEX_INFO_TYPES);
816 return rs;
817 }
818
819 public int getJDBCMajorVersion() throws SQLException {
820 return 4;
821 }
822
823 public int getJDBCMinorVersion() throws SQLException {
824 return 0;
825 }
826
827 public int getMaxBinaryLiteralLength() throws SQLException {
828 return 0;
829 }
830
831 public int getMaxCatalogNameLength() throws SQLException {
832 return 0;
833 }
834
835 public int getMaxCharLiteralLength() throws SQLException {
836 return 0;
837 }
838
839 public int getMaxColumnNameLength() throws SQLException {
840 return 0;
841 }
842
843 public int getMaxColumnsInGroupBy() throws SQLException {
844 return 0;
845 }
846
847 public int getMaxColumnsInIndex() throws SQLException {
848 return 0;
849 }
850
851 public int getMaxColumnsInOrderBy() throws SQLException {
852 return 0;
853 }
854
855 public int getMaxColumnsInSelect() throws SQLException {
856 return 0;
857 }
858
859 public int getMaxColumnsInTable() throws SQLException {
860 return 0;
861 }
862
863 public int getMaxConnections() throws SQLException {
864 return 0;
865 }
866
867 public int getMaxCursorNameLength() throws SQLException {
868 return 0;
869 }
870
871 public int getMaxIndexLength() throws SQLException {
872 return 0;
873 }
874
875 public int getMaxProcedureNameLength() throws SQLException {
876 return 0;
877 }
878
879 public int getMaxRowSize() throws SQLException {
880 return 0;
881 }
882
883 public int getMaxSchemaNameLength() throws SQLException {
884 return 0;
885 }
886
887 public int getMaxStatementLength() throws SQLException {
888 return 0;
889 }
890
891 public int getMaxStatements() throws SQLException {
892 return 0;
893 }
894
895 public int getMaxTableNameLength() throws SQLException {
896 return 0;
897 }
898
899 public int getMaxTablesInSelect() throws SQLException {
900 return 0;
901 }
902
903 public int getMaxUserNameLength() throws SQLException {
904 return 0;
905 }
906
907 public String getNumericFunctions() throws SQLException {
908 return "";
909 }
910
911
912
913
914
915
916
917 static final String[] PRIMARY_KEY_CNAMES = new String[]{
918 "TABLE_CAT",
919 "TABLE_SCHEM",
920 "TABLE_NAME",
921 "COLUMN_NAME",
922 "KEY_SEQ",
923 "PK_NAME"
924 };
925 private static final int[] PRIMARY_KEY_CTYPES = new int[]{
926 Types.VARCHAR,
927 Types.VARCHAR,
928 Types.VARCHAR,
929 Types.VARCHAR,
930 Types.INTEGER,
931 Types.VARCHAR
932 };
933
934 public ResultSet getPrimaryKeys(final String catalog, final String schema, final String table) throws SQLException {
935 final OlapResultSet resRS = new OlapResultSet();
936 OlapResultSetMetaData.setMetaData(resRS, PRIMARY_KEY_CNAMES, PRIMARY_KEY_CTYPES);
937 if (table == null) {
938 return resRS;
939 }
940
941 final List<String> catalogs = getCatalogsByName(catalog);
942
943 XmlaHelper helper = new XmlaHelper();
944 for (String cat : catalogs) {
945 if (catalog == null || catalog.equals(cat)) {
946 final NodeList rows = xmlaConn.getTablesNodeList(cat, schema, table);
947
948 for (int i = 0; i < rows.getLength(); i++) {
949 final Node item = rows.item(i);
950 String cube = "";
951 String tableUniqueName = "";
952 String tableName = "";
953
954 final NodeList nl = item.getChildNodes();
955 for (int j = 0; j < nl.getLength(); j++) {
956 org.w3c.dom.Node node = nl.item(j);
957 final String nodeName = node.getNodeName();
958 final String nodeTextContent = helper.getTextContent(node);
959 if (nodeName.equals("CUBE_NAME")) {
960 cube = nodeTextContent;
961 } else if (nodeName.equals(xmlaConn.getTableUniqueNameProperty())) {
962 tableUniqueName = nodeTextContent;
963 } else if (nodeName.equals(xmlaConn.getTableNameProperty())) {
964 tableName = nodeTextContent;
965 }
966 }
967 final Object[] val = new Object[6];
968 val[0] = cat;
969 val[1] = cube;
970 val[2] = tableUniqueName;
971 val[3] = tableName + "_ID";
972 val[4] = 1;
973 val[5] = null;
974 resRS.add(val);
975 }
976 }
977 }
978 return resRS;
979 }
980
981 public ResultSet getProcedureColumns(final String arg0, final String arg1, final String arg2,
982 final String arg3) throws SQLException {
983 return OlapResultSet.createEmptyResultSet();
984 }
985
986 public String getProcedureTerm() throws SQLException {
987 return null;
988 }
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003 static final String[] PROCS_COL_NAMES = new String[]{
1004 "PROCEDURE_CAT",
1005 "PROCEDURE_SCHEM",
1006 "PROCEDURE_NAME",
1007 "REMARKS",
1008 "PROCEDURE_TYPE",
1009 };
1010 private static final int[] PROCS_COL_TYPES = new int[]{
1011 Types.VARCHAR,
1012 Types.VARCHAR,
1013 Types.VARCHAR,
1014 Types.VARCHAR,
1015 Types.INTEGER
1016 };
1017
1018 public ResultSet getProcedures(final String arg0, final String arg1, final String arg2)
1019 throws SQLException {
1020
1021 final OlapResultSet rs = new OlapResultSet();
1022 OlapResultSetMetaData.setMetaData(rs, PROCS_COL_NAMES, PROCS_COL_TYPES);
1023 return rs;
1024 }
1025
1026 public int getResultSetHoldability() throws SQLException {
1027 return ResultSet.HOLD_CURSORS_OVER_COMMIT;
1028 }
1029
1030 public String getSQLKeywords() throws SQLException {
1031 return null;
1032 }
1033
1034 public int getSQLStateType() throws SQLException {
1035 return 0;
1036 }
1037
1038 public String getSchemaTerm() throws SQLException {
1039 return "cube";
1040 }
1041
1042 public ResultSet getSchemas() throws SQLException {
1043
1044
1045
1046 if (schemasCache == null) {
1047
1048 schemasCache = new ArrayList<String[]>();
1049 XmlaHelper helper = new XmlaHelper();
1050 for (String[] catalog : getCatalogsCache()) {
1051 final String cat = catalog[0];
1052
1053 NodeList rows = xmlaConn.getCubesNodeList(cat);
1054
1055 for (int i = 0; i < rows.getLength(); i++) {
1056 final String[] val = new String[2];
1057
1058 final Node item = rows.item(i);
1059 val[0] = helper.getTextContent(item);
1060 val[1] = cat;
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072 schemasCache.add(val);
1073 }
1074 }
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085 }
1086
1087 final OlapResultSet rsSchemasCache = new OlapResultSet();
1088 for (String[] schema : schemasCache) {
1089 rsSchemasCache.add(schema);
1090 }
1091 OlapResultSetMetaData.setMetaDataStringCols(rsSchemasCache, new String[]{"TABLE_SCHEM", "TABLE_CATALOG"});
1092
1093
1094 return rsSchemasCache;
1095 }
1096
1097 private ArrayList<String[]> getCatalogsCache() throws SQLException {
1098
1099 if (catalogsCache == null) {
1100 catalogsCache = new ArrayList<String[]>();
1101
1102 final NodeList nodeListCatalogs = xmlaConn.getCatalogsNodeList();
1103 XmlaHelper helper = new XmlaHelper();
1104 for (int i = 0; i < nodeListCatalogs.getLength(); i++) {
1105 final String[] val = new String[1];
1106 Node node = nodeListCatalogs.item(i);
1107 val[0] = helper.getTextContent(node);
1108 catalogsCache.add(val);
1109 }
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120 }
1121
1122 return catalogsCache;
1123 }
1124
1125 public String getSearchStringEscape() throws SQLException {
1126 return null;
1127 }
1128
1129 public String getStringFunctions() throws SQLException {
1130 return "";
1131 }
1132
1133
1134
1135
1136
1137 static final String[] SUPER_TABLE_COL_NAMES = new String[]{
1138 "TABLE_CAT",
1139 "TABLE_SCHEM",
1140 "TABLE_NAME",
1141 "SUPERTABLE_NAME"
1142 };
1143
1144 public ResultSet getSuperTables(final String arg0, final String arg1, final String arg2) throws SQLException {
1145 final OlapResultSet rs = new OlapResultSet();
1146 OlapResultSetMetaData.setMetaDataStringCols(rs, SUPER_TABLE_COL_NAMES);
1147 return rs;
1148 }
1149
1150 public ResultSet getSuperTypes(final String arg0, final String arg1, final String arg2)
1151 throws SQLException {
1152 return OlapResultSet.createEmptyResultSet();
1153 }
1154
1155 public String getSystemFunctions() throws SQLException {
1156 return "";
1157 }
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168 static final String[] TABLE_PRIV_NAMES = new String[]{
1169 "TABLE_CAT",
1170 "TABLE_SCHEM",
1171 "TABLE_NAME",
1172 "GRANTOR",
1173 "GRANTEE",
1174 "PRIVILEGE",
1175 "IS_GRANTABLE"
1176 };
1177
1178 public ResultSet getTablePrivileges(final String arg0, final String arg1, final String arg2)
1179 throws SQLException {
1180 final OlapResultSet rs = new OlapResultSet();
1181 OlapResultSetMetaData.setMetaDataStringCols(rs, TABLE_PRIV_NAMES);
1182 return rs;
1183 }
1184
1185 public ResultSet getTableTypes() throws SQLException {
1186 final OlapResultSet rs = new OlapResultSet();
1187 rs.add(new String[]{"TABLE"});
1188
1189 OlapResultSetMetaData.setMetaDataStringCols(rs, new String[]{"TABLE_TYPE"});
1190 return rs;
1191 }
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208 static final String[] TABLE_DESC_NAME = new String[]{
1209 "TABLE_CAT",
1210 "TABLE_SCHEM",
1211 "TABLE_NAME",
1212 "TABLE_TYPE",
1213 "REMARKS",
1214 "TYPE_CAT",
1215 "TYPE_SCHEM",
1216 "TYPE_NAME",
1217 "SELF_REFERENCING_COL_NAME",
1218 "REF_GENERATION"
1219 };
1220
1221 public ResultSet getTables(final String catalog, final String schemaPattern, final String tableNamePattern,
1222 final String[] types) throws SQLException {
1223 final OlapResultSet resRS = new OlapResultSet();
1224 OlapResultSetMetaData.setMetaDataStringCols(resRS, TABLE_DESC_NAME);
1225
1226 if (("".equals(catalog)) || ("".equals(schemaPattern)) || ("".equals(tableNamePattern))) {
1227 return resRS;
1228 }
1229
1230 final List<String> catalogs = getCatalogsByName(catalog);
1231 XmlaHelper helper = new XmlaHelper();
1232 for (String cat : catalogs) {
1233 if (catalog == null || catalog.equals(cat)) {
1234 final NodeList rows = xmlaConn.getTablesNodeList(cat, translatePattern(schemaPattern), translatePattern(tableNamePattern));
1235
1236 for (int i = 0; i < rows.getLength(); i++) {
1237 final Node item = rows.item(i);
1238 String cube = "";
1239 String table = "";
1240 String desc = "";
1241 final NodeList nl = item.getChildNodes();
1242
1243 for (int j = 0; j < nl.getLength(); j++) {
1244 org.w3c.dom.Node node = nl.item(j);
1245 final String nodeName = node.getNodeName();
1246 final String nodeTextContent = helper.getTextContent(node);
1247
1248 if (nodeName.equals("CUBE_NAME")) {
1249 cube = nodeTextContent;
1250 } else if (nodeName.equals(xmlaConn.getTableUniqueNameProperty())) {
1251 table = nodeTextContent;
1252 } else if (nodeName.equals("DESCRIPTION")) {
1253 desc = nodeTextContent;
1254 }
1255 }
1256 final String[] val = new String[10];
1257 val[0] = cat;
1258 val[1] = cube;
1259 val[2] = table;
1260 val[3] = "TABLE";
1261 val[4] = desc;
1262 resRS.add(val);
1263 }
1264 }
1265 }
1266 return resRS;
1267 }
1268
1269 public String getTimeDateFunctions() throws SQLException {
1270 return "";
1271 }
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308 private static final String[] TYPE_INFO_COL_NAMES = new String[]{
1309 "TYPE_NAME",
1310 "DATA_TYPE",
1311 "PRECISION",
1312 "LITERAL_PREFIX",
1313 "LITERAL_SUFFIX",
1314 "CREATE_PARAMS",
1315 "NULLABLE",
1316 "CASE_SENSITIVE",
1317 "SEARCHABLE",
1318 "UNSIGNED_ATTRIBUTE",
1319 "FIXED_PREC_SCALE",
1320 "AUTO_INCREMENT",
1321 "LOCAL_TYPE_NAME",
1322 "MINIMUM_SCALE",
1323 "MAXIMUM_SCALE",
1324 "SQL_DATA_TYPE",
1325 "SQL_DATETIME_SUB",
1326 "NUM_PREC_RADIX"
1327 };
1328 private static final int[] TYPE_INFO_COL_TYPES = new int[]{
1329 Types.VARCHAR,
1330 Types.INTEGER,
1331 Types.INTEGER,
1332 Types.VARCHAR,
1333 Types.VARCHAR,
1334 Types.VARCHAR,
1335 Types.INTEGER,
1336 Types.BOOLEAN,
1337 Types.INTEGER,
1338 Types.BOOLEAN,
1339 Types.BOOLEAN,
1340 Types.BOOLEAN,
1341 Types.VARCHAR,
1342 Types.INTEGER,
1343 Types.INTEGER,
1344 Types.INTEGER,
1345 Types.INTEGER,
1346 Types.INTEGER,
1347 };
1348
1349 public ResultSet getTypeInfo() throws SQLException {
1350 final OlapResultSet rs = new OlapResultSet();
1351 OlapResultSetMetaData.setMetaData(rs, TYPE_INFO_COL_NAMES, TYPE_INFO_COL_TYPES);
1352 return rs;
1353 }
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368 private static final String[] UDT_COL_NAMES = new String[]{
1369 "TYPE_CAT",
1370 "TYPE_SCHEM",
1371 "TYPE_NAME",
1372 "CLASS_NAME",
1373 "DATA_TYPE",
1374 "REMARKS",
1375 "BASE_TYPE"
1376 };
1377 private static final int[] UDT_COL_TYPES = new int[]{
1378 Types.VARCHAR,
1379 Types.VARCHAR,
1380 Types.VARCHAR,
1381 Types.VARCHAR,
1382 Types.INTEGER,
1383 Types.VARCHAR,
1384 Types.INTEGER,
1385 };
1386
1387 public ResultSet getUDTs(final String arg0, final String arg1, final String arg2, final int[] arg3)
1388 throws SQLException {
1389
1390 final OlapResultSet rs = new OlapResultSet();
1391 OlapResultSetMetaData.setMetaData(rs, UDT_COL_NAMES, UDT_COL_TYPES);
1392 return rs;
1393 }
1394
1395 public String getURL() throws SQLException {
1396 return xmlaConn.getEndpoint().toString();
1397 }
1398
1399 public String getUserName() throws SQLException {
1400 return xmlaConn.getLogin().getUserName();
1401 }
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417 static final String[] VERSION_COL_NAMES = new String[]{
1418 "SCOPE",
1419 "COLUMN_NAME",
1420 "DATA_TYPE",
1421 "TYPE_NAME",
1422 "COLUMN_SIZE",
1423 "BUFFER_LENGTH",
1424 "DECIMAL_DIGITS",
1425 "PSEUDO_COLUMN"
1426 };
1427 static final int[] VERSION_COL_TYPES = new int[]{
1428 Types.INTEGER,
1429 Types.VARCHAR,
1430 Types.INTEGER,
1431 Types.VARCHAR,
1432 Types.INTEGER,
1433 Types.INTEGER,
1434 Types.INTEGER,
1435 Types.INTEGER
1436 };
1437
1438 public ResultSet getVersionColumns(final String arg0, final String arg1, final String arg2)
1439 throws SQLException {
1440 final OlapResultSet rs = new OlapResultSet();
1441 OlapResultSetMetaData.setMetaData(rs, VERSION_COL_NAMES, VERSION_COL_TYPES);
1442 return rs;
1443 }
1444
1445 public boolean insertsAreDetected(final int arg0) throws SQLException {
1446 return false;
1447 }
1448
1449 public boolean isCatalogAtStart() throws SQLException {
1450 return true;
1451 }
1452
1453 public boolean isReadOnly() throws SQLException {
1454 return true;
1455 }
1456
1457 public boolean locatorsUpdateCopy() throws SQLException {
1458 return false;
1459 }
1460
1461 public boolean nullPlusNonNullIsNull() throws SQLException {
1462 return false;
1463 }
1464
1465 public boolean nullsAreSortedAtEnd() throws SQLException {
1466 return false;
1467 }
1468
1469 public boolean nullsAreSortedAtStart() throws SQLException {
1470 return false;
1471 }
1472
1473 public boolean nullsAreSortedHigh() throws SQLException {
1474 return false;
1475 }
1476
1477 public boolean nullsAreSortedLow() throws SQLException {
1478 return false;
1479 }
1480
1481 public boolean othersDeletesAreVisible(final int arg0) throws SQLException {
1482 return false;
1483 }
1484
1485 public boolean othersInsertsAreVisible(final int arg0) throws SQLException {
1486 return false;
1487 }
1488
1489 public boolean othersUpdatesAreVisible(final int arg0) throws SQLException {
1490 return false;
1491 }
1492
1493 public boolean ownDeletesAreVisible(final int arg0) throws SQLException {
1494 return false;
1495 }
1496
1497 public boolean ownInsertsAreVisible(final int arg0) throws SQLException {
1498 return false;
1499 }
1500
1501 public boolean ownUpdatesAreVisible(final int arg0) throws SQLException {
1502 return false;
1503 }
1504
1505 public boolean storesLowerCaseIdentifiers() throws SQLException {
1506 return false;
1507 }
1508
1509 public boolean storesLowerCaseQuotedIdentifiers() throws SQLException {
1510 return false;
1511 }
1512
1513 public boolean storesMixedCaseIdentifiers() throws SQLException {
1514 return false;
1515 }
1516
1517 public boolean storesMixedCaseQuotedIdentifiers() throws SQLException {
1518 return false;
1519 }
1520
1521 public boolean storesUpperCaseIdentifiers() throws SQLException {
1522 return false;
1523 }
1524
1525 public boolean storesUpperCaseQuotedIdentifiers() throws SQLException {
1526 return false;
1527 }
1528
1529 public boolean supportsANSI92EntryLevelSQL() throws SQLException {
1530 return false;
1531 }
1532
1533 public boolean supportsANSI92FullSQL() throws SQLException {
1534 return false;
1535 }
1536
1537 public boolean supportsANSI92IntermediateSQL() throws SQLException {
1538 return false;
1539 }
1540
1541 public boolean supportsAlterTableWithAddColumn() throws SQLException {
1542 return false;
1543 }
1544
1545 public boolean supportsAlterTableWithDropColumn() throws SQLException {
1546 return false;
1547 }
1548
1549 public boolean supportsBatchUpdates() throws SQLException {
1550 return false;
1551 }
1552
1553 public boolean supportsCatalogsInDataManipulation() throws SQLException {
1554 return true;
1555 }
1556
1557 public boolean supportsCatalogsInIndexDefinitions() throws SQLException {
1558 return false;
1559 }
1560
1561 public boolean supportsCatalogsInPrivilegeDefinitions() throws SQLException {
1562 return false;
1563 }
1564
1565 public boolean supportsCatalogsInProcedureCalls() throws SQLException {
1566 return false;
1567 }
1568
1569 public boolean supportsCatalogsInTableDefinitions() throws SQLException {
1570 return true;
1571 }
1572
1573 public boolean supportsColumnAliasing() throws SQLException {
1574 return true;
1575 }
1576
1577 public boolean supportsConvert() throws SQLException {
1578 return false;
1579 }
1580
1581 public boolean supportsConvert(final int arg0, final int arg1) throws SQLException {
1582 return false;
1583 }
1584
1585 public boolean supportsCoreSQLGrammar() throws SQLException {
1586 return false;
1587 }
1588
1589 public boolean supportsCorrelatedSubqueries() throws SQLException {
1590 return false;
1591 }
1592
1593 public boolean supportsDataDefinitionAndDataManipulationTransactions()
1594 throws SQLException {
1595 return false;
1596 }
1597
1598 public boolean supportsDataManipulationTransactionsOnly()
1599 throws SQLException {
1600 return false;
1601 }
1602
1603 public boolean supportsDifferentTableCorrelationNames() throws SQLException {
1604 return false;
1605 }
1606
1607 public boolean supportsExpressionsInOrderBy() throws SQLException {
1608 return false;
1609 }
1610
1611 public boolean supportsExtendedSQLGrammar() throws SQLException {
1612 return false;
1613 }
1614
1615 public boolean supportsFullOuterJoins() throws SQLException {
1616 return false;
1617 }
1618
1619 public boolean supportsGetGeneratedKeys() throws SQLException {
1620 return false;
1621 }
1622
1623 public boolean supportsGroupBy() throws SQLException {
1624 return false;
1625 }
1626
1627 public boolean supportsGroupByBeyondSelect() throws SQLException {
1628 return false;
1629 }
1630
1631 public boolean supportsGroupByUnrelated() throws SQLException {
1632 return false;
1633 }
1634
1635 public boolean supportsIntegrityEnhancementFacility() throws SQLException {
1636 return false;
1637 }
1638
1639 public boolean supportsLikeEscapeClause() throws SQLException {
1640 return false;
1641 }
1642
1643 public boolean supportsLimitedOuterJoins() throws SQLException {
1644 return false;
1645 }
1646
1647 public boolean supportsMinimumSQLGrammar() throws SQLException {
1648 return false;
1649 }
1650
1651 public boolean supportsMixedCaseIdentifiers() throws SQLException {
1652 return true;
1653 }
1654
1655 public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException {
1656 return true;
1657 }
1658
1659 public boolean supportsMultipleOpenResults() throws SQLException {
1660 return false;
1661 }
1662
1663 public boolean supportsMultipleResultSets() throws SQLException {
1664 return false;
1665 }
1666
1667 public boolean supportsMultipleTransactions() throws SQLException {
1668 return false;
1669 }
1670
1671 public boolean supportsNamedParameters() throws SQLException {
1672 return false;
1673 }
1674
1675 public boolean supportsNonNullableColumns() throws SQLException {
1676 return false;
1677 }
1678
1679 public boolean supportsOpenCursorsAcrossCommit() throws SQLException {
1680 return false;
1681 }
1682
1683 public boolean supportsOpenCursorsAcrossRollback() throws SQLException {
1684 return false;
1685 }
1686
1687 public boolean supportsOpenStatementsAcrossCommit() throws SQLException {
1688 return false;
1689 }
1690
1691 public boolean supportsOpenStatementsAcrossRollback() throws SQLException {
1692 return false;
1693 }
1694
1695 public boolean supportsOrderByUnrelated() throws SQLException {
1696 return false;
1697 }
1698
1699 public boolean supportsOuterJoins() throws SQLException {
1700 return false;
1701 }
1702
1703 public boolean supportsPositionedDelete() throws SQLException {
1704 return false;
1705 }
1706
1707 public boolean supportsPositionedUpdate() throws SQLException {
1708 return false;
1709 }
1710
1711 public boolean supportsResultSetConcurrency(final int arg0, final int arg1)
1712 throws SQLException {
1713 return (arg0 == ResultSet.TYPE_FORWARD_ONLY
1714 && arg1 == ResultSet.CONCUR_READ_ONLY);
1715 }
1716
1717 public boolean supportsResultSetHoldability(final int arg0) throws SQLException {
1718 return false;
1719 }
1720
1721 public boolean supportsResultSetType(final int arg0) throws SQLException {
1722 return arg0 == ResultSet.TYPE_FORWARD_ONLY;
1723 }
1724
1725 public boolean supportsSavepoints() throws SQLException {
1726 return false;
1727 }
1728
1729 public boolean supportsSchemasInDataManipulation() throws SQLException {
1730 return true;
1731 }
1732
1733 public boolean supportsSchemasInIndexDefinitions() throws SQLException {
1734 return false;
1735 }
1736
1737 public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException {
1738 return false;
1739 }
1740
1741 public boolean supportsSchemasInProcedureCalls() throws SQLException {
1742 return false;
1743 }
1744
1745 public boolean supportsSchemasInTableDefinitions() throws SQLException {
1746 return false;
1747 }
1748
1749 public boolean supportsSelectForUpdate() throws SQLException {
1750 return false;
1751 }
1752
1753 public boolean supportsStatementPooling() throws SQLException {
1754 return false;
1755 }
1756
1757 public boolean supportsStoredProcedures() throws SQLException {
1758 return false;
1759 }
1760
1761 public boolean supportsSubqueriesInComparisons() throws SQLException {
1762 return false;
1763 }
1764
1765 public boolean supportsSubqueriesInExists() throws SQLException {
1766 return false;
1767 }
1768
1769 public boolean supportsSubqueriesInIns() throws SQLException {
1770 return false;
1771 }
1772
1773 public boolean supportsSubqueriesInQuantifieds() throws SQLException {
1774 return false;
1775 }
1776
1777 public boolean supportsTableCorrelationNames() throws SQLException {
1778 return false;
1779 }
1780
1781 public boolean supportsTransactionIsolationLevel(final int arg0)
1782 throws SQLException {
1783 return false;
1784 }
1785
1786 public boolean supportsTransactions() throws SQLException {
1787 return false;
1788 }
1789
1790 public boolean supportsUnion() throws SQLException {
1791 return false;
1792 }
1793
1794 public boolean supportsUnionAll() throws SQLException {
1795 return false;
1796 }
1797
1798 public boolean updatesAreDetected(final int arg0) throws SQLException {
1799 return false;
1800 }
1801
1802 public boolean usesLocalFilePerTable() throws SQLException {
1803 return false;
1804 }
1805
1806 public boolean usesLocalFiles() throws SQLException {
1807 return false;
1808 }
1809
1810 private String translatePattern(final String pattern) {
1811 if ("%".equals(pattern)) {
1812 return null;
1813 } else {
1814 return pattern;
1815 }
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825 }
1826
1827
1828 }