2 * This file is part of the LibreOffice project.
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 * This file incorporates work covered by the following license notice:
10 * Licensed to the Apache Software Foundation (ASF) under one or more
11 * contributor license agreements. See the NOTICE file distributed
12 * with this work for additional information regarding copyright
13 * ownership. The ASF licenses this file to you under the Apache
14 * License, Version 2.0 (the "License"); you may not use this file
15 * except in compliance with the License. You may obtain a copy of
16 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
19 package mod
._dbaccess
;
21 import ifc
.sdb
._XCompletedExecution
;
23 import java
.io
.PrintWriter
;
24 import java
.util
.ArrayList
;
26 import lib
.StatusException
;
28 import lib
.TestEnvironment
;
29 import lib
.TestParameters
;
32 import util
.db
.DataSource
;
33 import util
.db
.DataSourceDescriptor
;
35 import com
.sun
.star
.beans
.PropertyValue
;
36 import com
.sun
.star
.beans
.XPropertySet
;
37 import com
.sun
.star
.frame
.XModel
;
38 import com
.sun
.star
.lang
.XComponent
;
39 import com
.sun
.star
.lang
.XMultiServiceFactory
;
40 import com
.sun
.star
.sdb
.CommandType
;
41 import com
.sun
.star
.sdb
.ParametersRequest
;
42 import com
.sun
.star
.sdb
.RowChangeEvent
;
43 import com
.sun
.star
.sdb
.XInteractionSupplyParameters
;
44 import com
.sun
.star
.sdbc
.SQLException
;
45 import com
.sun
.star
.sdbc
.XConnection
;
46 import com
.sun
.star
.sdbc
.XParameters
;
47 import com
.sun
.star
.sdbc
.XResultSet
;
48 import com
.sun
.star
.sdbc
.XResultSetUpdate
;
49 import com
.sun
.star
.sdbc
.XRow
;
50 import com
.sun
.star
.sdbc
.XRowSet
;
51 import com
.sun
.star
.sdbc
.XRowUpdate
;
52 import com
.sun
.star
.task
.XInteractionAbort
;
53 import com
.sun
.star
.task
.XInteractionContinuation
;
54 import com
.sun
.star
.task
.XInteractionRequest
;
55 import com
.sun
.star
.ucb
.AuthenticationRequest
;
56 import com
.sun
.star
.uno
.UnoRuntime
;
57 import com
.sun
.star
.uno
.XInterface
;
58 import com
.sun
.star
.util
.XCloseable
;
61 * Test for object which is represented by service
62 * <code>com.sun.star.sdb.RowSet</code>. <p>
64 * The following files used by this test :
66 * <li><b> TestDB/TestDB.dbf </b> : the database file with some
67 * predefined fields described in <code>util.DBTools</code>.
68 * The copy of this file is always made in temp directory for
69 * testing purposes.</li>
71 * The following parameters in ini-file used by this test:
73 * <li><code>test.db.url</code> - URL to MySQL database.
74 * For example: <code>mysql://mercury:3306/api_current</code></li>
75 * <li><code>test.db.user</code> - user for MySQL database</li>
76 * <li><code>test.db.password</code> - password for MySQL database</li>
79 * @see com.sun.star.sdbc.RowSet
80 * @see com.sun.star.sdbcx.XRowLocate
81 * @see com.sun.star.sdbc.XResultSetUpdate
82 * @see com.sun.star.util.XCancellable
83 * @see com.sun.star.sdbc.XParameters
84 * @see com.sun.star.sdbc.XResultSetMetaDataSupplier
85 * @see com.sun.star.sdbcx.XDeleteRows
86 * @see com.sun.star.sdbc.XCloseable
87 * @see com.sun.star.sdbcx.XColumnsSupplier
88 * @see com.sun.star.sdb.XResultSetAccess
89 * @see com.sun.star.sdbc.XResultSet
90 * @see com.sun.star.sdbc.XColumnLocate
91 * @see com.sun.star.sdbc.XRowSet
92 * @see com.sun.star.sdb.RowSet
93 * @see com.sun.star.sdbc.XRowUpdate
94 * @see com.sun.star.sdb.XRowSetApproveBroadcaster
95 * @see com.sun.star.beans.XPropertySet
96 * @see com.sun.star.sdbc.XRow
97 * @see com.sun.star.sdbc.XWarningsSupplier
98 * @see com.sun.star.lang.XComponent
99 * @see com.sun.star.sdbcx.ResultSet
100 * @see com.sun.star.sdbc.ResultSet
101 * @see ifc.sdbc._RowSet
102 * @see ifc.sdbcx._XRowLocate
103 * @see ifc.sdbc._XResultSetUpdate
104 * @see ifc.util._XCancellable
105 * @see ifc.sdbc._XParameters
106 * @see ifc.sdbc._XResultSetMetaDataSupplier
107 * @see ifc.sdbcx._XDeleteRows
108 * @see ifc.sdbc._XCloseable
109 * @see ifc.sdbcx._XColumnsSupplier
110 * @see ifc.sdb._XResultSetAccess
111 * @see ifc.sdbc._XResultSet
112 * @see ifc.sdbc._XColumnLocate
113 * @see ifc.sdbc._XRowSet
114 * @see ifc.sdb._RowSet
115 * @see ifc.sdbc._XRowUpdate
116 * @see ifc.sdb._XRowSetApproveBroadcaster
117 * @see ifc.beans._XPropertySet
118 * @see ifc.sdbc._XRow
119 * @see ifc.sdbc._XWarningsSupplier
120 * @see ifc.lang._XComponent
121 * @see ifc.sdbcx._ResultSet
122 * @see ifc.sdbc._ResultSet
124 public class ORowSet
extends TestCase
{
126 private static int uniqueSuffix
= 0 ;
127 private DBTools dbTools
= null ;
128 private static String origDB
= null ;
129 String tableName
= null;
130 DataSourceDescriptor srcInf
= null;
131 boolean isMySQLDB
= false;
132 protected final static String dbSourceName
= "ORowSetDataSource";
133 public XConnection m_connection
= null;
134 private Object m_rowSet
= null;
135 private DataSource m_dataSource
;
136 private String m_tableFile
;
139 * Initializes some class fields. Then creates DataSource, which serves
140 * as a single source for all tables created in the test.
141 * This DataSource then registered in the global
142 * <code>DatabaseContext</code> service. This data source's URL
143 * points to SOffice temp directory where tables are copied from
144 * <code>TestDocuments</code> directory on every environment
146 * To create DataSource for MySQL database next parameters required
149 * <li><code>test.db.url</code> - URL to MySQL database.
150 * For example: <code>mysql://mercury:3306/api_current</code></li>
151 * <li><code>test.db.user</code> - user for MySQL database</li>
152 * <li><code>test.db.password</code> - password for MySQL database</li>
155 * @throws StatusException if DataSource can not be created or
159 protected void initialize ( TestParameters Param
, PrintWriter _log
)
160 throws StatusException
162 XMultiServiceFactory orb
= Param
.getMSF();
164 String tmpDir
= utils
.getOfficeTemp( orb
);
166 origDB
= util
.utils
.getFullTestDocName("TestDB/testDB.dbf");
168 dbTools
= new DBTools( orb
);
170 // creating DataSource and registering it in DatabaseContext
171 String dbURL
= (String
) Param
.get("test.db.url");
172 String dbUser
= (String
) Param
.get("test.db.user");
173 String dbPassword
= (String
) Param
.get("test.db.password");
175 log
.println("Creating and registering DataSource ...");
176 srcInf
= new DataSourceDescriptor( orb
);
177 if (dbURL
!= null && dbUser
!= null && dbPassword
!= null)
180 log
.println("dbURL = " + dbURL
);
181 log
.println("dbUSER = " + dbUser
);
182 log
.println("dbPASSWORD = " + dbPassword
);
183 //DataSource for mysql db
184 tableName
= "soffice_test_table";
185 srcInf
.URL
= "jdbc:" + dbURL
;
186 srcInf
.IsPasswordRequired
= Boolean
.TRUE
;
187 srcInf
.Password
= dbPassword
;
188 srcInf
.User
= dbUser
;
189 PropertyValue
[] propInfo
= new PropertyValue
[1];
190 propInfo
[0] = new PropertyValue();
191 propInfo
[0].Name
= "JavaDriverClass";
192 propInfo
[0].Value
= "org.gjt.mm.mysql.Driver";
193 srcInf
.Info
= propInfo
;
197 srcInf
.URL
= "sdbc:dbase:" + DBTools
.dirToUrl(tmpDir
);
199 m_dataSource
= srcInf
.createDataSource();
200 m_dataSource
.registerAs( dbSourceName
, true );
204 * Creating a Testenvironment for the interfaces to be tested.
205 * The database (DBF) file is copied from test document directory
206 * into SOffice temp dir with unique name for each environment
207 * creation. If the file cann't be copied (is not released)
208 * then another unique name is used (file name suffix incremented
211 * <code>com.sun.star.sdb.RowSet</code> service created and its
212 * source is all rows from the current copy of the table. Then
213 * row set command ("select all rows from a table") is executed
214 * and cursor is positioned to the first row. <p>
216 * Object relations created :
218 * <li> <code>'ORowSet.Connection'</code> for
219 * internal component test usage. Is used for
220 * closing connection when cleaning up environment. </li>
221 * <li> <code>'XRowSetApproveBroadcaster.ApproveChecker'</code> for
222 * {@link ifc.sdb._XRowSetApproveBroadcaster} interface
223 * implementation which made actions required </li>
224 * <li> <code>'CurrentRowData'</code> for
225 * {@link ifc.sdbc._XRow}, {@link ifc.sdbc._XRowUpdate} :
226 * exports types and values of the current row data.</li>
227 * <li> <code>'XColumnLocate.ColumnName'</code> for
228 * {@link ifc.sdbc._XColumnLocate} :
229 * the name of the first column of the table.</li>
230 * <li> <code>'XParameters.ParamValues'</code> for
231 * {@link ifc.sdbc._XParameters} :
232 * Collection of parameter types presented in the query. </li>
233 * <li> <code>'XRowUpdate.XRow'</code> for
234 * {@link ifc.sdbc._XRowUpdate} :
235 * <code>XRow</code> interface of the current component.</li>
236 * <li> <code>'XResultSetUpdate.UpdateTester'</code> for
237 * {@link ifc.sdbc._XResultSetUpdate} </li>
240 * @see com.sun.star.sdb.DatabaseContext
241 * @see com.sun.star.sdb.DataSource
244 protected TestEnvironment
createTestEnvironment(TestParameters Param
,
247 XMultiServiceFactory orb
= Param
.getMSF();
249 boolean envCreatedOK
= false ;
251 //initialize test table
256 DBTools
.DataSourceInfo legacyDescriptor
= dbTools
.newDataSourceInfo();
257 legacyDescriptor
.Name
= srcInf
.Name
;
258 legacyDescriptor
.User
= srcInf
.User
;
259 legacyDescriptor
.Password
= srcInf
.Password
;
260 legacyDescriptor
.Info
= srcInf
.Info
;
261 legacyDescriptor
.URL
= srcInf
.URL
;
262 legacyDescriptor
.IsPasswordRequired
= srcInf
.IsPasswordRequired
;
263 dbTools
.initTestTableUsingJDBC(tableName
, legacyDescriptor
);
265 catch(java
.sql
.SQLException e
)
267 throw new StatusException(e
, Status
.failed("Couldn't " +
268 " init test table. SQLException..."));
270 catch(java
.lang
.ClassNotFoundException e
)
272 throw new StatusException(e
, Status
.failed("Couldn't " +
273 "register mysql driver"));
280 String tempFolder
= utils
.getOfficeTemp( orb
);
283 tableName
= "ORowSet_tmp" + uniqueSuffix
;
284 oldF
= utils
.getFullURL(origDB
);
285 newF
= tempFolder
+ tableName
+ ".dbf";
287 while ( !utils
.tryOverwriteFile( orb
, oldF
, newF
) );
293 m_rowSet
= orb
.createInstance("com.sun.star.sdb.RowSet");
295 XPropertySet rowSetProps
= UnoRuntime
.queryInterface( XPropertySet
.class, m_rowSet
);
297 log
.println("Trying to open: " + tableName
);
299 rowSetProps
.setPropertyValue("DataSourceName", dbSourceName
);
300 rowSetProps
.setPropertyValue("Command", tableName
);
301 rowSetProps
.setPropertyValue("CommandType",
302 Integer
.valueOf(CommandType
.TABLE
));
304 final XRowSet rowSet
= UnoRuntime
.queryInterface( XRowSet
.class, m_rowSet
);
306 m_connection
= UnoRuntime
.queryInterface( XConnection
.class, rowSetProps
.getPropertyValue("ActiveConnection") );
308 XResultSet xRes
= UnoRuntime
.queryInterface( XResultSet
.class, m_rowSet
);
311 log
.println( "creating a new environment for object" );
312 TestEnvironment tEnv
= new TestEnvironment( (XInterface
)m_rowSet
);
314 // Adding obj relation for XRowSetApproveBroadcaster test
316 final XResultSet resultSet
= UnoRuntime
.queryInterface( XResultSet
.class, m_rowSet
);
317 final XResultSetUpdate resultSetUpdate
= UnoRuntime
.queryInterface( XResultSetUpdate
.class, m_rowSet
);
318 final XRowUpdate rowUpdate
= UnoRuntime
.queryInterface(XRowUpdate
.class, m_rowSet
);
319 final PrintWriter logF
= log
;
320 tEnv
.addObjRelation( "XRowSetApproveBroadcaster.ApproveChecker",
321 new ifc
.sdb
._XRowSetApproveBroadcaster
.RowSetApproveChecker()
323 public void moveCursor()
327 resultSet
.beforeFirst();
328 resultSet
.afterLast();
331 catch (com
.sun
.star
.sdbc
.SQLException e
)
333 logF
.println("### _XRowSetApproveBroadcaster.RowSetApproveChecker.moveCursor() :");
334 e
.printStackTrace(logF
);
335 throw new StatusException( "RowSetApproveChecker.moveCursor failed", e
);
338 public RowChangeEvent
changeRow()
343 rowUpdate
.updateString(1, "ORowSetTest2");
344 resultSetUpdate
.updateRow();
346 catch (com
.sun
.star
.sdbc
.SQLException e
)
348 logF
.println("### _XRowSetApproveBroadcaster.RowSetApproveChecker.changeRow() :");
349 e
.printStackTrace(logF
);
350 throw new StatusException( "RowSetApproveChecker.changeRow failed", e
);
352 RowChangeEvent ev
= new RowChangeEvent();
353 ev
.Action
= com
.sun
.star
.sdb
.RowChangeAction
.UPDATE
;
358 public void changeRowSet()
362 // since we gave the row set a parametrized statement, we need to ensure the
363 // parameter is actually filled, otherwise we would get an empty result set,
364 // which would imply some further tests failing
365 XParameters rowSetParams
= UnoRuntime
.queryInterface( XParameters
.class, resultSet
);
366 rowSetParams
.setString( 1, "String2" );
370 catch (com
.sun
.star
.sdbc
.SQLException e
)
372 logF
.println("### _XRowSetApproveBroadcaster.RowSetApproveChecker.changeRowSet() :");
373 e
.printStackTrace(logF
);
374 throw new StatusException( "RowSetApproveChecker.changeRowSet failed", e
);
380 // Adding relations for XRow as a Vector with all data
381 // of current row of RowSet.
383 ArrayList
<Object
> rowData
= new ArrayList
<Object
>();
385 for (int i
= 0; i
< DBTools
.TST_TABLE_VALUES
[0].length
; i
++) {
386 rowData
.add(DBTools
.TST_TABLE_VALUES
[0][i
]);
389 // here XRef must be added
390 // here XBlob must be added
391 // here XClob must be added
392 // here XArray must be added
394 tEnv
.addObjRelation("CurrentRowData", rowData
);
396 // Adding relation for XColumnLocate ifc test
397 tEnv
.addObjRelation( "XColumnLocate.ColumnName", DBTools
.TST_STRING_F
);
399 // Adding relation for XCompletedExecution
400 tEnv
.addObjRelation( "InteractionHandlerChecker", new InteractionHandlerImpl() );
403 String sqlCommand
= isMySQLDB
404 ?
"SELECT Column0 FROM soffice_test_table WHERE ( ( Column0 = :param1 ) )"
405 : "SELECT \"_TEXT\" FROM \"" + tableName
+ "\" WHERE ( ( \"_TEXT\" = :param1 ) )";
406 rowSetProps
.setPropertyValue( "DataSourceName", dbSourceName
);
407 rowSetProps
.setPropertyValue( "Command", sqlCommand
);
408 rowSetProps
.setPropertyValue( "CommandType", Integer
.valueOf(CommandType
.COMMAND
) );
412 throw new StatusException( "setting up the RowSet with a parametrized command failed", e
);
415 // Adding relation for XParameters ifc test
416 tEnv
.addObjRelation( "XParameters.ParamValues", new ArrayList
<String
>() );
418 // Adding relation for XRowUpdate
419 final XRow row
= UnoRuntime
.queryInterface( XRow
.class, m_rowSet
);
420 tEnv
.addObjRelation("XRowUpdate.XRow", row
);
422 // Adding relation for XResultSetUpdate
424 final XResultSet resultSet
= UnoRuntime
.queryInterface( XResultSet
.class, m_rowSet
);
425 final XRowUpdate rowUpdate
= UnoRuntime
.queryInterface( XRowUpdate
.class, m_rowSet
);
427 tEnv
.addObjRelation("XResultSetUpdate.UpdateTester",
428 new ifc
.sdbc
._XResultSetUpdate
.UpdateTester()
430 String lastUpdate
= null ;
432 public int rowCount() throws SQLException
434 int prevPos
= resultSet
.getRow();
436 int count
= resultSet
.getRow();
437 resultSet
.absolute(prevPos
);
442 public void update() throws SQLException
444 lastUpdate
= row
.getString(1);
446 rowUpdate
.updateString(1, lastUpdate
);
449 public boolean wasUpdated() throws SQLException
451 String getStr
= row
.getString(1);
452 return lastUpdate
.equals(getStr
);
455 public int currentRow() throws SQLException
457 return resultSet
.getRow();
463 envCreatedOK
= true ;
467 catch(com
.sun
.star
.uno
.Exception e
)
469 log
.println( "couldn't set up test environment:" );
470 e
.printStackTrace(log
);
473 if ( m_connection
!= null )
474 m_connection
.close();
479 throw new StatusException( "couldn't set up test environment", e
);
487 m_connection
.close();
495 } // finish method getTestEnvironment
498 * Closes connection of <code>RowSet</code> instance created.
501 protected void cleanup( TestParameters Param
, PrintWriter log
)
506 doing
= "revoking data source registration";
507 log
.println( doing
);
508 m_dataSource
.revokeRegistration();
510 doing
= "closing database document";
511 log
.println( doing
);
512 XModel databaseDocModel
= UnoRuntime
.queryInterface( XModel
.class,
513 m_dataSource
.getDatabaseDocument().getDatabaseDocument() );
514 String documentFile
= databaseDocModel
.getURL();
516 XCloseable closeModel
= UnoRuntime
.queryInterface( XCloseable
.class,
517 m_dataSource
.getDatabaseDocument().getDatabaseDocument() );
518 closeModel
.close( true );
520 if ( m_rowSet
!= null )
522 doing
= "disposing row set";
523 log
.println( doing
);
524 XComponent rowSetComponent
= UnoRuntime
.queryInterface( XComponent
.class, m_rowSet
);
525 rowSetComponent
.dispose();
530 doing
= "closing connection";
531 log
.println( doing
);
532 m_connection
.close();
534 catch (com
.sun
.star
.lang
.DisposedException e
)
536 log
.println( "already closed - okay." );
539 doing
= "deleting database file (" + documentFile
+ ")";
540 log
.println( doing
);
541 impl_deleteFile( documentFile
);
543 if ( m_tableFile
!= null )
545 doing
= "deleting dBase table file (" + m_tableFile
+ ")";
546 log
.println( doing
);
547 impl_deleteFile( m_tableFile
);
550 catch (com
.sun
.star
.uno
.Exception e
)
552 log
.println( "error: ");
553 e
.printStackTrace(log
);
557 private final void impl_deleteFile( final String _file
)
559 java
.io
.File file
= new java
.io
.File( _file
);
566 * Implementation of interface _XCompletedExecution.CheckInteractionHandler
567 * for the XCompletedExecution test
568 * @see ifc.sdb._XCompletedExecution
570 private class InteractionHandlerImpl
implements _XCompletedExecution
.CheckInteractionHandler
{
571 private boolean handlerWasUsed
= false;
572 private PrintWriter log
= new PrintWriter(System
.out
);
574 public boolean checkInteractionHandler() {
575 return handlerWasUsed
;
578 public void handle(XInteractionRequest xInteractionRequest
) {
579 log
.println("### _XCompletedExecution.InteractionHandlerImpl: handle called.");
580 boolean abort
= false;
582 Object o
= xInteractionRequest
.getRequest();
583 if (o
instanceof ParametersRequest
) {
585 else if (o
instanceof AuthenticationRequest
) {
586 log
.println("### The request in XCompletedExecution is of type 'AuthenticationRequest'");
587 log
.println("### This is not implemented in ORowSet.InteractionHandlerImpl test -> abort.");
591 log
.println("### Unknown request:" + o
.toString());
592 log
.println("### This is not implemented in ORowSet.InteractionHandlerImpl test -> abort.");
596 XInteractionContinuation
[]xCont
= xInteractionRequest
.getContinuations();
597 XInteractionSupplyParameters xParamCallback
= null;
598 for(int i
=0; i
<xCont
.length
; i
++) {
600 XInteractionAbort xAbort
= null;
601 xAbort
= UnoRuntime
.queryInterface(XInteractionAbort
.class, xCont
[i
]);
607 xParamCallback
= UnoRuntime
.queryInterface(XInteractionSupplyParameters
.class, xCont
[i
]);
608 if (xParamCallback
!= null)
612 if (xParamCallback
!= null) {
613 log
.println("### _XCompletedExecution.InteractionHandlerImpl: supplying parameters.");
614 handlerWasUsed
= true;
615 PropertyValue
[] prop
= new PropertyValue
[1];
616 prop
[0] = new PropertyValue();
617 prop
[0].Name
= "param1";
618 prop
[0].Value
= "Hi.";
620 xParamCallback
.setParameters(prop
);
621 xParamCallback
.select();
623 else { // we should never reach this: abort has to be true first.
624 log
.println("### _XCompletedExecution.InteractionHandlerImpl: Got no " +
625 "'XInteractionSupplyParameters' and no 'XInteractionAbort'.");
629 public void setLog(PrintWriter log
) {