Tutorial 24: Datasource Snapshot Mechanism

This tutorial explains how to benefit from the datasource snapshot mechanism in Formspider. You will discover why you need this mechanism and how to use it by taking, loading and deleting snapshots for specific datasources.

What’s a snapshot in Formspider?

In Formspider the snapshot concept represents the state of a Formspider datasource at a particular point in time. Taking the snapshot of a datasource stores a copy of this datasource (with the information of all rows that are created, edited or deleted) at this particular time. You can take as many snapshots as you want of the same datasource.

Snapshots are stored in a stack data structure by Formspider. Therefore, loading the snapshot of a datasource restores the last snapshot taken, if available.

You can also delete all snapshots taken from a specific datasource any time.

In this tutorial you will create a basic application with a grid containing data provided by a datasource. You will discover how to take snapshots of a datasource and store them for further use, how to load them to restore a previous state of the datasource and how to delete them.

You may click here to run the completed application.

Open Formspider IDE and click “New Application” under the “File” menu. The “New Application” dialog will show up. Enter “snapshotMechanism” as the name of the application and “HR” as its Datasource Schema name.  If you are using Formspider Online, you do not need to enter database schema name since your account is already configured to use your online database. Leave other fields empty and click “OK”. This creates the “snapshotMechanism” application with a default mainframe (called “mainFrame”) and a default panel (called “mainPanel”).

Creating the Model

As the second step, you will create the necessary Datasource Definition (DSD) for your grid.
Expand the Datasource Definitions accordion, select the Datasource Definitions node and click the “+” button. Alternatively, you may right click the “Datasource Definitions” node and select “New” from the pop up menu. The “New Datasource Definition” Dialog will show up. Ensure that the “Table” radio button is selected and pick “EMPLOYEES” table from the combo box. Note that the combo box shows a list of all tables in your Datasource Schema “HR”. Also ensure that the “Create Datasource” checkbox is ticked. Please note that the Formspider IDE automatically assigned the name “EMPLOYEES” to your DSD and picked the “EMPLOYEE_ID” as its Primary Key.

Filling properties of the Employees DSD.

Click OK to save and close the “New Datasource Definition” dialog. This will create the “EMPLOYEES” DSD and the “EMPLOYEES1″ datasource. You will use the “EMPLOYEES1” datasource as the datasource of your grid.

Creating the User Interface

Double click the “mainPanel” under the “Panels” node of the “Containers” navigation tree to open it in the editor. Your panel will contain a grid displaying “First Name”, “Last Name”, “Hire Date”, “E-mail”, “Phone Number” and “Salary” information of the employees using “EMPLOYEES1” datasource that you have created recently. Also you will add three buttons labeled “Take Snapshot”, “ Load Snapshot” and “Delete Snapshots” for taking, loading and deleting snapshots of “EMPLOYEES1” datasource and two buttons labeled as “Create Row” and “Delete Row” for creating new rows in the “EMPLOYEES1” datasource and deleting row from the same. Your panel XML will look like;

<panel>
  <tableLayout cellSpacing="10">
    <row height="200">
      <cell columnSpan="3" hAlign="Full" vAlign="Full">
        <grid dataSource="EMPLOYEES1">
          <column headerLabel="First Name">
            <textField column="FIRST_NAME"/>
          </column>
          <column headerLabel="Last Name">
            <textField column="LAST_NAME"/>
          </column>
          <column headerLabel="Hire Date">
            <dateField dateFormat="DD/MM/YYYY" column="HIRE_DATE"/>
          </column>
          <column headerLabel="Email">
            <textField column="EMAIL"/>
          </column>
          <column headerLabel="Phone Number">
            <textField column="PHONE_NUMBER"/>
          </column>
          <column headerLabel="Salary">
            <textField column="SALARY"/>
          </column>
        </grid>
      </cell>
    </row>
    <row height="20">
      <cell hAlign="Center" childWidth="120">
        <button label="Take Snapshot"/>
      </cell>
      <cell hAlign="Center" childWidth="120">
        <button label="Load Snapshot"/>
      </cell>
      <cell hAlign="Center" childWidth="120">
        <button label="Delete Snapshots"/>
      </cell>
    </row>
    <row height="20">
      <cell hAlign="Center" childWidth="120">
        <button label="Create Row"/>
      </cell>
      <cell hAlign="Center" childWidth="120">
        <button label="Delete Row"/>
      </cell>
      <cell/>
    </row>
  </tableLayout>
