1*e6e6073dSLiu Zhe /************************************************************** 2*e6e6073dSLiu Zhe * 3*e6e6073dSLiu Zhe * Licensed to the Apache Software Foundation (ASF) under one 4*e6e6073dSLiu Zhe * or more contributor license agreements. See the NOTICE file 5*e6e6073dSLiu Zhe * distributed with this work for additional information 6*e6e6073dSLiu Zhe * regarding copyright ownership. The ASF licenses this file 7*e6e6073dSLiu Zhe * to you under the Apache License, Version 2.0 (the 8*e6e6073dSLiu Zhe * "License"); you may not use this file except in compliance 9*e6e6073dSLiu Zhe * with the License. You may obtain a copy of the License at 10*e6e6073dSLiu Zhe * 11*e6e6073dSLiu Zhe * http://www.apache.org/licenses/LICENSE-2.0 12*e6e6073dSLiu Zhe * 13*e6e6073dSLiu Zhe * Unless required by applicable law or agreed to in writing, 14*e6e6073dSLiu Zhe * software distributed under the License is distributed on an 15*e6e6073dSLiu Zhe * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*e6e6073dSLiu Zhe * KIND, either express or implied. See the License for the 17*e6e6073dSLiu Zhe * specific language governing permissions and limitations 18*e6e6073dSLiu Zhe * under the License. 19*e6e6073dSLiu Zhe * 20*e6e6073dSLiu Zhe *************************************************************/ 21*e6e6073dSLiu Zhe 22*e6e6073dSLiu Zhe package testlib.uno; 23*e6e6073dSLiu Zhe 24*e6e6073dSLiu Zhe import com.sun.star.beans.PropertyValue; 25*e6e6073dSLiu Zhe import com.sun.star.beans.PropertyState; 26*e6e6073dSLiu Zhe import com.sun.star.beans.XPropertySet; 27*e6e6073dSLiu Zhe import com.sun.star.container.ElementExistException; 28*e6e6073dSLiu Zhe import com.sun.star.container.XNameAccess; 29*e6e6073dSLiu Zhe import com.sun.star.frame.XStorable; 30*e6e6073dSLiu Zhe import com.sun.star.lang.XMultiServiceFactory; 31*e6e6073dSLiu Zhe import com.sun.star.sdb.XDocumentDataSource; 32*e6e6073dSLiu Zhe import com.sun.star.sdb.XOfficeDatabaseDocument; 33*e6e6073dSLiu Zhe import com.sun.star.sdbc.SQLException; 34*e6e6073dSLiu Zhe import com.sun.star.sdbc.XCloseable; 35*e6e6073dSLiu Zhe import com.sun.star.sdbc.XConnection; 36*e6e6073dSLiu Zhe import com.sun.star.sdbc.XDataSource; 37*e6e6073dSLiu Zhe import com.sun.star.sdbc.XStatement; 38*e6e6073dSLiu Zhe import com.sun.star.sdbcx.XAppend; 39*e6e6073dSLiu Zhe import com.sun.star.sdbcx.XTablesSupplier; 40*e6e6073dSLiu Zhe import com.sun.star.uno.UnoRuntime; 41*e6e6073dSLiu Zhe import com.sun.star.util.CloseVetoException; 42*e6e6073dSLiu Zhe 43*e6e6073dSLiu Zhe import java.util.HashMap; 44*e6e6073dSLiu Zhe import java.util.Iterator; 45*e6e6073dSLiu Zhe import java.util.Set; 46*e6e6073dSLiu Zhe import java.io.File; 47*e6e6073dSLiu Zhe 48*e6e6073dSLiu Zhe import org.openoffice.test.common.FileUtil; 49*e6e6073dSLiu Zhe 50*e6e6073dSLiu Zhe 51*e6e6073dSLiu Zhe public class DBUtil { 52*e6e6073dSLiu Zhe // the service factory 53*e6e6073dSLiu Zhe protected static XMultiServiceFactory m_orb; 54*e6e6073dSLiu Zhe // the URL of the temporary file used for the database document 55*e6e6073dSLiu Zhe protected static String m_databaseDocumentFile; 56*e6e6073dSLiu Zhe // the database document 57*e6e6073dSLiu Zhe protected static XOfficeDatabaseDocument m_databaseDocument; 58*e6e6073dSLiu Zhe // the data source belonging to the database document 59*e6e6073dSLiu Zhe protected static XDataSource m_dataSource; 60*e6e6073dSLiu Zhe // the default connection 61*e6e6073dSLiu Zhe protected static XConnection m_connection; 62*e6e6073dSLiu Zhe 63*e6e6073dSLiu Zhe 64*e6e6073dSLiu Zhe static public void createNewDocument(final XMultiServiceFactory orb) 65*e6e6073dSLiu Zhe throws Exception { 66*e6e6073dSLiu Zhe m_orb = orb; 67*e6e6073dSLiu Zhe createDBDocument(); 68*e6e6073dSLiu Zhe } 69*e6e6073dSLiu Zhe 70*e6e6073dSLiu Zhe static public void loadNewDocument(final XMultiServiceFactory orb, 71*e6e6073dSLiu Zhe final String _existingDocumentURL) throws Exception { 72*e6e6073dSLiu Zhe m_orb = orb; 73*e6e6073dSLiu Zhe getDocument(_existingDocumentURL); 74*e6e6073dSLiu Zhe } 75*e6e6073dSLiu Zhe 76*e6e6073dSLiu Zhe /** 77*e6e6073dSLiu Zhe * creates an empty database document in a temporary location 78*e6e6073dSLiu Zhe */ 79*e6e6073dSLiu Zhe public static void createDBDocument() throws Exception { 80*e6e6073dSLiu Zhe final File documentFile = File.createTempFile("testdb", ".odb"); 81*e6e6073dSLiu Zhe if (documentFile.exists()) 82*e6e6073dSLiu Zhe documentFile.delete(); 83*e6e6073dSLiu Zhe m_databaseDocumentFile = FileUtil.getUrl(documentFile); 84*e6e6073dSLiu Zhe m_databaseDocument = (XOfficeDatabaseDocument) UnoRuntime 85*e6e6073dSLiu Zhe .queryInterface( 86*e6e6073dSLiu Zhe XOfficeDatabaseDocument.class, 87*e6e6073dSLiu Zhe m_orb.createInstance("com.sun.star.sdb.OfficeDatabaseDocument")); 88*e6e6073dSLiu Zhe m_dataSource = m_databaseDocument.getDataSource(); 89*e6e6073dSLiu Zhe 90*e6e6073dSLiu Zhe final XPropertySet dsProperties = (XPropertySet) UnoRuntime 91*e6e6073dSLiu Zhe .queryInterface(XPropertySet.class, 92*e6e6073dSLiu Zhe m_databaseDocument.getDataSource()); 93*e6e6073dSLiu Zhe dsProperties.setPropertyValue("URL", "sdbc:embedded:hsqldb"); 94*e6e6073dSLiu Zhe 95*e6e6073dSLiu Zhe final XStorable storable = (XStorable) UnoRuntime.queryInterface( 96*e6e6073dSLiu Zhe XStorable.class, m_databaseDocument); 97*e6e6073dSLiu Zhe storable.storeAsURL(m_databaseDocumentFile, 98*e6e6073dSLiu Zhe new PropertyValue[] { new PropertyValue("PickListEntry", 0, 99*e6e6073dSLiu Zhe false, PropertyState.DIRECT_VALUE) }); 100*e6e6073dSLiu Zhe } 101*e6e6073dSLiu Zhe 102*e6e6073dSLiu Zhe 103*e6e6073dSLiu Zhe public static void getDocument(final String _docURL) throws Exception { 104*e6e6073dSLiu Zhe m_databaseDocumentFile = _docURL; 105*e6e6073dSLiu Zhe 106*e6e6073dSLiu Zhe final XNameAccess dbContext = UnoRuntime.queryInterface( 107*e6e6073dSLiu Zhe XNameAccess.class, 108*e6e6073dSLiu Zhe m_orb.createInstance("com.sun.star.sdb.DatabaseContext")); 109*e6e6073dSLiu Zhe final XDocumentDataSource dataSource = UnoRuntime.queryInterface( 110*e6e6073dSLiu Zhe XDocumentDataSource.class, dbContext.getByName(_docURL)); 111*e6e6073dSLiu Zhe 112*e6e6073dSLiu Zhe m_databaseDocument = dataSource.getDatabaseDocument(); 113*e6e6073dSLiu Zhe m_dataSource = m_databaseDocument.getDataSource(); 114*e6e6073dSLiu Zhe } 115*e6e6073dSLiu Zhe 116*e6e6073dSLiu Zhe /** 117*e6e6073dSLiu Zhe * drops the table with a given name 118*e6e6073dSLiu Zhe * 119*e6e6073dSLiu Zhe * @param _name 120*e6e6073dSLiu Zhe * the name of the table to drop 121*e6e6073dSLiu Zhe * @param _ifExists 122*e6e6073dSLiu Zhe * TRUE if it should be dropped only when it exists. 123*e6e6073dSLiu Zhe */ 124*e6e6073dSLiu Zhe static public void dropTable(final String _name, final boolean _ifExists) 125*e6e6073dSLiu Zhe throws SQLException { 126*e6e6073dSLiu Zhe final StringBuffer dropStatement = new StringBuffer("DROP TABLE \""); 127*e6e6073dSLiu Zhe dropStatement.append(_name); 128*e6e6073dSLiu Zhe if (_ifExists) { 129*e6e6073dSLiu Zhe dropStatement.append("\" IF EXISTS"); 130*e6e6073dSLiu Zhe } 131*e6e6073dSLiu Zhe executeSQL(dropStatement.toString()); 132*e6e6073dSLiu Zhe } 133*e6e6073dSLiu Zhe 134*e6e6073dSLiu Zhe static public void createTable(String _name, 135*e6e6073dSLiu Zhe HsqlColumnDescriptor[] _columns, final boolean _dropIfExists) 136*e6e6073dSLiu Zhe throws SQLException { 137*e6e6073dSLiu Zhe if (_dropIfExists) { 138*e6e6073dSLiu Zhe dropTable(_name, true); 139*e6e6073dSLiu Zhe } 140*e6e6073dSLiu Zhe createTable(_name, _columns); 141*e6e6073dSLiu Zhe } 142*e6e6073dSLiu Zhe 143*e6e6073dSLiu Zhe /** 144*e6e6073dSLiu Zhe * creates a table 145*e6e6073dSLiu Zhe */ 146*e6e6073dSLiu Zhe static public void createTable(String _name, HsqlColumnDescriptor[] _columns) 147*e6e6073dSLiu Zhe throws SQLException { 148*e6e6073dSLiu Zhe StringBuffer createStatement = new StringBuffer( 149*e6e6073dSLiu Zhe "CREATE CACHED TABLE \""); 150*e6e6073dSLiu Zhe createStatement.append(_name); 151*e6e6073dSLiu Zhe createStatement.append("\" ( "); 152*e6e6073dSLiu Zhe 153*e6e6073dSLiu Zhe String primaryKeyList = ""; 154*e6e6073dSLiu Zhe 155*e6e6073dSLiu Zhe final HashMap foreignKeys = new HashMap(); 156*e6e6073dSLiu Zhe final HashMap foreignKeyRefs = new HashMap(); 157*e6e6073dSLiu Zhe 158*e6e6073dSLiu Zhe final HsqlColumnDescriptor[] columns = _columns; 159*e6e6073dSLiu Zhe for (int i = 0; i < columns.length; ++i) { 160*e6e6073dSLiu Zhe if (i > 0) { 161*e6e6073dSLiu Zhe createStatement.append(", "); 162*e6e6073dSLiu Zhe } 163*e6e6073dSLiu Zhe 164*e6e6073dSLiu Zhe createStatement.append("\"" + columns[i].getName()); 165*e6e6073dSLiu Zhe createStatement.append("\" " + columns[i].getTypeName()); 166*e6e6073dSLiu Zhe 167*e6e6073dSLiu Zhe if (columns[i].isRequired()) { 168*e6e6073dSLiu Zhe createStatement.append(" NOT NULL"); 169*e6e6073dSLiu Zhe } 170*e6e6073dSLiu Zhe 171*e6e6073dSLiu Zhe if (columns[i].isPrimaryKey()) { 172*e6e6073dSLiu Zhe if (primaryKeyList.length() > 0) { 173*e6e6073dSLiu Zhe primaryKeyList += ", "; 174*e6e6073dSLiu Zhe } 175*e6e6073dSLiu Zhe primaryKeyList += "\"" + columns[i].getName() + "\""; 176*e6e6073dSLiu Zhe } 177*e6e6073dSLiu Zhe 178*e6e6073dSLiu Zhe if (columns[i].isForeignKey()) { 179*e6e6073dSLiu Zhe final String foreignTable = columns[i].getForeignTable(); 180*e6e6073dSLiu Zhe 181*e6e6073dSLiu Zhe String foreignKeysForTable = foreignKeys 182*e6e6073dSLiu Zhe .containsKey(foreignTable) ? (String) foreignKeys 183*e6e6073dSLiu Zhe .get(foreignTable) : ""; 184*e6e6073dSLiu Zhe if (foreignKeysForTable.length() > 0) { 185*e6e6073dSLiu Zhe foreignKeysForTable += ", "; 186*e6e6073dSLiu Zhe } 187*e6e6073dSLiu Zhe foreignKeysForTable += "\"" + columns[i].getName() + "\""; 188*e6e6073dSLiu Zhe foreignKeys.put(foreignTable, foreignKeysForTable); 189*e6e6073dSLiu Zhe 190*e6e6073dSLiu Zhe final StringBuffer foreignKeyRefsForTable = new StringBuffer( 191*e6e6073dSLiu Zhe foreignKeyRefs.containsKey(foreignTable) ? (String) foreignKeyRefs 192*e6e6073dSLiu Zhe .get(foreignTable) : ""); 193*e6e6073dSLiu Zhe if (foreignKeyRefsForTable.length() > 0) { 194*e6e6073dSLiu Zhe foreignKeyRefsForTable.append(", "); 195*e6e6073dSLiu Zhe } 196*e6e6073dSLiu Zhe foreignKeyRefsForTable.append("\"" 197*e6e6073dSLiu Zhe + columns[i].getForeignColumn() + "\""); 198*e6e6073dSLiu Zhe foreignKeyRefs.put(foreignTable, 199*e6e6073dSLiu Zhe foreignKeyRefsForTable.toString()); 200*e6e6073dSLiu Zhe } 201*e6e6073dSLiu Zhe } 202*e6e6073dSLiu Zhe 203*e6e6073dSLiu Zhe if (primaryKeyList.length() > 0) { 204*e6e6073dSLiu Zhe createStatement.append(", PRIMARY KEY ("); 205*e6e6073dSLiu Zhe createStatement.append(primaryKeyList); 206*e6e6073dSLiu Zhe createStatement.append(')'); 207*e6e6073dSLiu Zhe } 208*e6e6073dSLiu Zhe 209*e6e6073dSLiu Zhe final Set foreignKeyTables = foreignKeys.keySet(); 210*e6e6073dSLiu Zhe for (final Iterator foreignKey = foreignKeyTables.iterator(); foreignKey 211*e6e6073dSLiu Zhe .hasNext();) { 212*e6e6073dSLiu Zhe final String foreignTable = (String) foreignKey.next(); 213*e6e6073dSLiu Zhe 214*e6e6073dSLiu Zhe createStatement.append(", FOREIGN KEY ("); 215*e6e6073dSLiu Zhe createStatement.append((String) foreignKeys.get(foreignTable)); 216*e6e6073dSLiu Zhe createStatement.append(") REFERENCES \""); 217*e6e6073dSLiu Zhe createStatement.append(foreignTable); 218*e6e6073dSLiu Zhe createStatement.append("\"("); 219*e6e6073dSLiu Zhe createStatement.append((String) foreignKeyRefs.get(foreignTable)); 220*e6e6073dSLiu Zhe createStatement.append(')'); 221*e6e6073dSLiu Zhe } 222*e6e6073dSLiu Zhe 223*e6e6073dSLiu Zhe createStatement.append(')'); 224*e6e6073dSLiu Zhe 225*e6e6073dSLiu Zhe // System.err.println( createStatement ); 226*e6e6073dSLiu Zhe executeSQL(createStatement.toString()); 227*e6e6073dSLiu Zhe } 228*e6e6073dSLiu Zhe 229*e6e6073dSLiu Zhe 230*e6e6073dSLiu Zhe /** 231*e6e6073dSLiu Zhe * executes the given SQL statement via the defaultConnection 232*e6e6073dSLiu Zhe */ 233*e6e6073dSLiu Zhe static public void executeSQL(final String statementString) 234*e6e6073dSLiu Zhe throws SQLException { 235*e6e6073dSLiu Zhe final XStatement statement = defaultConnection().createStatement(); 236*e6e6073dSLiu Zhe statement.execute(statementString); 237*e6e6073dSLiu Zhe } 238*e6e6073dSLiu Zhe 239*e6e6073dSLiu Zhe /** 240*e6e6073dSLiu Zhe * returns a connection to the database 241*e6e6073dSLiu Zhe * 242*e6e6073dSLiu Zhe * Multiple calls to this method return the same connection. The 243*e6e6073dSLiu Zhe * DbaseDatabase object keeps the ownership of the connection, so you don't 244*e6e6073dSLiu Zhe * need to (and should not) dispose/close it. 245*e6e6073dSLiu Zhe */ 246*e6e6073dSLiu Zhe static public XConnection defaultConnection() throws SQLException { 247*e6e6073dSLiu Zhe if (m_connection == null) 248*e6e6073dSLiu Zhe m_connection = m_databaseDocument.getDataSource().getConnection("", 249*e6e6073dSLiu Zhe ""); 250*e6e6073dSLiu Zhe 251*e6e6073dSLiu Zhe return m_connection; 252*e6e6073dSLiu Zhe } 253*e6e6073dSLiu Zhe 254*e6e6073dSLiu Zhe /** 255*e6e6073dSLiu Zhe * closes the database document 256*e6e6073dSLiu Zhe * 257*e6e6073dSLiu Zhe * Any CloseVetoExceptions fired by third parties are ignored, and any 258*e6e6073dSLiu Zhe * reference to the database document is released. 259*e6e6073dSLiu Zhe */ 260*e6e6073dSLiu Zhe static public void close() { 261*e6e6073dSLiu Zhe // close connection 262*e6e6073dSLiu Zhe final XCloseable closeConn = UnoRuntime.queryInterface( 263*e6e6073dSLiu Zhe XCloseable.class, m_connection != null ? m_connection : null); 264*e6e6073dSLiu Zhe if (closeConn != null) { 265*e6e6073dSLiu Zhe try { 266*e6e6073dSLiu Zhe closeConn.close(); 267*e6e6073dSLiu Zhe } catch (SQLException e) { 268*e6e6073dSLiu Zhe } 269*e6e6073dSLiu Zhe } 270*e6e6073dSLiu Zhe m_connection = null; 271*e6e6073dSLiu Zhe 272*e6e6073dSLiu Zhe // close document 273*e6e6073dSLiu Zhe final com.sun.star.util.XCloseable closeDoc = UnoRuntime 274*e6e6073dSLiu Zhe .queryInterface(com.sun.star.util.XCloseable.class, 275*e6e6073dSLiu Zhe m_databaseDocument); 276*e6e6073dSLiu Zhe if (closeDoc != null) { 277*e6e6073dSLiu Zhe try { 278*e6e6073dSLiu Zhe closeDoc.close(true); 279*e6e6073dSLiu Zhe } catch (CloseVetoException e) { 280*e6e6073dSLiu Zhe } 281*e6e6073dSLiu Zhe } 282*e6e6073dSLiu Zhe m_databaseDocument = null; 283*e6e6073dSLiu Zhe } 284*e6e6073dSLiu Zhe 285*e6e6073dSLiu Zhe /** 286*e6e6073dSLiu Zhe * returns the underlying database document 287*e6e6073dSLiu Zhe */ 288*e6e6073dSLiu Zhe static public XOfficeDatabaseDocument getDatabaseDocument() { 289*e6e6073dSLiu Zhe return m_databaseDocument; 290*e6e6073dSLiu Zhe } 291*e6e6073dSLiu Zhe 292*e6e6073dSLiu Zhe static public String getDocumentURL() { 293*e6e6073dSLiu Zhe return m_databaseDocumentFile; 294*e6e6073dSLiu Zhe } 295*e6e6073dSLiu Zhe } 296