Home
Archives
About us...
Advertising
Contacts
Site Map
 

ruby in steel

 

BLOGGING WITH DELPHI #1

Delphi 2005 and Enterprise Core Objects (ECO) II can be used to define and implement an application handling web logs - also called blogs.
by Bob Swart

Requirements:
Borland's Delphi 2005 Architect

 

Download The Source Code:
delphiblog1.zip

 

See also Part Two

Borland Delphi 2005 Architect contains a featureset called Enterprise Core Objects 2, which allows us developers to create applications based on a model (with objects, inheritance and associations), which can be made persistent in a DBMS, and used to create GUI as well as web applications.

This month I'll introduce Enterprise Core Objects in Delphi 2005 Architect, and show how to build the model to create and maintain weblog entries (and feedback). After designing the model, I'll explain and demonstrates how to make the instance of the model - called the EcoSpace - persistent in a database like SQL Server, Interbase or any other ADO.NET or BDP compliant DBMS. Next month, we'll build the ASP.NET user interface on top of the EcoSpace model.

ECO ASP.NET Web Application

If you have Delphi 2005 Architect (or the trial edition), feel free to play along. I will not only explain what I'm doing and why, but also offer clear steps along the way. First of all, we need to create a new ECO project. Since a weblog application is - as the name indicates - a web application, we create an ECO ASP.NET Web Application. The alternatives when using ECO are a WinForms application, or an ECO ASP.NET Web Service application. Neither will do it, although the ECO WinForms application might come in handy to maintain the blog entries from a local machine (instead of the internet), but that's a story for another day.

Start Delphi 2005, and select File | New - Other which will show the Delphi 2005 Object Repository. ECO is only available for Delphi for .NET or C# projects, but not for Win32 targets.


Figure 1. Delphi 2005 Object Repository

From the Delphi for .NET Projects category, select the ECO ASP.NET Web Application (see Figure 1) and click on OK.

Before creating the ECO project, this will first present you with the ASP.NET Web Application wizard, asking you where to place the project and which web server to use for local testing and debugging.

As a name for the project, I've specified Weblog, which will be placed in the local c:\inetpub\wwwroot\Weblog directory. The name Weblog will also return as the name of the code behind assembly Weblog.dll in the Bin subdirectory of my Weblog directory.


Figure 2. NEW ECO ASP.NET Web Application Dialog

As the choice for the Web Server, we can either select Internet Information Server (IIS) if it is available on your machine or the Cassini Web Server. The latter is provided as a C# demo project with Delphi 2005 (in the BDS\3.0\Demos\Cassini directory), but should in my opinion only be used if you do not have IIS, or if you have problems using IIS as your local web server. The reason why I prefer to use IIS is that IIS will most likely be the deployment web server for your application. Cassini is only meant as a personal (test) web server, and not for real-world deployment. And if you test your application with Cassini and it works fine, you may be surprised to find that it doesn't work in the "real world", when deployed against IIS. To avoid these surprises, I always test with IIS right from the start.

Anyway, once you click on the OK button in the New ECO ASP.NET Web Application dialog, the Weblog ECO ASP.NET project is finally created for you.

Note: before we continue, I've found it sometimes necessary with ECO projects to compile, save and close the project, and then reopen it so the ECO types are known to the relevant components in the entire application. So, do Project | Build Weblog, then File | Close All, and say Yes when asked to save changes to the project Weblog. Then, you can reopen the project. This issue may have been fixed by the time you read this, but it only takes a second or two and I'd rather be safe than sorry.

Step #1 - The Model

Let's first start to define the model for our weblog application. For this, we need to click on the Model View tab of the Project Manager. Open the treeview with the model nodes, and select the CoreClasses node. Expand this node, and select the CoreClasses leaf node inside. This is the node that we can use to draw the UML diagram for our ECO model. Double-click on the CoreClasses leaf node in the Model View to start the UML Designer.


Figure 3. UML Designer

When the UML Designer is shown, the Tool Palette will contain the ECO Class Diagram "drawing" controls that we can use to create a new ECO Package, a new ECO Class, an Association between two classes, a Generalization/Implementation relation between two classes (i.e. if one class is derived from another), a Note and a Note Link.

