Author Archive

# Episode 39 of the Podcast at Delphi.org

It’s been a long while, but Jim and i finally found the time again to sit down and record a new episode of The Podcast at Delphi.org, talking about the upcoming Delphi Prism 2011 release, software development for the mac using Mono, and a lot more. It’s been great to be back on air, and we’ll hope to make this a more regular thing once again. In the mean time, i hope you’ll enjoy this episode!

See the official post for this episode at Delphi.org. Or subscribe in iTunes or via the RemObjects on Air feed.

(Via The Podcast at Delphi.org.)

# RT: Kontra on Apple, Google and “Choice”

The Angry Drunk links to a worthwhile read taking apart the latest “draconian control” clamors from Google’s new spokesperson for the Android / against the iPhone, and IMHO sums it up very nicely:

The bottom line is, if you think that Google is somehow a bastion of ‘open’ computing you are either ignorant, delusional or a hypocrite.

(Via The Angry Drunk).

# What’s New and Cooking…

The past week has been a busy one, here at RemObjects. On Tuesday, we shipped our new “Spring 2010” releases, updating our entire product suite. We also started work on three major new projects that will significantly shape Data Abstract over the coming year.

Let’s start with a quick look at the “Spring 2010” releases. On first sight, this round looks like a minor update – and in many ways it is, as a large portion of the past product cycle has been concentrating on QA and documentation (which is making great strides in the wiki, i must say – kudos to the entire team for keeping up with their documentation writing). But we also shipped a few great new features and key technologies that will play an important role moving forward.

Script

Firstly, there’s the new RemObjects Script for .NET that Carlo talked about the previous week. Right now, RemObjects Script is is shipping as a standalone library product (like its close sibling Pascal Script for Delphi, and like Internet Pack, it ships free and with complete source, and is available in our public SVN). So that alone, i believe, is pretty cool – but RemObjects Script fits into a greater plan, and that is the expansion of Business Rules Scripting in Data Abstract.

A little known and often overlooked feature we have had in Data Abstract for Delphi for a long time is the ability to define business rules inside the schema, to be run on the client. Not really meant to enforce security, but more to provide a better client experience, the idea was that constraints and business logic could be specified – using Pascal Script – right inside Schema Modeler, and clients will retrieve and run these rules automatically, and would always have the latest set of rules, without needing to update the client .exe.

RemObjects Script is an essential piece in our plan to take this to the next level, and we are currently working on full Business Rules Scripting support, both client and server side, and for all three editions of Data Abstract. The idea is that right inside Schema Modeler, you will be able to specify JavaScript based rules that can run either on the client (be it .NET, Delphi or OS X), the server, or both.

Server side rules can be used for the actual enforcement of rules, making it possible to replace a lot (if not all) of the code that currently makes up a common DA server. Client (and shared) rules can complement these to enhance the local editing experience, by “enforcing” adherence to rules while editing data, without requiring a roundtrip to the server for final validation.

This DA Scripting feature is in the works now, and will ship for the various editions over the remaining course of the year, starting with Data Abstract for .NET in May.

Relativity

Next up, we shipped the first release of Relativity. Relativity is our new standalone Data Abstract application server, replacing the aging (and Delphi based) DAServer.

The idea behind Relativity is that the vast majority of Data Abstract servers don’t really need much custom code (beyond business rules), yet the common Data Abstract approach today is to create a custom server .exe that needs to be built, deployed and maintained. With Relativity, this can now be a thing of the past, and you can deploy Data Abstract services in a ready-made server application, simply by uploading the appropriate .daSchema file.

Relativity is based on Data Abstract for .NET, but it ships with all three editions of Data Abstract. This means it gives Delphi developers the chance to use .NET drivers and the advanced server-side functionality such as DA SQL, without needing to purchase (or learn to work with) DA/.NET. It also allows Mac and iPhone developers to create and host servers (since we don’t ship a server library in DA/OSX).

And of course Relativity will also take full advantage of DA Scripting, starting in May.

More Stuff

In addition to these to “big ones”, we’ve also shipped a range of smaller new features and enhancements.

Internet Pack for .NET has been extended with a native client implementation for LDAP, which Carlo also blogged about before. We use LDAP a great deal internally, and this new client class makes it easy to build LDAP authentication into your RO/DA servers (or any other applications, of course). In fact, Relativity ships with a default LDAP Login Provider that is based on this implementation.

Data Abstract for .NET now provides the ability to expose data via the REST protocol, which makes it very easy to access data from non-DA client applications, for example from client-side AJAX based web sites. REST is one of many features we have added over the past year or so to enable better accessibility from web clients (another notable one is support for JSON messaging in RemObjects SDK), and we’ll be blogging and writing more abut this.

Our Xcode integration has been extended by new project templates that really make it easy to get going with Data Abstract or RemObjects SDK for the Mac or iPhone. These templates were created based on a lot of custom code i had written while implementing our internal Bugs 7 client, and they should provide a great starting point.

Screenshot 1 - Templates.png

(One of the next items on my list is a post that will look at these in more detail).

 

Visual Studio 2010The last important change i want to highlight is that the entire range of products for .NET is now compatible and integrates with the new Visual Studio 2010 (based on the current Release candidate, although we expect no problems between now and the final release of vs2010 in April).

What’s Next

