Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.spi / src / main / java / org / gvsig / fmap / dal / feature / spi / SQLBuilderBase_save.java @ 43020

History | View | Annotate | Download (71.4 KB)

1
package org.gvsig.fmap.dal.feature.spi;
2

    
3
import java.text.MessageFormat;
4
import java.util.ArrayList;
5
import java.util.HashMap;
6
import java.util.HashSet;
7
import java.util.List;
8
import java.util.Map;
9
import java.util.Set;
10
import org.apache.commons.lang3.StringUtils;
11
import org.apache.commons.lang3.tuple.ImmutablePair;
12
import org.apache.commons.lang3.tuple.Pair;
13
import org.cresques.cts.IProjection;
14
import org.gvsig.fmap.dal.DataTypes;
15
import org.gvsig.fmap.dal.feature.SQLBuilder_save;
16
import org.gvsig.fmap.dal.feature.SQLBuilder_save.AlterTableBuilder;
17
import org.gvsig.fmap.dal.feature.SQLBuilder_save.ColumnBuilder;
18
import org.gvsig.fmap.dal.feature.SQLBuilder_save.CreateTableBuilder;
19
import org.gvsig.fmap.dal.feature.SQLBuilder_save.DeleteBuilder;
20
import org.gvsig.fmap.dal.feature.SQLBuilder_save.DropTableBuilder;
21
import org.gvsig.fmap.dal.feature.SQLBuilder_save.ExpBuilder;
22
import org.gvsig.fmap.dal.feature.SQLBuilder_save.FromBuilder;
23
import org.gvsig.fmap.dal.feature.SQLBuilder_save.GeometrySupportType;
24
import static org.gvsig.fmap.dal.feature.SQLBuilder_save.GeometrySupportType.EWKB;
25
import static org.gvsig.fmap.dal.feature.SQLBuilder_save.GeometrySupportType.WKB;
26
import static org.gvsig.fmap.dal.feature.SQLBuilder_save.GeometrySupportType.WKT;
27
import org.gvsig.fmap.dal.feature.SQLBuilder_save.GrantBuilder;
28
import org.gvsig.fmap.dal.feature.SQLBuilder_save.InsertBuilder;
29
import org.gvsig.fmap.dal.feature.SQLBuilder_save.OpBuilder;
30
import org.gvsig.fmap.dal.feature.SQLBuilder_save.Parameter;
31
import org.gvsig.fmap.dal.feature.SQLBuilder_save.Privilege;
32
import org.gvsig.fmap.dal.feature.SQLBuilder_save.SelectBuilder;
33
import org.gvsig.fmap.dal.feature.SQLBuilder_save.UpdateBuilder;
34
import org.gvsig.fmap.dal.feature.SQLBuilder_save.UpdateTableStatisticsBuilder;
35
import org.gvsig.fmap.geom.Geometry;
36
import org.gvsig.fmap.geom.primitive.Envelope;
37
import org.gvsig.tools.dataTypes.DataType;
38
import org.slf4j.Logger;
39
import org.slf4j.LoggerFactory;
40

    
41
public class SQLBuilderBase_save implements SQLBuilder_save {
42

    
43
    protected static final Logger logger = LoggerFactory.getLogger(SQLBuilderBase.class);
44
    
45
    protected SelectBuilder select;
46
    protected UpdateBuilder update;
47
    protected InsertBuilder insert;
48
    protected DeleteBuilder delete;
49
    protected AlterTableBuilder alter_table;
50
    protected CreateTableBuilder create_table;
51
    protected GrantBuilder grant;
52
    protected DropTableBuilder drop_table;
53
    protected UpdateTableStatisticsBuilder update_table_statistics;
54
    protected List<Parameter> parameters;
55
    protected SQLBuilderConfig config;
56

    
57
    public class SQLBuilderConfig {
58

    
59
        public boolean allowAutomaticValues;
60
        public boolean has_spatial_functions;
61
        public String default_schema;
62
        public String quote_for_identifiers;
63
        public String quote_for_strings;
64
        public GeometrySupportType geometry_type_support;
65
        public String sql_true;
66
        
67
        public String ST_AsText;
68
        public String ST_AsBinary;
69
        public String ST_AsEWKB;
70
        public String ST_ExtentAggregate;
71
        public String ST_UnionAggregate;
72
        public String ST_Contains;
73
        public String ST_Crosses;
74
        public String ST_Disjoint;
75
        public String ST_IsClosed;
76
        public String ST_Overlaps;
77
        public String ST_Touches;
78
        public String ST_Within;
79
        public String ST_Intersects;
80
        public String ST_Envelope;
81
        public String ST_GeomFromText;
82
        public String ST_GeomFromWKB;
83
        public String ST_GeomFromEWKB;
84
        public String lcase;
85
        public String ucase;
86
        public String isNull;
87
        public String count;
88

    
89
        public String type_boolean;
90
        public String type_byte;
91
        public String type_bytearray;
92
        public String type_geometry;
93
        public String type_char;
94
        public String type_date;
95
        public String type_double;
96
        public String type_numeric_p;
97
        public String type_numeric_ps;
98
        public String type_bigdecimal;
99
        public String type_float;
100
        public String type_int;
101
        public String type_long;
102
        public String type_string;
103
        public String type_string_p;
104
        public String type_time;
105
        public String type_timestamp;
106
        public String type_version;
107
        public String type_URI;
108
        public String type_URL;
109
        public String type_FILE;
110
        public String type_FOLDER;;
111
     
112
        public String operator_AND;
113
        public String operator_OR;
114
        public String operator_EQ;
115
        public String operator_NE;
116
        public String operator_GT;
117
        public String operator_GE;
118
        public String operator_LT;
119
        public String operator_LE;
120
        public String operator_LIKE;
121
        public String operator_ILIKE;
122

    
123
        public String DELETE_FROM_table_WHERE_expresion;
124
        public String DELETE_FROM_table;
125
        public String INSERT_INTO_table_columns_VALUES_values;
126
        public String UPDATE_TABLE_STATISTICS_table;        
127
        public String DROP_TABLE_table;
128
        public String DELETE_GEOMETRY_COLUMN_FROM_TABLE_schema_table;
129
        public String DELETE_GEOMETRY_COLUMN_FROM_TABLE_table;
130
        public String UPDATE_table_SET_columnsAndValues_WHERE_expresion;
131
        public String UPDATE_table_SET_columnsAndValues;
132

    
133
        public SQLBuilderConfig() {
134
            has_spatial_functions = false;
135
            allowAutomaticValues = true;
136
            
137
            sql_true = "(1=1)";
138
            default_schema = "public";
139
            quote_for_identifiers = "\"";
140
            quote_for_strings = "'";
141
            geometry_type_support = GeometrySupportType.WKT;
142
            
143
            ST_AsText  = "ST_AsText({0})";
144
            ST_AsBinary = "ST_AsBinary({0})";
145
            ST_AsEWKB = "ST_AsWKB({0})";
146
            ST_ExtentAggregate = "ST_Extent({0})";
147
            ST_UnionAggregate = "ST_Union({0})";
148
            ST_Contains = "ST_Contains(({0}), ({1}))";            
149
            ST_Crosses =  "ST_Crosses(({0}), ({1}))";
150
            ST_Disjoint  =  "ST_Disjoint (({0}), ({1}))";
151
            ST_IsClosed =  "ST_IsClosed({0})";
152
            ST_Overlaps =  "ST_Overlaps(({0}), ({1}))";
153
            ST_Touches =  "ST_Touches(({0}), ({1}))";
154
            ST_Within = "ST_Within(({0}), ({1}))";            
155
            ST_Envelope = "ST_envelope({0})";
156
            ST_Intersects = "ST_intersects({0}, {1})";
157
            ST_GeomFromText = "ST_GeomFromText({0}, {1})";
158
            ST_GeomFromWKB = "ST_GeomFromWKB({0}, {1})";
159
            ST_GeomFromEWKB = "ST_GeomFromEWKB({0}, {1})";
160
            lcase = "LCASE({0})";
161
            ucase = "UCASE({0})";
162
            count = "count({0})";
163
            isNull = "{0} is null";
164

    
165
            /*
166
             * https://www.postgresql.org/docs/9.1/static/datatype.html
167
             * http://www.w3schools.com/sql/sql_datatypes.asp
168
             */
169
            type_boolean = "BOOLEAN";
170
            type_byte = "TINYINT";
171
            type_bytearray = "BYTEA";
172
            type_geometry = "TEXT";
173
            type_char = "CHARACTER(1)";
174
            type_date = "DATE";
175
            type_double = "DOUBLE PRECISION";
176
            type_numeric_p = "NUMERIC({0})";
177
            type_numeric_ps = "NUMERIC({0},{1})";
178
            type_bigdecimal = "NUMERIC({0},{1})";
179
            type_float = "REAL";
180
            type_int = "INT";
181
            type_long = "BIGINT";
182
            type_string = "TEXT";
183
            type_string_p = "VARCHAR({0})";
184
            type_time = "TIME";
185
            type_timestamp = "TIMESTAMP";
186
            type_version = "VARCHAR(30)";
187
            type_URI = "TEXT";
188
            type_URL = "TEXT";
189
            type_FILE = "TEXT";
190
            type_FOLDER = "TEXT";
191
            
192
            operator_AND = "{0} AND {1}";
193
            operator_OR = "{0} OR {1}";
194
            operator_EQ = "{0} = {1}";
195
            operator_NE = "{0} <> {1}";
196
            operator_GT = "{0} > {1}";
197
            operator_GE = "{0} >= {1}";
198
            operator_LT = "{0} < {1}";
199
            operator_LE = "{0} <= {1}";
200
            operator_LIKE = "{0} LIKE {1}";
201
            operator_ILIKE = "{0} ILIKE {1}";
202

    
203
            DELETE_FROM_table_WHERE_expresion = "DELETE FROM {0} WHERE {1}";
204
            DELETE_FROM_table = "DELETE FROM {0}";
205
            INSERT_INTO_table_columns_VALUES_values = "INSERT INTO {0} ( {1} ) VALUES ( {2} )";
206
            UPDATE_TABLE_STATISTICS_table = "VACUUM ANALYZE {0}";
207
            DROP_TABLE_table = "DROP TABLE {0}";
208
            DELETE_GEOMETRY_COLUMN_FROM_TABLE_schema_table = "DELETE FROM GEOMETRY_COLUMNS WHERE f_table_schema = {0} AND f_table_name = {1}";
209
            DELETE_GEOMETRY_COLUMN_FROM_TABLE_table = "DELETE FROM GEOMETRY_COLUMNS WHERE f_table_name = {0}";
210
            UPDATE_table_SET_columnsAndValues_WHERE_expresion = "UPDATE {0} SET {1} WHERE {2}";
211
            UPDATE_table_SET_columnsAndValues = "UPDATE {0} SET {1}";
212
            
213
        }
214
    }
215

    
216
    public class ParameterBase implements Parameter {
217

    
218
        protected int type;
219
        protected String name;
220
        protected IProjection crs;
221
        protected Object value;
222

    
223
        public ParameterBase(int type, String name, IProjection crs) {
224
            this.type = type;
225
            this.name = name;
226
            this.crs = crs;
227
            this.value = null;
228
        }
229

    
230
        public ParameterBase(Object value) {
231
            this.type = DataTypes.UNKNOWN;
232
            this.name = null;
233
            this.crs = null;
234
            this.value = value;
235
        }
236
        
237
        @Override
238
        public int getType() {
239
            return this.type;
240
        }
241
            
242
        @Override
243
        public String getName() {
244
            return this.name;
245
        }
246
        
247
        @Override
248
        public IProjection getCRS() {
249
            return this.crs;
250
        }
251

    
252
        @Override
253
        public boolean isConstant() {
254
            return this.name == null;
255
        }
256

    
257
        @Override
258
        public Object getValue() {
259
            return this.value;
260
        }
261
    }
262

    
263
    public class ParameterValue {
264
        
265
    }
266
    
267
    protected class ColumnInfo {
268

    
269
        public String name;
270
        public int type;
271
        public int type_p;
272
        public int type_s;
273
        public boolean isPk;
274
        public boolean allowNulls;
275
        public boolean isAutomatic;
276
        public Object defaultValue;
277

    
278
        public ColumnInfo(String name, int type, Object defaultValue) {
279
            this.name = name;
280
            this.type = type;
281
            this.type_p = -1;
282
            this.type_s = -1;
283
            this.isPk = false;
284
            this.allowNulls = true;
285
            this.isAutomatic = false;
286
            this.defaultValue = defaultValue;
287
        }
288

    
289
        public ColumnInfo(String name, int type, int type_p, int type_s, boolean isPk, boolean allowNulls, boolean isAutomatic, Object defaultValue) {
290
            this.name = name;
291
            this.type = type;
292
            this.type_p = type_p;
293
            this.type_s = type_s;
294
            this.isPk = isPk;
295
            this.allowNulls = allowNulls;
296
            this.isAutomatic = isAutomatic;
297
            this.defaultValue = defaultValue;
298
        }
299
    }
300

    
301
    public class OpBuilderBase implements OpBuilder {
302

    
303
        private String operador;
304
        private ExpBuilder op1;
305
        private ExpBuilder op2;
306

    
307
        public OpBuilderBase(String operador) {
308
            this.operador = operador;
309
        }
310

    
311
        public OpBuilderBase(String operador, String op1, String op2) {
312
            this.operador = operador;
313
            this.setop1(op1);
314
            this.setop2(op2);
315
        }
316

    
317
        @Override
318
        public OpBuilder setop1(String op) {
319
            this.op1 = createExpBuilder();
320
            this.op1.set(op);
321
            return this;
322
        }
323

    
324
        @Override
325
        public OpBuilder setop2(String op) {
326
            this.op2 = createExpBuilder();
327
            this.op2.set(op);
328
            return this;
329
        }
330

    
331
        protected OpBuilder add(String operator, ExpBuilder value) {
332
            if (this.op2 == null) {
333
                this.op2 = value;
334
                this.operador = operator;
335
                return this;
336
            }
337
            OpBuilderBase op = (OpBuilderBase) createOpBuilder(operator);
338
            op.op1 = this.op2;
339
            op.op2 = value;
340
            this.op2 = createExpresionBuilder(op);
341
            return this;
342
        }
343

    
344
        @Override
345
        public String toString() {
346
            if (this.op2 == null || this.op2.isEmpty() ) {
347
                return this.op1.toString();
348
            }
349
            return MessageFormat.format(this.operador, this.op1.toString(), this.op2.toString());
350
        }
351
    }
352

    
353
    public class ExpBuilderBase implements ExpBuilder {
354

    
355
        private String value;
356
        private OpBuilderBase op;
357

    
358
        public ExpBuilderBase() {
359
        }
360

    
361
        public ExpBuilderBase(String value) {
362
            this.value = value;
363
        }
364

    
365
        public ExpBuilderBase(OpBuilder op) {
366
            this.op = (OpBuilderBase) op;
367
        }
368

    
369
        @Override
370
        public boolean isEmpty() {
371
            return ( this.value == null && this.op == null );
372
        }
373
        
374
        @Override
375
        public ExpBuilder set(String value) {
376
            this.value = value;
377
            return this;
378
        }
379

    
380
        @Override
381
        public ExpBuilder set(OpBuilder op) {
382
            this.op = (OpBuilderBase) op;
383
            return this;
384
        }
385

    
386
        @Override
387
        public String toString() {
388
            if (this.value != null) {
389
                return this.value;
390
            }
391
            return this.op.toString();
392
        }
393

    
394
        protected ExpBuilder addOperator(String operator, String value) {
395
            if (this.op == null) {
396
                if (this.value == null) {
397
                    this.value = value;
398
                } else {
399
                    OpBuilderBase op = (OpBuilderBase) createOpBuilder(operator);
400
                    op.setop1(this.value);
401
                    op.setop2(value);
402
                    this.value = null;
403
                    this.op = op;
404
                }
405
            } else {
406
                this.op.add(operator, createExpresionBuilder(value));
407
            }
408
            return this;
409
        }
410

    
411
        @Override
412
        public ExpBuilder and(String value) {
413
            this.addOperator(config.operator_AND, value);
414
            return this;
415
        }
416

    
417
        @Override
418
        public ExpBuilder and(OpBuilder op) {
419
            this.addOperator(config.operator_AND, op.toString());
420
            return this;
421
        }
422

    
423
        @Override
424
        public ExpBuilder or(String value) {
425
            this.addOperator(config.operator_OR, value);
426
            return this;
427
        }
428

    
429
        @Override
430
        public ExpBuilder or(OpBuilder op) {
431
            this.addOperator(config.operator_OR, op.toString());
432
            return this;
433
        }
434
    }
435

    
436
    public class TableId {
437

    
438
        public String tableName;
439
        public String schemaName;
440
        private String dbName;
441

    
442
        public TableId(String dbName, String schemaName, String tableName) {
443
            this.dbName = dbName;
444
            this.tableName = tableName;
445
            this.schemaName = schemaName;
446
        }
447

    
448
        public TableId(String schemaName, String tableName) {
449
            this(null, schemaName, tableName);
450
        }
451

    
452
        public TableId(String tableName) {
453
            this(null, null, tableName);
454
        }
455

    
456
        public String getTableName() {
457
            return this.tableName;
458
        }
459

    
460
        public String getSchemaName() {
461
            return this.schemaName;
462
        }
463

    
464
        public boolean hasSchemaName() {
465
            return !StringUtils.isEmpty(this.schemaName);
466
        }
467

    
468
        public boolean hasDatabaseName() {
469
            return !StringUtils.isEmpty(this.dbName);
470
        }
471
        
472
        @Override
473
        public String toString() {
474
            if( this.hasDatabaseName() ) {
475
                if( this.hasSchemaName() ) {
476
                    return identifier(this.dbName) + "." + 
477
                           identifier(this.schemaName) + "." + 
478
                           identifier(this.tableName);
479
                }
480
            } else {
481
                if( this.hasSchemaName() ) {
482
                    return identifier(this.schemaName) + "." + 
483
                           identifier(this.tableName);
484
                }                
485
            }
486
            return identifier(this.tableName);
487
        }
488

    
489
    }
490

    
491
    public class FromBuilderBase implements FromBuilder {
492

    
493
        protected TableId tableName= null;
494
        private String subquery = null;
495
        private String passthrough = null;
496

    
497
        @Override
498
        public FromBuilder table(String dbName, String schemaName, String tableName) {
499
            this.tableName = new TableId(dbName, schemaName, tableName);
500
            return this;
501
        }
502

    
503
        @Override
504
        public FromBuilder table(String tableName) {
505
            this.tableName = new TableId(tableName);
506
            return this;
507
        }
508

    
509
        @Override
510
        public FromBuilder passThrough(String passthrough) {
511
            this.passthrough = passthrough;
512
            return this;
513
        }
514

    
515
        @Override
516
        public FromBuilder subquery(String subquery) {
517
            this.subquery = subquery;
518
            return this;
519
        }
520
        
521
        @Override
522
        public String toString() {
523
            if( ! StringUtils.isEmpty(passthrough) ) {
524
                return passthrough;
525
            }
526
            if( ! StringUtils.isEmpty(subquery) ) {
527
                return "( " + this.subquery + ") as _subquery_alias_ ";
528
            }
529
            return this.tableName.toString();
530
        }
531

    
532
    }
533

    
534
    public class ColumnBuilderBase implements ColumnBuilder {
535

    
536
        private String name = null;
537
        private String expression = null;
538
        private String alias = null;
539

    
540
        @Override
541
        public ColumnBuilder name(String name) {
542
            String quote = getQuoteForIdentifiers();
543
            if (name.startsWith(quote)) {
544
                // Remove quotes
545
                name = name.substring(1, name.length() - 1);
546
            }
547
            this.name = name;
548
            this.expression = null;
549
            return this;
550
        }
551
        
552
        @Override
553
        public ColumnBuilder expression(String value) {
554
            this.expression = value;
555
            this.name = null;
556
            return this;
557
        }
558

    
559
        @Override
560
        public ColumnBuilder geometry(String name) {
561
            if( config.has_spatial_functions ) {
562
                switch( geometry_support_type() ) {
563
                    case WKB:
564
                        this.expression = ST_AsBinary(name);
565
                        break;
566
                    case EWKB:
567
                        this.expression = ST_AsEWKB(name);
568
                        break;
569
                    case WKT:
570
                    default:
571
                        this.expression = ST_AsText(name);
572
                        break;
573
                }
574
                this.name = null;
575
            } else {
576
                this.name = name;
577
                this.expression = null;                
578
            }
579
            return this;
580
        }
581
        
582
        
583
        @Override
584
        public ColumnBuilder as(String alias) {
585
            this.alias = alias;
586
            return this;
587
        }
588

    
589
        @Override
590
        public String getName() {
591
            return this.name;
592
        }
593
        
594
        @Override
595
        public String getAlias() {
596
            return this.alias;
597
        }
598
        
599
        @Override
600
        public String getExpression() {
601
            return this.alias;
602
        }
603

    
604
        @Override
605
        public String toString() {
606
            StringBuilder builder = new StringBuilder();
607
            if( this.name != null ) {
608
                builder.append(identifier(this.name));
609
            } else {
610
                builder.append(this.expression);
611
            }
612
            if( this.alias != null ) {
613
                builder.append(" AS ");
614
                builder.append(identifier(this.alias));
615
            }
616
            return builder.toString();
617
        }
618
    }
619

    
620
    public class SelectBuilderBase implements SelectBuilder {
621

    
622
        protected FromBuilder from;
623
        protected ExpBuilder where;
624
        protected long limit = -1;
625
        protected long offset = -1;
626
        protected List<ColumnBuilder> columns;
627
        protected List<Pair<String,Boolean>> order_by;
628

    
629
        public SelectBuilderBase() {
630
            this.columns = new ArrayList<>();
631
        }
632

    
633
        @Override
634
        public ColumnBuilder column() {
635
            ColumnBuilder builder = createColumnBuilder();
636
            this.columns.add(builder);
637
            return builder;
638
        }
639

    
640
        @Override
641
        public boolean has_column(String name) {
642
            for (ColumnBuilder column : columns) {
643
                if( name.equals(column.getName()) ) {
644
                    return true;
645
                }
646
            }
647
            return false;
648
        }
649

    
650
        @Override
651
        public FromBuilder from() {
652
            if (this.from == null) {
653
                this.from = createFromBuilder();
654
            }
655
            return this.from;
656
        }
657

    
658
        @Override
659
        public FromBuilder from(String s) {
660
            return this.from().table(s);
661
        }
662
        
663
        @Override
664
        public ExpBuilder where() {
665
            if (this.where == null) {
666
                this.where = createExpBuilder();
667
            }
668
            return this.where;
669
        }
670
        
671
        @Override
672
        public ExpBuilder where(String s) {
673
            this.where = createExpBuilder();
674
            this.where.set(s);
675
            return this.where;
676
        }
677

    
678
        @Override
679
        public ExpBuilder where(OpBuilder s) {
680
            this.where = createExpBuilder();
681
            this.where.set(s);
682
            return this.where;
683
        }
684

    
685
        @Override
686
        public SelectBuilder limit(long limit) {
687
            this.limit = limit;
688
            return this;
689
        }
690

    
691
        @Override
692
        public SelectBuilder offset(long offset) {
693
            this.offset = offset;
694
            return this;
695
        }
696

    
697
        @Override
698
        public SelectBuilder add_order_by(String order) {
699
            this.order_by.add(new ImmutablePair(order,null));
700
            return this;
701
        }
702

    
703
        @Override
704
        public SelectBuilder add_order_by(String column, boolean ascending) {
705
            this.order_by.add(new ImmutablePair(column,ascending));
706
            return this;
707
        }
708

    
709
        @Override
710
        public boolean has_order_by() {
711
            if( this.order_by == null ) {
712
                return false;
713
            }
714
            return !this.order_by.isEmpty();
715
        }
716
        
717
        @Override
718
        public String toString() {
719
            StringBuilder builder = new StringBuilder();
720

    
721
            builder.append("SELECT ");
722
            boolean first = true;
723
            for (ColumnBuilder column : columns) {
724
                if (first) {
725
                    first = false;
726
                } else {
727
                    builder.append(", ");
728
                }
729
                builder.append(column.toString());
730
            }
731

    
732
            if (this.from != null) {
733
                builder.append(" FROM ");
734
                builder.append(this.from.toString());
735
            }
736
            if (this.where != null) {
737
                builder.append(" WHERE ");
738
                builder.append(this.where.toString());
739
            }
740
            
741
            if( this.has_order_by() ) {
742
                builder.append(" ORDER BY ");
743
                first = true;
744
                for (Pair<String,Boolean> item : this.order_by) {
745
                    if (first) {
746
                        first = false;
747
                    } else {
748
                        builder.append(", ");
749
                    }
750
                    builder.append(item.getLeft());                    
751
                    if( item.getRight()!=null ) {
752
                        // Si es null no a?adimos nada ya que puede habernos
753
                        // llegado ya un valor con el ASC o DESC incluido.
754
                        if( item.getRight() ) {
755
                            builder.append(" ASC");
756
                        } else {
757
                            builder.append(" DESC");
758
                        }
759
                    }
760
                }   
761
            }
762
            
763
            if (this.limit > 0) {
764
                builder.append(" LIMIT ");
765
                builder.append(this.limit);
766
            }
767
            if (this.offset > 0) {
768
                builder.append(" OFFSET ");
769
                builder.append(this.offset);
770
            }
771
            return builder.toString();
772

    
773
        }
774
    }
775

    
776
    public class DropTableBuilderBase implements DropTableBuilder {
777

    
778
        protected TableId table;
779

    
780
        @Override
781
        public DropTableBuilderBase table(String dbName, String schemaName, String tableName) {
782
            this.table = new TableId(dbName, schemaName, tableName);
783
            return this;
784
        }
785

    
786
        @Override
787
        public DropTableBuilderBase table(String tableName) {
788
            this.table = new TableId(tableName);
789
            return this;
790
        }
791

    
792
        @Override
793
        public String toString() {
794
            StringBuilder builder = new StringBuilder();
795
            boolean first = true;
796
            for (String sql : toStrings()) {
797
                if( StringUtils.isEmpty(sql) ) {
798
                    continue;
799
                }
800
                if (first) {
801
                    first = false;
802
                } else {
803
                    builder.append("; ");
804
                }
805
                builder.append(sql);
806
            }
807
            return builder.toString();
808
        }
809

    
810
        @Override
811
        public List<String> toStrings() {
812
            List<String> sqls = new ArrayList<>();
813

    
814
            sqls.add(
815
                    MessageFormat.format(
816
                            config.DROP_TABLE_table, 
817
                            this.table.toString()
818
                    )
819
            );
820
            String sql;
821
            if (this.table.hasSchemaName()) {
822
                sql = MessageFormat.format(
823
                        config.DELETE_GEOMETRY_COLUMN_FROM_TABLE_schema_table, 
824
                        identifier(this.table.getSchemaName()),
825
                        identifier(this.table.getTableName())
826
                );
827
            } else {
828
                sql = MessageFormat.format(
829
                        config.DELETE_GEOMETRY_COLUMN_FROM_TABLE_table, 
830
                        identifier(this.table.getTableName())
831
                );
832
            }
833
            if( !StringUtils.isEmpty(sql) ) {
834
                sqls.add(sql);
835
            }
836
            return sqls;
837
        }
838

    
839
    }
840

    
841
    public class GrantBuilderBase implements GrantBuilder {
842

    
843
        protected TableId table;
844
        protected Map<String, Set<Privilege>> privilegesByRole;
845

    
846
        @Override
847
        public GrantBuilderBase table(String dbName, String schemaName, String tableName) {
848
            this.table = new TableId(dbName, schemaName, tableName);
849
            return this;
850
        }
851

    
852
        @Override
853
        public GrantBuilderBase table(String tableName) {
854
            this.table = new TableId(tableName);
855
            return this;
856
        }
857

    
858
        @Override
859
        public GrantBuilder add(String roleid, Privilege privilege) {
860
            if (this.privilegesByRole.containsKey(roleid)) {
861
                this.privilegesByRole.get(roleid).add(privilege);
862
            } else {
863
                this.privilegesByRole.put(roleid, new HashSet<Privilege>());
864
                this.privilegesByRole.get(roleid).add(privilege);
865
            }
866
            return this;
867
        }
868

    
869
        @Override
870
        public GrantBuilder select(String roleid) {
871
            this.add(roleid, Privilege.SELECT);
872
            return this;
873
        }
874

    
875
        @Override
876
        public GrantBuilder insert(String roleid) {
877
            this.add(roleid, Privilege.INSERT);
878
            return this;
879
        }
880

    
881
        @Override
882
        public GrantBuilder delete(String roleid) {
883
            this.add(roleid, Privilege.DELETE);
884
            return this;
885
        }
886

    
887
        @Override
888
        public GrantBuilder truncate(String roleid) {
889
            this.add(roleid, Privilege.TRUNCATE);
890
            return this;
891
        }
892

    
893
        @Override
894
        public GrantBuilder reference(String roleid) {
895
            this.add(roleid, Privilege.REFERENCE);
896
            return this;
897
        }
898

    
899
        @Override
900
        public GrantBuilder trigger(String roleid) {
901
            this.add(roleid, Privilege.TRIGGER);
902
            return this;
903
        }
904

    
905
        @Override
906
        public GrantBuilder all(String roleid) {
907
            this.add(roleid, Privilege.ALL);
908
            return this;
909
        }
910

    
911
        @Override
912
        public GrantBuilder select() {
913
            this.add("PUBLIC", Privilege.SELECT);
914
            return this;
915
        }
916

    
917
        @Override
918
        public GrantBuilder insert() {
919
            this.add("PUBLIC", Privilege.INSERT);
920
            return this;
921
        }
922

    
923
        @Override
924
        public GrantBuilder delete() {
925
            this.add("PUBLIC", Privilege.DELETE);
926
            return this;
927
        }
928

    
929
        @Override
930
        public GrantBuilder truncate() {
931
            this.add("PUBLIC", Privilege.TRUNCATE);
932
            return this;
933
        }
934

    
935
        @Override
936
        public GrantBuilder reference() {
937
            this.add("PUBLIC", Privilege.REFERENCE);
938
            return this;
939
        }
940

    
941
        @Override
942
        public GrantBuilder trigger() {
943
            this.add("PUBLIC", Privilege.TRIGGER);
944
            return this;
945
        }
946

    
947
        @Override
948
        public GrantBuilder all() {
949
            this.add("PUBLIC", Privilege.ALL);
950
            return this;
951
        }
952

    
953
        @Override
954
        public String toString() {
955
            StringBuilder builder = new StringBuilder();
956
            boolean first = true;
957
            for (String sql : toStrings()) {
958
                if( StringUtils.isEmpty(sql) ) {
959
                    continue;
960
                }
961
                if (first) {
962
                    first = false;
963
                } else {
964
                    builder.append("; ");
965
                }
966
                builder.append(sql);
967
            }
968
            return builder.toString();
969
        }
970

    
971
        @Override
972
        public List<String> toStrings() {
973
            List<String> sqls = new ArrayList<>();
974
            if( this.privilegesByRole == null ) {
975
                return sqls;
976
            }
977
            Map<Privilege, String> privileges2SQL = new HashMap<>();
978
            privileges2SQL.put(Privilege.ALL, "ALL");
979
            privileges2SQL.put(Privilege.SELECT, "SELECT");
980
            privileges2SQL.put(Privilege.INSERT, "INSERT");
981
            privileges2SQL.put(Privilege.DELETE, "DELETE");
982
            privileges2SQL.put(Privilege.REFERENCE, "REFERENCE");
983
            privileges2SQL.put(Privilege.TRIGGER, "TRIGGER");
984
            privileges2SQL.put(Privilege.TRUNCATE, "TRUNCATE");
985
            privileges2SQL.put(Privilege.UPDATE, "UPDATE");
986

    
987
            for (String role : this.privilegesByRole.keySet()) {
988
                StringBuilder builder = new StringBuilder();
989
                builder.append("GRANT ");
990
                boolean first = true;
991
                for (Privilege privilege : this.privilegesByRole.get(role)) {
992
                    if (first) {
993
                        first = false;
994
                    } else {
995
                        builder.append(", ");
996
                    }
997
                    builder.append(privileges2SQL.get(privilege));
998
                }
999
                builder.append(" ON ");
1000
                builder.append(this.table);
1001
                builder.append(" TO ");
1002
                builder.append(role);
1003
                sqls.add(builder.toString());
1004
            }
1005
            return sqls;
1006
        }
1007
    }
1008

    
1009
    public class UpdateBuilderBase implements UpdateBuilder {
1010

    
1011
        protected ExpBuilder where;
1012
        protected List<Pair<String,String>> columns;
1013
        protected TableId table;
1014

    
1015
        public UpdateBuilderBase() {
1016
            this.columns = new ArrayList<>();
1017
        }
1018

    
1019
        @Override
1020
        public ExpBuilder where() {
1021
            if (this.where == null) {
1022
                this.where = createExpBuilder();
1023
            }
1024
            return this.where;
1025
        }
1026

    
1027
        @Override
1028
        public UpdateBuilder table(String dbName, String schemaName, String tableName) {
1029
            this.table = new TableId(dbName, schemaName, tableName);
1030
            return this;
1031
        }
1032

    
1033
        @Override
1034
        public UpdateBuilder table(String tableName) {
1035
            this.table = new TableId(tableName);
1036
            return this;
1037
        }
1038

    
1039
        @Override
1040
        public UpdateBuilder set(String columnName, String value) {
1041
            Pair<String,String> pair = new ImmutablePair<>(columnName, value);
1042
            this.columns.add(pair);
1043
            return this;
1044
        }
1045

    
1046
        @Override
1047
        public UpdateBuilder setGeometry(String columnName, String value, IProjection crs) {
1048
            String g;
1049
            switch( geometry_support_type() ) {
1050
                case WKB:
1051
                    g = ST_GeomFromWKB(value, crs(crs));
1052
                    break;
1053
                case EWKB:
1054
                    g = ST_GeomFromEWKB(value, crs(crs));
1055
                    break;
1056
                case WKT:
1057
                default:
1058
                    g = ST_GeomFromText(value, crs(crs));
1059
                    break;
1060
            }
1061
            this.set(identifier(columnName),g);
1062
            return this;
1063
        }
1064

    
1065
        @Override
1066
        public boolean hasWhere() {
1067
            return this.where != null;
1068
        }
1069

    
1070
        @Override
1071
        public String toString() {
1072
            /*
1073
             * UPDATE [ ONLY ] table [ [ AS ] alias ] SET { column = { expression |
1074
             * DEFAULT } | ( column [, ...] ) = ( { expression | DEFAULT } [, ...] )
1075
             * } [, ...] [ FROM fromlist ] [ WHERE condition ] [ RETURNING * |
1076
             * output_expression [ AS output_name ] [, ...] ]
1077
             */
1078
            StringBuilder columnsAndValues = new StringBuilder();
1079

    
1080
            boolean first = true;
1081
            for (Pair<String,String> column : columns) {
1082
                if (first) {
1083
                    first = false;
1084
                } else {
1085
                    columnsAndValues.append(", ");
1086
                }
1087
                columnsAndValues.append(identifier(column.getLeft()));
1088
                columnsAndValues.append(" = ");
1089
                columnsAndValues.append(column.getRight());
1090
            }
1091
            
1092
            String sql;
1093
            if (this.where == null || this.where.isEmpty() ) {
1094
                sql = MessageFormat.format(
1095
                        config.UPDATE_table_SET_columnsAndValues,
1096
                        this.table.toString(),
1097
                        columnsAndValues.toString()
1098
                );
1099
            } else {
1100
                sql = MessageFormat.format(
1101
                        config.UPDATE_table_SET_columnsAndValues_WHERE_expresion,
1102
                        this.table.toString(),
1103
                        columnsAndValues.toString(),
1104
                        this.where.toString()
1105
                );
1106
            }
1107
            return sql;
1108

    
1109
        }
1110
    }
1111

    
1112
    public class DeleteBuilderBase implements DeleteBuilder {
1113

    
1114
        protected ExpBuilder where;
1115
        protected TableId table;
1116

    
1117
        public DeleteBuilderBase() {
1118
        }
1119

    
1120
        @Override
1121
        public ExpBuilder where() {
1122
            if (this.where == null) {
1123
                this.where = createExpBuilder();
1124
            }
1125
            return this.where;
1126
        }
1127

    
1128
        @Override
1129
        public DeleteBuilder table(String dbName, String schemaName, String tableName) {
1130
            this.table = new TableId(dbName, schemaName, tableName);
1131
            return this;
1132
        }
1133

    
1134
        @Override
1135
        public DeleteBuilder table(String tableName) {
1136
            this.table = new TableId(tableName);
1137
            return this;
1138
        }
1139

    
1140
        @Override
1141
        public boolean hasWhere() {
1142
            return this.where != null;
1143
        }
1144

    
1145
        @Override
1146
        public String toString() {
1147
            /*
1148
             * DELETE FROM table_name
1149
             * WHERE some_column=some_value; 
1150
             */
1151
            String sql;
1152
            if( this.hasWhere() ) {
1153
                sql = MessageFormat.format(
1154
                        config.DELETE_FROM_table_WHERE_expresion,
1155
                        this.table.toString(),
1156
                        this.where.toString()
1157
                );
1158
            } else {
1159
                sql = MessageFormat.format(
1160
                        config.DELETE_FROM_table,
1161
                        this.table.toString()
1162
                );
1163
            }
1164
            return sql;
1165
        }
1166
    }
1167

    
1168
    public class AlterTableBuilderBase implements AlterTableBuilder {
1169

    
1170
        protected TableId table;
1171
        protected List<String> drops;
1172
        protected List<ColumnInfo> adds;
1173
        protected List<ColumnInfo> alters;
1174
        protected List<Pair> renames;
1175

    
1176
        public AlterTableBuilderBase() {
1177
            this.drops = new ArrayList<>();
1178
            this.adds = new ArrayList<>();
1179
            this.alters = new ArrayList<>();
1180
            this.renames = new ArrayList<>();
1181
        }
1182

    
1183
        @Override
1184
        public AlterTableBuilder table(String dbName, String schemaName, String tableName) {
1185
            this.table = new TableId(dbName, schemaName, tableName);
1186
            return this;
1187
        }
1188

    
1189
        @Override
1190
        public AlterTableBuilder table(String tableName) {
1191
            this.table = new TableId(tableName);
1192
            return this;
1193
        }
1194

    
1195
        @Override
1196
        public AlterTableBuilder drop_column(String columnName) {
1197
            this.drops.add(columnName);
1198
            return this;
1199
        }
1200

    
1201
        @Override
1202
        public AlterTableBuilder add_column(String columnName, int type, int type_p, int type_s, boolean isPk, boolean allowNulls, boolean isAutomatic, Object defaultValue) {
1203
            if (isPk || isAutomatic) {
1204
                allowNulls = false;
1205
            }
1206
            this.adds.add(new ColumnInfo(columnName, type, type_p, type_s, isPk, allowNulls, isAutomatic, defaultValue));
1207
            return this;
1208
        }
1209

    
1210
        @Override
1211
        public AlterTableBuilder alter_column(String columnName, int type, int type_p, int type_s, boolean isPk, boolean allowNulls, boolean isAutomatic, Object defaultValue) {
1212
            if (isPk || isAutomatic) {
1213
                allowNulls = false;
1214
            }
1215
            this.alters.add(new ColumnInfo(columnName, type, type_p, type_s, isPk, allowNulls, isAutomatic, defaultValue));
1216
            return this;
1217
        }
1218

    
1219
        @Override
1220
        public AlterTableBuilder rename_column(String source, String target) {
1221
            this.renames.add(new ImmutablePair(source, target));
1222
            return this;
1223
        }
1224

    
1225
        @Override
1226
        public String toString() {
1227
            StringBuilder builder = new StringBuilder();
1228
            boolean first = true;
1229
            for (String sql : toStrings()) {
1230
                if( StringUtils.isEmpty(sql) ) {
1231
                    continue;
1232
                }
1233
                if (first) {
1234
                    first = false;
1235
                } else {
1236
                    builder.append("; ");
1237
                }
1238
                builder.append(sql);
1239
            }
1240
            return builder.toString();
1241
        }
1242

    
1243
        @Override
1244
        public List<String> toStrings() {
1245
            List<String> sqls = new ArrayList<>();
1246
            /*
1247
             ALTER TABLE [ ONLY ] name [ * ]
1248
             action [, ... ]
1249
             ALTER TABLE [ ONLY ] name [ * ]
1250
             RENAME [ COLUMN ] column TO new_column
1251
             ALTER TABLE name
1252
             RENAME TO new_name
1253
             ALTER TABLE name
1254
             SET SCHEMA new_schema
1255

1256
             where action is one of:
1257

1258
             ADD [ COLUMN ] column data_type [ COLLATE collation ] [ column_constraint [ ... ] ]
1259
             DROP [ COLUMN ] [ IF EXISTS ] column [ RESTRICT | CASCADE ]
1260
             ALTER [ COLUMN ] column [ SET DATA ] TYPE data_type [ COLLATE collation ] [ USING expression ]
1261
             ALTER [ COLUMN ] column SET DEFAULT expression
1262
             ALTER [ COLUMN ] column DROP DEFAULT
1263
             ALTER [ COLUMN ] column { SET | DROP } NOT NULL
1264
             ALTER [ COLUMN ] column SET STATISTICS integer
1265
             ALTER [ COLUMN ] column SET ( attribute_option = value [, ... ] )
1266
             ALTER [ COLUMN ] column RESET ( attribute_option [, ... ] )
1267
             ALTER [ COLUMN ] column SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }
1268
             ADD table_constraint [ NOT VALID ]
1269
             ADD table_constraint_using_index
1270
             VALIDATE CONSTRAINT constraint_name
1271
             DROP CONSTRAINT [ IF EXISTS ]  constraint_name [ RESTRICT | CASCADE ]
1272
             DISABLE TRIGGER [ trigger_name | ALL | USER ]
1273
             ENABLE TRIGGER [ trigger_name | ALL | USER ]
1274
             ENABLE REPLICA TRIGGER trigger_name
1275
             ENABLE ALWAYS TRIGGER trigger_name
1276
             DISABLE RULE rewrite_rule_name
1277
             ENABLE RULE rewrite_rule_name
1278
             ENABLE REPLICA RULE rewrite_rule_name
1279
             ENABLE ALWAYS RULE rewrite_rule_name
1280
             CLUSTER ON index_name
1281
             SET WITHOUT CLUSTER
1282
             SET WITH OIDS
1283
             SET WITHOUT OIDS
1284
             SET ( storage_parameter = value [, ... ] )
1285
             RESET ( storage_parameter [, ... ] )
1286
             INHERIT parent_table
1287
             NO INHERIT parent_table
1288
             OF type_name
1289
             NOT OF
1290
             OWNER TO new_owner
1291
             SET TABLESPACE new_tablespace
1292

1293
             and table_constraint_using_index is:
1294

1295
             [ CONSTRAINT constraint_name ]
1296
             { UNIQUE | PRIMARY KEY } USING INDEX index_name
1297
             [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
1298

1299
             */
1300
            StringBuilder builder = new StringBuilder();
1301

    
1302
            builder.append("ALTER TABLE");
1303
            builder.append(this.table);
1304
            builder.append(" ");
1305
            boolean first = true;
1306
            for (String column : drops) {
1307
                if (first) {
1308
                    first = false;
1309
                } else {
1310
                    builder.append(", ");
1311
                }
1312
                builder.append("DROP COLUMN IF EXISTS ");
1313
                builder.append(column);
1314
            }
1315
            first = drops.isEmpty();
1316
            for (ColumnInfo column : adds) {
1317
                if (first) {
1318
                    first = false;
1319
                } else {
1320
                    builder.append(", ");
1321
                }
1322
                builder.append("ADD COLUMN ");
1323
                builder.append(column.name);
1324
                builder.append(" ");
1325
                if( column.type == DataTypes.INT && column.isAutomatic ) {
1326
                    builder.append(" SERIAL");
1327
                } else {
1328
                    builder.append(sqltype(column.type, column.type_p, column.type_s));
1329
                }
1330
                if (column.defaultValue == null) {
1331
                    if (column.allowNulls) {
1332
                        builder.append(" DEFAULT NULL");
1333
                    }
1334
                } else {
1335
                    builder.append(" DEFAULT '");
1336
                    builder.append(column.defaultValue.toString());
1337
                    builder.append("'");
1338
                }
1339
                if (column.allowNulls) {
1340
                    builder.append(" NULL");
1341
                } else {
1342
                    builder.append(" NOT NULL");
1343
                }
1344
                if (column.isPk) {
1345
                    builder.append(" PRIMARY KEY");
1346
                }
1347
            }
1348
            first = drops.isEmpty() && adds.isEmpty();
1349
            for (ColumnInfo column : alters) {
1350
                if (first) {
1351
                    first = false;
1352
                } else {
1353
                    builder.append(", ");
1354
                }
1355
                builder.append("ALTER COLUMN ");
1356
                builder.append(column.name);
1357
                builder.append("SET DATA TYPE ");
1358
                if( column.type == DataTypes.INT && column.isAutomatic ) {
1359
                    builder.append(" SERIAL");
1360
                } else {
1361
                    builder.append(sqltype(column.type, column.type_p, column.type_s));
1362
                }
1363
                builder.append(", ");
1364
                if (column.defaultValue == null) {
1365
                    if (column.allowNulls) {
1366
                        builder.append("ALTER COLUMN ");
1367
                        builder.append(column.name);
1368
                        builder.append(" SET DEFAULT NULL");
1369
                    } else {
1370
                        builder.append("ALTER COLUMN ");
1371
                        builder.append(column.name);
1372
                        builder.append(" DROP DEFAULT");
1373
                    }
1374
                } else {
1375
                    builder.append("ALTER COLUMN ");
1376
                    builder.append(column.name);
1377
                    builder.append(" SET DEFAULT '");
1378
                    builder.append(column.defaultValue.toString());
1379
                    builder.append("'");
1380
                }
1381
            }
1382
            first = drops.isEmpty() && adds.isEmpty() && alters.isEmpty();
1383
            for (Pair pair : renames) {
1384
                if (first) {
1385
                    first = false;
1386
                } else {
1387
                    builder.append(", ");
1388
                }
1389
                builder.append("RENAME COLUMN ");
1390
                builder.append(pair.getLeft());
1391
                builder.append(" TO ");
1392
                builder.append(pair.getRight());
1393
            }
1394
            sqls.add(builder.toString());
1395

    
1396
            return sqls;
1397
        }
1398

    
1399
    }
1400

    
1401
    public class CreateTableBuilderBase implements CreateTableBuilder {
1402

    
1403
        protected TableId table;
1404
        protected List<ColumnInfo> columns;
1405

    
1406
        public CreateTableBuilderBase() {
1407
            this.columns = new ArrayList<>();
1408
        }
1409

    
1410
        @Override
1411
        public CreateTableBuilder table(String dbName, String schemaName, String tableName) {
1412
            this.table = new TableId(dbName, schemaName, tableName);
1413
            return this;
1414
        }
1415

    
1416
        @Override
1417
        public CreateTableBuilder table(String tableName) {
1418
            this.table = new TableId(tableName);
1419
            return this;
1420
        }
1421

    
1422
        @Override
1423
        public CreateTableBuilderBase add_column(String columnName, int type, int type_p, int type_s, boolean isPk, boolean allowNulls, boolean isAutomatic, Object defaultValue) {
1424
            if (isPk || isAutomatic) {
1425
                allowNulls = false;
1426
            }
1427
            this.columns.add(new ColumnInfo(columnName, type, type_p, type_s, isPk, allowNulls, isAutomatic, defaultValue));
1428
            return this;
1429
        }
1430

    
1431
        @Override
1432
        public String toString() {
1433
            StringBuilder builder = new StringBuilder();
1434
            boolean first = true;
1435
            for (String sql : toStrings()) {
1436
                if( StringUtils.isEmpty(sql) ) {
1437
                    continue;
1438
                }
1439
                if (first) {
1440
                    first = false;
1441
                } else {
1442
                    builder.append("; ");
1443
                }
1444
                builder.append(sql);
1445
            }
1446
            return builder.toString();
1447
        }
1448

    
1449
        @Override
1450
        public List<String> toStrings() {
1451
            List<String> sqls = new ArrayList<>();
1452
            /**
1453
             * CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE
1454
             * table_name ( { column_name data_type [ DEFAULT default_expr ] [
1455
             * column_constraint [ ... ] ] | table_constraint | LIKE
1456
             * parent_table [ { INCLUDING | EXCLUDING } DEFAULTS ] } [, ... ] )
1457
             * [ INHERITS ( parent_table [, ... ] ) ] [ WITH OIDS | WITHOUT OIDS
1458
             * ] [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
1459
             *
1460
             * where column_constraint is:
1461
             *
1462
             * [ CONSTRAINT constraint_name ] { NOT NULL | NULL | UNIQUE |
1463
             * PRIMARY KEY | CHECK (expression) | REFERENCES reftable [ (
1464
             * refcolumn ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON
1465
             * DELETE action ] [ ON UPDATE action ] } [ DEFERRABLE | NOT
1466
             * DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
1467
             *
1468
             * and table_constraint is:
1469
             *
1470
             * [ CONSTRAINT constraint_name ] { UNIQUE ( column_name [, ... ] )
1471
             * | PRIMARY KEY ( column_name [, ... ] ) | CHECK ( expression ) |
1472
             * FOREIGN KEY ( column_name [, ... ] ) REFERENCES reftable [ (
1473
             * refcolumn [, ... ] ) ] [ MATCH FULL | MATCH PARTIAL | MATCH
1474
             * SIMPLE ] [ ON DELETE action ] [ ON UPDATE action ] } [ DEFERRABLE
1475
             * | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
1476
             */
1477
            StringBuilder builder = new StringBuilder();
1478

    
1479
            builder.append("CREATE TABLE ");
1480
            builder.append(this.table.toString());
1481
            builder.append(" (");
1482
            boolean first = true;
1483
            for (ColumnInfo column : columns) {
1484
                if (first) {
1485
                    first = false;
1486
                } else {
1487
                    builder.append(", ");
1488
                }
1489
                builder.append(identifier(column.name));
1490
                builder.append(" ");
1491
                if( column.isAutomatic && column.type == DataTypes.INT ) {
1492
                    builder.append("SERIAL");
1493
                } else if( column.isAutomatic && column.type == DataTypes.LONG ) {
1494
                    builder.append("BIGSERIAL");
1495
                } else {
1496
                    builder.append(sqltype(column.type, column.type_p, column.type_s));
1497
                }
1498
                if (column.defaultValue == null) {
1499
                    if (column.allowNulls) {
1500
                        builder.append(" DEFAULT NULL");
1501
                    }
1502
                } else {
1503
                    builder.append(" DEFAULT '");
1504
                    builder.append(column.defaultValue.toString());
1505
                    builder.append("'");
1506
                }
1507
                if (column.allowNulls) {
1508
                    builder.append(" NULL");
1509
                } else {
1510
                    builder.append(" NOT NULL");
1511
                }
1512
                if (column.isPk) {
1513
                    builder.append(" PRIMARY KEY");
1514
                }
1515
            }
1516
            builder.append(" )");
1517
            sqls.add(builder.toString());
1518

    
1519
            return sqls;
1520
        }
1521
    }
1522

    
1523
    public class InsertBuilderBase implements InsertBuilder {
1524

    
1525
        protected List<Pair<String,String>> columns;
1526
        protected TableId table;
1527

    
1528
        public InsertBuilderBase() {
1529
            this.columns = new ArrayList<>();
1530
        }
1531

    
1532
        @Override
1533
        public InsertBuilder table(String dbName, String schemaName, String tableName) {
1534
            this.table = new TableId(dbName, schemaName, tableName);
1535
            return this;
1536
        }
1537

    
1538
        @Override
1539
        public InsertBuilder table(String tableName) {
1540
            this.table = new TableId(tableName);
1541
            return this;
1542
        }
1543

    
1544
        @Override
1545
        public InsertBuilder set(String columnName, String value) {
1546
            Pair<String,String> pair = new ImmutablePair<>(columnName, value);
1547
            this.columns.add(pair);
1548
            return this;
1549
        }
1550

    
1551
        @Override
1552
        public InsertBuilder setGeometry(String columnName, String value, IProjection crs) {
1553
            String g;
1554
            switch( geometry_support_type() ) {
1555
                case WKB:
1556
                    g = ST_GeomFromWKB(value, crs(crs));
1557
                    break;
1558
                case EWKB:
1559
                    g = ST_GeomFromEWKB(value, crs(crs));
1560
                    break;
1561
                case WKT:
1562
                default:
1563
                    g = ST_GeomFromText(value, crs(crs));
1564
                    break;
1565
            }
1566
            this.set(identifier(columnName),g);
1567
            return this;
1568
        }
1569

    
1570
        @Override
1571
        public String toString() {
1572
            /*
1573
             * INSERT INTO table [ ( column [, ...] ) ] { DEFAULT VALUES | VALUES (
1574
             * { expression | DEFAULT } [, ...] ) [, ...] | query } [ RETURNING * |
1575
             * output_expression [ AS output_name ] [, ...] ]
1576
             */
1577
            StringBuilder builderColumns = new StringBuilder();
1578
            StringBuilder builderValues = new StringBuilder();
1579
            
1580
            boolean first = true;
1581
            for (Pair<String,String> column : columns) {
1582
                if (first) {
1583
                    first = false;
1584
                } else {
1585
                    builderColumns.append(", ");
1586
                }
1587
                builderColumns.append(identifier(column.getLeft()));
1588
            }
1589
            first = true;
1590
            for (Pair column : columns) {
1591
                if (first) {
1592
                    first = false;
1593
                } else {
1594
                    builderValues.append(", ");
1595
                }
1596
                builderValues.append(column.getRight());
1597
            }
1598
            
1599
            String sql = MessageFormat.format(
1600
                    config.INSERT_INTO_table_columns_VALUES_values,
1601
                    this.table.toString(),
1602
                    builderColumns,
1603
                    builderValues
1604
            );
1605
            return sql;
1606

    
1607
        }
1608
    }
1609

    
1610
    public class UpdateTableStatisticsBuilderBase implements UpdateTableStatisticsBuilder {
1611

    
1612
        protected TableId table;
1613

    
1614
        @Override
1615
        public UpdateTableStatisticsBuilderBase table(String dbName, String schemaName, String tableName) {
1616
            this.table = new TableId(dbName, schemaName, tableName);
1617
            return this;
1618
        }
1619

    
1620
        @Override
1621
        public UpdateTableStatisticsBuilderBase table(String tableName) {
1622
            this.table = new TableId(tableName);
1623
            return this;
1624
        }
1625
        @Override
1626
        public String toString() {
1627
            StringBuilder builder = new StringBuilder();
1628
            boolean first = true;
1629
            for (String sql : toStrings()) {
1630
                if( StringUtils.isEmpty(sql) ) {
1631
                    continue;
1632
                }
1633
                if (first) {
1634
                    first = false;
1635
                } else {
1636
                    builder.append("; ");
1637
                }
1638
                builder.append(sql);
1639
            }
1640
            return builder.toString();
1641
        }
1642

    
1643
        @Override
1644
        public List<String> toStrings() {
1645
            List<String> sqls = new ArrayList<>();
1646
            
1647
            String sql = MessageFormat.format(
1648
                    config.UPDATE_TABLE_STATISTICS_table,
1649
                    identifier(table.toString())
1650
                );
1651
            if( !StringUtils.isEmpty(sql) ) {
1652
                sqls.add(sql);
1653
            }
1654
            return sqls;
1655
        }
1656
    }
1657
    
1658
    public SQLBuilderBase_save() {
1659
        parameters = new ArrayList<>();
1660
        config = this.createConfig();
1661
    }
1662

    
1663
    @Override
1664
    public boolean has_spatial_functions() {
1665
        return config.has_spatial_functions;
1666
    }
1667
    
1668
    @Override
1669
    public String ST_AsText(String geom) {
1670
        return MessageFormat.format(config.ST_AsText,geom.trim());
1671
    }
1672

    
1673
    @Override
1674
    public String ST_AsBinary(String geom) {
1675
        return MessageFormat.format(config.ST_AsBinary,geom.trim());
1676
    }
1677

    
1678
    @Override
1679
    public String ST_AsEWKB(String geom) {
1680
        return MessageFormat.format(config.ST_AsEWKB,geom.trim());
1681
    }
1682

    
1683
    @Override
1684
    public String ST_ExtentAggregate(String geom) {
1685
        return MessageFormat.format(config.ST_ExtentAggregate,geom.trim());
1686
    }
1687

    
1688
    @Override
1689
    public String ST_UnionAggregate(String geom) {
1690
        return MessageFormat.format(config.ST_UnionAggregate,geom.trim());
1691
    }
1692

    
1693
    @Override
1694
    public String ST_Envelope(String geom) {
1695
        return MessageFormat.format(config.ST_Envelope,geom.trim());
1696
    }
1697

    
1698
    @Override
1699
    public String ST_Intersects(String geom1, String geom2) {
1700
        if( config.has_spatial_functions ) {
1701
            return MessageFormat.format(config.ST_Intersects,geom1.trim(), geom2.trim());
1702
        }
1703
        return config.sql_true;
1704
    }
1705

    
1706
    @Override
1707
    public String ST_Contains(String geom1, String geom2) {
1708
        if( config.has_spatial_functions ) {
1709
            return MessageFormat.format(config.ST_Contains,geom1.trim(), geom2.trim());
1710
        }
1711
        return config.sql_true;
1712
    }
1713

    
1714
    @Override
1715
    public String ST_Crosses(String geom1, String geom2) {
1716
        if( config.has_spatial_functions ) {
1717
            return MessageFormat.format(config.ST_Crosses,geom1.trim(), geom2.trim());
1718
        }
1719
        return config.sql_true;
1720
    }
1721

    
1722
    @Override
1723
    public String ST_IsClosed(String geom1, String geom2) {
1724
        if( config.has_spatial_functions ) {
1725
            return MessageFormat.format(config.ST_IsClosed,geom1.trim(), geom2.trim());
1726
        }
1727
        return config.sql_true;
1728
    }
1729

    
1730
    @Override
1731
    public String ST_Overlaps(String geom1, String geom2) {
1732
        if( config.has_spatial_functions ) {
1733
            return MessageFormat.format(config.ST_Overlaps,geom1.trim(), geom2.trim());
1734
        }
1735
        return config.sql_true;
1736
    }
1737

    
1738
    @Override
1739
    public String ST_Touches(String geom1, String geom2) {
1740
        if( config.has_spatial_functions ) {
1741
            return MessageFormat.format(config.ST_Touches,geom1.trim(), geom2.trim());
1742
        }
1743
        return config.sql_true;
1744
    }
1745

    
1746
    @Override
1747
    public String ST_Within(String geom1, String geom2) {
1748
        if( config.has_spatial_functions ) {
1749
            return MessageFormat.format(config.ST_Within,geom1.trim(), geom2.trim());
1750
        }
1751
        return config.sql_true;
1752
    }
1753

    
1754
    @Override
1755
    public String ST_GeomFromText(String geom, String crs) {
1756
        return MessageFormat.format(config.ST_GeomFromText,geom.trim(), crs.trim());
1757
    }
1758

    
1759
    @Override
1760
    public String ST_GeomFromWKB(String geom, String crs) {
1761
        return MessageFormat.format(config.ST_GeomFromWKB,geom.trim(), crs.trim());
1762
    }
1763
    
1764
    @Override
1765
    public String ST_GeomFromEWKB(String geom, String crs) {
1766
        return MessageFormat.format(config.ST_GeomFromEWKB,geom.trim(), crs.trim());
1767
    }
1768

    
1769
    @Override
1770
    public String lcase(String s) {
1771
        return MessageFormat.format(config.lcase, s);
1772
    }
1773
    
1774
    @Override
1775
    public String ucase(String s) {
1776
        return MessageFormat.format(config.ucase, s);
1777
    }
1778

    
1779
    @Override
1780
    public String count(String column) {
1781
        if( StringUtils.isEmpty(column) ) { 
1782
            return MessageFormat.format(config.count, "*");
1783
        }
1784
        if( "*".equals(column)) {
1785
            return MessageFormat.format(config.count, "*");
1786
        }
1787
        return MessageFormat.format(config.count, identifier(column));
1788
    }
1789
    
1790
    @Override
1791
    public String isNull(String s) {
1792
        return MessageFormat.format(config.isNull, s);
1793
    }
1794
    
1795
    @Override
1796
    public String default_schema() {
1797
        return config.default_schema;
1798
    }
1799
    
1800
    protected String getQuoteForIdentifiers() {
1801
        return config.quote_for_identifiers;
1802
    }
1803

    
1804
    protected String getQuoteForStrings() {
1805
        return config.quote_for_strings;
1806
    }
1807

    
1808
    protected boolean allowAutomaticValues() {
1809
        return config.allowAutomaticValues;
1810
    }
1811
    
1812
    @Override
1813
    public GeometrySupportType geometry_support_type() {
1814
        return config.geometry_type_support;
1815
    }
1816

    
1817
    @Override
1818
    public String sqltype(int type, int p, int s) {
1819
        switch (type) {
1820
            case DataTypes.BOOLEAN:
1821
                return config.type_boolean;
1822
            case DataTypes.BYTE:
1823
                return config.type_byte;
1824
            case DataTypes.BYTEARRAY:
1825
                return config.type_bytearray;
1826
            case DataTypes.GEOMETRY:
1827
                return config.type_geometry;
1828
            case DataTypes.CHAR:
1829
                return config.type_char;
1830
            case DataTypes.DATE:
1831
                return config.type_date;
1832
            case DataTypes.DOUBLE:
1833
                if (p > 1) {
1834
                    if (s < 0) {
1835
                        return MessageFormat.format(config.type_numeric_p, p);
1836
                    }
1837
                    return MessageFormat.format(config.type_numeric_ps, p,s);
1838
                }
1839
                return MessageFormat.format(config.type_double,p,s);
1840
            case DataTypes.BIGDECIMAL:
1841
                if (p < 1) {
1842
                    p = 20;
1843
                }
1844
                if (s < 0) {
1845
                    s = 10;
1846
                }
1847
                return MessageFormat.format(config.type_bigdecimal, p,s);
1848
            case DataTypes.FLOAT:
1849
                return MessageFormat.format(config.type_float, p,s);
1850
            case DataTypes.INT:
1851
                return MessageFormat.format(config.type_int, p,s);
1852
            case DataTypes.LONG:
1853
                return MessageFormat.format(config.type_long, p,s);
1854
            case DataTypes.STRING:
1855
                if (p < 0) {
1856
                    return config.type_string;
1857
                } else if (p < 4096) {
1858
                    return MessageFormat.format(config.type_string_p,p);
1859
                }
1860
                return config.type_string;
1861
            case DataTypes.TIME:
1862
                return config.type_time;
1863
            case DataTypes.TIMESTAMP:
1864
                return config.type_timestamp;
1865
            case DataTypes.VERSION:
1866
                return config.type_version;
1867
            case DataTypes.URI:
1868
                return config.type_URI;
1869
            case DataTypes.URL:
1870
                return config.type_URL;
1871
            case DataTypes.FILE:
1872
                return config.type_FILE;
1873
            case DataTypes.FOLDER:
1874
                return config.type_FOLDER;
1875
            default:
1876
                return null;
1877
        }
1878
    }
1879

    
1880
    public SQLBuilderConfig getConfig() {
1881
        return this.config;
1882
    }
1883
    
1884
    @Override
1885
    public String crs(IProjection crs) {
1886
        return getQuoteForStrings() + crs.getAbrev() + getQuoteForStrings();
1887
    }
1888

    
1889
    @Override
1890
    public String crs(String crs) {
1891
        String quote = this.getQuoteForStrings();
1892
        if (crs.startsWith(quote)) {
1893
            return crs;
1894
        }
1895
        return getQuoteForStrings() + crs + getQuoteForStrings();
1896
    }
1897

    
1898
    @Override
1899
    public String geometry(Geometry geom, IProjection crs) {
1900
        if( config.has_spatial_functions ) {
1901
            switch(geometry_support_type()) {
1902
                case WKB:
1903
                    return ST_GeomFromWKB(geom, crs);
1904
                case EWKB:
1905
                    return ST_GeomFromEWKB(geom, crs);
1906
                case WKT:
1907
                default:
1908
                    return ST_GeomFromText(geom, crs);
1909
            }
1910
        } else {
1911
            return string(getWKT(geom));
1912
        }
1913
    }
1914

    
1915
    @Override
1916
    public String geometry(Envelope env, IProjection crs) {
1917
        return geometry(env.getGeometry(), crs);
1918
    }
1919

    
1920
    @Override
1921
    public String string(String s) {
1922
        String quote = this.getQuoteForStrings();
1923
        if (s.startsWith(quote)) {
1924
            return s;
1925
        }
1926
        return quote + s + quote;
1927
    }
1928

    
1929
    @Override
1930
    public String identifier(String id) {
1931
        String quote = this.getQuoteForIdentifiers();
1932
        if (id.startsWith(quote)) {
1933
            return id;
1934
        }
1935
        return quote + id + quote;
1936
    }
1937

    
1938
    @Override
1939
    public String bytearray(byte[] data) {
1940
        StringBuilder builder = new StringBuilder();
1941
        builder.append("0x");
1942
        for (byte abyte : data) {
1943
            int v = abyte & 0xff;
1944
            builder.append(String.format("%02x", v));
1945
        }
1946
        return builder.toString();
1947
    }
1948

    
1949
    @Override
1950
    public String ST_GeomFromText(String geom, int crs) {
1951
        return ST_GeomFromText(geom, Integer.toString(crs));
1952
    }
1953

    
1954
    @Override
1955
    public String ST_GeomFromText(Geometry geom, IProjection crs) {
1956
        return this.ST_GeomFromText(string(getWKT(geom)), crs(crs));
1957
    }
1958

    
1959
    @Override
1960
    public String ST_GeomFromWKB(Geometry geom, IProjection crs) {
1961
        return this.ST_GeomFromWKB(bytearray(getWKB(geom)), crs(crs));
1962
    }
1963

    
1964
    @Override
1965
    public String ST_GeomFromEWKB(Geometry geom, IProjection crs) {
1966
        return this.ST_GeomFromEWKB(bytearray(getEWKB(geom)), crs(crs));
1967
    }
1968

    
1969
    @Override
1970
    public String ST_GeomFromText(Envelope env, IProjection crs) {
1971
        return this.ST_GeomFromText(getWKT(env), crs(crs));
1972
    }
1973

    
1974
    @Override
1975
    public String getWKT(Geometry geom) {
1976
        if (geom == null) {
1977
            throw new RuntimeException("Can't convert geometry to WKT, geometry is null");
1978
        }
1979
        try {
1980
            return geom.convertToWKT();
1981
        } catch (Exception ex) {
1982
            throw new RuntimeException("Can't convert geometry to WKT", ex);
1983
        }
1984
    }
1985

    
1986
    @Override
1987
    public String getWKT(Envelope env) {
1988
        return getWKT(env.getGeometry());
1989
    }
1990

    
1991
    @Override
1992
    public byte[] getWKB(Geometry geom) {
1993
        if (geom == null) {
1994
            throw new RuntimeException("Can't convert geometry to WKB, geometry is null");
1995
        }
1996
        try {
1997
            return geom.convertToWKB();
1998
        } catch (Exception ex) {
1999
            throw new RuntimeException("Can't convert geometry to WKB", ex);
2000
        }
2001
    }
2002

    
2003
    @Override
2004
    public byte[] getWKB(Envelope env) {
2005
        return getWKB(env.getGeometry());
2006
    }
2007

    
2008
    @Override
2009
    public byte[] getEWKB(Geometry geom) {
2010
        if (geom == null) {
2011
            throw new RuntimeException("Can't convert geometry to EWKB, geometry is null");
2012
        }
2013
        try {
2014
            return geom.convertToEWKB();
2015
        } catch (Exception ex) {
2016
            throw new RuntimeException("Can't convert geometry to EWKB", ex);
2017
        }
2018
    }
2019

    
2020
    @Override
2021
    public byte[] getEWKB(Envelope env) {
2022
        return getEWKB(env.getGeometry());
2023
    }
2024

    
2025
    @Override
2026
    public void clearParameters() {
2027
        parameters = new ArrayList<>();
2028
    }
2029

    
2030
    @Override
2031
    public void addParameter(DataType type, String name) {
2032
        this.addParameter(type.getType(), name, null);
2033
    }
2034

    
2035
    @Override
2036
    public void addParameter(int type, String name) {
2037
        this.addParameter(type, name, null);
2038
    }
2039

    
2040
    @Override
2041
    public void addParameter(int type, String name, IProjection crs) {
2042
        String quote = this.getQuoteForIdentifiers();
2043
        if (name.startsWith(quote)) {
2044
            // Remove quotes
2045
            name = name.substring(1, name.length() - 1);
2046
        }
2047
        this.parameters.add(new ParameterBase(type, name, crs));
2048
    }
2049

    
2050
    @Override
2051
    public void addConstantParameter(Object value) {
2052
        this.parameters.add(new ParameterBase(value));
2053
    }
2054
    
2055
    @Override
2056
    public ExpBuilder createExpresionBuilder(String x) {
2057
        return new ExpBuilderBase(x);
2058
    }
2059

    
2060
    @Override
2061
    public ExpBuilder createExpresionBuilder(OpBuilder x) {
2062
        return new ExpBuilderBase(x);
2063
    }
2064

    
2065
    @Override
2066
    public ExpBuilder createExpresionBuilder() {
2067
        return new ExpBuilderBase();
2068
    }
2069

    
2070
    protected SQLBuilderConfig createConfig() {
2071
        return new SQLBuilderConfig();
2072
    }
2073
    
2074
    protected ColumnBuilder createColumnBuilder() {
2075
        return new ColumnBuilderBase();
2076
    }
2077

    
2078
    protected ExpBuilder createExpBuilder() {
2079
        return new ExpBuilderBase();
2080
    }
2081

    
2082
    protected OpBuilder createOpBuilder(String operator) {
2083
        return new OpBuilderBase(operator);
2084
    }
2085

    
2086
    protected FromBuilder createFromBuilder() {
2087
        return new FromBuilderBase();
2088
    }
2089

    
2090
    protected SelectBuilder createSelectBuilder() {
2091
        return new SelectBuilderBase();
2092
    }
2093

    
2094
    protected UpdateBuilder createUpdateBuilder() {
2095
        return new UpdateBuilderBase();
2096
    }
2097

    
2098
    protected DeleteBuilder createDeleteBuilder() {
2099
        return new DeleteBuilderBase();
2100
    }
2101

    
2102
    protected GrantBuilder createGrantBuilder() {
2103
        return new GrantBuilderBase();
2104
    }
2105

    
2106
    protected DropTableBuilder createDropTableBuilder() {
2107
        return new DropTableBuilderBase();
2108
    }
2109

    
2110
    protected CreateTableBuilder createCreateTableBuilder() {
2111
        return new CreateTableBuilderBase();
2112
    }
2113

    
2114
    protected AlterTableBuilder createAlterTableBuilder() {
2115
        return new AlterTableBuilderBase();
2116
    }
2117

    
2118
    protected InsertBuilder createInsertBuilder() {
2119
        return new InsertBuilderBase();
2120
    }
2121

    
2122
    protected UpdateTableStatisticsBuilder createUpdateTableStatisticsBuilder() {
2123
        return new UpdateTableStatisticsBuilderBase();
2124
    }
2125
    @Override
2126
    public SelectBuilder select() {
2127
        if (this.select == null) {
2128
            this.select = this.createSelectBuilder();
2129
        }
2130
        return this.select;
2131
    }
2132

    
2133
    @Override
2134
    public UpdateBuilder update() {
2135
        if (this.update == null) {
2136
            this.update = this.createUpdateBuilder();
2137
        }
2138
        return this.update;
2139
    }
2140

    
2141
    @Override
2142
    public UpdateTableStatisticsBuilder update_table_statistics() {
2143
        if (this.update_table_statistics == null) {
2144
            this.update_table_statistics = this.createUpdateTableStatisticsBuilder();
2145
        }
2146
        return this.update_table_statistics;
2147
    }
2148

    
2149
    @Override
2150
    public DropTableBuilder drop_table() {
2151
        if (this.drop_table == null) {
2152
            this.drop_table = this.createDropTableBuilder();
2153
        }
2154
        return this.drop_table;
2155
    }
2156

    
2157
    @Override
2158
    public DeleteBuilder delete() {
2159
        if (this.delete == null) {
2160
            this.delete = this.createDeleteBuilder();
2161
        }
2162
        return this.delete;
2163
    }
2164

    
2165
    @Override
2166
    public InsertBuilder insert() {
2167
        if (this.insert == null) {
2168
            this.insert = this.createInsertBuilder();
2169
        }
2170
        return this.insert;
2171
    }
2172

    
2173
    @Override
2174
    public AlterTableBuilder alter_table() {
2175
        if (this.alter_table == null) {
2176
            this.alter_table = this.createAlterTableBuilder();
2177
        }
2178
        return this.alter_table;
2179
    }
2180

    
2181
    @Override
2182
    public CreateTableBuilder create_table() {
2183
        if (this.create_table == null) {
2184
            this.create_table = this.createCreateTableBuilder();
2185
        }
2186
        return this.create_table;
2187
    }
2188

    
2189
    @Override
2190
    public GrantBuilder grant() {
2191
        if (this.grant == null) {
2192
            this.grant = this.createGrantBuilder();
2193
        }
2194
        return this.grant;
2195
    }
2196

    
2197
    @Override
2198
    public List<Parameter> getParameters() {
2199
        return this.parameters;
2200
    }
2201
  
2202
    @Override
2203
    public OpBuilder and(String op1, String op2) {
2204
        OpBuilder op = new OpBuilderBase(config.operator_AND, op1, op2);
2205
        return op;
2206
    }
2207

    
2208
    @Override
2209
    public OpBuilder or(String op1, String op2) {
2210
        OpBuilder op = new OpBuilderBase(config.operator_OR, op1, op2);
2211
        return op;
2212
    }
2213

    
2214
    @Override
2215
    public OpBuilder eq(String op1, String op2) {
2216
        OpBuilder op = new OpBuilderBase(config.operator_EQ, op1, op2);
2217
        return op;
2218
    }
2219

    
2220
    @Override
2221
    public OpBuilder ne(String op1, String op2) {
2222
        OpBuilder op = new OpBuilderBase(config.operator_NE, op1, op2);
2223
        return op;
2224
    }
2225

    
2226
    @Override
2227
    public OpBuilder gt(String op1, String op2) {
2228
        OpBuilder op = new OpBuilderBase(config.operator_GT, op1, op2);
2229
        return op;
2230
    }
2231

    
2232
    @Override
2233
    public OpBuilder ge(String op1, String op2) {
2234
        OpBuilder op = new OpBuilderBase(config.operator_GE, op1, op2);
2235
        return op;
2236
    }
2237

    
2238
    @Override
2239
    public OpBuilder lt(String op1, String op2) {
2240
        OpBuilder op = new OpBuilderBase(config.operator_LT, op1, op2);
2241
        return op;
2242
    }
2243

    
2244
    @Override
2245
    public OpBuilder le(String op1, String op2) {
2246
        OpBuilder op = new OpBuilderBase(config.operator_LE, op1, op2);
2247
        return op;
2248
    }
2249

    
2250
    @Override
2251
    public OpBuilder like(String op1, String op2) {
2252
        OpBuilder op = new OpBuilderBase(config.operator_LIKE, op1, op2);
2253
        return op;
2254
    }
2255

    
2256
    @Override
2257
    public OpBuilder ilike(String op1, String op2) {
2258
        OpBuilder op = new OpBuilderBase(config.operator_ILIKE, op1, op2);
2259
        return op;
2260
    }
2261

    
2262
    @Override
2263
    public String toString() {
2264
        if (this.select != null) {
2265
            return this.select.toString();
2266
        }
2267
        if (this.update != null) {
2268
            return this.update.toString();
2269
        }
2270
        if (this.insert != null) {
2271
            return this.insert.toString();
2272
        }
2273
        if (this.delete != null) {
2274
            return this.delete.toString();
2275
        }
2276
        if (this.alter_table != null) {
2277
            return this.alter_table.toString();
2278
        }
2279
        if (this.create_table != null) {
2280
            return this.create_table.toString();
2281
        }
2282
        if (this.drop_table != null) {
2283
            return this.drop_table.toString();
2284
        }
2285
        return "";
2286
    }
2287

    
2288
}