@@ -16,9 +16,13 @@ public interface Identifiable extends Serializable { | |||||
int UUID_MAXLEN = BasicConstraintConstants.UUID_MAXLEN; | int UUID_MAXLEN = BasicConstraintConstants.UUID_MAXLEN; | ||||
String CTIME = "ctime"; | |||||
String MTIME = "mtime"; | |||||
String ENTITY_TYPE_HEADER_NAME = "ZZ-TYPE"; | String ENTITY_TYPE_HEADER_NAME = "ZZ-TYPE"; | ||||
String[] IGNORABLE_UPDATE_FIELDS = { "uuid", "name", "children", "ctime", "mtime" }; | |||||
String[] IGNORABLE_UPDATE_FIELDS = { UUID, "name", "children", CTIME, MTIME }; | |||||
default String[] excludeUpdateFields(boolean strict) { return StringUtil.EMPTY_ARRAY; } | default String[] excludeUpdateFields(boolean strict) { return StringUtil.EMPTY_ARRAY; } | ||||
String getUuid(); | String getUuid(); | ||||
@@ -20,14 +20,16 @@ import javax.persistence.Transient; | |||||
import java.util.*; | import java.util.*; | ||||
import java.util.concurrent.ConcurrentHashMap; | import java.util.concurrent.ConcurrentHashMap; | ||||
import static java.util.UUID.randomUUID; | |||||
import static org.cobbzilla.util.daemon.ZillaRuntime.*; | import static org.cobbzilla.util.daemon.ZillaRuntime.*; | ||||
import static org.cobbzilla.util.reflect.ReflectionUtil.copy; | import static org.cobbzilla.util.reflect.ReflectionUtil.copy; | ||||
import static org.cobbzilla.util.string.StringUtil.uncapitalize; | |||||
@MappedSuperclass @Slf4j | @MappedSuperclass @Slf4j | ||||
public class IdentifiableBase implements Identifiable { | public class IdentifiableBase implements Identifiable { | ||||
public String simpleName () { return getClass().getSimpleName(); } | public String simpleName () { return getClass().getSimpleName(); } | ||||
public String propName () { return StringUtil.uncapitalize(getClass().getSimpleName()); } | |||||
public String propName () { return uncapitalize(getClass().getSimpleName()); } | |||||
public String tableName () { return ImprovedNamingStrategy.INSTANCE.classToTableName(getClass().getName()); } | public String tableName () { return ImprovedNamingStrategy.INSTANCE.classToTableName(getClass().getName()); } | ||||
public String tableName (String className) { return ImprovedNamingStrategy.INSTANCE.classToTableName(className); } | public String tableName (String className) { return ImprovedNamingStrategy.INSTANCE.classToTableName(className); } | ||||
@@ -74,7 +76,7 @@ public class IdentifiableBase implements Identifiable { | |||||
@Override public void beforeUpdate() { setMtime(); } | @Override public void beforeUpdate() { setMtime(); } | ||||
public void initUuid() { setUuid(java.util.UUID.randomUUID().toString()); } | |||||
public void initUuid() { setUuid(randomUUID().toString()); } | |||||
@Override public Identifiable update(Identifiable thing) { return update(thing, null); } | @Override public Identifiable update(Identifiable thing) { return update(thing, null); } | ||||
@@ -120,12 +122,12 @@ public class IdentifiableBase implements Identifiable { | |||||
public static String[] toUuidArray(List<? extends Identifiable> entities) { | public static String[] toUuidArray(List<? extends Identifiable> entities) { | ||||
return empty(entities) | return empty(entities) | ||||
? StringUtil.EMPTY_ARRAY | ? StringUtil.EMPTY_ARRAY | ||||
: (String[]) collectArray(entities, "uuid"); | |||||
: (String[]) collectArray(entities, UUID); | |||||
} | } | ||||
public static List<String> toUuidList(Collection<? extends Identifiable> entities) { | public static List<String> toUuidList(Collection<? extends Identifiable> entities) { | ||||
if (empty(entities)) return Collections.emptyList(); | if (empty(entities)) return Collections.emptyList(); | ||||
return collectList(entities, "uuid"); | |||||
return collectList(entities, UUID); | |||||
} | } | ||||
private static final Map<String, FieldTransformer> fieldTransformerCache = new ConcurrentHashMap<>(); | private static final Map<String, FieldTransformer> fieldTransformerCache = new ConcurrentHashMap<>(); | ||||
@@ -19,6 +19,7 @@ import static org.cobbzilla.util.daemon.ZillaRuntime.die; | |||||
import static org.cobbzilla.util.daemon.ZillaRuntime.empty; | import static org.cobbzilla.util.daemon.ZillaRuntime.empty; | ||||
import static org.cobbzilla.util.reflect.ReflectionUtil.instantiate; | import static org.cobbzilla.util.reflect.ReflectionUtil.instantiate; | ||||
import static org.cobbzilla.util.string.StringUtil.camelCaseToSnakeCase; | import static org.cobbzilla.util.string.StringUtil.camelCaseToSnakeCase; | ||||
import static org.cobbzilla.wizard.model.Identifiable.UUID; | |||||
import static org.cobbzilla.wizard.model.entityconfig.EntityFieldType.*; | import static org.cobbzilla.wizard.model.entityconfig.EntityFieldType.*; | ||||
import static org.cobbzilla.wizard.model.search.SearchField.*; | import static org.cobbzilla.wizard.model.search.SearchField.*; | ||||
@@ -64,7 +65,7 @@ public class SqlDefaultSearchField implements SearchField { | |||||
if (ecForeignKey != null) { | if (ecForeignKey != null) { | ||||
fieldType = reference; | fieldType = reference; | ||||
} else { | } else { | ||||
fieldType = ecField != null ? ecField.type() : guessFieldType(f); | |||||
fieldType = ecField != null && ecField.type() != none_set ? ecField.type() : guessFieldType(f); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -88,10 +89,12 @@ public class SqlDefaultSearchField implements SearchField { | |||||
case reference: | case reference: | ||||
bounds.addAll(asList(bindUuid(name()))); | bounds.addAll(asList(bindUuid(name()))); | ||||
break; | break; | ||||
case string: case email: case time_zone: case locale: | |||||
case ip4: case ip6: case http_url: | |||||
case us_phone: case us_state: case us_zip: | |||||
if (f.getName().equals("uuid")) { | |||||
case http_url: case us_phone: case us_state: case us_zip: | |||||
case email: case time_zone: case locale: case ip4: case ip6: | |||||
bounds.addAll(asList(bindNonSortableString(name()))); | |||||
break; | |||||
case string: | |||||
if (f.getName().equals(UUID)) { | |||||
bounds.addAll(asList(bindUuid(name()))); | bounds.addAll(asList(bindUuid(name()))); | ||||
} else { | } else { | ||||
bounds.addAll(asList(bindString(name()))); | bounds.addAll(asList(bindString(name()))); | ||||
@@ -374,7 +374,7 @@ public class EntityConfig { | |||||
return this; | return this; | ||||
} | } | ||||
private String fieldNameFromAccessor(AccessibleObject accessor) throws IllegalArgumentException { | |||||
public static String fieldNameFromAccessor(AccessibleObject accessor) throws IllegalArgumentException { | |||||
if (accessor instanceof Field) return ((Field) accessor).getName(); | if (accessor instanceof Field) return ((Field) accessor).getName(); | ||||
if (accessor instanceof Method) { | if (accessor instanceof Method) { | ||||
@@ -451,7 +451,7 @@ public class EntityConfig { | |||||
if (ecToUpdate == null) return this; | if (ecToUpdate == null) return this; | ||||
final String fieldName = fieldPathParts.get(fieldPathParts.size() - 1); | final String fieldName = fieldPathParts.get(fieldPathParts.size() - 1); | ||||
ecToUpdate.fields.put(fieldName, buildFieldCfgFromAnnotation(fieldName, annotation.fieldDef(), fieldIndexes)); | |||||
ecToUpdate.fields.put(fieldName, buildFieldCfgFromAnnotation(fieldName, annotation.fieldDef(), null, null, fieldIndexes)); | |||||
return this; | return this; | ||||
} | } | ||||
@@ -524,8 +524,14 @@ public class EntityConfig { | |||||
} | } | ||||
} | } | ||||
private EntityFieldConfig buildFieldCfgFromAnnotation(String fieldName, ECField fieldAnnotation, Map<String, Integer> fieldIndexes) { | |||||
EntityFieldConfig cfg = new EntityFieldConfig().setMode(fieldAnnotation.mode()).setType(fieldAnnotation.type()); | |||||
private EntityFieldConfig buildFieldCfgFromAnnotation(String fieldName, | |||||
ECField fieldAnnotation, | |||||
AccessibleObject accessor, | |||||
ECForeignKey fkAnnotation, | |||||
Map<String, Integer> fieldIndexes) { | |||||
final EntityFieldConfig cfg = new EntityFieldConfig() | |||||
.setMode(fieldAnnotation.mode()) | |||||
.setType(getFieldType(fieldName, fieldAnnotation, accessor, fkAnnotation)); | |||||
if (!empty(fieldAnnotation.name())) cfg.setName(fieldAnnotation.name()); | if (!empty(fieldAnnotation.name())) cfg.setName(fieldAnnotation.name()); | ||||
if (!empty(fieldAnnotation.displayName())) cfg.setDisplayName(fieldAnnotation.displayName()); | if (!empty(fieldAnnotation.displayName())) cfg.setDisplayName(fieldAnnotation.displayName()); | ||||
if (fieldAnnotation.length() > 0) cfg.setLength(fieldAnnotation.length()); | if (fieldAnnotation.length() > 0) cfg.setLength(fieldAnnotation.length()); | ||||
@@ -540,13 +546,30 @@ public class EntityConfig { | |||||
return cfg; | return cfg; | ||||
} | } | ||||
private EntityFieldType getFieldType(String fieldName, ECField fieldAnnotation, AccessibleObject accessor, ECForeignKey fkAnnotation) { | |||||
if (fieldAnnotation.type() != EntityFieldType.none_set) return fieldAnnotation.type(); | |||||
if (fkAnnotation != null) return EntityFieldType.reference; | |||||
if (accessor != null) { | |||||
if (accessor instanceof Field) { | |||||
return EntityFieldType.guessFieldType((Field) accessor); | |||||
} else if (accessor instanceof Method) { | |||||
return EntityFieldType.guessFieldType((Method) accessor); | |||||
} else { | |||||
log.warn("getFieldType("+fieldName+"): accessor is neither Field nor Method: "+accessor.getClass().getName()); | |||||
} | |||||
} | |||||
log.warn("getFieldType("+fieldName+"): error detecting type, defaulting to 'string'"); | |||||
return EntityFieldType.string; | |||||
} | |||||
private EntityFieldConfig buildFieldConfig(AccessibleObject accessor, Map<String, Integer> fieldIndexes) { | private EntityFieldConfig buildFieldConfig(AccessibleObject accessor, Map<String, Integer> fieldIndexes) { | ||||
final String fieldName = fieldNameFromAccessor(accessor); | final String fieldName = fieldNameFromAccessor(accessor); | ||||
final EntityFieldConfig cfg = EntityFieldConfig.field(fieldName); | final EntityFieldConfig cfg = EntityFieldConfig.field(fieldName); | ||||
final ECField fieldAnnotation = annotationFromAccessor(accessor, ECField.class); | final ECField fieldAnnotation = annotationFromAccessor(accessor, ECField.class); | ||||
final ECForeignKey fkAnnotation = annotationFromAccessor(accessor, ECForeignKey.class); | |||||
if (fieldAnnotation != null) { | if (fieldAnnotation != null) { | ||||
return buildFieldCfgFromAnnotation(fieldName, fieldAnnotation, fieldIndexes); | |||||
return buildFieldCfgFromAnnotation(fieldName, fieldAnnotation, accessor, fkAnnotation, fieldIndexes); | |||||
} | } | ||||
if (!(accessor instanceof Field) && !(accessor instanceof Method)) { | if (!(accessor instanceof Field) && !(accessor instanceof Method)) { | ||||
@@ -9,9 +9,13 @@ import org.cobbzilla.wizard.validation.Validator; | |||||
import javax.persistence.Column; | import javax.persistence.Column; | ||||
import java.lang.reflect.Field; | import java.lang.reflect.Field; | ||||
import java.lang.reflect.Method; | |||||
import java.util.Locale; | import java.util.Locale; | ||||
import static org.cobbzilla.util.daemon.ZillaRuntime.empty; | import static org.cobbzilla.util.daemon.ZillaRuntime.empty; | ||||
import static org.cobbzilla.wizard.model.Identifiable.CTIME; | |||||
import static org.cobbzilla.wizard.model.Identifiable.MTIME; | |||||
import static org.cobbzilla.wizard.model.entityconfig.EntityConfig.fieldNameFromAccessor; | |||||
@AllArgsConstructor @Slf4j | @AllArgsConstructor @Slf4j | ||||
public enum EntityFieldType { | public enum EntityFieldType { | ||||
@@ -149,13 +153,21 @@ public enum EntityFieldType { | |||||
} | } | ||||
public static EntityFieldType guessFieldType(Field f) { | public static EntityFieldType guessFieldType(Field f) { | ||||
switch (f.getType().getName()) { | |||||
return guessFieldType(f.getName(), f.getType()); | |||||
} | |||||
public static EntityFieldType guessFieldType(Method m) { | |||||
return guessFieldType(fieldNameFromAccessor(m), m.getReturnType()); | |||||
} | |||||
public static EntityFieldType guessFieldType(String name, Class<?> type) { | |||||
switch (type.getName()) { | |||||
case "boolean": | case "boolean": | ||||
case "java.lang.Boolean": | case "java.lang.Boolean": | ||||
return flag; | return flag; | ||||
case "long": | case "long": | ||||
case "java.lang.Long": | case "java.lang.Long": | ||||
if (f.getName().equals("ctime") || f.getName().equals("mtime")) return epoch_time; | |||||
if (name.equals(CTIME) || name.equals(MTIME)) return epoch_time; | |||||
case "byte": | case "byte": | ||||
case "short": | case "short": | ||||
case "int": | case "int": | ||||
@@ -175,8 +187,8 @@ public enum EntityFieldType { | |||||
case "java.math.BigDecimal": | case "java.math.BigDecimal": | ||||
return decimal; | return decimal; | ||||
default: | default: | ||||
if (f.getType().isEnum()) return string; | |||||
log.warn("guessFieldType: unrecognized type ("+f.getType().getName()+") for field: "+f.getName()); | |||||
if (type.isEnum()) return string; | |||||
log.warn("guessFieldType: unrecognized type ("+type.getName()+") for field: "+name); | |||||
return null; | return null; | ||||
} | } | ||||
} | } | ||||
@@ -23,6 +23,9 @@ import static org.cobbzilla.util.io.FileUtil.toFileOrDie; | |||||
import static org.cobbzilla.util.io.StreamUtil.loadResourceAsStringOrDie; | import static org.cobbzilla.util.io.StreamUtil.loadResourceAsStringOrDie; | ||||
import static org.cobbzilla.util.json.JsonUtil.*; | import static org.cobbzilla.util.json.JsonUtil.*; | ||||
import static org.cobbzilla.util.reflect.ReflectionUtil.*; | import static org.cobbzilla.util.reflect.ReflectionUtil.*; | ||||
import static org.cobbzilla.wizard.model.Identifiable.UUID; | |||||
import static org.cobbzilla.wizard.model.Identifiable.CTIME; | |||||
import static org.cobbzilla.wizard.model.Identifiable.MTIME; | |||||
import static org.cobbzilla.wizard.model.entityconfig.ModelSetup.id; | import static org.cobbzilla.wizard.model.entityconfig.ModelSetup.id; | ||||
@Slf4j | @Slf4j | ||||
@@ -157,7 +160,7 @@ public class StandardModelVerifyLog implements ModelVerifyLog { | |||||
} | } | ||||
} | } | ||||
protected static final String[] EXCLUDED = {"uuid", "children", "entity", "ctime", "ctimeAge", "mtime", "mtimeAge", "entity"}; | |||||
protected static final String[] EXCLUDED = {UUID, "children", CTIME, "ctimeAge", MTIME, "mtimeAge", "entity"}; | |||||
protected static final Set<String> EXCLUDED_FIELDS = new HashSet<>(Arrays.asList(EXCLUDED)); | protected static final Set<String> EXCLUDED_FIELDS = new HashSet<>(Arrays.asList(EXCLUDED)); | ||||
protected Set<String> getExcludedFields() { return EXCLUDED_FIELDS; } | protected Set<String> getExcludedFields() { return EXCLUDED_FIELDS; } | ||||
@@ -17,7 +17,7 @@ public @interface ECField { | |||||
String name() default ""; | String name() default ""; | ||||
String displayName() default ""; | String displayName() default ""; | ||||
EntityFieldMode mode() default EntityFieldMode.standard; | EntityFieldMode mode() default EntityFieldMode.standard; | ||||
EntityFieldType type() default EntityFieldType.string; | |||||
EntityFieldType type() default EntityFieldType.none_set; | |||||
int length() default -1; | int length() default -1; | ||||
EntityFieldControl control() default EntityFieldControl.unset; | EntityFieldControl control() default EntityFieldControl.unset; | ||||
String options() default ""; | String options() default ""; | ||||
@@ -59,13 +59,14 @@ public interface SearchField { | |||||
like.bind(name, SearchFieldType.string) | like.bind(name, SearchFieldType.string) | ||||
}; | }; | ||||
} | } | ||||
static SearchBound[] bindUuid(String name) { | |||||
static SearchBound[] bindNonSortableString(String name) { | |||||
return new SearchBound[] { | return new SearchBound[] { | ||||
eq.bind(name, SearchFieldType.string), | eq.bind(name, SearchFieldType.string), | ||||
ne.bind(name, SearchFieldType.string), | ne.bind(name, SearchFieldType.string), | ||||
like.bind(name, SearchFieldType.string) | like.bind(name, SearchFieldType.string) | ||||
}; | }; | ||||
} | } | ||||
static SearchBound[] bindUuid(String name) { return bindNonSortableString(name); } | |||||
static SearchBound[] bindNullable(String name) { return new SearchBound[] { is_null.bind(name), not_null.bind(name) }; } | static SearchBound[] bindNullable(String name) { return new SearchBound[] { is_null.bind(name), not_null.bind(name) }; } | ||||
String name(); | String name(); | ||||
@@ -18,6 +18,7 @@ import java.util.Arrays; | |||||
import static org.cobbzilla.util.daemon.ZillaRuntime.die; | import static org.cobbzilla.util.daemon.ZillaRuntime.die; | ||||
import static org.cobbzilla.util.daemon.ZillaRuntime.empty; | import static org.cobbzilla.util.daemon.ZillaRuntime.empty; | ||||
import static org.cobbzilla.wizard.model.Identifiable.CTIME; | |||||
@NoArgsConstructor @Accessors(chain=true) @ToString | @NoArgsConstructor @Accessors(chain=true) @ToString | ||||
public class SearchQuery { | public class SearchQuery { | ||||
@@ -35,7 +36,7 @@ public class SearchQuery { | |||||
public static final int MAX_FILTER_LENGTH = 50; | public static final int MAX_FILTER_LENGTH = 50; | ||||
public static final int MAX_SORTFIELD_LENGTH = 50; | public static final int MAX_SORTFIELD_LENGTH = 50; | ||||
public static final String DEFAULT_SORT_FIELD = "ctime"; | |||||
public static final String DEFAULT_SORT_FIELD = CTIME; | |||||
public enum SortOrder { | public enum SortOrder { | ||||
ASC, DESC; | ASC, DESC; | ||||
@@ -39,6 +39,7 @@ import static org.cobbzilla.util.json.JsonUtil.json; | |||||
import static org.cobbzilla.util.json.JsonUtil.toJsonOrDie; | import static org.cobbzilla.util.json.JsonUtil.toJsonOrDie; | ||||
import static org.cobbzilla.util.reflect.ReflectionUtil.*; | import static org.cobbzilla.util.reflect.ReflectionUtil.*; | ||||
import static org.cobbzilla.util.time.TimeUtil.formatDuration; | import static org.cobbzilla.util.time.TimeUtil.formatDuration; | ||||
import static org.cobbzilla.wizard.model.Identifiable.MTIME; | |||||
import static org.hibernate.criterion.Restrictions.*; | import static org.hibernate.criterion.Restrictions.*; | ||||
@Transactional @Slf4j | @Transactional @Slf4j | ||||
@@ -57,19 +58,19 @@ public abstract class AbstractCRUDDAO<E extends Identifiable> | |||||
@Override public List<E> findAll() { return list(criteria()); } | @Override public List<E> findAll() { return list(criteria()); } | ||||
@Transactional(readOnly=true) | @Transactional(readOnly=true) | ||||
@Override public E findByUuid(String uuid) { return findByUniqueField("uuid", uuid); } | |||||
@Override public E findByUuid(String uuid) { return findByUniqueField(Identifiable.UUID, uuid); } | |||||
@Transactional(readOnly=true) | @Transactional(readOnly=true) | ||||
public List<E> findByUuids(Collection<String> uuids) { | public List<E> findByUuids(Collection<String> uuids) { | ||||
return empty(uuids) ? new ArrayList<E>() : findByFieldIn("uuid", uuids); | |||||
return empty(uuids) ? new ArrayList<E>() : findByFieldIn(Identifiable.UUID, uuids); | |||||
} | } | ||||
@Transactional(readOnly=true) | @Transactional(readOnly=true) | ||||
public List<E> findByUuids(Object[] uuids) { | public List<E> findByUuids(Object[] uuids) { | ||||
return empty(uuids) ? new ArrayList<E>() : findByFieldIn("uuid", uuids); | |||||
return empty(uuids) ? new ArrayList<E>() : findByFieldIn(Identifiable.UUID, uuids); | |||||
} | } | ||||
@Transactional(readOnly=true) | @Transactional(readOnly=true) | ||||
public E findFirstByUuids(Collection<String> uuids) { return findFirstByFieldIn("uuid", uuids); } | |||||
public E findFirstByUuids(Collection<String> uuids) { return findFirstByFieldIn(Identifiable.UUID, uuids); } | |||||
@Transactional(readOnly=true) | @Transactional(readOnly=true) | ||||
@Override public boolean exists(String uuid) { return findByUuid(uuid) != null; } | @Override public boolean exists(String uuid) { return findByUuid(uuid) != null; } | ||||
@@ -337,7 +338,7 @@ public abstract class AbstractCRUDDAO<E extends Identifiable> | |||||
DetachedCriteria criteria = criteria().add(and( | DetachedCriteria criteria = criteria().add(and( | ||||
ilike(likeField, likeValue) | ilike(likeField, likeValue) | ||||
)); | )); | ||||
if (mtime != null) criteria = criteria.add(gt("mtime", mtime)); | |||||
if (mtime != null) criteria = criteria.add(gt(MTIME, mtime)); | |||||
return list(criteria, 0, getFinderMaxResults()); | return list(criteria, 0, getFinderMaxResults()); | ||||
} | } | ||||
@@ -11,6 +11,7 @@ import java.util.List; | |||||
import java.util.Map; | import java.util.Map; | ||||
import static com.google.common.base.Preconditions.checkNotNull; | import static com.google.common.base.Preconditions.checkNotNull; | ||||
import static org.cobbzilla.wizard.model.Identifiable.UUID; | |||||
public abstract class AbstractChildCRUDDAO<C extends ChildEntity, P> extends AbstractDAO<C> { | public abstract class AbstractChildCRUDDAO<C extends ChildEntity, P> extends AbstractDAO<C> { | ||||
@@ -23,7 +24,7 @@ public abstract class AbstractChildCRUDDAO<C extends ChildEntity, P> extends Abs | |||||
} | } | ||||
@Override public C findByUuid(String uuid) { | @Override public C findByUuid(String uuid) { | ||||
return uniqueResult(Restrictions.eq("uuid", uuid)); | |||||
return uniqueResult(Restrictions.eq(UUID, uuid)); | |||||
} | } | ||||
@Override public C findByUniqueField(String field, Object value) { | @Override public C findByUniqueField(String field, Object value) { | ||||
@@ -48,7 +49,7 @@ public abstract class AbstractChildCRUDDAO<C extends ChildEntity, P> extends Abs | |||||
} | } | ||||
private P findParentByUuid(String parentId) { | private P findParentByUuid(String parentId) { | ||||
return (P) uniqueResult(criteria(parentEntityClass).add(Restrictions.eq("uuid", parentId))); | |||||
return (P) uniqueResult(criteria(parentEntityClass).add(Restrictions.eq(UUID, parentId))); | |||||
} | } | ||||
public C create(String parentUuid, @Valid C child) { | public C create(String parentUuid, @Valid C child) { | ||||
@@ -26,6 +26,8 @@ import static org.cobbzilla.util.daemon.ZillaRuntime.hashOf; | |||||
import static org.cobbzilla.util.reflect.ReflectionUtil.fieldsWithAnnotation; | import static org.cobbzilla.util.reflect.ReflectionUtil.fieldsWithAnnotation; | ||||
import static org.cobbzilla.util.string.StringUtil.camelCaseToSnakeCase; | import static org.cobbzilla.util.string.StringUtil.camelCaseToSnakeCase; | ||||
import static org.cobbzilla.util.string.StringUtil.sqlFilter; | import static org.cobbzilla.util.string.StringUtil.sqlFilter; | ||||
import static org.cobbzilla.wizard.model.Identifiable.CTIME; | |||||
import static org.cobbzilla.wizard.model.Identifiable.UUID; | |||||
public interface SqlViewSearchableDAO<T extends Identifiable> extends DAO<T> { | public interface SqlViewSearchableDAO<T extends Identifiable> extends DAO<T> { | ||||
@@ -76,7 +78,7 @@ public interface SqlViewSearchableDAO<T extends Identifiable> extends DAO<T> { | |||||
return die("buildBound: no bound defined for: "+bound); | return die("buildBound: no bound defined for: "+bound); | ||||
} | } | ||||
default String getDefaultSort() { return "ctime"; } | |||||
default String getDefaultSort() { return CTIME; } | |||||
String getSelectClause(SearchQuery searchQuery); | String getSelectClause(SearchQuery searchQuery); | ||||
@@ -104,7 +106,7 @@ public interface SqlViewSearchableDAO<T extends Identifiable> extends DAO<T> { | |||||
@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { | @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { | ||||
switch (method.getName()) { | switch (method.getName()) { | ||||
case "getRelated": | case "getRelated": | ||||
final Object uuid = ReflectionUtil.get(proxy, "uuid"); | |||||
final Object uuid = ReflectionUtil.get(proxy, UUID); | |||||
if (uuid == null) return die("getRelated: no uuid found: "+proxy); | if (uuid == null) return die("getRelated: no uuid found: "+proxy); | ||||
return this.getRelatedByUuid().get().computeIfAbsent(uuid.toString(), k -> new RelatedEntities()); | return this.getRelatedByUuid().get().computeIfAbsent(uuid.toString(), k -> new RelatedEntities()); | ||||
} | } | ||||
@@ -36,12 +36,13 @@ import java.util.*; | |||||
import java.util.concurrent.*; | import java.util.concurrent.*; | ||||
import java.util.concurrent.atomic.AtomicLong; | import java.util.concurrent.atomic.AtomicLong; | ||||
import static org.cobbzilla.util.daemon.Await.awaitAndCollect; | |||||
import static org.cobbzilla.util.daemon.Await.awaitFirst; | |||||
import static org.cobbzilla.util.daemon.ZillaRuntime.*; | import static org.cobbzilla.util.daemon.ZillaRuntime.*; | ||||
import static org.cobbzilla.util.reflect.ReflectionUtil.*; | import static org.cobbzilla.util.reflect.ReflectionUtil.*; | ||||
import static org.cobbzilla.util.security.ShaUtil.sha256_hex; | import static org.cobbzilla.util.security.ShaUtil.sha256_hex; | ||||
import static org.cobbzilla.wizard.model.Identifiable.UUID; | |||||
import static org.cobbzilla.wizard.resources.ResourceUtil.timeoutEx; | import static org.cobbzilla.wizard.resources.ResourceUtil.timeoutEx; | ||||
import static org.cobbzilla.util.daemon.Await.awaitAndCollect; | |||||
import static org.cobbzilla.util.daemon.Await.awaitFirst; | |||||
import static org.cobbzilla.wizard.util.SpringUtil.autowire; | import static org.cobbzilla.wizard.util.SpringUtil.autowire; | ||||
@Transactional @Slf4j | @Transactional @Slf4j | ||||
@@ -299,10 +300,10 @@ public abstract class AbstractShardedDAO<E extends Shardable, D extends SingleSh | |||||
} | } | ||||
@Transactional(readOnly=true) | @Transactional(readOnly=true) | ||||
@Override public E findByUuid(final String uuid) { return findByUniqueField("uuid", uuid); } | |||||
@Override public E findByUuid(final String uuid) { return findByUniqueField(UUID, uuid); } | |||||
@Transactional(readOnly=true) | @Transactional(readOnly=true) | ||||
public E findByUuid(final String uuid, boolean useCache) { return findByUniqueField("uuid", uuid, useCache); } | |||||
public E findByUuid(final String uuid, boolean useCache) { return findByUniqueField(UUID, uuid, useCache); } | |||||
@Transactional(readOnly=true) | @Transactional(readOnly=true) | ||||
@Override public E findByUniqueField(String field, Object value) { return findByUniqueField(field, value, true); } | @Override public E findByUniqueField(String field, Object value) { return findByUniqueField(field, value, true); } | ||||
@@ -523,7 +524,7 @@ public abstract class AbstractShardedDAO<E extends Shardable, D extends SingleSh | |||||
} | } | ||||
@Override public void delete(String uuid) { | @Override public void delete(String uuid) { | ||||
final List<D> daos = hashOn.equals("uuid") ? getAllDAOs(uuid) : getAllDAOs(); | |||||
final List<D> daos = hashOn.equals(UUID) ? getAllDAOs(uuid) : getAllDAOs(); | |||||
for (D dao : daos) dao.delete(uuid); | for (D dao : daos) dao.delete(uuid); | ||||
flushShardCache(uuid); | flushShardCache(uuid); | ||||
} | } | ||||
@@ -21,6 +21,7 @@ import java.util.Set; | |||||
import static org.cobbzilla.util.daemon.ZillaRuntime.die; | import static org.cobbzilla.util.daemon.ZillaRuntime.die; | ||||
import static org.cobbzilla.util.daemon.ZillaRuntime.empty; | import static org.cobbzilla.util.daemon.ZillaRuntime.empty; | ||||
import static org.cobbzilla.util.jdbc.ResultSetBean.row2map; | import static org.cobbzilla.util.jdbc.ResultSetBean.row2map; | ||||
import static org.cobbzilla.wizard.model.Identifiable.UUID; | |||||
import static org.cobbzilla.wizard.model.ModelCryptUtil.getCryptor; | import static org.cobbzilla.wizard.model.ModelCryptUtil.getCryptor; | ||||
@Accessors(chain=true) @Slf4j | @Accessors(chain=true) @Slf4j | ||||
@@ -91,7 +92,7 @@ public class AnonScrubber { | |||||
die("anonymize: error handling table.column: " + errColumn, e); | die("anonymize: error handling table.column: " + errColumn, e); | ||||
} | } | ||||
} | } | ||||
update.setString(columns.length + 1, row.get("uuid").toString()); | |||||
update.setString(columns.length + 1, row.get(UUID).toString()); | |||||
if (update.executeUpdate() != 1) { | if (update.executeUpdate() != 1) { | ||||
die("anonymize: error updating"); | die("anonymize: error updating"); | ||||
} | } | ||||
@@ -12,12 +12,13 @@ import java.util.List; | |||||
import java.util.Set; | import java.util.Set; | ||||
import static org.cobbzilla.util.daemon.ZillaRuntime.empty; | import static org.cobbzilla.util.daemon.ZillaRuntime.empty; | ||||
import static org.cobbzilla.wizard.model.Identifiable.UUID; | |||||
@Accessors(chain=true) @ToString(of="table") | @Accessors(chain=true) @ToString(of="table") | ||||
public class AnonTable { | public class AnonTable { | ||||
@Getter @Setter private String table; | @Getter @Setter private String table; | ||||
@Getter @Setter private String id = "uuid"; | |||||
@Getter @Setter private String id = UUID; | |||||
@Getter @Setter private AnonColumn[] columns; | @Getter @Setter private AnonColumn[] columns; | ||||
@Getter @Setter private boolean truncate = false; | @Getter @Setter private boolean truncate = false; | ||||