/
area/
classes/net/sourceforge/pain/logic/
classes/net/sourceforge/pain/logic/event/
classes/net/sourceforge/pain/logic/fn/util/
classes/net/sourceforge/pain/network/console/
classes/net/sourceforge/pain/plugin/
classes/net/sourceforge/pain/plugin/reset/
classes/net/sourceforge/pain/plugin/shutdown/
classes/net/sourceforge/pain/plugin/social/
classest/net/sourceforge/pain/db/data/
doc/
doc/paindb/resources/
src/net/sourceforge/pain/logic/
src/net/sourceforge/pain/logic/event/
src/net/sourceforge/pain/logic/fn/util/
src/net/sourceforge/pain/network/console/
src/net/sourceforge/pain/network/console/telnet/
src/net/sourceforge/pain/plugin/
src/net/sourceforge/pain/plugin/command/
src/net/sourceforge/pain/plugin/reset/
src/net/sourceforge/pain/plugin/shutdown/
src/net/sourceforge/pain/plugin/social/
src/net/sourceforge/pain/util/
tests/
tests/net/sourceforge/pain/db/data/
package net.sourceforge.pain.db;

import junit.framework.*;
import net.sourceforge.pain.db.data.*;

import java.io.*;

/**
 * User: fmike  Date: Aug 26, 2003   Time: 3:30:29 AM
 */
public final class TransactionTest extends TestCase {


	private PainDB db;

	public TransactionTest() {
		super("TransactionTest");
	}

	protected void setUp() throws Exception {
		db = new PainDB(getName() + ".db");
		db.ALLOW_PLAIN_WRITE = true; // allow work without transactions
		db.MANUAL_FLUSH_MODE = true; // commit will not flush (objects stays dirty)

	}

	protected void tearDown() throws Exception {
		if (db != null) {
			File file = new File(db.getDbFileName());
			if (!db.isClosed()) {
				db.forceClose();
			}
			db = null;
			file.delete();
		}
	}

	public void testState1() throws Exception {
		AllFieldTypesObject obj = new AllFieldTypesObject(db);
		assertTrue(obj.isDirty()); // in plain write mode there is no NEW state
		assertEquals(false, obj.getBOOLEAN());

		db.beginTransaction();
		assertTrue(obj.isDirty());
		obj.setBOOLEAN(true);
		assertTrue(obj.isDirty());
		db.rollbackTransaction();
		assertTrue(obj.isDirty());
		assertEquals(false, obj.getBOOLEAN());

		db.flush();

		assertTrue(obj.isClean());

		db.beginTransaction();
		obj.setBOOLEAN(true);
		assertTrue(obj.isDirty());
		db.commitTransaction();
		assertTrue(obj.isDirty());
		assertEquals(true, obj.getBOOLEAN());

		db.flush();
		assertTrue(obj.isClean());

		db.beginTransaction();
		obj.delete();
		assertTrue(obj.isDeleted());
		db.rollbackTransaction();
		assertTrue(obj.isClean());

		Object oid = obj.getOid();
		db.beginTransaction();
		obj.delete();
		assertTrue(obj.isDeleted());
		assertNull(db.getObject(oid));
		db.commitTransaction();
		assertTrue(obj.isDetached());
		assertNull(db.getObject(oid));
		db.flush();
		assertTrue(obj.isDetached());

		String fileName = db.getDbFileName();
		db.close();
		db = new PainDB(fileName);
		obj = (AllFieldTypesObject) db.getObject(oid);
		assertNull(obj);
	}

	public void testInverse1() throws Exception {

		AllFieldTypesObject obj1 = new AllFieldTypesObject(db);
		AllFieldTypesObject obj2 = new AllFieldTypesObject(db);

		db.beginTransaction();
		obj1.setREFERENCE(obj2);
		obj2.getREFERENCE_SET().add(obj1);
		db.commitTransaction();
		assertSame(obj1.getREFERENCE(), obj2);
		assertTrue(obj2.getREFERENCE_SET().contains(obj1));

		db.beginTransaction();
		obj2.getREFERENCE_SET().remove(obj1);
		assertFalse(obj2.getREFERENCE_SET().contains(obj1));
		db.rollbackTransaction();
		assertTrue(obj2.getREFERENCE_SET().contains(obj1));

		db.beginTransaction();
		obj1.delete();
		assertFalse(obj2.getREFERENCE_SET().contains(obj1));
		db.rollbackTransaction();
		assertTrue(obj2.getREFERENCE_SET().contains(obj1));

		db.beginTransaction();
		obj2.delete();
		assertNull(obj1.getREFERENCE());
		db.rollbackTransaction();
		assertSame(obj1.getREFERENCE(), obj2);
		assertTrue(obj2.getREFERENCE_SET().contains(obj1));
	}