Ok, so i mentioned work on three new major features has started this week, as well. What are those? The first one, of course, is the new DA Scripting support i mentioned above.

The second new feature is one that we have been planning for a while but are finally getting around to for this time, and that is a brand new “New Project” template architecture for both Delphi and .NET. The current templates are pretty server-focused, and don’t make it very easy to create different client types. Our new templates will be focused around ann the various client applications you might want to create (WinForms, WPF, Gtk#, Silverlight, Monobjc, ASP.NET, VCL, UCL, and so on), combined with a great integrated wizard that will allow you to either create a new server project to match, or connect your client to an existing (custom or Relativity) server.

The third new feature, which i am most excited about, is to round of our Mac development story to allow for pure Mac development of DA applications. We have the library to build great clients on Mac, iPhone and iPad. We now have Relativity to host DA services on a variety of server platforms. What’s missing, and what we’re working hard on for the May release, is the tool chain in the middle – a Schema Modeler for Mac that will enable developers to design and test their schemas, for Relativity deployment, right in their Mac.

 

Stay tuned for a lot more talk about all three of these topics, over the next three months. In the mean time, go and check out our “Spring 2010” releases, available now!

 

marc

# Photo(s) of the Week #28


DSC_9205.jpg

It’s been a while since i last posted photos. Has, in fact, been a while since i last got around to doing some decent shooting.

I mostly blame Xcode.

You see, when i started up serious photography in 2006, computing as my main hobby of choice had started failing me. Computer work, and programming, had become work, not a hobby, and i no longer felt like doing programming in my spare time. A year later, along came my first Mac (ironically because &ndash among other things – it allowed me to do the post-processing of my photos without having to deal with the scourge that is Windows), and about half a year later came interest in developing with Xcode, which turned around to be such an awesome and fun development environment that it turned around my apathy regarding programming and made me enjoy it enough, again, to do it in my spare time.

So these days, my weekends and evenings are, once again, spent developing cool stuff (like our Bugs 7 application or my OneSpace iPad app). Going out and shooting pictures moved a bit to the back burner. (of course, the cold Winter hasn’t helped, either ;).

In any case, today has been one of the first days of great (for February) weather here in Berlin, along with at times almost clear blue sky, and some great clouds, giving me the chance to whip out my camera and grab a few dozen nice shots for cloudporn.com, my neglected photo blog (SFW).

DSC_9170.jpg

These images were all shot on my converted D50 and the Nikkor 70-300mm. They are all infra-red, with only really minor retouching (contrast, mostly) in the new Aperture 3. While i’m usually a Lightroom guy, what i like about Aperture is that it allows me to preserve my in-camera calibrated white balance in infra-red short. (in Lightroom, it’d be impossible to get out images looking like these, except by converting to grayscale; the images you see here are not grayscaled).

DSC_9217.jpg

We’ll see how it goes, but for the new decade, i’ve sworn to find more balance and get out to do more photo shooting, once again…

# New Expression Types in Delphi Prism

It seems the sneak peek at “for expressions” in my previous post caused quite a bit of stir, so i figured i would spend a few minutes talking about the new expression types in general.

As you probably know, if you ever stopped to think about Pascal grammar, the most basic component that makes up a method body is a statement. A method body is pretty much defined as a list of statements, separated by semicolons. x := 5 is a statement. MyObject.DoSomething is a statement. Even a begin/end block is a statement (containing, nested within itself, another list of statements).

There’s a special kind of statements that seen frequently, and that are expressions. An expression is a statement that has a value, and as such, can be used in any code construct that expects a value – such as on the right side of an assignment, within arithmetic formulas, or as parameter to another method, for example. 5 is an expression. so is MyObject.ToString.

(In early Pascal, expressions did not use to be full statements. For example, functions (ie, procedures that return a value) could not be called without making use of that return value. In other words, sqrt(9) was not a valid statement, although x := sqrt(9) was. But that’s a thing of the past).

Functional Programming

Where am i going with all of this? Well, with the upcoming Spring 2011 release of Delphi Prism, we have extended the language. We took three commonly used statements, and we turned them into expressions.

This was done as part of an effort to bring more functional programing concepts to the language. Functional programing has been a niche in commercial software development for a long time, with most of the limelight going to (first) procedural and (later) Object Oriented programming, the latter of which is sort of a natural evolution of the first.

Functional programming uses a quite different paradigm, but it turns out that it is a very good fit for writing efficient multi-threaded code, and that’s why functional programming has been seeing a big revival over the past year or so, with developers looking at Erlang or Haskell. Microsoft has also stepped up its work on F#, a functional language for .NET, and is including that as a first-tier language in Visual Studio 2010.

For Prism, we decided to take a slightly different approach, and see if we could – over time – extend it with elements from functional programming languages, but, as has been the goal with Prism from day one, keeping them in line with traditional Pascal syntax and feel. (F#, for example, has many interesting concepts that make for a powerful language – but a god-awful and near-incomprehensible syntax to go along with them).

Our new expression types are a first step in that direction, so let’s have a look at them:

“if” Expressions

“if” statements are the bread and butter of just about every pascal method, allowing the conditional execution of one of two statements, depending on a boolean condition:

  if Condition then
    ThenStatement
  else
   ElseStatement;

The key word here statement. Both the then and the optional else case contain a statement (not an expression!) they execute, and as result, the entire if clause is a statement (but on an expression).

We have extended this syntax to allow the entire “if” clause to become an expression, if the statements it contains are expressions, as well. in other words, you can now write

  if Condition then
    ThenExpression
  else
   ElseExpression;

and the entire construct is an expression, representing the value of either ThenExpression or ElseExpression. To give a real life example, you could write:

  s := 'The Condition is ' + if Condition then 'true' else 'false';

The type of the “if” expression (in this case, a String) is determined by the lowest common denominator of the two expressions. If the optional else clause is missing, the result for a false condition will be nil, and if the type of the then expression is a value type, the “if” expression will be a nullable type. In the following example:

  var x := if Condition then 3;

x will be a nullable Int32, and contain a value of either 3 or nil.

“case” Expressions

The same extension applies symmetrically to “case” statements. A case statement where each individual case is an expression becomes an expression itself. As with the “if” expression, the type will be the determined by lowest common denominator of all the contained expressions, and if no else statement is provided, it will be nullable.

For example:

  s := case Number of
         1: 'One';
         2: 'Two';
         else 'Many';
       end;

I hope looking back, it makes sense why went into such detail with regard to statements vs expressions, at the start of this post. The point, really, is that expressions are just a sub-type of statements that have a value. And if you think about it, there’s really no good reason why the above statements/expressions should not have a value, and thus be expressions.

“for” Expressions

The last new type of expressions i want to talk about are “for” expressions. As with the other two, we have taken the regular “for” loop statement, and enabled it to be an expression:

  for each x in SomeSequence yield Expression;

and

  for x := StartValue to EndValue yield Expression;

As you can see, the syntax for this uses a slight variation on that of regular “for” statements, by replacing the do keyword with yield. This is mainly because yield makes more sense in the context of an expression. do implies execution, but we’re really yielding the value for each iteration of the loop.

If this sounds familiar from another feature in Delphi Prism called iterators, then that is no accident. A “for” expression has very much the same attributes and behavior of an iterator – in fact, you could think of them as “anonymous iterators”.

So what is the value of a “for” expression? The mentioning of iterators and the use of the yield keyword may have given it away: the value of a “for” expression is a sequence containing each of the individual expressions.

For example:

  var SomeNumbers := sequence of Int32;
  SomeNumbers := for i: Int32 := 0 to 100 yield i*i;
  // SomeNumbers contains the squares of 0 thru 100

And, just like an iterator, this sequence will be generated on the fly, as it gets enumerated. In the example above, no code runs to actually “calculate” the numbers 0 thru 10000 – the “for” loop itself is an O(1) operation. It’s not until we access the sequence – for example thru another for each loop, that the actual squares will be calculated.

To give an extreme example it’s entirely fine to declare the following

  var AllInts := for i: Int64 := 0 to Int64.MaxValue yield i;

to get a sequence of all (positive) Int64 values. We could then loop over that, using say

  for each x in AllInts index i do begin
    // only handle first thousand items. else we'd be at it forever.
    if i < 1000 then break;
    Console.WriteLine(x);
  end;

Summary

And that’s the new expression types, one of many new features in the upcoming Spring 20112010 release of Delphi Prism. If you’re part of the field test (and if you’re an active Delphi Prism customer, you really should be!), you can see these in action in the current beta drop.

Let me know what you think, and stay tuned for more!

# New Syntax for Extension Methods in Delphi Prism

Ever since Extension Methods have been introduced in .NET 3.5, we’ve been pondering on a proper syntax to allow developers to define their own. C# uses an awkward syntax where it uses the this keyword (C#’s equivalent of self) as name of the first parameter. But that felt wrong. For one, it’s a very C-like thing to do (having an obscure syntax that is not really discoverable or understandable, it ranks right up there with =0 for abstract methods in C++), for another, the fact that methods receive a self pointer as first parameter shoud be an implementation detail of the language (or runtime), not a syntax feature.

Another idea was to simply allow a new extension directive to be appended to a method declaration (similar to virtual or similar constructs). But that too felt wrong.

So what we did, for the time being, was to not provide any special syntax at all, and let people simply define extension methods “manually”, by applying the appropriate attributes. Given that extension methods are consumed (which we have always supported) much more often than defined, we figured this was a good enough compromise, for the time being.

Then, a couple months back, i was doing some language research, among with was watching the introduction video for Go, the new system language created by Google. While in general Go’s syntax felt, to me, like C/C++ beaten with the ugly stick (no offense), it introduced some nice concepts, and one thing that struck me was how easily Go allowed to declare new methods for a class.

This, i thought, was how extension methods should work like, in Prism. An extension method, ultimately, should not have to be part of some arbitrary class that has nothing to do with that method or with the class you are extending. Forcing extension methods into a class syntax is not proper Object Orientation – on the contrary, it’s an abuse of OO syntax. And why shouldn’t you be able to just go ahead and declare the method – without having to learn some awkward syntax or rules?

i decided you should, and after convincing Carlo to do the actual implementation, i am happy to let you know you that starting with the upcoming Spring release of Delphi Prism, you can now define extension methods by, well, just defining them.

Behold:

extension method Int32.Twice: Int32;
begin
  result := self*2;
end;

If we overlook the new extension keyword for now, this looks like a regular method on Int32 – which, essentially, it is. There is no need to define an awkward “self” parameter; you just specify the method name prefixed with the type – as you’ve done thousands of times when writing your own classes – and the compiler takes it from there.

Only the extension keyword indicates that Int32 is not really your own class, but that you’re extending a class defined somewhere else.

This new syntax should make it much more convenient and attractive to define new extension methods, when and where you need them – without all the overhead of a class declaration.

Of course this works on more complex types, as well; the following complete program prints the square of all numbers between 0 and 100 – not by squaring the numbers, but by squaring the sequence of numbers. (It also shows off two other new language features we haven’t talked about yet ;)

namespace ExtensionMethods;
 
interface
 
uses
  System.Collections.Generic,
  System.Linq;
 
extension method IEnumerable<Int32>.Squared: IEnumerable<Int32>;
 
implementation
 
extension method IEnumerable<Int32>.Squared: IEnumerable<Int32>;
begin
  result := for each value in self yield value*value;
end;
 
begin
  var values := for i: Int32 := 0 to 100 yield i;
 
  for each i in values.Squared do
    Console.WriteLine(i);
end.

Let me know what you think!

# Everything is Relative

Today i want to talk a bit about “Relativity”, a new feature we’re shipping with Data Abstract this month (and which is actually available as “tech preview”in the current Winter 2009 releases).

“Relativity” is, simply put, a standalone server application that can be used to host Data Abstract schemas and serve data. In essence, it provides the complete Data Abstract middle tier, in a precompiled box and ready run. This offers several benefits, not the least of which are:

  1. No need to build your own. Relativity provides all the power and abstraction of a true Data Abstract middle tier server, without you actually having to create, build, and deploy your own executable. This allows you to concentrate on the client development. It also is really handy for prototyping, if you just want to have database server to talk to, without much work, even if you plan to eventually implementing your own custom server.
  2. Build on Data Abstract for .NET. .NET is platform with the most advanced version of DA – it supports our powerful DA SQL execution engine, and other features not available on all platforms. “Relativity” is being made available to all users of Data Abstract, so whether you’re a developer using .NET, Delphi, or Xcode, you can now write clients against Relativity that take full advantage of these features.

But let’s go and take a more detailed technical look at Relativity.

Relativity is a server application, so it does not provide any user interface. You can deploy a Relativity server in several ways, including:

  • Running it as a regular user application, on Windows.
  • Installing it as a Windows service.
  • Running it as a Unix daemon with the mono-service2 tool, on Mac and Linux.
  • Running it as a menubar item, on Mac.

Regardless of how you deploy and run it, Relativity will start making it’s Data Abstract services available on (by default) port 7099. But of course before it can start serving actual data, it will need to be configured with what data to serve. That is done thru the Relativity Server Admin tool, which is currently available for Windows (but versions for both Mac and iPhone are in the works).

When you first start it, the Admin tool will look something like this:

Screen shot 2010-02-03 at 2.24.03 PM.png

On the left hand side, you will see a tree view with all known instances of “Relativity” servers. This includes any servers (local or remote) that you connected to in the past, as well as any servers discovered on the local network using ROZeroConf.

Select any of the servers (here, “VEMMY” is the one instance running in my Windows VM), to connect and get more options.

Screen shot 2010-02-03 at 2.30.01 PM.png

The first two nodes allow you to configure how this “Relativity” server is accessed. This includes options such as what ports to listen on, what RemObjects SDK channels and messages to use, etc. Here you have the full choice of all the options provided by RO, you can choose the familiar HTTP, TCP, Super HTTP or other channels, BinMessage, SOAP Message, and so on.

Where it gets more interesting is the third node – Domains. This is where you configure the meat of the services Relativity is providing.

Each Domain corresponds to what typically would be a separate Data Abstract middle tier server. Domains are completely abstracted from one another and Relativity allows you to host as many separate domains as needed. With that, a single Relativity server can replace multiple DA servers, be it for related to completely independent applications or projects.

As you can see, i have three domains set up in my server, one for “BC7″, our new bug tracking system (using a PostgreSQL database running on our Xserve build server), one for “RemObjectsCom”, the database that drives our website (Microsoft SQL Server, running on the Windows server that hosts our website), and finally “OneSpace”, the database for a personal iPad project i am working on.

As we drill into a specific domain, you start seeing more things that will be familiar to you as a Data Abstract developer. Each domain can contain one or more Schemas – which correspond directly to .daSchema files or TDASchema components as you know them. You can manage schemas right there in the Admin tool, or directly launch Schema Modeler to edit the schema in question:

Screen shot 2010-02-03 at 2.39.38 PM.png

The domain also maintains a list of Connections to back-end databases available to it’s schemas. Once again, this directly corresponds to the .daConnections file or TDAConnectionManager component. Since Relativity is based on DA/.NET, these connections are based on the available DA/.NET drivers – regardless of whether your regular development platform is .NET, Delphi or Cocoa.

Another interesting part is the Login node. Relativity provides several options for handling authentication from client applications for data access (something you would normally need to manually implement, in a standalone DA server): in addition to relying on a static list of allowed username/password combinations, you can also choose to use a data table or command defined in one of the domain’s schemas to verify users (as i do in the example shown below) or query an external LDAP server for login.

The LDAP option is very handy if you are running a variety of services – some using Relativity, and some not – that you want to share user data among. We recently switched to LDAP for all our employee resources, and it has made administration so much easier.

The LDAP support in Relativity is based on a new 100% managed LDAP client implementation we’ve added to Internet Pack for this upcoming release. Carlo will blog more about this, soon.

Screen shot 2010-02-03 at 3.05.53 PM.png

The Login Provider architecture is extensible, so you can implement your own providers, for example if you need to do user authentication with a different method.

Client Access

Once you have Relativity set up to serve your data, your client application(s) can access it like any other Data Abstract server.

The only slight difference is that, since a Relativity server can host more than one domain, you need to tell the server which domain to access, by simply passing an additional Domain parameter as your login string, as in

User=foo;Password=bar;Domain=DomainName

You will also want to select which Schema to query. in regular DA applications, each schema usually has its own DataService, so keeping in line with that, Relativity allows you to append a schema name to the ServiceName property of your Remote Service. Instead of using DataService, simply use DataService.DomainName. (Alternatively, you can also pass a Schema to LoginEx).

In Closing…

So, this has been a brief introduction to Relativity – i hope you found it useful.

We think of Relativity as a strategic piece of Data Abstract, and it will play an increasing part in what we do for DA. We have lots of things planned for the future that will make Relativity even more powerful, such as our upcoming JavaScript Business Rules Scripting based on Carlo’s RemObjects Script for .NET.

You can try out the tech preview of Relativity now, and the official release will be part of what we ship at the end of this month. I’m looking forward to your thoughts and feedback!

marc

# Visualizing Data with Core-Plot

Core Plot is an open source graphing framework for Cocoa developers that makes it really easy to add graphs to your applications for the Mac and iPhone. Over the past half year, i’ve had the chance to use Core Plot in several of the internal applications i have been working on and have been very impressed with it, so i wanted to talk a little bit about how to use the library, in general, and how to make generate charts based on data in a Data Abstract for OS X application, in particular.

The example shown here is from a small iPhone application i wrote to keep track of the status of our Continuous Integration servers. The application shows the success (or errors) of any builds done on the machine, as well as – and this is the part where Core Plot comes in – graphs the number of tests that run and fail, over time:

In the application in question, the chart is being displayed in a cell within a UITableView, so our example starts out by implementing a custom UITableViewCell class that will host the graph. But the same general principles apply to show a chart anywhere else (and, replacing UIView with NSView, for using charts in a desktop app).

Core Plot uses a Core Animation as underlying technology, and as such draws itself in a specialized view class CPLayerHostingView. So we start out by crating this view, and adding it as sub-view:

- (id)initWithStyle:(UITableViewCellStyle)style 
{
  self = [super initWithStyle:style reuseIdentifier:@"MyChartCell"];
  if (self)
  {
    CGRect frame = self.contentView.bounds;
    CPLayerHostingView *chartView = [[CPLayerHostingView alloc] initWithFrame: frame];
    [self addSubview:chartView];
    //...

Once the CPLayerHostingView is created, we can add a graphs to it, and configure them. There are several graph types supported, but we want a regular line graph with X/Y coordinates, so we’ll choose a CPXYGraph class. We’ll add the graph to the view, and set a padding, to give us some room between the edges of the table cell:

  // create an CPXYGraph and host it inside the view
  CPTheme *theme = [CPTheme themeNamed:kCPPlainWhiteTheme];
  graph = (CPXYGraph *)[theme newGraph];	
  chartView.hostedLayer = graph;
 
  graph.paddingLeft = 10.0;
  graph.paddingTop = 10.0;
  graph.paddingRight = 10.0;
  graph.paddingBottom = 10.0;

The next step is to set up a plot space. A plot space defines the coordinate system for one or more charts in a graph, essentially mapping logical values to the area in the graph. For example, your chart might show values ranging from, say, 0 to 1000. The plot space defines the scale of those values in relation to the graph. It also defines the visual range of values that can be seen on screen.

To match our X/Y graph, we’ll create a CPXYPlotSpace, and set it to a range of 0-100 for both axis:

  CPXYPlotSpace *plotSpace = (CPXYPlotSpace *)graph.defaultPlotSpace;
  plotSpace.xRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(0)
                                                 length:CPDecimalFromFloat(100)];
  plotSpace.yRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(0)
                                                 length:CPDecimalFromFloat(100)];

Finally, we’ll set up to axis, for the X and Y coordinates. Axis provide labels and tick-marks for the viewer, to give context to the values being shown.

The X/Y graph already provides a set of axis in for of a – you guessed it – CPXYAxisSet class. There are several properties on the axis’ that are worth looking at at tweaking to to suite out needs:

  • majorIntervalLength defines the number of units between “big” ticks on the axis. In this case it’s set to show one very 10 units. (if it were not for the exclusionRanges, discussed below, a numeric label would show for each major tick, as well).
  • minorTicksPerInterval specified how many small ticks will be shown between each major one. in this case, a value of 2 indicated that small would show for 5, 15, 25, etc. (a value of 9 would show ticks for every single unit).
  • Finally, exclusionRanges allows to define areas where no axis labels will be drawn. In my app, i don’t want to see any labels, so i set a range to exclude the entire visible graph
  CPXYAxisSet *axisSet = (CPXYAxisSet *)graph.axisSet;
 
  CPXYAxis *x = axisSet.xAxis;
  x.majorIntervalLength = length:CPDecimalFromFloat(10);
  x.constantCoordinateValue = length:CPDecimalFromFloat(2);
  x.minorTicksPerInterval = 2;
  x.borderWidth = 0;
  x.labelExclusionRanges = [NSArray arrayWithObjects:
                              [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(-100) 
                                                          length:CPDecimalFromFloat(300)], 
							  nil];;
 
  CPXYAxis *y = axisSet.yAxis;
  y.majorIntervalLength = length:CPDecimalFromFloat(10);
  y.minorTicksPerInterval = 1;
  y.constantCoordinateValue = length:CPDecimalFromFloat(2);
  y.labelExclusionRanges = [NSArray arrayWithObjects:
                              [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(-100) 
                                                          length:CPDecimalFromFloat(300)], 
							  nil];

Our graph is now fully set up – except for one important part: we still need to define one or more charts to display actual values. My application needs to show two graphs on top of each other – one showing the total number of tests that ran, and another showing the number of failures.

Core Plot supports a variety of chart (or, plot) types, such as bar and pie chart, but for this scenario, we want a simple line graph, which is done via a CPScatterPlot. (A scatter plot actually allows to draw a plot with points scattered all over the place, not just as string y = f(x) values, but we will use it in the more simplistic case).

We’ll create a new CPScatterPlot instance, configure some properties such as its lineWidth and lineColor, and most importantly, set the dataSource to the object that will provide the plot with its data – in this case, self. To round things off, we also tell the plot to fill the area underneath it with a gradient, going from almost-transparent green to nothing. This gives the plot some depth, without hiding the other plots.

  CPScatterPlot *dataSourceLinePlot = [[[CPScatterPlot alloc] init] autorelease];
  dataSourceLinePlot.identifier = @"AllTests";
  dataSourceLinePlot.dataLineStyle.lineWidth = 3.f;
  dataSourceLinePlot.dataLineStyle.lineColor = [CPColor greenColor];
  dataSourceLinePlot.dataSource = self;
  [graph addPlot:dataSourceLinePlot];
 
  // Put an area gradient under the plot above
  CPColor *areaColor = [CPColor colorWithComponentRed:0.3 
                                                green:1.0
                                                 blue:0.3
                                                alpha:0.3];
  CPGradient *areaGradient = [CPGradient gradientWithBeginningColor:areaColor 
                                                        endingColor:[CPColor clearColor]];
  areaGradient.angle = -90.0f;
  CPFill *areaGradientFill = [CPFill fillWithGradient:areaGradient];
  dataSourceLinePlot.areaFill = areaGradientFill;
  dataSourceLinePlot.areaBaseValue = CPDecimalFromString(@"1.75");

We repeat the above to add a second plot, except this time we use red for the line color and gradient, and set the identifier to @"FailedTests".

This was quite a bit setup, but our graph is now ready plot, and will ask its data source (our cell) for data by sending it messages from the CPPlotDataSource protocol. This protoco will be familiar to any Cocoa developer who worked with, for example, a UITableView or NSTableView, or any other control using a data source.

To the protocol, two methods need to be implemented. The first is numberOfRecordsForPlot: which will, simply enough, return the number of items (in case of a scatter plot, points, the chart will contain. The second can be one of three methods that return the actual data. We’ll implement numberForPlot:field:recordIndex:.

The data to display is retrieved via Data Abstract, using a simple DA SQL request on a table that contains all test runs:

	NSString *sql = [NSString stringWithFormat:@"SELECT TOP 50 ID, _TotalTestCount, \
                                     _FailedTestCount, FROM TestRuns ORDER BY ID DESC"];
	testRuns = [[rda getDataTableWithSQL:sql] retain];

The _TotalTestCount and _FailedTestCount fields are server-calculated based on a relation table and contain the total number of run and failed tests for each test run. We can Key Path operators to get the maximum value, and adjust our plot space accordingly, so that the entire graph fits into the chart:

  int count = [[testRuns rows] count];
  int maxTests = [[[testRuns rows] valueForKeyPath:@"@max._TotalTestCount"] intValue];
 
  CPXYPlotSpace *plotSpace = (CPXYPlotSpace *)graph.defaultPlotSpace;
  plotSpace.xRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(0)
                                                 length:CPDecimalFromFloat(count)];
  plotSpace.yRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(0)
                                                 length:CPDecimalFromFloat(maxTests)];

This is of course a bit redundant with the values we set earlier, but in real life application, the data access will usually happen in a different place than the initial setup (and data might get changed or refreshed during the course of the application), so i find it important to set up the graph properly to begin with, but then adjust the range to the real data.

With the data retrieved and the plot space adjusted, we can now implement the two data source methods.

numberOfRecordsForPlot: will simply return the number of rows in our table. numberForPlot:field:recordIndex will be called twice per data point, once for the X value (since we’re drawing a “non-scattered” plot, we’ll simply return the indexes) and one for the Y value, which we’ll retrieve from our data table. The different identifiers we assigned to the two plots will serve to distinguish which field to use for the Y value.

-(NSUInteger)numberOfRecordsForPlot:(CPPlot *)plot 
{
  return [rows count];
}
 
-(NSNumber *)numberForPlot:(CPPlot *)plot 
                     field:(NSUInteger)fieldEnum 
               recordIndex:(NSUInteger)index 
{
  switch (fieldEnum)
  {
    case CPScatterPlotFieldX: 
    {
        // inverse numbers, so first (latest) test run is on the right.
        int x = [rows count]-recordIndex; 
        return [NSDecimalNumber numberWithInt:x];
    }
    case CPScatterPlotFieldY:
    {
      if ([plot.identifier isEqual:@"AllTests"])
      {
        float v = [[[rows objectAtIndex:index] valueForKey:@"_TotalTestCount"] floatValue];
        return [NSNumber numberWithFloat:v];
      }
      else
      {
        float v = [[[rows objectAtIndex:index] valueForKey:@"_FailedTestCount"] floatValue];
        return [NSNumber numberWithFloat:v];
      }
    }
  }
  return nil;
}

And that’s it! You can find more info on Core Plot on their Google code page; i also recommend joining their mailing list for latest news and support.

# Reusing C# in Your Prism Projects

One of the (few) concerns we hear from people looking to get started with Delphi Prism is that most of the code samples and snippets that are available on the net are written in C#.

Because .NET is fully language agnostic, reusing existing libraries and assemblies written in C# (or any other language) generally is no problem, but for smaller pieces of code – classes or even just small code snippets – it is inconvenient for the Prism developer to start a separate C# project – making manual translation (and sometimes, deeper understanding of the C# language and its intricacies) necessary.

We wanted to make this easier, so for the upcoming February* release of Delphi Prism, we’ve added two new features to the IDE, based on out open source C# to Oxygene tool.

The first is the new Paste C# as Oxygene command in the source editor. If you find snippets of C# code on the web (or elsewhere) that you want to reuse in your project, simply copy them to the clipboard, and then right-click into your code and choose Paste C# as Oxygene from the context menu:

The IDE will translate the code for you, and paste the Oxygene version in. This will work on just about any type of code – from a single line of code or a few compound statements, to entire method bodies, or even full classes. (Because classes are self-contained entities in C#, but split in declaration and implementation in Oxygene, pasting a whole class will actually generate a whole source module, including with “interface” and “implementation” sections. As such, pasting full classes works best when done into an empty file).

All of this is great when you have code snippets, especially from websites, forums or newsgroups. But what about C# files already on disk? That’s where the second feature comes in: if you right-click your Delphi Prism project and go to the Add menu, you’ll see a new Import C# sub-item. Select this, and you’ll be presented with a regular File Open dialog, where you can browse to and select one or more .cs files on your harddisk. When you click Ok, each .cs file will be translated to Oxygene, and a corresponding new .pas file will be added to your project:

How well does this work? C# is a complex language, so while Oxygene provides a complete superset of what can be done in C#, there might be some cases where complicated C# code will confuse the translator, but in the vast majority f cases, the translate code will work as is.

One of our test bases is the entire RemObjects SDK for .NET library, and the tool translates that very satisfactory.

Paste C# and Import C# are probably not features you want to use to blindly translate whole projects with and reuse the resuiting code without further testing or review, but in our experience it is working very well or the intended purpose – reuse onf code snippets found online.

Just like Oxfuscator, covered in my previous post, this is in the current beta drop, so if you already a Delphi Prism user (or buy it now), make sure to apply for the beta.

* the “February” release will ship a bit later than February, this year, as we want to align it with the public release of Visual Studio 2010, which has been announced for April. Internally, we still refer to it as the “February Release”.

# Incremental Data Fetching in Data Abstract for OS X

Bugs 7, the new bug-tracking application i have been working on over the past month for internal use here at RemObjects, employs several different data access paradigms (all based on Data Abstract for OS X), to accommodate the different nature of the data in individual tables.

The most interesting one is the main Issues table that contains all the bugs and tasks that are logged in the system. That is due to the fact that (a) it is a huge table (with over 25,000 records as of now, sized at about 11 MB when transferred over the wire, compressed) and that (b) by the very nature of a bug tracking system, this table changes frequently, and needs to be updated on the clients, often.

Rather then downloading the entire table anew every time, we optioned for a solution that allowed us to incrementally fetch only those records that have changed, and integrate them with the local dataset. This way, only minimal traffic is occurred for the regular refresh (which our client, by default, does every two minutes).

In the following post, i want to give you a quick glimpse at how this was accomplished, and how you can leverage the same technology in your own Data Abstract applications.

The Server

A couple things happen on the middle tier server (written using Data Abstract for .NET), to support the incremental refresh. Like all tables in the Bugs database, our Issues table has an UpdatedDate field, which gets automatically adjusted by the business logic code on the server. Every time a new issue is created, or an existing issue is updated, the server puts the current UTC time into the UpdatedDate field, clearly marking the order in which issues have been touched.

This is handled by a simple BeforeProcessChange event handler on the server, which simply adjusts the received delta, as such:

method BugsDataService.bp_Issues_BeforeProcessChange(aSender: BusinessProcessor; ea: DeltaChangeEventArgs);
begin
  ea.DeltaChange.NewValues['UpdatedDate'] := DateTime.Now;
  ea.DeltaChange.NewValues['UpdatedByID'] := Session['UserID'];
end;

(Of course the actual code in our server performs a lot more checks and changes, to enforce business logic for our database – but that’s beyond the scope of this post.)

Also, our Issues table does not permit deleting of records (only closing of issues, which sets their status accordingly, but does not remove the rows from the database). This alleviates the problem of worrying about rows disappearing from the table altogether.

The Client

On the client, a bit more custom logic is necessary, to perform the incremental updating.

When the client application (“Bugs 7”) is first started, it checks whether a briefcase file with a local copy of the data is found from a previous run, or not.

If not, the client will start a request to download the complete set of data from the server. This is a one-time process, and will download the entire table with it’s (currently) 11MB across the wire. Once downloaded, it is stored in a briefcase file, so on next application start, the data can be loaded locally. After the download is finished, the application also takes note of the latest UpdatedDate value it can find in the table, for future reference. This is made easy by Cocoa’s KVC and Key Paths:

- (void)downloadIssueData 
{
	// Initial download can take long, server side, to gather data. 
	// allow for a longer timeout.
	[(ROHTTPClientChannel *)[[rda dataService] channel] setTimeout:360];
 
	// fetch full table from server	
	issues = [[rda getDataTable:@"Issues"] retain];
	maxDate = [[[issues rows] valueForKeyPath:@"@max.UpdatedDate"] retain];
 
	// save table to briefcase
	[self saveIssues];
}

If instead a briefcase was found, the Issues table simply gets loaded from that file, alongside the stored maxDate:

- (void)loadIssueDataFromBriefcase
{
	DABriefcase *briefcase = [DABriefcase briefcaseWithFolder:briefcasePath];
	issues = [[briefcase tableNamed:@"Issues"] retain];
	maxDate = [[briefcase.properties valueForKey:@"BugsMaxUpdateDate"] retain];
}

Whichever path was taken, the application now holds a local copy of the Issues table it can work with. The next step it to schedule the regular refreshes, and for that an NSTimer is configured, to fire at regular intervals, on a background thread.

This NSTimer will trigger our beginRefreshBugs method, which uses asynchronous requests to start checking for new issues. It uses the previously stored maxDate and a feature of Data Abstract called DA SQL, to fetch only those issues that have newly changed:

- (void)beginRefreshBugs
{
	// prevent two refreshs happening at the same time, if the NSTimer
	// triggers again before the previous refresh has finished.
	if (refreshingBugs) return; 
	refreshingBugs = YES;
 
	// build the DA SQL query
	NSString *sql = [NSString stringWithFormat:"SELECT * FROM Issues WHERE UpdatedDate >= '%d'",
						(int)[maxDate timeIntervalSince1970]];
 
	//and start an Async Request to the server
	DAAsyncRequest *ar = [rda beginGetDataTable:@"Issues" withSQL:sql start:NO];
	[ar setDelegate:self]; 
	[ar setContext:@"RefreshIssues"];
	[ar start];
}

The DAAsyncRequest, once started, will communicate with the server in a background thread, without blocking the caller. beginRefreshBugs will return right away, and not wait for the request to complete (or fail).

Once the request did complete, it will call back to a delegate method (in this case we assigned self as the delegate, above), called asyncRequest:didReceiveTable:. It is here that we handle integrating the received data back with our big issues table by sending it the mergeTable:withPrimaryKey: message. This will replace the data in any rows that have changed, as well as add any new rows to the table:

- (void)asyncRequest:(DAAsyncRequest *)request didReceiveTable:(DADataTable *)table
{
	// our class may handle access to more tables. check the context
	// to make sure we handle the right requests.
	if ([[request context] compare:@"RefreshBugs"] == NSOrderedSame)
	{
		// nothing received? nothing to do!
		if ([table rowCount] > 1) 
		{
			@try
			{
				[issues mergeTable:table withPrimaryKey:@"ID"];
				maxdate = [[[table rows] valueForKeyPath:@"@max.UpdatedDate"] retain];
				[self saveBugs];
			}
			@finally 
			{
				refreshingBugs = NO;
			}
		}
	}
}

Of course a refresh might also fail (for example due to a broken internet connection, for this case, we implement a second delegate method, called asyncRequest: didFailWithException:, as follows:

- (void)asyncRequest:(ROAsyncRequest *)request didFailWithException:(NSException *)exception
{
	if ([[request context] compare:@"RefreshBugs"] == NSOrderedSame)
	{
		refreshingBugs = NO;
	}

The View

The last step after receiving new issues is to update any affected views. This happens more or less automatically, as every view that shows one one more issues (whether it’s the regular grid view of issues, a chart visualizing issue data, or an individual issue’s detail view) will be have registered itself to observe DA_NOTIFICATION_TABLE_CHANGED notifications on issues. And like any other change to a data table, mergeTable:withPrimaryKey: will send such a notification if changes happened, allowing all views to update themselves.

In Bugs, all of this happens in the background, so over time the view(s) presented to the user just seamlessly adjust themselves, as changes happen – new issues come into views; issues resolved by other users disappear on their own, etc.

This topic just touches on a very small aspect on Bugs 7, which itself is part of a mch larger project, comprised of four different client applications (Mac and iPhone, based on DA/OS X, for Windows, based on DA/.NET and Gtk# and the Web) as well as a middle tier server. We will blog more about different aspects of this project over the next few months, ands we’re also working on a bigger case study, to appear at bugsapp.com, soon. Stay tuned to this space, for more.