http://git-wip-us.apache.org/repos/asf/ignite/blob/25ef0f6c/modules/schema-import-db/pom.xml ---------------------------------------------------------------------- diff --cc modules/schema-import-db/pom.xml index 6d0dc2c,0000000..3b9d7e6 mode 100644,000000..100644 --- a/modules/schema-import-db/pom.xml +++ b/modules/schema-import-db/pom.xml @@@ -1,39 -1,0 +1,46 @@@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + ~ /* + ~ * 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. + ~ */ + --> + +<!-- + POM file. +--> +<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.ignite</groupId> + <artifactId>ignite-parent</artifactId> + <version>1</version> + <relativePath>../../parent</relativePath> + </parent> + + <artifactId>ignite-schema-import-db</artifactId> + <version>1.5.0-SNAPSHOT</version> + ++ <dependencies> ++ <dependency> ++ <groupId>org.apache.ignite</groupId> ++ <artifactId>ignite-core</artifactId> ++ <version>${project.version}</version> ++ </dependency> ++ </dependencies> +</project>
http://git-wip-us.apache.org/repos/asf/ignite/blob/25ef0f6c/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/DbTable.java ---------------------------------------------------------------------- diff --cc modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/DbTable.java index 6ec9d1f,0000000..cc321c1 mode 100644,000000..100644 --- a/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/DbTable.java +++ b/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/DbTable.java @@@ -1,109 -1,0 +1,84 @@@ +/* + * + * * 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; + ++import org.apache.ignite.cache.QueryIndex; ++ +import java.util.Collection; - import java.util.Map; - import java.util.Set; + +/** + * Database table. + */ +public class DbTable { + /** Schema name. */ + private final String schema; + + /** Table name. */ + private final String tbl; + + /** Columns. */ + private final Collection<DbColumn> cols; + - /** Columns in ascending order. */ - private final Set<String> ascCols; - - /** Columns in descending order. */ - private final Set<String> descCols; - + /** Indexes. */ - private final Map<String, Map<String, Boolean>> idxs; ++ private final Collection<QueryIndex> idxs; + + /** + * Default columns. + * + * @param schema Schema name. + * @param tbl Table name. + * @param cols Columns. - * @param ascCols Columns in ascending order. - * @param descCols Columns in descending order. + * @param idxs Indexes; + */ - public DbTable(String schema, String tbl, Collection<DbColumn> cols, Set<String> ascCols, Set<String> descCols, - Map<String, Map<String, Boolean>> idxs) { ++ public DbTable(String schema, String tbl, Collection<DbColumn> cols, Collection<QueryIndex> idxs) { + this.schema = schema; + this.tbl = tbl; + this.cols = cols; - this.ascCols = ascCols; - this.descCols = descCols; + this.idxs = idxs; + } + + /** + * @return Schema name. + */ + public String schema() { + return schema; + } + + /** + * @return Table name. + */ + public String table() { + return tbl; + } + + /** + * @return Columns. + */ + public Collection<DbColumn> columns() { + return cols; + } + + /** - * @return Fields in ascending order - */ - public Set<String> ascendingColumns() { - return ascCols; - } - - /** - * @return Fields in descending order - */ - public Set<String> descendingColumns() { - return descCols; - } - - /** + * @return Indexes. + */ - public Map<String, Map<String, Boolean>> indexes() { ++ public Collection<QueryIndex> indexes() { + return idxs; + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/25ef0f6c/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 db8adfd,0000000..fad5b0e 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,97 -1,0 +1,77 @@@ +/* + * + * * 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.sql.Connection; +import java.sql.SQLException; +import java.util.Collection; +import java.util.Collections; - import java.util.HashSet; +import java.util.List; - import java.util.Map; +import java.util.Set; ++ ++import org.apache.ignite.cache.QueryIndex; +import org.apache.ignite.schema.parser.DbColumn; +import org.apache.ignite.schema.parser.DbTable; + +/** + * 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 Collection<String> schemas(Connection conn) throws SQLException; + + /** + * Gets tables from database. + * + * @param conn Database connection. - * @param schemas Collention of schema names to load. ++ * @param schemas Collection 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, 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); ++ protected DbTable table(String schema, String tbl, Collection<DbColumn> cols, Collection<QueryIndex>idxs) { ++ return new DbTable(schema, tbl, cols, idxs); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/25ef0f6c/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 f315481,0000000..c3ffa32 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,193 -1,0 +1,199 @@@ +/* + * + * * 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.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; ++ ++import org.apache.ignite.cache.QueryIndex; ++import org.apache.ignite.cache.QueryIndexType; +import org.apache.ignite.schema.parser.DbColumn; +import org.apache.ignite.schema.parser.DbTable; + +/** + * 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<String> schemas(Connection conn) throws SQLException { + Collection<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<>(); + - if (schemas.size() == 0) ++ if (schemas.isEmpty()) + schemas.add(null); + + 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); + + // In case of MySql we should use catalog. + String schema = tblSchema != null ? tblSchema : tblCatalog; + + // Skip system schemas. + if (sys.contains(schema)) + continue; + + 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<>(); + + 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)); + } + } + - Map<String, Map<String, Boolean>> idxs = new LinkedHashMap<>(); ++ Map<String, QueryIndex> idxs = new LinkedHashMap<>(); + + 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); + + if (idxName == null || colName == null) + continue; + - Map<String, Boolean> idx = idxs.get(idxName); ++ QueryIndex idx = idxs.get(idxName); + + if (idx == null) { - idx = new LinkedHashMap<>(); ++ idx = new QueryIndex(); ++ idx.setName(idxName); ++ idx.setIndexType(QueryIndexType.SORTED); ++ idx.setFields(new LinkedHashMap<String, Boolean>()); + + idxs.put(idxName, idx); + } + + String askOrDesc = idxRs.getString(IDX_ASC_OR_DESC_IDX); + - Boolean desc = askOrDesc != null ? "D".equals(askOrDesc) : null; ++ Boolean asc = askOrDesc == null || "A".equals(askOrDesc); + - idx.put(colName, desc); ++ idx.getFields().put(colName, asc); + } + } + - tbls.add(table(schema, tblName, cols, idxs)); ++ tbls.add(table(schema, tblName, cols, idxs.values())); + } + } + } + + return tbls; + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/25ef0f6c/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 3f10672,0000000..9456b53 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,360 -1,0 +1,366 @@@ +/* + * + * * 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.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; ++ ++import org.apache.ignite.cache.QueryIndex; ++import org.apache.ignite.cache.QueryIndexType; +import org.apache.ignite.schema.parser.DbColumn; +import org.apache.ignite.schema.parser.DbTable; + +import static java.sql.Types.BIGINT; +import static java.sql.Types.BLOB; +import static java.sql.Types.BOOLEAN; +import static java.sql.Types.CHAR; +import static java.sql.Types.CLOB; +import static java.sql.Types.DATE; +import static java.sql.Types.DOUBLE; +import static java.sql.Types.FLOAT; +import static java.sql.Types.INTEGER; +import static java.sql.Types.LONGVARBINARY; +import static java.sql.Types.LONGVARCHAR; +import static java.sql.Types.NUMERIC; +import static java.sql.Types.OTHER; +import static java.sql.Types.SMALLINT; +import static java.sql.Types.SQLXML; +import static java.sql.Types.TIMESTAMP; +import static java.sql.Types.TINYINT; +import static java.sql.Types.VARCHAR; + +/** + * 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 " + + " %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 Collection<String> schemas(Connection conn) throws SQLException { + Collection<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": + return CLOB; + + case "XMLTYPE": + return SQLXML; + } + } + + 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. ++ * @return Indexes. + * @throws SQLException If failed to retrieve indexes columns. + */ - private Map<String, Map<String, Boolean>> indexes(PreparedStatement stmt, String owner, String tbl) ++ private Collection<QueryIndex> indexes(PreparedStatement stmt, String owner, String tbl) + throws SQLException { - Map<String, Map<String, Boolean>> idxs = new LinkedHashMap<>(); ++ Map<String, QueryIndex> 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); ++ QueryIndex idx = idxs.get(idxName); + + if (idx == null) { - idx = new LinkedHashMap<>(); ++ idx = new QueryIndex(); ++ idx.setName(idxName); ++ idx.setIndexType(QueryIndexType.SORTED); ++ idx.setFields(new LinkedHashMap<String, Boolean>()); + + 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))); ++ idx.getFields().put(col, !"DESC".equals(idxsRs.getString(IDX_COL_DESCEND_IDX))); + } + } + - return idxs; ++ return idxs.values(); + } + + /** {@inheritDoc} */ + @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) ++ if (schemas.isEmpty()) + schemas.add(null); + + Set<String> sysSchemas = systemSchemas(); + + try (Statement colsStmt = conn.createStatement()) { + for (String schema: schemas) { + if (systemSchemas().contains(schema) || (schema != null && schema.startsWith("FLOWS_"))) + continue; + + Collection<DbColumn> cols = new ArrayList<>(); + + Set<String> pkCols = Collections.emptySet(); - Map<String, Map<String, Boolean>> idxs = Collections.emptyMap(); ++ Collection<QueryIndex> idxs = Collections.emptyList(); + + 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 = ""; + + boolean first = true; + + while (colsRs.next()) { + String owner = colsRs.getString(OWNER_IDX); + String tbl = colsRs.getString(TBL_NAME_IDX); + + if (sysSchemas.contains(owner) || (schema != null && schema.startsWith("FLOWS_"))) + continue; + + boolean changed = !owner.equals(prevSchema) || !tbl.equals(prevTbl); + + if (changed) { + if (first) + first = false; + else + tbls.add(table(prevSchema, prevTbl, cols, idxs)); + + prevSchema = owner; + prevTbl = tbl; + cols = new ArrayList<>(); + pkCols = primaryKeys(pkStmt, owner, tbl); + idxs = indexes(idxStmt, owner, tbl); + } + + String colName = colsRs.getString(COL_NAME_IDX); + + 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/25ef0f6c/modules/schema-import/src/main/java/org/apache/ignite/schema/parser/DatabaseMetadataParser.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/25ef0f6c/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 cbcddc2,495c316..124b623 --- 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 @@@ -808,7 -944,8 +808,8 @@@ public class SchemaImportApp extends Ap schemaPnl.wrap(); - schemaPnl.add(button("Load schemas", "Load schemas for specified database", new EventHandler<ActionEvent>() { + schemaPnl.add(Controls.button("Load schemas", "Load schemas for specified database", new EventHandler<ActionEvent>() { + /** {@inheritDoc} */ @Override public void handle(ActionEvent evt) { loadSchemas(); } http://git-wip-us.apache.org/repos/asf/ignite/blob/25ef0f6c/parent/pom.xml ---------------------------------------------------------------------- diff --cc parent/pom.xml index 08763b5,2d3ff5f..9550f9f --- a/parent/pom.xml +++ b/parent/pom.xml @@@ -709,7 -714,10 +714,11 @@@ <exclude>dev-tools/.gradle/**/*</exclude> <exclude>dev-tools/gradle/wrapper/**/*</exclude> <exclude>dev-tools/gradlew</exclude> + <exclude>src/test/portables/repo/org/apache/ignite/portable/test2/1.1/test2-1.1.pom</exclude> + <exclude>src/test/portables/repo/org/apache/ignite/portable/test2/maven-metadata-local.xml</exclude> + <exclude>src/test/portables/repo/org/apache/ignite/portable/test1/1.1/test1-1.1.pom</exclude> + <exclude>src/test/portables/repo/org/apache/ignite/portable/test1/maven-metadata-local.xml</exclude> + <exclude>src/main/js/package.json</exclude> <!--shmem--> <exclude>ipc/shmem/**/Makefile.in</exclude><!--auto generated files--> <exclude>ipc/shmem/**/Makefile</exclude><!--auto generated files--> http://git-wip-us.apache.org/repos/asf/ignite/blob/25ef0f6c/pom.xml ----------------------------------------------------------------------