xref: /AOO41X/test/testuno/source/testlib/uno/DBUtil.java (revision e6e6073ddaad3a04a985e8f05823629a884eb203)
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