1c3ab0d6aSAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3c3ab0d6aSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4c3ab0d6aSAndrew Rist * or more contributor license agreements. See the NOTICE file 5c3ab0d6aSAndrew Rist * distributed with this work for additional information 6c3ab0d6aSAndrew Rist * regarding copyright ownership. The ASF licenses this file 7c3ab0d6aSAndrew Rist * to you under the Apache License, Version 2.0 (the 8c3ab0d6aSAndrew Rist * "License"); you may not use this file except in compliance 9c3ab0d6aSAndrew Rist * with the License. You may obtain a copy of the License at 10c3ab0d6aSAndrew Rist * 11c3ab0d6aSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12c3ab0d6aSAndrew Rist * 13c3ab0d6aSAndrew Rist * Unless required by applicable law or agreed to in writing, 14c3ab0d6aSAndrew Rist * software distributed under the License is distributed on an 15c3ab0d6aSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16c3ab0d6aSAndrew Rist * KIND, either express or implied. See the License for the 17c3ab0d6aSAndrew Rist * specific language governing permissions and limitations 18c3ab0d6aSAndrew Rist * under the License. 19c3ab0d6aSAndrew Rist * 20c3ab0d6aSAndrew Rist *************************************************************/ 21c3ab0d6aSAndrew Rist 22c3ab0d6aSAndrew Rist 23cdf0e10cSrcweir package connectivity.tools; 24cdf0e10cSrcweir 25cdf0e10cSrcweir import com.sun.star.beans.PropertyValue; 26cdf0e10cSrcweir import com.sun.star.beans.PropertyState; 27cdf0e10cSrcweir import com.sun.star.container.ElementExistException; 28cdf0e10cSrcweir import com.sun.star.container.NoSuchElementException; 29cdf0e10cSrcweir import com.sun.star.frame.XComponentLoader; 30cdf0e10cSrcweir import com.sun.star.frame.XController; 31cdf0e10cSrcweir import com.sun.star.frame.XModel; 32cdf0e10cSrcweir import com.sun.star.io.IOException; 33cdf0e10cSrcweir import com.sun.star.lang.IllegalArgumentException; 34cdf0e10cSrcweir import com.sun.star.lang.WrappedTargetException; 35cdf0e10cSrcweir import com.sun.star.lang.XComponent; 36cdf0e10cSrcweir import com.sun.star.lang.XMultiServiceFactory; 37cdf0e10cSrcweir import com.sun.star.sdb.XSingleSelectQueryComposer; 38cdf0e10cSrcweir import com.sun.star.sdb.application.XDatabaseDocumentUI; 39cdf0e10cSrcweir import com.sun.star.sdbc.SQLException; 40cdf0e10cSrcweir import com.sun.star.sdbcx.XTablesSupplier; 41cdf0e10cSrcweir import com.sun.star.uno.UnoRuntime; 42cdf0e10cSrcweir import com.sun.star.util.XRefreshable; 43cdf0e10cSrcweir import connectivity.tools.sdb.Connection; 44cdf0e10cSrcweir 45cdf0e10cSrcweir /** implements a small Customer Relationship Management database 46cdf0e10cSrcweir * 47cdf0e10cSrcweir * Not finished, by far. Feel free to add features as you need them. 48cdf0e10cSrcweir */ 49cdf0e10cSrcweir public class CRMDatabase 50cdf0e10cSrcweir { 51cdf0e10cSrcweir private static final String INTEGER = "INTEGER"; 52cdf0e10cSrcweir private static final String VARCHAR50 = "VARCHAR(50)"; 53cdf0e10cSrcweir private final XMultiServiceFactory m_orb; 54cdf0e10cSrcweir private final HsqlDatabase m_database; 55cdf0e10cSrcweir private final DataSource m_dataSource; 56cdf0e10cSrcweir private final Connection m_connection; 57cdf0e10cSrcweir 58cdf0e10cSrcweir /** constructs the CRM database 59cdf0e10cSrcweir */ CRMDatabase( XMultiServiceFactory _orb, boolean _withUI )60cdf0e10cSrcweir public CRMDatabase( XMultiServiceFactory _orb, boolean _withUI ) throws Exception 61cdf0e10cSrcweir { 62cdf0e10cSrcweir m_orb = _orb; 63cdf0e10cSrcweir 64cdf0e10cSrcweir m_database = new HsqlDatabase( m_orb ); 65cdf0e10cSrcweir m_dataSource = m_database.getDataSource(); 66cdf0e10cSrcweir 67cdf0e10cSrcweir if ( _withUI ) 68cdf0e10cSrcweir { 69cdf0e10cSrcweir final XComponentLoader loader = UnoRuntime.queryInterface( XComponentLoader.class, 70cdf0e10cSrcweir m_orb.createInstance( "com.sun.star.frame.Desktop" ) ); 71cdf0e10cSrcweir PropertyValue[] loadArgs = new PropertyValue[] { 72cdf0e10cSrcweir new PropertyValue( "PickListEntry", 0, false, PropertyState.DIRECT_VALUE ) 73cdf0e10cSrcweir }; 74cdf0e10cSrcweir loader.loadComponentFromURL( m_database.getDocumentURL(), "_blank", 0, loadArgs ); 75cdf0e10cSrcweir getDocumentUI().connect(); 76cdf0e10cSrcweir m_connection = new Connection( getDocumentUI().getActiveConnection() ); 77cdf0e10cSrcweir } 78cdf0e10cSrcweir else 79cdf0e10cSrcweir { 80cdf0e10cSrcweir m_connection = m_database.defaultConnection(); 81cdf0e10cSrcweir } 82cdf0e10cSrcweir 83cdf0e10cSrcweir createTables(); 84cdf0e10cSrcweir createQueries(); 85cdf0e10cSrcweir } 86cdf0e10cSrcweir 87cdf0e10cSrcweir /** 88cdf0e10cSrcweir * creates a CRMDatabase from an existing document, given by URL 89cdf0e10cSrcweir * @param _orb 90cdf0e10cSrcweir * @param _existingDocumentURL 91*e6b649b5SPedro Giffuni * @throws Exception 92cdf0e10cSrcweir */ CRMDatabase( XMultiServiceFactory _orb, final String _existingDocumentURL )93cdf0e10cSrcweir public CRMDatabase( XMultiServiceFactory _orb, final String _existingDocumentURL ) throws Exception 94cdf0e10cSrcweir { 95cdf0e10cSrcweir m_orb = _orb; 96cdf0e10cSrcweir 97cdf0e10cSrcweir m_database = new HsqlDatabase( m_orb, _existingDocumentURL ); 98cdf0e10cSrcweir m_dataSource = m_database.getDataSource(); 99cdf0e10cSrcweir m_connection = m_database.defaultConnection(); 100cdf0e10cSrcweir } 101cdf0e10cSrcweir 102cdf0e10cSrcweir // -------------------------------------------------------------------------------------------------------- 103cdf0e10cSrcweir /** returns the database document underlying the CRM database 104cdf0e10cSrcweir */ getDatabase()105cdf0e10cSrcweir public final HsqlDatabase getDatabase() 106cdf0e10cSrcweir { 107cdf0e10cSrcweir return m_database; 108cdf0e10cSrcweir } 109cdf0e10cSrcweir 110cdf0e10cSrcweir // -------------------------------------------------------------------------------------------------------- 111cdf0e10cSrcweir /** returns the default connection to the database 112cdf0e10cSrcweir */ getConnection()113cdf0e10cSrcweir public final Connection getConnection() 114cdf0e10cSrcweir { 115cdf0e10cSrcweir return m_connection; 116cdf0e10cSrcweir } 117cdf0e10cSrcweir 118cdf0e10cSrcweir // -------------------------------------------------------------------------------------------------------- saveAndClose()119cdf0e10cSrcweir public void saveAndClose() throws SQLException, IOException 120cdf0e10cSrcweir { 121cdf0e10cSrcweir XDatabaseDocumentUI ui = getDocumentUI(); 122cdf0e10cSrcweir if ( ui != null ) 123cdf0e10cSrcweir ui.closeSubComponents(); 124cdf0e10cSrcweir m_database.store(); 125cdf0e10cSrcweir m_database.closeAndDelete(); 126cdf0e10cSrcweir } 127cdf0e10cSrcweir 128cdf0e10cSrcweir // -------------------------------------------------------------------------------------------------------- getDocumentUI()129cdf0e10cSrcweir public XDatabaseDocumentUI getDocumentUI() 130cdf0e10cSrcweir { 131cdf0e10cSrcweir XModel docModel = UnoRuntime.queryInterface( XModel.class, m_database.getDatabaseDocument() ); 132cdf0e10cSrcweir return UnoRuntime.queryInterface( XDatabaseDocumentUI.class, docModel.getCurrentController() ); 133cdf0e10cSrcweir } 134cdf0e10cSrcweir 135cdf0e10cSrcweir // -------------------------------------------------------------------------------------------------------- loadSubComponent( final int _objectType, final String _name )136cdf0e10cSrcweir public XController loadSubComponent( final int _objectType, final String _name ) throws IllegalArgumentException, SQLException, NoSuchElementException 137cdf0e10cSrcweir { 138cdf0e10cSrcweir XDatabaseDocumentUI docUI = getDocumentUI(); 139cdf0e10cSrcweir if ( !docUI.isConnected() ) 140cdf0e10cSrcweir docUI.connect(); 141cdf0e10cSrcweir 142cdf0e10cSrcweir XComponent subComponent = docUI.loadComponent( _objectType, _name, false ); 143cdf0e10cSrcweir XController controller = UnoRuntime.queryInterface( XController.class, subComponent ); 144cdf0e10cSrcweir if ( controller != null ) 145cdf0e10cSrcweir return controller; 146cdf0e10cSrcweir XModel document = UnoRuntime.queryInterface( XModel.class, subComponent ); 147cdf0e10cSrcweir return document.getCurrentController(); 148cdf0e10cSrcweir } 149cdf0e10cSrcweir 150cdf0e10cSrcweir // -------------------------------------------------------------------------------------------------------- createTables()151cdf0e10cSrcweir private void createTables() throws SQLException 152cdf0e10cSrcweir { 153cdf0e10cSrcweir HsqlTableDescriptor table = new HsqlTableDescriptor( "categories", 154cdf0e10cSrcweir new HsqlColumnDescriptor[] { 155cdf0e10cSrcweir new HsqlColumnDescriptor( "ID",INTEGER, HsqlColumnDescriptor.PRIMARY ), 156cdf0e10cSrcweir new HsqlColumnDescriptor( "Name",VARCHAR50), 157cdf0e10cSrcweir new HsqlColumnDescriptor( "Description", "VARCHAR(1024)" ), 158cdf0e10cSrcweir new HsqlColumnDescriptor( "Image", "LONGVARBINARY" ) } ); 159cdf0e10cSrcweir m_database.createTable( table, true ); 160cdf0e10cSrcweir 161cdf0e10cSrcweir m_database.executeSQL( "INSERT INTO \"categories\" ( \"ID\", \"Name\" ) VALUES ( 1, 'Food' )" ); 162cdf0e10cSrcweir m_database.executeSQL( "INSERT INTO \"categories\" ( \"ID\", \"Name\" ) VALUES ( 2, 'Furniture' )" ); 163cdf0e10cSrcweir 164cdf0e10cSrcweir table = new HsqlTableDescriptor( "products", 165cdf0e10cSrcweir new HsqlColumnDescriptor[] { 166cdf0e10cSrcweir new HsqlColumnDescriptor( "ID",INTEGER, HsqlColumnDescriptor.PRIMARY ), 167cdf0e10cSrcweir new HsqlColumnDescriptor( "Name",VARCHAR50), 168cdf0e10cSrcweir new HsqlColumnDescriptor( "CategoryID",INTEGER, HsqlColumnDescriptor.REQUIRED, "categories", "ID" ) } ); 169cdf0e10cSrcweir m_database.createTable( table, true ); 170cdf0e10cSrcweir 171cdf0e10cSrcweir m_database.executeSQL( "INSERT INTO \"products\" VALUES ( 1, 'Oranges', 1 )" ); 172cdf0e10cSrcweir m_database.executeSQL( "INSERT INTO \"products\" VALUES ( 2, 'Apples', 1 )" ); 173cdf0e10cSrcweir m_database.executeSQL( "INSERT INTO \"products\" VALUES ( 3, 'Pears', 1 )" ); 174cdf0e10cSrcweir m_database.executeSQL( "INSERT INTO \"products\" VALUES ( 4, 'Strawberries', 1 )" ); 175cdf0e10cSrcweir 176cdf0e10cSrcweir table = new HsqlTableDescriptor( "customers", 177cdf0e10cSrcweir new HsqlColumnDescriptor[] { 178cdf0e10cSrcweir new HsqlColumnDescriptor( "ID",INTEGER, HsqlColumnDescriptor.PRIMARY ), 179cdf0e10cSrcweir new HsqlColumnDescriptor( "Name",VARCHAR50), 180cdf0e10cSrcweir new HsqlColumnDescriptor( "Address",VARCHAR50), 181cdf0e10cSrcweir new HsqlColumnDescriptor( "City",VARCHAR50), 182cdf0e10cSrcweir new HsqlColumnDescriptor( "Postal",VARCHAR50), 183cdf0e10cSrcweir new HsqlColumnDescriptor( "Comment","LONGVARCHAR")} ); 184cdf0e10cSrcweir m_database.createTable( table, true ); 185cdf0e10cSrcweir 186cdf0e10cSrcweir m_database.executeSQL( "INSERT INTO \"customers\" VALUES(1,'Food, Inc.','Down Under','Melbourne','509','Prefered') " ); 187cdf0e10cSrcweir m_database.executeSQL( "INSERT INTO \"customers\" VALUES(2,'Simply Delicious','Down Under','Melbourne','518',null) " ); 188cdf0e10cSrcweir m_database.executeSQL( "INSERT INTO \"customers\" VALUES(3,'Pure Health','10 Fish St.','San Francisco','94107',null) " ); 189cdf0e10cSrcweir m_database.executeSQL( "INSERT INTO \"customers\" VALUES(4,'Milk And More','Arlington Road 21','Dublin','31021','Good one.') " ); 190cdf0e10cSrcweir 191cdf0e10cSrcweir table = new HsqlTableDescriptor( "orders", 192cdf0e10cSrcweir new HsqlColumnDescriptor[] { 193cdf0e10cSrcweir new HsqlColumnDescriptor( "ID",INTEGER, HsqlColumnDescriptor.PRIMARY ), 194cdf0e10cSrcweir new HsqlColumnDescriptor( "CustomerID",INTEGER, HsqlColumnDescriptor.REQUIRED, "customers", "ID" ), 195cdf0e10cSrcweir new HsqlColumnDescriptor( "OrderDate", "DATE" ), 196cdf0e10cSrcweir new HsqlColumnDescriptor( "ShipDate", "DATE" ) } ); 197cdf0e10cSrcweir m_database.createTable( table, true ); 198cdf0e10cSrcweir 199cdf0e10cSrcweir m_database.executeSQL( "INSERT INTO \"orders\" (\"ID\", \"CustomerID\", \"OrderDate\") VALUES(1, 1, {D '2009-01-01'})" ); 200cdf0e10cSrcweir m_database.executeSQL( "INSERT INTO \"orders\" VALUES(2, 2, {D '2009-01-01'}, {D '2009-01-23'})" ); 201cdf0e10cSrcweir 202cdf0e10cSrcweir table = new HsqlTableDescriptor( "orders_details", 203cdf0e10cSrcweir new HsqlColumnDescriptor[] { 204cdf0e10cSrcweir new HsqlColumnDescriptor( "OrderID",INTEGER, HsqlColumnDescriptor.PRIMARY, "orders", "ID" ), 205cdf0e10cSrcweir new HsqlColumnDescriptor( "ProductID",INTEGER, HsqlColumnDescriptor.PRIMARY, "products", "ID" ), 206cdf0e10cSrcweir new HsqlColumnDescriptor( "Quantity",INTEGER) } ); 207cdf0e10cSrcweir m_database.createTable( table, true ); 208cdf0e10cSrcweir 209cdf0e10cSrcweir m_database.executeSQL( "INSERT INTO \"orders_details\" VALUES(1, 1, 100)" ); 210cdf0e10cSrcweir m_database.executeSQL( "INSERT INTO \"orders_details\" VALUES(1, 2, 100)" ); 211cdf0e10cSrcweir m_database.executeSQL( "INSERT INTO \"orders_details\" VALUES(2, 2, 2000)" ); 212cdf0e10cSrcweir m_database.executeSQL( "INSERT INTO \"orders_details\" VALUES(2, 3, 2000)" ); 213cdf0e10cSrcweir m_database.executeSQL( "INSERT INTO \"orders_details\" VALUES(2, 4, 2000)" ); 214cdf0e10cSrcweir 215cdf0e10cSrcweir // since we created the tables by directly executing the SQL statements, we need to refresh 216cdf0e10cSrcweir // the tables container 217cdf0e10cSrcweir m_connection.refreshTables(); 218cdf0e10cSrcweir } 219cdf0e10cSrcweir 220cdf0e10cSrcweir // -------------------------------------------------------------------------------------------------------- validateUnparseable()221cdf0e10cSrcweir private void validateUnparseable() 222cdf0e10cSrcweir { 223cdf0e10cSrcweir /* 224cdf0e10cSrcweir // The "unparseable" query should be indeed be unparseable by OOo (though a valid HSQL query) 225cdf0e10cSrcweir XSingleSelectQueryComposer composer; 226cdf0e10cSrcweir QueryDefinition unparseableQuery; 227cdf0e10cSrcweir try 228cdf0e10cSrcweir { 229cdf0e10cSrcweir final XMultiServiceFactory factory = UnoRuntime.queryInterface( 230cdf0e10cSrcweir XMultiServiceFactory.class, m_database.defaultConnection().getXConnection() ); 231cdf0e10cSrcweir composer = UnoRuntime.queryInterface( 232cdf0e10cSrcweir XSingleSelectQueryComposer.class, factory.createInstance( "com.sun.star.sdb.SingleSelectQueryComposer" ) ); 233cdf0e10cSrcweir unparseableQuery = m_dataSource.getQueryDefinition( "unparseable" ); 234cdf0e10cSrcweir } 235cdf0e10cSrcweir catch( Exception e ) 236cdf0e10cSrcweir { 237cdf0e10cSrcweir throw new RuntimeException( "caught an unexpected exception: " + e.getMessage() ); 238cdf0e10cSrcweir } 239cdf0e10cSrcweir 240cdf0e10cSrcweir boolean caughtExpected = false; 241cdf0e10cSrcweir try 242cdf0e10cSrcweir { 243cdf0e10cSrcweir composer.setQuery( unparseableQuery.getCommand() ); 244cdf0e10cSrcweir } 245cdf0e10cSrcweir catch (WrappedTargetException e) { } 246cdf0e10cSrcweir catch( SQLException e ) 247cdf0e10cSrcweir { 248cdf0e10cSrcweir caughtExpected = true; 249cdf0e10cSrcweir } 250cdf0e10cSrcweir 251cdf0e10cSrcweir if ( !caughtExpected ) 252cdf0e10cSrcweir throw new RuntimeException( "Somebody improved the parser! This is bad :), since we need an unparsable query here!" ); 253cdf0e10cSrcweir */ 254cdf0e10cSrcweir } 255cdf0e10cSrcweir 256cdf0e10cSrcweir // -------------------------------------------------------------------------------------------------------- createQueries()257cdf0e10cSrcweir private void createQueries() throws ElementExistException, WrappedTargetException, com.sun.star.lang.IllegalArgumentException 258cdf0e10cSrcweir { 259cdf0e10cSrcweir m_database.getDataSource().createQuery( 260cdf0e10cSrcweir "all orders", 261cdf0e10cSrcweir "SELECT \"orders\".\"ID\" AS \"Order No.\", " + 262cdf0e10cSrcweir "\"customers\".\"Name\" AS \"Customer Name\", " + 263cdf0e10cSrcweir "\"orders\".\"OrderDate\" AS \"Order Date\", " + 264cdf0e10cSrcweir "\"orders\".\"ShipDate\" AS \"Ship Date\", " + 265cdf0e10cSrcweir "\"orders_details\".\"Quantity\", " + 266cdf0e10cSrcweir "\"products\".\"Name\" AS \"Product Name\" " + 267cdf0e10cSrcweir "FROM \"orders_details\" AS \"orders_details\", " + 268cdf0e10cSrcweir "\"orders\" AS \"orders\", " + 269cdf0e10cSrcweir "\"products\" AS \"products\", " + 270cdf0e10cSrcweir "\"customers\" AS \"customers\" " + 271cdf0e10cSrcweir "WHERE ( \"orders_details\".\"OrderID\" = \"orders\".\"ID\" " + 272cdf0e10cSrcweir "AND \"orders_details\".\"ProductID\" = \"products\".\"ID\" " + 273cdf0e10cSrcweir "AND \"orders\".\"CustomerID\" = \"customers\".\"ID\" )" 274cdf0e10cSrcweir ); 275cdf0e10cSrcweir 276cdf0e10cSrcweir m_database.getDataSource().createQuery( 277cdf0e10cSrcweir "unshipped orders", 278cdf0e10cSrcweir "SELECT * " + 279cdf0e10cSrcweir "FROM \"all orders\"" + 280cdf0e10cSrcweir "WHERE ( \"ShipDate\" IS NULL )" 281cdf0e10cSrcweir ); 282cdf0e10cSrcweir 283cdf0e10cSrcweir m_database.getDataSource().createQuery( "parseable", "SELECT * FROM \"customers\"" ); 284cdf0e10cSrcweir m_database.getDataSource().createQuery( "parseable native", "SELECT * FROM INFORMATION_SCHEMA.SYSTEM_VIEWS", false ); 285cdf0e10cSrcweir /* 286cdf0e10cSrcweir m_database.getDataSource().createQuery( "unparseable", 287cdf0e10cSrcweir "SELECT {fn DAYOFMONTH ('2001-01-01')} AS \"ID_VARCHAR\" FROM \"products\"", false ); 288cdf0e10cSrcweir */ 289cdf0e10cSrcweir validateUnparseable(); 290cdf0e10cSrcweir } 291cdf0e10cSrcweir } 292