YAML Syntax

Why choose YAML as external representation of sample data for testing:

  1. The format could be edit by any of your favor editors.

  2. The format could be maintained in VCS.

  3. The alias of YAML, which benefits editing data of PK and FK on relational-database.

You may reference the sample YAML used in testing code of this framework


Tags

Every document should define namespace(tag) of YAML:

%TAG !jdut! tag:jdut.mikelue.guru:1.0/
%TAG !dbtype! tag:jdut.mikelue.guru:jdbcType:1.8/
%TAG !sql! tag:jdut.mikelue.guru:sql:1.0/

---
= 1st document

---
= 2nd document

By the implementation of YamlConductorFactory, every document in YAML would be an instance of DuetConductor.


Structure

A document is defined by:

defines(optional)

You could defines the aliases with this map(the engine would ignore this node).

config(optional)

Configuration for processing of data defined in this document

!sql!table! <table_name>(multiple)

Data definitions

  • For example: !sql!table yp_book, !sql!table yp_vendor

!sql!code(multiple)

Native SQL statement if you like to execute SQL to database directly

defines

In this node, there is nothing to be processed, you may use this node to define alias.

- defines : [
    &id_1 1,
    &id_2 2
]

config

The configuration for data processing.

  • build_operation(!!str): The operation for building data.

    • build-in operators: See Guidelines(default value: INSERT)

  • clean_operation(!!str): The operation for cleaning data.

    • value domain: As same as build_operation(default value: DELETE)

  • decorator(!!str) - The name of decorator for every data grain

  • transaction(!!bool): Use the transaction function of JDBC for processing data

    • value domain:

      • true - Use transaction

      • false(default value) - Not use transaction

  • transaction_isolation(!!str): Set the transaction isolation over JDBC

- config : {
    build_operation: "REFRESH",
    clean_operation: "DELETE",
    decorator: "decorator_name",
    transaction: false,
    transaction_isolation: "REPEATABLE_READ"
}

!sql!table

This node represents the data to be update into database.

  1. Override the configuration defined at document-level

  2. Set default name of columns

  3. Set default usage of key to target row to be updated or deleted

    config(optional)

    The configuration section for this table

    • build_operation - The name of operator for building

    • clean_operation - The name of operator for cleaning

    • decorator: The decorator chains after the global one to decorate this data grain

    columns(mandatory if you like to use implicit data row)

    The columns for implicit data of row(by !!seq)

    keys(optional)

    The explicit definition for key(used by UPDATE, DELETE operator)

    data(mandatory)

    The data section for this table, as !!seq of YAML, see simple definition

- !sql!table tab_2 {
  # build/clean name of operation
  config : {
      build_operation: "INSERT",
      clean_operation: "DELETE",
      decorator: "tab_2_decorator"
  },
  # define keys for UPDATE/REFRESH/DELETE
  keys : [ "id_1" ]
  # defines implicit columns
  columns: [ "col_1", "col_2", "col_3", "col_4" ]
  # defines data(implicit or explicit definition are both working)
  data : [
      { col_1: 20, col_2: 40, col_3: "Thing" },
      [ "c1", 20, 40, 50 ]
  ]
}

!jdut!supplier

The engine supports the value of column from lambda expression(Supplier).

!jdata-unit-test:value,1.0:supplier(!jdut!supplier)

The name which is registered with a instance of Supplier

%TAG !jdut! tag:jdut.mikelue.guru:1.0/
%TAG !dbtype! tag:jdut.mikelue.guru:jdbcType:1.8/
%TAG !sql! tag:jdut.mikelue.guru:sql:1.0/

'''
- !sql!table tab_3 : [
  {
    col_2: !jdut!supplier "value_1",
  }
]
YamlConductor.build(
    builder -> builder
        .namedSupplier("value_1", () -> 30);
);

!sql!code

build_operation

The operation while executing DuetConductor.build

clean_operation

The operation while executing DuetConductor.clean

!sql!statement

indicates that the text is a SQL statement to be executed by Statement.executeUpdate().

!sql!jdbcfunction

indicates that the text is the name of a JdbcFunction

You don’t have to provide both of the two operations in !sql!code node

- !sql!code
  build_operation: !sql!statement
    INSERT INTO tab_1(col_1, col_2, col_3)
    VALUES(10, '3323', 20)
  clean_operation: !sql!statement
    DELETE tab_1 WHERE col_1 = 10

- !sql!code
  build_operation: !sql!jdbcfunction "func_1"
  clean_operation: !sql!jdbcfunction "func_1"
YamlConductor.build(
    builder -> builder
        .namedJdbcFunction(
            "func_1",
            (connection) -> {
                /* Your JDBC operations */
            }
        );
);

Named Operator

Also, following methods can override the configurations of factory:

= Document level configuration
- config : {
    build_operation: "insert_and_check"
}

- !sql!table tab_1 {
    config : {
        // Overrides the one assigned in document level
        build_operation: "insert_and_check"
    }
    data : [
        # data ....
    ]
}
YamlConductorFactory.build(
    dataSource,
    builder -> builder
        .namedOperation(
            "insert_and_check",
            (connection, dataRows) -> {
                /* Your JDBC operations */
            }
        );
);

Named Decorator

Also, following methods can override the configurations of factory:

- config : {
    decorator: "coffee_decorate",
}
YamlConductorFactory.build(
    dataSource,
    builder -> builder
        .namedDecorator(
            "value_1",
            (tableDef, data) -> {
                /* Your decoration of data grain */
            }
        );
);

Quick example

%TAG !jdut! tag:jdut.mikelue.guru:1.0/
%TAG !dbtype! tag:jdut.mikelue.guru:jdbcType:1.8/
%TAG !sql! tag:jdut.mikelue.guru:sql:1.0/

---
= Skipped processing for alias usage
- defines : [
    &v1 20,
    &v2 40
]

- config : {
    build_operation: "INSERT",
    clean_operation: "DELETE"
}

- !sql!table tab_1 : [
  { col_1: 10, col_2: "String Value", col_3: !!Timestamp "2010-05-05 10:20:35+08" },
]

- !sql!table tab_2 : {
  columns : [ "col_id", "col_name" ]
  data : [
    [10, "v1"],
    [20, "v2"],
    { col_id: 30, col_name: "new-name"},
  ]
}

- !sql!code
  build_operation: !sql!statement
    INSERT INTO tab_1(col_1, col_2, col_3)
    VALUES(10, '3323', 20)
  clean_operation: !sql!statement
    DELETE tab_1 WHERE col_1 = 10

- !sql!code {
    build_operation: !sql!jdbcfunction "func_1",
    clean_operation: !sql!jdbcfunction "func_2"
}