Hibernate SVN: r15166 - in search/trunk/src: java/org/hibernate/search/util and 1 other directories.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2008-09-09 15:22:59 -0400 (Tue, 09 Sep 2008)
New Revision: 15166
Modified:
search/trunk/src/java/org/hibernate/search/annotations/FilterCacheModeType.java
search/trunk/src/java/org/hibernate/search/util/FilterCacheModeTypeHelper.java
search/trunk/src/test/org/hibernate/search/test/filter/Driver.java
Log:
HSEARCH-260 rename NO by NONE
Modified: search/trunk/src/java/org/hibernate/search/annotations/FilterCacheModeType.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/annotations/FilterCacheModeType.java 2008-09-09 18:59:28 UTC (rev 15165)
+++ search/trunk/src/java/org/hibernate/search/annotations/FilterCacheModeType.java 2008-09-09 19:22:59 UTC (rev 15166)
@@ -7,10 +7,10 @@
*/
public enum FilterCacheModeType {
/**
- * NO filter instance and no result is cached by Hibernate Search
+ * No filter instance and no result is cached by Hibernate Search
* For every filter call, a new filter instance is created
*/
- NO,
+ NONE,
/**
* The filter instance is cached by Hibernate Search and reused across
Modified: search/trunk/src/java/org/hibernate/search/util/FilterCacheModeTypeHelper.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/util/FilterCacheModeTypeHelper.java 2008-09-09 18:59:28 UTC (rev 15165)
+++ search/trunk/src/java/org/hibernate/search/util/FilterCacheModeTypeHelper.java 2008-09-09 19:22:59 UTC (rev 15166)
@@ -11,7 +11,7 @@
public static boolean cacheInstance(FilterCacheModeType type) {
switch ( type ) {
- case NO:
+ case NONE:
return false;
case INSTANCE_AND_BITSETRESULTS:
return true;
@@ -24,7 +24,7 @@
public static boolean cacheResults(FilterCacheModeType type) {
switch ( type ) {
- case NO:
+ case NONE:
return false;
case INSTANCE_AND_BITSETRESULTS:
return true;
Modified: search/trunk/src/test/org/hibernate/search/test/filter/Driver.java
===================================================================
--- search/trunk/src/test/org/hibernate/search/test/filter/Driver.java 2008-09-09 18:59:28 UTC (rev 15165)
+++ search/trunk/src/test/org/hibernate/search/test/filter/Driver.java 2008-09-09 19:22:59 UTC (rev 15166)
@@ -21,7 +21,7 @@
@Entity
@Indexed
@FullTextFilterDefs( {
- @FullTextFilterDef(name = "bestDriver", impl = BestDriversFilter.class, cache = FilterCacheModeType.NO), //actual Filter implementation
+ @FullTextFilterDef(name = "bestDriver", impl = BestDriversFilter.class, cache = FilterCacheModeType.NONE), //actual Filter implementation
@FullTextFilterDef(name = "security", impl = SecurityFilterFactory.class, cache = FilterCacheModeType.INSTANCE_AND_BITSETRESULTS), //Filter factory with parameters
@FullTextFilterDef(name = "cacheresultstest", impl = ExcludeAllFilterFactory.class, cache = FilterCacheModeType.INSTANCE_AND_BITSETRESULTS),
@FullTextFilterDef(name = "cacheinstancetest", impl = InstanceBasedExcludeAllFilter.class, cache = FilterCacheModeType.INSTANCE_ONLY)
16 years, 3 months
Hibernate SVN: r15165 - in search/trunk/src: java/org/hibernate/search/engine and 2 other directories.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2008-09-09 14:59:28 -0400 (Tue, 09 Sep 2008)
New Revision: 15165
Modified:
search/trunk/src/java/org/hibernate/search/annotations/FullTextFilterDef.java
search/trunk/src/java/org/hibernate/search/engine/FilterDef.java
search/trunk/src/java/org/hibernate/search/util/FilterCacheModeTypeHelper.java
search/trunk/src/test/org/hibernate/search/test/filter/Driver.java
Log:
HSEARCH-260 @FulltextFilterDef.cache is now one single paramenter enum based
HSEARCH-259 fitlers are now isolated by name in the cache
Modified: search/trunk/src/java/org/hibernate/search/annotations/FullTextFilterDef.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/annotations/FullTextFilterDef.java 2008-09-09 18:46:44 UTC (rev 15164)
+++ search/trunk/src/java/org/hibernate/search/annotations/FullTextFilterDef.java 2008-09-09 18:59:28 UTC (rev 15165)
@@ -37,5 +37,5 @@
/**
* Cache mode for the filter. Default to instance and results caching
*/
- FilterCacheModeType cache() default FilterCacheModeType.INSTANCE_AND_RESULTS;
+ FilterCacheModeType cache() default FilterCacheModeType.INSTANCE_AND_BITSETRESULTS;
}
Modified: search/trunk/src/java/org/hibernate/search/engine/FilterDef.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/engine/FilterDef.java 2008-09-09 18:46:44 UTC (rev 15164)
+++ search/trunk/src/java/org/hibernate/search/engine/FilterDef.java 2008-09-09 18:59:28 UTC (rev 15165)
@@ -7,7 +7,6 @@
import java.util.Map;
import org.hibernate.search.SearchException;
-import org.hibernate.search.annotations.CacheBitResults;
import org.hibernate.search.annotations.FilterCacheModeType;
import org.hibernate.search.annotations.FullTextFilterDef;
Modified: search/trunk/src/java/org/hibernate/search/util/FilterCacheModeTypeHelper.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/util/FilterCacheModeTypeHelper.java 2008-09-09 18:46:44 UTC (rev 15164)
+++ search/trunk/src/java/org/hibernate/search/util/FilterCacheModeTypeHelper.java 2008-09-09 18:59:28 UTC (rev 15165)
@@ -13,7 +13,7 @@
switch ( type ) {
case NO:
return false;
- case INSTANCE_AND_RESULTS:
+ case INSTANCE_AND_BITSETRESULTS:
return true;
case INSTANCE_ONLY:
return true;
@@ -26,7 +26,7 @@
switch ( type ) {
case NO:
return false;
- case INSTANCE_AND_RESULTS:
+ case INSTANCE_AND_BITSETRESULTS:
return true;
case INSTANCE_ONLY:
return false;
Modified: search/trunk/src/test/org/hibernate/search/test/filter/Driver.java
===================================================================
--- search/trunk/src/test/org/hibernate/search/test/filter/Driver.java 2008-09-09 18:46:44 UTC (rev 15164)
+++ search/trunk/src/test/org/hibernate/search/test/filter/Driver.java 2008-09-09 18:59:28 UTC (rev 15165)
@@ -22,8 +22,8 @@
@Indexed
@FullTextFilterDefs( {
@FullTextFilterDef(name = "bestDriver", impl = BestDriversFilter.class, cache = FilterCacheModeType.NO), //actual Filter implementation
- @FullTextFilterDef(name = "security", impl = SecurityFilterFactory.class, cache = FilterCacheModeType.INSTANCE_AND_RESULTS), //Filter factory with parameters
- @FullTextFilterDef(name = "cacheresultstest", impl = ExcludeAllFilterFactory.class, cache = FilterCacheModeType.INSTANCE_AND_RESULTS),
+ @FullTextFilterDef(name = "security", impl = SecurityFilterFactory.class, cache = FilterCacheModeType.INSTANCE_AND_BITSETRESULTS), //Filter factory with parameters
+ @FullTextFilterDef(name = "cacheresultstest", impl = ExcludeAllFilterFactory.class, cache = FilterCacheModeType.INSTANCE_AND_BITSETRESULTS),
@FullTextFilterDef(name = "cacheinstancetest", impl = InstanceBasedExcludeAllFilter.class, cache = FilterCacheModeType.INSTANCE_ONLY)
})
public class Driver {
16 years, 3 months
Hibernate SVN: r15164 - core/branches/Branch_3_3/core/src/main/java/org/hibernate/type.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2008-09-09 14:46:44 -0400 (Tue, 09 Sep 2008)
New Revision: 15164
Added:
core/branches/Branch_3_3/core/src/main/java/org/hibernate/type/NumericBooleanType.java
Log:
HHH-3471 : add NumericBooleanType
Added: core/branches/Branch_3_3/core/src/main/java/org/hibernate/type/NumericBooleanType.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/type/NumericBooleanType.java (rev 0)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/type/NumericBooleanType.java 2008-09-09 18:46:44 UTC (rev 15164)
@@ -0,0 +1,94 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.type;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.PreparedStatement;
+import java.sql.Types;
+
+import org.hibernate.dialect.Dialect;
+
+/**
+ * Maps {@link Types#INTEGER interger} database values to boolean java values. Zero is considered false;
+ * <tt>NULL</tt> maps to {@link #getDefaultValue()}; any other value is considered true.
+ *
+ * @author Steve Ebersole
+ * @see #getName()
+ */
+public class NumericBooleanType extends BooleanType {
+
+ /**
+ * {@inheritDoc}
+ * <p/>
+ * This type's name is <tt>numeric_boolean</tt>
+ */
+ public String getName() {
+ return "numeric_boolean";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Object get(ResultSet rs, String name) throws SQLException {
+ int value = rs.getInt( name );
+ if ( rs.wasNull() ) {
+ return getDefaultValue();
+ }
+ else if ( value == 0 ) {
+ return Boolean.FALSE;
+ }
+ else {
+ return Boolean.TRUE;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void set(PreparedStatement st, Object value, int index) throws SQLException {
+ if ( value == null ) {
+ st.setNull( index, Types.INTEGER );
+ }
+ else {
+ boolean bool = ( ( Boolean ) value ).booleanValue();
+ st.setInt( index, bool ? 1 : 0 );
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String objectToSQLString(Object value, Dialect dialect) throws Exception {
+ return ( ( Boolean ) value ).booleanValue() ? "1" : "0";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int sqlType() {
+ return Types.INTEGER;
+ }
+}
16 years, 3 months
Hibernate SVN: r15163 - core/trunk/core/src/main/java/org/hibernate/type.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2008-09-09 14:46:25 -0400 (Tue, 09 Sep 2008)
New Revision: 15163
Added:
core/trunk/core/src/main/java/org/hibernate/type/NumericBooleanType.java
Log:
HHH-3471 : add NumericBooleanType
Added: core/trunk/core/src/main/java/org/hibernate/type/NumericBooleanType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/NumericBooleanType.java (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/type/NumericBooleanType.java 2008-09-09 18:46:25 UTC (rev 15163)
@@ -0,0 +1,94 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.type;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.PreparedStatement;
+import java.sql.Types;
+
+import org.hibernate.dialect.Dialect;
+
+/**
+ * Maps {@link Types#INTEGER interger} database values to boolean java values. Zero is considered false;
+ * <tt>NULL</tt> maps to {@link #getDefaultValue()}; any other value is considered true.
+ *
+ * @author Steve Ebersole
+ * @see #getName()
+ */
+public class NumericBooleanType extends BooleanType {
+
+ /**
+ * {@inheritDoc}
+ * <p/>
+ * This type's name is <tt>numeric_boolean</tt>
+ */
+ public String getName() {
+ return "numeric_boolean";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Object get(ResultSet rs, String name) throws SQLException {
+ int value = rs.getInt( name );
+ if ( rs.wasNull() ) {
+ return getDefaultValue();
+ }
+ else if ( value == 0 ) {
+ return Boolean.FALSE;
+ }
+ else {
+ return Boolean.TRUE;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void set(PreparedStatement st, Object value, int index) throws SQLException {
+ if ( value == null ) {
+ st.setNull( index, Types.INTEGER );
+ }
+ else {
+ boolean bool = ( ( Boolean ) value ).booleanValue();
+ st.setInt( index, bool ? 1 : 0 );
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String objectToSQLString(Object value, Dialect dialect) throws Exception {
+ return ( ( Boolean ) value ).booleanValue() ? "1" : "0";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int sqlType() {
+ return Types.INTEGER;
+ }
+}
16 years, 3 months
Hibernate SVN: r15162 - core/branches/Branch_3_2/src/org/hibernate/type.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2008-09-09 14:46:01 -0400 (Tue, 09 Sep 2008)
New Revision: 15162
Added:
core/branches/Branch_3_2/src/org/hibernate/type/NumericBooleanType.java
Log:
HHH-3471 : add NumericBooleanType
Added: core/branches/Branch_3_2/src/org/hibernate/type/NumericBooleanType.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/type/NumericBooleanType.java (rev 0)
+++ core/branches/Branch_3_2/src/org/hibernate/type/NumericBooleanType.java 2008-09-09 18:46:01 UTC (rev 15162)
@@ -0,0 +1,94 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.type;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.PreparedStatement;
+import java.sql.Types;
+
+import org.hibernate.dialect.Dialect;
+
+/**
+ * Maps {@link Types#INTEGER interger} database values to boolean java values. Zero is considered false;
+ * <tt>NULL</tt> maps to {@link #getDefaultValue()}; any other value is considered true.
+ *
+ * @author Steve Ebersole
+ * @see #getName()
+ */
+public class NumericBooleanType extends BooleanType {
+
+ /**
+ * {@inheritDoc}
+ * <p/>
+ * This type's name is <tt>numeric_boolean</tt>
+ */
+ public String getName() {
+ return "numeric_boolean";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Object get(ResultSet rs, String name) throws SQLException {
+ int value = rs.getInt( name );
+ if ( rs.wasNull() ) {
+ return getDefaultValue();
+ }
+ else if ( value == 0 ) {
+ return Boolean.FALSE;
+ }
+ else {
+ return Boolean.TRUE;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void set(PreparedStatement st, Object value, int index) throws SQLException {
+ if ( value == null ) {
+ st.setNull( index, Types.INTEGER );
+ }
+ else {
+ boolean bool = ( ( Boolean ) value ).booleanValue();
+ st.setInt( index, bool ? 1 : 0 );
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String objectToSQLString(Object value, Dialect dialect) throws Exception {
+ return ( ( Boolean ) value ).booleanValue() ? "1" : "0";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int sqlType() {
+ return Types.INTEGER;
+ }
+}
16 years, 3 months
Hibernate SVN: r15161 - search/trunk/src/java/org/hibernate/search/annotations.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2008-09-09 13:26:36 -0400 (Tue, 09 Sep 2008)
New Revision: 15161
Removed:
search/trunk/src/java/org/hibernate/search/annotations/CacheBitResults.java
Modified:
search/trunk/src/java/org/hibernate/search/annotations/FilterCacheModeType.java
Log:
HSEARCH-260 @FulltextFilterDef.cache is now one single paramenter enum based
HSEARCH-259 fitlers are now isolated by name in the cache
Deleted: search/trunk/src/java/org/hibernate/search/annotations/CacheBitResults.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/annotations/CacheBitResults.java 2008-09-09 17:15:44 UTC (rev 15160)
+++ search/trunk/src/java/org/hibernate/search/annotations/CacheBitResults.java 2008-09-09 17:26:36 UTC (rev 15161)
@@ -1,24 +0,0 @@
-// $Id$
-package org.hibernate.search.annotations;
-
-/**
- * Defines the strategy for caching the <code>BitSet</code> returned by a defined filter.
- *
- * @author Hardy Ferentschik
- * @see org.hibernate.search.filter.CachingWrapperFilter
- */
-public enum CacheBitResults {
- /**
- * Caching is dependent on the value of the <code>cache</code>
- * parameter of the filter definition. If <code>cache == true</code> a wrapping filter will
- * be used, otherwise not.
- * @see FullTextFilterDef#cache()
- */
- AUTOMATIC,
-
-
- /**
- * No caching of the filter's <code>BitSet</code>.
- */
- NO;
-}
\ No newline at end of file
Modified: search/trunk/src/java/org/hibernate/search/annotations/FilterCacheModeType.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/annotations/FilterCacheModeType.java 2008-09-09 17:15:44 UTC (rev 15160)
+++ search/trunk/src/java/org/hibernate/search/annotations/FilterCacheModeType.java 2008-09-09 17:26:36 UTC (rev 15161)
@@ -25,6 +25,6 @@
* concurrent filter.bits() calls
* BitSet Results are cached per IndexReader
*/
- INSTANCE_AND_RESULTS
+ INSTANCE_AND_BITSETRESULTS
}
16 years, 3 months
Hibernate SVN: r15160 - in search/trunk/src: java/org/hibernate/search/engine and 4 other directories.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2008-09-09 13:15:44 -0400 (Tue, 09 Sep 2008)
New Revision: 15160
Added:
search/trunk/src/java/org/hibernate/search/annotations/FilterCacheModeType.java
search/trunk/src/java/org/hibernate/search/util/FilterCacheModeTypeHelper.java
search/trunk/src/test/org/hibernate/search/test/filter/InstanceBasedExcludeAllFilter.java
Modified:
search/trunk/src/java/org/hibernate/search/annotations/FullTextFilterDef.java
search/trunk/src/java/org/hibernate/search/engine/FilterDef.java
search/trunk/src/java/org/hibernate/search/impl/SearchFactoryImpl.java
search/trunk/src/java/org/hibernate/search/query/FullTextQueryImpl.java
search/trunk/src/test/org/hibernate/search/test/filter/Driver.java
search/trunk/src/test/org/hibernate/search/test/filter/ExcludeAllFilter.java
search/trunk/src/test/org/hibernate/search/test/filter/FilterTest.java
search/trunk/src/test/org/hibernate/search/test/filter/SecurityFilterFactory.java
Log:
HSEARCH-260 @FulltextFilterDef.cache is now one single paramenter enum based
HSEARCH-259 fitlers are now isolated by name in the cache
Added: search/trunk/src/java/org/hibernate/search/annotations/FilterCacheModeType.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/annotations/FilterCacheModeType.java (rev 0)
+++ search/trunk/src/java/org/hibernate/search/annotations/FilterCacheModeType.java 2008-09-09 17:15:44 UTC (rev 15160)
@@ -0,0 +1,30 @@
+package org.hibernate.search.annotations;
+
+/**
+ * Cache mode strategy for Full Text filters
+ *
+ * @author Emmanuel Bernard
+ */
+public enum FilterCacheModeType {
+ /**
+ * NO filter instance and no result is cached by Hibernate Search
+ * For every filter call, a new filter instance is created
+ */
+ NO,
+
+ /**
+ * The filter instance is cached by Hibernate Search and reused across
+ * concurrent filter.bits() calls
+ * Results are not cache by Hibernate Search
+ */
+ INSTANCE_ONLY,
+
+ /**
+ * Both the filter instance and the BitSet results are cached.
+ * The filter instance is cached by Hibernate Search and reused across
+ * concurrent filter.bits() calls
+ * BitSet Results are cached per IndexReader
+ */
+ INSTANCE_AND_RESULTS
+
+}
Modified: search/trunk/src/java/org/hibernate/search/annotations/FullTextFilterDef.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/annotations/FullTextFilterDef.java 2008-09-08 19:50:44 UTC (rev 15159)
+++ search/trunk/src/java/org/hibernate/search/annotations/FullTextFilterDef.java 2008-09-09 17:15:44 UTC (rev 15160)
@@ -32,16 +32,10 @@
*
*/
@SuppressWarnings("unchecked")
- Class impl();
+ Class<?> impl();
/**
- * Enable caching for this filter (default true).
+ * Cache mode for the filter. Default to instance and results caching
*/
- boolean cache() default true;
-
- /**
- * Determines whether the <code>BitSet</code> returned from the filter should be
- * cached or not. Default is <code>CacheBitResults.AUTOMATIC</code>.
- */
- CacheBitResults cacheBitResult() default CacheBitResults.AUTOMATIC;
+ FilterCacheModeType cache() default FilterCacheModeType.INSTANCE_AND_RESULTS;
}
Modified: search/trunk/src/java/org/hibernate/search/engine/FilterDef.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/engine/FilterDef.java 2008-09-08 19:50:44 UTC (rev 15159)
+++ search/trunk/src/java/org/hibernate/search/engine/FilterDef.java 2008-09-09 17:15:44 UTC (rev 15160)
@@ -8,6 +8,8 @@
import org.hibernate.search.SearchException;
import org.hibernate.search.annotations.CacheBitResults;
+import org.hibernate.search.annotations.FilterCacheModeType;
+import org.hibernate.search.annotations.FullTextFilterDef;
/**
* A wrapper class which encapsualtes all required information to create a defined filter.
@@ -17,28 +19,29 @@
//TODO serialization
@SuppressWarnings("unchecked")
public class FilterDef {
- private Class impl;
private Method factoryMethod;
private Method keyMethod;
private Map<String, Method> setters = new HashMap<String, Method>();
- private boolean cache;
- private CacheBitResults useCachingWrapperFilter;
+ private final FilterCacheModeType cacheMode;
+ private final Class<?> impl;
+ private final String name;
- public CacheBitResults getUseCachingWrapperFilter() {
- return useCachingWrapperFilter;
+ public FilterDef(FullTextFilterDef def) {
+ this.name = def.name();
+ this.impl = def.impl();
+ this.cacheMode = def.cache();
}
- public void setUseCachingWrapperFilter(
- CacheBitResults useCachingWrapperFilter) {
- this.useCachingWrapperFilter = useCachingWrapperFilter;
+ public String getName() {
+ return name;
}
- public Class getImpl() {
- return impl;
+ public FilterCacheModeType getCacheMode() {
+ return cacheMode;
}
- public void setImpl(Class impl) {
- this.impl = impl;
+ public Class<?> getImpl() {
+ return impl;
}
public Method getFactoryMethod() {
@@ -75,12 +78,4 @@
throw new SearchException( "Unable to set Filter parameter: " + parameterName + " on filter class: " + this.impl, e );
}
}
-
- public void setCache(boolean cache) {
- this.cache = cache;
- }
-
- public boolean isCache() {
- return cache;
- }
}
Modified: search/trunk/src/java/org/hibernate/search/impl/SearchFactoryImpl.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/impl/SearchFactoryImpl.java 2008-09-08 19:50:44 UTC (rev 15159)
+++ search/trunk/src/java/org/hibernate/search/impl/SearchFactoryImpl.java 2008-09-09 17:15:44 UTC (rev 15160)
@@ -18,6 +18,9 @@
import java.util.concurrent.locks.ReentrantLock;
import org.apache.lucene.analysis.Analyzer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import org.hibernate.annotations.common.reflection.ReflectionManager;
import org.hibernate.annotations.common.reflection.XClass;
import org.hibernate.annotations.common.reflection.java.JavaReflectionManager;
@@ -49,9 +52,6 @@
import org.hibernate.search.store.DirectoryProvider;
import org.hibernate.search.store.DirectoryProviderFactory;
import org.hibernate.search.store.optimization.OptimizerStrategy;
-import org.hibernate.search.util.ScopedAnalyzer;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
/**
* @author Emmanuel Bernard
@@ -200,10 +200,8 @@
throw new SearchException("Multiple definition of @FullTextFilterDef.name=" + defAnn.name() + ": "
+ mappedXClass.getName() );
}
- FilterDef filterDef = new FilterDef();
- filterDef.setImpl( defAnn.impl() );
- filterDef.setCache( defAnn.cache() );
- filterDef.setUseCachingWrapperFilter( defAnn.cacheBitResult() );
+
+ FilterDef filterDef = new FilterDef(defAnn);
try {
filterDef.getImpl().newInstance();
}
Modified: search/trunk/src/java/org/hibernate/search/query/FullTextQueryImpl.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/query/FullTextQueryImpl.java 2008-09-08 19:50:44 UTC (rev 15159)
+++ search/trunk/src/java/org/hibernate/search/query/FullTextQueryImpl.java 2008-09-09 17:15:44 UTC (rev 15160)
@@ -41,7 +41,6 @@
import org.hibernate.search.FullTextFilter;
import org.hibernate.search.FullTextQuery;
import org.hibernate.search.SearchException;
-import org.hibernate.search.annotations.CacheBitResults;
import org.hibernate.search.engine.DocumentBuilder;
import org.hibernate.search.engine.DocumentExtractor;
import org.hibernate.search.engine.EntityInfo;
@@ -53,6 +52,7 @@
import org.hibernate.search.engine.SearchFactoryImplementor;
import org.hibernate.search.filter.ChainedFilter;
import org.hibernate.search.filter.FilterKey;
+import org.hibernate.search.filter.StandardFilterKey;
import org.hibernate.search.reader.ReaderProvider;
import org.hibernate.search.store.DirectoryProvider;
import org.hibernate.search.util.ContextHelper;
@@ -60,6 +60,8 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import static org.hibernate.search.util.FilterCacheModeTypeHelper.*;
+
/**
* Implementation of {@link org.hibernate.search.FullTextQuery}
*
@@ -352,7 +354,7 @@
FilterKey key = createFilterKey(def, instance);
// try to get the filter out of the cache
- Filter filter = def.isCache() ?
+ Filter filter = cacheInstance( def.getCacheMode() ) ?
searchFactoryImplementor.getFilterCachingStrategy().getCachedFilter( key ) :
null;
@@ -360,7 +362,7 @@
filter = createFilter(def, instance);
// add filter to cache if we have to
- if ( def.isCache() ) {
+ if ( cacheInstance( def.getCacheMode() ) ) {
searchFactoryImplementor.getFilterCachingStrategy().addCachedFilter( key, filter );
}
}
@@ -391,8 +393,9 @@
filter = (Filter) instance;
}
catch (ClassCastException e) {
- throw new SearchException( "@Key method does not return a org.apache.lucene.search.Filter class: "
- + def.getImpl().getName() + "." + def.getFactoryMethod().getName() );
+ throw new SearchException( "Filter implementation does not implement the Filter interface: "
+ + def.getImpl().getName() + ". "
+ + (def.getFactoryMethod() != null ? def.getFactoryMethod().getName() : ""), e );
}
}
@@ -409,7 +412,7 @@
* <code>def</code>.
*/
private Filter addCachingWrapperFilter(Filter filter, FilterDef def) {
- if (def.getUseCachingWrapperFilter() == CacheBitResults.AUTOMATIC && def.isCache() ) {
+ if ( cacheResults( def.getCacheMode() ) ) {
int cachingWrapperFilterSize = getSearchFactoryImplementor().getFilterCacheBitResultsSize();
filter = new org.hibernate.search.filter.CachingWrapperFilter(filter, cachingWrapperFilterSize);
}
@@ -419,7 +422,7 @@
private FilterKey createFilterKey(FilterDef def, Object instance) {
FilterKey key = null;
- if ( !def.isCache() ) {
+ if ( !cacheInstance( def.getCacheMode() ) ) {
return key; // if the filter is not cached there is no key!
}
@@ -454,7 +457,12 @@
}
}
key.setImpl( def.getImpl() );
- return key;
+
+ //Make sure Filters are isolated by filter def name
+ StandardFilterKey wrapperKey = new StandardFilterKey();
+ wrapperKey.addParameter( def.getName() );
+ wrapperKey.addParameter( key );
+ return wrapperKey;
}
private Object createFilterInstance(FullTextFilterImpl fullTextFilter,
@@ -472,7 +480,7 @@
for (Map.Entry<String, Object> entry : fullTextFilter.getParameters().entrySet()) {
def.invoke( entry.getKey(), instance, entry.getValue() );
}
- if ( def.isCache() && def.getKeyMethod() == null && fullTextFilter.getParameters().size() > 0 ) {
+ if ( cacheInstance( def.getCacheMode() ) && def.getKeyMethod() == null && fullTextFilter.getParameters().size() > 0 ) {
throw new SearchException( "Filter with parameters and no @Key method: " + fullTextFilter.getName() );
}
return instance;
Added: search/trunk/src/java/org/hibernate/search/util/FilterCacheModeTypeHelper.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/util/FilterCacheModeTypeHelper.java (rev 0)
+++ search/trunk/src/java/org/hibernate/search/util/FilterCacheModeTypeHelper.java 2008-09-09 17:15:44 UTC (rev 15160)
@@ -0,0 +1,37 @@
+package org.hibernate.search.util;
+
+import org.hibernate.search.annotations.FilterCacheModeType;
+import org.hibernate.annotations.common.AssertionFailure;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class FilterCacheModeTypeHelper {
+ private FilterCacheModeTypeHelper() {}
+
+ public static boolean cacheInstance(FilterCacheModeType type) {
+ switch ( type ) {
+ case NO:
+ return false;
+ case INSTANCE_AND_RESULTS:
+ return true;
+ case INSTANCE_ONLY:
+ return true;
+ default:
+ throw new AssertionFailure("Unknwn FilterCacheModeType:" + type);
+ }
+ }
+
+ public static boolean cacheResults(FilterCacheModeType type) {
+ switch ( type ) {
+ case NO:
+ return false;
+ case INSTANCE_AND_RESULTS:
+ return true;
+ case INSTANCE_ONLY:
+ return false;
+ default:
+ throw new AssertionFailure("Unknwn FilterCacheModeType:" + type);
+ }
+ }
+}
Modified: search/trunk/src/test/org/hibernate/search/test/filter/Driver.java
===================================================================
--- search/trunk/src/test/org/hibernate/search/test/filter/Driver.java 2008-09-08 19:50:44 UTC (rev 15159)
+++ search/trunk/src/test/org/hibernate/search/test/filter/Driver.java 2008-09-09 17:15:44 UTC (rev 15160)
@@ -13,6 +13,7 @@
import org.hibernate.search.annotations.Resolution;
import org.hibernate.search.annotations.FullTextFilterDef;
import org.hibernate.search.annotations.FullTextFilterDefs;
+import org.hibernate.search.annotations.FilterCacheModeType;
/**
* @author Emmanuel Bernard
@@ -20,9 +21,10 @@
@Entity
@Indexed
@FullTextFilterDefs( {
- @FullTextFilterDef(name = "bestDriver", impl = BestDriversFilter.class), //actual Filter implementation
- @FullTextFilterDef(name = "security", impl = SecurityFilterFactory.class), //Filter factory with parameters
- @FullTextFilterDef(name = "cachetest", impl = ExcludeAllFilterFactory.class, cache = true) //Filter factory with parameters
+ @FullTextFilterDef(name = "bestDriver", impl = BestDriversFilter.class, cache = FilterCacheModeType.NO), //actual Filter implementation
+ @FullTextFilterDef(name = "security", impl = SecurityFilterFactory.class, cache = FilterCacheModeType.INSTANCE_AND_RESULTS), //Filter factory with parameters
+ @FullTextFilterDef(name = "cacheresultstest", impl = ExcludeAllFilterFactory.class, cache = FilterCacheModeType.INSTANCE_AND_RESULTS),
+ @FullTextFilterDef(name = "cacheinstancetest", impl = InstanceBasedExcludeAllFilter.class, cache = FilterCacheModeType.INSTANCE_ONLY)
})
public class Driver {
@Id
Modified: search/trunk/src/test/org/hibernate/search/test/filter/ExcludeAllFilter.java
===================================================================
--- search/trunk/src/test/org/hibernate/search/test/filter/ExcludeAllFilter.java 2008-09-08 19:50:44 UTC (rev 15159)
+++ search/trunk/src/test/org/hibernate/search/test/filter/ExcludeAllFilter.java 2008-09-09 17:15:44 UTC (rev 15160)
@@ -1,4 +1,4 @@
-// $Id:$
+// $Id$
package org.hibernate.search.test.filter;
import java.util.BitSet;
@@ -12,7 +12,7 @@
*/
@SuppressWarnings("serial")
public class ExcludeAllFilter extends Filter {
- private static boolean done = false;
+ private static volatile boolean done = false;
public BitSet bits(IndexReader reader) throws IOException {
if (done) throw new IllegalStateException("Called twice");
Modified: search/trunk/src/test/org/hibernate/search/test/filter/FilterTest.java
===================================================================
--- search/trunk/src/test/org/hibernate/search/test/filter/FilterTest.java 2008-09-08 19:50:44 UTC (rev 15159)
+++ search/trunk/src/test/org/hibernate/search/test/filter/FilterTest.java 2008-09-09 17:15:44 UTC (rev 15160)
@@ -65,7 +65,7 @@
assertEquals("No filter should happen", 3, ftQuery.getResultSize() );
ftQuery = s.createFullTextQuery( query, Driver.class );
- ftQuery.enableFullTextFilter( "cachetest");
+ ftQuery.enableFullTextFilter( "cacheresultstest");
assertEquals("Should filter out all", 0, ftQuery.getResultSize() );
// HSEARCH-174 - we call System.gc() to force a garbage collection.
@@ -74,15 +74,33 @@
System.gc();
ftQuery = s.createFullTextQuery( query, Driver.class );
- ftQuery.enableFullTextFilter( "cachetest");
+ ftQuery.enableFullTextFilter( "cacheresultstest");
try {
ftQuery.getResultSize();
}
catch (IllegalStateException e) {
- fail("Cache does not work");
+ fail("Cache results does not work");
}
+ ftQuery = s.createFullTextQuery( query, Driver.class );
+ ftQuery.enableFullTextFilter( "cacheinstancetest");
+ assertEquals("Should filter out all", 0, ftQuery.getResultSize() );
+
+ ftQuery = s.createFullTextQuery( query, Driver.class );
+ ftQuery.enableFullTextFilter( "cacheinstancetest");
+ try {
+ ftQuery.getResultSize();
+ fail("Cache instance does not work");
+ }
+ catch (IllegalStateException e) {
+ //success
+ }
+
+
s.getTransaction().commit();
+
+
+
s.close();
deleteData();
}
Added: search/trunk/src/test/org/hibernate/search/test/filter/InstanceBasedExcludeAllFilter.java
===================================================================
--- search/trunk/src/test/org/hibernate/search/test/filter/InstanceBasedExcludeAllFilter.java (rev 0)
+++ search/trunk/src/test/org/hibernate/search/test/filter/InstanceBasedExcludeAllFilter.java 2008-09-09 17:15:44 UTC (rev 15160)
@@ -0,0 +1,21 @@
+package org.hibernate.search.test.filter;
+
+import java.util.BitSet;
+import java.io.IOException;
+
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.search.Filter;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class InstanceBasedExcludeAllFilter extends Filter {
+ private volatile boolean done = false;
+
+ public BitSet bits(IndexReader reader) throws IOException {
+ if (done) throw new IllegalStateException("Called twice");
+ BitSet bitSet = new BitSet( reader.maxDoc() );
+ done = true;
+ return bitSet;
+ }
+}
Modified: search/trunk/src/test/org/hibernate/search/test/filter/SecurityFilterFactory.java
===================================================================
--- search/trunk/src/test/org/hibernate/search/test/filter/SecurityFilterFactory.java 2008-09-08 19:50:44 UTC (rev 15159)
+++ search/trunk/src/test/org/hibernate/search/test/filter/SecurityFilterFactory.java 2008-09-09 17:15:44 UTC (rev 15160)
@@ -1,18 +1,17 @@
//$Id$
package org.hibernate.search.test.filter;
-import org.hibernate.search.filter.FilterKey;
-import org.hibernate.search.filter.StandardFilterKey;
-import org.hibernate.search.annotations.Key;
-import org.hibernate.search.annotations.Factory;
+import org.apache.lucene.index.Term;
import org.apache.lucene.search.Filter;
-import org.apache.lucene.search.QueryFilter;
import org.apache.lucene.search.Query;
-import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.QueryWrapperFilter;
-import org.apache.lucene.search.CachingWrapperFilter;
-import org.apache.lucene.index.Term;
+import org.apache.lucene.search.TermQuery;
+import org.hibernate.search.annotations.Factory;
+import org.hibernate.search.annotations.Key;
+import org.hibernate.search.filter.FilterKey;
+import org.hibernate.search.filter.StandardFilterKey;
+
/**
* Apply a security filter to the results
*
@@ -38,6 +37,6 @@
@Factory
public Filter getFilter() {
Query query = new TermQuery( new Term("teacher", login) );
- return new CachingWrapperFilter( new QueryWrapperFilter(query) );
+ return new QueryWrapperFilter(query);
}
}
16 years, 3 months
Hibernate SVN: r15159 - in core/branches/Branch_3_2/src/org/hibernate/dialect: function and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2008-09-08 15:50:44 -0400 (Mon, 08 Sep 2008)
New Revision: 15159
Added:
core/branches/Branch_3_2/src/org/hibernate/dialect/function/DerbyConcatFunction.java
Modified:
core/branches/Branch_3_2/src/org/hibernate/dialect/DerbyDialect.java
core/branches/Branch_3_2/src/org/hibernate/dialect/function/VarArgsSQLFunction.java
Log:
HHH-3424 : concat function on Derby
Modified: core/branches/Branch_3_2/src/org/hibernate/dialect/DerbyDialect.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/dialect/DerbyDialect.java 2008-09-08 19:43:43 UTC (rev 15158)
+++ core/branches/Branch_3_2/src/org/hibernate/dialect/DerbyDialect.java 2008-09-08 19:50:44 UTC (rev 15159)
@@ -7,9 +7,9 @@
import org.hibernate.engine.Mapping;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.type.Type;
-import org.hibernate.dialect.function.VarArgsSQLFunction;
import org.hibernate.dialect.function.SQLFunction;
import org.hibernate.dialect.function.SQLFunctionTemplate;
+import org.hibernate.dialect.function.DerbyConcatFunction;
import org.hibernate.id.TableHiLoGenerator;
import org.hibernate.sql.CaseFragment;
import org.hibernate.sql.DerbyCaseFragment;
@@ -17,19 +17,19 @@
import java.util.List;
import java.util.ArrayList;
-/**
- * @author Simon Johnston
- *
+/** *
* Hibernate Dialect for Cloudscape 10 - aka Derby. This implements both an
* override for the identity column generator as well as for the case statement
* issue documented at:
* http://www.jroller.com/comments/kenlars99/Weblog/cloudscape_soon_to_be_derby
+ *
+ * @author Simon Johnston
*/
public class DerbyDialect extends DB2Dialect {
public DerbyDialect() {
super();
- registerFunction( "concat", new VarArgsSQLFunction( Hibernate.STRING, "(","||",")" ) );
+ registerFunction( "concat", new DerbyConcatFunction() );
registerFunction( "trim", new DerbyTrimFunctionEmulation() );
}
Added: core/branches/Branch_3_2/src/org/hibernate/dialect/function/DerbyConcatFunction.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/dialect/function/DerbyConcatFunction.java (rev 0)
+++ core/branches/Branch_3_2/src/org/hibernate/dialect/function/DerbyConcatFunction.java 2008-09-08 19:50:44 UTC (rev 15159)
@@ -0,0 +1,179 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.dialect.function;
+
+import java.util.List;
+import java.util.Iterator;
+
+import org.hibernate.Hibernate;
+import org.hibernate.QueryException;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.type.Type;
+
+/**
+ * A specialized concat() function definition in which:<ol>
+ * <li>we translate to use the concat operator ('||')</li>
+ * <li>wrap dynamic parameters in CASTs to VARCHAR</li>
+ * </ol>
+ * <p/>
+ * This last spec is to deal with a limitation on DB2 and variants (e.g. Derby)
+ * where dynamic parameters cannot be used in concatenation unless they are being
+ * concatenated with at least one non-dynamic operand. And even then, the rules
+ * are so convoluted as to what is allowed and when the CAST is needed and when
+ * it is not that we just go ahead and do the CASTing.
+ *
+ * @author Steve Ebersole
+ */
+public class DerbyConcatFunction implements SQLFunction {
+ /**
+ * {@inheritDoc}
+ * <p/>
+ * Here we always return {@link Hibernate#STRING}.
+ */
+ public Type getReturnType(Type columnType, Mapping mapping) throws QueryException {
+ return Hibernate.STRING;
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p/>
+ * Here we always return <tt>true</tt>
+ */
+ public boolean hasArguments() {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p/>
+ * Here we always return <tt>true</tt>
+ */
+ public boolean hasParenthesesIfNoArguments() {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p/>
+ * Here's the meat.. The whole reason we have a separate impl for this for Derby is to re-define
+ * this method. The logic here says that if not all the incoming args are dynamic parameters
+ * (i.e. <tt>?</tt>) then we simply use the Derby concat operator (<tt>||</tt>) on the unchanged
+ * arg elements. However, if all the args are dynamic parameters, then we need to wrap the individual
+ * arg elements in <tt>cast</tt> function calls, use the concantenation operator on the <tt>cast</tt>
+ * returns, and then wrap that whole thing in a call to the Derby <tt>varchar</tt> function.
+ */
+ public String render(List args, SessionFactoryImplementor factory) throws QueryException {
+ boolean areAllArgsParams = true;
+ Iterator itr = args.iterator();
+ while ( itr.hasNext() ) {
+ final String arg = ( String ) itr.next();
+ if ( ! "?".equals( arg ) ) {
+ areAllArgsParams = false;
+ break;
+ }
+ }
+
+ if ( areAllArgsParams ) {
+ return join(
+ args.iterator(),
+ new StringTransformer() {
+ public String transform(String string) {
+ return "cast( ? as varchar(32672) )";
+ }
+ },
+ new StringJoinTemplate() {
+ public String getBeginning() {
+ return "varchar( ";
+ }
+ public String getSeparator() {
+ return " || ";
+ }
+ public String getEnding() {
+ return " )";
+ }
+ }
+ );
+ }
+ else {
+ return join(
+ args.iterator(),
+ new StringTransformer() {
+ public String transform(String string) {
+ return string;
+ }
+ },
+ new StringJoinTemplate() {
+ public String getBeginning() {
+ return "(";
+ }
+ public String getSeparator() {
+ return "||";
+ }
+ public String getEnding() {
+ return ")";
+ }
+ }
+ );
+ }
+ }
+
+ private static interface StringTransformer {
+ public String transform(String string);
+ }
+
+ private static interface StringJoinTemplate {
+ /**
+ * Getter for property 'beginning'.
+ *
+ * @return Value for property 'beginning'.
+ */
+ public String getBeginning();
+ /**
+ * Getter for property 'separator'.
+ *
+ * @return Value for property 'separator'.
+ */
+ public String getSeparator();
+ /**
+ * Getter for property 'ending'.
+ *
+ * @return Value for property 'ending'.
+ */
+ public String getEnding();
+ }
+
+ private String join(Iterator/*<String>*/ elements, StringTransformer elementTransformer, StringJoinTemplate template) {
+ StringBuffer buffer = new StringBuffer( template.getBeginning() );
+ while ( elements.hasNext() ) {
+ final String element = ( String ) elements.next();
+ buffer.append( elementTransformer.transform( element ) );
+ if ( elements.hasNext() ) {
+ buffer.append( template.getSeparator() );
+ }
+ }
+ return buffer.append( template.getEnding() ).toString();
+ }
+}
Modified: core/branches/Branch_3_2/src/org/hibernate/dialect/function/VarArgsSQLFunction.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/dialect/function/VarArgsSQLFunction.java 2008-09-08 19:43:43 UTC (rev 15158)
+++ core/branches/Branch_3_2/src/org/hibernate/dialect/function/VarArgsSQLFunction.java 2008-09-08 19:50:44 UTC (rev 15159)
@@ -1,4 +1,27 @@
-//$Id$
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
package org.hibernate.dialect.function;
import java.util.List;
@@ -9,50 +32,97 @@
import org.hibernate.type.Type;
/**
- * Support for slightly more general templating than <tt>StandardSQLFunction</tt>,
+ * Support for slightly more general templating than {@link StandardSQLFunction},
* with an unlimited number of arguments.
+ *
* @author Gavin King
*/
public class VarArgsSQLFunction implements SQLFunction {
-
private final String begin;
private final String sep;
private final String end;
private final Type type;
-
+
+ /**
+ * Constructs a VarArgsSQLFunction instance with a 'static' return type. An example of a 'static'
+ * return type would be something like an <tt>UPPER</tt> function which is always returning
+ * a SQL VARCHAR and thus a string type.
+ *
+ * @param type The return type.
+ * @param begin The beginning of the function templating.
+ * @param sep The separator for each individual function argument.
+ * @param end The end of the function templating.
+ */
public VarArgsSQLFunction(Type type, String begin, String sep, String end) {
+ this.type = type;
this.begin = begin;
this.sep = sep;
this.end = end;
- this.type = type;
}
+ /**
+ * Constructs a VarArgsSQLFunction instance with a 'dynamic' return type. For a dynamic return type,
+ * the type of the arguments are used to resolve the type. An example of a function with a
+ * 'dynamic' return would be <tt>MAX</tt> or <tt>MIN</tt> which return a double or an integer etc
+ * based on the types of the arguments.
+ *
+ * @param begin The beginning of the function templating.
+ * @param sep The separator for each individual function argument.
+ * @param end The end of the function templating.
+ *
+ * @see #getReturnType Specifically, the 'columnType' argument is the 'dynamic' type.
+ */
public VarArgsSQLFunction(String begin, String sep, String end) {
- this.begin = begin;
- this.sep = sep;
- this.end = end;
- this.type = null;
+ this( null, begin, sep, end );
}
+ /**
+ * {@inheritDoc}
+ */
public Type getReturnType(Type columnType, Mapping mapping) throws QueryException {
- return type==null ? columnType : type;
+ return type == null ? columnType : type;
}
+ /**
+ * {@inheritDoc}
+ * <p/>
+ * Always returns true here.
+ */
public boolean hasArguments() {
return true;
}
+ /**
+ * {@inheritDoc}
+ * <p/>
+ * Always returns true here.
+ */
public boolean hasParenthesesIfNoArguments() {
return true;
}
+ /**
+ * {@inheritDoc}
+ */
public String render(List args, SessionFactoryImplementor factory) throws QueryException {
- StringBuffer buf = new StringBuffer().append(begin);
- for ( int i=0; i<args.size(); i++ ) {
- buf.append( args.get(i) );
- if (i<args.size()-1) buf.append(sep);
+ StringBuffer buf = new StringBuffer().append( begin );
+ for ( int i = 0; i < args.size(); i++ ) {
+ buf.append( transformArgument( ( String ) args.get( i ) ) );
+ if ( i < args.size() - 1 ) {
+ buf.append( sep );
+ }
}
- return buf.append(end).toString();
+ return buf.append( end ).toString();
}
+ /**
+ * Called from {@link #render} to allow applying a change or transformation to each individual
+ * argument.
+ *
+ * @param argument The argument being processed.
+ * @return The transformed argument; may be the same, though should never be null.
+ */
+ protected String transformArgument(String argument) {
+ return argument;
+ }
}
16 years, 3 months
Hibernate SVN: r15158 - in core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect: function and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2008-09-08 15:43:43 -0400 (Mon, 08 Sep 2008)
New Revision: 15158
Added:
core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/function/DerbyConcatFunction.java
Modified:
core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/DerbyDialect.java
core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/function/VarArgsSQLFunction.java
Log:
HHH-3424 : concat function on Derby
Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/DerbyDialect.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/DerbyDialect.java 2008-09-08 19:43:09 UTC (rev 15157)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/DerbyDialect.java 2008-09-08 19:43:43 UTC (rev 15158)
@@ -30,9 +30,9 @@
import org.hibernate.engine.Mapping;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.type.Type;
-import org.hibernate.dialect.function.VarArgsSQLFunction;
import org.hibernate.dialect.function.SQLFunction;
import org.hibernate.dialect.function.SQLFunctionTemplate;
+import org.hibernate.dialect.function.DerbyConcatFunction;
import org.hibernate.id.TableHiLoGenerator;
import org.hibernate.sql.CaseFragment;
import org.hibernate.sql.DerbyCaseFragment;
@@ -41,18 +41,18 @@
import java.util.ArrayList;
/**
- * @author Simon Johnston
- *
* Hibernate Dialect for Cloudscape 10 - aka Derby. This implements both an
* override for the identity column generator as well as for the case statement
* issue documented at:
* http://www.jroller.com/comments/kenlars99/Weblog/cloudscape_soon_to_be_derby
+ *
+ * @author Simon Johnston
*/
public class DerbyDialect extends DB2Dialect {
public DerbyDialect() {
super();
- registerFunction( "concat", new VarArgsSQLFunction( Hibernate.STRING, "(","||",")" ) );
+ registerFunction( "concat", new DerbyConcatFunction() );
registerFunction( "trim", new DerbyTrimFunctionEmulation() );
}
Added: core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/function/DerbyConcatFunction.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/function/DerbyConcatFunction.java (rev 0)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/function/DerbyConcatFunction.java 2008-09-08 19:43:43 UTC (rev 15158)
@@ -0,0 +1,179 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.dialect.function;
+
+import java.util.List;
+import java.util.Iterator;
+
+import org.hibernate.Hibernate;
+import org.hibernate.QueryException;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.type.Type;
+
+/**
+ * A specialized concat() function definition in which:<ol>
+ * <li>we translate to use the concat operator ('||')</li>
+ * <li>wrap dynamic parameters in CASTs to VARCHAR</li>
+ * </ol>
+ * <p/>
+ * This last spec is to deal with a limitation on DB2 and variants (e.g. Derby)
+ * where dynamic parameters cannot be used in concatenation unless they are being
+ * concatenated with at least one non-dynamic operand. And even then, the rules
+ * are so convoluted as to what is allowed and when the CAST is needed and when
+ * it is not that we just go ahead and do the CASTing.
+ *
+ * @author Steve Ebersole
+ */
+public class DerbyConcatFunction implements SQLFunction {
+ /**
+ * {@inheritDoc}
+ * <p/>
+ * Here we always return {@link Hibernate#STRING}.
+ */
+ public Type getReturnType(Type columnType, Mapping mapping) throws QueryException {
+ return Hibernate.STRING;
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p/>
+ * Here we always return <tt>true</tt>
+ */
+ public boolean hasArguments() {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p/>
+ * Here we always return <tt>true</tt>
+ */
+ public boolean hasParenthesesIfNoArguments() {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p/>
+ * Here's the meat.. The whole reason we have a separate impl for this for Derby is to re-define
+ * this method. The logic here says that if not all the incoming args are dynamic parameters
+ * (i.e. <tt>?</tt>) then we simply use the Derby concat operator (<tt>||</tt>) on the unchanged
+ * arg elements. However, if all the args are dynamic parameters, then we need to wrap the individual
+ * arg elements in <tt>cast</tt> function calls, use the concantenation operator on the <tt>cast</tt>
+ * returns, and then wrap that whole thing in a call to the Derby <tt>varchar</tt> function.
+ */
+ public String render(List args, SessionFactoryImplementor factory) throws QueryException {
+ boolean areAllArgsParams = true;
+ Iterator itr = args.iterator();
+ while ( itr.hasNext() ) {
+ final String arg = ( String ) itr.next();
+ if ( ! "?".equals( arg ) ) {
+ areAllArgsParams = false;
+ break;
+ }
+ }
+
+ if ( areAllArgsParams ) {
+ return join(
+ args.iterator(),
+ new StringTransformer() {
+ public String transform(String string) {
+ return "cast( ? as varchar(32672) )";
+ }
+ },
+ new StringJoinTemplate() {
+ public String getBeginning() {
+ return "varchar( ";
+ }
+ public String getSeparator() {
+ return " || ";
+ }
+ public String getEnding() {
+ return " )";
+ }
+ }
+ );
+ }
+ else {
+ return join(
+ args.iterator(),
+ new StringTransformer() {
+ public String transform(String string) {
+ return string;
+ }
+ },
+ new StringJoinTemplate() {
+ public String getBeginning() {
+ return "(";
+ }
+ public String getSeparator() {
+ return "||";
+ }
+ public String getEnding() {
+ return ")";
+ }
+ }
+ );
+ }
+ }
+
+ private static interface StringTransformer {
+ public String transform(String string);
+ }
+
+ private static interface StringJoinTemplate {
+ /**
+ * Getter for property 'beginning'.
+ *
+ * @return Value for property 'beginning'.
+ */
+ public String getBeginning();
+ /**
+ * Getter for property 'separator'.
+ *
+ * @return Value for property 'separator'.
+ */
+ public String getSeparator();
+ /**
+ * Getter for property 'ending'.
+ *
+ * @return Value for property 'ending'.
+ */
+ public String getEnding();
+ }
+
+ private String join(Iterator/*<String>*/ elements, StringTransformer elementTransformer, StringJoinTemplate template) {
+ StringBuffer buffer = new StringBuffer( template.getBeginning() );
+ while ( elements.hasNext() ) {
+ final String element = ( String ) elements.next();
+ buffer.append( elementTransformer.transform( element ) );
+ if ( elements.hasNext() ) {
+ buffer.append( template.getSeparator() );
+ }
+ }
+ return buffer.append( template.getEnding() ).toString();
+ }
+}
Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/function/VarArgsSQLFunction.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/function/VarArgsSQLFunction.java 2008-09-08 19:43:09 UTC (rev 15157)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/function/VarArgsSQLFunction.java 2008-09-08 19:43:43 UTC (rev 15158)
@@ -32,50 +32,97 @@
import org.hibernate.type.Type;
/**
- * Support for slightly more general templating than <tt>StandardSQLFunction</tt>,
+ * Support for slightly more general templating than {@link StandardSQLFunction},
* with an unlimited number of arguments.
+ *
* @author Gavin King
*/
public class VarArgsSQLFunction implements SQLFunction {
-
private final String begin;
private final String sep;
private final String end;
private final Type type;
-
+
+ /**
+ * Constructs a VarArgsSQLFunction instance with a 'static' return type. An example of a 'static'
+ * return type would be something like an <tt>UPPER</tt> function which is always returning
+ * a SQL VARCHAR and thus a string type.
+ *
+ * @param type The return type.
+ * @param begin The beginning of the function templating.
+ * @param sep The separator for each individual function argument.
+ * @param end The end of the function templating.
+ */
public VarArgsSQLFunction(Type type, String begin, String sep, String end) {
+ this.type = type;
this.begin = begin;
this.sep = sep;
this.end = end;
- this.type = type;
}
+ /**
+ * Constructs a VarArgsSQLFunction instance with a 'dynamic' return type. For a dynamic return type,
+ * the type of the arguments are used to resolve the type. An example of a function with a
+ * 'dynamic' return would be <tt>MAX</tt> or <tt>MIN</tt> which return a double or an integer etc
+ * based on the types of the arguments.
+ *
+ * @param begin The beginning of the function templating.
+ * @param sep The separator for each individual function argument.
+ * @param end The end of the function templating.
+ *
+ * @see #getReturnType Specifically, the 'columnType' argument is the 'dynamic' type.
+ */
public VarArgsSQLFunction(String begin, String sep, String end) {
- this.begin = begin;
- this.sep = sep;
- this.end = end;
- this.type = null;
+ this( null, begin, sep, end );
}
+ /**
+ * {@inheritDoc}
+ */
public Type getReturnType(Type columnType, Mapping mapping) throws QueryException {
- return type==null ? columnType : type;
+ return type == null ? columnType : type;
}
+ /**
+ * {@inheritDoc}
+ * <p/>
+ * Always returns true here.
+ */
public boolean hasArguments() {
return true;
}
+ /**
+ * {@inheritDoc}
+ * <p/>
+ * Always returns true here.
+ */
public boolean hasParenthesesIfNoArguments() {
return true;
}
+ /**
+ * {@inheritDoc}
+ */
public String render(List args, SessionFactoryImplementor factory) throws QueryException {
- StringBuffer buf = new StringBuffer().append(begin);
- for ( int i=0; i<args.size(); i++ ) {
- buf.append( args.get(i) );
- if (i<args.size()-1) buf.append(sep);
+ StringBuffer buf = new StringBuffer().append( begin );
+ for ( int i = 0; i < args.size(); i++ ) {
+ buf.append( transformArgument( ( String ) args.get( i ) ) );
+ if ( i < args.size() - 1 ) {
+ buf.append( sep );
+ }
}
- return buf.append(end).toString();
+ return buf.append( end ).toString();
}
+ /**
+ * Called from {@link #render} to allow applying a change or transformation to each individual
+ * argument.
+ *
+ * @param argument The argument being processed.
+ * @return The transformed argument; may be the same, though should never be null.
+ */
+ protected String transformArgument(String argument) {
+ return argument;
+ }
}
16 years, 3 months
Hibernate SVN: r15157 - in core/trunk/core/src/main/java/org/hibernate/dialect: function and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2008-09-08 15:43:09 -0400 (Mon, 08 Sep 2008)
New Revision: 15157
Added:
core/trunk/core/src/main/java/org/hibernate/dialect/function/DerbyConcatFunction.java
Modified:
core/trunk/core/src/main/java/org/hibernate/dialect/DerbyDialect.java
core/trunk/core/src/main/java/org/hibernate/dialect/function/VarArgsSQLFunction.java
Log:
HHH-3424 : concat function on Derby
Modified: core/trunk/core/src/main/java/org/hibernate/dialect/DerbyDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/DerbyDialect.java 2008-09-08 14:07:27 UTC (rev 15156)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/DerbyDialect.java 2008-09-08 19:43:09 UTC (rev 15157)
@@ -30,9 +30,9 @@
import org.hibernate.engine.Mapping;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.type.Type;
-import org.hibernate.dialect.function.VarArgsSQLFunction;
import org.hibernate.dialect.function.SQLFunction;
import org.hibernate.dialect.function.SQLFunctionTemplate;
+import org.hibernate.dialect.function.DerbyConcatFunction;
import org.hibernate.id.TableHiLoGenerator;
import org.hibernate.sql.CaseFragment;
import org.hibernate.sql.DerbyCaseFragment;
@@ -41,18 +41,18 @@
import java.util.ArrayList;
/**
- * @author Simon Johnston
- *
* Hibernate Dialect for Cloudscape 10 - aka Derby. This implements both an
* override for the identity column generator as well as for the case statement
* issue documented at:
* http://www.jroller.com/comments/kenlars99/Weblog/cloudscape_soon_to_be_derby
+ *
+ * @author Simon Johnston
*/
public class DerbyDialect extends DB2Dialect {
public DerbyDialect() {
super();
- registerFunction( "concat", new VarArgsSQLFunction( Hibernate.STRING, "(","||",")" ) );
+ registerFunction( "concat", new DerbyConcatFunction() );
registerFunction( "trim", new DerbyTrimFunctionEmulation() );
}
Added: core/trunk/core/src/main/java/org/hibernate/dialect/function/DerbyConcatFunction.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/function/DerbyConcatFunction.java (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/function/DerbyConcatFunction.java 2008-09-08 19:43:09 UTC (rev 15157)
@@ -0,0 +1,180 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.dialect.function;
+
+import java.util.List;
+import java.util.Iterator;
+
+import org.hibernate.Hibernate;
+import org.hibernate.QueryException;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.type.Type;
+
+/**
+ * A specialized concat() function definition in which:<ol>
+ * <li>we translate to use the concat operator ('||')</li>
+ * <li>wrap dynamic parameters in CASTs to VARCHAR</li>
+ * </ol>
+ * <p/>
+ * This last spec is to deal with a limitation on DB2 and variants (e.g. Derby)
+ * where dynamic parameters cannot be used in concatenation unless they are being
+ * concatenated with at least one non-dynamic operand. And even then, the rules
+ * are so convoluted as to what is allowed and when the CAST is needed and when
+ * it is not that we just go ahead and do the CASTing.
+ *
+ * @author Steve Ebersole
+ */
+public class DerbyConcatFunction implements SQLFunction {
+ /**
+ * {@inheritDoc}
+ * <p/>
+ * Here we always return {@link Hibernate#STRING}.
+ */
+ public Type getReturnType(Type columnType, Mapping mapping) throws QueryException {
+ return Hibernate.STRING;
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p/>
+ * Here we always return <tt>true</tt>
+ */
+ public boolean hasArguments() {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p/>
+ * Here we always return <tt>true</tt>
+ */
+ public boolean hasParenthesesIfNoArguments() {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p/>
+ * Here's the meat.. The whole reason we have a separate impl for this for Derby is to re-define
+ * this method. The logic here says that if not all the incoming args are dynamic parameters
+ * (i.e. <tt>?</tt>) then we simply use the Derby concat operator (<tt>||</tt>) on the unchanged
+ * arg elements. However, if all the args are dynamic parameters, then we need to wrap the individual
+ * arg elements in <tt>cast</tt> function calls, use the concantenation operator on the <tt>cast</tt>
+ * returns, and then wrap that whole thing in a call to the Derby <tt>varchar</tt> function.
+ */
+ public String render(List args, SessionFactoryImplementor factory) throws QueryException {
+ boolean areAllArgsParams = true;
+ Iterator itr = args.iterator();
+ while ( itr.hasNext() ) {
+ final String arg = ( String ) itr.next();
+ if ( ! "?".equals( arg ) ) {
+ areAllArgsParams = false;
+ break;
+ }
+ }
+
+ if ( areAllArgsParams ) {
+ return join(
+ args.iterator(),
+ new StringTransformer() {
+ public String transform(String string) {
+ return "cast( ? as varchar(32672) )";
+ }
+ },
+ new StringJoinTemplate() {
+ public String getBeginning() {
+ return "varchar( ";
+ }
+ public String getSeparator() {
+ return " || ";
+ }
+ public String getEnding() {
+ return " )";
+ }
+ }
+ );
+ }
+ else {
+ return join(
+ args.iterator(),
+ new StringTransformer() {
+ public String transform(String string) {
+ return string;
+ }
+ },
+ new StringJoinTemplate() {
+ public String getBeginning() {
+ return "(";
+ }
+ public String getSeparator() {
+ return "||";
+ }
+ public String getEnding() {
+ return ")";
+ }
+ }
+ );
+ }
+ }
+
+ private static interface StringTransformer {
+ public String transform(String string);
+ }
+
+ private static interface StringJoinTemplate {
+ /**
+ * Getter for property 'beginning'.
+ *
+ * @return Value for property 'beginning'.
+ */
+ public String getBeginning();
+ /**
+ * Getter for property 'separator'.
+ *
+ * @return Value for property 'separator'.
+ */
+ public String getSeparator();
+ /**
+ * Getter for property 'ending'.
+ *
+ * @return Value for property 'ending'.
+ */
+ public String getEnding();
+ }
+
+ private static String join(Iterator/*<String>*/ elements, StringTransformer elementTransformer, StringJoinTemplate template) {
+ // todo : make this available via StringHelper?
+ StringBuffer buffer = new StringBuffer( template.getBeginning() );
+ while ( elements.hasNext() ) {
+ final String element = ( String ) elements.next();
+ buffer.append( elementTransformer.transform( element ) );
+ if ( elements.hasNext() ) {
+ buffer.append( template.getSeparator() );
+ }
+ }
+ return buffer.append( template.getEnding() ).toString();
+ }
+}
Modified: core/trunk/core/src/main/java/org/hibernate/dialect/function/VarArgsSQLFunction.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/function/VarArgsSQLFunction.java 2008-09-08 14:07:27 UTC (rev 15156)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/function/VarArgsSQLFunction.java 2008-09-08 19:43:09 UTC (rev 15157)
@@ -32,50 +32,97 @@
import org.hibernate.type.Type;
/**
- * Support for slightly more general templating than <tt>StandardSQLFunction</tt>,
+ * Support for slightly more general templating than {@link StandardSQLFunction},
* with an unlimited number of arguments.
+ *
* @author Gavin King
*/
public class VarArgsSQLFunction implements SQLFunction {
-
private final String begin;
private final String sep;
private final String end;
private final Type type;
-
+
+ /**
+ * Constructs a VarArgsSQLFunction instance with a 'static' return type. An example of a 'static'
+ * return type would be something like an <tt>UPPER</tt> function which is always returning
+ * a SQL VARCHAR and thus a string type.
+ *
+ * @param type The return type.
+ * @param begin The beginning of the function templating.
+ * @param sep The separator for each individual function argument.
+ * @param end The end of the function templating.
+ */
public VarArgsSQLFunction(Type type, String begin, String sep, String end) {
+ this.type = type;
this.begin = begin;
this.sep = sep;
this.end = end;
- this.type = type;
}
+ /**
+ * Constructs a VarArgsSQLFunction instance with a 'dynamic' return type. For a dynamic return type,
+ * the type of the arguments are used to resolve the type. An example of a function with a
+ * 'dynamic' return would be <tt>MAX</tt> or <tt>MIN</tt> which return a double or an integer etc
+ * based on the types of the arguments.
+ *
+ * @param begin The beginning of the function templating.
+ * @param sep The separator for each individual function argument.
+ * @param end The end of the function templating.
+ *
+ * @see #getReturnType Specifically, the 'columnType' argument is the 'dynamic' type.
+ */
public VarArgsSQLFunction(String begin, String sep, String end) {
- this.begin = begin;
- this.sep = sep;
- this.end = end;
- this.type = null;
+ this( null, begin, sep, end );
}
+ /**
+ * {@inheritDoc}
+ */
public Type getReturnType(Type columnType, Mapping mapping) throws QueryException {
- return type==null ? columnType : type;
+ return type == null ? columnType : type;
}
+ /**
+ * {@inheritDoc}
+ * <p/>
+ * Always returns true here.
+ */
public boolean hasArguments() {
return true;
}
+ /**
+ * {@inheritDoc}
+ * <p/>
+ * Always returns true here.
+ */
public boolean hasParenthesesIfNoArguments() {
return true;
}
+ /**
+ * {@inheritDoc}
+ */
public String render(List args, SessionFactoryImplementor factory) throws QueryException {
- StringBuffer buf = new StringBuffer().append(begin);
- for ( int i=0; i<args.size(); i++ ) {
- buf.append( args.get(i) );
- if (i<args.size()-1) buf.append(sep);
+ StringBuffer buf = new StringBuffer().append( begin );
+ for ( int i = 0; i < args.size(); i++ ) {
+ buf.append( transformArgument( ( String ) args.get( i ) ) );
+ if ( i < args.size() - 1 ) {
+ buf.append( sep );
+ }
}
- return buf.append(end).toString();
+ return buf.append( end ).toString();
}
+ /**
+ * Called from {@link #render} to allow applying a change or transformation to each individual
+ * argument.
+ *
+ * @param argument The argument being processed.
+ * @return The transformed argument; may be the same, though should never be null.
+ */
+ protected String transformArgument(String argument) {
+ return argument;
+ }
}
16 years, 3 months