</panel>

When “Take Snapshot” button is pressed you will take a snapshot of your “EMPOYEES1” datasource. To accomplish this you have to create a Formspider action which will be fired when “Take Snapshot” button is pressed.

In your datasource schema, create a package called  “snapshotMechanism_pkg” and open your newly created “snapshotMechanism_pkg” package in your favorite PL/SQL Editor. Add a procedure named “takeSnapshot” and ensure that the procedure is exposed in the package specification. This procedure uses api_datasource.takesnapshot API to take snapshot of “EMPLOYEES1” datasource.

procedure takeSnapshot is
begin
  api_datasource.takesnapshot('EMPLOYEES1');
end;

In Formspider IDE expand the “Actions” accordion, select the “Actions” node, click the “+” button to create a new action. Alternatively you may right click the “Actions” node and select “New” from the pop-up menu. The “New Action” dialog will show up. Enter “takeSnapshot” as the action name and “snapshotmechanism_pkg.takeSnapshot” as the procedure. Click “OK” to save your action.

Creating “takeSnapshot” action

Open the “mainpanel” in the editor. Add a buttonPress event to the “Take Snapshot” button triggering the “takeSnapshot” action, the panel XML should look like;

<panel>
  <tableLayout cellSpacing="10">
    <row height="200">
      <cell columnSpan="3" hAlign="Full" vAlign="Full">
        <grid dataSource="EMPLOYEES1">
          <column headerLabel="First Name">
            <textField column="FIRST_NAME"/>
          </column>
          <column headerLabel="Last Name">
            <textField column="LAST_NAME"/>
          </column>
          <column headerLabel="Hire Date">
            <dateField dateFormat="DD/MM/YYYY" column="HIRE_DATE"/>
          </column>
          <column headerLabel="Email">
            <textField column="EMAIL"/>
          </column>
          <column headerLabel="Phone Number">
            <textField column="PHONE_NUMBER"/>
          </column>
          <column headerLabel="Salary">
            <textField column="SALARY"/>
          </column>
        </grid>
      </cell>
    </row>
    <row height="20">
      <cell hAlign="Center" childWidth="120">
        <button label="Take Snapshot">
          <events>
            <buttonPress action="takeSnapshot"/>
          </events>
        </button>
      </cell>
      <cell hAlign="Center" childWidth="120">
        <button label="Load Snapshot"/>
      </cell>
      <cell hAlign="Center" childWidth="120">
        <button label="Delete Snapshots"/>
      </cell>
    </row>
    <row height="20">
      <cell hAlign="Center" childWidth="120">
        <button label="Create Row"/>
      </cell>
      <cell hAlign="Center" childWidth="120">
        <button label="Delete Row"/>
      </cell>
      <cell/>
    </row>
  </tableLayout>
</panel>

Next you will create a procedure named “loadSnaphot” which will be used when “Load Snapshot” button is pressed.

Open “snapshotMechanism_pkg” package and create the “loadSnapshot” procedure, this procedure uses api_datasource.loadsnapshot API to restore the last snapshot taken from “EMPLOYEES1” datasource.

procedure loadSnapshot is
begin
  api_datasource.loadSnapshot('EMPLOYEES1');
end;

Next, create a procedure named “deleteSnapshots” which will be used when “Delete Snapshots” button is pressed. This procedure uses api_datasource.clear API to provide delete functionality. The “api_datasource.clearSnapshots” value indicates that only snapshots will be cleared from “EMPLOYEES1” datasource.

procedure deleteSnapshots is
begin
  api_datasource.clear('EMPLOYEES1', api_datasource.clearSnapshots);
end;

Next, add two procedures for creating and deleting row from “EMPLOYEES1” datasource. The purpose of these procedures are experimenting how the snapshot mechanism stores the information deleted and added rows.

procedure createRow is
  v_row_id number;
begin
  v_row_id := api_datasource.createRow('EMPLOYEES1');
end;
procedure deleteRow is
begin
  if api_datasource.getCurrentRowID('EMPLOYEES1') is not null then
    api_datasource.deleteRow('EMPLOYEES1');
  end if;
end;

In order to use these procedures when the buttons are pressed you will create a Formspider action for each of these newly created procedures.

