From 68930d845c27578c60fbf6d083a5a9e36fd5078e Mon Sep 17 00:00:00 2001 From: bartolomiew Date: Sun, 28 Oct 2012 08:41:27 +0100 Subject: Allows to gain full control of transactions --- src/com/iciql/Db.java | 38 ++++++++++ src/com/iciql/TableDefinition.java | 6 +- tests/com/iciql/test/ForeignKeyTest.java | 3 + tests/com/iciql/test/IciqlSuite.java | 4 +- tests/com/iciql/test/TransactionTest.java | 119 ++++++++++++++++++++++++++++++ 5 files changed, 167 insertions(+), 3 deletions(-) create mode 100644 tests/com/iciql/test/TransactionTest.java diff --git a/src/com/iciql/Db.java b/src/com/iciql/Db.java index caec637..32b7c6a 100644 --- a/src/com/iciql/Db.java +++ b/src/com/iciql/Db.java @@ -1,6 +1,7 @@ /* * Copyright 2004-2011 H2 Group. * Copyright 2011 James Moger. + * Copyright 2012 Frederic Gaillard. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -68,6 +69,9 @@ public class Db { private DbUpgrader dbUpgrader = new DefaultDbUpgrader(); private final Set> upgradeChecked = Collections.synchronizedSet(new HashSet>()); + private boolean skipCreate; + private boolean autoSavePoint = true; + static { TOKENS = Collections.synchronizedMap(new WeakIdentityHashMap()); DIALECTS = Collections.synchronizedMap(new HashMap>()); @@ -563,6 +567,11 @@ public class Db { } Savepoint prepareSavepoint() { + // don't change auto-commit mode. + // don't create save point. + if (!autoSavePoint) { + return null; + } // create a savepoint Savepoint savepoint = null; try { @@ -731,4 +740,33 @@ public class Db { JdbcUtils.closeSilently(stat); } } + + /** + * Allow to enable/disable globally createIfRequired in TableDefinition. + * For advanced user wanting to gain full control of transactions. + * Default value is false. + * @param skipCreate + */ + public void setSkipCreate(boolean skipCreate) { + this.skipCreate = skipCreate; + } + + public boolean getSkipCreate() { + return this.skipCreate; + } + + /** + * Allow to enable/disable usage of save point. + * For advanced user wanting to gain full control of transactions. + * Default value is false. + * @param autoSavePoint + */ + public void setAutoSavePoint(boolean autoSavePoint) { + this.autoSavePoint = autoSavePoint; + } + + public boolean getAutoSavePoint() { + return this.autoSavePoint; + } + } diff --git a/src/com/iciql/TableDefinition.java b/src/com/iciql/TableDefinition.java index 1ecf394..e96b61c 100644 --- a/src/com/iciql/TableDefinition.java +++ b/src/com/iciql/TableDefinition.java @@ -1,7 +1,7 @@ /* * Copyright 2004-2011 H2 Group. * Copyright 2011 James Moger. - * Copyright 2012 Frédéric Gaillard. + * Copyright 2012 Frederic Gaillard. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -839,6 +839,10 @@ public class TableDefinition { } TableDefinition createIfRequired(Db db) { + // globally enable/disable check of create if required + if (db.getSkipCreate()) { + return this; + } if (!createIfRequired) { // skip table and index creation // but still check for upgrades diff --git a/tests/com/iciql/test/ForeignKeyTest.java b/tests/com/iciql/test/ForeignKeyTest.java index d789408..ed85cbc 100644 --- a/tests/com/iciql/test/ForeignKeyTest.java +++ b/tests/com/iciql/test/ForeignKeyTest.java @@ -28,6 +28,9 @@ import com.iciql.IciqlException; import com.iciql.test.models.CategoryAnnotationOnly; import com.iciql.test.models.ProductAnnotationOnlyWithForeignKey; +/** + * Tests of Foreign Keys. + */ public class ForeignKeyTest { /** diff --git a/tests/com/iciql/test/IciqlSuite.java b/tests/com/iciql/test/IciqlSuite.java index 9181db7..1202d0e 100644 --- a/tests/com/iciql/test/IciqlSuite.java +++ b/tests/com/iciql/test/IciqlSuite.java @@ -1,6 +1,6 @@ /* * Copyright 2011 James Moger. - * Copyright 2012 Frédéric Gaillard. + * Copyright 2012 Frederic Gaillard. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -93,7 +93,7 @@ import com.iciql.util.Utils; @SuiteClasses({ AliasMapTest.class, AnnotationsTest.class, BooleanModelTest.class, ClobTest.class, ConcurrencyTest.class, EnumsTest.class, ModelsTest.class, PrimitivesTest.class, RuntimeQueryTest.class, SamplesTest.class, UpdateTest.class, UpgradesTest.class, JoinTest.class, - UUIDTest.class, ViewsTest.class, ForeignKeyTest.class }) + UUIDTest.class, ViewsTest.class, ForeignKeyTest.class, TransactionTest.class }) public class IciqlSuite { private static final TestDb[] TEST_DBS = { diff --git a/tests/com/iciql/test/TransactionTest.java b/tests/com/iciql/test/TransactionTest.java new file mode 100644 index 0000000..d1c6749 --- /dev/null +++ b/tests/com/iciql/test/TransactionTest.java @@ -0,0 +1,119 @@ +/* + * Copyright 2012 Frederic Gaillard. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.iciql.test; + +import static org.junit.Assert.assertEquals; + +import java.sql.SQLException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.iciql.Db; +import com.iciql.IciqlException; +import com.iciql.test.models.CategoryAnnotationOnly; +import com.iciql.test.models.ProductAnnotationOnlyWithForeignKey; + +/** + * Tests of transactions. + */ +public class TransactionTest { + + /** + * This object represents a database (actually a connection to the + * database). + */ + + private Db db; + + @Before + public void setUp() { + db = IciqlSuite.openNewDb(); + + // tables creation + db.from(new CategoryAnnotationOnly()); + db.from(new ProductAnnotationOnlyWithForeignKey()); + + startTransactionMode(); + } + + @After + public void tearDown() { + + endTransactionMode(); + + db.dropTable(ProductAnnotationOnlyWithForeignKey.class); + db.dropTable(CategoryAnnotationOnly.class); + db.close(); + } + + @Test + public void testTransaction() { + + // insert in 2 tables inside a transaction + + // insertAll don't use save point in this transaction + db.insertAll(CategoryAnnotationOnly.getList()); + db.insertAll(ProductAnnotationOnlyWithForeignKey.getList()); + + // don't commit changes + try { + db.getConnection().rollback(); + } catch (SQLException e) { + throw new IciqlException(e, "Can't rollback"); + } + + ProductAnnotationOnlyWithForeignKey p = new ProductAnnotationOnlyWithForeignKey(); + long count1 = db.from(p).selectCount(); + + CategoryAnnotationOnly c = new CategoryAnnotationOnly(); + long count2 = db.from(c).selectCount(); + + // verify changes aren't committed + assertEquals(count1, 0L); + assertEquals(count2, 0L); + } + + /** + * Helper to set transaction mode + */ + private void startTransactionMode() { + db.setSkipCreate(true); + db.setAutoSavePoint(false); + + try { + db.getConnection().setAutoCommit(false); + } catch (SQLException e) { + throw new IciqlException(e, "Could not change auto-commit mode"); + } + } + + /** + * Helper to return to initial mode + */ + private void endTransactionMode() { + try { + db.getConnection().setAutoCommit(true); + } catch (SQLException e) { + throw new IciqlException(e, "Could not change auto-commit mode"); + } + // returns to initial states + db.setSkipCreate(false); + db.setAutoSavePoint(true); + } + +} -- cgit v1.2.3