Statistics
| Revision:

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

History | View | Annotate | Download (14.9 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.JDBCFeaturesWriter;
24
import org.gvsig.data.datastores.vectorial.db.jdbc.JDBCStore;
25
import org.gvsig.data.datastores.vectorial.db.jdbc.JDBCTypes;
26
import org.gvsig.data.exception.InitializeException;
27
import org.gvsig.data.exception.InitializeWriterException;
28
import org.gvsig.data.exception.OpenException;
29
import org.gvsig.data.exception.ReadException;
30
import org.gvsig.data.exception.WriteException;
31
import org.gvsig.data.vectorial.IFeature;
32
import org.gvsig.data.vectorial.IFeatureAttributeDescriptor;
33
import org.gvsig.data.vectorial.IFeatureStore;
34
import org.gvsig.data.vectorial.IFeatureType;
35

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

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

    
50
        private PreparedStatement insertSt;
51
        private PreparedStatement updateSt;
52

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

    
55
        H2FeaturesWriter(){
56

    
57
        }
58

    
59
        public void init(IFeatureStore store) {
60
                this.store = (H2Store)store;
61
                this.parameters=(H2StoreParameters)store.getParameters();
62

    
63
                this.featureType = (DBFeatureType)this.store.getDefaultFeatureType();
64
                conex = this.store.getConnection();
65
        }
66

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

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

    
83
        public void preProcess() throws OpenException, InitializeWriterException {
84
                Statement st;
85

    
86

    
87
                try {
88
                        conex.setAutoCommit(false);
89
                        st = conex.createStatement();
90

    
91
                        if (bCreateTable) {
92
                                dropTableIfExist();
93

    
94
                                String sqlCreate = getSqlCreateSpatialTable(featureType);
95
                                System.out.println("sqlCreate =" + sqlCreate);
96
                                st.execute(sqlCreate);
97

    
98
//                                conex.commit();
99
                        }
100

    
101
//                        fieldManager = new JdbcFieldManager(((ConnectionJDBC)conex).getConnection(), lyrDef.getTableName());
102

    
103
                } catch (SQLException e) {
104
                        e.printStackTrace();
105
//                        throw new InitializeWriterException(getName(),e);
106
                }
107

    
108
//        ResultSet rsAux;
109
//                try {
110
////                                conex.setAutoCommit(false);
111
////                        alterTable();
112
//
113
////                        rsAux = st.executeQuery("SHOW server_encoding;");
114
////                rsAux.next();
115
////                String serverEncoding = rsAux.getString(1);
116
////                System.out.println("Server encoding = " + serverEncoding);
117
//                // st.execute("SET CLIENT_ENCODING TO 'UNICODE';");
118
//                // Intentamos convertir nuestras cadenas a ese encode.
119
////                setEncoding(serverEncoding);
120
//                } catch (SQLException e) {
121
//                        throw new InitializeWriterException("H2",e);
122
//                }
123
        }
124

    
125
        public void deleteFeature(IFeature feature) throws WriteException {
126
                Statement st;
127
                String sqlDelete = getSqlDeleteFeature(featureType, feature);
128
                System.out.println("sql = " + sqlDelete);
129
                try {
130
                        st = this.conex.createStatement();
131
                        st.execute(sqlDelete);
132
                } catch (SQLException e) {
133
                        throw new WriteException(this.store.getName(),e);
134
                }
135

    
136
        }
137

    
138
        public void insertFeature(IFeature feature) throws WriteException {
139

    
140
                DBFeatureType ftype = (DBFeatureType)feature.getType();
141

    
142
                try {
143
                        PreparedStatement ps=this.getInsertFeatureStatement(ftype);
144
                        Iterator it = ftype.iterator();
145

    
146
                        int index= 1;
147
                        while (it.hasNext()){
148
                                JDBCAttributeDescriptor fad=(JDBCAttributeDescriptor)it.next();
149
                                if (fad.isReadOnly() || fad.isAutoIncrement())
150
                                        continue;
151

    
152

    
153
                                loadValueInPreparedStatement(ps, index, fad, feature);
154
                                index++;
155
                        }
156
//                        ps.setObject(index, feature.get(ftype.getFieldIdIndex()));
157

    
158
                        ps.execute();
159

    
160
                } catch (SQLException e) {
161
                        throw new WriteException(this.store.getName(),e);
162
                }
163
        }
164

    
165
        private PreparedStatement getInsertFeatureStatement(DBFeatureType ftype) throws SQLException {
166
                if (this.insertSt == null){
167
                        StringBuffer fields = new StringBuffer();
168
                        StringBuffer values = new StringBuffer();
169
                        StringBuffer sql = new StringBuffer();
170

    
171
                        Iterator iter = ftype.iterator();
172
                        while (iter.hasNext()){
173
                                DBAttributeDescriptor fad=(DBAttributeDescriptor)iter.next();
174
                                String name = fad.getName();
175
                                if (fad.isReadOnly() || fad.isAutoIncrement())
176
                                        continue;
177
                                fields.append(name+",");
178
                                values.append("?,");
179

    
180
                        }
181
                        sql.append("INSERT INTO "+ftype.getTableID()+" (");
182
                        sql.append(fields.substring(0, fields.length()-1));
183
                        sql.append(") VALUES (");
184
                        sql.append(values.substring(0, values.length()-1));
185
                        sql.append(")");
186

    
187
                        this.insertSt= this.conex.prepareStatement(sql.toString());
188
                        System.out.println(sql.toString());
189
                } else{
190
                        this.insertSt.clearParameters();
191
                }
192
                return this.insertSt;
193

    
194
        }
195

    
196
        public void updateFeatureType(IFeatureType featureType) {
197
                this.featureType=(DBFeatureType)featureType;
198
        }
199

    
200
        /**
201
         * @param createTable
202
         *            The bCreateTable to set.
203
         */
204
        public void setCreateTable(boolean createTable) {
205
                bCreateTable = createTable;
206
        }
207

    
208
        boolean dropTableIfExist() throws SQLException{
209
                if (!this.existTable(parameters.getSchema(), parameters.getTableName())){
210
                        return false;
211
                }
212
                Statement st = conex.createStatement();
213
                st.execute("DROP TABLE " + parameters.tableID() + ";");
214
                st.close();
215
                return false;
216
        }
217
        private boolean existTable(String schema, String tableName) throws SQLException{
218
                boolean exists =false;
219
                DatabaseMetaData metadata = conex.getMetaData();
220

    
221
                ResultSet rs = metadata.getTables(null, schema, tableName, null);
222

    
223
                exists = !rs.isAfterLast();
224
                rs.close();
225

    
226
                return exists;
227
        }
228

    
229
        public void updateFeature(IFeature oldFeature, IFeature feature) throws WriteException, ReadException {
230

    
231
                DBFeatureType ftype = (DBFeatureType)feature.getType();
232

    
233
                try {
234
                        PreparedStatement ps=this.getUpdateFeatureStatement(ftype);
235
                        Iterator it = ftype.iterator();
236

    
237
                        int index= 1;
238
                        while (it.hasNext()){
239
                                JDBCAttributeDescriptor fad=(JDBCAttributeDescriptor)it.next();
240
                                if (fad.isPrimaryKey())
241
                                        continue;
242
                                loadValueInPreparedStatement(ps, index, fad, feature);
243
                                index++;
244
                        }
245

    
246
                        loadPkInPreparedStatement(ps, index, ftype, feature);
247

    
248
                        ps.execute();
249

    
250
                } catch (SQLException e) {
251
                        throw new WriteException(this.store.getName(),e);
252
                }
253
        }
254

    
255
        public void deleteAttribute(IFeatureAttributeDescriptor attribute) throws WriteException {
256
                try {
257
                        Statement st = conex.createStatement();
258
                        String sql = "ALTER TABLE " + parameters.tableID() + " DROP COLUMN "
259
                                + attribute.getName() + ";";
260
                        st.execute(sql);
261
                } catch (SQLException e) {
262
                        throw new WriteException(this.store.getName(),e);
263
                }
264
        }
265

    
266
        public void updateAttribute(IFeatureAttributeDescriptor oldAttribute, IFeatureAttributeDescriptor attribute) throws WriteException, ReadException {
267
                try {
268
                        Statement st = conex.createStatement();
269
                        String sql = "ALTER TABLE " + parameters.tableID() + " RENAME COLUMN "
270
                        + oldAttribute.getName() + " TO " + attribute.getName() + ";";
271
                        st.execute(sql);
272
                } catch (SQLException e) {
273
                        throw new WriteException(this.store.getName(),e);
274
                }
275
        }
276

    
277
        public void insertAttribute(IFeatureAttributeDescriptor attribute) throws WriteException {
278
                try {
279
                        Statement st = conex.createStatement();
280

    
281
                        String sql = "ALTER TABLE "
282
                                + parameters.tableID()
283
                                + " ADD COLUMN "
284
                                + attribute.getName()
285
                                + " "
286
                                + JDBCTypes.fieldTypeToString(attribute.getDataType())
287
                                + " "
288
                                + "DEFAULT " + attribute.getDefaultValue()
289
                                + ";";
290
                        st.execute(sql);
291
                } catch (SQLException e) {
292
                        throw new WriteException(this.store.getName(),e);
293
                }
294
        }
295

    
296
        public String getSqlCreateSpatialTable(DBFeatureType featureType) {
297

    
298
                String resul;
299
                /* boolean bExistGID = false;
300
                for (int i = 0; i < dbLayerDef.getFieldNames().length; i++) {
301
                        if (dbLayerDef.getFieldNames()[i].equalsIgnoreCase("gid")) {
302
                                bExistGID = true;
303
                                break;
304
                        }
305
                } */
306
                /* if (bExistGID) // Usamos el existente y no a?adimos ninguno nosotros
307
                        resul = "CREATE TABLE " + dbLayerDef.getTableName() + " (";
308
                else */
309
                // FJP: NUEVO: NO TOLERAMOS CAMPOS QUE SE LLAMEN GID. Lo reservamos para uso nuestro.
310
                resul = "CREATE TABLE " + this.parameters.tableID()
311
                                        + " ( " + featureType.getFieldId() +" serial PRIMARY KEY ";
312
                int j=0;
313
                for (int i = 0; i < featureType.size(); i++) {
314
                        IFeatureAttributeDescriptor fad=(IFeatureAttributeDescriptor)this.featureType.get(i);
315
                        String fieldType = fad.getDataType();
316
                        String strType = JDBCTypes.fieldTypeToString(fieldType);
317
                        /*
318
                         * if (fieldType == Types.VARCHAR) strType = strType + "(" +
319
                         * fieldsDescr[i].getFieldLength() + ")";
320
                         */
321
                        if (fad.getName().equalsIgnoreCase(featureType.getFieldId()))
322
                                continue;
323
                        resul = resul + ", " + fad.getName() + " "        + strType;
324
                        j++;
325
                }
326
                resul = resul + ");";
327
                return resul;
328
        }
329

    
330
        public boolean canWriteGeometry(int gvSIGgeometryType) {
331
                switch (gvSIGgeometryType) {
332
                case FShape.POINT:
333
                        return true;
334
                case FShape.LINE:
335
                        return true;
336
                case FShape.POLYGON:
337
                        return true;
338
                case FShape.ARC:
339
                        return false;
340
                case FShape.ELLIPSE:
341
                        return false;
342
                case FShape.MULTIPOINT:
343
                        return true;
344
                case FShape.TEXT:
345
                        return false;
346
                }
347
                return false;
348
        }
349

    
350

    
351
        private PreparedStatement getUpdateFeatureStatement(DBFeatureType dbFeatureType) throws SQLException{
352
                if (this.updateSt == null){
353
                        StringBuffer sqlBuf = new StringBuffer("UPDATE "
354
                                        + this.parameters.tableID() + " SET");
355
                        String sql = null;
356

    
357
                        Iterator iter = dbFeatureType.iterator();
358
                        while (iter.hasNext()){
359
                                IFeatureAttributeDescriptor fad=(IFeatureAttributeDescriptor)iter.next();
360
                                String name = fad.getName();
361
                                // El campo gid no lo actualizamos.
362
                                if (fad.isPrimaryKey())
363
                                        continue;
364
                                sqlBuf.append(" " + name + " = ? ,");
365

    
366
                        }
367
                        sqlBuf.deleteCharAt(sqlBuf.lastIndexOf(","));
368
                        sqlBuf.append(" WHERE ");
369
                        sqlBuf.append(getFliterForIDForPStatement(dbFeatureType));
370
                        sql = sqlBuf.toString();
371

    
372

    
373
                        this.updateSt= this.conex.prepareStatement(sql);
374
                } else{
375
                        this.updateSt.clearParameters();
376
                }
377
                return this.updateSt;
378

    
379
        }
380

    
381
        public String getSqlDeleteFeature(DBFeatureType dbFeatureType, IFeature feature) {
382
                StringBuffer sqlBuf = new StringBuffer("DELETE FROM "
383
                                + this.parameters.tableID() + " WHERE ");
384
                String sql = null;
385
                sqlBuf.append(H2Utils.getFilterForID(dbFeatureType, feature));
386
                sql = sqlBuf.toString();
387

    
388
                return sql;
389
        }
390

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

    
394
                StringBuffer sb=new StringBuffer();
395
                sb.append("CREATE TABLE ");
396
                sb.append(parameters.tableID());
397
                sb.append(" (");
398
                sb.append("id int, ");
399
                for (int i=0 ; i<featureType.size() ; i++){
400
                        IFeatureAttributeDescriptor descriptor=(IFeatureAttributeDescriptor)featureType.get(i);
401
                        String type = descriptor.getDataType();
402

    
403
                        if (type.equals(IFeatureAttributeDescriptor.TYPE_BOOLEAN)){
404
                                sb.append(descriptor.getName());
405
                                sb.append(" bit, ");
406
                        }else if (type.equals(IFeatureAttributeDescriptor.TYPE_BYTE)){
407
                                sb.append(descriptor.getName());
408
                                sb.append(" byte, ");
409
                        }else if (type.equals(IFeatureAttributeDescriptor.TYPE_DATE)){
410
                                sb.append(descriptor.getName());
411
                                sb.append(" date, ");
412
                        }else if (type.equals(IFeatureAttributeDescriptor.TYPE_DOUBLE)){
413
                                sb.append(descriptor.getName());
414
                                sb.append(" double, ");
415
                        }else if (type.equals(IFeatureAttributeDescriptor.TYPE_FLOAT)){
416
                                sb.append(descriptor.getName());
417
                                sb.append(" float, ");
418
                        }else if (type.equals(IFeatureAttributeDescriptor.TYPE_INT)){
419
                                sb.append(descriptor.getName());
420
                                sb.append(" int, ");
421
                        }else if (type.equals(IFeatureAttributeDescriptor.TYPE_LONG)){
422
                                sb.append(descriptor.getName());
423
                                sb.append(" bigint, ");
424
                        }else if (type.equals(IFeatureAttributeDescriptor.TYPE_STRING)){
425
                                sb.append(descriptor.getName());
426
                                sb.append(" varchar, ");
427
                        }else if (type.equals(IFeatureAttributeDescriptor.TYPE_GEOMETRY)){
428
                                sb.append(descriptor.getName());
429
                                sb.append(" other, ");
430
                        }else {
431
                                System.out.print(" ---- " + "TYPE UNKNOWN");
432
                        }
433
                }
434
                String createTable=sb.toString();
435
                createTable=createTable.substring(0, createTable.length()-2);
436
                createTable+=")";
437

    
438
                try{
439
                        Statement st=con.createStatement();
440
                        st.execute(createTable);
441
                        st.close();
442
                }
443
                catch(SQLException except){
444
                        throw new InitializeWriterException(parameters.getDataStoreName(),except);
445

    
446
                }
447
        }
