cdmlib-persistence/src/test/java/eu/etaxonomy/cdm/persistence/dao/hibernate/reference/ReferenceDaoHibernateImplTest.java -text
cdmlib-persistence/src/test/java/eu/etaxonomy/cdm/persistence/dao/hibernate/taxon/TaxonDaoHibernateImplTest.java -text
cdmlib-persistence/src/test/java/eu/etaxonomy/cdm/persistence/dao/hibernate/taxon/TaxonNodeDaoHibernateImplTest.java -text
+cdmlib-persistence/src/test/java/eu/etaxonomy/cdm/persistence/dao/hibernate/view/AuditEventDaoTest.java -text
cdmlib-persistence/src/test/java/eu/etaxonomy/cdm/persistence/hibernate/CacheStrategyGeneratorTest.java -text
cdmlib-persistence/src/test/java/eu/etaxonomy/cdm/persistence/hibernate/CdmDeleteListenerTest.java -text
cdmlib-persistence/src/test/java/eu/etaxonomy/cdm/test/function/Datasource.java -text
cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/hibernate/taxon/TaxonDaoHibernateImplTest.testGetTaxaByNameAndArea.xml -text
cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/hibernate/taxon/TaxonDaoHibernateImplTest.xml -text
cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/hibernate/taxon/TaxonNodeDaoHibernateImplTest.xml -text
+cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/hibernate/view/AuditEventDaoTest.xml -text
cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/hibernate/CacheStrategyGeneratorTest.testOnSaveOrUpdateAgents-result.xml -text
cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/hibernate/CacheStrategyGeneratorTest.testOnSaveOrUpdateNames-result.xml -text
cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/hibernate/CacheStrategyGeneratorTest.xml -text
import java.util.List;
+import org.hibernate.envers.query.criteria.AuditCriterion;
+
import eu.etaxonomy.cdm.model.common.VersionableEntity;
+import eu.etaxonomy.cdm.model.view.AuditEvent;
import eu.etaxonomy.cdm.model.view.AuditEventRecord;
public interface IVersionableDao<T extends VersionableEntity> extends ICdmEntityDao<T> {
* @return a record of the previous audit event to affect t, or null if the current event is the first to affect t
*/
public AuditEventRecord<T> getPreviousAuditEvent(T t);
+
+ /**
+ * Returns a count of the total number of audit events affecting objects of class T, optionally restricted to objects of
+ * class clazz, the AuditEvents from and to, inclusive, optionally filtered by other criteria
+ *
+ * @param clazz Restrict the results returned to objects of this class
+ * @param from The audit event to start from (or pass null to start from the beginning of the recordset)
+ * @param to The audit event to continue until (or pass null to return audit events up to the time of the query)
+ * @param criteria Extra criteria to filter by
+ * @return the count of audit events
+ */
+ public Integer countAuditEvents(Class<? extends T> clazz,AuditEvent from,AuditEvent to,List<AuditCriterion> criteria);
+
+ /**
+ * Returns a list of all audit events occurring to objects of type T, optionally restricted to objects of type clazz
+ * between the AuditEvents from and to, inclusive, optionally filtered by other criteria
+ *
+ * @param clazz Restrict the results returned to objects of this class
+ * @param from The audit event to start from (inclusive, or pass null to start from the beginning of the recordset)
+ * @param to The audit event to continue until (exclusive, or pass null to return audit events up to the time of the query)
+ * @param criteria Extra criteria to filter by
+ * @param pageSize The maximum number of objects returned (can be null for all matching objects)
+ * @param pageNumber The offset (in pageSize chunks) from the start of the result set (0 - based,
+ * can be null, equivalent of starting at the beginning of the recordset)
+ * @param sort Sort the events either forwards or backwards in time
+ * @param propertyPaths properties to be initialized
+ * @return
+ */
+ public List<AuditEventRecord<T>> getAuditEvents(Class<? extends T> clazz, AuditEvent from,AuditEvent to,List<AuditCriterion> criteria, Integer pageSize, Integer pageNumber,AuditEventSort sort,List<String> propertyPaths);
}
import org.apache.commons.logging.LogFactory;\r
import org.apache.lucene.search.Sort;\r
import org.apache.lucene.search.SortField;\r
+import org.hibernate.criterion.Criterion;\r
import org.hibernate.envers.AuditReader;\r
import org.hibernate.envers.AuditReaderFactory;\r
import org.hibernate.envers.query.AuditEntity;\r
import org.hibernate.envers.query.AuditQuery;\r
+import org.hibernate.envers.query.criteria.AuditCriterion;\r
import org.hibernate.envers.query.order.AuditOrder;\r
import org.hibernate.search.FullTextQuery;\r
import org.joda.time.DateTime;\r
return auditEvents.get(0);\r
}\r
}\r
+\r
+ public Integer countAuditEvents(Class<? extends T> clazz, AuditEvent from, AuditEvent to, List<AuditCriterion> criteria) {\r
+ AuditQuery query = null;\r
+ \r
+ if(clazz == null) {\r
+ query = getAuditReader().createQuery().forRevisionsOfEntity(type, false, true);\r
+ } else {\r
+ query = getAuditReader().createQuery().forRevisionsOfEntity(clazz, false, true);\r
+ }\r
+ \r
+ if(from != null) {\r
+ query.add(AuditEntity.revisionNumber().ge(from.getRevisionNumber()));\r
+ } \r
+ \r
+ if(to != null && !to.equals(AuditEvent.CURRENT_VIEW)) {\r
+ query.add(AuditEntity.revisionNumber().lt(to.getRevisionNumber()));\r
+ } \r
+ \r
+ addCriteria(query,criteria);\r
+ \r
+ query.addProjection(AuditEntity.property("id").count());\r
+ \r
+ return ((Long)query.getSingleResult()).intValue();\r
+ }\r
+\r
+ protected void addCriteria(AuditQuery query, List<AuditCriterion> criteria) {\r
+ if(criteria != null) {\r
+ for(AuditCriterion c : criteria) {\r
+ query.add(c);\r
+ }\r
+ }\r
+ }\r
+\r
+ public List<AuditEventRecord<T>> getAuditEvents(Class<? extends T> clazz,AuditEvent from, AuditEvent to, List<AuditCriterion> criteria, Integer pageSize, Integer pageNumber, AuditEventSort sort, List<String> propertyPaths) {\r
+ AuditQuery query = null;\r
+ \r
+ if(clazz == null) {\r
+ query = getAuditReader().createQuery().forRevisionsOfEntity(type, false, true);\r
+ } else {\r
+ query = getAuditReader().createQuery().forRevisionsOfEntity(clazz, false, true);\r
+ }\r
+ \r
+ if(from != null) {\r
+ query.add(AuditEntity.revisionNumber().ge(from.getRevisionNumber()));\r
+ } \r
+ \r
+ if(to != null && !to.equals(AuditEvent.CURRENT_VIEW)) {\r
+ query.add(AuditEntity.revisionNumber().lt(to.getRevisionNumber()));\r
+ } \r
+ \r
+ addCriteria(query,criteria);\r
+ \r
+ if(pageSize != null) {\r
+ query.setMaxResults(pageSize);\r
+ if(pageNumber != null) {\r
+ query.setFirstResult(pageNumber * pageSize);\r
+ } else {\r
+ query.setFirstResult(0);\r
+ }\r
+ }\r
+ \r
+ /**\r
+ * At the moment we need to transform the data manually\r
+ */\r
+ List<Object[]> objs = (List<Object[]>)query.getResultList();\r
+ List<AuditEventRecord<T>> records = new ArrayList<AuditEventRecord<T>>();\r
+ \r
+ for(Object[] obj : objs) {\r
+ records.add(new AuditEventRecordImpl<T>(obj));\r
+ }\r
+ \r
+ for(AuditEventRecord<T> record : records) {\r
+ defaultBeanInitializer.initialize(record.getAuditableObject(), propertyPaths);\r
+ }\r
+ return records;\r
+ }\r
}\r
import java.util.UUID;
import org.hibernate.Query;
+import org.hibernate.envers.AuditReader;
+import org.hibernate.envers.AuditReaderFactory;
+import org.joda.time.DateTime;
import org.springframework.stereotype.Repository;
import eu.etaxonomy.cdm.model.view.AuditEvent;
@Repository
public class AuditEventDao extends DaoBase implements IAuditEventDao {
+
+ protected AuditReader getAuditReader() {
+ return AuditReaderFactory.get(getSession());
+ }
public int count() {
Query query = getSession().createQuery("select count(auditEvent) from AuditEvent auditEvent");
return (List<AuditEvent>)query.list();
}
+
+ public AuditEvent findByDate(DateTime dateTime) {
+ Number id = getAuditReader().getRevisionNumberForDate(dateTime.toDate());
+ return (AuditEvent)getSession().load(AuditEvent.class, id);
+ }
}
import java.util.List;
import java.util.UUID;
+import org.joda.time.DateTime;
+
import eu.etaxonomy.cdm.model.view.AuditEvent;
import eu.etaxonomy.cdm.persistence.dao.common.AuditEventSort;
* @return true if an AuditEvent with a matching uuid exists in the database, false otherwise
*/
public boolean exists(UUID uuid);
+
+ /**
+ * Returns the AuditEvent that represents the given DateTime
+ * @param dateTime
+ * @return an AuditEvent object
+ */
+ public AuditEvent findByDate(DateTime dateTime);
}
import java.util.UUID;\r
\r
import org.hibernate.Hibernate;\r
+import org.hibernate.envers.query.AuditEntity;\r
+import org.hibernate.envers.query.criteria.AuditCriterion;\r
import org.junit.After;\r
import org.junit.Before;\r
import org.junit.Ignore;\r
TaxonomicTree taxonomicTree = taxonomicTreeDao.findByUuid(taxonomicTreeUuid);\r
assertNotNull(taxonDao.getTaxonNodeUuidAndTitleCacheOfAcceptedTaxaByTaxonomicTree(taxonomicTree));\r
}\r
+ \r
+ @Test\r
+ @DataSet("TaxonDaoHibernateImplTest.testFindDeleted.xml")\r
+ public void testGetAuditEventsByType() {\r
+ \r
+ List<String> propertyPaths = new ArrayList<String>();\r
+ propertyPaths.add("name");\r
+ propertyPaths.add("createdBy");\r
+ propertyPaths.add("updatedBy");\r
+ \r
+ List<AuditEventRecord<TaxonBase>> auditEvents = taxonDao.getAuditEvents(TaxonBase.class, previousAuditEvent, mostRecentAuditEvent, null,null, null, AuditEventSort.FORWARDS, propertyPaths);\r
+ assertNotNull("getAuditEvents should return a list",auditEvents);\r
+ assertFalse("the list should not be empty",auditEvents.isEmpty());\r
+ assertEquals("There should be thirty eight AuditEventRecords in the list",38, auditEvents.size());\r
+ }\r
+ \r
+ @Test\r
+ @DataSet("TaxonDaoHibernateImplTest.testFindDeleted.xml")\r
+ public void testGetAuditEventsByTypeWithRestrictions() {\r
+ \r
+ List<String> propertyPaths = new ArrayList<String>();\r
+ propertyPaths.add("name");\r
+ propertyPaths.add("createdBy");\r
+ propertyPaths.add("updatedBy");\r
+ \r
+ List<AuditCriterion> criteria = new ArrayList<AuditCriterion>();\r
+ criteria.add(AuditEntity.property("lsid_lsid").isNotNull());\r
+ \r
+ List<AuditEventRecord<TaxonBase>> auditEvents = taxonDao.getAuditEvents(TaxonBase.class, previousAuditEvent, mostRecentAuditEvent, criteria,null, null, AuditEventSort.FORWARDS, propertyPaths);\r
+ assertNotNull("getAuditEvents should return a list",auditEvents);\r
+ assertFalse("the list should not be empty",auditEvents.isEmpty());\r
+ assertEquals("There should be one AuditEventRecord in the list",1, auditEvents.size());\r
+ }\r
}\r
--- /dev/null
+/**\r
+* Copyright (C) 2009 EDIT\r
+* European Distributed Institute of Taxonomy\r
+* http://www.e-taxonomy.eu\r
+*\r
+* The contents of this file are subject to the Mozilla Public License Version 1.1\r
+* See LICENSE.TXT at the top of this package for the full license terms.\r
+*/ \r
+\r
+package eu.etaxonomy.cdm.persistence.dao.hibernate.view;\r
+\r
+import static junit.framework.Assert.assertEquals;\r
+import static junit.framework.Assert.assertFalse;\r
+import static junit.framework.Assert.assertNotNull;\r
+import static junit.framework.Assert.assertSame;\r
+import static junit.framework.Assert.assertTrue;\r
+import static org.junit.Assert.assertNull;\r
+import static org.junit.Assert.fail;\r
+\r
+import java.io.FileOutputStream;\r
+import java.util.ArrayList;\r
+import java.util.HashSet;\r
+import java.util.List;\r
+import java.util.Set;\r
+import java.util.UUID;\r
+\r
+import org.hibernate.Hibernate;\r
+import org.hibernate.envers.query.AuditEntity;\r
+import org.hibernate.envers.query.criteria.AuditCriterion;\r
+import org.joda.time.DateTime;\r
+import org.junit.After;\r
+import org.junit.Before;\r
+import org.junit.Ignore;\r
+import org.junit.Test;\r
+import org.unitils.dbunit.annotation.DataSet;\r
+import org.unitils.dbunit.annotation.ExpectedDataSet;\r
+import org.unitils.spring.annotation.SpringBeanByType;\r
+\r
+import eu.etaxonomy.cdm.model.description.DescriptionElementBase;\r
+import eu.etaxonomy.cdm.model.description.Distribution;\r
+import eu.etaxonomy.cdm.model.description.TaxonDescription;\r
+import eu.etaxonomy.cdm.model.location.NamedArea;\r
+import eu.etaxonomy.cdm.model.name.NonViralName;\r
+import eu.etaxonomy.cdm.model.name.Rank;\r
+import eu.etaxonomy.cdm.model.name.TaxonNameBase;\r
+import eu.etaxonomy.cdm.model.reference.ReferenceBase;\r
+import eu.etaxonomy.cdm.model.taxon.Synonym;\r
+import eu.etaxonomy.cdm.model.taxon.SynonymRelationship;\r
+import eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType;\r
+import eu.etaxonomy.cdm.model.taxon.Taxon;\r
+import eu.etaxonomy.cdm.model.taxon.TaxonBase;\r
+import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;\r
+import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;\r
+import eu.etaxonomy.cdm.model.taxon.TaxonomicTree;\r
+import eu.etaxonomy.cdm.model.view.AuditEvent;\r
+import eu.etaxonomy.cdm.model.view.AuditEventRecord;\r
+import eu.etaxonomy.cdm.model.view.context.AuditEventContextHolder;\r
+import eu.etaxonomy.cdm.persistence.dao.common.AuditEventSort;\r
+import eu.etaxonomy.cdm.persistence.dao.common.IDefinedTermDao;\r
+import eu.etaxonomy.cdm.persistence.dao.reference.IReferenceDao;\r
+import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao;\r
+import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonomicTreeDao;\r
+import eu.etaxonomy.cdm.persistence.fetch.CdmFetch;\r
+import eu.etaxonomy.cdm.persistence.query.GroupByCount;\r
+import eu.etaxonomy.cdm.persistence.query.GroupByDate;\r
+import eu.etaxonomy.cdm.persistence.query.Grouping;\r
+import eu.etaxonomy.cdm.persistence.query.MatchMode;\r
+import eu.etaxonomy.cdm.persistence.query.OrderHint;\r
+import eu.etaxonomy.cdm.persistence.query.OrderHint.SortOrder;\r
+import eu.etaxonomy.cdm.persistence.view.IAuditEventDao;\r
+import eu.etaxonomy.cdm.test.integration.CdmTransactionalIntegrationTest;\r
+\r
+/**\r
+ * @author a.mueller\r
+ * @author ben.clark\r
+ *\r
+ */\r
+public class AuditEventDaoTest extends CdmTransactionalIntegrationTest {\r
+ \r
+ @SpringBeanByType \r
+ private IAuditEventDao auditEventDao;\r
+ \r
+ private DateTime dateTime;\r
+ \r
+ @Before\r
+ public void setUp() {\r
+ dateTime = new DateTime();\r
+ }\r
+ \r
+ \r
+ /**\r
+ * Test method for {@link eu.etaxonomy.cdm.persistence.dao.hibernate.view.AuditEventDao#findByDate()}.\r
+ */\r
+ @Test\r
+ @DataSet\r
+ public void testFindByDate() {\r
+ AuditEvent auditEvent = auditEventDao.findByDate(dateTime);\r
+ assertNotNull(auditEvent);\r
+ }\r
+}\r
lsid_revision varchar(255),
protectedtitlecache bit not null,
titleCache varchar(255),
- primary key (id),
- unique (uuid)
+ primary key (id, REV)
);
<?xml version='1.0' encoding='UTF-8'?>\r
<dataset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../dataset.xsd">\r
+ <AUDITEVENT REVISIONNUMBER="1000" TIMESTAMP="1232914238974" UUID="a680fab4-365e-4765-b49e-768f2ee30cda"/>\r
+ <AUDITEVENT REVISIONNUMBER="1001" TIMESTAMP="1232914244116" UUID="afe8e761-8545-497b-9134-6a6791fc0b0d"/>\r
<HOMOTYPICALGROUP ID="1" CREATED="2008-12-10 09:56:07.0" UUID="7b214eb9-a6ac-48e5-af02-bbea634d2a03" UPDATED="2008-12-10 09:56:07.238"/>\r
<HOMOTYPICALGROUP ID="2" CREATED="2008-12-10 09:56:07.0" UUID="6c241a4c-e5a0-4344-8e5e-a81f17b75973" UPDATED="2008-12-10 09:56:07.253"/>\r
<HOMOTYPICALGROUP_AUD ID="1" REV="1000" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="7b214eb9-a6ac-48e5-af02-bbea634d2a03" UPDATED="2008-12-10 09:56:07.238"/>\r
<TAXONBASE DTYPE="Taxon" ID="38" CREATED="2008-12-10 09:56:07.0" UUID="bc09aca6-06fd-4905-b1e7-cbf7cc65d783" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Cryptocoryne x purpurea nothovar borneoensis N.Jacobsen, Bastm. & Yuji Sasaki sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONSTATUSUNKNOWN="false" TAXONOMICCHILDRENCOUNT="0" TAXONNAME_FK="38" SEC_ID="3"/>
<TAXONBASE_AUD DTYPE="Taxon" ID="1" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="496b1325-be50-4b0a-9aa2-3ecd610215f2" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE=" sec. ???" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="1" SEC_ID="1" TAXONOMICCHILDRENCOUNT="1" TAXONSTATUSUNKNOWN="false"/>
<TAXONBASE_AUD DTYPE="Taxon" ID="2" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="822d98dc-9ef7-44b7-a870-94573a3bcb46" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE=" sec. ???" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="2" SEC_ID="1" TAXONOMICCHILDRENCOUNT="0" TAXONOMICPARENTCACHE_ID="1" TAXONSTATUSUNKNOWN="false"/>
- <TAXONBASE_AUD DTYPE="Taxon" ID="3" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="54e767ee-894e-4540-a758-f906ecb4e2d9" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Sphingidae Linnaeus, 1758 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="3" SEC_ID="2" TAXONOMICCHILDRENCOUNT="204" TAXONSTATUSUNKNOWN="false"/>
- <TAXONBASE_AUD DTYPE="Taxon" ID="3" REV="1026" REVTYPE="1" CREATED="2008-12-10 09:56:07.0" UUID="54e767ee-894e-4540-a758-f906ecb4e2d9" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Sphingidae Linnaeus, 1758 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="3" SEC_ID="2" TAXONOMICCHILDRENCOUNT="204" TAXONSTATUSUNKNOWN="false"/>
+ <TAXONBASE_AUD DTYPE="Taxon" ID="3" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="54e767ee-894e-4540-a758-f906ecb4e2d9" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Sphingidae Linnaeus, 1758 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="3" SEC_ID="2" TAXONOMICCHILDRENCOUNT="204" TAXONSTATUSUNKNOWN="false" LSID_LSID="urn:lsid:cate-project.org:taxonconcepts:234" LSID_AUTHORITY="cate-project.org" LSID_NAMESPACE="taxonconcepts" LSID_OBJECT="234"/>
+ <TAXONBASE_AUD DTYPE="Taxon" ID="3" REV="1026" REVTYPE="1" CREATED="2008-12-10 09:56:07.0" UUID="54e767ee-894e-4540-a758-f906ecb4e2d9" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Sphingidae Linnaeus, 1758 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="3" SEC_ID="2" TAXONOMICCHILDRENCOUNT="204" TAXONSTATUSUNKNOWN="false" LSID_LSID="urn:lsid:cate-project.org:taxonconcepts:234" LSID_AUTHORITY="cate-project.org" LSID_NAMESPACE="taxonconcepts" LSID_OBJECT="234"/>
<TAXONBASE_AUD DTYPE="Taxon" ID="4" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="ef96fafa-7750-4141-b31b-1ad1daab3e76" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Lathoe Fabricius, 1807 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="4" SEC_ID="2" TAXONOMICCHILDRENCOUNT="6" TAXONSTATUSUNKNOWN="false"/>
<TAXONBASE_AUD DTYPE="Taxon" ID="5" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="17233b5e-74e7-42fc-bc37-522684657ed4" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Smerinthus Latreille, 1802 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="5" SEC_ID="2" TAXONOMICCHILDRENCOUNT="15" TAXONSTATUSUNKNOWN="false"/>
<TAXONBASE_AUD DTYPE="Taxon" ID="6" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="b989a278-c414-49f7-9a10-7d784700e4c4" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Manduca Hübner, 1807 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="6" SEC_ID="2" TAXONOMICCHILDRENCOUNT="18" TAXONSTATUSUNKNOWN="false"/>
- <TAXONBASE_AUD DTYPE="Taxon" ID="7" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="15611343-6b11-487f-8233-4756a49a83e2" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Lepchina Oberthür, 1904 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="7" SEC_ID="2" TAXONOMICCHILDRENCOUNT="13"/>
+ <TAXONBASE_AUD DTYPE="Taxon" ID="7" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="15611343-6b11-487f-8233-4756a49a83e2" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Lepchina Oberthür, 1904 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="7" SEC_ID="2" TAXONOMICCHILDRENCOUNT="13" TAXONSTATUSUNKNOWN="false"/>
<TAXONBASE_AUD DTYPE="Taxon" ID="8" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="1489d3dd-71da-4b34-aa5a-d15fccb6bb22" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Smerinthus kindermannii Lederer, 1853 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="8" SEC_ID="2" TAXONOMICCHILDRENCOUNT="4" TAXONSTATUSUNKNOWN="false"/>
- <TAXONBASE_AUD DTYPE="Taxon" ID="9" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="900052b7-b69c-4e26-a8f0-01c215214c40" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Mimas Hübner, 1819 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="9" SEC_ID="2" TAXONOMICCHILDRENCOUNT="2"/>
+ <TAXONBASE_AUD DTYPE="Taxon" ID="9" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="900052b7-b69c-4e26-a8f0-01c215214c40" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Mimas Hübner, 1819 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="9" SEC_ID="2" TAXONOMICCHILDRENCOUNT="2" TAXONSTATUSUNKNOWN="false"/>
<TAXONBASE_AUD DTYPE="Taxon" ID="10" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="8e312b40-924f-46b7-8e8d-837f9ad12f51" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Callambulyx Rothschild & Jordan, 1903 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="10" SEC_ID="2" TAXONOMICCHILDRENCOUNT="9" TAXONSTATUSUNKNOWN="false"/>
<TAXONBASE_AUD DTYPE="Taxon" ID="11" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="53fac190-0b4b-44f5-b4e7-b1ca9a25a6e9" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Dolbina Staudinger, 1877 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="11" SEC_ID="2" TAXONOMICCHILDRENCOUNT="7" TAXONSTATUSUNKNOWN="false"/>
<TAXONBASE_AUD DTYPE="Taxon" ID="12" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="7748d6f0-04d8-4052-9904-c43f55682419" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Akbesia Rothschild & Jordan, 1903 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="12" SEC_ID="2" TAXONOMICCHILDRENCOUNT="1" TAXONSTATUSUNKNOWN="false"/>
<TAXONBASE_AUD DTYPE="Taxon" ID="15" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="c5cc8674-4242-49a4-aada-72d63194f5fa" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Acherontia Laspeyres, 1809 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="15" SEC_ID="2" TAXONOMICCHILDRENCOUNT="3" TAXONSTATUSUNKNOWN="false"/>
<TAXONBASE_AUD DTYPE="Taxon" ID="15" REV="1026" REVTYPE="2"/>
<TAXONBASE_AUD DTYPE="Taxon" ID="16" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="6ecc117a-3e9a-4030-8748-f63a0412e065" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Hemaris Dalman, 1816 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="16" SEC_ID="2" TAXONOMICCHILDRENCOUNT="23" TAXONSTATUSUNKNOWN="false"/>
- <TAXONBASE_AUD DTYPE="Taxon" ID="17" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="f6700b5b-b6dc-421a-b979-9429ffad8262" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Proserpinus Hübner, 1819 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="17" SEC_ID="2" TAXONOMICCHILDRENCOUNT="7"/>
+ <TAXONBASE_AUD DTYPE="Taxon" ID="17" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="f6700b5b-b6dc-421a-b979-9429ffad8262" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Proserpinus Hübner, 1819 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="17" SEC_ID="2" TAXONOMICCHILDRENCOUNT="7" TAXONSTATUSUNKNOWN="false"/>
<TAXONBASE_AUD DTYPE="Taxon" ID="18" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="b503efaf-b800-421b-beba-3c6fab4b3c34" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Sphingonaepiopsis Wallengren, 1858 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="18" SEC_ID="2" TAXONOMICCHILDRENCOUNT="7" TAXONSTATUSUNKNOWN="false"/>
<TAXONBASE_AUD DTYPE="Taxon" ID="19" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="a9f42927-e507-4fda-9629-62073a908aae" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Rethera Rothschild & Jordan, 1903 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="19" SEC_ID="2" TAXONOMICCHILDRENCOUNT="4" TAXONSTATUSUNKNOWN="false"/>
<TAXONBASE_AUD DTYPE="Taxon" ID="20" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="557ac748-90df-47a6-b6f4-92d7b1d53abb" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Daphnis Hübner, 1819 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="20" SEC_ID="2" TAXONOMICCHILDRENCOUNT="10" TAXONSTATUSUNKNOWN="false"/>
- <TAXONBASE_AUD DTYPE="Taxon" ID="21" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="c089d514-f599-4f5a-bc90-3a11176d0f76" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Clarina Tutt, 1903 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="21" SEC_ID="2" TAXONOMICCHILDRENCOUNT="2"/>
+ <TAXONBASE_AUD DTYPE="Taxon" ID="21" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="c089d514-f599-4f5a-bc90-3a11176d0f76" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Clarina Tutt, 1903 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="21" SEC_ID="2" TAXONOMICCHILDRENCOUNT="2" TAXONSTATUSUNKNOWN="false"/>
<TAXONBASE_AUD DTYPE="Taxon" ID="22" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="74ad1d5e-4f73-4e0d-a209-4bf07abd33fa" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Acosmeryx Boisduval, 1875 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="22" SEC_ID="2" TAXONOMICCHILDRENCOUNT="12" TAXONSTATUSUNKNOWN="false"/>
<TAXONBASE_AUD DTYPE="Taxon" ID="23" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="8ecb0dfa-31fd-4f5a-bb83-b897cda813db" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Macroglossum Scopoli, 1777 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="23" SEC_ID="2" TAXONOMICCHILDRENCOUNT="104" TAXONSTATUSUNKNOWN="false"/>
<TAXONBASE_AUD DTYPE="Taxon" ID="24" REV="1025" REVTYPE="0" CREATED="2008-12-10 09:56:07.0" UUID="3d2a3441-4602-405f-8ba7-0685d88d7235" UPDATED="2008-12-10 09:56:07.253" PROTECTEDTITLECACHE="true" TITLECACHE="Hyles Hübner, 1819 sec. cate-sphingidae.org" DOUBTFUL="false" USENAMECACHE="false" TAXONNAME_FK="24" SEC_ID="2" TAXONOMICCHILDRENCOUNT="31" TAXONSTATUSUNKNOWN="false"/>
--- /dev/null
+<?xml version='1.0' encoding='UTF-8'?>
+<dataset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../dataset.xsd">
+ <AUDITEVENT REVISIONNUMBER="1025" TIMESTAMP="1232914238974" UUID="a680fab4-365e-4765-b49e-768f2ee30cda"/>
+ <AUDITEVENT REVISIONNUMBER="1026" TIMESTAMP="1232914244116" UUID="afe8e761-8545-497b-9134-6a6791fc0b0d"/>
+</dataset>