|
|
Using data management to synchronize server updates
Data management features allow you to synchronize adding,
updating, and deleting of records in a database. Changes you make
in the client application are not written to the server until a
commit method is called. You can call a revert method to roll back
changes made in the client application.
Data management requires a data service that implements one or
more operations with the following signatures:
createItem(item:CustomDatatype):int
deleteItem(itemID:Number):void
updateItem((item: CustomDatatype):void
getItem(itemID:Number): CustomDatatype
CustomDatatype is a data type representing complex data
returned from the server. In server-side typing, the service defines
the custom data type. In client-side typing, use Flash Builder to
introspect the service and configure the custom data type.
Data Management (ColdFusion)The application you create in this tutorial accesses the fb_tutorial_db database.
For information on installing this database, see Installing the tutorial database
In this tutorial, you create an application that contains an
editable DataGrid displaying employee records. You can modify one
or more records in place in the DataGrid. You can also add or delete
selected records from the DataGrid. All the changes in the DataGrid
are local until you select a Save All Changes button that updates
the database.
Create the remote service and import it into a Flex projectIn your favorite ColdFusion editor, create a ColdFusion
service that implements the required data management functions.
<cfcomponent output="false">
<cffunction name="getAllItems" output="false" access="remote" returntype="any" >
<cfset var qAllItems="">
<cfquery name="qAllItems" datasource="fb_tutorial_db">
SELECT * FROM employees
</cfquery>
<cfreturn qAllItems>
</cffunction>
<cffunction name="getItem" output="false" access="remote" returntype="any" >
<cfargument name="itemID" type="numeric" required="true" />
<cfset var qItem="">
<cfquery name="qItem" datasource="fb_tutorial_db">
SELECT * FROM employees
WHERE emp_no = <CFQUERYPARAM CFSQLTYPE="CF_SQL_INTEGER" VALUE="#ARGUMENTS.itemID#">
</cfquery>
<cfreturn qItem>
</cffunction>
<cffunction name="createItem" output="false" access="remote" returntype="any" >
<cfargument name="item" required="true" />
<cfquery name="createItem" datasource="fb_tutorial_db" result="result">
INSERT INTO employees (first_name, last_name, gender, birth_date, hire_date)
VALUES (<CFQUERYPARAM cfsqltype="CF_SQL_VARCHAR" VALUE="#item.first_name#">,
<CFQUERYPARAM cfsqltype="CF_SQL_VARCHAR" VALUE="#item.last_name#">,
<CFQUERYPARAM cfsqltype="CF_SQL_VARCHAR" VALUE="#item.gender#">,
<CFQUERYPARAM cfsqltype="CF_SQL_DATE" VALUE="#item.birth_date#">,
<CFQUERYPARAM cfsqltype="CF_SQL_DATE" VALUE="#item.hire_date#">)
</cfquery>
<cfreturn result.GENERATED_KEY/>
</cffunction>
<cffunction name="updateItem" output="false" access="remote" returntype="void" >
<cfargument name="item" required="true" />
<cfquery name="updateItem" datasource="fb_tutorial_db">
UPDATE employees SET birth_date = <CFQUERYPARAM cfsqltype="CF_SQL_DATE"
VALUE="#item.birth_date#">,
hire_date = <CFQUERYPARAM cfsqltype="CF_SQL_DATE" VALUE="#item.hire_date#">,
gender = <CFQUERYPARAM cfsqltype="CF_SQL_VARCHAR" VALUE="#item.gender#">,
first_name = <CFQUERYPARAM cfsqltype="CF_SQL_VARCHAR" VALUE="#item.first_name#">,
last_name = <CFQUERYPARAM cfsqltype="CF_SQL_VARCHAR" VALUE="#item.last_name#">
WHERE emp_no = <CFQUERYPARAM CFSQLTYPE="CF_SQL_INTEGER" VALUE="#item.emp_no#">
</cfquery>
</cffunction>
<cffunction name="deleteItem" output="false" access="remote" returntype="void" >
<cfargument name="itemID" type="numeric" required="true" />
<cfquery name="delete" datasource="fb_tutorial_db">
DELETE FROM employees
WHERE emp_no = <CFQUERYPARAM CFSQLTYPE="CF_SQL_INTEGER" VALUE="#ARGUMENTS.itemID#">
</cfquery>
</cffunction>
</cfcomponent>
Save the service in the web root of your ColdFusion installation.
Name
the file EmployeeService.cfc and place it in a directory named DataMgtCF.
In Flash Builder, create a Flex project. Name the project
DataMgtCF and specify ColdFusion for the server technology as listed
below. Click Next.
Application Server Type: ColdFusion
Enable Use Remote Object Access Service
Select ColdFusion Flash Remoting
Validate your ColdFusion settings and specify the DataMgtCF
directory for the Output Folder. Click Finish.
From the Flash Builder Data menu, select Connect to Data
Service. Select ColdFusion and click Next.
Click Browse and navigate to the EmployeeService.cfc file
you created in step 1. Click Finish.
In the Flash Builder Data/Services view, from the context
menu for the getItem() operation, select Configure
Return Type.
Flash Builder needs to configure a custom data
type for data returned from the data service. By introspecting the getItem() operation,
you can define the custom data type Employee.
In the Configure Return Type dialog, Auto-Detect the Return
Type is selected by default. Click Next.
Specify a value and type for the parameter to the getItem() operation
as described below. Click Next:
Argument
|
Argument Type
|
Value
|
itemID
|
Number
|
10002
|
You need to supply valid parameters to
the operation for Flash Builder to introspect the operation. 10002
is a valid itemID.
Specify Employee in the Array Of field
toto define a custom type for returned data.
Flex uses custom
data types to access and update complex data types returned from
a server.
The Configure Return Type dialog displays the properties
of the data type returned by the service.
Click Finish to configure the Employee return type.
In the Flash Builder Data/Services view, from the context
menu for the getAllItems() operation, select Configure
Return Type.
Select Use an Existing Data Type. Select Employee from
the Array Of drop-down list. Click Finish.
Enable Data Management FeaturesIn the Data/Services view, expand the Data Types
node for EmployeeService and select the Employee data type.
From the context menu for the Employee data type, select
Enable Data Management.
In the Select Unique Identifier dialog, select emp_no and
click Next.
In the Map Database Operations dialog, specify the following
operations. Click Finish.
Create (Add) Operation:
createItem( item: Employee )
Get Item Operation: getItem( itemID: Number )
Update Operation: updateItem( item: Employee )
Delete Operation: deleteItem ( itemID: Number )
Data
management is now enabled for this operation. Flash Builder generates client
code that can update data using a combination of the mapped operations.
Create the application and add a DataGrid and ButtonsSelect Design to open the MXML editor in Design
mode.
From the Components view, drag a DataGrid component onto
the Design Area and place it near the top.
The DataGrid component
is available under Data Controls.
In the Properties view, with the DataGrid selected, specify
the following properties:
Property
|
Value
|
ID
|
dg
|
Editable
|
true
|
Drag four Buttons to the Design Area, lining them up beneath
the DataGrid.
Double-click each button to edit their labels. Provide the
following Labels:
Label
|
Add
|
Delete
|
Revert
|
Save All Changes
|
In the Data/Services view, select the getAllItems() operation
and drop it onto the DataGrid.
With the DataGrid selected, in the Properties view Click
Configure Columns and do the following:
Select emp_no
column. In the Data Binding area, deselect the editable check box.
emp_no
is a key field that is automatically generated by the database.
(Optional) Rename and rearrange the columns.
Generate event handlers for the ButtonsEach Button requires an event handler to specify the action
to take when the Button is clicked. Flash Builder generates stubs
for event handlers, which you can then code to specify the service
actions to take.
Select the Add button. Then, for the On Click field of
the Add button, click the Pencil icon and then select Generate Event
Handler.
The MXML editor changes to Source View, placing the
cursor in the generated event handler.
In the Script block, add the following import statement:
import services.employeeservice.EmployeeService;
import valueObjects.Employee;
In the event handler body, type the following:
var e:Employee = new Employee();
var birthDate:Date = new Date(2000, 01, 01);
var hireDate:Date = new Date(2000, 01, 01);
e.first_name = "New";
e.last_name = "New";
e.birth_date = birthDate;
e.hire_date = hireDate;
e.gender = "M";
dg.dataProvider.addItem(e);
dg.verticalScrollPosition = dg.dataProvider.length -1;
As
you type, Flash Builder content assist helps you view the available
methods and values.
Modify the DataGrid columns for birth_date and hire_date
to add a date chooser:
<mx:DataGridColumn headerText="birth_date" editorDataField="selectedDate"
dataField="birth_date" itemEditor="mx.controls.DateField"/>
<mx:DataGridColumn headerText="hire_date" editorDataField="selectedDate"
dataField="hire_date" itemEditor="mx.controls.DateField"/>
In Design mode, add an On Click event handler for the Delete
button and specify the following code:
employeeService.deleteItem(dg.selectedItem.emp_no);
Similarly, add an On Click event handler for the Revert button
with the following code:
employeeService.getDataManager(employeeService.DATA_MANAGER_EMPLOYEE).revertChanges();
Add an On click event handler for the Save All Changes button
with the following code:
employeeService.commit();
Save the application and select Run > Run DataMgtCF.
You
can update and delete selected employees in the DataGrid. You can
also add new employees.
When you add an employee, the Employee
Number defaults to zero. This is because the new employee has not
been updated on the server. When you click Save All Changes, the
new employee is added to the server. At that time, an Employee Number
is generated.
Click the Revert button to undo any changes
you made.
Click the Save All Changes button to write all
changes to the database.
Data Management (PHP)The application you create in this tutorial accesses the
employee database that you previously downloaded and installed.
In this tutorial, you create an application that contains an
editable DataGrid displaying employee records. You can modify one
or more records in place in the DataGrid, and also add or delete
selected records from the DataGrid. All the changes in the DataGrid
are local until you select a Save All Changes button, which updates
the database.
Create the remote service and import it into a Flex projectIn your favorite PHP editor, create a PHP service
class that implements the required data management functions.
<?php
class EmployeeService {
var $username = "root";
var $password = "";
var $server = "localhost";
var $port = "3306";
var $databasename = "fb_tutorial_db";
var $tablename = "employees";
var $connection;
public function __construct() {
$this->connection = mysqli_connect(
$this->server,
$this->username,
$this->password,
$this->databasename,
$this->port
);
$this->throwExceptionOnError($this->connection);
}
public function getAllEmployees() {
$stmt = mysqli_prepare($this->connection, "SELECT * FROM $this->tablename");
$this->throwExceptionOnError();
mysqli_stmt_execute($stmt);
$this->throwExceptionOnError();
$rows = array();
mysqli_stmt_bind_result($stmt, $row->emp_no, $row->birth_date,
$row->first_name, $row->last_name, $row->gender, $row->hire_date);
while (mysqli_stmt_fetch($stmt)) {
$rows[] = $row;
$row = new stdClass();
mysqli_stmt_bind_result($stmt, $row->emp_no, $row->birth_date,
$row->first_name, $row->last_name, $row->gender, $row->hire_date);
}
mysqli_stmt_free_result($stmt);
mysqli_close($this->connection);
return $rows;
}
public function getEmployeesByID($itemID) {
$stmt = mysqli_prepare($this->connection,
"SELECT * FROM $this->tablename where emp_no=?");
$this->throwExceptionOnError();
mysqli_bind_param($stmt, 'i', $itemID);
$this->throwExceptionOnError();
mysqli_stmt_execute($stmt);
$this->throwExceptionOnError();
mysqli_stmt_bind_result($stmt, $row->emp_no, $row->birth_date,
$row->first_name, $row->last_name, $row->gender, $row->hire_date);
if(mysqli_stmt_fetch($stmt)) {
return $row;
} else {
return null;
}
}
public function createEmployees($item) {
$stmt = mysqli_prepare($this->connection,
"INSERT INTO $this->tablename (emp_no, birth_date,
first_name, last_name, gender, hire_date) VALUES (?, ?, ?, ?, ?, ?)");
$this->throwExceptionOnError();
mysqli_bind_param($stmt, 'isssss', $item->emp_no, $item->birth_date,
$item->first_name, $item->last_name, $item->gender, $item->hire_date);
$this->throwExceptionOnError();
mysqli_stmt_execute($stmt);
$this->throwExceptionOnError();
$autoid = mysqli_stmt_insert_id($stmt);
mysqli_stmt_free_result($stmt);
mysqli_close($this->connection);
return $autoid;
}
public function updateEmployees($item) {
$stmt = mysqli_prepare($this->connection,
"UPDATE $this->tablename SET emp_no=?, birth_date=?,
first_name=?, last_name=?, gender=?, hire_date=?
WHERE emp_no=?");
$this->throwExceptionOnError();
mysqli_bind_param($stmt, 'isssssi', $item->emp_no, $item->birth_date,
$item->first_name, $item->last_name, $item->gender, $item->hire_date, $item->emp_no);
$this->throwExceptionOnError();
mysqli_stmt_execute($stmt);
$this->throwExceptionOnError();
mysqli_stmt_free_result($stmt);
mysqli_close($this->connection);
}
public function deleteEmployees($itemID) {
$stmt = mysqli_prepare($this->connection,
"DELETE FROM $this->tablename WHERE emp_no = ?");
$this->throwExceptionOnError();
mysqli_bind_param($stmt, 'i', $itemID);
mysqli_stmt_execute($stmt);
$this->throwExceptionOnError();
mysqli_stmt_free_result($stmt);
mysqli_close($this->connection);
}
/**
* Utitity function to throw an exception if an error occurs
* while running a mysql command.
*/
private function throwExceptionOnError($link = null) {
if($link == null) {
$link = $this->connection;
}
if(mysqli_error($link)) {
$msg = mysqli_errno($link) . ": " . mysqli_error($link);
throw new Exception('MySQL Error - '. $msg);
}
}
}
?>
Modify the connection variables to provide your server, username,
and password for access to the fb_tutorial_db database.
Save the service in the web root of your PHP installation,
as described below.
In your web root directory, create
a directory named DataMgtPHP.
In the DataMgtPHP directory, create a directory named services.
Name the file EmployeeService.php and save
it in the services directory.
In Flash Builder, create a Flex project. Name the project
DataMgtPHP and specify PHP for the server technology. Click Next.
Specify the Web Root and Root URL for your system. Validate
your server settings and specify the DataMgtPHP directory for the
Output Folder. Click Finish.
From the Flash Builder Data menu, select Connect to Data
Service. Select PHP and click Next.
Click Browse and navigate to the EmployeeService.php file
you created in step 1. Select EmployeeService.php and click Finish.
In the Flash Builder Data/Services view, from the context
menu for the getEmployeesbyID() operation, select
Configure Return Type.
Flash Builder needs to configure a
custom data type for data returned from the data service. By introspecting
the getEmployeesbyID() operation, you can define
the custom data type Employee.
In the Configure Return Type dialog, Auto-Detect the Return
Type is selected by default. Click Next.
Specify a value and type for the parameter to the getEmployeesbyID() operation
as described below. Click Next:
Argument
|
Argument Type
|
Value
|
itemID
|
int
|
10002
|
You need to supply valid parameters to
the operation for Flash Builder to introspect the operation. 10002
is a valid itemID.
Specify Employee in the Array Of field
toto define a custom type for returned data.
Flex uses custom
data types to access and update complex data types returned from
a server.
The Configure Return Type dialog displays the properties
of the data type returned by the service.
Click Finish to configure the Employee return type.
In the Flash Builder Data/Services view, from the context
menu for the getAllItems() operation, select Configure
Return Type.
Configure the return type for the deleteEmployees(),
specifying the parameter and type as described below. Click Next
and Finish.
Argument
|
Argument Type
|
Value
|
itemID
|
int
|
10001
|
Select Use an Existing Data Type. Select Employee from
the Array Of drop-down list. Click Finish.
Enable Data Management FeaturesIn the Data/Services view, expand the Data Types
node for EmployeeService and select the Employee data type.
From the context menu for the Employee data type, select
Enable Data Management.
In the Select Unique Identifier dialog, select emp_no and
click Next.
In the Map Database Operations dialog, specify the following
operations and click Finish.
Create (Add) Operation:
createEmployees( item: Employee )
Get Item Operation: getEmployeesByID( itemID: Number
)
Update Operation: updateEmployees( item: Employee
)
Delete Operation: deleteEmployees ( itemID: Number
)
Data management is now enabled for this operation.
Flash Builder generates client code that can update data using a
combination of the mapped operations.
Create the application and add a DataGrid and ButtonsSelect Design to open the MXML editor in Design
mode.
From the Components view, drag a DataGrid component onto
the Design Area and place it near the top.
The DataGrid component
is available under Data Controls.
In the Properties view, with the DataGrid selected, specify
the following properties:
Property
|
Value
|
ID
|
dg
|
Editable
|
true
|
Drag four Buttons to the Design Area, lining them up beneath
the DataGrid.
Double-click each button to edit their labels. Provide the
following Labels:
Label
|
Add
|
Delete
|
Revert
|
Save All Changes
|
In the Data/Services view, select the getAllEmployees() operation
and drop it onto the DataGrid.
With the DataGrid selected, in the Properties view Click
Configure Columns and do the following:
Select emp_no
column. In the Data Binding area, deselect the editable check box.
emp_no
is a key field that is automatically generated by the database.
(Optional) Rename and rearrange the columns.
(Optional) Click Configure Columns to rename and rearrange
the columns.
Generate and code event handlers for the ButtonsEach Button needs an event handler to specify the action
to take when the Button is clicked. Flash Builder generates stubs
for event handlers, which you can then code to specify the service
actions to take.
Select the Add button. Then, for the On Click field of
the Add button, click the Pencil icon and then select Generate Event
Handler.
The MXML editor changes to Source View, placing the
cursor in the generated event handler.
In the Script block, add the following import statement:
import services.employeeservice.EmployeeService;
import valueObjects.Employee;
In the event handler body, type the following:
var e:Employee = new Employee();
e.first_name = "New";
e.last_name = "New";
e.birth_date = "2000-01-01";
e.hire_date = "2000-01-01";
e.gender = "M";
dg.dataProvider.addItem(e);
dg.verticalScrollPosition = dg.dataProvider.length -1;
As
you type, Flash Builder content assist helps you view the available
methods and values.
In Design mode, add an On Click event handler for the Delete
button and specify the following code:
employeeService.deleteEmployees(dg.selectedItem.emp_no);
Similarly, add an On Click event handler for the Revert button
with the following code:
employeeService.getDataManager(employeeService.DATA_MANAGER_EMPLOYEE).revertChanges();
Add an On click event handler for the Save All Changes button
with the following code:
employeeService.commit();
Save the application and select Run > Run DataMgtPHP.
You
can update and delete selected employees in the DataGrid. You can
also add new employees.
When you add an employee, the Employee
Number defaults to zero. This is because the new employee has not
been updated on the server. When you click Save All Changes, the
new employee is added to the server. At that time, an Employee Number
is generated.
Click the Revert button to undo any changes
you made.
Click the Save All Changes button to write all
changes to the database.
|