001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/io/datastore/sql/transaction/SQLTransaction.java $
002 /*---------------- FILE HEADER ------------------------------------------
003
004 This file is part of deegree.
005 Copyright (C) 2001-2008 by:
006 EXSE, Department of Geography, University of Bonn
007 http://www.giub.uni-bonn.de/deegree/
008 lat/lon GmbH
009 http://www.lat-lon.de
010
011 This library is free software; you can redistribute it and/or
012 modify it under the terms of the GNU Lesser General Public
013 License as published by the Free Software Foundation; either
014 version 2.1 of the License, or (at your option) any later version.
015
016 This library is distributed in the hope that it will be useful,
017 but WITHOUT ANY WARRANTY; without even the implied warranty of
018 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
019 Lesser General Public License for more details.
020
021 You should have received a copy of the GNU Lesser General Public
022 License along with this library; if not, write to the Free Software
023 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
024
025 Contact:
026
027 Andreas Poth
028 lat/lon GmbH
029 Aennchenstraße 19
030 53177 Bonn
031 Germany
032 E-Mail: poth@lat-lon.de
033
034 Prof. Dr. Klaus Greve
035 Department of Geography
036 University of Bonn
037 Meckenheimer Allee 166
038 53115 Bonn
039 Germany
040 E-Mail: greve@giub.uni-bonn.de
041
042 ---------------------------------------------------------------------------*/
043 package org.deegree.io.datastore.sql.transaction;
044
045 import java.sql.Connection;
046 import java.sql.SQLException;
047 import java.util.List;
048 import java.util.Map;
049
050 import org.deegree.framework.log.ILogger;
051 import org.deegree.framework.log.LoggerFactory;
052 import org.deegree.io.datastore.DatastoreException;
053 import org.deegree.io.datastore.DatastoreTransaction;
054 import org.deegree.io.datastore.FeatureId;
055 import org.deegree.io.datastore.schema.MappedFeatureType;
056 import org.deegree.io.datastore.sql.AbstractRequestHandler;
057 import org.deegree.io.datastore.sql.AbstractSQLDatastore;
058 import org.deegree.io.datastore.sql.TableAliasGenerator;
059 import org.deegree.io.datastore.sql.transaction.delete.DeleteHandler;
060 import org.deegree.io.datastore.sql.transaction.insert.InsertHandler;
061 import org.deegree.model.feature.Feature;
062 import org.deegree.model.feature.FeatureProperty;
063 import org.deegree.model.filterencoding.Filter;
064 import org.deegree.ogcbase.PropertyPath;
065 import org.deegree.ogcwebservices.wfs.operation.transaction.Native;
066 import org.deegree.ogcwebservices.wfs.operation.transaction.Transaction;
067
068 /**
069 * Handles {@link Transaction} requests to SQL based datastores.
070 *
071 * @author <a href="mailto:schneider@lat-lon.de">Markus Schneider</a>
072 * @author <a href="mailto:deshmukh@lat-lon.de">Anup Deshmukh</a>
073 * @author last edited by: $Author: apoth $
074 *
075 * @version $Revision: 9342 $, $Date: 2007-12-27 13:32:57 +0100 (Do, 27 Dez 2007) $
076 */
077 public class SQLTransaction extends AbstractRequestHandler implements DatastoreTransaction {
078
079 private static final ILogger LOG = LoggerFactory.getLogger( SQLTransaction.class );
080
081 /**
082 * Creates a new instance of <code>SQLTransaction</code> from the given parameters.
083 *
084 * @param datastore
085 * @param aliasGenerator
086 * @param conn
087 * @throws DatastoreException
088 */
089 public SQLTransaction( AbstractSQLDatastore datastore, TableAliasGenerator aliasGenerator, Connection conn )
090 throws DatastoreException {
091 super( datastore, aliasGenerator, conn );
092 try {
093 conn.setAutoCommit( false );
094 } catch ( SQLException e ) {
095 String msg = "Unable to disable auto commit: " + e.getMessage();
096 LOG.logError( msg );
097 throw new DatastoreException( msg, e );
098 }
099 }
100
101 /**
102 * Returns the underlying <code>AbstractSQLDatastore</code>.
103 *
104 * @return the underlying <code>AbstractSQLDatastore</code>
105 */
106 public AbstractSQLDatastore getDatastore() {
107 return this.datastore;
108 }
109
110 /**
111 * Returns the underlying JDBC connection.
112 *
113 * @return the underlying JDBC connection
114 */
115 public Connection getConnection() {
116 return this.conn;
117 }
118
119 /**
120 * Makes the changes persistent that have been performed in this transaction.
121 *
122 * @throws DatastoreException
123 */
124 public void commit()
125 throws DatastoreException {
126 try {
127 conn.commit();
128 } catch ( SQLException e ) {
129 String msg = "Unable to commit transaction: " + e.getMessage();
130 LOG.logError( msg );
131 throw new DatastoreException( msg, e );
132 }
133 }
134
135 /**
136 * Aborts the changes that have been performed in this transaction.
137 *
138 * @throws DatastoreException
139 */
140 public void rollback()
141 throws DatastoreException {
142 try {
143 conn.rollback();
144 } catch ( SQLException e ) {
145 String msg = "Unable to rollback transaction: " + e.getMessage();
146 LOG.logError( msg );
147 throw new DatastoreException( msg, e );
148 }
149 }
150
151 /**
152 * Returns the transaction instance so other clients may acquire a transaction (and underlying resources, such as
153 * JDBCConnections can be freed).
154 *
155 * @throws DatastoreException
156 */
157 public void release()
158 throws DatastoreException {
159 this.datastore.releaseTransaction( this );
160 }
161
162 /**
163 * Inserts the given feature instances into the datastore.
164 *
165 * @param features
166 * @return feature ids of the inserted (root) features
167 * @throws DatastoreException
168 */
169 public List<FeatureId> performInsert( List<Feature> features )
170 throws DatastoreException {
171
172 InsertHandler handler = new InsertHandler( this, this.aliasGenerator, this.conn );
173 List<FeatureId> fids = handler.performInsert( features );
174 return fids;
175 }
176
177 /**
178 * Performs an update operation against the datastore.
179 *
180 * @param mappedFeatureType
181 * feature type that is to be updated
182 * @param replacementProps
183 * properties and their replacement values
184 * @param filter
185 * selects the feature instances that are to be updated
186 * @param lockId
187 * optional id of associated lock (may be null)
188 * @return number of updated feature instances
189 * @throws DatastoreException
190 */
191 public int performUpdate( MappedFeatureType mappedFeatureType, Map<PropertyPath, FeatureProperty> replacementProps,
192 Filter filter, String lockId )
193 throws DatastoreException {
194
195 UpdateHandler handler = new UpdateHandler( this, this.aliasGenerator, this.conn, lockId );
196 int updatedFeatures = handler.performUpdate( mappedFeatureType, replacementProps, filter );
197 return updatedFeatures;
198 }
199
200 /**
201 * Performs an update operation against the datastore.
202 * <p>
203 * The filter is expected to match exactly one feature which will be replaced by the specified replacement feature.
204 *
205 * @param mappedFeatureType
206 * feature type that is to be updated
207 * @param replacementFeature
208 * feature instance that will replace the selected feature
209 * @param filter
210 * selects the single feature instances that is to be replaced
211 * @param lockId
212 * optional id of associated lock (may be null)
213 * @return number of updated feature instances (must be 0 or 1)
214 * @throws DatastoreException
215 */
216 public int performUpdate( MappedFeatureType mappedFeatureType, Feature replacementFeature, Filter filter,
217 String lockId )
218 throws DatastoreException {
219
220 UpdateHandler handler = new UpdateHandler( this, this.aliasGenerator, this.conn, lockId );
221 int updatedFeatures = handler.performUpdate( mappedFeatureType, replacementFeature, filter );
222 return updatedFeatures;
223 }
224
225 /**
226 * Deletes the features from the datastore that are matched by the given filter and type.
227 *
228 * @param mappedFeatureType
229 * @param filter
230 * @param lockId
231 * optional id of associated lock (may be null)
232 * @return number of deleted feature instances
233 * @throws DatastoreException
234 */
235 public int performDelete( MappedFeatureType mappedFeatureType, Filter filter, String lockId )
236 throws DatastoreException {
237
238 DeleteHandler handler = new DeleteHandler( this, this.aliasGenerator, this.conn, lockId );
239 int deletedFeatures = handler.performDelete( mappedFeatureType, filter );
240 return deletedFeatures;
241 }
242
243 /**
244 * Performs a 'native' operation against the datastore.
245 *
246 * @param operation
247 * @return number of processed feature instances.
248 * @throws DatastoreException
249 */
250 public int performNative( Native operation )
251 throws DatastoreException {
252
253 throw new UnsupportedOperationException( "Native operations are not supported." );
254 }
255 }