Statistics
| Revision:

root / trunk / libraries / libDataSourceDBBaseDrivers / src / org / gvsig / data / datastores / vectorial / db / jdbc / postgresqlbin / PostgresqlBinStoreUtils.java @ 19960

History | View | Annotate | Download (12.6 KB)

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

    
3
import java.math.BigDecimal;
4
import java.nio.ByteBuffer;
5
import java.sql.Connection;
6
import java.sql.Date;
7
import java.sql.DriverManager;
8
import java.sql.ResultSet;
9
import java.sql.ResultSetMetaData;
10
import java.sql.Statement;
11
import java.sql.Timestamp;
12
import java.sql.Types;
13
import java.util.Iterator;
14

    
15
import org.gvsig.data.datastores.vectorial.db.DBFeatureType;
16
import org.gvsig.data.datastores.vectorial.db.jdbc.JDBCAttributeDescriptor;
17
import org.gvsig.data.datastores.vectorial.db.jdbc.JDBCFeature;
18
import org.gvsig.data.datastores.vectorial.db.jdbc.JDBCStore;
19
import org.gvsig.data.datastores.vectorial.db.jdbc.exception.JDBCDriverNotFoundException;
20
import org.gvsig.data.datastores.vectorial.db.jdbc.exception.SQLException;
21
import org.gvsig.data.datastores.vectorial.db.jdbc.postgresql.PostgresqlFeature;
22
import org.gvsig.data.datastores.vectorial.db.jdbc.postgresql.PostgresqlStore;
23
import org.gvsig.data.datastores.vectorial.db.jdbc.postgresql.PostgresqlStoreParameters;
24
import org.gvsig.data.datastores.vectorial.db.jdbc.postgresql.PostgresqlStoreUtils;
25
import org.gvsig.data.exception.InitializeException;
26
import org.gvsig.data.exception.ReadException;
27
import org.gvsig.data.vectorial.DefaultAttributeDescriptor;
28
import org.gvsig.data.vectorial.IFeature;
29
import org.gvsig.data.vectorial.IFeatureAttributeDescriptor;
30

    
31
import com.iver.cit.gvsig.fmap.core.IGeometry;
32
import com.iver.cit.gvsig.fmap.drivers.WKBParser2;
33
import com.iver.cit.gvsig.fmap.drivers.XTypes;
34
import com.vividsolutions.jts.io.WKBWriter;
35

    
36
public class PostgresqlBinStoreUtils {
37

    
38
        private static WKBParser2 wkbParser = new WKBParser2();
39
        private static WKBWriter wkbWriter = new WKBWriter();
40

    
41
        private static int cursorCount=0;
42
        private static String baseCursorName=null;
43

    
44

    
45
        public static IFeature createFeatureFromBinaryCursor(JDBCStore store, ResultSet rs, DBFeatureType featureType) throws ReadException {
46

    
47
                PostgresqlFeature feature=null;
48

    
49

    
50
                Object[] pk;
51
                try {
52
                        pk = getPkFromResulsetBinary(rs, featureType);
53

    
54
                        feature=new PostgresqlFeature(featureType,store,pk);
55

    
56
                        Iterator iter = featureType.iterator();
57
                        IGeometry geom = null;
58
                        while (iter.hasNext()) {
59
                                JDBCAttributeDescriptor fad=(JDBCAttributeDescriptor)iter.next();
60
                                feature.set(fad.getName(), getFieldValueFromBinaryCursor(rs, fad));
61
                        }
62

    
63
                        return feature;
64
                } catch (java.sql.SQLException e) {
65
                        throw new ReadException("CreateFeature",e);
66
                }
67
        }
68

    
69
        public static Connection getConnection(String dbUrl, String dbUser, String dbPass) throws InitializeException {
70
                //TODO: Aqu? habria que implementar la llamada
71
                //      al Resource Manager para comprobar si ya hay
72
                //                una connexion a la BD
73
                String connID = getConnectionResourceID(dbUrl, dbUser);
74

    
75
                Connection conn = null;
76
//                IResource res = ResourceManager.getResourceManager().getResource(connID);
77

    
78

    
79

    
80
                try {
81
                        Class.forName("org.postgresql.Driver");
82
                } catch (ClassNotFoundException e) {
83
                        throw new JDBCDriverNotFoundException("org.postgresql.Driver",e);
84
                }
85
                try {
86
                        conn = DriverManager.getConnection(dbUrl, dbUser, dbPass);
87
                        conn.setAutoCommit(false);
88

    
89
                } catch (java.sql.SQLException e1) {
90
                        throw new InitializeException(PostgresqlStore.DATASTORE_NAME,e1);
91
                }
92
                //TODO: Registrar en el Resource manager
93
                // ResourceManager.getResourceManager().addResource(res);
94

    
95
                return conn;
96
        }
97

    
98
        static String getConnectionResourceID(String dbUrl,String dbUser){
99
                return PostgresqlStore.CONNECTION_STRING+";"+dbUrl+";"+dbUser;
100

    
101
        }
102

    
103
        static Object getFieldValueFromBinaryCursor(ResultSet aRs, JDBCAttributeDescriptor attrDescriptor) throws java.sql.SQLException {
104
                int fieldId = attrDescriptor.ordinal();
105
                int sqlType = attrDescriptor.getSqlType();
106
                byte[] byteBuf = aRs.getBytes(fieldId+1);
107
                if (byteBuf == null)
108
                        return null;
109
                else {
110
                        ByteBuffer buf = ByteBuffer.wrap(byteBuf);
111

    
112
                        switch (sqlType) {
113
                        case Types.VARCHAR:
114
                                //FIXME Error
115
                                return aRs.getString(fieldId);
116
//                                return new String(buf.toString());
117
                        case Types.FLOAT:
118
                                return new Float(buf.getFloat());
119
                        case Types.DOUBLE:
120
                                return new Double(buf.getDouble());
121
                        case Types.REAL:
122
                                return new Float(buf.getFloat());
123
                        case Types.INTEGER:
124
                                return new Integer(buf.getInt());
125
                        case Types.BIGINT:
126
                                return new Long(buf.getLong());
127
                        case Types.BIT:
128
                                return new Boolean(byteBuf[0] == 1);
129
                        case Types.BOOLEAN:
130
                                return new Boolean(aRs.getBoolean(fieldId));
131
                        case Types.DATE:
132
                                long daysAfter2000 = buf.getInt() + 1;
133
                                long msecs = daysAfter2000*24*60*60*1000;
134
                                long real_msecs_date1 = (long) (XTypes.NUM_msSecs2000 + msecs);
135
                                Date realDate1 = new Date(real_msecs_date1);
136
                                return realDate1;
137
                        case Types.TIME:
138
                                // TODO:
139
                                // throw new RuntimeException("TIME type not implemented yet");
140
                                return "NOT IMPLEMENTED YET";
141
                        case Types.TIMESTAMP:
142
                                double segsReferredTo2000 = buf.getDouble();
143
                                long real_msecs = (long) (XTypes.NUM_msSecs2000 + segsReferredTo2000*1000);
144
                                Timestamp valTimeStamp = new Timestamp(real_msecs);
145
                                return valTimeStamp;
146
                        case Types.NUMERIC:
147
                                // System.out.println(metaData.getColumnName(fieldId) + " "
148
                                // + metaData.getColumnClassName(fieldId));
149
                                short ndigits = buf.getShort();
150
                                short weight = buf.getShort();
151
                                short sign = buf.getShort();
152
                                short dscale = buf.getShort();
153
                                String strAux;
154
                                if (sign == 0)
155
                                        strAux = "+";
156
                                else
157
                                        strAux = "-";
158

    
159
                                for (int iDigit = 0; iDigit < ndigits; iDigit++) {
160
                                        short digit = buf.getShort();
161
                                        strAux = strAux + digit;
162
                                        if (iDigit == weight)
163
                                                strAux = strAux + ".";
164

    
165
                                }
166
                                strAux = strAux + "0";
167
                                BigDecimal dec;
168
                                dec = new BigDecimal(strAux);
169
                                // System.out.println(ndigits + "_" + weight + "_" + dscale
170
                                // + "_" + strAux);
171
                                // System.out.println(strAux + " Big= " + dec);
172
                                return new Double(dec.doubleValue());
173

    
174

    
175
                        default:
176
                                if (attrDescriptor.getDataType() == IFeatureAttributeDescriptor.TYPE_GEOMETRY){
177
                                        if (byteBuf == null)
178
                                                return null;
179
                                        return wkbParser.parse(byteBuf);
180
                                }
181
                                return null;
182
                        }
183

    
184
                }
185
        }
186

    
187

    
188
        static Object[] getPkFromResulsetBinary(ResultSet rs, DBFeatureType featureType) throws java.sql.SQLException{
189
                String[] fieldsId = featureType.getFieldsId();
190
                Object[] result = new Object[fieldsId.length];
191
                for (int i=0;i<fieldsId.length;i++){
192
                        result[i] = getFieldValueFromBinaryCursor(
193
                                        rs,
194
                                        (JDBCAttributeDescriptor)featureType.get(
195
                                                        featureType.getFieldIndex(fieldsId[i])
196
                                                        )
197
                                );
198

    
199
                }
200
                return result;
201

    
202
        }
203

    
204

    
205
        static IFeature createFeature(JDBCStore store,ResultSet rs,DBFeatureType featureType) throws ReadException{
206

    
207
                JDBCFeature feature=null;
208

    
209

    
210
                Object[] pk;
211
                try {
212
                        pk = getPkFromResulset(rs, featureType);
213

    
214
                        feature=new PostgresqlBinFeature(featureType,store,pk);
215

    
216
                        Iterator iter = featureType.iterator();
217
                        IGeometry geom = null;
218
                        while (iter.hasNext()) {
219
                                IFeatureAttributeDescriptor fad=(IFeatureAttributeDescriptor)iter.next();
220
                                if (fad.getDataType().equals(IFeatureAttributeDescriptor.TYPE_GEOMETRY)) {
221
                                        byte[] data = rs.getBytes(fad.getName());
222

    
223
                                        if (data == null) {
224
                                                geom = null;
225
                                        } else{
226
                                                geom = wkbParser.parse(data);
227
                                        }
228
                                        feature.setGeometry(fad.getName(),geom);
229
                                } else {
230
                                        feature.set(fad.getName(), rs.getObject(fad.getName()));
231
                                }
232

    
233
                        }
234
                        return feature;
235
                } catch (java.sql.SQLException e) {
236
                        throw new ReadException("CreateFeature",e);
237
                }
238
        }
239

    
240
        static String addLimitsToSQL(String aSql,int fetchSize,int page){
241
                return aSql+ " limit " + fetchSize + " offset " + (fetchSize*page);
242
        }
243

    
244
        public static String createCursorName() {
245
                if (baseCursorName == null){
246
                        baseCursorName = "gv_"+ System.currentTimeMillis();
247
                }
248
                cursorCount++;
249
                return baseCursorName+"_"+cursorCount;
250
        }
251

    
252

    
253

    
254
        public static DBFeatureType getFeatureType(Connection connection, PostgresqlStoreParameters params) throws ReadException{
255
                DBFeatureType featureType = new DBFeatureType();
256

    
257

    
258
                loadFieldsToFeatureType(connection, params, featureType);
259

    
260

    
261
                featureType.setFieldsId(params.getFieldsId());
262

    
263
                if (params.getDefaultGeometryField() != null && params.getDefaultGeometryField() != ""){
264
                        if (featureType.getFieldIndex(params.getDefaultGeometryField())< 0){
265
                                // FIXME: crear una nueva excepcion??
266
                                throw new InitializeException(
267
                                                PostgresqlStore.DATASTORE_NAME,
268
                                                new Exception("Geometry Field '"+ params.getDefaultGeometryField() +"' not Found"));
269

    
270
                        }
271

    
272
                        featureType.setDefaultGeometry(params.getDefaultGeometryField());
273
                }
274

    
275
                return featureType;
276

    
277
        }
278

    
279
        private static void loadFieldsToFeatureType(Connection conn,PostgresqlStoreParameters params,DBFeatureType featureType) throws ReadException{
280
                String sql="";
281
                String columns=params.getFieldsString();
282

    
283
                if (params.getSqlSoure() != null){
284
                        sql = params.getSqlSoure();
285
                } else {
286
                        sql = "Select "+columns+" from " + params.tableID() + " limit 1;";
287
                }
288

    
289
                try {
290

    
291
                        Statement stAux = conn.createStatement();
292
                        ResultSet rs = stAux.executeQuery(sql);
293
                        ResultSetMetaData rsMetadata = rs.getMetaData();
294

    
295
                        int i;
296

    
297
                        featureType.setTableID(params.tableID());
298
                        DefaultAttributeDescriptor attr;
299
                        for (i=1;i<=rsMetadata.getColumnCount();i++){
300
                                attr = getAttributeFromJDBC(conn,rsMetadata,i);
301
                                featureType.add(attr);
302
                                attr.setOrdinal(i-1);
303
                        }
304
                        rs.close();
305
                } catch (java.sql.SQLException e) {
306
                        // TODO Auto-generated catch block
307
                        throw new SQLException(sql,"getFeatureType",e);
308
                }
309

    
310
        }
311

    
312
        private static DefaultAttributeDescriptor getAttributeFromJDBC(Connection conn,ResultSetMetaData rsMetadata,int colIndex) throws SQLException{
313
                JDBCAttributeDescriptor column= new JDBCAttributeDescriptor();
314
                try {
315
                        column.setName(rsMetadata.getColumnName(colIndex));
316
                        column.setSqlType(rsMetadata.getColumnType(colIndex));
317
                        column.setAllowNull(rsMetadata.isNullable(colIndex) == ResultSetMetaData.columnNullable);
318
                        column.setAutoIncrement(rsMetadata.isAutoIncrement(colIndex));
319
                        column.setReadOnly(rsMetadata.isReadOnly(colIndex));
320

    
321
                        switch (rsMetadata.getColumnType(colIndex)) {
322
                        case java.sql.Types.INTEGER:
323
                                column.setType(IFeatureAttributeDescriptor.TYPE_INT);
324
                                break;
325
                        case java.sql.Types.BIGINT:
326
                                column.setType(IFeatureAttributeDescriptor.TYPE_LONG);
327
                                break;
328
                        case java.sql.Types.REAL:
329
                                column.setType(IFeatureAttributeDescriptor.TYPE_DOUBLE);
330
                                column.setPrecision(rsMetadata.getPrecision(colIndex));
331
                                break;
332
                        case java.sql.Types.DOUBLE:
333
                                column.setType(IFeatureAttributeDescriptor.TYPE_DOUBLE);
334
                                column.setPrecision(rsMetadata.getPrecision(colIndex));
335
                                break;
336
                        case java.sql.Types.CHAR:
337
                                column.setType(IFeatureAttributeDescriptor.TYPE_STRING);
338
                                column.setSize(rsMetadata.getColumnDisplaySize(colIndex));
339
                                break;
340
                        case java.sql.Types.VARCHAR:
341
                                column.setType(IFeatureAttributeDescriptor.TYPE_STRING);
342
                                column.setSize(rsMetadata.getColumnDisplaySize(colIndex));
343
                                break;
344
                        case java.sql.Types.FLOAT:
345
                                column.setType(IFeatureAttributeDescriptor.TYPE_FLOAT);
346
                                column.setSize(rsMetadata.getColumnDisplaySize(colIndex));
347
                                column.setPrecision(rsMetadata.getPrecision(colIndex));
348
                                break;
349
                        case java.sql.Types.DECIMAL:
350
                                column.setType(IFeatureAttributeDescriptor.TYPE_FLOAT);
351
                                column.setSize(rsMetadata.getColumnDisplaySize(colIndex));
352
                                column.setPrecision(rsMetadata.getPrecision(colIndex));
353
                                break;
354
                        case java.sql.Types.DATE:
355
                                column.setType(IFeatureAttributeDescriptor.TYPE_DATE);
356
                                break;
357
                        case java.sql.Types.BOOLEAN:
358
                                column.setType(IFeatureAttributeDescriptor.TYPE_BOOLEAN);
359
                                break;
360
                        default:
361
                                column.setType(IFeatureAttributeDescriptor.TYPE_OBJECT);
362
                                break;
363
                        }
364
                } catch (java.sql.SQLException e){
365
                        throw new SQLException("","load attribute definition",e);
366
                }
367

    
368
                return column;
369

    
370
        }
371

    
372

    
373
        public static String getFliterForID(DBFeatureType featureType, Object[] featureKey) {
374
                // TODO Auto-generated method stub
375
                return null;
376
        }
377

    
378

    
379

    
380
        protected static String getFliterForID(DBFeatureType fType, IFeature feature){
381
                return getFliterForID(fType, getPkFromFeature(feature,fType));
382
        }
383

    
384

    
385
        protected static Object[] getPkFromResulset(ResultSet rs, DBFeatureType featureType) throws java.sql.SQLException{
386
                String[] fieldsId = featureType.getFieldsId();
387
                Object[] result = new Object[fieldsId.length];
388
                for (int i=0;i<fieldsId.length;i++){
389
                        result[i] = rs.getObject(fieldsId[i]);
390
                }
391
                return result;
392

    
393
        }
394

    
395

    
396

    
397
        protected static Object[] getPkFromFeature(IFeature feature, DBFeatureType featureType){
398
                String[] fieldsId = featureType.getFieldsId();
399
                Object[] result = new Object[fieldsId.length];
400
                for (int i=0;i<fieldsId.length;i++){
401
                        result[i] = feature.get(fieldsId[i]);
402
                }
403
                return result;
404

    
405
        }
406

    
407
        public static String getJDBCUrl(String host, String db, String port) {
408
                String url;
409
                url = "jdbc:postgresql://"+host+":" + port +"/"+db;
410

    
411
                return url;
412
        }
413

    
414
}
415