/*
* #!
* Ontopia DB2TM
* #-
* Copyright (C) 2001 - 2013 The Ontopia Project
* #-
* 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 net.ontopia.topicmaps.db2tm;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.Statement;
import net.ontopia.topicmaps.impl.basic.InMemoryTopicMapStore;
import net.ontopia.topicmaps.utils.ltm.LTMTopicMapWriter;
import net.ontopia.infoset.core.LocatorIF;
import net.ontopia.persistence.proxy.ConnectionFactoryIF;
import net.ontopia.persistence.proxy.DefaultConnectionFactory;
import net.ontopia.topicmaps.core.TopicMapIF;
import net.ontopia.topicmaps.core.TopicMapStoreIF;
import net.ontopia.topicmaps.xml.CanonicalXTMWriter;
import net.ontopia.utils.FileUtils;
import net.ontopia.utils.PropertyUtils;
import net.ontopia.utils.StreamUtils;
import net.ontopia.utils.TestFileUtils;
import net.ontopia.utils.URIUtils;
import org.junit.Test;
import org.junit.Assert;
public class JDBCDataSourceTest {
private static final boolean DEBUG_LTM = false; // keep off in CVS
// NOTE: these are hardcoded for the time being
String propfile = "classpath:db2tm.h2.props";
private final static String testdataDirectory = "db2tm";
/* Disabled: 'Wrong change type' for row 4. Also fails in trunk.
* Update and re-enabled after test is fixed in trunk.
@Test
public void testReaders() throws Exception {
ConnectionFactoryIF cf = new DefaultConnectionFactory(PropertyUtils.loadProperties(StreamUtils.getInputStream(propfile)), false);
Connection conn = cf.requestConnection();
try {
// create tables
Statement stm = conn.createStatement();
stm.executeUpdate("drop table if exists jdst");
stm.executeUpdate("drop table if exists jdst_changes");
stm.executeUpdate("create table jdst (a integer, b varchar, c integer, d date)");
stm.executeUpdate("create table jdst_changes (a integer, b varchar, c integer, d date, ct varchar, cd integer)");
// insert rows
stm.executeUpdate("insert into jdst (a,b,c,d) values (1,'a',10, date '2007-01-01')");
stm.executeUpdate("insert into jdst (a,b,c,d) values (2,'b',20, date '2007-01-02')");
stm.executeUpdate("insert into jdst (a,b,c,d) values (3,'c',30, date '2007-01-03')");
stm.executeUpdate("insert into jdst (a,b,c,d) values (4,'d',40, date '2007-01-04')");
conn.commit();
// read mapping
RelationMapping mapping = RelationMapping.readFromClasspath("net/ontopia/topicmaps/db2tm/JDBCDataSourceTest-readers.xml");
JDBCDataSource ds = (JDBCDataSource)mapping.getDataSource("jdbc");
Relation relation = mapping.getRelation("jdst");
// test tuple reader
TupleReaderIF reader = ds.getReader("jdst");
String [] tuple;
tuple = reader.readNext();
Assert.assertTrue("Row 1 not equals to " + Arrays.asList(tuple), Arrays.equals(tuple, new String[] {"1", "a", "10", "2007-01-01"}));
tuple = reader.readNext();
Assert.assertTrue("Row 2 not equals to " + Arrays.asList(tuple), Arrays.equals(tuple, new String[] {"2", "b", "20", "2007-01-02"}));
tuple = reader.readNext();
Assert.assertTrue("Row 3 not equals to " + Arrays.asList(tuple), Arrays.equals(tuple, new String[] {"3", "c", "30", "2007-01-03"}));
tuple = reader.readNext();
Assert.assertTrue("Row 4 not equals to " + Arrays.asList(tuple), Arrays.equals(tuple, new String[] {"4", "d", "40", "2007-01-04"}));
tuple = reader.readNext();
Assert.assertTrue("Row 5 does exist", tuple == null);
reader.close();
stm.executeUpdate("delete from jdst where a = 3");
stm.executeUpdate("update jdst set b = 'e' where a = 4");
stm.executeUpdate("insert into jdst_changes (a,b,c,d,ct,cd) values (1,'a',10, date '2007-01-01', 'a', 1)");
stm.executeUpdate("insert into jdst_changes (a,b,c,d,ct,cd) values (2,'b',20, date '2007-01-02', 'a', 2)");
stm.executeUpdate("insert into jdst_changes (a,b,c,d,ct,cd) values (2,'x',22, date '2007-01-02', 'x', 3)");
stm.executeUpdate("insert into jdst_changes (a,b,c,d,ct,cd) values (3,'c',30, date '2007-01-03', 'r', 4)");
stm.executeUpdate("insert into jdst_changes (a,b,c,d,ct,cd) values (4,'d',40, date '2007-01-04', 'a', 5)");
stm.executeUpdate("insert into jdst_changes (a,b,c,d,ct,cd) values (4,'e',40, date '2007-01-04', 'u', 6)");
conn.commit();
// test changelog reader
ChangelogReaderIF clreader = ds.getChangelogReader((Changelog)relation.getSyncs().iterator().next(), null);
tuple = clreader.readNext();
Assert.assertTrue("Row 1 not equals to " + Arrays.asList(tuple), Arrays.equals(tuple, new String[] {"1", "a", "10", "2007-01-01"}));
Assert.assertTrue("Wrong change type", clreader.getChangeType() == ChangelogReaderIF.CHANGE_TYPE_CREATE);
Assert.assertTrue("Wrong order value", clreader.getOrderValue().equals("1"));
tuple = clreader.readNext();
Assert.assertTrue("Row 2 not equals to " + Arrays.asList(tuple), Arrays.equals(tuple, new String[] {"2", "b", "20", "2007-01-02"}));
Assert.assertTrue("Wrong change type", clreader.getChangeType() == ChangelogReaderIF.CHANGE_TYPE_CREATE);
Assert.assertTrue("Wrong order value", clreader.getOrderValue().equals("2"));
tuple = clreader.readNext();
Assert.assertTrue("Row 3 not equals to " + Arrays.asList(tuple), Arrays.equals(tuple, new String[] {"3", null, null, null}));
Assert.assertTrue("Wrong change type", clreader.getChangeType() == ChangelogReaderIF.CHANGE_TYPE_DELETE);
Assert.assertTrue("Wrong order value", clreader.getOrderValue().equals("4"));
tuple = clreader.readNext();
Assert.assertTrue("Row 4 not equals to " + Arrays.asList(tuple), Arrays.equals(tuple, new String[] {"4", "e", "40", "2007-01-04"}));
Assert.assertTrue("Wrong change type", clreader.getChangeType() == ChangelogReaderIF.CHANGE_TYPE_UPDATE);
Assert.assertTrue("Wrong order value", clreader.getOrderValue().equals("6"));
tuple = clreader.readNext();
Assert.assertTrue("Row 5 does exist", tuple == null);
clreader.close();
stm.executeUpdate("insert into jdst (a,b,c,d) values (5,'f',50, date '2007-01-05')");
stm.executeUpdate("insert into jdst_changes (a,b,c,d,ct,cd) values (5,'f',50, date '2007-01-05', 'a', 7)");
conn.commit();
// test changelog reader with start value
clreader = ds.getChangelogReader((Changelog)relation.getSyncs().iterator().next(), "4");
tuple = clreader.readNext();
Assert.assertTrue("Row 1 not equals to " + Arrays.asList(tuple), Arrays.equals(tuple, new String[] {"4", "e", "40", "2007-01-04"}));
Assert.assertTrue("Wrong change type", clreader.getChangeType() == ChangelogReaderIF.CHANGE_TYPE_UPDATE);
Assert.assertTrue("Wrong order value", clreader.getOrderValue().equals("6"));
tuple = clreader.readNext();
Assert.assertTrue("Row 2 not equals to " + Arrays.asList(tuple), Arrays.equals(tuple, new String[] {"5", "f", "50", "2007-01-05"}));
Assert.assertTrue("Wrong change type", clreader.getChangeType() == ChangelogReaderIF.CHANGE_TYPE_CREATE);
Assert.assertTrue("Wrong order value", clreader.getOrderValue().equals("7"));
tuple = clreader.readNext();
Assert.assertTrue("Row 3 does exist", tuple == null);
clreader.close();
mapping.close();
// delete tables
stm.executeUpdate("drop table jdst");
stm.executeUpdate("drop table jdst_changes");
stm.close();
conn.commit();
} catch (Exception e) {
conn.rollback();
throw e;
} finally {
conn.close();
}
}
*/
@Test
public void testSecondary() throws Exception {
ConnectionFactoryIF cf = new DefaultConnectionFactory(PropertyUtils.loadProperties(StreamUtils.getInputStream(propfile)), false);
Connection conn = cf.requestConnection();
try {
// create tables
Statement stm = conn.createStatement();
stm.executeUpdate("drop table if exists first");
stm.executeUpdate("drop table if exists first_changes");
stm.executeUpdate("drop table if exists second");
stm.executeUpdate("drop table if exists second_changes");
stm.executeUpdate("create table first (a integer, b varchar, c integer, d date)");
stm.executeUpdate("create table first_changes (a integer, b varchar, c integer, d date, ct varchar, cd integer)");
stm.executeUpdate("create table second (a integer, b varchar, c integer, d date)");
stm.executeUpdate("create table second_changes (a integer, b varchar, c integer, d date, ct varchar, cd integer)");
// insert rows
stm.executeUpdate("insert into first (a,b,c,d) values (1,'a',10, date '2007-01-01')");
stm.executeUpdate("insert into first (a,b,c,d) values (2,'b',20, date '2007-01-02')");
stm.executeUpdate("insert into first (a,b,c,d) values (3,'c',30, date '2007-01-03')");
stm.executeUpdate("insert into first (a,b,c,d) values (4,'d',40, date '2007-01-04')");
stm.executeUpdate("insert into second (a,b,c,d) values (1,'e',50, date '2007-02-01')");
stm.executeUpdate("insert into second (a,b,c,d) values (2,'f',60, date '2007-02-02')");
stm.executeUpdate("insert into second (a,b,c,d) values (3,'g',70, date '2007-02-03')");
stm.executeUpdate("insert into second (a,b,c,d) values (4,'h',80, date '2007-02-04')");
conn.commit();
// read mapping
RelationMapping mapping = RelationMapping.readFromClasspath("net/ontopia/topicmaps/db2tm/JDBCDataSourceTest-secondary.xml");
TopicMapStoreIF store = new InMemoryTopicMapStore();
LocatorIF baseloc = URIUtils.getURILocator("base:foo");
store.setBaseAddress(baseloc);
TopicMapIF topicmap = store.getTopicMap();
// add relations
Processor.addRelations(mapping, null, topicmap, baseloc);
exportTopicMap(topicmap, "after-first-sync");
stm.executeUpdate("insert into second_changes (a,b,c,d,ct,cd) values (2,'f',60,date '2007-02-02', 'r', 2)");
stm.executeUpdate("delete from second where a = 2");
conn.commit();
// synchronize relations
Processor.synchronizeRelations(mapping, null, topicmap, baseloc);
exportTopicMap(topicmap, "after-second-sync");
mapping.close();
// delete tables
stm.executeUpdate("drop table first");
stm.executeUpdate("drop table first_changes");
stm.executeUpdate("drop table second");
stm.executeUpdate("drop table second_changes");
stm.close();
store.close();
conn.commit();
} catch (Exception e) {
conn.rollback();
throw e;
} finally {
conn.close();
}
}
private void exportTopicMap(TopicMapIF topicmap, String name) throws IOException {
File cxtm = TestFileUtils.getTestOutputFile(testdataDirectory, "out", name + ".cxtm");
String baseline = TestFileUtils.getTestInputFile(testdataDirectory, "baseline", name + ".cxtm");
// Export the result topic map to ltm, for manual inspection purposes.
if (DEBUG_LTM) {
File ltm = TestFileUtils.getTestOutputFile(testdataDirectory, "out", name + ".ltm");
(new LTMTopicMapWriter(new FileOutputStream(ltm))).write(topicmap);
}
// Export the result topic map to cxtm
(new CanonicalXTMWriter(new FileOutputStream(cxtm))).write(topicmap);
// Check that the cxtm output matches the baseline.
Assert.assertTrue("The canonicalized conversion from " + name
+ " does not match the baseline.",
FileUtils.compareFileToResource(cxtm, baseline));
}
}