Skip to content

Commit 2b358e1

Browse files
committed
issue #334 - add db support for timestamp precision
1. added generic support in fhir-database-utils for passing precision 2. extended IDataBaseTypeAdapter to cover TIMESTAMP and default to including the precision argument (i.e. `TIMESTAMP[(precision)]`) 3. override this default in Derby because it doesn't actually support specifying the precision! 4. updated FhirSchemaGenerator to pass a precision of 6 (microsecond precision to match our model) Also added a "SimpleSchemaPrinter" class that has a single main method for quickly printing the schema DDL. Signed-off-by: Lee Surprenant <lmsurpre@us.ibm.com>
1 parent 23b7f44 commit 2b358e1

10 files changed

Lines changed: 99 additions & 14 deletions

File tree

fhir-database-utils/src/main/java/com/ibm/fhir/database/utils/api/IDatabaseTypeAdapter.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,19 @@ public interface IDatabaseTypeAdapter {
3434
*/
3535
public String varcharClause(int size);
3636

37+
/**
38+
* Generate a clause for TIMESTAMP
39+
* @param precision
40+
* @return
41+
* @implSpec the default implementation returns TIMESTAMP[(precision)]
42+
* and excludes the precision if it is null
43+
*/
44+
default public String timestampClause(Integer precision) {
45+
StringBuilder typeDef = new StringBuilder();
46+
if (precision != null) {
47+
typeDef.append("(" + precision + ")");
48+
}
49+
return typeDef.toString();
50+
};
51+
3752
}

fhir-database-utils/src/main/java/com/ibm/fhir/database/utils/derby/DerbyAdapter.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,12 @@ public String blobClause(long size, int inlineSize) {
203203
public String varcharClause(int size) {
204204
return "VARCHAR(" + size + ")";
205205
}
206+
207+
@Override
208+
public String timestampClause(Integer precision) {
209+
// Derby doesn't support the timestamp precision argument
210+
return "TIMESTAMP";
211+
}
206212

207213
@Override
208214
public void createForeignKeyConstraint(String constraintName, String schemaName, String name,

fhir-database-utils/src/main/java/com/ibm/fhir/database/utils/derby/DerbyTranslator.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,13 +142,12 @@ public String getUrl(Properties connectionProperties) {
142142
return "jdbc:derby:memory:" + adapter.getDatabase();
143143
}
144144
else {
145-
return "jdbc:derby:" + adapter.getDatabase();
145+
return "jdbc:derby:" + adapter.getDatabase();
146146
}
147147
}
148148

149149
@Override
150150
public boolean clobSupportsInline() {
151151
return false;
152152
}
153-
154153
}

