ramblings on PHP, SQL, the web, politics, ultimate frisbee and what else is on in my life
back

c# 3.0's LINQ

I have been looking a bit at c# 3.0's LINQ feature. Essentially it provides with c# with an SQL syntax to do what SQL does on DBMS, XML, Array and many other forms of data. What is interesting that the syntax also allows you to define not only what data you want but also the structure you want it in. Furthermore using reflection on the data source and generally the fact that you are no longer passing just a string to your datasource (SQL or XQuery) it is now possible to do compile time checking.

At first it seemed quite wierd to me. But I am slowly warming up to the idea. Pondering things a bit further I discovered that in many ways PHP has tried to push things into a similar direction. For example PEAR::DB's getAssoc() method (as well as equivalent methods in MDB2 and PDO) have the ability to group a single column in a result set. All of the mentioned database layers are also able to immediatly construct new objects of a given class from the returned data. PDO even supports re-using an existing instance on fetch. However its obvious that LINQ takes things further by allowing much deeper structures and by making this a single step. In PHP we would still need to define the SQL and then in a second step tell the API to group things for example.

As for the idea of providing an SQL like syntax to work with all sorts of data sources I was sort of reminded by my work on the LiveUser_Admin API. While I do not support quite as much features as LINQ does, its possible to pass a fairly complex set of parameters and get SQL generated. I have designed the API in such a way that I think it should be possible to also write an XML backend for this.

So the following code:


<?php
$admin->perm->getGroups(
 array(
  'fields' => 'group_id',
  'filters' => array('right_id' => array(1, 5)),
  'select' => 'col',
  'orders' => array('perm_user_id' => 'DESC'),
 )
);

/* Will generate the following SQL query and will fetch the first column into a single dimensional array

SELECT groups.group_id AS group_id
 FROM groups, groupusers, grouprights
 WHERE grouprights.right_id IN (1, 5)
   AND groups.group_id = grouprights.group_id
 ORDER BY groupusers.perm_user_id DESC */
?>

The code that generates the SQL can be found here. Since this stuff can make use of MDB2 the storage layer is database independent. Well honestly I have only tested things with MySQL and SQLite myself. But I know there are users on PostGreSQL and MS SQL (though there is a bug in MDB2 that prevents smooth installation of the xml based DBMS schema via the MDB2_Schema based installer class). An equivalent class would have to be written for the XML backend.

If PHP would have named parameter support I could add compile time checking to some extend which would make error messages much clearer, however this is less of a problem for PHP anyways as here the lines between compile time and run time are a bit more blurred compared to c#.

Another thing that they have added is improved serialization support. I have not yet checked out how they are handling data changes for the DBMS stuff, but they are able to dump XML from a in in memory representation. I guess we have that in the form of XML_Serializer, SimpleXML and XMLwriter already.

While on the topic of data persistance aka data changes aka serialization I would also like to point people at SDO. Unfortunately SDO does not cover data reading natively. Instead you have to pass it a PDO result or DOM ressource along with a definition of the structure (here LINQ uses their Reflection API instead). But from then on you have a nice API that is defined in a granular manner to allow you to either work data source agnostic or increasingly data source specific. I would love to work more closely with IBM on this project, though thanks to IP issues they first have to work out some sort of a license so that we can talk at all. *sigh*

Anyways I will try to somehow find time to check this stuff out in more detail, but I currently have so much work on my plate. *double sigh*

Comments



Re: c# 3.0's LINQ

Isn't LINQ in the same sort of territory as IBM's Service Data Objects? (see this article about the PHP extension: http://www.zend.com/pecl/tutorials/sdo.php).

Of course you don't get a native SQL-like syntax but you do seem to get something XPath-like - one of the examples from the article;


<?php
// Get the address object that contains the addressline1 of "1 Engine Close"
$address = $root["contact/address[addressline1=\"1 Engine Close\"]"];
?>

Re: c# 3.0's LINQ

Probably did not read my post to the end Harry? Like I said SDO does play in this territory. However the major differences are:

  1. not done on the language level, so no compile time checks
  2. requires explicit structure definition, rather than reading the structure via reflection from the data source itself
  3. does not cover data reading directly

As such the scope is severly more limited.

Re: c# 3.0's LINQ

Sorry - read the version on planet-php (which was truncated)