/
DatabaseInfo.java
1346 lines (1212 loc) · 49.4 KB
/
DatabaseInfo.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/**
* Licensed to JumpMind Inc under one or more contributor
* license agreements. See the NOTICE file distributed
* with this work for additional information regarding
* copyright ownership. JumpMind Inc licenses this file
* to you under the GNU General Public License, version 3.0 (GPLv3)
* (the "License"); you may not use this file except in compliance
* with the License.
*
* You should have received a copy of the GNU General Public License,
* version 3.0 (GPLv3) along with this library; if not, see
* <http://www.gnu.org/licenses/>.
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jumpmind.db.platform;
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.Types;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.function.Supplier;
import org.jumpmind.db.model.ColumnTypes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Contains information about the database platform such as supported features and native type mappings.
*/
public class DatabaseInfo {
/** The Log to which logging calls will be made. */
private final Logger log = LoggerFactory.getLogger(DatabaseInfo.class);
/**
* Whether the database requires the explicit stating of NULL as the default value.
*/
private boolean nullAsDefaultValueRequired = false;
/**
* Whether default values can be defined for LONGVARCHAR/LONGVARBINARY columns.
*/
private boolean defaultValuesForLongTypesSupported = true;
// properties influencing the specification of table constraints
/**
* Whether primary key constraints are embedded inside the create table statement.
*/
private boolean primaryKeyEmbedded = true;
/**
* Whether foreign key constraints are embedded inside the create table statement.
*/
private boolean foreignKeysEmbedded = false;
/** Whether embedded foreign key constraints are explicitly named. */
private boolean embeddedForeignKeysNamed = false;
/** Whether non-unique indices are supported. */
private boolean indicesSupported = true;
/** Whether database has foreign key support */
private boolean foreignKeysSupported = true;
/** Whether indices are embedded inside the create table statement. */
private boolean indicesEmbedded = false;
/**
* Whether unique constraints are embedded inside the column definition statement.
*/
private boolean uniqueEmbedded = true;
private boolean triggersSupported = true;
private boolean triggersCreateOrReplaceSupported = false;
/** Whether identity specification is supported for non-primary key columns. */
private boolean nonPKIdentityColumnsSupported = true;
/** Whether generated/computed/virtual columns are supported. */
private boolean generatedColumnsSupported = false;
/** Whether expressions can be used as default values */
private boolean expressionsAsDefaultValuesSupported = false;
/** Whether functional indices are supported */
private boolean functionalIndicesSupported = false;
/**
* Whether the auto-increment definition is done via the DEFAULT part of the column definition.
*/
private boolean defaultValueUsedForIdentitySpec = false;
// properties influencing the reading of models from live databases
/**
* Whether system indices (database-generated indices for primary and foreign keys) are returned when reading a model from a database.
*/
private boolean systemIndicesReturned = true;
/**
* Whether system indices for foreign keys are always non-unique or can be unique (i.e. if a primary key column is used to establish the foreign key).
*/
private boolean systemForeignKeyIndicesAlwaysNonUnique = false;
/**
* Whether the database returns a synthetic default value for non-identity required columns.
*/
private boolean syntheticDefaultValueForRequiredReturned = false;
/**
* Whether the platform is able to determine auto increment status from an existing database.
*/
private boolean identityStatusReadingSupported = true;
// other DDL/DML properties
/** Whether comments are supported. */
private boolean sqlCommentsSupported = true;
/** Whether delimited identifiers are supported or not. */
private boolean delimitedIdentifiersSupported = true;
/** Whether an ALTER TABLE is needed to drop indexes. */
private boolean alterTableForDropUsed = false;
/**
* Whether the platform allows for the explicit specification of values for identity columns in INSERT and UPDATE statements.
*/
private boolean identityOverrideAllowed = true;
/**
* Whether the values of identity columns can be read back from the database after insertion.
*/
private boolean lastIdentityValueReadable = true;
/**
* Whether auto-commit mode for the reading of the values of identity columns after insertion shall be used.
*/
private boolean autoCommitModeForLastIdentityValueReading = true;
/**
* Specifies the maximum length that a table name can have for this database (-1 if there is no limit).
*/
private int maxTableNameLength = -1;
/**
* Specifies the maximum length that a column name can have for this database (-1 if there is no limit).
*/
private int maxColumnNameLength = -1;
/**
* Specifies the maximum length that a constraint name can have for this database (-1 if there is no limit).
*/
private int maxConstraintNameLength = -1;
/**
* Specifies the maximum length that a foreign key name can have for this database (-1 if there is no limit).
*/
private int maxForeignKeyNameLength = -1;
/**
* The string used for delimiting SQL identifiers, eg. table names, column names etc.
*/
private String delimiterToken = "\"";
/**
* The string used for escaping values when generating textual SQL statements.
*/
private String valueQuoteToken = "'";
private String binaryQuoteStart = "'";
private String binaryQuoteEnd = "'";
/** The string that starts a comment. */
private String commentPrefix = "--";
/** The string that ends a comment. */
private String commentSuffix = "";
/** The text separating individual sql commands. */
private String sqlCommandDelimiter = ";";
private boolean dateOverridesToTimestamp;
private boolean emptyStringNulled = false;
private boolean autoIncrementUpdateAllowed = true;
/**
* True if blank characters are padded out
*/
private boolean blankCharColumnSpacePadded;
/**
* True if non-blank characters are padded out
*/
private boolean nonBlankCharColumnSpacePadded;
private boolean charColumnSpaceTrimmed;
/***
* Indicates whether each ddl statement needs to be committed.
*/
private boolean requiresAutoCommitForDdl = false;
private boolean requiresSavePointsInTransaction = false;
private String catalogSeparator = ".";
private String schemaSeparator = ".";
/** Contains non-default mappings from jdbc to native types. */
private Map<Integer, String> nativeTypes = new HashMap<Integer, String>();
/**
* Contains the jdbc types corresponding to the native types for non-default mappings.
*/
private Map<Integer, Integer> targetJdbcTypes = new HashMap<Integer, Integer>();
/**
* Contains those JDBC types whose corresponding native types have a null value as the default value.
*/
private Set<Integer> typesWithNullDefault = new HashSet<Integer>();
/**
* Contains those JDBC types whose corresponding native types are types that have a size on this platform.
*/
private Set<Integer> typesWithSize = new HashSet<Integer>();
/**
* Contains the default sizes for those JDBC types whose corresponding native types require a size.
*/
private Map<Integer, Integer> typesDefaultSizes = new HashMap<Integer, Integer>();
/**
* Contains the maximum sizes for those JDBC types whose corresponding native types require a size.
*/
private Map<String, Integer> nativeTypeMaxSizes = new HashMap<String, Integer>();
/**
* Contains those JDBC types whose corresponding native types are types that have precision and scale on this platform.
*/
private HashSet<Integer> typesWithPrecisionAndScale = new HashSet<Integer>();
private Supplier<Set<String>> defaultValuesToLeaveUnquotedSupplier;
private Supplier<Map<String, String>> defaultValuesToTranslateSupplier;
/**
* The minimum transaction isolation level for the given database that will prevent phantom reads from occurring. Default is TRANSACTION_READ_COMMITTED
* which covers most dbs
*/
private int minIsolationLevelToPreventPhantomReads = Connection.TRANSACTION_READ_COMMITTED;
/**
* Specifies if an empty string entered into a required char column will be read out as null (Sql Anywhere).
*/
private boolean requiredCharColumnEmptyStringSameAsNull;
private boolean notNullColumnsSupported = true;
private boolean zeroDateAllowed;
private String cteExpression;
private boolean logBased;
private boolean triggersContainJava = false;
/**
* Creates a new platform info object.
*/
public DatabaseInfo() {
this.typesWithNullDefault.add(Integer.valueOf(Types.CHAR));
this.typesWithNullDefault.add(Integer.valueOf(Types.VARCHAR));
this.typesWithNullDefault.add(Integer.valueOf(Types.LONGVARCHAR));
this.typesWithNullDefault.add(Integer.valueOf(Types.CLOB));
this.typesWithNullDefault.add(Integer.valueOf(Types.BINARY));
this.typesWithNullDefault.add(Integer.valueOf(Types.VARBINARY));
this.typesWithNullDefault.add(Integer.valueOf(Types.LONGVARBINARY));
this.typesWithNullDefault.add(Integer.valueOf(Types.BLOB));
this.typesWithSize.add(Integer.valueOf(Types.CHAR));
this.typesWithSize.add(Integer.valueOf(Types.VARCHAR));
this.typesWithSize.add(Integer.valueOf(Types.BINARY));
this.typesWithSize.add(Integer.valueOf(Types.VARBINARY));
this.typesWithSize.add(Integer.valueOf(ColumnTypes.NCHAR));
this.typesWithSize.add(Integer.valueOf(ColumnTypes.NVARCHAR));
this.typesWithPrecisionAndScale.add(Integer.valueOf(Types.DECIMAL));
this.typesWithPrecisionAndScale.add(Integer.valueOf(Types.NUMERIC));
this.nativeTypes.put(Integer.valueOf(ColumnTypes.TIMESTAMPTZ), "TIMESTAMP");
this.nativeTypes.put(Integer.valueOf(ColumnTypes.TIMESTAMPLTZ), "TIMESTAMP");
this.nativeTypes.put(Integer.valueOf(ColumnTypes.TIMETZ), "TIME");
this.targetJdbcTypes.put(Integer.valueOf(ColumnTypes.TIMESTAMPTZ), Types.TIMESTAMP);
this.targetJdbcTypes.put(Integer.valueOf(ColumnTypes.TIMESTAMPLTZ), Types.TIMESTAMP);
this.targetJdbcTypes.put(Integer.valueOf(ColumnTypes.TIMETZ), Types.TIME);
}
// properties influencing the definition of columns
/**
* Determines whether a NULL needs to be explicitly stated when the column has no specified default value. Default is false.
*
* @return <code>true</code> if NULL must be written for empty default values
*/
public boolean isNullAsDefaultValueRequired() {
return nullAsDefaultValueRequired;
}
/**
* Specifies whether a NULL needs to be explicitly stated when the column has no specified default value. Default is false.
*
* @param requiresNullAsDefaultValue
* Whether NULL must be written for empty default values
*/
public void setNullAsDefaultValueRequired(boolean requiresNullAsDefaultValue) {
this.nullAsDefaultValueRequired = requiresNullAsDefaultValue;
}
/**
* Determines whether default values can be specified for LONGVARCHAR/LONGVARBINARY columns.
*
* @return <code>true</code> if default values are allowed
*/
public boolean isDefaultValuesForLongTypesSupported() {
return defaultValuesForLongTypesSupported;
}
/**
* Specifies whether default values can be specified for LONGVARCHAR/LONGVARBINARY columns.
*
* @param isSupported
* <code>true</code> if default values are supported
*/
public void setDefaultValuesForLongTypesSupported(boolean isSupported) {
this.defaultValuesForLongTypesSupported = isSupported;
}
// properties influencing the specification of table constraints
/**
* Determines whether primary key constraints are embedded in the create table clause or as seperate alter table statements. The default is embedded pks.
*
* @return <code>true</code> if pk constraints are embedded
*/
public boolean isPrimaryKeyEmbedded() {
return primaryKeyEmbedded;
}
/**
* Specifies whether the primary key constraints are embedded in the create table clause or as seperate alter table statements.
*
* @param primaryKeyEmbedded
* Whether pk constraints are embedded
*/
public void setPrimaryKeyEmbedded(boolean primaryKeyEmbedded) {
this.primaryKeyEmbedded = primaryKeyEmbedded;
}
/**
* Determines whether foreign key constraints are embedded in the create table clause or as seperate alter table statements. Per default, foreign keys are
* external.
*
* @return <code>true</code> if fk constraints are embedded
*/
public boolean isForeignKeysEmbedded() {
return foreignKeysEmbedded;
}
/**
* Specifies whether foreign key constraints are embedded in the create table clause or as seperate alter table statements.
*
* @param foreignKeysEmbedded
* Whether fk constraints are embedded
*/
public void setForeignKeysEmbedded(boolean foreignKeysEmbedded) {
this.foreignKeysEmbedded = foreignKeysEmbedded;
}
/**
* Returns whether embedded foreign key constraints should have a name.
*
* @return <code>true</code> if embedded fks have name
*/
public boolean isEmbeddedForeignKeysNamed() {
return embeddedForeignKeysNamed;
}
/**
* Specifies whether embedded foreign key constraints should be named.
*
* @param embeddedForeignKeysNamed
* Whether embedded fks shall have a name
*/
public void setEmbeddedForeignKeysNamed(boolean embeddedForeignKeysNamed) {
this.embeddedForeignKeysNamed = embeddedForeignKeysNamed;
}
/**
* Determines whether indices are supported.
*
* @return <code>true</code> if indices are supported
*/
public boolean isIndicesSupported() {
return indicesSupported;
}
/**
* Specifies whether indices are supported.
*
* @param supportingIndices
* <code>true</code> if indices are supported
*/
public void setIndicesSupported(boolean supportingIndices) {
this.indicesSupported = supportingIndices;
}
/**
* Determines whether indices are supported.
*
* @return <code>true</code> if indices are supported
*/
public boolean isForeignKeysSupported() {
return foreignKeysSupported;
}
/**
* Specifies whether indices are supported.
*
* @param supportingIndices
* <code>true</code> if indices are supported
*/
public void setForeignKeysSupported(boolean foreignKeysSupported) {
this.foreignKeysSupported = foreignKeysSupported;
}
/**
* Determines whether the indices are embedded in the create table clause or as seperate statements. Per default, indices are external.
*
* @return <code>true</code> if indices are embedded
*/
public boolean isIndicesEmbedded() {
return indicesEmbedded;
}
/**
* Specifies whether indices are embedded in the create table clause or as seperate alter table statements.
*
* @param indicesEmbedded
* Whether indices are embedded
*/
public void setIndicesEmbedded(boolean indicesEmbedded) {
this.indicesEmbedded = indicesEmbedded;
}
/**
* Determines whether unique constraints are embedded in the column definition or as separate constraint statements. The default is non-embedded unique.
*
* @return <code>true</code> if unique constraints are embedded
*/
public boolean isUniqueEmbedded() {
return uniqueEmbedded;
}
/**
* Specifies whether the unique constraints are embedded in the column definition or as separate constraint statements.
*
* @param primaryKeyEmbedded
* Whether unique constraints are embedded
*/
public void setUniqueEmbedded(boolean unique) {
this.uniqueEmbedded = unique;
}
/**
* Determines whether non-primary key columns can be auto-incrementing (IDENTITY columns).
*
* @return <code>true</code> if normal non-PK columns can be auto-incrementing
*/
public boolean isNonPKIdentityColumnsSupported() {
return nonPKIdentityColumnsSupported;
}
/**
* Specifies whether non-primary key columns can be auto-incrementing (IDENTITY columns).
*
* @param supportingNonPKIdentityColumns
* <code>true</code> if normal non-PK columns can be auto-incrementing
*/
public void setNonPKIdentityColumnsSupported(boolean supportingNonPKIdentityColumns) {
this.nonPKIdentityColumnsSupported = supportingNonPKIdentityColumns;
}
/**
* Determines whether generated/computed/virtual columns are supported.
*
* @return <code>true</code> if generated/computed/virtual columns are supported
*/
public boolean isGeneratedColumnsSupported() {
return generatedColumnsSupported;
}
/**
* Specifies whether generated/computed/virtual columns are supported.
*
* @param generatedColumnsSupported
* <code>true</code> if generated/computed/virtual columns are supported
*/
public void setGeneratedColumnsSupported(boolean generatedColumnsSupported) {
this.generatedColumnsSupported = generatedColumnsSupported;
}
/**
* Determines whether expressions can be used as default values.
*
* @return <code>true</code> if expressions can be used as default values
*/
public boolean isExpressionsAsDefaultValuesSupported() {
return expressionsAsDefaultValuesSupported;
}
/**
* Specifies whether expressions can be used as default values.
*
* @param expressionsAsDefaultValuesSupported
* <code>true</code> if expressions can be used as default values
*/
public void setExpressionsAsDefaultValuesSupported(boolean expressionsAsDefaultValuesSupported) {
this.expressionsAsDefaultValuesSupported = expressionsAsDefaultValuesSupported;
}
/**
* Determines whether the auto-increment specification uses the DEFAULT value of the column definition.
*
* @return <code>true</code> if the auto-increment spec is done via the DEFAULT value
*/
public boolean isDefaultValueUsedForIdentitySpec() {
return defaultValueUsedForIdentitySpec;
}
/**
* Specifies whether the auto-increment specification uses the DEFAULT value of the column definition.
*
* @param identitySpecUsesDefaultValue
* <code>true</code> if the auto-increment spec is done via the DEFAULT value
*/
public void setDefaultValueUsedForIdentitySpec(boolean identitySpecUsesDefaultValue) {
this.defaultValueUsedForIdentitySpec = identitySpecUsesDefaultValue;
}
// properties influencing the reading of models from live databases
/**
* Determines whether database-generated indices for primary and foreign keys are returned when reading a model from a database.
*
* @return <code>true</code> if system indices are read from a live database
*/
public boolean isSystemIndicesReturned() {
return systemIndicesReturned;
}
/**
* Specifies whether database-generated indices for primary and foreign keys are returned when reading a model from a database.
*
* @param returningSystemIndices
* <code>true</code> if system indices are read from a live database
*/
public void setSystemIndicesReturned(boolean returningSystemIndices) {
this.systemIndicesReturned = returningSystemIndices;
}
/**
* Determines whether system indices for foreign keys are always non-unique or can be unique (i.e. if a primary key column is used to establish the foreign
* key).
*
* @return <code>true</code> if system foreign key indices are always non-unique; default is <code>false</code>
*/
public boolean isSystemForeignKeyIndicesAlwaysNonUnique() {
return systemForeignKeyIndicesAlwaysNonUnique;
}
/**
* Specifies whether system indices for foreign keys are always non-unique or can be unique (i.e. if a primary key column is used to establish the foreign
* key).
*
* @param alwaysNonUnique
* <code>true</code> if system foreign key indices are always non-unique
*/
public void setSystemForeignKeyIndicesAlwaysNonUnique(boolean alwaysNonUnique) {
this.systemForeignKeyIndicesAlwaysNonUnique = alwaysNonUnique;
}
/**
* Determines whether the platform returns synthetic default values (e.g. 0 for numeric columns etc.) for non-identity required columns when reading a model
* from a database.
*
* @return <code>true</code> if synthetic default values are returned for non-identity required columns
*/
public boolean isSyntheticDefaultValueForRequiredReturned() {
return syntheticDefaultValueForRequiredReturned;
}
/**
* Specifies whether the platform returns synthetic default values (e.g. 0 for numeric columns etc.) for non-identity required columns when reading a model
* from a database.
*
* @param returningDefaultValue
* <code>true</code> if synthetic default values are returned for non-identity required columns
*/
public void setSyntheticDefaultValueForRequiredReturned(boolean returningDefaultValue) {
this.syntheticDefaultValueForRequiredReturned = returningDefaultValue;
}
/**
* Determines whether the platform is able to read the auto-increment status for columns from an existing database.
*
* @return <code>true</code> if the auto-increment status can be determined from an existing database
*/
public boolean getIdentityStatusReadingSupported() {
return identityStatusReadingSupported;
}
/**
* Specifies whether the platform is able to read the auto-increment status for columns from an existing database.
*
* @param canReadAutoIncrementStatus
* <code>true</code> if the auto-increment status can be determined from an existing database
*/
public void setIdentityStatusReadingSupported(boolean canReadAutoIncrementStatus) {
this.identityStatusReadingSupported = canReadAutoIncrementStatus;
}
// other ddl properties
/**
* Determines whether the database supports SQL comments.
*
* @return <code>true</code> if comments are supported
*/
public boolean isSqlCommentsSupported() {
return sqlCommentsSupported;
}
/**
* Specifies whether SQL comments are supported by the database.
*
* @param commentsSupported
* <code>true</code> if comments are supported
*/
public void setSqlCommentsSupported(boolean commentsSupported) {
this.sqlCommentsSupported = commentsSupported;
}
/**
* Determines whether delimited identifiers are supported.
*
* @return <code>true</code> if delimited identifiers are supported
*/
public boolean isDelimitedIdentifiersSupported() {
return delimitedIdentifiersSupported;
}
/**
* Specifies whether delimited identifiers are supported.
*
* @param areSupported
* <code>true</code> if delimited identifiers are supported
*/
public void setDelimitedIdentifiersSupported(boolean areSupported) {
this.delimitedIdentifiersSupported = areSupported;
}
/**
* Determines whether an ALTER TABLE statement shall be used for dropping indices or constraints. The default is false.
*
* @return <code>true</code> if ALTER TABLE is required
*/
public boolean isAlterTableForDropUsed() {
return alterTableForDropUsed;
}
/**
* Specifies whether an ALTER TABLE statement shall be used for dropping indices or constraints.
*
* @param useAlterTableForDrop
* Whether ALTER TABLE will be used
*/
public void setAlterTableForDropUsed(boolean useAlterTableForDrop) {
this.alterTableForDropUsed = useAlterTableForDrop;
}
/**
* Determines whether the platform is allows the explicit specification of values for identity columns in INSERT/UPDATE statements.
*
* @return <code>true</code> if values for identity columns can be specified
*/
public boolean isIdentityOverrideAllowed() {
return identityOverrideAllowed;
}
/**
* Specifies whether the platform is allows the explicit specification of values for identity columns in INSERT/UPDATE statements.
*
* @param identityOverrideAllowed
* <code>true</code> if values for identity columns can be specified
*/
public void setIdentityOverrideAllowed(boolean identityOverrideAllowed) {
this.identityOverrideAllowed = identityOverrideAllowed;
}
/**
* Determines whether the values of identity columns can be read back from the database after insertion of a row.
*
* @return <code>true</code> if the identity column(s) can be read back
*/
public boolean isLastIdentityValueReadable() {
return lastIdentityValueReadable;
}
/**
* Specifies whether the values of identity columns can be read back from the database after insertion of a row.
*
* @param lastIdentityValueReadable
* <code>true</code> if the identity column(s) can be read back
*/
public void setLastIdentityValueReadable(boolean lastIdentityValueReadable) {
this.lastIdentityValueReadable = lastIdentityValueReadable;
}
/**
* Determines whether auto-commit mode for the reading of the values of identity columns after insertion shall be used, i.e. whether between the insertion
* of the row and the reading of the database-generated identity value a commit is issued.
*
* @return <code>true</code> if auto-commit mode is used
*/
public boolean isAutoCommitModeForLastIdentityValueReading() {
return autoCommitModeForLastIdentityValueReading;
}
/**
* Determines whether auto-commit mode for the reading of the values of identity columns after insertion shall be used, i.e. whether between the insertion
* of the row and the reading of the database-generated identity value a commit is issued.
*
* @param autoCommitModeForLastIdentityValueReading
* <code>true</code> if auto-commit mode shall be used
*/
public void setAutoCommitModeForLastIdentityValueReading(
boolean autoCommitModeForLastIdentityValueReading) {
this.autoCommitModeForLastIdentityValueReading = autoCommitModeForLastIdentityValueReading;
}
/**
* Returns the maximum number of characters that a table name can have.
*
* @return The number of characters, or -1 if not limited
*/
public int getMaxTableNameLength() {
return maxTableNameLength;
}
/**
* Returns the maximum number of characters that a column name can have.
*
* @return The number of characters, or -1 if not limited
*/
public int getMaxColumnNameLength() {
return maxColumnNameLength;
}
/**
* Returns the maximum number of characters that a constraint name can have.
*
* @return The number of characters, or -1 if not limited
*/
public int getMaxConstraintNameLength() {
return maxConstraintNameLength;
}
/**
* Returns the maximum number of characters that a foreign key name can have.
*
* @return The number of characters, or -1 if not limited
*/
public int getMaxForeignKeyNameLength() {
return maxForeignKeyNameLength;
}
/**
* Sets the maximum length of all identifiers that this database allows. Use this method if the length limit is the same for all kinds of identifiers.
*
* @param maxIdentifierLength
* The maximum identifier length, -1 if unlimited
*/
public void setMaxIdentifierLength(int maxIdentifierLength) {
this.maxTableNameLength = maxIdentifierLength;
this.maxColumnNameLength = maxIdentifierLength;
this.maxConstraintNameLength = maxIdentifierLength;
this.maxForeignKeyNameLength = maxIdentifierLength;
}
/**
* Sets the maximum length of table names that this database allows.
*
* @param maxTableNameLength
* The maximum length, -1 if unlimited
*/
public void setMaxTableNameLength(int maxTableNameLength) {
this.maxTableNameLength = maxTableNameLength;
}
/**
* Sets the maximum length of column names that this database allows.
*
* @param maxColumnNameLength
* The maximum length, -1 if unlimited
*/
public void setMaxColumnNameLength(int maxColumnNameLength) {
this.maxColumnNameLength = maxColumnNameLength;
}
/**
* Sets the maximum length of constraint names that this database allows.
*
* @param maxConstraintNameLength
* The maximum length, -1 if unlimited
*/
public void setMaxConstraintNameLength(int maxConstraintNameLength) {
this.maxConstraintNameLength = maxConstraintNameLength;
}
/**
* Sets the maximum length of foreign key names that this database allows.
*
* @param maxForeignKeyNameLength
* The maximum length, -1 if unlimited
*/
public void setMaxForeignKeyNameLength(int maxForeignKeyNameLength) {
this.maxForeignKeyNameLength = maxForeignKeyNameLength;
}
/**
* Returns the text that is used to delimit identifiers (eg. table names). Per default, this is a double quotation character (").
*
* @return The delimiter text
*/
public String getDelimiterToken() {
return delimiterToken;
}
/**
* Sets the text that is used to delimit identifiers (eg. table names).
*
* @param delimiterToken
* The delimiter text
*/
public void setDelimiterToken(String delimiterToken) {
this.delimiterToken = delimiterToken;
}
/**
* Returns the text that is used for for quoting values (e.g. text) when printing default values and in generates insert/update/delete statements. Per
* default, this is a single quotation character (').
*
* @return The quote text
*/
public String getValueQuoteToken() {
return valueQuoteToken;
}
/**
* Sets the text that is used for for quoting values (e.g. text) when printing default values and in generates insert/update/delete statements.
*
* @param valueQuoteChar
* The new quote text
*/
public void setValueQuoteToken(String valueQuoteChar) {
this.valueQuoteToken = valueQuoteChar;
}
/**
* Returns the string that denotes the beginning of a comment.
*
* @return The comment prefix
*/
public String getCommentPrefix() {
return commentPrefix;
}
/**
* Sets the text that starts a comment.
*
* @param commentPrefix
* The new comment prefix
*/
public void setCommentPrefix(String commentPrefix) {
this.commentPrefix = (commentPrefix == null ? "" : commentPrefix);
}
/**
* Returns the string that denotes the end of a comment. Note that comments will be always on their own line.
*
* @return The comment suffix
*/
public String getCommentSuffix() {
return commentSuffix;
}
/**
* Sets the text that ends a comment.
*
* @param commentSuffix
* The new comment suffix
*/
public void setCommentSuffix(String commentSuffix) {
this.commentSuffix = (commentSuffix == null ? "" : commentSuffix);
}
/**
* Returns the text separating individual sql commands.
*
* @return The delimiter text
*/
public String getSqlCommandDelimiter() {
return sqlCommandDelimiter;
}
/**
* Sets the text separating individual sql commands.
*
* @param sqlCommandDelimiter
* The delimiter text
*/
public void setSqlCommandDelimiter(String sqlCommandDelimiter) {
this.sqlCommandDelimiter = sqlCommandDelimiter;
}
/**
* Returns the database-native type for the given type code.
*
* @param typeCode
* The {@link java.sql.Types} type code
*
* @return The native type or <code>null</code> if there isn't one defined
*/
public String getNativeType(int typeCode) {
return (String) this.nativeTypes.get(Integer.valueOf(typeCode));
}
/**
* Returns the jdbc type corresponding to the native type that is used for the given jdbc type. This is most often the same jdbc type, but can also be a
* different one. For instance, if a database has no native boolean type, then the source jdbc type would be <code>BIT</code> or <code>BOOLEAN</code>, and
* the target jdbc type might be <code>TINYINT</code> or <code>SMALLINT</code>.
*
* @param typeCode
* The {@link java.sql.Types} type code
*
* @return The target jdbc type
*/
public int getTargetJdbcType(int typeCode) {
Integer targetJdbcType = (Integer) targetJdbcTypes.get(Integer.valueOf(typeCode));
return targetJdbcType == null ? typeCode : targetJdbcType.intValue();
}
/**
* Adds a mapping from jdbc type to database-native type.
*
* @param jdbcTypeCode
* The jdbc type code as defined by {@link java.sql.Types}
*
* @param nativeType
* The native type
*/
public void addNativeTypeMapping(int jdbcTypeCode, String nativeType) {
this.nativeTypes.put(Integer.valueOf(jdbcTypeCode), nativeType);
}
/**
* Adds a mapping from jdbc type to database-native type.
*
* @param jdbcTypeCode
* The jdbc type code as defined by {@link java.sql.Types}
*
* @param nativeType
* The native type
*
* @param targetJdbcTypeCode
* The jdbc type code corresponding to the native type (e.g. when reading the model from the database)
*/
public void addNativeTypeMapping(int jdbcTypeCode, String nativeType, int targetJdbcTypeCode) {
addNativeTypeMapping(jdbcTypeCode, nativeType);
this.targetJdbcTypes.put(Integer.valueOf(jdbcTypeCode), Integer.valueOf(targetJdbcTypeCode));
}
/**
* Adds a mapping from jdbc type to database-native type. Note that this method accesses the named constant in {@link java.sql.Types} via reflection and is
* thus safe to use under JDK 1.2/1.3 even with constants defined only in later Java versions - for these, the method simply will not add a mapping.
*
* @param jdbcTypeName
* The jdbc type name, one of the constants defined in {@link java.sql.Types}
*
* @param nativeType
* The native type
*/
public void addNativeTypeMapping(String jdbcTypeName, String nativeType) {
try {
Field constant = Types.class.getField(jdbcTypeName);
if (constant != null) {
addNativeTypeMapping(constant.getInt(null), nativeType);
}
} catch (Exception ex) {
// ignore -> won't be defined
this.log.warn("Cannot add native type mapping for undefined jdbc type " + jdbcTypeName,
ex);
}
}
/**
* Adds a mapping from jdbc type to database-native type. Note that this method accesses the named constant in {@link java.sql.Types} via reflection and is
* thus safe to use under JDK 1.2/1.3 even with constants defined only in later Java versions - for these, the method simply will not add a mapping.
*
* @param jdbcTypeName
* The jdbc type name, one of the constants defined in {@link java.sql.Types}
*
* @param nativeType
* The native type
*
* @param targetJdbcTypeName
* The jdbc type corresponding to the native type (e.g. when reading the model from the database)
*/
public void addNativeTypeMapping(String jdbcTypeName, String nativeType,
String targetJdbcTypeName) {
try {
Field sourceType = Types.class.getField(jdbcTypeName);
Field targetType = Types.class.getField(targetJdbcTypeName);
if ((sourceType != null) && (targetType != null)) {
addNativeTypeMapping(sourceType.getInt(null), nativeType, targetType.getInt(null));
}
} catch (Exception ex) {
// ignore -> won't be defined
this.log.warn("Cannot add native type mapping for undefined jdbc type " + jdbcTypeName
+ ", target jdbc type " + targetJdbcTypeName, ex);
}