448

    
449
        protected void loadPkInPreparedStatement(PreparedStatement ps,int paramIndex,DBFeatureType fType,IFeature feature) throws java.sql.SQLException{
450
                if (fType.getFieldsId().length != 1)
451
                        throw new UnsupportedOperationException("ID fields > 1");
452
                String id =fType.getFieldsId()[0];
453
                loadValueInPreparedStatement(ps, paramIndex, (JDBCAttributeDescriptor)fType.get(fType.getFieldIndex(id)), feature);
454
        }
455

    
456
        protected void loadValueInPreparedStatement(PreparedStatement ps,int paramIndex,JDBCAttributeDescriptor attr,IFeature feature) throws java.sql.SQLException{
457
                Object value = feature.get(attr.ordinal());
458
                if (value == null){
459
                        ps.setNull(paramIndex, attr.getSqlType());
460
                        return;
461
                }
462

    
463
                if (attr.getDataType() == IFeatureAttributeDescriptor.TYPE_GEOMETRY){
464
                        IGeometry geom =(IGeometry)feature.get(attr.ordinal());
465
                        ps.setBytes(
466
                                paramIndex,        wkbWriter.write(geom.toJTSGeometry())
467
                        );
468
                        return;
469
                }
470
                ps.setObject(paramIndex, feature.get(attr.ordinal()));
471
        }
472

    
473
        protected static String getFliterForIDForPStatement(DBFeatureType fType) {
474
                if (fType.getFieldsId().length != 1)
475
                        throw new UnsupportedOperationException("ID fields > 1");
476
                String id =fType.getFieldsId()[0];
477
                return id + " = ?";
478
        }
479
}