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 19845 vcaballero
package org.gvsig.data.datastores.vectorial.db.jdbc.h2;
2 19541 vcaballero
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 19610 jmvivo
import java.sql.DatabaseMetaData;
12 19691 jmvivo
import java.sql.PreparedStatement;
13 19541 vcaballero
import java.sql.ResultSet;
14
import java.sql.SQLException;
15
import java.sql.Statement;
16
import java.sql.Types;
17 19691 jmvivo
import java.util.Iterator;
18 19541 vcaballero
19 19845 vcaballero
import org.gvsig.data.datastores.vectorial.ISelectiveWriter;
20 19893 jmvivo
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 19845 vcaballero
import org.gvsig.data.datastores.vectorial.db.jdbc.JDBCTypes;
26 19893 jmvivo
import org.gvsig.data.exception.InitializeException;
27 19541 vcaballero
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 19738 vcaballero
import org.gvsig.data.vectorial.IFeatureStore;
34 19541 vcaballero
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 20029 jmvivo
import com.vividsolutions.jts.io.WKBWriter;
42 19541 vcaballero
43 19965 jmvivo
class H2FeaturesWriter extends JDBCFeaturesWriter implements ISelectiveWriter {
44 19893 jmvivo
        DBFeatureType featureType;
45
        boolean bCreateTable=false;
46 19541 vcaballero
        private String toEncode;
47 19893 jmvivo
        H2Store store;
48
        H2StoreParameters parameters;
49 19541 vcaballero
50 19691 jmvivo
        private PreparedStatement insertSt;
51
        private PreparedStatement updateSt;
52 19610 jmvivo
53 20029 jmvivo
        private static WKBWriter wkbWriter = new WKBWriter();
54 19691 jmvivo
55 20029 jmvivo
        H2FeaturesWriter(){
56
57
        }
58
59 19738 vcaballero
        public void init(IFeatureStore store) {
60
                this.store = (H2Store)store;
61
                this.parameters=(H2StoreParameters)store.getParameters();
62 19610 jmvivo
63 19738 vcaballero
                this.featureType = (DBFeatureType)this.store.getDefaultFeatureType();
64
                conex = this.store.getConnection();
65 20029 jmvivo
        }
66
67
        public void postProcess() throws OpenException, WriteException {
68 19541 vcaballero
                try {
69 20029 jmvivo
                        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 19541 vcaballero
                        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 20029 jmvivo
//                                conex.commit();
99 19541 vcaballero
                        }
100 20029 jmvivo
101 19541 vcaballero
//                        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 20029 jmvivo
//        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 19541 vcaballero
        }
124
125
        public void deleteFeature(IFeature feature) throws WriteException {
126 19691 jmvivo
                Statement st;
127 19541 vcaballero
                String sqlDelete = getSqlDeleteFeature(featureType, feature);
128
                System.out.println("sql = " + sqlDelete);
129
                try {
130 19691 jmvivo
                        st = this.conex.createStatement();
131 19541 vcaballero
                        st.execute(sqlDelete);
132
                } catch (SQLException e) {
133 20029 jmvivo
                        throw new WriteException(this.store.getName(),e);
134 19541 vcaballero
                }
135
136
        }
137
138
        public void insertFeature(IFeature feature) throws WriteException {
139 19691 jmvivo
140
                DBFeatureType ftype = (DBFeatureType)feature.getType();
141
142 19541 vcaballero
                try {
143 19691 jmvivo
                        PreparedStatement ps=this.getInsertFeatureStatement(ftype);
144
                        Iterator it = ftype.iterator();
145
146 19697 jmvivo
                        int index= 1;
147 19691 jmvivo
                        while (it.hasNext()){
148 19893 jmvivo
                                JDBCAttributeDescriptor fad=(JDBCAttributeDescriptor)it.next();
149 19744 jmvivo
                                if (fad.isReadOnly() || fad.isAutoIncrement())
150 19691 jmvivo
                                        continue;
151
152
153 20029 jmvivo
                                loadValueInPreparedStatement(ps, index, fad, feature);
154 19691 jmvivo
                                index++;
155
                        }
156 19744 jmvivo
//                        ps.setObject(index, feature.get(ftype.getFieldIdIndex()));
157 19691 jmvivo
158
                        ps.execute();
159
160 19541 vcaballero
                } catch (SQLException e) {
161 20029 jmvivo
                        throw new WriteException(this.store.getName(),e);
162 19541 vcaballero
                }
163 19691 jmvivo
        }
164 19541 vcaballero
165 19691 jmvivo
        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 19744 jmvivo
                                if (fad.isReadOnly() || fad.isAutoIncrement())
176 19691 jmvivo
                                        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 19697 jmvivo
                        sql.append(")");
186 19691 jmvivo
187
                        this.insertSt= this.conex.prepareStatement(sql.toString());
188 19744 jmvivo
                        System.out.println(sql.toString());
189 19691 jmvivo
                } else{
190
                        this.insertSt.clearParameters();
191
                }
