| This FAQ contains the following sections:
If you have a question and do not find the answer in this FAQ,
please contact us at
support@themidnightcoders.com or post your question on our
user
interest group. |
|
General
- What is WebORB Data Management for
Flex?
WebORB Data Management for Flex (WDMF) is a an innovative data
management framework designed to client/server
integration for data-driven Flex applications. WDMF consists
of a design-time code generator and a runtime data management
and object relational mapping engine. The code generator
accepts a configurable data model which may consist of one or
more data tables from one or more databases. Generated code
includes a set of ActionScript v3 classes as well as all the
supporting backend code. Using WDMF, Flex developers can focus
on the core application logic without spending time on
creating code for ‘data management plumbing’. The framework
includes rich support for all fundamental database operations
(CRUD), as well as the ability to dynamically compose data
retrieval queries using the dynamic method composition
technique. The technique has been borrowed from the Ruby on
Rails ActiveRecord pattern and elegantly adapted to the
ActionScript environment.
-
What can I do with WDMF?
Using WDMF a developer can easily operate on data from a
remote data source directly from a Flex client application. In
its core the WDMF functionality includes all traditional
database functions (CRUD). However the API exposed to the
developer works at the data level and hides the complexity of
the database integration, query execution and object
materialization. For instance, suppose an Order class is
generated by WDMF to represent a row in the Orders table.
//
generated by the WDMF code generator
public
class Order extends ActiveRecord
{
public var Id:Number;
public var OrderDate:Date;
public var ShipDate:Date;
public var CustomerName:String
} |
The API below demonstrates various ways to operate on the
data from the table:
Retrieving all Order records from the Orders table. Each
record is represented as an Order object:
// the
call returns an ArrayCollection with Order objects
ActiveRecords.Order.findAll(); |
Retrieving all Order records for a particular customer.
Notice the "CustomerName" in the method name refers to a
property on the Orders class:
// the
call returns an ArrayCollection with Order objects
ActiveRecords.Order.findByCustomerName("Acme
Corp"); |
Retrieving all Order records for a customer with a
particular ship date.
// the
call returns an ArrayCollection with Order objects
var
shipDate:Date = new Date( 2007, 2 );
ActiveRecords.Order.findByCustomerNameAndDate("ABC",
shipDate); |
Creating a new order:
var
order:Order = new Order();
order.OrderDate = new Date();
order.CustomerName = "Midnight Coders";
order.save(); |
Deleting an order:
var
order:Order
// retrieve an order object using any of the find methods
order.delete(); |
- How does WDMF work?
We would rather keep it as magic, but we realize it is
important to understand some of the WDMF concepts. The process
starts with the code generator. The code generator is
integrated with the WebORB Management Console. You connect to
the database(s) of your choice and create a data model
by selecting the tables. Each table in the data model will be
represented by a class. An instance of the class represents a
row in a table. Class properties are mapped directly to the
table columns. The concept and design pattern implemented by
these classes is called ActiveRecord. The class
has two representations: one for the client code in the
ActionScript v3 format and the other for the server-side. Code
generator automatically establishes mapping between the client
and server side ActiveRecord classes. When you generate the
code from the data model, WebORB automatically deploys the
server side code so it is ready to run, and gives you a ZIP
archive with all the client code so you can expand it into
your Flex Builder project. This is where the real fun begins.
Once the generated client code is a part of your project, you
can do complete data management for the tables included in the
original data model. You do not need to write any additional
code on the server or make any configuration changes. Use the
ActiveRecord API with the generated classes and enjoy the best
data management system a Flex client even had.
- What is ActiveRecord?
There is a partial description in the answer above, but to
fully understand AR, start with the
Wikipedia
entry. To apply the concept to WDMF, ActiveRecord is a
class typically generated by the WebORB code generator and
available in both client and server environment. The class
represents data in a database table, an instance of the class
represents a row in the database table. The class gives you
access and full control over all basic database operations
(Create, Retrieve, Update, Delete - CRUD) through an intuitive
and easily customizable API.
-
What languages/platforms is WDMF
available for?
Server support in WDMF is currently limited to .NET. The
system can generate either C# or VB.Net code for the
server-side functionality. We are working on extending server
support to include PHP, Ruby and Java.
-
What databases can WDMF work with?
WDMF includes support for MySQL and Microsoft SQL Server.
Future releases will add support for Oracle and PostgreSQL
databases.
-
Does WDMF support transactions?
Yes. By default all data management functions implemented by
WDMF code generator use transactions. Adding transaction
support to any extensibility code introduced by a developer is
as simple as declaring a method attribute.
-
Is WDMF a part of WebORB or it is
available standalone?
WDMF is an integral part of WebORB and is built on top
of variety of product features. The WDMF subsystem is
partially available with WebORB Professional Edition and fully
available in the Enterprise Edition of the product. The
Professional Edition excludes support for client
synchronization, transactions and clustering.
-
How much does WDMF cost?
Since
WDMF is a part of WebORB, standard product pricing applies.
-
What edition of WebORB is WDMF
available in?
WebORB Professional Edition will include the majority of the WDMF
functionality, excluding support for client synchronization,
transactions and clustering. WebORB Enterprise Edition
will provide full unrestricted WDMF support. The functionality
should be available March, 2007.
-
Is WDMF a replacement for Flex Data
Management Services (FDMS)?
We certainly do not think so. WDMF is not a one-for-all
solution. It addresses a lot of problems and significantly
simplifies integration between a Flex client and a remote data
store. Both WDMF and FDMS provide a level of abstraction over
a set of data management problems developers have to solve.
The degree of abstraction differs between the frameworks and
thus impacts the level of control and detail of
customizations. There is no universal recipe for deciding
which of the systems is more appropriate for creating a
particular data management solution. As a result, each
scenario should be studied to weigh the benefit and relevance
of each system.
|
|
|
CODE GENERATION
|
|
|
DATA RETRIEVAL
-
What are the basic data
retrieval functions in WDMF?
How can I load my data using WDMF?
There are several ways to load data. All ActiveRecord
classes inherit the data retrieval API from
WDM.ActiveRecord. Below is a summary of the available data
retrieval methods in any generated ActiveRecord class:
//
retrieving all records
findAll( r:Responder = null ) : ArrayCollection
// retrieving the first
record
findFirst( r:Responder = null ) : ActiveRecord
// retrieving a record by
primary key
findByPrimaryKey( key:Object, r:Responder = null ): ActiveRecord
// running an SQL query
findBySql( sqlQuery:String, r:Responder = null ):ArrayCollection
// running a custom search by
ActiveRecord properties
// See an example here.
findBy______( ... args, r:Responder = null ) :
ArrayCollection |
-
Can I see an example
of WDMF data retrieval?
Suppose the Order class is generated by WDMF. The Orders
table contains the following columns: OrderID,
CustomerName, BillDate and ShipDate. The MXML code below
shows how to retrieve all records from the Orders table
and bind the data grid to the returned collection. Any
time any other makes a change to the collection, the data
grid is automatically synchronized:
<mx:DataGrid
dataProvider="{ActiveRecords.Order.findAll()}">
<mx:columns>
<mx:DataGridColumn dataField="OrderID" />
<mx:DataGridColumn dataField="CustomerName" />
<mx:DataGridColumn dataField="BillDate" />
<mx:DataGridColumn dataField="ShipDate" />
</mx:columns>
</mx:DataGrid> |
-
How can I
customize a data retrieval operation?
There are three ways to run a custom data retrieval:
(1) using a dynamic ActiveRecord functions;
(2) using raw SQL query in a findBySql call ;
(3) creating a new data retrieval method on the server
side and invoking it through an ActiveRecord object;
1) Dynamic ActiveRecord functions:
For any ActiveRecord a developer can invoke a function
with the name composed of the ActiveRecord properties. For
example, consider the following ActiveRecord class:
//
generated by the WDMF code generator
public
class Order extends ActiveRecord
{
public var Id:Number;
public var OrderDate:Date;
public var ShipDate:Date;
public var CustomerName:String
} |
The class allows the following custom data retrieval
methods:
// find all orders with the given
order date
ActiveRecords.Order.findByOrderDate( dateObj )
// find all orders with the given shipping date
ActiveRecords.Order.findByShipDate( dateObj )
// find all orders for a customer
ActiveRecords.Order.findByCustomerName( customerNameStr )
// find all orders for a customer and order date
ActiveRecords.Order.findByCustomerNameAndOrderDate( name,
date )
// find all orders for two given shipping dates
ActiveRecords.findByShipDateOrShipDate( date1, date2 ); |
2) Using SQL query in a findBySql() call:
Flex client can run an SQL query using the findBySql
method available through the ActiveRecords class. So for
the Order class, client can call the following method and
get a collection of the Order objects:
ActiveRecords.Order.findBySql(
"select * from Orders where
CustomerName LIKE %Soft%" ); |
3) Server extensions:
Any number of custom methods can be added to the
server-side data mapper classes. All framework facilities
including CRUD operations and transaction are available to
the custom code. Flex client can invoke custom data mapper
methods using the ActiveRecords class.
-
How do I get a result object from a data
retrieval operation?
All data retrieval operations return an object as a
traditional synchronous call. However, if the object
contents are not available (i.e. that ActiveRecord has
never been loaded before), data retrieval is handled
asynchronously. When the data arrives from the server, the
original object returned from the invocation is
automatically updated. The returned object is an instance
of ArrayCollection for all find__() methods except for
findByPrimaryKey(). The latter returns a specific instance
of the requested type. The returned value is a bindable
object. As a result, it can be used as a data provider for
bindable components using the synchronous model. For
example, the code below initializes a data grid with all
orders from the database:
<mx:DataGrid dataProvider="{ActiveRecords.Order.findAll()}">
<mx:columns>
<mx:DataGridColumn dataField="OrderID" />
<mx:DataGridColumn dataField="OrderDate" />
<mx:DataGridColumn dataField="RequiredDate" />
<mx:DataGridColumn dataField="ShippedDate" />
</mx:columns>
</mx:DataGrid> |
Alternatively, if the application logic requires a
notification when the data arrives, it can pass an
instance of mx.rpc.Responder into any find___() call. For
example:
var responder:Responder = new
Responder( onResult, onFault );
ActiveRecords.Orders.findAll( responder );
public function onResult( data:Object ):void
{
var collection:ArrayCollection = ArrayCollection( data );
}
public function onFault( faultEvent:FaultEvent ):void
{
} |
Additionally, if the Responder approach is not
acceptable or undesirable, WDMF supports the following
approach:
var coll:ArrayCollection;
coll = ActiveRecords.Orders.findAll( responder );
coll.addEventListener( "loaded", gotData );
public function gotData( evt:DynamicLoadEvent ):void
{
// at this point the original "coll" collection
// has all the data. Alternatively, the loaded data
// can be obtained using the provided "evt" event object:
var receivedData:ArrayCollection;
receivedData= ArrayCollection( evt.data() );
} |
-
Can I retrieve an association
for an Active Record object?
Yes, WDMF includes rich support for data associations. A
class generated for a table associated with other tables
will include a property function for each association.
Associated data is loaded "lazily" simply through property
access. For example, if the Order table has a one-to-many
relationship with the OrderDetails table, the Order class
will contain the OrderDetails property returning a
collection of OrderDetail objects.
- Can I bind active record
objects to UI controls?
Yes, all data retrieval results returned by findAll,
findBySql, findByPrimaryKey or dynamic find___()
operations are bindable. For example, the code below
retrieves a collection of order objects and automatically
binds them to a data grid:
<mx:DataGrid dataProvider="{ActiveRecords.Order.findAll()}">
<mx:columns>
<mx:DataGridColumn dataField="OrderID" />
<mx:DataGridColumn dataField="OrderDate" />
<mx:DataGridColumn dataField="RequiredDate" />
<mx:DataGridColumn dataField="ShippedDate" />
</mx:columns>
</mx:DataGrid> |
-
What happens if I
retrieve the same ActiveRecord object twice in the same
program?
WDMF enforces a strict identity management policy which
guarantees that no two ActiveRecord objects pointing to
the same row of data will ever exist in the same
application. When an ActiveRecord object is loaded into
the client program, WDMF checks the identity and makes
sure only one ActiveRecord object for a row of data exists
in the process.
-
How can I handle data retrieval errors?
Data retrieval errors can be handled using the Responder
or event listener approaches described
above.
|
|
|
CREATING NEW DATA RECORDS
- What API do I use to create a
new data record?
TBA (to be answered)
- What happens if I try to
create a new record but do not provide all the required
data?
TBA (to be answered)
- How can I create hierarchial
data records in tables with relationships?
TBA (to be answered)
- How can I handle data
creation errors?
TBA (to be answered)
|
|
|
UPDATING DATA
- What API do I use to update
a data record?
TBA (to be answered)
- How can I handle data
creation errors?
TBA (to be answered)
|
|
|
DELETING DATA
- What API do I use to update
a data record?
TBA (to be answered)
- How can I handle data
creation errors?
TBA (to be answered)
|
|
|
CLIENT SYNCHRONIZATION
- What is client
synchronization?
TBA (to be answered)
- What triggers client
synchronization events?
TBA (to be answered)
- How can I intercept client
synchronization event?
TBA (to be answered)
- Can I customize default
synchronization behavior on the client?
|
| |
|
|