# Application updates

Application updates enable any 4app to execute sql or java code before the 4allportal startup. Updates are only execute once. Update files go as XML-files into the directory called "updates".

├── global
├── modules
└── updates
    ├── 100IT.xml
    ├── 101MS.xml
    ├── 104.xml
    └── ...

The file name and optional version and part is used as the update name properties from XML file used. All executed updates and their Status can be found in the module update_mngt.

The following instruction are supported:

The different update instructions can be stored in an update file can be combined.

# Add column

<upd version="1.1" priority="normal">
  <description>Add column test_column to table book</description>
  <add-column table="book">
    <column name="test_column" type="INTEGER" nulls="true"/>
  </add-column>
</upd>

# Add restriction

<upd version="20180819-0001">
  <add-constraint table="book_autor" name="FK_book_autor" refTable="book">
    <foreign_keys>
      <cols>
        <col>book</col>
      </cols>
    </foreign_keys>
    <ref_columns>
      <cols>
        <col>id_key</col>
      </cols>
    </ref_columns>
  </add-constraint>
</upd>

# Add index

<upd version="20100819-0001">
  <add-index table="autor" name="unique_autor_name_age" unique="true">
    <cols>
      <col>name</col>
      <col>age</col>
    </cols>
  </add-index>
</upd>

# Add primary key

<upd version="20100824-0004">
  <add-primary-key table="autor">
    <cols>
      <col>id_key</col>
      <col>name</col>
    </cols>
  </add-primary-key>
</upd>

# Create table

<upd version="20100824-0001">
  <create-table table="book">
    <columns>
      <column name="id_key" type="BIGINT" nulls="false" autoincrement="true" />
      <column name="name" type="TEXT" length="255" nulls="false" />
      <column name="create_date" type="datetime" nulls="true" />
      <column name="isbn" type="varchar" length="13" nulls="false" />
      <column name="change_date" type="datetime" nulls="true" />
      <column name="version" type="BIGINT" nulls="true" default="2" />
    </columns>
    <primary_key>
      <cols>
        <col>id_key</col>
      </cols>
    </primary_key>
  </create-table>
</upd>

# Remove column

<upd version="20100819-0001">
  <drop-column table="book">
    <column name="test_column" />
  </drop-column>
</upd>

# Remove restriction

<upd version="20100819-0001">
  <drop-constraint table="book_autor" name="FK_book_autor"/>
</upd>

# Remove index

<upd version="20100819-0001">
  <drop-index table="autor" name="unique_autor_name_age"/>
</upd>

# Remove primary key

<upd version="20100819-0001">
  <drop-primary_key table="autor" />
</upd>

# Delete table

<upd version="20100819-0001">
  <drop-table table="book_autor" />
</upd>

# Add entries

<upd version="20100913" part="101LO">
  <insert table="project_status_group_type">
    <rows>
      <row>
        <id_key>5</id_key>
        <enum_name>DRAFT</enum_name>
      </row>
      <row>
        <id_key>6</id_key>
          <enum_name>OBSOLETE</enum_name>
      </row>
      <row>
        <id_key>7</id_key>
          <enum_name>EXPIRED</enum_name>
      </row>
    </rows>
  </insert>
</upd>

# Change column

<upd version="20100819-0001">
  <modify-column table="mytest">
    <column name="id_key" type="BIGINT" nulls="true" autoincrement="true"/>
  </modify-column>
</upd>

# Rename column

<upd version="20101018" part="100LO">
  <rename-column table="mytable">
    <column name="ttt" newname="test"/>
  </rename-column>
</upd>

# Execute SQL script

<upd version="20100819-0001">
  <sql dbtype="mysql">
    <stmt>
      <![CDATA[
          UPDATE TABLE ´customer´
          SET ´password´ = MD5('crossmedia');
      ]]>
    </stmt>
    <stmt>
      <![CDATA[
          UPDATE TABLE ´user´
          SET ´change_password_on_login´ = '0';
      ]]>
    </stmt>
  </sql>
  <sql dbtype="sqlserver">
    <stmt>
      <![CDATA[
          UPDATE [customer]
          SET password = SUBSTRING(sys.fn_sqlvarbasetostr(HASHBYTES('MD5', 'crossmedia')),3,32)
      ]]>
    </stmt>
    <stmt>
      <![CDATA[
          UPDATE [user]
          SET [change_password_on_login] = '0'
      ]]>
    </stmt>
  </sql>
</upd>

# Execute Java function

<upd version="20190523-0001">
  <description>Java Test</description>
  <java classname="com.cm4ap.ce.update.JavaTestFunction">
    <args>
      <arg class="boolean">false</arg>
      <arg>arg2</arg>
      <arg class="long">25</arg>
    </args>
  </java>
</upd>
<upd version="20190523-0002" priority="high">
  <java classname="com.cm4ap.ce.update.JavaTestFunction" method="doUpdate">
    <args>
      <arg class="boolean">false</arg>
      <arg>arg2</arg>
      <arg class="long">25</arg>
    </args>
  </java>
</upd>

If method attributes are not specified, the Java class of com.cm4ap.ce.update.AppUpdate can be derived. The arguments are passed in the specified order to the specified Java function (method) or "doUpdate" function transferred. Additionally, objects such as Connection, CEConfig, IDatabaseDAO and UserPermission. Return value of the function is evaluated and if it is about update status, it is evaluated according to passed on. Furthermore, the constructor of the class CEConfig, IDatabaseDAO and UserPermission as arguments.

Warning

Because update instructions execute before the CoreEngine initialization, the CoreEngine functions are strongly limited.

# Status

  • INITIAL(0)
  • IN_PROGRESS(1)
  • FINAL_WARNING(2)
  • FINAL_SUCCESS(3)
  • ERROR(4)
  • SKIP(5)
  • FATAL_ERROR(6)

# Priority

  • LOW
  • NORMAL
  • HIGH

Warning

Updates configured with priority "HIGH" will cancel the CoreEngine startup if the update fails.

# com.cm4ap.ce.update.AppUpdate

package com.cm4ap.ce.update;

import java.sql.Connection;

public interface AppUpdate {
  UpdateStatus doUpdate(Connection con, Object... args);
}
Request missing documentation