192
                return this.insertSt;
193
194 19541 vcaballero
        }
195 19691 jmvivo
196 19541 vcaballero
        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 20029 jmvivo
208 19893 jmvivo
        boolean dropTableIfExist() throws SQLException{
209 19610 jmvivo
                if (!this.existTable(parameters.getSchema(), parameters.getTableName())){
210 19541 vcaballero
                        return false;
211
                }
212 19691 jmvivo
                Statement st = conex.createStatement();
213 19610 jmvivo
                st.execute("DROP TABLE " + parameters.tableID() + ";");
214 19541 vcaballero
                st.close();
215
                return false;
216
        }
217
        private boolean existTable(String schema, String tableName) throws SQLException{
218
                boolean exists =false;
219 19610 jmvivo
                DatabaseMetaData metadata = conex.getMetaData();
220 19541 vcaballero
221 19610 jmvivo
                ResultSet rs = metadata.getTables(null, schema, tableName, null);
222 19541 vcaballero
223 19610 jmvivo
                exists = !rs.isAfterLast();
224 19541 vcaballero
                rs.close();
225
226
                return exists;
227
        }
228
229
        public void updateFeature(IFeature oldFeature, IFeature feature) throws WriteException, ReadException {
230
231 19691 jmvivo
                DBFeatureType ftype = (DBFeatureType)feature.getType();
232 19541 vcaballero
233
                try {
234 19691 jmvivo
                        PreparedStatement ps=this.getUpdateFeatureStatement(ftype);
235
                        Iterator it = ftype.iterator();
236
237
                        int index= 1;
238
                        while (it.hasNext()){
239 19893 jmvivo
                                JDBCAttributeDescriptor fad=(JDBCAttributeDescriptor)it.next();
240 19781 jmvivo
                                if (fad.isPrimaryKey())
241 19691 jmvivo
                                        continue;
242 20029 jmvivo
                                loadValueInPreparedStatement(ps, index, fad, feature);
243 19691 jmvivo
                                index++;
244
                        }
245
246 20029 jmvivo
                        loadPkInPreparedStatement(ps, index, ftype, feature);
247 19781 jmvivo
248 19691 jmvivo
                        ps.execute();
249
250 19541 vcaballero
                } catch (SQLException e) {
251 20029 jmvivo
                        throw new WriteException(this.store.getName(),e);
252 19541 vcaballero
                }
253
        }
254
255
        public void deleteAttribute(IFeatureAttributeDescriptor attribute) throws WriteException {
256
                try {
257 19691 jmvivo
                        Statement st = conex.createStatement();
258 19610 jmvivo
                        String sql = "ALTER TABLE " + parameters.tableID() + " DROP COLUMN "
259 19541 vcaballero
                                + attribute.getName() + ";";
260
                        st.execute(sql);
261
                } catch (SQLException e) {
262 20029 jmvivo
                        throw new WriteException(this.store.getName(),e);
263 19541 vcaballero
                }
264
        }
