Statistics
| Revision:

root / branches / v2_0_0_prep / libraries / libFMap_daldb / src / org / gvsig / fmap / dal / store / jdbc / JDBCStoreProviderWriter.java @ 29326

History | View | Annotate | Download (19.8 KB)

1
/* 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
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
48
import org.gvsig.fmap.dal.feature.spi.FeatureReferenceProviderServices;
49
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
50
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCExecutePreparedSQLException;
51
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCExecuteSQLException;
52
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCPreparingSQLException;
53
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCSQLException;
54
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCUpdateWithoutChangesException;
55
import org.gvsig.tools.dynobject.DynObject;
56
import org.slf4j.Logger;
57
import org.slf4j.LoggerFactory;
58

    
59
/**
60
 * @author jmvivo
61
 *
62
 */
63
public class JDBCStoreProviderWriter extends JDBCStoreProvider {
64

    
65
        final static private Logger logger = LoggerFactory
66
                        .getLogger(JDBCStoreProviderWriter.class);
67

    
68

    
69
        protected String appendModeSql;
70
        protected List appendModeAttributes;
71

    
72

    
73
        public JDBCStoreProviderWriter(JDBCStoreParameters params,
74
                        DataStoreProviderServices storeServices)
75
                        throws InitializeException {
76
                super(params, storeServices);
77
        }
78

    
79
        protected JDBCStoreProviderWriter(JDBCStoreParameters params,
80
                        DataStoreProviderServices storeServices, DynObject metadata)
81
                        throws InitializeException {
82
                super(params, storeServices, metadata);
83
        }
84

    
85

    
86

    
87
        protected void addToListFeatureValues(FeatureProvider featureProvider,
88
                        FeatureAttributeDescriptor attrOfList,
89
                        FeatureAttributeDescriptor attr, List values) throws DataException {
90
                if (attr == null) {
91
                        if (attrOfList.isPrimaryKey()) {
92
                                // FIXME excepton
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
                        values.add(helper.dalValueToJDBC(attr, featureProvider.get(attr
100
                                        .getIndex())));
101
                }
102

    
103
        }
104

    
105
        protected void addToListFeatureValues(FeatureProvider featureProvider,
106
                        List attributes, List values) throws DataException {
107
                FeatureAttributeDescriptor attr, attrOfList;
108
                FeatureType fType = featureProvider.getType();
109
                for (int i = 0; i < attributes.size(); i++) {
110
                        attrOfList = (FeatureAttributeDescriptor) attributes.get(i);
111
                        attr = fType.getAttributeDescriptor(attrOfList.getName());
112
                        addToListFeatureValues(featureProvider, attrOfList, attr, values);
113
                }
114
        }
115

    
116
        protected void appendToSQLPreparedPkWhereClause(StringBuilder sql,
117
                        List pkAttributes) {
118
                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
                        List attributes, Iterator featureReferences) throws DataException {
133
                                PreparedStatement st;
134
                                try {
135
                                        st = conn.prepareStatement(sql);
136
                                } catch (SQLException e) {
137
                                        throw new JDBCPreparingSQLException(sql, e);
138
                                }
139
                                try {
140
                                        List values = new ArrayList();
141
                                        FeatureReferenceProviderServices featureRef;
142
                                        FeatureType featureType;
143
                                        while (featureReferences.hasNext()) {
144
                                                st.clearParameters();
145
                                                featureRef = (FeatureReferenceProviderServices) featureReferences
146
                                                                .next();
147
                                                values.clear();
148
                                                featureType = this.getFeatureStore().getFeatureType(
149
                                                featureRef
150
                                                                .getFeatureTypeId());
151

    
152
                                                Iterator iter = attributes.iterator();
153
                                                FeatureAttributeDescriptor attr;
154
                                                while (iter.hasNext()) {
155
                                                        attr = (FeatureAttributeDescriptor) iter.next();
156
                                                        values.add(helper.dalValueToJDBC(attr, featureRef
157
                                                                        .getKeyValue(attr.getName())));
158
                                                }
159

    
160
                                                for (int i = 0; i < values.size(); i++) {
161
                                                        st.setObject(i + 1, values.get(i));
162
                                                }
163
                                                try {
164
                                                        int nAffected =st.executeUpdate();
165
                                                        if (nAffected == 0) {
166
                                                                throw new JDBCUpdateWithoutChangesException(sql, values);
167
                                                        }
168
                                                        if (nAffected > 1){
169
                                                                logger.warn("Remove statement affectst to {} rows: {}",
170
                                                                                nAffected, sql);
171
                                                        }
172

    
173
                                                } catch (SQLException e) {
174
                                                        throw new JDBCExecutePreparedSQLException(sql, values, e);
175
                                                }
176

    
177
                                        }
178
                                } catch (SQLException e) {
179
                                        throw new JDBCSQLException(e);
180
                                } finally {
181
                                        try {st.close();} catch (SQLException e) {        };
182
                                }
183

    
184
                        }
185

    
186
        protected void executeUpdatePreparedStatement(Connection conn, String sql,
187
                        List attributes, Iterator featureProviders) throws DataException {
188
                                PreparedStatement st;
189
                                try {
190
                                        st = conn.prepareStatement(sql);
191
                                } catch (SQLException e) {
192
                                        throw new JDBCPreparingSQLException(sql, e);
193
                                }
194
                                try {
195
                                        List values = new ArrayList();
196
                                        FeatureProvider featureProvider;
197
                                        while (featureProviders.hasNext()) {
198
                                                st.clearParameters();
199
                                                featureProvider = (FeatureProvider) featureProviders.next();
200
                                                values.clear();
201
                                                addToListFeatureValues(featureProvider, attributes, values);
202
                                                for (int i = 0; i < values.size(); i++) {
203
                                                        st.setObject(i + 1, values.get(i));
204
                                                }
205
                                                try {
206
                                                        if (st.executeUpdate() == 0) {
207
                                                                throw new JDBCUpdateWithoutChangesException(sql, values);
208
                                                        }
209
                                                } catch (SQLException e) {
210
                                                        throw new JDBCExecutePreparedSQLException(sql, values, e);
211
                                                }
212

    
213
                                        }
214
                                } catch (SQLException e) {
215
                                        throw new JDBCSQLException(e);
216
                                } finally {
217
                                        try {st.close();} catch (SQLException e) {        };
218
                                }
219

    
220
                        }
221

    
222
        protected void performDeletes(Connection conn, Iterator deleteds, List pkAttributes)
223
                        throws DataException {
224

    
225
                                if (pkAttributes.size() < 0) {
226
                                        // FIXME Exception
227
                                        throw new RuntimeException("Operation requires missing pk");
228
                                }
229

    
230
                                // ************ Prepare SQL ****************
231
                                StringBuilder sqlb = new StringBuilder();
232
                                sqlb.append("Delete from ");
233
                                sqlb.append(getJDBCParameters().tableID());
234
                                appendToSQLPreparedPkWhereClause(sqlb, pkAttributes);
235
                                String sql = sqlb.toString();
236
                                // ************ Prepare SQL (end) ****************
237

    
238
                                executeRemovePreparedStatement(conn, sql, pkAttributes, deleteds);
239
                        }
240

    
241
        protected String getSqlStatementAddField(FeatureAttributeDescriptor attr,
242
                        List additionalStatement) throws DataException {
243
                StringBuilder strb = new StringBuilder();
244
                strb.append("ADD ");
245
                strb.append(this.helper.getSqlFieldDescription(attr));
246
                return strb.toString();
247
        }
248

    
249
        protected String getSqlStatementDropField(FeatureAttributeDescriptor attr,List additionalStatement) {
250
                // DROP [ COLUMN ] column
251
                return " DROP COLUMN "
252
                                + this.helper.escapeFieldName(attr.getName());
253

    
254
        }
255

    
256
        public boolean supportsAppendMode() {
257
                return true;
258
        }
259

    
260
        public void endAppend() throws DataException {
261
                this.loadMetadata();
262
                appendModeSql = null;
263
                appendModeAttributes = null;
264
        }
265

    
266
        protected List getSqlStatementAlterField(
267
                        FeatureAttributeDescriptor attrOrg,
268
                        FeatureAttributeDescriptor attrTrg, List additionalStatement)
269
                        throws DataException {
270
                //
271
                List actions = new ArrayList();
272
                StringBuilder strb;
273
                if (attrOrg.getDataType() != attrTrg.getDataType()) {
274
                        // ALTER COLUMN {col} TYPE {type} character varying(35)
275
                        strb = new StringBuilder();
276
                        strb.append("ALTER COLUMN ");
277
                        strb.append(helper.escapeFieldName(attrTrg.getName()));
278
                        strb.append(" ");
279
                        strb.append(helper.getSqlColumnTypeDescription(attrTrg));
280

    
281
                        actions.add(strb.toString());
282
                }
283

    
284
                if (attrOrg.allowNull() != attrTrg.allowNull()) {
285
                        // ALTER [ COLUMN ] column { SET | DROP } NOT NULL
286

    
287
                        strb = new StringBuilder();
288
                        strb.append("ALTER COLUMN ");
289
                        strb.append(helper.escapeFieldName(attrTrg.getName()));
290
                        strb.append(' ');
291
                        if (attrTrg.allowNull()) {
292
                                strb.append("SET ");
293
                        } else {
294
                                strb.append("DROP ");
295
                        }
296
                        strb.append("NOT NULL");
297
                        actions.add(strb.toString());
298
                }
299

    
300
                if (attrOrg.getDefaultValue() != attrTrg.getDefaultValue()) {
301
                        if (attrTrg.getDefaultValue() == null) {
302
                                // ALTER [ COLUMN ] column DROP DEFAULT
303

    
304
                                strb = new StringBuilder();
305
                                strb.append("ALTER COLUMN ");
306
                                strb.append(helper.escapeFieldName(attrTrg.getName()));
307
                                strb.append(" DROP DEFAULT");
308
                                actions.add(strb.toString());
309
                        } else if (!attrTrg.getDefaultValue().equals(
310
                                        attrOrg.getDefaultValue())) {
311
                                // ALTER [ COLUMN ] column DROP DEFAULT
312

    
313
                                strb = new StringBuilder();
314
                                strb.append("ALTER COLUMN ");
315
                                strb.append(helper.escapeFieldName(attrTrg.getName()));
316
                                strb.append(" SET DEFAULT");
317
                                strb.append(helper.dalValueToJDBC(attrTrg, attrTrg
318
                                                .getDefaultValue()));
319
                                actions.add(strb.toString());
320
                        }
321
                }
322

    
323
                return actions;
324
        }
325

    
326
        protected void performUpdateTable(Connection conn, FeatureType original,
327
                        FeatureType target) throws DataException {
328

    
329
                /*
330
                 *
331
                 * ALTER TABLE [ ONLY ] name [ * ] action [, ... ]
332
                 */
333

    
334
                List toDrop = new ArrayList();
335
                List toAdd = new ArrayList();
336
                List toAlter = new ArrayList();
337

    
338
                List additionalStatement = new ArrayList();
339

    
340
                FeatureAttributeDescriptor attrOrg;
341
                FeatureAttributeDescriptor attrTrg;
342
                Iterator attrs = original.iterator();
343
                while (attrs.hasNext()) {
344
                        attrOrg = (FeatureAttributeDescriptor) attrs.next();
345
                        attrTrg = target.getAttributeDescriptor(attrOrg.getName());
346
                        if (attrTrg == null) {
347
                                toDrop.add(getSqlStatementDropField(attrOrg,
348
                                                additionalStatement));
349
                        } else {
350
                                toAlter.addAll(getSqlStatementAlterField(attrOrg, attrTrg,
351
                                                additionalStatement));
352
                        }
353

    
354
                }
355
                attrs = target.iterator();
356
                while (attrs.hasNext()) {
357
                        attrTrg = (FeatureAttributeDescriptor) attrs.next();
358
                        if (original.getAttributeDescriptor(attrTrg.getName()) == null) {
359
                                toAdd
360
                                                .add(getSqlStatementAddField(attrTrg,
361
                                                                additionalStatement));
362
                        }
363
                }
364

    
365
                StringBuilder sqlb = new StringBuilder();
366

    
367
                sqlb.append("ALTER TABLE ");
368
                sqlb.append(getJDBCParameters().tableID());
369
                sqlb.append(' ');
370

    
371
                List actions = new ArrayList();
372
                actions.addAll(toDrop);
373
                actions.addAll(toAlter);
374
                actions.addAll(toAdd);
375

    
376
                Iterator it = actions.iterator();
377
                while (it.hasNext()) {
378
                        if (it.next() == null) {
379
                                it.remove();
380
                        }
381
                }
382

    
383
                it = additionalStatement.iterator();
384
                while (it.hasNext()) {
385
                        if (it.next() == null) {
386
                                it.remove();
387
                        }
388
                }
389

    
390
                if (actions.size() < 1) {
391
                        return;
392
                }
393

    
394
                helper.stringJoin(actions, ", ", sqlb);
395

    
396
                String sql = sqlb.toString();
397

    
398
                Statement st = null;
399

    
400
                try {
401
                        st = conn.createStatement();
402
                } catch (SQLException e1) {
403
                        throw new JDBCSQLException(e1);
404
                }
405
                try {
406
                        st.execute(sql);
407
                        Iterator iter = additionalStatement.iterator();
408
                        while (iter.hasNext()) {
409
                                sql = (String) iter.next();
410
                                st.execute(sql);
411
                        }
412
                } catch (SQLException e1) {
413
                        throw new JDBCExecuteSQLException(sql, e1);
414
                } finally {
415
                        try {
416
                                st.close();
417
                        } catch (Exception e) {
418
                                logger.error("Exception closing statement", e);
419
                        }
420
                        ;
421
                }
422

    
423
        }
424

    
425

    
426
        private void perfomInsert(Connection conn, PreparedStatement insertSt,
427
                        String sql, FeatureProvider feature, List attributes)
428
                        throws DataException {
429

    
430
                try {
431
                        insertSt.clearParameters();
432
                        List values = new ArrayList();
433
                        addToListFeatureValues(feature, attributes, values);
434
                        FeatureAttributeDescriptor attr;
435
                        int j = 1;
436
                        for (int i = 0; i < values.size(); i++) {
437
                                insertSt.setObject(j, values.get(i));
438
                                j++;
439
                        }
440
                        if (logger.isDebugEnabled()) {
441
                                logger.debug("Executing insert. sql={} value={}", new Object[] {
442
                                                sql, values });
443
                        }
444
                        try {
445
                                insertSt.execute();
446
                        } catch (SQLException e) {
447
                                throw new JDBCExecutePreparedSQLException(sql, values, e);
448
                        }
449

    
450
                } catch (SQLException e1) {
451
                        throw new JDBCSQLException(e1);
452
                }
453
        }
454

    
455
        public void append(final FeatureProvider featureProvider) throws DataException {
456
                TransactionalAction action = new TransactionalAction() {
457
                        public Object action(Connection conn) throws DataException {
458

    
459
                                PreparedStatement st;
460
                                try {
461
                                        st = conn.prepareStatement(appendModeSql);
462
                                } catch (SQLException e) {
463
                                        throw new JDBCPreparingSQLException(appendModeSql, e);
464
                                }
465
                                try {
466
                                        perfomInsert(conn, st, appendModeSql, featureProvider,
467
                                                        appendModeAttributes);
468
                                } finally {
469
                                        try {
470
                                                st.close();
471
                                        } catch (SQLException e) {
472
                                        }
473
                                        ;
474
                                }
475
                                return null;
476
                        }
477

    
478
                        public boolean continueTransactionAllowed() {
479
                                return false;
480
                        }
481
                };
482
                try {
483
                        this.helper.doConnectionAction(action);
484

    
485
                        resetCount();
486

    
487
                } catch (Exception e) {
488
                        throw new PerformEditingException(this.getName(), e);
489
                }
490
        }
491

    
492
        protected void prepareAttributeForUpdate(FeatureAttributeDescriptor attr,
493
                        List values) {
494
                values.add(helper.escapeFieldName(attr.getName()) + " = ?");
495
        }
496

    
497
        protected void prepareAttributeForInsert(FeatureAttributeDescriptor attr,
498
                        List fields, List values) {
499

    
500
                fields.add(helper.escapeFieldName(attr.getName()));
501
                values.add("?");
502

    
503
        }
504

    
505

    
506
        protected void prepareSQLAndAttributeListForInsert(StringBuilder sqlb,
507
                        List attributes) throws DataException {
508
                /*
509
                 * INSERT INTO table [ ( column [, ...] ) ] { DEFAULT VALUES | VALUES (
510
                 * { expression | DEFAULT } [, ...] ) [, ...] | query } [ RETURNING * |
511
                 * output_expression [ AS output_name ] [, ...] ]
512
                 */
513

    
514
                sqlb.append("INSERT INTO ");
515
                sqlb.append(getJDBCParameters().tableID());
516

    
517
                sqlb.append(" (");
518

    
519
                FeatureType type = this.getFeatureStore().getDefaultFeatureType();
520

    
521
                List fields = new ArrayList();
522
                List values = new ArrayList();
523

    
524
                Iterator iter = type.iterator();
525
                FeatureAttributeDescriptor attr;
526
                while (iter.hasNext()) {
527
                        attr = (FeatureAttributeDescriptor) iter.next();
528
                        if (attr.isAutomatic() || attr.isReadOnly()) {
529
                                continue;
530
                        }
531
                        attributes.add(attr);
532
                        prepareAttributeForInsert(attr, fields, values);
533

    
534
                }
535
                if (attributes.size() < 1) {
536
                        // FIXME exception
537
                        throw new RuntimeException("no fields to set");
538
                }
539

    
540
                helper.stringJoin(fields, ", ", sqlb);
541

    
542
                sqlb.append(") VALUES (");
543
                helper.stringJoin(values, ", ", sqlb);
544

    
545
                sqlb.append(") ");
546

    
547
        }
548

    
549

    
550
        protected void performInserts(Connection conn, Iterator inserteds)
551
                        throws DataException {
552

    
553
                StringBuilder sqlb = new StringBuilder();
554
                List attrs = new ArrayList();
555

    
556
                prepareSQLAndAttributeListForInsert(sqlb, attrs);
557

    
558
                String sql = sqlb.toString();
559
                PreparedStatement st;
560
                try {
561
                        st = conn.prepareStatement(sql);
562
                } catch (SQLException e) {
563
                        throw new JDBCPreparingSQLException(sql, e);
564
                }
565
                try {
566
                        while (inserteds.hasNext()) {
567
                                perfomInsert(conn, st, sql, (FeatureProvider) inserteds.next(),
568
                                                attrs);
569
                        }
570
                } finally {
571
                        try {st.close();} catch (SQLException e) {logger.error("Error closing statement", e);};
572
                }
573
        }
574

    
575
        protected void performUpdates(Connection conn, Iterator updateds,
576
                        List pkAttributes) throws DataException {
577
                /*
578
                 * UPDATE [ ONLY ] table [ [ AS ] alias ] SET { column = { expression |
579
                 * DEFAULT } | ( column [, ...] ) = ( { expression | DEFAULT } [, ...] )
580
                 * } [, ...] [ FROM fromlist ] [ WHERE condition ] [ RETURNING * |
581
                 * output_expression [ AS output_name ] [, ...] ]
582
                 */
583

    
584
                if (pkAttributes.size() < 0) {
585
                        // FIXME Exception
586
                        throw new RuntimeException("Operation requires missing pk");
587
                }
588

    
589
                // ************ Prepare SQL ****************
590

    
591
                StringBuilder sqlb = new StringBuilder();
592
                sqlb.append("UPDATE ");
593
                sqlb.append(getJDBCParameters().tableID());
594

    
595
                sqlb.append(" SET ");
596

    
597
                List values = new ArrayList();
598

    
599
                FeatureType type = this.getFeatureStore().getDefaultFeatureType();
600

    
601
                Iterator iter = type.iterator();
602
                FeatureAttributeDescriptor attr;
603
                List updateAttrs = new ArrayList();
604
                while (iter.hasNext()) {
605
                        attr = (FeatureAttributeDescriptor) iter.next();
606
                        if (attr.isPrimaryKey() || attr.isAutomatic() || attr.isReadOnly()) {
607
                                continue;
608
                        }
609
                        updateAttrs.add(attr);
610
                        prepareAttributeForUpdate(attr, values);
611

    
612
                }
613
                if (updateAttrs.size() < 1) {
614
                        // FIXME exception
615
                        throw new RuntimeException("no fields to set");
616
                }
617

    
618
                helper.stringJoin(values, ", ", sqlb);
619

    
620
                sqlb.append(' ');
621
                appendToSQLPreparedPkWhereClause(sqlb, pkAttributes);
622

    
623
                String sql = sqlb.toString();
624
                // ************ Prepare SQL (end) ****************
625

    
626
                updateAttrs.addAll(pkAttributes);
627

    
628
                executeUpdatePreparedStatement(conn, sql, updateAttrs, updateds);
629
        }
630

    
631

    
632
        public void beginAppend() throws DataException {
633
                StringBuilder sqlb = new StringBuilder();
634
                List attrs = new ArrayList();
635

    
636
                prepareSQLAndAttributeListForInsert(sqlb, attrs);
637

    
638
                appendModeSql = sqlb.toString();
639
                appendModeAttributes = attrs;
640
        }
641

    
642

    
643
        protected TransactionalAction getPerformChangesAction(
644
                        final Iterator deleteds, final Iterator inserteds,
645
                        final Iterator updateds, final Iterator featureTypesChanged) {
646

    
647
                TransactionalAction action = new TransactionalAction() {
648

    
649
                        public Object action(Connection conn) throws DataException {
650

    
651
                                if (featureTypesChanged.hasNext()) {
652

    
653
                                        FeatureTypeChanged item = (FeatureTypeChanged) featureTypesChanged
654
                                                        .next();
655
                                        performUpdateTable(conn, item.getSource(), item.getTarget());
656
                                }
657

    
658
                                List pkAttributes = null;
659
                                if (deleteds.hasNext() || updateds.hasNext()) {
660
                                        pkAttributes = Arrays.asList(getFeatureStore()
661
                                                        .getDefaultFeatureType()
662
                                                        .getPrimaryKey());
663
                                }
664

    
665
                                if (deleteds.hasNext()) {
666
                                        performDeletes(conn, deleteds, pkAttributes);
667
                                }
668

    
669
                                if (updateds.hasNext()) {
670
                                        performUpdates(conn, updateds, pkAttributes);
671
                                }
672

    
673
                                if (inserteds.hasNext()) {
674
                                        performInserts(conn, inserteds);
675
                                }
676

    
677
                                return null;
678
                        }
679

    
680
                        public boolean continueTransactionAllowed() {
681
                                return false;
682
                        }
683

    
684
                };
685

    
686
                return action;
687

    
688
        }
689

    
690
        public void performChanges(Iterator deleteds, Iterator inserteds,
691
                        Iterator updateds, Iterator featureTypesChanged)
692
                        throws PerformEditingException {
693

    
694
                boolean countChanged = deleteds.hasNext() || inserteds.hasNext();
695

    
696
                try {
697
                        this.helper.doConnectionAction(getPerformChangesAction(deleteds,
698
                                        inserteds, updateds, featureTypesChanged));
699

    
700
                        this.initFeatureType();
701
                        if (countChanged) {
702
                                resetCount();
703
                        }
704

    
705
                } catch (Exception e) {
706
                        throw new PerformEditingException(this.getName(), e);
707
                }
708
        }
709

    
710

    
711
        public boolean allowWrite() {
712
                if (directSQLMode) {
713
                        return false;
714
                }
715
                if (getJDBCParameters().getPkFields() == null
716
                                || getJDBCParameters().getPkFields().length > 0) {
717
                        FeatureType ft = null;
718
                        try {
719
                                ft = this.getFeatureStore().getDefaultFeatureType();
720
                        } catch (DataException e) {
721
                                logger.error("Excepton get default Feature Type", e);
722
                        }
723

    
724
                        if (ft == null) {
725
                                return false;
726
                        }
727
                        FeatureAttributeDescriptor attr;
728
                        Iterator iter = ft.iterator();
729
                        while (iter.hasNext()) {
730
                                attr = (FeatureAttributeDescriptor) iter.next();
731
                                if (attr.isPrimaryKey()) {
732
                                        return true;
733
                                }
734
                        }
735
                        return false;
736

    
737
                } else {
738
                        return true;
739
                }
740
        }
741
}