Create a new action and enter “loadSnapshot” as the action name and “snapshotMechanism_pkg.loadSnapshot” as the procedure. Click “OK” to save your action.

Create a new action and enter “deleteSnapshots” as the action name and “snapshotMechanism_pkg.deleteSnapshots” as the procedure. Click “OK” to save your action.

Create a new action and enter “createRow” as the action name and “snapshotMechanism_pkg.createRow” as the procedure. Click “OK” to save your action.

Create a new action and enter “deleteRow” as the action name and “snapshotMechanism_pkg.deleteRow” as the procedure. Click “OK” to save your action.

Finally, double click the “mainPanel” to open it in the editor and add buttonPress events to the “Load Snapshot”,“Delete Snapshots”, “Create Row” and “Delete Row” buttons triggering the “loadSnapshot”,“deleteSnapshots”, “createRow” and “deleteRow” actions;

<panel>
  <tableLayout cellSpacing="10">
    <row height="200">
      <cell columnSpan="3" hAlign="Full" vAlign="Full">
        <grid dataSource="EMPLOYEES1">
          <column headerLabel="First Name">
            <textField column="FIRST_NAME"/>
          </column>
          <column headerLabel="Last Name">
            <textField column="LAST_NAME"/>
          </column>
          <column headerLabel="Hire Date">
            <dateField dateFormat="DD/MM/YYYY" column="HIRE_DATE"/>
          </column>
          <column headerLabel="Email">
            <textField column="EMAIL"/>
          </column>
          <column headerLabel="Phone Number">
            <textField column="PHONE_NUMBER"/>
          </column>
          <column headerLabel="Salary">
            <textField column="SALARY"/>
          </column>
        </grid>
      </cell>
    </row>
    <row height="20">
      <cell hAlign="Center" childWidth="120">
        <button label="Take Snapshot">
          <events>
            <buttonPress action="takeSnapshot"/>
          </events>
        </button>
      </cell>
      <cell hAlign="Center" childWidth="120">
        <button label="Load Snapshot">
          <events>
            <buttonPress action="loadSnapshot"/>
          </events>
        </button>
      </cell>
      <cell hAlign="Center" childWidth="120">
        <button label="Delete Snapshots">
          <events>
            <buttonPress action="deleteSnapshots"/>
          </events>
        </button>
      </cell>
    </row>
    <row height="20">
      <cell hAlign="Center" childWidth="120">
        <button label="Create Row">
          <events>
            <buttonPress action="createRow"/>
          </events>
        </button>
      </cell>
      <cell hAlign="Center" childWidth="120">
        <button label="Delete Row">
          <events>
            <buttonPress action="deleteRow"/>
          </events>
        </button>
      </cell>
      <cell/>
    </row>
  </tableLayout>
</panel>

Experimenting with the Snapshot Mechanism

Run your application, you will see that the data provided by your datasource “EMPLOYEES1” is displayed in the grid.

You may click here to run the application.

Created Application is running

Taking and Loading Snapshots

1. Press “Take Snapshot” button without doing any changes on the grid, now you store a copy of original data.

2. Edit the email information for the employees named “Steven King” and “Neena Kochar”, enter “unknown” as value and than press “Take Snapshot” button again. Now you have a second copy of this datasource containing edited data this time.

3. Next, click to the row belonging to the employee named “Steven King” and press “Delete Row” button, the row is deleted, press “Take Snapshot” button again. Now you have a third copy of your datasource.

4. Create a new row by pressing “Create Row“ button, notice that a new row is added to the bottom of the grid.

5. Press “Load Snapshot” button once. This will return your datasource back to the state of last taken snapshot, therefore the third snaphot will be loaded and your datasource will return from step 4 to the step 3, please notice that the row created in step 4 is disappeared.

6. Press “Load Snapshot” button again, your datasource will return to state reached in step 2, notice that the row for the employee named “Steven King” is added back to the top of your grid with “unknown” as email value.

7. Press “Load Snapshot” button again, this time your datasource will return to state reached in step 1, meaning the original state. Please notice that email information for the employees named “Steven King” and “Neena Kochar” returned back to their original values.

Deleting Snapshots

Repeat the steps one through four again and press “Delete Snapshots” button. This time since all of your snapshots that you have taken are deleted when you press “Load Snapshot” button there will be no change in your datasource.