ECO Classes and Attributes

Apart from these controls in the Tool Palette, we can also right-click on the UML Designer and use the pop-up menu to Add a new ECO Package or ECO Class. For our weblog example, right-click on the designer, and Add a new ECO Class. Change the name to Entry. A weblog entry can be a post (by the main author) or a comment (by a visitor). So the Entry class is like a base class for both.

We can add attributes and operations to an ECO class. Obvious attributes for a weblog entry are the author, title and the date it was posted. So, right-click on the Entry class, and add a new attribute called Author of type String. Right-click again and add a second attribute called Title of type String, and finally a third attribute called Posted of type DateTime.


Figure 4. ECO class

Derived Classes

The Entry class is not one that we will use directly. Instead, we should derive two other classes from it: Post and Comment. In fact, we should mark the Entry class as abstract by setting its abstract property to True (so no instances of it can be made).

Then, we can add a new class called Post. We don't have to add the Author, Title and Posted attributes, since Post will be derived from Entry. This is done with the icon in the Tool Palette that says "Generalization/Implementation". Click on this icon, then on the Post class (the derived class), and finally on the Entry class (the parent class). Note that the order matters!


Figure 5. ECO Classes

There is a new attribute that we should add to Post: Contents of type string. If you look at the properties for the Contents attribute, you may notice the Length property, which is set to 255 by default. A string of only 255 characters seems a bit short to store a blog entry, so I've changed the Length property of the Contents attribute to 4096, which is probably long enough (famous last words). Note that a value of 8192 fails to generate a database schema (been there, done that), although you may want to experiment to find an optimal maximum for the Contents size.

Note: do not use Content (singular) as the name of the attribute, as this will clash with an internal field in the ECO class called _content. Each attribute is stored in a strict protected field with the name of the attribute and an underscore prefix. Unfortunately, since there is also a _content field in the ECO class, we cannot add an attribute called Content.

After finishing the Post class, we can add another class derived from Entry, this time called Comment. Use the Generalization/Implementation to reflect the fact that the Comment class is derived from the Entry class, just like the Post class is.

