ignite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From akuznet...@apache.org
Subject [2/2] ignite git commit: IGNITE-3144 Refactor Schema Import Utility. Split for two modules: schema-import and schema-import-db.
Date Tue, 17 May 2016 07:22:41 GMT
IGNITE-3144 Refactor Schema Import Utility. Split for two modules: schema-import and schema-import-db.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/fa197d2f
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/fa197d2f
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/fa197d2f

Branch: refs/heads/ignite-1.6
Commit: fa197d2f71430cb5e8765335eff6a9c2d4f6ec10
Parents: c9f9d24
Author: Alexey Kuznetsov <akuznetsov@apache.org>
Authored: Tue May 17 14:22:23 2016 +0700
Committer: Alexey Kuznetsov <akuznetsov@apache.org>
Committed: Tue May 17 14:22:23 2016 +0700

----------------------------------------------------------------------
 assembly/dependencies-schema-import.xml         |   1 +
 assembly/release-schema-import.xml              |   2 +-
 modules/schema-import-db/README.txt             |   4 +
 modules/schema-import-db/pom.xml                |  44 ++
 .../apache/ignite/schema/parser/DbColumn.java   |  76 +++
 .../ignite/schema/parser/DbMetadataReader.java  | 147 ++++++
 .../apache/ignite/schema/parser/DbTable.java    |  82 +++
 .../parser/dialect/DB2MetadataDialect.java      |  33 ++
 .../parser/dialect/DatabaseMetadataDialect.java |  75 +++
 .../parser/dialect/JdbcMetadataDialect.java     | 197 +++++++
 .../parser/dialect/MySQLMetadataDialect.java    |  62 +++
 .../parser/dialect/OracleMetadataDialect.java   | 364 +++++++++++++
 modules/schema-import/pom.xml                   |   6 +
 .../schema/parser/DatabaseMetadataParser.java   |  44 +-
 .../apache/ignite/schema/parser/DbColumn.java   |  76 ---
 .../apache/ignite/schema/parser/DbTable.java    |  82 ---
 .../parser/dialect/DB2MetadataDialect.java      |  33 --
 .../parser/dialect/DatabaseMetadataDialect.java |  75 ---
 .../parser/dialect/JdbcMetadataDialect.java     | 197 -------
 .../parser/dialect/MySQLMetadataDialect.java    |  61 ---
 .../parser/dialect/OracleMetadataDialect.java   | 364 -------------
 .../ignite/schema/ui/SchemaImportApp.java       | 526 ++++++++-----------
 pom.xml                                         |   2 +
 23 files changed, 1328 insertions(+), 1225 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/fa197d2f/assembly/dependencies-schema-import.xml
----------------------------------------------------------------------
diff --git a/assembly/dependencies-schema-import.xml b/assembly/dependencies-schema-import.xml
index 53c32c2..d7aa3ae 100644
--- a/assembly/dependencies-schema-import.xml
+++ b/assembly/dependencies-schema-import.xml
@@ -33,6 +33,7 @@
         <moduleSet>
             <includes>
                 <include>org.apache.ignite:ignite-schema-import</include>
+                <include>org.apache.ignite:ignite-schema-import-db</include>
             </includes>
             <sources>
                 <includeModuleDirectory>false</includeModuleDirectory>

http://git-wip-us.apache.org/repos/asf/ignite/blob/fa197d2f/assembly/release-schema-import.xml
----------------------------------------------------------------------
diff --git a/assembly/release-schema-import.xml b/assembly/release-schema-import.xml
index b746c83..38457b9 100644
--- a/assembly/release-schema-import.xml
+++ b/assembly/release-schema-import.xml
@@ -21,7 +21,7 @@
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2
           http://maven.apache.org/xsd/assembly-1.1.2.xsd">
-    <id>scala</id>
+    <id>release-schema-import</id>
 
     <includeBaseDirectory>false</includeBaseDirectory>
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/fa197d2f/modules/schema-import-db/README.txt
----------------------------------------------------------------------
diff --git a/modules/schema-import-db/README.txt b/modules/schema-import-db/README.txt
new file mode 100644
index 0000000..556e1c6
--- /dev/null
+++ b/modules/schema-import-db/README.txt
@@ -0,0 +1,4 @@
+Apache Ignite Schema Import DB Module
+------------------------------------------
+
+Utility classes to extract database metadata.

