1 | /* ============================================================= |
2 | * SmallSQL : a free Java DBMS library for the Java(tm) platform |
3 | * ============================================================= |
4 | * |
5 | * (C) Copyright 2004-2006, by Volker Berlin. |
6 | * |
7 | * Project Info: http://www.smallsql.de/ |
8 | * |
9 | * This library is free software; you can redistribute it and/or modify it |
10 | * under the terms of the GNU Lesser General Public License as published by |
11 | * the Free Software Foundation; either version 2.1 of the License, or |
12 | * (at your option) any later version. |
13 | * |
14 | * This library is distributed in the hope that it will be useful, but |
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
16 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public |
17 | * License for more details. |
18 | * |
19 | * You should have received a copy of the GNU Lesser General Public |
20 | * License along with this library; if not, write to the Free Software |
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, |
22 | * USA. |
23 | * |
24 | * [Java is a trademark or registered trademark of Sun Microsystems, Inc. |
25 | * in the United States and other countries.] |
26 | * |
27 | * --------------- |
28 | * SSDatabaseMetaData.java |
29 | * --------------- |
30 | * Author: Volker Berlin |
31 | * |
32 | */ |
33 | package smallsql.database; |
34 | |
35 | import java.sql.*; |
36 | import java.util.ArrayList; |
37 | |
38 | |
39 | final class SSDatabaseMetaData implements DatabaseMetaData { |
40 | final private SSConnection con; |
41 | final private SSStatement st; |
42 | |
43 | |
44 | /** |
45 | * @throws SQLException Exception can be throw if the Connection already closed. |
46 | */ |
47 | SSDatabaseMetaData(SSConnection con) throws SQLException{ |
48 | this.con = con; |
49 | st = new SSStatement(con); |
50 | } |
51 | |
52 | public boolean allProceduresAreCallable() { |
53 | return true; |
54 | } |
55 | |
56 | |
57 | public boolean allTablesAreSelectable() { |
58 | return true; |
59 | } |
60 | |
61 | |
62 | public String getURL() throws SQLException { |
63 | Database database = con.getDatabase(true); |
64 | if(database == null) |
65 | return SSDriver.URL_PREFIX; |
66 | return SSDriver.URL_PREFIX + ':' + database.getName(); |
67 | } |
68 | |
69 | |
70 | public String getUserName() { |
71 | return ""; |
72 | } |
73 | |
74 | |
75 | public boolean isReadOnly() { |
76 | return false; |
77 | } |
78 | |
79 | |
80 | public boolean nullsAreSortedHigh() { |
81 | return false; |
82 | } |
83 | |
84 | |
85 | public boolean nullsAreSortedLow() { |
86 | return true; |
87 | } |
88 | |
89 | |
90 | public boolean nullsAreSortedAtStart() { |
91 | return false; |
92 | } |
93 | |
94 | |
95 | public boolean nullsAreSortedAtEnd() { |
96 | return false; |
97 | } |
98 | |
99 | |
100 | public String getDatabaseProductName() { |
101 | return "SmallSQL Database"; |
102 | } |
103 | |
104 | |
105 | public String getDatabaseProductVersion() { |
106 | return getDriverVersion(); |
107 | } |
108 | |
109 | |
110 | public String getDriverName() throws SQLException { |
111 | return "SmallSQL Driver"; |
112 | } |
113 | |
114 | |
115 | public String getDriverVersion() { |
116 | return getDriverMajorVersion() + "." + SSDriver.drv.getMinorVersion(); |
117 | } |
118 | |
119 | |
120 | public int getDriverMajorVersion() { |
121 | return SSDriver.drv.getMajorVersion(); |
122 | } |
123 | |
124 | |
125 | public int getDriverMinorVersion() { |
126 | return SSDriver.drv.getMinorVersion(); |
127 | } |
128 | |
129 | |
130 | public boolean usesLocalFiles() { |
131 | return false; |
132 | } |
133 | |
134 | |
135 | public boolean usesLocalFilePerTable() { |
136 | return false; |
137 | } |
138 | |
139 | |
140 | public boolean supportsMixedCaseIdentifiers() { |
141 | return true; |
142 | } |
143 | |
144 | |
145 | public boolean storesUpperCaseIdentifiers() { |
146 | return false; |
147 | } |
148 | |
149 | |
150 | public boolean storesLowerCaseIdentifiers() { |
151 | return false; |
152 | } |
153 | |
154 | |
155 | public boolean storesMixedCaseIdentifiers() { |
156 | return true; |
157 | } |
158 | |
159 | |
160 | public boolean supportsMixedCaseQuotedIdentifiers() { |
161 | return true; |
162 | } |
163 | |
164 | |
165 | public boolean storesUpperCaseQuotedIdentifiers() { |
166 | return false; |
167 | } |
168 | |
169 | |
170 | public boolean storesLowerCaseQuotedIdentifiers() { |
171 | return false; |
172 | } |
173 | |
174 | |
175 | public boolean storesMixedCaseQuotedIdentifiers() { |
176 | return true; |
177 | } |
178 | |
179 | |
180 | public String getIdentifierQuoteString() { |
181 | return "\""; |
182 | } |
183 | |
184 | |
185 | public String getSQLKeywords() { |
186 | return "database,use"; |
187 | } |
188 | |
189 | |
190 | private String getFunctions(int from, int to){ |
191 | StringBuffer buf = new StringBuffer(); |
192 | for(int i=from; i<=to; i++){ |
193 | if(i != from) buf.append(','); |
194 | buf.append( SQLTokenizer.getKeyWord(i) ); |
195 | } |
196 | return buf.toString(); |
197 | } |
198 | |
199 | |
200 | public String getNumericFunctions() { |
201 | return getFunctions(SQLTokenizer.ABS, SQLTokenizer.TRUNCATE); |
202 | } |
203 | |
204 | |
205 | public String getStringFunctions() { |
206 | return getFunctions(SQLTokenizer.ASCII, SQLTokenizer.UCASE); |
207 | } |
208 | |
209 | |
210 | public String getSystemFunctions() { |
211 | return getFunctions(SQLTokenizer.IFNULL, SQLTokenizer.IIF); |
212 | } |
213 | |
214 | |
215 | public String getTimeDateFunctions() { |
216 | return getFunctions(SQLTokenizer.CURDATE, SQLTokenizer.YEAR); |
217 | } |
218 | |
219 | |
220 | public String getSearchStringEscape() { |
221 | return "\\"; |
222 | } |
223 | |
224 | |
225 | public String getExtraNameCharacters() { |
226 | return "#$ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ"; |
227 | } |
228 | |
229 | |
230 | public boolean supportsAlterTableWithAddColumn() { |
231 | /**@todo: Implement this java.sql.DatabaseMetaData method*/ |
232 | throw new java.lang.UnsupportedOperationException("Method supportsAlterTableWithAddColumn() not yet implemented."); |
233 | } |
234 | public boolean supportsAlterTableWithDropColumn() throws SQLException { |
235 | /**@todo: Implement this java.sql.DatabaseMetaData method*/ |
236 | throw new java.lang.UnsupportedOperationException("Method supportsAlterTableWithDropColumn() not yet implemented."); |
237 | } |
238 | |
239 | |
240 | public boolean supportsColumnAliasing() { |
241 | return true; |
242 | } |
243 | |
244 | |
245 | public boolean nullPlusNonNullIsNull() { |
246 | return true; |
247 | } |
248 | |
249 | |
250 | public boolean supportsConvert() { |
251 | return true; |
252 | } |
253 | |
254 | |
255 | public boolean supportsConvert(int fromType, int toType) { |
256 | return true; |
257 | } |
258 | |
259 | |
260 | public boolean supportsTableCorrelationNames() { |
261 | return true; |
262 | } |
263 | |
264 | |
265 | public boolean supportsDifferentTableCorrelationNames() { |
266 | return true; |
267 | } |
268 | |
269 | |
270 | public boolean supportsExpressionsInOrderBy() { |
271 | return true; |
272 | } |
273 | |
274 | |
275 | public boolean supportsOrderByUnrelated() { |
276 | return true; |
277 | } |
278 | |
279 | |
280 | public boolean supportsGroupBy() { |
281 | return true; |
282 | } |
283 | |
284 | |
285 | public boolean supportsGroupByUnrelated() { |
286 | return true; |
287 | } |
288 | |
289 | |
290 | public boolean supportsGroupByBeyondSelect() { |
291 | return true; |
292 | } |
293 | |
294 | |
295 | public boolean supportsLikeEscapeClause() { |
296 | return true; |
297 | } |
298 | |
299 | |
300 | public boolean supportsMultipleResultSets() { |
301 | return true; |
302 | } |
303 | |
304 | |
305 | public boolean supportsMultipleTransactions() { |
306 | return true; |
307 | } |
308 | |
309 | |
310 | public boolean supportsNonNullableColumns() { |
311 | return true; |
312 | } |
313 | |
314 | |
315 | public boolean supportsMinimumSQLGrammar() { |
316 | return true; |
317 | } |
318 | |
319 | |
320 | public boolean supportsCoreSQLGrammar() { |
321 | return true; |
322 | } |
323 | |
324 | |
325 | public boolean supportsExtendedSQLGrammar() { |
326 | return true; |
327 | } |
328 | |
329 | |
330 | public boolean supportsANSI92EntryLevelSQL() { |
331 | return true; |
332 | } |
333 | |
334 | |
335 | public boolean supportsANSI92IntermediateSQL() { |
336 | return true; |
337 | } |
338 | |
339 | |
340 | public boolean supportsANSI92FullSQL() { |
341 | return true; |
342 | } |
343 | |
344 | |
345 | public boolean supportsIntegrityEnhancementFacility() { |
346 | return true; |
347 | } |
348 | |
349 | |
350 | public boolean supportsOuterJoins() { |
351 | return true; |
352 | } |
353 | |
354 | |
355 | public boolean supportsFullOuterJoins() { |
356 | return true; |
357 | } |
358 | |
359 | |
360 | public boolean supportsLimitedOuterJoins() { |
361 | return true; |
362 | } |
363 | |
364 | |
365 | public String getSchemaTerm() { |
366 | return "owner"; |
367 | } |
368 | |
369 | |
370 | public String getProcedureTerm() { |
371 | return "procedure"; |
372 | } |
373 | |
374 | |
375 | public String getCatalogTerm() { |
376 | return "database"; |
377 | } |
378 | |
379 | |
380 | public boolean isCatalogAtStart() { |
381 | return true; |
382 | } |
383 | |
384 | |
385 | public String getCatalogSeparator() { |
386 | return "."; |
387 | } |
388 | |
389 | |
390 | public boolean supportsSchemasInDataManipulation() { |
391 | return false; |
392 | } |
393 | |
394 | |
395 | public boolean supportsSchemasInProcedureCalls() { |
396 | return false; |
397 | } |
398 | |
399 | |
400 | public boolean supportsSchemasInTableDefinitions() { |
401 | return false; |
402 | } |
403 | |
404 | |
405 | public boolean supportsSchemasInIndexDefinitions() { |
406 | return false; |
407 | } |
408 | |
409 | |
410 | public boolean supportsSchemasInPrivilegeDefinitions() { |
411 | return false; |
412 | } |
413 | |
414 | |
415 | public boolean supportsCatalogsInDataManipulation() { |
416 | return true; |
417 | } |
418 | |
419 | |
420 | public boolean supportsCatalogsInProcedureCalls() { |
421 | return true; |
422 | } |
423 | |
424 | |
425 | public boolean supportsCatalogsInTableDefinitions() { |
426 | return true; |
427 | } |
428 | |
429 | |
430 | public boolean supportsCatalogsInIndexDefinitions() { |
431 | return true; |
432 | } |
433 | |
434 | |
435 | public boolean supportsCatalogsInPrivilegeDefinitions() { |
436 | return true; |
437 | } |
438 | |
439 | |
440 | public boolean supportsPositionedDelete() { |
441 | return true; |
442 | } |
443 | |
444 | |
445 | public boolean supportsPositionedUpdate() { |
446 | return true; |
447 | } |
448 | |
449 | |
450 | public boolean supportsSelectForUpdate() { |
451 | return true; |
452 | } |
453 | |
454 | |
455 | public boolean supportsStoredProcedures() { |
456 | return false; |
457 | } |
458 | |
459 | |
460 | public boolean supportsSubqueriesInComparisons() { |
461 | return true; |
462 | } |
463 | |
464 | |
465 | public boolean supportsSubqueriesInExists() { |
466 | return true; |
467 | } |
468 | |
469 | |
470 | public boolean supportsSubqueriesInIns() { |
471 | return true; |
472 | } |
473 | |
474 | |
475 | public boolean supportsSubqueriesInQuantifieds() { |
476 | return true; |
477 | } |
478 | |
479 | |
480 | public boolean supportsCorrelatedSubqueries() { |
481 | return true; |
482 | } |
483 | |
484 | |
485 | public boolean supportsUnion() { |
486 | return true; |
487 | } |
488 | |
489 | |
490 | public boolean supportsUnionAll() { |
491 | return true; |
492 | } |
493 | |
494 | |
495 | public boolean supportsOpenCursorsAcrossCommit() { |
496 | return true; |
497 | } |
498 | |
499 | |
500 | public boolean supportsOpenCursorsAcrossRollback() { |
501 | return true; |
502 | } |
503 | |
504 | |
505 | public boolean supportsOpenStatementsAcrossCommit() { |
506 | return true; |
507 | } |
508 | |
509 | |
510 | public boolean supportsOpenStatementsAcrossRollback() { |
511 | return true; |
512 | } |
513 | |
514 | |
515 | public int getMaxBinaryLiteralLength() { |
516 | return 0; |
517 | } |
518 | |
519 | |
520 | public int getMaxCharLiteralLength() { |
521 | return 0; |
522 | } |
523 | |
524 | |
525 | public int getMaxColumnNameLength() { |
526 | return 255; |
527 | } |
528 | |
529 | |
530 | public int getMaxColumnsInGroupBy() { |
531 | return 0; |
532 | } |
533 | |
534 | |
535 | public int getMaxColumnsInIndex() { |
536 | return 0; |
537 | } |
538 | |
539 | |
540 | public int getMaxColumnsInOrderBy() { |
541 | return 0; |
542 | } |
543 | |
544 | |
545 | public int getMaxColumnsInSelect() { |
546 | return 0; |
547 | } |
548 | |
549 | |
550 | public int getMaxColumnsInTable() { |
551 | return 0; |
552 | } |
553 | |
554 | |
555 | public int getMaxConnections() { |
556 | return 0; |
557 | } |
558 | |
559 | |
560 | public int getMaxCursorNameLength() { |
561 | return 0; |
562 | } |
563 | |
564 | |
565 | public int getMaxIndexLength() { |
566 | return 0; |
567 | } |
568 | |
569 | |
570 | public int getMaxSchemaNameLength() { |
571 | return 255; |
572 | } |
573 | |
574 | |
575 | public int getMaxProcedureNameLength() { |
576 | return 255; |
577 | } |
578 | |
579 | |
580 | public int getMaxCatalogNameLength() { |
581 | return 255; |
582 | } |
583 | |
584 | |
585 | public int getMaxRowSize() { |
586 | return 0; |
587 | } |
588 | |
589 | |
590 | public boolean doesMaxRowSizeIncludeBlobs() { |
591 | return false; |
592 | } |
593 | |
594 | |
595 | public int getMaxStatementLength() { |
596 | return 0; |
597 | } |
598 | |
599 | |
600 | public int getMaxStatements() { |
601 | return 0; |
602 | } |
603 | |
604 | |
605 | public int getMaxTableNameLength() { |
606 | return 255; |
607 | } |
608 | |
609 | |
610 | public int getMaxTablesInSelect() { |
611 | return 0; |
612 | } |
613 | |
614 | |
615 | public int getMaxUserNameLength() { |
616 | return 0; |
617 | } |
618 | |
619 | |
620 | public int getDefaultTransactionIsolation() { |
621 | return Connection.TRANSACTION_READ_COMMITTED; |
622 | } |
623 | |
624 | |
625 | public boolean supportsTransactions() { |
626 | return true; |
627 | } |
628 | |
629 | |
630 | public boolean supportsTransactionIsolationLevel(int level) { |
631 | switch(level){ |
632 | case Connection.TRANSACTION_NONE: |
633 | case Connection.TRANSACTION_READ_UNCOMMITTED: |
634 | case Connection.TRANSACTION_READ_COMMITTED: |
635 | case Connection.TRANSACTION_REPEATABLE_READ: |
636 | case Connection.TRANSACTION_SERIALIZABLE: |
637 | return true; |
638 | } |
639 | return false; |
640 | } |
641 | |
642 | |
643 | public boolean supportsDataDefinitionAndDataManipulationTransactions() { |
644 | return true; |
645 | } |
646 | |
647 | |
648 | public boolean supportsDataManipulationTransactionsOnly() { |
649 | return false; |
650 | } |
651 | |
652 | |
653 | public boolean dataDefinitionCausesTransactionCommit() { |
654 | return false; |
655 | } |
656 | |
657 | |
658 | public boolean dataDefinitionIgnoredInTransactions() { |
659 | return false; |
660 | } |
661 | |
662 | |
663 | public ResultSet getProcedures(String catalog, String schemaPattern, String procedureNamePattern) throws SQLException { |
664 | String[] colNames = {"PROCEDURE_CAT", "PROCEDURE_SCHEM", "PROCEDURE_NAME", "", "", "", "REMARKS", "PROCEDURE_TYPE"}; |
665 | Object[][] data = new Object[0][]; |
666 | return new SSResultSet( st, Utils.createMemoryCommandSelect( con, colNames, data)); |
667 | } |
668 | |
669 | |
670 | public ResultSet getProcedureColumns(String catalog, String schemaPattern, String procedureNamePattern, String columnNamePattern) throws SQLException { |
671 | String[] colNames = {"PROCEDURE_CAT", "PROCEDURE_SCHEM", "PROCEDURE_NAME", "COLUMN_NAME", "COLUMN_TYPE", "DATA_TYPE", "TYPE_NAME", "PRECISION", "LENGTH", "SCALE", "RADIX", "NULLABLE", "REMARKS" }; |
672 | Object[][] data = new Object[0][]; |
673 | return new SSResultSet( st, Utils.createMemoryCommandSelect( con, colNames, data)); |
674 | } |
675 | |
676 | |
677 | public ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types) throws SQLException { |
678 | String[] colNames = {"TABLE_CAT","TABLE_SCHEM","TABLE_NAME","TABLE_TYPE","REMARKS","TYPE_CAT","TYPE_SCHEM","TYPE_NAME","SELF_REFERENCING_COL_NAME","REF_GENERATION"}; |
679 | Database database; |
680 | if(catalog == null){ |
681 | database = con.getDatabase(true); |
682 | if(database != null) |
683 | catalog = database.getName(); |
684 | }else{ |
685 | database = Database.getDatabase(catalog, con, false); |
686 | } |
687 | ArrayList rows = new ArrayList(); |
688 | boolean isTypeTable = types == null; |
689 | boolean isTypeView = types == null; |
690 | for(int i=0; types != null && i<types.length; i++){ |
691 | if("TABLE".equalsIgnoreCase(types[i])) isTypeTable = true; |
692 | if("VIEW" .equalsIgnoreCase(types[i])) isTypeView = true; |
693 | } |
694 | |
695 | if(database != null){ |
696 | Strings tables = database.getTables(tableNamePattern); |
697 | for(int i=0; i<tables.size(); i++){ |
698 | String table = tables.get(i); |
699 | Object[] row = new Object[10]; |
700 | row[0] = catalog; |
701 | row[2] = table; |
702 | try{ |
703 | if(database.getTableView( con, table) instanceof View){ |
704 | if(isTypeView){ |
705 | row[3] = "VIEW"; |
706 | rows.add(row); |
707 | } |
708 | }else{ |
709 | if(isTypeTable){ |
710 | row[3] = "TABLE"; |
711 | rows.add(row); |
712 | } |
713 | } |
714 | }catch(Exception e){ |
715 | //TODO invalid VIEWS does not show because it can't load. |
716 | } |
717 | } |
718 | } |
719 | Object[][] data = new Object[rows.size()][]; |
720 | rows.toArray(data); |
721 | CommandSelect cmdSelect = Utils.createMemoryCommandSelect( con, colNames, data); |
722 | Expressions order = new Expressions(); |
723 | order.add( new ExpressionName("TABLE_TYPE") ); |
724 | order.add( new ExpressionName("TABLE_NAME") ); |
725 | cmdSelect.setOrder( order ); |
726 | return new SSResultSet( st, cmdSelect); |
727 | } |
728 | |
729 | |
730 | public ResultSet getSchemas() throws SQLException { |
731 | String[] colNames = {"TABLE_SCHEM"}; |
732 | Object[][] data = new Object[0][]; |
733 | return new SSResultSet( st, Utils.createMemoryCommandSelect( con, colNames, data)); |
734 | } |
735 | |
736 | |
737 | public ResultSet getCatalogs() throws SQLException { |
738 | String[] colNames = {"TABLE_CAT"}; |
739 | Object[][] data = Database.getCatalogs(con.getDatabase(true)); |
740 | return new SSResultSet( st, Utils.createMemoryCommandSelect( con, colNames, data)); |
741 | } |
742 | |
743 | |
744 | public ResultSet getTableTypes() throws SQLException { |
745 | String[] colNames = {"TABLE_TYPE"}; |
746 | Object[][] data = {{"SYSTEM TABLE"}, {"TABLE"}, {"VIEW"}}; |
747 | return new SSResultSet( st, Utils.createMemoryCommandSelect( con, colNames, data)); |
748 | } |
749 | |
750 | |
751 | public ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException { |
752 | try { |
753 | String[] colNames = {"TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", "COLUMN_NAME", "DATA_TYPE", "TYPE_NAME", "COLUMN_SIZE", "BUFFER_LENGTH", "DECIMAL_DIGITS", "NUM_PREC_RADIX", "NULLABLE", "REMARKS", "COLUMN_DEF", "SQL_DATA_TYPE", "SQL_DATETIME_SUB", "CHAR_OCTET_LENGTH", "ORDINAL_POSITION", "IS_NULLABLE"}; |
754 | Object[][] data = con.getDatabase(false).getColumns(con, tableNamePattern, columnNamePattern); |
755 | return new SSResultSet( st, Utils.createMemoryCommandSelect( con, colNames, data)); |
756 | } catch (Exception e) { |
757 | throw Utils.createSQLException(e); |
758 | } |
759 | } |
760 | |
761 | |
762 | public ResultSet getColumnPrivileges(String catalog, String schema, String table, String columnNamePattern) throws SQLException { |
763 | String[] colNames = {"TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", "COLUMN_NAME", "GRANTOR", "GRANTEE", "PRIVILEGE", "IS_GRANTABLE"}; |
764 | /**@todo: Implement this java.sql.DatabaseMetaData method*/ |
765 | throw new java.lang.UnsupportedOperationException("Method getColumnPrivileges() not yet implemented."); |
766 | } |
767 | |
768 | |
769 | public ResultSet getTablePrivileges(String catalog, String schemaPattern, String tableNamePattern) throws SQLException { |
770 | String[] colNames = {"TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", "GRANTOR", "GRANTEE", "PRIVILEGE", "IS_GRANTABLE"}; |
771 | /**@todo: Implement this java.sql.DatabaseMetaData method*/ |
772 | throw new java.lang.UnsupportedOperationException("Method getTablePrivileges() not yet implemented."); |
773 | } |
774 | |
775 | |
776 | public ResultSet getBestRowIdentifier(String catalog, String schema, String table, int scope, boolean nullable) throws SQLException { |
777 | try { |
778 | String[] colNames = {"SCOPE", "COLUMN_NAME", "DATA_TYPE", "TYPE_NAME", "COLUMN_SIZE", "BUFFER_LENGTH", "DECIMAL_DIGITS", "PSEUDO_COLUMN"}; |
779 | Object[][] data = con.getDatabase(false).getBestRowIdentifier(con, table); |
780 | return new SSResultSet( st, Utils.createMemoryCommandSelect( con, colNames, data)); |
781 | } catch (Exception e) { |
782 | throw Utils.createSQLException(e); |
783 | } |
784 | } |
785 | |
786 | |
787 | public ResultSet getVersionColumns(String catalog, String schema, String table) throws SQLException { |
788 | try { |
789 | String[] colNames = {"SCOPE", "COLUMN_NAME", "DATA_TYPE", "TYPE_NAME", "COLUMN_SIZE", "BUFFER_LENGTH", "DECIMAL_DIGITS", "PSEUDO_COLUMN"}; |
790 | Object[][] data = new Object[0][0]; |
791 | return new SSResultSet( st, Utils.createMemoryCommandSelect( con, colNames, data)); |
792 | } catch (Exception e) { |
793 | throw Utils.createSQLException(e); |
794 | } |
795 | } |
796 | |
797 | |
798 | public ResultSet getPrimaryKeys(String catalog, String schema, String table) throws SQLException { |
799 | try { |
800 | String[] colNames = {"TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", "COLUMN_NAME", "KEY_SEQ", "PK_NAME"}; |
801 | Object[][] data = con.getDatabase(false).getPrimaryKeys(con, table); |
802 | return new SSResultSet( st, Utils.createMemoryCommandSelect( con, colNames, data)); |
803 | } catch (Exception e) { |
804 | throw Utils.createSQLException(e); |
805 | } |
806 | } |
807 | |
808 | |
809 | public ResultSet getImportedKeys(String catalog, String schema, String table) throws SQLException { |
810 | return getCrossReference( null, null, null, null, null, table ); |
811 | } |
812 | |
813 | |
814 | public ResultSet getExportedKeys(String catalog, String schema, String table) throws SQLException { |
815 | return getCrossReference( null, null, table, null, null, null ); |
816 | } |
817 | |
818 | |
819 | public ResultSet getCrossReference(String primaryCatalog, String primarySchema, String primaryTable, String foreignCatalog, String foreignSchema, String foreignTable) throws SQLException { |
820 | try { |
821 | String[] colNames = {"PKTABLE_CAT", "PKTABLE_SCHEM", "PKTABLE_NAME", "PKCOLUMN_NAME", "FKTABLE_CAT", "FKTABLE_SCHEM", "FKTABLE_NAME", "FKCOLUMN_NAME", "KEY_SEQ", "UPDATE_RULE", "DELETE_RULE", "FK_NAME", "PK_NAME", "DEFERRABILITY"}; |
822 | Object[][] data = con.getDatabase(false).getReferenceKeys(con, primaryTable, foreignTable); |
823 | return new SSResultSet( st, Utils.createMemoryCommandSelect( con, colNames, data)); |
824 | } catch (Exception e) { |
825 | throw Utils.createSQLException(e); |
826 | } |
827 | } |
828 | |
829 | |
830 | public ResultSet getTypeInfo() throws SQLException { |
831 | String[] colNames = { "TYPE_NAME", "DATA_TYPE", "PRECISION", "LITERAL_PREFIX", "LITERAL_SUFFIX", "CREATE_PARAMS", "NULLABLE", "CASE_SENSITIVE", "SEARCHABLE", "UNSIGNED_ATTRIBUTE", "FIXED_PREC_SCALE", "AUTO_INCREMENT", "LOCAL_TYPE_NAME", "MINIMUM_SCALE", "MAXIMUM_SCALE", "SQL_DATA_TYPE", "SQL_DATETIME_SUB", "NUM_PREC_RADIX"}; |
832 | Object[][] data = { |
833 | {SQLTokenizer.getKeyWord(SQLTokenizer.UNIQUEIDENTIFIER),Utils.getShort(SQLTokenizer.getSQLDataType( SQLTokenizer.UNIQUEIDENTIFIER)), Utils.getInteger(36), "'", "'", null, Utils.getShort(typeNullable), Boolean.FALSE, Utils.getShort(typeSearchable), null, Boolean.FALSE, Boolean.FALSE, null, null, null, null, null, null}, |
834 | {SQLTokenizer.getKeyWord(SQLTokenizer.BIT), Utils.getShort(SQLTokenizer.getSQLDataType( SQLTokenizer.BIT) ), Utils.getInteger(1), null, null, null, Utils.getShort(typeNullable), Boolean.FALSE, Utils.getShort(typeSearchable), null, Boolean.FALSE, Boolean.FALSE, null, Utils.getInteger(0), Utils.getInteger(0), null, null, null}, |
835 | {SQLTokenizer.getKeyWord(SQLTokenizer.TINYINT), Utils.getShort(SQLTokenizer.getSQLDataType( SQLTokenizer.TINYINT) ), Utils.getInteger(3), null, null, null, Utils.getShort(typeNullable), Boolean.FALSE, Utils.getShort(typeSearchable), Boolean.TRUE, Boolean.FALSE, Boolean.FALSE, null, Utils.getInteger(0), Utils.getInteger(0), null, null, null}, |
836 | {SQLTokenizer.getKeyWord(SQLTokenizer.BIGINT), Utils.getShort(SQLTokenizer.getSQLDataType( SQLTokenizer.BIGINT) ), Utils.getInteger(19), null, null, null, Utils.getShort(typeNullable), Boolean.FALSE, Utils.getShort(typeSearchable), Boolean.FALSE, Boolean.FALSE, Boolean.FALSE, null, Utils.getInteger(0), Utils.getInteger(0), null, null, null}, |
837 | {SQLTokenizer.getKeyWord(SQLTokenizer.LONGVARBINARY), Utils.getShort(SQLTokenizer.getSQLDataType( SQLTokenizer.LONGVARBINARY) ), Utils.getInteger(2147483647), "0x", null, null, Utils.getShort(typeNullable), Boolean.FALSE, Utils.getShort(typeSearchable), null, Boolean.FALSE, Boolean.FALSE, null, null, null, null, null, null}, |
838 | {SQLTokenizer.getKeyWord(SQLTokenizer.VARBINARY), Utils.getShort(SQLTokenizer.getSQLDataType( SQLTokenizer.VARBINARY) ), Utils.getInteger(65535), "0x", null, "max length", Utils.getShort(typeNullable), Boolean.FALSE, Utils.getShort(typeSearchable), null, Boolean.FALSE, Boolean.FALSE, null, null, null, null, null, null}, |
839 | {SQLTokenizer.getKeyWord(SQLTokenizer.BINARY), Utils.getShort(SQLTokenizer.getSQLDataType( SQLTokenizer.BINARY) ), Utils.getInteger(65535), "0x", null, "length", Utils.getShort(typeNullable), Boolean.FALSE, Utils.getShort(typeSearchable), null, Boolean.FALSE, Boolean.FALSE, null, null, null, null, null, null}, |
840 | {SQLTokenizer.getKeyWord(SQLTokenizer.LONGVARCHAR), Utils.getShort(SQLTokenizer.getSQLDataType( SQLTokenizer.LONGVARCHAR) ), Utils.getInteger(2147483647), "'", "'", null, Utils.getShort(typeNullable), Boolean.FALSE, Utils.getShort(typeSearchable), null, Boolean.FALSE, Boolean.FALSE, null, null, null, null, null, null}, |
841 | {SQLTokenizer.getKeyWord(SQLTokenizer.LONGNVARCHAR), Utils.getShort(SQLTokenizer.getSQLDataType( SQLTokenizer.LONGNVARCHAR) ), Utils.getInteger(2147483647), "'", "'", null, Utils.getShort(typeNullable), Boolean.FALSE, Utils.getShort(typeSearchable), null, Boolean.FALSE, Boolean.FALSE, null, null, null, null, null, null}, |
842 | {SQLTokenizer.getKeyWord(SQLTokenizer.CHAR), Utils.getShort(SQLTokenizer.getSQLDataType( SQLTokenizer.CHAR) ), Utils.getInteger(65535), "'", "'", "length", Utils.getShort(typeNullable), Boolean.FALSE, Utils.getShort(typeSearchable), null, Boolean.FALSE, Boolean.FALSE, null, null, null, null, null, null}, |
843 | {SQLTokenizer.getKeyWord(SQLTokenizer.NCHAR), Utils.getShort(SQLTokenizer.getSQLDataType( SQLTokenizer.NCHAR) ), Utils.getInteger(65535), "'", "'", "length", Utils.getShort(typeNullable), Boolean.FALSE, Utils.getShort(typeSearchable), null, Boolean.FALSE, Boolean.FALSE, null, null, null, null, null, null}, |
844 | {SQLTokenizer.getKeyWord(SQLTokenizer.NUMERIC), Utils.getShort(SQLTokenizer.getSQLDataType( SQLTokenizer.NUMERIC) ), Utils.getInteger(38), null, null, "precision,scale", Utils.getShort(typeNullable), Boolean.FALSE, Utils.getShort(typeSearchable), Boolean.FALSE, Boolean.FALSE, Boolean.FALSE, null, Utils.getInteger(0), Utils.getInteger(38),null, null, null}, |
845 | {SQLTokenizer.getKeyWord(SQLTokenizer.DECIMAL), Utils.getShort(SQLTokenizer.getSQLDataType( SQLTokenizer.DECIMAL) ), Utils.getInteger(38), null, null, "precision,scale", Utils.getShort(typeNullable), Boolean.FALSE, Utils.getShort(typeSearchable), Boolean.FALSE, Boolean.FALSE, Boolean.FALSE, null, Utils.getInteger(0), Utils.getInteger(38),null, null, null}, |
846 | {SQLTokenizer.getKeyWord(SQLTokenizer.MONEY), Utils.getShort(SQLTokenizer.getSQLDataType( SQLTokenizer.MONEY) ), Utils.getInteger(19), null, null, null, Utils.getShort(typeNullable), Boolean.FALSE, Utils.getShort(typeSearchable), Boolean.FALSE, Boolean.FALSE, Boolean.FALSE, null, Utils.getInteger(4), Utils.getInteger(4), null, null, null}, |
847 | {SQLTokenizer.getKeyWord(SQLTokenizer.SMALLMONEY), Utils.getShort(SQLTokenizer.getSQLDataType( SQLTokenizer.SMALLMONEY) ), Utils.getInteger(10), null, null, null, Utils.getShort(typeNullable), Boolean.FALSE, Utils.getShort(typeSearchable), Boolean.FALSE, Boolean.FALSE, Boolean.FALSE, null, Utils.getInteger(4), Utils.getInteger(4), null, null, null}, |
848 | {SQLTokenizer.getKeyWord(SQLTokenizer.INT), Utils.getShort(SQLTokenizer.getSQLDataType( SQLTokenizer.INT) ), Utils.getInteger(10), null, null, null, Utils.getShort(typeNullable), Boolean.FALSE, Utils.getShort(typeSearchable), Boolean.FALSE, Boolean.FALSE, Boolean.FALSE, null, Utils.getInteger(0), Utils.getInteger(0), null, null, null}, |
849 | {SQLTokenizer.getKeyWord(SQLTokenizer.SMALLINT), Utils.getShort(SQLTokenizer.getSQLDataType( SQLTokenizer.SMALLINT) ), Utils.getInteger(5), null, null, null, Utils.getShort(typeNullable), Boolean.FALSE, Utils.getShort(typeSearchable), Boolean.FALSE, Boolean.FALSE, Boolean.FALSE, null, Utils.getInteger(0), Utils.getInteger(0), null, null, null}, |
850 | {SQLTokenizer.getKeyWord(SQLTokenizer.FLOAT), Utils.getShort(SQLTokenizer.getSQLDataType( SQLTokenizer.FLOAT) ), Utils.getInteger(15), null, null, null, Utils.getShort(typeNullable), Boolean.FALSE, Utils.getShort(typeSearchable), Boolean.FALSE, Boolean.FALSE, Boolean.FALSE, null, Utils.getInteger(0), Utils.getInteger(0), null, null, null}, |
851 | {SQLTokenizer.getKeyWord(SQLTokenizer.REAL), Utils.getShort(SQLTokenizer.getSQLDataType( SQLTokenizer.REAL) ), Utils.getInteger(7), null, null, null, Utils.getShort(typeNullable), Boolean.FALSE, Utils.getShort(typeSearchable), Boolean.FALSE, Boolean.FALSE, Boolean.FALSE, null, Utils.getInteger(0), Utils.getInteger(0), null, null, null}, |
852 | {SQLTokenizer.getKeyWord(SQLTokenizer.DOUBLE), Utils.getShort(SQLTokenizer.getSQLDataType( SQLTokenizer.DOUBLE) ), Utils.getInteger(15), null, null, null, Utils.getShort(typeNullable), Boolean.FALSE, Utils.getShort(typeSearchable), Boolean.FALSE, Boolean.FALSE, Boolean.FALSE, null, Utils.getInteger(0), Utils.getInteger(0), null, null, null}, |
853 | {SQLTokenizer.getKeyWord(SQLTokenizer.VARCHAR), Utils.getShort(SQLTokenizer.getSQLDataType( SQLTokenizer.VARCHAR) ), Utils.getInteger(65535), "'", "'", "max length", Utils.getShort(typeNullable), Boolean.FALSE, Utils.getShort(typeSearchable), null, Boolean.FALSE, Boolean.FALSE, null, null, null, null, null, null}, |
854 | {SQLTokenizer.getKeyWord(SQLTokenizer.NVARCHAR), Utils.getShort(SQLTokenizer.getSQLDataType( SQLTokenizer.NVARCHAR) ), Utils.getInteger(65535), "'", "'", "max length", Utils.getShort(typeNullable), Boolean.FALSE, Utils.getShort(typeSearchable), null, Boolean.FALSE, Boolean.FALSE, null, null, null, null, null, null}, |
855 | {SQLTokenizer.getKeyWord(SQLTokenizer.BOOLEAN), Utils.getShort(SQLTokenizer.getSQLDataType( SQLTokenizer.BOOLEAN) ), Utils.getInteger(1), null, null, null, Utils.getShort(typeNullable), Boolean.FALSE, Utils.getShort(typeSearchable), null, Boolean.FALSE, Boolean.FALSE, null, Utils.getInteger(0), Utils.getInteger(0), null, null, null}, |
856 | {SQLTokenizer.getKeyWord(SQLTokenizer.DATE), Utils.getShort(SQLTokenizer.getSQLDataType( SQLTokenizer.DATE) ), Utils.getInteger(10), "'", "'", null, Utils.getShort(typeNullable), Boolean.FALSE, Utils.getShort(typeSearchable), null, Boolean.FALSE, Boolean.FALSE, null, null, null, null, null, null}, |
857 | {SQLTokenizer.getKeyWord(SQLTokenizer.TIME), Utils.getShort(SQLTokenizer.getSQLDataType( SQLTokenizer.TIME) ), Utils.getInteger(8), "'", "'", null, Utils.getShort(typeNullable), Boolean.FALSE, Utils.getShort(typeSearchable), null, Boolean.FALSE, Boolean.FALSE, null, null, null, null, null, null}, |
858 | {SQLTokenizer.getKeyWord(SQLTokenizer.TIMESTAMP), Utils.getShort(SQLTokenizer.getSQLDataType( SQLTokenizer.TIMESTAMP) ), Utils.getInteger(23), "'", "'", null, Utils.getShort(typeNullable), Boolean.FALSE, Utils.getShort(typeSearchable), null, Boolean.FALSE, Boolean.FALSE, null, Utils.getInteger(3), Utils.getInteger(3), null, null, null}, |
859 | {SQLTokenizer.getKeyWord(SQLTokenizer.SMALLDATETIME), Utils.getShort(SQLTokenizer.getSQLDataType( SQLTokenizer.SMALLDATETIME) ), Utils.getInteger(16), "'", "'", null, Utils.getShort(typeNullable), Boolean.FALSE, Utils.getShort(typeSearchable), null, Boolean.FALSE, Boolean.FALSE, null, null, null, null, null, null}, |
860 | {SQLTokenizer.getKeyWord(SQLTokenizer.JAVA_OBJECT), Utils.getShort(SQLTokenizer.getSQLDataType( SQLTokenizer.JAVA_OBJECT) ), Utils.getInteger(65535), null, null, null, Utils.getShort(typeNullable), Boolean.FALSE, Utils.getShort(typeSearchable), null, Boolean.FALSE, Boolean.FALSE, null, null, null, null, null, null}, |
861 | {SQLTokenizer.getKeyWord(SQLTokenizer.BLOB), Utils.getShort(SQLTokenizer.getSQLDataType( SQLTokenizer.BLOB) ), Utils.getInteger(2147483647), "0x", null, null, Utils.getShort(typeNullable), Boolean.FALSE, Utils.getShort(typeSearchable), null, Boolean.FALSE, Boolean.FALSE, null, null, null, null, null, null}, |
862 | {SQLTokenizer.getKeyWord(SQLTokenizer.CLOB), Utils.getShort(SQLTokenizer.getSQLDataType( SQLTokenizer.CLOB) ), Utils.getInteger(2147483647), "'", "'", null, Utils.getShort(typeNullable), Boolean.FALSE, Utils.getShort(typeSearchable), null, Boolean.FALSE, Boolean.FALSE, null, null, null, null, null, null}, |
863 | {SQLTokenizer.getKeyWord(SQLTokenizer.NCLOB), Utils.getShort(SQLTokenizer.getSQLDataType( SQLTokenizer.NCLOB) ), Utils.getInteger(2147483647), "'", "'", null, Utils.getShort(typeNullable), Boolean.FALSE, Utils.getShort(typeSearchable), null, Boolean.FALSE, Boolean.FALSE, null, null, null, null, null, null}, |
864 | }; |
865 | //TODO weitere Datentypen hinzufügen zur Liste |
866 | return new SSResultSet( st, Utils.createMemoryCommandSelect( con, colNames, data)); |
867 | } |
868 | |
869 | |
870 | public ResultSet getIndexInfo(String catalog, String schema, String table, boolean unique, boolean approximate) throws SQLException { |
871 | try { |
872 | String[] colNames = {"TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", "NON_UNIQUE", "INDEX_QUALIFIER", "INDEX_NAME", "TYPE", "ORDINAL_POSITION", "COLUMN_NAME", "ASC_OR_DESC", "CARDINALITY", "PAGES", "FILTER_CONDITION"}; |
873 | Object[][] data = con.getDatabase(false).getIndexInfo(con, table, unique); |
874 | return new SSResultSet( st, Utils.createMemoryCommandSelect( con, colNames, data)); |
875 | } catch (Exception e) { |
876 | throw Utils.createSQLException(e); |
877 | } |
878 | } |
879 | |
880 | |
881 | public boolean supportsResultSetType(int type) { |
882 | switch(type){ |
883 | case ResultSet.TYPE_FORWARD_ONLY: |
884 | case ResultSet.TYPE_SCROLL_INSENSITIVE: |
885 | case ResultSet.TYPE_SCROLL_SENSITIVE: |
886 | return true; |
887 | } |
888 | return false; |
889 | } |
890 | |
891 | |
892 | public boolean supportsResultSetConcurrency(int type, int concurrency) { |
893 | if(type >= ResultSet.TYPE_FORWARD_ONLY && type <= ResultSet.TYPE_SCROLL_SENSITIVE && |
894 | concurrency >= ResultSet.CONCUR_READ_ONLY && concurrency <= ResultSet.CONCUR_UPDATABLE) |
895 | return true; |
896 | return false; |
897 | } |
898 | |
899 | |
900 | public boolean ownUpdatesAreVisible(int type) { |
901 | return supportsResultSetType(type); |
902 | } |
903 | |
904 | |
905 | public boolean ownDeletesAreVisible(int type) { |
906 | return supportsResultSetType(type); |
907 | } |
908 | |
909 | |
910 | public boolean ownInsertsAreVisible(int type) { |
911 | return supportsResultSetType(type); |
912 | } |
913 | |
914 | |
915 | public boolean othersUpdatesAreVisible(int type) { |
916 | return supportsResultSetType(type); |
917 | } |
918 | |
919 | |
920 | public boolean othersDeletesAreVisible(int type) { |
921 | return supportsResultSetType(type); |
922 | } |
923 | |
924 | |
925 | public boolean othersInsertsAreVisible(int type) { |
926 | return supportsResultSetType(type); |
927 | } |
928 | |
929 | |
930 | public boolean updatesAreDetected(int type) { |
931 | return false; |
932 | } |
933 | |
934 | |
935 | public boolean deletesAreDetected(int type) { |
936 | return supportsResultSetType(type); |
937 | } |
938 | |
939 | |
940 | public boolean insertsAreDetected(int type) { |
941 | return supportsResultSetType(type); |
942 | } |
943 | |
944 | |
945 | public boolean supportsBatchUpdates() { |
946 | return true; |
947 | } |
948 | |
949 | |
950 | public ResultSet getUDTs(String catalog, String schemaPattern, String typeNamePattern, int[] types) throws SQLException { |
951 | String[] colNames = {"TYPE_CAT", "TYPE_SCHEM", "TYPE_NAME", "CLASS_NAME", "DATA_TYPE", "REMARKS"}; |
952 | Object[][] data = new Object[0][]; |
953 | return new SSResultSet( st, Utils.createMemoryCommandSelect( con, colNames, data)); |
954 | } |
955 | |
956 | |
957 | public Connection getConnection() { |
958 | return con; |
959 | } |
960 | |
961 | |
962 | public boolean supportsSavepoints() { |
963 | return false; |
964 | } |
965 | |
966 | |
967 | public boolean supportsNamedParameters() { |
968 | return true; |
969 | } |
970 | |
971 | |
972 | public boolean supportsMultipleOpenResults() { |
973 | return true; |
974 | } |
975 | |
976 | |
977 | public boolean supportsGetGeneratedKeys() { |
978 | return true; |
979 | } |
980 | |
981 | |
982 | public ResultSet getSuperTypes(String catalog, String schemaPattern, String typeNamePattern) throws SQLException { |
983 | /**@todo: Implement this java.sql.DatabaseMetaData method*/ |
984 | throw new java.lang.UnsupportedOperationException("Method getSuperTypes() not yet implemented."); |
985 | } |
986 | public ResultSet getSuperTables(String catalog, String schemaPattern, String tableNamePattern) throws SQLException { |
987 | /**@todo: Implement this java.sql.DatabaseMetaData method*/ |
988 | throw new java.lang.UnsupportedOperationException("Method getSuperTables() not yet implemented."); |
989 | } |
990 | public ResultSet getAttributes(String catalog, String schemaPattern, String typeNamePattern, String attributeNamePattern) throws SQLException { |
991 | /**@todo: Implement this java.sql.DatabaseMetaData method*/ |
992 | throw new java.lang.UnsupportedOperationException("Method getAttributes() not yet implemented."); |
993 | } |
994 | |
995 | |
996 | public boolean supportsResultSetHoldability(int holdability) { |
997 | return true; |
998 | } |
999 | |
1000 | |
1001 | public int getResultSetHoldability() { |
1002 | return ResultSet.HOLD_CURSORS_OVER_COMMIT; |
1003 | } |
1004 | |
1005 | |
1006 | public int getDatabaseMajorVersion() { |
1007 | return getDriverMajorVersion(); |
1008 | } |
1009 | |
1010 | |
1011 | public int getDatabaseMinorVersion() { |
1012 | return getDriverMinorVersion(); |
1013 | } |
1014 | |
1015 | |
1016 | public int getJDBCMajorVersion() { |
1017 | return 3; |
1018 | } |
1019 | |
1020 | |
1021 | public int getJDBCMinorVersion() { |
1022 | return 0; |
1023 | } |
1024 | |
1025 | |
1026 | public int getSQLStateType() { |
1027 | return sqlStateSQL99; |
1028 | } |
1029 | |
1030 | |
1031 | public boolean locatorsUpdateCopy() { |
1032 | return false; |
1033 | } |
1034 | |
1035 | |
1036 | public boolean supportsStatementPooling() { |
1037 | return false; |
1038 | } |
1039 | } |