Statistics
| Revision:

root / branches / v2_0_0_prep / extensions / org.gvsig.oracle / src / org / gvsig / fmap / dal / store / oracle / OracleStoreProvider.java @ 38084

History | View | Annotate | Download (27.7 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 */
22

    
23
/*
24
 * AUTHORS (In addition to CIT):
25
 * 2009 Prodevelop S.L. main development
26
 */
27

    
28
package org.gvsig.fmap.dal.store.oracle;
29

    
30
import java.security.InvalidParameterException;
31
import java.sql.Connection;
32
import java.sql.PreparedStatement;
33
import java.sql.ResultSet;
34
import java.sql.SQLException;
35
import java.sql.Statement;
36
import java.util.ArrayList;
37
import java.util.HashMap;
38
import java.util.Iterator;
39
import java.util.List;
40
import java.util.Map;
41

    
42
import oracle.sql.STRUCT;
43
import oracle.sql.TIMESTAMP;
44

    
45
import org.slf4j.Logger;
46
import org.slf4j.LoggerFactory;
47

    
48
import org.gvsig.fmap.dal.DALLocator;
49
import org.gvsig.fmap.dal.DataManager;
50
import org.gvsig.fmap.dal.DataServerExplorer;
51
import org.gvsig.fmap.dal.DataStoreParameters;
52
import org.gvsig.fmap.dal.DataTypes;
53
import org.gvsig.fmap.dal.exception.DataException;
54
import org.gvsig.fmap.dal.exception.InitializeException;
55
import org.gvsig.fmap.dal.exception.OpenException;
56
import org.gvsig.fmap.dal.exception.ReadException;
57
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
58
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
59
import org.gvsig.fmap.dal.feature.FeatureIndexes;
60
import org.gvsig.fmap.dal.feature.FeatureQuery;
61
import org.gvsig.fmap.dal.feature.FeatureType;
62
import org.gvsig.fmap.dal.feature.exception.CreateFeatureException;
63
import org.gvsig.fmap.dal.feature.impl.DefaultFeatureIndexes;
64
import org.gvsig.fmap.dal.feature.impl.DefaultFeatureStore;
65
import org.gvsig.fmap.dal.feature.spi.AbstractFeatureStoreProvider;
66
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
67
import org.gvsig.fmap.dal.feature.spi.FeatureReferenceProviderServices;
68
import org.gvsig.fmap.dal.feature.spi.FeatureSetProvider;
69
import org.gvsig.fmap.dal.feature.spi.FeatureStoreProviderServices;
70
import org.gvsig.fmap.dal.resource.ResourceAction;
71
import org.gvsig.fmap.dal.resource.exception.ResourceExecuteException;
72
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
73
import org.gvsig.fmap.dal.store.db.DBHelper;
74
import org.gvsig.fmap.dal.store.jdbc.JDBCHelper;
75
import org.gvsig.fmap.dal.store.jdbc.JDBCStoreParameters;
76
import org.gvsig.fmap.dal.store.jdbc.JDBCStoreProviderWriter;
77
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCException;
78
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCExecutePreparedSQLException;
79
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCPreparingSQLException;
80
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCSQLException;
81
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCUpdateWithoutChangesException;
82
import org.gvsig.fmap.dal.store.oracle.index.OracleFeatureIndex;
83
import org.gvsig.fmap.dal.store.oracle.index.OracleRemoteFeatureIndexProvider;
84
import org.gvsig.fmap.geom.Geometry;
85
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
86
import org.gvsig.fmap.geom.operation.towkb.ToWKB;
87
import org.gvsig.tools.ToolsLocator;
88
import org.gvsig.tools.dataTypes.CoercionException;
89
import org.gvsig.tools.dataTypes.DataTypesManager;
90
import org.gvsig.tools.dataTypes.impl.coercion.CoerceToDateTime;
91
import org.gvsig.tools.dynobject.DynObject;
92
import org.gvsig.tools.exception.BaseException;
93

    
94
/**
95
 * Oracle Provider
96
 * 
97
 * @author vsanjaime
98
 * 
99
 */
100
public class OracleStoreProvider extends JDBCStoreProviderWriter {
101

    
102
        public final static Logger logger = LoggerFactory
103
                        .getLogger(OracleStoreProvider.class);
104

    
105
        public static String NAME = "Oracle";
106
        public static String DESCRIPTION = "Oracle source";
107
        public static final String METADATA_DEFINITION_NAME = NAME;
108
        
109
        private boolean oracleIndexSet = false;
110
        
111
        private Map selectedFields = null;
112
        
113
        /*
114
        protected static void registerDynClass() {
115
                DynObjectManager dynman = ToolsLocator.getDynObjectManager();
116
                DynClass dynClass;
117
                if (DYNCLASS == null) {
118
                        dynClass = dynman.add(DYNCLASS_NAME, DESCRIPTION);
119

120
                        // dynClass.extend(dynman.get(FeatureStore.DYNCLASS_NAME));
121
                        DYNCLASS = dynClass;
122
                }
123
        }
124
        */
125

    
126
        public OracleStoreProvider(OracleStoreParameters params,
127
                        DataStoreProviderServices storeServices) throws InitializeException {
128
                super(params, storeServices,
129
                                DBHelper.newMetadataContainer(METADATA_DEFINITION_NAME));
130
                
131
                String defaultGeometryAttributeName;
132
                try {
133
                        defaultGeometryAttributeName = this.getFeatureStore()
134
                                .getDefaultFeatureType()
135
                                        .getDefaultGeometryAttributeName();
136
                } catch (DataException e) {
137
                        throw new InitializeException(e);
138
                }
139
                
140
                String ora_srid =
141
                        getOraHelper().getOraTableSrid(params, defaultGeometryAttributeName);
142
                this.setDynValue(OracleStoreParameters.ORA_TABLE_SRID_KEY, ora_srid);
143
                String sFields = (String)getParameters().getDynValue("fields");
144
                if (sFields != null){
145
                    selectedFields = new HashMap();
146
                    String[] fields = sFields.split(",");
147
                    for (int i=0 ; i<fields.length ; i++){
148
                        selectedFields.put(fields[i].trim(), Boolean.TRUE);
149
                    }
150
                }
151
        }
152
        
153
        /**
154
         * Default Constructor.
155
         *
156
         * @param params
157
         * @param storeServices
158
         * @param metadata
159
         */
160
        protected OracleStoreProvider(DataStoreParameters params,
161
                        DataStoreProviderServices storeServices, DynObject metadata) throws InitializeException {
162
                super((JDBCStoreParameters) params, storeServices, metadata);
163
        }
164

    
165
        /**
166
         * Constructor when cannot create metada in constrution time. <br>
167
         * <br>
168
         * <strong>Note: </strong> Don't use it if not is necesary. Set metada
169
         * <strong>as soon as posible</strong> by
170
         * {@link AbstractFeatureStoreProvider#setMetadata(DynObject)}
171
         * 
172
         * @param params
173
         * @param storeServices
174
         */
175
        protected OracleStoreProvider(DataStoreParameters params,
176
                        DataStoreProviderServices storeServices) throws InitializeException {
177
                this((JDBCStoreParameters) params, storeServices, null);
178
        }
179
        
180
        
181
        
182

    
183
        private OracleStoreParameters getOracleStoreParameters() {
184
                return (OracleStoreParameters) this.getParameters();
185
        }
186

    
187
        protected JDBCHelper createHelper() throws InitializeException {
188
                return new OracleHelper(this, getOracleStoreParameters());
189
        }
190
        
191
        public void open() throws OpenException {
192
                super.open();
193
                
194
                // =============== add remote oracle geometry index to prevent default index
195
                if (!oracleIndexSet) {
196
                        
197
                        DefaultFeatureStore dfs = null;
198
                        if (!(getFeatureStore() instanceof DefaultFeatureStore)) {
199
                                logger.warn("Feature store not DefaultFeatureStore: " + dfs.getClass().getName());
200
                                return;
201
                        }
202
                        dfs = (DefaultFeatureStore) getFeatureStore();
203
                        
204
                        FeatureType ft = null;
205
            try {
206
                ft = dfs.getDefaultFeatureType();
207
            } catch (DataException e) {
208
                throw new OpenException(getFeatureStore().getName(), e);
209
            }                        
210
                        
211
            //It there is not a geometry the index is not created
212
                        if (ft.getDefaultGeometryAttributeName() != null){
213
                            FeatureIndexes findexes = dfs.getIndexes();
214
                            if (findexes instanceof DefaultFeatureIndexes) {
215
                                    DefaultFeatureIndexes dfi = (DefaultFeatureIndexes) findexes;                                   
216
                                    dfi.addIndex(
217
                                                    new OracleFeatureIndex(
218
                                                                    (FeatureStoreProviderServices) getFeatureStore(),
219
                                                                    ft,
220
                                                                    new OracleRemoteFeatureIndexProvider(dfs),
221
                                                                    ft.getDefaultGeometryAttributeName(),
222
                                                                    OracleRemoteFeatureIndexProvider.NAME));
223
                            }
224
                        }
225
                        oracleIndexSet = true;
226
                }
227
                // ===============                 
228
        }
229

    
230

    
231
        protected String fixFilter(String filter) {
232
                // filter was created by a class in oracle plugin, should not need fix
233
                return filter;
234
        }
235

    
236
        public String getName() {
237
                return NAME;
238
        }
239
        
240
        public int getOIDType() {
241
                return DataTypes.LONG;
242
        }
243
        
244
        private static long ora_oid = 100000000;
245
        
246
        public Object createNewOID() {
247
                return new Long(ora_oid++);
248
        }
249

    
250
        public FeatureSetProvider createSet(FeatureQuery query,
251
                        FeatureType featureType) throws DataException {
252

    
253
                return new OracleSetProvider(this, query, featureType);
254
        }
255

    
256
        public DataServerExplorer getExplorer() throws ReadException {
257
                DataManager manager = DALLocator.getDataManager();
258
                OracleServerExplorerParameters exParams;
259
                OracleStoreParameters params = getOracleStoreParameters();
260
                try {
261
                        exParams = (OracleServerExplorerParameters) manager
262
                                        .createServerExplorerParameters(OracleServerExplorer.NAME);
263
                        exParams.setUrl(params.getUrl());
264
                        exParams.setHost(params.getHost());
265
                        exParams.setPort(params.getPort());
266
                        exParams.setDBName(params.getDBName());
267
                        exParams.setUser(params.getUser());
268
                        exParams.setPassword(params.getPassword());
269
                        exParams.setCatalog(params.getCatalog());
270
                        exParams.setSchema(params.getSchema());
271
                        exParams.setJDBCDriverClassName(params.getJDBCDriverClassName());
272
                        exParams.setUseSSL(params.getUseSSL());
273
                        exParams.setOraDriverType(params.getOraDriverType());
274

    
275
                        return manager.openServerExplorer(OracleServerExplorer.NAME, exParams);
276
                } catch (DataException e) {
277
                        throw new ReadException(this.getName(), e);
278
                } catch (ValidateDataParametersException e) {
279
                        throw new ReadException(this.getName(), e);
280
                }
281
        }
282

    
283
        public boolean allowAutomaticValues() {
284
                return true;
285
        }
286

    
287
        public boolean hasGeometrySupport() {
288
                return true;
289
        }
290

    
291
        protected OracleHelper getOraHelper() {
292
                return (OracleHelper) getHelper();
293
        }
294

    
295
        public boolean canWriteGeometry(int geometryType, int geometrySubtype)
296
                        throws DataException {
297
                FeatureType type = getFeatureStore().getDefaultFeatureType();
298
                FeatureAttributeDescriptor geomAttr = type.getAttributeDescriptor(type
299
                                .getDefaultGeometryAttributeName());
300
                if (geomAttr == null) {
301
                        return false;
302
                }
303
                if (geometrySubtype != geomAttr.getGeometrySubType()) {
304
                        return false;
305
                }
306
                switch (geomAttr.getGeometryType()) {
307
                case Geometry.TYPES.GEOMETRY:
308
                        return true;
309

    
310
                case Geometry.TYPES.MULTISURFACE:
311
                        return geometryType == Geometry.TYPES.MULTISURFACE;
312

    
313
                case Geometry.TYPES.MULTIPOINT:
314
                        return geometryType == Geometry.TYPES.MULTIPOINT;
315

    
316
                case Geometry.TYPES.MULTICURVE:
317
                        return geometryType == Geometry.TYPES.MULTICURVE;
318

    
319
                case Geometry.TYPES.MULTISOLID:
320
                        return geometryType == Geometry.TYPES.MULTISOLID;
321

    
322
                case Geometry.TYPES.SURFACE:
323
                        return geometryType == Geometry.TYPES.SURFACE;
324

    
325
                case Geometry.TYPES.POINT:
326
                        return geometryType == Geometry.TYPES.POINT;
327

    
328
                case Geometry.TYPES.CURVE:
329
                        return geometryType == Geometry.TYPES.CURVE;
330

    
331
                case Geometry.TYPES.SOLID:
332
                        return geometryType == Geometry.TYPES.SOLID;
333

    
334
                default:
335
                        return geometryType == geomAttr.getGeometryType();
336
                }
337

    
338
        }
339

    
340
        protected void addToListFeatureValues(FeatureProvider featureProvider,
341
                        FeatureAttributeDescriptor attrOfList,
342
                        FeatureAttributeDescriptor attr, List values) throws DataException {
343

    
344
                
345
                
346
                // geometry
347
                if (attr.getDataType().getType() == DataTypes.GEOMETRY) {
348
                        Geometry geom = (Geometry) featureProvider.get(attr.getIndex());
349
                        
350
                        STRUCT stru = null;
351
                        
352
                        if (geom != null){                        
353
                            String ora_srid_str = null;
354
                            boolean is_geo = false;
355
                            boolean has_srid = false;
356

    
357
                            Object ora_srid = getDynValue("ora_table_srid");
358
                            if (ora_srid != null) {
359
                                if (ora_srid instanceof String) {
360
                                    ora_srid_str = (String) ora_srid; 
361
                                } else {
362
                                    if (ora_srid instanceof Integer) {
363
                                        ora_srid_str = "" + ((Integer) ora_srid).intValue(); 
364
                                    }
365
                                }
366
                            }
367

    
368
                            has_srid = ora_srid_str != null && ora_srid_str.compareToIgnoreCase("0") != 0; 
369
                            is_geo = OracleUtils.getIsGCS(
370
                                ora_srid_str, has_srid);
371

    
372
                            stru = OracleUtils.buildSTRUCT(
373
                                geom, 0, helper.getConnection(),
374
                                ora_srid_str, has_srid, false, is_geo);
375
                            
376
                            values.add(stru);
377
                        }else{
378
                            values.add(null);
379
                        }                        
380
                } else {
381
                        super.addToListFeatureValues(featureProvider, attrOfList, attr, values);
382
                }
383
        }
384

    
385
        protected String getSqlStatementAddField(FeatureAttributeDescriptor attr,
386
                        List additionalStatement) throws DataException {
387

    
388
                if (attr.getDataType().getType() == DataTypes.GEOMETRY) {
389
                        OracleStoreParameters params = getOracleStoreParameters();
390
                        additionalStatement.add(((OracleHelper) helper)
391
                                        .getSqlGeometryFieldAdd(attr, params.getTable(), params
392
                                                        .getSchema()));
393
                }
394

    
395
                return super.getSqlStatementAddField(attr, additionalStatement);
396

    
397
        }
398

    
399
        protected String getSqlStatementDropField(FeatureAttributeDescriptor attr,
400
                        List additionalStatement) {
401
                String result = super.getSqlStatementDropField(attr,
402
                                additionalStatement);
403
                if (attr.getDataType().getType() == DataTypes.GEOMETRY) {
404
                        additionalStatement.add(getSqlGeometryFieldDrop(attr));
405
                }
406
                return result;
407
        }
408

    
409
        protected List<String> getSqlStatementAlterField(
410
                        FeatureAttributeDescriptor attrOrg,
411
                        FeatureAttributeDescriptor attrTrg, List additionalStatement)
412
                        throws DataException {
413

    
414
                List<String> actions = new ArrayList<String>();
415
                StringBuilder strb;
416
                OracleStoreParameters params = getOracleStoreParameters();
417

    
418
                // diferent column type
419
                if (attrOrg.getDataType() != attrTrg.getDataType()) {
420
                        strb = new StringBuilder();
421
                        strb.append("MODIFY (");
422
                        strb.append(helper.escapeFieldName(attrTrg.getName()));
423
                        strb.append(" ");
424
                        strb.append(helper.getSqlColumnTypeDescription(attrTrg));
425
                        strb.append(")");
426

    
427
                        if (attrOrg.getDataType().getType() == DataTypes.GEOMETRY) {
428
                                additionalStatement.add(getSqlGeometryFieldDrop(attrOrg));
429
                        }
430
                        if (attrTrg.getDataType().getType() == DataTypes.GEOMETRY) {
431
                                additionalStatement.addAll(((OracleHelper) helper)
432
                                                .getSqlGeometryFieldAdd(attrTrg, params.getTable(),
433
                                                                params.getSchema()));
434
                        }
435

    
436
                        actions.add(strb.toString());
437
                }
438

    
439
                if (attrOrg.allowNull() != attrTrg.allowNull()) {
440

    
441
                        strb = new StringBuilder();
442
                        strb.append("MODIFY (");
443
                        strb.append(helper.escapeFieldName(attrTrg.getName()));
444
                        strb.append(" ");
445
                        if (attrTrg.allowNull()) {
446
                                strb.append("SET ");
447
                        } else {
448
                                strb.append("DROP ");
449
                        }
450
                        strb.append("NOT NULL)");
451
                        actions.add(strb.toString());
452
                }
453

    
454
                if (attrOrg.getDefaultValue() != attrTrg.getDefaultValue()) {
455
                        if (attrTrg.getDefaultValue() == null) {
456

    
457
                                strb = new StringBuilder();
458
                                strb.append("MODIFY (");
459
                                strb.append(helper.escapeFieldName(attrTrg.getName()));
460
                                strb.append(" DROP DEFAULT)");
461
                                actions.add(strb.toString());
462
                        } else if (!attrTrg.getDefaultValue().equals(
463
                                        attrOrg.getDefaultValue())) {
464
                                // ALTER [ COLUMN ] column DROP DEFAULT
465

    
466
                                strb = new StringBuilder();
467
                                strb.append("MODIFY (");
468
                                strb.append(helper.escapeFieldName(attrTrg.getName()));
469
                                strb.append(" SET DEFAULT ");
470
                                strb.append(helper.dalValueToJDBC(attrTrg, attrTrg
471
                                                .getDefaultValue()));
472
                                strb.append(")");
473
                                actions.add(strb.toString());
474
                        }
475
                }
476

    
477
                if (attrOrg.getDataType() == attrTrg.getDataType()
478
                                && attrTrg.getDataType().getType() == DataTypes.GEOMETRY) {
479
                        // TODO Checks SRS and GeomType/Subtype
480
                }
481

    
482
                return actions;
483
        }
484

    
485
        private Object getSqlGeometryFieldDrop(FeatureAttributeDescriptor attr) {
486
                StringBuilder strb = new StringBuilder();
487
                OracleStoreParameters params = getOracleStoreParameters();
488
                
489
                strb.append("DELETE FROM ");
490
                strb.append(OracleValues.USER_ORACLE_GEOMETADATA_VIEW);
491
                strb.append(" WHERE ");
492
                strb.append(OracleValues.USER_ORACLE_GEOMETADATA_VIEW_TABLE_NAME);
493
                strb.append(" = '");
494
                strb.append(params.getTable());
495
                strb.append("' AND ");
496
                strb.append(OracleValues.USER_ORACLE_GEOMETADATA_VIEW_COLUMN_NAME);
497
                strb.append(" = '");
498
                strb.append(attr.getName());
499
                strb.append("'");
500

    
501
                return strb.toString();
502
        }
503
        
504
        
505
        protected void loadFeatureProviderValue(FeatureProvider data, ResultSet rs,
506
                        FeatureAttributeDescriptor attr) throws DataException {
507
                if (attr.getDataType().getType() == DataTypes.GEOMETRY) {
508

    
509
                        try {
510
                                Object geo_str_obj = rs.getObject(attr.getIndex() + 1);
511
                                if (geo_str_obj == null) {
512
                                        data.set(attr.getIndex(), OracleUtils.createNullGeometry(SUBTYPES.GEOM2D));
513
                                } else {
514
                                        STRUCT geo_str = (STRUCT) geo_str_obj;
515
                                        
516
                                        // IProjection proj = attr.getSRS();
517
                                        // OracleUtils.
518
                                        
519
                                        Geometry geom = OracleUtils.getGeometry(
520
                                                        geo_str,
521
                                                        false,
522
                                                        false,
523
                                                        "",
524
                                                        helper.getConnection());
525
                                        data.set(attr.getIndex(), geom);
526
                                }
527
                        } catch (SQLException e) {
528
                                throw new JDBCSQLException(e);
529
                        } catch (BaseException e) {
530
                                throw new ReadException(getName(), e);
531
                        }
532

    
533
                } else {
534
                        
535
                        try {
536
                                Object obj_data = rs.getObject(attr.getName());
537

    
538
                                if (obj_data != null) {
539
                                    obj_data = coerce(attr, obj_data);
540
                                }
541
                                
542
                                data.set(attr.getName(), obj_data);
543
                                
544
                                if (attr.isPrimaryKey()) {
545
                                        
546
                                        try {
547
                                                obj_data = getDataTypesManager().coerce(DataTypes.LONG, obj_data);
548
                                                data.setOID(obj_data);
549
                                        } catch (Exception ex) {
550
                                                // logger.warn("Unable to convert OID to Long. Auto-increm will be used.");
551
                                        }
552

    
553
                                }
554
                        } catch (Exception e) {
555
                                throw new CreateFeatureException(e, NAME);
556
                        }
557
                }
558
        }
559
        
560
        
561
        
562
        /**
563
         * Load data form a resulset.<br>
564
         *
565
         * <strong>Note:</strong><br>
566
         * this method have to perform <code>resouceBegin</code> at the begining and
567
         * <code>resourceEnd</code> at the end of execution.
568
         *
569
         *
570
         * @param data
571
         * @param resulsetID
572
         *
573
         * @return
574
         * @throws DataException
575
         */
576
        public void loadFeatureProvider(final FeatureProvider data, final int resultsetID)
577
                        throws DataException {
578
                getResource().execute(new ResourceAction() {
579
                        public Object run() throws Exception {
580
                                ResultSet rs = getResultSet(resultsetID);
581
                                
582
                                FeatureAttributeDescriptor attr;
583
                                FeatureAttributeDescriptor[] atts = data.getType().getAttributeDescriptors();
584
                                int len = atts.length;
585
                                if (selectedFields == null){
586
                                    for (int i=0; i<len; i++) {
587
                                            attr = atts[i];
588
                                            loadFeatureProviderValue(data, rs, attr);
589
                                    }
590
                                }else{
591
                                    for (int i=0; i<len; i++) {
592
                        attr = atts[i];
593
                        if (selectedFields.containsKey(attr.getName())){
594
                            loadFeatureProviderValue(data, rs, attr);
595
                        }
596
                    }
597
                                }
598

    
599
                                // this should not happen, loadFeatureProviderValue checks PK
600
                                if (data.getOID() == null) {
601
                                        data.setOID(createNewOID());
602
                                }
603
                                return null;
604
                        }
605
                });
606
        }
607
        
608
        
609
        
610
        protected ResultSet createNewResultSet(final String sql,
611
                        final Object[] values, final int fetchSize)
612
                        throws DataException {
613
                this.open();
614
                return (ResultSet) getResource().execute(new ResourceAction() {
615
                        public Object run() throws Exception {
616
                                Connection conn = null;
617
                                PreparedStatement st = null;
618
                                ResultSet rs = null;
619
                                try {
620

    
621
                                        conn = helper.getConnection();
622
                                        conn.setAutoCommit(false);
623
                                        st = conn.prepareStatement(sql);
624

    
625
                                        if (values != null) {
626
                                                Object value;
627
                                                for (int i = 0; i < values.length; i++) {
628
                                                        value = values[i];
629
                                                        if (value instanceof Geometry) {
630
                                                                byte[] bytes;
631
                                                                try {
632
                                                                        bytes =
633
                                                                                        (byte[]) ((Geometry) value).invokeOperation(
634
                                                                                                        ToWKB.CODE, null);
635
                                                                } catch (BaseException e) {
636
                                                                        throw new InvalidParameterException();
637
                                                                }
638
                                                                st.setBytes(i + 1, bytes);
639
                                                        }
640
                                                        st.setObject(i + 1, value);
641
                                                }
642
                                        }
643

    
644
                                        if (fetchSize > 0) {
645
                                                st.setFetchSize(fetchSize);
646
                                        }
647
                                        rs = st.executeQuery();
648
                                        if (fetchSize > 0) {
649
                                                rs.setFetchSize(fetchSize);
650
                                        }
651
                                        return rs;
652
                                } catch (SQLException e) {
653
                                        try {
654
                                                rs.close();
655
                                        } catch (Exception e1) {
656
                                        }
657
                                        try {
658
                                                st.close();
659
                                        } catch (Exception e1) {
660
                                        }
661
                                        /*
662
                                        try {
663
                                                conn.close();
664
                                        } catch (Exception e1) {
665
                                        }
666
                                        */
667
                                        throw new JDBCExecutePreparedSQLException(sql,values,e);
668
                                }
669
                        }
670
                });
671
        }
672
        
673
        
674
        
675
        
676
        
677
        protected void closeResulset(final ResultSet rs) throws JDBCException,
678
        ResourceExecuteException {
679
                getResource().execute(new ResourceAction() {
680
                        public Object run() throws Exception {
681
                                Statement st = rs.getStatement();
682
                                Connection con = st.getConnection();
683
                                try {
684
                                        rs.close();
685
                                } finally {
686
                                        // TODO revisar esto
687
                                        try{ st.close();  } catch (Exception ex){ };
688
                                        // try{ con.close(); } catch (Exception ex){ };
689
                                }
690
                                return null;
691
                        }
692
                });
693
        }
694
        
695
        
696
        
697
        public String compoundSelect(FeatureType type, String filter, String order,
698
                        long limit, long offset) throws DataException {
699
                StringBuilder sql = new StringBuilder();
700
                JDBCStoreParameters params = getJDBCParameters();
701
                if (directSQLMode) {
702
                        sql.append(params.getSQL());
703
                        sql.append(' ');
704
                } else {
705
                    String sFields = (String)getParameters().getDynValue("fields");
706
            if (sFields == null){
707
                FeatureAttributeDescriptor[] fields = type
708
                .getAttributeDescriptors();
709

    
710
                // Select
711
                sql.append("Select ");
712
                for (int i = 0; i < fields.length - 1; i++) {
713
                    sql.append(helper.getSqlFieldName(fields[i]));
714
                    sql.append(", ");
715
                }
716

    
717
                sql.append(helper.getSqlFieldName(fields[fields.length - 1]));
718
                sql.append(' ');
719

    
720
                FeatureAttributeDescriptor[] pkFields = getStoreServices()
721
                .getProviderFeatureType(type.getId()).getPrimaryKey();
722

    
723
                if (pkFields != null && pkFields.length > 0) {
724
                    // checks for pk fields are in select
725
                    boolean toAdd;
726
                    for (int i = 0; i < pkFields.length; i++) {
727
                        toAdd = true;
728
                        for (int j = 0; j < fields.length; j++) {
729
                            if (pkFields[i].getName().equals(fields[j].getName())) {
730
                                toAdd = false;
731
                                break;
732
                            }
733
                        }
734
                        if (toAdd) {
735
                            sql.append(", ");
736
                            sql.append(helper.getSqlFieldName(pkFields[i]));
737
                        }                       
738
                    }
739
                    sql.append(' ');
740
                }
741
            }else{
742
                sql.append("Select ");
743
                sql.append(sFields);
744
                sql.append(' ');
745
            }
746

    
747
                        // table
748
                        sql.append("from ");
749
                        sql.append(params.tableID());
750
                        sql.append(' ');
751
                                  
752
            // Where
753
            appendWhere(sql, filter);                        
754
        
755
            if (limit == 0 && offset > 1) {            
756
                StringBuilder romNumberQuery = new StringBuilder();
757
                romNumberQuery.append("SELECT * FROM ( SELECT A.*, ROWNUM row_number FROM (");
758
                romNumberQuery.append(sql);
759
                romNumberQuery.append(") A WHERE ROWNUM <= ");                
760
                romNumberQuery.append(offset + 100);
761
                romNumberQuery.append(" ) WHERE row_number >");
762
                romNumberQuery.append(offset);
763
                sql = romNumberQuery;  
764
                }  
765

    
766
                        // Order
767
                        /*
768
                        if ((params.getBaseOrder() != null && params.getBaseOrder()
769
                                        .length() != 0)
770
                                        || (order != null && order.length() != 0)) {
771
                                sql.append("order by ");
772

773
                                if (order != null && order.length() != 0) {
774
                                        // order
775
                                        sql.append(order);
776
                                } else {
777
                                        // initial order
778
                                        sql.append(params.getBaseOrder());
779
                                }
780
                                sql.append(' ');
781
                        }
782
                        */
783
                }
784
                // limit offset
785

    
786
                sqlCount++;
787

    
788
                if (System.currentTimeMillis() - lastPrint > 5000) {
789
                        logger.info("Executing SQL # " + sqlCount + ": " + sql.toString());
790
                        lastPrint = System.currentTimeMillis(); 
791
                }
792
                
793
                return sql.toString();
794
        }
795
        
796
        private static long lastPrint = 0;
797
        private static long sqlCount = 0;
798
        
799
        private Object coerce(FeatureAttributeDescriptor att, Object v) throws CoercionException {
800
                
801
                if (!att.getObjectClass().isInstance(v)) {
802
                    
803
                    if (v instanceof TIMESTAMP && att.getDataType().getCoercion() instanceof CoerceToDateTime) {
804
                        
805
                        TIMESTAMP ora_ts = (TIMESTAMP) v;
806
                        try {
807
                            return ora_ts.timestampValue(); 
808
                        } catch (Exception ex) {
809
                            throw new CoercionException(ex);
810
                        }
811

    
812
                    } else {
813
                    return getDataTypesManager().coerce(att.getType(), v);
814
                    }
815
                    
816
                } else {
817
                        return v;
818
                }
819
        }
820
        
821
        private static DataTypesManager dtManager = null;
822
        
823
        
824
        protected DataTypesManager getDataTypesManager() {
825
                if( dtManager==null ) {
826
                        dtManager = ToolsLocator.getDataTypesManager();
827
                }
828
                return dtManager;
829
        }
830
        
831
            
832
        @Override
833
        protected FeatureProvider internalGetFeatureProviderByReference(
834
                        FeatureReferenceProviderServices reference,
835
                        FeatureType featureType)
836
                        throws DataException {
837
                
838
            if (reference.isNewFeature()){
839
                return createFeatureProvider(featureType);                    
840
            }else{
841
                return super.internalGetFeatureProviderByReference(reference, featureType);
842
            }   
843
        }
844
    
845
        protected void executeRemovePreparedStatement(Connection conn, String sql,
846
            List<FeatureAttributeDescriptor> attributes, Iterator<FeatureReferenceProviderServices> featureReferences) throws DataException {
847
            PreparedStatement st;
848
            try {
849
                st = conn.prepareStatement(sql);
850
            } catch (SQLException e) {
851
                throw new JDBCPreparingSQLException(sql, e);
852
            }
853
            try {
854
                List<Object> values = new ArrayList<Object>();
855
                FeatureReferenceProviderServices featureRef;
856
                //              FeatureType featureType;
857
                while (featureReferences.hasNext()) {
858
                    st.clearParameters();
859
                    featureRef = featureReferences.next();
860
                    values.clear();                   
861

    
862
                    Iterator<FeatureAttributeDescriptor> iter = attributes.iterator();
863
                    FeatureAttributeDescriptor attr;
864
                    while (iter.hasNext()) {
865
                        attr =  iter.next();
866
                        if (attr.isPrimaryKey()){
867
                            values.add(helper.dalValueToJDBC(attr, featureRef.getFeature().get(attr.getIndex())));
868
                        }                       
869
                    }
870

    
871
                    for (int i = 0; i < values.size(); i++) {
872
                        st.setObject(i + 1, values.get(i));
873
                    }
874
                    try {
875
                        int nAffected =st.executeUpdate();
876
                        if (nAffected == 0) {
877
                            throw new JDBCUpdateWithoutChangesException(sql, values);
878
                        }
879
                        if (nAffected > 1){
880
                            logger.warn("Remove statement affectst to {} rows: {}",
881
                                nAffected, sql);
882
                        }
883

    
884
                    } catch (SQLException e) {
885
                        throw new JDBCExecutePreparedSQLException(sql, values, e);
886
                    }
887

    
888
                }
889
            } catch (SQLException e) {
890
                throw new JDBCSQLException(e);
891
            } finally {
892
                try {st.close();} catch (SQLException e) {  };
893
            }
894

    
895
        }
896
        
897
        
898
        
899

    
900
}