Tutorial 1: Initiating the Project

 

The first step is to create a folder for the project files, so, use the Windows Explorer or your favorite file management tool to create a C:\Tastrade folder on your local drive.

 

 

 

CD C:\Tastrade

 

 

We will start defining some basic entities from our object model. Let us begin with the simplest entities like Category, Product and Address. To define our classes we will put the classes’ definition code in a simple PRG file named Classes.PRG.

 

 

 

Modify Command classes

 

 

 

 

DEFINE CLASS Category AS Custom

      CategoryName  = ""

      Description   = ""

      PictureBitMap = ""

ENDDEFINE

 

DEFINE CLASS Product AS Custom

      ProductName       = ""

      EnglishName       = ""

      Category          = .Null.

      QuantityInUnits   = 0

      UnitPrice         = 0.0000

      UnitCost          = 0.0000

      UnitsInStock      = 0

      UnitsOnOrder      = 0

      ReorderLevel      = 0

      Discontinued      = .F.

ENDDEFINE

 

DEFINE CLASS Address AS Custom

      Street      = ""

      City        = ""

      Region      = ""

      PostalCode  = ""

      Country     = ""

ENDDEFINE

 

 

 

Note that, in the class definitions, we have not defined properties for object identification, just the business-required attributes. This is the first difference we encounter why modeling our classes in a complete object oriented realm. In the object-oriented world, objects has identity by themselves, they do not require a “primary key”. The Primary Key concept appears when we deal with a Relational schema; however, that is a job for FoxDataObjects…

 

String-type properties are declared by assigning a string value in the class definition code. You can specify an empty or a non-empty initial value. The initial value is used when a new instance is created for the class definition and as Default value for the corresponding column in the relational model.

In the Category class definition, the PictureBitMap property is defined as a string value, however at runtime, we will store a binary value (a BitMap graphic) and it will be stored and retrieved to/from the database as a binary string. We will see that in a moment.

 

Note that numeric properties are defined by assigning a numeric value to the property declaration in the class definition. FoxDataObjects analyze the default value for the property to determine the numeric data type to be used by default.

To help FDO identify Currency (or Money) data types we declared those properties using a numeric value with four decimal places. Numeric values with no decimal places are mapped by default as Integer types. Decimal values with more or less than four decimal digits are mapped as Decimal types.

 

Special attention must be paid to the Product.Category property. A Product instance may (or may not) be related to a Category instance. In the object world, an object instance reference another object instance just by using an object pointer (or a contained object, as we will see on other samples). Therefore, we do not need to use Primary/Foreign keys values to reference a Category from a Product. We just make a Product instance to point to a Category instance by using an object pointer. That is why Product.Category property is declared as a null Object Pointer. When your application runs, you can relate a Product instance to a Category instance simply by storing the Category object pointer in the Product.Category property. When you persist your object instances, FoxDataObjects do the job for you, defining the Primary/Foreign key columns on the relational model tables to store such relationships automatically.

 

So, let us start using FoxDataObjects with your recently created business classes.

 

 

FoxDataObjects stores all of the mapping information for your business classes into a Mapping Schema file (a XML file with a .FDO extension). 

 


After creating the schema file, the Copy/Update FDO libraries files into project location form appears.

 

At this time, you have created a basic class library file, an empty mapping schema file and copied the FoxDataObjects library into your application folder.

The Schema Manager shows your empty mapping schema file in a two-panel split window. In the left panel, a Tree View control lets you navigate on both, the Object Model and the resulting Relational Model or Data Dictionary entries.

The Object Model nodes show all of your Classes and Members definitions. The Relational Model nodes show all of the tables definitions needed to persist your object instances in a relational database. By now, your schema file is empty.

 

At development time, FoxDataObjects can parse your classes’ definitions either manually or automatically, and document them on the Object Model sub tree. You cannot add items directly to your Object Model tree. It is the current representation of your classes’ definitions from your class libraries.

To add a class or a member to your object model, it is as simple as adding a class definition or a member definition into your class library. It means that now, you will only need to focus on your classes’ code. There is no need to worry about maintaining synchronized definitions or parallel mapping structures like most of the ORM frameworks for Java or .NET require. FoxDataObjects parses your class libraries and maintain those structures for you.

 

Now you can instruct the Schema Manager to parse your library file in order to document your classes’ definitions for the first time.

 

  • Choose Tools \ Parse class library… in the Schema Manager menu, and select your Classes.PRG file.

 

The class library is parsed and your classes are documented. Click to expand the Object Model node and you will see all of your classes and properties documented on the schema file as you can see in the figure.

 

Note that in the Product class, the Category member is shown as an object pointer to any object (we will change that soon).

 

Feel free to navigate the Object Model nodes. When you click on a Class node or on a Member node, the right side panel shows a form where you can document your object model item, customize how FoxDataObjects maps the item to the Relational Model, and specify advanced options for Concurrency Control, Relationships definitions, and more.

 

 

 

 

At this time, all of your Object Model entities have been mapped into a Relational Model schema. Click to expand the Relational Model node and you will see all of the tables and columns definitions that FoxDataObjects created when mapped your Object Model.

 

 

 

Note that, by default,  FoxDataObjects created a table definition for each class defined in the class library. Tables’ definitions contain not only the columns needed to store a given entity instance (one table column per single value type property or simple reference) but also a Primary Key column definition named Object_ID. FDO uses this column as a record/instance unique identifier and builds all of the relationships the relational model needs, over those values. Please, check the documentation to get a detailed explanation on how this works.

 

At this point, FoxDataObjects parsed your class library, documented your object model and mapped your classes and members into a complete relational model definition ready to be used to create a database on any supported data store and begin storing and retrieving object instances. All of this has been done almost without your intervention, you just written your class code. However, you may want to customize how FDO maps your classes or make changes to the resulting Relational Model. We will do that soon, but before making changes on the proposed schema, save the current mapping schema state:

 

 

 

Therefore, without any code you are ready to begin storing objects instances on a real database!

To do so, you will use the Persistence Services provided by the FoxDataObjects library copied into your application folder (when you created the empty schema file).

FoxDataObjects provides a powerful persistence engine in two lightweight files. The FDO.FLL file contains all the low-level code (C++ compiled code) required to persist, retrieve and fill your object instances. However, all of the Persistence Services are exposed as an easy to use object model provided by a set of classes stored on the FDO.FXP file. The FDO.FXP file contains all the classes that wrap the C++ level functions calls and constitute a powerful interface to the complete services provided by FDO.

 

 

You can check the documentation manual for a complete description of the classes, methods, properties provided by the Persistence Engine. However, we will introduce here some concepts to make the process even easier.

 

You will need to get a Session object (from the fdoSession class provided in the FDO.FXP file) in order to get access to all of the Persistence Services. A Session object represents a connection to a database and lets you Connect, Disconnect, Save and Retrieve Objects and so on.

You get a valid Session object by using the NewSession() method exposed by the Server object. You will see a sample in the next lines.

The Server.NewSession() method works as a Session object factory. There are two main resources required to get a valid Session object:

 

A datasource object is an easy to use wrapper around supported ODBC drivers (and VFP native databases) that provides meaningful information to FDO, not only on how to connect with the database layer, but also on what to do at the first connection time.

Please check the Documentation Reference to get detailed information on DataSources.

 

You can create a datasource object programmatically and set the minimum properties values required to connect to a data store or you can create and store a datasource definition directly in the mapping schema file. This way, Server.NewSession will look into your mapping schema file for a valid DataSource definition, and will use it to connect to the data store.

 

In the next steps, you will learn how to create a datasource definition and store it on your recently created schema file.

 

 

If you have SqlServer or MySQL installed on your local computer or in your LAN please select it, so you can see the full potential of FDO using a RDBMS at development time. Otherwise, select Visual FoxPro (native DBC access) and make sure you create a dedicated folder for the database file named (as an example) data on your current folder (use the Windows Explorer or click on the Visual FoxPro window and type :

 

MD data

 

(make sure your Database Path field contains the name of you data folder).

 

If you selected Microsoft SQl Server or MySql, make sure your Server, UID and PWD fields contains the proper information (leave the Database Name (DB) field empty). You can use the Test button to make sure the DataSource definition is valid.

 

 

Now, you can begin testing your classes and using persistence services. You can do it from the Visual FoxPro’s Command window:

 

Command

Result

 

SET PROCEDURE TO FDO, Classes ADDITIVE

 

 

 

oServer=CREATEOBJECT(“fdoServer”)

 

 

 

oSession=oServer.NewSession(“Tastrade.FDO”)

 

 

 

? oSession.IsConnected

 

.T.

 

At this point, you have a valid Session object. The Session object connected to the data store and created the database automatically for you.

Please, check the documentation manual for a complete description on the Server and Session classes.

 

If you created a datasource definition for native FoxPro databases, you can use the Windows Explorer and explore the C:\tastrade\data folder, where you will find the Tastrade.DBC container and all of the tables and indexes defined in the Relational Model data dictionary.

If you created a Microsoft SQL Server or MySQL datasource definition, use your favorite administrative or query tool to connect to your server and you will see the recently created Tastrade database.

 

With a valid Session object you can access all of the persistence services to save, retrieve or delete objects from the database. The next commands shows how simple is to use the persistence services.

 

 

oAddress=CREATEOBJECT(“Address”)

 

 

 

oAddress.Street=”647 White Blvrd”

 

 

 

oAddress.City=”New York

 

 

 

oAddress.Region=”NY”

 

 

 

 

? oSession.SaveObject(oAddress)

 

.T.

 

oAddress=.Null.

 

 

 

oAddress=oSession.GetObject("Address","Street='647'")

 

 

 

? oAddress.City

 

New York

 

? oAddress.Street

 

647 White Blvrd

 

? oSession.DeleteObject(oAddress)

 

.T.

 

In this very basic example, FoxDataObjects mapped your classes, created the database container, tables and indexes, and a simple address objects has been saved, retrieved and deleted from the database.

 

In the next tutorial, you will learn how to make changes on mapping definitions and how to work with simple relationships.

 

 

 

 


< Tutorials and Walkthroughs

Home

Tutorial 2: Working with objects references >

 

 

Send feedback on this topic to RunAhead Technologies

For Technical support and product issues please contact us at support@foxdataobjects.com or visit http://www.foxdataobjects.com

 

Copyright (c) 2000-2005 RunAhead Technologies