Table Facet

  • A table facet is the rules about rows to be generated for a database table.

  • Use JdbcTableFacet.builder() to define a table facet.

  • The default number of rows is 1024.

Java package: guru.mikelue.foxglove.jdbc

Setting

Use DataSetting on table
var setting = new DataSetting()
    // Excludes any column with JDBCType of OTHER
    .excludeWhen(columnMeta -> columnMeta.jdbcType() == JDBCType.OTHER)
    // For any column with type of "VARCHAR", using the supplier
    .givenType(JDBCType.VARCHAR)
        .useSupplier(() -> sampleText + suffixSupplier.get())
    // For not-nullable SMALLINT columns, generating values between 2010 and 2020
    .columnMatcher(
        columnMeta -> columnMeta.jdbcType() == JDBCType.SMALLINT &&
            !columnMeta.properties().contains(Property.NULLABLE)
    )
        .useSupplier(gen().shorts().range((short)2010, (short)2020)::get);

var facet = JdbcTableFacet.builder(TABLE_CAR)
    // Uses the setting on the whole table
    .withSetting(setting)
    .numberOfRows(RANDOM_SIZE)
    .build();

Set number of rows

Fixed number of rows
var facet = JdbcTableFacet.builder(TABLE_CAR)
    .numberOfRows(RANDOM_SIZE)
    .build();
Bound range of a key column
// The range of cr_id is between 1000 and 1000 + RANDOM_SIZE - 1
var facet = JdbcTableFacet.builder(TABLE_CAR)
    .keyOfInt("cr_id").limit(1000, RANDOM_SIZE)
    .build();
Cartesian product across columns
// Generates 3 (brands) * 3 (years) = 9 rows
var facet = JdbcTableFacet.builder(TABLE_CAR)
    .cartesianProduct("cr_brand")
        .domain("Toyota", "Honda", "Ford")
    .cartesianProduct("cr_year")
        .domain(2020, 2021, 2022)
    .build();

Column generators

Fixed value
var facet = JdbcTableFacet.builder(TABLE_CAR)
    .numberOfRows(RANDOM_SIZE)
    .column("cr_color").fixed(sampleColor)
    .build();
Custom random values
// Generates random year between 2015 and 2025
var yearSupplier = gen().ints().range(2015, 2025);
var facet = JdbcTableFacet.builder(TABLE_CAR)
    .numberOfRows(RANDOM_SIZE)
    .column("cr_year").useSupplier(yearSupplier)
    .build();
Round robin values
// Round robin among BMW, Audi, and Mercedes
var facet = JdbcTableFacet.builder(TABLE_CAR)
    .numberOfRows(RANDOM_SIZE)
    .column("cr_brand")
        .roundRobin("BMW", "Audi", "Mercedes")
    .build();
Sequence number
// Generates license plate like CAR-01, CAR-02, ...
var sequence = new Int4SequenceSupplier(2, 2);
Supplier<String> plateSupplier = () -> String.format(
    "CAR-%02d",
    sequence.getAsInt()
);
var facet = JdbcTableFacet.builder(TABLE_CAR)
    .numberOfRows(RANDOM_SIZE)
    .column("cr_license_plate").useSupplier(plateSupplier)
    .build();
Null value(Instancio)
// Generates colors(red, blue, green, or NULL) and 1/6 odds to be null
var colorSupplier = gen().oneOf("red", "blue", "green")
    .nullable();
var facet = JdbcTableFacet.builder(TABLE_CAR)
    .numberOfRows(ROWS)
    .column("cr_color").useSupplier(colorSupplier)
    .build();
Null value(customize odds)
// Generates colors(red, blue, green, or NULL) and 50% chance to be null
var colorSupplier = Suppliers.rollingSupplier(
    gen().oneOf("red", "blue", "green"), 2
);
var facet = JdbcTableFacet.builder(TABLE_CAR)
    .numberOfRows(ROWS)
    .column("cr_color").useSupplier(colorSupplier)
    .build();

Referencing another table

Referencing(control number of rows)
// Prepares parent facet
var carFacet = JdbcTableFacet.builder(TABLE_CAR)
    .numberOfRows(RANDOM_SIZE)
    .build();

// Generates rows referencing to the parent facet.
// The number of features is equal to "RANDOM_SIZE".
var featureFacet = JdbcTableFacet.builder(TABLE_CAR_FEATURE)
    .referencing("cf_cr_id").parent(carFacet, "cr_id")
        // Every car is referenced by one feature.
        .cardinality(1)
    .column("cf_feature_name")
        .fixed("Sunroof")
    .build();
Use values of another table as domain
// Prepares parent facet
var carFacet = JdbcTableFacet.builder(TABLE_CAR)
    .numberOfRows(RANDOM_SIZE)
    .column("cr_color")
        .roundRobin("Red", "Blue", "Green")
    .build();

var carArchivedFacet = JdbcTableFacet.builder(TABLE_CAR_ARCHIVED)
    .numberOfRows(10)
    // Has no effect on the number of rows
    .column("ca_color")
        .from(carFacet, "cr_color")
        // Chooses the values of cars' colors randomly
        .random()
    .build();

See Many-to-Many relationship for more examples about referencing another table.

After generation hook

Change generated rows
var facet = JdbcTableFacet.builder(TABLE_CAR)
    .numberOfRows(RANDOM_SIZE)
    .column("cr_brand")
        .roundRobin("Toyota", "Honda", "Ford", "BMW", "Audi")
    // Sets the value of "cr_license_plate" by combination of "cr_brand" and a random number
    .onTupleGenerated(tuple -> tuple.setValue(
        "cr_license_plate",
        tuple.getValue("cr_brand") + "-" + randomNumber.get()
    ))
    .build();

References

  • Table Facet - Defines logics for generating data for a specific table.

  • Settings - Defines logics for generating data by data type, etc.

  • InstancioGenApi - For generating random values.