From 10e416f1a6b986559be3d39896d8d64cf41c6c44 Mon Sep 17 00:00:00 2001 From: Lassi Immonen Date: Thu, 30 Dec 2010 10:14:09 +0000 Subject: [PATCH] Added reset and nested transaction tests. Changed beginOverwrite to beginReset. Added documentation to LuceneSession. --- .../query/lucene/session/LuceneSession.java | 44 +++++++- .../lucene/session/impl/LuceneSearcher.java | 4 + .../impl/LuceneSessionFactoryImpl.java | 5 +- .../session/impl/LuceneSessionImpl.java | 2 +- .../lucene/session/impl/LuceneWriterImpl.java | 3 + .../session/LuceneSessionFactoryTest.java | 25 ++++- .../impl/LuceneTransactionalHandlerTest.java | 105 ++++++++++++++---- 7 files changed, 158 insertions(+), 30 deletions(-) diff --git a/querydsl-lucene/src/main/java/com/mysema/query/lucene/session/LuceneSession.java b/querydsl-lucene/src/main/java/com/mysema/query/lucene/session/LuceneSession.java index fa8c61f04..e601b3ca8 100644 --- a/querydsl-lucene/src/main/java/com/mysema/query/lucene/session/LuceneSession.java +++ b/querydsl-lucene/src/main/java/com/mysema/query/lucene/session/LuceneSession.java @@ -4,14 +4,50 @@ import com.mysema.query.lucene.LuceneQuery; public interface LuceneSession { + /** + * Creates a new query. + * + * @return LuceneQuery instance + * @throws SessionClosedException if session is closed + */ LuceneQuery createQuery(); - + + /** + * Adds documents to index. Creates a new index if the index is not + * available. + * + * @return LuceneWriter instance + * @throws SessionReadOnlyException if session is opened in read-only mode + * @throws SessionClosedException if session is closed + */ LuceneWriter beginAppend(); - - LuceneWriter beginOverwrite(); - + + /** + * Resets the whole index and starts new writer. Old readers will still see + * the index as it was when they were opened but new readers will see only + * the data this writer has committed. + * + * @return LuceneWriter instance + * @throws SessionReadOnlyException if session is opened in read-only mode + * @throws SessionClosedException if session is closed + */ + LuceneWriter beginReset(); + + /** + * Flushes all data writer has changed. Queries created after this will see + * the new index. Queries created before, will see the old snapshot. + * + * @throws SessionClosedException if session is closed + */ void flush(); + /** + * Closes the session. All writes are committed and resources are cleared. + * This should always be called in finally block if this session was created + * explicitly by calling session factory's openSession + * + * @throws SessionClosedException if session is closed + */ void close(); } diff --git a/querydsl-lucene/src/main/java/com/mysema/query/lucene/session/impl/LuceneSearcher.java b/querydsl-lucene/src/main/java/com/mysema/query/lucene/session/impl/LuceneSearcher.java index 79eb34430..af5f3371c 100644 --- a/querydsl-lucene/src/main/java/com/mysema/query/lucene/session/impl/LuceneSearcher.java +++ b/querydsl-lucene/src/main/java/com/mysema/query/lucene/session/impl/LuceneSearcher.java @@ -2,6 +2,8 @@ package com.mysema.query.lucene.session.impl; import java.io.IOException; +import javax.annotation.Nullable; + import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.store.Directory; @@ -16,6 +18,8 @@ import com.mysema.query.QueryException; public class LuceneSearcher { private final IndexSearcher searcher; + + @Nullable private final ReleaseListener releaseListener; public LuceneSearcher(Directory directory, ReleaseListener releaseListener) { diff --git a/querydsl-lucene/src/main/java/com/mysema/query/lucene/session/impl/LuceneSessionFactoryImpl.java b/querydsl-lucene/src/main/java/com/mysema/query/lucene/session/impl/LuceneSessionFactoryImpl.java index 7ffea25bc..0818fd9c7 100644 --- a/querydsl-lucene/src/main/java/com/mysema/query/lucene/session/impl/LuceneSessionFactoryImpl.java +++ b/querydsl-lucene/src/main/java/com/mysema/query/lucene/session/impl/LuceneSessionFactoryImpl.java @@ -4,6 +4,8 @@ import java.io.File; import java.io.IOException; import java.util.concurrent.atomic.AtomicReference; +import javax.annotation.Nullable; + import org.apache.lucene.store.Directory; import org.apache.lucene.store.SimpleFSDirectory; import org.slf4j.Logger; @@ -22,6 +24,7 @@ public class LuceneSessionFactoryImpl implements LuceneSessionFactory { private final AtomicReference searcher = new AtomicReference(); + @Nullable private final ReleaseListener releaseListener; public LuceneSessionFactoryImpl(String indexPath) throws IOException { @@ -52,7 +55,7 @@ public class LuceneSessionFactoryImpl implements LuceneSessionFactory { @Override public LuceneSession getCurrentSession() { if (!LuceneSessionHolder.isTransactionalScope()) { - throw new SessionNotBoundException("There is transactional scope"); + throw new SessionNotBoundException("There is no transactional scope"); } if (!LuceneSessionHolder.hasCurrentSession(this)) { diff --git a/querydsl-lucene/src/main/java/com/mysema/query/lucene/session/impl/LuceneSessionImpl.java b/querydsl-lucene/src/main/java/com/mysema/query/lucene/session/impl/LuceneSessionImpl.java index b8362b50e..d98b34b74 100644 --- a/querydsl-lucene/src/main/java/com/mysema/query/lucene/session/impl/LuceneSessionImpl.java +++ b/querydsl-lucene/src/main/java/com/mysema/query/lucene/session/impl/LuceneSessionImpl.java @@ -47,7 +47,7 @@ public class LuceneSessionImpl implements LuceneSession { } @Override - public LuceneWriter beginOverwrite() { + public LuceneWriter beginReset() { checkClosed(); return createWriter(true); } diff --git a/querydsl-lucene/src/main/java/com/mysema/query/lucene/session/impl/LuceneWriterImpl.java b/querydsl-lucene/src/main/java/com/mysema/query/lucene/session/impl/LuceneWriterImpl.java index e559fa85b..99d0a301b 100644 --- a/querydsl-lucene/src/main/java/com/mysema/query/lucene/session/impl/LuceneWriterImpl.java +++ b/querydsl-lucene/src/main/java/com/mysema/query/lucene/session/impl/LuceneWriterImpl.java @@ -3,6 +3,8 @@ package com.mysema.query.lucene.session.impl; import java.io.FileNotFoundException; import java.io.IOException; +import javax.annotation.Nullable; + import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.index.IndexWriter; @@ -22,6 +24,7 @@ public class LuceneWriterImpl implements LuceneWriter { private IndexWriter writer; + @Nullable private final ReleaseListener releaseListener; public LuceneWriterImpl(Directory directory, boolean createNew, ReleaseListener releaseListener) { diff --git a/querydsl-lucene/src/test/java/com/mysema/query/lucene/session/LuceneSessionFactoryTest.java b/querydsl-lucene/src/test/java/com/mysema/query/lucene/session/LuceneSessionFactoryTest.java index 1a279c2e9..4e8dc2c25 100644 --- a/querydsl-lucene/src/test/java/com/mysema/query/lucene/session/LuceneSessionFactoryTest.java +++ b/querydsl-lucene/src/test/java/com/mysema/query/lucene/session/LuceneSessionFactoryTest.java @@ -106,7 +106,7 @@ public class LuceneSessionFactoryTest { @Test(expected = SessionReadOnlyException.class) public void Readonly() { LuceneSession session = sessionFactory.openSession(true); - session.beginOverwrite(); + session.beginReset(); } @Test(expected = SessionClosedException.class) @@ -141,7 +141,7 @@ public class LuceneSessionFactoryTest { public void SessionClosedOverwrite() { LuceneSession session = sessionFactory.openSession(false); session.close(); - session.beginOverwrite(); + session.beginReset(); } private class ReleaseCounter implements ReleaseListener { @@ -178,6 +178,27 @@ public class LuceneSessionFactoryTest { closes.put(writer, closes.get(writer) + 1); } } + + @Test + public void Reset() { + addData(sessionFactory); + + LuceneSession session = sessionFactory.openSession(true); + assertEquals(4, session.createQuery().count()); + session.close(); + + session = sessionFactory.openSession(false); + + assertEquals(4, session.createQuery().count()); + session.beginReset().addDocument(getDocument()); + session.flush(); + assertEquals(1, session.createQuery().count()); + session.close(); + + session = sessionFactory.openSession(true); + assertEquals(1, session.createQuery().count()); + session.close(); + } @Test public void ResourcesAreReleased() throws IOException { diff --git a/querydsl-lucene/src/test/java/com/mysema/query/lucene/session/impl/LuceneTransactionalHandlerTest.java b/querydsl-lucene/src/test/java/com/mysema/query/lucene/session/impl/LuceneTransactionalHandlerTest.java index ac67526a3..233c3ebeb 100644 --- a/querydsl-lucene/src/test/java/com/mysema/query/lucene/session/impl/LuceneTransactionalHandlerTest.java +++ b/querydsl-lucene/src/test/java/com/mysema/query/lucene/session/impl/LuceneTransactionalHandlerTest.java @@ -22,48 +22,46 @@ public class LuceneTransactionalHandlerTest { private LuceneTransactionHandler handler = new LuceneTransactionHandler(); - private TxTest txTest; + private TestDao testDao; private QDocument doc = new QDocument("test"); - - //private StringPath title = doc.title; @Before public void before() { sessionFactory = new LuceneSessionFactoryImpl(new RAMDirectory()); - AspectJProxyFactory factory = new AspectJProxyFactory(new TxTestImpl(sessionFactory)); + AspectJProxyFactory factory = new AspectJProxyFactory(new TestDaoImpl(sessionFactory)); factory.addAspect(handler); - txTest = factory.getProxy(); + testDao = factory.getProxy(); } @Test public void Empty() { - txTest.empty(); - assertEquals(1, txTest.count()); + testDao.empty(); + assertEquals(1, testDao.count()); } @Test(expected = SessionNotBoundException.class) public void NoAnnotation() { - txTest.noAnnotation(); + testDao.noAnnotation(); } @Test public void Annotation() { - txTest.annotation(); - assertEquals(1, txTest.count()); + testDao.annotation(); + assertEquals(1, testDao.count()); } @Test(expected = SessionReadOnlyException.class) public void ReadOnly() { - txTest.readOnly(); + testDao.readOnly(); } @Test public void Writing() { - txTest.writing(); + testDao.writing(); LuceneQuery q = sessionFactory.openSession(true).createQuery(); assertEquals(4, q.where(doc.title.like("*")).count()); @@ -76,11 +74,11 @@ public class LuceneTransactionalHandlerTest { LuceneSessionFactory sf2 = new LuceneSessionFactoryImpl(new RAMDirectory()); LuceneSessionFactory sf3 = new LuceneSessionFactoryImpl(new RAMDirectory()); - AspectJProxyFactory factory = new AspectJProxyFactory(new TxTestImpl(sf1,sf2,sf3)); + AspectJProxyFactory factory = new AspectJProxyFactory(new TestDaoImpl(sf1,sf2,sf3)); factory.addAspect(handler); - txTest = factory.getProxy(); + testDao = factory.getProxy(); - txTest.multiFactories(); + testDao.multiFactories(); LuceneQuery q = sf1.openSession(true).createQuery(); assertEquals(1, q.where(doc.title.eq("sf1")).count()); @@ -92,9 +90,24 @@ public class LuceneTransactionalHandlerTest { assertEquals(1, q.where(doc.title.eq("sf3")).count()); } + @Test + public void NestedSession() { + AspectJProxyFactory factory = new AspectJProxyFactory(new NestedDaoImpl(sessionFactory)); + factory.addAspect(handler); + NestedDao nestedDao = factory.getProxy(); + + testDao.setNested(nestedDao); + + testDao.nested(); + + LuceneSession session = sessionFactory.openSession(true); + assertEquals(1, session.createQuery().where(doc.title.eq("nested")).count()); + session.close(); + + } - private static interface TxTest { + private static interface TestDao { void empty(); int count(); @@ -108,15 +121,21 @@ public class LuceneTransactionalHandlerTest { void writing(); void multiFactories(); + + void nested(); + + void setNested(NestedDao nested); } - - private static class TxTestImpl implements TxTest { + + private static class TestDaoImpl implements TestDao { private int count = 0; private LuceneSessionFactory[] factories; - TxTestImpl(LuceneSessionFactory ... factories) { + private NestedDao nested; + + TestDaoImpl(LuceneSessionFactory ... factories) { this.factories = factories; } @@ -164,9 +183,51 @@ public class LuceneTransactionalHandlerTest { LuceneSession s2 = factories[1].getCurrentSession(); LuceneSession s3 = factories[2].getCurrentSession(); - s1.beginOverwrite().addDocument(createDocument("sf1","","",0,0)); - s2.beginOverwrite().addDocument(createDocument("sf2","","",0,0)); - s3.beginOverwrite().addDocument(createDocument("sf3","","",0,0)); + s1.beginReset().addDocument(createDocument("sf1","","",0,0)); + s2.beginReset().addDocument(createDocument("sf2","","",0,0)); + s3.beginReset().addDocument(createDocument("sf3","","",0,0)); + } + + @Override + public void setNested(NestedDao nested) { + this.nested = nested; + } + + @Override + @LuceneTransactional + public void nested() { + LuceneSession session = factories[0].getCurrentSession(); + session.beginReset().addDocument(createDocument("nested","","",0,0)); + nested.nested(); + } + } + + private static interface NestedDao { + void nested(); + } + + private class NestedDaoImpl implements NestedDao { + + private LuceneSessionFactory sessionFactory; + + public NestedDaoImpl(LuceneSessionFactory sessionFactory) { + this.sessionFactory = sessionFactory; + } + + @Override + @LuceneTransactional + public void nested() { + LuceneSession session = sessionFactory.getCurrentSession(); + LuceneQuery query = session.createQuery(); + + assertEquals(0, query.where(doc.title.eq("nested")).count()); + + // This verifies that the we are using the same session opened in + // the caller scope + session.flush(); + + query = session.createQuery(); + assertEquals(1, query.where(doc.title.eq("nested")).count()); } } }