1f7cf3d52SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3f7cf3d52SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4f7cf3d52SAndrew Rist * or more contributor license agreements. See the NOTICE file 5f7cf3d52SAndrew Rist * distributed with this work for additional information 6f7cf3d52SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7f7cf3d52SAndrew Rist * to you under the Apache License, Version 2.0 (the 8f7cf3d52SAndrew Rist * "License"); you may not use this file except in compliance 9f7cf3d52SAndrew Rist * with the License. You may obtain a copy of the License at 10f7cf3d52SAndrew Rist * 11f7cf3d52SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12f7cf3d52SAndrew Rist * 13f7cf3d52SAndrew Rist * Unless required by applicable law or agreed to in writing, 14f7cf3d52SAndrew Rist * software distributed under the License is distributed on an 15f7cf3d52SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16f7cf3d52SAndrew Rist * KIND, either express or implied. See the License for the 17f7cf3d52SAndrew Rist * specific language governing permissions and limitations 18f7cf3d52SAndrew Rist * under the License. 19f7cf3d52SAndrew Rist * 20f7cf3d52SAndrew Rist *************************************************************/ 21f7cf3d52SAndrew Rist 22f7cf3d52SAndrew Rist 23cdf0e10cSrcweir package complex.dbaccess; 24cdf0e10cSrcweir 25cdf0e10cSrcweir import com.sun.star.beans.PropertyVetoException; 26cdf0e10cSrcweir import com.sun.star.beans.UnknownPropertyException; 27cdf0e10cSrcweir import com.sun.star.beans.XPropertySet; 28cdf0e10cSrcweir import com.sun.star.container.XIndexAccess; 29cdf0e10cSrcweir import com.sun.star.lang.WrappedTargetException; 30cdf0e10cSrcweir import com.sun.star.lang.XComponent; 31cdf0e10cSrcweir import com.sun.star.sdb.CommandType; 32cdf0e10cSrcweir import com.sun.star.sdb.XParametersSupplier; 33cdf0e10cSrcweir import com.sun.star.sdb.XResultSetAccess; 34cdf0e10cSrcweir import com.sun.star.sdb.XRowSetApproveBroadcaster; 35cdf0e10cSrcweir import com.sun.star.sdbc.SQLException; 36cdf0e10cSrcweir import com.sun.star.sdbc.XParameters; 37cdf0e10cSrcweir import com.sun.star.sdbc.XPreparedStatement; 38cdf0e10cSrcweir import com.sun.star.sdbc.XResultSet; 39cdf0e10cSrcweir import com.sun.star.sdbc.XResultSetUpdate; 40cdf0e10cSrcweir import com.sun.star.sdbc.XRow; 41cdf0e10cSrcweir import com.sun.star.sdbc.XRowSet; 42cdf0e10cSrcweir import com.sun.star.sdbc.XRowUpdate; 43cdf0e10cSrcweir import com.sun.star.sdbcx.XColumnsSupplier; 44cdf0e10cSrcweir import com.sun.star.sdbcx.XDeleteRows; 45cdf0e10cSrcweir import com.sun.star.sdbcx.XRowLocate; 46cdf0e10cSrcweir import com.sun.star.uno.UnoRuntime; 47cdf0e10cSrcweir 48cdf0e10cSrcweir import connectivity.tools.CRMDatabase; 49cdf0e10cSrcweir import connectivity.tools.DataSource; 50cdf0e10cSrcweir import connectivity.tools.HsqlDatabase; 51cdf0e10cSrcweir import connectivity.tools.sdb.Connection; 52cdf0e10cSrcweir import java.lang.reflect.Method; 53cdf0e10cSrcweir import java.util.Random; 54cdf0e10cSrcweir 55cdf0e10cSrcweir // ---------- junit imports ----------------- 56cdf0e10cSrcweir import org.junit.Test; 57cdf0e10cSrcweir import static org.junit.Assert.*; 58cdf0e10cSrcweir // ------------------------------------------ 59cdf0e10cSrcweir 60cdf0e10cSrcweir public class RowSet extends TestCase 61cdf0e10cSrcweir { 62cdf0e10cSrcweir 63cdf0e10cSrcweir static final int MAX_TABLE_ROWS = 100; 64cdf0e10cSrcweir static final int MAX_FETCH_ROWS = 10; 65cdf0e10cSrcweir private static final String NEXT = "next"; 66cdf0e10cSrcweir private static final String TEST21 = "Test21"; 67cdf0e10cSrcweir HsqlDatabase m_database; 68cdf0e10cSrcweir DataSource m_dataSource; 69cdf0e10cSrcweir XRowSet m_rowSet; 70cdf0e10cSrcweir XResultSet m_resultSet; 71cdf0e10cSrcweir XResultSetUpdate m_resultSetUpdate; 72cdf0e10cSrcweir XRow m_row; 73cdf0e10cSrcweir XRowLocate m_rowLocate; 74cdf0e10cSrcweir XPropertySet m_rowSetProperties; 75cdf0e10cSrcweir XParametersSupplier m_paramsSupplier; 76cdf0e10cSrcweir 77cdf0e10cSrcweir // -------------------------------------------------------------------------------------------------------- 78cdf0e10cSrcweir class ResultSetMovementStress implements Runnable 79cdf0e10cSrcweir { 80cdf0e10cSrcweir 81cdf0e10cSrcweir XResultSet m_resultSet; 82cdf0e10cSrcweir XRow m_row; 83cdf0e10cSrcweir int m_id; 84cdf0e10cSrcweir ResultSetMovementStress(XResultSet _resultSet, int _id)85cdf0e10cSrcweir ResultSetMovementStress(XResultSet _resultSet, int _id) throws java.lang.Exception 86cdf0e10cSrcweir { 87cdf0e10cSrcweir m_resultSet = _resultSet; 88cdf0e10cSrcweir m_row = UnoRuntime.queryInterface( XRow.class, m_resultSet ); 89cdf0e10cSrcweir m_id = _id; 90cdf0e10cSrcweir } 91cdf0e10cSrcweir run()92cdf0e10cSrcweir public void run() 93cdf0e10cSrcweir { 94cdf0e10cSrcweir try 95cdf0e10cSrcweir { 96cdf0e10cSrcweir m_resultSet.beforeFirst(); 97cdf0e10cSrcweir for (int i = 0; m_resultSet.next(); ++i) 98cdf0e10cSrcweir { 99cdf0e10cSrcweir int pos = m_resultSet.getRow(); 100cdf0e10cSrcweir // final int val = m_row.getInt(1); 101cdf0e10cSrcweir // System.out.println("Clone Move(" + m_id +") before i: " + (i+1) + " Pos: " + pos + " Val: " + val); 102cdf0e10cSrcweir testPosition(m_resultSet, m_row, i + 1, "clone move(" + m_id + ")"); 103cdf0e10cSrcweir // val = m_row.getInt(1); 104cdf0e10cSrcweir // System.out.println("Clone Move(" + m_id +") after i: " + (i+1) + " Pos: " + pos + " Val: " + val); 105cdf0e10cSrcweir int pos2 = m_resultSet.getRow(); 106cdf0e10cSrcweir assertTrue("ResultSetMovementStress wrong position: " + i + " Pos1: " + pos + " Pos2: " + pos2, pos == pos2); 107cdf0e10cSrcweir } 108cdf0e10cSrcweir } 109cdf0e10cSrcweir catch (Exception e) 110cdf0e10cSrcweir { 111cdf0e10cSrcweir fail("ResultSetMovementStress(" + m_id + ") failed: " + e); 112cdf0e10cSrcweir } 113cdf0e10cSrcweir } 114cdf0e10cSrcweir } 115cdf0e10cSrcweir // -------------------------------------------------------------------------------------------------------- createTestCase(boolean _defaultRowSet)116cdf0e10cSrcweir private void createTestCase(boolean _defaultRowSet) 117cdf0e10cSrcweir { 118cdf0e10cSrcweir if (m_database == null) 119cdf0e10cSrcweir { 120cdf0e10cSrcweir try 121cdf0e10cSrcweir { 122cdf0e10cSrcweir final CRMDatabase database = new CRMDatabase( getMSF(), false ); 123cdf0e10cSrcweir m_database = database.getDatabase(); 124cdf0e10cSrcweir m_dataSource = m_database.getDataSource(); 125cdf0e10cSrcweir } 126cdf0e10cSrcweir catch (Exception e) 127cdf0e10cSrcweir { 128cdf0e10cSrcweir fail("could not create the embedded HSQL database: " + e.getMessage()); 129cdf0e10cSrcweir } 130cdf0e10cSrcweir } 131cdf0e10cSrcweir 132cdf0e10cSrcweir try 133cdf0e10cSrcweir { 134cdf0e10cSrcweir createStruture(); 135cdf0e10cSrcweir } 136cdf0e10cSrcweir catch (SQLException e) 137cdf0e10cSrcweir { 138cdf0e10cSrcweir fail("could not connect to the database/table structure, error message:\n" + e.getMessage()); 139cdf0e10cSrcweir } 140cdf0e10cSrcweir 141cdf0e10cSrcweir if (_defaultRowSet) 142cdf0e10cSrcweir { 143cdf0e10cSrcweir createRowSet("TEST1", CommandType.TABLE, true, true); 144cdf0e10cSrcweir } 145cdf0e10cSrcweir } 146cdf0e10cSrcweir 147cdf0e10cSrcweir // -------------------------------------------------------------------------------------------------------- 148cdf0e10cSrcweir /** creates a com.sun.star.sdb.RowSet to use during the test 149cdf0e10cSrcweir * @param command 150cdf0e10cSrcweir * the command to use for the RowSet 151cdf0e10cSrcweir * @param commandType 152cdf0e10cSrcweir * the command type to use for the RowSet 153cdf0e10cSrcweir * @param execute 154cdf0e10cSrcweir * determines whether the RowSet should be executed 155cdf0e10cSrcweir */ createRowSet(String command, int commandType, boolean execute)156cdf0e10cSrcweir private void createRowSet(String command, int commandType, boolean execute) 157cdf0e10cSrcweir { 158cdf0e10cSrcweir createRowSet(command, commandType, execute, false); 159cdf0e10cSrcweir } 160cdf0e10cSrcweir 161cdf0e10cSrcweir // -------------------------------------------------------------------------------------------------------- 162cdf0e10cSrcweir /** creates a com.sun.star.sdb.RowSet to use during the test 163cdf0e10cSrcweir * @param command 164cdf0e10cSrcweir * the command to use for the RowSet 165cdf0e10cSrcweir * @param commandType 166cdf0e10cSrcweir * the command type to use for the RowSet 167cdf0e10cSrcweir * @param limitFetchSize 168cdf0e10cSrcweir * determines whether the fetch size of the RowSet should be limited to MAX_FETCH_ROWS 169cdf0e10cSrcweir * @param execute 170cdf0e10cSrcweir * determines whether the RowSet should be executed 171cdf0e10cSrcweir */ createRowSet(String command, int commandType, boolean execute, boolean limitFetchSize)172cdf0e10cSrcweir private void createRowSet(String command, int commandType, boolean execute, boolean limitFetchSize) 173cdf0e10cSrcweir { 174cdf0e10cSrcweir try 175cdf0e10cSrcweir { 176cdf0e10cSrcweir m_rowSet = UnoRuntime.queryInterface( XRowSet.class, getMSF().createInstance( "com.sun.star.sdb.RowSet" ) ); 177cdf0e10cSrcweir final XPropertySet rowSetProperties = UnoRuntime.queryInterface( XPropertySet.class, m_rowSet ); 178cdf0e10cSrcweir rowSetProperties.setPropertyValue("Command", command); 179cdf0e10cSrcweir rowSetProperties.setPropertyValue("CommandType", Integer.valueOf(commandType)); 180cdf0e10cSrcweir rowSetProperties.setPropertyValue("ActiveConnection", m_database.defaultConnection().getXConnection()); 181cdf0e10cSrcweir if (limitFetchSize) 182cdf0e10cSrcweir { 183cdf0e10cSrcweir rowSetProperties.setPropertyValue("FetchSize", Integer.valueOf(MAX_FETCH_ROWS)); 184cdf0e10cSrcweir } 185cdf0e10cSrcweir 186cdf0e10cSrcweir m_resultSet = UnoRuntime.queryInterface( XResultSet.class, m_rowSet ); 187cdf0e10cSrcweir m_resultSetUpdate = UnoRuntime.queryInterface( XResultSetUpdate.class, m_rowSet ); 188cdf0e10cSrcweir m_row = UnoRuntime.queryInterface( XRow.class, m_rowSet ); 189cdf0e10cSrcweir m_rowLocate = UnoRuntime.queryInterface( XRowLocate.class, m_resultSet ); 190cdf0e10cSrcweir m_rowSetProperties = UnoRuntime.queryInterface( XPropertySet.class, m_rowSet ); 191cdf0e10cSrcweir m_paramsSupplier = UnoRuntime.queryInterface( XParametersSupplier.class, m_rowSet ); 192cdf0e10cSrcweir 193cdf0e10cSrcweir if (execute) 194cdf0e10cSrcweir { 195cdf0e10cSrcweir m_rowSet.execute(); 196cdf0e10cSrcweir } 197cdf0e10cSrcweir } 198cdf0e10cSrcweir catch (Exception e) 199cdf0e10cSrcweir { 200cdf0e10cSrcweir fail("caught an exception while creating the RowSet. Type:\n" + e.getClass().toString() + "\nMessage:\n" + e.getMessage()); 201cdf0e10cSrcweir } 202cdf0e10cSrcweir } 203cdf0e10cSrcweir 204cdf0e10cSrcweir // -------------------------------------------------------------------------------------------------------- 205cdf0e10cSrcweir @Test testRowSet()206cdf0e10cSrcweir public void testRowSet() throws java.lang.Exception 207cdf0e10cSrcweir { 208cdf0e10cSrcweir 209cdf0e10cSrcweir System.out.println("testing testRowSet"); 210cdf0e10cSrcweir createTestCase(true); 211cdf0e10cSrcweir 212*300d4866SJohn Bampton // sequential positioning 213cdf0e10cSrcweir m_resultSet.beforeFirst(); 214cdf0e10cSrcweir testSequentialPositining(m_resultSet, m_row); 215cdf0e10cSrcweir 216cdf0e10cSrcweir // absolute positioning 217cdf0e10cSrcweir testAbsolutePositioning(m_resultSet, m_row); 218cdf0e10cSrcweir 219cdf0e10cSrcweir // 3rd test 220cdf0e10cSrcweir test3(createClone(), m_resultSet); 221cdf0e10cSrcweir // 4th test 222cdf0e10cSrcweir test4(m_resultSet); 223cdf0e10cSrcweir 224cdf0e10cSrcweir // concurrent (multi threaded) access to the row set and its clones 225cdf0e10cSrcweir testConcurrentAccess(m_resultSet); 226cdf0e10cSrcweir } 227cdf0e10cSrcweir 228cdf0e10cSrcweir // -------------------------------------------------------------------------------------------------------- createClone()229cdf0e10cSrcweir XResultSet createClone() throws SQLException 230cdf0e10cSrcweir { 231cdf0e10cSrcweir final XResultSetAccess rowAcc = UnoRuntime.queryInterface( XResultSetAccess.class, m_rowSet ); 232cdf0e10cSrcweir return rowAcc.createResultSet(); 233cdf0e10cSrcweir } 234cdf0e10cSrcweir 235cdf0e10cSrcweir // -------------------------------------------------------------------------------------------------------- createStruture()236cdf0e10cSrcweir void createStruture() throws SQLException 237cdf0e10cSrcweir { 238cdf0e10cSrcweir m_database.executeSQL("DROP TABLE \"TEST1\" IF EXISTS"); 239cdf0e10cSrcweir m_database.executeSQL("CREATE TABLE \"TEST1\" (\"ID\" integer not null primary key, \"col2\" varchar(50) )"); 240cdf0e10cSrcweir 241cdf0e10cSrcweir final Connection connection = m_database.defaultConnection(); 242cdf0e10cSrcweir final XPreparedStatement prep = connection.prepareStatement("INSERT INTO \"TEST1\" values (?,?)"); 243cdf0e10cSrcweir final XParameters para = UnoRuntime.queryInterface( XParameters.class, prep ); 244cdf0e10cSrcweir for (int i = 1; i <= MAX_TABLE_ROWS; ++i) 245cdf0e10cSrcweir { 246cdf0e10cSrcweir para.setInt(1, i); 247cdf0e10cSrcweir para.setString(2, "Test" + i); 248cdf0e10cSrcweir prep.executeUpdate(); 249cdf0e10cSrcweir } 250cdf0e10cSrcweir 251cdf0e10cSrcweir connection.refreshTables(); 252cdf0e10cSrcweir } 253cdf0e10cSrcweir 254cdf0e10cSrcweir // -------------------------------------------------------------------------------------------------------- testPosition(XResultSet m_resultSet, XRow m_row, int expectedValue, String location)255cdf0e10cSrcweir void testPosition(XResultSet m_resultSet, XRow m_row, int expectedValue, String location) throws SQLException 256cdf0e10cSrcweir { 257cdf0e10cSrcweir final int val = m_row.getInt(1); 258cdf0e10cSrcweir final int pos = m_resultSet.getRow(); 259cdf0e10cSrcweir assertTrue(location + ": value/position do not match: " + pos + " (pos) != " + val + " (val)", val == pos); 260cdf0e10cSrcweir assertTrue(location + ": value/position are not as expected: " + val + " (val) != " + expectedValue + " (expected)", val == expectedValue); 261cdf0e10cSrcweir } 262cdf0e10cSrcweir 263cdf0e10cSrcweir // -------------------------------------------------------------------------------------------------------- testSequentialPositining(XResultSet _resultSet, XRow _row)264cdf0e10cSrcweir void testSequentialPositining(XResultSet _resultSet, XRow _row) 265cdf0e10cSrcweir { 266cdf0e10cSrcweir try 267cdf0e10cSrcweir { 268cdf0e10cSrcweir // 1st test 269cdf0e10cSrcweir int i = 1; 270cdf0e10cSrcweir while (_resultSet.next()) 271cdf0e10cSrcweir { 272cdf0e10cSrcweir testPosition(_resultSet, _row, i, "testSequentialPositining"); 273cdf0e10cSrcweir ++i; 274cdf0e10cSrcweir } 275cdf0e10cSrcweir } 276cdf0e10cSrcweir catch (Exception e) 277cdf0e10cSrcweir { 278cdf0e10cSrcweir fail("testSequentialPositining failed: " + e); 279cdf0e10cSrcweir } 280cdf0e10cSrcweir } 281cdf0e10cSrcweir 282cdf0e10cSrcweir // -------------------------------------------------------------------------------------------------------- testAbsolutePositioning(XResultSet _resultSet, XRow _row)283cdf0e10cSrcweir void testAbsolutePositioning(XResultSet _resultSet, XRow _row) 284cdf0e10cSrcweir { 285cdf0e10cSrcweir try 286cdf0e10cSrcweir { 287cdf0e10cSrcweir for (int i = 1; i <= MAX_FETCH_ROWS; ++i) 288cdf0e10cSrcweir { 289cdf0e10cSrcweir final int calcPos = (MAX_TABLE_ROWS % i) + 1; 290cdf0e10cSrcweir assertTrue("testAbsolutePositioning failed", _resultSet.absolute(calcPos)); 291cdf0e10cSrcweir testPosition(_resultSet, _row, calcPos, "testAbsolutePositioning"); 292cdf0e10cSrcweir } 293cdf0e10cSrcweir } 294cdf0e10cSrcweir catch (Exception e) 295cdf0e10cSrcweir { 296cdf0e10cSrcweir fail("testAbsolutePositioning failed: " + e); 297cdf0e10cSrcweir } 298cdf0e10cSrcweir } 299cdf0e10cSrcweir 300cdf0e10cSrcweir // -------------------------------------------------------------------------------------------------------- test3(XResultSet clone, XResultSet _resultSet)301cdf0e10cSrcweir void test3(XResultSet clone, XResultSet _resultSet) 302cdf0e10cSrcweir { 303cdf0e10cSrcweir try 304cdf0e10cSrcweir { 305cdf0e10cSrcweir final XRow _row = UnoRuntime.queryInterface( XRow.class, _resultSet ); 306cdf0e10cSrcweir final XRow cloneRow = UnoRuntime.queryInterface( XRow.class, clone ); 307cdf0e10cSrcweir for (int i = 1; i <= MAX_FETCH_ROWS; ++i) 308cdf0e10cSrcweir { 309cdf0e10cSrcweir final int calcPos = (MAX_TABLE_ROWS % i) + 1; 310cdf0e10cSrcweir if (clone.absolute(calcPos)) 311cdf0e10cSrcweir { 312cdf0e10cSrcweir testPosition(clone, cloneRow, calcPos, "test3"); 313cdf0e10cSrcweir testAbsolutePositioning(_resultSet, _row); 314cdf0e10cSrcweir testAbsolutePositioning(clone, cloneRow); 315cdf0e10cSrcweir } 316cdf0e10cSrcweir } 317cdf0e10cSrcweir } 318cdf0e10cSrcweir catch (Exception e) 319cdf0e10cSrcweir { 320cdf0e10cSrcweir fail("test3 failed: " + e); 321cdf0e10cSrcweir } 322cdf0e10cSrcweir } 323cdf0e10cSrcweir 324cdf0e10cSrcweir // -------------------------------------------------------------------------------------------------------- test4(XResultSet _resultSet)325cdf0e10cSrcweir void test4(XResultSet _resultSet) 326cdf0e10cSrcweir { 327cdf0e10cSrcweir try 328cdf0e10cSrcweir { 329cdf0e10cSrcweir final XRow _row = UnoRuntime.queryInterface( XRow.class, _resultSet ); 330cdf0e10cSrcweir _resultSet.beforeFirst(); 331cdf0e10cSrcweir 332cdf0e10cSrcweir for (int i = 1; i <= MAX_TABLE_ROWS; ++i) 333cdf0e10cSrcweir { 334cdf0e10cSrcweir _resultSet.next(); 335cdf0e10cSrcweir final XResultSet clone = createClone(); 336cdf0e10cSrcweir final XRow cloneRow = UnoRuntime.queryInterface( XRow.class, clone ); 337cdf0e10cSrcweir final int calcPos = MAX_TABLE_ROWS - 1; 338cdf0e10cSrcweir if (calcPos != 0 && clone.absolute(calcPos)) 339cdf0e10cSrcweir { 340cdf0e10cSrcweir testPosition(clone, cloneRow, calcPos, "test4: clone"); 341cdf0e10cSrcweir testPosition(_resultSet, _row, i, "test4: rowset"); 342cdf0e10cSrcweir } 343cdf0e10cSrcweir } 344cdf0e10cSrcweir } 345cdf0e10cSrcweir catch (Exception e) 346cdf0e10cSrcweir { 347cdf0e10cSrcweir fail("test4 failed: " + e); 348cdf0e10cSrcweir } 349cdf0e10cSrcweir } 350cdf0e10cSrcweir 351cdf0e10cSrcweir // -------------------------------------------------------------------------------------------------------- testConcurrentAccess(XResultSet _resultSet)352cdf0e10cSrcweir void testConcurrentAccess(XResultSet _resultSet) 353cdf0e10cSrcweir { 354cdf0e10cSrcweir System.out.println("testing Thread"); 355cdf0e10cSrcweir try 356cdf0e10cSrcweir { 357cdf0e10cSrcweir // final XRow _row = (XRow)UnoRuntime.queryInterface(XRow.class,_resultSet); 358cdf0e10cSrcweir _resultSet.beforeFirst(); 359cdf0e10cSrcweir 360cdf0e10cSrcweir final int numberOfThreads = 10; 361cdf0e10cSrcweir 362cdf0e10cSrcweir final Thread threads[] = new Thread[numberOfThreads]; 363cdf0e10cSrcweir for (int i = 0; i < numberOfThreads; ++i) 364cdf0e10cSrcweir { 365cdf0e10cSrcweir threads[i] = new Thread(new ResultSetMovementStress(createClone(), i)); 366cdf0e10cSrcweir System.out.println("starting thread " + (i + 1) + " of " + (numberOfThreads)); 367cdf0e10cSrcweir threads[i].start(); 368cdf0e10cSrcweir } 369cdf0e10cSrcweir 370cdf0e10cSrcweir for (int i = 0; i < numberOfThreads; ++i) 371cdf0e10cSrcweir { 372cdf0e10cSrcweir threads[i].join(); 373cdf0e10cSrcweir } 374cdf0e10cSrcweir } 375cdf0e10cSrcweir catch (Exception e) 376cdf0e10cSrcweir { 377cdf0e10cSrcweir fail("testConcurrentAccess failed: " + e); 378cdf0e10cSrcweir } 379cdf0e10cSrcweir } 380cdf0e10cSrcweir // -------------------------------------------------------------------------------------------------------- 381cdf0e10cSrcweir 382cdf0e10cSrcweir @Test testRowSetEvents()383cdf0e10cSrcweir public void testRowSetEvents() throws java.lang.Exception 384cdf0e10cSrcweir { 385cdf0e10cSrcweir System.out.println("testing RowSet Events"); 386cdf0e10cSrcweir createTestCase(true); 387cdf0e10cSrcweir 388cdf0e10cSrcweir // first we create our RowSet object 389cdf0e10cSrcweir final RowSetEventListener pRow = new RowSetEventListener(); 390cdf0e10cSrcweir 391cdf0e10cSrcweir final XColumnsSupplier colSup = UnoRuntime.queryInterface( XColumnsSupplier.class, m_rowSet ); 392cdf0e10cSrcweir final XPropertySet col = UnoRuntime.queryInterface( XPropertySet.class, colSup.getColumns().getByName( "ID" ) ); 393cdf0e10cSrcweir col.addPropertyChangeListener("Value", pRow); 394cdf0e10cSrcweir m_rowSetProperties.addPropertyChangeListener("IsModified", pRow); 395cdf0e10cSrcweir m_rowSetProperties.addPropertyChangeListener("IsNew", pRow); 396cdf0e10cSrcweir m_rowSetProperties.addPropertyChangeListener("IsRowCountFinal", pRow); 397cdf0e10cSrcweir m_rowSetProperties.addPropertyChangeListener("RowCount", pRow); 398cdf0e10cSrcweir 399cdf0e10cSrcweir final XRowSetApproveBroadcaster xApBroad = UnoRuntime.queryInterface( XRowSetApproveBroadcaster.class, m_resultSet ); 400cdf0e10cSrcweir xApBroad.addRowSetApproveListener(pRow); 401cdf0e10cSrcweir m_rowSet.addRowSetListener(pRow); 402cdf0e10cSrcweir 403cdf0e10cSrcweir // do some movements to check if we got all notifications 404cdf0e10cSrcweir final Class cResSet = Class.forName("com.sun.star.sdbc.XResultSet"); 405cdf0e10cSrcweir final boolean moves[] = new boolean[9]; 406cdf0e10cSrcweir for (int i = 0; i < moves.length; ++i) 407cdf0e10cSrcweir { 408cdf0e10cSrcweir moves[i] = false; 409cdf0e10cSrcweir } 410cdf0e10cSrcweir moves[RowSetEventListener.APPROVE_CURSOR_MOVE] = true; 411cdf0e10cSrcweir moves[RowSetEventListener.COLUMN_VALUE] = true; 412cdf0e10cSrcweir moves[RowSetEventListener.CURSOR_MOVED] = true; 413cdf0e10cSrcweir moves[RowSetEventListener.IS_ROW_COUNT_FINAL] = true; 414cdf0e10cSrcweir moves[RowSetEventListener.ROW_COUNT] = true; 415cdf0e10cSrcweir 416cdf0e10cSrcweir testCursorMove(m_resultSet, cResSet.getMethod("afterLast", (Class[]) null), pRow, moves, null); 417cdf0e10cSrcweir 418cdf0e10cSrcweir moves[RowSetEventListener.IS_ROW_COUNT_FINAL] = false; 419cdf0e10cSrcweir moves[RowSetEventListener.ROW_COUNT] = false; 420cdf0e10cSrcweir testCursorMove(m_resultSet, cResSet.getMethod(NEXT, (Class[]) null), pRow, moves, null); 421cdf0e10cSrcweir testCursorMove(m_resultSet, cResSet.getMethod(NEXT, (Class[]) null), pRow, moves, null); 422cdf0e10cSrcweir testCursorMove(m_resultSet, cResSet.getMethod(NEXT, (Class[]) null), pRow, moves, null); 423cdf0e10cSrcweir testCursorMove(m_resultSet, cResSet.getMethod("last", (Class[]) null), pRow, moves, null); 424cdf0e10cSrcweir testCursorMove(m_resultSet, cResSet.getMethod(NEXT, (Class[]) null), pRow, moves, null); 425cdf0e10cSrcweir testCursorMove(m_resultSet, cResSet.getMethod("first", (Class[]) null), pRow, moves, null); 426cdf0e10cSrcweir testCursorMove(m_resultSet, cResSet.getMethod("previous", (Class[]) null), pRow, moves, null); 427cdf0e10cSrcweir testCursorMove(m_resultSet, cResSet.getMethod(NEXT, (Class[]) null), pRow, moves, null); 428cdf0e10cSrcweir moves[RowSetEventListener.IS_MODIFIED] = true; 429cdf0e10cSrcweir final XRowUpdate updRow = UnoRuntime.queryInterface( XRowUpdate.class, m_resultSet ); 430cdf0e10cSrcweir updRow.updateString(2, TEST21); 431cdf0e10cSrcweir testCursorMove(m_resultSet, cResSet.getMethod(NEXT, (Class[]) null), pRow, moves, null); 432cdf0e10cSrcweir 433cdf0e10cSrcweir moves[RowSetEventListener.IS_MODIFIED] = false; 434cdf0e10cSrcweir updRow.updateString(2, m_row.getString(2)); 435cdf0e10cSrcweir testCursorMove(m_resultSet, cResSet.getMethod(NEXT, (Class[]) null), pRow, moves, null); 436cdf0e10cSrcweir 437cdf0e10cSrcweir moves[RowSetEventListener.IS_MODIFIED] = false; 438cdf0e10cSrcweir final Class cupd = Class.forName("com.sun.star.sdbc.XResultSetUpdate"); 439cdf0e10cSrcweir final XResultSetUpdate upd = UnoRuntime.queryInterface( XResultSetUpdate.class, m_resultSet ); 440cdf0e10cSrcweir testCursorMove(upd, cupd.getMethod("moveToInsertRow", (Class[]) null), pRow, moves, null); 441cdf0e10cSrcweir 442cdf0e10cSrcweir updRow.updateInt(1, MAX_TABLE_ROWS + 2); 443cdf0e10cSrcweir updRow.updateString(2, "HHHH"); 444cdf0e10cSrcweir moves[RowSetEventListener.APPROVE_CURSOR_MOVE] = false; 445cdf0e10cSrcweir moves[RowSetEventListener.CURSOR_MOVED] = false; 446cdf0e10cSrcweir moves[RowSetEventListener.IS_MODIFIED] = true; 447cdf0e10cSrcweir moves[RowSetEventListener.IS_NEW] = true; 448cdf0e10cSrcweir moves[RowSetEventListener.ROW_COUNT] = true; 449cdf0e10cSrcweir moves[RowSetEventListener.APPROVE_ROW_CHANGE] = true; 450cdf0e10cSrcweir moves[RowSetEventListener.ROW_CHANGED] = true; 451cdf0e10cSrcweir testCursorMove(upd, cupd.getMethod("insertRow", (Class[]) null), pRow, moves, null); 452cdf0e10cSrcweir 453cdf0e10cSrcweir moves[RowSetEventListener.IS_NEW] = false; 454cdf0e10cSrcweir moves[RowSetEventListener.ROW_COUNT] = false; 455cdf0e10cSrcweir m_resultSet.first(); 456cdf0e10cSrcweir updRow.updateInt(1, MAX_TABLE_ROWS + 3); 457cdf0e10cSrcweir updRow.updateString(2, "__"); 458cdf0e10cSrcweir testCursorMove(upd, cupd.getMethod("updateRow", (Class[]) null), pRow, moves, null); 459cdf0e10cSrcweir 460cdf0e10cSrcweir moves[RowSetEventListener.IS_NEW] = true; 461cdf0e10cSrcweir moves[RowSetEventListener.ROW_COUNT] = true; 462cdf0e10cSrcweir m_resultSet.first(); 463cdf0e10cSrcweir testCursorMove(upd, cupd.getMethod("deleteRow", (Class[]) null), pRow, moves, null); 464cdf0e10cSrcweir 465cdf0e10cSrcweir moves[RowSetEventListener.IS_NEW] = false; 466cdf0e10cSrcweir moves[RowSetEventListener.COLUMN_VALUE] = true; 467cdf0e10cSrcweir moves[RowSetEventListener.ROW_COUNT] = false; 468cdf0e10cSrcweir m_resultSet.first(); 469cdf0e10cSrcweir updRow.updateString(2, TEST21); 470cdf0e10cSrcweir testCursorMove(m_resultSet, cResSet.getMethod("refreshRow", (Class[]) null), pRow, moves, null); 471cdf0e10cSrcweir 472cdf0e10cSrcweir m_resultSet.first(); 473cdf0e10cSrcweir updRow.updateString(2, TEST21); 474cdf0e10cSrcweir testCursorMove(upd, cupd.getMethod("cancelRowUpdates", (Class[]) null), pRow, moves, null); 475cdf0e10cSrcweir 476cdf0e10cSrcweir for (int i = 0; i < moves.length; ++i) 477cdf0e10cSrcweir { 478cdf0e10cSrcweir moves[i] = false; 479cdf0e10cSrcweir } 480cdf0e10cSrcweir moves[RowSetEventListener.APPROVE_CURSOR_MOVE] = true; 481cdf0e10cSrcweir moves[RowSetEventListener.COLUMN_VALUE] = true; 482cdf0e10cSrcweir moves[RowSetEventListener.CURSOR_MOVED] = true; 483cdf0e10cSrcweir 484cdf0e10cSrcweir final Class cloc = Class.forName("com.sun.star.sdbcx.XRowLocate"); 485cdf0e10cSrcweir m_resultSet.first(); 486cdf0e10cSrcweir final Object bookmark = m_rowLocate.getBookmark(); 487cdf0e10cSrcweir m_resultSet.next(); 488cdf0e10cSrcweir final Object temp[] = new Object[1]; 489cdf0e10cSrcweir temp[0] = bookmark; 490cdf0e10cSrcweir Class ctemp[] = new Class[1]; 491cdf0e10cSrcweir ctemp[0] = Object.class; 492cdf0e10cSrcweir testCursorMove(m_rowLocate, cloc.getMethod("moveToBookmark", ctemp), pRow, moves, temp); 493cdf0e10cSrcweir 494cdf0e10cSrcweir final Object temp2[] = new Object[2]; 495cdf0e10cSrcweir temp2[0] = bookmark; 496cdf0e10cSrcweir temp2[1] = Integer.valueOf(1); 497cdf0e10cSrcweir final Class ctemp2[] = new Class[2]; 498cdf0e10cSrcweir ctemp2[0] = Object.class; 499cdf0e10cSrcweir ctemp2[1] = int.class; 500cdf0e10cSrcweir testCursorMove(m_rowLocate, cloc.getMethod("moveRelativeToBookmark", ctemp2), pRow, moves, temp2); 501cdf0e10cSrcweir 502cdf0e10cSrcweir for (int i = 0; i < moves.length; ++i) 503cdf0e10cSrcweir { 504cdf0e10cSrcweir moves[i] = false; 505cdf0e10cSrcweir } 506cdf0e10cSrcweir moves[RowSetEventListener.APPROVE_ROW_CHANGE] = true; 507cdf0e10cSrcweir moves[RowSetEventListener.ROW_CHANGED] = true; 508cdf0e10cSrcweir moves[RowSetEventListener.ROW_COUNT] = true; 509cdf0e10cSrcweir final Class cdelRows = Class.forName("com.sun.star.sdbcx.XDeleteRows"); 510cdf0e10cSrcweir ctemp[0] = Object[].class; 511cdf0e10cSrcweir final XDeleteRows delRows = UnoRuntime.queryInterface( XDeleteRows.class, m_resultSet ); 512cdf0e10cSrcweir final Object bookmarks[] = new Object[5]; 513cdf0e10cSrcweir m_resultSet.first(); 514cdf0e10cSrcweir for (int i = 0; i < bookmarks.length; ++i) 515cdf0e10cSrcweir { 516cdf0e10cSrcweir m_resultSet.next(); 517cdf0e10cSrcweir bookmarks[i] = m_rowLocate.getBookmark(); 518cdf0e10cSrcweir } 519cdf0e10cSrcweir 520cdf0e10cSrcweir temp[0] = bookmarks; 521cdf0e10cSrcweir testCursorMove(delRows, cdelRows.getMethod("deleteRows", ctemp), pRow, moves, temp); 522cdf0e10cSrcweir 523cdf0e10cSrcweir // now destroy the RowSet 524cdf0e10cSrcweir final XComponent xComp = UnoRuntime.queryInterface( XComponent.class, m_resultSet ); 525cdf0e10cSrcweir xComp.dispose(); 526cdf0e10cSrcweir } 527cdf0e10cSrcweir 528cdf0e10cSrcweir // -------------------------------------------------------------------------------------------------------- testCursorMove(Object res, Method _method, RowSetEventListener _evt, boolean _must[], Object args[])529cdf0e10cSrcweir private void testCursorMove(Object res, Method _method, RowSetEventListener _evt, boolean _must[], Object args[]) throws java.lang.Exception 530cdf0e10cSrcweir { 531cdf0e10cSrcweir _evt.clearCalling(); 532cdf0e10cSrcweir _method.invoke(res, args); 533cdf0e10cSrcweir 534cdf0e10cSrcweir System.out.println("testing events for " + _method.getName()); 535cdf0e10cSrcweir final int calling[] = _evt.getCalling(); 536cdf0e10cSrcweir int pos = 1; 537cdf0e10cSrcweir assertTrue("Callings are not in the correct order for APPROVE_CURSOR_MOVE ", 538cdf0e10cSrcweir (!_must[RowSetEventListener.APPROVE_CURSOR_MOVE] || calling[RowSetEventListener.APPROVE_CURSOR_MOVE] == -1) || calling[RowSetEventListener.APPROVE_CURSOR_MOVE] == pos++); 539cdf0e10cSrcweir assertTrue("Callings are not in the correct order for APPROVE_ROW_CHANGE", 540cdf0e10cSrcweir (!_must[RowSetEventListener.APPROVE_ROW_CHANGE] || calling[RowSetEventListener.APPROVE_ROW_CHANGE] == -1) || calling[RowSetEventListener.APPROVE_ROW_CHANGE] == pos++); 541cdf0e10cSrcweir assertTrue("Callings are not in the correct order for COLUMN_VALUE", 542cdf0e10cSrcweir (!_must[RowSetEventListener.COLUMN_VALUE] || calling[RowSetEventListener.COLUMN_VALUE] == -1) || calling[RowSetEventListener.COLUMN_VALUE] == pos++); 543cdf0e10cSrcweir assertTrue("Callings are not in the correct order for CURSOR_MOVED", 544cdf0e10cSrcweir (!_must[RowSetEventListener.CURSOR_MOVED] || calling[RowSetEventListener.CURSOR_MOVED] == -1) || calling[RowSetEventListener.CURSOR_MOVED] == pos++); 545cdf0e10cSrcweir assertTrue("Callings are not in the correct order for ROW_CHANGED", 546cdf0e10cSrcweir (!_must[RowSetEventListener.ROW_CHANGED] || calling[RowSetEventListener.ROW_CHANGED] == -1) || calling[RowSetEventListener.ROW_CHANGED] == pos++); 547cdf0e10cSrcweir assertTrue("Callings are not in the correct order for IS_MODIFIED", 548cdf0e10cSrcweir (!_must[RowSetEventListener.IS_MODIFIED] || calling[RowSetEventListener.IS_MODIFIED] == -1) || calling[RowSetEventListener.IS_MODIFIED] == pos++); 549cdf0e10cSrcweir assertTrue("Callings are not in the correct order for IS_NEW", 550cdf0e10cSrcweir (!_must[RowSetEventListener.IS_NEW] || calling[RowSetEventListener.IS_NEW] == -1) || calling[RowSetEventListener.IS_NEW] == pos++); 551cdf0e10cSrcweir assertTrue("Callings are not in the correct order for ROW_COUNT", 552cdf0e10cSrcweir (!_must[RowSetEventListener.ROW_COUNT] || calling[RowSetEventListener.ROW_COUNT] == -1) || calling[RowSetEventListener.ROW_COUNT] == pos++); 553cdf0e10cSrcweir assertTrue("Callings are not in the correct order for IS_ROW_COUNT_FINAL", 554cdf0e10cSrcweir (!_must[RowSetEventListener.IS_ROW_COUNT_FINAL] || calling[RowSetEventListener.IS_ROW_COUNT_FINAL] == -1) || calling[RowSetEventListener.IS_ROW_COUNT_FINAL] == pos); 555cdf0e10cSrcweir 556cdf0e10cSrcweir _evt.clearCalling(); 557cdf0e10cSrcweir } 558cdf0e10cSrcweir 559cdf0e10cSrcweir // -------------------------------------------------------------------------------------------------------- 560cdf0e10cSrcweir /** returns the current row count of the RowSet 561cdf0e10cSrcweir */ currentRowCount()562cdf0e10cSrcweir private int currentRowCount() throws UnknownPropertyException, WrappedTargetException 563cdf0e10cSrcweir { 564cdf0e10cSrcweir final Integer rowCount = (Integer) m_rowSetProperties.getPropertyValue("RowCount"); 565cdf0e10cSrcweir return rowCount.intValue(); 566cdf0e10cSrcweir } 567cdf0e10cSrcweir 568cdf0e10cSrcweir // -------------------------------------------------------------------------------------------------------- 569cdf0e10cSrcweir /** positions the row set at an arbitrary position between 2 and (current row count - 1) 570cdf0e10cSrcweir */ positionRandom()571cdf0e10cSrcweir private int positionRandom() throws SQLException, UnknownPropertyException, WrappedTargetException 572cdf0e10cSrcweir { 573cdf0e10cSrcweir final int position = (new Random()).nextInt(currentRowCount() - 2) + 2; 574cdf0e10cSrcweir assertTrue("sub task failed: could not position to row no. " + (Integer.valueOf(position)).toString(), 575cdf0e10cSrcweir m_resultSet.absolute(position)); 576cdf0e10cSrcweir return m_resultSet.getRow(); 577cdf0e10cSrcweir } 578cdf0e10cSrcweir 579cdf0e10cSrcweir // -------------------------------------------------------------------------------------------------------- 580cdf0e10cSrcweir /** moves the result set to a random record between 2 and (current row count - 1), and deletes this record 581cdf0e10cSrcweir * 582cdf0e10cSrcweir * After returning from this method, the row set is still positioned at the deleted record 583cdf0e10cSrcweir * @return 584cdf0e10cSrcweir * the number/position of the record which has been deleted 585cdf0e10cSrcweir */ deleteRandom()586cdf0e10cSrcweir private int deleteRandom() throws SQLException, UnknownPropertyException, WrappedTargetException 587cdf0e10cSrcweir { 588cdf0e10cSrcweir // check if the current position and the row count in the result set is changed by a deletion (it should not) 589cdf0e10cSrcweir final int positionBefore = positionRandom(); 590cdf0e10cSrcweir final int rowCountBefore = currentRowCount(); 591cdf0e10cSrcweir 592cdf0e10cSrcweir m_resultSetUpdate.deleteRow(); 593cdf0e10cSrcweir 594cdf0e10cSrcweir final int positionAfter = m_resultSet.getRow(); 595cdf0e10cSrcweir final int rowCountAfter = currentRowCount(); 596cdf0e10cSrcweir assertTrue("position changed during |deleteRow| (it should not)", positionAfter == positionBefore); 597cdf0e10cSrcweir assertTrue("row count changed with a |deleteRow| (it should not)", rowCountBefore == rowCountAfter); 598cdf0e10cSrcweir assertTrue("RowSet does not report the current row as deleted after |deleteRow|", m_resultSet.rowDeleted()); 599cdf0e10cSrcweir 600cdf0e10cSrcweir return positionBefore; 601cdf0e10cSrcweir } 602cdf0e10cSrcweir 603cdf0e10cSrcweir // -------------------------------------------------------------------------------------------------------- 604cdf0e10cSrcweir @Test testDeleteBehavior()605cdf0e10cSrcweir public void testDeleteBehavior() throws Exception 606cdf0e10cSrcweir { 607cdf0e10cSrcweir createTestCase(true); 608cdf0e10cSrcweir 609cdf0e10cSrcweir // ensure that all records are known 610cdf0e10cSrcweir m_resultSet.last(); 611cdf0e10cSrcweir final int initialRowCount = currentRowCount(); 612cdf0e10cSrcweir 613cdf0e10cSrcweir // delete a random row 614cdf0e10cSrcweir int deletedRow = deleteRandom(); 615cdf0e10cSrcweir 616cdf0e10cSrcweir // ..................................................................................................... 617cdf0e10cSrcweir // asking for the bookmark of a deleted row should fail 618cdf0e10cSrcweir boolean caughtException = false; 619cdf0e10cSrcweir try 620cdf0e10cSrcweir { 621cdf0e10cSrcweir m_rowLocate.getBookmark(); 622cdf0e10cSrcweir } 623cdf0e10cSrcweir catch (SQLException e) 624cdf0e10cSrcweir { 625cdf0e10cSrcweir caughtException = true; 626cdf0e10cSrcweir } 627cdf0e10cSrcweir assertTrue("asking for the bookmark of a deleted row should throw an exception", caughtException); 628cdf0e10cSrcweir 629cdf0e10cSrcweir // ..................................................................................................... 630cdf0e10cSrcweir // isXXX methods should return |false| on a deleted row 631cdf0e10cSrcweir assertTrue("one of the isFoo failed after |deleteRow|", !m_resultSet.isBeforeFirst() && !m_resultSet.isAfterLast() && !m_resultSet.isFirst() && !m_resultSet.isLast()); 632cdf0e10cSrcweir // note that we can assume that isFirst / isLast also return |false|, since deleteRandom did 633cdf0e10cSrcweir // not position on the first or last record, but inbetween 634cdf0e10cSrcweir 635cdf0e10cSrcweir // ..................................................................................................... 636cdf0e10cSrcweir // check if moving away from this row in either direction yields the expected results 637cdf0e10cSrcweir assertTrue("|previous| after |deleteRow| failed", m_resultSet.previous()); 638cdf0e10cSrcweir final int positionPrevious = m_resultSet.getRow(); 639cdf0e10cSrcweir assertTrue("position after |previous| after |deleteRow| is not as expected", positionPrevious == deletedRow - 1); 640cdf0e10cSrcweir 641cdf0e10cSrcweir deletedRow = deleteRandom(); 642cdf0e10cSrcweir assertTrue("|next| after |deleteRow| failed", m_resultSet.next()); 643cdf0e10cSrcweir final int positionAfter = m_resultSet.getRow(); 644cdf0e10cSrcweir assertTrue("position after |next| after |deleteRow| is not as expected", positionAfter == deletedRow); 645cdf0e10cSrcweir // since the deleted record "vanishs" as soon as the cursor is moved away from it, the absolute position does 646cdf0e10cSrcweir // not change with a |next| call here 647cdf0e10cSrcweir 648cdf0e10cSrcweir // ..................................................................................................... 649cdf0e10cSrcweir // check if the deleted rows really vanished after moving away from them 650cdf0e10cSrcweir assertTrue("row count did not change as expected after two deletions", initialRowCount - 2 == currentRowCount()); 651cdf0e10cSrcweir 652cdf0e10cSrcweir // ..................................................................................................... 653cdf0e10cSrcweir // check if the deleted row vanishes after moving to the insertion row 654cdf0e10cSrcweir final int rowCountBefore = currentRowCount(); 655cdf0e10cSrcweir final int deletedPos = deleteRandom(); 656cdf0e10cSrcweir m_resultSetUpdate.moveToInsertRow(); 657cdf0e10cSrcweir assertTrue("moving to the insertion row immediately after |deleteRow| does not adjust the row count", rowCountBefore == currentRowCount() + 1); 658cdf0e10cSrcweir 659cdf0e10cSrcweir m_resultSetUpdate.moveToCurrentRow(); 660cdf0e10cSrcweir assertTrue("|moveToCurrentRow| after |deleteRow| + |moveToInsertRow| results in unexpected position", 661cdf0e10cSrcweir (m_resultSet.getRow() == deletedPos) && !m_resultSet.rowDeleted()); 662cdf0e10cSrcweir 663cdf0e10cSrcweir // the same, but this time with deleting the first row (which is not covered by deleteRandom) 664cdf0e10cSrcweir m_resultSet.last(); 665cdf0e10cSrcweir m_resultSetUpdate.deleteRow(); 666cdf0e10cSrcweir m_resultSetUpdate.moveToInsertRow(); 667cdf0e10cSrcweir m_resultSetUpdate.moveToCurrentRow(); 668cdf0e10cSrcweir assertTrue("|last| + |deleteRow| + |moveToInsertRow| + |moveToCurrentRow| results in wrong state", m_resultSet.isAfterLast()); 669cdf0e10cSrcweir 670cdf0e10cSrcweir // ..................................................................................................... 671cdf0e10cSrcweir // check if deleting a deleted row fails as expected 672cdf0e10cSrcweir deleteRandom(); 673cdf0e10cSrcweir caughtException = false; 674cdf0e10cSrcweir try 675cdf0e10cSrcweir { 676cdf0e10cSrcweir m_resultSetUpdate.deleteRow(); 677cdf0e10cSrcweir } 678cdf0e10cSrcweir catch (SQLException e) 679cdf0e10cSrcweir { 680cdf0e10cSrcweir caughtException = true; 681cdf0e10cSrcweir } 682cdf0e10cSrcweir assertTrue("deleting a deleted row succeeded - it shouldn't", caughtException); 683cdf0e10cSrcweir 684cdf0e10cSrcweir // ..................................................................................................... 685cdf0e10cSrcweir // check if deleteRows fails if it contains the bookmark of a previously-deleted row 686cdf0e10cSrcweir m_resultSet.first(); 687cdf0e10cSrcweir final Object firstBookmark = m_rowLocate.getBookmark(); 688cdf0e10cSrcweir positionRandom(); 689cdf0e10cSrcweir final Object deleteBookmark = m_rowLocate.getBookmark(); 690cdf0e10cSrcweir m_resultSetUpdate.deleteRow(); 691cdf0e10cSrcweir final XDeleteRows multiDelete = UnoRuntime.queryInterface( XDeleteRows.class, m_resultSet ); 692cdf0e10cSrcweir final int[] deleteSuccess = multiDelete.deleteRows(new Object[] 693cdf0e10cSrcweir { 694cdf0e10cSrcweir firstBookmark, deleteBookmark 695cdf0e10cSrcweir }); 696cdf0e10cSrcweir assertTrue("XDeleteRows::deleteRows with the bookmark of an already-deleted row failed", 697cdf0e10cSrcweir (deleteSuccess.length == 2) && (deleteSuccess[0] != 0) && (deleteSuccess[1] == 0)); 698cdf0e10cSrcweir 699cdf0e10cSrcweir // ..................................................................................................... 700cdf0e10cSrcweir // check if refreshing a deleted row fails as expected 701cdf0e10cSrcweir deleteRandom(); 702cdf0e10cSrcweir caughtException = false; 703cdf0e10cSrcweir try 704cdf0e10cSrcweir { 705cdf0e10cSrcweir m_resultSet.refreshRow(); 706cdf0e10cSrcweir } 707cdf0e10cSrcweir catch (SQLException e) 708cdf0e10cSrcweir { 709cdf0e10cSrcweir caughtException = true; 710cdf0e10cSrcweir } 711cdf0e10cSrcweir assertTrue("refreshing a deleted row succeeded - it shouldn't", caughtException); 712cdf0e10cSrcweir 713cdf0e10cSrcweir // ..................................................................................................... 714cdf0e10cSrcweir // rowUpdated/rowDeleted 715cdf0e10cSrcweir deleteRandom(); 716cdf0e10cSrcweir assertTrue("rowDeleted and/or rowUpdated are wrong on a deleted row", !m_resultSet.rowUpdated() && !m_resultSet.rowInserted()); 717cdf0e10cSrcweir 718cdf0e10cSrcweir // ..................................................................................................... 719cdf0e10cSrcweir // updating values in a deleted row should fail 720cdf0e10cSrcweir deleteRandom(); 721cdf0e10cSrcweir final XRowUpdate rowUpdated = UnoRuntime.queryInterface( XRowUpdate.class, m_resultSet ); 722cdf0e10cSrcweir caughtException = false; 723cdf0e10cSrcweir try 724cdf0e10cSrcweir { 725cdf0e10cSrcweir rowUpdated.updateString(2, TEST21); 726cdf0e10cSrcweir } 727cdf0e10cSrcweir catch (SQLException e) 728cdf0e10cSrcweir { 729cdf0e10cSrcweir caughtException = true; 730cdf0e10cSrcweir } 731cdf0e10cSrcweir assertTrue("updating values in a deleted row should not succeed", caughtException); 732cdf0e10cSrcweir } 733cdf0e10cSrcweir 734cdf0e10cSrcweir // -------------------------------------------------------------------------------------------------------- 735cdf0e10cSrcweir /** checks whether deletions on the main RowSet properly interfere (or don't interfere) with the movement 736cdf0e10cSrcweir * on a clone of the RowSet 737cdf0e10cSrcweir */ 738cdf0e10cSrcweir @Test testCloneMovesPlusDeletions()739cdf0e10cSrcweir public void testCloneMovesPlusDeletions() throws SQLException, UnknownPropertyException, WrappedTargetException 740cdf0e10cSrcweir { 741cdf0e10cSrcweir createTestCase(true); 742cdf0e10cSrcweir // ensure that all records are known 743cdf0e10cSrcweir m_resultSet.last(); 744cdf0e10cSrcweir 745cdf0e10cSrcweir final XResultSet clone = createClone(); 746cdf0e10cSrcweir final XRowLocate cloneRowLocate = UnoRuntime.queryInterface( XRowLocate.class, clone ); 747cdf0e10cSrcweir 748cdf0e10cSrcweir positionRandom(); 749cdf0e10cSrcweir 750cdf0e10cSrcweir // ..................................................................................................... 751cdf0e10cSrcweir // move the clone to the same record as the RowSet, and delete this record 752cdf0e10cSrcweir cloneRowLocate.moveToBookmark(m_rowLocate.getBookmark()); 753cdf0e10cSrcweir final int clonePosition = clone.getRow(); 754cdf0e10cSrcweir m_resultSetUpdate.deleteRow(); 755cdf0e10cSrcweir 756cdf0e10cSrcweir assertTrue("clone doesn't know that its current row has been deleted via the RowSet", clone.rowDeleted()); 757cdf0e10cSrcweir assertTrue("clone's position changed somehow during deletion", clonePosition == clone.getRow()); 758cdf0e10cSrcweir 759cdf0e10cSrcweir // ..................................................................................................... 760cdf0e10cSrcweir // move the row set away from the deleted record. This should still not touch the state of the clone 761cdf0e10cSrcweir m_resultSet.previous(); 762cdf0e10cSrcweir 763cdf0e10cSrcweir assertTrue("clone doesn't know (anymore) that its current row has been deleted via the RowSet", clone.rowDeleted()); 764cdf0e10cSrcweir assertTrue("clone's position changed somehow during deletion and RowSet-movement", clonePosition == clone.getRow()); 765cdf0e10cSrcweir 766cdf0e10cSrcweir // ..................................................................................................... 767cdf0e10cSrcweir // move the clone away from the deleted record 768cdf0e10cSrcweir clone.next(); 769cdf0e10cSrcweir assertTrue("clone still assumes that its row is deleted - but we already moved it", !clone.rowDeleted()); 770cdf0e10cSrcweir 771cdf0e10cSrcweir // ..................................................................................................... 772cdf0e10cSrcweir // check whether deleting the extremes (first / last) work 773cdf0e10cSrcweir m_resultSet.first(); 774cdf0e10cSrcweir cloneRowLocate.moveToBookmark(m_rowLocate.getBookmark()); 775cdf0e10cSrcweir m_resultSetUpdate.deleteRow(); 776cdf0e10cSrcweir clone.previous(); 777cdf0e10cSrcweir assertTrue("deleting the first record left the clone in a strange state (after |previous|)", clone.isBeforeFirst()); 778cdf0e10cSrcweir clone.next(); 779cdf0e10cSrcweir assertTrue("deleting the first record left the clone in a strange state (after |previous| + |next|)", clone.isFirst()); 780cdf0e10cSrcweir 781cdf0e10cSrcweir m_resultSet.last(); 782cdf0e10cSrcweir cloneRowLocate.moveToBookmark(m_rowLocate.getBookmark()); 783cdf0e10cSrcweir m_resultSetUpdate.deleteRow(); 784cdf0e10cSrcweir clone.next(); 785cdf0e10cSrcweir assertTrue("deleting the last record left the clone in a strange state (after |next|)", clone.isAfterLast()); 786cdf0e10cSrcweir clone.previous(); 787cdf0e10cSrcweir assertTrue("deleting the first record left the clone in a strange state (after |next| + |previous|)", clone.isLast()); 788cdf0e10cSrcweir 789cdf0e10cSrcweir // ..................................................................................................... 790cdf0e10cSrcweir // check whether movements of the clone interfere with movements of the RowSet, if the latter is on a deleted row 791cdf0e10cSrcweir final int positionBefore = positionRandom(); 792cdf0e10cSrcweir m_resultSetUpdate.deleteRow(); 793cdf0e10cSrcweir assertTrue("|deleteRow|, but no |rowDeleted| (this should have been found much earlier!)", m_resultSet.rowDeleted()); 794cdf0e10cSrcweir clone.beforeFirst(); 795cdf0e10cSrcweir while (clone.next()); 796cdf0e10cSrcweir assertTrue("row set forgot that the current row is deleted", m_resultSet.rowDeleted()); 797cdf0e10cSrcweir 798cdf0e10cSrcweir assertTrue("moving to the next record after |deleteRow| and clone moves failed", m_resultSet.next()); 799cdf0e10cSrcweir assertTrue("wrong position after |deleteRow| and clone movement", !m_resultSet.isAfterLast() && !m_resultSet.isBeforeFirst()); 800cdf0e10cSrcweir assertTrue("wrong absolute position after |deleteRow| and clone movement", m_resultSet.getRow() == positionBefore); 801cdf0e10cSrcweir } 802cdf0e10cSrcweir 803cdf0e10cSrcweir // -------------------------------------------------------------------------------------------------------- 804cdf0e10cSrcweir /** checks whether insertions on the main RowSet properly interfere (or don't interfere) with the movement 805cdf0e10cSrcweir * on a clone of the RowSet 806cdf0e10cSrcweir */ 807cdf0e10cSrcweir @Test testCloneMovesPlusInsertions()808cdf0e10cSrcweir public void testCloneMovesPlusInsertions() throws SQLException, UnknownPropertyException, WrappedTargetException, PropertyVetoException, com.sun.star.lang.IllegalArgumentException 809cdf0e10cSrcweir { 810cdf0e10cSrcweir createTestCase(true); 811cdf0e10cSrcweir // ensure that all records are known 812cdf0e10cSrcweir m_rowSetProperties.setPropertyValue("FetchSize", Integer.valueOf(10)); 813cdf0e10cSrcweir 814cdf0e10cSrcweir final XResultSet clone = createClone(); 815cdf0e10cSrcweir final XRow cloneRow = UnoRuntime.queryInterface( XRow.class, clone ); 816cdf0e10cSrcweir 817cdf0e10cSrcweir // ..................................................................................................... 818cdf0e10cSrcweir // first check the basic scenario without the |moveToInsertRow| |moveToCurrentRow|, to ensure that 819cdf0e10cSrcweir // really those are broken, if at all 820cdf0e10cSrcweir m_resultSet.last(); 821cdf0e10cSrcweir clone.first(); 822cdf0e10cSrcweir clone.absolute(11); 823cdf0e10cSrcweir clone.first(); 824cdf0e10cSrcweir 825cdf0e10cSrcweir final int rowValue1 = m_row.getInt(1); 826cdf0e10cSrcweir final int rowPos = m_resultSet.getRow(); 827cdf0e10cSrcweir final int rowValue2 = m_row.getInt(1); 828cdf0e10cSrcweir assertTrue("repeated query for the same column value delivers different values (" + rowValue1 + " and " + rowValue2 + ") on row: " + rowPos, 829cdf0e10cSrcweir rowValue1 == rowValue2); 830cdf0e10cSrcweir 831cdf0e10cSrcweir testPosition(clone, cloneRow, 1, "mixed clone/rowset move: clone check"); 832cdf0e10cSrcweir testPosition(m_resultSet, m_row, MAX_TABLE_ROWS, "mixed clone/rowset move: rowset check"); 833cdf0e10cSrcweir 834cdf0e10cSrcweir // ..................................................................................................... 835cdf0e10cSrcweir // now the complete scenario 836cdf0e10cSrcweir m_resultSet.last(); 837cdf0e10cSrcweir m_resultSetUpdate.moveToInsertRow(); 838cdf0e10cSrcweir clone.first(); 839cdf0e10cSrcweir clone.absolute(11); 840cdf0e10cSrcweir clone.first(); 841cdf0e10cSrcweir m_resultSetUpdate.moveToCurrentRow(); 842cdf0e10cSrcweir 843cdf0e10cSrcweir testPosition(clone, cloneRow, 1, "mixed clone/rowset move/insertion: clone check"); 844cdf0e10cSrcweir testPosition(m_resultSet, m_row, 100, "mixed clone/rowset move/insertion: rowset check"); 845cdf0e10cSrcweir } 846cdf0e10cSrcweir 847cdf0e10cSrcweir // -------------------------------------------------------------------------------------------------------- testTableParameters()848cdf0e10cSrcweir private void testTableParameters() 849cdf0e10cSrcweir { 850cdf0e10cSrcweir // for a row set simply based on a table, there should be not parameters at all 851cdf0e10cSrcweir createRowSet("products", CommandType.TABLE, false); 852cdf0e10cSrcweir try 853cdf0e10cSrcweir { 854cdf0e10cSrcweir verifyParameters(new String[] 855cdf0e10cSrcweir { 856cdf0e10cSrcweir }, "testTableParameters"); 857cdf0e10cSrcweir } 858cdf0e10cSrcweir catch (Exception e) 859cdf0e10cSrcweir { 860cdf0e10cSrcweir fail("testing the parameters of a table failed" + e.getMessage()); 861cdf0e10cSrcweir } 862cdf0e10cSrcweir } 863cdf0e10cSrcweir // -------------------------------------------------------------------------------------------------------- 864cdf0e10cSrcweir testParametersAfterNormalExecute()865cdf0e10cSrcweir private void testParametersAfterNormalExecute() 866cdf0e10cSrcweir { 867cdf0e10cSrcweir try 868cdf0e10cSrcweir { 869cdf0e10cSrcweir createRowSet("SELECT * FROM \"customers\"", CommandType.COMMAND, true); 870cdf0e10cSrcweir m_rowSetProperties.setPropertyValue("Command", "SELECT * FROM \"customers\" WHERE \"City\" = :city"); 871cdf0e10cSrcweir final XParameters rowsetParams = UnoRuntime.queryInterface( XParameters.class, m_rowSet ); 872cdf0e10cSrcweir rowsetParams.setString(1, "London"); 873cdf0e10cSrcweir m_rowSet.execute(); 874cdf0e10cSrcweir } 875cdf0e10cSrcweir catch (Exception e) 876cdf0e10cSrcweir { 877cdf0e10cSrcweir fail("testing the parameters of a table failed" + e.getMessage()); 878cdf0e10cSrcweir } 879cdf0e10cSrcweir } 880cdf0e10cSrcweir 881cdf0e10cSrcweir // -------------------------------------------------------------------------------------------------------- verifyParameters(String[] _paramNames, String _context)882cdf0e10cSrcweir private void verifyParameters(String[] _paramNames, String _context) throws com.sun.star.uno.Exception 883cdf0e10cSrcweir { 884cdf0e10cSrcweir final XIndexAccess params = m_paramsSupplier.getParameters(); 885cdf0e10cSrcweir final int expected = _paramNames.length; 886cdf0e10cSrcweir final int found = params != null ? params.getCount() : 0; 887cdf0e10cSrcweir 888cdf0e10cSrcweir assertTrue("wrong number of parameters (expected: " + expected + ", found: " + found + ") in " + _context, 889cdf0e10cSrcweir found == expected); 890cdf0e10cSrcweir 891cdf0e10cSrcweir if (found == 0) 892cdf0e10cSrcweir { 893cdf0e10cSrcweir return; 894cdf0e10cSrcweir } 895cdf0e10cSrcweir 896cdf0e10cSrcweir for (int i = 0; i < expected; ++i) 897cdf0e10cSrcweir { 898cdf0e10cSrcweir final XPropertySet parameter = UnoRuntime.queryInterface( XPropertySet.class, params.getByIndex( i ) ); 899cdf0e10cSrcweir 900cdf0e10cSrcweir final String expectedName = _paramNames[i]; 901cdf0e10cSrcweir final String foundName = (String) parameter.getPropertyValue("Name"); 902cdf0e10cSrcweir assertTrue("wrong parameter name (expected: " + expectedName + ", found: " + foundName + ") in" + _context, 903cdf0e10cSrcweir expectedName.equals(foundName)); 904cdf0e10cSrcweir } 905cdf0e10cSrcweir } 906cdf0e10cSrcweir 907cdf0e10cSrcweir // -------------------------------------------------------------------------------------------------------- testParametrizedQuery()908cdf0e10cSrcweir private void testParametrizedQuery() 909cdf0e10cSrcweir { 910cdf0e10cSrcweir try 911cdf0e10cSrcweir { 912cdf0e10cSrcweir // for a row set based on a parametrized query, those parameters should be properly 913cdf0e10cSrcweir // recognized 914cdf0e10cSrcweir m_dataSource.createQuery("products like", "SELECT * FROM \"products\" WHERE \"Name\" LIKE :product_name"); 915cdf0e10cSrcweir createRowSet("products like", CommandType.QUERY, false); 916cdf0e10cSrcweir verifyParameters(new String[] 917cdf0e10cSrcweir { 918cdf0e10cSrcweir "product_name" 919cdf0e10cSrcweir }, "testParametrizedQuery"); 920cdf0e10cSrcweir } 921cdf0e10cSrcweir catch (Exception e) 922cdf0e10cSrcweir { 923cdf0e10cSrcweir fail("testing the parameters of a parametrized query failed" + e.getMessage()); 924cdf0e10cSrcweir } 925cdf0e10cSrcweir } 926cdf0e10cSrcweir 927cdf0e10cSrcweir // -------------------------------------------------------------------------------------------------------- testParametersInteraction()928cdf0e10cSrcweir private void testParametersInteraction() 929cdf0e10cSrcweir { 930cdf0e10cSrcweir try 931cdf0e10cSrcweir { 932cdf0e10cSrcweir createRowSet("products like", CommandType.QUERY, false); 933cdf0e10cSrcweir 934cdf0e10cSrcweir // let's fill in a parameter value via XParameters, and see whether it is respected by the parameters container 935cdf0e10cSrcweir final XParameters rowsetParams = UnoRuntime.queryInterface(XParameters.class, m_rowSet); 936cdf0e10cSrcweir rowsetParams.setString(1, "Apples"); 937cdf0e10cSrcweir 938cdf0e10cSrcweir XIndexAccess params = m_paramsSupplier.getParameters(); 939cdf0e10cSrcweir XPropertySet firstParam = UnoRuntime.queryInterface( XPropertySet.class, params.getByIndex( 0 ) ); 940cdf0e10cSrcweir Object firstParamValue = firstParam.getPropertyValue("Value"); 941cdf0e10cSrcweir 942cdf0e10cSrcweir assertTrue("XParameters and the parameters container do not properly interact", 943cdf0e10cSrcweir "Apples".equals(firstParamValue)); 944cdf0e10cSrcweir 945cdf0e10cSrcweir // let's see whether this also survices an execute of the row set 946cdf0e10cSrcweir rowsetParams.setString(1, "Oranges"); 947cdf0e10cSrcweir m_rowSet.execute(); 948cdf0e10cSrcweir { 949cdf0e10cSrcweir // TODO: the following would not be necessary if the parameters container would *survive* 950cdf0e10cSrcweir // the execution of the row set. It currently doesn't (though the values it represents do). 951cdf0e10cSrcweir // It would be nice, but not strictly necessary, if it would. 952cdf0e10cSrcweir params = m_paramsSupplier.getParameters(); 953cdf0e10cSrcweir firstParam = UnoRuntime.queryInterface( XPropertySet.class, params.getByIndex( 0 ) ); 954cdf0e10cSrcweir } 955cdf0e10cSrcweir firstParamValue = firstParam.getPropertyValue("Value"); 956cdf0e10cSrcweir assertTrue("XParameters and the parameters container do not properly interact, after the row set has been executed", 957cdf0e10cSrcweir "Oranges".equals(firstParamValue)); 958cdf0e10cSrcweir } 959cdf0e10cSrcweir catch (Exception e) 960cdf0e10cSrcweir { 961cdf0e10cSrcweir fail("could not test the relationship between XParameters and XParametersSupplier" + e.getMessage()); 962cdf0e10cSrcweir } 963cdf0e10cSrcweir } 964cdf0e10cSrcweir 965cdf0e10cSrcweir // -------------------------------------------------------------------------------------------------------- testParametersInFilter()966cdf0e10cSrcweir private void testParametersInFilter() 967cdf0e10cSrcweir { 968cdf0e10cSrcweir try 969cdf0e10cSrcweir { 970cdf0e10cSrcweir createRowSet("SELECT * FROM \"customers\"", CommandType.COMMAND, false); 971cdf0e10cSrcweir m_rowSetProperties.setPropertyValue("Filter", "\"City\" = :city"); 972cdf0e10cSrcweir 973cdf0e10cSrcweir m_rowSetProperties.setPropertyValue("ApplyFilter", Boolean.TRUE); 974cdf0e10cSrcweir verifyParameters(new String[] 975cdf0e10cSrcweir { 976cdf0e10cSrcweir "city" 977cdf0e10cSrcweir }, "testParametersInFilter"); 978cdf0e10cSrcweir 979cdf0e10cSrcweir m_rowSetProperties.setPropertyValue("ApplyFilter", Boolean.FALSE); 980cdf0e10cSrcweir verifyParameters(new String[] 981cdf0e10cSrcweir { 982cdf0e10cSrcweir }, "testParametersInFilter"); 983cdf0e10cSrcweir } 984cdf0e10cSrcweir catch (Exception e) 985cdf0e10cSrcweir { 986cdf0e10cSrcweir fail("testing the parameters within a WHERE clause failed" + e.getMessage()); 987cdf0e10cSrcweir } 988cdf0e10cSrcweir } 989cdf0e10cSrcweir 990cdf0e10cSrcweir // -------------------------------------------------------------------------------------------------------- 991cdf0e10cSrcweir /** checks the XParametersSupplier functionality of a RowSet 992cdf0e10cSrcweir */ 993cdf0e10cSrcweir @Test testParameters()994cdf0e10cSrcweir public void testParameters() 995cdf0e10cSrcweir { 996cdf0e10cSrcweir createTestCase(false); 997cdf0e10cSrcweir // use an own RowSet instance, not the one which is also used for the other cases 998cdf0e10cSrcweir 999cdf0e10cSrcweir testTableParameters(); 1000cdf0e10cSrcweir testParametrizedQuery(); 1001cdf0e10cSrcweir testParametersInFilter(); 1002cdf0e10cSrcweir 1003cdf0e10cSrcweir testParametersAfterNormalExecute(); 1004cdf0e10cSrcweir 1005cdf0e10cSrcweir testParametersInteraction(); 1006cdf0e10cSrcweir } 1007cdf0e10cSrcweir } 1008cdf0e10cSrcweir 1009