root / branches / v2_0_0_prep / libraries / libFMap_daldb / src / org / gvsig / fmap / dal / store / jdbc / JDBCStoreProviderWriter.java @ 33717
History | View | Annotate | Download (20.8 KB)
1 | 28909 | jmvivo | /* gvSIG. Geographic Information System of the Valencian Government
|
---|---|---|---|
2 | *
|
||
3 | * Copyright (C) 2007-2008 Infrastructures and Transports Department
|
||
4 | * of the Valencian Government (CIT)
|
||
5 | *
|
||
6 | * This program is free software; you can redistribute it and/or
|
||
7 | * modify it under the terms of the GNU General Public License
|
||
8 | * as published by the Free Software Foundation; either version 2
|
||
9 | * of the License, or (at your option) any later version.
|
||
10 | *
|
||
11 | * This program is distributed in the hope that it will be useful,
|
||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
14 | * GNU General Public License for more details.
|
||
15 | *
|
||
16 | * You should have received a copy of the GNU General Public License
|
||
17 | * along with this program; if not, write to the Free Software
|
||
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||
19 | * MA 02110-1301, USA.
|
||
20 | *
|
||
21 | */
|
||
22 | |||
23 | /*
|
||
24 | * AUTHORS (In addition to CIT):
|
||
25 | * 2009 IVER T.I {{Task}}
|
||
26 | */
|
||
27 | |||
28 | /**
|
||
29 | *
|
||
30 | */
|
||
31 | package org.gvsig.fmap.dal.store.jdbc; |
||
32 | |||
33 | import java.sql.Connection; |
||
34 | import java.sql.PreparedStatement; |
||
35 | import java.sql.SQLException; |
||
36 | import java.sql.Statement; |
||
37 | import java.util.ArrayList; |
||
38 | import java.util.Arrays; |
||
39 | import java.util.Iterator; |
||
40 | import java.util.List; |
||
41 | |||
42 | import org.gvsig.fmap.dal.exception.DataException; |
||
43 | import org.gvsig.fmap.dal.exception.InitializeException; |
||
44 | import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor; |
||
45 | import org.gvsig.fmap.dal.feature.FeatureType; |
||
46 | import org.gvsig.fmap.dal.feature.exception.PerformEditingException; |
||
47 | 29289 | jmvivo | import org.gvsig.fmap.dal.feature.spi.FeatureProvider; |
48 | 28909 | jmvivo | import org.gvsig.fmap.dal.feature.spi.FeatureReferenceProviderServices; |
49 | 29326 | jmvivo | import org.gvsig.fmap.dal.spi.DataStoreProviderServices; |
50 | 32880 | jjdelcerro | import org.gvsig.fmap.dal.store.db.FeatureTypeHelper; |
51 | 28909 | jmvivo | import org.gvsig.fmap.dal.store.jdbc.exception.JDBCExecutePreparedSQLException; |
52 | import org.gvsig.fmap.dal.store.jdbc.exception.JDBCExecuteSQLException; |
||
53 | import org.gvsig.fmap.dal.store.jdbc.exception.JDBCPreparingSQLException; |
||
54 | import org.gvsig.fmap.dal.store.jdbc.exception.JDBCSQLException; |
||
55 | import org.gvsig.fmap.dal.store.jdbc.exception.JDBCUpdateWithoutChangesException; |
||
56 | 29326 | jmvivo | import org.gvsig.tools.dynobject.DynObject; |
57 | 28909 | jmvivo | import org.slf4j.Logger; |
58 | import org.slf4j.LoggerFactory; |
||
59 | |||
60 | /**
|
||
61 | * @author jmvivo
|
||
62 | *
|
||
63 | */
|
||
64 | public class JDBCStoreProviderWriter extends JDBCStoreProvider { |
||
65 | |||
66 | final static private Logger logger = LoggerFactory |
||
67 | .getLogger(JDBCStoreProviderWriter.class); |
||
68 | |||
69 | |||
70 | protected String appendModeSql; |
||
71 | 32880 | jjdelcerro | protected List<FeatureAttributeDescriptor> appendModeAttributes; |
72 | 28909 | jmvivo | |
73 | 29326 | jmvivo | |
74 | public JDBCStoreProviderWriter(JDBCStoreParameters params,
|
||
75 | DataStoreProviderServices storeServices) |
||
76 | throws InitializeException {
|
||
77 | super(params, storeServices);
|
||
78 | 28909 | jmvivo | } |
79 | |||
80 | 29326 | jmvivo | protected JDBCStoreProviderWriter(JDBCStoreParameters params,
|
81 | DataStoreProviderServices storeServices, DynObject metadata) |
||
82 | 28909 | jmvivo | throws InitializeException {
|
83 | 29326 | jmvivo | super(params, storeServices, metadata);
|
84 | 28909 | jmvivo | } |
85 | |||
86 | |||
87 | |||
88 | 29292 | jmvivo | protected void addToListFeatureValues(FeatureProvider featureProvider, |
89 | 28909 | jmvivo | FeatureAttributeDescriptor attrOfList, |
90 | 32880 | jjdelcerro | FeatureAttributeDescriptor attr, List<Object> values) throws DataException { |
91 | 28909 | jmvivo | if (attr == null) { |
92 | if (attrOfList.isPrimaryKey()) {
|
||
93 | throw new RuntimeException("pk attribute '" |
||
94 | + attrOfList.getName() + "' not found in feature");
|
||
95 | } |
||
96 | values.add(helper |
||
97 | .dalValueToJDBC(attr, attrOfList.getDefaultValue())); |
||
98 | } else {
|
||
99 | 29292 | jmvivo | values.add(helper.dalValueToJDBC(attr, featureProvider.get(attr |
100 | 28909 | jmvivo | .getIndex()))); |
101 | } |
||
102 | |||
103 | } |
||
104 | |||
105 | 29292 | jmvivo | protected void addToListFeatureValues(FeatureProvider featureProvider, |
106 | 32880 | jjdelcerro | List<FeatureAttributeDescriptor> attributes, List<Object> values) throws DataException { |
107 | 28909 | jmvivo | FeatureAttributeDescriptor attr, attrOfList; |
108 | 29292 | jmvivo | FeatureType fType = featureProvider.getType(); |
109 | 28909 | jmvivo | for (int i = 0; i < attributes.size(); i++) { |
110 | attrOfList = (FeatureAttributeDescriptor) attributes.get(i); |
||
111 | attr = fType.getAttributeDescriptor(attrOfList.getName()); |
||
112 | 29292 | jmvivo | addToListFeatureValues(featureProvider, attrOfList, attr, values); |
113 | 28909 | jmvivo | } |
114 | } |
||
115 | |||
116 | protected void appendToSQLPreparedPkWhereClause(StringBuilder sql, |
||
117 | 32880 | jjdelcerro | List<FeatureAttributeDescriptor> pkAttributes) {
|
118 | 28909 | jmvivo | sql.append(" Where ");
|
119 | FeatureAttributeDescriptor attr; |
||
120 | for (int i = 0; i < pkAttributes.size() - 1; i++) { |
||
121 | attr = (FeatureAttributeDescriptor) pkAttributes.get(i); |
||
122 | sql.append(helper.escapeFieldName(attr.getName())); |
||
123 | sql.append(" = ? AND ");
|
||
124 | } |
||
125 | attr = (FeatureAttributeDescriptor) pkAttributes.get(pkAttributes |
||
126 | .size() - 1);
|
||
127 | sql.append(helper.escapeFieldName(attr.getName())); |
||
128 | sql.append(" = ? ");
|
||
129 | } |
||
130 | |||
131 | protected void executeRemovePreparedStatement(Connection conn, String sql, |
||
132 | 32880 | jjdelcerro | List<FeatureAttributeDescriptor> attributes, Iterator<FeatureReferenceProviderServices> featureReferences) throws DataException { |
133 | 28909 | jmvivo | PreparedStatement st;
|
134 | try {
|
||
135 | st = conn.prepareStatement(sql); |
||
136 | } catch (SQLException e) { |
||
137 | throw new JDBCPreparingSQLException(sql, e); |
||
138 | } |
||
139 | try {
|
||
140 | 32880 | jjdelcerro | List<Object> values = new ArrayList<Object>(); |
141 | 28909 | jmvivo | FeatureReferenceProviderServices featureRef; |
142 | 32880 | jjdelcerro | // FeatureType featureType;
|
143 | 28909 | jmvivo | while (featureReferences.hasNext()) {
|
144 | st.clearParameters(); |
||
145 | 32880 | jjdelcerro | featureRef = featureReferences.next(); |
146 | 28909 | jmvivo | values.clear(); |
147 | 32880 | jjdelcerro | // featureType = this.getFeatureStore()
|
148 | // .getFeatureType(featureRef.getFeatureTypeId());
|
||
149 | 28909 | jmvivo | |
150 | 32880 | jjdelcerro | Iterator<FeatureAttributeDescriptor> iter = attributes.iterator();
|
151 | 28909 | jmvivo | FeatureAttributeDescriptor attr; |
152 | while (iter.hasNext()) {
|
||
153 | 32880 | jjdelcerro | attr = iter.next(); |
154 | values.add( helper.dalValueToJDBC(attr, featureRef |
||
155 | 28909 | jmvivo | .getKeyValue(attr.getName()))); |
156 | } |
||
157 | |||
158 | for (int i = 0; i < values.size(); i++) { |
||
159 | st.setObject(i + 1, values.get(i));
|
||
160 | } |
||
161 | try {
|
||
162 | int nAffected =st.executeUpdate();
|
||
163 | if (nAffected == 0) { |
||
164 | throw new JDBCUpdateWithoutChangesException(sql, values); |
||
165 | } |
||
166 | if (nAffected > 1){ |
||
167 | logger.warn("Remove statement affectst to {} rows: {}",
|
||
168 | nAffected, sql); |
||
169 | } |
||
170 | |||
171 | } catch (SQLException e) { |
||
172 | throw new JDBCExecutePreparedSQLException(sql, values, e); |
||
173 | } |
||
174 | |||
175 | } |
||
176 | } catch (SQLException e) { |
||
177 | throw new JDBCSQLException(e); |
||
178 | } finally {
|
||
179 | try {st.close();} catch (SQLException e) { }; |
||
180 | } |
||
181 | |||
182 | } |
||
183 | |||
184 | protected void executeUpdatePreparedStatement(Connection conn, String sql, |
||
185 | 32880 | jjdelcerro | List<FeatureAttributeDescriptor> attributes, Iterator<FeatureProvider> featureProviders) throws DataException { |
186 | 28909 | jmvivo | PreparedStatement st;
|
187 | try {
|
||
188 | st = conn.prepareStatement(sql); |
||
189 | } catch (SQLException e) { |
||
190 | throw new JDBCPreparingSQLException(sql, e); |
||
191 | } |
||
192 | try {
|
||
193 | 32880 | jjdelcerro | List<Object> values = new ArrayList<Object>(); |
194 | 29292 | jmvivo | FeatureProvider featureProvider; |
195 | while (featureProviders.hasNext()) {
|
||
196 | 28909 | jmvivo | st.clearParameters(); |
197 | 29292 | jmvivo | featureProvider = (FeatureProvider) featureProviders.next(); |
198 | 28909 | jmvivo | values.clear(); |
199 | 29292 | jmvivo | addToListFeatureValues(featureProvider, attributes, values); |
200 | 28909 | jmvivo | for (int i = 0; i < values.size(); i++) { |
201 | st.setObject(i + 1, values.get(i));
|
||
202 | } |
||
203 | try {
|
||
204 | if (st.executeUpdate() == 0) { |
||
205 | throw new JDBCUpdateWithoutChangesException(sql, values); |
||
206 | } |
||
207 | } catch (SQLException e) { |
||
208 | throw new JDBCExecutePreparedSQLException(sql, values, e); |
||
209 | } |
||
210 | |||
211 | } |
||
212 | } catch (SQLException e) { |
||
213 | throw new JDBCSQLException(e); |
||
214 | } finally {
|
||
215 | try {st.close();} catch (SQLException e) { }; |
||
216 | } |
||
217 | |||
218 | } |
||
219 | |||
220 | 32880 | jjdelcerro | protected void performDeletes(Connection conn, Iterator<FeatureReferenceProviderServices> deleteds, List<FeatureAttributeDescriptor> pkAttributes) |
221 | 28909 | jmvivo | throws DataException {
|
222 | |||
223 | if (pkAttributes.size() < 0) { |
||
224 | throw new RuntimeException("Operation requires missing pk"); |
||
225 | } |
||
226 | |||
227 | // ************ Prepare SQL ****************
|
||
228 | StringBuilder sqlb = new StringBuilder(); |
||
229 | sqlb.append("Delete from ");
|
||
230 | 29326 | jmvivo | sqlb.append(getJDBCParameters().tableID()); |
231 | 28909 | jmvivo | appendToSQLPreparedPkWhereClause(sqlb, pkAttributes); |
232 | String sql = sqlb.toString();
|
||
233 | // ************ Prepare SQL (end) ****************
|
||
234 | |||
235 | executeRemovePreparedStatement(conn, sql, pkAttributes, deleteds); |
||
236 | } |
||
237 | |||
238 | protected String getSqlStatementAddField(FeatureAttributeDescriptor attr, |
||
239 | 32880 | jjdelcerro | List<String> additionalStatement) throws DataException { |
240 | 28909 | jmvivo | StringBuilder strb = new StringBuilder(); |
241 | strb.append("ADD ");
|
||
242 | strb.append(this.helper.getSqlFieldDescription(attr));
|
||
243 | return strb.toString();
|
||
244 | } |
||
245 | |||
246 | 32880 | jjdelcerro | protected String getSqlStatementDropField(FeatureAttributeDescriptor attr,List<String> additionalStatement) { |
247 | 28909 | jmvivo | // DROP [ COLUMN ] column
|
248 | return " DROP COLUMN " |
||
249 | + this.helper.escapeFieldName(attr.getName());
|
||
250 | |||
251 | } |
||
252 | |||
253 | public boolean supportsAppendMode() { |
||
254 | return true; |
||
255 | } |
||
256 | |||
257 | public void endAppend() throws DataException { |
||
258 | appendModeSql = null;
|
||
259 | appendModeAttributes = null;
|
||
260 | } |
||
261 | |||
262 | 32880 | jjdelcerro | protected List<String> getSqlStatementAlterField( |
263 | 28909 | jmvivo | FeatureAttributeDescriptor attrOrg, |
264 | 32880 | jjdelcerro | FeatureAttributeDescriptor attrTrg, List<String> additionalStatement) |
265 | 28909 | jmvivo | throws DataException {
|
266 | //
|
||
267 | 32880 | jjdelcerro | List<String> actions = new ArrayList<String>(); |
268 | 28909 | jmvivo | StringBuilder strb;
|
269 | if (attrOrg.getDataType() != attrTrg.getDataType()) {
|
||
270 | // ALTER COLUMN {col} TYPE {type} character varying(35)
|
||
271 | strb = new StringBuilder(); |
||
272 | strb.append("ALTER COLUMN ");
|
||
273 | strb.append(helper.escapeFieldName(attrTrg.getName())); |
||
274 | strb.append(" ");
|
||
275 | strb.append(helper.getSqlColumnTypeDescription(attrTrg)); |
||
276 | |||
277 | actions.add(strb.toString()); |
||
278 | } |
||
279 | |||
280 | if (attrOrg.allowNull() != attrTrg.allowNull()) {
|
||
281 | // ALTER [ COLUMN ] column { SET | DROP } NOT NULL
|
||
282 | |||
283 | strb = new StringBuilder(); |
||
284 | strb.append("ALTER COLUMN ");
|
||
285 | strb.append(helper.escapeFieldName(attrTrg.getName())); |
||
286 | strb.append(' ');
|
||
287 | if (attrTrg.allowNull()) {
|
||
288 | strb.append("SET ");
|
||
289 | } else {
|
||
290 | strb.append("DROP ");
|
||
291 | } |
||
292 | strb.append("NOT NULL");
|
||
293 | actions.add(strb.toString()); |
||
294 | } |
||
295 | |||
296 | if (attrOrg.getDefaultValue() != attrTrg.getDefaultValue()) {
|
||
297 | if (attrTrg.getDefaultValue() == null) { |
||
298 | // ALTER [ COLUMN ] column DROP DEFAULT
|
||
299 | |||
300 | strb = new StringBuilder(); |
||
301 | strb.append("ALTER COLUMN ");
|
||
302 | strb.append(helper.escapeFieldName(attrTrg.getName())); |
||
303 | strb.append(" DROP DEFAULT");
|
||
304 | actions.add(strb.toString()); |
||
305 | } else if (!attrTrg.getDefaultValue().equals( |
||
306 | attrOrg.getDefaultValue())) { |
||
307 | // ALTER [ COLUMN ] column DROP DEFAULT
|
||
308 | |||
309 | strb = new StringBuilder(); |
||
310 | strb.append("ALTER COLUMN ");
|
||
311 | strb.append(helper.escapeFieldName(attrTrg.getName())); |
||
312 | strb.append(" SET DEFAULT");
|
||
313 | strb.append(helper.dalValueToJDBC(attrTrg, attrTrg |
||
314 | .getDefaultValue())); |
||
315 | actions.add(strb.toString()); |
||
316 | } |
||
317 | } |
||
318 | |||
319 | return actions;
|
||
320 | } |
||
321 | |||
322 | protected void performUpdateTable(Connection conn, FeatureType original, |
||
323 | FeatureType target) throws DataException {
|
||
324 | |||
325 | /*
|
||
326 | *
|
||
327 | * ALTER TABLE [ ONLY ] name [ * ] action [, ... ]
|
||
328 | */
|
||
329 | |||
330 | 32880 | jjdelcerro | List<String> toDrop = new ArrayList<String>(); |
331 | List<String> toAdd = new ArrayList<String>(); |
||
332 | List<String> toAlter = new ArrayList<String>(); |
||
333 | 28909 | jmvivo | |
334 | 32880 | jjdelcerro | List<String> additionalStatement = new ArrayList<String>(); |
335 | 28909 | jmvivo | |
336 | FeatureAttributeDescriptor attrOrg; |
||
337 | FeatureAttributeDescriptor attrTrg; |
||
338 | 32880 | jjdelcerro | Iterator<FeatureAttributeDescriptor> attrs = FeatureTypeHelper.iterator(original);
|
339 | 28909 | jmvivo | while (attrs.hasNext()) {
|
340 | attrOrg = (FeatureAttributeDescriptor) attrs.next(); |
||
341 | attrTrg = target.getAttributeDescriptor(attrOrg.getName()); |
||
342 | if (attrTrg == null) { |
||
343 | toDrop.add(getSqlStatementDropField(attrOrg, |
||
344 | additionalStatement)); |
||
345 | } else {
|
||
346 | 32880 | jjdelcerro | toAlter.addAll(getSqlStatementAlterField(attrOrg, attrTrg,additionalStatement)); |
347 | 28909 | jmvivo | } |
348 | |||
349 | } |
||
350 | 32880 | jjdelcerro | attrs = FeatureTypeHelper.iterator(target); |
351 | 28909 | jmvivo | while (attrs.hasNext()) {
|
352 | attrTrg = (FeatureAttributeDescriptor) attrs.next(); |
||
353 | if (original.getAttributeDescriptor(attrTrg.getName()) == null) { |
||
354 | 32880 | jjdelcerro | toAdd.add(getSqlStatementAddField(attrTrg, |
355 | 28909 | jmvivo | additionalStatement)); |
356 | } |
||
357 | } |
||
358 | |||
359 | StringBuilder sqlb = new StringBuilder(); |
||
360 | |||
361 | sqlb.append("ALTER TABLE ");
|
||
362 | 29326 | jmvivo | sqlb.append(getJDBCParameters().tableID()); |
363 | 28909 | jmvivo | sqlb.append(' ');
|
364 | |||
365 | 32880 | jjdelcerro | List<String> actions = new ArrayList<String>(); |
366 | 28909 | jmvivo | actions.addAll(toDrop); |
367 | actions.addAll(toAlter); |
||
368 | actions.addAll(toAdd); |
||
369 | |||
370 | 32880 | jjdelcerro | Iterator<String> it = actions.iterator(); |
371 | 28909 | jmvivo | while (it.hasNext()) {
|
372 | if (it.next() == null) { |
||
373 | it.remove(); |
||
374 | } |
||
375 | } |
||
376 | |||
377 | it = additionalStatement.iterator(); |
||
378 | while (it.hasNext()) {
|
||
379 | if (it.next() == null) { |
||
380 | it.remove(); |
||
381 | } |
||
382 | } |
||
383 | |||
384 | if (actions.size() < 1) { |
||
385 | return;
|
||
386 | } |
||
387 | |||
388 | helper.stringJoin(actions, ", ", sqlb);
|
||
389 | |||
390 | String sql = sqlb.toString();
|
||
391 | |||
392 | Statement st = null; |
||
393 | |||
394 | try {
|
||
395 | st = conn.createStatement(); |
||
396 | } catch (SQLException e1) { |
||
397 | throw new JDBCSQLException(e1); |
||
398 | } |
||
399 | try {
|
||
400 | st.execute(sql); |
||
401 | 32880 | jjdelcerro | Iterator<String> iter = additionalStatement.iterator(); |
402 | 28909 | jmvivo | while (iter.hasNext()) {
|
403 | sql = (String) iter.next();
|
||
404 | st.execute(sql); |
||
405 | } |
||
406 | } catch (SQLException e1) { |
||
407 | throw new JDBCExecuteSQLException(sql, e1); |
||
408 | } finally {
|
||
409 | try {
|
||
410 | st.close(); |
||
411 | } catch (Exception e) { |
||
412 | logger.error("Exception closing statement", e);
|
||
413 | } |
||
414 | ; |
||
415 | } |
||
416 | |||
417 | } |
||
418 | |||
419 | |||
420 | private void perfomInsert(Connection conn, PreparedStatement insertSt, |
||
421 | 32880 | jjdelcerro | String sql, FeatureProvider feature, List<FeatureAttributeDescriptor> attributes) |
422 | 28909 | jmvivo | throws DataException {
|
423 | |||
424 | try {
|
||
425 | insertSt.clearParameters(); |
||
426 | 32880 | jjdelcerro | List<Object> values = new ArrayList<Object>(); |
427 | 28909 | jmvivo | addToListFeatureValues(feature, attributes, values); |
428 | 32880 | jjdelcerro | // FeatureAttributeDescriptor attr;
|
429 | 28909 | jmvivo | int j = 1; |
430 | for (int i = 0; i < values.size(); i++) { |
||
431 | insertSt.setObject(j, values.get(i)); |
||
432 | j++; |
||
433 | } |
||
434 | if (logger.isDebugEnabled()) {
|
||
435 | logger.debug("Executing insert. sql={} value={}", new Object[] { |
||
436 | sql, values }); |
||
437 | } |
||
438 | try {
|
||
439 | insertSt.execute(); |
||
440 | } catch (SQLException e) { |
||
441 | throw new JDBCExecutePreparedSQLException(sql, values, e); |
||
442 | } |
||
443 | |||
444 | } catch (SQLException e1) { |
||
445 | throw new JDBCSQLException(e1); |
||
446 | } |
||
447 | } |
||
448 | |||
449 | 29292 | jmvivo | public void append(final FeatureProvider featureProvider) throws DataException { |
450 | 28909 | jmvivo | TransactionalAction action = new TransactionalAction() {
|
451 | public Object action(Connection conn) throws DataException { |
||
452 | |||
453 | PreparedStatement st;
|
||
454 | try {
|
||
455 | st = conn.prepareStatement(appendModeSql); |
||
456 | } catch (SQLException e) { |
||
457 | throw new JDBCPreparingSQLException(appendModeSql, e); |
||
458 | } |
||
459 | try {
|
||
460 | 29292 | jmvivo | perfomInsert(conn, st, appendModeSql, featureProvider, |
461 | 28909 | jmvivo | appendModeAttributes); |
462 | } finally {
|
||
463 | try {
|
||
464 | st.close(); |
||
465 | } catch (SQLException e) { |
||
466 | } |
||
467 | ; |
||
468 | } |
||
469 | return null; |
||
470 | } |
||
471 | |||
472 | public boolean continueTransactionAllowed() { |
||
473 | return false; |
||
474 | } |
||
475 | }; |
||
476 | try {
|
||
477 | this.helper.doConnectionAction(action);
|
||
478 | |||
479 | resetCount(); |
||
480 | |||
481 | } catch (Exception e) { |
||
482 | 33717 | jjdelcerro | throw new PerformEditingException(this.getProviderName(), e); |
483 | 28909 | jmvivo | } |
484 | } |
||
485 | |||
486 | protected void prepareAttributeForUpdate(FeatureAttributeDescriptor attr, |
||
487 | 32880 | jjdelcerro | List<String> values) { |
488 | 28909 | jmvivo | values.add(helper.escapeFieldName(attr.getName()) + " = ?");
|
489 | } |
||
490 | |||
491 | protected void prepareAttributeForInsert(FeatureAttributeDescriptor attr, |
||
492 | 32880 | jjdelcerro | List<String> fields, List<String> values) { |
493 | 28909 | jmvivo | |
494 | fields.add(helper.escapeFieldName(attr.getName())); |
||
495 | values.add("?");
|
||
496 | |||
497 | } |
||
498 | |||
499 | |||
500 | protected void prepareSQLAndAttributeListForInsert(StringBuilder sqlb, |
||
501 | 32880 | jjdelcerro | List<FeatureAttributeDescriptor> attributes) throws DataException { |
502 | 28909 | jmvivo | /*
|
503 | * INSERT INTO table [ ( column [, ...] ) ] { DEFAULT VALUES | VALUES (
|
||
504 | * { expression | DEFAULT } [, ...] ) [, ...] | query } [ RETURNING * |
|
||
505 | * output_expression [ AS output_name ] [, ...] ]
|
||
506 | */
|
||
507 | |||
508 | sqlb.append("INSERT INTO ");
|
||
509 | 29326 | jmvivo | sqlb.append(getJDBCParameters().tableID()); |
510 | 28909 | jmvivo | |
511 | sqlb.append(" (");
|
||
512 | |||
513 | 29326 | jmvivo | FeatureType type = this.getFeatureStore().getDefaultFeatureType();
|
514 | 28909 | jmvivo | |
515 | 32880 | jjdelcerro | List<String> fields = new ArrayList<String>(); |
516 | List<String> values = new ArrayList<String>(); |
||
517 | 28909 | jmvivo | |
518 | 32880 | jjdelcerro | Iterator<FeatureAttributeDescriptor> iter = FeatureTypeHelper.iterator(type);
|
519 | 28909 | jmvivo | FeatureAttributeDescriptor attr; |
520 | while (iter.hasNext()) {
|
||
521 | 32880 | jjdelcerro | attr = iter.next(); |
522 | 28909 | jmvivo | if (attr.isAutomatic() || attr.isReadOnly()) {
|
523 | continue;
|
||
524 | } |
||
525 | attributes.add(attr); |
||
526 | prepareAttributeForInsert(attr, fields, values); |
||
527 | |||
528 | } |
||
529 | if (attributes.size() < 1) { |
||
530 | throw new RuntimeException("no fields to set"); |
||
531 | } |
||
532 | |||
533 | helper.stringJoin(fields, ", ", sqlb);
|
||
534 | |||
535 | sqlb.append(") VALUES (");
|
||
536 | helper.stringJoin(values, ", ", sqlb);
|
||
537 | |||
538 | sqlb.append(") ");
|
||
539 | |||
540 | } |
||
541 | |||
542 | |||
543 | 32880 | jjdelcerro | protected void performInserts(Connection conn, Iterator<FeatureProvider> inserteds) |
544 | 28909 | jmvivo | throws DataException {
|
545 | |||
546 | StringBuilder sqlb = new StringBuilder(); |
||
547 | 32880 | jjdelcerro | List<FeatureAttributeDescriptor> attrs = new ArrayList<FeatureAttributeDescriptor>(); |
548 | 28909 | jmvivo | |
549 | prepareSQLAndAttributeListForInsert(sqlb, attrs); |
||
550 | |||
551 | String sql = sqlb.toString();
|
||
552 | PreparedStatement st;
|
||
553 | try {
|
||
554 | st = conn.prepareStatement(sql); |
||
555 | } catch (SQLException e) { |
||
556 | throw new JDBCPreparingSQLException(sql, e); |
||
557 | } |
||
558 | try {
|
||
559 | while (inserteds.hasNext()) {
|
||
560 | 32880 | jjdelcerro | perfomInsert(conn, st, sql, inserteds.next(), |
561 | 28909 | jmvivo | attrs); |
562 | } |
||
563 | } finally {
|
||
564 | try {st.close();} catch (SQLException e) {logger.error("Error closing statement", e);}; |
||
565 | } |
||
566 | } |
||
567 | |||
568 | 32880 | jjdelcerro | protected void performUpdates(Connection conn, Iterator<FeatureProvider> updateds, |
569 | List<FeatureAttributeDescriptor> pkAttributes) throws DataException { |
||
570 | 28909 | jmvivo | /*
|
571 | * UPDATE [ ONLY ] table [ [ AS ] alias ] SET { column = { expression |
|
||
572 | * DEFAULT } | ( column [, ...] ) = ( { expression | DEFAULT } [, ...] )
|
||
573 | * } [, ...] [ FROM fromlist ] [ WHERE condition ] [ RETURNING * |
|
||
574 | * output_expression [ AS output_name ] [, ...] ]
|
||
575 | */
|
||
576 | |||
577 | if (pkAttributes.size() < 0) { |
||
578 | throw new RuntimeException("Operation requires missing pk"); |
||
579 | } |
||
580 | |||
581 | // ************ Prepare SQL ****************
|
||
582 | |||
583 | StringBuilder sqlb = new StringBuilder(); |
||
584 | sqlb.append("UPDATE ");
|
||
585 | 29326 | jmvivo | sqlb.append(getJDBCParameters().tableID()); |
586 | 28909 | jmvivo | |
587 | sqlb.append(" SET ");
|
||
588 | |||
589 | 32880 | jjdelcerro | List<String> values = new ArrayList<String>(); |
590 | 28909 | jmvivo | |
591 | 29326 | jmvivo | FeatureType type = this.getFeatureStore().getDefaultFeatureType();
|
592 | 28909 | jmvivo | |
593 | 32880 | jjdelcerro | Iterator<FeatureAttributeDescriptor> iter = FeatureTypeHelper.iterator(type);
|
594 | 28909 | jmvivo | FeatureAttributeDescriptor attr; |
595 | 32880 | jjdelcerro | List<FeatureAttributeDescriptor> updateAttrs = new ArrayList<FeatureAttributeDescriptor>(); |
596 | 28909 | jmvivo | while (iter.hasNext()) {
|
597 | 32880 | jjdelcerro | attr = iter.next(); |
598 | 28909 | jmvivo | if (attr.isPrimaryKey() || attr.isAutomatic() || attr.isReadOnly()) {
|
599 | continue;
|
||
600 | } |
||
601 | updateAttrs.add(attr); |
||
602 | prepareAttributeForUpdate(attr, values); |
||
603 | |||
604 | } |
||
605 | if (updateAttrs.size() < 1) { |
||
606 | throw new RuntimeException("no fields to set"); |
||
607 | } |
||
608 | |||
609 | helper.stringJoin(values, ", ", sqlb);
|
||
610 | |||
611 | sqlb.append(' ');
|
||
612 | appendToSQLPreparedPkWhereClause(sqlb, pkAttributes); |
||
613 | |||
614 | String sql = sqlb.toString();
|
||
615 | // ************ Prepare SQL (end) ****************
|
||
616 | |||
617 | updateAttrs.addAll(pkAttributes); |
||
618 | |||
619 | executeUpdatePreparedStatement(conn, sql, updateAttrs, updateds); |
||
620 | } |
||
621 | |||
622 | |||
623 | public void beginAppend() throws DataException { |
||
624 | StringBuilder sqlb = new StringBuilder(); |
||
625 | 32880 | jjdelcerro | List<FeatureAttributeDescriptor> attrs = new ArrayList<FeatureAttributeDescriptor>(); |
626 | 28909 | jmvivo | |
627 | prepareSQLAndAttributeListForInsert(sqlb, attrs); |
||
628 | |||
629 | appendModeSql = sqlb.toString(); |
||
630 | appendModeAttributes = attrs; |
||
631 | } |
||
632 | |||
633 | |||
634 | 29289 | jmvivo | protected TransactionalAction getPerformChangesAction(
|
635 | 32880 | jjdelcerro | final Iterator<FeatureReferenceProviderServices> deleteds, |
636 | final Iterator<FeatureProvider> inserteds, |
||
637 | final Iterator<FeatureProvider> updateds, |
||
638 | final Iterator<FeatureTypeChanged> featureTypesChanged) { |
||
639 | 28909 | jmvivo | |
640 | TransactionalAction action = new TransactionalAction() {
|
||
641 | |||
642 | public Object action(Connection conn) throws DataException { |
||
643 | |||
644 | 29289 | jmvivo | if (featureTypesChanged.hasNext()) {
|
645 | |||
646 | 32880 | jjdelcerro | FeatureTypeChanged item = featureTypesChanged.next(); |
647 | 29289 | jmvivo | performUpdateTable(conn, item.getSource(), item.getTarget()); |
648 | 28909 | jmvivo | } |
649 | |||
650 | 32880 | jjdelcerro | List<FeatureAttributeDescriptor> pkAttributes = null; |
651 | 28909 | jmvivo | if (deleteds.hasNext() || updateds.hasNext()) {
|
652 | 29326 | jmvivo | pkAttributes = Arrays.asList(getFeatureStore()
|
653 | .getDefaultFeatureType() |
||
654 | 28909 | jmvivo | .getPrimaryKey()); |
655 | } |
||
656 | |||
657 | if (deleteds.hasNext()) {
|
||
658 | performDeletes(conn, deleteds, pkAttributes); |
||
659 | } |
||
660 | |||
661 | if (updateds.hasNext()) {
|
||
662 | performUpdates(conn, updateds, pkAttributes); |
||
663 | } |
||
664 | |||
665 | if (inserteds.hasNext()) {
|
||
666 | performInserts(conn, inserteds); |
||
667 | } |
||
668 | |||
669 | return null; |
||
670 | } |
||
671 | |||
672 | public boolean continueTransactionAllowed() { |
||
673 | return false; |
||
674 | } |
||
675 | |||
676 | }; |
||
677 | |||
678 | return action;
|
||
679 | |||
680 | } |
||
681 | |||
682 | 32880 | jjdelcerro | @SuppressWarnings("unchecked") |
683 | 29289 | jmvivo | public void performChanges(Iterator deleteds, Iterator inserteds, |
684 | Iterator updateds, Iterator featureTypesChanged) |
||
685 | 28909 | jmvivo | throws PerformEditingException {
|
686 | |||
687 | boolean countChanged = deleteds.hasNext() || inserteds.hasNext();
|
||
688 | |||
689 | try {
|
||
690 | 29289 | jmvivo | this.helper.doConnectionAction(getPerformChangesAction(deleteds,
|
691 | inserteds, updateds, featureTypesChanged)); |
||
692 | 28909 | jmvivo | |
693 | this.initFeatureType();
|
||
694 | if (countChanged) {
|
||
695 | resetCount(); |
||
696 | } |
||
697 | |||
698 | } catch (Exception e) { |
||
699 | 33717 | jjdelcerro | throw new PerformEditingException(this.getProviderName(), e); |
700 | 28909 | jmvivo | } |
701 | } |
||
702 | |||
703 | |||
704 | public boolean allowWrite() { |
||
705 | if (directSQLMode) {
|
||
706 | return false; |
||
707 | } |
||
708 | 29326 | jmvivo | if (getJDBCParameters().getPkFields() == null |
709 | || getJDBCParameters().getPkFields().length > 0) {
|
||
710 | 28909 | jmvivo | FeatureType ft = null;
|
711 | try {
|
||
712 | 29326 | jmvivo | ft = this.getFeatureStore().getDefaultFeatureType();
|
713 | 28909 | jmvivo | } catch (DataException e) {
|
714 | logger.error("Excepton get default Feature Type", e);
|
||
715 | } |
||
716 | |||
717 | if (ft == null) { |
||
718 | return false; |
||
719 | } |
||
720 | FeatureAttributeDescriptor attr; |
||
721 | 32880 | jjdelcerro | Iterator<FeatureAttributeDescriptor> iter = FeatureTypeHelper.iterator(ft);
|
722 | 28909 | jmvivo | while (iter.hasNext()) {
|
723 | attr = (FeatureAttributeDescriptor) iter.next(); |
||
724 | if (attr.isPrimaryKey()) {
|
||
725 | return true; |
||
726 | } |
||
727 | } |
||
728 | return false; |
||
729 | |||
730 | } else {
|
||
731 | return true; |
||
732 | } |
||
733 | } |
||
734 | } |