Goal: Generate (PostgreSQL) SQL table definition (DDL) from entities. The table definition is based on the entity name and the fields (the name, the type and the annotations).
First the name of the entity is converted to lower case and made plural (add a 's' at the end),
e.g. the Student
entity, becomes the students
table.
Second all Java types are converted to their respective SQL types, see table Mapping of types from Java to SQL . This relation is already given in the class TypeMappings
.
The annotations on the fields are converted into different types or into restrictions, see the list below.
-
@ID
should generate aSERIAL
(if the field is an integer) orBIGSERIAL
(if the field is a long) and have thePRIMARY KEY
attribute. -
@NotNull
should result in aNOT NULL
constraint. -
@Check
should copy the value (text) of the annotation as parameter to theCHECK
constraint. -
@Default
should copy the value as theDEFAULT
value. Quote the value where needed.
Java | SQL |
---|---|
java.lang.String |
TEXT |
java.lang.Character |
CHAR(1) |
java.lang.Integer |
INTEGER |
int |
INTEGER |
java.lang.Short |
SMALLINT |
short |
SMALLINT |
java.lang.Long |
BIGINT |
long |
BIGINT |
java.math.BigDecimal |
DECIMAL |
java.math.BigInteger |
NUMERIC |
java.lang.Float |
REAL |
float |
REAL |
java.lang.Double |
DOUBLE PRECISION |
double |
DOUBLE PRECISION |
java.time.LocalDate |
DATE |
java.time.LocalDateTime |
TIMESTAMP |
Given the entity below:
public class CourseModule {
@ID
private Integer moduleid;
@NotNull
String name;
@NotNull
@Default(value = "5")
@Check(value = "credits > 0")
Integer credits;
// extra ctor to make the default values take effect.
public CourseModule( Integer moduleid, String name ) {
this( moduleid, name, 5 );
}
}
The output should look like:
CREATE TABLE coursemodules (
moduleid SERIAL PRIMARY KEY,
name TEXT NOT NULL,
credits INTEGER NOT NULL DEFAULT (5) CHECK (credits > 0)
);
-
Start by implementing
GeneratorTestBase
-
Implement the
startWithCREATE
method-
Assert that the first line starts with
CREATE TABLE
-
Use the
tableDefinition
to get the first line
-
-
Implement the
tableName
method-
Assert that the correct table name is used in the
CREATE TABLE
statement -
Again use the
tableDefinition
to get the first line and assert thattableName
is present
-
-
Implement
assertTypeConversion
-
Use
SoftAssertions
-
Assert that the column for the given fieldname is present (
columnDefinition
) -
Assert that the column definition is as expected (
expectedDefinition
)
-
-
-
Implement
PGTableCreator
-
Start by implementing
createTable
-
Implement
processAnnotations
-
Use a
StringBuilder
to store the intermediate result -
Retrieve the annotations from the provided
field
-
To compare a retrieved
Annotation
with anAnnotation
, e.g.NotNull
you can useannotationType
to retrieve the class from theAnnotation
and then compare usingannotation.annotationType() == NotNull.class
-
Check the [annotations] rules
-
For the
@ID
annotation it might be easiest to override thepgTypeName
to the correct type
-
-
-