@Computed enhancements from Zell.
This commit is contained in:
@@ -20,12 +20,22 @@
|
||||
|
||||
package com.samskivert.jdbc.depot;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Marks a field as computed, meaning it's ignored for schema purposes, it does not directly
|
||||
* correspond to a column in a table, and thus its value must be overridden in the {@link Query}.
|
||||
*
|
||||
* TODO: Add fieldDefinition="count (*)" or somesuch.
|
||||
*/
|
||||
@Retention(value=RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface Computed
|
||||
{
|
||||
/** If this value is false, the field is not populated by Depot at all. */
|
||||
boolean required() default true;
|
||||
|
||||
/** A non-empty value here is taken as literal SQL and used to populate the computed field. */
|
||||
String fieldDefinition() default "";
|
||||
}
|
||||
|
||||
@@ -109,6 +109,14 @@ public abstract class FieldMarshaller
|
||||
return _field;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Computed annotation on this field, if any.
|
||||
*/
|
||||
public Computed getComputed ()
|
||||
{
|
||||
return _computed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the GeneratedValue annotation on this field, if any.
|
||||
*/
|
||||
@@ -172,8 +180,9 @@ public abstract class FieldMarshaller
|
||||
}
|
||||
}
|
||||
|
||||
_computed = field.getAnnotation(Computed.class);
|
||||
// if this field is @Computed, it has no SQL definition
|
||||
if (field.getAnnotation(Computed.class) != null) {
|
||||
if (_computed != null) {
|
||||
_columnDefinition = null;
|
||||
return;
|
||||
}
|
||||
@@ -383,5 +392,6 @@ public abstract class FieldMarshaller
|
||||
|
||||
protected Field _field;
|
||||
protected String _columnName, _columnDefinition;
|
||||
protected Computed _computed;
|
||||
protected GeneratedValue _generatedValue;
|
||||
}
|
||||
|
||||
@@ -94,18 +94,37 @@ public abstract class Query<T>
|
||||
DepotMarshaller<?> mainMarshaller = _classMap.get(_mainType);
|
||||
String[] fields = mainMarshaller._allFields;
|
||||
StringBuilder query = new StringBuilder("select ");
|
||||
boolean skip = true;
|
||||
for (int ii = 0; ii < fields.length; ii ++) {
|
||||
if (ii > 0) {
|
||||
if (!skip) {
|
||||
query.append(", ");
|
||||
}
|
||||
skip = false;
|
||||
|
||||
FieldOverrideClause clause = _disMap.get(fields[ii]);
|
||||
if (clause != null) {
|
||||
clause.appendClause(this, query);
|
||||
} else if (mainMarshaller._fields.get(fields[ii]).getColumnDefinition() != null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Computed computed = mainMarshaller._fields.get(fields[ii]).getComputed();
|
||||
if (computed == null) {
|
||||
// if it's neither overridden nor computed, it's a standard field
|
||||
query.append("T.").append(fields[ii]);
|
||||
continue;
|
||||
}
|
||||
|
||||
// check if the computed field has a literal SQL definition
|
||||
if (computed.fieldDefinition().length() > 0) {
|
||||
query.append(computed.fieldDefinition() + " as " + fields[ii]);
|
||||
|
||||
} else if (!computed.required()) {
|
||||
// or if we can simply ignore the field
|
||||
skip = true;
|
||||
|
||||
} else {
|
||||
throw new SQLException(
|
||||
"Computed field must be overridden [field=" + fields[ii] + "]");
|
||||
"@Computed(required) field without definition [field=" + fields[ii] + "]");
|
||||
}
|
||||
}
|
||||
query.append(" from " + mainMarshaller.getTableName() + " as T ");
|
||||
|
||||
Reference in New Issue
Block a user