Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.db / org.gvsig.fmap.dal.db.jdbc / src / main / java / org / gvsig / fmap / dal / store / jdbc2 / spi / operations / AppendOperation.java @ 45507

History | View | Annotate | Download (7.33 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2020 gvSIG Association.
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 3
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
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.fmap.dal.store.jdbc2.spi.operations;
25

    
26
import java.sql.Connection;
27
import java.sql.PreparedStatement;
28
import java.sql.SQLException;
29
import java.util.Collections;
30
import java.util.List;
31
import org.gvsig.expressionevaluator.GeometryExpressionBuilder;
32
import org.gvsig.fmap.dal.DataTypes;
33
import org.gvsig.fmap.dal.exception.DataException;
34
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
35
import org.gvsig.fmap.dal.feature.FeatureType;
36
import org.gvsig.fmap.dal.feature.exception.AlreadyEditingException;
37
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
38
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCPreparingSQLException;
39
import org.gvsig.fmap.dal.store.jdbc2.JDBCHelper;
40
import org.gvsig.fmap.dal.store.jdbc2.JDBCUtils;
41
import org.gvsig.fmap.dal.store.jdbc2.OperationsFactory.TableReference;
42
import org.gvsig.fmap.dal.store.jdbc2.spi.JDBCSQLBuilderBase;
43
import org.gvsig.tools.dispose.Disposable;
44
import org.gvsig.tools.dispose.DisposeUtils;
45

    
46

    
47
public class AppendOperation {
48
    
49
    protected Connection connection = null;
50
    protected final JDBCHelper helper;
51
    protected final TableReference table;
52
    protected final FeatureType type;
53
    
54
    protected JDBCSQLBuilderBase sqlbuilder = null;
55
    protected GeometryExpressionBuilder expbuilder;
56

    
57
    protected PreparedStatement preparedStatement;
58
    protected String insertSQL;
59
    protected int batchCount;
60
    private final int batchSize;
61
    
62
    public AppendOperation(
63
            JDBCHelper helper, 
64
            TableReference table, 
65
            FeatureType type
66
        ) {
67
        this.helper = helper;
68
        this.table = table;
69
        this.type = type;
70
        this.batchSize = this.helper.getConnectionParameters().getBatchSize();
71
    }
72
    
73
    public void begin() throws DataException {
74
        if (this.sqlbuilder != null) {
75
            throw new AlreadyEditingException(this.helper.getSourceId());
76
        }
77

    
78
        try {
79
            this.connection = this.helper.getConnectionWritable();
80
            
81
            this.sqlbuilder = this.helper.createSQLBuilder();
82
            this.expbuilder = this.sqlbuilder.expression();
83

    
84
            this.sqlbuilder.insert().table()
85
                    .database(this.table.getDatabase())
86
                    .schema(this.table.getSchema())
87
                    .name(this.table.getTable()
88
            );
89
            for (FeatureAttributeDescriptor attr : type) {
90
                if( attr.isAutomatic() || attr.isComputed() ) {
91
                    continue;
92
                }
93
                if (attr.getType() == DataTypes.GEOMETRY) {
94
                        this.sqlbuilder.insert().column().name(attr.getName()).with_value( 
95
                            expbuilder.parameter(attr.getName()).as_geometry_variable().srs( 
96
                                    expbuilder.parameter().value(attr.getSRS()) 
97
                            ) 
98
                        );
99
                    } else {
100
                        this.sqlbuilder.insert().column().name(attr.getName()).with_value(
101
                        expbuilder.parameter(attr.getName()).as_variable()
102
                    );
103
                }
104
            }
105

    
106
            this.insertSQL = this.sqlbuilder.insert().toString();
107
            if( this.connection != null ) { // Not in test mode ???
108
              this.preparedStatement = this.connection.prepareStatement(insertSQL);
109
              this.connection.setAutoCommit(false);
110
              for (String sql : this.getPreviousSQLs()) {
111
                JDBCUtils.execute(this.connection, sql);
112
              }
113
            }
114
            
115
        } catch (SQLException ex) {
116
            throw new JDBCPreparingSQLException(this.sqlbuilder.toString(),ex);
117
        }
118

    
119
    }
120
    
121
    protected void clean() {
122
        JDBCUtils.closeQuietly(this.preparedStatement);
123
        this.helper.closeConnection(this.connection);
124
        this.connection = null;
125
        this.preparedStatement = null;
126
        this.sqlbuilder = null;
127
        this.insertSQL = null;        
128
    }
129
    
130
    public void end() {
131
        try {
132
            if( this.connection == null ) {
133
              return; // In test mode ???
134
            }
135
            if( this.batchCount > 0 ) {
136
                this.batchCount = 0;
137
                JDBCUtils.executeBatch(this.preparedStatement,this.insertSQL);
138
            }
139

    
140
            this.connection.commit();
141
            for (String sql : this.getPostSQLs()) {
142
              JDBCUtils.execute(this.connection, sql);
143
            }
144
        } catch (SQLException ex) {
145
            try {
146
                this.connection.rollback();
147
            } catch (SQLException ex1) {
148
            }
149
            throw new RuntimeException("Can't commit transaction", ex);
150
        } finally {
151
            clean();
152
        }
153
    }
154
    
155
    public void abort() {        
156
        try {
157
            if( this.connection == null ) {
158
              return; // In test mode ???
159
            }
160
            this.connection.rollback();
161
            for (String sql : this.getPostSQLs()) {
162
              JDBCUtils.execute(this.connection, sql);
163
            }
164
        } catch (SQLException ex) {
165
        } finally {
166
          clean();
167
        }
168
    }
169

    
170
    public String getSQL() { // For test
171
      return this.insertSQL;
172
    }
173
    
174
    public List<String> getPreviousSQLs() {
175
      return Collections.EMPTY_LIST;
176
    }
177
    
178
    public List<String> getPostSQLs() {
179
      return Collections.EMPTY_LIST;
180
    }    
181
    
182
    public List<Object> getSQLParameters(FeatureProvider feature) {
183
      return this.sqlbuilder.getParameters(feature);
184
    }
185
    
186
    @SuppressWarnings("UseSpecificCatch")
187
    public void append(FeatureProvider feature) throws DataException {
188
        int status[] = null;
189
        Disposable paramsDisposer = null;
190
        try {
191
            paramsDisposer = this.sqlbuilder.setParameters(this.preparedStatement, feature);
192
            JDBCUtils.addBatch(this.preparedStatement,this.insertSQL);
193
            if( ++this.batchCount >= this.batchSize ) {
194
                this.batchCount = 0;
195
                status = JDBCUtils.executeBatch(this.preparedStatement,this.insertSQL);
196
            }
197
        } catch(Exception ex) {
198
            throw new RuntimeException("Can't insert feature.", ex);
199
        } finally {
200
            DisposeUtils.disposeQuietly(paramsDisposer);
201
        }
202
        if( status!=null ) {
203
            for (int n : status) {
204
                if( n<1 ) {
205
                    throw new RuntimeException("Can't insert feature (n="+n+").");
206
                }
207
            }
208
        }
209
    }
210
}