Skip to content

Commit

Permalink
Fix some issues regarding to the new naming conventions
Browse files Browse the repository at this point in the history
  • Loading branch information
Emil Forslund committed Mar 1, 2016
1 parent 55a7d4c commit dcea29d
Show file tree
Hide file tree
Showing 7 changed files with 137 additions and 72 deletions.
20 changes: 0 additions & 20 deletions src/main/java/com/speedment/config/db/Dbms.java
Expand Up @@ -120,25 +120,6 @@ default String defaultConnectionUrl(Speedment speedment) throws SpeedmentExcepti
.getConnectionUrlGenerator().from(this); .getConnectionUrlGenerator().from(this);
} }


/**
* Determines the connection URL to use for this {@code Dbms} by first:
* <ol>
* <li>checking if the {@code CONNECTION_URL} property is set;
* <li>otherwise, calculate it using the {@link DbmsType}.
* </ol>
* If the current {@link DbmsType} can not be found by calling
* {@link DocumentDbUtil#dbmsTypeOf(Speedment, Dbms)}, a
* {@code SpeedmentException} will be thrown.
*
* @param speedment the speedment instance
* @return the connection URL to use
* @throws SpeedmentException if the {@link DbmsType} couldn't be found
*/
default String findConnectionUrl(Speedment speedment) throws SpeedmentException {
return getConnectionUrl()
.orElseGet(() -> defaultConnectionUrl(speedment));
}

/** /**
* Returns the database username to use when connecting to the dbms. If no * Returns the database username to use when connecting to the dbms. If no
* username is specified, {@code empty} is returned. * username is specified, {@code empty} is returned.
Expand All @@ -156,7 +137,6 @@ default Optional<String> getUsername() {
*/ */
Stream<? extends Schema> schemas(); Stream<? extends Schema> schemas();



