What is Tangram?

Each piece of the Qi Qiao Tu (Seven Ingenious Plan, or Tangram) is a combination of multiple copies of the smallest piece.

In the ancient Chinese puzzle of Qiqiaotu, seven pieces are arranged to try to form a specific shape. Each piece is simple, yet as they fit together seamlessly the scope for different configurations is endless.

Tangram provides for your Perl programs the basic pieces that allow you to take a program model - such as a UML or Entity Relationship diagram - and convert it directly to a Tangram Schema. Interfaces have been written to allow a more rapid development of data models, similar to the Alzabo data modeller.

Once you have this schema, you can easily create transaction-savvy applications that can perform complex queries on your data base, without directly coding SQL. Advanced demand loading1 combined with a superb data caching model2 removes the need for a fantastic proportion of queries in a typical program.

Tangram implements Orthogonal Object Persistence to Relational Databases

That term might not make much sense to a lot of people - no doubt including people who have been programming for decades - so your first reaction might be, "Oh, no, another Object Orientated Loony! Please $self->fornicate". If that is your reaction, perhaps one of the other similar tools mentioned on this page will be more your style.

To explain it piece by piece - Object Persistence in this context, means taking Perl objects and saving them somewhere. Lots of tools on CPAN will do that for you, from humble serializers like Storable or YAML, to more structured solutions like MLDBM or Pixie.

Orthogonal (literally “at a tangent to”) means that the tool itself does not intrude on the application, such as by requiring all stored objects to have a common base class, associating storage-related information in the (user-visible) data structure or requiring the objects to conform to an interface by implementing special methods. Very few CPAN modules that implement forms of object persistence are truly orthogonal.

Whilst Tangram itself is orthogonal, a companion module Class::Tangram exists that makes Perl classes from entire Tangram Schemas (via Class::Tangram::Generator) or portions of schema and give you fully customisable packages and DWIM accessors for your data structure. Class::Tangram has been designed to honour various Object Orientation principles.

Relational Databases are the predominant storage systems used and taught throughout the advanced programming world. They are distinctly different from heirarchical databases, such as file systems, in that they are based on Set Theory. Some understanding of set theory, or experience with relational databases is beneficial but not essential for using Tangram.

What Tangram is not

Tangram does not provide Storage Objects. That is, the programming style where every action performed on an object will immediately be updated in the open database transaction, perhaps after calling a “store” method. This is a complementary approach to Tangram - and a very simple and effective technique, used by modules such as Class::DBI or Class::Persist3.

Tangram can not (always) be used to retro-actively fit a database in the way that Alzabo or Class::DBI can. If you are able to accomodate minor schema additions to the original database, and certain conditions are met, it can be possible to engineer a Tangram Schema that maps to a desired database structure - but this is not the design intent of Tangram, and you will be missing out on a lot of features.

The current version of Tangram is not lightweight. The focus has never been on optimising for Perl-side performance, but more for schema flexibility and enabling you to write database efficient programs. No library can really put trainer wheels on the open-ended nature of data structure design.

For long-running applications such as OLTP (eg, web applications), this is generally a good thing, however there are applications that would be unncecessarily slowed by using Tangram over using DBI directly. This may change when Tangram is refactored to T2. Don't you just hate it when software projects go the same way as movie sequels? The same mentality that brought you, $hollywood_blockbuster now brings you $hollywood_blockbuster[1]. But nobody stopped to think, “hey, guys, what do you think the cinematography was like on that one, don't you think we wrote the lead characters to be a bit stock, dead and lifeless? Maybe we should fire the sound engineer who kept repeating all that patriotic fanfare during the fight scenes, you know maybe that portraying the American Dream Perpetuating along with scenes of gooks dying, good guys winning and people being mutilated with Hot Irons would be so ... very ... ironic?”. In the words of the late Allen Ginsberg - "Hollywood will get what it deserves: time."

But I digress. Rest assured that T2 is not going to be a badly done sequel. See, I haven't even bumped the version number, it can't be getting new, improved, etc. It will be Tangram 2 refined.

Update: looks like hell was freezing over at a faster rate than T2 being finished. But all is not lost, I hope to start again using Moose as a meta-model and DBIx::Class as a database driver for the new project, which I have written a paper on. Somebody once said that you can tell that the death of a project is nigh when they start putting up specifications in postscript. Oh, well.

Getting Started

There is extensive documentation for Tangram, including tutorials and (soon!) example schemas and applications. There is also a relatively low volume mailing list. You can get the latest version of Tangram from search.cpan.org, the downloads section of this web site, or directly from the utsl.gen.nz Git repository.


Footnotes
  1. Demand loading is the normal RAD way of building apps, but pre-caching facilities are also available for those situations where you need it.
  2. All objects are cached, but there is an easy way to dump the cache - so you can start each database transaction free of “dirty read” related problems.
  3. Class::Persist perhaps doesn't fit cleanly into this category, but then trying to categorise programming libraries into hard and fast categories is a mistake in the first place. I put it in this category primarily because the data source (connection) and package are tightly bound.