Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libDataSourceDBBaseDrivers / src / org / gvsig / data / datastores / vectorial / db / jdbc / postgresql / PostgresqlFeaturesWriter.java @ 20376

History | View | Annotate | Download (14.4 KB)

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

    
3
import java.io.ByteArrayOutputStream;
4
import java.io.PrintStream;
5
import java.io.UnsupportedEncodingException;
6
import java.sql.Connection;
7
import java.sql.DatabaseMetaData;
8
import java.sql.PreparedStatement;
9
import java.sql.ResultSet;
10
import java.sql.SQLException;
11
import java.sql.Statement;
12
import java.util.Iterator;
13

    
14
import org.gvsig.data.IDataExplorer;
15
import org.gvsig.data.IDataStoreParameters;
16
import org.gvsig.data.datastores.vectorial.ISelectiveWriter;
17
import org.gvsig.data.datastores.vectorial.db.DBAttributeDescriptor;
18
import org.gvsig.data.datastores.vectorial.db.DBFeatureType;
19
import org.gvsig.data.datastores.vectorial.db.jdbc.JDBCAttributeDescriptor;
20
import org.gvsig.data.datastores.vectorial.db.jdbc.JDBCFeature;
21
import org.gvsig.data.datastores.vectorial.db.jdbc.JDBCFeaturesWriter;
22
import org.gvsig.data.datastores.vectorial.db.jdbc.JDBCTypes;
23
import org.gvsig.data.exception.InitializeException;
24
import org.gvsig.data.exception.InitializeWriterException;
25
import org.gvsig.data.exception.ReadException;
26
import org.gvsig.data.exception.WriteException;
27
import org.gvsig.data.vectorial.IFeature;
28
import org.gvsig.data.vectorial.IFeatureAttributeDescriptor;
29
import org.gvsig.data.vectorial.IFeatureStore;
30
import org.gvsig.data.vectorial.IFeatureType;
31
import org.gvsig.data.vectorial.INewFeatureStoreParameters;
32

    
33
import com.iver.cit.gvsig.fmap.core.FShape;
34
import com.iver.cit.gvsig.fmap.core.IGeometry;
35
import com.vividsolutions.jts.io.WKBWriter;
36

    
37
public class PostgresqlFeaturesWriter extends JDBCFeaturesWriter {
38
        DBFeatureType featureType;
39
        boolean bCreateTable=false;
40
        private String toEncode;
41
        PostgresqlStoreParameters parameters;
42

    
43
        private PreparedStatement insertSt;
44
        private PreparedStatement updateSt;
45

    
46
        private static WKBWriter wkbWriter = new WKBWriter();
47

    
48
        PostgresqlFeaturesWriter(){
49
        }
50

    
51
        public void init(IFeatureStore store) {
52
                super.init(store);
53
                PostgresqlStore pgStore = (PostgresqlStore)store;
54
                this.parameters=pgStore.getParametersPostgresql();
55

    
56
                this.featureType = (DBFeatureType)this.store.getDefaultFeatureType();
57

    
58
        }
59

    
60
        public void preProcess() throws WriteException, ReadException {
61
                super.preProcess();
62
                //??????????????????????????
63
                // ATENTION: We will transform (in PostGIS class; doubleQuote())
64
        // to UTF-8 strings. Then, we tell the PostgreSQL server
65
        // that we will use UTF-8, and it can translate
66
        // to its charset
67
        // Note: we have to translate to UTF-8 because
68
        // the server cannot manage UTF-16
69
                //??????????????????????????
70

    
71

    
72
                if (bCreateTable) {
73

    
74
                        IDataExplorer explorer = this.store.getExplorer();
75

    
76
                        IDataStoreParameters params =this.store.getParameters();
77
                        explorer.remove(params);
78

    
79
                        INewFeatureStoreParameters newParam = (INewFeatureStoreParameters)explorer.createNewDataStoreParameter();
80

    
81

    
82
                        newParam.setFeatureType(this.featureType);
83
                        explorer.add(newParam);
84
                }
85

    
86
//        ResultSet rsAux;
87
//                try {
88
////                                conex.setAutoCommit(false);
89
////                        alterTable();
90
//
91
////                        rsAux = st.executeQuery("SHOW server_encoding;");
92
////                rsAux.next();
93
////                String serverEncoding = rsAux.getString(1);
94
////                System.out.println("Server encoding = " + serverEncoding);
95
//                // st.execute("SET CLIENT_ENCODING TO 'UNICODE';");
96
//                // Intentamos convertir nuestras cadenas a ese encode.
97
////                setEncoding(serverEncoding);
98
//                } catch (SQLException e) {
99
//                        throw new InitializeWriterException("H2",e);
100
//                }
101

    
102
        }
103

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

    
115
        }
116

    
117
        public void insertFeature(IFeature feature) throws WriteException {
118

    
119
                DBFeatureType ftype = (DBFeatureType)feature.getType();
120

    
121
                try {
122
                        PreparedStatement ps=this.getInsertFeatureStatement(ftype);
123
                        Iterator it = ftype.iterator();
124

    
125
                        int index= 1;
126
                        while (it.hasNext()){
127
                                JDBCAttributeDescriptor fad=(JDBCAttributeDescriptor)it.next();
128
                                if (fad.isReadOnly())
129
                                        continue;
130

    
131

    
132
                                loadValueInPreparedStatement(ps, index, fad, feature);
133
                                index++;
134
                        }
135
//                        ps.setObject(index, feature.get(ftype.getFieldIdIndex()));
136

    
137
                        ps.execute();
138

    
139
                } catch (SQLException e) {
140
                        throw new WriteException(this.store.getName(),e);
141
                }
142
        }
143

    
144
        private PreparedStatement getInsertFeatureStatement(DBFeatureType ftype) throws SQLException {
145
                if (this.insertSt == null){
146
                        StringBuffer fields = new StringBuffer();
147
                        StringBuffer values = new StringBuffer();
148
                        StringBuffer sql = new StringBuffer();
149

    
150
                        Iterator iter = ftype.iterator();
151
                        while (iter.hasNext()){
152
                                DBAttributeDescriptor fad=(DBAttributeDescriptor)iter.next();
153
                                String name = fad.getName();
154
                                if (fad.isReadOnly())
155
                                        continue;
156
                                fields.append(name+",");
157
                                values.append("?,");
158

    
159
                        }
160
                        sql.append("INSERT INTO "+ftype.getTableID()+" (");
161
                        sql.append(fields.substring(0, fields.length()-1));
162
                        sql.append(") VALUES (");
163
                        sql.append(values.substring(0, values.length()-1));
164
                        sql.append(")");
165

    
166
                        this.insertSt= this.conex.prepareStatement(sql.toString());
167
                        System.out.println(sql.toString());
168
                } else{
169
                        this.insertSt.clearParameters();
170
                }
171
                return this.insertSt;
172

    
173
        }
174

    
175
        public void updateFeatureType(IFeatureType featureType) {
176
                this.featureType=(DBFeatureType)featureType;
177
        }
178

    
179
        /**
180
         * @param createTable
181
         *            The bCreateTable to set.
182
         */
183
        public void setCreateTable(boolean createTable) {
184
                bCreateTable = createTable;
185
        }
186
        boolean dropTableIfExist() throws SQLException{
187
                if (!this.existTable(parameters.getSchema(), parameters.getTableName())){
188
                        return false;
189
                }
190
                Statement st = conex.createStatement();
191
                st.execute("DROP TABLE " + parameters.tableID() + ";");
192
                st.close();
193
                return false;
194
        }
195
        private boolean existTable(String schema, String tableName) throws SQLException{
196
                boolean exists =false;
197
                DatabaseMetaData metadata = conex.getMetaData();
198

    
199
                ResultSet rs = metadata.getTables(null, schema, tableName, null);
200

    
201
                exists = !rs.isAfterLast();
202
                rs.close();
203

    
204
                return exists;
205
        }
206

    
207
        public void updateFeature(IFeature oldFeature, IFeature feature) throws WriteException, ReadException {
208

    
209
                DBFeatureType ftype = (DBFeatureType)feature.getType();
210

    
211
                try {
212
                        PreparedStatement ps=this.getUpdateFeatureStatement(ftype);
213
                        Iterator it = ftype.iterator();
214

    
215
                        int index= 1;
216
                        while (it.hasNext()){
217
                                JDBCAttributeDescriptor fad=(JDBCAttributeDescriptor)it.next();
218
                                if (fad.isPrimaryKey())
219
                                        continue;
220
                                loadValueInPreparedStatement(ps, index, fad, feature);
221
                                index++;
222
                        }
223

    
224
                        loadPkInPreparedStatement(ps, index, ftype, feature);
225

    
226
                        ps.execute();
227

    
228
                } catch (SQLException e) {
229
                        throw new WriteException(this.store.getName(),e);
230
                }
231
        }
232

    
233
        public void deleteAttribute(IFeatureAttributeDescriptor attribute) throws WriteException {
234
                try {
235
                        Statement st = conex.createStatement();
236
                        String sql = "ALTER TABLE " + parameters.tableID() + " DROP COLUMN "
237
                                + attribute.getName() + ";";
238
                        st.execute(sql);
239
                } catch (SQLException e) {
240
                        throw new WriteException(this.store.getName(),e);
241
                }
242
        }
243

    
244
        public void updateAttribute(IFeatureAttributeDescriptor oldAttribute, IFeatureAttributeDescriptor attribute) throws WriteException, ReadException {
245
                try {
246
                        Statement st = conex.createStatement();
247
                        String sql = "ALTER TABLE " + parameters.tableID() + " RENAME COLUMN "
248
                        + oldAttribute.getName() + " TO " + attribute.getName() + ";";
249
                        st.execute(sql);
250
                } catch (SQLException e) {
251
                        throw new WriteException(this.store.getName(),e);
252
                }
253
        }
254

    
255
        public void insertAttribute(IFeatureAttributeDescriptor attribute) throws WriteException {
256
                try {
257
                        Statement st = conex.createStatement();
258

    
259
                        String sql = "ALTER TABLE "
260
                                + parameters.tableID()
261
                                + " ADD COLUMN "
262
                                + attribute.getName()
263
                                + " "
264
                                + JDBCTypes.fieldTypeToString(attribute.getDataType())
265
                                + " "
266
                                + "DEFAULT " + attribute.getDefaultValue()
267
                                + ";";
268
                        st.execute(sql);
269
                } catch (SQLException e) {
270
                        throw new WriteException(this.store.getName(),e);
271
                }
272
        }
273

    
274
        /** @deprecated ???
275
        *
276
        */
277
        public void setEncoding(String toEncode){
278
                if (toEncode.compareToIgnoreCase("SQL_ASCII") == 0){
279
                   this.toEncode = "ASCII";
280
                  } else {
281
                          this.toEncode = toEncode;
282
                  }
283
        }
284

    
285
        /** @deprecated ???
286
        *
287
        */
288
        public String getEncoding() {
289
                return toEncode;
290
        }
291

    
292
        /** @deprecated ???
293
        *
294
        */
295
        public boolean canWriteGeometry(int gvSIGgeometryType) {
296
                switch (gvSIGgeometryType) {
297
                case FShape.POINT:
298
                        return true;
299
                case FShape.LINE:
300
                        return true;
301
                case FShape.POLYGON:
302
                        return true;
303
                case FShape.ARC:
304
                        return false;
305
                case FShape.ELLIPSE:
306
                        return false;
307
                case FShape.MULTIPOINT:
308
                        return true;
309
                case FShape.TEXT:
310
                        return false;
311
                }
312
                return false;
313
        }
314

    
315

    
316
        /** @deprecated ???
317
        *
318
        */
319
        protected String addQuotes(Object value) {
320
                String retString;
321

    
322
                if (value != null) {
323
                        retString = "'" + doubleQuote(value) + "'";
324

    
325
                } else {
326
                        retString = "null";
327
                }
328

    
329
                return retString;
330
        }
331

    
332
        /** @deprecated ???
333
        *
334
        */
335
        private String doubleQuote(Object obj) {
336
                String aux = obj.toString().replaceAll("'", "''");
337
                StringBuffer strBuf = new StringBuffer(aux);
338
                ByteArrayOutputStream out = new ByteArrayOutputStream(strBuf.length());
339
                PrintStream printStream = new PrintStream(out);
340
                printStream.print(aux);
341
                String aux2 = "ERROR";
342
                try {
343
                        aux2 = out.toString(toEncode);
344
                        System.out.println(aux + " " + aux2);
345
                } catch (UnsupportedEncodingException e) {
346
                        // TODO Auto-generated catch block
347
                        e.printStackTrace();
348
                }
349

    
350
                return aux2;
351
        }
352

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

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

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

    
374

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

    
381
        }
382

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

    
390
                return sql;
391
        }
392

    
393
        public static void create(PostgresqlStoreParameters parameters, IFeatureType featureType)throws InitializeWriterException, InitializeException {
394
                Connection con = PostgresqlStoreUtils.getConnection(parameters.getUrl(), parameters.getUser(), parameters.getPassw());
395

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

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

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

    
448
                }
449
        }
450

    
451
        protected void loadPkInPreparedStatement(PreparedStatement ps,int paramIndex,DBFeatureType fType,IFeature feature) throws java.sql.SQLException{
452
                if (fType.getFieldsId().length != 1)
453
                        throw new UnsupportedOperationException("ID fields > 1");
454
                String id =fType.getFieldsId()[0];
455
                loadValueInPreparedStatement(ps, paramIndex, (JDBCAttributeDescriptor)fType.get(fType.getFieldIndex(id)), feature);
456
        }
457
        protected void loadValueInPreparedStatement(PreparedStatement ps,int paramIndex,JDBCAttributeDescriptor attr,IFeature feature) throws java.sql.SQLException{
458
                Object value = feature.get(attr.ordinal());
459
                if (value == null){
460
                        ps.setNull(paramIndex, attr.getSqlType());
461
                        return;
462
                }
463

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

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