001    //$HeadURL: svn+ssh://mschneider@svn.wald.intevation.org/deegree/base/trunk/resources/eclipse/svn_classfile_header_template.xml $
002    /*----------------    FILE HEADER  ------------------------------------------
003     This file is part of deegree.
004     Copyright (C) 2001-2007 by:
005     Department of Geography, University of Bonn
006     http://www.giub.uni-bonn.de/deegree/
007     lat/lon GmbH
008     http://www.lat-lon.de
009    
010     This library is free software; you can redistribute it and/or
011     modify it under the terms of the GNU Lesser General Public
012     License as published by the Free Software Foundation; either
013     version 2.1 of the License, or (at your option) any later version.
014     This library is distributed in the hope that it will be useful,
015     but WITHOUT ANY WARRANTY; without even the implied warranty of
016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
017     Lesser General Public License for more details.
018     You should have received a copy of the GNU Lesser General Public
019     License along with this library; if not, write to the Free Software
020     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
021     Contact:
022    
023     Andreas Poth
024     lat/lon GmbH
025     Aennchenstr. 19
026     53177 Bonn
027     Germany
028     E-Mail: poth@lat-lon.de
029    
030     Prof. Dr. Klaus Greve
031     Department of Geography
032     University of Bonn
033     Meckenheimer Allee 166
034     53115 Bonn
035     Germany
036     E-Mail: greve@giub.uni-bonn.de
037     ---------------------------------------------------------------------------*/
038    
039    package org.deegree.io.datastore.sql.generic;
040    
041    import java.sql.Connection;
042    import java.sql.ResultSet;
043    import java.sql.Statement;
044    import java.util.List;
045    import java.util.Map;
046    
047    import org.deegree.framework.log.ILogger;
048    import org.deegree.framework.log.LoggerFactory;
049    import org.deegree.io.DBConnectionPool;
050    import org.deegree.io.JDBCConnection;
051    import org.deegree.io.datastore.DatastoreException;
052    import org.deegree.io.datastore.FeatureId;
053    import org.deegree.io.datastore.schema.MappedFeatureType;
054    import org.deegree.io.datastore.sql.AbstractSQLDatastore;
055    import org.deegree.io.datastore.sql.SQLDatastoreConfiguration;
056    import org.deegree.io.datastore.sql.TableAliasGenerator;
057    import org.deegree.io.datastore.sql.transaction.SQLTransaction;
058    import org.deegree.io.quadtree.DBQuadtree;
059    import org.deegree.io.quadtree.IndexException;
060    import org.deegree.model.feature.Feature;
061    import org.deegree.model.feature.FeatureProperty;
062    import org.deegree.model.filterencoding.Filter;
063    import org.deegree.model.spatialschema.Envelope;
064    import org.deegree.model.spatialschema.GeometryException;
065    import org.deegree.ogcbase.PropertyPath;
066    
067    /**
068     * Special transaction implementation for the {@link GenericSQLDatastore}.
069     * <p>
070     * Updates the quadtree after successful transactions.
071     * 
072     * @see org.deegree.io.quadtree
073     * 
074     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth </a>
075     * @author <a href="mailto:schneider@lat-lon.de">Markus Schneider </a>
076     * @author last edited by: $Author:$
077     * 
078     * @version $Revision:$, $Date:$
079     */
080    public class GenericSQLTransaction extends SQLTransaction {
081    
082        private static final ILogger LOG = LoggerFactory.getLogger( GenericSQLTransaction.class );
083    
084        private String indexName;
085    
086        /**
087         * 
088         * @param ds
089         * @param aliasGenerator
090         * @param conn
091         * @throws DatastoreException
092         */
093        GenericSQLTransaction( AbstractSQLDatastore ds, TableAliasGenerator aliasGenerator, Connection conn )
094                                throws DatastoreException {
095            super( ds, aliasGenerator, conn );
096        }
097    
098        @Override
099        public int performDelete( MappedFeatureType mappedFeatureType, Filter filter, String lockId )
100                                throws DatastoreException {
101            int cnt = super.performDelete( mappedFeatureType, filter, lockId );
102    
103            // update index
104    
105            return cnt;
106        }
107    
108        @Override
109        public List<FeatureId> performInsert( List<Feature> features )
110                                throws DatastoreException {
111            List<FeatureId> fids = super.performInsert( features );
112    
113            // update index
114            try {
115                for ( int i = 0; i < features.size(); i++ ) {
116                    Envelope env = features.get( i ).getBoundedBy();
117                    if ( env != null ) {
118                        MappedFeatureType mft = datastore.getFeatureType( features.get( i ).getFeatureType().getName() );
119                        Integer id = (Integer) FeatureId.removeFIDPrefix( fids.get( i ).getAsString(), mft.getGMLId() );
120                        SQLDatastoreConfiguration config = (SQLDatastoreConfiguration) getDatastore().getConfiguration();
121                        String table = mft.getTable();
122                        JDBCConnection jdbc = config.getJDBCConnection();
123                        int fk_index = loadIndexMetadata( jdbc, table );
124                        DBQuadtree qt = new DBQuadtree( fk_index, indexName, jdbc );
125                        qt.insert( id, env );
126                    }
127                }
128            } catch ( IndexException e ) {
129                LOG.logError( e.getMessage(), e );
130                throw new DatastoreException( e.getMessage(), e );
131            } catch ( GeometryException e ) {
132                LOG.logError( e.getMessage(), e );
133                throw new DatastoreException( e.getMessage(), e );
134            }
135    
136            return fids;
137        }
138    
139        @Override
140        public int performUpdate( MappedFeatureType mappedFeatureType, Feature replacementFeature, Filter filter,
141                                  String lockId )
142                                throws DatastoreException {
143            int cnt = super.performUpdate( mappedFeatureType, replacementFeature, filter, lockId );
144    
145            // update index
146    
147            return cnt;
148        }
149    
150        @Override
151        public int performUpdate( MappedFeatureType mappedFeatureType, Map<PropertyPath, FeatureProperty> replacementProps,
152                                  Filter filter, String lockId )
153                                throws DatastoreException {
154    
155            int cnt = super.performUpdate( mappedFeatureType, replacementProps, filter, lockId );
156    
157            // update index
158    
159            return cnt;
160        }
161    
162        /**
163         * loads the metadata of a Index from the TAB_DEEGREE_IDX table
164         * 
165         * @param jdbc
166         *            database connection information
167         * @param table
168         *            name of the table containing a featuretypes data
169         * 
170         * @return FK to the index
171         * @throws IndexException
172         */
173        private int loadIndexMetadata( JDBCConnection jdbc, String table )
174                                throws IndexException {
175            int fk_indexTree = -1;
176            Connection con = null;
177            DBConnectionPool pool = null;
178            try {
179                pool = DBConnectionPool.getInstance();
180                con = pool.acquireConnection( jdbc.getDriver(), jdbc.getURL(), jdbc.getUser(), jdbc.getPassword() );
181    
182                StringBuffer sb = new StringBuffer( 200 );
183                sb.append( "Select INDEX_NAME, FK_INDEXTREE from TAB_DEEGREE_IDX where " );
184                sb.append( "column_name = 'geometry' AND " );
185                sb.append( "table_name = '" ).append( table.toLowerCase() ).append( "'" );
186    
187                LOG.logDebug( "Get Index Metadata: ", sb );
188    
189                Statement stmt = con.createStatement();
190                ResultSet rs = stmt.executeQuery( sb.toString() );
191    
192                if ( rs.next() ) {
193                    indexName = rs.getString( "INDEX_NAME" );
194                    fk_indexTree = rs.getInt( "FK_INDEXTREE" );
195                } else {
196                    throw new IndexException( "could not read index metadata" );
197                }
198                rs.close();
199                stmt.close();
200            } catch ( Exception e ) {
201                LOG.logError( e.getMessage(), e );
202                throw new IndexException( "could not load quadtree definition from database", e );
203            } finally {
204                try {
205                    pool.releaseConnection( con, jdbc.getDriver(), jdbc.getURL(), jdbc.getUser(), jdbc.getPassword() );
206                } catch ( Exception e1 ) {
207                    e1.printStackTrace();
208                }
209            }
210            return fk_indexTree;
211        }
212    }