@@ -0,0 +1,1665 @@
+package foam.dao;%0A%0Aimport java.util.Comparator;%0A%0Aimport foam.core.Expression;%0Aimport foam.core.FObject;%0Aimport foam.core.X;%0A%0A/**%0A * Basic eager caching DAO: selects all from the delegate for storing in the cache.%0A *%0A * Updates are written through to the delegate, and the cache is updated if they succeed.%0A */%0Apublic class CachingDAO extends AbstractDAO %7B%0A  protected DAO delegate;%0A  protected DAO cache;%0A  private boolean populated = false;%0A%0A  /**%0A   * Defaults to caching in a newly created MDAO.%0A   * @param delegate The underlying %7B@link DAO%7D we're caching.%0A   */%0A  public CachingDAO(DAO delegate) %7B%0A    this(delegate, new MDAO(delegate.getModel()));%0A  %7D%0A%0A  public CachingDAO(DAO delegate, DAO cache) %7B%0A    super(delegate.getModel());%0A    this.delegate = delegate;%0A    this.cache = cache;%0A  %7D%0A%0A  private void setup(X x) throws DAOException, DAOInternalException %7B%0A    populated = true;%0A    delegate.select(x, cache);%0A    delegate.listen(cache);%0A  %7D%0A%0A  @Override%0A  public Sink select_(X x, Sink sink, Expression%3CBoolean%3E p, Comparator c, long skip, long limit) throws DAOException, DAOInternalException %7B%0A    if (!populated) setup(x);%0A    return cache.select_(x, sink, p, c, skip, limit);%0A  %7D%0A%0A  @Override%0A  public void removeAll_(X x, Expression%3CBoolean%3E p) throws DAOException, DAOInternalException %7B%0A    delegate.removeAll_(x, p);%0A  %7D%0A%0A  @Override%0A  public void remove(X x, FObject obj) throws DAOException, DAOInternalException %7B%0A    if (!populated) setup(x);%0A    delegate.remove(x, obj);%0A  %7D%0A%0A  @Override%0A  public FObject put(X x, FObject obj) throws DAOException, DAOInternalException %7B%0A    if (!populated) setup(x);%0A    return delegate.put(x, obj);%0A  %7D%0A%7D%0A

Add the "eager" CachingDAO (full select on load)