Author: desruisseaux
Date: Fri Apr 20 14:50:37 2018
New Revision: 1829660
URL: http://svn.apache.org/viewvc?rev=1829660&view=rev
Log:
Work on SQL store: reduce the visibility of classes. Avoid reference to
internal types from public API. Edit javadoc, add some @todo items.
Added:
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/Dialect.java
- copied, changed from r1829659,
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/sql/dialect/SQLDialect.java
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/package-info.java
(with props)
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/reverse/QueryFeatureSet.java
- copied, changed from r1829659,
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/sql/SQLQueryFeatureSet.java
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/reverse/package-info.java
(with props)
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/sql/SQLStore.java
- copied, changed from r1829659,
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/sql/AbstractSQLStore.java
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/sql/SQLStoreProvider.java
- copied, changed from r1829659,
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/sql/AbstractSQLProvider.java
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/sql/package-info.java
(with props)
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/sql/postgres/PostgresStoreProvider.java
- copied, changed from r1829659,
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/sql/postgres/PostgresProvider.java
Removed:
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/sql/AbstractSQLProvider.java
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/sql/AbstractSQLStore.java
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/sql/SQLQueryFeatureSet.java
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/sql/dialect/
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/sql/postgres/PostgresProvider.java
Modified:
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/system/Modules.java
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/SQLUtilities.java
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/SingleAttributeTypeBuilder.java
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/reverse/CachedResultSet.java
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/reverse/ColumnMetaModel.java
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/reverse/DataBaseModel.java
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/reverse/InsertRelation.java
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/reverse/MetaDataConstants.java
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/reverse/PrimaryKey.java
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/reverse/RelationMetaModel.java
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/reverse/SchemaMetaModel.java
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/reverse/TableMetaModel.java
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/sql/postgres/PostgresDialect.java
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/sql/postgres/PostgresStore.java
Modified:
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/system/Modules.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/system/Modules.java?rev=1829660&r1=1829659&r2=1829660&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/system/Modules.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/system/Modules.java
[UTF-8] Fri Apr 20 14:50:37 2018
@@ -83,6 +83,11 @@ public final class Modules {
public static final String GDAL = "org.apache.sis.storage.gdal";
/**
+ * The {@value} module name.
+ */
+ public static final String SQL = "org.apache.sis.sql";
+
+ /**
* The major version number of all Apache SIS modules.
*
* @see org.apache.sis.util.Version
Copied:
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/Dialect.java
(from r1829659,
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/sql/dialect/SQLDialect.java)
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/Dialect.java?p2=sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/Dialect.java&p1=sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/sql/dialect/SQLDialect.java&r1=1829659&r2=1829660&rev=1829660&view=diff
==============================================================================
---
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/sql/dialect/SQLDialect.java
[UTF-8] (original)
+++
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/Dialect.java
[UTF-8] Fri Apr 20 14:50:37 2018
@@ -14,146 +14,154 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.sis.sql.dialect;
+package org.apache.sis.internal.sql;
+import java.util.Map;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
-import java.util.Map;
-import org.apache.sis.internal.sql.SingleAttributeTypeBuilder;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.apache.sis.internal.sql.reverse.ColumnMetaModel;
import org.apache.sis.storage.DataStoreException;
-import org.opengis.referencing.crs.CoordinateReferenceSystem;
+
/**
- * Each database has specific syntax elements.
- *
- * The dialect provide descriptions and methods to process the different
- * needs required by the store to generate the SQL requests.
+ * Description or handling of syntax elements specific to a database.
+ * The dialect provides descriptions and methods implementing the different
+ * functionalities required by the data store to generate SQL statements.
*
- * @author Johann Sorel (Geomatys)
+ * @author Johann Sorel (Geomatys)
* @version 1.0
* @since 1.0
* @module
*/
-public interface SQLDialect {
+public abstract class Dialect {
+ /**
+ * For subclass constructors.
+ */
+ protected Dialect() {
+ }
/**
- * Indicate if JDBC driver support global metadatas.
- * Some driver force specifying a schema or table to return results.
- * This prevent us from loading the all metadata in one request and
+ * Indicates if the JDBC driver support global metadata.
+ * Some drivers force specifying a schema or table to return results.
+ * This prevent us from loading all metadata in one request and
* makes us loop on all tables.
*
- * @return true if global JDBC metadatas are available.
+ * @return whether global JDBC metadata are available.
*/
- boolean supportGlobalMetadata();
+ public abstract boolean supportGlobalMetadata();
/**
- * Test if a table is to be used as a FeatureType.
- * @param name database table name
- * @return true if table should be ignored as a feature type.
+ * Indicates whether a table will be used as a {@code FeatureType}.
+ *
+ * @param name database table name.
+ * @return {@code true} if the named table should be ignored when looking
for feature types.
*/
- boolean ignoreTable(String name);
+ public abstract boolean isTableIgnored(String name);
/**
- * Get java mapping type for SQL type.
+ * Gets the Java class mapped to a given SQL type.
+ *
+ * @param sqlType SQL type code as one of {@link java.sql.Types}
constants.
+ * @param sqlTypeName name of {@code sqlType}.
+ * @return corresponding java type.
*
- * @param sqlType SQL type identifier code
- * @param sqlTypeName SQL type identifier name
- * @return corresponding java type
+ * @todo What happen if there is no match?
*/
- Class<?> getJavaType(int sqlType, String sqlTypeName);
+ public abstract Class<?> getJavaType(int sqlType, String sqlTypeName);
/**
- * Encode column name.
+ * Encodes the column name part of a SQL query.
*
- * @param sql StringBuilder to write into
- * @param name column name, not null
+ * @param sql where to write the SQL statement.
+ * @param name column name to write, not null.
*/
- void encodeColumnName(StringBuilder sql, String name);
+ public abstract void encodeColumnName(StringBuilder sql, String name);
/**
- * Encode schema and table name portion of an sql query.
+ * Encodes the schema and table name parts of a SQL query.
*
- * @param sql StringBuilder to write into
- * @param databaseSchema database schema, can be null
- * @param tableName database table, not null
+ * @param sql where to write the SQL statement.
+ * @param schema database schema to write, or null if none.
+ * @param table database table to write, not null.
*/
- void encodeSchemaAndTableName(StringBuilder sql, String databaseSchema,
String tableName);
+ public abstract void encodeSchemaAndTableName(StringBuilder sql, String
schema, String table);
/**
- * If a column is an Auto-increment or has a sequence, try to extract next
value.
+ * If a column is an auto-increment or has a sequence, tries to extract
next value.
*
- * @param column database column description
- * @param cx database connection
- * @return column value or null
- * @throws SQLException
- * @throws DataStoreException
+ * @param column description of the database column for which to get the
next value.
+ * @param cx connection to the database.
+ * @return column value or null if none.
+ * @throws SQLException if a JDBC error occurred while executing a
statement.
+ * @throws DataStoreException if another error occurred while fetching the
next value.
*/
- Object nextValue(ColumnMetaModel column, Connection cx) throws
SQLException, DataStoreException;
+ public abstract Object nextValue(ColumnMetaModel column, Connection cx)
throws SQLException, DataStoreException;
/**
- * Get value sequence name used by a column.
+ * Gets the value sequence name used by a column.
*
- * @param cx database connection
- * @param schemaName database schema
- * @param tableName database table
- * @param columnName database column
- * @return sequence name or null
- * @throws SQLException
+ * @param cx connection to the database.
+ * @param schema name of the database schema.
+ * @param table name of the database table.
+ * @param column name of the database column.
+ * @return sequence name or null if none.
+ * @throws SQLException if a JDBC error occurred while executing a
statement.
*/
- String getColumnSequence(Connection cx, String schemaName, String
tableName, String columnName) throws SQLException;
+ public abstract String getColumnSequence(Connection cx, String schema,
String table, String column) throws SQLException;
/**
- * Build column attribute type.
+ * Builds column attribute type.
*
- * @param atb attribute currently created
- * @param cx database connection
- * @param typeName column data type name
- * @param datatype column data type identifier
- * @param schemaName database schema
- * @param tableName database table
- * @param columnName database column
- * @throws SQLException
+ * @param atb builder for the attribute being created.
+ * @param cx connection to the database.
+ * @param typeName column data type name.
+ * @param datatype column data type code.
+ * @param schema name of the database schema.
+ * @param table name of the database table.
+ * @param column name of the database column.
+ * @throws SQLException if a JDBC error occurred while executing a
statement.
*/
- void decodeColumnType(final SingleAttributeTypeBuilder atb, final
Connection cx,
- final String typeName, final int datatype, final String schemaName,
- final String tableName, final String columnName) throws
SQLException;
+ public abstract void decodeColumnType(final SingleAttributeTypeBuilder
atb, final Connection cx,
+ final String typeName, final int datatype, final String schema,
+ final String table, final String column) throws SQLException;
+
/**
- * Build geometry column attribute type.
+ * Builds geometry column attribute type.
*
- * @param atb attribute currently created
- * @param cx database connection
- * @param rs connection result set
- * @param columnIndex geometric column index
- * @param customquery true if the request is a custom query
- * @throws SQLException
+ * @param atb builder for the attribute being created.
+ * @param cx connection to the database.
+ * @param rs connection result set.
+ * @param columnIndex geometric column index.
+ * @param customquery {@code true} if the request is a custom query.
+ * @throws SQLException if a JDBC error occurred while executing a
statement.
*/
- void decodeGeometryColumnType(final SingleAttributeTypeBuilder atb, final
Connection cx,
+ public abstract void decodeGeometryColumnType(final
SingleAttributeTypeBuilder atb, final Connection cx,
final ResultSet rs, final int columnIndex, boolean customquery)
throws SQLException;
/**
- * Get geometric field SRID.
+ * Gets the geometric field SRID.
*
- * @param schemaName database schema
- * @param tableName database table
- * @param columnName database column
- * @param metas
- * @param cx database connection
+ * @param schema name of the database schema.
+ * @param table name of the database table.
+ * @param column name of the database column.
+ * @param cx connection to the database.
* @return CoordinateReferenceSystem ID in the database
- * @throws SQLException
+ * @throws SQLException if a JDBC error occurred while executing a
statement.
*/
- Integer getGeometrySRID(final String schemaName, final String tableName,
- final String columnName, Map<String,Object> metas, final
Connection cx) throws SQLException;
+ public abstract Integer getGeometrySRID(final String schema, final String
table,
+ final String column, Map<String,Object> metas, final Connection
cx) throws SQLException;
/**
- * Get CoordinateReferenceSystem from database SRID.
+ * Gets a coordinate reference system from database SRID.
+ *
+ * @param srid Coordinate Reference System identifier in the database.
+ * @param cx connection to the database.
+ * @return The coordinate reference system for the given identifier.
+ * @throws SQLException if a JDBC error occurred while executing a
statement.
*
- * @param srid CoordinateReferenceSystem ID in the database
- * @param cx database connection
- * @return CoordinateReferenceSystem
- * @throws SQLException
+ * @todo what happen if no CRS is found for the given identifier?
*/
- CoordinateReferenceSystem createCRS(final int srid, final Connection cx)
throws SQLException;
-
+ public abstract CoordinateReferenceSystem createCRS(final int srid, final
Connection cx) throws SQLException;
}
Modified:
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/SQLUtilities.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/SQLUtilities.java?rev=1829660&r1=1829659&r2=1829660&view=diff
==============================================================================
---
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/SQLUtilities.java
[UTF-8] (original)
+++
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/SQLUtilities.java
[UTF-8] Fri Apr 20 14:50:37 2018
@@ -17,54 +17,58 @@
package org.apache.sis.internal.sql;
import java.util.Iterator;
+import org.apache.sis.util.CharSequences;
+
/**
- * For internal use of SQL store.
+ * Miscellaneous utility methods.
*
- * @author Johann Sorel (Geomatys)
+ * @author Johann Sorel (Geomatys)
* @version 1.0
* @since 1.0
* @module
*/
public final class SQLUtilities {
-
+ /**
+ * Do not allow instantiation of this class.
+ */
private SQLUtilities(){
}
/**
* Returns a graphical representation of the specified objects. This
representation can be
* printed to the {@linkplain System#out standard output stream} (for
example) if it uses
- * a monospaced font and supports unicode.
+ * a monospaced font and supports Unicode.
*
- * @param root The root name of the tree to format.
- * @param objects The objects to format as root children.
- * @return A string representation of the tree.
+ * @param root the root name of the tree to format, or {@code null}
if none.
+ * @param objects the objects to format as root children, or {@code
null} if none.
+ * @return a string representation of the tree.
*/
- public static String toStringTree(String root, final Iterable<?> objects) {
- final StringBuilder sb = new StringBuilder();
+ public static String toTreeString(String root, final Iterable<?> objects) {
+ final StringBuilder sb = new StringBuilder(100);
if (root != null) {
sb.append(root);
}
if (objects != null) {
- final Iterator<?> ite = objects.iterator();
- while (ite.hasNext()) {
- sb.append('\n');
- final Object next = ite.next();
- final boolean last = !ite.hasNext();
- sb.append(last ? "└─ " : "├─ ");
+ final String lineSeparator = System.lineSeparator();
+ final Iterator<?> it = objects.iterator();
+ boolean hasNext;
+ if (it.hasNext()) do {
+ sb.append(lineSeparator);
+ final Object next = it.next();
+ hasNext = it.hasNext();
+ sb.append(hasNext ? "├─ " : "└─ ");
- final String[] parts = String.valueOf(next).split("\n");
+ final CharSequence[] parts =
CharSequences.splitOnEOL(String.valueOf(next));
sb.append(parts[0]);
- for (int k=1;k<parts.length;k++) {
- sb.append('\n');
- sb.append(last ? ' ' : '│');
- sb.append(" ");
- sb.append(parts[k]);
+ for (int k=1; k < parts.length; k++) {
+ sb.append(lineSeparator)
+ .append(hasNext ? '│' : ' ')
+ .append(" ")
+ .append(parts[k]);
}
- }
+ } while (hasNext);
}
-
return sb.toString();
}
-
}
Modified:
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/SingleAttributeTypeBuilder.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/SingleAttributeTypeBuilder.java?rev=1829660&r1=1829659&r2=1829660&view=diff
==============================================================================
---
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/SingleAttributeTypeBuilder.java
[UTF-8] (original)
+++
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/SingleAttributeTypeBuilder.java
[UTF-8] Fri Apr 20 14:50:37 2018
@@ -23,7 +23,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.sis.feature.DefaultAttributeType;
-import static org.apache.sis.feature.AbstractIdentifiedType.*;
import org.opengis.feature.AttributeType;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.util.GenericName;
@@ -31,100 +30,145 @@ import org.apache.sis.internal.feature.A
import org.apache.sis.internal.system.DefaultFactories;
import org.opengis.util.NameFactory;
+import static org.apache.sis.feature.AbstractIdentifiedType.*;
+
+
/**
+ * Builder for a single {@link AttributeType}.
+ * This is an alternative to {@link
org.apache.sis.feature.builder.PropertyTypeBuilder}.
*
- * @author Johann Sorel (Geomatys)
+ * @author Johann Sorel (Geomatys)
* @version 1.0
* @since 1.0
* @module
+ *
+ * @todo Is this class really needed?
*/
public class SingleAttributeTypeBuilder {
+ /**
+ * Properties (name, description, …) to give to the attribute type
constructor.
+ */
+ private final Map<String,Object> properties;
+
+ /**
+ * Optional characteristics of the attribute.
+ */
+ private final List<AttributeType<?>> characteristics;
- private final Map<String,Object> parameters = new HashMap<>();
- private final List<AttributeType<?>> atts = new ArrayList<>();
+ /**
+ * The class of the attribute.
+ */
private Class<?> valueClass;
+
+ /**
+ * Minimum number of occurrences.
+ */
private int minimumOccurs;
+
+ /**
+ * Maximum number of occurrences.
+ */
private int maximumOccurs;
+
+ /**
+ * The default value, or {@code null} if none.
+ */
private Object defaultValue;
+ /**
+ * Creates a new attribute type builder.
+ */
public SingleAttributeTypeBuilder() {
- minimumOccurs = 1;
- maximumOccurs = 1;
+ properties = new HashMap<>();
+ characteristics = new ArrayList<>();
+ minimumOccurs = 1;
+ maximumOccurs = 1;
}
+ /**
+ * Restores this builder to its initial state.
+ * This method can be invoked before to build another attribute.
+ *
+ * @return {@code this} for method call chaining.
+ */
public SingleAttributeTypeBuilder reset(){
- parameters.clear();
- atts.clear();
- valueClass = null;
+ properties.clear();
+ characteristics.clear();
+ valueClass = null;
minimumOccurs = 1;
maximumOccurs = 1;
- defaultValue = null;
+ defaultValue = null;
return this;
}
- public SingleAttributeTypeBuilder copy(AttributeType<?> base){
- setName(base.getName());
- setDefinition(base.getDefinition());
- setDescription(base.getDescription());
- setDesignation(base.getDesignation());
- atts.addAll(base.characteristics().values());
- valueClass = base.getValueClass();
- minimumOccurs = base.getMinimumOccurs();
- maximumOccurs = base.getMaximumOccurs();
- defaultValue = base.getDefaultValue();
+ /**
+ * Sets this builder to the same properties then the given attribute type.
+ *
+ * @param template the attribute type to use as a template.
+ * @return {@code this} for method call chaining.
+ */
+ public SingleAttributeTypeBuilder copy(AttributeType<?> template) {
+ reset();
+ setName (template.getName());
+ setDefinition (template.getDefinition());
+ setDescription(template.getDescription());
+ setDesignation(template.getDesignation());
+ characteristics.addAll(template.characteristics().values());
+ valueClass = template.getValueClass();
+ minimumOccurs = template.getMinimumOccurs();
+ maximumOccurs = template.getMaximumOccurs();
+ defaultValue = template.getDefaultValue();
return this;
}
- public SingleAttributeTypeBuilder setName(String localPart){
- this.setName(null,localPart);
- return this;
+ public SingleAttributeTypeBuilder setName(String localPart) {
+ return setName(null, localPart);
}
- public SingleAttributeTypeBuilder setName(String namespace, String
localPart){
+ public SingleAttributeTypeBuilder setName(String namespace, String
localPart) {
final GenericName name;
if (namespace == null || namespace.isEmpty()) {
name =
DefaultFactories.forBuildin(NameFactory.class).createGenericName(null,
localPart);
} else {
name =
DefaultFactories.forBuildin(NameFactory.class).createGenericName(null,
namespace, localPart);
}
- setName(name);
- return this;
+ return setName(name);
}
public SingleAttributeTypeBuilder setName(GenericName name) {
- parameters.put(DefaultAttributeType.NAME_KEY, name);
+ properties.put(DefaultAttributeType.NAME_KEY, name);
return this;
}
- public GenericName getName(){
- return
GenericName.class.cast(parameters.get(DefaultAttributeType.NAME_KEY));
+ public GenericName getName() {
+ return (GenericName) properties.get(DefaultAttributeType.NAME_KEY);
}
- public SingleAttributeTypeBuilder setDescription(CharSequence description){
- parameters.put(DESCRIPTION_KEY, description);
+ public SingleAttributeTypeBuilder setDescription(CharSequence description)
{
+ properties.put(DESCRIPTION_KEY, description);
return this;
}
- public CharSequence getDescription(){
- return CharSequence.class.cast(parameters.get(DESCRIPTION_KEY));
+ public CharSequence getDescription() {
+ return (CharSequence) properties.get(DESCRIPTION_KEY);
}
public SingleAttributeTypeBuilder setDesignation(CharSequence designation){
- parameters.put(DESIGNATION_KEY, designation);
+ properties.put(DESIGNATION_KEY, designation);
return this;
}
public CharSequence getDesignation(){
- return CharSequence.class.cast(parameters.get(DESIGNATION_KEY));
+ return (CharSequence) properties.get(DESIGNATION_KEY);
}
public SingleAttributeTypeBuilder setDefinition(CharSequence definition){
- parameters.put(DEFINITION_KEY, definition);
+ properties.put(DEFINITION_KEY, definition);
return this;
}
public CharSequence getDefinition(){
- return CharSequence.class.cast(parameters.get(DEFINITION_KEY));
+ return (CharSequence) properties.get(DEFINITION_KEY);
}
public SingleAttributeTypeBuilder setValueClass(Class<?> valueClass) {
@@ -164,53 +208,53 @@ public class SingleAttributeTypeBuilder
}
/**
- * Set maximum string length
- * @param length
- * @return created attribute
+ * Set maximum string length.
+ *
+ * @param length maximal number of characters.
+ * @return {@code this} for method call chaining.
*/
- public SingleAttributeTypeBuilder setLength(int length){
+ public SingleAttributeTypeBuilder setLength(int length) {
return
addCharacteristic(AttributeConvention.MAXIMAL_LENGTH_CHARACTERISTIC,
Integer.class, 0, 1, length);
}
- public SingleAttributeTypeBuilder setCRS(CoordinateReferenceSystem crs){
+ public SingleAttributeTypeBuilder setCRS(CoordinateReferenceSystem crs) {
return addCharacteristic(AttributeConvention.CRS_CHARACTERISTIC,
CoordinateReferenceSystem.class, 0, 1, crs);
}
- public SingleAttributeTypeBuilder setPossibleValues(Collection values){
+ public SingleAttributeTypeBuilder setPossibleValues(Collection<?> values) {
return
addCharacteristic(AttributeConvention.VALID_VALUES_CHARACTERISTIC,
Object.class, 0, 1, values);
}
- public SingleAttributeTypeBuilder addCharacteristic(String localPart,
Class valueClass, int minimumOccurs, int maximumOccurs, Object defaultValue) {
+ public SingleAttributeTypeBuilder addCharacteristic(String localPart,
Class<?> valueClass, int minimumOccurs, int maximumOccurs, Object defaultValue)
{
final GenericName name =
DefaultFactories.forBuildin(NameFactory.class).createGenericName(null,
localPart);
return
addCharacteristic(name,valueClass,minimumOccurs,maximumOccurs,defaultValue);
}
- public SingleAttributeTypeBuilder addCharacteristic(GenericName name,
Class valueClass, int minimumOccurs, int maximumOccurs, Object defaultValue) {
+ public SingleAttributeTypeBuilder addCharacteristic(GenericName name,
Class<?> valueClass, int minimumOccurs, int maximumOccurs, Object defaultValue)
{
return addCharacteristic(new DefaultAttributeType(
Collections.singletonMap(NAME_KEY, name),
valueClass,minimumOccurs,maximumOccurs,defaultValue));
}
- public SingleAttributeTypeBuilder addCharacteristic(AttributeType
characteristic){
+ public SingleAttributeTypeBuilder addCharacteristic(AttributeType<?>
characteristic) {
//search and remove previous characteristic with the same id if it
exist
- for (AttributeType at : atts) {
+ for (AttributeType<?> at : characteristics) {
if (at.getName().equals(characteristic.getName())) {
- atts.remove(at);
+ characteristics.remove(at);
break;
}
}
- atts.add(characteristic);
+ characteristics.add(characteristic);
return this;
}
- public AttributeType build(){
- return new DefaultAttributeType(parameters, valueClass,
+ public AttributeType<?> build(){
+ return new DefaultAttributeType(properties, valueClass,
minimumOccurs, maximumOccurs,
- defaultValue, atts.toArray(new AttributeType[atts.size()]));
+ defaultValue, characteristics.toArray(new
AttributeType[characteristics.size()]));
}
- public static AttributeType create(GenericName name, Class valueClass) {
+ public static AttributeType<?> create(GenericName name, Class<?>
valueClass) {
return new DefaultAttributeType(Collections.singletonMap("name",
name), valueClass, 1, 1, null);
}
-
}
Added:
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/package-info.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/package-info.java?rev=1829660&view=auto
==============================================================================
---
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/package-info.java
(added)
+++
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/package-info.java
[UTF-8] Fri Apr 20 14:50:37 2018
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+
+/**
+ * A set of helper classes for the SIS implementation of SQL data stores.
+ *
+ * <STRONG>Do not use!</STRONG>
+ *
+ * This package is for internal use by SIS only. Classes in this package
+ * may change in incompatible ways in any future version without notice.
+ *
+ * @author Johann Sorel (Geomatys)
+ * @version 1.0
+ * @since 1.0
+ * @module
+ */
+package org.apache.sis.internal.sql;
Propchange:
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/package-info.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/package-info.java
------------------------------------------------------------------------------
svn:mime-type = text/plain;charset=UTF-8
Modified:
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/reverse/CachedResultSet.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/reverse/CachedResultSet.java?rev=1829660&r1=1829659&r2=1829660&view=diff
==============================================================================
---
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/reverse/CachedResultSet.java
[UTF-8] (original)
+++
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/reverse/CachedResultSet.java
[UTF-8] Fri Apr 20 14:50:37 2018
@@ -19,43 +19,55 @@ package org.apache.sis.internal.sql.reve
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+
/**
- * Cached a ResultSet content.
+ * A cache of {@link ResultSet} content.
*
- * @author Johann Sorel (Geomatys)
+ * @author Johann Sorel (Geomatys)
* @version 1.0
* @since 1.0
* @module
+ *
+ * @todo Current implementation consumes more memory than needed, with the
construction of a hash map for each record.
+ * The construction of {@code DenseFeature} instances would be more
efficient. Furthermore this construct reads
+ * all records at construction time. We should consider lazy population
instead.
*/
-public class CachedResultSet {
-
- private final List<Map<String,Object>> records = new ArrayList<>();
-
- public CachedResultSet() {
+final class CachedResultSet {
+ /**
+ * All records read by the SQL query, as (column, value) pairs.
+ */
+ final List<Map<String,Object>> records;
+
+ /**
+ * Creates an initially empty set.
+ */
+ CachedResultSet() {
+ records = new ArrayList<>();
}
- public CachedResultSet(ResultSet rs, String... columns) throws
SQLException {
+ /**
+ * Creates a set initialized with the given content.
+ */
+ CachedResultSet(final ResultSet rs, final String... columns) throws
SQLException {
+ records = new ArrayList<>(columns.length);
append(rs, columns);
}
- public void append(ResultSet rs, String... columns) throws SQLException {
+ /**
+ * Appends the given content to this set.
+ */
+ void append(final ResultSet rs, final String... columns) throws
SQLException {
while (rs.next()) {
final Map<String,Object> record = new HashMap<>();
- for (String col : columns) {
+ for (final String col : columns) {
record.put(col, rs.getObject(col));
}
records.add(record);
}
rs.close();
}
-
- public Collection<Map<String,Object>> records() {
- return records;
- }
-
}
Modified:
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/reverse/ColumnMetaModel.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/reverse/ColumnMetaModel.java?rev=1829660&r1=1829659&r2=1829660&view=diff
==============================================================================
---
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/reverse/ColumnMetaModel.java
[UTF-8] (original)
+++
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/reverse/ColumnMetaModel.java
[UTF-8] Fri Apr 20 14:50:37 2018
@@ -16,185 +16,193 @@
*/
package org.apache.sis.internal.sql.reverse;
+import org.apache.sis.internal.sql.Dialect;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
+import java.util.Collections;
import java.util.UUID;
-import java.util.logging.Logger;
-import org.apache.sis.feature.builder.FeatureTypeBuilder;
-import org.apache.sis.sql.dialect.SQLDialect;
-import org.apache.sis.storage.DataStoreException;
import org.opengis.feature.AttributeType;
+import org.apache.sis.feature.DefaultAttributeType;
+import org.apache.sis.storage.DataStoreException;
+
/**
* Description of a table column.
*
- * @author Johann Sorel (Geomatys)
+ * @author Johann Sorel (Geomatys)
* @version 1.0
* @since 1.0
* @module
*/
-public class ColumnMetaModel {
-
+public final class ColumnMetaModel {
/**
- * Property information, The native SRID associated to a certain
descriptor.
- * Value is an Integer.
+ * Description of the attribute holding native SRID associated to a
certain descriptor.
*/
- public static final AttributeType<Integer> JDBC_PROPERTY_SRID = new
FeatureTypeBuilder().addAttribute(Integer.class).setName("nativeSRID").build();
+ static final AttributeType<Integer> JDBC_PROPERTY_SRID = new
DefaultAttributeType<>(
+ Collections.singletonMap(DefaultAttributeType.NAME_KEY,
"nativeSRID"),
+ Integer.class, 1, 1, null);
/**
- * Property information, if the field is unique in the database.
- * Value is a Boolean.
+ * Description of the attribute telling whether a field is unique in the
database.
*/
- public static final AttributeType<Boolean> JDBC_PROPERTY_UNIQUE = new
FeatureTypeBuilder().addAttribute(Boolean.class).setName("unique").build();
+ static final AttributeType<Boolean> JDBC_PROPERTY_UNIQUE = new
DefaultAttributeType<>(
+ Collections.singletonMap(DefaultAttributeType.NAME_KEY, "unique"),
+ Boolean.class, 1, 1, null);
/**
* Property information, if the field is a relation.
- * Value is a RelationMetaModel.
*/
- public static final AttributeType<RelationMetaModel>
JDBC_PROPERTY_RELATION = new
FeatureTypeBuilder().addAttribute(RelationMetaModel.class).setName("relation").build();
+ static final AttributeType<RelationMetaModel> JDBC_PROPERTY_RELATION = new
DefaultAttributeType<>(
+ Collections.singletonMap(DefaultAttributeType.NAME_KEY,
"relation"),
+ RelationMetaModel.class, 1, 1, null);
- public enum Type {
+ /**
+ * Whether values in a column are generated by the database, computed from
a sequence of supplied.
+ */
+ enum Type {
/**
* Indicate this field value is generated by the database.
*/
AUTO,
+
/**
* Indicate a sequence is used to generate field values.
*/
SEQUENCED,
+
/**
* Indicate field value must be provided.
*/
PROVIDED
}
- private final String schema;
- private final String table;
- private final String name;
- private final int sqlType;
- private final String sqlTypeName;
- private final Class<?> clazz;
- private final Type type;
- private final String sequenceName;
-
/**
- *
- * @param schema database scheme where this column is found
- * @param table database table where this column is found
- * @param name name of the column
- * @param sqlType column sql type
- * @param sqlTypeName column sql type name
- * @param clazz java type
- * @param type if column is a primary key, specify how the value is
generated
- * @param sequenceName if column is a primary key, optional sequence name
- */
- public ColumnMetaModel(String schema, String table, String name,
- int sqlType, String sqlTypeName, Class<?> clazz, Type type, String
sequenceName) {
- this.schema = schema;
- this.table = table;
- this.name = name;
- this.sqlType = sqlType;
- this.sqlTypeName = sqlTypeName;
- this.clazz = clazz;
- this.type = type;
- this.sequenceName = sequenceName;
- }
+ * Database scheme where this column is found.
+ */
+ final String schema;
- public String getSchema() {
- return schema;
- }
+ /**
+ * Database table where this column is found
+ */
+ final String table;
- public String getTable() {
- return table;
- }
+ /**
+ * Name of the column.
+ */
+ final String name;
- public String getName() {
- return name;
- }
+ /**
+ * Column SQL type (integer, characters, …) as one of {@link
java.sql.Types} constants.
+ */
+ final int sqlType;
- public int getSqlType() {
- return sqlType;
- }
+ /**
+ * Name of {@link #sqlType}.
+ */
+ final String sqlTypeName;
- public String getSqlTypeName() {
- return sqlTypeName;
- }
+ /**
+ * Java class for the {@link #sqlType}.
+ */
+ final Class<?> clazz;
- public Class<?> getJavaType() {
- return clazz;
- }
+ /**
+ * If the column is a primary key, specifies how the value is generated.
+ */
+ final Type type;
- public Type getType() {
- return type;
- }
+ /**
+ * If the column is a primary key, the optional sequence name.
+ */
+ final String sequenceName;
- public String getSequenceName() {
- return sequenceName;
+ /**
+ * Stores information about a table column.
+ *
+ * @param schema database scheme where this column is found.
+ * @param table database table where this column is found.
+ * @param name name of this column.
+ * @param sqlType column SQL type as one of {@link java.sql.Types}
constants.
+ * @param sqlTypeName name of {@code sqlType}.
+ * @param clazz Java class for {@code sqlType}.
+ * @param type if the column is a primary key, specify how the
value is generated.
+ * @param sequenceName if the column is a primary key, optional sequence
name.
+ */
+ ColumnMetaModel(final String schema, final String table, final String name,
+ final int sqlType, final String sqlTypeName, final Class<?> clazz,
+ final Type type, final String sequenceName)
+ {
+ this.schema = schema;
+ this.table = table;
+ this.name = name;
+ this.sqlType = sqlType;
+ this.sqlTypeName = sqlTypeName;
+ this.clazz = clazz;
+ this.type = type;
+ this.sequenceName = sequenceName;
}
/**
- * Try to compute next column value.
+ * Tries to compute next column value.
*
- * @param dialect database dialect
- * @param logger database logger
- * @param cx database connection
- * @return next field value
- * @throws SQLException
- * @throws DataStoreException
+ * @param dialect handler for syntax elements specific to the database.
+ * @param cx connection to the database.
+ * @return next field value.
+ * @throws SQLException if a JDBC error occurred while executing a
statement.
+ * @throws DataStoreException if another error occurred while fetching the
next value.
*/
- public Object nextValue(final SQLDialect dialect, Logger logger, final
Connection cx)
- throws SQLException, DataStoreException {
+ public Object nextValue(final Dialect dialect, final Connection cx) throws
SQLException, DataStoreException {
Object next = null;
-
if (type == Type.AUTO || type == Type.SEQUENCED) {
- //question the database for next value
+ // Delegate to the database for next value.
next = dialect.nextValue(this, cx);
} else {
- //generate value if possible
+ // Generate value if possible.
if (Number.class.isAssignableFrom(clazz)) {
- //Get the maximum value in the database and increment it
+ // Get the maximum value in the database and increment it
final StringBuilder sql = new StringBuilder();
sql.append("SELECT 1 + MAX(");
- dialect.encodeColumnName(sql, getName());
+ dialect.encodeColumnName(sql, name);
sql.append(") FROM ");
dialect.encodeSchemaAndTableName(sql, schema, table);
-
try (Statement st = cx.createStatement();
- ResultSet rs = st.executeQuery(sql.toString())) {
+ ResultSet rs = st.executeQuery(sql.toString())) {
rs.next();
next = rs.getObject(1);
}
-
if (next == null) {
- //can be the result of an empty table
+ // Can be the result of an empty table.
next = 1;
}
-
} else if (CharSequence.class.isAssignableFrom(clazz)) {
- //use an UUID to reduce risk of conflicts
+ // Use an UUID to reduce risk of conflicts.
next = UUID.randomUUID().toString();
}
-
if (next == null) {
throw new DataStoreException("Failed to generate a value for
column " + toString());
}
}
-
return next;
}
+ /**
+ * Returns a string representation of this column description for
debugging purpose.
+ * The string returned by this method may change in any future SIS version.
+ *
+ * @return a string representation for debugging purpose.
+ */
@Override
public String toString() {
- final StringBuilder sb = new StringBuilder(name);
- sb.append('[');
- sb.append(sqlType);
- sb.append(',');
- sb.append(sqlTypeName);
- sb.append(',');
- sb.append(type);
- sb.append(']');
- return sb.toString();
+ return new StringBuilder(name)
+ .append('[')
+ .append(sqlType)
+ .append(", ")
+ .append(sqlTypeName)
+ .append(", ")
+ .append(type)
+ .append(']')
+ .toString();
}
}
Modified:
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/reverse/DataBaseModel.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/reverse/DataBaseModel.java?rev=1829660&r1=1829659&r2=1829660&view=diff
==============================================================================
---
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/reverse/DataBaseModel.java
[UTF-8] (original)
+++
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/reverse/DataBaseModel.java
[UTF-8] Fri Apr 20 14:50:37 2018
@@ -33,61 +33,63 @@ import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Predicate;
-import java.util.logging.Level;
-import java.util.logging.Logger;
+import org.opengis.util.GenericName;
+import org.opengis.coverage.Coverage;
+import org.opengis.feature.AttributeType;
+import org.opengis.feature.FeatureType;
+import org.opengis.feature.PropertyNotFoundException;
+import org.opengis.feature.PropertyType;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.apache.sis.feature.builder.AttributeRole;
import org.apache.sis.feature.builder.AttributeTypeBuilder;
import org.apache.sis.feature.builder.FeatureTypeBuilder;
import org.apache.sis.feature.builder.PropertyTypeBuilder;
import org.apache.sis.internal.feature.Geometries;
+import org.apache.sis.internal.sql.Dialect;
import org.apache.sis.internal.sql.SingleAttributeTypeBuilder;
-import org.apache.sis.internal.sql.reverse.ColumnMetaModel.Type;
import org.apache.sis.internal.sql.reverse.MetaDataConstants.*;
-import org.apache.sis.sql.AbstractSQLStore;
-import org.apache.sis.sql.dialect.SQLDialect;
+import org.apache.sis.sql.SQLStore;
+import org.apache.sis.storage.DataStore;
import org.apache.sis.storage.DataStoreException;
import org.apache.sis.storage.FeatureNaming;
-import org.opengis.coverage.Coverage;
-import org.opengis.feature.AttributeType;
-import org.opengis.feature.FeatureType;
-import org.opengis.feature.PropertyNotFoundException;
-import org.opengis.feature.PropertyType;
-import org.opengis.referencing.crs.CoordinateReferenceSystem;
-import org.opengis.util.GenericName;
+import org.apache.sis.util.logging.WarningListeners;
/**
- * Represent the structure of the database. The work done here is similar to
- * reverse engineering.
+ * Represent the structure of the database.
+ * The work done here is similar to reverse engineering.
*
- * @author Johann Sorel (Geomatys)
+ * @author Johann Sorel (Geomatys)
* @version 1.0
* @since 1.0
* @module
*/
public final class DataBaseModel {
-
- public static final String ASSOCIATION_SEPARATOR = "→";
+ /**
+ * @todo Does not seem to be used yet.
+ */
+ private static final String ASSOCIATION_SEPARATOR = "→";
/**
* The native SRID associated to a certain descriptor
+ *
+ * @todo Does not seem to be used yet.
*/
- public static final String JDBC_NATIVE_SRID = "nativeSRID";
-
+ private static final String JDBC_NATIVE_SRID = "nativeSRID";
/**
- * Feature type used to mark types which are sub types of others.
+ * Feature type used to mark types which are sub-types of others.
*/
private static final FeatureType SUBTYPE;
static {
- final FeatureTypeBuilder ftb = new FeatureTypeBuilder();
- ftb.setName("SubType");
- ftb.setAbstract(true);
+ final FeatureTypeBuilder ftb = new FeatureTypeBuilder()
+ .setName("SubType")
+ .setAbstract(true);
SUBTYPE = ftb.build();
}
- private final AbstractSQLStore store;
- private final Logger logger;
+ private final SQLStore store;
+ private final Dialect dialect;
private final String databaseSchema;
private final String databaseTable;
@@ -110,22 +112,24 @@ public final class DataBaseModel {
private Set<String> visitedSchemas;
private Set<String> requieredSchemas;
+ private final WarningListeners<DataStore> listeners;
- public DataBaseModel(final AbstractSQLStore store, Logger logger, String
schema, String table){
- this.store = store;
- this.logger = logger;
+ public DataBaseModel(final SQLStore store, final Dialect dialect, final
String schema, final String table, final WarningListeners<DataStore> listeners)
{
+ this.store = store;
+ this.dialect = dialect;
this.databaseSchema = schema;
- this.databaseTable = table;
+ this.databaseTable = table;
+ this.listeners = listeners;
}
- public Collection<SchemaMetaModel> getSchemaMetaModels() throws
DataStoreException {
+ private Collection<SchemaMetaModel> getSchemaMetaModels() throws
DataStoreException {
if (schemas == null) {
analyze();
}
return schemas.values();
}
- public SchemaMetaModel getSchemaMetaModel(String name) throws
DataStoreException{
+ private SchemaMetaModel getSchemaMetaModel(String name) throws
DataStoreException{
if (schemas == null) {
analyze();
}
@@ -136,22 +140,22 @@ public final class DataBaseModel {
* Clear the model cache. A new database analyze will be made the next time
* it is needed.
*/
- public synchronized void clearCache() {
- pkIndex = new FeatureNaming<>();
+ private synchronized void clearCache() {
+ pkIndex = new FeatureNaming<>();
typeIndex = new FeatureNaming<>();
typeNames = new HashSet<>();
nameCache = null;
- schemas = null;
+ schemas = null;
}
- public PrimaryKey getPrimaryKey(final String featureTypeName) throws
DataStoreException{
+ private PrimaryKey getPrimaryKey(final String featureTypeName) throws
DataStoreException{
if (schemas == null) {
analyze();
}
return pkIndex.get(store, featureTypeName);
}
- public synchronized Set<GenericName> getNames() throws DataStoreException {
+ private synchronized Set<GenericName> getNames() throws DataStoreException
{
Set<GenericName> ref = nameCache;
if (ref == null) {
analyze();
@@ -159,7 +163,7 @@ public final class DataBaseModel {
for (GenericName name : typeNames) {
final FeatureType type = typeIndex.get(store, name.toString());
if (SUBTYPE.isAssignableFrom(type)) continue;
- if (store.getDialect().ignoreTable(name.tip().toString()))
continue;
+ if (dialect.isTableIgnored(name.tip().toString())) continue;
names.add(name);
}
ref = Collections.unmodifiableSet(names);
@@ -176,19 +180,15 @@ public final class DataBaseModel {
}
/**
- * Explore all tables and views then recreate a complex feature model from
- * relations.
+ * Explores all tables and views then recreate a complex feature model
from relations.
*/
private synchronized void analyze() throws DataStoreException{
if (schemas != null) {
- //already analyzed
+ // Already analyzed
return;
}
-
clearCache();
schemas = new HashMap<>();
- final SQLDialect dialect = store.getDialect();
-
visitedSchemas = new HashSet<>();
requieredSchemas = new HashSet<>();
@@ -245,10 +245,10 @@ public final class DataBaseModel {
cacheImportedKeys = new CachedResultSet();
cacheExportedKeys = new CachedResultSet();
- final Iterator<Map<String,Object>> ite =
cacheSchemas.records().iterator();
+ final Iterator<Map<String,Object>> ite =
cacheSchemas.records.iterator();
while (ite.hasNext()) {
final String schemaName = (String)
ite.next().get(Schema.TABLE_SCHEM);
- for (Map<String,Object> info : cacheTables.records()) {
+ for (Map<String,Object> info : cacheTables.records) {
if
(!Objects.equals(info.get(Table.TABLE_SCHEM),schemaName)) continue;
cachePrimaryKeys.append(metadata.getPrimaryKeys(null,
schemaName, (String) info.get(Table.TABLE_NAME)),
Column.TABLE_SCHEM,
@@ -280,13 +280,13 @@ public final class DataBaseModel {
if (databaseSchema != null) {
requieredSchemas.add(databaseSchema);
} else {
- final Iterator<Map<String,Object>> ite =
cacheSchemas.records().iterator();
+ final Iterator<Map<String,Object>> ite =
cacheSchemas.records.iterator();
while (ite.hasNext()) {
requieredSchemas.add((String)
ite.next().get(Schema.TABLE_SCHEM));
}
}
- //we need to analyze requiered schema references
+ // We need to analyze requiered schema references
while (!requieredSchemas.isEmpty()) {
final String sn = requieredSchemas.iterator().next();
visitedSchemas.add(sn);
@@ -298,7 +298,7 @@ public final class DataBaseModel {
reverseSimpleFeatureTypes(cx);
} catch (SQLException e) {
- throw new DataStoreException("Error occurred analyzing database
model.\n"+e.getMessage(), e);
+ throw new DataStoreException("Error occurred analyzing database
model.\n" + e.getMessage(), e);
} finally {
cacheSchemas = null;
cacheTables = null;
@@ -313,7 +313,7 @@ public final class DataBaseModel {
}
- //build
indexes---------------------------------------------------------
+ // Build
indexes---------------------------------------------------------
final String baseSchemaName = databaseSchema;
final Collection<SchemaMetaModel> candidates;
@@ -326,13 +326,13 @@ public final class DataBaseModel {
for (SchemaMetaModel schema : candidates) {
if (schema != null) {
- for (TableMetaModel table : schema.tables.values()) {
+ for (TableMetaModel table : schema.getTables()) {
final FeatureTypeBuilder ft =
table.getType(TableMetaModel.View.SIMPLE_FEATURE_TYPE);
final GenericName name = ft.getName();
pkIndex.add(store, name, table.key);
if (table.isSubType()) {
- //we don't show subtype, they are part of other
feature types, add a flag to identify then
+ // We don't show subtype, they are part of other
feature types, add a flag to identify then
ft.setSuperTypes(SUBTYPE);
}
typeNames.add(name);
@@ -346,11 +346,9 @@ public final class DataBaseModel {
}
private SchemaMetaModel analyzeSchema(final String schemaName, final
Connection cx) throws DataStoreException {
-
final SchemaMetaModel schema = new SchemaMetaModel(schemaName);
-
try {
- for (Map<String,Object> info : cacheTables.records()) {
+ for (Map<String,Object> info : cacheTables.records) {
if (!Objects.equals(info.get(Table.TABLE_SCHEM), schemaName))
continue;
if (databaseTable != null && !databaseTable.isEmpty() &&
!Objects.equals(info.get(Table.TABLE_NAME),databaseTable)) continue;
final TableMetaModel table = analyzeTable(info,cx);
@@ -359,36 +357,33 @@ public final class DataBaseModel {
} catch (SQLException e) {
throw new DataStoreException("Error occurred analyzing database
model.", e);
}
-
return schema;
}
private TableMetaModel analyzeTable(final Map tableSet, final Connection
cx) throws DataStoreException, SQLException {
- final SQLDialect dialect = store.getDialect();
-
final String schemaName = (String) tableSet.get(Table.TABLE_SCHEM);
- final String tableName = (String) tableSet.get(Table.TABLE_NAME);
- final String tableType = (String) tableSet.get(Table.TABLE_TYPE);
+ final String tableName = (String) tableSet.get(Table.TABLE_NAME);
+ final String tableType = (String) tableSet.get(Table.TABLE_TYPE);
final TableMetaModel table = new TableMetaModel(tableName,tableType);
final FeatureTypeBuilder ftb = new FeatureTypeBuilder();
try {
- //explore all columns
----------------------------------------------
+ // Explore all columns
----------------------------------------------
final Predicate<Map<String,Object>> tableFilter =
(Map<String,Object> info) -> {
return Objects.equals(info.get(Table.TABLE_SCHEM), schemaName)
&& Objects.equals(info.get(Table.TABLE_NAME), tableName);
};
- final Iterator<Map<String,Object>> ite1 =
cacheColumns.records().stream().filter(tableFilter).iterator();
+ final Iterator<Map<String,Object>> ite1 =
cacheColumns.records.stream().filter(tableFilter).iterator();
while (ite1.hasNext()) {
ftb.addAttribute(analyzeColumn(ite1.next(),cx));
}
- //find primary key
-------------------------------------------------
+ // Find primary key
-------------------------------------------------
final List<ColumnMetaModel> cols = new ArrayList<>();
- final Iterator<Map<String,Object>> pkIte =
cachePrimaryKeys.records().stream().filter(tableFilter).iterator();
+ final Iterator<Map<String,Object>> pkIte =
cachePrimaryKeys.records.stream().filter(tableFilter).iterator();
while (pkIte.hasNext()) {
final Map<String,Object> result = pkIte.next();
final String columnName = (String)
result.get(Column.COLUMN_NAME);
@@ -396,7 +391,7 @@ public final class DataBaseModel {
final Predicate<Map<String,Object>> colFilter =
(Map<String,Object> info) -> {
return Objects.equals(info.get(Column.COLUMN_NAME),
columnName);
};
- final Iterator<Map<String,Object>> cite =
cacheColumns.records().stream().filter(tableFilter.and(colFilter)).iterator();
+ final Iterator<Map<String,Object>> cite =
cacheColumns.records.stream().filter(tableFilter.and(colFilter)).iterator();
final Map<String,Object> column = cite.next();
final int sqlType = ((Number)
column.get(Column.DATA_TYPE)).intValue();
@@ -404,7 +399,7 @@ public final class DataBaseModel {
Class<?> columnType = dialect.getJavaType(sqlType,
sqlTypeName);
if (columnType == null) {
- logger.log(Level.WARNING, "No class for sql type {0}",
sqlType);
+ listeners.warning("No class for SQL type " + sqlType,
null);
columnType = Object.class;
}
@@ -412,35 +407,35 @@ public final class DataBaseModel {
final String str = (String)
column.get(Column.IS_AUTOINCREMENT);
if (Column.VALUE_YES.equalsIgnoreCase(str)) {
- col = new ColumnMetaModel(schemaName, tableName,
columnName, sqlType, sqlTypeName, columnType, Type.AUTO, null);
+ col = new ColumnMetaModel(schemaName, tableName,
columnName, sqlType, sqlTypeName, columnType, ColumnMetaModel.Type.AUTO, null);
} else {
final String sequenceName =
dialect.getColumnSequence(cx,schemaName, tableName, columnName);
if (sequenceName != null) {
col = new ColumnMetaModel(schemaName, tableName,
columnName, sqlType,
- sqlTypeName, columnType,
Type.SEQUENCED,sequenceName);
+ sqlTypeName, columnType,
ColumnMetaModel.Type.SEQUENCED,sequenceName);
} else {
col = new ColumnMetaModel(schemaName, tableName,
columnName, sqlType,
- sqlTypeName, columnType, Type.PROVIDED, null);
+ sqlTypeName, columnType,
ColumnMetaModel.Type.PROVIDED, null);
}
}
-
cols.add(col);
}
-
- //Search indexes, they provide informations such as :
- // - Unique indexes may indicate 1:1 relations in complexe features
- // - Unique indexes can be used as primary key if no primary key
are defined
+ /*
+ * Search indexes, they provide informations such as:
+ * - Unique indexes may indicate 1:1 relations in complexe features
+ * - Unique indexes can be used as primary key if no primary key
are defined
+ */
final boolean pkEmpty = cols.isEmpty();
final List<String> names = new ArrayList<>();
final Map<String,List<String>> uniqueIndexes = new HashMap<>();
String indexname = null;
- //we can't cache this one, seems to be a bug in the driver, it
won't find anything for table name like '%'
+ // We can't cache this one, seems to be a bug in the driver, it
won't find anything for table name like '%'
cacheIndexInfos = new CachedResultSet(metadata.getIndexInfo(null,
schemaName, tableName, true, false),
Index.TABLE_SCHEM,
Index.TABLE_NAME,
Index.COLUMN_NAME,
Index.INDEX_NAME);
- final Iterator<Map<String,Object>> indexIte =
cacheIndexInfos.records().stream().filter(tableFilter).iterator();
+ final Iterator<Map<String,Object>> indexIte =
cacheIndexInfos.records.stream().filter(tableFilter).iterator();
while (indexIte.hasNext()) {
final Map<String,Object> result = indexIte.next();
final String columnName = (String)
result.get(Index.COLUMN_NAME);
@@ -454,8 +449,8 @@ public final class DataBaseModel {
lst.add(columnName);
if (pkEmpty) {
- //we use a single index columns set as primary key
- //we must not mix with other potential indexes.
+ // We use a single index columns set as primary key
+ // We must not mix with other potential indexes.
if (indexname == null) {
indexname = idxName;
} else if (!indexname.equals(idxName)) {
@@ -465,7 +460,7 @@ public final class DataBaseModel {
}
}
- //for each unique index composed of one column add a flag on the
property descriptor
+ // For each unique index composed of one column add a flag on the
property descriptor
for (Entry<String,List<String>> entry : uniqueIndexes.entrySet()) {
final List<String> columns = entry.getValue();
if (columns.size() == 1) {
@@ -480,8 +475,8 @@ public final class DataBaseModel {
}
if (pkEmpty && !names.isEmpty()) {
- //build a primary key from unique index
- final Iterator<Map<String,Object>> ite =
cacheColumns.records().stream().filter(tableFilter).iterator();
+ // Build a primary key from unique index
+ final Iterator<Map<String,Object>> ite =
cacheColumns.records.stream().filter(tableFilter).iterator();
while (ite.hasNext()) {
final Map<String,Object> result = ite.next();
final String columnName = (String)
result.get(Column.COLUMN_NAME);
@@ -493,10 +488,10 @@ public final class DataBaseModel {
final String sqlTypeName = (String)
result.get(Column.TYPE_NAME);
final Class<?> columnType = dialect.getJavaType(sqlType,
sqlTypeName);
final ColumnMetaModel col = new
ColumnMetaModel(schemaName, tableName, columnName,
- sqlType, sqlTypeName, columnType, Type.PROVIDED,
null);
+ sqlType, sqlTypeName, columnType,
ColumnMetaModel.Type.PROVIDED, null);
cols.add(col);
- //set as identifier
+ // Set as identifier
for (PropertyTypeBuilder desc : ftb.properties()) {
if
(desc.getName().tip().toString().equals(columnName)) {
final AttributeTypeBuilder<?> atb =
(AttributeTypeBuilder) desc;
@@ -510,15 +505,15 @@ public final class DataBaseModel {
if (cols.isEmpty()) {
if (Table.VALUE_TYPE_TABLE.equals(tableType)) {
- logger.log(Level.INFO, "No primary key found for {0}.",
tableName);
+ listeners.warning("No primary key found for " + tableName,
null);
}
}
table.key = new PrimaryKey(tableName, cols);
- //mark primary key columns
+ // Mark primary key columns
for (PropertyTypeBuilder desc : ftb.properties()) {
for (ColumnMetaModel col : cols) {
- if (desc.getName().tip().toString().equals(col.getName()))
{
+ if (desc.getName().tip().toString().equals(col.name)) {
final AttributeTypeBuilder<?> atb =
(AttributeTypeBuilder) desc;
atb.addRole(AttributeRole.IDENTIFIER_COMPONENT);
break;
@@ -527,12 +522,12 @@ public final class DataBaseModel {
}
- //find imported keys
-----------------------------------------------
+ // Find imported keys
-----------------------------------------------
final Predicate<Map<String,Object>> fkFilter = (Map<String,Object>
info) -> {
return Objects.equals(info.get(ImportedKey.FKTABLE_SCHEM),
schemaName)
&& Objects.equals(info.get(ImportedKey.FKTABLE_NAME),
tableName);
};
- Iterator<Map<String,Object>> ite =
cacheImportedKeys.records().stream().filter(fkFilter).iterator();
+ Iterator<Map<String,Object>> ite =
cacheImportedKeys.records.stream().filter(fkFilter).iterator();
while (ite.hasNext()) {
final Map<String,Object> result = ite.next();
String relationName = (String) result.get(ImportedKey.PK_NAME);
@@ -549,7 +544,7 @@ public final class DataBaseModel {
if (refSchemaName!=null &&
!visitedSchemas.contains(refSchemaName)) requieredSchemas.add(refSchemaName);
- //set the information
+ // Set the information
for (PropertyTypeBuilder desc : ftb.properties()) {
if (desc.getName().tip().toString().equals(localColumn)) {
final AttributeTypeBuilder<?> atb =
(AttributeTypeBuilder) desc;
@@ -559,12 +554,12 @@ public final class DataBaseModel {
}
}
- //find exported keys
-----------------------------------------------
+ // Find exported keys
-----------------------------------------------
final Predicate<Map<String,Object>> ekFilter = (Map<String,Object>
info) -> {
return Objects.equals(info.get(ImportedKey.PKTABLE_SCHEM),
schemaName)
&& Objects.equals(info.get(ImportedKey.PKTABLE_NAME),
tableName);
};
- ite =
cacheExportedKeys.records().stream().filter(ekFilter).iterator();
+ ite =
cacheExportedKeys.records.stream().filter(ekFilter).iterator();
while (ite.hasNext()) {
final Map<String,Object> result = ite.next();
String relationName = (String)
result.get(ExportedKey.FKCOLUMN_NAME);
@@ -581,7 +576,7 @@ public final class DataBaseModel {
if (refSchemaName != null &&
!visitedSchemas.contains(refSchemaName)) requieredSchemas.add(refSchemaName);
}
- //find parent table if any
-----------------------------------------
+ // Find parent table if any
-----------------------------------------
// if(handleSuperTableMetadata == null || handleSuperTableMetadata){
// try{
// result = metadata.getSuperTables(null, schemaName,
tableName);
@@ -599,53 +594,38 @@ public final class DataBaseModel {
// }
} catch (SQLException e) {
- throw new DataStoreException("Error occurred analyzing table : " +
tableName, e);
+ throw new DataStoreException("Error occurred analyzing table: " +
tableName, e);
}
-
ftb.setName(tableName);
table.tableType = ftb;
return table;
}
private AttributeType<?> analyzeColumn(final Map<String,Object> columnSet,
final Connection cx) throws SQLException, DataStoreException{
- final SQLDialect dialect = store.getDialect();
- final SingleAttributeTypeBuilder atb = new
SingleAttributeTypeBuilder();
-
- final String schemaName = (String)
columnSet.get(Column.TABLE_SCHEM);
- final String tableName = (String)
columnSet.get(Column.TABLE_NAME);
- final String columnName = (String)
columnSet.get(Column.COLUMN_NAME);
+ final String schemaName = (String)
columnSet.get(Column.TABLE_SCHEM);
+ final String tableName = (String)
columnSet.get(Column.TABLE_NAME);
+ final String columnName = (String)
columnSet.get(Column.COLUMN_NAME);
final int columnSize = ((Number)
columnSet.get(Column.COLUMN_SIZE)).intValue();
final int columnDataType = ((Number)
columnSet.get(Column.DATA_TYPE)).intValue();
- final String columnTypeName = (String) columnSet.get(Column.TYPE_NAME);
- final String columnNullable = (String)
columnSet.get(Column.IS_NULLABLE);
-
+ final String columnTypeName = (String)
columnSet.get(Column.TYPE_NAME);
+ final String columnNullable = (String)
columnSet.get(Column.IS_NULLABLE);
+ final SingleAttributeTypeBuilder atb = new
SingleAttributeTypeBuilder();
atb.setName(columnName);
atb.setLength(columnSize);
-
try {
dialect.decodeColumnType(atb, cx, columnTypeName, columnDataType,
schemaName, tableName, columnName);
} catch (SQLException e) {
- throw new DataStoreException("Error occurred analyzing column : "
+ columnName, e);
+ throw new DataStoreException("Error occurred analyzing column: " +
columnName, e);
}
-
atb.setMinimumOccurs(Column.VALUE_NO.equalsIgnoreCase(columnNullable)
? 1 : 0);
atb.setMaximumOccurs(1);
-
return atb.build();
}
/**
* Analyze the metadata of the ResultSet to rebuild a feature type.
- *
- * @param result
- * @param name
- * @return FeatureType
- * @throws SQLException
- * @throws org.apache.sis.storage.DataStoreException
*/
public FeatureType analyzeResult(final ResultSet result, final String
name) throws SQLException, DataStoreException{
- final SQLDialect dialect = store.getDialect();
-
final FeatureTypeBuilder ftb = new FeatureTypeBuilder();
ftb.setName(name);
@@ -661,7 +641,7 @@ public final class DataBaseModel {
final int sqlType = metadata.getColumnType(i);
final String sqlTypeName = metadata.getColumnTypeName(i);
- //search if we already have this property
+ // Search if we already have this property
PropertyType desc = null;
final SchemaMetaModel schema = getSchemaMetaModel(schemaName);
if (schema != null) {
@@ -698,24 +678,19 @@ public final class DataBaseModel {
} catch (SQLException e) {
throw new DataStoreException("Error occurred analyzing
column : " + columnName, e);
}
-
desc = atb.build();
}
-
ftb.addProperty(desc);
}
-
return ftb.build();
}
/**
* Rebuild simple feature types for each table.
*/
- private void reverseSimpleFeatureTypes(final Connection cx){
- final SQLDialect dialect = store.getDialect();
-
+ private void reverseSimpleFeatureTypes(final Connection cx) throws
SQLException {
for (final SchemaMetaModel schema : schemas.values()) {
- for (final TableMetaModel table : schema.tables.values()) {
+ for (final TableMetaModel table : schema.getTables()) {
final String tableName = table.name;
final FeatureTypeBuilder ftb = new
FeatureTypeBuilder(table.tableType.build());
@@ -732,28 +707,21 @@ public final class DataBaseModel {
atb.setName(name);
//Configure CRS if it is a geometry
- final Class binding = atb.getValueClass();
+ final Class<?> binding = atb.getValueClass();
if (Geometries.isKnownType(binding)) {
- final Predicate<Map> colFilter = (Map info) -> {
+ final Predicate<Map<?,?>> colFilter = (Map<?,?> info)
-> {
return Objects.equals(info.get(Table.TABLE_SCHEM),
schema.name)
&& Objects.equals(info.get(Table.TABLE_NAME),
tableName)
&&
Objects.equals(info.get(Column.COLUMN_NAME), name);
};
- final Map metas =
cacheColumns.records().stream().filter(colFilter).findFirst().get();
+ final Map<String,Object> metas =
cacheColumns.records.stream().filter(colFilter).findFirst().get();
- Integer srid = null;
CoordinateReferenceSystem crs = null;
- try {
- srid = dialect.getGeometrySRID(databaseSchema,
tableName, name, metas, cx);
- if (srid != null) {
- crs = dialect.createCRS(srid, cx);
- }
- } catch (SQLException e) {
- String msg = "Error occured determing srid for " +
tableName + "."+ name;
- logger.log(Level.WARNING, msg, e);
+ Integer srid = dialect.getGeometrySRID(databaseSchema,
tableName, name, metas, cx);
+ if (srid != null) {
+ crs = dialect.createCRS(srid, cx);
}
-
atb.setCRS(crs);
if (srid != null) {
atb.addCharacteristic(ColumnMetaModel.JDBC_PROPERTY_SRID).setDefaultValue(srid);
@@ -763,28 +731,19 @@ public final class DataBaseModel {
}
}
} else if (Coverage.class.isAssignableFrom(binding)) {
-
final Predicate<Map<String,Object>> colFilter =
(Map<String,Object> info) -> {
return Objects.equals(info.get(Table.TABLE_SCHEM),
schema.name)
&& Objects.equals(info.get(Table.TABLE_NAME),
tableName)
&&
Objects.equals(info.get(Column.COLUMN_NAME), name);
};
- final Map<String,Object> metas =
cacheColumns.records().stream().filter(colFilter).findFirst().get();
+ final Map<String,Object> metas =
cacheColumns.records.stream().filter(colFilter).findFirst().get();
- //add the attribute as a geometry, try to figure out
- // its srid first
- Integer srid = null;
+ // Add the attribute as a geometry, try to figure out
its srid first
CoordinateReferenceSystem crs = null;
- try {
- srid = dialect.getGeometrySRID(databaseSchema,
tableName, name, metas, cx);
- if (srid != null) {
- crs = dialect.createCRS(srid, cx);
- }
- } catch (SQLException e) {
- String msg = "Error occured determing srid for " +
tableName + "."+ name;
- logger.log(Level.WARNING, msg, e);
+ Integer srid = dialect.getGeometrySRID(databaseSchema,
tableName, name, metas, cx);
+ if (srid != null) {
+ crs = dialect.createCRS(srid, cx);
}
-
atb.setCRS(crs);
if (srid != null) {
atb.addCharacteristic(ColumnMetaModel.JDBC_PROPERTY_SRID).setDefaultValue(srid);
@@ -803,11 +762,8 @@ public final class DataBaseModel {
}
}
}
-
table.simpleFeatureType = ftb;
}
}
-
}
-
}
Modified:
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/reverse/InsertRelation.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/reverse/InsertRelation.java?rev=1829660&r1=1829659&r2=1829660&view=diff
==============================================================================
---
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/reverse/InsertRelation.java
[UTF-8] (original)
+++
sis/branches/JDK8/storage/sis-sql/src/main/java/org/apache/sis/internal/sql/reverse/InsertRelation.java
[UTF-8] Fri Apr 20 14:50:37 2018
@@ -23,15 +23,13 @@ import org.opengis.feature.Feature;
* When inserting a complex feature in base. it must be divided in smaller
elements.
* Those flat insertions and relations are represented by this class.
*
- * @author Johann Sorel (Geomatys)
+ * @author Johann Sorel (Geomatys)
* @version 1.0
* @since 1.0
* @module
*/
-public final class InsertRelation {
-
- public Feature parent;
- public Feature child;
- public RelationMetaModel relation;
-
+final class InsertRelation {
+ Feature parent;
+ Feature child;
+ RelationMetaModel relation;
}