Statistics
| Revision:

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
}