Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.db / org.gvsig.fmap.dal.db.mdb / src / main / java / org / gvsig / fmap / dal / store / mdb / MDBSQLBuilder.java @ 46104

History | View | Annotate | Download (31.6 KB)

1
package org.gvsig.fmap.dal.store.mdb;
2

    
3
import java.sql.Clob;
4
import java.sql.PreparedStatement;
5
import java.sql.SQLException;
6
import java.sql.Timestamp;
7
import java.text.MessageFormat;
8
import java.util.ArrayList;
9
import java.util.Date;
10
import java.util.List;
11
import java.util.Objects;
12
import org.apache.commons.codec.binary.Hex;
13
import org.apache.commons.lang3.mutable.MutableBoolean;
14
import org.apache.commons.lang3.tuple.Pair;
15
import org.gvsig.expressionevaluator.ExpressionBuilder;
16
import org.gvsig.expressionevaluator.ExpressionBuilder.Parameter;
17
import org.gvsig.expressionevaluator.Formatter;
18
import org.gvsig.expressionevaluator.GeometryExpressionBuilderHelper;
19
import org.gvsig.expressionevaluator.GeometryExpressionBuilderHelper.GeometryParameter;
20
import org.gvsig.fmap.dal.DataTypes;
21
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
22
import org.gvsig.fmap.dal.feature.FeatureType;
23
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
24
import org.gvsig.fmap.dal.store.mdb.expressionbuilderformatter.MDBFormatter;
25
import org.gvsig.fmap.dal.store.jdbc2.spi.JDBCSQLBuilderBase;
26
import org.gvsig.fmap.geom.Geometry;
27
import org.gvsig.fmap.geom.exception.CreateGeometryException;
28
import org.gvsig.tools.dispose.Disposable;
29
import org.hsqldb.jdbc.JDBCClob;
30

    
31
public class MDBSQLBuilder extends JDBCSQLBuilderBase {
32

    
33
    protected Formatter formatter = null;
34
    
35
    public MDBSQLBuilder(MDBHelper helper) {
36
        super(helper);
37
        
38
        this.defaultSchema = "";
39
        this.supportSchemas = false;
40
        this.allowAutomaticValues = true;
41
        this.geometrySupportType = this.helper.getGeometrySupportType();
42
        this.hasSpatialFunctions = this.helper.hasSpatialFunctions();
43

    
44
        this.STMT_DELETE_GEOMETRY_COLUMN_FROM_TABLE_schema_table = null;
45
        this.STMT_DELETE_GEOMETRY_COLUMN_FROM_TABLE_table = null;
46
         
47
        this.STMT_UPDATE_TABLE_STATISTICS_table = "";
48

    
49
        this.type_boolean = "BOOLEAN";
50
        this.type_byte = "TINYINT";
51
        this.type_bytearray = "BLOB";
52
        this.type_geometry = "CLOB";
53
        this.type_char = "CHAR";
54
        this.type_date = "DATETIME";
55
        this.type_double = "FLOAT"; 
56
        this.type_decimal_ps = "DECIMAL({0,Number,##########},{1,Number,##########})";
57
        this.type_decimal_p = "DECIMAL({0,Number,##########})";
58
        this.type_float = "REAL";
59
        this.type_int = "INTEGER";
60
        this.type_long = "DECIMAL(19,0)";
61
        this.type_string = "VARCHAR";
62
        this.type_string_p = "VARCHAR({0,Number,##########})";
63
        this.type_time = "DATETIME";
64
        this.type_timestamp = "DATETIME";
65
        this.type_version = "VARCHAR";
66
        this.type_URI = "VARCHAR";
67
        this.type_URL = "VARCHAR";
68
        this.type_FILE = "VARCHAR";
69
        this.type_FOLDER = "VARCHAR";             
70
    }
71

    
72
    @Override
73
    public Formatter formatter() {
74
        if( this.formatter==null ) {
75
            this.formatter = new MDBFormatter(this);
76
        }
77
        return this.formatter;
78
    }
79

    
80
    public class MDBTableNameBuilderBase extends TableNameBuilderBase {
81

    
82
        @Override
83
        public boolean has_database() {
84
            return false;
85
        }
86
        
87
    }
88

    
89
    public class MDBCreateIndexBuilder extends CreateIndexBuilderBase {
90
    
91
        @Override
92
        public List<String> toStrings(Formatter formatter) {
93
            StringBuilder builder = new StringBuilder();
94
            builder.append("CREATE ");
95
            if( this.isUnique ) {
96
                builder.append("UNIQUE ");
97
            }
98
            if( this.isSpatial ) {
99
                builder.append("SPATIAL ");
100
            }
101
            builder.append("INDEX ");
102
            if( this.ifNotExist ) {
103
                builder.append("IF NOT EXISTS ");
104
            }
105
            builder.append(as_identifier(this.indexName));
106
            builder.append(" ON ");
107
            builder.append(this.table.toString(formatter));
108
            builder.append(" ( ");
109
            boolean is_first_column = true;
110
            for( String column : this.columns) {
111
                if( is_first_column ) {
112
                    is_first_column = false;
113
                } else {
114
                    builder.append(", ");
115
                }
116
                builder.append(as_identifier(column));
117
            }
118
            builder.append(" )");
119
            
120
            List<String> sqls = new ArrayList<>();
121
            sqls.add(builder.toString());
122
            return sqls;
123
        }
124

    
125
    }
126
        
127
    protected class MDBAlterTableBuilderBase extends AlterTableBuilderBase {
128
        @Override
129
        public List<String> toStrings(Formatter formatter) {
130
            List<String> sqls = new ArrayList<>();
131
            if( this.isEmpty() ) {
132
                return sqls;
133
            }
134
            for (String column : drops) {
135
                StringBuilder builder = new StringBuilder();
136
                builder.append("ALTER TABLE ");
137
                builder.append(this.table.toString(formatter));
138
                builder.append(" DROP COLUMN IF EXISTS ");
139
                builder.append(as_identifier(column)); 
140
                sqls.add(builder.toString());
141
            }
142
            for (ColumnDescriptor column : adds) {
143
                StringBuilder builder = new StringBuilder();
144
                builder.append("ALTER TABLE ");
145
                builder.append(this.table.toString(formatter));
146
                builder.append(" ADD COLUMN ");
147
                builder.append(as_identifier(column.getName())); 
148
                builder.append(" ");
149
                if( column.getType() == DataTypes.INT && column.isAutomatic() ) {
150
                    builder.append(" SERIAL");
151
                } else {
152
                    builder.append(
153
                        sqltype(
154
                            column.getType(), 
155
                            column.getSize(),
156
                            column.getPrecision(), 
157
                            column.getScale(), 
158
                            column.getGeometryType(), 
159
                            column.getGeometrySubtype()
160
                        )
161
                    );
162
                }
163
                if (column.getDefaultValue() == null) {
164
                    if (column.allowNulls()) {
165
                        builder.append(" DEFAULT NULL");
166
                    }
167
                } else {
168
                    builder.append(" DEFAULT '");
169
                    builder.append(Objects.toString(column.getDefaultValue(),""));
170
                    builder.append("'");
171
                }
172
                if (column.allowNulls()) {
173
                    builder.append(" NULL");
174
                } else {
175
                    builder.append(" NOT NULL");
176
                }
177
                if (column.isPrimaryKey()) {
178
                    builder.append(" PRIMARY KEY");
179
                }
180
                sqls.add(builder.toString());
181
                
182
//                if( column.isGeometry() ) {
183
//                    String constraint_name = "constraint_" + this.table().getName() + "_" + column.getName()+"_geom";
184
//                    String sql;
185
//                    if( column.getGeometrySRSId()==null ) {
186
//                      sql = MessageFormat.format(
187
//                            "ALTER TABLE \"{0}\".\"{1}\" ADD CONSTRAINT IF NOT EXISTS \"{2}\" CHECK NVL2(\"{3}\", ST_GeometryTypeCode(\"{3}\") = {4,number,###} AND ST_CoordDim(\"{3}\") = {5,number,###}, TRUE)",
188
//                            this.table().getSchema(),
189
//                            this.table().getName(),
190
//                            constraint_name,
191
//                            column.getName(),
192
//                            sqlgeometrytype(column.getGeometryType(),column.getGeometrySubtype()),
193
//                            sqlgeometrynumdimension(column.getGeometryType(),column.getGeometrySubtype()),
194
//                            column.getGeometrySRSId() 
195
//                      );
196
//                    } else {
197
//                      sql = MessageFormat.format(
198
//                            "ALTER TABLE \"{0}\".\"{1}\" ADD CONSTRAINT IF NOT EXISTS \"{2}\" CHECK NVL2(\"{3}\", ST_GeometryTypeCode(\"{3}\") = {4,number,###} AND ST_CoordDim(\"{3}\") = {5,number,###} AND ST_SRID(\"{3}\") = {6,number,#####}, TRUE)",
199
//                            this.table().getSchema(),
200
//                            this.table().getName(),
201
//                            constraint_name,
202
//                            column.getName(),
203
//                            sqlgeometrytype(column.getGeometryType(),column.getGeometrySubtype()),
204
//                            sqlgeometrynumdimension(column.getGeometryType(),column.getGeometrySubtype()),
205
//                            column.getGeometrySRSId() 
206
//                      );
207
//                    }
208
//                    sqls.add(sql);
209
//                }
210
            }
211
            for (ColumnDescriptor column : alters) {
212
                StringBuilder builder = new StringBuilder();
213
                builder.append("ALTER TABLE ");
214
                builder.append(this.table.toString(formatter));
215
                builder.append(" ALTER COLUMN ");
216
                builder.append(as_identifier(column.getName())); 
217
                builder.append(" ");
218
                builder.append(
219
                    sqltype(
220
                        column.getType(), 
221
                        column.getSize(),
222
                        column.getPrecision(), 
223
                        column.getScale(), 
224
                        column.getGeometryType(), 
225
                        column.getGeometrySubtype()
226
                    )
227
                );
228
                if (column.getDefaultValue() == null) {
229
                    if (column.allowNulls()) {
230
                        builder.append(" DEFAULT NULL");
231
                    }
232
                } else {
233
                    builder.append(" DEFAULT '");
234
                    builder.append(column.getDefaultValue().toString());
235
                    builder.append("'");
236
                }
237
                if( column.isAutomatic() ) {
238
                    builder.append(" AUTO_INCREMENT");
239
                }
240
                sqls.add(builder.toString());
241
//                if( column.isGeometry() ) {
242
//                    String sql;
243
//                    String constraint_name = "constraint_" + this.table().getName() + "_" + column.getName()+"_dim";
244
//                    sql = MessageFormat.format(
245
//                        "ALTER TABLE \"{0}\".\"{1}\" ADD CONSTRAINT IF NOT EXISTS \"{2}\" CHECK ST_CoordDim(\"{3}\") = {4}",
246
//                        this.table().getSchema(),
247
//                        this.table().getName(),
248
//                        constraint_name,
249
//                        column.getName(),
250
//                        sqlgeometrynumdimension(column.getGeometryType(),column.getGeometrySubtype())
251
//                    );
252
//                    sqls.add(sql);
253
//                }
254
            }
255
            for (Pair<String,String> pair : renames) {
256
                StringBuilder builder = new StringBuilder();
257
                builder.append("ALTER TABLE ");
258
                builder.append(this.table.toString(formatter));
259
                builder.append(" RENAME COLUMN ");
260
                builder.append(as_identifier(pair.getLeft())); 
261
                builder.append(" TO ");
262
                builder.append(as_identifier(pair.getRight())); 
263
                sqls.add(builder.toString());
264
            }
265
            return sqls;
266
        }
267

    
268
    }
269

    
270
    protected class MDBCreateTableBuilder extends CreateTableBuilderBase {
271

    
272
        @Override
273
        public List<String> toStrings(Formatter formatter) {
274

    
275
            List<String> sqls = new ArrayList<>();
276
            StringBuilder builder = new StringBuilder();
277

    
278
            builder.append("CREATE TABLE ");
279
            builder.append(this.table.toString(formatter));
280
            builder.append(" (");
281
            boolean first = true;
282
            for (ColumnDescriptor column : columns) {
283

    
284
                if (first) {
285
                    first = false;
286
                } else {
287
                    builder.append(", ");
288
                }
289
                builder.append(as_identifier(column.getName()));
290
                builder.append(" ");
291
                if( column.isGeometry() ) {
292
                    builder.append(type_geometry);
293
                } else {
294
                    builder.append(
295
                        sqltype(
296
                            column.getType(), 
297
                            column.getSize(),
298
                            column.getPrecision(), 
299
                            column.getScale(), 
300
                            column.getGeometryType(), 
301
                            column.getGeometrySubtype()
302
                        )
303
                    );
304
                }
305
                if (column.isPrimaryKey()) {
306
                    builder.append(" PRIMARY KEY");
307
                    if( column.isAutomatic() ) {
308
                        builder.append(" AUTO_INCREMENT");
309
                    }
310
                } else {
311
                    if( column.isAutomatic() ) {
312
                        builder.append(" AUTO_INCREMENT");
313
                    }
314
                    if (column.getDefaultValue() == null) {
315
                        if (column.allowNulls()) {
316
                            builder.append(" DEFAULT NULL");
317
                        }
318
                    } else {
319
                        if( column.getType() == DataTypes.DATE ) {
320
                            builder.append(" DEFAULT ( TIMESTAMP '");
321
                            Date d = (Date) column.getDefaultValue();
322
                            builder.append(MessageFormat.format( "{0,date,yyyy-MM-dd HH:mm:ss.S}",d));
323
                            builder.append("' )");
324
                        } else {
325
                            builder.append(" DEFAULT '");
326
                            builder.append(Objects.toString(column.getDefaultValue(),""));
327
                            builder.append("'");
328
                        }
329
                    }                    
330
                }
331
                if (!column.allowNulls()) {
332
                    builder.append(" NOT NULL");
333
                }
334
            }
335
            builder.append(" )");
336
            sqls.add(builder.toString());
337
            return sqls;
338
        }
339
    }
340
    
341
    public class MDBInsertColumnBuilderBase extends InsertColumnBuilderBase {
342
        @Override
343
       public String toString(Formatter<ExpressionBuilder.Value> formatter) {
344
            if( formatter!=null && formatter.canApply(this) ) {
345
                return formatter.format(this);
346
            }
347
            return this.value.toString(formatter);
348
        }
349
    }
350
    
351
    public class MDBInsertBuilderBase extends InsertBuilderBase {
352
        @Override
353
        public String toString(Formatter formatter) {
354
            return super.toString(formatter);
355
        }
356
    }
357
    
358
    public class MDBSelectColumnBuilderBase extends SelectColumnBuilderBase {
359
        @Override
360
        public String toString(Formatter formatter) {
361
            return super.toString(formatter);
362
        }
363
    }
364
        
365
    public class MDBSelectBuilderBase extends SelectBuilderBase {
366
        
367
        @Override
368
        public String toString(Formatter formatter) {
369
            StringBuilder builder = new StringBuilder();
370
            if( !isValid(builder) ) {
371
                throw new IllegalStateException(builder.toString());
372
            }
373
            builder.append("SELECT ");
374
            if( this.distinct ) {
375
                builder.append("DISTINCT ");
376
            }
377
            boolean first = true;
378
            for (SelectColumnBuilder column : columns) {
379
                if (first) {
380
                    first = false;
381
                } else {
382
                    builder.append(", ");
383
                }
384
                
385
                builder.append(column.toString(formatter));
386
            }
387

    
388
            if ( this.has_from() ) {
389
                builder.append(" FROM ");
390
                builder.append(this.from.toString(formatter));
391
            }
392
            if ( this.has_where() ) {
393
                builder.append(" WHERE ");
394
                builder.append(this.where.toString(formatter));
395
            }
396
            if( this.has_group_by() ) {
397
                builder.append(" GROUP BY ");
398
                builder.append(this.groupColumn.get(0).toString(formatter));
399
                for (int i = 1; i < groupColumn.size(); i++) {
400
                    builder.append(", ");
401
                    builder.append(this.groupColumn.get(i).toString(formatter));
402
                }
403
            }
404
            if( this.has_order_by() ) {
405
                builder.append(" ORDER BY ");
406
                first = true;
407
                for (OrderByBuilder item : this.order_by) {
408
                    if (first) {
409
                        first = false;
410
                    } else {
411
                        builder.append(", ");
412
                    }
413
                    builder.append(item.toString(formatter));                    
414
                }   
415
            }
416
            
417
            if ( this.has_limit() && this.has_offset() ) {
418
                builder.append(" LIMIT ");
419
                builder.append(this.limit);
420
                builder.append(" OFFSET ");
421
                builder.append(this.offset);
422
                
423
            } else if ( this.has_limit()) {
424
                builder.append(" LIMIT ");
425
                builder.append(this.limit);
426

    
427
            } else if ( this.has_offset() ) {
428
                builder.append(" LIMIT -1 OFFSET ");
429
                builder.append(this.offset);    
430
            }
431
            return builder.toString();
432

    
433
        }
434
    }
435

    
436
    @Override
437
    public Object sqlgeometrydimension(int type, int subtype) {
438
        //'XY' or 2: 2D points, identified by X and Y coordinates
439
        //'XYM': 2D points, identified by X and Y coordinates. Each point stores an M-value (measure) as well
440
        //'XYZ' or 3: 3D points, identified by X, Y and Z coordinates
441
        //'XYZM' or 4: 3D points, identified by X, Y and Z coordinates. Each point stores an M-value (measure) as well
442
        switch(subtype) {
443
            case Geometry.SUBTYPES.GEOM2D:
444
            default:
445
                return "XY";
446
            case Geometry.SUBTYPES.GEOM2DM:
447
                return "XYM";
448
            case Geometry.SUBTYPES.GEOM3D:
449
                return "XYZ";
450
            case Geometry.SUBTYPES.GEOM3DM:
451
                return "XYZM";
452
        }
453
    }
454

    
455
    @Override
456
    public String sqltype(int type, int size, int precision, int scale, int geomtype, int geomSubtype) {
457
        if( type!=DataTypes.GEOMETRY ) {
458
            return super.sqltype(type, size, precision, scale, geomtype, geomSubtype);
459
        }
460
        return this.type_geometry;
461
    }
462
    
463
    @Override
464
    public Object sqlgeometrytype(int geomtype, int geomsubtype) {
465
        //
466
        // https://github.com/orbisgis/h2gis/wiki/1.-Spatial-data#geometry-columns-view
467
        //
468
        switch(geomtype) {
469
        case Geometry.TYPES.POINT:
470
            return 1; 
471
        case Geometry.TYPES.MULTIPOINT:
472
            return 4; 
473
        case Geometry.TYPES.LINE:
474
            return 2; 
475
        case Geometry.TYPES.MULTILINE:
476
            return 5; 
477
        case Geometry.TYPES.POLYGON:
478
            return 3; 
479
        case Geometry.TYPES.MULTIPOLYGON:
480
            return 6;
481
        case Geometry.TYPES.GEOMETRY:
482
        default:
483
            return 0; // "GEOMETRY";
484
        }
485
    }
486
    
487
    public Object sqlgeometrynumdimension(int type, int subtype) {
488
        int dimensions=2;
489
        switch(subtype) {
490
        case Geometry.SUBTYPES.GEOM3D:
491
            dimensions = 3;
492
            break;
493
        case Geometry.SUBTYPES.GEOM2D:
494
            dimensions = 2;
495
            break;
496
        case Geometry.SUBTYPES.GEOM2DM:
497
            dimensions = 2; // ??????
498
            break;
499
        case Geometry.SUBTYPES.GEOM3DM:
500
            dimensions = 3; // ??????
501
            break;
502
        }
503
        return dimensions;
504
    }
505
    
506
    @Override
507
    public MDBHelper getHelper() {
508
        return (MDBHelper) this.helper;
509
    }
510
   
511
    @Override
512
    public Disposable setParameters(PreparedStatement st, FeatureProvider feature) {
513
        try {
514
            FeatureType featureType = feature.getType();
515
            List<Object> values = new ArrayList<>();
516
            List<Parameter> parameters = this.parametersWithoutSRS();
517
            for (Parameter parameter : parameters) {
518
                if (parameter.is_constant()) {
519
                    values.add(parameter.value());
520
                } else {
521
                    String name = parameter.name();
522
                    FeatureAttributeDescriptor descriptor = featureType.getAttributeDescriptor(name);
523
                    switch( descriptor.getType() ) {
524
                    case DataTypes.DATE:
525
                        Date value = (Date)(feature.get(name));
526
                        if( value == null ) {
527
                            values.add(null);
528
                        } else {
529
                            values.add(new java.sql.Date(value.getTime()));
530
                        }
531
                        break;
532
                    case DataTypes.GEOMETRY:
533
                        Geometry geom = this.forceGeometryType(
534
                            descriptor.getGeomType(),
535
                            (Geometry)(feature.get(name))
536
                        );
537
                        values.add(geom);
538
                        break;
539
                    default:
540
                        values.add(feature.get(name));
541
                        break;
542
                    }
543
                }
544
            }
545
            return this.setStatementParameters(st, values, this.geometry_support_type());
546
        } catch (SQLException | CreateGeometryException ex) {
547
            String f = "unknow";
548
            try {
549
                f = feature.toString();
550
            } catch (Exception ex2) {
551
                // Do nothing
552
            }
553
            throw new RuntimeException("Can't set parameters to prepared statement from the feature (" + f + ")", ex);
554
        }
555
    }
556

    
557
    public List<Parameter> parametersWithoutSRS() {
558
        final List<Parameter>  params = new ArrayList<>();
559
        MutableBoolean skipNextParameter = new MutableBoolean(false);
560
        this.accept((ExpressionBuilder.Visitable value1) -> {
561
            if (skipNextParameter.isTrue()) {
562
                skipNextParameter.setFalse();
563
                return;
564
            }
565
            if (value1 instanceof GeometryExpressionBuilderHelper.GeometryParameter) {
566
                GeometryParameter g = (GeometryParameter) value1;
567
                if (g.srs()!= null) {
568
                    skipNextParameter.setTrue();
569
                }
570
                
571
            }
572
          params.add((Parameter) value1);
573
        }, new ExpressionBuilder.ClassVisitorFilter(Parameter.class));
574
        return params;
575
    }
576
//.
577
//    public List<Parameter> parametersWithoutSRS() { // aqui hay que eliminar el srs. Visitor de tipo GeometryParameterBase, si ese tiene srs. si lo tiene y es de tipo Parametro debe saltarselo
578
//        final List<Parameter> params = new ArrayList<>();
579
//        this.accept(new ExpressionBuilder.Visitor() {
580
//            @Override
581
//            public void visit(ExpressionBuilder.Visitable value) {
582
//                params.add((Parameter) value);
583
//            }
584
//        }, new ExpressionBuilder.ClassVisitorFilter(Parameter.class));
585
//        return params;
586
//    }
587

    
588
    @Override
589
    public InsertColumnBuilderBase createInsertColumnBuilder() {
590
        return new MDBInsertColumnBuilderBase();
591
    }
592
        
593
    @Override
594
    public InsertBuilderBase createInsertBuilder() {
595
        return new MDBInsertBuilderBase();
596
    }
597

    
598
    @Override
599
    public AlterTableBuilder createAlterTableBuilder() {
600
        return new MDBAlterTableBuilderBase();
601
    }
602
            
603
    @Override
604
    public TableNameBuilder createTableNameBuilder() {
605
        return new MDBTableNameBuilderBase();
606
    }
607
    
608
    @Override
609
    protected CreateTableBuilder createCreateTableBuilder() {
610
        return new MDBCreateTableBuilder();
611
    }
612

    
613
    @Override
614
    protected SelectBuilder createSelectBuilder() {
615
        return new MDBSelectBuilderBase();
616
    }
617

    
618
    @Override
619
    protected SelectColumnBuilder createSelectColumnBuilder() {
620
        
621
        return new MDBSelectColumnBuilderBase(); //super.createSelectColumnBuilder().; // SelectColumnBuilderBase, override el metodo toString
622
    }
623
    
624
    @Override
625
    protected CreateIndexBuilder createCreateIndexBuilder() {
626
        return new MDBCreateIndexBuilder();
627
    }
628
    
629
    @Override
630
    public String as_identifier(String id) {
631
        if (id.startsWith("[")) {
632
            return id;
633
        }
634
        return "["+id+"]";
635
    }
636
    
637
    @Override
638
    public Disposable setStatementParameters(
639
            PreparedStatement st,
640
            List values,
641
            GeometryExpressionBuilderHelper.GeometrySupportType geometrySupportType) throws SQLException {
642

    
643
        //
644
        DisposableClobs disposableClobs = new DisposableClobs();
645
        //
646
        if (values == null) {
647
            return disposableClobs;
648
        }
649
        if (true || LOGGER.isDebugEnabled()) {
650
            StringBuilder debug = new StringBuilder();
651
            debug.append("st.set(");
652
            try {
653
                byte[] bytes;
654
                int columnIndex = 1;
655
                for (Object value : values) {
656
                    if (value instanceof Geometry) {
657
                        switch (geometrySupportType) {
658
                            case WKT:
659
                                value = ((Geometry) value).convertToWKT();
660
                                debug.append("/*");
661
                                debug.append(columnIndex);
662
                                debug.append("*/ ");
663
                                debug.append(as_string(value));
664
                                debug.append(", ");
665
                                break;
666
                            case NATIVE:
667
                            case WKB:
668
                                bytes = ((Geometry) value).convertToWKB();
669
                                debug.append("/*");
670
                                debug.append(columnIndex);
671
                                debug.append("*/ ");
672
                                debug.append(as_string(bytes));
673
                                debug.append(", ");
674
                                break;
675
                            case EWKB:
676
                                bytes = ((Geometry) value).convertToEWKB();
677
                                debug.append("/*");
678
                                debug.append(columnIndex);
679
                                debug.append("*/ ");
680
                                debug.append(as_string(bytes));
681
                                debug.append(", ");
682
                                break;
683
                        }
684
                    } else {
685
                        debug.append("/*");
686
                        debug.append(columnIndex);
687
                        debug.append("*/ ");
688
                        if (value instanceof String) {
689
                            debug.append(as_string(value));
690
                        } else if (value instanceof Boolean) {
691
                            debug.append(((Boolean) value) ? constant_true : constant_false);
692
                        } else {
693
                            debug.append(value);
694
                        }
695
                        debug.append(", ");
696
                    }
697
                    columnIndex++;
698
                }
699
                debug.append(")");
700
                LOGGER.debug(debug.toString());
701
            } catch (Exception ex) {
702
            }
703
        }
704
        byte[] bytes;
705
        char[] hexGeomEwkb;
706
        int columnIndex = 1;
707
        Object theValue;
708
        Clob cl;
709
        try {
710
            for (Object value : values) {
711
                theValue = value;
712

    
713
                if (value instanceof Geometry) {
714
                    switch (geometrySupportType) {
715
                        case WKT:
716
                            value = ((Geometry) value).convertToWKT();
717
                            st.setObject(columnIndex, value);
718
                            break;
719
                        case NATIVE:
720
                        case WKB:
721
                            bytes = ((Geometry) value).convertToWKB();
722
                            cl = disposableClobs.add(bytes);
723
                            st.setClob(columnIndex, cl);
724
                            break;
725

    
726
                        case EWKB:
727
                            bytes = ((Geometry) value).convertToEWKB();
728
                            cl = disposableClobs.add(bytes);
729
                            st.setClob(columnIndex, cl);
730
                            break;
731

    
732

    
733
                    }
734
                } else if (value instanceof Date) {
735
                    // Access solo soporta timestamp
736
                    value = new Timestamp(((Date) value).getTime());
737
                    st.setObject(columnIndex, value);
738
                } else {
739
                    if (value == null) {
740
                        st.setNull(columnIndex, java.sql.Types.BIT);
741
                    } else {
742
                        st.setObject(columnIndex, value);
743
                    }
744
                }
745
                columnIndex++;
746
            }
747
            return disposableClobs;
748
        } catch (Exception ex) {
749
            throw new SQLException("Can't set values for the prepared statement.", ex);
750
        }
751
    }
752

    
753
    @Override
754
    public List<Object> getParameters(FeatureProvider feature) {
755
        try {
756
            FeatureType type = feature.getType();
757
            List<Object> values = new ArrayList<>();
758
            Object value;
759
            for (Parameter parameter : this.parameters()) {
760
                if (parameter.is_constant()) {
761
                    value = parameter.value();
762
                    values.add(value);
763
                } else {
764
                    String name = parameter.name();
765
                    value = feature.get(name);
766
                    FeatureAttributeDescriptor attrDesc = type.getAttributeDescriptor(name);
767
                    switch (attrDesc.getType()) {
768
                        case org.gvsig.fmap.dal.DataTypes.BOOLEAN:
769
                            if (value == null) {
770
                                value = false;
771
                            }
772
                            values.add(value);
773
                            break;
774
                        case org.gvsig.fmap.dal.DataTypes.DATE:
775
                            if (value == null) {
776
                                values.add(null);
777
                            } else {
778
                                values.add(new java.sql.Date(((Date) value).getTime()));
779
                            }
780
                            break;
781
                        case org.gvsig.fmap.dal.DataTypes.GEOMETRY:
782
                            Geometry geom = this.forceGeometryType(
783
                                    attrDesc.getGeomType(),
784
                                    (Geometry) value
785
                            );
786
                            values.add(geom);
787
                            break;
788
                        default:
789
                            values.add(value);
790
                            break;
791
                    }
792
                }
793
            }
794
            return values;
795
        } catch (Exception ex) {
796
            String f = "unknow";
797
            try {
798
                f = feature.toString();
799
            } catch (Exception ex2) {
800
                // Do nothing
801
            }
802
            throw new RuntimeException("Can't get parameters to prepared statement from the feature (" + f + ")", ex);
803
        }
804
    }
805

    
806

    
807
        public class DisposableClobs implements Disposable {
808

    
809
        private final List<Clob> clobList = new ArrayList<>();
810

    
811
        public Clob add(byte[] bytes) throws SQLException {
812
            char[] hexGeom = Hex.encodeHex(bytes);
813
            String strHexGeo = new String(hexGeom);
814
            JDBCClob clob = new JDBCClob(strHexGeo);
815
            clobList.add(clob);
816
            return clob;
817
        }
818

    
819
        @Override
820
        public void dispose() {
821
            clobList.forEach((Clob clob) -> {
822
                try {
823
                    clob.free();
824
                } catch (SQLException ex) {
825
                }
826
            });
827
        }
828

    
829
    }    
830
}