Using InterBase XE7 Change Views with Visual Studio

Posted by on in Data

 

Using InterBase XE7 Change Views with Visual Studio

 

InterBase Change Views are a new “subscription based” model allowing you to “subscribe” to data; once subscribed you are able to ask the database at a later time, spanning connections, for what has changed.

You can download the demo here

 

For full detail on the InterBase XE7 Change View feature; http://docwiki.embarcadero.com/InterBase/XE7/en/Change_Views

And for other great resources.

https://delphiaball.co.uk/2015/03/06/interbase-change-views-example-demo-skill-sprint/

https://delphiaball.co.uk/2015/02/06/interbase-change-views-part-1/

https://delphiaball.co.uk/2015/02/06/interbase-change-views-part-2-creating-change-view/

https://delphiaball.co.uk/2015/02/07/using-interbase-change-views/

These are the steps that I used to create an application with Microsoft Visual Studio 2013 and using the NEW InterBase XE7 Change View feature to sync the changes between 2 databases.

  1. Install InterBase XE7

  2. Install the InterBase ODBC driver

  3. Run a script to create both the local and remote databases that have the new InterBase XE7 Change View feature that contain subscriptions

  4. Create an ODBC data source for the local database

  5. Create an ODBC data source for the remote database

  6. Create a new Visual Studio Project C# Windows Form Application

  7. Add Components to your form

  8. Connect to both Databases

  9. Edit your Data

  10. See the changes

  11. Merge the data

Install InterBase XE7

Registered Users can download the InterBase XE7 installer here -The free Trial is available here

Install the InterBase ODBC driver

Registered users can download the InterBase ODBC installer here

Run a script to create both the local and remote databases that have the new InterBase XE7 Change View feature that contain subscriptions

The following is an InterBase SQL script that will create the sample database that is used in the Demo.

If you have never used isql to create a database here is a good link http://docwiki.embarcadero.com/InterBase/XE7/en/To_Run_a_SQL_Script_Using_the_Command-line_isql_Tool

CREATE DATABASE 'C:\SUB.IB'

USER 'SYSDBA' PASSWORD 'masterkey'

DEFAULT CHARACTER SET UTF8;

CREATE GENERATOR gen;

CREATE TABLE tab (

id DECIMAL(10,0) NOT NULL PRIMARY KEY,

name VARCHAR(20)

);

SET TERM ^ ;

CREATE TRIGGER tr_tab_before_ins FOR tab

ACTIVE BEFORE INSERT POSITION 0

AS

BEGIN

IF (NEW.id IS NULL) THEN

BEGIN

NEW.id = GEN_ID( gen, 1);

END

END

^

CREATE TRIGGER tr_tab_after_ins FOR tab

ACTIVE AFTER INSERT POSITION 0

AS

BEGIN

POST_EVENT 'TAB';

END

^

CREATE TRIGGER tr_tab_after_upd FOR tab

ACTIVE AFTER UPDATE POSITION 0

AS

BEGIN

POST_EVENT 'TAB';

END

^

CREATE TRIGGER tr_tab_after_del FOR tab

ACTIVE AFTER DELETE POSITION 0

AS

BEGIN

POST_EVENT 'TAB';

END

^

SET TERM ; ^

CREATE SUBSCRIPTION subinsertup ON tab FOR ROW (INSERT, UPDATE);

CREATE SUBSCRIPTION subdelete ON tab FOR ROW (INSERT, UPDATE);

INSERT INTO tab (name) VALUES ('aaa');

INSERT INTO tab (name) VALUES ('bbb');

INSERT INTO tab (name) VALUES ('ccc');

SET SUBSCRIPTION SUBDELETE ACTIVE;

select * from tab;

SET SUBSCRIPTION SUBDELETE INACTIVE;

SET SUBSCRIPTION SUBINSERTUP ACTIVE

select * from tab;

After running the script, copy the database C:\Sub.ib to c:\Sub2.ib to be used as the remote database for demonstration purposes.

Create an ODBC data source for the local database

image001

Create an ODBC data source for the remote database

image003

Create a new Visual Studio Project C# Windows Form Application

In Visual Studio select File->New->Visual C# -> Widows Forms Application

This will create a blank Windows Application.

image005

Add Components to your form

The DataGridView control provides a great way to display data in a tabular format.

View->Toolbox and type DataGridView. We will add 4 of these components for displaying our different Datasets and subscriptions.

image007

The 4 DataGridViews will be for

  1. The Local Dataset

  2. The Remote Dataset

  3. The Subscription that tracks Inserts and Updates

  4. The Subscription that tracks Deletes

In Addition to the DataGridViews, this Demo will use 3 Buttons and one BindingNavigator Component. We will bind the BindingNavigator Component to the Local Dataset to allow for easy updates, inserts and deletes to the Data.

The 3 Buttons will be for

  1. Opening our databases

  2. Committing the Edit from the Local Dataset and viewing the Changes

  3. Merging the data to our remote Dataset

image009

Connect to both Databases

Because we already setup our ODBC Data Sources earlier connecting to our 2 Databases will be simple.

First we will set up simple methods to connect to our DataSources

public OdbcConnection getConnection()

