Statistics
| Revision:

root / trunk / libraries / libFMap_dataDB / src / org / gvsig / data / datastores / vectorial / db / jdbc / postgresql / PostgresqlFeaturesWriter.java @ 20920

History | View | Annotate | Download (14.3 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.db.DBAttributeDescriptor;
17
import org.gvsig.data.datastores.vectorial.db.DBFeatureType;
18
import org.gvsig.data.datastores.vectorial.db.jdbc.JDBCFeature;
19
import org.gvsig.data.datastores.vectorial.db.jdbc.JDBCFeaturesWriter;
20
import org.gvsig.data.datastores.vectorial.db.jdbc.JDBCTypes;
21
import org.gvsig.data.exception.InitializeException;
22
import org.gvsig.data.exception.InitializeWriterException;
23
import org.gvsig.data.exception.ReadException;
24
import org.gvsig.data.exception.WriteException;
25
import org.gvsig.data.vectorial.IFeature;
26
import org.gvsig.data.vectorial.IFeatureAttributeDescriptor;
27
import org.gvsig.data.vectorial.IFeatureStore;
28
import org.gvsig.data.vectorial.IFeatureType;
29
import org.gvsig.data.vectorial.INewFeatureStoreParameters;
30
import org.gvsig.fmap.geom.Geometry;
31

    
32
import com.vividsolutions.jts.io.WKBWriter;
33

    
34
public class PostgresqlFeaturesWriter extends JDBCFeaturesWriter {
35
        DBFeatureType featureType;
36
        boolean bCreateTable=false;
37
        private String toEncode;
38
        PostgresqlStoreParameters parameters;
39

    
40
        private PreparedStatement insertSt;
41
        private PreparedStatement updateSt;
42

    
43
        private static WKBWriter wkbWriter = new WKBWriter();
44

    
45
        PostgresqlFeaturesWriter(){
46
        }
47

    
48
        public void init(IFeatureStore store) throws InitializeWriterException {
49
                super.init(store);
50
                PostgresqlStore pgStore = (PostgresqlStore)store;
51
                this.parameters=pgStore.getParametersPostgresql();
52

    
53
                this.featureType = (DBFeatureType)this.store.getDefaultFeatureType();
54

    
55
        }
56

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

    
68

    
69
                if (bCreateTable) {
70

    
71
                        IDataExplorer explorer = this.store.getExplorer();
72

    
73
                        IDataStoreParameters params =this.store.getParameters();
74
                        explorer.remove(params);
75

    
76
                        INewFeatureStoreParameters newParam = (INewFeatureStoreParameters)explorer.createNewDataStoreParameter();
77

    
78

    
79
                        newParam.setFeatureType(this.featureType);
80
                        explorer.add(newParam);
81
                }
82

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

    
99
        }
100

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

    
112
        }
113

    
114
        public void insertFeature(IFeature feature) throws WriteException {
115

    
116
                DBFeatureType ftype = (DBFeatureType)feature.getType();
117

    
118
                try {
119
                        PreparedStatement ps=this.getInsertFeatureStatement(ftype);
120
                        Iterator it = ftype.iterator();
121

    
122
                        int index= 1;
123
                        while (it.hasNext()){
124
                                DBAttributeDescriptor fad=(DBAttributeDescriptor)it.next();
125
                                if (fad.isReadOnly())
126
                                        continue;
127

    
128

    
129
                                loadValueInPreparedStatement(ps, index, fad, feature);
130
                                index++;
131
                        }
132
//                        ps.setObject(index, feature.get(ftype.getFieldIdIndex()));
133

    
134
                        ps.execute();
135

    
136
                } catch (SQLException e) {
137
                        throw new WriteException(this.store.getName(),e);
138
                }
139
        }
140

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

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

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

    
163
                        this.insertSt= this.conex.prepareStatement(sql.toString());
164
                        System.out.println(sql.toString());
165
                } else{
166
                        this.insertSt.clearParameters();
167
                }
168
                return this.insertSt;
169

    
170
        }
171

    
172
        public void updateFeatureType(IFeatureType featureType) {
173
                this.featureType=(DBFeatureType)featureType;
174
        }
175

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

    
196
                ResultSet rs = metadata.getTables(null, schema, tableName, null);
197

    
198
                exists = !rs.isAfterLast();
199
                rs.close();
200

    
201
                return exists;
202
        }
203

    
204
        public void updateFeature(IFeature feature) throws WriteException, ReadException {
205

    
206
                DBFeatureType ftype = (DBFeatureType)feature.getType();
207

    
208
                try {
209
                        PreparedStatement ps=this.getUpdateFeatureStatement(ftype);
210
                        Iterator it = ftype.iterator();
211

    
212
                        int index= 1;
213
                        while (it.hasNext()){
214
                                DBAttributeDescriptor fad=(DBAttributeDescriptor)it.next();
215
                                if (fad.isPrimaryKey())
216
                                        continue;
217
                                loadValueInPreparedStatement(ps, index, fad, feature);
218
                                index++;
219
                        }
220

    
221
                        loadPkInPreparedStatement(ps, index, ftype, feature);
222

    
223
                        ps.execute();
224

    
225
                } catch (SQLException e) {
226
                        throw new WriteException(this.store.getName(),e);
227
                }
228
        }
229

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

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

    
252
        public void insertAttribute(IFeatureAttributeDescriptor attribute) throws WriteException {
253
                try {
254
                        Statement st = conex.createStatement();
255

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

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

    
282
        /** @deprecated ???
283
        *
284
        */
285
        public String getEncoding() {
286
                return toEncode;
287
        }
288

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

    
312

    
313
        /** @deprecated ???
314
        *
315
        */
316
        protected String addQuotes(Object value) {
317
                String retString;
318

    
319
                if (value != null) {
320
                        retString = "'" + doubleQuote(value) + "'";
321

    
322
                } else {
323
                        retString = "null";
324
                }
325

    
326
                return retString;
327
        }
328

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

    
347
                return aux2;
348
        }
349

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

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

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

    
371

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

    
378
        }
379

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

    
387
                return sql;
388
        }
389

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

    
393
                StringBuffer sb=new StringBuffer();
394
                sb.append("CREATE TABLE ");
395
                sb.append(parameters.tableID());
396
                sb.append(" (");
397
                sb.append("id int, ");
398
                Iterator iterator=featureType.iterator();
399
                while (iterator.hasNext()) {
400
                        IFeatureAttributeDescriptor descriptor = (IFeatureAttributeDescriptor) iterator.next();
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, (DBAttributeDescriptor)fType.get(id), feature);
454
        }
455
        protected void loadValueInPreparedStatement(PreparedStatement ps,int paramIndex,DBAttributeDescriptor attr,IFeature feature) throws java.sql.SQLException{
456
                Object value = feature.get(attr.ordinal());
457
                if (value == null){
458
                        ps.setNull(paramIndex, attr.getSqlType());
459
                        return;
460
                }
461

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

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