arminw 2005/04/09 15:31:11
Modified: src/schema Tag: OJB_1_0_RELEASE ojbtest-schema.xml
src/test/org/apache/ojb/odmg Tag: OJB_1_0_RELEASE
CircularTest.java
src/test/org/apache/ojb Tag: OJB_1_0_RELEASE
repository_junit_odmg.xml
Log:
update test
Revision Changes Path
No revision
No revision
1.80.2.17 +26 -1 db-ojb/src/schema/ojbtest-schema.xml
Index: ojbtest-schema.xml
===================================================================
RCS file: /home/cvs/db-ojb/src/schema/ojbtest-schema.xml,v
retrieving revision 1.80.2.16
retrieving revision 1.80.2.17
diff -u -r1.80.2.16 -r1.80.2.17
--- ojbtest-schema.xml 3 Apr 2005 17:21:55 -0000 1.80.2.16
+++ ojbtest-schema.xml 9 Apr 2005 22:31:10 -0000 1.80.2.17
@@ -1382,6 +1382,31 @@
</foreign-key>
</table>
+ <table name="CT_OBJECT_A">
+ <column name="OBJ_ID" required="true" primaryKey="true"
type="INTEGER"/>
+ <column name="NAME" type="VARCHAR" size="250"/>
+ <column name="CONCRETE_CLASS" type="VARCHAR" size="250"/>
+ <column name="FK_ID" type="INTEGER"/>
+ <foreign-key foreignTable="CT_OBJECT_AA">
+ <reference local="FK_ID" foreign="OBJ_ID"/>
+ </foreign-key>
+ </table>
+ <table name="CT_OBJECT_AA">
+ <column name="OBJ_ID" required="true" primaryKey="true"
type="INTEGER"/>
+ <column name="NAME" type="VARCHAR" size="250"/>
+ <column name="CONCRETE_CLASS" type="VARCHAR" size="250"/>
+ <column name="FK_ID" type="INTEGER"/>
+ <foreign-key foreignTable="CT_OBJECT_AAA">
+ <reference local="FK_ID" foreign="OBJ_ID"/>
+ </foreign-key>
+ </table>
+ <table name="CT_OBJECT_AAA">
+ <column name="OBJ_ID" required="true" primaryKey="true"
type="INTEGER"/>
+ <column name="NAME" type="VARCHAR" size="250"/>
+ <column name="CONCRETE_CLASS" type="VARCHAR" size="250"/>
+ <column name="FK_ID" type="INTEGER"/>
+ </table>
+
<!-- =================================================== -->
<!-- Complex test model tables -->
<!-- =================================================== -->
No revision
No revision
1.1.2.3 +381 -18
db-ojb/src/test/org/apache/ojb/odmg/Attic/CircularTest.java
Index: CircularTest.java
===================================================================
RCS file:
/home/cvs/db-ojb/src/test/org/apache/ojb/odmg/Attic/CircularTest.java,v
retrieving revision 1.1.2.2
retrieving revision 1.1.2.3
diff -u -r1.1.2.2 -r1.1.2.3
--- CircularTest.java 3 Apr 2005 17:21:55 -0000 1.1.2.2
+++ CircularTest.java 9 Apr 2005 22:31:11 -0000 1.1.2.3
@@ -5,6 +5,7 @@
import java.util.Iterator;
import java.util.List;
+import org.apache.ojb.broker.metadata.ObjectReferenceDescriptor;
import org.apache.ojb.junit.ODMGTestCase;
import org.odmg.OQLQuery;
@@ -26,7 +27,7 @@
/**
* Testing complex object graphs with circular and bidirectional references.
* <p/>
- * The class hierachy looks like:
+ * The classes hierarchy looks like:
* <br/>
* - Class Shop has a bidirectional 1:1 reference with ShopDetail.<br/>
* - Shop has a 1:n relation with Product, Product has a 1:1 reference to
Shop.<br/>
@@ -39,6 +40,12 @@
* - Product has a FK to Product<br/>
* - Product has a FK to Shop<br/>
* - CT_SHOP_DISTRIBUTOR indirection table has FK's to Shop and
Distributor<br/>
+ * <br/>
+ * <br/>
+ * - Class ObjectA has a 1:1 reference to ObjectAA, ObjectAA has 1:1 to
ObjectAAA, ObjectAAA has 1:1 to ObjectA.
+ * <br/>
+ * - ObjectA has FK to ObjectAA<br/>
+ * - ObjectAA has FK to ObjectAAA<br/>
*
* @version $Id$
*/
@@ -50,8 +57,17 @@
junit.textui.TestRunner.main(arr);
}
+ /**
+ * Class Shop has a bidirectional 1:1 reference with ShopDetail and the
DB table of Shop
+ * has a foreign key constraint on ShopDetail table.
+ * <p/>
+ * This test fails!! The ordering isn't able to handle this with causing
+ * a key constraint violation.
+ */
public void testBidirectionalWithConstraint_1a() throws Exception
{
+ if(ojbSkipKnownIssueProblem("odmg-ordering problem with circular
references")) return;
+
String name = "testBidirectionalWithConstraint_1a_" +
System.currentTimeMillis();
TransactionExt tx = (TransactionExt) odmg.newTransaction();
tx.begin();
@@ -61,20 +77,21 @@
s1.setDetail(sd);
sd.setShop(s1);
- // madatory to persist referenced ShopDetail first, the Shop
- // object will be detected automatic. In this case first the
ShopDetail
- // will be created and then the Shop
- database.makePersistent(sd);
+ database.makePersistent(s1);
tx.commit();
tx.begin();
- // madatory to mark object with DB FK constraint first on delete
- // then OJB will use this order to delete the bidirectional objects
database.deletePersistent(s1);
database.deletePersistent(sd);
tx.commit();
}
+ /**
+ * Class Shop has a bidirectional 1:1 reference with ShopDetail and the
DB table of Shop
+ * has a foreign key constraint on ShopDetail table.
+ * <p/>
+ * If the user take care of the ordering itself the test pass.
+ */
public void testBidirectionalWithConstraint_1b() throws Exception
{
String name = "testBidirectionalWithConstraint_1b_" +
System.currentTimeMillis();
@@ -82,13 +99,51 @@
tx.begin();
Shop s1 = new Shop(name + "_1");
- // when using flush() we can use a more "natural" order
+ // when using flush() we can use the "natural" order
// without getting DB constraint violence.
database.makePersistent(s1);
+ // write to DB object without references
tx.flush();
ShopDetail sd = new ShopDetail(name + "_1");
+ // now set references
+ s1.setDetail(sd);
+ sd.setShop(s1);
+ // no need to persist the ShopDetail object
+ // (will be detected by OJB)
+ // but it doesn't matter if you do
+ // database.makePersistent(sd);
+ tx.commit();
+
+ tx.begin();
+ // madatory to mark object with DB FK constraint first on delete
+ // then OJB will use this order to delete the bidirectional objects
+ database.deletePersistent(s1);
+ database.deletePersistent(sd);
+ tx.commit();
+ }
+
+ /**
+ * Class Shop has a bidirectional 1:1 reference with ShopDetail and the
DB table of Shop
+ * has a foreign key constraint on ShopDetail table.
+ * <p/>
+ * If the user take care of the ordering itself the test pass.
+ */
+ public void testBidirectionalWithConstraint_1c() throws Exception
+ {
+ String name = "testBidirectionalWithConstraint_1c_" +
System.currentTimeMillis();
+ TransactionExt tx = (TransactionExt) odmg.newTransaction();
+ tx.begin();
+
+ Shop s1 = new Shop(name + "_1");
+ ShopDetail sd = new ShopDetail(name + "_1");
s1.setDetail(sd);
sd.setShop(s1);
+
+ // madatory to persist referenced ShopDetail first, the Shop
+ // object will be detected automatic. In this case first the
ShopDetail
+ // will be created and then the Shop
+ database.makePersistent(sd);
+ database.makePersistent(s1);
tx.commit();
tx.begin();
@@ -99,6 +154,155 @@
tx.commit();
}
+ /**
+ * This test is only for comparison of ODMG- with PB-api. It's not
recommended
+ * to do this in ODMG production environment.
+ *
+ * @throws Exception
+ */
+ public void testBidirectionalWithConstraint_1d_PB() throws Exception
+ {
+ ojbChangeReferenceSetting(Shop.class, "detail", true,
ObjectReferenceDescriptor.CASCADE_OBJECT,
ObjectReferenceDescriptor.CASCADE_OBJECT, false);
+ ojbChangeReferenceSetting(ShopDetail.class, "shop", true,
ObjectReferenceDescriptor.CASCADE_OBJECT,
ObjectReferenceDescriptor.CASCADE_OBJECT, false);
+ String name = "testBidirectionalWithConstraint_1a_" +
System.currentTimeMillis();
+ TransactionExt tx = (TransactionExt) odmg.newTransaction();
+ tx.begin();
+
+ Shop s1 = new Shop(name + "_1");
+ ShopDetail sd = new ShopDetail(name + "_1");
+ s1.setDetail(sd);
+ sd.setShop(s1);
+
+ // only for testing, we completely bypass odmg
+ tx.getBroker().beginTransaction();
+ tx.getBroker().store(s1);
+ tx.commit();
+
+
+ tx.begin();
+ // only for testing, we completely bypass odmg
+ tx.getBroker().beginTransaction();
+ // madatory to mark object with DB FK constraint first on delete
+ // then OJB will use this order to delete the bidirectional objects
+ tx.getBroker().delete(s1);
+ tx.commit();
+ }
+
+ /**
+ * Handling of circular 1:1 reference:
ObjetA--1:1-->ObjectAA--1:1-->ObjectAAA--1:1-->ObjectA
+ * with FK constraint from ObjectA to ObjectAA and ObjectAA to ObjectAAA.
+ * <p/>
+ * This test fails!! The ordering isn't able to handle this with causing
+ * a key constraint violation.
+ */
+ public void testCircularOneToOne_1()
+ {
+ if(ojbSkipKnownIssueProblem("odmg-ordering problem with circular
references")) return;
+
+ String name = "testCircularOneToOne_1_" + System.currentTimeMillis();
+
+ TransactionExt tx = (TransactionExt) odmg.newTransaction();
+ tx.begin();
+
+ ObjectA a = new ObjectA(name + "_ObjectA");
+ ObjectAA aa = new ObjectAA(name + "_ObjectAA");
+ ObjectAAA aaa = new ObjectAAA(name + "_ObjectAAA");
+ // now set the circular references
+ a.setRefAA(aa);
+ aa.setRefAAA(aaa);
+ aaa.setRefA(a);
+ database.makePersistent(a);
+ tx.commit();
+
+ tx.begin();
+ database.deletePersistent(a);
+ tx.commit();
+ }
+
+ /**
+ * Handling of circular 1:1 reference:
ObjetA--1:1-->ObjectAA--1:1-->ObjectAAA--1:1-->ObjectA
+ * with FK constraint from ObjectA to ObjectAA and ObjectAA to ObjectAAA.
+ * <p/>
+ * If the user take care of the ordering itself the test pass.
+ */
+ public void testCircularOneToOne_2()
+ {
+ String name = "testCircularOneToOne_2_" + System.currentTimeMillis();
+
+ TransactionExt tx = (TransactionExt) odmg.newTransaction();
+ tx.begin();
+
+ ObjectA a = new ObjectA(name + "_ObjectA");
+ ObjectAA aa = new ObjectAA(name + "_ObjectAA");
+ ObjectAAA aaa = new ObjectAAA(name + "_ObjectAAA");
+ // now set the circular references
+ a.setRefAA(aa);
+ aa.setRefAAA(aaa);
+ aaa.setRefA(a);
+ database.makePersistent(aaa);
+ database.makePersistent(aa);
+ database.makePersistent(a);
+ tx.commit();
+
+ tx.begin();
+ database.deletePersistent(a);
+ database.deletePersistent(aa);
+ database.deletePersistent(aaa);
+ tx.commit();
+ }
+
+ /**
+ * This test is only for comparison of ODMG- with PB-api. It's not
recommended
+ * to do this in ODMG production environment.
+ * Handling of circular 1:1 reference:
ObjetA--1:1-->ObjectAA--1:1-->ObjectAAA--1:1-->ObjectA
+ * when each object has a FK constraint to it's reference.
+ *
+ * @throws Exception
+ */
+ public void testCircularOneToOne_PB() throws Exception
+ {
+ ojbChangeReferenceSetting(ObjectA.class, "refAA", true,
ObjectReferenceDescriptor.CASCADE_OBJECT,
ObjectReferenceDescriptor.CASCADE_OBJECT, false);
+ ojbChangeReferenceSetting(ObjectAA.class, "refAAA", true,
ObjectReferenceDescriptor.CASCADE_OBJECT,
ObjectReferenceDescriptor.CASCADE_OBJECT, false);
+ //ojbChangeReferenceSetting(ObjectAAA.class, "refA", true,
ObjectReferenceDescriptor.CASCADE_OBJECT,
ObjectReferenceDescriptor.CASCADE_OBJECT, false);
+ String name = "testCircularOneToOne_PB" + System.currentTimeMillis();
+ TransactionExt tx = (TransactionExt) odmg.newTransaction();
+ tx.begin();
+
+ ObjectA a = new ObjectA(name + "_ObjectA");
+ // only for testing, we completely bypass odmg
+ tx.getBroker().beginTransaction();
+ //tx.getBroker().store(a);
+
+ ObjectAA aa = new ObjectAA(name + "_ObjectAA");
+ ObjectAAA aaa = new ObjectAAA(name + "_ObjectAAA");
+ // now set the circular references
+ a.setRefAA(aa);
+ aa.setRefAAA(aaa);
+ aaa.setRefA(a);
+
+ tx.getBroker().store(a);
+
+ tx.commit();
+
+
+ tx.begin();
+ // only for testing, we completely bypass odmg
+ tx.getBroker().beginTransaction();
+ // madatory to mark object with DB FK constraint first on delete
+ // then OJB will use this order to delete the bidirectional objects
+ //aaa.setRefA(null);
+ //tx.getBroker().store(aaa);
+ tx.getBroker().delete(a);
+ tx.commit();
+ }
+
+ /**
+ * Class Shop has a bidirectional 1:1 reference with ShopDetail and the
DB table of Shop
+ * has a foreign key constraint on ShopDetail table. Shop has a m:n
relation with Distributor.
+ * <p/>
+ * This test fails!! The ordering isn't able to handle this with causing
+ * a key constraint violation.
+ */
public void testBidirectionalWithConstraint_2a() throws Exception
{
String name = "testBidirectionalWithConstraint_2a_" +
System.currentTimeMillis();
@@ -113,6 +317,37 @@
TransactionExt tx = (TransactionExt) odmg.newTransaction();
tx.begin();
+ database.makePersistent(s1);
+ tx.commit();
+
+ // Now we delete the Shop with ShopDetail, but don't
+ // touch the Distributor object
+ tx.begin();
+ database.deletePersistent(s1);
+ database.deletePersistent(sd);
+ tx.commit();
+ }
+
+ /**
+ * Class Shop has a bidirectional 1:1 reference with ShopDetail and the
DB table of Shop
+ * has a foreign key constraint on ShopDetail table. Shop has a m:n
relation with Distributor.
+ * <p/>
+ * If the user take care of the ordering itself the test pass.
+ */
+ public void testBidirectionalWithConstraint_2b() throws Exception
+ {
+ String name = "testBidirectionalWithConstraint_2b_" +
System.currentTimeMillis();
+
+ Shop s1 = new Shop(name + "_1");
+ ShopDetail sd = new ShopDetail(name + "_1");
+ s1.setDetail(sd);
+ sd.setShop(s1);
+ Distributor d1 = new Distributor(name + "_1");
+ s1.addDistributor(d1);
+ d1.addShop(s1);
+
+ TransactionExt tx = (TransactionExt) odmg.newTransaction();
+ tx.begin();
// mandatory to first persist the referenced object of the
// bidirectional 1:1 reference, because of the FK in Shop
// the m:n relation will be handled without problems
@@ -131,9 +366,15 @@
tx.commit();
}
- public void testBidirectionalWithConstraint_2b() throws Exception
+ /**
+ * Class Shop has a bidirectional 1:1 reference with ShopDetail and the
DB table of Shop
+ * has a foreign key constraint on ShopDetail table. Shop has a m:n
relation with Distributor.
+ * <p/>
+ * If the user take care of the ordering itself the test pass.
+ */
+ public void testBidirectionalWithConstraint_2c() throws Exception
{
- String name = "testBidirectionalWithConstraint_2b_" +
System.currentTimeMillis();
+ String name = "testBidirectionalWithConstraint_2c_" +
System.currentTimeMillis();
TransactionExt tx = (TransactionExt) odmg.newTransaction();
tx.begin();
// When using flush() we can use a more "natural" object persisting
order
@@ -158,9 +399,15 @@
tx.commit();
}
- public void testBidirectionalWithConstraint_3() throws Exception
+ /**
+ * Class Shop has a bidirectional 1:1 reference with ShopDetail and the
DB table of Shop
+ * has a foreign key constraint on ShopDetail table. Shop has a m:n
relation with Distributor.
+ * <p/>
+ * If the user take care of the ordering itself the test pass.
+ */
+ public void testBidirectionalWithConstraint_2d() throws Exception
{
- String name = "testBidirectionalWithConstraint_3_" +
System.currentTimeMillis();
+ String name = "testBidirectionalWithConstraint_2d_" +
System.currentTimeMillis();
Shop s1 = new Shop(name + "_1");
ShopDetail sd = new ShopDetail(name + "_1");
s1.setDetail(sd);
@@ -190,7 +437,7 @@
TransactionExt tx = (TransactionExt) odmg.newTransaction();
tx.begin();
- // mandatory to add the ShopDetail object first
+ // mandatory to add the ShopDetail object first, because of the
ordering bug
database.makePersistent(sd);
database.makePersistent(s1);
database.makePersistent(s2);
@@ -237,9 +484,6 @@
{
String name = "testMtoNWithBackReference_2_" +
System.currentTimeMillis();
Shop s1 = new Shop(name + "_1");
- ShopDetail sd = new ShopDetail(name + "_1");
- s1.setDetail(sd);
- sd.setShop(s1);
Shop s2 = new Shop(name + "_2");
Shop s3 = new Shop(name + "_3");
Distributor d1 = new Distributor(name + "_1");
@@ -266,7 +510,6 @@
TransactionExt tx = (TransactionExt) odmg.newTransaction();
tx.begin();
// madatory to add the ShopDetail object first
- database.makePersistent(sd);
database.makePersistent(s1);
database.makePersistent(s2);
database.makePersistent(s3);
@@ -1016,4 +1259,124 @@
this.shop = shop;
}
}
+
+ abstract static class BaseObject
+ {
+ private Integer id;
+ private String name;
+ private String ojbConcreteClass;
+
+ public BaseObject()
+ {
+ this.ojbConcreteClass = this.getClass().getName();
+ }
+
+ public BaseObject(String name)
+ {
+ this();
+ this.name = name;
+ }
+
+ public Integer getId()
+ {
+ return id;
+ }
+
+ public void setId(Integer id)
+ {
+ this.id = id;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public void setName(String name)
+ {
+ this.name = name;
+ }
+
+ public String getOjbConcreteClass()
+ {
+ return ojbConcreteClass;
+ }
+
+ public void setOjbConcreteClass(String ojbConcreteClass)
+ {
+ this.ojbConcreteClass = ojbConcreteClass;
+ }
+ }
+
+ public static class ObjectA extends BaseObject
+ {
+ private ObjectAA refAA;
+
+ public ObjectA()
+ {
+ }
+
+ public ObjectA(String name)
+ {
+ super(name);
+ }
+
+ public ObjectAA getRefAA()
+ {
+ return refAA;
+ }
+
+ public void setRefAA(ObjectAA refAA)
+ {
+ this.refAA = refAA;
+ }
+ }
+
+ public static class ObjectAA extends BaseObject
+ {
+ private ObjectAAA refAAA;
+
+ public ObjectAA()
+ {
+ }
+
+ public ObjectAA(String name)
+ {
+ super(name);
+ }
+
+ public ObjectAAA getRefAAA()
+ {
+ return refAAA;
+ }
+
+ public void setRefAAA(ObjectAAA refAAA)
+ {
+ this.refAAA = refAAA;
+ }
+ }
+
+ public static class ObjectAAA extends BaseObject
+ {
+ private ObjectA refA;
+
+ public ObjectAAA()
+ {
+ }
+
+ public ObjectAAA(String name)
+ {
+ super(name);
+ }
+
+ public ObjectA getRefA()
+ {
+ return refA;
+ }
+
+ public void setRefA(ObjectA refA)
+ {
+ this.refA = refA;
+ }
+ }
}
No revision
No revision
1.13.2.8 +130 -1 db-ojb/src/test/org/apache/ojb/repository_junit_odmg.xml
Index: repository_junit_odmg.xml
===================================================================
RCS file: /home/cvs/db-ojb/src/test/org/apache/ojb/repository_junit_odmg.xml,v
retrieving revision 1.13.2.7
retrieving revision 1.13.2.8
diff -u -r1.13.2.7 -r1.13.2.8
--- repository_junit_odmg.xml 3 Apr 2005 01:48:10 -0000 1.13.2.7
+++ repository_junit_odmg.xml 9 Apr 2005 22:31:11 -0000 1.13.2.8
@@ -2020,4 +2020,133 @@
</class-descriptor>
+<class-descriptor
+ class="org.apache.ojb.odmg.CircularTest$ObjectA"
+ table="CT_OBJECT_A"
+ >
+ <field-descriptor
+ name="id"
+ column="OBJ_ID"
+ jdbc-type="INTEGER"
+ primarykey="true"
+ autoincrement="true"
+ />
+
+ <field-descriptor
+ name="name"
+ column="NAME"
+ jdbc-type="VARCHAR"
+ />
+
+ <field-descriptor
+ name="ojbConcreteClass"
+ column="CONCRETE_CLASS"
+ jdbc-type="VARCHAR"
+ />
+
+ <field-descriptor
+ name="fkId"
+ column="FK_ID"
+ jdbc-type="INTEGER"
+ access="anonymous"
+ />
+
+ <reference-descriptor name="refAA"
+ class-ref="org.apache.ojb.odmg.CircularTest$ObjectAA"
+ proxy="false"
+ auto-retrieve="true"
+ auto-update="none"
+ auto-delete="none"
+ >
+ <foreignkey field-ref="fkId"/>
+ </reference-descriptor>
+
+</class-descriptor>
+
+<class-descriptor
+ class="org.apache.ojb.odmg.CircularTest$ObjectAA"
+ table="CT_OBJECT_AA"
+ >
+ <field-descriptor
+ name="id"
+ column="OBJ_ID"
+ jdbc-type="INTEGER"
+ primarykey="true"
+ autoincrement="true"
+ />
+
+ <field-descriptor
+ name="name"
+ column="NAME"
+ jdbc-type="VARCHAR"
+ />
+
+ <field-descriptor
+ name="ojbConcreteClass"
+ column="CONCRETE_CLASS"
+ jdbc-type="VARCHAR"
+ />
+
+ <field-descriptor
+ name="fkId"
+ column="FK_ID"
+ jdbc-type="INTEGER"
+ access="anonymous"
+ />
+
+ <reference-descriptor name="refAAA"
+ class-ref="org.apache.ojb.odmg.CircularTest$ObjectAAA"
+ proxy="false"
+ auto-retrieve="true"
+ auto-update="none"
+ auto-delete="none"
+ >
+ <foreignkey field-ref="fkId"/>
+ </reference-descriptor>
+
+</class-descriptor>
+
+<class-descriptor
+ class="org.apache.ojb.odmg.CircularTest$ObjectAAA"
+ table="CT_OBJECT_AAA"
+ >
+ <field-descriptor
+ name="id"
+ column="OBJ_ID"
+ jdbc-type="INTEGER"
+ primarykey="true"
+ autoincrement="true"
+ />
+
+ <field-descriptor
+ name="name"
+ column="NAME"
+ jdbc-type="VARCHAR"
+ />
+
+ <field-descriptor
+ name="ojbConcreteClass"
+ column="CONCRETE_CLASS"
+ jdbc-type="VARCHAR"
+ />
+
+ <field-descriptor
+ name="fkId"
+ column="FK_ID"
+ jdbc-type="INTEGER"
+ access="anonymous"
+ />
+
+ <reference-descriptor name="refA"
+ class-ref="org.apache.ojb.odmg.CircularTest$ObjectA"
+ proxy="false"
+ auto-retrieve="true"
+ auto-update="none"
+ auto-delete="none"
+ >
+ <foreignkey field-ref="fkId"/>
+ </reference-descriptor>
+
+</class-descriptor>
+
<!-- Mapping of classes used in junit tests and tutorials ends here -->
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]