265
266
        public void updateAttribute(IFeatureAttributeDescriptor oldAttribute, IFeatureAttributeDescriptor attribute) throws WriteException, ReadException {
267
                try {
268 19691 jmvivo
                        Statement st = conex.createStatement();
269 19610 jmvivo
                        String sql = "ALTER TABLE " + parameters.tableID() + " RENAME COLUMN "
270 19541 vcaballero
                        + oldAttribute.getName() + " TO " + attribute.getName() + ";";
271
                        st.execute(sql);
272
                } catch (SQLException e) {
273 20029 jmvivo
                        throw new WriteException(this.store.getName(),e);
274 19541 vcaballero
                }
275
        }
276
277
        public void insertAttribute(IFeatureAttributeDescriptor attribute) throws WriteException {
278
                try {
279 19691 jmvivo
                        Statement st = conex.createStatement();
280 19541 vcaballero
281
                        String sql = "ALTER TABLE "
282 19610 jmvivo
                                + parameters.tableID()
283 19541 vcaballero
                                + " 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 20029 jmvivo
                        throw new WriteException(this.store.getName(),e);
293 19541 vcaballero
                }
294
        }
295
296 19610 jmvivo
        public String getSqlCreateSpatialTable(DBFeatureType featureType) {
297 19541 vcaballero
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 19610 jmvivo
                resul = "CREATE TABLE " + this.parameters.tableID()
311
                                        + " ( " + featureType.getFieldId() +" serial PRIMARY KEY ";
312 19541 vcaballero
                int j=0;
313 19610 jmvivo
                for (int i = 0; i < featureType.size(); i++) {
314
                        IFeatureAttributeDescriptor fad=(IFeatureAttributeDescriptor)this.featureType.get(i);
315 19541 vcaballero
                        String fieldType = fad.getDataType();
316
                        String strType = JDBCTypes.fieldTypeToString(fieldType);
317
                        /*
318
                         * if (fieldType == Types.VARCHAR) strType = strType + "(" +
319
                         * fieldsDescr[i].getFieldLength() + ")";
320
                         */
321 19610 jmvivo
                        if (fad.getName().equalsIgnoreCase(featureType.getFieldId()))
322 19541 vcaballero
                                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 19691 jmvivo
        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 19541 vcaballero
                                String name = fad.getName();
361
                                // El campo gid no lo actualizamos.
362 19781 jmvivo
                                if (fad.isPrimaryKey())
363 19541 vcaballero
                                        continue;
364 19691 jmvivo
                                sqlBuf.append(" " + name + " = ? ,");
365
366 19541 vcaballero
                        }
367 19691 jmvivo
                        sqlBuf.deleteCharAt(sqlBuf.lastIndexOf(","));
368
                        sqlBuf.append(" WHERE ");
369 20029 jmvivo
                        sqlBuf.append(getFliterForIDForPStatement(dbFeatureType));
370 19691 jmvivo
                        sql = sqlBuf.toString();
371
372
373
                        this.updateSt= this.conex.prepareStatement(sql);
374
                } else{
375
                        this.updateSt.clearParameters();
376 19541 vcaballero
                }
377 19691 jmvivo
                return this.updateSt;
378 19541 vcaballero
379
        }
380 19691 jmvivo
381 19541 vcaballero
        public String getSqlDeleteFeature(DBFeatureType dbFeatureType, IFeature feature) {
382
                StringBuffer sqlBuf = new StringBuffer("DELETE FROM "
383 19610 jmvivo
                                + this.parameters.tableID() + " WHERE ");
384 19541 vcaballero
                String sql = null;
385 20029 jmvivo
                sqlBuf.append(H2Utils.getFilterForID(dbFeatureType, feature));
386 19541 vcaballero
                sql = sqlBuf.toString();
387
388
                return sql;
389
        }
390 19674 vcaballero
391 19893 jmvivo
        public static void create(H2StoreParameters parameters, IFeatureType featureType)throws InitializeWriterException, InitializeException {
392
                Connection con = H2Utils.getConnection(parameters.getUrl(), parameters.getUser(), parameters.getPassw());
393
394 19674 vcaballero
                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 20029 jmvivo
                        throw new InitializeWriterException(parameters.getDataStoreName(),except);
445 19674 vcaballero
446
                }
447
        }
448 20029 jmvivo
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 19541 vcaballero
}