<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4899156161526860882</id><updated>2012-01-09T13:24:55.440-08:00</updated><category term='Digital curation'/><category term='Database Role'/><category term='DataGrid'/><category term='Conceptual model'/><category term='Database models'/><category term='WPF'/><category term='REST'/><category term='cloud databases'/><category term='POCO'/><category term='Transactions'/><title type='text'>Pyrrho DBMS</title><subtitle type='html'>This blog is for discussions about the open source Pyrrho Database Management System.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>48</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-6464068834305538625</id><published>2012-01-09T13:24:00.000-08:00</published><updated>2012-01-09T13:24:39.508-08:00</updated><title type='text'>Linux support restored</title><content type='html'>New upload on 6 Jan 2012 fixes some important bugs and works for Linux (under Mono).If you find any bugs please email me.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-6464068834305538625?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/6464068834305538625/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2012/01/linux-support-restored.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/6464068834305538625'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/6464068834305538625'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2012/01/linux-support-restored.html' title='Linux support restored'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-8169772147189519200</id><published>2011-09-24T07:23:00.000-07:00</published><updated>2011-09-24T07:23:29.835-07:00</updated><title type='text'>Data Visualisation</title><content type='html'>I’ve made a start on adding some data visualisation facilities to Pyrrho. These will come built in to REST, and take advantage of the HTML5 canvas facilites. The REST service has been improving steadily, and now accepts posted text/csv data. But the Data Visualisation ideas are not quite such an obvious step.&lt;p&gt;There are lots of charting and data visualisation libraries, but adding a package such as Visiblox to Pyrrho would more than double its size (the Visiblox DLL is 797KB, while Pyrrho is 700KB). So for now I plan to code the extensions myself. &lt;p&gt;I have added a set of metadata flags for Tables and Columns that activate the charting code. As usual these are role specific so it is easy to imagine a data visualisation role, with multiple charts for tables. By design column metadata can also be added to views. The flags can be added using ALTER syntax, e.g. &lt;br&gt;alter table monthlysales series ‘Sales analysis by month’&lt;br&gt;alter table monthlysales alter mth X ‘Month’&lt;br&gt;alter table monthlysales alter total line ‘Total Sales $M’&lt;br&gt;alter table monthlysales alter recurring line ‘Repeat Orders $M’&lt;p&gt;The following flags have been added so far:&lt;table border&gt;&lt;tr&gt;&lt;th&gt;Output flag	&lt;/th&gt;&lt;th&gt;Context&lt;/th&gt;&lt;th&gt;Effect&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Pie&lt;/td&gt;&lt;td&gt;	Table/View&lt;/td&gt;&lt;td&gt;	Pie chart&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Series&lt;/td&gt;&lt;td&gt;	Table/View&lt;/td&gt;&lt;td&gt;	Data Series&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Points&lt;/td&gt;&lt;td&gt;	Table/View&lt;/td&gt;&lt;td&gt;	Scatter chart&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Caption&lt;/td&gt;&lt;td&gt;	Column&lt;/td&gt;&lt;td&gt;	Column contains strings to annotate chart points&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;X&lt;/td&gt;&lt;td&gt;	Column&lt;/td&gt;&lt;td&gt;	Common column for series or X for X-Y plot. The plan here is that X could be a string, an int, or a real&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Y&lt;/td&gt;&lt;td&gt;	Column&lt;/td&gt;&lt;td&gt;	Y column for points chart. Data should be int or real&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Histogram	&lt;/td&gt;&lt;td&gt;Column&lt;/td&gt;&lt;td&gt;	For bar series chart: description string is for legend&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Line&lt;/td&gt;&lt;td&gt;	Column&lt;/td&gt;&lt;td&gt;	For line series chart: description string is for legend&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;/table&gt;Unfortunately at present the Windows control used by the RESTClient does not support the HTML5 Canvas, so the results need to be displayed in an ordinary browser.I have made a start on implementation, as the graphic here shows. The axis ranges are selected automatically. So far the new facilities have required less than 20KB in the server, and less than 100 lines of script need to be downloaded to the client. A few more lines will be needed for the titles, multiple series and pie charts, and I hope to add these soon.&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-Yvv8fVfmtHQ/Tn3nMbddNII/AAAAAAAAAG0/ugSq5l4-CiA/s1600/chart1.png" imageanchor="1" style="clear:right; float:right; margin-left:1em; margin-bottom:1em"&gt;&lt;img border="0" height="291" width="320" src="http://2.bp.blogspot.com/-Yvv8fVfmtHQ/Tn3nMbddNII/AAAAAAAAAG0/ugSq5l4-CiA/s320/chart1.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-8169772147189519200?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/8169772147189519200/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2011/09/data-visualisation.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/8169772147189519200'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/8169772147189519200'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2011/09/data-visualisation.html' title='Data Visualisation'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-Yvv8fVfmtHQ/Tn3nMbddNII/AAAAAAAAAG0/ugSq5l4-CiA/s72-c/chart1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-5917444639607897426</id><published>2011-09-12T11:06:00.000-07:00</published><updated>2011-09-12T11:09:34.584-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WPF'/><category scheme='http://www.blogger.com/atom/ns#' term='DataGrid'/><title type='text'>Using the WPF DataGrid</title><content type='html'>I have no great solutions to this one. Placing data in a DataGrid is not hard. If you want to avoid writing your own Binding and Column definitions, we need to add getters and setters to the relevant class (this is okay).&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt; Unfortunately using object[] as an ItemsSource is not good enough: we need to copy the objects into a List&lt;author&gt;.&lt;/author&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-tm7r4hkmZmA/Tm5GBdPOeCI/AAAAAAAAAGo/fTgTwdnjdcA/s1600/poco2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://3.bp.blogspot.com/-tm7r4hkmZmA/Tm5GBdPOeCI/AAAAAAAAAGo/fTgTwdnjdcA/s320/poco2.png" width="262" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-ccgATUvlqkw/Tm5G5hfWufI/AAAAAAAAAGs/1FFj9ZLz-us/s1600/poco3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-ccgATUvlqkw/Tm5G5hfWufI/AAAAAAAAAGs/1FFj9ZLz-us/s1600/poco3.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&amp;nbsp;This is simple enough, but&amp;nbsp;there is no easy way&amp;nbsp;to support updates to the cells (though there are lots of tricky ways). On balance, with the facilities available in .NET 4, I recommend not using DataGrid. It is really at least as easy to add your own textboxes to an ordinary Grid, and while you are doing that it is easy to add LostFocus events to catch updates, and to keep a copy of the data so that you can see if it has changed. There is some code in PyrrhoSQL that will get you started.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;I'd be interested in comments: is the above sample useful enough to get Pyrrho to generate the getters and setters? or to provide a verbose internal AUTHOR[] Get(db,rurl) {...}&amp;nbsp;implementation in the generated class?&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-5917444639607897426?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/5917444639607897426/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2011/09/using-wpf-datagrid.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/5917444639607897426'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/5917444639607897426'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2011/09/using-wpf-datagrid.html' title='Using the WPF DataGrid'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-tm7r4hkmZmA/Tm5GBdPOeCI/AAAAAAAAAGo/fTgTwdnjdcA/s72-c/poco2.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-7418308155340703764</id><published>2011-09-11T08:27:00.000-07:00</published><updated>2011-09-12T11:09:02.796-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='POCO'/><category scheme='http://www.blogger.com/atom/ns#' term='REST'/><title type='text'>Application Programming with POCO</title><content type='html'>At long last, Pyrrho has its own POCO technology, which (I modestly claim) is much neater and easier to use than ADO.NET, LINQ, JPA etc. It all links well to the role-based conceptual models and REST service described in previous postings.Recall that a REST url for Pyrrho starts with (http or https)http://host:port/Database/Role/Normally this is followed by table names and selectors. But a GET to this URL, returns a set of POCO definitions:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-qv4ymsDehZU/TmzRE9yTraI/AAAAAAAAAGk/8AmCBKqxly0/s1600/poco1.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="158" src="http://1.bp.blogspot.com/-qv4ymsDehZU/TmzRE9yTraI/AAAAAAAAAGk/8AmCBKqxly0/s320/poco1.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;You can paste these class definitions into your application program. If this has been done for a MOVIE class in a database called Movies, the following simple code works:&lt;pre&gt;&lt;br /&gt;using Pyrrho;&lt;br /&gt;class Test&lt;br /&gt;{&lt;br /&gt;   public static void Main(string[] args)&lt;br /&gt;   {&lt;br /&gt;       var db = new PyrrhoConnect("Files=Movies");&lt;br /&gt;       db.Open();&lt;br /&gt;       var obs = db.Get("/MOVIE");&lt;br /&gt;        foreach(MOVIE m in obs)&lt;br /&gt;                Console.WriteLine(m.TITLE);&lt;br /&gt;        db.Close();&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;POCO stands for Plain Old CLR Object. The above example is using the following API in the PyrrhoConnect class:&lt;table border=1&gt;&lt;tr&gt;&lt;th&gt;Property or Method signature&lt;/th&gt;&lt;th&gt;Explanation&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;object[] Get(string rurl)&lt;/td&gt;&lt;td&gt;Return the set of objects selected by the given relative URL&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;void Get(object ob,string rurl)&lt;/td&gt;&lt;td&gt;The actual type of the object should match the first object returned by the URL. Fills the object with the data returned.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;void Post(object ob)&lt;/td&gt;&lt;td&gt;Installs the given object as a new row in the appropriate base table.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;void Put(object old,object ob)&lt;/td&gt;&lt;td&gt;The old object should have been obtained from the database using one of the Get methods above. ob should be an updated version of this: the database will be updated.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;void Delete(object ob)&lt;/td&gt;&lt;td&gt;The object should have been obtained from the database using one of the Get methods above. The object will be deleted from the database.&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;Needless to say, all the REST-style machinery can be used in the GET rurls. When you paste class definitions obtained from Pyrrho, you can add other things to these classes provided what you add is not public (e.g. use internal instead).This feature will be available in tomorrow's update to Pyrrho (along with some bugfixes to v4.5).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-7418308155340703764?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/7418308155340703764/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2011/09/application-programming-with-poco.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/7418308155340703764'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/7418308155340703764'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2011/09/application-programming-with-poco.html' title='Application Programming with POCO'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-qv4ymsDehZU/TmzRE9yTraI/AAAAAAAAAGk/8AmCBKqxly0/s72-c/poco1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-7148797590902656895</id><published>2011-09-08T02:44:00.000-07:00</published><updated>2011-09-12T11:09:59.194-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='REST'/><category scheme='http://www.blogger.com/atom/ns#' term='Transactions'/><title type='text'>REST and transactions</title><content type='html'>Much has been said recently about transactions and databases in the cloud. We really need transactions, at almost any price, and Pyrrho supports long-running transactions for as long as a connection to the server stays open.&lt;br /&gt;But Http is supposed to be a stateless protocol, and connections are closed on each request. &lt;br /&gt;&lt;br /&gt;In recent years there has been a trend away from using session state as it creates server affinity and so is not scalable. One option is to use stored procedures to wrap several steps into an action that can be called using REST. Another is to offer transaction scripts, and these are available in Pyrrho v4.5 as described in this posting.&lt;br /&gt;&lt;br /&gt;Recall that a REST URL in Pyrrho has the form&lt;br /&gt;proto://host:port/database/role{/Selector|/Processing}&lt;br /&gt;&lt;br /&gt;If no Selector or Processing components are provided, the target is the Role itself, to which a REST transaction script can be POSTed. This is envisaged for application use (not for an interactive user). Here is an example (POST to https://mybank:8133/MyBank/Teller):&lt;br /&gt;&lt;br /&gt;(&lt;br /&gt; (POST /CurrentAccount (AC:567123,AMT:655.43,REASON:’From Malcolm’))&lt;br /&gt; (POST /CurrentAccount (AC:423991,AMT:-655.43,REASON:’To Fred’))&lt;br /&gt; (COMMIT)&lt;br /&gt;)&lt;br /&gt;&lt;br /&gt;In this syntax embedded spaces in the url must be encoded as %20. In XML this could look like:&lt;br /&gt;&lt;br /&gt;&amp;lt;?xml version=”1.0”?&gt;&lt;br /&gt;&amp;lt;root&gt;&lt;br /&gt;&amp;lt;POST Path=”/CurrentAccount” AC=”567123” AMT=”655.43”&gt; &lt;br /&gt; &amp;lt;REASON&gt;From Malcolm&amp;lt;/REASON&gt;&lt;br /&gt;&amp;lt;/POST&gt;&lt;br /&gt;&amp;lt;POST Path=”/CurrentAccount” AC=”423991” AMT=”-655.43”&gt;&lt;br /&gt;  &amp;lt;REASON&gt;To Fred&amp;lt;/REASON&gt;&lt;br /&gt;&amp;lt;/POST&gt;&lt;br /&gt;&amp;lt;COMMIT/&gt;&lt;br /&gt;&amp;lt;/root&gt;&lt;br /&gt;&lt;br /&gt;As usual with transactions, from within the transaction each step is seen to complete, but no external or persistent changes are made unless the COMMIT executes without conflict. The SQL syntax for a transaction script is thus:&lt;br /&gt;&lt;br /&gt;Script = ‘(‘ ‘(‘ Step ‘)’ { [‘,’] ‘(‘ Step ‘)’ } ‘)’ .&lt;br /&gt;Step = POST url Row_Value&lt;br /&gt; | PUT url ‘(‘ Row_Value {[‘,’] Row_Value } ‘)’&lt;br /&gt; | GET url&lt;br /&gt; | DELETE url&lt;br /&gt; | COMMIT .&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-7148797590902656895?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/7148797590902656895/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2011/09/rest-and-transactions.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/7148797590902656895'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/7148797590902656895'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2011/09/rest-and-transactions.html' title='REST and transactions'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-1492770347652999824</id><published>2011-09-06T12:45:00.000-07:00</published><updated>2011-09-12T11:10:51.311-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Database Role'/><category scheme='http://www.blogger.com/atom/ns#' term='Conceptual model'/><title type='text'>REST and role-based CRUD operations</title><content type='html'>This posting will demonstrate the use of the REST interface to perform updates, insertions and deletions in a database, where the URL structure, access permissions and navigation are determined by the roles in the database, rather than by application defined routing tables or configuration files. The default Pyrrho REST service from version 4.5 uses Windows authentication, and the server administrator has the option to use a secure channel for the http transport. The features apply in both the standard and Open Source version of Pyrrho (OSP).&lt;br /&gt;We will use the following simple REST client (which is not Pyrrho-specific):&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-3No16Hzwn4I/TmZ2i2c4RlI/AAAAAAAAAFU/y0GxNfZfi0U/s1600/pic18.png" imageanchor="1" style="clear:right; float:right; margin-left:1em; margin-bottom:1em"&gt;&lt;img border="0" height="268" width="320" src="http://4.bp.blogspot.com/-3No16Hzwn4I/TmZ2i2c4RlI/AAAAAAAAAFU/y0GxNfZfi0U/s320/pic18.png" /&gt;&lt;/a&gt;&lt;/div&gt;This screenshot shows the database as Library, the role as Library, and the table as BOOK (the REST interface is case-sensitive, and the default case in SQL is upper case).&lt;br /&gt;Let us use PUT to provide better author names. With the permissions set up in previous postings, any user granted the Library or LIBRARIAN roles can do this. The roles are different as we will see below. We can use XML or SQL format for the data we supply. First let’s use SQL. The SQL output format for http://localhost:8180/Library/Library/AUTHOR/NAME gives (('Dickens')(‘Conrad’)), so we use the same format, naturally, to update the names:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-i573kL97Mgc/TmZ20WIV_UI/AAAAAAAAAFc/KvsCS1BnqzA/s1600/pic19.png" imageanchor="1" style="clear:right; float:right; margin-left:1em; margin-bottom:1em"&gt;&lt;img border="0" height="268" width="320" src="http://3.bp.blogspot.com/-i573kL97Mgc/TmZ20WIV_UI/AAAAAAAAAFc/KvsCS1BnqzA/s320/pic19.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-opDyPMjpPKI/TmZ2-R97EzI/AAAAAAAAAFk/IEHgzOl40CY/s1600/pic20.png" imageanchor="1" style="clear:right; float:right; margin-left:1em; margin-bottom:1em"&gt;&lt;img border="0" height="268" width="320" src="http://1.bp.blogspot.com/-opDyPMjpPKI/TmZ2-R97EzI/AAAAAAAAAFk/IEHgzOl40CY/s320/pic20.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;If we use XML, things look a little different. Let’s look at BOOK with XML&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-CxyMXmTljVs/TmZ3IuBB8CI/AAAAAAAAAFs/4p_52VDrJnU/s1600/pic21.png" imageanchor="1" style="clear:right; float:right; margin-left:1em; margin-bottom:1em"&gt;&lt;img border="0" height="268" width="320" src="http://4.bp.blogspot.com/-CxyMXmTljVs/TmZ3IuBB8CI/AAAAAAAAAFs/4p_52VDrJnU/s320/pic21.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Here the librarian has changed the names of some columns for the LIBRARIAN role, and marked book as an entity and id and aid as attributes. We can post a new book:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-mXrDX4u2lwA/TmZ3UfpeXqI/AAAAAAAAAF0/QUAoTMgOhn8/s1600/pic22.png" imageanchor="1" style="clear:right; float:right; margin-left:1em; margin-bottom:1em"&gt;&lt;img border="0" height="268" width="320" src="http://4.bp.blogspot.com/-mXrDX4u2lwA/TmZ3UfpeXqI/AAAAAAAAAF0/QUAoTMgOhn8/s320/pic22.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Notice that we don’t need to supply all of the fields (in this case it would be incorrect to supply values for the generated Author column). Pyrrho is forgiving about whether columns are supplied as attributes or children. But only one record can be POSTed at a time.&lt;br /&gt;POST does not return data.&lt;br /&gt;Checking, we see the new book has gone in with a generated key value of 1 (we could have given our own value).&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-mTLCVx9eXBY/TmZ3ojjx1tI/AAAAAAAAAGE/RbzAzNsi7ss/s1600/pic24.png" imageanchor="1" style="clear:right; float:right; margin-left:1em; margin-bottom:1em"&gt;&lt;img border="0" height="268" width="320" src="http://4.bp.blogspot.com/-mTLCVx9eXBY/TmZ3ojjx1tI/AAAAAAAAAGE/RbzAzNsi7ss/s320/pic24.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Recall that this table looks very different in other roles:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-8y54e6uN_ME/TmZ3zokLAeI/AAAAAAAAAGM/pq1k6stu5_I/s1600/pic25.png" imageanchor="1" style="clear:right; float:right; margin-left:1em; margin-bottom:1em"&gt;&lt;img border="0" height="268" width="320" src="http://2.bp.blogspot.com/-8y54e6uN_ME/TmZ3zokLAeI/AAAAAAAAAGM/pq1k6stu5_I/s320/pic25.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-q2TrZIAKp8o/TmZ4AsJmJVI/AAAAAAAAAGU/G8wfk_mzATo/s1600/pic26.png" imageanchor="1" style="clear:right; float:right; margin-left:1em; margin-bottom:1em"&gt;&lt;img border="0" height="268" width="320" src="http://1.bp.blogspot.com/-q2TrZIAKp8o/TmZ4AsJmJVI/AAAAAAAAAGU/G8wfk_mzATo/s320/pic26.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-_cgwBgpd1I4/TmZ4Az64QEI/AAAAAAAAAGc/sdu67s7HHdM/s1600/pic27.png" imageanchor="1" style="clear:right; float:right; margin-left:1em; margin-bottom:1em"&gt;&lt;img border="0" height="268" width="320" src="http://4.bp.blogspot.com/-_cgwBgpd1I4/TmZ4Az64QEI/AAAAAAAAAGc/sdu67s7HHdM/s320/pic27.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Finally DELETE works. Provided the current role has the right permissions, the records that would be returned by GET are instead deleted.&lt;br /&gt;Role names do not need to be meaningful, and using a hard-t-guess name for a role with extra privileges can be a useful extra layer of security.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-1492770347652999824?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/1492770347652999824/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2011/09/rest-and-role-based-crud-operations.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/1492770347652999824'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/1492770347652999824'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2011/09/rest-and-role-based-crud-operations.html' title='REST and role-based CRUD operations'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-3No16Hzwn4I/TmZ2i2c4RlI/AAAAAAAAAFU/y0GxNfZfi0U/s72-c/pic18.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-4857009069806097654</id><published>2011-08-31T08:20:00.000-07:00</published><updated>2011-09-12T11:11:44.655-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='REST'/><category scheme='http://www.blogger.com/atom/ns#' term='Database Role'/><title type='text'>REST and role models</title><content type='html'>In this posting I want to discuss the new role-based REST service in Pyrrho v4.5. For simplicity we will continue to use the example database from the last two postings, with the following additional steps. These create a new role "Web" with read-only access to the tables, and some metadata for XML formatting of the output. The details are given at the end of this article.&lt;br /&gt;For now let’s just consider GET actions. (As we will see in the next posting, one simple way of handling moderate security for PUT, DELETE and POST is to grant Insert, Update and Delete to a role with a hard-to-guess name.)&lt;br /&gt;We can use REST to explore the Web role of the database:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-xokFqk4EgRo/Tl5QEZ2809I/AAAAAAAAAEc/TWiqrD8BPAM/s1600/pic1.png" imageanchor="1" style="clear:right; float:right; margin-left:1em; margin-bottom:1em"&gt;&lt;img border="0" height="256" width="320" src="http://2.bp.blogspot.com/-xokFqk4EgRo/Tl5QEZ2809I/AAAAAAAAAEc/TWiqrD8BPAM/s320/pic1.png" /&gt;&lt;/a&gt;&lt;/div&gt;For the Author table, AUTHOR has been declared as an entity, and ID has been declared as an attribute, so the output has a different form:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-jH61MnEq-Ms/Tl5QOwqzALI/AAAAAAAAAEk/upNivcFg-6k/s1600/pic2.png" imageanchor="1" style="clear:right; float:right; margin-left:1em; margin-bottom:1em"&gt;&lt;img border="0" height="179" width="320" src="http://3.bp.blogspot.com/-jH61MnEq-Ms/Tl5QOwqzALI/AAAAAAAAAEk/upNivcFg-6k/s320/pic2.png" /&gt;&lt;/a&gt;&lt;/div&gt;We can select by a primary key value&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-zjL9Oj2tIN8/Tl5QYKkX9vI/AAAAAAAAAEs/RbEuHW6GYO8/s1600/pic3.png" imageanchor="1" style="clear:right; float:right; margin-left:1em; margin-bottom:1em"&gt;&lt;img border="0" height="132" width="320" src="http://4.bp.blogspot.com/-zjL9Oj2tIN8/Tl5QYKkX9vI/AAAAAAAAAEs/RbEuHW6GYO8/s320/pic3.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;We can limit the output to particular columns:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-TO32ParwzB8/Tl5QhfIp_3I/AAAAAAAAAE0/smHePPjOk_Q/s1600/pic4.png" imageanchor="1" style="clear:right; float:right; margin-left:1em; margin-bottom:1em"&gt;&lt;img border="0" height="109" width="320" src="http://3.bp.blogspot.com/-TO32ParwzB8/Tl5QhfIp_3I/AAAAAAAAAE0/smHePPjOk_Q/s320/pic4.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;We can select rows satisfying a particular set of conditions:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-0j_bL9Jeihc/Tl5QrOEsyzI/AAAAAAAAAE8/yaBrk6Kqjbc/s1600/pic5.png" imageanchor="1" style="clear:right; float:right; margin-left:1em; margin-bottom:1em"&gt;&lt;img border="0" height="109" width="320" src="http://1.bp.blogspot.com/-0j_bL9Jeihc/Tl5QrOEsyzI/AAAAAAAAAE8/yaBrk6Kqjbc/s320/pic5.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;We can navigate foreign keys:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-PatxN-Nw8FI/Tl5Q0LAQ4NI/AAAAAAAAAFE/xGgyLJwVXBo/s1600/pic6.png" imageanchor="1" style="clear:right; float:right; margin-left:1em; margin-bottom:1em"&gt;&lt;img border="0" height="105" width="320" src="http://1.bp.blogspot.com/-PatxN-Nw8FI/Tl5Q0LAQ4NI/AAAAAAAAAFE/xGgyLJwVXBo/s320/pic6.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;We can reverse-navigate foreign keys using the OF keyword (see below)&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-bc3Ivdqpp3c/Tl5RENQ5NSI/AAAAAAAAAFM/Q4EFtM0n1a4/s1600/pic7.png" imageanchor="1" style="clear:right; float:right; margin-left:1em; margin-bottom:1em"&gt;&lt;img border="0" height="126" width="320" src="http://2.bp.blogspot.com/-bc3Ivdqpp3c/Tl5RENQ5NSI/AAAAAAAAAFM/Q4EFtM0n1a4/s320/pic7.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;The syntax here is&lt;br /&gt;http://host:port/database/role{/Selector|/Processing}&lt;br /&gt;Selector matches&lt;br /&gt;[table ]Table_id&lt;br /&gt;[procedure ]Procedure_id&lt;br /&gt;[where ]Column_id=string&lt;br /&gt;[select ]Column_id{,Column_id}&lt;br /&gt;[key ]string&lt;br /&gt;[of ]Table_id[(Column_id{, Column_id})]&lt;br /&gt;Appending another selector is used to restrict a list of data to match a given primary key value or named column values, or to navigate to another list by following a foreign key, or supply the current result as the parameters of a named procedure. The of option is used for reverse navigation of foreign keys, or to traverse many-many relationships.&lt;br /&gt;Processing matches:&lt;br /&gt;distinct [Column_id{, Column_id}]&lt;br /&gt;ascending Column_id{, Column_id}&lt;br /&gt;descending Column_id{, Column_id}&lt;br /&gt;skip Int_string&lt;br /&gt;count Int_string&lt;br /&gt;The relationship of this Library database to the one in the last posting is (approximately) as follows:&lt;br /&gt;In role Library:&lt;br /&gt;Create role “Web”&lt;br /&gt;Grant select on author to “Web”&lt;br /&gt;Grant select on book to “Web”&lt;br /&gt;Insert into book(title,aid) values(‘Great Expectations’,1)&lt;br /&gt;In role “Web”:&lt;br /&gt;Alter table author entity&lt;br /&gt;Alter table author alter id attribute&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-4857009069806097654?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/4857009069806097654/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2011/08/rest-and-role-models.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/4857009069806097654'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/4857009069806097654'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2011/08/rest-and-role-models.html' title='REST and role models'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-xokFqk4EgRo/Tl5QEZ2809I/AAAAAAAAAEc/TWiqrD8BPAM/s72-c/pic1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-752389563792427109</id><published>2011-08-28T08:39:00.000-07:00</published><updated>2011-08-28T08:39:37.423-07:00</updated><title type='text'>Conceptual models in the physical database – II</title><content type='html'>In the first part of this article, I set up a simple database to show how Pyrrho allows roles to change object names and define new ones. In this article we will take a deep dive into Pyrrho’s system tables to explore how the mechanisms work. (Later articles will explore more of the features of the new server version, including REST and entity models. The general reader can skip this article and wait for REST.)&lt;br /&gt;The database creator has set up the following objects in the Library database: tables AUTHOR(ID,NAME) and BOOK(ID,TITLE,AID,ANAME). In the “Role$Object” system table we can see these objects as owned by the default database role, and the PUBLIC standard types that have been used: INTEGER and CHAR as required for these tables, and the BOOLEAN standard type that the librarian used for his new Availability column.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-zRJR1A-AkNc/Tlpe9VAKmMI/AAAAAAAAADk/ozBc-uO9fmI/s1600/pic10.png" imageanchor="1" style="clear:right; float:right; margin-left:1em; margin-bottom:1em"&gt;&lt;img border="0" height="257" width="320" src="http://4.bp.blogspot.com/-zRJR1A-AkNc/Tlpe9VAKmMI/AAAAAAAAADk/ozBc-uO9fmI/s320/pic10.png" /&gt;&lt;/a&gt;&lt;/div&gt;In this table we can also see that database objects can have other role-based metadata such as an output flag (this can be Entity or Attribute as we will see later), a human-readable Description, and an Iri for Web metadata.&lt;br /&gt;In the corresponding tables for the other roles, we see different metadata for different sets of objects. The LIBRARIAN role renamed three of these objects, and defined the Availability column, and the READER role contains just a few entries. As at the end of the last blog posting, the database owner cannot use this role: it was created by the LIBRARIAN and had not yet been made public. Fred can get us the entries, and also make the role PUBLIC so anyone can use it.&lt;br /&gt;Instead of looking at the Role$Object table for each role, let’s instead look at the Role$Column table: the first is for “Library”, the second for “LIBRARIAN”, the third for “READER”:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-p-KDApQq07o/TlpfazPQIBI/AAAAAAAAADs/6DDj8FmlNPI/s1600/pic11.png" imageanchor="1" style="clear:right; float:right; margin-left:1em; margin-bottom:1em"&gt;&lt;img border="0" height="187" width="320" src="http://4.bp.blogspot.com/-p-KDApQq07o/TlpfazPQIBI/AAAAAAAAADs/6DDj8FmlNPI/s320/pic11.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-PFg4LL7EWZc/Tlpfs1A4zYI/AAAAAAAAAD0/GCEaX3HN_OQ/s1600/pic12.png" imageanchor="1" style="clear:right; float:right; margin-left:1em; margin-bottom:1em"&gt;&lt;img border="0" height="164" width="320" src="http://4.bp.blogspot.com/-PFg4LL7EWZc/Tlpfs1A4zYI/AAAAAAAAAD0/GCEaX3HN_OQ/s320/pic12.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-xvRHxy_a04A/Tlpfs01FH5I/AAAAAAAAAD8/E5nk6IUhltQ/s1600/pic13.png" imageanchor="1" style="clear:right; float:right; margin-left:1em; margin-bottom:1em"&gt;&lt;img border="0" height="194" width="320" src="http://1.bp.blogspot.com/-xvRHxy_a04A/Tlpfs01FH5I/AAAAAAAAAD8/E5nk6IUhltQ/s320/pic13.png" /&gt;&lt;/a&gt;&lt;/div&gt;As expected, we see the librarian’s column names in the second two tables. But the biggest difference is the way that the Default value for the ANAME or Author column is shown. None of these exactly matches the actual definition used (select name from author a where a.id=aid). The first screenshot shows the identifiers capitalised, the second uses the LIBRARIAN’s name Authorid for the AID column, and in the third the code cannot be displayed, since the READER role does not know about the AUTHOR table. In fact, Pyrrho uses numeric identifiers internally (select “158” from “68” a where a.”119”=”277”), and, if possible, displays the code appropriately for the viewing role.&lt;br /&gt;There are four blank columns in these tables Update can specify a set of actual assignments to be carried out if a generated column is assigned to. The next three columns are used for reverse relationship navigation and are specified using Pyrrho’s new REFLECTS syntax. These new features of Pyrrho were announced in July and will be described in future postings.&lt;br /&gt;Let’s examine the list of users allowed to login to roles (this Sys$RoleUser table looks the same from any role allowed to see it):&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-m6q8TM8uAM0/Tlpf9zPXUNI/AAAAAAAAAEE/bQIe95es7-c/s1600/pic14.png" imageanchor="1" style="clear:right; float:right; margin-left:1em; margin-bottom:1em"&gt;&lt;img border="0" height="264" width="320" src="http://3.bp.blogspot.com/-m6q8TM8uAM0/Tlpf9zPXUNI/AAAAAAAAAEE/bQIe95es7-c/s320/pic14.png" /&gt;&lt;/a&gt;&lt;/div&gt;“guest” appears in this list because Fred has ordered “grant reader to public”.&lt;br /&gt;Finally in this posting I’d like to show some entries from what the database file actually contains. These are from the Log$ table. &lt;br /&gt;The first shows where I create the LIBRARIAN role and grant all privileges on table AUTHOR with grant option. I’d have liked to crop this image to show only the lines from 570 to 643:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-KjZ50MmHUwc/Tlpg07Pwl8I/AAAAAAAAAEM/WxPV0H71zUY/s1600/pic15.png" imageanchor="1" style="clear:right; float:right; margin-left:1em; margin-bottom:1em"&gt;&lt;img border="0" height="207" width="320" src="http://4.bp.blogspot.com/-KjZ50MmHUwc/Tlpg07Pwl8I/AAAAAAAAAEM/WxPV0H71zUY/s320/pic15.png" /&gt;&lt;/a&gt;&lt;/div&gt;We can see that both these transactions are by Role=4, which is the default role for the database (always the first database object to be created). User=35 is TORE\Malcolm, the database creator. So role Library is defining the librarian role. Granting all privileges on the AUTHOR table, unless it is restricted to a particular set of columns, implies granting all privileges on all the columns too. And “all privileges” means all the privileges held by the grantor, in this case also all of the grant options. So the single SQL statement has been expanded into three Grant records in the database. 586, as we can see, refers to the Librarian. Generally, log entries refer to database objects by number rather than by name. Pyrrho has always done this because objects can be renamed. The mechanism now works really well for role-based naming, so that the new version is backwards compatible with existing Pyrrho databases.&lt;br /&gt;The second extract is the last few entries in the log, from 878 on, where the user is Fred: &lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-iKA5QIAntPA/Tlpg043neDI/AAAAAAAAAEU/8qayFj2TfH8/s1600/pic16.png" imageanchor="1" style="clear:right; float:right; margin-left:1em; margin-bottom:1em"&gt;&lt;img border="0" height="207" width="320" src="http://3.bp.blogspot.com/-iKA5QIAntPA/Tlpg043neDI/AAAAAAAAAEU/8qayFj2TfH8/s320/pic16.png" /&gt;&lt;/a&gt;&lt;/div&gt;Here the user is Fred, and the role is LIBRARIAN. The transactions correspond to the four SQL statements:&lt;br /&gt;alter table book add “Available” boolean default true&lt;br /&gt;create role reader&lt;br /&gt;grant select(“Title”,”Author”,”Available”) on book to reader&lt;br /&gt;grant reader to public&lt;br /&gt;The Grant NoPrivilege entry is probably not required, but at present it ensures that table BOOK (197) is entered in the namespace for READER (970). One other oddity in this list is where the “Avaialble” column is defined. The figures 197(4)[895] are for the table BOOK, the table’s owner, and the new column’s domain, which is a slightly odd collection of data to display in the Log entry (the table’s owner is not actually mentioned in the log entry).&lt;br /&gt;There are some extra columns in the Log$ table: the record type, a related previous log entry if any, and the start of the transaction. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-752389563792427109?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/752389563792427109/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2011/08/conceptual-models-in-physical-database_28.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/752389563792427109'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/752389563792427109'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2011/08/conceptual-models-in-physical-database_28.html' title='Conceptual models in the physical database – II'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-zRJR1A-AkNc/Tlpe9VAKmMI/AAAAAAAAADk/ozBc-uO9fmI/s72-c/pic10.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-2718262157100755923</id><published>2011-08-27T12:27:00.000-07:00</published><updated>2011-09-12T11:11:18.227-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Database models'/><title type='text'>Conceptual Models in the Physical Database - I</title><content type='html'>Having promised a progress report on the new role-based conceptual modelling features in Pyrrho, it is now time to post some news on this project. In this post I will walk through  a simple database example. There is also a new Pyrrho client to show off.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-4mzaEYnuRLg/TllDbo5-T_I/AAAAAAAAACc/ZWFdrY3ZVgs/s1600/pic1.png" imageanchor="1" style="clear:right; float:right; margin-left:1em; margin-bottom:1em"&gt;&lt;img border="0" height="194" width="320" src="http://4.bp.blogspot.com/-4mzaEYnuRLg/TllDbo5-T_I/AAAAAAAAACc/ZWFdrY3ZVgs/s320/pic1.png" /&gt;&lt;/a&gt;&lt;/div&gt;Let’s start to build a simple database of books and authors.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-YCaHGvUHVM4/TllDsqXrKSI/AAAAAAAAACk/zOk6hOdsnbM/s1600/pic2.png" imageanchor="1" style="clear:right; float:right; margin-left:1em; margin-bottom:1em"&gt;&lt;img border="0" height="175" width="320" src="http://1.bp.blogspot.com/-YCaHGvUHVM4/TllDsqXrKSI/AAAAAAAAACk/zOk6hOdsnbM/s320/pic2.png" /&gt;&lt;/a&gt;&lt;/div&gt;This looks okay to a database specialist but the Librarian is not impressed. He wants the author’s name in the book table: after feebly trying to explain about joins, I provide a special generated column in this table using the standard SQL2008 syntax:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-jAFCxthVkpg/TllD4T55KKI/AAAAAAAAACs/MLSvN2fXHtE/s1600/pic3.png" imageanchor="1" style="clear:right; float:right; margin-left:1em; margin-bottom:1em"&gt;&lt;img border="0" height="186" width="320" src="http://2.bp.blogspot.com/-jAFCxthVkpg/TllD4T55KKI/AAAAAAAAACs/MLSvN2fXHtE/s320/pic3.png" /&gt;&lt;/a&gt;&lt;/div&gt;This pleases him a bit but he wants more reader-friendly names and to hide these numeric columns. So I add a new role for the Librarian, and allow Fred  the admin option so he can define his preferred column headings:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-T8rFA4GKC4Y/TllECvZNPZI/AAAAAAAAAC0/52MMQVct3HI/s1600/pic4.png" imageanchor="1" style="clear:right; float:right; margin-left:1em; margin-bottom:1em"&gt;&lt;img border="0" height="186" width="320" src="http://3.bp.blogspot.com/-T8rFA4GKC4Y/TllECvZNPZI/AAAAAAAAAC0/52MMQVct3HI/s320/pic4.png" /&gt;&lt;/a&gt;&lt;/div&gt;(A generation rule in SQL2008 is not allowed to contain a query expression. Otherwise there are no Pyrrho extensions here.)&lt;br /&gt;Fred can now log in to the system with his Librarian role. He decides to rename some columns (this is a Pyrrho extension), define a new column called Availability, and to create a role for his readers with a simpler table structure:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-O5SLxVhK0V4/TllEOjZ5sFI/AAAAAAAAAC8/PXg-Z5D80JY/s1600/pic5.png" imageanchor="1" style="clear:right; float:right; margin-left:1em; margin-bottom:1em"&gt;&lt;img border="0" height="174" width="320" src="http://3.bp.blogspot.com/-O5SLxVhK0V4/TllEOjZ5sFI/AAAAAAAAAC8/PXg-Z5D80JY/s320/pic5.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-vsy8r7n35uM/TllEWAk4FKI/AAAAAAAAADE/FkRNJKjSTYk/s1600/pic6.png" imageanchor="1" style="clear:right; float:right; margin-left:1em; margin-bottom:1em"&gt;&lt;img border="0" height="194" width="320" src="http://4.bp.blogspot.com/-vsy8r7n35uM/TllEWAk4FKI/AAAAAAAAADE/FkRNJKjSTYk/s320/pic6.png" /&gt;&lt;/a&gt;&lt;/div&gt;The only columns the Reader can see are the ones granted, so Reader can say simply “table book” to see these:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-UH0bnMhFhcQ/TllEhmVgE2I/AAAAAAAAADM/fcRwNEUvAVE/s1600/pic7.png" imageanchor="1" style="clear:right; float:right; margin-left:1em; margin-bottom:1em"&gt;&lt;img border="0" height="174" width="320" src="http://2.bp.blogspot.com/-UH0bnMhFhcQ/TllEhmVgE2I/AAAAAAAAADM/fcRwNEUvAVE/s320/pic7.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Note that the Author data comes from a table that is otherwise inaccessible to the Reader, because the generation rule uses “definer’s rights”.&lt;br /&gt;Now this is how things stand. The database objects as viewed from the default “Library” role have not changed:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-pOLfzpJbl1k/TllEx6yd2DI/AAAAAAAAADU/CTwng6ksyIM/s1600/pic8.png" imageanchor="1" style="clear:right; float:right; margin-left:1em; margin-bottom:1em"&gt;&lt;img border="0" height="194" width="320" src="http://4.bp.blogspot.com/-pOLfzpJbl1k/TllEx6yd2DI/AAAAAAAAADU/CTwng6ksyIM/s320/pic8.png" /&gt;&lt;/a&gt;&lt;/div&gt;From the Librarian role we have:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-s0JWvZZsdmU/TllFBz1FxAI/AAAAAAAAADc/AS2gCm3M0iI/s1600/pic9.png" imageanchor="1" style="clear:right; float:right; margin-left:1em; margin-bottom:1em"&gt;&lt;img border="0" height="194" width="320" src="http://4.bp.blogspot.com/-s0JWvZZsdmU/TllFBz1FxAI/AAAAAAAAADc/AS2gCm3M0iI/s320/pic9.png" /&gt;&lt;/a&gt;&lt;/div&gt;and as we have seen the Reader does not see the numeric fields.&lt;br /&gt;It is important (I think) that the renaming of columns is the only non-standard aspect here.&lt;br /&gt;In the next posting we will look at how Pyrrho’s system tables reflect this structure. After that I plan postings on the resulting role-based REST service. The other promised Pyrrho features are on the way and I hope to offer the open source version of Pyrrho 4.5 within a week or two.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-2718262157100755923?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/2718262157100755923/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2011/08/conceptual-models-in-physical-database.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/2718262157100755923'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/2718262157100755923'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2011/08/conceptual-models-in-physical-database.html' title='Conceptual Models in the Physical Database - I'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-4mzaEYnuRLg/TllDbo5-T_I/AAAAAAAAACc/ZWFdrY3ZVgs/s72-c/pic1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-7134903759784793573</id><published>2011-07-25T05:27:00.000-07:00</published><updated>2011-09-08T02:25:11.041-07:00</updated><title type='text'>REST and role-based data models</title><content type='html'>Despite the popularity of REST approaches, there is still no standard mechanism for automatically generating url patterns appropriate for a database. The early implementations from Microsoft had a very complex url syntax, and the later MVC3 approaches simply expect programmers to create routing URLs.&lt;br /&gt;There is not even any agreed way of deciding whether a data value should be given as an attribute or a child element of a given entity. Many data modelling systems allow a distinction between data values and attributes, and this can help. Let us suppose that the data model system is extended by adding a small set of metadata flags to indicate which tables are entities and which columns are attributes or properties.&lt;br /&gt;Then the following modest proposal is offered as a natural url model for a REST service:&lt;br /&gt;All data segments are URLencoded so that SQL identifiers never need to be enclosed in double quotes. Matching rules are applied in the order given, but can be disambiguated using the optional $ prefixes. White space is significant (e.g. the spaces in the rules below must be a single space, and the commas should not have adjacent spaces).&lt;br /&gt;&lt;br /&gt;http://host:port/database/role{/Selector}{/Processing}&lt;br /&gt;&lt;br /&gt;Selector matches&lt;br /&gt;[$table ]id&lt;br /&gt;[$procedure ]id[(string{,string}]&lt;br /&gt;[$where ]id=string&lt;br /&gt;[$select ]id{,id}&lt;br /&gt;[$key ]string&lt;br /&gt;Appending another selector is used to restrict a list of data to match a given primary key value or named column values, or to navigate to another list by following a foreign key, or supply the current result as the parameters of a named procedure, function, or method.&lt;br /&gt;&lt;br /&gt;Processing matches:&lt;br /&gt;distinct&lt;br /&gt;ascending id{,id}&lt;br /&gt;descending id{,id}&lt;br /&gt;skip Int_string&lt;br /&gt;count Int_string&lt;br /&gt;&lt;br /&gt;For example with an obvious data model, GET http://Sales/Sales/Orders/1234 returns a single row from the Orders table, while http://Sales/Sales/Orders/1234/OrderItem returns a list of rows from the OrderItem table, and http://Sales/Sales/Orders/1234/CUST/Customer returns the row from the Customer table. &lt;br /&gt;A URL can be used to GET a single item, a list of rows or single items, PUT an update to a single items, POST a new item to a list, or DELETE a single row.&lt;br /&gt;For example, PUT http://Sales/Sales/Orders/1234/DeliveryDate with posted data of 2011-07-20 will update the DeliveryDate cell in a row of the Orders table. &lt;br /&gt;POST http://Sales/Sales/Orders will create a new row in the Orders table: the posted data should contain the XML version of the row. In all cases the new primary key value will be contained in the Http response.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-7134903759784793573?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/7134903759784793573/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2011/07/rest-and-role-based-data-models.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/7134903759784793573'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/7134903759784793573'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2011/07/rest-and-role-based-data-models.html' title='REST and role-based data models'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-4750335198405488935</id><published>2011-07-25T05:11:00.000-07:00</published><updated>2011-07-25T05:11:05.682-07:00</updated><title type='text'>Generated columns and updatable views</title><content type='html'>When developing the conceptual level of a database, new structure can be added by using views and generated columns. The programming model for this in the SQL standard is theoretically complete, but in practical examples the standard machinery using triggers can seem over-complex.&lt;br /&gt;Recent programming frameworks (e.g. .NET 4) have focussed instead on providing up to 4 pieces of SQL for the GET, PUT, POST and DELETE operations for any named structure. This suggests an extension to the CREATE VIEW syntax as follows:&lt;br /&gt;CREATE VIEW id AS QueryExpression [UPDATE SqlStatement] [INSERT SqlStatement] [DELETE SqlStatement] &lt;br /&gt;Similarly the syntax for a generated column can be extended:&lt;br /&gt;GenerationRule = GENERATED ALWAYS AS '('Value')' [UPDATE '(' Assignments ')' ] &lt;br /&gt;The implementation of these ideas is extremely straightfoward so they are good candidates for inclusion in the next version of Pyrrho.&lt;br /&gt;More importantly, together with the following syntax extensions:&lt;br /&gt;SqlStatement =|  HTTP (POST|UPDATE|DELETE) url ['('Value')'] &lt;br /&gt;QueryExpression =| HTTP GET url .&lt;br /&gt;we can see how a local database include or refer to data selected from an external database.&lt;br /&gt;It is quite interesting to consider the effect of such extensions on the transaction model. One reasonable approach would be to recommend that for long transactions database designers should use Web-based transaction control as in JAX-RS. Another reasonable suggestion would be that such web requests should be tunnelled in duplex streams established for each web host referenced in the transaction, and this would be quite suitable for short transactions. For example, instead of the sequence&lt;br /&gt;PUT http://myhost/mydb/url1 (+20)&lt;br /&gt;PUT http://myhost/mydb/url2 (-20)&lt;br /&gt;send&lt;br /&gt;POST http://myhost/mydb/strtrans (PUT /url1 (+20) PUT /url2 (-20) COMMIT)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-4750335198405488935?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/4750335198405488935/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2011/07/generated-columns-and-updatable-views.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/4750335198405488935'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/4750335198405488935'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2011/07/generated-columns-and-updatable-views.html' title='Generated columns and updatable views'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-8884776627209135881</id><published>2011-07-09T02:35:00.000-07:00</published><updated>2011-07-09T02:38:10.177-07:00</updated><title type='text'>Reflection and Relationships</title><content type='html'>Relational databases need to provide support two-way relationships especially now that such relationships are so easily navigated using REST-style URLs. This article proposes a simple approach to defining path navigation in the relational database at physical or conceptual level. The resulting generated columns (or properties) are of type ROW ARRAY and are quite difficult to use in SQL, but very easy from REST. &lt;br /&gt;Interestingly the Java Persistence Query Language provides query language support for such two-way relationships, but required a lot of annotation infrastructure. &lt;br /&gt;For example (inspired by the Java Tutorial), suppose we have tables&lt;br /&gt;player: (pid int primary key, pname char)&lt;br /&gt;team: (tid int primary key, tname char, capt int references player)&lt;br /&gt;playerteam: (pid references player, tid references team)&lt;br /&gt;This club has a number of teams for different purposes, and players can belong to (or even captain) more than one team. Then the syntax proposed here would allow us to write definitions as simple as&lt;br /&gt;alter table player add captains reflects team&lt;br /&gt;alter table player add playsin reflects playerteam&lt;br /&gt;Then in the REST interface we can write&lt;br /&gt;http://myclub.org/db/db/player(pname=’Fred Bloggs’)/captains/tname&lt;br /&gt;to obtain the names of all the teams Fred captains. &lt;br /&gt;The syntax is one of the alternatives for ColumnDefinition, and defines a generated-always column:&lt;br /&gt;| id REFLECTS [Cols IN] Table_id [Cols]&lt;br /&gt;Recall that ColumnDefinition is also used to define a property in a role-based data model, and of course in that context entity and property identifiers can be used in place of table and column identifiers.&lt;br /&gt;The REFLECTS definition sets up an array-valued generated column as a reverse reference: e.g. if t.f references g(i) then “alter g add h reflects t” is a shorthand for “alter g add h row t array generated always as (select * from t where f=i)”. That is, each cell in the generated column contains a list of rows from the referenced table.&lt;br /&gt;The optional [Cols] following the referenced Table_id allows selection of a particular foreign key if there is more than one.&lt;br /&gt;For many-many relationships the referenced table will be a secondary table, so that the type of the generated column is defined only implicitly. Still the basic idea is simple enough. Suppose we have a many-many relationship R between tables A and B. In a relational database this will be implemented by means of a secondary table AB consisting of pairs of primary keys for A and B. In both A and B we can easily define additional generated columns for our convenience (e.g. for REST navigation):&lt;br /&gt;alter table A add X reflects AB&lt;br /&gt;alter table B add Y reflects AB&lt;br /&gt;Then in each row of A, X will be a list of rows from table B; and in each row of B, Y will be a list of rows from table A. In practice we would probably name these properties B and A rather than X and Y to make the resulting REST-based navigation more intuitive.&lt;br /&gt;Again, the optional column specification [Cols IN] allows selection of a particular foreign key in the secondary table. In the above player and team example we could define&lt;br /&gt;alter table player add captains reflects team(capt)&lt;br /&gt;alter table team add players reflects (pid) in playerteam(tid)&lt;br /&gt;The full details of the [Cols IN] option are as follows. [Cols IN] is only permitted in relationships that navigate a secondary table. In a definition such as “alter S add C reflects (TF) in MM (SF)”, MM will be a secondary table implementing a many-many relationship between table S and some other table T, containing (at least) foreign keys SF and F where TF references the target table T and SF references the source table S. Then the values of C will be lists of rows of T. &lt;br /&gt;The final [Cols] syntax allows selection of a foreign key that references the source table, and can be used in any REFLECTS construct.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-8884776627209135881?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/8884776627209135881/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2011/07/reflection-and-relationships.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/8884776627209135881'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/8884776627209135881'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2011/07/reflection-and-relationships.html' title='Reflection and Relationships'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-1477985417326970796</id><published>2011-07-06T12:43:00.000-07:00</published><updated>2011-07-06T12:43:54.210-07:00</updated><title type='text'>On concurrency tokens</title><content type='html'>Microsoft states for .NET Framework 4: "WCF Data Services supports the optimistic concurrency model by enabling you to define a concurrency token for an entity. This concurrency token, which includes one or more properties of the entity, is used by the data service to determine whether a change has occurred in the data that is being requested, updated, or deleted."&lt;br /&gt;Now this is interesting as it suggests a growing realisation that more needs to be done about optimistic concurrency. But alas, all that is done here is to declare a property as useful for applications to test: it comes with no guarantees.&lt;br /&gt;Pyrrho already has (mandatory) optimistic concurrency control, but still, it is an attractive notion to have a test to perform during a transaction ("is it already too late to commit?").&lt;br /&gt;So from the next version (4.5) of Pyrrho, there will be a boolean property of transactions. Requesting the value of Transaction.Conflict will cause a server round trip to discover if other transaction commits have already made committing this transaction impossible.&lt;br /&gt;Whatever the result of this test, the Transaction will remain open as it probably still contains useful information, until Commit or Rollback is called.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-1477985417326970796?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/1477985417326970796/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2011/07/on-concurrency-tokens.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/1477985417326970796'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/1477985417326970796'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2011/07/on-concurrency-tokens.html' title='On concurrency tokens'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-3929098886433221611</id><published>2011-07-05T06:06:00.000-07:00</published><updated>2011-08-02T00:10:21.967-07:00</updated><title type='text'>Role-based Data Models</title><content type='html'>It does appear that Entity Frameworks loom ever larger in the data access world, whether they are used in a code-first or model-first way. But any database can support several data models. &lt;br /&gt;It has been a common occurrence that Java programmers will use different data models (as defined by annotations in their program) to access the same database. This is because annotations can provide different entity and property names and map their relationships in different ways. Pyrrho (up to version 4.4) therefore regarded the data model in use as a thread-specific structure. This now seems quite the wrong thing to do.&lt;br /&gt;Instead, Pyrrho now takes its cue from the business analytics and business modelling field, and considers that it will be best practice for each role to have a different view of the data in the database, and it is at such a conceptual model level that entity modelling should take place.&lt;br /&gt;So, from version 4.5 of Pyrrho, a data model will be regarded as a property of a Role. The physical database defines a default data model, and an associated default Role. This default Role treats each base table with a primary key as an entity, and each column of such a table as a property, and allows navigation using foreign keys. Multi-column keys are handled as lists whose property name is the reserved word KEY.&lt;br /&gt;[Updated 2 August: Users with admin access to a role can create new database objects for their role. Granting access to database objects for a Role copies the necessary entitiy and property definitions into the Role's data model. The data model that is applied is determined by the current Role: this is initially set in the connection but can be changed during the session to any other role that the user has been granted.]&lt;br /&gt;The data model can be modified for a Role by hiding entity types or properties, or defining entity types and properties by renaming inherited entities and properties tables or views and their columns. Descriptive text can be associated with the entity and property definitions. An additional syntax for ALTER ROLE has been created for providing this facility.&lt;br /&gt;This allows data models to have more user-friendly names and allows Roles to be localised for different languages. Pyrrho 4.5 enhances generated columns by introducing updatable generated columns in addition to updatable views so additional derived columns can be added to the database schema where required for making data models more natural. It is a feature of Pyrrho that such derived columns are only computed when required, so there is little overhead in using them.&lt;br /&gt;[Added 2 August: The SQL contained within e.g. stored procedures executes under definer's rights. Although there is only one copy of the SQL in the database, a developer viewing the SQL will see a version adapted to their current data model.  The SQL will execute with definer's rights, although the code will reflect the user's data model. The resulting dependencies between roles and their data models are tracked by Pyrrho, and the usual restrict/cascade protocols apply to changes to the data model schema.]&lt;br /&gt;The data model can be retrieved from the database is the usual way in EDMX  format, and will determine the URL mapping used in Pyrrho's new secure REST service. SQL will of course continue to be applied at the level of base tables. Pyrrho's implementation of LINQ and Java Persistence will also use the new role-based data models: for these APIs the change will only be noticed if a Role is specified in the connection string.&lt;br /&gt;In Pyrrho, strong types, including types with embedded metadata, will continue to be supported in the physical database. The new derived column machinery can present the same physical data as different types as appropriate for role-based data models.&lt;br /&gt;Over the summer I hope to publish more articles on the version 4.5 goodies, including some better support for role base security.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-3929098886433221611?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/3929098886433221611/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2011/07/role-based-data-models.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/3929098886433221611'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/3929098886433221611'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2011/07/role-based-data-models.html' title='Role-based Data Models'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-7176017385413016505</id><published>2011-03-05T11:16:00.000-08:00</published><updated>2011-03-06T05:14:44.805-08:00</updated><title type='text'>A Database for the Windows Phone</title><content type='html'>The purpose of this demonstration is to introduce the embedded Pyrrho engine that is now available for the Windows Phone 7. This uses Web local storage on the client device to hold any databases used.&lt;br /&gt;The demo application is a simple persistent shopping list, and for simplicity only addition and deletion of items is supported. The application has a reference to PhoneOSP.dll. This document contains step-by-step instructions to build this complete application. You will need Windows Phone developer tools, which you can get from &lt;a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=04704acf-a63a-4f97-952c-8b51b34b00ce&amp;displaylang=en"&gt;Microsoft&lt;/a&gt;&lt;br /&gt;and the PhoneOSP.dll from the Pyrrho distribution.&lt;br /&gt;The new project&lt;br /&gt;1. Open Visual Studio 2010, File&gt;New&gt;Project..  In the New Project dialogue box, find the Silverlight for Windows Phone entry under Visual C#, ensure that .NET Framework 4 is selected, and select Windows Phone Application. Set the name of the application to ShoppingList, and the Location to somewhere you control, such as C:\Temp. Select OK.&lt;br /&gt;&lt;b&gt;The Xaml Markup&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;2. Position the mouse cursor just after “LayoutRoot”, and type a space and H. From the Intellisense dropdown, double-click HorizontalAlignment  and then Left. Similarly add VerticalAlignment=”Top”.&lt;br /&gt;3. Position the mouse cursor at the start of the blank line between &amp;lt;Grid ..&gt; and &amp;lt;/Grid&gt; . Type an opening pointy bracket &amp;lt; and from the IntelliSense dropdown, double-click StackPanel. Type a closing pointy bracket &gt;.&lt;br /&gt;4. The cursor is now between &amp;lt;StackPanel&gt; and &amp;lt;StackPanel&gt; . View&gt;ToolBox, and double-click ListBox. Change the Height attribute of the ListBox to 350 and the Width to 400.&lt;br /&gt;5. Place the cursor just before &amp;lt;/StackPanel&gt; again.  Type &amp;lt;S and from the IntelliSense dropdown, double-click  StackPanel and type &gt; .&lt;br /&gt;6. Place the cursor just before the closing pointy bracket of the new &amp;lt;StackPanel&gt; element. Type a space followed by O. Double-click Orientation, and then Horizontal.&lt;br /&gt;7. Move the cursor to just before the first &amp;lt;/StackPanel&gt;, and double-click TextBox from the Toolbox. Set the width property to 240.&lt;br /&gt;8. Now double-click Button in the Toolbox . In the Properties window, change the name of the Button to bAdd,  set the Content property to Add, and press the Enter key.&lt;br /&gt;9. Move the mouse cursor to just before the second &amp;lt;/StackPanel&gt; and select Button from the ToolBox. Change the name of the button to bDEl and the Content to Delete Selected. Change the Width to 100. Now select Debug (the green arrow in the toolbar).  The application should display as shown in a browser. Close the browser window.&lt;br /&gt;&lt;b&gt;The Shopping class&lt;/b&gt;&lt;br /&gt;10. If you want to know how Pyrrho works, you can add the source code for Pyrrho by right-clicking the Solution, and Add PhoneOSP as an Existing Project…., and browse in to PhoneOSP\PhoneOSP to open PhoneOSP.csproj.&lt;br /&gt;11. Right-click on References in the ShoppingList Project, select AddReference.. If you have just done step 10, use the Projects tab to add PhoneOSP. If not, Browse to add PhoneOSP.dll. &lt;br /&gt;12. In the Solution Explorer, right-click on the ShoppingList project and select Add&gt; Class. In the Add New Item – ShoppingList , given the name as Shopping.cs, and select Add. The Shopping.cs file opens in the designer.&lt;br /&gt;13. Change the Shopping.cs file to contain the following:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;using System.Windows;&lt;br /&gt;using System.Windows.Controls;&lt;br /&gt;using System.Windows.Documents;&lt;br /&gt;using System.Windows.Ink;&lt;br /&gt;using System.Windows.Input;&lt;br /&gt;using System.Windows.Media;&lt;br /&gt;using System.Windows.Media.Animation;&lt;br /&gt;using System.Windows.Shapes;&lt;br /&gt;using System.Collections.ObjectModel;&lt;br /&gt;using Pyrrho;&lt;br /&gt;&lt;br /&gt;namespace WindowsPhoneShopping&lt;br /&gt;{&lt;br /&gt;    public class Shopping&lt;br /&gt;    {&lt;br /&gt;        public PyrrhoConnect conn = null;&lt;br /&gt;        MainPage main = null;&lt;br /&gt;&lt;br /&gt;        public Shopping(MainPage page)&lt;br /&gt;        {&lt;br /&gt;            main = page;&lt;br /&gt;            FillData();&lt;br /&gt;        }&lt;br /&gt;        void FillData()&lt;br /&gt;        {&lt;br /&gt;            try&lt;br /&gt;            {&lt;br /&gt;                conn = new PyrrhoConnect("Files=Shopping");&lt;br /&gt;                conn.Open();&lt;br /&gt;                PyrrhoCommand cmd = conn.CreateCommand();&lt;br /&gt;                cmd.CommandText = "select * from Items";&lt;br /&gt;                PyrrhoReader rdr = null;&lt;br /&gt;                try&lt;br /&gt;                {&lt;br /&gt;                    rdr = cmd.ExecuteReader();&lt;br /&gt;                }&lt;br /&gt;                catch (Exception)&lt;br /&gt;                {&lt;br /&gt;                    rdr = null;&lt;br /&gt;                }&lt;br /&gt;                if (rdr == null)&lt;br /&gt;                {&lt;br /&gt;                    conn.Act("create table Items(Name char primary key)");&lt;br /&gt;                }&lt;br /&gt;                else&lt;br /&gt;                {&lt;br /&gt;                    while (rdr.Read())&lt;br /&gt;                    {&lt;br /&gt;                        main.listBox1.Items.Add(rdr.GetString(0));&lt;br /&gt;                    }&lt;br /&gt;                    rdr.Close();&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;            catch (Exception) { }&lt;br /&gt;        }&lt;br /&gt;        public void Refresh()&lt;br /&gt;        {&lt;br /&gt;            main.listBox1.Items.Clear();&lt;br /&gt;            FillData();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;Check this still runs as before. Close the browser window.&lt;br /&gt;&lt;b&gt;Adding code to add and delete items&lt;/b&gt;&lt;br /&gt;14.    In the MainPage.xaml markup, place the mouse cursor in the Grid element. In the Properties window, select the Events tab, and double-click the Loaded event. The MainPage.xaml.cs file opens and you should add the following lines to the LayoutRoot_Loaded event handler:&lt;br /&gt;&lt;pre&gt;shopping = new Shopping(this);&lt;br /&gt;            textBox1.Text = "";&lt;br /&gt;&lt;/pre&gt;15.    Still in the MainPage.xaml.cs file, position the mouse cursor just inside the first curly bracket, and enter&lt;br /&gt;&lt;pre&gt;Shopping shopping = null;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;16. In the MainPage.xaml designer, double-click the Add button.  The MainPage.xaml.cs file opens in the designer window. Insert the following code in the the bAdd_Click  method (between the curly brackets): &lt;br /&gt;&lt;pre&gt;try&lt;br /&gt;    {&lt;br /&gt;        shopping.conn.Act("insert into Items values('" + textBox1.Text + "')");&lt;br /&gt;        shopping.Refresh();&lt;br /&gt;        textBox1.Text = "";&lt;br /&gt;     }&lt;br /&gt;     catch (Exception) { }&lt;br /&gt;&lt;/pre&gt;17. In the MainPage.xaml designer, double-click the Delete Selected button. When the MainPage.xaml.cs file opens again, insert the following code in the bDel_Click method:&lt;br /&gt;&lt;pre&gt;try&lt;br /&gt;     {&lt;br /&gt;         var it = listBox1.SelectedItem as string;&lt;br /&gt;         if (it != null)&lt;br /&gt;            shopping.conn.Act("delete from Items where name='" + it + "'");&lt;br /&gt;         shopping.Refresh();&lt;br /&gt;      }&lt;br /&gt;      catch (Exception) { }&lt;br /&gt;&lt;/pre&gt;18. The application should now run.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-7176017385413016505?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/7176017385413016505/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2011/03/database-for-windows-phone.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/7176017385413016505'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/7176017385413016505'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2011/03/database-for-windows-phone.html' title='A Database for the Windows Phone'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-8068963617628092234</id><published>2011-03-04T11:26:00.000-08:00</published><updated>2011-03-04T11:35:42.435-08:00</updated><title type='text'>A Silverlight OSP Tutorial</title><content type='html'>The purpose of this demonstration is to introduce the embedded Pyrrho engine that is now available for Silverlight 4. This uses Web local storage on the client machine to hold any databases used.&lt;br /&gt;The demo application is a simple persistent shopping list, and for simplicity only addition and deletion of items is supported. The application has a reference to SilverlightOSP. This document contains step-by-step instructions to build this complete application. You will need the Silverlight 4 SDK and Tools for Visual Studio 2010, which you can get from www.silverlight.net, and the SilverlightOSP.dll from the Pyrrho distribution.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-qpqceDGSqy8/TXE4Z7Ciy9I/AAAAAAAAAB4/S8C2eO8q6KM/s1600/image001.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="290" src="http://1.bp.blogspot.com/-qpqceDGSqy8/TXE4Z7Ciy9I/AAAAAAAAAB4/S8C2eO8q6KM/s320/image001.png" width="250" /&gt;&lt;/a&gt;&lt;/div&gt;The new project&lt;br /&gt;&lt;br /&gt;1. Open Visual Studio 2010, File&amp;gt;New&amp;gt;Project..  In the New Project dialogue box, find the Silverlight entry under Visual C#, ensure that .NET Framework 4 is selected, and select Silverlight Application. Set the name of the application to ShoppingList, and the Location to somewhere you control, such as C:\Temp. Select OK.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-GWN_bUKbBq8/TXE4rRJvD7I/AAAAAAAAACA/kKQhqu_Q_t8/s1600/image002.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="171" src="http://4.bp.blogspot.com/-GWN_bUKbBq8/TXE4rRJvD7I/AAAAAAAAACA/kKQhqu_Q_t8/s320/image002.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;2. In the New Silverlight Application dialogue box, accept the defaults and click OK. The designer for MainPage.xaml opens.&lt;br /&gt;The Xaml Markup&lt;br /&gt;3. Position the mouse cursor just after "LayoutRoot", and type a space and H. From the Intellisense dropdown, double-click HorizontalAlignment  and then Left. Similarly add VerticalAlignment="Top".&lt;br /&gt;4. Position the mouse cursor at the start of the blank line between &amp;lt;Grid ..&amp;gt; and &amp;lt;/Grid&amp;gt; .&lt;br /&gt;Type an opening pointy bracket &amp;lt; and from the IntelliSense dropdown,&lt;br /&gt;double-click StackPanel. Type a closing pointy&lt;br /&gt;bracket &amp;gt;.&lt;br /&gt;5. The cursor is now between &amp;lt;StackPanel&amp;gt; and &amp;lt;StackPanel&amp;gt; . View&amp;gt;ToolBox, and double-click DataGrid. Change the Height attribute of the DataGrid to 150 and the Width to 200.&lt;br /&gt;6. Place the cursor just before &amp;lt;/StackPanel&amp;gt; again.  Type &amp;lt;S and from the IntelliSense dropdown, double-click  StackPanel and type &amp;gt; .&lt;br /&gt;7. Place the cursor just before the closing pointy bracket of the new &amp;lt;StackPanel&amp;gt; element. Type a space followed by O. Double-click Orientation, and then Horizontal.&lt;br /&gt;8. Move the cursor to just before the first &amp;lt;/StackPanel&amp;gt;, and double-click TextBox&lt;br /&gt;from the Toolbox.&lt;br /&gt;9. Now double-click Button in the Toolbox . In the Properties window, change the name of the Button to bAdd,  set the Content property to Add, and press the Enter key.&lt;br /&gt;10. Move the mouse cursor to just before the second &amp;lt;/StackPanel&amp;gt; and select Button from the ToolBox. Change the name of the button to bDEl and the Content to Delete Selected. Change the Width to 100. Now select Debug (the green arrow in the toolbar).  The application should display as shown in a browser. Close the browser window.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-1djrDaDPONY/TXE46dfbuUI/AAAAAAAAACI/k24UISEbE7w/s1600/image003.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="320" src="http://4.bp.blogspot.com/-1djrDaDPONY/TXE46dfbuUI/AAAAAAAAACI/k24UISEbE7w/s320/image003.png" width="286" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-K8APRqLxDp0/TXE5APFp6jI/AAAAAAAAACQ/41Wd3EM-OIU/s1600/image004.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="290" src="http://1.bp.blogspot.com/-K8APRqLxDp0/TXE5APFp6jI/AAAAAAAAACQ/41Wd3EM-OIU/s320/image004.png" width="250" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;b&gt;&lt;/b&gt;&lt;br /&gt;You can see the MainPage.xaml markup: &lt;a href="http://pyrrhodb.uws.ac.uk/ShoppingList.htm"&gt;here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The Shopping class&lt;br /&gt;&lt;br /&gt;11. If you want to know how Pyrrho works, you can add the source code for Pyrrho by right-clicking the Solution, and Add SilverlightOSP as an Existing Project…., and browse in to SilverlistOSP\SilverlightOSP to open SilverlightOSP.csproj.&lt;br /&gt;12. Right-click on References in the ShoppingList Project, select AddReference.. If you have just done step 11, use the Projects tab to add SilverlightOSP. If not, Browse to add SilverlightOSP.dll. &lt;br /&gt;13. In the Solution Explorer, right-click on the ShoppingList project and select Add&amp;gt; Class. In the Add New Item – ShoppingList , given the name as Shopping.cs, and select Add. The Shopping.cs file opens in the designer.&lt;br /&gt;14. Change the Shopping.cs file to contain the following:&lt;br /&gt;&lt;pre&gt;using System;&lt;br /&gt;using System.Net;&lt;br /&gt;using System.Windows;&lt;br /&gt;using System.Windows.Controls;&lt;br /&gt;using System.Windows.Documents;&lt;br /&gt;using System.Windows.Ink;&lt;br /&gt;using System.Windows.Input;&lt;br /&gt;using System.Windows.Media;&lt;br /&gt;using System.Windows.Media.Animation;&lt;br /&gt;using System.Windows.Shapes;&lt;br /&gt;using System.Collections.ObjectModel;&lt;br /&gt;using Pyrrho;&lt;br /&gt;&lt;br /&gt;namespace ShoppingList&lt;br /&gt;{&lt;br /&gt;  public class Shopping&lt;br /&gt;  {&lt;br /&gt;     public ObservableCollection&lt;itemtobuy&gt; ItemsRequired { get; set; }&lt;br /&gt;     public static PyrrhoConnect conn = null;&lt;br /&gt;     public static Shopping theList = null;&lt;br /&gt;&lt;br /&gt;     public Shopping()&lt;br /&gt;     {&lt;br /&gt;        ItemsRequired = new ObservableCollection&lt;itemtobuy&gt;();&lt;br /&gt;        theList = this;&lt;br /&gt;        FillData();&lt;br /&gt;      }&lt;br /&gt;      void FillData()&lt;br /&gt;      {&lt;br /&gt;        try&lt;br /&gt;        {&lt;br /&gt;           conn = new PyrrhoConnect("Files=Shopping");&lt;br /&gt;           conn.Open();&lt;br /&gt;           PyrrhoCommand cmd = conn.CreateCommand();&lt;br /&gt;           cmd.CommandText = "select * from Items";&lt;br /&gt;           PyrrhoReader rdr = null;&lt;br /&gt;           try&lt;br /&gt;           {&lt;br /&gt;              rdr = cmd.ExecuteReader();&lt;br /&gt;           }&lt;br /&gt;           catch (Exception)&lt;br /&gt;           {&lt;br /&gt;              rdr = null;&lt;br /&gt;           }&lt;br /&gt;           if (rdr == null)&lt;br /&gt;           {&lt;br /&gt;              conn.Act("create table Items(Name char primary key)");&lt;br /&gt;           }&lt;br /&gt;           else&lt;br /&gt;           {&lt;br /&gt;              while (rdr.Read())&lt;br /&gt;              {&lt;br /&gt;                 ItemsRequired.Add(new ItemToBuy()&lt;br /&gt;                     {&lt;br /&gt;                       Name = rdr.GetString(0)&lt;br /&gt;                     });&lt;br /&gt;              }&lt;br /&gt;              rdr.Close();&lt;br /&gt;           }&lt;br /&gt;        }&lt;br /&gt;        catch (Exception) { }&lt;br /&gt;      }&lt;br /&gt;      public void Refresh()&lt;br /&gt;      {&lt;br /&gt;        ItemsRequired.Clear();&lt;br /&gt;        FillData();&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;   public class ItemToBuy&lt;br /&gt;   {&lt;br /&gt;      string name;&lt;br /&gt;      public string Name { get; set; }&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;15. Check this still runs as before. Close the browser window.&lt;br /&gt;16. Return to the MainPage.xaml designer by double-clicking its tab. Place the mouse cursor just after mc:ignorable=”d” and enter xmlns:my="clr-namespace:ShoppingList"   &lt;br /&gt;17. Place the mouse cursor just before &amp;lt;Grid and paste the following code:&lt;br /&gt;&amp;lt;UserControl.Resources&amp;gt;&lt;br /&gt;&amp;lt;my:ShoppingManager x:Key="shoppingListViewSource" /&amp;gt;&lt;br /&gt;&amp;lt;/UserControl.Resources&amp;gt;&lt;br /&gt;18. Place the mouse cursor after “LayoutRoot” and paste the following: &lt;br /&gt;DataContext="{Binding Path=ItemsRequired, Source={StaticResource shoppingListViewSource}}" &lt;br /&gt;19.  In the DataGrid markup, change the value of AutoGenerateColumns to True.&lt;br /&gt;20. Place the mouse cursor just after "True" and paste the following:&lt;br /&gt;HeadersVisibility="Column" ItemsSource ="{Binding}"&lt;br /&gt;21. Notice that the DataGrid already shows the Name column header. Run the application. Close the browser window.&lt;br /&gt;Adding code to add and delete items&lt;br /&gt;22. In the MainPage.xaml designer, double-click the Add button.  The MainPage.xaml.cs file opens in the designer window. Insert the following code in the the bAdd_Click  method (between the curly brackets): &lt;br /&gt;try&lt;br /&gt;{&lt;br /&gt;Shopping.conn.Act("insert into Items values('" + textBox1.Text + "')");&lt;br /&gt;Shopping.theList.Refresh();&lt;br /&gt;textBox1.Text = "";&lt;br /&gt;}&lt;br /&gt;catch (Exception) { }&lt;br /&gt;23. In the MainPage.xaml designer, double-click the Delete Selected button. When the MainPage.xaml.cs file opens again, insert the following code in the bDel_Click method:&lt;br /&gt;try&lt;br /&gt;{&lt;br /&gt;var it = dataGrid1.SelectedItem as ItemToBuy;&lt;br /&gt;if (it != null)&lt;br /&gt;Shopping.conn.Act("delete from Items where name='" + it.Name + "'");&lt;br /&gt;Shopping.theList.Refresh();&lt;br /&gt;}&lt;br /&gt;catch (Exception) { }&lt;br /&gt;24. Now test out the application. You should be able to add and remove items using the buttons. (To add an item, type its name in the textbox and click Add.)&lt;/itemtobuy&gt;&lt;/itemtobuy&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-8068963617628092234?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/8068963617628092234/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2011/03/silverlight-osp-tutorial.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/8068963617628092234'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/8068963617628092234'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2011/03/silverlight-osp-tutorial.html' title='A Silverlight OSP Tutorial'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-qpqceDGSqy8/TXE4Z7Ciy9I/AAAAAAAAAB4/S8C2eO8q6KM/s72-c/image001.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-2205732145808101150</id><published>2011-03-01T07:45:00.000-08:00</published><updated>2011-03-05T13:33:02.601-08:00</updated><title type='text'>Silverlight and OWL2</title><content type='html'>Version 4.4 of PyrrhoDBMS is released today, with support for OWL 2 subtypes and Silverlight applications.&lt;br /&gt;I am particularly excited by the Silverlight version. This is a dll that is included in your Silverlight project, and via inclusion in the .xap file, runs on the client machine, using secure local storage in the client machine for the database(s) used by your application. I really feel this brings a whole new perspective on persistence, since the application can organise the data flexibly using SQL. Full SQL is available (apart from the xmlquery primitive) in a compact engine (600KB !).&lt;br /&gt;Okay, I've removed a few previous technologies in this edition. Many people thought I was mad to include SPARQL in a DBMS, and this has now been removed, as have the built-in HTTP services, and the datamodel machinery.&lt;br /&gt;I will publish some samples for both of the above innovations on the PyrrhoDB web site in the next few days. So much has changed that there are bound to be some bugs. For the moment the download pages also provide previous versions of the PyrrhoDBMS. Please let me know if anything strange happens for you.&lt;br /&gt;UPDATE 2 March: The 1 March versions had a serious bug affecting Alter table add, with database corruption. The 2 March versions fix this problem.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-2205732145808101150?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/2205732145808101150/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2011/03/silverlight-and-owl2.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/2205732145808101150'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/2205732145808101150'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2011/03/silverlight-and-owl2.html' title='Silverlight and OWL2'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-8537915783928006987</id><published>2010-10-11T00:28:00.000-07:00</published><updated>2010-10-11T00:28:09.784-07:00</updated><title type='text'>Library update</title><content type='html'>Today's updates are to the PyrrhoLink and OSPLink libraries, to fix a bug in code from 17 Sept.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-8537915783928006987?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/8537915783928006987/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2010/10/library-update.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/8537915783928006987'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/8537915783928006987'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2010/10/library-update.html' title='Library update'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-8954009967990414974</id><published>2010-09-24T03:28:00.000-07:00</published><updated>2010-09-24T03:28:32.255-07:00</updated><title type='text'>Adding a Mono version</title><content type='html'>Today's update includes some version compiled for Linux.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-8954009967990414974?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/8954009967990414974/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2010/09/adding-mono-version.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/8954009967990414974'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/8954009967990414974'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2010/09/adding-mono-version.html' title='Adding a Mono version'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-5543937022574935408</id><published>2010-09-10T06:44:00.000-07:00</published><updated>2010-09-10T06:44:06.434-07:00</updated><title type='text'>Transaction Profiling</title><content type='html'>Today's update fixes some mathematical functions that the parser didn't recognise, and makes some improvements to threading.&lt;br /&gt;There is also some new support for transaction profiling, to be discussed in a paper I am writing.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-5543937022574935408?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/5543937022574935408/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2010/09/transaction-profiling.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/5543937022574935408'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/5543937022574935408'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2010/09/transaction-profiling.html' title='Transaction Profiling'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-5936872434573538438</id><published>2010-06-02T01:24:00.001-07:00</published><updated>2010-06-02T01:25:18.543-07:00</updated><title type='text'>Fix to ordering</title><content type='html'>Today's update fixes a problem with rowset ordering.&lt;br /&gt;Keep me posted on any performance issues.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-5936872434573538438?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/5936872434573538438/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2010/06/fix-to-ordering.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/5936872434573538438'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/5936872434573538438'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2010/06/fix-to-ordering.html' title='Fix to ordering'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-2821439573535142922</id><published>2010-05-24T06:00:00.000-07:00</published><updated>2010-05-24T06:04:47.705-07:00</updated><title type='text'>SQL2008 Compliance</title><content type='html'>Belatedly perhaps, the version released today has been updated to address SQL2008 compliance. The main change is the new FETCH FIRST n ROWS ONLY clause that can be added in any top-level query expression (usually in combination with an ORDER BY clause).&lt;br /&gt;Please advise me of any performance issues.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-2821439573535142922?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/2821439573535142922/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2010/05/sql2008-compliance.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/2821439573535142922'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/2821439573535142922'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2010/05/sql2008-compliance.html' title='SQL2008 Compliance'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-2818392568288096631</id><published>2010-04-26T15:41:00.001-07:00</published><updated>2010-04-26T15:42:20.046-07:00</updated><title type='text'>Groups and Window Functions</title><content type='html'>Today's fix is for the advanced window functions.&lt;br /&gt;Email me if you find anything that does not work.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-2818392568288096631?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/2818392568288096631/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2010/04/groups-and-window-functions.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/2818392568288096631'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/2818392568288096631'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2010/04/groups-and-window-functions.html' title='Groups and Window Functions'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-6051931555809225149</id><published>2010-04-01T05:35:00.000-07:00</published><updated>2010-04-01T05:43:04.271-07:00</updated><title type='text'>Java Persistence Library</title><content type='html'>The Open Source Edition has been updated to fix an error in the Java Persistence implementation org.pyrrhodb.* (PyrrhoJC.jar).&lt;br /&gt;Please report any performance issues to malcolm@pyrrhodb.com .&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-6051931555809225149?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/6051931555809225149/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2010/04/java-persistence-library.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/6051931555809225149'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/6051931555809225149'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2010/04/java-persistence-library.html' title='Java Persistence Library'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-773344741860298968</id><published>2010-03-29T09:04:00.001-07:00</published><updated>2010-03-29T09:05:10.933-07:00</updated><title type='text'>Fixing Date Types</title><content type='html'>Today's fixes relate to the date type, which contained some serious errors.&lt;br /&gt;Keep me posted on any performance issues.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-773344741860298968?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/773344741860298968/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2010/03/fixing-date-types.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/773344741860298968'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/773344741860298968'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2010/03/fixing-date-types.html' title='Fixing Date Types'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-595179135307498638</id><published>2010-02-26T01:02:00.001-08:00</published><updated>2010-02-26T01:11:52.296-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Digital curation'/><title type='text'>Version 4.0 is released</title><content type='html'>Pyrrho DBMS Version 4.0 is now available. There are three editions, all free to use: Standard, Embedded and OpenSourcePyrrho (OSP). As before, OSP contains an implementation of Java Persistence Architecture v1.0.&lt;br /&gt;The Standard and OSP editions include deployment options for taking advantage of cloud computing technologies, following the design of my December 2009 blog post. There is also an advanced implementation of subtypes as I believe they can be very useful in identifying special features of individual data values (similar to annotations in Excel, or footnotes in documents). I expect this sort of feature in databases to become more important with the increasing interest in provenance and digital curation.&lt;br /&gt;A lot of the code in Version 4.0 is new, so I will be continuing to test this version and updates should get posted regularly. I look forward to receiving feedback on any performance issues and on the concepts introduced in this version.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-595179135307498638?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/595179135307498638/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2010/02/version-40-is-released.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/595179135307498638'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/595179135307498638'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2010/02/version-40-is-released.html' title='Version 4.0 is released'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-1357600241195303196</id><published>2009-12-10T13:11:00.000-08:00</published><updated>2009-12-13T03:07:04.524-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cloud databases'/><title type='text'>Pyrrho and the Cloud</title><content type='html'>A number of writers, considering the poor support for transactions and locking support, have concluded that cloud storage might not be suitable as a data store for the purposes of most line-of-business applications (Chantry 2009), (Abadi, 2009), (Wei et al, 2009). Brantner et al (2009) reviewing the support for databases in the cloud, note that although some services are quite powerful, they might not directly satisfy the requirements for a given task. In particular, storage providers usually give only relaxed consistency guarantees, and storage services are “orders of magnitude” slower than locally attached disks. Abadi (2009) discusses the limitations of the “simple databases” offered by cloud services such as Amazon and Yahoo, noting that they simply relax the ACID requirements for transactions and do not guarantee consistency.&lt;br /&gt;The different cloud services providers differ most of all in their choice of implementation language. Microsoft’s Windows Azure platform, based on .NET and its language set, notably C#, provides three sorts of storage: Blobs, Tables, and Queues, which are accessible either using Web Roles (from IIS) or from Worker Roles (from Azure). Azure hosted services can also be accessed using WCF and REST, but so far I haven’t been able to access Azure Storage by this route. Distressingly, the web pages generated to access Azure storage using the November 2009 samples seem to have a lot of hidden authorisation stuff, and I haven’t been able to generate my own client applications to consume Azure Storage data. It is all still clearly under development, and is only due for release in 2010.&lt;br /&gt;Still, I am sure that &lt;a href="http://timheuer.com/blog/archive/2009/11/30/using-windows-azure-to-replace-silverlight-streaming-howto.aspx"&gt;before too long&lt;/a&gt; we will be able to use WCF Streaming from Azure storage, so I am assuming this in the following design ideas.&lt;br /&gt;Many authors draw attention to the CAP theorem whereby a shared-data system can choose at most two out of the three properties: consistency, availability, and tolerance to partitions. DBMS designers usually insist on consistency at all costs. For this reason, we will end up with a solution that retains a transaction master server for each database, while taking advantage of the cloud for data replication and transaction routing. The &lt;a href="http://www.globule.org/publi/STWAC_europar2009.pdf"&gt;paper by Wei et al&lt;/a&gt; (2009) presents essentially the same solution as the one proposed here.&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&lt;br /&gt;Pyrrho’s Binary Storage Architecture&lt;/span&gt;&lt;br /&gt;Pyrrho operates a layered architecture described in the documentation using the diagram shown. In this diagram the bottom two layers represent durable storage (e.g. file storage on the hard disk). It is natural to focus on using Cloud storage as an alternative form of durable storage, and the concept of a logical file consisting of binary segments, all but the last of which will never require updating, makes Pyrrho particularly attractive for such a design.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_phVlSHDhxb4/SyFlV300YnI/AAAAAAAAABA/qpMrfKHbaD8/s1600-h/Pyrrho.jpg"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 320px; height: 282px;" src="http://3.bp.blogspot.com/_phVlSHDhxb4/SyFlV300YnI/AAAAAAAAABA/qpMrfKHbaD8/s320/Pyrrho.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5413719653513192050" /&gt;&lt;/a&gt;&lt;br /&gt;In fact, the original design of Pyrrho envisaged completely immutable file data, where each committed transaction would simply append new durable data to the file.&lt;br /&gt;The current physical design of these two layers is not ideally suited to use with the cloud however. In the first place, there is a tamper-proofing end-of-file marker which is overwritten by the next transaction commit. Secondly, the segment size used on the hard disk is measured in gigabytes, which is too large for current internet implementations. Finally, there is exactly one disk write for each transaction commit.&lt;br /&gt;Taking this last point first, all of Pyrrho’s competitors, when committing a transaction finally to disk storage, write in many places in the disk file, so that multiple disk writes are required. Measurements of disk traffic show that under heavy transaction loading, Pyrrho uses fewer disk writes by a factor of around 70 compared to commercial DBMSs. Nevertheless, the default transaction mode used is that each SQL statement will autocommit, so that there is approximately one disk update for each INSERT/UPDATE/DELETE statement. If cloud storage is used, there will be one server round-trip corresponding to each storage change: this strongly motivates the use of explicit BEGIN TRANSACTION and COMMIT if many changes are to be made, as this would tend to group associated modifications in a single batch. It is an obvious first step towards implementation to modify Pyrrho’s autocommit policy so that by default, transactions are committed when a connection is closed rather than at completion of each statement. This will have the effect of adding to cloud storage in larger chunks, and this seems to point to a natural solution for the segment size issue mentioned in the second point.&lt;br /&gt;For the segment size of cloud storage, there is obviously a balance to be struck between the practical size of a binary transmission and the number of connection requests managed by the network. Assuming an efficient streaming implementation, which we will come to in a moment, the natural thing to do would be to store the data from each transaction in a new segment to be committed to cloud storage.&lt;br /&gt;This leaves the question of the end-of-file marker, which we no longer need. Its purpose was to ensure that the contents of the entire data file had not been changed since they were committed. Instead, we simply store the same marker data in the cloud storage along with the associated segment: the marker can be used to check the entire data file up to that point. &lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_phVlSHDhxb4/SyFlWIrlmVI/AAAAAAAAABI/6G11geRInNg/s1600-h/Cloud1.jpg"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 320px; height: 170px;" src="http://1.bp.blogspot.com/_phVlSHDhxb4/SyFlWIrlmVI/AAAAAAAAABI/6G11geRInNg/s320/Cloud1.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5413719658037877074" /&gt;&lt;/a&gt;&lt;br /&gt;Following this step, the Pyrrho DBMS server can operate using local (disk) storage and remote (cloud) storage. So far, this model could be conveniently hosted by a simple REST/bytestream service such as Amazon S3. Older parts of the database can be replicated without loss of consistency. We consider next how we can ensure that the data is up-to-date.&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Transaction Serialisation&lt;/span&gt;&lt;br /&gt;Pyrrho’s transaction design is actually very well suited to sharing cloud storage between database engines, because its transaction serialisation handling is performed at the level of the binary records (“Physical”s) that are written to the durable storage when a transaction commits. Pyrrho uses optimistic locking, which is also very well suited to use with cloud storage, since it would be a bad idea to have an exclusive lock on the Cloud service.&lt;br /&gt;For a proper understanding of the mechanism, it is necessary first to mention that the tree and queue data structures managed in the Logical Database layer have the property that all their elements are immutable: any change results in a new head structure, and following links through new components of the data structure usually leads to components of the original structure.&lt;br /&gt;So, at the start of a transaction, new headers for the database(s) involved are created, which initially lead to the current committed state: if a few transactions are in progress, there will be several versions of the database(s), mostly coinciding (on unchanged portions). The changes associated with the transaction each have a Physical which will be written to durable storage along with a descriptor of the transaction itself.&lt;br /&gt;Whether such ongoing transactions conflict can be determined by examining just these Physicals. For example, two updates to the same row of a table will conflict, an insert in a table will conflict with dropping the table, etc. This means that transaction serialisation can be determined at the Physical Records level of the database.&lt;br /&gt;There are two subtleties to the resulting design, which apply equally to local and remote storage. The first relates to relocation of Physicals, the second to transaction conflicts where reads conflict with changes.&lt;br /&gt;The relocation issue arises because Pyrrho uses the (immutable) defining addresses of data in Physical records: so that for example a Column will refer to its parent Table by giving its defining address rather than its (mutable) name. For this reason a group of Physicals in a transaction are very likely to refer to each other using their positions in the data file. While transactions are in progress, nobody can tell which transaction will commit first, so the positions of Physicals in the data file are generally not known until the Commit succeeds. The physical layer of the DBMS therefore relocates the transaction to its final place in the data file.&lt;br /&gt;The read-conflict issue is rather pedantic. Pyrrho uses a very strict concept of transaction isolation, and notes all data that a transaction reads. If any of this data changes before the transaction commits, Pyrrho will roll back the transaction. For example, if a transaction computes a value to insert in the database, it should be invalidated by changes to any values used in the computation. Pyrrho calls these ReadConstraints. &lt;br /&gt;Similarly, referential constraints (called IndexConstraints in the code) must also be checked again at Commit time, in case another transaction has inserted a record with a conflicting unique key, or deleted a record that our transaction intends to refer to.&lt;br /&gt;For this reason, the data used in the Commit process consists of the list of proposed Physicals together with sets of ReadConstraints and IndexConstraints. For a remote database. It is this collection of data, and not the final binary data, that must be sent to the remote master server for processing. &lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_phVlSHDhxb4/SyFlWUqtTtI/AAAAAAAAABQ/N-lLfv9PbHw/s1600-h/Cloud2.jpg"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 320px; height: 177px;" src="http://2.bp.blogspot.com/_phVlSHDhxb4/SyFlWUqtTtI/AAAAAAAAABQ/N-lLfv9PbHw/s320/Cloud2.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5413719661255413458" /&gt;&lt;/a&gt;&lt;br /&gt;Unfortunately, we are left with the situation that serialisation must ultimately be decided by a single DBMS server. The most we can use the cloud for in transaction management is as an enterprise system bus, routing transaction streams to the transaction master. To ensure that we have read the most up-to-date version, we simply call commit: if it is not up to date, our transaction will fail, and re-running the query will get its new value.&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;The Data Stream&lt;/span&gt;&lt;br /&gt;The upper layers of the DBMS still need to construct and maintain the logical database for doing query processing, joins etc, and for this purpose, as with local databases, the complete data stream of Physicals must be read at some stage. For a large database, this is a time-consuming process (roughly 1 minute per 200MB) so should only be carried out when a cold-start of the DBMS occurs. Thus the DBMS itself is too stateful to be placed in the cloud. &lt;br /&gt;On the other hand, once the DBMS is up to date with all of the Physicals that have committed to the local or remote data file, it is relatively easy matter to check for transactions committed by other servers, at the start of a transaction and again at transaction commit. The protocol for obtaining this Physical data must be able to deal with both small and large volumes of data, and take into account that Physicals can vary greatly in size. A binary large object (blob) for example, is committed in a single Physical.&lt;br /&gt;Pyrrho already has excellent mechanisms for serialising such diverse binary data, with the AsyncStream class. This streaming mechanism can be used directly to deal with the Physical data from cloud storage. It is important to be able to use streamed responses from the cloud service, though, as it would be unacceptably slow to recreate repeated connections for downloading such data piecemeal. The AsyncStream class is also a useful mechanism for uploading to the cloud service the data described in the last section. It also supports a mechanism for reporting any exceptions thrown by the cloud service, which would most likely be transaction conflicts.&lt;br /&gt;Nevertheless, a local initialisation device (such as an SD card) containing a copy of a database up to a certain date would seem an obvious way to save a lot of time, particularly if the remote database is often used.&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Distributed Databases&lt;/span&gt;&lt;br /&gt;Pyrrho maintains a single logical file for each database, which as we have seen might comprise a number of segments. This has the advantage that ordinary operating system utilities can be used for backing up, moving or renaming databases. &lt;br /&gt;Pyrrho supports multi-database connections, where one DBMS can combine data from several databases in response to a query. A two-phase commit protocol must be used to ensure that all of the participating databases succeed in committing the data, or all roll it back. Pyrrho does not support multi-database relationships: it is not possible to have a foreign key relationship to a table in another database, since references to another database would be vulnerable to the sorts of file operations just mentioned. Whenever a multi-database connection is used, Pyrrho checks that all distributed transaction commits recorded in the databases are reflected in all of the databases in the connection. &lt;br /&gt;In the simplest cases the DBMS has at its disposal the logical database structure for all of the databases involved in the connection, either because the data comes from local durable files under its control, or has been synchronised from another DBMS or the cloud service. In the latter case, there may be a local file or device that contains a copy of the data for initialisation purposes. Another DBMS is involved in cluster computing scenarios, where only one member of the cluster is given write access to the data file for each database, but all members maintain all the logical databases. This mechanism, can be used effectively to partition data among servers so that transaction masters for each partition of the data collaborate to ensure the ACID properties of the transaction.&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Remote Databases&lt;/span&gt;&lt;br /&gt;With the introduction of cloud storage, and with the increasing use of smaller devices as servers, it becomes important to extend the storage modes available for remote data, to include the case where, although the local server needs to know the schema for all databases in a connection, it does not have row or index information for remote databases. The logical databases all need to exist somewhere, of course: in this case the remote database needs to be managed by a remote DBMS, not just by the cloud service. During query processing, the local server constructs a query for the remote DBMS which includes join, projection and selection aspects to minimise the amount of traffic required, and it is only when there is local data to be combined with the resulting rowset(s) that the local DBMS actually needs to do much work.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_phVlSHDhxb4/SyFlWp9JUYI/AAAAAAAAABY/0KB6Djo3H7c/s1600-h/Cloud3.jpg"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 320px; height: 174px;" src="http://3.bp.blogspot.com/_phVlSHDhxb4/SyFlWp9JUYI/AAAAAAAAABY/0KB6Djo3H7c/s320/Cloud3.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5413719666969891202" /&gt;&lt;/a&gt;&lt;br /&gt;It will be seen that this is a rather different matter than simply using cloud storage. Which approach is preferable will depend on whether the memory of the local device is capable of holding the whole of the remote logical database, and how frequently consultation of the remote database is really required.&lt;br /&gt;As a result of these developments, in the next edition of the Pyrrho DBMS, any server can have a configuration file which specifies which databases are available from specific servers or cloud storage (and how to access them): and the cloud service needs to refer all transactions to their transaction masters. In addition, the configuration file should explain for remote databases whether the local database maintains the full logical database, and if so, whether there is a local initialisation file.&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;“Eventual Consistency”&lt;/span&gt;&lt;br /&gt;It seems reasonable for read-only transactions to appeal to the eventual consistency of cloud computing services.  A client can always COMMIT a read-only transaction if they wish to be warned about a recent update that might have invalidated their work; but this is of limited value since a further update can always occur before they commit their next transaction. It is best for the reasons given above to transact reads with their resulting updates. For simplicity we have stayed with a single transaction master per data item, although a majority voting (Byzantine) system would be theoretically possible.&lt;br /&gt;Conclusion&lt;br /&gt;This paper has outlined a manifesto for a future version of Pyrrho DBMS supporting cloud storage and the use of small devices as local DBMS servers. We agree with other published studies that cloud storage on its own would violate several key database principles and so remains unsuitable for transactional data management. It is pleasing that this approach is corroborated by the work reported in Wei et al (2009).&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;References&lt;/span&gt;&lt;br /&gt;Abadi, Daniel (2009): Data Management in the Cloud: Limitations and Opportunities, Bulletin of the IEEE Computer Society, 32 (2009), p.3-12.&lt;br /&gt;Brantner, Matthias; Florescu, Daniela; Graf, David; Kossmann, Donald; Kraska, Tim (2009) Building a Database in the Cloud, Technical Report, ETH Zurich, www.dbiz.ethz.ch&lt;br /&gt;Chantry, Darryl (2009): Mapping Applications to the Cloud, The Architecture Journal, 19 (2009), p.2-9 (Microsoft, www.architecturejournal.net)&lt;br /&gt;Crowe, Malcolm (2007): The Pyrrho Database Management System, Computing and Information Systems Technical Reports No. 38 (University of the West of Scotland) www.pyrrhodb.com&lt;br /&gt;Wei, Zhou; Pierre, Guillaume; Chi, Chi-Hung (2009) Scalable transactions for web applications in the cloud, Proc 15th International Euro-Par Conference on Parallel Processing, LNCS 5704, p.442-453 (Springer)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-1357600241195303196?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/1357600241195303196/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2009/12/pyrrho-and-cloud.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/1357600241195303196'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/1357600241195303196'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2009/12/pyrrho-and-cloud.html' title='Pyrrho and the Cloud'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_phVlSHDhxb4/SyFlV300YnI/AAAAAAAAABA/qpMrfKHbaD8/s72-c/Pyrrho.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-2420945294040781788</id><published>2009-11-21T06:14:00.000-08:00</published><updated>2009-11-21T06:15:56.501-08:00</updated><title type='text'>Embedded Pyrrho</title><content type='html'>The main effect of today's updates is to make Embedded Pyrrho available again.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-2420945294040781788?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/2420945294040781788/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2009/11/embedded-pyrrho.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/2420945294040781788'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/2420945294040781788'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2009/11/embedded-pyrrho.html' title='Embedded Pyrrho'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-379206440715383218</id><published>2009-11-07T00:03:00.000-08:00</published><updated>2009-11-07T00:14:58.465-08:00</updated><title type='text'>Bugfixes</title><content type='html'>The 6 November updates dealt with three quite severe bugs. Two were in the fundamental data structures in the Pyrrho data engine - indexing and multi-level indexes, and seem to have crept in at different stages, fairly recently. They weren't detected in routine testing. An unrelated query processing problem was just days old, and should have been spotted.&lt;br /&gt;The Embedded edition is temporarily unavailable because of a different problem.&lt;br /&gt;Please send in reports any time you find anything incorrect.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-379206440715383218?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/379206440715383218/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2009/11/bugfixes.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/379206440715383218'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/379206440715383218'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2009/11/bugfixes.html' title='Bugfixes'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-8697425293641103409</id><published>2009-11-02T12:40:00.000-08:00</published><updated>2009-11-05T12:03:03.824-08:00</updated><title type='text'>Updatable RowSets</title><content type='html'>Today's update fixes a number of issues with the updatability of RowSets. The basic idea is unchanged: a RowSet is updatable if is has been selected (via a view or directly) from a single base table and its columns include the primary key. Unfortunately this simple idea got overlaid with PyrrhoMgr trying to be too clever.&lt;br /&gt;(Updated: 5 Nov 09)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-8697425293641103409?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/8697425293641103409/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2009/11/updatable-rowsets.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/8697425293641103409'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/8697425293641103409'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2009/11/updatable-rowsets.html' title='Updatable RowSets'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-1432277588992465390</id><published>2009-10-20T13:00:00.000-07:00</published><updated>2009-10-20T13:03:32.486-07:00</updated><title type='text'>Sparql fix</title><content type='html'>Today's fix is to the Sparql engine which has obviously been broken since the last posting. I have also reformatted the Sparql tutorial as I noticed some unfortunate page and line breaks in the code samples that caused difficulties if people pasted the text into the Rdf tool without watching carefully.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-1432277588992465390?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/1432277588992465390/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2009/10/sparql-fix.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/1432277588992465390'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/1432277588992465390'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2009/10/sparql-fix.html' title='Sparql fix'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-2767593064379968804</id><published>2009-10-04T13:56:00.000-07:00</published><updated>2009-10-05T15:41:11.383-07:00</updated><title type='text'>Transaction Conflicts</title><content type='html'>Today's fix is to the mechanism for detecting and handling Transaction conflicts. (Updated: 5 Oct)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-2767593064379968804?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/2767593064379968804/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2009/10/transaction-conflicts.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/2767593064379968804'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/2767593064379968804'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2009/10/transaction-conflicts.html' title='Transaction Conflicts'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-3871642421695769838</id><published>2009-09-25T08:34:00.000-07:00</published><updated>2009-09-25T08:35:28.111-07:00</updated><title type='text'>Out and Inout Parameters</title><content type='html'>Yesterday's fix was about output parameters from procedures and methods.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-3871642421695769838?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/3871642421695769838/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2009/09/out-and-inout-parameters.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/3871642421695769838'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/3871642421695769838'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2009/09/out-and-inout-parameters.html' title='Out and Inout Parameters'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-860553665135537106</id><published>2009-09-22T10:47:00.000-07:00</published><updated>2009-09-22T10:57:15.375-07:00</updated><title type='text'>Procedure body syntax</title><content type='html'>Today's fix relates to procedure bodies.&lt;br /&gt;According to SQL2003 (in section 02) procedure call statements must have the CALL keyword and (in section 04) assignment statements must have the SET keyword. For ages Pyrrho has not been enforcing this rule properly. It would be (strictly speaking) a breaking change to start enforcing it now.&lt;br /&gt;So, both keywords had better be optional in Pyrrho procedure bodies, at least for call statements that have a possibly empty parameter list enclosed in () and for simple assignment statements, and this is yet another departure from SQL2003. I will confess to this in the next version of the user manual.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-860553665135537106?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/860553665135537106/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2009/09/procedure-body-syntax.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/860553665135537106'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/860553665135537106'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2009/09/procedure-body-syntax.html' title='Procedure body syntax'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-8935955488722383685</id><published>2009-09-21T14:06:00.000-07:00</published><updated>2009-09-21T14:08:19.150-07:00</updated><title type='text'>Embedded Pyrrho etc</title><content type='html'>Today there is a fix for the Embedded edition, and for yet another type-checking bug in the server...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-8935955488722383685?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/8935955488722383685/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2009/09/embedded-pyrrho-etc.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/8935955488722383685'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/8935955488722383685'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2009/09/embedded-pyrrho-etc.html' title='Embedded Pyrrho etc'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-205119916532065455</id><published>2009-09-19T12:18:00.000-07:00</published><updated>2009-09-20T05:09:21.551-07:00</updated><title type='text'>Triggers and DataGridView</title><content type='html'>Today's update is mainly about fixing some errors in the implementation of Triggers and DataGridViews. A serious issue about type checking has also been resolved.&lt;br /&gt;&lt;br /&gt;For the improved functionality of DataGridView, please use the new version of PyrrhoLink.dll or OSPLink.dll. (Anything that worked previously should still work.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-205119916532065455?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/205119916532065455/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2009/09/triggers-and-datagridview.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/205119916532065455'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/205119916532065455'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2009/09/triggers-and-datagridview.html' title='Triggers and DataGridView'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-1657650049433271722</id><published>2009-09-07T07:45:00.000-07:00</published><updated>2009-09-07T08:47:51.452-07:00</updated><title type='text'>DataTypeName</title><content type='html'>The ADO.NET API includes a method called GetDataTypeName on the IDataReader: this is supposed to return a string, given a field index. The documentation says &lt;br /&gt;&lt;span style="font-style:italic;"&gt;&lt;br /&gt;The data type information can differ from the type information returned by GetFieldType, especially where the underlying data types do not map one for one to the runtime types supported by the language. (for example, DataTypeName may be "integer", while Type.Name may be "Int32".) &lt;/span&gt;&lt;br /&gt;&lt;p&gt;Up to now, the DataTypeName was just the name of the closest native type, such as System.Decimal.&lt;br /&gt;&lt;p&gt;From today, and version 3.3 of Pyrrho, it will return the name of the SQL type. For example, NUMERIC(8,2) or a user defined type name.&lt;br /&gt;&lt;p&gt;The version number is changed since the new version of PyrrhoLink for this behaviour will then only work with server versions 3.3 or later. (In all other respects backwards compatibility is preserved.)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-1657650049433271722?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/1657650049433271722/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2009/09/datatypename.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/1657650049433271722'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/1657650049433271722'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2009/09/datatypename.html' title='DataTypeName'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-6614764735402912272</id><published>2009-08-30T07:59:00.000-07:00</published><updated>2009-08-30T08:02:17.318-07:00</updated><title type='text'>The SPARQL Tutorial</title><content type='html'>Today's update (30 August 2009) includes a version of the ARQ SPARQL Tutorial and some associated fixes to the SPARQL subsystem. Specifically, default data sets should work better for the RDF application program.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-6614764735402912272?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/6614764735402912272/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2009/08/sparql-tutorial.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/6614764735402912272'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/6614764735402912272'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2009/08/sparql-tutorial.html' title='The SPARQL Tutorial'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-6020717449900817640</id><published>2009-08-22T09:13:00.000-07:00</published><updated>2009-08-22T09:17:08.440-07:00</updated><title type='text'>Better Numeric Types</title><content type='html'>Today's update (22 August) fixes a number of bugs mostly related to handling of numeric types. Two corrections to the syntax checking fix the BETWEEN predicate and named columns joins.&lt;br /&gt;I really do like finding and fixing bugs!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-6020717449900817640?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/6020717449900817640/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2009/08/better-numeric-types.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/6020717449900817640'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/6020717449900817640'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2009/08/better-numeric-types.html' title='Better Numeric Types'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-1560355665934084913</id><published>2009-08-14T08:32:00.000-07:00</published><updated>2009-08-14T08:40:40.674-07:00</updated><title type='text'>Subtype improvements</title><content type='html'>Today's update to the DBMS corrects the handling of the new URI-based subtypes of standard types. As mentioned in previous posts, these are a novelty in Pyrrho, allowing declarations such as&lt;br /&gt;  create type uk_numberplate as char with 'http://dvla.gov.uk'&lt;br /&gt;As of today's version the representation clause ("as char" in this example) for such types is constrained to be a standard type. Subtypes of such types must be declared as follows:&lt;br /&gt;  create type sc_nunberplate under uk_numberplate as char with 'http://dvla.scotland.gov.uk'&lt;br /&gt;The semantic of IS OF for these subtypes has been corrected.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-1560355665934084913?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/1560355665934084913/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2009/08/subtype-improvements.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/1560355665934084913'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/1560355665934084913'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2009/08/subtype-improvements.html' title='Subtype improvements'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-1655699146557049813</id><published>2009-07-11T06:32:00.000-07:00</published><updated>2009-07-11T06:46:10.964-07:00</updated><title type='text'>Provenance again</title><content type='html'>Today's version of the software aims to fix a number of issues.&lt;br /&gt;(a) a bug in transaction handling that resulted in premature closure of transactions&lt;br /&gt;(b) a number of corrections to provenance handling and subtypes.&lt;br /&gt;(c) a new system table called Sys$Object which makes it easier to see the provenance of tables and types.&lt;br /&gt;&lt;br /&gt;To try out the new ideas, here are some examples. &lt;br /&gt;&lt;br /&gt;1. To have database objects or inserted rows with a particular provenance, say something like&lt;br /&gt;begin transaction with provenance 'http://example.com'&lt;br /&gt;...&lt;br /&gt;commit&lt;br /&gt;Pyrrho refers to this internally as an import provenance, but of course it is more flexible than that.&lt;br /&gt;&lt;br /&gt;2. To have rows in a table associated with a provenance, you can also say&lt;br /&gt;insert with provenance '/data' into ...&lt;br /&gt;and then the rows have a provenance consisting of eith or both the import and row provenance (if both are specified the provenance is the result of concatenating them).&lt;br /&gt;&lt;br /&gt;There is no way of modifying provenance (this would be heresy).&lt;br /&gt;&lt;br /&gt;3. Subtypes can be associated with a uri: there is a WITH syntax defined in Pyrrho for this purpose, e.g.&lt;br /&gt;create type abcint as integer with 'http://abc.net'&lt;br /&gt;and then if desired the subtype can be used for values you want to mark with the URI, by using (say) treat(11) as abcint instead of just 11.&lt;br /&gt;Such a subtype behaves like an integer of course, but you can select on such subtype values using the OF predicate, e.g. select * from a where b is of(only abcint).&lt;br /&gt;&lt;br /&gt;Write to me with any problems.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-1655699146557049813?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/1655699146557049813/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2009/07/provenance-again.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/1655699146557049813'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/1655699146557049813'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2009/07/provenance-again.html' title='Provenance again'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-1869356536043134847</id><published>2009-06-11T15:21:00.000-07:00</published><updated>2009-06-12T05:18:45.427-07:00</updated><title type='text'>Bug fixed: SelectedColumnsRowSet</title><content type='html'>In previous releases of v3.2, the rowType was incorrectly reported as the original rowType, not the rowType with just the selected  columns. This would have caused an error 22202 when the wrong rowType was used.&lt;br /&gt;Similar fixes to other RowSet classes. Fixed as of 12 June.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-1869356536043134847?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/1869356536043134847/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2009/06/bug-fixed-selectedcolumnsrowset.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/1869356536043134847'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/1869356536043134847'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2009/06/bug-fixed-selectedcolumnsrowset.html' title='Bug fixed: SelectedColumnsRowSet'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-6021167909016625702</id><published>2009-06-08T14:21:00.000-07:00</published><updated>2009-06-10T11:11:24.697-07:00</updated><title type='text'>On importing data</title><content type='html'>I've started to provide better support for data import into Pyrrho. Version 3.x has been introducing ideas of provenance. Now I am enhancing the PyrrhoMgr application a bit. The changes will get published in the next few days. So far they amount to:&lt;br /&gt;1. Supporting direct import from Access 2007 in addition to Access 2003 and SQL Server.&lt;br /&gt;2. Supporting the "Percent" numeric format in Access. (Intriguingly in Access 2007 the default Percent format is for a long integer, and so validation changes every value to either 0.0% or 100.0% !)&lt;br /&gt;3. Allowing the importer to specify the "From Culture" so that culture specific formats for numbers and dates can get converted into the culture used by the importing thread (the culture of the machine that PyrrhoMgr is running on).&lt;br /&gt;As mentioned in the last posting, the server always uses an invariant culture.&lt;br /&gt;As a result of some ongoing research, more changes in this area can be expected soon.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-6021167909016625702?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/6021167909016625702/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2009/06/on-importing-data.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/6021167909016625702'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/6021167909016625702'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2009/06/on-importing-data.html' title='On importing data'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-3956194897610821093</id><published>2009-06-06T00:28:00.001-07:00</published><updated>2009-06-06T00:28:34.381-07:00</updated><title type='text'>Why the version hasn’t changed</title><content type='html'>Changes like this are possible in Pyrrho because of the distinctive way that Pyrrho is designed. Nearly all DBMSs store data structures like indexes in permanent storage within the files making up the database. Pyrrho by contrast places in permanent storage only the data required for durability of each committed transaction. This approach minimises disk activity during normal operations, to about one-seventieth of the disk activity of rival systems. &lt;br /&gt;The server’s data structures are private to the server, and are initialised when the server starts up, and the server brings its state up to date by re-reading the database file, which is just the transaction record. This is a time-consuming process for a large database, equivalent to a cold-start with resynchronisation step for other products.&lt;br /&gt;The format of this data is as far as possible version and platform-independent – there is not even any assumption for what “double precision” means, or how many bits make up a long integer. This means that every aspect of the organisation of data structures can evolve without breaking backward compatibility. Database files created by version 0.1 can still be used in every version of Pyrrho, so all Pyrrho data bases can always be managed by the latest version of the server. New features, such as the recently introduced concept of provenance, or URI-based data types, introduce new or modified data formats which would not be understood by earlier versions, but they really should not be in use. Upgrading to the latest version is always recommended, and is free of charge.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-3956194897610821093?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/3956194897610821093/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2009/06/why-version-hasnt-changed.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/3956194897610821093'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/3956194897610821093'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2009/06/why-version-hasnt-changed.html' title='Why the version hasn’t changed'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-7472596812862194950</id><published>2009-06-03T09:43:00.000-07:00</published><updated>2009-06-04T12:55:46.468-07:00</updated><title type='text'>Speeding up joins</title><content type='html'>The next version (still numbered 3.2) will have a new implementation of the matching code for joins. There will be situations where a significant performance improvement can be expected, for example where the join condition refers to a component of a primary or foreign key. In the source code this is called a TrivialJoin, but it is not necessarily quite so trivial where the join condition does not constrain all the components of the key...&lt;br /&gt;I should be able to release this implementation this weekend following testing.&lt;br /&gt;Update 4 June: so FDJoin is a better term than TrivialJoin, with consequential renaming of lots of things. I've introduced a new internal datatype called Wild for dealing with partial matches. And better handling of recursive traversal of multilevel indexes. It's all loking rather nice.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-7472596812862194950?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/7472596812862194950/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2009/06/speeding-up-joins.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/7472596812862194950'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/7472596812862194950'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2009/06/speeding-up-joins.html' title='Speeding up joins'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-4278169043781825977</id><published>2009-05-27T14:30:00.000-07:00</published><updated>2009-05-27T14:32:08.271-07:00</updated><title type='text'>Version 3.2 is done</title><content type='html'>I will release the next version 3.2 tomorrow 28th May.&lt;br /&gt;It contains the promised improvements to the infrastructure.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-4278169043781825977?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/4278169043781825977/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2009/05/version-32-is-done.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/4278169043781825977'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/4278169043781825977'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2009/05/version-32-is-done.html' title='Version 3.2 is done'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-8309860746475728254</id><published>2009-05-13T13:54:00.000-07:00</published><updated>2009-05-16T00:17:38.009-07:00</updated><title type='text'>Towards stronger types internally</title><content type='html'>The next version of Pyrrho will use much stronger generics. The internal Tree structures will be Tree&amp;lt;Key,Value&amp;gt; instead of just Tree&amp;lt;Key&amp;gt; . But this is taking an age to sort out...&lt;br /&gt;With any luck version 3.2 should be out next month (June 2009) though.&lt;br /&gt;The change has flushed out a few obscure bugs, but unfortunately the changes to the code are extensive so no doubt there will be the occasional null refernce that slips through. So if you get a bad message from the server, please let me know about it...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-8309860746475728254?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/8309860746475728254/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2009/05/towards-stronger-types-internally.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/8309860746475728254'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/8309860746475728254'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2009/05/towards-stronger-types-internally.html' title='Towards stronger types internally'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4899156161526860882.post-2415661064252952600</id><published>2009-05-03T06:34:00.000-07:00</published><updated>2009-05-03T06:46:11.251-07:00</updated><title type='text'>The REST service</title><content type='html'>&lt;span style="font-family: arial;"&gt;Pyrrho's new REST service is similar to ADO.NET data services, from which it differs by providing a default data model. For a Pyrrho database file myfile, the default data service is myfile.svc. Custom data models can be supplied, and then the data service is given the same name as the data model, e.g. mymodel.pdm.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;The service is hosted by default on port 8080 on the host running the Pyrrho DBMS server, e.g.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;http://example.com:8080/mydatabase.svc/&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;and the rest of the URI follows the rules for ADO.NET.&lt;/span&gt; &lt;span style="font-family: arial;"&gt;As with ADO.NET, the detailed datamodel is obtained by adding $metadata to the end of the service URI.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;The methods GET, PUT, POST, and DELETE are supported. If no resource path is specified, a GET on the service gives a synopsis of the service, and otherwise returns XML for the specified data. POST is used for inserting new entities, PUT for updating specified data in existing entities, and DELETE for deleting specified entities.&lt;br /&gt;&lt;br /&gt;However, to make any changes to the database, you need to supply UserID and Role identifiers in the HTTP headers. This means that most browser access will support only GET,&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;p class="MsoNormal" style="margin-top: 6pt; text-align: justify;"&gt;&lt;br /&gt;&lt;span style="font-size:10;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4899156161526860882-2415661064252952600?l=pyrrhodb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pyrrhodb.blogspot.com/feeds/2415661064252952600/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pyrrhodb.blogspot.com/2009/05/rest-service.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/2415661064252952600'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4899156161526860882/posts/default/2415661064252952600'/><link rel='alternate' type='text/html' href='http://pyrrhodb.blogspot.com/2009/05/rest-service.html' title='The REST service'/><author><name>Malcolm Crowe</name><uri>http://www.blogger.com/profile/09753616974538155811</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_phVlSHDhxb4/Sf2uOK5WujI/AAAAAAAAAAY/CCMoM2UNWI4/S220/malcolm1.jpg'/></author><thr:total>0</thr:total></entry></feed>