fhir-database-utils/src/main/java/com/ibm/fhir/database/utils/model/ColumnDef.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public class ColumnDef implements Comparable<ColumnDef> {
1414
private boolean nullable;
1515
private ColumnType columnType;
1616
private long size;
17-
private int precision;
17+
private Integer precision;
1818
private int inlineSize;
1919

2020
/**
@@ -47,7 +47,7 @@ public long getSize() {
4747
public void setSize(long size) {
4848
this.size = size;
4949
}
50-
public int getPrecision() {
50+
public Integer getPrecision() {
5151
return precision;
5252
}
5353
public void setPrecision(int precision) {

fhir-database-utils/src/main/java/com/ibm/fhir/database/utils/model/ColumnDefBuilder.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,11 @@ protected List<ColumnBase> buildColumns() {
156156
column = new DoubleColumn(cd.getName(), cd.isNullable());
157157
break;
158158
case TIMESTAMP:
159-
column = new TimestampColumn(cd.getName(), cd.isNullable());
159+
if (cd.getPrecision() == null) {
160+
column = new TimestampColumn(cd.getName(), cd.isNullable());
161+
} else {
162+
column = new TimestampColumn(cd.getName(), cd.isNullable(), cd.getPrecision());
163+
}
160164
break;
161165
case VARCHAR:
162166
if (cd.getSize() > Integer.MAX_VALUE) {

fhir-database-utils/src/main/java/com/ibm/fhir/database/utils/model/Table.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,19 @@ public Builder addTimestampColumn(String columnName, boolean nullable) {
261261
columns.add(cd);
262262
return this;
263263
}
264+
265+
public Builder addTimestampColumn(String columnName, int numberOfFractionalSecondDigits, boolean nullable) {
266+
ColumnDef cd = new ColumnDef(columnName);
267+
if (columns.contains(cd)) {
268+
throw new IllegalArgumentException("Duplicate column: " + columnName);
269+
}
270+
271+
cd.setNullable(nullable);
272+
cd.setColumnType(ColumnType.TIMESTAMP);
273+
cd.setPrecision(numberOfFractionalSecondDigits);
274+
columns.add(cd);
275+
return this;
276+
}
264277

265278
public Builder addVarcharColumn(String columnName, int size, boolean nullable) {
266279
ColumnDef cd = new ColumnDef(columnName);
@@ -498,7 +511,11 @@ protected List<ColumnBase> buildColumns() {
498511
column = new DoubleColumn(cd.getName(), cd.isNullable());
499512
break;
500513
case TIMESTAMP:
501-
column = new TimestampColumn(cd.getName(), cd.isNullable());
514+
if (cd.getPrecision() == null) {
515+
column = new TimestampColumn(cd.getName(), cd.isNullable());
516+
} else {
517+
column = new TimestampColumn(cd.getName(), cd.isNullable(), cd.getPrecision());
518+
}
502519
break;
503520
case VARCHAR:
504521
if (cd.getSize() > Integer.MAX_VALUE) {

fhir-database-utils/src/main/java/com/ibm/fhir/database/utils/model/TimestampColumn.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,23 @@
1212
* Timestamp Column
1313
*/
1414
public class TimestampColumn extends ColumnBase {
15-
1615
/**
17-
* @param name
16+
* The number of fractional second decimals to store or null to use the database's default
1817
*/
18+
private final Integer precision;
19+
1920
public TimestampColumn(String name, boolean nullable) {
2021
super(name, nullable);
22+
this.precision = null;
23+
}
24+
25+
public TimestampColumn(String name, boolean nullable, int precision) {
26+
super(name, nullable);
27+
this.precision = precision;
2128
}
2229

2330
@Override
24-
public String getTypeInfo(IDatabaseTypeAdapter translator) {
25-
return "TIMESTAMP";
31+
public String getTypeInfo(IDatabaseTypeAdapter adapter) {
32+
return adapter.timestampClause(precision);
2633
}
27-
2834
}

fhir-persistence-schema/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
/derby/
22
/derby.log
33
/bin/
4+
/fhirschema.log
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* (C) Copyright IBM Corp. 2019
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
package com.ibm.fhir.schema.app;
8+
9+
import com.ibm.fhir.database.utils.common.PrintTarget;
10+
11+
import com.ibm.fhir.database.utils.db2.Db2Adapter;
12+
import com.ibm.fhir.database.utils.model.PhysicalDataModel;
13+
import com.ibm.fhir.schema.control.FhirSchemaGenerator;
14+
15+
/**
16+
* A simple main method for printing the DDL of the FHIR Server.
17+
* For real work, use {@link Main}.
18+
*/
19+
public class SimpleSchemaPrinter {
20+
private static final String SCHEMA_NAME = "FHIRAPP";
21+
private static final String ADMIN_SCHEMA_NAME = "FHIRADMIN";
22+
23+
public static void main(String[] args) {
24+
// Create an instance of the service and use it to test creation
25+
// of the FHIR schema
26+
FhirSchemaGenerator gen = new FhirSchemaGenerator(ADMIN_SCHEMA_NAME, SCHEMA_NAME);
27+
PhysicalDataModel model = new PhysicalDataModel();
28+
gen.buildSchema(model);
29+
30+
// Print the statements instead of executing them against a database
31+
PrintTarget tgt = new PrintTarget(null, true);
32+
33+
// Pretend that our target is a DB2 database
34+
Db2Adapter adapter = new Db2Adapter(tgt);
35+
model.apply(adapter);
36+
}
37+
}

fhir-persistence-schema/src/main/java/com/ibm/fhir/schema/control/FhirSchemaGenerator.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -435,9 +435,9 @@ public void addResourceDateValues(PhysicalDataModel model) {
435435
Table tbl = Table.builder(schemaName, tableName)
436436
.setTenantColumnName(MT_ID)
437437
.addIntColumn( PARAMETER_NAME_ID, false)
438-
.addTimestampColumn( DATE_VALUE, true)
439-
.addTimestampColumn( DATE_START, true)
440-
.addTimestampColumn( DATE_END, true)
438+
.addTimestampColumn( DATE_VALUE,6, true)
439+
.addTimestampColumn( DATE_START,6, true)
440+
.addTimestampColumn( DATE_END,6, true)
441441
.addBigIntColumn(LOGICAL_RESOURCE_ID, false)
442442
.addIndex(IDX + tableName + "_PVR", PARAMETER_NAME_ID, DATE_VALUE, LOGICAL_RESOURCE_ID)
443443
.addIndex(IDX + tableName + "_RPV", LOGICAL_RESOURCE_ID, PARAMETER_NAME_ID, DATE_VALUE)

0 commit comments

Comments
 (0)