= Database Access Layer =

This module defines an API for accessing the database.

The main entry point is the DbFacade class which is a singleton
factory for accessing Database Access Objects (DAO) e.g.

  VDS vds = DbFacade.getInstance().getVdsDAO().get(vdsId);

== Unit Tests ==

WARNING: the unit tests empty the database tables before running.
Please do not run these tests against a database with valuable
data. Please also make sure that the database has been updated
to the latest schema before running the tests.

The DAO interfaces have a significant number of unit tests. These are
disabled by default because they require a local database to be
configured. However, the tests are run in our Jenkins continuous
integration builds and reports are emailed if a regression is
introduced.

To run the DAO tests manually you can either do:

  $> mvn -P enable-dao-tests test

or enable them using your ~/.m2/settings.xml:

   <activeProfiles>
     <activeProfile>enable-dao-tests</activeProfile>
   </activeProfiles>

You can also choose to run individual tests:

  $> mvn -D test=VdcOptionDAOTest test

By default, this will run the tests using the JDBC implementation
against a PostgreSQL database called 'engine-dao-tests' on the
localhost using the username 'engine' and password 'engine'.

You can change the database configuration in ~/.m2/settings.xml e.g.

  <profile>
    <id>my-engine-db</id>
    <activation>
      <activeByDefault>true</activeByDefault>
    </activation>
    <properties>
      <engine.db.username>foo</engine.db.username>
      <engine.db.password>bar</engine.db.password>
      <engine.db.url>jdbc:postgresql://my-db-host/mydb</engine.db.url>
      <engine.db.url.escaped>jdbc:postgresql://localhost/mydb</engine.db.url.escaped>
      <engine.db.driver>org.postgresql.Driver</engine.db.driver>
    </properties>
  </profile>

== More on Impl DAOs ==

Most methods in these classes execute a stored procedure (see
packaging/dbscripts/*_sp.sql) using the supplied parameters and
return the results from it.

These methods are implemented with Spring Framework's JDBC library.

There are three parts to each Java method:

 1) The parameter source:

      public VDS get(Guid id) {
          MapSqlParameterSource parameterSource = new CustomMapSqlParameterSource()
                  .addValue("vds_id", vds_id);

     which adds the parameters required by the GetVdsByVdsId stored
     procedure in vds_sp.sql:


       Create or replace FUNCTION GetVdsByUniqueID(v_vds_unique_id VARCHAR(128)) RETURNS SETOF vds STABLE
          AS $procedure$

 2) The row mapper:

        RowMapper<VDS> mapper = new RowMapper<VDS>() {
            public VDS mapRow(ResultSet rs, int rowNum) throws SQLException {
                VDS entity = new VDS();
                entity.setvds_id(rs.getInt("vds_id"));
                entity.setcluster_id(rs.getInt("cluster_id"));
                entity.setcluster_name(rs.getString("cluster_name"));
                entity.setcluster_description(rs.getString("cluster_description"));
                ...
                return entity;
            }
        };

    which maps a row of result parameters to a new business entity
    instance. The result parameters in the mapper must match the results
    from the stored procedure:

                RETURN QUERY SELECT DISTINCT vds.*
                FROM vds
                WHERE vds_unique_id = v_vds_unique_id;

    CustomMapSqlParameterSource is a variant of MapSqlParameterSource
    which converts enums to ints and guids to strings.

 3) The call:

                return getCallsHandler().executeRead("GetVdsByVdsId",
                        VdsRowMapper.instance,
                        getCustomMapSqlParameterSource()
                               .addValue("vds_id", id));