	public void testReference1() throws IOException {

		AllFieldTypesObject obj1 = new AllFieldTypesObject(db);
		AllFieldTypesObject obj2 = new AllFieldTypesObject(db);

		db.beginTransaction();
		obj1.setREFERENCE(obj2);
		assertSame(obj1.getREFERENCE(), obj2);
		obj2.delete();
		assertNull(obj1.getREFERENCE());
		db.rollbackTransaction();
		assertNull(obj1.getREFERENCE());

		db.beginTransaction();
		obj1.setREFERENCE(obj2);
		db.commitTransaction();
		db.flush();

		db.beginTransaction();
		assertSame(obj1.getREFERENCE(), obj2);
		obj2.delete();
		assertNull(obj1.getREFERENCE());
		db.rollbackTransaction();
		assertSame(obj1.getREFERENCE(), obj2);

		db.beginTransaction();
		obj1.delete();
		obj2.delete();
		db.rollbackTransaction();
		assertSame(obj1.getREFERENCE(), obj2);
		assertTrue(obj1.isClean()); // was flush
	}

	public void testCreate1() throws IOException {
		AllFieldTypesObject obj;
		db.beginTransaction();
		obj = new AllFieldTypesObject(db);
		assertTrue(obj.isNew());
		db.commitTransaction();
		assertTrue(obj.isDirty());
		db.flush();
		assertTrue(obj.isClean());
	}

	public void testDataIndexClean1() throws IOException {
		AllFieldTypesObject obj;
		db.beginTransaction();
		obj = new AllFieldTypesObject(db);
		obj.getREFERENCE_SET().add(obj);
		db.commitTransaction();

		db.beginTransaction();
		obj.delete();
		db.commitTransaction();

		db.beginTransaction();
		obj = new AllFieldTypesObject(db);
		assertTrue(obj.getREFERENCE_SET().isEmpty());
		db.commitTransaction();
	}


	public void testSavePoint1() throws IOException {
		db.beginTransaction();
		AllFieldTypesObject obj = new AllFieldTypesObject(db);
		assertTrue(obj.isNew());
		db.beginTransaction();
		assertTrue(obj.isNew());
		db.commitTransaction();
		assertTrue(obj.isNew());
		db.commitTransaction();
		assertTrue(obj.isDirty());
		db.flush();
		assertTrue(obj.isClean());
		obj.delete();
		assertTrue(obj.isDetached());
	}

	public void testSavePoint2() throws IOException {
		db.beginTransaction();
		AllFieldTypesObject obj = new AllFieldTypesObject(db);
		assertTrue(obj.isNew());
		obj.setINT(10);
		assertTrue(obj.isNew());
		assertEquals(10, obj.getINT());
		db.beginTransaction();
		obj.setINT(20);
		assertEquals(20, obj.getINT());
		obj.delete();
		assertTrue(obj.isDeleted());
		db.rollbackTransaction();
		assertTrue(obj.isNew());
		assertEquals(10, obj.getINT());
		db.commitTransaction();
		assertTrue(obj.isDirty());
		obj.delete();
		assertTrue(obj.isDetached());
	}

	public void testSavePoint3() throws IOException {
		db.beginTransaction();
		AllFieldTypesObject obj1 = new AllFieldTypesObject(db);
		AllFieldTypesObject obj2 = new AllFieldTypesObject(db);
		obj1.setREFERENCE(obj2);
		assertSame(obj1.getREFERENCE(), obj2);
		db.beginTransaction();
		obj1.setREFERENCE(null);
		db.rollbackTransaction();
		assertSame(obj2, obj1.getREFERENCE());
		assertTrue(obj2.isNew());
		obj2.delete();
		assertTrue(obj2.isDeleted());
		db.commitTransaction();
		assertTrue(obj2.isDetached());
		assertNull(obj1.getREFERENCE());
	}

	/** object created in internal transaction should save state after commitTN */
	public void testSavePoint4() throws IOException {
		db.beginTransaction();
		new AllFieldTypesObject(db); //class created
		db.beginTransaction();
		AllFieldTypesObject obj2 = new AllFieldTypesObject(db);
		assertTrue(obj2.isNew());
		db.commitTransaction();
		assertTrue(obj2.isNew());
		db.commitTransaction();
		assertTrue(obj2.isDirty());
	}


	public void testStringKeySetBUG1() throws IOException {
		db.beginTransaction();
		AllFieldTypesObject obj = new AllFieldTypesObject(db);
		db.commitTransaction();

		db.beginTransaction();   //1
		obj.getSTRING_SET().add("ok");
		db.beginTransaction(); //2

		db.beginTransaction(); //3
		obj.delete();
		db.beginTransaction(); // 4
		db.rollbackTransaction(); //4

		db.rollbackTransaction(); //3
		db.rollbackTransaction(); //2
		db.rollbackTransaction(); //1
	}

	public void testStringSetBackupRestoreBug1() throws IOException {
		db.beginTransaction();
		AllFieldTypesObject obj = new AllFieldTypesObject(db);
		obj.getSTRING_SET().add("item");
		assertEquals(1, obj.getSTRING_SET().size());
		db.beginTransaction();
		obj.setINT(10);
		db.rollbackTransaction();
		assertEquals(1, obj.getSTRING_SET().size());
		db.commitTransaction();
		assertEquals(1, obj.getSTRING_SET().size());

	}
}