@Override @Override
default Class<Dbms> mainInterface() { default Class<Dbms> mainInterface() {
return Dbms.class; return Dbms.class;
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/com/speedment/db/DatabaseNamingConvention.java
Expand Up @@ -17,6 +17,7 @@


import com.speedment.annotation.Api; import com.speedment.annotation.Api;
import com.speedment.config.db.Column; import com.speedment.config.db.Column;
import com.speedment.config.db.PrimaryKeyColumn;
import com.speedment.config.db.Table; import com.speedment.config.db.Table;
import java.util.Set; import java.util.Set;


Expand All @@ -29,6 +30,17 @@
@Api(version="2.3") @Api(version="2.3")
public interface DatabaseNamingConvention { public interface DatabaseNamingConvention {


/**
* Returns the full name used in the database for the specified
* {@link PrimaryKeyColumn}. This is typically constructed by combining the
* table and the column name with a separator, but that might be different
* in different implementations.
*
* @param pkc the primary key column to retreive the name of
* @return the full name
*/
String fullNameOf(PrimaryKeyColumn pkc);

/** /**
* Returns the full name used in the database for the specified * Returns the full name used in the database for the specified
* {@link Column}. This is typically constructed by combining the table and * {@link Column}. This is typically constructed by combining the table and
Expand Down
Expand Up @@ -17,6 +17,7 @@


import com.speedment.config.Document; import com.speedment.config.Document;
import com.speedment.config.db.Column; import com.speedment.config.db.Column;
import com.speedment.config.db.PrimaryKeyColumn;
import com.speedment.config.db.Schema; import com.speedment.config.db.Schema;
import com.speedment.config.db.Table; import com.speedment.config.db.Table;
import com.speedment.db.DatabaseNamingConvention; import com.speedment.db.DatabaseNamingConvention;
Expand All @@ -31,19 +32,24 @@
*/ */
public abstract class AbstractDatabaseNamingConvention public abstract class AbstractDatabaseNamingConvention
implements DatabaseNamingConvention { implements DatabaseNamingConvention {

@Override
public String fullNameOf(PrimaryKeyColumn pkc) {
return encloseField(pkc.getName());
}


@Override @Override
public String fullNameOf(Column column) { public String fullNameOf(Column column) {
return column.getParent().map(Table::getName) return encloseField(column.getParent().map(Table::getName)
.orElseThrow(() -> noParentException(column)) .orElseThrow(() -> noParentException(column)))
+ "." + column.getName(); + "." + encloseField(column.getName());
} }


@Override @Override
public String fullNameOf(Table table) { public String fullNameOf(Table table) {
return table.getParent().map(Schema::getName) return encloseField(table.getParent().map(Schema::getName)
.orElseThrow(() -> noParentException(table)) .orElseThrow(() -> noParentException(table)))
+ "." + table.getName(); + "." + encloseField(table.getName());
} }


@Override @Override
Expand Down
Expand Up @@ -56,6 +56,7 @@
import static com.speedment.internal.util.document.DocumentDbUtil.dbmsTypeOf; import static com.speedment.internal.util.document.DocumentDbUtil.dbmsTypeOf;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import static com.speedment.internal.core.stream.OptionalUtil.unwrap; import static com.speedment.internal.core.stream.OptionalUtil.unwrap;
import com.speedment.internal.util.document.DocumentDbUtil;
import static com.speedment.util.NullUtil.requireNonNulls; import static com.speedment.util.NullUtil.requireNonNulls;
import static java.util.Objects.requireNonNull; import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.toMap; import static java.util.stream.Collectors.toMap;
Expand Down Expand Up @@ -90,7 +91,7 @@ public Dbms getDbms() {


// Todo: Use DataSource instead: http://docs.oracle.com/javase/tutorial/jdbc/basics/sqldatasources.html // Todo: Use DataSource instead: http://docs.oracle.com/javase/tutorial/jdbc/basics/sqldatasources.html
public Connection getConnection() { public Connection getConnection() {
final String url = dbms.findConnectionUrl(speedment); final String url = DocumentDbUtil.findConnectionUrl(speedment, dbms);
final String user = unwrap(dbms.getUsername()); final String user = unwrap(dbms.getUsername());
final char[] password = unwrap(speedment.getPasswordComponent().get(dbms)); final char[] password = unwrap(speedment.getPasswordComponent().get(dbms));


Expand Down
Expand Up @@ -19,8 +19,6 @@
import com.speedment.Speedment; import com.speedment.Speedment;
import com.speedment.config.db.Column; import com.speedment.config.db.Column;
import com.speedment.config.db.Dbms; import com.speedment.config.db.Dbms;
import com.speedment.config.db.PrimaryKeyColumn;
import com.speedment.config.db.Schema;
import com.speedment.config.db.Table; import com.speedment.config.db.Table;
import com.speedment.config.db.parameters.DbmsType; import com.speedment.config.db.parameters.DbmsType;
import com.speedment.internal.core.manager.AbstractManager; import com.speedment.internal.core.manager.AbstractManager;
Expand Down Expand Up @@ -63,7 +61,6 @@
import static com.speedment.internal.util.document.DocumentDbUtil.dbmsTypeOf; import static com.speedment.internal.util.document.DocumentDbUtil.dbmsTypeOf;
import static com.speedment.internal.util.document.DocumentUtil.ancestor; import static com.speedment.internal.util.document.DocumentUtil.ancestor;
import static com.speedment.internal.core.stream.OptionalUtil.unwrap; import static com.speedment.internal.core.stream.OptionalUtil.unwrap;
import static com.speedment.internal.util.document.DocumentUtil.relativeName;
import static com.speedment.util.NullUtil.requireNonNulls; import static com.speedment.util.NullUtil.requireNonNulls;
import static java.util.Objects.requireNonNull; import static java.util.Objects.requireNonNull;


Expand All @@ -77,7 +74,6 @@ public abstract class AbstractSqlManager<ENTITY> extends AbstractManager<ENTITY>


private final LazyString sqlColumnList; private final LazyString sqlColumnList;
private final LazyString sqlColumnListQuestionMarks; private final LazyString sqlColumnListQuestionMarks;
private final Supplier<String> columnListSupplier = () -> sqlColumnList(Function.identity());
private SqlFunction<ResultSet, ENTITY> entityMapper; private SqlFunction<ResultSet, ENTITY> entityMapper;


protected AbstractSqlManager(Speedment speedment) { protected AbstractSqlManager(Speedment speedment) {
Expand All @@ -104,36 +100,14 @@ public <T> Stream<T> synchronousStreamOf(String sql, List<Object> values, SqlFun
return dbmsHandler().executeQuery(sql, values, rsMapper); return dbmsHandler().executeQuery(sql, values, rsMapper);
} }


public String sqlColumnList() { /**
return sqlColumnList.getOrCompute(columnListSupplier); * Returns a SQL statement string that counts the number of rows in the
} * current table.

*
private final Supplier<String> columnListWithQuestionMarkSupplier = () -> sqlColumnList(c -> "?"); * @return the count SQL statement

*/
public String sqlColumnListWithQuestionMarks() { public String sqlCount() {
return sqlColumnListQuestionMarks.getOrCompute(columnListWithQuestionMarkSupplier); return "select count(*) from " + sqlTableReference();
}

private String sqlColumnList(Function<String, String> postMapper) {
requireNonNull(postMapper);
return getTable().columns()
.map(Column::getName)
.map(this::quoteField)
.map(postMapper)
.collect(Collectors.joining(","));
}

public String sqlPrimaryKeyColumnList(Function<String, String> postMapper) {
requireNonNull(postMapper);
return getTable().primaryKeyColumns()
.map(PrimaryKeyColumn::getName)
.map(this::quoteField)
.map(postMapper)
.collect(Collectors.joining(" AND "));
}

public String sqlTableReference() {
return relativeName(getTable(), Schema.class, this::quoteField);
} }


public String sqlSelect(String suffix) { public String sqlSelect(String suffix) {
Expand Down Expand Up @@ -372,8 +346,73 @@ protected SQLXML getSQLXML(final ResultSet resultSet, final int ordinalPosition)
return getNullableFrom(resultSet, rs -> rs.getSQLXML(ordinalPosition)); return getNullableFrom(resultSet, rs -> rs.getSQLXML(ordinalPosition));
} }


private String quoteField(final String s) { /**
return getDbmsType().getDatabaseNamingConvention().encloseField(s); * Short-cut for retreiving the current {@link DatabaseNamingConvention}.
*
* @return the current naming convention
*/
private DatabaseNamingConvention naming() {
return getDbmsType().getDatabaseNamingConvention();
}

/**
* Returns a comma separated list of column names, fully formatted in
* accordance to the current {@link DbmsType}.
*
* @return the comma separated column list
*/
private String sqlColumnList() {
return sqlColumnList.getOrCompute(() -> sqlColumnList(c -> c));
}

/**
* Returns a comma separated list of question marks (?), fully formatted in
* accordance to the current {@link DbmsType} to represent column value
* wildcards.
*
* @return the comma separated question mark list
*/
private String sqlColumnListWithQuestionMarks() {
return sqlColumnListQuestionMarks.getOrCompute(() -> sqlColumnList(c -> "?"));
}

/**
* Returns a {@code AND} separated list of {@link PrimaryKeyColumn} database
* names, formatted in accordance to the current {@link DbmsType}.
*
* @return list of fully quoted primary key column names
*/
private String sqlColumnList(Function<String, String> postMapper) {
requireNonNull(postMapper);
return getTable().columns()
.map(naming()::fullNameOf)
.map(postMapper)
.collect(Collectors.joining(","));
}

/**
* Returns a {@code AND} separated list of {@link PrimaryKeyColumn} database
* names, formatted in accordance to the current {@link DbmsType}.
*
* @return list of fully quoted primary key column names
*/
private String sqlPrimaryKeyColumnList(Function<String, String> postMapper) {
requireNonNull(postMapper);
return getTable().primaryKeyColumns()
.map(naming()::fullNameOf)
.map(postMapper)
.collect(Collectors.joining(" AND "));
}

/**
* Returns the full name of a table formatted in accordance to the current
* {@link DbmsType}. The returned value will be within quotes if that is
* what the database expects.
*
* @return the full quoted table name
*/
private String sqlTableReference() {
return naming().fullNameOf(getTable());
} }


private <T> T getNullableFrom(ResultSet rs, SqlFunction<ResultSet, T> mapper) throws SQLException { private <T> T getNullableFrom(ResultSet rs, SqlFunction<ResultSet, T> mapper) throws SQLException {
Expand Down
Expand Up @@ -37,6 +37,7 @@
import com.speedment.field.trait.FieldTrait; import com.speedment.field.trait.FieldTrait;
import com.speedment.internal.core.stream.builder.streamterminator.StreamTerminatorUtil; import com.speedment.internal.core.stream.builder.streamterminator.StreamTerminatorUtil;
import com.speedment.stream.StreamDecorator; import com.speedment.stream.StreamDecorator;
import static com.speedment.util.NullUtil.requireNonNulls;
import java.util.ArrayList; import java.util.ArrayList;
import static java.util.Objects.requireNonNull; import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.joining; import static java.util.stream.Collectors.joining;
Expand Down Expand Up @@ -96,8 +97,8 @@ public void modifySource(final List<SpeedmentPredicate<ENTITY, ?, ?>> predicateB
.map(spv::transform) .map(spv::transform)
.collect(toList()); .collect(toList());


final String sql = manager.sqlSelect(" where " final String sql = manager.sqlSelect(" where " +
+ fragments.stream() fragments.stream()
.map(SqlPredicateFragment::getSql) .map(SqlPredicateFragment::getSql)
.collect(joining(" AND ")) .collect(joining(" AND "))
); );
Expand Down Expand Up @@ -148,19 +149,24 @@ public <T> long count(ReferencePipeline<T> pipeline) {
private static final Predicate<Action<?, ?>> CHECK_RETAIN_SIZE = action -> action.is(PRESERVE, SIZE); private static final Predicate<Action<?, ?>> CHECK_RETAIN_SIZE = action -> action.is(PRESERVE, SIZE);


/** /**
* Optimizer for count operations! * Optimizer for count operations.
* *
* @param pipeline * @param pipeline the pipeline
* @param fallbackSupplier * @param fallbackSupplier a fallback supplier should every item be size
* retaining
* @return the number of rows * @return the number of rows
*/ */
private long countHelper(Pipeline pipeline, LongSupplier fallbackSupplier) { private long countHelper(Pipeline pipeline, LongSupplier fallbackSupplier) {
requireNonNull(pipeline); requireNonNulls(pipeline, fallbackSupplier);
requireNonNull(fallbackSupplier);
if (pipeline.stream().allMatch(CHECK_RETAIN_SIZE)) { if (pipeline.stream().allMatch(CHECK_RETAIN_SIZE)) {
final String sql = "select count(*) from " + manager.sqlTableReference(); return manager.synchronousStreamOf(
return manager.synchronousStreamOf(sql, Collections.emptyList(), rs -> rs.getLong(1)).findAny().get(); manager.sqlCount(),
Collections.emptyList(),
rs -> rs.getLong(1)
).findAny().get();
} }

return fallbackSupplier.getAsLong(); return fallbackSupplier.getAsLong();
} }


Expand Down
Expand Up @@ -182,6 +182,27 @@ public static Stream<? extends Document> typedChildrenOf(Table table) {
table.foreignKeys().map(Document.class::cast) table.foreignKeys().map(Document.class::cast)
); );
} }

/**
* Determines the connection URL to use for the specified {@code Dbms} by
* first:
* <ol>
* <li>checking if the {@code CONNECTION_URL} property is set;
* <li>otherwise, calculate it using the {@link DbmsType}.
* </ol>
* If the {@link DbmsType} can not be found by calling
* {@link DocumentDbUtil#dbmsTypeOf(Speedment, Dbms)}, a
* {@code SpeedmentException} will be thrown.
*
* @param speedment the speedment instance
* @param dbms the database manager
* @return the connection URL to use
* @throws SpeedmentException if the {@link DbmsType} couldn't be found
*/
public static String findConnectionUrl(Speedment speedment, Dbms dbms) throws SpeedmentException {
return dbms.getConnectionUrl()
.orElseGet(() -> dbms.defaultConnectionUrl(speedment));
}


/** /**
* Utility classes should not be instantiated. * Utility classes should not be instantiated.
Expand Down

0 comments on commit dcea29d

Please sign in to comment.