Added reset and nested transaction tests. Changed beginOverwrite to beginReset. Added documentation to LuceneSession.

This commit is contained in:
Lassi Immonen 2010-12-30 10:14:09 +00:00
parent 06e155e5bb
commit 10e416f1a6
7 changed files with 158 additions and 30 deletions

View File

@ -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();
}

View File

@ -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) {

View File

@ -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<LuceneSearcher> searcher = new AtomicReference<LuceneSearcher>();
@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)) {

View File

@ -47,7 +47,7 @@ public class LuceneSessionImpl implements LuceneSession {
}
@Override
public LuceneWriter beginOverwrite() {
public LuceneWriter beginReset() {
checkClosed();
return createWriter(true);
}

View File

@ -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) {

View File

@ -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 {

View File

@ -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());
}
}
}