<?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-2417324817603252106</id><updated>2011-10-04T11:01:15.387-06:00</updated><category term='Python'/><category term='Hosting'/><category term='PostgreSQL'/><category term='API'/><category term='Javascript'/><category term='ORM'/><category term='binary'/><category term='Rdbadmin'/><title type='text'>Rdbhost</title><subtitle type='html'>SQL Databases as a Web Service</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>69</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-8262711447743023002</id><published>2011-07-15T10:18:00.000-06:00</published><updated>2011-07-15T10:18:01.437-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><title type='text'>Named Query Parameters</title><content type='html'>The Rdbhost protocol now uses named parameters in addition to positional parameters.&lt;br /&gt;&lt;br /&gt;Where before you could submit a query like:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&amp;lt;input name="q" &lt;br /&gt;value="SELECT * FROM personnel WHERE firstName = %s AND lastName = %s" /&amp;gt&lt;br /&gt;&amp;lt;input name="arg000" value="John" /&amp;gt;&lt;br /&gt;&amp;lt;input name="arg001" value="Smith" /&amp;gt;&lt;/blockquote&gt;&lt;br /&gt;Now you can make it more readable, like:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&amp;lt;input name="q" value="SELECT * FROM personnel WHERE firstName = %(first) AND lastName = %(last)" /&amp;gt;&lt;br /&gt;&amp;lt;input name="arg:first" value="John" /&amp;gt;&lt;br /&gt;&amp;ltinput name="arg:last" value="Smith" /&amp;gt;&lt;/blockquote&gt;&lt;br /&gt;This addition has a couple of benefits.  The first is the greater readability and greater ease in assuring the correct parameter values are matched to the correct query tokens.&lt;br /&gt;&lt;br /&gt;The other is that each parameter can be used in the query multiple times.  For example, in the following snippet, we want to ensure that the value is at least 0.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;CASE WHEN (%(val))&lt;=0 THEN trunc(%(val),6) ELSE 0.00 END&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;The query snippet could be written with positional parameters, but there would then be no way to ensure the same value is passed as both values, and a negative value could be returned.  Using a named parameter ensures that parameter value is used both times.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-8262711447743023002?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/8262711447743023002/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2011/07/named-query-parameters.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/8262711447743023002'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/8262711447743023002'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2011/07/named-query-parameters.html' title='Named Query Parameters'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-3093087511677001097</id><published>2011-07-02T09:09:00.001-06:00</published><updated>2011-07-02T09:09:00.508-06:00</updated><title type='text'>Using your own SSL/TLS Certificate</title><content type='html'>Rdbhost now supports your using your own SSL/TLS certificate for your rdbhost subdomain, to encrypt and authenticate data transfer with your account at www.rdbhost.com.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Why Use Certificates&lt;/h3&gt;&lt;br /&gt;The SSL/TLS certificates have two purposes, encryption and authentication.  Any certificate, including a free self-signed certificate, will enable the server to encrypt data transferred between server and client.  This encryption prevents data from being observed by eavesdroppers who might have access to your data stream.  &lt;br /&gt;&lt;br /&gt;However, a connection encrypted with a non-authenticated certificate is vulnerable to a type of attack known as a 'man in the middle' attack.  If someone can insert a proxy into the network path between the client and the server, they can conduct a 'man in the middle' attack, impersonating each end of the connection to the other end.  When the client (browser) requests a certificate, the proxy sends its own, and then requests a cert from the server.  The proxy would hold a certificate for each half of the connection, and thus decrypt and encrypt all data passing through, recording whatever part it is interested in intercepting.  This attack can happen because with an un-authenticated certificate, the client has no way of knowing that it is getting a cert from the proxy rather than the server.  &lt;br /&gt;&lt;br /&gt;The way to prevent this sort of 'man in the middle' attack, if it concerns you, is to use an authenticated, or 'trusted', certificate.  If you purchase a 'trusted' certificate from vendor, they supposedly verify that you are indeed the owner of the site, and issue you a certificate that is digitally signed by them using their own trusted certificate.  The client can verify the issuers signature with the issuer directly, and thus be assured that the certificate you present is your own.  The 'man in the middle' attacker can present a certificate, but presumably would not be able to convince a trusted certificate issuer that they owned *your* domain, and thus could not present a certificate for your domain with a trusted issuer certificate.&lt;br /&gt;&lt;br /&gt;There are a few certificate issuers that are trusted by all browsers as released.  If your vendor is not one of those, they will have a certificate signed by one of those, sign your certificate with theirs, and send a bundle of certificates that establish a chain of trust from a trusted issuer to you.  Godaddy.com is a very popular issuer of certificates, and they issue a bundle file with multiple certificates to establish the chain of trust. The client browser can see who signed your certificate, read the issuers certificate and find who signed it, and repeat until an intrinsically trusted issuer is found.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;User Experience&lt;/h3&gt;&lt;br /&gt;Even if you are not very worried about someone conducting such an attack, you might still want a signed certificate to avoid browser warnings.  Browsers, especially Firefox, can be very assertive about warning users of perceived limitations in a site's certificate.  Having a trusted certificate avoids warnings and gives the user a smoother user experience.  The warnings are so common these days, that many users are blase about it, but it is your call as to how tolerant your users will be.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;The Rdbhost Way&lt;/h3&gt;&lt;br /&gt;Buy your trusted certificate from a vendor of your choice.  There are websites that will create a public key pair and a &lt;i&gt;CSR&lt;/i&gt; Certificate Signing Request for you, and you should create the CSR using your domain and the subdomain you use for Rdbhost server access, for example rdbhost.mydomain.com.  The certificate vendor will create a certificate based on the CSR and make it available for download.&lt;br /&gt;&lt;br /&gt;If you have not registered a domain alias on the site, do so now, registering the domain and subdomain, that you use for Rdbhost database access, for example 'rdbhost.mydomain.com'.  The domain alias page is linked from the profile page.&lt;br /&gt;&lt;br /&gt;If you have not entered the subdomain into the DNS zone manager of your domain registrar, you need to do so.&lt;br /&gt;&lt;br /&gt;Visit the Certificate Manager on www.rdbhost.com and paste the certificate into the form field.  If your vendor provides a chain (or 'bundle') file, paste it in after your certificate.  Paste the private key in at the beginning or the end. Each of these files is a simple text file, so it can be opened in a text editor for cutting and pasting.&lt;br /&gt;&lt;br /&gt;Within a minute or two after submitting the form, your account will be accessible using that domain, secured by SSL/TLS and your authenticated certificate.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Limitations&lt;/h3&gt;&lt;br /&gt;This SSL/TLS service relies on &lt;i&gt;&lt;b&gt;SNI&lt;/b&gt;&lt;/i&gt; Server Name Indication, an extension to the HTTP protocol.  SNI is supported by many modern browsers, but not all.  On Windows, notably, SNI handling is left to the OS by most browser brands, and while Vista and later support it, XP does not.&lt;br /&gt;&lt;br /&gt;If your user is accessing the database using a browser that does not support SNI, they will get the default Rdbhost certificate, in lieu of your trusted certificate.  &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;As always, comments are welcome.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-3093087511677001097?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/3093087511677001097/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2011/07/using-your-own-ssltls-certificate.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/3093087511677001097'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/3093087511677001097'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2011/07/using-your-own-ssltls-certificate.html' title='Using your own SSL/TLS Certificate'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-875823896917446728</id><published>2011-06-16T09:04:00.007-06:00</published><updated>2011-06-16T09:04:00.390-06:00</updated><title type='text'>Wizardry</title><content type='html'>When we first went online, many months ago, with the MVP (minimum viable product), the profile page had three or four options, and no subordinate pages.  As we have added features, the members area of Rdbhost.com has grown to include six detail pages in addition to the profile page itself, the Rdbadmin utility and the log display.&lt;br /&gt;&lt;br /&gt;For any given user, some of those options are irrelevant, and it can be confusing to have to sort through them.  We have just added a &lt;i&gt;wizard&lt;/i&gt;, which steps the user through the process of configuring everything necessary for their application.&lt;br /&gt;&lt;br /&gt;When a user first logs in, they are shown the wizard and it guides him or her through initial configuration.  All configuration options are available from the members pages, outside the wizard, or the user can rerun the wizard at any time.  Whatever suits each of you.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-obaNFMnuypI/Tfj5sXqojWI/AAAAAAAAACM/sYfvOvz0tGU/s1600/wiz.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="221" width="320" src="http://4.bp.blogspot.com/-obaNFMnuypI/Tfj5sXqojWI/AAAAAAAAACM/sYfvOvz0tGU/s320/wiz.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;The wizard can be as brief as four screens, or as elaborate as eleven.  Configuring for use from Python can be straightforward, and use from JavaScript is necessarily more elaborate, as the browser security constraints have to be navigated around.  Where we cannot do everything required (subdomain configuration, for example) for you, the wizard gives you guidance on how to do the necessary tasks.&lt;br /&gt;&lt;br /&gt;Rdbhost, of course, is at:  &lt;a href="http://www.rdbhost.com"&gt;http://www.rdbhost.com&lt;br /&gt;&lt;/a&gt;and the wizard is at: &lt;a href="http://www.rdbhost.com/mbr/wizard"&gt;http://www.rdbhost.com/mbr/wizard&lt;br /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-875823896917446728?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/875823896917446728/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2011/06/wizardry.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/875823896917446728'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/875823896917446728'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2011/06/wizardry.html' title='Wizardry'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-obaNFMnuypI/Tfj5sXqojWI/AAAAAAAAACM/sYfvOvz0tGU/s72-c/wiz.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-1858858371574542926</id><published>2011-06-14T09:01:00.001-06:00</published><updated>2011-06-14T09:01:00.472-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><title type='text'>Home, home on the Ra..</title><content type='html'>Our server move is done, and Rdbhost.com now runs on a later version of PostgreSQL, a later OS version, and is on a new server company.   We were looking to upgrade the software versions, and Slicehost announced their planned termination, so off we went.  &lt;br /&gt;&lt;br /&gt;The new server hosting is with Rackspace.  They seem to have a good reputation, so hopefully this will work out for us.&lt;br /&gt;&lt;br /&gt;Rdbhost.com now runs on PostgreSQL 9.0.4.  This is an upgrade from 8.3, and provides us some useful new features.&lt;br /&gt;&lt;br /&gt;We have, in the past, setup roles as an automated website operation, but had to handoff permission setting to the user, requiring you to use SQL to set permissions for each table, index, or other resource, for each role.  PostgreSQL 9.0 supports setting permissions globally (within the schema) for a given role, and permits setting default permissions for resources not yet created.  For now, that is useful to you in manually setting privileges, but we will be providing an automated setup to set permissions broadly for each role.&lt;br /&gt;&lt;br /&gt;Rdbadmin has been upgraded to accommodate system table changes in the PostgreSQL upgrade.&lt;br /&gt;&lt;br /&gt;David&lt;br /&gt;&lt;br /&gt;Comments are welcome.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-1858858371574542926?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/1858858371574542926/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2011/06/home-home-on-ra.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/1858858371574542926'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/1858858371574542926'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2011/06/home-home-on-ra.html' title='Home, home on the Ra..'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-7938586054356834974</id><published>2011-05-24T08:18:00.027-06:00</published><updated>2011-05-24T08:18:00.645-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='Rdbadmin'/><title type='text'>Not one, but *two* new videos</title><content type='html'>It's been months since &lt;b&gt;&lt;i&gt;RDBHost&lt;/i&gt;&lt;/b&gt; added CORS support enabling cross-site AJAX requests, and even longer since we put the JavaScript module online for general use.&lt;br /&gt;&lt;br /&gt;A few days ago, we put online a new video showing the complete process of creating a JavaScript app. &amp;nbsp;As online videos go, it is a tad long at 11 minutes plus, but it does cover the whole process. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;If you think 11:25 is just &lt;b&gt;too &lt;/b&gt;long for a video, we put up another shorter video. &amp;nbsp;It shows a few features of the Rdbhost database administration utility, &lt;i&gt;RdbAdmin&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.rdbhost.com/screencasts/introscreencast_javascript.html"&gt;Link to JavaScript Video&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.rdbhost.com/screencasts/introscreencast_rdbadmin.html"&gt;Link to RdbAdmin Video&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.rdbhost.com"&gt;Link to Rdbhost.com&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-7938586054356834974?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/7938586054356834974/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2011/05/not-one-but-two-new-videos.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/7938586054356834974'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/7938586054356834974'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2011/05/not-one-but-two-new-videos.html' title='Not one, but *two* new videos'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-2981259728367118987</id><published>2011-05-05T10:15:00.009-06:00</published><updated>2011-05-05T10:15:00.928-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hosting'/><title type='text'>Host your database-backed site on GitHub, for free!</title><content type='html'>We could say, "Host your github page's database on Rdbhost, for free", and be equally correct. &amp;nbsp;But Github has a greater profile than we do, so they get first billing.&lt;br /&gt;&lt;br /&gt;A database backed website is mostly in the database, but it cannot be done without some static content. &amp;nbsp;The styling and the code are in plain files, which you have to host somewhere behind an accessible url. &amp;nbsp; Rdbhost clients can server static content from the database, using plain urls, but you can reasonably want to host static content elsewhere. &amp;nbsp;Github.com is a very well known git repository host that can also serve web pages. &amp;nbsp;The web site is under your domain name, and the git repository hosting doubles as a handy deployment system for the site.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://github.com/"&gt;Github&lt;/a&gt; hosts the static pages, and &lt;a href="http://www.rdbhost.com/"&gt;Rdbhost&lt;/a&gt; hosts the database, for a database-backed web application at no cost&lt;sup&gt;1&lt;/sup&gt;. &amp;nbsp;We describe how to set this up, in some detail, &lt;a href="https://www.rdbhost.com/github_hosting.html"&gt;here&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;We have a demonstration online, at &lt;a href="http://gh.rdbhost.com/threefaves"&gt;http://gh.rdbhost.com/threefaves&lt;/a&gt;&amp;nbsp;, of a database-backed site hosted on github. &amp;nbsp;Three Faves is a little taste-association app, the simplest demonstration app I could think of that might be fun. The site content itself is in a public repository at&amp;nbsp;&lt;a href="https://github.com/rdbhost/rdbhost.github.com"&gt;https://github.com/rdbhost/rdbhost.github.com&lt;/a&gt;&amp;nbsp;. &amp;nbsp; All coding is in the repo, in one file, there for you to read and copy. &amp;nbsp;The Rdbhost account white-lists SQL queries, so undesirable queries cannot be run against the threefaves account.&lt;br /&gt;&lt;br /&gt;Links:&lt;br /&gt;&lt;a href="http://www.rdbhost.com/"&gt;Rdbhost SQL Database Host&lt;/a&gt;&lt;br /&gt;&lt;a href="http://gh.rdbhost.com/threefaves"&gt;Threefaves Site&lt;/a&gt;&lt;br /&gt;&lt;a href="https://github.com/rdbhost/rdbhost.github.com"&gt;Threefaves Repo&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;sup&gt;1&lt;/sup&gt;&amp;nbsp;We say free, but that is qualified: Github will host non-private content for free, at apparently no volume limit; Rdbhost will host private or public data for free, but only at low volumes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-2981259728367118987?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/2981259728367118987/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2011/05/host-your-database-backed-site-on.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/2981259728367118987'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/2981259728367118987'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2011/05/host-your-database-backed-site-on.html' title='Host your database-backed site on GitHub, for free!'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-4717718587636954665</id><published>2011-04-28T16:30:00.000-06:00</published><updated>2011-04-28T16:30:00.575-06:00</updated><title type='text'>Minor gains</title><content type='html'>The Rdbadmin utility has been upgraded again.&amp;nbsp; I improve it from time to time, and sometimes I write aobut the changes.&lt;br /&gt;&lt;br /&gt;A bug-fix corrected the problem that dropped schema names from function identifiers.&amp;nbsp; This proved to be a problem in managing the log trimming functions for our sql logging facility.&lt;br /&gt;&lt;br /&gt;We also added comment displays to all the items of the table structure display, including indexes and constraints.&amp;nbsp; Only the table structure edit tool facilitates adding comments, but comments can be added to anything using SQL, like:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;COMMENT ON INDEX idx_name IS 'this index is the primary key';&lt;/blockquote&gt;&lt;br /&gt;We have been adding comments to tables and other resources that Rdbhost creates in user accounts;&amp;nbsp;When you go exploring existing tables using Rdbadmin, the comments displayed will help you, hopefully, understand how&amp;nbsp;each resource was intended to serve.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-4717718587636954665?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/4717718587636954665/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2011/04/minor-gains.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/4717718587636954665'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/4717718587636954665'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2011/04/minor-gains.html' title='Minor gains'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-3118721374521899213</id><published>2011-04-26T08:09:00.000-06:00</published><updated>2011-04-26T08:09:00.543-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><title type='text'>SQL Logging, how mundane</title><content type='html'>When you're sending requests to a database, or to any online API, it can be useful to be able to tell what requests are getting through, and whether results are being sent back to your client. &lt;br /&gt;&lt;br /&gt;Rdbhost accounts now have SQL query logging. &amp;nbsp;Each SQL query is stored in a table in your account, with arguments and contextual information. &amp;nbsp;The log table is in a separate schema (called 'monitor') to minimize name collisions with your data tables, but you can run queries against the log table just like any other table. &amp;nbsp;The page displaying recent queries is linked from the account profile page.&lt;br /&gt;&lt;br /&gt;The logs are trimmed automatically, and you can redefine the trimming function to set your own criteria. &lt;br /&gt;&lt;br /&gt;&lt;a href="https://www.rdbhost.com/sqllogging.html"&gt;https://www.rdbhost.com/sqllogging.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If you are&amp;nbsp;unacquainted&amp;nbsp;with Rdbhost, each account has one database, which can be accessed via a choice of client-side APIs, or from an administration program, RdbAdmin, that we host.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-3118721374521899213?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/3118721374521899213/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2011/04/sql-logging-how-mundane.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/3118721374521899213'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/3118721374521899213'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2011/04/sql-logging-how-mundane.html' title='SQL Logging, how mundane'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-3097212078436736763</id><published>2011-03-31T06:50:00.002-06:00</published><updated>2011-03-31T06:50:00.645-06:00</updated><title type='text'>A post about Authentication</title><content type='html'>At Rdbhost, there are passwords, and there are 'authcodes'. &amp;nbsp;What is the difference?&lt;br /&gt;&lt;br /&gt;Passwords are about 30 characters or less, memorable, and submitted with an email address as a login. &amp;nbsp;The email/password login process is back-stopped by failure counters, that inhibit a brute force attack on the password by requiring increasing delays between tries.&lt;br /&gt;&lt;br /&gt;Authcodes are 50 characters, base-64 character set, that are randomly generated and assigned to the account. &amp;nbsp;Machine requests to the database are submitted with a role name and an authcode. &amp;nbsp;There is a failure counting here, too, but for performance reasons there are multiple counters distributed around and they don't max out simultaneously, and the tolerated failure count for each is fairly high. &amp;nbsp;The authcodes are fairly resistant to 'social engineering' type attacks, as nobody chose them and there is little reason to remember them. &amp;nbsp;They get embedded in code, and forgotten. &lt;br /&gt;&lt;br /&gt;Two roles have authcodes, and two do not. &amp;nbsp;Other than the super role, only the auth role has an authcode.&lt;br /&gt;&lt;br /&gt;The auth role is different from the super role in that it can only run white-listed queries, and a given white-listed query can be restricted to only run for that particular role. &amp;nbsp;Since the auth role requires authentication, you can restrict its use to certain prequalified users, and give the role more Postgres privileges and its white-listed queries more power.&lt;br /&gt;&lt;br /&gt;There has always been a way to change passwords, and now there is a way to reset authcodes, meaning to replace one with a new random authcode.&lt;br /&gt;&lt;br /&gt;&lt;a href="https://www.rdbhost.com/roles.html"&gt;https://www.rdbhost.com/roles.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-3097212078436736763?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/3097212078436736763/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2011/03/post-about-authentication.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/3097212078436736763'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/3097212078436736763'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2011/03/post-about-authentication.html' title='A post about Authentication'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-3411909359876170533</id><published>2011-03-28T12:15:00.005-06:00</published><updated>2011-03-28T12:15:00.237-06:00</updated><title type='text'>More Backup Options</title><content type='html'>This week, Rdbhost has upgraded its bulk data transfer tools to be able to save the database dump to Amazon's S3 service, and to restore from same.&lt;br /&gt;&lt;br /&gt;The additions are found on the Bulk Transfer page, which is in the left-hand menu bar on most membership pages.&amp;nbsp; There is an S3 configuration page, which askes for the access-key and secret-key, and the name of the bucket to store to.&amp;nbsp; The transfer to S3&amp;nbsp;page itself will save to an object named for the account, something like 'rdbhost0000000002' for account 2.&amp;nbsp; The S3 to rdbhost transfer asks for the object name.&lt;br /&gt;&lt;br /&gt;The intended purpose for the tool is safe-keeping of snapshots of&amp;nbsp;your database, for restoration in the case of data loss, but it is also useful for transferring databases quickly from one account to another.&lt;br /&gt;&lt;br /&gt;The bulk transfer server uses streaming data flows (for all bulk transfers, not just S3), so no temporary copies of the dump are made anywhere, and the largest databases can be transferred.&amp;nbsp; The server will open up to five simultaneous transfers to accelerate the data flow to S3, so the S3 backup will presumably be faster than saving to the browser, though we have not measured the improvement.&lt;br /&gt;&lt;br /&gt;You do need an Amazon Web Services Account (see &lt;a href="http://aws.amazon.com/"&gt;aws.amazon.com&lt;/a&gt;), before you can use this streaming to S3 service, and you should create a bucket to receive the object.&amp;nbsp; We only create the object and put the data in it; the bucket must pre-exist.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;&lt;a href="https://www.rdbhost.com/bulktransfer.html"&gt;https://www.rdbhost.com/bulktransfer.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-3411909359876170533?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/3411909359876170533/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2011/03/more-backup-options.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/3411909359876170533'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/3411909359876170533'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2011/03/more-backup-options.html' title='More Backup Options'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-3094865916365673041</id><published>2011-03-03T07:05:00.006-07:00</published><updated>2011-03-03T07:05:00.425-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Rdbadmin'/><title type='text'>Update for RdbAdmin</title><content type='html'>The RdbAdmin utility has been updated. &amp;nbsp;This is the 3rd major revision, and adds quite a few nice features.&lt;br /&gt;&lt;br /&gt;New features:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Supports use of back and forward buttons within the app. &amp;nbsp;This was implemented using the sammy.js library.&lt;/li&gt;&lt;li&gt;Breadcrumb display to assist navigation.&lt;/li&gt;&lt;li&gt;New Function editor&lt;/li&gt;&lt;li&gt;New Trigger editor, linked from the table structure page.&lt;/li&gt;&lt;li&gt;Record Editing forms now include table and column comments; when adding or editing a record, you can see how the table owner described each field.&lt;/li&gt;&lt;li&gt;Record editing now supports a null checkbox for making value NULL.&lt;/li&gt;&lt;li&gt;Most forms (all except SQL-command) support dynamic display of SQL generated. &amp;nbsp;As you fill in the form, you can see what SQL RdbAdmin will generate to change the database when you submit the form.&lt;/li&gt;&lt;li&gt;Most forms have an edit option, so that dynamically generated SQL can be edited in the SQL-command form. &amp;nbsp;So if you need your query to include options not provided by the form, you can 'rough-in' the necessary query using the form, and fine-tune it by editing in the SQL-command form prior to submitting.&lt;/li&gt;&lt;li&gt;Most forms have an 'add query to lookup.queries' link that will display the record-insert form, with the dynamic SQL from the previous form pre-loaded into the record form. &amp;nbsp;When you have a query perfected and tested, you can add it to the lookup.queries table in one step. &amp;nbsp;The lookup.queries table enables your script to execute queries by keyword, and invoke queries using roles that cannot execute free-form queries directly.&lt;/li&gt;&lt;li&gt;In various forms interface now enables and disables buttons depending on relevance.&lt;/li&gt;&lt;li&gt;The '** keep same **' option in record-edit type lists is now gone, replaced by relevant custom type name.&lt;/li&gt;&lt;li&gt;In select panel, records are editable whenever a suitable index is available to uniquely identify unique records.&lt;/li&gt;&lt;li&gt;You cannot see this, but most classes have been refactored to make private attributes genuinely private, and minimize the number of global variables.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Todo:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Restore syntax highlighting; Previously, it previously used CodeMirror, but I had intermittent problems with code dependencies not getting defined.&lt;/li&gt;&lt;li&gt;Add type editing tool, for creating and modifying custom types.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Links:&lt;br /&gt;&lt;a href="https://github.com/rdbhost/Rdbadmin"&gt;Github repository&lt;/a&gt;&lt;br /&gt;&lt;a href="https://www.rdbhost.com/rdbadmin/?r0000000002#/"&gt;Sample Account&lt;/a&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/2417324817603252106-3094865916365673041?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/3094865916365673041/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2011/03/update-for-rdbadmin.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/3094865916365673041'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/3094865916365673041'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2011/03/update-for-rdbadmin.html' title='Update for RdbAdmin'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-6532454882330087096</id><published>2011-01-12T08:49:00.004-07:00</published><updated>2011-03-01T19:09:54.335-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Javascript'/><title type='text'>Welcome to the new world. HTTP Databases and JSON Storage. Quirkey</title><content type='html'>Aaron Quint (Quirkey) blogged (more than a year ago, but still very relevant) about the transforming of web architecture. &lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Welcome to the new world. HTTP Databases and JSON Storage. The simple act of making the database and the browser more powerful on either end has destroyed the need for the middle tier. In the new architecture, Our database (JSON/HTTP based ...) serves data as JSON directly to the browser. On the browser side we create a much smaller/tighter ‘controller’ layer with JavaScript. This handles the directing of the user to the right place, the displaying of the data to the user, and the conversion of user interaction into state + data. This middle piece is jQuery + Sammy.js.&lt;/blockquote&gt;&lt;br /&gt;His &lt;a href="http://www.quirkey.com/blog/2009/09/15/sammy-js-couchdb-and-the-new-web-architecture/"&gt;blog post&lt;/a&gt;&amp;nbsp;uses CouchDB and CloudKit as the server-side elements of the architecture, but his commentary on the appeal of&amp;nbsp;omitting&amp;nbsp;the whole&amp;nbsp;custom server-side layer is just as relevant to Rdbhost as to either of those.&lt;br /&gt;&lt;br /&gt;Rdbhost differs from CouchDB, in that the latter is a document database, and the former uses a relational database. &amp;nbsp;For any particular application, one will be preferable to the other. &amp;nbsp;I cannot speak to the authorization aspects of CouchDB as I have no experience with it, but several commenters on Quirkey's post had cautionary statements regarding the authentication/authorization.&lt;br /&gt;&lt;br /&gt;Rdbhost supports multiple role-permission levels, and the ability to easily control what exact queries each role can execute. &amp;nbsp;See &lt;a href="https://www.rdbhost.com/training.html"&gt;training your server&lt;/a&gt;, and &lt;a href="https://www.rdbhost.com/roles.html"&gt;roles&lt;/a&gt; pages.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-6532454882330087096?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/6532454882330087096/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2011/01/welcome-to-new-world-http-databases-and.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/6532454882330087096'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/6532454882330087096'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2011/01/welcome-to-new-world-http-databases-and.html' title='Welcome to the new world. HTTP Databases and JSON Storage. Quirkey'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-5490782479495537177</id><published>2011-01-07T09:45:00.001-07:00</published><updated>2011-01-07T09:45:00.652-07:00</updated><title type='text'>Upgrade</title><content type='html'>I sent an email to all of our account holders about three weeks ago, informing them of a planned upgrade of our back-end server from PostgreSQL 8.3 to 9.0.1.  We projected that conversion to happen the week after Christmas; that is now last week.&lt;br /&gt;&lt;br /&gt;It didn't happen, because other stuff took longer than planned.  We are now planning for this to happen the last week of January.  That should allow time to get all the prerequisites done, and the conversion automated.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-5490782479495537177?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/5490782479495537177/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2011/01/upgrade.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/5490782479495537177'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/5490782479495537177'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2011/01/upgrade.html' title='Upgrade'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-1040939829383090055</id><published>2010-12-01T09:08:00.001-07:00</published><updated>2010-12-01T10:25:03.676-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><title type='text'>The four roles on each Rdbhost account</title><content type='html'>Rdbhost provides up to four PostgreSQL roles for each database account. &amp;nbsp;Each account has exactly one database, and the roles are associated exclusively with the database. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;NAMING&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;They are named uniformly, so that when a role, a database name, or an account id is&amp;nbsp;received&amp;nbsp;by the server, the other identifiers (roles, db names, account id) can be deduced. &amp;nbsp; The database name is the prefix 'db' followed by the account id (an integer) as a '0' left-padded 10 digit string. &amp;nbsp; The role names are 's', 'a', 'p', or 'r' followed by the same '0' padded 10 digit string.&lt;br /&gt;&lt;br /&gt;The 's' role (Super) is created with the database, and owns every object in the database, including the 'lookup' schema, if present. &amp;nbsp;The other roles are optional, created at your request via the '/mbr/role_manager' page, and their privileges are whatever you set, via SQL 'GRANT' and 'REVOKE' commands. &amp;nbsp;Below we present a guideline for how you should set privileges for each.&lt;br /&gt;&lt;br /&gt;There are important differences between the roles, though, aside from the differing privileges you grant each. &amp;nbsp;Some are permitted to submit arbitrary queries, and some are limited to&amp;nbsp;pre-authorized&amp;nbsp;queries. &amp;nbsp;Let us look at each in turn.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;ROLES&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The 's'-role, as mentioned above, is the owner of everything in the database. &amp;nbsp;The 's' is a&amp;nbsp;mnemonic&amp;nbsp;for Super, as it is the do-anything 'super' role within the database. &amp;nbsp;&amp;nbsp;An authcode must &amp;nbsp;be submitted with each query request, and that authcode is your security, to prevent unauthorized users from damaging database resources. &amp;nbsp;You do not need to create any privileges for this role, as its ownership of each resource permits any operation.&lt;/li&gt;&lt;li&gt;The 'a'-role, like the Super role, has an authcode, and that authcode must be provided with every request. &amp;nbsp;'a' is a mnemonic for Authenticated, as the authcode authenticates the requester to use this role. &amp;nbsp;This role is limited to preauthorized queries (that is, queries found in either the lookup.queries or the lookup.preauth_queries tables), so it can be restrained to only run safe queries. &amp;nbsp;The web site uses the name Auth to refer to this role.&lt;/li&gt;&lt;li&gt;The 'p' role is like the Auth role in that it only executes preauthorized queries, but is *not* authenticated. &amp;nbsp;Any query preauthorized for this role can be executed by any member of the public. &amp;nbsp;'p' is a mnemonic for Preauthorized. &amp;nbsp;(It could also be a mnemonic for Public, reflecting the unauthenticated quality, but don't confuse it with the PostgreSQL role 'public'). &amp;nbsp;Securing this role is a combination of setting role privileges and prequalifying safe queries. &amp;nbsp;For example a blog site might allow APPEND privilege to this role for the 'comments' table, so that anonymous readers of the blog can comment, and the query saved to the lookup.preauth_queries table would be written to require the user IP address to be entered into the 'comments' table to facilitate anti-spam maintenance. &amp;nbsp;The web site uses the name Preauth to refer to this role.&lt;/li&gt;&lt;li&gt;Last but not least, the 'r'-role is also *not* authenticated, and allows free-form queries. &amp;nbsp;Your only security with this role is in setting PostgreSQL privileges carefully. &amp;nbsp; Generally, you would grant SELECT privilege on tables that anonymous users need to read, and no other privilege. &amp;nbsp;'r' is a mnemonic for Reader.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;PRE-AUTHORIZED&amp;nbsp;QUERIES&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The Auth and Preauth roles may only execute queries that have been preauthorized by entering them into one of the lookup tables, lookup.queries or lookup.preauth_queries. &amp;nbsp; The first is intended for manual entry, and the second is intended for automated entry. &lt;br /&gt;&lt;br /&gt;Automated entry is done by the training mechanism. &amp;nbsp;See link below for more on that.&lt;br /&gt;&lt;br /&gt;Manual entry into the lookup.queries is done by the Super role, using either the SQL_Form or the RdbAdmin tool. &amp;nbsp;Queries in the lookup.queries table must be accessed by their tag, not by the query string itself. &amp;nbsp;Use the 'kw' request parameter rather than 'q'. &amp;nbsp;Unfortunately, the Python DB API library (Rdbhdb) at this time does not support 'kw' lookups.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;LINKS&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.rdbhost.com/roles.html"&gt;The roles&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.rdbhost.com/training.html"&gt;Training&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.rdbhost.com/lookupqueries.html"&gt;Lookup.queries&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-1040939829383090055?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/1040939829383090055/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2010/12/four-roles-on-each-rdbhost-account.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/1040939829383090055'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/1040939829383090055'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2010/12/four-roles-on-each-rdbhost-account.html' title='The four roles on each Rdbhost account'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-4006862948211646183</id><published>2010-11-28T15:12:00.000-07:00</published><updated>2010-11-28T15:12:19.068-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>Django?</title><content type='html'>I suspect that the Django ORM gets more use than either SQLObject or SQLAlchemy, just because it is part of the Django stack, included in Django installs by default. For this reason, I would like to include Rdbhost support in Django. &lt;br /&gt;&lt;br /&gt;A day plus spent in pursuit of that goal has been fruitless.  This post is a summary of my experience.&lt;br /&gt;&lt;br /&gt;Before I announce support for an ORM or framework, I try to ensure that as much as possible of the framework's tests pass with this database.  I found Django's testing tools difficult to understand and difficult to use.&lt;br /&gt;&lt;br /&gt;I started testing in an app, with 'manage.py test', until someone cued me in to the runtests.py utility; the Pip/easy_install version of Django does not include most of the test suite, so when I found out, I switched to the tarball version.&lt;br /&gt;&lt;br /&gt;Testing with runtests.py worked better, but still not great.  Firstly, it seemed to ignore the '--fastfail' switch when the failure was an exception (an Error, in testing parlance), rather than a negative result of an assertion (a Fail).  Most 'failures', for me, will be exceptions, and --fastfail should abort on them, as do unittest and py.test with the -x switch.&lt;br /&gt;&lt;br /&gt;runtests.py doesn't abort on Error, and its error message is just 'ERROR', without a test name or line number or anything.  Aborting with a ctl-C will abort the test run, but will not display the test report for prior failures.  So the only way to get a test result (with test name and stack-trace) displayed for an exception is to wait for the batch of tests to complete, which could be 20-50 tests and take upwards of 10 minutes.  This is an extremely tedious way to diagnose problems.&lt;br /&gt;&lt;br /&gt;When you do have the name of a test, like 'modeltests.aggregration.tests.BaseAggregateTestCase', and try to run it specifically, with 'runtests.py modeltests.aggregration.tests.BaseAggregateTestCase', you get an error about 'test labels' and 'app...'&lt;br /&gt;&lt;br /&gt;When I tried to runtests.py with a simple 'sqlite3' based settings file, I still got many errors, failing on 25-35% of the tests.  This casts doubt on whether the test suite itself is maintained, and it is very frustrating to try to get a component to comply with test expectations when you cannot be sure the tests aren't themselves broken.  The test runner seemed to find the json fixtures when running with the sqlite3 settings, but not with the rdbhost settings.  Why would retrieving data from a file in the distro depend on what backend was configured?&lt;br /&gt;&lt;br /&gt;The test suite looks fairly comprehensive, but without a test runner that will run specific tests in a predictable way, developing to the tests is not practical.  The Django compatibility effort here is on the shelf for a while.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-4006862948211646183?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/4006862948211646183/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2010/11/django.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/4006862948211646183'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/4006862948211646183'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2010/11/django.html' title='Django?'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-5936397829450725878</id><published>2010-11-23T09:21:00.002-07:00</published><updated>2010-11-23T09:21:00.620-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hosting'/><title type='text'>Page hosting at Rdbhost</title><content type='html'>We have long presented our service as a database hosting service, providing data querying for applications hosted somewhere else.&lt;br /&gt;&lt;br /&gt;Now, you can host the whole thing right here. &lt;br /&gt;&lt;br /&gt;Just stuff your html and JavaScript files into database blob fields, point your domain at our server&lt;br /&gt;and register the domain name as belonging to your account here. &amp;nbsp;The registration is done from the 'Domain Alias' page, linked from the profile page.&lt;br /&gt;&lt;br /&gt;Rdbhost will interpret a plain-jane URL as identifying specific data elements, and deliver your html and JavaScript blobs as pages to your users' browsers.&lt;br /&gt;&lt;br /&gt;Setting the whole thing up involves a few steps, so it is probably not the easiest plan to develop incrementally with an Rdbhosted configuration; &amp;nbsp;instead, develop using a local server, as discussed in the &lt;a href="http://www.rdbhost.com/dns.html"&gt;DNS&lt;/a&gt; page, and move the JavaScript and html files to Postgresql field blobs for production deployment.&lt;br /&gt;&lt;br /&gt;See a discussion of the features at:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.rdbhost.com/user_domains.html"&gt;http://www.rdbhost.com/user_domains.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-5936397829450725878?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/5936397829450725878/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2010/11/page-hosting-at-rdbhost.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/5936397829450725878'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/5936397829450725878'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2010/11/page-hosting-at-rdbhost.html' title='Page hosting at Rdbhost'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-1494141926017360039</id><published>2010-11-22T09:43:00.002-07:00</published><updated>2010-11-22T09:43:00.591-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><title type='text'>Query Timing</title><content type='html'>A small change has been made to add a data element to the data returned by queries. &amp;nbsp;The change applies to both the JSON variants and XML.&lt;br /&gt;&lt;br /&gt;There is a new top-level element called 'times' which is an array of two decimal values. &amp;nbsp;The first decimal value is the duration, in seconds, of the processing the website front-end does prior to passing the query to the database back-end. The second is the duration of the database operation in the database backend.&lt;br /&gt;&lt;br /&gt;A sample excerpt for JSON:&lt;br /&gt;&lt;blockquote&gt;&lt;pre style="white-space: pre-wrap; word-wrap: break-word;"&gt;"status": [&lt;br /&gt;        "complete", &lt;br /&gt;        "OK"&lt;br /&gt;    ], &lt;br /&gt;    "times": [&lt;br /&gt;        "0.036002", &lt;br /&gt;        "0.000000"&lt;br /&gt;    ]&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;There is a third major element in the on-site processing of the query, and that is the time spent serializing the results into JSON or XML. &amp;nbsp;This time is not included in the time record, as the time array has to be populated prior to serializing.&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;You can measure the total round-trip time, yourself, from the client, but that time includes internet overhead. &amp;nbsp;These data items may be helpful in optimizing your queries.&lt;br /&gt;&lt;br /&gt;As always, comments are welcome.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-1494141926017360039?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/1494141926017360039/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2010/11/query-timing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/1494141926017360039'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/1494141926017360039'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2010/11/query-timing.html' title='Query Timing'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-9122869687427580894</id><published>2010-11-15T10:29:00.013-07:00</published><updated>2010-11-15T10:29:00.483-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='API'/><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><title type='text'>How to Train Your Database Server</title><content type='html'>Rdbhost allows SQL queries to be submitted from the browser and executed. &amp;nbsp; A cursory consideration of that model suggests security problems, in that whatever is in the browser can be manipulated, and user-generated queries can be submitted by &lt;b&gt;any&lt;/b&gt;&amp;nbsp;user using authentication information extracted from your source code.&lt;br /&gt;&lt;br /&gt;We thought of that, and provide means to authenticate individual queries and prevent execution of unapproved queries. &amp;nbsp;The Rdbhost service supports four different roles; two of them allow free-form queries, and the other two only allow pre-authorized queries. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Roles for Free-form Queries&lt;/b&gt;&lt;br /&gt;The first two, the s- (super) and r- (read) roles allow any arbitrary query to be executed. &amp;nbsp;The first is all-powerful, owning every resource in the database, and relies on an authcode (a long non-memorable password) to prevent use by arbitrary non-authorized users. &amp;nbsp;The second, the r- role, allows any query from any user, and relies on the Postgresql role privileges being set to prevent unwanted changes to the database. &amp;nbsp;Basically the r- role would have &lt;b&gt;only&lt;/b&gt;&amp;nbsp;SELECT privileges on relevant tables, allowing data to be read, but erroring on attempts to change the data. &amp;nbsp;The r- role provides the convenience of being able to change queries in your client source code without retraining the server. &amp;nbsp;Web applications, in my experience, tend to have many more read queries than write queries, both in access count and in number of distinct query strings.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Roles for Mutating Queries&lt;/b&gt;&lt;br /&gt;The other two roles allow only pre-authorized queries, and are the roles subject to &lt;b&gt;training. &amp;nbsp;&lt;/b&gt;These roles may&lt;br /&gt;submit queries with either the SQL query verbatim, or with a keyword that retrieves the SQL from a lookup table. &amp;nbsp;The query SQL itself must already be in either the keyword lookup table or in a table of pre-authorized queries. &amp;nbsp;The keyword lookup table is called 'lookup.queries' and is intended for manual entry and maintenance. &amp;nbsp;The other table is called 'lookup.preauth_queries', and is intended for automated query entry. &amp;nbsp;These two roles are prefixed with 'p' and 'a'. &amp;nbsp;'p' is a&amp;nbsp;mnemonic&amp;nbsp;for public and has no authcode, &amp;nbsp;while 'a' is a mnemonic for 'authenticated', and does have an authcode. &amp;nbsp;Most apps will use 'r-' role and 'p-' roles exclusively.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Training&lt;/b&gt;&lt;br /&gt;Queries are entered into the preauth_queries table via the training process. &amp;nbsp;The website has a page in the members area for enabling training. &amp;nbsp;Training is enabled for individual client IPs separately, so some clients can be using the table in the usual safe way, while your workstation client, registered as a trainer, is entering queries into it. &amp;nbsp; Once your workstation's IP is added to the trainers list, you can run any query from any role; when a query is&amp;nbsp;received&amp;nbsp;for a p- or a- role it is added to the preauth_queries table before executing. &amp;nbsp;So executing your apps test suite or simply exercising every feature of the app will put all necessary queries into the preauth_queries table. &amp;nbsp;You can then disable the training mode, test your app again, and release it.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Overview&lt;/b&gt;&lt;br /&gt;The general approach to application development in Javascript is:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Create an account, with its own database, on www.Rdbhost.com&lt;/li&gt;&lt;li&gt;Create necessary roles from role_manager page&lt;/li&gt;&lt;li&gt;Enable training for your workstation from training page&lt;/li&gt;&lt;li&gt;Configure your hosts file to include necessary local and Rdhost server entries&lt;/li&gt;&lt;li&gt;Run a local server; a tiny Python 8-liner will do&lt;/li&gt;&lt;li&gt;Develop your application&lt;/li&gt;&lt;li&gt;Develop your application (it's in here twice, because it's big)&lt;/li&gt;&lt;li&gt;Develop a test suite (optional)&lt;/li&gt;&lt;li&gt;Clear the preauth_queries table on the server; this removes development cruft&lt;/li&gt;&lt;li&gt;Run your test suite, or just exercise all SQL-using features of the app&lt;/li&gt;&lt;li&gt;Disable training for your workstation, from training page&lt;/li&gt;&lt;li&gt;Test application, either by test suite or manually&lt;/li&gt;&lt;li&gt;Release and distribute your app&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;A process of thirteen steps seems long, but only steps 6-8,10 and 12 are more than a few mouse-clicks worth of effort.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Related Links:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;a href="http://www.rdbhost.com/training.html"&gt;Training Page&lt;/a&gt;&lt;/li&gt;&lt;li&gt;PostgreSQL &lt;a href="http://www.rdbhost.com/roles.html"&gt;Roles&lt;/a&gt; on Rdbhost&lt;/li&gt;&lt;li&gt;Javascript &lt;a href="http://www.rdbhost.com/howjavascript.html"&gt;API module&lt;/a&gt; for Rdbhost&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Your comments are welcome, to &lt;a href="mailto:dkeeney@rdbhost.com"&gt;dkeeney@rdbhost.com&lt;/a&gt;, or in the blogspot comment facility below.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-9122869687427580894?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/9122869687427580894/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2010/11/how-to-train-your-database-server.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/9122869687427580894'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/9122869687427580894'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2010/11/how-to-train-your-database-server.html' title='How to Train Your Database Server'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-8462136814106133968</id><published>2010-10-19T09:45:00.006-06:00</published><updated>2010-10-19T13:50:30.152-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Javascript'/><title type='text'>Remote Database Access from the Browser Made Easy</title><content type='html'>You can now access Rdbhost databases from your in-browser javascript code without any special domain pre-configuration.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;jquery.rdbhost.cors.js&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;The jquery.rdbhost.cors.js library works in modern browsers only, those that support the CORS extension to HTTP. If you are building an html5'ish site, you are already constrained to modern browsers anyway, and this library may serve you very well. &lt;br /&gt;&lt;br /&gt;The API, the set of functions and methods, is the same as our other javascript library, jquery.rdbhost.js. You can switch between them by changing the script tag; the remaining code will generally still be valid. Obviously there are differences, otherwise why have two library? Read on for more detail.&lt;br /&gt;&lt;br /&gt;Since you, as a web developer, are very likely using the latest browser version, you can start using this library as a dropin. Setup an account on the www.rdbhost.com website, if you haven't already, add your development host url to the remote hosts config field on the website, add a script tag to your html page including the library, and you are in business.&lt;br /&gt;If the project develops to the point where compatibility with older browsers matters, or if you eventually need features like binary uploading that ajax does not support, you then easily swap out the jquery.rdbhost.cors.js module for the jquery.rdbhost.js module, and your code will be otherwise unchanged.&lt;br /&gt;&lt;br /&gt;Changes to the website to support this include adding the CORS compliant headers to those page requests that present 'Origin' headers, and adding a field to the account records that tracks which domains are permitted to access each account. There is a new status line on the profile page to report what domains are registered, and a new form page, 'remote_hosts', to permit changing that domain list.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Differences&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The regular library is both more capable and more hassle to setup.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Requires your domain (possibly 'local.host') to have a subdomain that points at our server.&lt;/li&gt;&lt;li&gt;Allows binary data uploads to database using file fields, as well as raw binary downloads.&lt;/li&gt;&lt;li&gt;Works in nearly all browsers in common use, including Internet Explorer 6.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;The cors library is easier to use, but has significant limits&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Domain configuration is NOT necessary&lt;/li&gt;&lt;li&gt;No binary upload, though binary downloads of database contents is still possible.&lt;/li&gt;&lt;li&gt;Requires a newer browser, Firefox 3.5+, Chrome 5+, Safari 4+, maybe Opera &lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;Links:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;Information about &lt;a href="http://www.rdbhost.com/dns.html"&gt;DNS subdomain&lt;/a&gt; configuration &amp;nbsp;&lt;/li&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;The &lt;a href="http://github.com/rdbhost/rdb.js"&gt;library&lt;/a&gt;, in Git, on github.com &amp;nbsp;&lt;/li&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;The w3c &lt;a href="http://www.w3.org/TR/cors/#ref-origin"&gt;working draft&lt;/a&gt; on CORS &amp;nbsp;&lt;/li&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;The Rdbhost Javascript &lt;a href="http://www.rdbhost.com/howjavascript.html"&gt;howto&lt;/a&gt; page. &amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-8462136814106133968?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/8462136814106133968/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2010/10/remote-database-access-from-browser.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/8462136814106133968'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/8462136814106133968'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2010/10/remote-database-access-from-browser.html' title='Remote Database Access from the Browser Made Easy'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-7754108192896042497</id><published>2010-10-12T08:06:00.003-06:00</published><updated>2010-10-12T08:06:00.477-06:00</updated><title type='text'>How does Rdbhost.com compare to other services?</title><content type='html'>I get asked, occasionally, questions along the line of 'Why should I use Rdbhost instead of a VPS?' or '... instead of Appengine?'...&lt;br /&gt;&lt;br /&gt;Now there is a page on the website that attempts to address that class of questions, at:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.rdbhost.com/comparisons.html"&gt;http://www.rdbhost.com/comparisons.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I am not going to rehash each comparison here in this blog-post, but am going to cover some generalities.&lt;br /&gt;&lt;br /&gt;Most of the competitors are variations of web hosting or web server accounts.  Each involves a fair amount of setup and custom configuration before it serves useful data.  Most involve setting up an SQL database, and then migrating the initial database tables, views and other resources to that database.  &lt;br /&gt;&lt;br /&gt;Rdbhost databases are created with JSON and XML encoding built-in.  Figuratively, ready 'out of the box', but literally 'already in the box'. Http request parsing and database querying, already in there.&lt;br /&gt;&lt;br /&gt;The SQL queries themselves, you have to write, as they are necessarily custom to the project.  What we can setup generically, we do setup.  We even provide a means to restrict specific database roles to running only pre-approved queries.&lt;br /&gt;&lt;br /&gt;There is also a cost difference, in that the hosting or server accounts charge by the month, so the minimum cost is always non-zero.  For most business developers, this would be the least concern.&lt;br /&gt;&lt;br /&gt;One competitor I looked at provided a web-service specifically limited to databases.  CloudDB seemed to use a non-standard query language, which would lock users in to their service, once the code was written.  I say 'seemed', as they have not seen fit to give me an account.  If any of you do have accounts there, I would appreciate reading a review, or at least, corrections or enhancements to what I have been able to glean from the documents.&lt;br /&gt;&lt;br /&gt;Comments are welcome, especially those that suggest competitors thay might be more of a straight-up substitute for Rdbhost.com.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-7754108192896042497?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/7754108192896042497/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2010/10/how-does-rdbhostcom-compare-to-other.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/7754108192896042497'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/7754108192896042497'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2010/10/how-does-rdbhostcom-compare-to-other.html' title='How does Rdbhost.com compare to other services?'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-2210891520252066742</id><published>2010-10-09T17:22:00.002-06:00</published><updated>2010-10-09T17:28:53.047-06:00</updated><title type='text'>Thanks to Ben Nadel</title><content type='html'>Firefox had been exhibiting an undesirable behavior on pages that used our javascript module, jquery.rdbhost.com.  The module, under Firefox, would function correctly, but never seemed to detect that data reception had completed, but would show the busy spinner and 'loading...' indicators.&lt;br /&gt;&lt;br /&gt;I googled in futility, I asked on stackoverflow, not constructively.&lt;br /&gt;&lt;br /&gt;Branko Vukelic cued me to read Ben Nadel's &lt;a href="http://www.bennadel.com/blog/1336-FireFox-Never-Stops-Loading-With-iFrame-Submission.htm"&gt;blogpost&lt;/a&gt; on just that topic, which explained why Firefox was behaving that way.  &lt;br /&gt;&lt;br /&gt;It seems that Firefox acknowledges that an iframe document was completely received only after the onload handler returns.  If the iframe is deleted from the DOM within the handler, Firefox never detects completion.  The solution Mr Nadel suggested, and which I used, is to use the javascript timer to call a deletion function to run after a brief delay.   This allows the handler to return while the iframe persists, but does not let the iframe linger around.&lt;br /&gt;&lt;br /&gt;The fix has been pushed to the github repository for &lt;a href="http://github.com/rdbhost/rdb.js"&gt;jquery.rdbhost.js&lt;/a&gt;, so feel free to grab the latest version.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-2210891520252066742?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/2210891520252066742/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2010/10/thanks-to-ben-nadel.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/2210891520252066742'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/2210891520252066742'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2010/10/thanks-to-ben-nadel.html' title='Thanks to Ben Nadel'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-782609407553086046</id><published>2010-08-29T22:35:00.009-06:00</published><updated>2011-05-10T20:32:06.700-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Javascript'/><title type='text'>jquery.rdbhost.com is out there.</title><content type='html'>&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Javascript programmers dodging that whole server-side programming thing are a market for us.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Unfortunately, until now, a JS programmer wanting to query Rdbhost databases has had to write there own low-level javascript ajax code, and do the domain pointer management... &amp;nbsp;I don't think anybody actually did all that.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Now, &lt;/b&gt;there is a module that makes accessing an Rdbhost.com database from your server easy. &amp;nbsp;You still have to set up a subdomain for your domain, to point at our server, but after that it is pretty straightforward.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A page snippet might look like:&lt;/div&gt;&lt;div&gt;&lt;pre&gt;&amp;lt;script&amp;gt;&lt;br /&gt;  $.ready( function () { &lt;br /&gt;    $.rdbhostConfig( { 'userName' : 's0000000002',&lt;br /&gt;                       'authcode' : '-' &amp;nbsp; } );  &lt;br /&gt;    $('table#big_cities').populateTable(&lt;br /&gt;         'SELECT * FROM cities WHERE population &amp;gt; 10000000');&lt;br /&gt;         // no pun intended&lt;br /&gt;  };&lt;br /&gt;&amp;lt;/script&amp;gt;;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;/pre&gt;&lt;pre&gt;&lt;/pre&gt;&lt;pre&gt;&lt;a href="https://github.com/rdbhost/Rdb.Js/blob/master/README.md"&gt;The library&lt;/a&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-782609407553086046?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/782609407553086046/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2010/08/jqueryrdbhostcom-is-out-there.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/782609407553086046'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/782609407553086046'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2010/08/jqueryrdbhostcom-is-out-there.html' title='jquery.rdbhost.com is out there.'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-5838281912743048190</id><published>2010-08-11T08:08:00.003-06:00</published><updated>2010-08-11T08:08:00.174-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Rdbadmin'/><title type='text'>New RdbAdmin Features</title><content type='html'>As I mentioned a couple days ago, the &lt;strong&gt;Rdbadmin &lt;/strong&gt;application has been revised.&amp;nbsp; The general goals of the revision was to make the app more maintainable and remove a few bugs.&lt;br /&gt;&lt;br /&gt;Specific goals were:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Access the host server via the new Rdb.js module, instead of $.ajax and custom code.&lt;/li&gt;&lt;li&gt;Make the application portable, so that it can be loaded from other servers under other domain names.&lt;/li&gt;&lt;li&gt;Move all html out of the javascript modules into the html host page itself.&amp;nbsp; This makes a css 'skin' designer's job easier, as all the html elements are there in the page&amp;nbsp;to see.&lt;/li&gt;&lt;li&gt;Move all the javascript out of the html host page, and into javascript files.&lt;/li&gt;&lt;li&gt;All javascript is to conform&amp;nbsp;to jslint expectations.&lt;/li&gt;&lt;li&gt;Minimize the number of globals. The former version included a global object for each form and a few more, with references to those globals scattered all over. &lt;/li&gt;&lt;/ol&gt;These were all accomplished, with exceptions here and there.&amp;nbsp; There is still a smidgen of login and initialization code in-line in the html file, and the javascript files still have some $('&amp;lt;option&amp;gt;') elements&amp;nbsp; here and there, so the html/js separation is not pristine.&amp;nbsp; JSlint compliance was with a custom configuration, not the default.&lt;br /&gt;&lt;br /&gt;In addition to the above items, an &lt;strong&gt;additional couple of features&lt;/strong&gt; &amp;nbsp;wer added:&lt;br /&gt;&lt;br /&gt;The table structure page now includes, in addition to the table columns and indexes, a list of constraints.&amp;nbsp; There is a new form to add or drop constraints for a table.&amp;nbsp; I also removed the 'primary key' and 'unique' columns from the table edit, as those constraints will be handled by the &lt;strong&gt;Constraints&lt;/strong&gt; form.&amp;nbsp; Eventually, they will be added back in.&lt;br /&gt;&lt;br /&gt;Also, each form now features an &lt;strong&gt;SQL display &lt;/strong&gt;box.&amp;nbsp; As the form is filled in, the app continuously generates and displays the SQL that will perform the desired action.&amp;nbsp; When filling in a create table form, for example, the SQL box will display the 'CREATE TABLE tablename...' code that will&amp;nbsp;be sent to the server to generate the table.&amp;nbsp; This might be useful to new&amp;nbsp;programmers to understand how&amp;nbsp;SQL syntax goes, and might help experienced programmers understand what&lt;em&gt;, exactly&lt;/em&gt;, the form is doing.&lt;br /&gt;&lt;br /&gt;Most forms&amp;nbsp;include an 'Edit SQL' button, which will load the displayed SQL into the SQL editor for refinement and submission to the server.&amp;nbsp; The &lt;strong&gt;PostgreSQL &lt;/strong&gt;syntax for various operations, such as creating tables, is more capable and feature-rich than the RdbAdmin interface, so for some less common requirements, you might need to drop to the SQL editor to get what you need.&lt;br /&gt;&lt;br /&gt;There is&amp;nbsp;a login page now, if none of the automated login approaches work.&amp;nbsp;&amp;nbsp; The app can be loaded with a non-authenticated role in the URL, and that role will be used for the database connection, otherwise it presents a login app, for entry of email and password.&amp;nbsp; When the app is loaded from Rdbhost itself, a cookie-based login is attempted, for users that have already logged in to Rdbhost itself.&lt;br /&gt;&lt;br /&gt;The code is at: &lt;a href="http://www.rdbhost.com/downloads/rdbadmin-0.8.zip"&gt;http://www.rdbhost.com/downloads/rdbadmin-0.8.zip&lt;/a&gt;&lt;br /&gt;The latest&amp;nbsp;code will always&amp;nbsp;be available from subversion, at: &lt;a href="http://www.assembla.com/code/rdbadmin/subversion/nodes"&gt;http://www.assembla.com/code/rdbadmin/subversion/nodes&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-5838281912743048190?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/5838281912743048190/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2010/08/new-rdbadmin-features.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/5838281912743048190'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/5838281912743048190'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2010/08/new-rdbadmin-features.html' title='New RdbAdmin Features'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-4608938295575284061</id><published>2010-08-09T09:43:00.003-06:00</published><updated>2010-08-11T07:42:36.569-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='Rdbadmin'/><title type='text'>RdbAdmin, free at last!</title><content type='html'>The &lt;strong&gt;Rdbadmin&lt;/strong&gt; database administration has a couple of purposes.&lt;br /&gt;&lt;br /&gt;Firstly, of course, it is a tool for administering &lt;strong&gt;Rdbhost&lt;/strong&gt; databases.&amp;nbsp; As an online application, it is available to all accounts immediately, without installing anything.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;Secondly, it is an example of what can be done from &lt;strong&gt;Javascript&lt;/strong&gt; to manipulate online databases.&amp;nbsp; We could have done a server-side admin script, ala PhpMysqlAdmin, but that might seem like an expression of no faith in the Rdbhost design.&amp;nbsp; If we are presenting the host as a do-anything-from-Javascript database host, shouldn't we walk the walk, and implement database tools in Javascript ourselves?&lt;br /&gt;&lt;br /&gt;Rdbadmin has, thus, always been a Javascript application, and source code has been available for the borrowing.&amp;nbsp; However, before now, it did not run on any server other than the rdbhost.com server, due to Javascript cross-site-scripting protections.&amp;nbsp; That is about to change:&amp;nbsp;&amp;nbsp;I have been, over the last month, rewriting the Rdbadmin app to use the &lt;strong&gt;Rdb.js&lt;/strong&gt; interface module, which makes it portable.&amp;nbsp; By mid-week, you will be able to check-out from subversion a version that works hosted on any* server, to access databases hosted on Rdbhost.&amp;nbsp; You&amp;nbsp;will then have a working admin script on your server, subject to your evolutionary refinements, or to just borrow working code from for your own Rdbhost-based projects.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The Rdb.js module itself will be properly released this week as well, with documentation.&amp;nbsp; It is available now, on github, but lacks documentation, and is still kindof crufty with dead code.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;* The Javascript cross-site-scripting constraints have not gone away, so you will need to be able to create (and point offsite) a new subdomain for your host server; a how-to will be in the release package.&amp;nbsp; We are also working on a CORS based approach, but that has its own limitations.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-4608938295575284061?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/4608938295575284061/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2010/08/rdbadmin-free-at-last.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/4608938295575284061'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/4608938295575284061'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2010/08/rdbadmin-free-at-last.html' title='RdbAdmin, free at last!'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-4333434569164776133</id><published>2010-07-19T08:11:00.001-06:00</published><updated>2010-07-19T08:11:00.112-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><title type='text'>Improvements to Bulk Transfer</title><content type='html'>We expected that the principle use of our bulk transfer page would be to backup databases and to restore a database from a prior backup.&lt;br /&gt;&lt;br /&gt;It is also useful for initial loading of databases, and an improvement this weekend makes that easier.&lt;br /&gt;&lt;br /&gt;When PostgreSQL dumps a database, it generally includes in the dump statements to assign each &lt;i&gt;relation&lt;/i&gt;&amp;nbsp;&amp;nbsp;to a specific role as owner. &amp;nbsp;This assumes that the same roles will be available on restore, an assumption justified by the use of dumps as backups.&lt;br /&gt;&lt;br /&gt;When a dump made elsewhere is uploaded to an &lt;b&gt;Rdbhos&lt;/b&gt;t database, the roles embedded in ALTER.. OWNER statements are generally not available, so the tables end up&amp;nbsp;inaccessible&amp;nbsp;to any of the defined roles.&lt;br /&gt;&lt;br /&gt;Now, at the end of a restore, any tables or views not owned by valid roles are given to the s-role for the account. &lt;br /&gt;&lt;br /&gt;So you can export tables owned by any role into a dump file, upload it to &lt;b&gt;Rdbhost&lt;/b&gt;, and end up with them all owned by the default role in your &lt;b&gt;Rdbhost&lt;/b&gt; account.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-4333434569164776133?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/4333434569164776133/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2010/07/improvements-to-bulk-transfer.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/4333434569164776133'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/4333434569164776133'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2010/07/improvements-to-bulk-transfer.html' title='Improvements to Bulk Transfer'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-8269904041544443608</id><published>2010-06-17T09:10:00.001-06:00</published><updated>2010-06-18T08:52:59.354-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Javascript'/><title type='text'>JSOND</title><content type='html'>In my last post, I introduced the &lt;b&gt;Rdb.js&lt;/b&gt; library, which allows making requests of an Rdbhost database, provided that the Rdbhost server has been aliased to a subdomain of your domain.&lt;br /&gt;&lt;br /&gt;The cross-site data retrieval relies on the data page containing a little executable javascript, that, when loaded into an &lt;i&gt;iframe&lt;/i&gt;, changes the &lt;i&gt;iframe&lt;/i&gt; 's &lt;i&gt;document.domain&lt;/i&gt; to a right-hand subset of the domain that then matches the main frame, similarly treated.&lt;br /&gt;&lt;br /&gt;The Rdb.js library handles all this for you, but I describe the method here in case anybody wants to create an alternate library, or modify the library. &lt;br /&gt;&lt;br /&gt;The request goes to the server using the client's domain, and with the 'format' parameter set to 'jsond'. The data returned by the server will be formatted similar to:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&amp;lt;html&amp;gt;&lt;br /&gt;&amp;lt;head&amp;gt;&lt;br /&gt;  &amp;lt;script type="text/javascript" &amp;gt;&lt;br /&gt;    window.document.domain=&lt;br /&gt;    "window.document.domain.split('.').slice(-2).join('.');"&lt;br /&gt;  &amp;lt;/script&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;&amp;lt;body&amp;gt;&lt;br /&gt;  &amp;lt;script type="text/plain"&amp;gt;&lt;br /&gt;    { ...json here... }&lt;br /&gt;  &amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;Lines 4 and 5 execute when the data is loaded into the &lt;i&gt;iframe&lt;/i&gt;, changing the &lt;i&gt;domain&lt;/i&gt;. It removes all but the rightmost two dot-delimited segments. For example, 'rdbhost.example.com' becomes 'example.com'.&lt;br /&gt;&lt;br /&gt;The calling frame also executes the &lt;i&gt;document.domain&lt;/i&gt; manipulation so the two have the same &lt;i&gt;domain&lt;/i&gt; value. The caller can then load the data from the body script container, and convert it using a JSON parser.&lt;br /&gt;&lt;br /&gt;The container is a script with type 'text/plain', as the browsers will leave the contents of such a container uninterpreted, a raw string. The body of the script tag is escaped by replacing all instances of '&amp;lt;/' with '&amp;lt;\/'. The JSON parser, or Javascript's eval, will interpret the two identically, so no unescaping is required.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-8269904041544443608?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/8269904041544443608/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2010/06/jsond.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/8269904041544443608'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/8269904041544443608'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2010/06/jsond.html' title='JSOND'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-8365173752058480735</id><published>2010-06-16T09:32:00.025-06:00</published><updated>2010-06-16T09:32:00.304-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='API'/><title type='text'>Rdb.js</title><content type='html'>&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Cross-server data transfer is one of the more problematic areas of javascript in-browser programming today. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The obstacles are designed into the browser for good pragmatic security concerns, but sometimes you have legitimate need to retrieve data from multiple servers in one page.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Using Rdbhost databases from javascript applications is one such need, and we provide a library to make access easy and reliable. The method we recommend, the method our library supports, involves some domain name server (DNS) manipulation.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I assume you are hosting under your own domain name, and that your domain registrar provides a way to configure subdomains. Just create a subdomain of your domain that points at our server. The IP address of the Rdbhost server is on your profile page.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For example:&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_YdCQDgwrFvw/TBbkAkaZUFI/AAAAAAAAAAM/4s9WIhbZ75U/s1600/domain_pic.png" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="60" src="http://4.bp.blogspot.com/_YdCQDgwrFvw/TBbkAkaZUFI/AAAAAAAAAAM/4s9WIhbZ75U/s320/domain_pic.png" width="370" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;With that done, wait a few hours for the change to propagate across the internet. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Include the javascript module 'rdb.js' in your page, by reference, and create a javascript inline sequence to initialize an SQLEngine object. Here is a code sample, and line-by-line explanation follows&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;01 var uid = 'r0000000002';&lt;br /&gt;02 var authcode = '2398473219847219834';&lt;br /&gt;03 var rdb = new SQLEngine(uid,authcode,'rdbhost');&lt;br /&gt;04 var query = 'SELECT * FROM css_data';&lt;br /&gt;05 var res = rdb.query(  {'callback' : success,&lt;br /&gt;06                        'q' : query } );&lt;br /&gt;07 function success(json) {&lt;br /&gt;08   // do something useful with data&lt;br /&gt;09   for (var i=0; i&amp;lt;json.records.rows.length; i++) {&lt;br /&gt;10     var val = json.records.rows[i];&lt;br /&gt;11     alert('engine: '+val[0]);&lt;br /&gt;12   }&lt;br /&gt;13 }&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;Lines 01 and 02 just store the necessary user id and authcode, copied from the account_manager page. &lt;br /&gt;&lt;br /&gt;Line 03 creates the SQLEngine object, which will handle making queries against the database. &lt;br /&gt;&lt;br /&gt;Lines 04-06 query the database; the function &lt;i&gt;&lt;b&gt;success&lt;/b&gt;&lt;/i&gt;&amp;nbsp;is called with a data structure containing the retrieved records.&lt;br /&gt;&lt;br /&gt;Lines 07-13 implement the &amp;nbsp;callback &lt;b&gt;&lt;i&gt;success&lt;/i&gt;&lt;/b&gt;, which simply loops over the list of rows, displaying an alert box with the value of the first field in each record.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Testing&lt;/b&gt;&lt;br /&gt;The above script can be pasted into a script element in an html page, after a script element loading the rdb.js library, and (with a valid uid/authcode combo) will function. &amp;nbsp;It does not need any supporting html, beyond the script container.&lt;br /&gt;&lt;br /&gt;The jquery plugin &lt;b&gt;DataTables&lt;/b&gt;&amp;nbsp;works very well with &lt;b&gt;Rdb.Js&lt;/b&gt;. &amp;nbsp;See examples here:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.paginaswww.com/rdb/examples/datatables_exrdb_json.html"&gt;JSON Example 1&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.paginaswww.com/rdb/examples/datatables_exrdb2_json.html"&gt;JSON Example 2&lt;/a&gt;&lt;br /&gt;&lt;!-- a href="http://www.paginaswww.com/rdb/examples/datatables_exrdb_ajax.html"&gt;JSON Example 3&lt;/a --&gt;&lt;br /&gt;&lt;br /&gt;The javascript database client code is inline in the source files, so &lt;i&gt;view-source&lt;/i&gt; will be informative.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;API&lt;/b&gt;&lt;br /&gt;The SQLEngine object has two methods intended for client use. &amp;nbsp;The &lt;b&gt;&lt;i&gt;query &lt;/i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;method, demonstrated above,&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;takes one object as a parameter, and expects at least two attributes in that object. &amp;nbsp;See the documentation&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;page on site for more specifics.&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;The other method is &lt;b&gt;&lt;i&gt;queryByForm&lt;/i&gt;, &lt;/b&gt;which takes three parameters: &amp;nbsp;the first is a string with the id of&lt;br /&gt;the source form, the second is the success callback function, and the last is an optional error callback. &amp;nbsp;This method is useful if you wish to send file-sourced data to the server; you can put file-fields in your form, and after the user has selected files, the form can be submitted using the &lt;b&gt;&lt;i&gt;queryByForm&lt;/i&gt;&lt;/b&gt; method. &amp;nbsp;The form must have a field (hidden or otherwise)&amp;nbsp;&lt;b&gt;&lt;i&gt;q &lt;/i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;for the query, and optionally &lt;/span&gt;&lt;i&gt;format&lt;/i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;, &lt;/span&gt;&lt;i&gt;arg###&lt;/i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt; and &lt;/span&gt;&lt;i&gt;argtype### &lt;/i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;fields.&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;a href="http://www.rdbhost.com/howjavascript.html"&gt;Rdb.js documentation&lt;/a&gt; &lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-8365173752058480735?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/8365173752058480735/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2010/06/rdbjs.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/8365173752058480735'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/8365173752058480735'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2010/06/rdbjs.html' title='Rdb.js'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_YdCQDgwrFvw/TBbkAkaZUFI/AAAAAAAAAAM/4s9WIhbZ75U/s72-c/domain_pic.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-943466486717045452</id><published>2010-06-09T12:55:00.003-06:00</published><updated>2010-06-14T23:09:51.763-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><title type='text'>PostgreSQL upgrade</title><content type='html'>The Postgresql server behind Rdbhost has been upgraded to the latest 8.3 maintenance release, version 8.3.11.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-943466486717045452?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/943466486717045452/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2010/06/postgresql-upgrade.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/943466486717045452'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/943466486717045452'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2010/06/postgresql-upgrade.html' title='PostgreSQL upgrade'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-5510526838417529931</id><published>2010-06-08T21:20:00.004-06:00</published><updated>2010-06-08T21:27:48.002-06:00</updated><title type='text'>YASOP</title><content type='html'>&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Our Stackoverflow data dump hosting account has been updated to include the latest data.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Take a look at:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.rdbhost.com/rdbadmin/main.html?r0000000767"&gt;Rdbhost Stackoverflow Account&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It now shows off a new custom look, designed for it  by Branko Vukelic.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Each account can now host its own css file, which is loaded by the admin script in lieu of the default. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;See this post on &lt;a href="http://rdbhost.blogspot.com/2010/05/css-skins-on-rdbhost.html"&gt;skinning&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-5510526838417529931?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/5510526838417529931/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2010/06/yasop.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/5510526838417529931'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/5510526838417529931'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2010/06/yasop.html' title='YASOP'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-7454784087399179150</id><published>2010-06-07T09:48:00.002-06:00</published><updated>2010-06-07T09:51:15.622-06:00</updated><title type='text'>Screencast is now shorter</title><content type='html'>Rdbhost's introductory (and so far, only) screencast has been slimmed down, from 8 minutes to 4 &amp;frac12;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.rdbhost.com/screencasts/introscreencast.html"&gt;http://www.rdbhost.com/screencasts/introscreencast.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Hopefully, more folks will watch, and more will finish.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-7454784087399179150?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/7454784087399179150/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2010/06/screencast-is-now-shorter.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/7454784087399179150'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/7454784087399179150'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2010/06/screencast-is-now-shorter.html' title='Screencast is now shorter'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-1702763247672449555</id><published>2010-05-21T09:16:00.007-06:00</published><updated>2010-08-09T08:03:21.126-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Rdbadmin'/><title type='text'>CSS skins on RdbAdmin</title><content type='html'>Those of you who consider our default Rdbadmin 'look' to be unattractive, can now provide your own css 'skins' for your own accounts.&lt;br /&gt;&lt;br /&gt;The admin program now checks for a query in the lookup.queries table called 'css'. If found, that query is requested and the contents used as a css style-sheet for the page. If none is found, the default stylesheet is used.&lt;br /&gt;&lt;br /&gt;Two demonstrations:&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://www.rdbhost.com/rdbadmin/main.html?r0000000767"&gt;Stackoverflow&lt;/a&gt; account now has a look suggestive of the stackoverflow site.&lt;br /&gt;A &lt;a href="http://www.rdbhost.com/rdbadmin/main.html?r0000000907"&gt;baseball data &lt;/a&gt;account has a distinctive green theme. &lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The baseball account has a logo image as part of its theme, and the theme is self-contained within the account. To accomplish this, I created a table in the lookup schema to hold the css stylesheet and the image file. I called this table 'pseudofiles', as it serves individual fields as though they were files. The css data and the image file went into separate records in the table, and the lookup.queries table gained an entry to retrieve the css, and another entry to retrieve the image file. The entries resembled:&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;tag: css&lt;/div&gt;&lt;div&gt;query: SELECT "body" FROM "lookup"."pseudofiles" WHERE "name" = 'css'&lt;/div&gt;&lt;div&gt;format: binary:text/css&lt;/div&gt;&lt;div&gt;nopermit: {} (empty set)&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;So the browser loads the rdadmin/main.html page, and embedded javascript loads the css stylesheet. The stylesheet contains a background image url, and that url includes a query for the background image. The result looks like &lt;a href="http://www.rdbhost.com/rdbadmin/main.html?r0000000907"&gt;this&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The &lt;i&gt;stackoverflow&lt;/i&gt; account uses a slightly different approach. The 'stylesheet' was a one-liner, completely embedded in the lookup.queries query.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;SELECT "@import url(http://www.freshfaves.com/css/stackoverflow.css);"&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;The real css style information is then stored in a regular file on the freshfaves.com server, and loaded by @import. This approach has the merit of keeping the true styles in a relatively easily edited format, but also the penalty of having to involve another server.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;em&gt;&lt;/em&gt;&lt;br /&gt;&lt;em&gt;&lt;/em&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;em&gt;minor grammatical and line-break editing 10 June&lt;/em&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-1702763247672449555?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/1702763247672449555/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2010/05/css-skins-on-rdbhost.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/1702763247672449555'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/1702763247672449555'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2010/05/css-skins-on-rdbhost.html' title='CSS skins on RdbAdmin'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-9049317220874643470</id><published>2010-05-07T09:29:00.002-06:00</published><updated>2010-05-16T22:36:05.855-06:00</updated><title type='text'>TechZing</title><content type='html'>&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;a href="http://techzinglive.com/"&gt;TechZing&lt;/a&gt;, a podcast by Justin Vincent and Jason Roberts, has reviewed &lt;strong&gt;Rdbhost&lt;/strong&gt; in their latest edition.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;The review was a rambling half hour of the 90 minute podcast, and was quite interesting. The principal lesson I drew from it, is that it can be difficult to clearly communicate your &lt;b&gt;USP&lt;/b&gt; (Unique Selling Proposition) for a web business.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Thank you to Mr Vincent and Mr Roberts for spending some time reviewing.  I enjoy each of your podcasts, and this one no less.&lt;br /&gt;&lt;br /&gt;&lt;p&gt;What is my &lt;b&gt;USP&lt;/b&gt;? &lt;/p&gt;&lt;p&gt; 'SQL over HTTP, demand priced' . &lt;/p&gt;&lt;p&gt; Some competitors offer the webservice (HTTP) with a proprietary query language, and others provide the SQL database without the webservice interface.  Demand pricing, with no minimum price, is not offered by any of them, that I know about.   I do not use that USP phrasing in the website anywhere, because it is just too geeky; I try to phrase the website presentation from more of a 'what good is it?' perspective.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-9049317220874643470?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/9049317220874643470/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2010/05/techzing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/9049317220874643470'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/9049317220874643470'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2010/05/techzing.html' title='TechZing'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-3500714518543174443</id><published>2010-05-03T09:40:00.002-06:00</published><updated>2010-06-14T23:11:03.285-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Rdbadmin'/><category scheme='http://www.blogger.com/atom/ns#' term='binary'/><title type='text'>Rdbadmin now supports file fields</title><content type='html'>&lt;b&gt;&lt;i&gt;Rdbadmin&lt;/i&gt;&lt;/b&gt; is our online database manipulation tool. It provides handy tools to create and edit tables, indexes, and views, but also provides for arbitrary free-form SQL (PL/pgSQL) queries.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The pages that support inserting records into tables and editing records have been enhanced to allow file uploads as field values. Any arbitrary data that you can put into a file, you can put into a database field using &lt;b&gt;&lt;i&gt;Rdbadmin&lt;/i&gt;&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The SQL panel has been enhanced similarly, in providing 8 argument fields. The SQL can include substitution parameters '%s'; these parameters are replaced, in sequence, with the values of fields 'arg000', 'arg001', etc. The field values are quoted appropriately to avoid SQL injections, and the fields can be file uploads as above.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The last improvement to report in this post is that the field in the SQL panel for entering the free-form queries now has syntax-coloring. The coloring is provided by CodeMirror and a plsql syntax file.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;As always, comments are welcome.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://marijn.haverbeke.nl/codemirror/"&gt;http://marijn.haverbeke.nl/codemirror/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-3500714518543174443?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/3500714518543174443/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2010/05/rdbadmin-now-supports-file-fields.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/3500714518543174443'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/3500714518543174443'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2010/05/rdbadmin-now-supports-file-fields.html' title='Rdbadmin now supports file fields'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-6828374135634058740</id><published>2010-04-29T08:36:00.002-06:00</published><updated>2010-06-14T23:11:03.286-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Rdbadmin'/><category scheme='http://www.blogger.com/atom/ns#' term='binary'/><title type='text'>Binary data and file fields</title><content type='html'>&lt;strong&gt;Rdbadmin&lt;/strong&gt; has been improved to easily allow binary data to be entered into table insert and update forms.&lt;br /&gt;&lt;br /&gt;Each input field in the &lt;em&gt;record-insert&lt;/em&gt; and &lt;em&gt;record-edit&lt;/em&gt; forms now has a 'file' button (which toggles to a text button), that converts the field to a file field, permitting you to upload a file to populate that field.&lt;br /&gt;&lt;br /&gt;The &lt;em&gt;record-edit&lt;/em&gt; and &lt;em&gt;record-insert&lt;/em&gt; forms are also more content-aware now, changing size to suit the field data-type; large input fields for large db fields, small for small.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-6828374135634058740?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/6828374135634058740/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2010/04/binary-data-and-file-fields.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/6828374135634058740'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/6828374135634058740'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2010/04/binary-data-and-file-fields.html' title='Binary data and file fields'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-783085875653200</id><published>2010-04-07T19:03:00.001-06:00</published><updated>2010-04-07T19:04:19.179-06:00</updated><title type='text'>Technorati Claim Code</title><content type='html'>This code BPKZ237VADQE helps Technorati verify that I own this blog, apparently.  The *rest* of you can ignore it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-783085875653200?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/783085875653200/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2010/04/technorati-claim-code.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/783085875653200'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/783085875653200'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2010/04/technorati-claim-code.html' title='Technorati Claim Code'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-3554006014382028013</id><published>2010-04-05T09:19:00.001-06:00</published><updated>2010-04-05T09:19:00.889-06:00</updated><title type='text'>YASOP: Yet another Stackoverflow Post</title><content type='html'>Our copy of the stackoverflow data-dump has been updated to the April release, containing data through March 2010.&lt;br /&gt;&lt;br /&gt;See:&lt;br /&gt;&lt;a href="https://www.rdbhost.com/rdbadmin/main.html?r0000000767"&gt;https://www.rdbhost.com/rdbadmin/main.html?r0000000767&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-3554006014382028013?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/3554006014382028013/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2010/04/yasop-yet-another-stackoverflow-post.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/3554006014382028013'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/3554006014382028013'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2010/04/yasop-yet-another-stackoverflow-post.html' title='YASOP: Yet another Stackoverflow Post'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-2186850945190266284</id><published>2010-03-30T10:48:00.002-06:00</published><updated>2010-06-14T23:11:03.286-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Rdbadmin'/><title type='text'>Rdbadmin looks much better</title><content type='html'>A couple of consultants have been working on the look of Rdbadmin lately, and it consequently looks much nicer.&lt;br /&gt;&lt;br /&gt;Ryan Foran reworked the appearance to make it more strongly resemble the rest of Rdbhost, with the purple round-cornered title panel, and similar colors otherwise.&lt;br /&gt;&lt;br /&gt;Branko Vukelic then reworked the link-buttons, so that they now look like buttons.  I recruited Branko to do some other work on the admin program, but you will have to wait to read about that.  I will tell you about it when it is pushed to the production server.&lt;br /&gt;&lt;br /&gt;So, a big thanks to Ryan and Branko.&lt;br /&gt;&lt;br /&gt;See &lt;a href="http://www.rdbhost.com/rdbadmin/main.html?r0000000767"&gt;http://www.rdbhost.com/rdbadmin/main.html?r0000000767&lt;/a&gt; , to observe the improved admin look with the stackoverflow database.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-2186850945190266284?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/2186850945190266284/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2010/03/rdbadmin-looks-much-better.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/2186850945190266284'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/2186850945190266284'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2010/03/rdbadmin-looks-much-better.html' title='Rdbadmin looks much better'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-2868575369164273888</id><published>2010-03-19T08:43:00.002-06:00</published><updated>2010-06-14T20:29:48.819-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ORM'/><title type='text'>Rdbhost module is in SQLObject trunk</title><content type='html'>The Rdbhost connection module for the Object Relational Mapper (ORM) SQLObject, is now included in the subversion trunk.  &lt;br /&gt;&lt;br /&gt;Check out (or update) the latest from:&lt;br /&gt;http://svn.colorstudy.com/SQLObject/trunk/&lt;br /&gt;&lt;br /&gt;Using your Rdbhost database via SQLOBject is done like this:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;from sqlobject import *&lt;br /&gt;&lt;br /&gt;role = 's0000000849'&lt;br /&gt;authcode = 'abc123~~~~~~~789xyz'&lt;br /&gt;sqlhub.processConnection = \&lt;br /&gt;connectionForURI('rdbhost://'+role+':'+authcode+'@www.rdbhost.com')&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-style:italic;"&gt;role&lt;/span&gt; and &lt;span style="font-style:italic;"&gt;authcode&lt;/span&gt; are found on your Rdbhost profile page after you log in.&lt;br /&gt;&lt;br /&gt;Presumably, the Rdbhost module will be in the next packaged release.  Until then, just check out HEAD from subversion to use SQLObject with Rdbhost.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-2868575369164273888?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/2868575369164273888/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2010/03/rdbhost-module-is-in-sqlobject-trunk.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/2868575369164273888'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/2868575369164273888'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2010/03/rdbhost-module-is-in-sqlobject-trunk.html' title='Rdbhost module is in SQLObject trunk'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-703471611217759799</id><published>2010-03-11T12:49:00.002-07:00</published><updated>2010-03-11T12:50:42.989-07:00</updated><title type='text'>Facebook</title><content type='html'>Rdbhost now has a modest presence on Facebook.  Created to catch the attention of any database customers who might be searching Facebook for postgresql or sql resources.&lt;br /&gt;&lt;br /&gt;May amount to nothing... don't know.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-703471611217759799?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/703471611217759799/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2010/03/facebook.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/703471611217759799'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/703471611217759799'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2010/03/facebook.html' title='Facebook'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-6381376120426497942</id><published>2010-03-10T09:56:00.010-07:00</published><updated>2010-06-14T23:09:51.764-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><title type='text'>PL/pgSQL on Rdbhost</title><content type='html'>We have added the server-hosted programming language PL/pgSQL to all Rdbhost accounts.&lt;br /&gt;&lt;br /&gt;It is enabled by default for new accounts, and can be enabled on existing accounts via the new Languages page, linked from the profile page.&lt;br /&gt;&lt;br /&gt;PL/pgSQL supports variables and conditional execution, so you can write more sophisticated queries than with straight SQL. It is now possible to write sequences of operations to be executed in one request, that formerly required multiple requests, with client side intermediate evaluations between.&lt;br /&gt;&lt;br /&gt;One example is illustrated &lt;a href="http://www.rdbhost.com/plpgsql.html"&gt;here &lt;/a&gt;. Instead of doing an &lt;em&gt;update&lt;/em&gt;, determining whether it succeeded, and conditionally doing an &lt;em&gt;insert &lt;/em&gt;in a follow-up query&lt;em&gt;,&lt;/em&gt; PL/pgSQL code can do the whole sequence on the server, and complete in one request.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.rdbhost.com/plpgsql.html"&gt;http://www.rdbhost.com/plpgsql.html&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.postgresql.org/docs/8.2/interactive/plpgsql.html"&gt;http://www.postgresql.org/docs/8.2/interactive/plpgsql.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-6381376120426497942?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/6381376120426497942/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2010/03/plpgsql-on-rdbhost.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/6381376120426497942'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/6381376120426497942'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2010/03/plpgsql-on-rdbhost.html' title='PL/pgSQL on Rdbhost'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-2792375434209664882</id><published>2010-03-06T13:10:00.002-07:00</published><updated>2010-03-06T13:36:13.124-07:00</updated><title type='text'>SO March</title><content type='html'>&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;The data from the March 2010 data dump from the Stackoverflow website is online, at:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="font-family:arial, sans-serif;font-size:100%;"&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse; font-size: 13px;"&gt;&lt;span class="Apple-style-span" style="border-collapse: separate; font-family: 'Trebuchet MS', Verdana, Arial, sans-serif; line-height: 18px; "&gt;&lt;div&gt;&lt;a href="http://www.rdbhost.com/rdbadmin/main.html?r0000000767" style="color: rgb(204, 102, 51); "&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;http://www.rdbhost.com/rdbadmin/main.html?r0000000767&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;The above link is to an online administrative program.  We also support access to the data via&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;a &lt;a href="http://www.rdbhost.com/howpython.html"&gt;DP API&lt;/a&gt; module, at:  http://www.rdbhost.com/howpython.html , and the API module supports ORMs, including &lt;a href="http://www.rdbhost.com/orms.html"&gt;SQLObject and SQLAlchemy&lt;/a&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Comments are welcome.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-2792375434209664882?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/2792375434209664882/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2010/03/so-march.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/2792375434209664882'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/2792375434209664882'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2010/03/so-march.html' title='SO March'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-4201960794320390811</id><published>2010-02-16T14:37:00.003-07:00</published><updated>2010-02-16T14:40:07.350-07:00</updated><title type='text'>Rdbhost on twitter</title><content type='html'>We are not really active on twitter, basically just letting twitterfeed create tweets based on blog posts here, but...&lt;br /&gt;&lt;br /&gt;if you keep up with things via twitter rather than a blog-reader, then you can get announcements of new blogposts here from our twitter feed.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.twitter.com/rdbhost"&gt;www.twitter.com/rdbhost&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-4201960794320390811?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/4201960794320390811/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2010/02/rdbhost-on-twitter.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/4201960794320390811'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/4201960794320390811'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2010/02/rdbhost-on-twitter.html' title='Rdbhost on twitter'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-9222741973064304048</id><published>2010-02-16T14:22:00.003-07:00</published><updated>2010-02-16T14:28:07.505-07:00</updated><title type='text'>RdbHost on ProgrammableWeb blog</title><content type='html'>We got a mention on ProgrammableWeb.com, in their API News page.  Thanks, PW!!&lt;br /&gt;&lt;br /&gt;See:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://blog.programmableweb.com/2010/02/14/5-new-apis-iphone-payments-photo-and-video-sharing-hosted-sql-and-silverlight-apps/"&gt;5 new APIs&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-9222741973064304048?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/9222741973064304048/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2010/02/rdbhost-on-programmableweb-blog.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/9222741973064304048'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/9222741973064304048'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2010/02/rdbhost-on-programmableweb-blog.html' title='RdbHost on ProgrammableWeb blog'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-2873045763054813456</id><published>2010-02-13T14:04:00.007-07:00</published><updated>2010-06-14T20:30:04.704-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ORM'/><title type='text'>SQLAlchemy and the Stackoverflow Data Dump</title><content type='html'>&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;We recently wrote an rdbhost module for SQLAlchemy (SQLA), allowing you to use Rdbhost databases through SQLAlchemy.  It was mentioned in this blog about a month ago,&lt;a href="http://rdbhost.blogspot.com/2010/01/sqlalchemy-and-rdbhost.html"&gt; here&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In the last couple of days I uploaded the February Stackoverflow data dump to our SO database here (account 767), and placed an announcement on &lt;a href="http://meta.stackoverflow.com/questions/39354/stackoverflow-data-dump-feb-version-available-on-rdbhost"&gt;meta.SO&lt;/a&gt;, including a mention of the DB API module.  If you are an SQLAlchemy fan, and wish to explore the SO data via SQLAlchemy, this post will help get you started.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;You do need SQLAlchemy installed, and it is installable from easy_install, or manually from a &lt;a href="http://www.sqlalchemy.org/download.html"&gt;downloaded&lt;/a&gt; copy.  You need the &lt;a href="http://code.assembla.com/rdbmisc/subversion/nodes/ORMs/SqlAlchemy/SQLAlchemy-0.5.6/lib/sqlalchemy/databases/rdbhost.py"&gt;rdbhost-module&lt;/a&gt;, as well, placed in the databases folder within your SQLAlchemy install.  SQLA will find it there.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Example:&lt;/b&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;Python 2.5.4 (r254:67916, Dec 23 2008, 15:10:54) [MSC v.1310 32 bit (Intel)] on win32&lt;br /&gt;IDLE 1.2.4  &lt;br /&gt;&gt;&gt;&gt; from sqlalchemy import *&lt;br /&gt;&gt;&gt;&gt; role = 'r0000000767'&lt;br /&gt;&gt;&gt;&gt; authcode = '-'&lt;br /&gt;&gt;&gt;&gt; dsn = 'rdbhost://'+role+':'+authcode+'@www.rdbhost.com'&lt;br /&gt;&gt;&gt;&gt; db = create_engine(dsn)&lt;br /&gt;&gt;&gt;&gt; meta = MetaData(db)&lt;br /&gt;&gt;&gt;&gt; meta.reflect(schema='so')&lt;br /&gt;... elided warnings from sqlalchemy about partial indexes ...&lt;br /&gt;&gt;&gt;&gt; for t in meta.tables:&lt;br /&gt;....  print t&lt;br /&gt;&lt;br /&gt;so.posts&lt;br /&gt;so.badges&lt;br /&gt;so.tags&lt;br /&gt;so.users&lt;br /&gt;so.votes&lt;br /&gt;so.comments&lt;br /&gt;so.tagging&lt;br /&gt;&gt;&gt;&gt; posts = meta.tables['so.posts']&lt;br /&gt;&gt;&gt;&gt; print posts.columns&lt;br /&gt;['posts.id', 'posts.type', 'posts.parentid', 'posts.title', &lt;br /&gt;'posts.creation', 'posts.owner', 'posts.accepted_answer', &lt;br /&gt;'posts.score', 'posts.viewcount', 'posts.body',  &lt;br /&gt;'posts.lasteditor', 'posts.lasteditorname', &lt;br /&gt;'posts.lasteditdate', 'posts.lastactivitydate', &lt;br /&gt;'posts.communityowneddate', 'posts.closeddate', &lt;br /&gt;'posts.tags', 'posts.answercount',  &lt;br /&gt;'posts.commentcount', 'posts.favoritecount']&lt;br /&gt;&gt;&gt;&gt; from sqlalchemy import select&lt;br /&gt;&gt;&gt;&gt; users = meta.tables['so.users']&lt;br /&gt;&gt;&gt;&gt; s = select([users],users.c.reputation &gt; 100000,limit=50)&lt;br /&gt;&gt;&gt;&gt; recs = db.execute(s)&lt;br /&gt;&gt;&gt;&gt; for user in recs:&lt;br /&gt;.... print user.name, user.reputation&lt;br /&gt;&lt;br /&gt;Marc Gravell 109683&lt;br /&gt;Jon Skeet 134930&lt;br /&gt;&gt;&gt;&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-2873045763054813456?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/2873045763054813456/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2010/02/sqlalchemy-and-stackoverflow-data-dump.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/2873045763054813456'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/2873045763054813456'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2010/02/sqlalchemy-and-stackoverflow-data-dump.html' title='SQLAlchemy and the Stackoverflow Data Dump'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-6223285860319643471</id><published>2010-02-12T06:59:00.003-07:00</published><updated>2010-02-12T09:41:09.704-07:00</updated><title type='text'>Bulk Data Transfer to/from Rdbhost</title><content type='html'>An upgrade to the server recently added the ability to upload and download data in bulk.&lt;br /&gt;&lt;br /&gt;Downloading works very similarly to &lt;em&gt;pg_dump&lt;/em&gt;, providing any of the three formats that &lt;em&gt;pg_dump&lt;/em&gt; supports.&lt;br /&gt;&lt;br /&gt;a) &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;plaintext&lt;/span&gt;&lt;br /&gt;b) tar file&lt;br /&gt;c) compressed format&lt;br /&gt;&lt;br /&gt;Uploading works like &lt;em&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;psql&lt;/span&gt;&lt;/em&gt; for &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;plaintext&lt;/span&gt;, and &lt;em&gt;pg_restore &lt;/em&gt;for the other two formats. In fact, the server feeds the input to those two utilities behind the scenes, so the results you get are exactly the same as if you were to use the utility directly.  If you are uploading, drop in advance any existing tables that are in the upload, as the upload does not drop them for you.&lt;br /&gt;&lt;br /&gt;The bulk transfer page is linked from the profile page, after logging in.&lt;br /&gt;&lt;br /&gt;The upload streams the data to &lt;strong&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;PostgreSQL&lt;/span&gt;&lt;/strong&gt;, so processing starts when the upload starts; if you cancel the upload (by closing the browser window, for example) partway done, you will likely leave the database in an incomplete state. Remember to &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;reclean&lt;/span&gt; the database before retrying the upload.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-6223285860319643471?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/6223285860319643471/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2010/02/bulk-data-transfer-tofrom-rdbhost.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/6223285860319643471'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/6223285860319643471'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2010/02/bulk-data-transfer-tofrom-rdbhost.html' title='Bulk Data Transfer to/from Rdbhost'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-4797656049908364144</id><published>2010-01-29T08:04:00.002-07:00</published><updated>2010-01-29T08:07:11.133-07:00</updated><title type='text'>Rdbhost API on ProgrammableWeb</title><content type='html'>We are now listed in the APIs section of ProgrammableWeb!&lt;br /&gt;&lt;br /&gt;This is a very cool event, as PW has a fairly high profile on the web, and should bring us more traffic and hopefully a few more ambitious developers.&lt;br /&gt;&lt;br /&gt;See: &lt;a href="http://www.programmableweb.com/api/rdbhost"&gt;http://www.programmableweb.com/api/rdbhost&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-4797656049908364144?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/4797656049908364144/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2010/01/rdbhost-api-on-programmableweb.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/4797656049908364144'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/4797656049908364144'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2010/01/rdbhost-api-on-programmableweb.html' title='Rdbhost API on ProgrammableWeb'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-4075883425808851245</id><published>2010-01-06T08:23:00.002-07:00</published><updated>2010-06-14T20:29:33.715-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ORM'/><title type='text'>SQLAlchemy and Rdbhost</title><content type='html'>SQLAlchemy is an ORM, an object relational mapper.    To some folks, that is a very meaningful phrase.  To me, it is just another way to programmatically access SQL databases.&lt;br /&gt;&lt;br /&gt;This week, I created a module to facilitate using Rdbhost databases from SQLAlchemy.  See it documented on: &lt;a href="http://www.rdbhost.com/orms.html"&gt;http://www.rdbhost.com/orms.html&lt;/a&gt; .   We provide one file, aptly called 'rdbhost.py' which you add to your SQLAlchemy's 'database' directory, and SQLAlchemy will then use it to open and access databases hosted on www.rdbhost.com.&lt;br /&gt;&lt;br /&gt;When you call the create_engine function, you give it a &lt;span style="font-style: italic;"&gt;connect string&lt;/span&gt; like: 'rdhbost://role:authcode@www.rdbhost.com' .&lt;br /&gt;&lt;br /&gt;Once you have the engine object, thus created, you can create, drop, and query tables using the SQLAlchemy/Python syntax.&lt;br /&gt;&lt;br /&gt;Here is an excerpt:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;from &lt;span class="il"&gt;sqlalchemy&lt;/span&gt; import *&lt;br /&gt;role = 's0000000849'&lt;br /&gt;authcode = 'h.89as9fa9dsaf.~~~~~~~~~~kajd8098ajsf'&lt;br /&gt;dsn = 'rdbhost://'+role+':'+authcode+'@www.rdbhost.com'&lt;br /&gt;db = create_engine(dsn)&lt;br /&gt;&lt;br /&gt;metadata = MetaData()&lt;br /&gt;users = Table('Users', metadata,&lt;br /&gt;... Column('id', Integer, primary_key=True),&lt;br /&gt;... Column('name', String),&lt;br /&gt;... Column('fullname', String),&lt;br /&gt;... )&lt;br /&gt;addresses = Table('addresses', metadata,&lt;br /&gt;... Column('id', Integer, primary_key=True),&lt;br /&gt;... Column(&lt;a href="http://user.id/" target="_blank"&gt;user.id&lt;/a&gt;', None, ForeignKey('&lt;a href="http://users.id/" target="_blank"&gt;users.id&lt;/a&gt;')),&lt;br /&gt;... Column('email_address', String, nullable=False)&lt;br /&gt;... )&lt;br /&gt;metadata.create_all(db)&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-4075883425808851245?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/4075883425808851245/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2010/01/sqlalchemy-and-rdbhost.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/4075883425808851245'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/4075883425808851245'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2010/01/sqlalchemy-and-rdbhost.html' title='SQLAlchemy and Rdbhost'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-1609402527034175164</id><published>2010-01-05T08:01:00.004-07:00</published><updated>2010-06-14T20:34:37.329-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='API'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>Rdbhdb 0.9.2</title><content type='html'>I've been working lately on making &lt;span style="font-weight: bold;"&gt;Rdbhost&lt;/span&gt; work better with ORMs, such as SQLObject and SQLAlchemy.  One outcome of that effort is improvements to &lt;span style="font-weight: bold;"&gt;Rdbhdb&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;A new release is out, version 0.9.2 with a couple of new features:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Fields fetched are now converted into datetime.Date, datetime.Time, datetime.Datetime, and decimal.Decimal objects, depending on type. &lt;br /&gt;&lt;/li&gt;&lt;li&gt;Times and Timestamps now have microsecond resolution.&lt;/li&gt;&lt;li&gt;Parameters provided to .execute* calls are now typed, so the server can return each data item, as necessary, in the appropriate type.&lt;/li&gt;&lt;/ul&gt;The module is available from here, or from PyPI.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.rdbhost.com/downloads/rdbhdb-0.9.1.zip"&gt;&lt;span style="text-decoration: underline;"&gt;http://www.rdbhost.com/downloads/rdbhdb-0.9.2.zip&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://pypi.python.org/pypi/rdbhdb/0.9.2"&gt;http://pypi.python.org/pypi/rdbhdb/0.9.2&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-1609402527034175164?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/1609402527034175164/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2010/01/rdbhdb-092.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/1609402527034175164'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/1609402527034175164'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2010/01/rdbhdb-092.html' title='Rdbhdb 0.9.2'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-1119554832609871018</id><published>2010-01-04T21:24:00.002-07:00</published><updated>2010-01-04T21:24:00.500-07:00</updated><title type='text'>Server update</title><content type='html'>&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The server software was updated yesterday.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The changes are:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;The /db app recognizes data-type arguments, named like 'arg###type', and having values from ( 'NONE'  'STRING' 'NUMBER' 'DATETIME' 'ROWID' 'BINARY' 'DATE' 'TIME').  The type argument describes the argument with the same prefix; 'arg001type' describes 'arg001'.  The type can be omitted, and defaults to STRING.   &lt;/li&gt;&lt;li&gt;JSON date format now includes microseconds.  Dates are just strings, like: '2009-12-31 12:59:00.000000.&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The Rdbhdb DB API module has been updated to use these features.  Expect it on PyPI soon, and a post here.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-1119554832609871018?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/1119554832609871018/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2010/01/server-update.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/1119554832609871018'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/1119554832609871018'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2010/01/server-update.html' title='Server update'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-8589871646009624934</id><published>2009-12-22T17:15:00.008-07:00</published><updated>2009-12-22T18:43:06.926-07:00</updated><title type='text'>The lookup schema and 'borrowed' privilege</title><content type='html'>In an &lt;a href="http://rdbhost.blogspot.com/2009/12/sudo-and-sql.html"&gt;earlier post&lt;/a&gt;, I discussed the need &lt;b&gt;Rdbhost&lt;/b&gt; has for a &lt;i&gt;sudo&lt;/i&gt; type function, where a lower privileged role can 'borrow' greater privilege for specific limited functionality.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What has been implemented (read on) can be used to that effect, but is not implemented quite that way.  Instead, we created additional roles (with and without authentication) that are restricted to running predefined queries only.  You can do most querying using a low privilege role (typically the &lt;i&gt;Reader&lt;/i&gt; role), and then adopt one of these new roles to do predefined operations that require higher privilege.  Because these roles are restricted to certain queries, they can be granted greater PostgreSQL privileges safely.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The two roles are &lt;i&gt;Auth&lt;/i&gt; and &lt;i&gt;Public&lt;/i&gt;, written like 'a0000000878' and 'p0000000878', incorporating the account id.  &lt;i&gt;Auth&lt;/i&gt; requires an authcode, and &lt;i&gt;Public&lt;/i&gt; does not.  They are both restricted, in that either one can &lt;b&gt;only &lt;/b&gt;run queries from the &lt;i&gt;lookup.queries&lt;/i&gt; table.  The roles can be created from the /mbr/role_manager page, and when you create one, the &lt;i&gt;lookup&lt;/i&gt; schema and the &lt;i&gt;queries&lt;/i&gt; table are both created for you.  Add records to them using your &lt;i&gt;Super&lt;/i&gt; role; the &lt;i&gt;&lt;b&gt;Rdbadmin&lt;/b&gt;&lt;/i&gt; utility can be useful here.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Queries in the &lt;i&gt;lookup.queries &lt;/i&gt;table are invoked just like free-form queries, except that a 'kw' parameter is provided in lieu of a 'q' parameter.  The 'kw' parameter value has the tag name for the desired query.  If there are any substitution tokens in the looked-up query, there must be a corresponding number of 'arg###' parameters.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There are now four roles defined for each account.  They are &lt;i&gt;Super&lt;/i&gt;, &lt;i&gt;Reader&lt;/i&gt;, &lt;i&gt;Auth&lt;/i&gt;, and &lt;i&gt;Public&lt;/i&gt;.  The first two can run arbitrary free-form queries against the database, in addition to the predefined lookup queries.  Typically, the &lt;i&gt;Reader&lt;/i&gt; role would have very restrictive permissions to protect the database, and the &lt;i&gt;Super&lt;/i&gt; role would only be used by the account owner.  The &lt;i&gt;Auth&lt;/i&gt; and &lt;i&gt;Super &lt;/i&gt;roles are authenticated, requiring an authcode to be submitted with the request.  The &lt;i&gt;Reader &lt;/i&gt;and &lt;i&gt;Public &lt;/i&gt;roles are not authenticated.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;An example of a lookup query, taken from www.Freshfaves.com, is:&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;br /&gt;tag: update&lt;/pre&gt;&lt;pre&gt;query: UPDATE faves f SET f.link = %s&lt;br /&gt;   WHERE f.id = %s&lt;br /&gt;     AND f.acctid IN (SELECT id FROM accounts WHERE key = %s)&lt;/pre&gt;&lt;/blockquote&gt;The role used, &lt;i&gt;Public,&lt;/i&gt; has privilege to UPDATE the faves table.  But because the &lt;i&gt;Public &lt;/i&gt;role can only execute queries from the &lt;i&gt;lookup.queries&lt;/i&gt; table, the only updating the user can do is the query above, and that only changes a record if the key value matches.  That is, the only records updateable are those for the account with the provided key.  The table is safe from malicious or accidental changes to other users' accounts.  The query above is invoked using a a javascript code sequence like the following (the example uses jQuery):&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;div&gt;var dbUrl = 'http://www.rdbhost.com/db/p0000000878?callback=?';&lt;/div&gt;&lt;div&gt;$.getJSON(dbUrl,&lt;/div&gt;&lt;div&gt;      {kw:'update', arg000:link, arg001:id, arg002:key},&lt;/div&gt;&lt;div&gt;      function(d) {&lt;/div&gt;&lt;div&gt;        alert('account updated');&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;   &lt;/span&gt;};&lt;/div&gt;&lt;div&gt;);&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;div&gt;The Freshfaves application just predefines all queries, but it could have defined the &lt;i&gt;Reader &lt;/i&gt;role and done free-form queries with it.&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;div&gt;var dbUrl = 'http://www.rdbhost.com/db/p0000000878?callback=?';&lt;/div&gt;&lt;div&gt;$.getJSON(dbUrl,&lt;/div&gt;&lt;div&gt;     {q:'SELECT * FROM faves WHERE id = %s', arg000:faveid},&lt;/div&gt;&lt;div&gt;     function(d) {&lt;/div&gt;&lt;div&gt;       // code here to handle data retrieved&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt;   &lt;/span&gt;};&lt;/div&gt;&lt;div&gt;);&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt; Between free-form queries on one unprivileged role, and predefined queries only on the other role, an application can manipulate databases as necessary without embedding any role authentication into the javascript.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Related Reading&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Rdbhost &lt;a href="http://www.rdbhost.com/roles.html"&gt;Roles&lt;/a&gt; page&lt;/div&gt;&lt;div&gt;Rdbhost &lt;a href="http://www.rdbhost.com/lookupqueries.html"&gt;Lookup&lt;/a&gt; page&lt;/div&gt;&lt;div&gt;&lt;div&gt;The &lt;a href="http://www.freshfaves.com/"&gt;FreshFaves&lt;/a&gt; website&lt;/div&gt;&lt;div&gt;&lt;div&gt;FreshFaves &lt;a href="http://www.freshfaves.com/downloads/freshfaves.0.7.zip"&gt;source code&lt;/a&gt; .zip&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-8589871646009624934?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/8589871646009624934/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2009/12/lookup-schema-and-borrowed-privilege.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/8589871646009624934'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/8589871646009624934'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2009/12/lookup-schema-and-borrowed-privilege.html' title='The &lt;i&gt;lookup&lt;/i&gt; schema and &apos;borrowed&apos; privilege'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-8659748687610435717</id><published>2009-12-22T13:48:00.002-07:00</published><updated>2010-06-14T23:09:51.764-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><title type='text'>Postgresql upgrade</title><content type='html'>&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The &lt;b&gt;Postgresql&lt;/b&gt; server behind &lt;b&gt;Rdbhost&lt;/b&gt; has been upgraded to the latest 8.3 maintenance release, version 8.3.8.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-8659748687610435717?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/8659748687610435717/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2009/12/postgresql-upgrade.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/8659748687610435717'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/8659748687610435717'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2009/12/postgresql-upgrade.html' title='Postgresql upgrade'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-5661705169105960865</id><published>2009-12-22T12:25:00.005-07:00</published><updated>2009-12-22T12:50:28.115-07:00</updated><title type='text'>Freshfaves: perishable bookmarks</title><content type='html'>&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Fresh Faves&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.freshfaves.com"&gt;Freshfaves&lt;/a&gt; is an online bookmarking tool that features perishable bookmarks.  Add pages to your bookmark list using a bookmarklet in your favorites/bookmarks list.  The bookmarks are kept there for following later, and when a bookmark goes 30 days without being clicked, it gets dropped from the bookmarks page.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Hence, a clutter-free bookmark list.  It is useful for keeping bookmarks that are of only temporary use, or are of uncertain usefulness.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Bookmarks of temporary value include shopping list type bookmarks, tracking a product option until you decide where to buy; once the purchase is done, the bookmarks lose their usefulness.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If you find a page is of uncertain value, you can bookmark it here; if you never find time to follow up, or if it proves on the first couple visits to not be worth keeping, it will go unvisited and drop off the list in time.  If such a link &lt;i&gt;does &lt;/i&gt;prove to be of value, we make it one-click easy to copy it to your accounts on other (more permanent) bookmarking sites.  Of course, we also provide a delete function to remove it immediately, if you so choose.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There are no login accounts or passwords; the authentication information is in the bookmarklet itself.  We do make it easy to email that bookmarklet to yourself (for safe-keeping) or a friend (for sharing).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;&lt;b&gt;Rdbhost&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;This service is implemented using &lt;b&gt;Rdbhost&lt;/b&gt;, of course.   I used the JSONP data format, as it allows making cross-site requests (in this case, from www.freshfaves.com to www.rdbhost.com).  It does not permit POST mode requests, but for this low-security application, that is ok.  I am working on an AJAX-Rdbhost toolkit to make cross-site requests straightforward in any mode, and that will be announced here in its time.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The source code is available in a zip file, &lt;a href="http://www.freshfaves.com/downloads/freshfaves.0.7.zip"&gt;here&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/2417324817603252106-5661705169105960865?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/5661705169105960865/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2009/12/freshfaves-perishable-bookmarks.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/5661705169105960865'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/5661705169105960865'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2009/12/freshfaves-perishable-bookmarks.html' title='Freshfaves: perishable bookmarks'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-6626742077494853935</id><published>2009-12-14T18:01:00.004-07:00</published><updated>2009-12-15T18:34:39.084-07:00</updated><title type='text'>Sudo and SQL</title><content type='html'>&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Rdbhost databases can be queried from Javascript applications.  Aside from the cross-site-scripting safeties, there is one major design obstacle to hosting your javascript applications data here.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;PostgreSQL provides the ability to setup multiple roles, but generally you do not want to create a new role for each web user.  Most web users are anonymous, in fact, and could not be correlated with a particular role.  Generally, for a web application,  you would set up a small number of PostgreSQL roles, and then provide additional programming layers to authenticate users and allow each only appropriate operations on the database.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Unfortunately, for a Javascript application hosted on Rdbhost, you would have to embed the Postgres role password (authcode)  in the javascript, in order to provide it to the server with each SQL request.  Even if you did not distribute it with the javascript app, but retrieved it dynamically conditional on the user entering a passphrase, say, it would still be in the javascript temporarily.  If the client were provided the authcode temporarily, for some legitimate purpose (say, to add themself to, or remove themself from,  a members table), you could not prevent them from submitting that authcode with different SQL later, perhaps malicious SQL.   If you were to provide them a role and authcode to remove their records from a table, you could not prevent them from removing others records as well.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now, there are useful javascript apps that can be written to work safely under these constraints.  For example a blog application could allow anonymous users to use a role that permits INSERT and SELECT on the comments table.  The blogger himself or herself would use a super role that permits everything, but the anonymous web user would be able to add comments.  That much can be controlled via PostgreSQL roles privileges.  Many apps, though, need a more refined security model.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Unix and its kin have long had a tool called &lt;b&gt;&lt;i&gt;sudo&lt;/i&gt;&lt;/b&gt;.   &lt;b&gt;&lt;i&gt;Sudo &lt;/i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;allows a user to run specific commands using the privileges of another user.  The specific commands to be permitted must be listed, in advance, by a user with greater privilege.&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Rdbhost needs a feature akin to &lt;i&gt;&lt;b&gt;sudo &lt;/b&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;for use by javascript programmers.  The programmer can configure the necessary queries that can be run, what role (privileges) they will run as, and who can be permitted to run them.  Then the javascript app can use a low privilege role for most purposes, and then use the &lt;b&gt;&lt;i&gt;sudo&lt;/i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;ish feature to do higher privilege operations that are predefined to operate safely.  A javascript programmer can write a javascript application that is widely distributed and widely studied, and use a hosted shared database for application data, without exposing that database to malice.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Comments welcome.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-6626742077494853935?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/6626742077494853935/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2009/12/sudo-and-sql.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/6626742077494853935'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/6626742077494853935'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2009/12/sudo-and-sql.html' title='Sudo and SQL'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-8920932781511444666</id><published>2009-12-04T17:29:00.003-07:00</published><updated>2010-06-14T20:35:55.599-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='API'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>Rdbhdb 0.9.1</title><content type='html'>The DB API module, Rdbhdb, has been re-released.  Only two changes in this version:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;https (TLS) is used by default.&lt;/li&gt;&lt;li&gt;A bug causing incompatility with Python 2.4 was fixed.  2.4 does not have an 'any' builtin,  so the module provisionally provides one.&lt;/li&gt;&lt;/ol&gt;Available here or from Pypi.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.rdbhost.com/downloads/rdbhdb-0.9.1.zip"&gt;&lt;span style="text-decoration: underline;"&gt;http://www.rdbhost.com/downloads/rdbhdb-0.9.1.zip&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://pypi.python.org/pypi/rdbhdb/0.9.1"&gt;http://pypi.python.org/pypi/rdbhdb/0.9.1&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-8920932781511444666?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/8920932781511444666/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2009/12/rdbhdb-091.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/8920932781511444666'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/8920932781511444666'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2009/12/rdbhdb-091.html' title='Rdbhdb 0.9.1'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-1961327226896618257</id><published>2009-11-23T22:07:00.007-07:00</published><updated>2010-06-14T23:11:03.286-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Rdbadmin'/><title type='text'>More changes to Rdbadmin and Rdbhost</title><content type='html'>&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;A few recent improvements to Rdbadmin:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Main page shows tables and fields. &lt;/li&gt;&lt;li&gt;New section of left-hand menu shows schemas.&lt;/li&gt;&lt;li&gt;Menu options create and rename schemas.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Improvements to Rdbhost:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Login page (and login link from front page) is https.&lt;/li&gt;&lt;li&gt;Login cookie is 'secure' so will not be available to non-https pages.&lt;/li&gt;&lt;li&gt;Attempting to access another account while logged into yours will result in an error.  You must log out of your account to access any other.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-1961327226896618257?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/1961327226896618257/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2009/11/more-changes-to-rdbadmin-and-rdbhost.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/1961327226896618257'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/1961327226896618257'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2009/11/more-changes-to-rdbadmin-and-rdbhost.html' title='More changes to Rdbadmin and Rdbhost'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-2291746528881775033</id><published>2009-11-18T19:34:00.006-07:00</published><updated>2010-06-14T23:11:03.287-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Rdbadmin'/><title type='text'>Improvements to Rdbadmin program</title><content type='html'>&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Rdbhost sports its own admin utility, &lt;b&gt;&lt;i&gt;Rdbadmin, &lt;/i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;implemented in Javascript.  It is useful to create and remove tables and views, adding and deleting data from tables, and performing queries.&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;i&gt;Rdbadmin &lt;/i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;has been upgraded, with both new features and bug fixes.&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;New features include:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Table and view lists are sorted.&lt;/li&gt;&lt;li&gt;Tables and views can belong to schemas other than &lt;i&gt;public&lt;/i&gt;.  This will become more important with upcoming features.&lt;/li&gt;&lt;li&gt;New feature to set field defaults on tables.&lt;/li&gt;&lt;li&gt;HTML content is now escaped, so that it reads as the tags themselves, and the data inline formats cannot interfere with the display table structure.&lt;/li&gt;&lt;li&gt;In the select page, query data values are parameterized, so the data values cannot be misinterpreted by the SQL engine as statements.&lt;/li&gt;&lt;li&gt;The login and logout functionality has been removed.  Logging in is done via the www.rdbhost.com front page (or the www.rdbhost.com login page), and logging out from the profile page.  The admin script gets role and authcode from the rdhost member cookie, and just bounces the user to the login page if member cookie is missing.  The 'guest_account' functionality is still present, where the 'r'-role can be provided on the url.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;As always, the admin program is linked from the profile page.  As always, your questions and criticisms are welcome.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-2291746528881775033?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/2291746528881775033/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2009/11/improvements-to-rdbadmin-program.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/2291746528881775033'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/2291746528881775033'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2009/11/improvements-to-rdbadmin-program.html' title='Improvements to Rdbadmin program'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-7979137116496145092</id><published>2009-11-14T21:28:00.005-07:00</published><updated>2009-11-14T22:25:02.178-07:00</updated><title type='text'>Guest usage of Rdbhost accounts</title><content type='html'>There is a handy way to provide other people read-only access to your Rdbhost database.&lt;br /&gt;&lt;br /&gt;If you have enabled the 'r'-role, and given it reasonable (ie: only SELECT) permissions on the tables, you can allow other people to access your database using that role.&lt;br /&gt;&lt;br /&gt;Just use the url for the rdbadmin page, and append the 'r'-role name to the url, with a '?'. &lt;br /&gt;&lt;br /&gt;For example, our stackoverflow database is account 'db0000000767', and the 'r' role has been enabled and GRANTed appropriate privileges.  The guest usage url is thus:&lt;br /&gt;http://www.rdbhost.com/rdbadmin/main.html?r0000000767 .&lt;br /&gt;&lt;br /&gt;Try it &lt;a href="http://www.rdbhost.com/rdbadmin/main.html?r0000000767"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;There is no way to provide an &lt;span style="font-style: italic;"&gt;authcode&lt;/span&gt; with the rolename, so it will not work for 's'-roles.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-7979137116496145092?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/7979137116496145092/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2009/11/guest-usage-of-rdbhost-accounts.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/7979137116496145092'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/7979137116496145092'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2009/11/guest-usage-of-rdbhost-accounts.html' title='Guest usage of Rdbhost accounts'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-6637885479715160474</id><published>2009-11-09T19:16:00.003-07:00</published><updated>2009-11-09T19:22:46.097-07:00</updated><title type='text'>YASOP: Yet another Stackoverflow post</title><content type='html'>&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The latest data dump from Stackoverflow has been placed in our stackoverflow account&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;See: &lt;a href="http://www.rdbhost.com/rdbadmin/main.html?r0000000767"&gt;http://www.rdbhost.com/rdbadmin/main.html?r0000000767&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I was just reading some old stuff on meta.stackoverflow.com about hosting a publicly query-able copy of the dump, with reporting or graphing options.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This account (at the above url) provides the data, with the flexible querying of SQL, Google's Appengine provides some charting tools, and our Rdbhdb module provides a DB API type interface for accessing the data from GAE.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Have fun.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.rdbhost.com"&gt;Rdbhost.com&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://code.google.com/appengine/"&gt;Google Appengine&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.rdbhost.com/downloads/rdbhdb-0.9.zip"&gt;Rdbhdb DB API module&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-6637885479715160474?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/6637885479715160474/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2009/11/yasop-yet-another-stackoverflow-post.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/6637885479715160474'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/6637885479715160474'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2009/11/yasop-yet-another-stackoverflow-post.html' title='YASOP: Yet another Stackoverflow post'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-8975361724441010772</id><published>2009-10-26T10:19:00.011-06:00</published><updated>2010-06-14T20:36:37.313-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='API'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>Rdbhdb v 0.9</title><content type='html'>A new version of &lt;strong&gt;&lt;em&gt;Rdbhdb&lt;/em&gt;&lt;/strong&gt; is available from Pypi.  &lt;em&gt;Rdbhdb&lt;/em&gt; is the DB API 2.0 module for accessing Rdbhost databases remotely from Python applications.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://pypi.python.org/pypi/rdbhdb/0.9"&gt;Rdbhdb v 0.9 download page on PyPI&lt;/a&gt;&lt;div&gt;&lt;a href="http://www.rdbhost.com/downloads.html"&gt;Rdbhdb v 0.9 download page on Rdbhost&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;New in this version:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Uses gzip decompression, optionally, for data downloads from server.&lt;/li&gt;&lt;li&gt;Supports the sending of binary data (as buffer datatype) in query parameters.&lt;/li&gt;&lt;li&gt;.execute_deferred() method provided to execute queries in deferred mode. Deferred mode does not return results, but allows a more generous time limit for query completion. Useful for updates or inserts that might need extra time.&lt;/li&gt;&lt;li&gt;.nextset() method implemented on cursors. Multiple queries can be aggregated into a single .execute() call, delimited by ';'. One result set is returned for each query, and .nextset() advances to the next result set in the returned list.&lt;/li&gt;&lt;li&gt;.https attribute added to connection, to force use of SSL. Defaults to False, no SSL.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;This version is the one currently in use on &lt;a href="http://rdbhost.appspot.com/"&gt;rdbhost.appspot.com&lt;/a&gt;, for its monitoring function.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;Edited 28 Oct 09: Added rdbhost hosted download link.&lt;/blockquote&gt;&lt;blockquote&gt;Edited 9 Nov 09: Spelled PyPI properly&lt;/blockquote&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-8975361724441010772?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/8975361724441010772/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2009/10/rdbhdb-v-09.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/8975361724441010772'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/8975361724441010772'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2009/10/rdbhdb-v-09.html' title='Rdbhdb v 0.9'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-552717650010464198</id><published>2009-10-26T10:16:00.003-06:00</published><updated>2009-10-27T20:11:17.979-06:00</updated><title type='text'>SSL Downtime</title><content type='html'>I was told yesterday by a site user that &lt;a href="http://www.rdbhost.com/"&gt;www.rdbhost.com's&lt;/a&gt; SSL certificate was expired.&lt;br /&gt;&lt;br /&gt;For the moment, the secure site of &lt;a href="http://www.rdbhost.com/"&gt;www.rdbhost.com&lt;/a&gt; is down, and will be back up later today when I have time to get the certificate updated and installed.&lt;br /&gt;&lt;br /&gt;David Keeney&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;blockquote&gt;As of 8PM on Tuesday, SSL is back up and working.&lt;/blockquote&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-552717650010464198?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/552717650010464198/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2009/10/ssl-downtime.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/552717650010464198'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/552717650010464198'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2009/10/ssl-downtime.html' title='SSL Downtime'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-8299746848263606358</id><published>2009-10-23T17:15:00.013-06:00</published><updated>2009-10-28T22:02:42.940-06:00</updated><title type='text'>User side testing and Twill</title><content type='html'>&lt;b&gt;History&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;RdbHost has two faces: one that the human user sees, and one that their software sees. The software side, the 'web service' has always had good testing. That it was designed to be computer parse-able without screen-scraping meant it was easy to write automated tests for it. There are in fact two sets of web service tests, one that uses urllib2 to query directly, and another that tests the DB API module &lt;em&gt;Rdbhdb&lt;/em&gt; by using it to query the server.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;div&gt;&lt;b&gt;Website Testing&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;Until recently, the human-readable (aka the web site) side of the business was not tested in any automated way. I would test features I thought might be affected by a change, manually, after an update. I am not sharing any details, but that strategy has proven to be deficient. Now we have a test suite for the user side as well.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Twill&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The software used for the new tests is &lt;em&gt;Twill&lt;/em&gt;. Twill can be run as its own scriptable shell, or included as a python module and the functions called from python. The Twill python module has an instantiated object syntax, where you create a browser object and call methods on it. Unfortunately, the browser object does not support the 'show' method. I ended up giving up on the explicit browser object, and just used the implicit browser. It works well, but doesn't satisfy my 'explicit code is more comfortable' preference.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://twill.idyll.org/"&gt;Twill&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Tests and Email &lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;Many features of the website use email for various authentication functions. To reset your password, the site emails a password reset-link. To change your email address of record, you have the site email a change link to the new address. Creating a new account involves emailing the initial login password to the submitted address. How does one test such a system with Python and Twill? &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="FONT-WEIGHT: normal"&gt;My solution was to use one of the spam-dodging sites that allow one to receive email anonymously. Just email to 'anyname@spamspot.com' and spamspot.com will post the email content to a blog style web page, intermingled chronologically with other user's emails. The test code can request an email, for whatever functionality being tested, give the site a spamspot.com email address to mail to, wait a few seconds for the email to arrive and be posted, and then use Python and Twill to request the spamspot page and parse out the rdbhost email and its embedded password or links using 're' module. It is appropriate (if also a little paranoid) to change the password shortly thereafter to minimize tampering by other readers of spamspot.&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There are many anonymous email receiver websites. Spamspot.com (mentioned above) and Makemeaking.com are more useful for our purposes than some, because they include the email inline to the page, without requiring another link-following step, and the prerequisite link parsing step.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://spamspot.com/"&gt;Spamspot.com&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://makemetheking.com/"&gt;Makemetheking.com&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="FONT-WEIGHT: normal"&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;Edited 24 Oct 09: added reference to Makemetheking.com &lt;/div&gt;&lt;div&gt;Edited 26 Oct 09: minor grammatical corrections&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-8299746848263606358?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/8299746848263606358/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2009/10/user-side-testing-and-twill.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/8299746848263606358'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/8299746848263606358'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2009/10/user-side-testing-and-twill.html' title='User side testing and Twill'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-811114833057803738</id><published>2009-09-25T12:54:00.011-06:00</published><updated>2009-09-26T08:33:27.670-06:00</updated><title type='text'>Multiple Recordsets</title><content type='html'>It can be very useful to put multiple queries into one web-service request.  You get multiple query responses, and only suffer the request overhead for one request.&lt;br /&gt;&lt;br /&gt;Rdbhost now supports returning multiple record sets for one request.&lt;br /&gt;&lt;br /&gt;If you have multiple Postgresql statements in your request 'q' param, delimited by ';', each is processed in sequence, and the results for each are added to the list of record sets.  Instead of one group in the results called 'records', you have an outer group called 'result_sets', and a group within that for each statement.  The details differ between the json, json-easy, xml, and xml-easy formats, but the above description applies to each.&lt;br /&gt;&lt;br /&gt;json format for multiple result-sets looks like:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;br /&gt;{    &lt;br /&gt;    "status": [&lt;br /&gt;        "complete", &lt;br /&gt;        "OK"&lt;br /&gt;    ],&lt;br /&gt;    "result_sets": [&lt;br /&gt;        {&lt;br /&gt;            "status": [&lt;br /&gt;                "complete", &lt;br /&gt;                "OK"&lt;br /&gt;            ],&lt;br /&gt;            "records": {&lt;br /&gt;                "header": {&lt;br /&gt;                    "id": 23&lt;br /&gt;                }, &lt;br /&gt;                "rows": [&lt;br /&gt;                    {&lt;br /&gt;                        "id": 1&lt;br /&gt;                    }&lt;br /&gt;                ]&lt;br /&gt;            }, &lt;br /&gt;            "row_count": [&lt;br /&gt;                1, &lt;br /&gt;                "1 Rows Affected"&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;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;for comparison, the single recordset variant looks like:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;br /&gt;{&lt;br /&gt;    "status": [&lt;br /&gt;        "complete", &lt;br /&gt;        "OK"&lt;br /&gt;    ],&lt;br /&gt;    "records": {&lt;br /&gt;        "header": {&lt;br /&gt;            "id": 23&lt;br /&gt;        }, &lt;br /&gt;        "rows": [&lt;br /&gt;            {&lt;br /&gt;                "id": 1&lt;br /&gt;            }&lt;br /&gt;        ]&lt;br /&gt;    }, &lt;br /&gt;    "row_count": [&lt;br /&gt;        1, &lt;br /&gt;        "1 Rows Affected"&lt;br /&gt;    ]&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;The single result-set variant puts the count, status, and records all in the root.  &lt;br /&gt;&lt;br /&gt;The multiple result-set variant puts creates a result-set group, containing count, status, and records, for each statement in the request.  There is also one status element in the root, and if the status is 'error', there will be no result sets.&lt;br /&gt;&lt;br /&gt;The xml formats have similar layout:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;xml xmlns="http://www.rdbhost.com/xml.html"&amp;gt;&lt;br /&gt;  &amp;lt;status value="complete"&amp;gt;OK&amp;lt;/status&amp;gt;&lt;br /&gt;  &amp;lt;result_sets&amp;gt;&lt;br /&gt;    &amp;lt;result_set&amp;gt;&lt;br /&gt;      &amp;lt;row_count value="1"&amp;gt;1 Rows Affected&amp;lt;/row_count&amp;gt;&lt;br /&gt;      &amp;lt;status value="complete"/&amp;gt;&lt;br /&gt;      &amp;lt;records&amp;gt;&lt;br /&gt;        &amp;lt;header&amp;gt;&lt;br /&gt;          &amp;lt;fld type="23"&amp;gt;id&amp;lt;/fld&amp;gt;&lt;br /&gt;        &amp;lt;/header&amp;gt;&lt;br /&gt;        &amp;lt;rec&amp;gt;&lt;br /&gt;          &amp;lt;fld&amp;gt;1&amp;lt;/fld&amp;gt;&lt;br /&gt;        &amp;lt;/rec&amp;gt;&lt;br /&gt;      &amp;lt;/records&amp;gt;&lt;br /&gt;    &amp;lt;/result_set&amp;gt;&lt;br /&gt;    &amp;lt;result_set&amp;gt;&lt;br /&gt;    ...&lt;br /&gt;    &amp;lt;/result_set&amp;gt;&lt;br /&gt;  &amp;lt;/result_sets&amp;gt;&lt;br /&gt;&amp;lt;/xml&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;The xml formats have a 'result_sets' container element, and multiple 'result_set' container elements within that.&lt;br /&gt;&lt;br /&gt;The service is free; you can learn more about it by registering for an account, reading the online documentation, and experimenting.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.rdbhost.com"&gt;http://www.rdbhost.com&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-811114833057803738?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/811114833057803738/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2009/09/multiple-recordsets.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/811114833057803738'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/811114833057803738'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2009/09/multiple-recordsets.html' title='Multiple Recordsets'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-6636412579355952020</id><published>2009-09-07T12:51:00.000-06:00</published><updated>2009-09-07T12:59:53.408-06:00</updated><title type='text'>Stackoverflow Data</title><content type='html'>&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The stackoverflow database account here has been updated to include the September data dump.  That includes cumulative data up to 31 August.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A fairly complete set of indexes was added to the basic tables.  Long text fields, like message bodies, do not benefit much from ordinary indexes, because you rarely search on the whole content, and the key content is not necessarily at the beginning of the field, where an index would accelerate access.  So the short fields are indexed, large text fields are not.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now, full text indexing might be useful, but the typical use case is to find posts on a given topic, and just searching the stackoverflow site using its on-site search, or Googling, would be more generally useful.  Full text searches in Postgresql involve, optimally, a non-standard functions that normalize the search terms; it gets better results than a straight keyword search, but involves a learning curve.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Maybe queries like 'how many posts about python have scores over 100?' would be useful, but that can be approximated by querying on tags joined to posts via tagging. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I hope the database is useful.  Let me know if you have any comments or complaints.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The stackoverflow database is at:&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.rdbhost.com/rdbadmin/main.html?r0000000767"&gt;http://www.rdbhost.com/rdbadmin/main.html?r0000000767&lt;/a&gt;&lt;/div&gt;&lt;div&gt;Just login with the default login and no password.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;David&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-6636412579355952020?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/6636412579355952020/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2009/09/stackoverflow-data.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/6636412579355952020'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/6636412579355952020'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2009/09/stackoverflow-data.html' title='Stackoverflow Data'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-3012770652401765584</id><published>2009-09-02T11:21:00.000-06:00</published><updated>2009-09-03T19:27:43.631-06:00</updated><title type='text'>UserTesting</title><content type='html'>I gave a try to the usability testing website, &lt;a href="http://www.usertesting.com/"&gt;UserTesting.com&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I paid around $70 for three tests. The first test occurred within 24 hours, and the others 3 days later. Each lasted 10 - 25 minutes.  UserTesting sets up their testers with screencast type software, and with the software is recording their session, they are talking about their thought process doing the task assigned.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Rdbhost.com&lt;/span&gt; is a site for programmers, to support programming efforts.  I did not think I could create a reasonable 15 minute task that involved creating a program, so I described a simple database operations task; create an account, create a table, put some data in it.  I required the testers already have some SQL programming knowledge.  Despite the task being tangential to our core purpose, the tests were informative, if also humbling.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;Some observations of the testers&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;All accomplished the basic task, despite some inefficiencies. Each fell back on typing SQL into the sql box for data entry, despite the existence of a form to do that function. The SQL box is there as a do-anything catchall, of course, and it did serve that purpose.&lt;br /&gt;&lt;br /&gt;One tester 'cheated' by visiting the site and looking at internal pages before starting the recording session. (link color betrayed him).  All offered subjective commentary beyond narrating their problem solving process.  The subjective criticism bothered me a bit, until I decided to just filter it out and focus on the observations.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;Observations by the testers&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;Rdbadmin javascript 'button' links did not look like buttons. Testers worked all around the 'new item' link, because it looked like a subtitle, rather than a link. I admit, my own tinkering with the page format a few days prior had busted the link display, and I had not noticed.&lt;br /&gt;&lt;br /&gt;The profile page was not intuitive, and while all three found their way to the Rdbadmin, only one did so quickly.  Only one of the three actually read help pages, despite their prominent link placement.&lt;br /&gt;&lt;br /&gt;The general look of the site got some knocking, getting called a 'spoof site', 'dated', and 'powerpoint slide'.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Outcome&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I have fixed the obvious problems, making the admin links look, again, like links, and adding description to the profile page links.  I have some notes for a more pervasive redesign, in time, but the quick fixes improved the usability quite a bit.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.usertesting.com/"&gt;UserTesting.com&lt;/a&gt; gets a recommendation from me.  The whole system is slick, with very useful screencasts delivered for each tester, as well as summary analysis in prose.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-3012770652401765584?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/3012770652401765584/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2009/09/usertesting.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/3012770652401765584'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/3012770652401765584'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2009/09/usertesting.html' title='UserTesting'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-4992283202532311041</id><published>2009-08-28T23:44:00.000-06:00</published><updated>2009-08-29T10:29:26.472-06:00</updated><title type='text'>JsonP</title><content type='html'>&lt;div&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Rdbhost.com now provides &lt;a href="http://bob.pythonmac.org/archives/2005/12/05/remote-json-jsonp/"&gt;JSONP&lt;/a&gt; as a format option.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;JSONP allows data to be requested from a site different from that of the referencing page.  You can put a page on your domain somewhere, and retrieve data from www.rdbhost.com using a cross-site request and the JSONP format.&lt;/div&gt;&lt;br /&gt;Let us look at a very simple example.  &lt;b&gt;Rdbhost&lt;/b&gt; maintains a table of performance statistics (on itself, about itself) in a table 'stats' in account db000000005 .  We will query that table from our page for a count of records.  The entire example page is 11 lines:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;br /&gt;01 &amp;lt;html&amp;gt;&lt;br /&gt;02 &amp;lt;body&amp;gt;&lt;br /&gt;03    Count of records in 'stats':   &amp;lt;span id="count"&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;04    &amp;lt;script&amp;gt;&lt;br /&gt;05   function showct(data){&lt;br /&gt;06      document.getElementById("count").innerHTML = data['records']['rows'][0]["count"];&lt;br /&gt;07   };&lt;br /&gt;08   &amp;lt;/script&amp;gt;&lt;br /&gt;09   &amp;lt;script src="http://www.rdbhost.com/db/r0000000005?q=SELECT%20count(*)%20from%20stats&amp;amp;callback=showct"&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;10 &amp;lt;/body&amp;gt;&lt;br /&gt;11 &amp;lt;/html&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;Lines 01 to 03 are just html to show the count when we get it.  Lines 05 to 07 are a javascript function to process the count data after receiving it, and line 09 is the actual request.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Line 09 is a script tag: it retrieves the page at the url identified in 'src', and processes it as a script.  The '&lt;i&gt;callback&lt;/i&gt;' parameter indicates the name to 'wrap' around the data, and implies the request needs JSONP output format. The content received is this:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;br /&gt;showct({&lt;br /&gt;  "records": {&lt;br /&gt;    "header": {&lt;br /&gt;               "count": 20&lt;br /&gt;              },&lt;br /&gt;    "rows": [&lt;br /&gt;             {&lt;br /&gt;               "count": "5456"&lt;br /&gt;             }&lt;br /&gt;            ]&lt;br /&gt;  },&lt;br /&gt;  "row_count": [&lt;br /&gt;                1,&lt;br /&gt;                "1 Rows Affected"&lt;br /&gt;               ],&lt;br /&gt;  "status": [&lt;br /&gt;              "complete",&lt;br /&gt;              "OK"&lt;br /&gt;            ]&lt;br /&gt;})&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;When this is processed as a script, the 'showct(...)' is interpreted as a function call, and executed.  The function had been defined in lines 05 to 07, and just extracted the 'count' element of the JSON and put it in the HTML element 'count', for display.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This page works cross-site, so you could host such a page on your site, under your domain, and retrieve records from rdbhost.com dynamically.  If you prefer &lt;b&gt;jQuery&lt;/b&gt;, you can retrieve JSONP content using the .getJSON function, including a 'callback' parameter in the url to retrieve.  Using &lt;b&gt;jQuery&lt;/b&gt; has the virtue that you do not need a named callback function, as &lt;b&gt;jQuery &lt;/b&gt;will allow its typical anonymous callbacks even with JSONP.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Limitations:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Requests use 'GET' mode, not 'POST', so any authentication information would be there in the link for users to read.&lt;/li&gt;&lt;li&gt;Rdbhost does not permit authcodes to be passed in GET requests, for security reasons.  JSONP usage is thus only useful for queries using the 'r' role, with no authentication.  To query your own account, you would need to enable the 'r' role from the profile page, and probably GRANT it some SELECT privileges on tables in the account, using &lt;b&gt;rdbadmin&lt;/b&gt; or the &lt;b&gt;SQL_form&lt;/b&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;Example pages can be found at the following links.  Use view source to see the internals.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.paginaswww.com/jsonp_demo.html"&gt;Script tag approach&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;a href="http://www.paginaswww.com/jsonp_jq_demo.html"&gt;jQuery approach&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The request urls can easily get long enough to be unwieldy.   These two pages demonstrate a technique for putting the url in a javascript variable, where it can be line-wrapped.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The Rdbhost website itself is at: &lt;a href="http://www.rdbhost.com/"&gt;http://www.rdbhost.com&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-4992283202532311041?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/4992283202532311041/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2009/08/jsonp.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/4992283202532311041'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/4992283202532311041'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2009/08/jsonp.html' title='JsonP'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-8705622451028536452</id><published>2009-08-10T22:20:00.000-06:00</published><updated>2009-08-11T10:22:07.902-06:00</updated><title type='text'>Stackoverflow Data</title><content type='html'>&lt;a href="http://www.stackoverflow.com/"&gt;Stackoverflow.com&lt;/a&gt;, in case you haven't heard of it, is a very popular question and answer site for programmers.&lt;br /&gt;&lt;br /&gt;It was developed by &lt;a href="http://www.codinghorror.com/"&gt;Jeff Atwood&lt;/a&gt; and &lt;a href="http://www.joelonsoftware.com/"&gt;Joel Spoelski&lt;/a&gt;, both well known bloggers on technology, and they produce an entertaining podcast on the development of stackoverflow.com and (more or less) related computer topics.&lt;br /&gt;&lt;br /&gt;Anyway, to get to the point, the data at stackoverflow is all user generated, and licensed under &lt;a href="http://blog.stackoverflow.com/2009/06/stack-overflow-creative-commons-data-dump/"&gt;Creative Commons&lt;/a&gt;. They release, about once a month, an xml dump of all the data, in a big archived file. The release includes all posts and all comments, and some user profile data.&lt;br /&gt;&lt;br /&gt;With some pro-active assistance from &lt;a href="http://www.bortzmeyer.org/stackoverflow-to-postgresql.html"&gt;Stéphane Bortzmeyer&lt;/a&gt;, I have imported the data from the August dump into an &lt;b&gt;Rdbhost&lt;/b&gt; database and made it available to anonymous users, with SELECT privilege only (no changes to data permitted).  The database engine behind the &lt;strong&gt;Rdbhost&lt;/strong&gt; webservice is Postgresql.&lt;br /&gt;&lt;br /&gt;The database is at: &lt;a href="http://www.rdbhost.com/rdbadmin/main.html?r0000000767"&gt;www.rdbhost.com/rdbadmin/main.html?r0000000767&lt;/a&gt;&lt;br /&gt;Just click the login button; no authentication is required. The SQL admin software is a work-alike to &lt;a href="http://www.adminer.org/"&gt;Adminer&lt;/a&gt; (formerly phpMinAdmin), implemented in javascript.&lt;br /&gt;&lt;br /&gt;Hopefully, the table and field names make sense and their meanings can be inferred. If you find the indexes to be insufficient for your purposes, email me or put a comment on this blog entry. There is a 3 second query duration limit, so any query needing a full-table scan on any of the larger tables will likely fail.&lt;br /&gt;&lt;br /&gt;Have fun.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Edited:  Added mention of Postgresql and made a few grammar/punctuation corrections.&lt;br /&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-8705622451028536452?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/8705622451028536452/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2009/08/stackoverflow-data.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/8705622451028536452'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/8705622451028536452'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2009/08/stackoverflow-data.html' title='Stackoverflow Data'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-1983254852561161461</id><published>2009-08-03T10:31:00.005-06:00</published><updated>2010-09-22T07:12:12.559-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='binary'/><title type='text'>Binary Content</title><content type='html'>&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;&lt;b&gt;Formats&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style=" ;font-size:18px;"&gt;&lt;/span&gt;The usual approach to using rdbhost is to request records, consisting of multiple fields, and that record data is incorporated into a structured &lt;b&gt;JSON&lt;/b&gt; or &lt;b&gt;XML&lt;/b&gt; page and delivered to requesting client. The client can then disassemble the structure to extract the data for use. Those &lt;b&gt;JSON&lt;/b&gt; or &lt;b&gt;XML&lt;/b&gt; formatted pages are text, and non-text data gets encoded/escaped to make it fit a textual structure.&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;/span&gt;&lt;br /&gt;Sometimes, though, you just want the raw data, without textual escaping. This would be useful for an image database, for example.  You would like to just send the binary image data to the browser or other client, and have it processed without any text-binary decoding.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;b&gt;Binary Format&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The &lt;em&gt;'binary'&lt;/em&gt; format does just this. If your request calls for a binary format, using the format parameter, all the fields of all the records of the output are just catenated together and the resulting blob is sent to the client. I would expect the typical use is querying for one field of one record, but if you have need to aggregate multiple fields together, it will do that. The data to be queried this way should generally be stored in &lt;em&gt;bytea&lt;/em&gt; fields; &lt;em&gt;bytea&lt;/em&gt; fields are delivered as-is, others are &lt;em&gt;utf-8&lt;/em&gt; decoded and non-decodable characters are escaped.&lt;br /&gt;&lt;br /&gt;When you request binary format, the format parameter value can have content-type appended to it, delimited by a colon; for example &lt;em&gt;"format=binary:image/jpeg"&lt;/em&gt; would result in the query data being sent as a binary blob, and with a &lt;em&gt;'content-type: image/jpeg'&lt;/em&gt; header line.  If you are delivering the binary content directly to a browser, the &lt;i&gt;content-type &lt;/i&gt;is very helpful to the browser in rendering the object correctly.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;b&gt;Inserting Binary Data into Database&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Getting the binary data into the database is its own problem. Our sql_form supports http file uploads of binary data. Put the binary data in a file, and upload it through the form, and it will be processed by the server as binary. Unless you put it into a &lt;em&gt;bytea&lt;/em&gt; field, it will be &lt;em&gt;utf-8&lt;/em&gt; encoded going into the table, and will be &lt;em&gt;utf-8&lt;/em&gt; decoded when delivered in response to a SELECT. The Python &lt;b&gt;DB API&lt;/b&gt; module does not, today, support binary uploads, but that is planned for the next version. In the meantime, the &lt;b&gt;PostgreSQL&lt;/b&gt; &lt;em&gt;decode(...,'base64')&lt;/em&gt; function can be used to put binary data into a field, but you would need a client side base64 encoder to pre-encode the data.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;b&gt;Sample Page&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;A sample page can be viewed &lt;a href="http://dev.rdbhost.com/db/r0000000763?q=select+data+from+d+where+tag%3d%27page%27&amp;amp;format=binary:text/html" format="'binary:text/html" tag="page"&gt;here&lt;/a&gt;. The full url is below, and it incorporates the account and the query all into the query string. The page itself is delivered in response to a database query, and the embedded image comes from another database query.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://dev.rdbhost.com/db/r0000000763?q"&gt;http://dev.rdbhost.com/db/r0000000763?q=select+data+from+d+where+tag%3d%27page%27&amp;amp;format=binary:text/html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;That page was created using the sql_form form linked from the profile page, with &lt;b&gt;SQL&lt;/b&gt; INSERTs and the file upload feature.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;David&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;17 May 2010&lt;/div&gt;&lt;div&gt;Updated to correct url.&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-1983254852561161461?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/1983254852561161461/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2009/08/binary-content.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/1983254852561161461'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/1983254852561161461'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2009/08/binary-content.html' title='Binary Content'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-5150818988636208457</id><published>2009-07-22T12:00:00.000-06:00</published><updated>2009-07-23T15:25:57.130-06:00</updated><title type='text'>Parts is parts</title><content type='html'>&lt;div&gt;&lt;br /&gt;&lt;b&gt;Rdbhost&lt;/b&gt; is a thin wrapper around the &lt;b&gt;Postgresql&lt;/b&gt; database engine (8.3.7). The web server receives the request, authenticates the requester, and provides the query to the database engine. The results of the query are then converted to &lt;strong&gt;XML&lt;/strong&gt; or &lt;strong&gt;JSON&lt;/strong&gt; and sent to the requester.&lt;br /&gt;&lt;br /&gt;Query results are formatted as &lt;strong&gt;XML&lt;/strong&gt; or &lt;strong&gt;JSON&lt;/strong&gt;, which are generated using the excellent Python libraries &lt;b&gt;&lt;i&gt;lxml&lt;/i&gt;&lt;/b&gt; and &lt;b&gt;&lt;i&gt;simplejson&lt;/i&gt;&lt;/b&gt;. The &lt;em&gt;&lt;strong&gt;lxml&lt;/strong&gt;&lt;/em&gt; library is a Python binding for &lt;em&gt;&lt;strong&gt;libxml2&lt;/strong&gt;&lt;/em&gt; "the Gnome XML C parser and toolkit".&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;a href="http://www.postgresql.org/"&gt;http://www.postgresql.org/&lt;/a&gt;  PostgreSQL&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;a href="http://xmlsoft.org/"&gt;http://xmlsoft.org/&lt;/a&gt;   libxml2&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;a href="http://code.google.com/p/simplejson/"&gt;http://code.google.com/p/simplejson/&lt;/a&gt;  SimpleJson&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;small&gt;The post title is from a classic American television ad for automotive parts, wherein the negative credibility speaker suggests that all parts are equal.&lt;/small&gt; &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-5150818988636208457?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/5150818988636208457/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2009/07/parts-is-parts.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/5150818988636208457'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/5150818988636208457'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2009/07/parts-is-parts.html' title='Parts is parts'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2417324817603252106.post-5069641728066296538</id><published>2009-07-21T08:49:00.000-06:00</published><updated>2009-07-21T23:16:55.910-06:00</updated><title type='text'>A modest venture</title><content type='html'>&lt;div&gt; &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;www.Rdbhost.Com provides a service that I have not seen available, in any similar form.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If you need an SQL database, and your web host does not provide or permit the installation of an SQL database, we can provide you one.  As a web service, rdbhost databases are accessed via http requests.  If you are coding in Python, we even have a DB API module for rdbhost databases; you can code your database usage without worrying about http or other networking issues.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Our pricing model is pay-as-you-go, so you only pay for actual bandwidth and diskspace used.  To get you started, very low usage is free.  To set up an account, we only ask of you a valid email address.  &lt;/div&gt;&lt;br /&gt;&lt;div&gt;Set up an account for free, and dabble with it; see first hand how it works.  If you agree with us that a true ACID-compliant SQL relational database is worth the modest additional setup effort, then go with it.  When your account usage exceeds our free limits, we will sell you as much or as little additional bandwidth and space as you need.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;We do support TLS encrypted https connections.&lt;/div&gt;&lt;br /&gt;&lt;div&gt; &lt;/div&gt;We provide tools for manipulating your database:&lt;div&gt;&lt;ul&gt;&lt;li&gt;Rdbadmin - a database manager similar to PhpMinAdmin&lt;/li&gt;&lt;li&gt;A database dump tool to dump the entire database (as SQL) to your browser for backup purposes&lt;/li&gt;&lt;li&gt; A plain-jane html form for submitting queries to the database, and getting XML/JSON responses&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A few starter links:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.rdbhost.com"&gt;Front page&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.rdbhost.com/qna.html"&gt;Questions and Answers&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.rdbhost.com/howitworks.html"&gt;HowItWorks&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;#&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2417324817603252106-5069641728066296538?l=rdbhost.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rdbhost.blogspot.com/feeds/5069641728066296538/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rdbhost.blogspot.com/2009/07/modest-venture.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/5069641728066296538'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2417324817603252106/posts/default/5069641728066296538'/><link rel='alternate' type='text/html' href='http://rdbhost.blogspot.com/2009/07/modest-venture.html' title='A modest venture'/><author><name>David Keeney</name><uri>http://www.blogger.com/profile/05853065350985701131</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
