/* * Copyright 2004-2009 the original author or authors. * * 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 org.compass.gps.device.jdbc; import java.sql.Connection; import java.sql.PreparedStatement; import org.compass.core.Compass; import org.compass.core.CompassDetachedHits; import org.compass.core.CompassTemplate; import org.compass.core.Resource; import org.compass.core.config.CompassConfiguration; import org.compass.core.config.CompassEnvironment; import org.compass.core.util.FileHandlerMonitor; import org.compass.gps.device.jdbc.mapping.DataColumnToPropertyMapping; import org.compass.gps.device.jdbc.mapping.IdColumnToPropertyMapping; import org.compass.gps.device.jdbc.mapping.ResultSetToResourceMapping; import org.compass.gps.device.jdbc.mapping.VersionColumnMapping; import org.compass.gps.impl.SingleCompassGps; /** * @author kimchy */ public class ResultSetJdbcGpsDeviceTests extends AbstractJdbcGpsDeviceTests { protected Compass compass; private FileHandlerMonitor fileHandlerMonitor; protected CompassTemplate compassTemplate; private ResultSetJdbcGpsDevice gpsDevice; private SingleCompassGps gps; protected void tearDown() throws Exception { if (gps != null) { gps.stop(); } if (compass != null) { compass.close(); } fileHandlerMonitor.verifyNoHandlers(); super.tearDown(); } protected void setUpExactMappingNoMirror() throws Exception { // set up the database mappings, since they are used both to generate // the resource mappings and configure the jdbc gps device ResultSetToResourceMapping mapping = new ResultSetToResourceMapping(); mapping.setAlias("result-set"); mapping.setSelectQuery("select " + "p.id as parent_id, p.first_name as parent_first_name, p.last_name as parent_last_name, " + "c.id as child_id, c.first_name as child_first_name, c.last_name child_last_name " + "from parent p left join child c on p.id = c.parent_id"); mapping.addIdMapping(new IdColumnToPropertyMapping("parent_id", "parent_id")); mapping.addIdMapping(new IdColumnToPropertyMapping("child_id", "child_id")); mapping.addDataMapping(new DataColumnToPropertyMapping("parent_first_name", "parent_first_name")); mapping.addDataMapping(new DataColumnToPropertyMapping("parent_first_name", "first_name")); mapping.addDataMapping(new DataColumnToPropertyMapping("child_first_name", "child_first_name")); mapping.addDataMapping(new DataColumnToPropertyMapping("child_first_name", "first_name")); CompassConfiguration conf = new CompassConfiguration().setSetting(CompassEnvironment.CONNECTION, "target/test-index"); conf.addMappingResolver(new ResultSetResourceMappingResolver(mapping, dataSource)); conf.getSettings().setBooleanSetting(CompassEnvironment.DEBUG, true); compass = conf.buildCompass(); fileHandlerMonitor = FileHandlerMonitor.getFileHandlerMonitor(compass); fileHandlerMonitor.verifyNoHandlers(); compass.getSearchEngineIndexManager().deleteIndex(); compass.getSearchEngineIndexManager().verifyIndex(); compassTemplate = new CompassTemplate(compass); gpsDevice = new ResultSetJdbcGpsDevice(); gpsDevice.setDataSource(dataSource); gpsDevice.setName("resultSetJdbcDevice"); // setting up no mirroring, even though it should not mirror since we // mapped no version columns gpsDevice.setMirrorDataChanges(false); gpsDevice.addMapping(mapping); gps = new SingleCompassGps(compass); gps.addGpsDevice(gpsDevice); gps.start(); } public void testExactMappingNoMirror() throws Exception { setUpExactMappingNoMirror(); gps.index(); Resource r = compassTemplate.getResource("result-set", "1", "1"); assertNotNull(r.getProperty("parent_id")); assertNotNull(r.getProperty("parent_first_name")); assertNotNull(r.getProperty("child_id")); assertNotNull(r.getProperty("child_first_name")); assertNotNull(r.getProperty("first_name")); assertNull(r.getProperty("ID")); assertNull(r.getProperty("FIRST_NAME")); assertNull(r.getProperty("LAST_NAME")); assertNotNull(r); r = compassTemplate.getResource("result-set", "4", "6"); assertNotNull(r); CompassDetachedHits hits = compassTemplate.findWithDetach("parent"); assertEquals(6, hits.getLength()); } protected void setUpUnmappedMappingNoMirror() throws Exception { // set up the database mappings, since they are used both to generate // the resource mappings and configure the jdbc gps device ResultSetToResourceMapping mapping = new ResultSetToResourceMapping("result-set", "select * from parent p left join child c on p.id = c.parent_id"); mapping.setIndexUnMappedColumns(true); mapping.addIdMapping(new IdColumnToPropertyMapping(1, "parent_id")); mapping.addIdMapping(new IdColumnToPropertyMapping(5, "child_id")); mapping.addDataMapping(new DataColumnToPropertyMapping(2, "parent_first_name")); mapping.addDataMapping(new DataColumnToPropertyMapping(7, "child_first_name")); CompassConfiguration conf = new CompassConfiguration().setSetting(CompassEnvironment.CONNECTION, "target/test-index"); conf.addMappingResolver(new ResultSetResourceMappingResolver(mapping, this.dataSource)); conf.getSettings().setBooleanSetting(CompassEnvironment.DEBUG, true); compass = conf.buildCompass(); fileHandlerMonitor = FileHandlerMonitor.getFileHandlerMonitor(compass); fileHandlerMonitor.verifyNoHandlers(); compass.getSearchEngineIndexManager().deleteIndex(); compass.getSearchEngineIndexManager().verifyIndex(); compassTemplate = new CompassTemplate(compass); gpsDevice = new ResultSetJdbcGpsDevice(); gpsDevice.setDataSource(dataSource); gpsDevice.setName("resultSetJdbcDevice"); // it should not mirror the data since we did not mapped any version // columns gpsDevice.setMirrorDataChanges(true); gpsDevice.addMapping(mapping); gps = new SingleCompassGps(compass); gps.addGpsDevice(gpsDevice); gps.start(); } public void testUnmappedMappingNoMirror() throws Exception { setUpUnmappedMappingNoMirror(); gps.index(); Resource r = compassTemplate.getResource("result-set", "1", "1"); assertNotNull(r); assertNotNull(r.getProperty("parent_id")); assertNotNull(r.getProperty("parent_first_name")); assertNotNull(r.getProperty("child_id")); assertNotNull(r.getProperty("child_first_name")); assertNotNull(r.getProperty("LAST_NAME")); assertNull(r.getProperty("FIRST_NAME")); r = compassTemplate.getResource("result-set", "4", "6"); assertNotNull(r); CompassDetachedHits hits = compassTemplate.findWithDetach("parent"); assertEquals(6, hits.getLength()); } protected void setUpExactMappingWithMirror() throws Exception { // set up the database mappings, since they are used both to generate // the resource mappings and configure the jdbc gps device ResultSetToResourceMapping mapping = new ResultSetToResourceMapping(); mapping.setAlias("result-set"); mapping .setSelectQuery("select " + "p.id as parent_id, p.first_name as parent_first_name, p.last_name as parent_last_name, p.version as parent_version, " + "COALESCE(c.id, 0) as child_id, c.first_name as child_first_name, c.last_name child_last_name, COALESCE(c.version, 0) as child_version " + "from parent p left join child c on p.id = c.parent_id"); mapping .setVersionQuery("select p.id as parent_id, COALESCE(c.id, 0) as child_id, p.version as parent_version, COALESCE(c.version, 0) as child_version from parent p left join child c on p.id = c.parent_id"); mapping.addIdMapping(new IdColumnToPropertyMapping("parent_id", "parent_id", "p.id")); mapping.addIdMapping(new IdColumnToPropertyMapping("child_id", "child_id", "COALESCE(c.id, 0)")); mapping.addDataMapping(new DataColumnToPropertyMapping("parent_first_name", "parent_first_name")); mapping.addDataMapping(new DataColumnToPropertyMapping("child_first_name", "child_first_name")); mapping.addVersionMapping(new VersionColumnMapping("parent_version")); mapping.addVersionMapping(new VersionColumnMapping("child_version")); CompassConfiguration conf = new CompassConfiguration().setSetting(CompassEnvironment.CONNECTION, "target/testindex"); conf.addMappingResolver(new ResultSetResourceMappingResolver(mapping, this.dataSource)); conf.getSettings().setBooleanSetting(CompassEnvironment.DEBUG, true); compass = conf.buildCompass(); fileHandlerMonitor = FileHandlerMonitor.getFileHandlerMonitor(compass); fileHandlerMonitor.verifyNoHandlers(); compass.getSearchEngineIndexManager().deleteIndex(); compass.getSearchEngineIndexManager().verifyIndex(); compassTemplate = new CompassTemplate(compass); gpsDevice = new ResultSetJdbcGpsDevice(); gpsDevice.setDataSource(dataSource); gpsDevice.setName("resultSetJdbcDevice"); gpsDevice.setMirrorDataChanges(true); gpsDevice.addMapping(mapping); gps = new SingleCompassGps(compass); gps.addGpsDevice(gpsDevice); gps.start(); } public void testExactMappingWithMirrorMockEvent() throws Exception { setUpExactMappingWithMirror(); MockSnapshotEventListener eventListener = new MockSnapshotEventListener(); gpsDevice.setSnapshotEventListener(eventListener); gps.index(); compassTemplate.loadResource("result-set", "1", "1"); Resource r = compassTemplate.getResource("result-set", "4", "6"); assertNotNull(r); CompassDetachedHits hits = compassTemplate.findWithDetach("parent"); assertEquals(6, hits.getLength()); eventListener.clear(); gpsDevice.performMirroring(); assertFalse(eventListener.isCreateAndUpdateCalled()); assertFalse(eventListener.isDeleteCalled()); // test that create works Connection con = JdbcUtils.getConnection(dataSource); PreparedStatement ps = con .prepareStatement("INSERT INTO parent VALUES (999, 'parent first 999', 'last 999', 1);"); ps.execute(); ps.close(); con.commit(); con.close(); eventListener.clear(); gpsDevice.performMirroring(); assertTrue(eventListener.isCreateAndUpdateCalled()); assertTrue(eventListener.isCreateHappen()); assertFalse(eventListener.isUpdateHappen()); assertFalse(eventListener.isDeleteCalled()); // test that update parent works con = JdbcUtils.getConnection(dataSource); ps = con.prepareStatement("update parent set first_name = 'new first name', version = 2 where id = 1"); ps.execute(); ps.close(); con.commit(); con.close(); eventListener.clear(); gpsDevice.performMirroring(); assertTrue(eventListener.isCreateAndUpdateCalled()); assertTrue(eventListener.isUpdateHappen()); assertFalse(eventListener.isCreateHappen()); assertFalse(eventListener.isDeleteCalled()); // test that update child works con = JdbcUtils.getConnection(dataSource); ps = con.prepareStatement("update child set first_name = 'new first name', version = 2 where id = 1"); ps.execute(); ps.close(); con.commit(); con.close(); eventListener.clear(); gpsDevice.performMirroring(); assertTrue(eventListener.isCreateAndUpdateCalled()); assertTrue(eventListener.isUpdateHappen()); assertFalse(eventListener.isCreateHappen()); assertFalse(eventListener.isDeleteCalled()); // test that delete works con = JdbcUtils.getConnection(dataSource); ps = con.prepareStatement("delete from parent where id = 999"); ps.execute(); ps.close(); con.commit(); con.close(); eventListener.clear(); gpsDevice.performMirroring(); assertTrue(eventListener.isDeleteCalled()); assertTrue(eventListener.isDeleteHappen()); assertFalse(eventListener.isCreateAndUpdateCalled()); eventListener.clear(); gpsDevice.performMirroring(); assertFalse(eventListener.isCreateAndUpdateCalled()); assertFalse(eventListener.isDeleteCalled()); } public void testExactMappingWithMirror() throws Exception { setUpExactMappingWithMirror(); gps.index(); compassTemplate.loadResource("result-set", "1", "1"); Resource r = compassTemplate.getResource("result-set", "4", "6"); assertNotNull(r); CompassDetachedHits hits = compassTemplate.findWithDetach("parent"); assertEquals(6, hits.getLength()); // test that create works Connection con = JdbcUtils.getConnection(dataSource); PreparedStatement ps = con .prepareStatement("INSERT INTO parent VALUES (999, 'parent first 999', 'last 999', 1);"); ps.execute(); ps.close(); con.commit(); con.close(); r = compassTemplate.getResource("result-set", "999", "0"); assertNull(r); gpsDevice.performMirroring(); compassTemplate.loadResource("result-set", "999", "0"); // test that update works con = JdbcUtils.getConnection(dataSource); ps = con.prepareStatement("update parent set first_name = 'new first name', version = 2 where id = 1"); ps.execute(); ps.close(); con.commit(); con.close(); gpsDevice.performMirroring(); r = compassTemplate.loadResource("result-set", "1", "1"); assertEquals("new first name", r.getValue("parent_first_name")); // test that delete works con = JdbcUtils.getConnection(dataSource); ps = con.prepareStatement("delete from parent where id = 999"); ps.execute(); ps.close(); con.commit(); con.close(); gpsDevice.performMirroring(); r = compassTemplate.getResource("result-set", "999", "0"); assertNull(r); } }