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 }