{

OdbcConnection c1 = new OdbcConnection("DSN=SUBSCRIPTION");

return c1;

}

public OdbcConnection getRemoteConnection()

{

OdbcConnection c1 = new OdbcConnection("DSN=SUBSCRIPTIONREMOTE");

return c1;

}

Then will have our BtnOpen Click Event handler connect both Databases.

private void BtnOpen_Click(object sender, EventArgs e)

{

OdbcConnection c = new OdbcConnection();

c = getConnection();

OdbcDataAdapter DataAp1 = new OdbcDataAdapter("select * from tab order by ID", c);

DataAp1.Fill(dsOriginal, "tab");

bindingSource1.DataSource = dsOriginal.Tables[0];

DgOriginal.DataSource = bindingSource1;

bindingNavigator1.BindingSource = bindingSource1;

c.Close();

BtnOpenDb.Enabled = false;

dgRemote.Enabled = false;

GetRemote();

}

private void GetRemote(){

OdbcConnection remotecon = new OdbcConnection();

remotecon = getRemoteConnection();

OdbcDataAdapter datapRemote = new OdbcDataAdapter("select * from tab order by ID", remotecon);

dsRemote.Tables.Clear();

datapRemote.Fill(dsRemote);

bs.DataSource = dsRemote.Tables[0];

dgRemote.DataSource = bs;

remotecon.Close();

}



The local data is setup to be editable, while the remote database will be read only from the form.

Edit your Data

Use the Binding Navigator and the Local DataGridView to add, insert or update the data.

image011

See the changes

The Commit Button Click Event will commit the changes we have made and then read what has changed.

image013

private void btnCommit_Click(object sender, EventArgs e)

{

if (dsOriginal.HasChanges())

{

OdbcConnection c = getConnection();

OdbcDataAdapter DataAp1 = new OdbcDataAdapter();

DataAp1.SelectCommand = new OdbcCommand("select * from tab", c);

OdbcCommandBuilder builder = new OdbcCommandBuilder(DataAp1);

DataAp1.Update(dsOriginal, "tab");

c.Close();

DgDelete.Enabled = false;

DgUpdate.Enabled = false;

ReadData(getConnection(), "SubInsertUp", DgUpdate);

ReadData(getConnection(), "SubDelete", DgDelete);

}

else

{

MessageBox.Show("No Changes detected to orginal Dataset");

}

}

public void ReadData(DbConnection conn, String sqlstring, DataGridView dg)

{

string sqlSubscribe = "set subscription " + sqlstring +" active;";

string sqlCommit = "Commit;";

string sqlSelect = "Select * from TAB;";

conn.Open();

DbCommand cmd = conn.CreateCommand();

DbTransaction sqltrans = conn.BeginTransaction(IsolationLevel.RepeatableRead);

cmd.Transaction = sqltrans;

cmd.CommandText = sqlSubscribe;

cmd.ExecuteNonQuery();

cmd.CommandText = sqlSelect;

DbDataReader myreader = cmd.ExecuteReader();

dg.DataSource = myreader;

DataSet ds = new DataSet();

ds.Clear();

ds.Tables.Clear();

DataTable dt = new DataTable("TAB");

ds.Tables.Add(dt);

ds.Load(myreader, LoadOption.PreserveChanges, ds.Tables[0]);

// Load the DataGrid

dg.DataSource = ds.Tables[0];

myreader.Close();

cmd.CommandText = sqlCommit;

cmd.ExecuteNonQuery();

conn.Close();

}



Merge the data

Now that we see Changes, we can apply the Changes to our Remote Dataset. The record with ID 2 will be removed and the record with ID 5 will be added.

image015

private void btnMerge_Click(object sender, EventArgs e)

{

DataTable tbl1 = DgUpdate.DataSource as DataTable;

DataTable tbl2 = DgDelete.DataSource as DataTable;

MergeData(tbl1, "SubInsertUp");

MergeData(tbl2, "SubDelete");

GetRemote();

}

// MergeData will check if its an update/insert/ or delete and apply the proper sql command.

public void MergeData(DataTable dt, String sqlstring)

{

OdbcConnection c = getRemoteConnection();

c.Open();

DbCommand cmd1 = c.CreateCommand();

if (sqlstring.Equals("SubInsertUp"))

{

foreach (DataRow row in dt.Rows)

{

string id = row["ID"].ToString();

string name = row["NAME"].ToString();

cmd1.CommandText = "insert into TAB values( " + id + ", '" + name + "' )";

try

{

//check if its an update

cmd1.ExecuteNonQuery();

}

catch (Exception ex)

{

}

finally

{

//execute the update

cmd1.CommandText = "Update Tab set ID=" + id + ",Name='" + name + "' where id =" + id;

cmd1.ExecuteNonQuery();

}

}

}

else

{

foreach (DataRow row in dt.Rows)

{

string id = row["ID"].ToString();

string name = row["NAME"].ToString();

cmd1.CommandText = "delete from tab where ID =" + id;

try

{

cmd1.ExecuteNonQuery();

}

catch (Exception ex)

{

}

}

}

c.Close();

}

 





Comments

Check out more tips and tricks in this development video: