[#1072] Add support for LIKE .. ESCAPE .. syntax

This commit is contained in:
Lukas Eder 2012-01-27 09:27:56 +00:00
parent 23a26069f2
commit 5115e356f9
5 changed files with 184 additions and 16 deletions

View File

@ -8179,6 +8179,8 @@ public abstract class jOOQAbstractTest<
@Test
public void testLike() throws Exception {
reset = false;
Field<String> notLike = TBook_PUBLISHED_IN().cast(String.class);
// DB2 doesn't support this syntax
@ -8193,6 +8195,25 @@ public abstract class jOOQAbstractTest<
.fetch();
assertEquals(3, books.size());
assertEquals(1,
create().insertInto(TBook())
.set(TBook_ID(), 5)
.set(TBook_AUTHOR_ID(), 2)
.set(TBook_PUBLISHED_IN(), 2012)
.set((Field<Integer>) TBook_LANGUAGE_ID(), 1)
.set(TBook_TITLE(), "About percentages (%) and underscores (_), a critical review")
.execute());
// [#1072] Add checks for ESCAPE syntax
books =
create().selectFrom(TBook())
.where(TBook_TITLE().like("%(!%)%", '!'))
.and(TBook_TITLE().like("%(#_)%", '#'))
.and(TBook_TITLE().notLike("%(!%)%", '#'))
.and(TBook_TITLE().notLike("%(#_)%", '!'))
.fetch();
}
@Test

View File

@ -376,109 +376,205 @@ public interface Field<T> extends NamedTypeProviderQueryPart<T>, AliasProvider<F
// ------------------------------------------------------------------------
/**
* <code>this is null</code>
* Create a condition to check this field against <code>null</code>.
* <p>
* SQL: <code>this is null</code>
*/
@Support
Condition isNull();
/**
* <code>this is not null</code>
* Create a condition to check this field against <code>null</code>.
* <p>
* SQL: <code>this is not null</code>
*/
@Support
Condition isNotNull();
/**
* Create a condition to check this field known string literals for
* <code>true</code>
* <p>
* SQL:
* <code>lcase(this) in ("1", "y", "yes", "true", "on", "enabled")</code>
*/
@Support
Condition isTrue();
/**
* Create a condition to check this field known string literals for
* <code>false</code>
* <p>
* SQL:
* <code>lcase(this) in ("0", "n", "no", "false", "off", "disabled")</code>
*/
@Support
Condition isFalse();
/**
* <code>this like value</code>
* Create a condition to pattern-check this field against a value
* <p>
* SQL: <code>this like value</code>
*/
@Support
Condition like(Field<T> value);
/**
* <code>this like value</code>
* Create a condition to pattern-check this field against a value
* <p>
* SQL: <code>this like value escape 'e'</code>
*/
@Support
Condition like(Field<T> value, char escape);
/**
* Create a condition to pattern-check this field against a value
* <p>
* SQL: <code>this like value</code>
*/
@Support
Condition like(T value);
/**
* <code>this not like value</code>
* Create a condition to pattern-check this field against a value
* <p>
* SQL: <code>this like value escape 'e'</code>
*/
@Support
Condition like(T value, char escape);
/**
* Create a condition to pattern-check this field against a value
* <p>
* SQL: <code>this not like value</code>
*/
@Support
Condition notLike(Field<T> value);
/**
* <code>this not like value</code>
* Create a condition to pattern-check this field against a value
* <p>
* SQL: <code>this not like value escape 'e'</code>
*/
@Support
Condition notLike(Field<T> value, char escape);
/**
* Create a condition to pattern-check this field against a value
* <p>
* SQL: <code>this not like value</code>
*/
@Support
Condition notLike(T value);
/**
* <code>this in (values...)</code>
* Create a condition to pattern-check this field against a value
* <p>
* SQL: <code>this not like value escape 'e'</code>
*/
@Support
Condition notLike(T value, char escape);
/**
* Create a condition to check this field against several values
* <p>
* SQL: <code>this in (values...)</code>
*/
@Support
Condition in(Collection<T> values);
/**
* <code>this in (values...)</code>
* Create a condition to check this field against several values
* <p>
* SQL: <code>this in (values...)</code>
*/
@Support
Condition in(T... values);
/**
* <code>this in (values...)</code>
* Create a condition to check this field against several values
* <p>
* SQL: <code>this in (values...)</code>
*/
@Support
Condition in(Field<?>... values);
/**
* <code>this in (select...)</code>
* Create a condition to check this field against a subquery
* <p>
* Note that the subquery must return exactly one field. This is not checked
* by jOOQ and will result in syntax errors on the database, if not used
* correctly.
* <p>
* SQL: <code>this in (select...)</code>
*/
@Support
Condition in(Select<?> query);
/**
* <code>this not in (values...)</code>
* Create a condition to check this field against several values
* <p>
* Note that if any of the passed values is <code>NULL</code>, then the
* condition will be <code>NULL</code> (or <code>false</code>, depending on
* the dialect) as well. This is standard SQL behaviour.
* <p>
* SQL: <code>this not in (values...)</code>
*/
@Support
Condition notIn(Collection<T> values);
/**
* <code>this not in (values...)</code>
* Create a condition to check this field against several values
* <p>
* Note that if any of the passed values is <code>NULL</code>, then the
* condition will be <code>NULL</code> (or <code>false</code>, depending on
* the dialect) as well. This is standard SQL behaviour.
* <p>
* SQL: <code>this not in (values...)</code>
*/
@Support
Condition notIn(T... values);
/**
* <code>this not in (values...)</code>
* Create a condition to check this field against several values
* <p>
* Note that if any of the passed values is <code>NULL</code>, then the
* condition will be <code>NULL</code> (or <code>false</code>, depending on
* the dialect) as well. This is standard SQL behaviour.
* <p>
* SQL: <code>this not in (values...)</code>
*/
@Support
Condition notIn(Field<?>... values);
/**
* <code>this not in (select...)</code>
* Create a condition to check this field against a subquery
* <p>
* Note that the subquery must return exactly one field. This is not checked
* by jOOQ and will result in syntax errors on the database, if not used
* correctly.
* <p>
* Note that if any of the passed values is <code>NULL</code>, then the
* condition will be <code>NULL</code> (or <code>false</code>, depending on
* the dialect) as well. This is standard SQL behaviour.
* <p>
* SQL: <code>this not in (select...)</code>
*/
@Support
Condition notIn(Select<?> query);
/**
* <code>this between minValue and maxValue</code>
* Create a condition to check this field against some bounds
* <p>
* SQL: <code>this between minValue and maxValue</code>
*/
@Support
Condition between(T minValue, T maxValue);
/**
* <code>this between minValue and maxValue</code>
* Create a condition to check this field against some bounds
* <p>
* SQL: <code>this between minValue and maxValue</code>
*/
@Support
Condition between(Field<T> minValue, Field<T> maxValue);

View File

@ -343,21 +343,41 @@ abstract class AbstractField<T> extends AbstractNamedTypeProviderQueryPart<T> im
return like(val(value));
}
@Override
public final Condition like(T value, char escape) {
return like(val(value), escape);
}
@Override
public final Condition like(Field<T> value) {
return new CompareCondition<T>(this, nullSafe(value), Comparator.LIKE);
}
@Override
public final Condition like(Field<T> value, char escape) {
return new CompareCondition<T>(this, nullSafe(value), Comparator.LIKE, escape);
}
@Override
public final Condition notLike(T value) {
return notLike(val(value));
}
@Override
public final Condition notLike(T value, char escape) {
return notLike(val(value), escape);
}
@Override
public final Condition notLike(Field<T> value) {
return new CompareCondition<T>(this, nullSafe(value), Comparator.NOT_LIKE);
}
@Override
public final Condition notLike(Field<T> value, char escape) {
return new CompareCondition<T>(this, nullSafe(value), Comparator.NOT_LIKE, escape);
}
@Override
public final Condition in(T... values) {
return in(vals(values).toArray(new Field<?>[0]));

View File

@ -54,11 +54,17 @@ class CompareCondition<T> extends AbstractCondition {
private final Field<T> field1;
private final Field<T> field2;
private final Comparator comparator;
private final Character escape;
CompareCondition(Field<T> field1, Field<T> field2, Comparator comparator) {
this(field1, field2, comparator, null);
}
CompareCondition(Field<T> field1, Field<T> field2, Comparator comparator, Character escape) {
this.field1 = field1;
this.field2 = field2;
this.comparator = comparator;
this.escape = escape;
}
@Override
@ -91,5 +97,11 @@ class CompareCondition<T> extends AbstractCondition {
context.sql(comparator.toSQL())
.sql(" ")
.sql(field2);
if (escape != null) {
context.sql(" escape '")
.sql(escape)
.sql("'");
}
}
}

View File

@ -720,6 +720,25 @@ public class jOOQTest {
context.assertIsSatisfied();
}
@Test
public void testLikeCondition() throws Exception {
Condition c1 = FIELD_NAME1.like("%a%");
assertEquals("\"TABLE1\".\"ID1\" like '%a%')", r_refI().render(c1));
assertEquals("\"TABLE1\".\"ID1\" like ?)", r_ref().render(c1));
Condition c2 = FIELD_NAME1.notLike("%a%");
assertEquals("\"TABLE1\".\"ID1\" not like '%a%')", r_refI().render(c2));
assertEquals("\"TABLE1\".\"ID1\" not like ?)", r_ref().render(c2));
Condition c3 = FIELD_NAME1.like("%a%", '!');
assertEquals("\"TABLE1\".\"ID1\" like '%a%' escape '!')", r_refI().render(c3));
assertEquals("\"TABLE1\".\"ID1\" like ? escape '!')", r_ref().render(c3));
Condition c4 = FIELD_NAME1.notLike("%a%", '!');
assertEquals("\"TABLE1\".\"ID1\" not like '%a%' escape '!')", r_refI().render(c4));
assertEquals("\"TABLE1\".\"ID1\" not like ? escape '!')", r_ref().render(c4));
}
@Test
public void testPlainSQLCondition() throws Exception {
Condition c1 = condition("TABLE1.ID = 10");