The Comment class also has an attribute for the contents, this time called Comments of type string, with the Length property to 1024 (so I'm not allowing people to comment as much as I post myself).

Operations

Where the attributes can be seen as properties, the ECO Classes can also have operations. These can be seen as the methods of an ECO Class. Although you define the operation at the model level, you can implement it using Delphi code.

As an example, for each weblog entry, I want to report the number of words in the contents of the Post. In order to add an operation, we must first click on the ECO Class itself, but not in the attribute area (since that will select one of the attributes). Make sure the Post class itself is selected, as shown in Figure 5.

When the ECO Class is selected, you can right-click on it and do Add | Operation. Set the name of the new operation to WordCount. If you don't set the Returns property as well, the operation will be a procedure. But since we want it to return the number of words, change the Returns property to integer. Alternatively, you could have entered "WordCount: integer" inside the text area for the new operation in the ECO Class. The brackets will be added automatically.

In order to implement the WordCount operation, right-click on it and select the "Go to Definition" option. This will bring you to the following source lines inside the Post class definition in the CoreClassesUnit.pas source file:

[UmlElement]
function WordCount: integer; 

In order to jump to the implementation of this function, hold down the control key and move the mouse cursor over the WordCount name, which will turn the WordCount name into a hyperlink. Hold down the Control key, and when you click on the WordCount hyperlink, you'll jump to the bottom of the CoreClassesUnit source file, where the empty WordCount function is waiting to be implemented.

A simple implementation of the number of words inside the content is as follows:

function Post.WordCount: integer;
var
  InSpace: Boolean;
  C: Char;
begin
  Result := 0;
  InSpace := True;
  for C in _Contents do
    if C <= #32 then InSpace := True
    else // not in space
      if InSpace then // used to be in space
      begin
        InSpace := False;
        Result := Result + 1
      end
end;

Note that I'm using the new for-in-do language feature here, to iterate over the characters in a string. Also note that we won't be testing the WordCount function this month, so if I made a mistake, we won't find out until next time.

The UML Model with the abstract Entry class and the two derived classes Post and Comment should now look as follows:


Figure 6. ECO Class Hierarchy

Although this might be enough to have a list of weblog entries posted, there are some things missing. Most weblogs out there seem to place their posts in categories. So, right-click on the UML Designer area and add a new class, called Category. The Category class gets only one attribute, called Name of type String.

The Category class has no relationship with the Entry, Post or Comment classes, yet. For that, we need to add an association between classes.

Associations

Posts can fall into one or more Categories. Zero or more, actually, unless you want to include a miscellaneous Category (which I won't, so let's assume it's 0 or more). Vice versa, a Category can contain 0 or more Posts. This relationship between Posts and Categories can be added to the model using an association. The association can be found in the Tool Palette, and the way to add it is fairly simple: click on the association icon in the Tool Palette, then click on the class you want to associate, and finally click on the class you want the first class to associate with. So first the association icon, then for example Category, and finally the Post class.

An association has properties that we can set to make it more descriptive, like the name. I've changed the name from Association_1 to Categorization. Next, we should examine both ends of the association. They also both indicate 0..1 as multiplicity. Meaning that zero or one Post belongs to zero of one Category. That has to change. At the Post end, change the 0..1 into 0..* to indicate that a Category has zero or more Posts. At the Category end, also change the 0..1 into 0..* since a Post can fit into zero or more categories.

The names that are used at the End points of the association should also end. Right now, they are Post and Category, but I've changed those names to Posts and Categories (to indicate that it can be 0 or more - likely more than 1).

This leads to the following version of the UML Model in the designer:


Figure 7. Associated Classes

There's still one more thing missing: the fact that a Comment should be associated with a Post (otherwise it wouldn't make much sense to comment, would it?). So, add an association between the Comment class and the Post class, and call it Commentary.

A Comment can be applied to only (exactly!) one Post, but a Post can have 0 or more comments, which is depicted as follows:


Figure 8. Final ECO Model

Although there are several additional enhancements possible, from comments commenting on comments, and Posts to follow-up on other Posts, and using a separate class to model the Authors, with all kinds of Author specific attributes, I leave the model as it is right now. We can always enhance and extend it later, and the best thing is that ECO will allow us to evolve the database and application when the model itself evolves. So that's true RAD, without having to throw everything away to start all over again.

At this time, we should save compile and our work, and get ready for step #2 - configuring the database to hold the model.

Step #2 - The Database

The classes that we've defined, will come to live in an environment called the EcoSpace. This EcoSpace is like the universe where instances of these classes (the objects) are created and interact with each other through associations. The EcoSpace can be made persistent by storing it inside an XML file (for single-user ECO applications) or a DBMS. The latter is the only solution for ASP.NET ECO applications, where multiple users can work on the EcoSpace simultaneously.

A PersistenceMapper component takes care of mapping the EcoSpace to a persistent file or database. In a multi-user environment, the PersistenceMapper must also take care of synchronization issues between multiple instances of an EcoSpace, and must then be placed on a PersistenceMapperProvider.

Use the Project Manager to open the EcoPersistenceMapperProvider.pas unit of the Weblog project. When you open this unit, it also has a Design tab, where we can place the PersistenceMapper component that we want to use. There are two multi-user aware PersistenceMapper components: PersistenceMapperBdp, and PersistenceMapperSqlServer. The third one, PersistenceMapperXml, can only be used in single-user ECO applications, as mentioned before.

The PersistenceMapperSqlServer works with Microsoft SQL Server using ADO.NET, while the PersistenceMapperBdp uses the Borland Data Provider for .NET, which offers connectivity to Microsoft SQL Server / MSDE, as well as InterBase, Oracle, IBM DB2, Informix, Sybase, and MS Access, plus additional third-party BDP drivers.

In this case, I want to use Microsoft SQL Server, and since the BDP components do not offer connection pooling support for SQL Server, yet, I prefer to use the SQL Server specific PersistenceMapperSqlServer component, which uses the SQL Server ADO.NET drivers from Microsoft (and support Connection Pooling).

ECO Database

First of all, we need to create the external database, so we can connect to it. This process differs from one database to another, so consult your DBMS documentation for more help. I usually prefer to use the command-line tools that are included with the DBMS to execute a "CREATE DATABASE" command.

For SQL Server, this commandline tool is called osql, which can also take a command-line script file with SQL commands. So, I've first prepared a little SQL script file with the following two lines:

CREATE DATABASE Weblog 
GO 
And with that script file saved in weblog.sql, I can run the osql command-line tool as follows:

osql -E . -i weblog.sql

As a result, osql will report that it has created a Weblog database as well as a Weblog_log logfile for the database.

Connecting to the Database

Once the database is created, we can return to Delphi 2005 and the EcoPersistenceMapperProvider unit. We need to place a SqlConnection component on the design area of the EcoPersistenceMapperProvider, and specify a valid ConnectionString to connect to the weblog database. If you double-click on the ConnectionString property of the SqlConnection component, the Data Link Properties dialog will pop-up. Here, we can select the server name, specify a username and password, and select the database on the server. Make sure to click on the "Test Connection" button to verify that you can make a connection to the database.

Note: do not select the "Use Windows NT Integrated security" option, since that will work at design-time, but may not work at runtime, especially when using SQL Server and IIS on a Windows XP or Windows 2003 web server. Always use a specified name and password to connect to the database.


Figure 9. Data Link Properties Dialog

The Model and the Database

Once the SqlConnection component is configured, we can place a PersistenceMapperSqlServer component on the EcoPersistenceMapperProvider. Right-click on the PersistenceMapperSqlServer component and select "SQL Server setup", to prepare it for SQL Server. Then, point the Connection property of the PersistenceMapperSqlServer component to the SqlConnection component, and set the SyncActive property to True.

Finally, click on the design area of the EcoPersistenceMapperProvider and in the Object Inspector verify that the PersistenceMapper property points to the PersistenceMapperSqlServer component.

The only thing left to do now, is creating the database schema, based on the model. For this, there are two buttons in the lower-left corner of the designer area of the EcoPersistenceMapperProvider: Generate Schema, and Evolve Schema. We may use the latter next month (if we decide to update the model), but right now, we only need to generate the schema (for the first time). So, click on this button, which will pop-up a dialog with the actions that will be performed in the database.


Figure 10. Generate Schema

If the database was not empty, then any existing table with a conflicting name (i.e. a name of a table that has to be created) will be marked as required to drop/recreate. Any existing table with a name that doesn't conflict will be listed in the "optionally delete" tab. So you can either keep existing tables in an ECO database (although not recommended), or make sure that all tables are deleted and/or recreated when the new schema is generated.

Note that each ECO class gets its own table (Entry, Post, Comment and Category), as well as the Categorization association (which is of type many-to-many), but not the Commentary association (which is of type one-to-many).

Click on OK to create the database tables, and then compile and save the project. We've completed the design of the weblog model, and also ensured it will be made persistent in a SQL Server database. The project source files are available for download, but require Delphi 2005 Architect to compile.

Feel free to experiment with the model or PersistenceMapper components, and stay tuned for next time when we continue with the user interface of the weblog application.

Next Time...

Next month, I'll build the user interface on top of the EcoSpace model. Obviously, a weblog application should run as a web application, so we started this time by creating an ASP.NET ECO Web Form application. Next month, we'll build multiple pages on top of the objects in the EcoSpace, showing weblog posts in categories, and allowing visitors to leave comments (storing the comments also in the EcoSpace). And I'll also make sure to cover deployment details and issues, as well as links to the actual deployed weblog application.

All this and more next time, so stay tuned...

Continued in Part Two

Copyright © 2005 Bob Swart


Bob Swart (aka Dr.Bob - www.drbob42.com) is an author, trainer, developer, consultant and webmaster for Bob Swart Training & Consultancy (eBob42) in The Netherlands, who has spoken at Delphi and Borland Developer Conferences since 1993. Bob has written chapters for seven books, as well as the Borland Delphi 8 for .NET Essentials and Delphi 8. ASP.NET Essentials courseware manuals licensed by Borland worldwide, and is selling his updated Delphi 2005 courseware manuals online at http://www.drbob42.com/training. Bob received the Spirit of Delphi award at BorCon in 1999, together with Marco Cantù.

June 2005

 


Home | Archives | Contacts

Copyright © 2006 Dark Neon Ltd. :: not to be reproduced without permission