@Computed enhancements from Zell.

This commit is contained in:
Michael Bayne
2006-10-20 04:26:27 +00:00
parent 2fabde7b1c
commit 1845859344
3 changed files with 45 additions and 6 deletions
@@ -20,12 +20,22 @@
package com.samskivert.jdbc.depot; 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 * 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}. * 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 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; 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. * 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 this field is @Computed, it has no SQL definition
if (field.getAnnotation(Computed.class) != null) { if (_computed != null) {
_columnDefinition = null; _columnDefinition = null;
return; return;
} }
@@ -383,5 +392,6 @@ public abstract class FieldMarshaller
protected Field _field; protected Field _field;
protected String _columnName, _columnDefinition; protected String _columnName, _columnDefinition;
protected Computed _computed;
protected GeneratedValue _generatedValue; protected GeneratedValue _generatedValue;
} }
+22 -3
View File
@@ -94,18 +94,37 @@ public abstract class Query<T>
DepotMarshaller<?> mainMarshaller = _classMap.get(_mainType); DepotMarshaller<?> mainMarshaller = _classMap.get(_mainType);
String[] fields = mainMarshaller._allFields; String[] fields = mainMarshaller._allFields;
StringBuilder query = new StringBuilder("select "); StringBuilder query = new StringBuilder("select ");
boolean skip = true;
for (int ii = 0; ii < fields.length; ii ++) { for (int ii = 0; ii < fields.length; ii ++) {
if (ii > 0) { if (!skip) {
query.append(", "); query.append(", ");
} }
skip = false;
FieldOverrideClause clause = _disMap.get(fields[ii]); FieldOverrideClause clause = _disMap.get(fields[ii]);
if (clause != null) { if (clause != null) {
clause.appendClause(this, query); 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]); 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 { } else {
throw new SQLException( 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 "); query.append(" from " + mainMarshaller.getTableName() + " as T ");