HHH-13496 Pre-compile and reuse regular expressions
This commit is contained in:
parent
bfc66ec356
commit
70d33e0c6b
|
@ -9,12 +9,21 @@ package org.hibernate.boot.model.source.internal.hbm;
|
|||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
* @author Sanne Grinovero
|
||||
*/
|
||||
public class CommaSeparatedStringHelper {
|
||||
public final class CommaSeparatedStringHelper {
|
||||
|
||||
private static final Pattern COMMA_SEPARATED_PATTERN = Pattern.compile( "\\s*,\\s*" );
|
||||
|
||||
private CommaSeparatedStringHelper() {
|
||||
}
|
||||
|
||||
|
@ -22,21 +31,25 @@ public class CommaSeparatedStringHelper {
|
|||
if ( values == null || values.isEmpty() ) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
HashSet<String> set = new HashSet<String>();
|
||||
Collections.addAll( set, values.split( "\\s*,\\s*" ) );
|
||||
return set;
|
||||
return COMMA_SEPARATED_PATTERN.splitAsStream( values ).collect( Collectors.toSet() );
|
||||
}
|
||||
|
||||
public static Set<String> splitAndCombine(Set<String> x, String values) {
|
||||
if ( x.isEmpty() && (values == null || values.isEmpty()) ) {
|
||||
if ( x.isEmpty() && ( values == null || values.isEmpty() ) ) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
HashSet<String> set = new HashSet<String>( x );
|
||||
if ( values != null && !values.isEmpty() ) {
|
||||
Collections.addAll( set, values.split( "\\s*,\\s*" ) );
|
||||
Collections.addAll( set, COMMA_SEPARATED_PATTERN.split( values ) );
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
public static List<String> parseCommaSeparatedString(String incomingString) {
|
||||
if ( StringHelper.isEmpty( incomingString ) ) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return COMMA_SEPARATED_PATTERN.splitAsStream( incomingString ).collect( Collectors.toList() );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
*/
|
||||
package org.hibernate.boot.model.source.spi;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
|
||||
/**
|
||||
|
@ -14,6 +17,11 @@ import org.hibernate.internal.util.StringHelper;
|
|||
public abstract class AbstractAttributeKey {
|
||||
// todo : replace this with "{element}"
|
||||
private static final String COLLECTION_ELEMENT = "collection&&element";
|
||||
private static final String DOT_COLLECTION_ELEMENT = '.' + COLLECTION_ELEMENT;
|
||||
private static final Pattern DOT_COLLECTION_ELEMENT_PATTERN = Pattern.compile(
|
||||
DOT_COLLECTION_ELEMENT,
|
||||
Pattern.LITERAL
|
||||
);
|
||||
|
||||
private final AbstractAttributeKey parent;
|
||||
private final String property;
|
||||
|
@ -130,11 +138,11 @@ public abstract class AbstractAttributeKey {
|
|||
* marker ({@link #COLLECTION_ELEMENT}.
|
||||
*/
|
||||
public boolean isPartOfCollectionElement() {
|
||||
return fullPath.contains( '.' + COLLECTION_ELEMENT );
|
||||
return fullPath.contains( DOT_COLLECTION_ELEMENT );
|
||||
}
|
||||
|
||||
public String stripCollectionElementMarker() {
|
||||
return fullPath.replace( '.' + COLLECTION_ELEMENT, "" );
|
||||
return DOT_COLLECTION_ELEMENT_PATTERN.matcher( fullPath ).replaceAll( Matcher.quoteReplacement( "" ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -14,6 +14,7 @@ import java.sql.Clob;
|
|||
import java.sql.Connection;
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.NClob;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
|
@ -25,12 +26,17 @@ import java.util.Locale;
|
|||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.hibernate.Criteria;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.Interceptor;
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.LockOptions;
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.NullPrecedence;
|
||||
import org.hibernate.Query;
|
||||
import org.hibernate.ScrollMode;
|
||||
import org.hibernate.boot.model.TypeContributions;
|
||||
import org.hibernate.boot.model.relational.AuxiliaryDatabaseObject;
|
||||
|
@ -73,6 +79,7 @@ import org.hibernate.exception.spi.SQLExceptionConverter;
|
|||
import org.hibernate.exception.spi.ViolatedConstraintNameExtracter;
|
||||
import org.hibernate.hql.spi.id.MultiTableBulkIdStrategy;
|
||||
import org.hibernate.hql.spi.id.persistent.PersistentTableBulkIdStrategy;
|
||||
import org.hibernate.id.IdentifierGenerator;
|
||||
import org.hibernate.id.IdentityGenerator;
|
||||
import org.hibernate.id.enhanced.SequenceStyleGenerator;
|
||||
import org.hibernate.internal.CoreLogging;
|
||||
|
@ -96,6 +103,7 @@ import org.hibernate.sql.ANSIJoinFragment;
|
|||
import org.hibernate.sql.CaseFragment;
|
||||
import org.hibernate.sql.ForUpdateFragment;
|
||||
import org.hibernate.sql.JoinFragment;
|
||||
import org.hibernate.tool.hbm2ddl.SchemaUpdate;
|
||||
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorLegacyImpl;
|
||||
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorNoOpImpl;
|
||||
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
|
||||
|
@ -107,6 +115,7 @@ import org.hibernate.tool.schema.internal.StandardTableExporter;
|
|||
import org.hibernate.tool.schema.internal.StandardUniqueKeyExporter;
|
||||
import org.hibernate.tool.schema.spi.Exporter;
|
||||
import org.hibernate.type.StandardBasicTypes;
|
||||
import org.hibernate.type.Type;
|
||||
import org.hibernate.type.descriptor.sql.ClobTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
|
||||
|
||||
|
@ -140,6 +149,11 @@ public abstract class Dialect implements ConversionContext {
|
|||
* Characters used as closing for quoting SQL identifiers
|
||||
*/
|
||||
public static final String CLOSED_QUOTE = "`\"]";
|
||||
private static final Pattern SINGLE_QUOTE_PATTERN = Pattern.compile(
|
||||
"'",
|
||||
Pattern.LITERAL
|
||||
);
|
||||
public static final String TWO_SINGLE_QUOTES_REPLACEMENT = Matcher.quoteReplacement( "''" );
|
||||
|
||||
private final TypeNames typeNames = new TypeNames();
|
||||
private final TypeNames hibernateTypeNames = new TypeNames();
|
||||
|
@ -325,9 +339,9 @@ public abstract class Dialect implements ConversionContext {
|
|||
|
||||
/**
|
||||
* Get the name of the database type associated with the given
|
||||
* {@link java.sql.Types} typecode.
|
||||
* {@link Types} typecode.
|
||||
*
|
||||
* @param code The {@link java.sql.Types} typecode
|
||||
* @param code The {@link Types} typecode
|
||||
* @return the database type name
|
||||
* @throws HibernateException If no mapping was specified for that type.
|
||||
*/
|
||||
|
@ -341,10 +355,10 @@ public abstract class Dialect implements ConversionContext {
|
|||
|
||||
/**
|
||||
* Get the name of the database type associated with the given
|
||||
* {@link java.sql.Types} typecode with the given storage specification
|
||||
* {@link Types} typecode with the given storage specification
|
||||
* parameters.
|
||||
*
|
||||
* @param code The {@link java.sql.Types} typecode
|
||||
* @param code The {@link Types} typecode
|
||||
* @param length The datatype length
|
||||
* @param precision The datatype precision
|
||||
* @param scale The datatype scale
|
||||
|
@ -363,9 +377,9 @@ public abstract class Dialect implements ConversionContext {
|
|||
|
||||
/**
|
||||
* Get the name of the database type appropriate for casting operations
|
||||
* (via the CAST() SQL function) for the given {@link java.sql.Types} typecode.
|
||||
* (via the CAST() SQL function) for the given {@link Types} typecode.
|
||||
*
|
||||
* @param code The {@link java.sql.Types} typecode
|
||||
* @param code The {@link Types} typecode
|
||||
* @return The database type name
|
||||
*/
|
||||
public String getCastTypeName(int code) {
|
||||
|
@ -427,7 +441,7 @@ public abstract class Dialect implements ConversionContext {
|
|||
* column length. <tt>$l</tt> in the type name with be replaced by the
|
||||
* column length (if appropriate).
|
||||
*
|
||||
* @param code The {@link java.sql.Types} typecode
|
||||
* @param code The {@link Types} typecode
|
||||
* @param capacity The maximum length of database type
|
||||
* @param name The database type name
|
||||
*/
|
||||
|
@ -439,7 +453,7 @@ public abstract class Dialect implements ConversionContext {
|
|||
* Subclasses register a type name for the given type code. <tt>$l</tt> in
|
||||
* the type name with be replaced by the column length (if appropriate).
|
||||
*
|
||||
* @param code The {@link java.sql.Types} typecode
|
||||
* @param code The {@link Types} typecode
|
||||
* @param name The database type name
|
||||
*/
|
||||
protected void registerColumnType(int code, String name) {
|
||||
|
@ -450,7 +464,7 @@ public abstract class Dialect implements ConversionContext {
|
|||
* Allows the dialect to override a {@link SqlTypeDescriptor}.
|
||||
* <p/>
|
||||
* If the passed {@code sqlTypeDescriptor} allows itself to be remapped (per
|
||||
* {@link org.hibernate.type.descriptor.sql.SqlTypeDescriptor#canBeRemapped()}), then this method uses
|
||||
* {@link SqlTypeDescriptor#canBeRemapped()}), then this method uses
|
||||
* {@link #getSqlTypeDescriptorOverride} to get an optional override based on the SQL code returned by
|
||||
* {@link SqlTypeDescriptor#getSqlType()}.
|
||||
* <p/>
|
||||
|
@ -648,11 +662,11 @@ public abstract class Dialect implements ConversionContext {
|
|||
// hibernate type mapping support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
/**
|
||||
* Get the name of the Hibernate {@link org.hibernate.type.Type} associated with the given
|
||||
* {@link java.sql.Types} type code.
|
||||
* Get the name of the Hibernate {@link Type} associated with the given
|
||||
* {@link Types} type code.
|
||||
*
|
||||
* @param code The {@link java.sql.Types} type code
|
||||
* @return The Hibernate {@link org.hibernate.type.Type} name.
|
||||
* @param code The {@link Types} type code
|
||||
* @return The Hibernate {@link Type} name.
|
||||
* @throws HibernateException If no mapping was specified for that type.
|
||||
*/
|
||||
@SuppressWarnings( {"UnusedDeclaration"})
|
||||
|
@ -677,15 +691,15 @@ public abstract class Dialect implements ConversionContext {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get the name of the Hibernate {@link org.hibernate.type.Type} associated
|
||||
* with the given {@link java.sql.Types} typecode with the given storage
|
||||
* Get the name of the Hibernate {@link Type} associated
|
||||
* with the given {@link Types} typecode with the given storage
|
||||
* specification parameters.
|
||||
*
|
||||
* @param code The {@link java.sql.Types} typecode
|
||||
* @param code The {@link Types} typecode
|
||||
* @param length The datatype length
|
||||
* @param precision The datatype precision
|
||||
* @param scale The datatype scale
|
||||
* @return The Hibernate {@link org.hibernate.type.Type} name.
|
||||
* @return The Hibernate {@link Type} name.
|
||||
* @throws HibernateException If no mapping was specified for that type.
|
||||
*/
|
||||
public String getHibernateTypeName(int code, int length, int precision, int scale) throws HibernateException {
|
||||
|
@ -703,23 +717,23 @@ public abstract class Dialect implements ConversionContext {
|
|||
}
|
||||
|
||||
/**
|
||||
* Registers a Hibernate {@link org.hibernate.type.Type} name for the given
|
||||
* {@link java.sql.Types} type code and maximum column length.
|
||||
* Registers a Hibernate {@link Type} name for the given
|
||||
* {@link Types} type code and maximum column length.
|
||||
*
|
||||
* @param code The {@link java.sql.Types} typecode
|
||||
* @param code The {@link Types} typecode
|
||||
* @param capacity The maximum length of database type
|
||||
* @param name The Hibernate {@link org.hibernate.type.Type} name
|
||||
* @param name The Hibernate {@link Type} name
|
||||
*/
|
||||
protected void registerHibernateType(int code, long capacity, String name) {
|
||||
hibernateTypeNames.put( code, capacity, name );
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a Hibernate {@link org.hibernate.type.Type} name for the given
|
||||
* {@link java.sql.Types} type code.
|
||||
* Registers a Hibernate {@link Type} name for the given
|
||||
* {@link Types} type code.
|
||||
*
|
||||
* @param code The {@link java.sql.Types} typecode
|
||||
* @param name The Hibernate {@link org.hibernate.type.Type} name
|
||||
* @param code The {@link Types} typecode
|
||||
* @param name The Hibernate {@link Type} name
|
||||
*/
|
||||
protected void registerHibernateType(int code, String name) {
|
||||
hibernateTypeNames.put( code, name );
|
||||
|
@ -736,7 +750,7 @@ public abstract class Dialect implements ConversionContext {
|
|||
|
||||
/**
|
||||
* Retrieves a map of the dialect's registered functions
|
||||
* (functionName => {@link org.hibernate.dialect.function.SQLFunction}).
|
||||
* (functionName => {@link SQLFunction}).
|
||||
*
|
||||
* @return The map of registered functions.
|
||||
*/
|
||||
|
@ -748,7 +762,7 @@ public abstract class Dialect implements ConversionContext {
|
|||
// native identifier generation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
/**
|
||||
* The class (which implements {@link org.hibernate.id.IdentifierGenerator})
|
||||
* The class (which implements {@link IdentifierGenerator})
|
||||
* which acts as this dialects native generation strategy.
|
||||
* <p/>
|
||||
* Comes into play whenever the user specifies the native generator.
|
||||
|
@ -947,7 +961,7 @@ public abstract class Dialect implements ConversionContext {
|
|||
* Get the select command used retrieve the names of all sequences.
|
||||
*
|
||||
* @return The select command; or null if sequences are not supported.
|
||||
* @see org.hibernate.tool.hbm2ddl.SchemaUpdate
|
||||
* @see SchemaUpdate
|
||||
*/
|
||||
public String getQuerySequencesString() {
|
||||
return null;
|
||||
|
@ -1129,8 +1143,8 @@ public abstract class Dialect implements ConversionContext {
|
|||
*
|
||||
* @param zeroBasedFirstResult The user-supplied, zero-based first row offset.
|
||||
* @return The corresponding db/dialect specific offset.
|
||||
* @see org.hibernate.Query#setFirstResult
|
||||
* @see org.hibernate.Criteria#setFirstResult
|
||||
* @see Query#setFirstResult
|
||||
* @see Criteria#setFirstResult
|
||||
* @deprecated {@link #getLimitHandler()} should be overridden instead.
|
||||
*/
|
||||
@Deprecated
|
||||
|
@ -1156,7 +1170,7 @@ public abstract class Dialect implements ConversionContext {
|
|||
* If this dialect supports specifying lock timeouts, are those timeouts
|
||||
* rendered into the <tt>SQL</tt> string as parameters. The implication
|
||||
* is that Hibernate will need to bind the timeout value as a parameter
|
||||
* in the {@link java.sql.PreparedStatement}. If true, the param position
|
||||
* in the {@link PreparedStatement}. If true, the param position
|
||||
* is always handled as the last parameter; if the dialect specifies the
|
||||
* lock timeout elsewhere in the <tt>SQL</tt> statement then the timeout
|
||||
* value should be directly rendered into the statement and this method
|
||||
|
@ -1498,7 +1512,7 @@ public abstract class Dialect implements ConversionContext {
|
|||
|
||||
/**
|
||||
* Registers a parameter (either OUT, or the new REF_CURSOR param type available in Java 8) capable of
|
||||
* returning {@link java.sql.ResultSet} *by position*. Pre-Java 8, registering such ResultSet-returning
|
||||
* returning {@link ResultSet} *by position*. Pre-Java 8, registering such ResultSet-returning
|
||||
* parameters varied greatly across database and drivers; hence its inclusion as part of the Dialect contract.
|
||||
*
|
||||
* @param statement The callable statement.
|
||||
|
@ -1517,7 +1531,7 @@ public abstract class Dialect implements ConversionContext {
|
|||
|
||||
/**
|
||||
* Registers a parameter (either OUT, or the new REF_CURSOR param type available in Java 8) capable of
|
||||
* returning {@link java.sql.ResultSet} *by name*. Pre-Java 8, registering such ResultSet-returning
|
||||
* returning {@link ResultSet} *by name*. Pre-Java 8, registering such ResultSet-returning
|
||||
* parameters varied greatly across database and drivers; hence its inclusion as part of the Dialect contract.
|
||||
*
|
||||
* @param statement The callable statement.
|
||||
|
@ -1537,7 +1551,7 @@ public abstract class Dialect implements ConversionContext {
|
|||
|
||||
/**
|
||||
* Given a callable statement previously processed by {@link #registerResultSetOutParameter},
|
||||
* extract the {@link java.sql.ResultSet} from the OUT parameter.
|
||||
* extract the {@link ResultSet} from the OUT parameter.
|
||||
*
|
||||
* @param statement The callable statement.
|
||||
* @return The extracted result set.
|
||||
|
@ -1551,7 +1565,7 @@ public abstract class Dialect implements ConversionContext {
|
|||
|
||||
/**
|
||||
* Given a callable statement previously processed by {@link #registerResultSetOutParameter},
|
||||
* extract the {@link java.sql.ResultSet}.
|
||||
* extract the {@link ResultSet}.
|
||||
*
|
||||
* @param statement The callable statement.
|
||||
* @param position The bind position at which to register the output param.
|
||||
|
@ -1569,7 +1583,7 @@ public abstract class Dialect implements ConversionContext {
|
|||
|
||||
/**
|
||||
* Given a callable statement previously processed by {@link #registerResultSetOutParameter},
|
||||
* extract the {@link java.sql.ResultSet} from the OUT parameter.
|
||||
* extract the {@link ResultSet} from the OUT parameter.
|
||||
*
|
||||
* @param statement The callable statement.
|
||||
* @param name The parameter name (for drivers which support named parameters).
|
||||
|
@ -1711,14 +1725,14 @@ public abstract class Dialect implements ConversionContext {
|
|||
// union subclass support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
/**
|
||||
* Given a {@link java.sql.Types} type code, determine an appropriate
|
||||
* Given a {@link Types} type code, determine an appropriate
|
||||
* null value to use in a select clause.
|
||||
* <p/>
|
||||
* One thing to consider here is that certain databases might
|
||||
* require proper casting for the nulls here since the select here
|
||||
* will be part of a UNION/UNION ALL.
|
||||
*
|
||||
* @param sqlType The {@link java.sql.Types} type code.
|
||||
* @param sqlType The {@link Types} type code.
|
||||
* @return The appropriate select clause value fragment.
|
||||
*/
|
||||
public String getSelectClauseNullString(int sqlType) {
|
||||
|
@ -1740,21 +1754,21 @@ public abstract class Dialect implements ConversionContext {
|
|||
|
||||
|
||||
/**
|
||||
* Create a {@link org.hibernate.sql.JoinFragment} strategy responsible
|
||||
* Create a {@link JoinFragment} strategy responsible
|
||||
* for handling this dialect's variations in how joins are handled.
|
||||
*
|
||||
* @return This dialect's {@link org.hibernate.sql.JoinFragment} strategy.
|
||||
* @return This dialect's {@link JoinFragment} strategy.
|
||||
*/
|
||||
public JoinFragment createOuterJoinFragment() {
|
||||
return new ANSIJoinFragment();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link org.hibernate.sql.CaseFragment} strategy responsible
|
||||
* Create a {@link CaseFragment} strategy responsible
|
||||
* for handling this dialect's variations in how CASE statements are
|
||||
* handled.
|
||||
*
|
||||
* @return This dialect's {@link org.hibernate.sql.CaseFragment} strategy.
|
||||
* @return This dialect's {@link CaseFragment} strategy.
|
||||
*/
|
||||
public CaseFragment createCaseFragment() {
|
||||
return new ANSICaseFragment();
|
||||
|
@ -1813,7 +1827,7 @@ public abstract class Dialect implements ConversionContext {
|
|||
* to the database and perhaps manipulate them in some fashion.
|
||||
* <p/>
|
||||
* The recommend approach is to instead use
|
||||
* {@link org.hibernate.Interceptor#onPrepareStatement(String)}.
|
||||
* {@link Interceptor#onPrepareStatement(String)}.
|
||||
*
|
||||
* @param select The select command
|
||||
* @return The mutated select command, or the same as was passed in.
|
||||
|
@ -2052,7 +2066,7 @@ public abstract class Dialect implements ConversionContext {
|
|||
* Get the SQL command used to retrieve the current schema name. Works in conjunction
|
||||
* with {@link #getSchemaNameResolver()}, unless the return from there does not need this
|
||||
* information. E.g., a custom impl might make use of the Java 1.7 addition of
|
||||
* the {@link java.sql.Connection#getSchema()} method
|
||||
* the {@link Connection#getSchema()} method
|
||||
*
|
||||
* @return The current schema retrieval SQL
|
||||
*/
|
||||
|
@ -2418,7 +2432,7 @@ public abstract class Dialect implements ConversionContext {
|
|||
|
||||
/**
|
||||
* Should LOBs (both BLOB and CLOB) be bound using stream operations (i.e.
|
||||
* {@link java.sql.PreparedStatement#setBinaryStream}).
|
||||
* {@link PreparedStatement#setBinaryStream}).
|
||||
*
|
||||
* @return True if BLOBs and CLOBs should be bound using stream operations.
|
||||
* @since 3.2
|
||||
|
@ -2493,14 +2507,14 @@ public abstract class Dialect implements ConversionContext {
|
|||
* Does this dialect support asking the result set its positioning
|
||||
* information on forward only cursors. Specifically, in the case of
|
||||
* scrolling fetches, Hibernate needs to use
|
||||
* {@link java.sql.ResultSet#isAfterLast} and
|
||||
* {@link java.sql.ResultSet#isBeforeFirst}. Certain drivers do not
|
||||
* {@link ResultSet#isAfterLast} and
|
||||
* {@link ResultSet#isBeforeFirst}. Certain drivers do not
|
||||
* allow access to these methods for forward only cursors.
|
||||
* <p/>
|
||||
* NOTE : this is highly driver dependent!
|
||||
*
|
||||
* @return True if methods like {@link java.sql.ResultSet#isAfterLast} and
|
||||
* {@link java.sql.ResultSet#isBeforeFirst} are supported for forward
|
||||
* @return True if methods like {@link ResultSet#isAfterLast} and
|
||||
* {@link ResultSet#isBeforeFirst} are supported for forward
|
||||
* only cursors; false otherwise.
|
||||
* @since 3.2
|
||||
*/
|
||||
|
@ -2559,17 +2573,17 @@ public abstract class Dialect implements ConversionContext {
|
|||
* locator instance...
|
||||
* <p/>
|
||||
* For BLOBs, the internal value might be changed by:
|
||||
* {@link java.sql.Blob#setBinaryStream},
|
||||
* {@link java.sql.Blob#setBytes(long, byte[])},
|
||||
* {@link java.sql.Blob#setBytes(long, byte[], int, int)},
|
||||
* or {@link java.sql.Blob#truncate(long)}.
|
||||
* {@link Blob#setBinaryStream},
|
||||
* {@link Blob#setBytes(long, byte[])},
|
||||
* {@link Blob#setBytes(long, byte[], int, int)},
|
||||
* or {@link Blob#truncate(long)}.
|
||||
* <p/>
|
||||
* For CLOBs, the internal value might be changed by:
|
||||
* {@link java.sql.Clob#setAsciiStream(long)},
|
||||
* {@link java.sql.Clob#setCharacterStream(long)},
|
||||
* {@link java.sql.Clob#setString(long, String)},
|
||||
* {@link java.sql.Clob#setString(long, String, int, int)},
|
||||
* or {@link java.sql.Clob#truncate(long)}.
|
||||
* {@link Clob#setAsciiStream(long)},
|
||||
* {@link Clob#setCharacterStream(long)},
|
||||
* {@link Clob#setString(long, String)},
|
||||
* {@link Clob#setString(long, String, int, int)},
|
||||
* or {@link Clob#truncate(long)}.
|
||||
* <p/>
|
||||
* NOTE : I do not know the correct answer currently for
|
||||
* databases which (1) are not part of the cruise control process
|
||||
|
@ -2976,7 +2990,7 @@ public abstract class Dialect implements ConversionContext {
|
|||
}
|
||||
|
||||
/**
|
||||
* Check whether the JDBC {@link java.sql.Connection} supports creating LOBs via {@link Connection#createBlob()},
|
||||
* Check whether the JDBC {@link Connection} supports creating LOBs via {@link Connection#createBlob()},
|
||||
* {@link Connection#createNClob()} or {@link Connection#createClob()}.
|
||||
*
|
||||
* @param databaseMetaData JDBC {@link DatabaseMetaData} which can be used if LOB creation is supported only starting from a given Driver version
|
||||
|
@ -2993,7 +3007,7 @@ public abstract class Dialect implements ConversionContext {
|
|||
* @return escaped String
|
||||
*/
|
||||
protected String escapeLiteral(String literal) {
|
||||
return literal.replace("'", "''");
|
||||
return SINGLE_QUOTE_PATTERN.matcher( literal ).replaceAll( TWO_SINGLE_QUOTES_REPLACEMENT );
|
||||
}
|
||||
|
||||
private void resolveLegacyLimitHandlerBehavior(ServiceRegistry serviceRegistry) {
|
||||
|
|
|
@ -10,6 +10,8 @@ import java.sql.CallableStatement;
|
|||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.hibernate.JDBCException;
|
||||
import org.hibernate.NullPrecedence;
|
||||
|
@ -45,6 +47,12 @@ import org.hibernate.type.StandardBasicTypes;
|
|||
@SuppressWarnings("deprecation")
|
||||
public class MySQLDialect extends Dialect {
|
||||
|
||||
private static final Pattern ESCAPE_PATTERN = Pattern.compile(
|
||||
"\\",
|
||||
Pattern.LITERAL
|
||||
);
|
||||
public static final String ESCAPE_PATTERN_REPLACEMENT = Matcher.quoteReplacement(
|
||||
"\\\\" );
|
||||
private final UniqueDelegate uniqueDelegate;
|
||||
private final MySQLStorageEngine storageEngine;
|
||||
|
||||
|
@ -593,6 +601,6 @@ public class MySQLDialect extends Dialect {
|
|||
|
||||
@Override
|
||||
protected String escapeLiteral(String literal) {
|
||||
return super.escapeLiteral( literal ).replace("\\", "\\\\");
|
||||
return ESCAPE_PATTERN.matcher( super.escapeLiteral( literal ) ).replaceAll( ESCAPE_PATTERN_REPLACEMENT );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ import java.util.LinkedHashSet;
|
|||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.boot.model.source.internal.hbm.CommaSeparatedStringHelper;
|
||||
import org.hibernate.engine.jdbc.cursor.internal.StandardRefCursorSupport;
|
||||
import org.hibernate.engine.jdbc.env.spi.ExtractedDatabaseMetaData;
|
||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||
|
@ -207,12 +208,7 @@ public class ExtractedDatabaseMetaDataImpl implements ExtractedDatabaseMetaData
|
|||
}
|
||||
|
||||
private Set<String> parseKeywords(String extraKeywordsString) {
|
||||
if ( StringHelper.isEmpty( extraKeywordsString ) ) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
final Set<String> keywordSet = new HashSet<String>( Arrays.asList( extraKeywordsString.split( "\\s*,\\s*" ) ) );
|
||||
return keywordSet;
|
||||
return CommaSeparatedStringHelper.split( extraKeywordsString );
|
||||
}
|
||||
|
||||
public Builder setConnectionSchemaName(String connectionSchemaName) {
|
||||
|
|
|
@ -63,10 +63,6 @@ public class IdentifierHelperBuilder {
|
|||
}
|
||||
|
||||
private static List<String> parseKeywords(String extraKeywordsString) {
|
||||
if ( StringHelper.isEmpty( extraKeywordsString ) ) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return StringHelper.parseCommaSeparatedString( extraKeywordsString );
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
import java.util.TimeZone;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.naming.Reference;
|
||||
import javax.naming.StringRefAddr;
|
||||
import javax.persistence.EntityGraph;
|
||||
|
@ -108,7 +109,9 @@ import org.hibernate.persister.entity.Loadable;
|
|||
import org.hibernate.procedure.ProcedureCall;
|
||||
import org.hibernate.proxy.EntityNotFoundDelegate;
|
||||
import org.hibernate.proxy.HibernateProxyHelper;
|
||||
import org.hibernate.query.NativeQuery;
|
||||
import org.hibernate.query.criteria.internal.CriteriaBuilderImpl;
|
||||
import org.hibernate.query.spi.NamedQueryRepository;
|
||||
import org.hibernate.resource.jdbc.spi.PhysicalConnectionHandlingMode;
|
||||
import org.hibernate.resource.jdbc.spi.StatementInspector;
|
||||
import org.hibernate.resource.transaction.backend.jta.internal.synchronization.AfterCompletionAction;
|
||||
|
@ -155,6 +158,7 @@ import static org.hibernate.metamodel.internal.JpaMetaModelPopulationSetting.det
|
|||
*/
|
||||
public final class SessionFactoryImpl implements SessionFactoryImplementor {
|
||||
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( SessionFactoryImpl.class );
|
||||
private static final Pattern LISTENER_SEPARATION_PATTERN = Pattern.compile( " ," );
|
||||
|
||||
private final String name;
|
||||
private final String uuid;
|
||||
|
@ -178,7 +182,7 @@ public final class SessionFactoryImpl implements SessionFactoryImplementor {
|
|||
private final transient CriteriaBuilderImpl criteriaBuilder;
|
||||
private final PersistenceUnitUtil jpaPersistenceUnitUtil;
|
||||
private final transient CacheImplementor cacheAccess;
|
||||
private final transient org.hibernate.query.spi.NamedQueryRepository namedQueryRepository;
|
||||
private final transient NamedQueryRepository namedQueryRepository;
|
||||
private final transient QueryPlanCache queryPlanCache;
|
||||
|
||||
private final transient CurrentSessionContext currentSessionContext;
|
||||
|
@ -410,7 +414,7 @@ public final class SessionFactoryImpl implements SessionFactoryImplementor {
|
|||
);
|
||||
final EventType eventType = EventType.resolveEventTypeByName( eventTypeName );
|
||||
final EventListenerGroup eventListenerGroup = eventListenerRegistry.getEventListenerGroup( eventType );
|
||||
for ( String listenerImpl : ( (String) entry.getValue() ).split( " ," ) ) {
|
||||
for ( String listenerImpl : LISTENER_SEPARATION_PATTERN.split( ( (String) entry.getValue() ) ) ) {
|
||||
eventListenerGroup.appendListener( instantiate( listenerImpl, classLoaderService ) );
|
||||
}
|
||||
}
|
||||
|
@ -712,7 +716,7 @@ public final class SessionFactoryImpl implements SessionFactoryImplementor {
|
|||
}
|
||||
|
||||
@Override
|
||||
public org.hibernate.query.spi.NamedQueryRepository getNamedQueryRepository() {
|
||||
public NamedQueryRepository getNamedQueryRepository() {
|
||||
return namedQueryRepository;
|
||||
}
|
||||
|
||||
|
@ -863,10 +867,10 @@ public final class SessionFactoryImpl implements SessionFactoryImplementor {
|
|||
org.hibernate.query.Query hibernateQuery = query.unwrap( org.hibernate.query.Query.class );
|
||||
if ( hibernateQuery != null ) {
|
||||
// create and register the proper NamedQueryDefinition...
|
||||
if ( org.hibernate.query.NativeQuery.class.isInstance( hibernateQuery ) ) {
|
||||
if ( NativeQuery.class.isInstance( hibernateQuery ) ) {
|
||||
getNamedQueryRepository().registerNamedSQLQueryDefinition(
|
||||
name,
|
||||
extractSqlQueryDefinition( (org.hibernate.query.NativeQuery) hibernateQuery, name )
|
||||
extractSqlQueryDefinition( (NativeQuery) hibernateQuery, name )
|
||||
);
|
||||
}
|
||||
else {
|
||||
|
@ -898,7 +902,7 @@ public final class SessionFactoryImpl implements SessionFactoryImplementor {
|
|||
);
|
||||
}
|
||||
|
||||
private NamedSQLQueryDefinition extractSqlQueryDefinition(org.hibernate.query.NativeQuery nativeSqlQuery, String name) {
|
||||
private NamedSQLQueryDefinition extractSqlQueryDefinition(NativeQuery nativeSqlQuery, String name) {
|
||||
final NamedSQLQueryDefinitionBuilder builder = new NamedSQLQueryDefinitionBuilder( name );
|
||||
fillInNamedQueryBuilder( builder, nativeSqlQuery );
|
||||
builder.setCallable( nativeSqlQuery.isCallable() )
|
||||
|
|
|
@ -15,7 +15,9 @@ import java.util.Iterator;
|
|||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.hibernate.boot.model.source.internal.hbm.CommaSeparatedStringHelper;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.internal.util.collections.ArrayHelper;
|
||||
|
||||
|
@ -700,8 +702,8 @@ public final class StringHelper {
|
|||
* Determine if the given name is quoted. It is considered quoted if either:
|
||||
* <ol>
|
||||
* <li>starts AND ends with backticks (`)</li>
|
||||
* <li>starts with dialect-specified {@link org.hibernate.dialect.Dialect#openQuote() open-quote}
|
||||
* AND ends with dialect-specified {@link org.hibernate.dialect.Dialect#closeQuote() close-quote}</li>
|
||||
* <li>starts with dialect-specified {@link Dialect#openQuote() open-quote}
|
||||
* AND ends with dialect-specified {@link Dialect#closeQuote() close-quote}</li>
|
||||
* </ol>
|
||||
*
|
||||
* @param name The name to check
|
||||
|
@ -835,7 +837,7 @@ public final class StringHelper {
|
|||
}
|
||||
|
||||
public static List<String> parseCommaSeparatedString(String incomingString) {
|
||||
return Arrays.asList( incomingString.split( "\\s*,\\s*" ) );
|
||||
return CommaSeparatedStringHelper.parseCommaSeparatedString( incomingString );
|
||||
}
|
||||
|
||||
public static <T> String join(Collection<T> values, Renderer<T> renderer) {
|
||||
|
|
Loading…
Reference in New Issue