Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libDataSourceDBBaseDrivers / src / org / gvsig / data / datastores / vectorial / db / jdbc / h2 / H2FeaturesWriter.java @ 20058

History | View | Annotate | Download (14.3 KB)

1
package org.gvsig.data.datastores.vectorial.db.jdbc.h2;
2

    
3
import java.io.ByteArrayOutputStream;
4
import java.io.File;
5
import java.io.IOException;
6
import java.io.PrintStream;
7
import java.io.RandomAccessFile;
8
import java.io.UnsupportedEncodingException;
9
import java.nio.channels.WritableByteChannel;
10
import java.sql.Connection;
11
import java.sql.DatabaseMetaData;
12
import java.sql.PreparedStatement;
13
import java.sql.ResultSet;
14
import java.sql.SQLException;
15
import java.sql.Statement;
16
import java.sql.Types;
17
import java.util.Iterator;
18

    
19
import org.gvsig.data.datastores.vectorial.ISelectiveWriter;
20
import org.gvsig.data.datastores.vectorial.db.DBAttributeDescriptor;
21
import org.gvsig.data.datastores.vectorial.db.DBFeatureType;
22
import org.gvsig.data.datastores.vectorial.db.jdbc.JDBCAttributeDescriptor;
23
import org.gvsig.data.datastores.vectorial.db.jdbc.JDBCFeature;
24
import org.gvsig.data.datastores.vectorial.db.jdbc.JDBCFeaturesWriter;
25
import org.gvsig.data.datastores.vectorial.db.jdbc.JDBCStore;
26
import org.gvsig.data.datastores.vectorial.db.jdbc.JDBCTypes;
27
import org.gvsig.data.exception.InitializeException;
28
import org.gvsig.data.exception.InitializeWriterException;
29
import org.gvsig.data.exception.OpenException;
30
import org.gvsig.data.exception.ReadException;
31
import org.gvsig.data.exception.WriteException;
32
import org.gvsig.data.vectorial.IFeature;
33
import org.gvsig.data.vectorial.IFeatureAttributeDescriptor;
34
import org.gvsig.data.vectorial.IFeatureStore;
35
import org.gvsig.data.vectorial.IFeatureType;
36

    
37
import com.iver.cit.gvsig.fmap.core.FShape;
38
import com.iver.cit.gvsig.fmap.core.GeneralPathX;
39
import com.iver.cit.gvsig.fmap.core.IGeometry;
40
import com.iver.cit.gvsig.fmap.core.IGeometry3D;
41
import com.iver.cit.gvsig.fmap.core.ShapeFactory;
42
import com.vividsolutions.jts.io.WKBWriter;
43

    
44
class H2FeaturesWriter extends JDBCFeaturesWriter implements ISelectiveWriter {
45
        DBFeatureType featureType;
46
        boolean bCreateTable=false;
47
        private String toEncode;
48
        JDBCStore store;
49
        H2StoreParameters parameters;
50

    
51
        private PreparedStatement insertSt;
52
        private PreparedStatement updateSt;
53

    
54
        private static WKBWriter wkbWriter = new WKBWriter();
55

    
56
        H2FeaturesWriter(){
57

    
58
        }
59

    
60
        public void init(IFeatureStore store) {
61
                H2Store h2Store = (H2Store)store;
62
                this.store = h2Store;
63

    
64
                this.parameters=(H2StoreParameters)store.getParameters();
65

    
66
                this.featureType = (DBFeatureType)this.store.getDefaultFeatureType();
67
                conex = h2Store.getConnection();
68
        }
69

    
70
        public void postProcess() throws OpenException, WriteException {
71
                try {
72
                        conex.commit();
73
                } catch (SQLException e) {
74
                        throw new WriteException(this.store.getName(),e);
75
                }
76
        }
77

    
78
        public void cancelActions() throws WriteException{
79
                try {
80
                        conex.rollback();
81
                } catch (SQLException e) {
82
                        throw new WriteException(this.store.getName(),e);
83
                }
84
        }
85

    
86
        public void preProcess() throws OpenException, InitializeWriterException {
87
                Statement st;
88

    
89

    
90
                try {
91
                        conex.setAutoCommit(false);
92
                        st = conex.createStatement();
93

    
94
                        if (bCreateTable) {
95
                                dropTableIfExist();
96

    
97
                                String sqlCreate = getSqlCreateSpatialTable(featureType);
98
                                System.out.println("sqlCreate =" + sqlCreate);
99
                                st.execute(sqlCreate);
100

    
101
                        }
102

    
103

    
104
                } catch (SQLException e) {
105
                        e.printStackTrace();
106
                }
107
        }
108

    
109
        public void deleteFeature(IFeature feature) throws WriteException {
110
                Statement st;
111
                String sqlDelete = getSqlDeleteFeature(featureType, (JDBCFeature)feature);
112
                System.out.println("sql = " + sqlDelete);
113
                try {
114
                        st = this.conex.createStatement();
115
                        st.execute(sqlDelete);
116
                } catch (SQLException e) {
117
                        throw new WriteException(this.store.getName(),e);
118
                }
119

    
120
        }
121

    
122
        public void insertFeature(IFeature feature) throws WriteException {
123

    
124
                DBFeatureType ftype = (DBFeatureType)feature.getType();
125

    
126
                try {
127
                        PreparedStatement ps=this.getInsertFeatureStatement(ftype);
128
                        Iterator it = ftype.iterator();
129

    
130
                        int index= 1;
131
                        while (it.hasNext()){
132
                                JDBCAttributeDescriptor fad=(JDBCAttributeDescriptor)it.next();
133
                                if (fad.isReadOnly() || fad.isAutoIncrement())
134
                                        continue;
135

    
136

    
137
                                loadValueInPreparedStatement(ps, index, fad, feature);
138
                                index++;
139
                        }
140
//                        ps.setObject(index, feature.get(ftype.getFieldIdIndex()));
141

    
142
                        ps.execute();
143

    
144
                } catch (SQLException e) {
145
                        throw new WriteException(this.store.getName(),e);
146
                }
147
        }
148

    
149
        private PreparedStatement getInsertFeatureStatement(DBFeatureType ftype) throws SQLException {
150
                if (this.insertSt == null){
151
                        StringBuffer fields = new StringBuffer();
152
                        StringBuffer values = new StringBuffer();
153
                        StringBuffer sql = new StringBuffer();
154

    
155
                        Iterator iter = ftype.iterator();
156
                        while (iter.hasNext()){
157
                                DBAttributeDescriptor fad=(DBAttributeDescriptor)iter.next();
158
                                String name = fad.getName();
159
                                if (fad.isReadOnly() || fad.isAutoIncrement())
160
                                        continue;
161
                                fields.append(name+",");
162
                                values.append("?,");
163

    
164
                        }
165
                        sql.append("INSERT INTO "+ftype.getTableID()+" (");
166
                        sql.append(fields.substring(0, fields.length()-1));
167
                        sql.append(") VALUES (");
168
                        sql.append(values.substring(0, values.length()-1));
169
                        sql.append(")");
170

    
171
                        this.insertSt= this.conex.prepareStatement(sql.toString());
172
                        System.out.println(sql.toString());
173
                } else{
174
                        this.insertSt.clearParameters();
175
                }
176
                return this.insertSt;
177

    
178
        }
179

    
180
        public void updateFeatureType(IFeatureType featureType) {
181
                this.featureType=(DBFeatureType)featureType;
182
        }
183

    
184
        /**
185
         * @param createTable
186
         *            The bCreateTable to set.
187
         */
188
        public void setCreateTable(boolean createTable) {
189
                bCreateTable = createTable;
190
        }
191

    
192
        boolean dropTableIfExist() throws SQLException{
193
                if (!this.existTable(parameters.getSchema(), parameters.getTableName())){
194
                        return false;
195
                }
196
                Statement st = conex.createStatement();
197
                st.execute("DROP TABLE " + parameters.tableID() + ";");
198
                st.close();
199
                return false;
200
        }
201
        private boolean existTable(String schema, String tableName) throws SQLException{
202
                boolean exists =false;
203
                DatabaseMetaData metadata = conex.getMetaData();
204

    
205
                ResultSet rs = metadata.getTables(null, schema, tableName, null);
206

    
207
                exists = !rs.isAfterLast();
208
                rs.close();
209

    
210
                return exists;
211
        }
212

    
213
        public void updateFeature(IFeature oldFeature, IFeature feature) throws WriteException, ReadException {
214

    
215
                DBFeatureType ftype = (DBFeatureType)feature.getType();
216

    
217
                try {
218
                        PreparedStatement ps=this.getUpdateFeatureStatement(ftype);
219
                        Iterator it = ftype.iterator();
220

    
221
                        int index= 1;
222
                        while (it.hasNext()){
223
                                JDBCAttributeDescriptor fad=(JDBCAttributeDescriptor)it.next();
224
                                if (fad.isPrimaryKey())
225
                                        continue;
226
                                loadValueInPreparedStatement(ps, index, fad, feature);
227
                                index++;
228
                        }
229

    
230
                        loadPkInPreparedStatement(ps, index, ftype, feature);
231

    
232
                        ps.execute();
233

    
234
                } catch (SQLException e) {
235
                        throw new WriteException(this.store.getName(),e);
236
                }
237
        }
238

    
239
        public void deleteAttribute(IFeatureAttributeDescriptor attribute) throws WriteException {
240
                try {
241
                        Statement st = conex.createStatement();
242
                        String sql = "ALTER TABLE " + parameters.tableID() + " DROP COLUMN "
243
                                + attribute.getName() + ";";
244
                        st.execute(sql);
245
                } catch (SQLException e) {
246
                        throw new WriteException(this.store.getName(),e);
247
                }
248
        }
249

    
250
        public void updateAttribute(IFeatureAttributeDescriptor oldAttribute, IFeatureAttributeDescriptor attribute) throws WriteException, ReadException {
251
                try {
252
                        Statement st = conex.createStatement();
253
                        String sql = "ALTER TABLE " + parameters.tableID() + " RENAME COLUMN "
254
                        + oldAttribute.getName() + " TO " + attribute.getName() + ";";
255
                        st.execute(sql);
256
                } catch (SQLException e) {
257
                        throw new WriteException(this.store.getName(),e);
258
                }
259
        }
260

    
261
        public void insertAttribute(IFeatureAttributeDescriptor attribute) throws WriteException {
262
                try {
263
                        Statement st = conex.createStatement();
264

    
265
                        String sql = "ALTER TABLE "
266
                                + parameters.tableID()
267
                                + " ADD COLUMN "
268
                                + attribute.getName()
269
                                + " "
270
                                + JDBCTypes.fieldTypeToString(attribute.getDataType())
271
                                + " "
272
                                + "DEFAULT " + attribute.getDefaultValue()
273
                                + ";";
274
                        st.execute(sql);
275
                } catch (SQLException e) {
276
                        throw new WriteException(this.store.getName(),e);
277
                }
278
        }
279

    
280
        public String getSqlCreateSpatialTable(DBFeatureType featureType) {
281

    
282
                String resul;
283
                /* boolean bExistGID = false;
284
                for (int i = 0; i < dbLayerDef.getFieldNames().length; i++) {
285
                        if (dbLayerDef.getFieldNames()[i].equalsIgnoreCase("gid")) {
286
                                bExistGID = true;
287
                                break;
288
                        }
289
                } */
290
                /* if (bExistGID) // Usamos el existente y no a?adimos ninguno nosotros
291
                        resul = "CREATE TABLE " + dbLayerDef.getTableName() + " (";
292
                else */
293
                // FJP: NUEVO: NO TOLERAMOS CAMPOS QUE SE LLAMEN GID. Lo reservamos para uso nuestro.
294
                resul = "CREATE TABLE " + this.parameters.tableID()
295
                                        + " ( " + featureType.getFieldId() +" serial PRIMARY KEY ";
296
                int j=0;
297
                for (int i = 0; i < featureType.size(); i++) {
298
                        IFeatureAttributeDescriptor fad=(IFeatureAttributeDescriptor)this.featureType.get(i);
299
                        String fieldType = fad.getDataType();
300
                        String strType = JDBCTypes.fieldTypeToString(fieldType);
301
                        /*
302
                         * if (fieldType == Types.VARCHAR) strType = strType + "(" +
303
                         * fieldsDescr[i].getFieldLength() + ")";
304
                         */
305
                        if (fad.getName().equalsIgnoreCase(featureType.getFieldId()))
306
                                continue;
307
                        resul = resul + ", " + fad.getName() + " "        + strType;
308
                        j++;
309
                }
310
                resul = resul + ");";
311
                return resul;
312
        }
313

    
314
        public boolean canWriteGeometry(int gvSIGgeometryType) {
315
                switch (gvSIGgeometryType) {
316
                case FShape.POINT:
317
                        return true;
318
                case FShape.LINE:
319
                        return true;
320
                case FShape.POLYGON:
321
                        return true;
322
                case FShape.ARC:
323
                        return false;
324
                case FShape.ELLIPSE:
325
                        return false;
326
                case FShape.MULTIPOINT:
327
                        return true;
328
                case FShape.TEXT:
329
                        return false;
330
                }
331
                return false;
332
        }
333

    
334

    
335
        private PreparedStatement getUpdateFeatureStatement(DBFeatureType dbFeatureType) throws SQLException{
336
                if (this.updateSt == null){
337
                        StringBuffer sqlBuf = new StringBuffer("UPDATE "
338
                                        + this.parameters.tableID() + " SET");
339
                        String sql = null;
340

    
341
                        Iterator iter = dbFeatureType.iterator();
342
                        while (iter.hasNext()){
343
                                IFeatureAttributeDescriptor fad=(IFeatureAttributeDescriptor)iter.next();
344
                                String name = fad.getName();
345
                                // El campo gid no lo actualizamos.
346
                                if (fad.isPrimaryKey())
347
                                        continue;
348
                                sqlBuf.append(" " + name + " = ? ,");
349

    
350
                        }
351
                        sqlBuf.deleteCharAt(sqlBuf.lastIndexOf(","));
352
                        sqlBuf.append(" WHERE ");
353
                        sqlBuf.append(getFliterForIDForPStatement(dbFeatureType));
354
                        sql = sqlBuf.toString();
355

    
356

    
357
                        this.updateSt= this.conex.prepareStatement(sql);
358
                } else{
359
                        this.updateSt.clearParameters();
360
                }
361
                return this.updateSt;
362

    
363
        }
364

    
365
        public String getSqlDeleteFeature(DBFeatureType dbFeatureType, JDBCFeature feature) {
366
                StringBuffer sqlBuf = new StringBuffer("DELETE FROM "
367
                                + this.parameters.tableID() + " WHERE ");
368
                String sql = null;
369
                sqlBuf.append(((JDBCFeature)feature).getFilterForID());
370
                sql = sqlBuf.toString();
371

    
372
                return sql;
373
        }
374

    
375
        public static void create(H2StoreParameters parameters, IFeatureType featureType)throws InitializeWriterException, InitializeException {
376
                Connection con = H2Utils.getConnection(parameters.getUrl(), parameters.getUser(), parameters.getPassw());
377

    
378
                StringBuffer sb=new StringBuffer();
379
                sb.append("CREATE TABLE ");
380
                sb.append(parameters.tableID());
381
                sb.append(" (");
382
                sb.append("id int, ");
383
                for (int i=0 ; i<featureType.size() ; i++){
384
                        IFeatureAttributeDescriptor descriptor=(IFeatureAttributeDescriptor)featureType.get(i);
385
                        String type = descriptor.getDataType();
386

    
387
                        if (type.equals(IFeatureAttributeDescriptor.TYPE_BOOLEAN)){
388
                                sb.append(descriptor.getName());
389
                                sb.append(" bit, ");
390
                        }else if (type.equals(IFeatureAttributeDescriptor.TYPE_BYTE)){
391
                                sb.append(descriptor.getName());
392
                                sb.append(" byte, ");
393
                        }else if (type.equals(IFeatureAttributeDescriptor.TYPE_DATE)){
394
                                sb.append(descriptor.getName());
395
                                sb.append(" date, ");
396
                        }else if (type.equals(IFeatureAttributeDescriptor.TYPE_DOUBLE)){
397
                                sb.append(descriptor.getName());
398
                                sb.append(" double, ");
399
                        }else if (type.equals(IFeatureAttributeDescriptor.TYPE_FLOAT)){
400
                                sb.append(descriptor.getName());
401
                                sb.append(" float, ");
402
                        }else if (type.equals(IFeatureAttributeDescriptor.TYPE_INT)){
403
                                sb.append(descriptor.getName());
404
                                sb.append(" int, ");
405
                        }else if (type.equals(IFeatureAttributeDescriptor.TYPE_LONG)){
406
                                sb.append(descriptor.getName());
407
                                sb.append(" bigint, ");
408
                        }else if (type.equals(IFeatureAttributeDescriptor.TYPE_STRING)){
409
                                sb.append(descriptor.getName());
410
                                sb.append(" varchar, ");
411
                        }else if (type.equals(IFeatureAttributeDescriptor.TYPE_GEOMETRY)){
412
                                sb.append(descriptor.getName());
413
                                sb.append(" other, ");
414
                        }else {
415
                                System.out.print(" ---- " + "TYPE UNKNOWN");
416
                        }
417
                }
418
                String createTable=sb.toString();
419
                createTable=createTable.substring(0, createTable.length()-2);
420
                createTable+=")";
421

    
422
                try{
423
                        Statement st=con.createStatement();
424
                        st.execute(createTable);
425
                        st.close();
426
                }
427
                catch(SQLException except){
428
                        throw new InitializeWriterException(parameters.getDataStoreName(),except);
429

    
430
                }
431
        }
432

    
433
        protected void loadPkInPreparedStatement(PreparedStatement ps,int paramIndex,DBFeatureType fType,IFeature feature) throws java.sql.SQLException{
434
                if (fType.getFieldsId().length != 1)
435
                        throw new UnsupportedOperationException("ID fields > 1");
436
                String id =fType.getFieldsId()[0];
437
                loadValueInPreparedStatement(ps, paramIndex, (JDBCAttributeDescriptor)fType.get(fType.getFieldIndex(id)), feature);
438
        }
439

    
440
        protected void loadValueInPreparedStatement(PreparedStatement ps,int paramIndex,JDBCAttributeDescriptor attr,IFeature feature) throws java.sql.SQLException{
441
                Object value = feature.get(attr.ordinal());
442
                if (value == null){
443
                        ps.setNull(paramIndex, attr.getSqlType());
444
                        return;
445
                }
446

    
447
                if (attr.getDataType() == IFeatureAttributeDescriptor.TYPE_GEOMETRY){
448
                        IGeometry geom =(IGeometry)feature.get(attr.ordinal());
449
                        ps.setBytes(
450
                                paramIndex,        wkbWriter.write(geom.toJTSGeometry())
451
                        );
452
                        return;
453
                }
454
                ps.setObject(paramIndex, feature.get(attr.ordinal()));
455
        }
456

    
457
        protected static String getFliterForIDForPStatement(DBFeatureType fType) {
458
                if (fType.getFieldsId().length != 1)
459
                        throw new UnsupportedOperationException("ID fields > 1");
460
                String id =fType.getFieldsId()[0];
461
                return id + " = ?";
462
        }
463
}