http://git-wip-us.apache.org/repos/asf/ignite/blob/fa197d2f/modules/schema-import-db/pom.xml
----------------------------------------------------------------------
diff --git a/modules/schema-import-db/pom.xml b/modules/schema-import-db/pom.xml
new file mode 100644
index 0000000..337f39a
--- /dev/null
+++ b/modules/schema-import-db/pom.xml
@@ -0,0 +1,44 @@
+<?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.6.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/fa197d2f/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/DbColumn.java
----------------------------------------------------------------------
diff --git a/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/DbColumn.java b/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/DbColumn.java
new file mode 100644
index 0000000..8b0c813
--- /dev/null
+++ b/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/DbColumn.java
@@ -0,0 +1,76 @@
+/*
+ * 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;
+
+/**
+ * Database table column.
+ */
+public class DbColumn {
+    /** Column name. */
+    private final String name;
+
+    /** Column JDBC type. */
+    private final int type;
+
+    /** Is this column belongs to primary key. */
+    private final boolean key;
+
+    /** Is {@code NULL} allowed for column in database. */
+    private final boolean nullable;
+
+    /**
+     * @param name Column name.
+     * @param type Column JDBC type.
+     * @param key {@code true} if this column belongs to primary key.
+     * @param nullable {@code true} if {@code NULL } allowed for column in database.
+     */
+    public DbColumn(String name, int type, boolean key, boolean nullable) {
+        this.name = name;
+        this.type = type;
+        this.key = key;
+        this.nullable = nullable;
+    }
+
+    /**
+     * @return Column name.
+     */
+    public String name() {
+        return name;
+    }
+
+    /**
+     * @return Column JDBC type.
+     */
+    public int type() {
+        return type;
+    }
+
+    /**
+     * @return {@code true} if this column belongs to primary key.
+     */
+    public boolean key() {
+        return key;
+    }
+
+    /**
+     * @return nullable {@code true} if {@code NULL } allowed for column in database.
+     */
+    public boolean nullable() {
+        return nullable;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/fa197d2f/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/DbMetadataReader.java
----------------------------------------------------------------------
diff --git a/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/DbMetadataReader.java b/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/DbMetadataReader.java
new file mode 100644
index 0000000..5b45f33
--- /dev/null
+++ b/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/DbMetadataReader.java
@@ -0,0 +1,147 @@
+/*
+ * 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.schema.parser.dialect.*;
+
+import java.io.*;
+import java.net.*;
+import java.sql.*;
+import java.util.*;
+import java.util.logging.*;
+
+/**
+ * Singleton to extract database metadata.
+ */
+public class DbMetadataReader {
+    /** Logger. */
+    private static final Logger log = Logger.getLogger(DbMetadataReader.class.getName());
+
+    /** */
+    private static final DbMetadataReader INSTANCE = new DbMetadataReader();
+
+    /** */
+    private final Map<String, Driver> drivers = new HashMap<>();
+
+    /**
+     * Default constructor.
+     */
+    private DbMetadataReader() {
+        // No-op.
+    }
+
+    /**
+     * @return Instance.
+     */
+    public static DbMetadataReader getInstance() {
+        return INSTANCE;
+    }
+
+    /**
+     * Get specified dialect object for selected database.
+     *
+     * @param conn Connection to database.
+     * @return Specific dialect object.
+     */
+    private DatabaseMetadataDialect dialect(Connection conn) {
+        try {
+            String dbProductName = conn.getMetaData().getDatabaseProductName();
+
+            if ("Oracle".equals(dbProductName))
+                return new OracleMetadataDialect();
+            else if (dbProductName.startsWith("DB2/"))
+                return new DB2MetadataDialect();
+            else if (dbProductName.equals("MySQL"))
+                return new MySQLMetadataDialect();
+            else
+                return new JdbcMetadataDialect();
+        }
+        catch (SQLException e) {
+            log.log(Level.SEVERE, "Failed to resolve dialect (JdbcMetaDataDialect will be used.", e);
+
+            return new JdbcMetadataDialect();
+        }
+    }
+
+    /**
+     * Get list of schemas from database.
+     *
+     * @param conn Connection to database.
+     * @return List of schema names.
+     * @throws SQLException If schemas loading failed.
+     */
+    public Collection<String> schemas(Connection conn) throws SQLException  {
+        return dialect(conn).schemas(conn);
+    }
+
+    /**
+     * Extract DB metadata.
+     *
+     * @param conn Connection.
+     * @param schemas List of database schemas to process. In case of empty list all schemas will be processed.
+     * @param tblsOnly Tables only flag.
+     */
+    public Collection<DbTable> metadata(Connection conn, List<String> schemas, boolean tblsOnly) throws SQLException {
+        return dialect(conn).tables(conn, schemas, tblsOnly);
+    }
+
+    /**
+     * Connect to database.
+     *
+     * @param jdbcDrvJarPath Path to JDBC driver.
+     * @param jdbcDrvCls JDBC class name.
+     * @param jdbcUrl JDBC connection URL.
+     * @param jdbcInfo Connection properties.
+     * @return Connection to database.
+     * @throws SQLException if connection failed.
+     */
+    public Connection connect(String jdbcDrvJarPath, String jdbcDrvCls, String jdbcUrl, Properties jdbcInfo)
+        throws SQLException {
+        Driver drv = drivers.get(jdbcDrvCls);
+
+        if (drv == null) {
+            if (jdbcDrvJarPath.isEmpty())
+                throw new IllegalStateException("Driver jar file name is not specified.");
+
+            File drvJar = new File(jdbcDrvJarPath);
+
+            if (!drvJar.exists())
+                throw new IllegalStateException("Driver jar file is not found.");
+
+            try {
+                URL u = new URL("jar:" + drvJar.toURI() + "!/");
+
+                URLClassLoader ucl = URLClassLoader.newInstance(new URL[] {u});
+
+                drv = (Driver)Class.forName(jdbcDrvCls, true, ucl).newInstance();
+
+                drivers.put(jdbcDrvCls, drv);
+            }
+            catch (Exception e) {
+                throw new IllegalStateException(e);
+            }
+        }
+
+        Connection conn = drv.connect(jdbcUrl, jdbcInfo);
+
+        if (conn == null)
+            throw new IllegalStateException("Connection was not established (JDBC driver returned null value).");
+
+        return conn;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/fa197d2f/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/DbTable.java
----------------------------------------------------------------------
diff --git 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
new file mode 100644
index 0000000..39f6f7b
--- /dev/null
+++ b/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/DbTable.java
@@ -0,0 +1,82 @@
+/*
+ * 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;
+
+/**
+ * Database table.
+ */
+public class DbTable {
+    /** Schema name. */
+    private final String schema;
+
+    /** Table name. */
+    private final String tbl;
+
+    /** Columns. */
+    private final Collection<DbColumn> cols;
+
+    /** Indexes. */
+    private final Collection<QueryIndex> idxs;
+
+    /**
+     * Default columns.
+     *
+     * @param schema Schema name.
+     * @param tbl Table name.
+     * @param cols Columns.
+     * @param idxs Indexes;
+     */
+    public DbTable(String schema, String tbl, Collection<DbColumn> cols, Collection<QueryIndex> idxs) {
+        this.schema = schema;
+        this.tbl = tbl;
+        this.cols = cols;
+        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 Indexes.
+     */
+    public Collection<QueryIndex> indexes() {
+        return idxs;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/fa197d2f/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/dialect/DB2MetadataDialect.java
----------------------------------------------------------------------
diff --git 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
new file mode 100644
index 0000000..b191ec3
--- /dev/null
+++ b/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/dialect/DB2MetadataDialect.java
@@ -0,0 +1,33 @@
+/*
+ * 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.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * DB2 specific metadata dialect.
+ */
+public class DB2MetadataDialect extends JdbcMetadataDialect {
+    /** {@inheritDoc} */
+    @Override public Set<String> systemSchemas() {
+        return new HashSet<>(Arrays.asList("SYSIBM", "SYSCAT", "SYSSTAT", "SYSTOOLS", "SYSFUN", "SYSIBMADM",
+            "SYSIBMINTERNAL", "SYSIBMTS", "SYSPROC", "SYSPUBLIC"));
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/fa197d2f/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/dialect/DatabaseMetadataDialect.java
----------------------------------------------------------------------
diff --git 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
new file mode 100644
index 0000000..f34eee4
--- /dev/null
+++ b/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/dialect/DatabaseMetadataDialect.java
@@ -0,0 +1,75 @@
+/*
+ * 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.List;
+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 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, Collection<QueryIndex>idxs) {
+        return new DbTable(schema, tbl, cols, idxs);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/fa197d2f/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/dialect/JdbcMetadataDialect.java
----------------------------------------------------------------------
diff --git 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
new file mode 100644
index 0000000..0b54b25
--- /dev/null
+++ b/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/dialect/JdbcMetadataDialect.java
@@ -0,0 +1,197 @@
+/*
+ * 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.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, 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;
+
+                            QueryIndex idx = idxs.get(idxName);
+
+                            if (idx == null) {
+                                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 asc = askOrDesc == null || "A".equals(askOrDesc);
+
+                            idx.getFields().put(colName, asc);
+                        }
+                    }
+
+                    tbls.add(table(schema, tblName, cols, idxs.values()));
+                }
+            }
+        }
+
+        return tbls;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/fa197d2f/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/dialect/MySQLMetadataDialect.java
----------------------------------------------------------------------
diff --git a/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/dialect/MySQLMetadataDialect.java b/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/dialect/MySQLMetadataDialect.java
new file mode 100644
index 0000000..3332046
--- /dev/null
+++ b/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/dialect/MySQLMetadataDialect.java
@@ -0,0 +1,62 @@
+/*
+ * 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.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * MySQL specific metadata dialect.
+ */
+public class MySQLMetadataDialect extends JdbcMetadataDialect {
+    /** {@inheritDoc} */
+    @Override public Collection<String> schemas(Connection conn) throws SQLException {
+        List<String> schemas = new ArrayList<>();
+
+        ResultSet rs = conn.getMetaData().getCatalogs();
+
+        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;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected boolean useCatalog() {
+        return true;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected boolean useSchema() {
+        return false;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/fa197d2f/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/dialect/OracleMetadataDialect.java
----------------------------------------------------------------------
diff --git 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
new file mode 100644
index 0000000..ed5cdc5
--- /dev/null
+++ b/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/dialect/OracleMetadataDialect.java
@@ -0,0 +1,364 @@
+/*
+ * 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 Indexes.
+     * @throws SQLException If failed to retrieve indexes columns.
+     */
+    private Collection<QueryIndex> indexes(PreparedStatement stmt, String owner, String tbl)
+        throws SQLException {
+        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);
+
+                QueryIndex idx = idxs.get(idxName);
+
+                if (idx == null) {
+                    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.getFields().put(col, !"DESC".equals(idxsRs.getString(IDX_COL_DESCEND_IDX)));
+            }
+        }
+
+        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.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();
+                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/fa197d2f/modules/schema-import/pom.xml
----------------------------------------------------------------------
diff --git a/modules/schema-import/pom.xml b/modules/schema-import/pom.xml
index 7156e32..7e83a84 100644
--- a/modules/schema-import/pom.xml
+++ b/modules/schema-import/pom.xml
@@ -42,6 +42,12 @@
         </dependency>
 
         <dependency>
+            <groupId>org.apache.ignite</groupId>
+            <artifactId>ignite-schema-import-db</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
             <groupId>com.h2database</groupId>
             <artifactId>h2</artifactId>
             <version>${h2.version}</version>

http://git-wip-us.apache.org/repos/asf/ignite/blob/fa197d2f/modules/schema-import/src/main/java/org/apache/ignite/schema/parser/DatabaseMetadataParser.java
----------------------------------------------------------------------
diff --git a/modules/schema-import/src/main/java/org/apache/ignite/schema/parser/DatabaseMetadataParser.java b/modules/schema-import/src/main/java/org/apache/ignite/schema/parser/DatabaseMetadataParser.java
index c4490ef..b86346f 100644
--- a/modules/schema-import/src/main/java/org/apache/ignite/schema/parser/DatabaseMetadataParser.java
+++ b/modules/schema-import/src/main/java/org/apache/ignite/schema/parser/DatabaseMetadataParser.java
@@ -26,52 +26,16 @@ import java.util.Comparator;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.logging.Level;
-import java.util.logging.Logger;
 import javafx.collections.FXCollections;
 import javafx.collections.ObservableList;
 import org.apache.ignite.cache.QueryIndex;
 import org.apache.ignite.schema.model.PojoDescriptor;
 import org.apache.ignite.schema.model.SchemaDescriptor;
-import org.apache.ignite.schema.parser.dialect.DB2MetadataDialect;
-import org.apache.ignite.schema.parser.dialect.DatabaseMetadataDialect;
-import org.apache.ignite.schema.parser.dialect.JdbcMetadataDialect;
-import org.apache.ignite.schema.parser.dialect.MySQLMetadataDialect;
-import org.apache.ignite.schema.parser.dialect.OracleMetadataDialect;
 
 /**
  * Database metadata parser.
  */
 public class DatabaseMetadataParser {
-    /** Logger. */
-    private static final Logger log = Logger.getLogger(DatabaseMetadataParser.class.getName());
-
-    /**
-     * Get specified dialect object for selected database.
-     *
-     * @param conn Connection to database.
-     * @return Specific dialect object.
-     */
-    private static DatabaseMetadataDialect dialect(Connection conn) {
-        try {
-            String dbProductName = conn.getMetaData().getDatabaseProductName();
-
-            if ("Oracle".equals(dbProductName))
-                return new OracleMetadataDialect();
-            else if (dbProductName.startsWith("DB2/"))
-                return new DB2MetadataDialect();
-            else if ("MySQL".equals(dbProductName))
-                return new MySQLMetadataDialect();
-            else
-                return new JdbcMetadataDialect();
-        }
-        catch (SQLException e) {
-            log.log(Level.SEVERE, "Failed to resolve dialect (JdbcMetaDataDialect will be used.", e);
-
-            return new JdbcMetadataDialect();
-        }
-    }
-
     /**
      * Get list of schemas from database.
      *
@@ -80,7 +44,7 @@ public class DatabaseMetadataParser {
      * @throws SQLException If schemas loading failed.
      */
     public static ObservableList<SchemaDescriptor> schemas(Connection conn) throws SQLException  {
-        List<String> dbSchemas = dialect(conn).schemas(conn);
+        Collection<String> dbSchemas = DbMetadataReader.getInstance().schemas(conn);
 
         List<SchemaDescriptor> uiSchemas = new ArrayList<>(dbSchemas.size());
 
@@ -94,20 +58,18 @@ public class DatabaseMetadataParser {
      * Parse database metadata.
      *
      * @param conn Connection to database.
-     * @param schemas Collection of schema names to load.
+     * @param schemas Collection of schema names to process.
      * @param tblsOnly If {@code true} then process tables only else process tables and views.
      * @return Collection of POJO descriptors.
      * @throws SQLException If parsing failed.
      */
     public static ObservableList<PojoDescriptor> parse(Connection conn, List<String> schemas, boolean tblsOnly)
         throws SQLException {
-        DatabaseMetadataDialect dialect = dialect(conn);
-
         Map<String, PojoDescriptor> parents = new HashMap<>();
 
         Map<String, Collection<PojoDescriptor>> childrens = new HashMap<>();
 
-        for (DbTable tbl : dialect.tables(conn, schemas, tblsOnly)) {
+        for (DbTable tbl : DbMetadataReader.getInstance().metadata(conn, schemas, tblsOnly)) {
             String schema = tbl.schema();
 
             PojoDescriptor parent = parents.get(schema);

http://git-wip-us.apache.org/repos/asf/ignite/blob/fa197d2f/modules/schema-import/src/main/java/org/apache/ignite/schema/parser/DbColumn.java
----------------------------------------------------------------------
diff --git a/modules/schema-import/src/main/java/org/apache/ignite/schema/parser/DbColumn.java b/modules/schema-import/src/main/java/org/apache/ignite/schema/parser/DbColumn.java
deleted file mode 100644
index 9a548f4..0000000
--- a/modules/schema-import/src/main/java/org/apache/ignite/schema/parser/DbColumn.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * 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;
-
-/**
- * Database table column.
- */
-public class DbColumn {
-    /** Column name. */
-    private final String name;
-
-    /** Column JDBC type. */
-    private final int type;
-
-    /** Is this column belongs to primary key. */
-    private final boolean key;
-
-    /** Is {@code NULL} allowed for column in database. */
-    private final boolean nullable;
-
-    /**
-     * @param name Column name.
-     * @param type Column JDBC type.
-     * @param key {@code true} if this column belongs to primary key.
-     * @param nullable {@code true} if {@code NULL } allowed for column in database.
-     */
-    public DbColumn(String name, int type, boolean key, boolean nullable) {
-        this.name = name;
-        this.type = type;
-        this.key = key;
-        this.nullable = nullable;
-    }
-
-    /**
-     * @return Column name.
-     */
-    public String name() {
-        return name;
-    }
-
-    /**
-     * @return Column JDBC type.
-     */
-    public int type() {
-        return type;
-    }
-
-    /**
-     * @return {@code true} if this column belongs to primary key.
-     */
-    public boolean key() {
-        return key;
-    }
-
-    /**
-     * @return nullable {@code true} if {@code NULL } allowed for column in database.
-     */
-    public boolean nullable() {
-        return nullable;
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/fa197d2f/modules/schema-import/src/main/java/org/apache/ignite/schema/parser/DbTable.java
----------------------------------------------------------------------
diff --git a/modules/schema-import/src/main/java/org/apache/ignite/schema/parser/DbTable.java b/modules/schema-import/src/main/java/org/apache/ignite/schema/parser/DbTable.java
deleted file mode 100644
index 39f6f7b..0000000
--- a/modules/schema-import/src/main/java/org/apache/ignite/schema/parser/DbTable.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * 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;
-
-/**
- * Database table.
- */
-public class DbTable {
-    /** Schema name. */
-    private final String schema;
-
-    /** Table name. */
-    private final String tbl;
-
-    /** Columns. */
-    private final Collection<DbColumn> cols;
-
-    /** Indexes. */
-    private final Collection<QueryIndex> idxs;
-
-    /**
-     * Default columns.
-     *
-     * @param schema Schema name.
-     * @param tbl Table name.
-     * @param cols Columns.
-     * @param idxs Indexes;
-     */
-    public DbTable(String schema, String tbl, Collection<DbColumn> cols, Collection<QueryIndex> idxs) {
-        this.schema = schema;
-        this.tbl = tbl;
-        this.cols = cols;
-        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 Indexes.
-     */
-    public Collection<QueryIndex> indexes() {
-        return idxs;
-    }
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/fa197d2f/modules/schema-import/src/main/java/org/apache/ignite/schema/parser/dialect/DB2MetadataDialect.java
----------------------------------------------------------------------
diff --git a/modules/schema-import/src/main/java/org/apache/ignite/schema/parser/dialect/DB2MetadataDialect.java b/modules/schema-import/src/main/java/org/apache/ignite/schema/parser/dialect/DB2MetadataDialect.java
deleted file mode 100644
index b191ec3..0000000
--- a/modules/schema-import/src/main/java/org/apache/ignite/schema/parser/dialect/DB2MetadataDialect.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * DB2 specific metadata dialect.
- */
-public class DB2MetadataDialect extends JdbcMetadataDialect {
-    /** {@inheritDoc} */
-    @Override public Set<String> systemSchemas() {
-        return new HashSet<>(Arrays.asList("SYSIBM", "SYSCAT", "SYSSTAT", "SYSTOOLS", "SYSFUN", "SYSIBMADM",
-            "SYSIBMINTERNAL", "SYSIBMTS", "SYSPROC", "SYSPUBLIC"));
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/fa197d2f/modules/schema-import/src/main/java/org/apache/ignite/schema/parser/dialect/DatabaseMetadataDialect.java
----------------------------------------------------------------------
diff --git a/modules/schema-import/src/main/java/org/apache/ignite/schema/parser/dialect/DatabaseMetadataDialect.java b/modules/schema-import/src/main/java/org/apache/ignite/schema/parser/dialect/DatabaseMetadataDialect.java
deleted file mode 100644
index bdf309b..0000000
--- a/modules/schema-import/src/main/java/org/apache/ignite/schema/parser/dialect/DatabaseMetadataDialect.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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.List;
-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 List<String> schemas(Connection conn) throws SQLException;
-
-    /**
-     * Gets tables from database.
-     *
-     * @param conn Database connection.
-     * @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, Collection<QueryIndex>idxs) {
-        return new DbTable(schema, tbl, cols, idxs);
-    }
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/fa197d2f/modules/schema-import/src/main/java/org/apache/ignite/schema/parser/dialect/JdbcMetadataDialect.java
----------------------------------------------------------------------
diff --git a/modules/schema-import/src/main/java/org/apache/ignite/schema/parser/dialect/JdbcMetadataDialect.java b/modules/schema-import/src/main/java/org/apache/ignite/schema/parser/dialect/JdbcMetadataDialect.java
deleted file mode 100644
index 45f0f9f..0000000
--- a/modules/schema-import/src/main/java/org/apache/ignite/schema/parser/dialect/JdbcMetadataDialect.java
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * 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 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<>();
-
-        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, 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;
-
-                            QueryIndex idx = idxs.get(idxName);
-
-                            if (idx == null) {
-                                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 asc = askOrDesc == null || "A".equals(askOrDesc);
-
-                            idx.getFields().put(colName, asc);
-                        }
-                    }
-
-                    tbls.add(table(schema, tblName, cols, idxs.values()));
-                }
-            }
-        }
-
-        return tbls;
-    }
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/fa197d2f/modules/schema-import/src/main/java/org/apache/ignite/schema/parser/dialect/MySQLMetadataDialect.java
----------------------------------------------------------------------
diff --git a/modules/schema-import/src/main/java/org/apache/ignite/schema/parser/dialect/MySQLMetadataDialect.java b/modules/schema-import/src/main/java/org/apache/ignite/schema/parser/dialect/MySQLMetadataDialect.java
deleted file mode 100644
index 090925e..0000000
--- a/modules/schema-import/src/main/java/org/apache/ignite/schema/parser/dialect/MySQLMetadataDialect.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-
-/**
- * MySQL specific metadata dialect.
- */
-public class MySQLMetadataDialect extends JdbcMetadataDialect {
-    /** {@inheritDoc} */
-    @Override public List<String> schemas(Connection conn) throws SQLException {
-        List<String> schemas = new ArrayList<>();
-
-        ResultSet rs = conn.getMetaData().getCatalogs();
-
-        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;
-    }
-
-    /** {@inheritDoc} */
-    @Override protected boolean useCatalog() {
-        return true;
-    }
-
-    /** {@inheritDoc} */
-    @Override protected boolean useSchema() {
-        return false;
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/fa197d2f/modules/schema-import/src/main/java/org/apache/ignite/schema/parser/dialect/OracleMetadataDialect.java
----------------------------------------------------------------------
diff --git a/modules/schema-import/src/main/java/org/apache/ignite/schema/parser/dialect/OracleMetadataDialect.java b/modules/schema-import/src/main/java/org/apache/ignite/schema/parser/dialect/OracleMetadataDialect.java
deleted file mode 100644
index 0d4e8d6..0000000
--- a/modules/schema-import/src/main/java/org/apache/ignite/schema/parser/dialect/OracleMetadataDialect.java
+++ /dev/null
@@ -1,364 +0,0 @@
-/*
- * 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 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":
-                    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 Indexes.
-     * @throws SQLException If failed to retrieve indexes columns.
-     */
-    private Collection<QueryIndex> indexes(PreparedStatement stmt, String owner, String tbl)
-        throws SQLException {
-        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);
-
-                QueryIndex idx = idxs.get(idxName);
-
-                if (idx == null) {
-                    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.getFields().put(col, !"DESC".equals(idxsRs.getString(IDX_COL_DESCEND_IDX)));
-            }
-        }
-
-        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.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();
-                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;
-    }
-}


Mime
View raw message