Repository: ignite Updated Branches: refs/heads/ignite-843 852772cf8 -> 39224cb15
Merge branches 'ignite-843' and 'master' of https://git-wip-us.apache.org/repos/asf/incubator-ignite into ignite-843 Conflicts: modules/schema-import/src/main/java/org/apache/ignite/schema/parser/DatabaseMetadataParser.java modules/schema-import/src/main/java/org/apache/ignite/schema/ui/SchemaImportApp.java Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/d32674ee Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/d32674ee Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/d32674ee Branch: refs/heads/ignite-843 Commit: d32674eea3050492a3bc906face5a5ed84a1ce29 Parents: 4e007c7 c55d923 Author: AKuznetsov <[email protected]> Authored: Fri Aug 21 19:38:21 2015 +0700 Committer: AKuznetsov <[email protected]> Committed: Fri Aug 21 19:38:21 2015 +0700 ---------------------------------------------------------------------- examples/config/example-cache.xml | 2 - .../apache/ignite/IgniteSystemProperties.java | 3 + .../store/jdbc/CacheAbstractJdbcStore.java | 45 +- .../cache/store/jdbc/CacheJdbcPojoStore.java | 32 +- .../store/jdbc/dialect/BasicJdbcDialect.java | 3 + .../cache/store/jdbc/dialect/DB2Dialect.java | 3 + .../cache/store/jdbc/dialect/H2Dialect.java | 3 + .../cache/store/jdbc/dialect/JdbcDialect.java | 3 +- .../cache/store/jdbc/dialect/MySQLDialect.java | 3 + .../cache/store/jdbc/dialect/OracleDialect.java | 3 + .../store/jdbc/dialect/SQLServerDialect.java | 3 + .../cluster/ClusterTopologyException.java | 18 + .../ignite/internal/MarshallerContextImpl.java | 24 +- .../ClusterTopologyCheckedException.java | 18 + .../CachePartialUpdateCheckedException.java | 11 +- .../processors/cache/GridCacheAdapter.java | 85 ++- .../processors/cache/GridCacheIoManager.java | 1 - .../cache/GridCacheSharedContext.java | 17 + .../processors/cache/GridCacheUtils.java | 23 + .../distributed/GridDistributedCacheEntry.java | 7 + .../dht/GridClientPartitionTopology.java | 20 + .../distributed/dht/GridDhtCacheAdapter.java | 12 +- .../cache/distributed/dht/GridDhtGetFuture.java | 12 +- .../dht/GridDhtPartitionTopology.java | 7 + .../dht/GridDhtPartitionTopologyImpl.java | 20 + .../cache/distributed/dht/GridDhtTxLocal.java | 4 +- .../distributed/dht/GridDhtTxPrepareFuture.java | 182 ++++++- .../dht/GridDhtTxPrepareResponse.java | 42 +- .../dht/GridPartitionedGetFuture.java | 104 ++-- .../dht/atomic/GridDhtAtomicCache.java | 16 +- .../dht/atomic/GridNearAtomicUpdateFuture.java | 3 + .../dht/colocated/GridDhtColocatedCache.java | 19 +- .../colocated/GridDhtColocatedLockFuture.java | 8 +- .../GridDhtPartitionsExchangeFuture.java | 40 +- .../distributed/near/GridNearAtomicCache.java | 6 +- .../distributed/near/GridNearCacheAdapter.java | 15 +- .../distributed/near/GridNearCacheEntry.java | 10 +- .../distributed/near/GridNearGetFuture.java | 120 ++-- .../distributed/near/GridNearLockFuture.java | 12 +- .../near/GridNearOptimisticTxPrepareFuture.java | 13 +- .../GridNearPessimisticTxPrepareFuture.java | 9 +- .../near/GridNearTransactionalCache.java | 9 +- .../cache/distributed/near/GridNearTxLocal.java | 7 +- .../near/GridNearTxPrepareResponse.java | 3 - .../local/atomic/GridLocalAtomicCache.java | 17 +- .../cache/transactions/IgniteInternalTx.java | 2 +- .../cache/transactions/IgniteTxAdapter.java | 19 +- .../cache/transactions/IgniteTxEntry.java | 18 + .../cache/transactions/IgniteTxHandler.java | 5 +- .../transactions/IgniteTxLocalAdapter.java | 4 +- .../service/GridServiceProcessor.java | 5 + .../ignite/internal/util/IgniteUtils.java | 10 +- .../ignite/internal/util/lang/GridFunc.java | 14 + .../TcpDiscoveryMulticastIpFinder.java | 38 ++ .../config/store/jdbc/ignite-type-metadata.xml | 8 + .../store/jdbc/CacheJdbcPojoStoreTest.java | 33 +- ...eJdbcStoreAbstractMultithreadedSelfTest.java | 16 +- .../ignite/cache/store/jdbc/model/Person.java | 26 +- .../cache/CrossCacheTxRandomOperationsTest.java | 542 +++++++++++++++++++ ...teAtomicCacheEntryProcessorNodeJoinTest.java | 32 ++ .../IgniteCacheEntryProcessorNodeJoinTest.java | 225 ++++++++ .../IgniteCacheTopologySafeGetSelfTest.java | 218 ++++++++ .../GridCacheTransformEventSelfTest.java | 2 + .../IgniteCacheCrossCacheTxFailoverTest.java | 433 +++++++++++++++ .../IgniteCachePutRetryAbstractSelfTest.java | 1 + ...gniteCachePutRetryTransactionalSelfTest.java | 187 +++++++ .../near/GridCacheNearOnlyTopologySelfTest.java | 4 +- .../near/GridCacheNearTxForceKeyTest.java | 76 +++ ...idCachePartitionedHitsAndMissesSelfTest.java | 20 +- .../OptimizedMarshallerNodeFailoverTest.java | 97 +++- .../IgniteCacheFailoverTestSuite.java | 2 + .../testsuites/IgniteCacheTestSuite2.java | 5 + .../parser/dialect/DB2MetadataDialect.java | 3 +- .../parser/dialect/DatabaseMetadataDialect.java | 13 +- .../parser/dialect/JdbcMetadataDialect.java | 129 +++-- .../parser/dialect/OracleMetadataDialect.java | 111 ++-- .../ignite/schema/model/PojoDescriptor.java | 6 +- .../ignite/schema/model/SchemaDescriptor.java | 61 +++ .../schema/parser/DatabaseMetadataParser.java | 52 +- .../parser/dialect/MySQLMetadataDialect.java | 57 ++ .../org/apache/ignite/schema/ui/Controls.java | 25 +- .../ignite/schema/ui/SchemaImportApp.java | 155 +++++- .../schema/test/AbstractSchemaImportTest.java | 10 +- .../jdbc/CacheJdbcPojoStoreFactorySelfTest.java | 14 +- 84 files changed, 3299 insertions(+), 396 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/d32674ee/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/dialect/DB2MetadataDialect.java ---------------------------------------------------------------------- diff --cc modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/dialect/DB2MetadataDialect.java index 17eb8b2,0000000..15063e2 mode 100644,000000..100644 --- a/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/dialect/DB2MetadataDialect.java +++ b/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/dialect/DB2MetadataDialect.java @@@ -1,30 -1,0 +1,31 @@@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.schema.parser.dialect; + +import java.util.*; + +/** + * DB2 specific metadata dialect. + */ +public class DB2MetadataDialect extends JdbcMetadataDialect { + /** {@inheritDoc} */ + @Override public Set<String> systemSchemas() { - return new HashSet<>(Arrays.asList("SYSIBM", "SYSCAT", "SYSSTAT", "SYSTOOLS")); ++ return new HashSet<>(Arrays.asList("SYSIBM", "SYSCAT", "SYSSTAT", "SYSTOOLS", "SYSFUN", "SYSIBMADM", ++ "SYSIBMINTERNAL", "SYSIBMTS", "SYSPROC", "SYSPUBLIC")); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/d32674ee/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/dialect/DatabaseMetadataDialect.java ---------------------------------------------------------------------- diff --cc modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/dialect/DatabaseMetadataDialect.java index 0d17567,0000000..9c059b8 mode 100644,000000..100644 --- a/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/dialect/DatabaseMetadataDialect.java +++ b/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/dialect/DatabaseMetadataDialect.java @@@ -1,78 -1,0 +1,89 @@@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.schema.parser.dialect; + +import org.apache.ignite.schema.parser.*; + +import java.sql.*; +import java.util.*; + +/** + * Base class for database metadata dialect. + */ +public abstract class DatabaseMetadataDialect { + /** ++ * Gets schemas from database. ++ * ++ * @param conn Database connection. ++ * @return Collection of schema descriptors. ++ * @throws SQLException If failed to get schemas. ++ */ ++ public abstract List<String> schemas(Connection conn) throws SQLException; ++ ++ /** + * Gets tables from database. + * + * @param conn Database connection. ++ * @param schemas Collention of schema names to load. + * @param tblsOnly If {@code true} then gets only tables otherwise gets tables and views. + * @return Collection of table descriptors. + * @throws SQLException If failed to get tables. + */ - public abstract Collection<DbTable> tables(Connection conn, boolean tblsOnly) throws SQLException; ++ public abstract Collection<DbTable> tables(Connection conn, List<String> schemas, boolean tblsOnly) ++ throws SQLException; + + /** + * @return Collection of database system schemas. + */ + public Set<String> systemSchemas() { + return Collections.singleton("INFORMATION_SCHEMA"); + } + + /** + * Create table descriptor. + * + * @param schema Schema name. + * @param tbl Table name. + * @param cols Table columns. + * @param idxs Table indexes. + * @return New {@code DbTable} instance. + */ + protected DbTable table(String schema, String tbl, Collection<DbColumn> cols, Map<String, Map<String, Boolean>>idxs) { + Set<String> ascCols = new HashSet<>(); + + Set<String> descCols = new HashSet<>(); + + for (Map<String, Boolean> idx : idxs.values()) { + if (idx.size() == 1) + for (Map.Entry<String, Boolean> idxCol : idx.entrySet()) { + String colName = idxCol.getKey(); + + Boolean desc = idxCol.getValue(); + + if (desc != null) { + if (desc) + descCols.add(colName); + else + ascCols.add(colName); + } + } + } + + return new DbTable(schema, tbl, cols, ascCols, descCols, idxs); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/d32674ee/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/dialect/JdbcMetadataDialect.java ---------------------------------------------------------------------- diff --cc modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/dialect/JdbcMetadataDialect.java index ab65e7a,0000000..1bb6840 mode 100644,000000..100644 --- a/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/dialect/JdbcMetadataDialect.java +++ b/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/dialect/JdbcMetadataDialect.java @@@ -1,141 -1,0 +1,182 @@@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.schema.parser.dialect; + +import org.apache.ignite.schema.parser.*; + +import java.sql.*; +import java.util.*; + +/** + * Metadata dialect that uses standard JDBC for reading metadata. + */ +public class JdbcMetadataDialect extends DatabaseMetadataDialect { + /** */ + private static final String[] TABLES_ONLY = {"TABLE"}; + + /** */ + private static final String[] TABLES_AND_VIEWS = {"TABLE", "VIEW"}; + + /** Schema catalog index. */ + private static final int TBL_CATALOG_IDX = 1; + + /** Schema name index. */ + private static final int TBL_SCHEMA_IDX = 2; + + /** Table name index. */ + private static final int TBL_NAME_IDX = 3; + + /** Primary key column name index. */ + private static final int PK_COL_NAME_IDX = 4; + + /** Column name index. */ + private static final int COL_NAME_IDX = 4; + + /** Column data type index. */ + private static final int COL_DATA_TYPE_IDX = 5; + + /** Column nullable index. */ + private static final int COL_NULLABLE_IDX = 11; + + /** Index name index. */ + private static final int IDX_NAME_IDX = 6; + + /** Index column name index. */ + private static final int IDX_COL_NAME_IDX = 9; + + /** Index column descend index. */ + private static final int IDX_ASC_OR_DESC_IDX = 10; + + /** {@inheritDoc} */ - @Override public Collection<DbTable> tables(Connection conn, boolean tblsOnly) throws SQLException { ++ @Override public List<String> schemas(Connection conn) throws SQLException { ++ List<String> schemas = new ArrayList<>(); ++ ++ ResultSet rs = conn.getMetaData().getSchemas(); ++ ++ Set<String> sys = systemSchemas(); ++ ++ while(rs.next()) { ++ String schema = rs.getString(1); ++ ++ // Skip system schemas. ++ if (sys.contains(schema)) ++ continue; ++ ++ schemas.add(schema); ++ } ++ ++ return schemas; ++ } ++ ++ /** ++ * @return If {@code true} use catalogs for table division. ++ */ ++ protected boolean useCatalog() { ++ return false; ++ } ++ ++ /** ++ * @return If {@code true} use schemas for table division. ++ */ ++ protected boolean useSchema() { ++ return true; ++ } ++ ++ /** {@inheritDoc} */ ++ @Override public Collection<DbTable> tables(Connection conn, List<String> schemas, boolean tblsOnly) ++ throws SQLException { + DatabaseMetaData dbMeta = conn.getMetaData(); + + Set<String> sys = systemSchemas(); + + Collection<DbTable> tbls = new ArrayList<>(); + - try (ResultSet tblsRs = dbMeta.getTables(null, null, "%", - tblsOnly ? TABLES_ONLY : TABLES_AND_VIEWS)) { - while (tblsRs.next()) { - String tblCatalog = tblsRs.getString(TBL_CATALOG_IDX); - String tblSchema = tblsRs.getString(TBL_SCHEMA_IDX); - String tblName = tblsRs.getString(TBL_NAME_IDX); ++ if (schemas.size() == 0) ++ schemas.add(null); + - // In case of MySql we should use catalog. - String schema = tblSchema != null ? tblSchema : tblCatalog; ++ for (String toSchema: schemas) { ++ try (ResultSet tblsRs = dbMeta.getTables(useCatalog() ? toSchema : null, useSchema() ? toSchema : null, "%", ++ tblsOnly ? TABLES_ONLY : TABLES_AND_VIEWS)) { ++ while (tblsRs.next()) { ++ String tblCatalog = tblsRs.getString(TBL_CATALOG_IDX); ++ String tblSchema = tblsRs.getString(TBL_SCHEMA_IDX); ++ String tblName = tblsRs.getString(TBL_NAME_IDX); + - // Skip system schemas. - if (sys.contains(schema)) - continue; ++ // In case of MySql we should use catalog. ++ String schema = tblSchema != null ? tblSchema : tblCatalog; + - Set<String> pkCols = new HashSet<>(); ++ // Skip system schemas. ++ if (sys.contains(schema)) ++ continue; + - try (ResultSet pkRs = dbMeta.getPrimaryKeys(tblCatalog, tblSchema, tblName)) { - while (pkRs.next()) - pkCols.add(pkRs.getString(PK_COL_NAME_IDX)); - } ++ Set<String> pkCols = new HashSet<>(); ++ ++ try (ResultSet pkRs = dbMeta.getPrimaryKeys(tblCatalog, tblSchema, tblName)) { ++ while (pkRs.next()) ++ pkCols.add(pkRs.getString(PK_COL_NAME_IDX)); ++ } + - List<DbColumn> cols = new ArrayList<>(); ++ List<DbColumn> cols = new ArrayList<>(); + - try (ResultSet colsRs = dbMeta.getColumns(tblCatalog, tblSchema, tblName, null)) { - while (colsRs.next()) { - String colName = colsRs.getString(COL_NAME_IDX); ++ try (ResultSet colsRs = dbMeta.getColumns(tblCatalog, tblSchema, tblName, null)) { ++ while (colsRs.next()) { ++ String colName = colsRs.getString(COL_NAME_IDX); + - cols.add(new DbColumn( - colName, - colsRs.getInt(COL_DATA_TYPE_IDX), - pkCols.contains(colName), - colsRs.getInt(COL_NULLABLE_IDX) == DatabaseMetaData.columnNullable)); ++ cols.add(new DbColumn( ++ colName, ++ colsRs.getInt(COL_DATA_TYPE_IDX), ++ pkCols.contains(colName), ++ colsRs.getInt(COL_NULLABLE_IDX) == DatabaseMetaData.columnNullable)); ++ } + } - } + - Map<String, Map<String, Boolean>> idxs = new LinkedHashMap<>(); ++ Map<String, Map<String, Boolean>> idxs = new LinkedHashMap<>(); + - try (ResultSet idxRs = dbMeta.getIndexInfo(tblCatalog, tblSchema, tblName, false, true)) { - while (idxRs.next()) { - String idxName = idxRs.getString(IDX_NAME_IDX); ++ try (ResultSet idxRs = dbMeta.getIndexInfo(tblCatalog, tblSchema, tblName, false, true)) { ++ while (idxRs.next()) { ++ String idxName = idxRs.getString(IDX_NAME_IDX); + - String colName = idxRs.getString(IDX_COL_NAME_IDX); ++ String colName = idxRs.getString(IDX_COL_NAME_IDX); + - if (idxName == null || colName == null) - continue; ++ if (idxName == null || colName == null) ++ continue; + - Map<String, Boolean> idx = idxs.get(idxName); ++ Map<String, Boolean> idx = idxs.get(idxName); + - if (idx == null) { - idx = new LinkedHashMap<>(); ++ if (idx == null) { ++ idx = new LinkedHashMap<>(); + - idxs.put(idxName, idx); - } ++ idxs.put(idxName, idx); ++ } + - String askOrDesc = idxRs.getString(IDX_ASC_OR_DESC_IDX); ++ String askOrDesc = idxRs.getString(IDX_ASC_OR_DESC_IDX); + - Boolean desc = askOrDesc != null ? "D".equals(askOrDesc) : null; ++ Boolean desc = askOrDesc != null ? "D".equals(askOrDesc) : null; + - idx.put(colName, desc); ++ idx.put(colName, desc); ++ } + } - } + - tbls.add(table(schema, tblName, cols, idxs)); ++ tbls.add(table(schema, tblName, cols, idxs)); ++ } + } + } + + return tbls; + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/d32674ee/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/dialect/OracleMetadataDialect.java ---------------------------------------------------------------------- diff --cc modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/dialect/OracleMetadataDialect.java index 30dda5d,0000000..c569a29 mode 100644,000000..100644 --- a/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/dialect/OracleMetadataDialect.java +++ b/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/dialect/OracleMetadataDialect.java @@@ -1,284 -1,0 +1,327 @@@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.schema.parser.dialect; + +import org.apache.ignite.schema.parser.*; + +import java.sql.*; +import java.util.*; + +import static java.sql.Types.*; + +/** + * Oracle specific metadata dialect. + */ +public class OracleMetadataDialect extends DatabaseMetadataDialect { + /** SQL to get columns metadata. */ + private static final String SQL_COLUMNS = "SELECT a.owner, a.table_name, a.column_name, a.nullable," + + " a.data_type, a.data_precision, a.data_scale " + - "FROM all_tab_columns a %s" + - " WHERE a.owner = '%s'" + ++ "FROM all_tab_columns a %s " + ++ " %s " + + " ORDER BY a.owner, a.table_name, a.column_id"; + + /** SQL to get list of PRIMARY KEYS columns. */ + private static final String SQL_PRIMARY_KEYS = "SELECT b.column_name" + + " FROM all_constraints a" + + " INNER JOIN all_cons_columns b ON a.owner = b.owner AND a.constraint_name = b.constraint_name" + + " WHERE a.owner = ? and a.table_name = ? AND a.constraint_type = 'P'"; + + /** SQL to get indexes metadata. */ + private static final String SQL_INDEXES = "SELECT i.index_name, u.column_expression, i.column_name, i.descend" + + " FROM all_ind_columns i" + + " LEFT JOIN user_ind_expressions u on u.index_name = i.index_name and i.table_name = u.table_name" + + " WHERE i.index_owner = ? and i.table_name = ?" + + " ORDER BY i.index_name, i.column_position"; + + /** Owner index. */ + private static final int OWNER_IDX = 1; + + /** Table name index. */ + private static final int TBL_NAME_IDX = 2; + + /** Column name index. */ + private static final int COL_NAME_IDX = 3; + + /** Nullable index. */ + private static final int NULLABLE_IDX = 4; + + /** Data type index. */ + private static final int DATA_TYPE_IDX = 5; + + /** Numeric precision index. */ + private static final int DATA_PRECISION_IDX = 6; + + /** Numeric scale index. */ + private static final int DATA_SCALE_IDX = 7; + + /** Index name index. */ + private static final int IDX_NAME_IDX = 1; + + /** Index name index. */ + private static final int IDX_EXPR_IDX = 2; + + /** Index column name index. */ + private static final int IDX_COL_NAME_IDX = 3; + + /** Index column sort order index. */ + private static final int IDX_COL_DESCEND_IDX = 4; + ++ /** {@inheritDoc} */ ++ @Override public Set<String> systemSchemas() { ++ return new HashSet<>(Arrays.asList("ANONYMOUS", "CTXSYS", "DBSNMP", "EXFSYS", "LBACSYS", "MDSYS", "MGMT_VIEW", ++ "OLAPSYS", "OWBSYS", "ORDPLUGINS", "ORDSYS", "OUTLN", "SI_INFORMTN_SCHEMA", "SYS", "SYSMAN", "SYSTEM", ++ "TSMSYS", "WK_TEST", "WKSYS", "WKPROXY", "WMSYS", "XDB", ++ ++ "APEX_040000", "APEX_PUBLIC_USER", "DIP", "FLOWS_30000", "FLOWS_FILES", "MDDATA", "ORACLE_OCM", ++ "SPATIAL_CSW_ADMIN_USR", "SPATIAL_WFS_ADMIN_USR", "XS$NULL", ++ ++ "BI", "HR", "OE", "PM", "IX", "SH")); ++ } ++ ++ /** {@inheritDoc} */ ++ @Override public List<String> schemas(Connection conn) throws SQLException { ++ List<String> schemas = new ArrayList<>(); ++ ++ ResultSet rs = conn.getMetaData().getSchemas(); ++ ++ Set<String> sysSchemas = systemSchemas(); ++ ++ while(rs.next()) { ++ String schema = rs.getString(1); ++ ++ if (!sysSchemas.contains(schema) && !schema.startsWith("FLOWS_")) ++ schemas.add(schema); ++ } ++ ++ return schemas; ++ } ++ + /** + * @param rs Result set with column type metadata from Oracle database. + * @return JDBC type. + * @throws SQLException If failed to decode type. + */ + private int decodeType(ResultSet rs) throws SQLException { + String type = rs.getString(DATA_TYPE_IDX); + + if (type.startsWith("TIMESTAMP")) + return TIMESTAMP; + else { + switch (type) { + case "CHAR": + case "NCHAR": + return CHAR; + + case "VARCHAR2": + case "NVARCHAR2": + return VARCHAR; + + case "LONG": + return LONGVARCHAR; + + case "LONG RAW": + return LONGVARBINARY; + + case "FLOAT": + return FLOAT; + + case "NUMBER": + int precision = rs.getInt(DATA_PRECISION_IDX); + int scale = rs.getInt(DATA_SCALE_IDX); + + if (scale > 0) { + if (scale < 4 && precision < 19) + return FLOAT; + + if (scale > 4 || precision > 19) + return DOUBLE; + + return NUMERIC; + } + else { + if (precision < 1) + return INTEGER; + + if (precision < 2) + return BOOLEAN; + + if (precision < 4) + return TINYINT; + + if (precision < 6) + return SMALLINT; + + if (precision < 11) + return INTEGER; + + if (precision < 20) + return BIGINT; + + return NUMERIC; + } + + case "DATE": + return DATE; + + case "BFILE": + case "BLOB": + return BLOB; + + case "CLOB": + case "NCLOB": + case "XMLTYPE": + return CLOB; + } + } + + return OTHER; + } + + /** + * Retrieve primary key columns. + * + * @param stmt Prepared SQL statement to execute. + * @param owner DB owner. + * @param tbl Table name. + * @return Primary key columns. + * @throws SQLException If failed to retrieve primary key columns. + */ + private Set<String> primaryKeys(PreparedStatement stmt, String owner, String tbl) throws SQLException { + Set<String> pkCols = new HashSet<>(); + + stmt.setString(1, owner); + stmt.setString(2, tbl); + + try (ResultSet pkRs = stmt.executeQuery()) { + while(pkRs.next()) + pkCols.add(pkRs.getString(1)); + } + + return pkCols; + } + + /** + * Retrieve index columns. + * + * @param stmt Prepared SQL statement to execute. + * @param owner DB owner. + * @param tbl Table name. + * @return Index columns. + * @throws SQLException If failed to retrieve indexes columns. + */ + private Map<String, Map<String, Boolean>> indexes(PreparedStatement stmt, String owner, String tbl) + throws SQLException { + Map<String, Map<String, Boolean>> idxs = new LinkedHashMap<>(); + + stmt.setString(1, owner); + stmt.setString(2, tbl); + + try (ResultSet idxsRs = stmt.executeQuery()) { + while (idxsRs.next()) { + String idxName = idxsRs.getString(IDX_NAME_IDX); + + Map<String, Boolean> idx = idxs.get(idxName); + + if (idx == null) { + idx = new LinkedHashMap<>(); + + idxs.put(idxName, idx); + } + + String expr = idxsRs.getString(IDX_EXPR_IDX); + + String col = expr == null ? idxsRs.getString(IDX_COL_NAME_IDX) : expr.replaceAll("\"", ""); + + idx.put(col, "DESC".equals(idxsRs.getString(IDX_COL_DESCEND_IDX))); + } + } + + return idxs; + } + + /** {@inheritDoc} */ - @Override public Collection<DbTable> tables(Connection conn, boolean tblsOnly) throws SQLException { ++ @Override public Collection<DbTable> tables(Connection conn, List<String> schemas, boolean tblsOnly) ++ throws SQLException { + Collection<DbTable> tbls = new ArrayList<>(); + + PreparedStatement pkStmt = conn.prepareStatement(SQL_PRIMARY_KEYS); + + PreparedStatement idxStmt = conn.prepareStatement(SQL_INDEXES); + ++ if (schemas.size() == 0) ++ schemas.add(null); ++ ++ Set<String> sysSchemas = systemSchemas(); ++ + try (Statement colsStmt = conn.createStatement()) { - Collection<DbColumn> cols = new ArrayList<>(); ++ for (String schema: schemas) { ++ if (systemSchemas().contains(schema) || (schema != null && schema.startsWith("FLOWS_"))) ++ continue; + - Set<String> pkCols = Collections.emptySet(); - Map<String, Map<String, Boolean>> idxs = Collections.emptyMap(); ++ Collection<DbColumn> cols = new ArrayList<>(); + - String user = conn.getMetaData().getUserName().toUpperCase(); ++ Set<String> pkCols = Collections.emptySet(); ++ Map<String, Map<String, Boolean>> idxs = Collections.emptyMap(); + - String sql = String.format(SQL_COLUMNS, - tblsOnly ? "INNER JOIN all_tables b on a.table_name = b.table_name and a.owner = b.owner" : "", user); ++ String sql = String.format(SQL_COLUMNS, ++ tblsOnly ? "INNER JOIN all_tables b on a.table_name = b.table_name and a.owner = b.owner" : "", ++ schema != null ? String.format(" WHERE a.owner = '%s' ", schema) : ""); + - try (ResultSet colsRs = colsStmt.executeQuery(sql)) { - String prevSchema = ""; - String prevTbl = ""; ++ try (ResultSet colsRs = colsStmt.executeQuery(sql)) { ++ String prevSchema = ""; ++ String prevTbl = ""; + - boolean first = true; ++ boolean first = true; + - while (colsRs.next()) { - String owner = colsRs.getString(OWNER_IDX); - String tbl = colsRs.getString(TBL_NAME_IDX); ++ while (colsRs.next()) { ++ String owner = colsRs.getString(OWNER_IDX); ++ String tbl = colsRs.getString(TBL_NAME_IDX); + - boolean changed = !owner.equals(prevSchema) || !tbl.equals(prevTbl); ++ if (sysSchemas.contains(owner) || (schema != null && schema.startsWith("FLOWS_"))) ++ continue; + - if (changed) { - if (first) - first = false; - else - tbls.add(table(prevSchema, prevTbl, cols, idxs)); ++ boolean changed = !owner.equals(prevSchema) || !tbl.equals(prevTbl); + - prevSchema = owner; - prevTbl = tbl; - cols = new ArrayList<>(); - pkCols = primaryKeys(pkStmt, owner, tbl); - idxs = indexes(idxStmt, owner, tbl); - } ++ if (changed) { ++ if (first) ++ first = false; ++ else ++ tbls.add(table(prevSchema, prevTbl, cols, idxs)); + - String colName = colsRs.getString(COL_NAME_IDX); ++ prevSchema = owner; ++ prevTbl = tbl; ++ cols = new ArrayList<>(); ++ pkCols = primaryKeys(pkStmt, owner, tbl); ++ idxs = indexes(idxStmt, owner, tbl); ++ } + - cols.add(new DbColumn(colName, decodeType(colsRs), pkCols.contains(colName), - !"N".equals(colsRs.getString(NULLABLE_IDX)))); - } ++ String colName = colsRs.getString(COL_NAME_IDX); + - if (!cols.isEmpty()) - tbls.add(table(prevSchema, prevTbl, cols, idxs)); ++ cols.add(new DbColumn(colName, decodeType(colsRs), pkCols.contains(colName), ++ !"N".equals(colsRs.getString(NULLABLE_IDX)))); ++ } ++ ++ if (!cols.isEmpty()) ++ tbls.add(table(prevSchema, prevTbl, cols, idxs)); ++ } + } + } + + return tbls; + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/d32674ee/modules/schema-import/src/main/java/org/apache/ignite/schema/parser/DatabaseMetadataParser.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/d32674ee/modules/schema-import/src/main/java/org/apache/ignite/schema/ui/SchemaImportApp.java ---------------------------------------------------------------------- diff --cc modules/schema-import/src/main/java/org/apache/ignite/schema/ui/SchemaImportApp.java index 67890fb,e524065..9bf06a6 --- a/modules/schema-import/src/main/java/org/apache/ignite/schema/ui/SchemaImportApp.java +++ b/modules/schema-import/src/main/java/org/apache/ignite/schema/ui/SchemaImportApp.java @@@ -342,8 -375,8 +369,8 @@@ public class SchemaImportApp extends Ap @Override protected Void call() throws Exception { long started = System.currentTimeMillis(); - try (Connection conn = connect()) { + try (Connection conn = DbMetadataReader.getInstance().connect(jdbcDrvJarPath, jdbcDrvCls, jdbcUrl, jdbcInfo)) { - pojos = DatabaseMetadataParser.parse(conn, tblsOnly); + pojos = DatabaseMetadataParser.parse(conn, selSchemas, tblsOnly); } perceptualDelay(started);
