The Power of Google Gears (Part 1)
Pages: 1, 2, 3
To get started with the Gears portion, I need to create one final server element, and that's the XML feed that will be consumed by the Ajax script on the client. This articles.php script is shown in Listing 4.
Listing 4. articles.php <?php
require_once("DB.php");
header( "content-type: text/xml" );
$db =& DB::Connect( 'mysql://root@localhost/articles', array() );
if (PEAR::isError($db)) { die($db->getMessage()); }
$res = $db->query( 'SELECT * FROM article' );
?>
<articles>
<?php
while( $res->fetchInto( $row ) ) {
?>
<article id="<?php echo($row[0]); ?>" title="<?php echo($row[1]); ?>">
<?php echo($row[2]); ?>
</article>
<?php
}
?>
</articles>
Once again I use the DB module to talk to the database and get all of the articles. I then use loop to write out the article tag for each of the articles. This article tag has the ID and title of the article as attributes, and the content of the article as text inside the node.
If I run the script on the command line I see the following output.
% php articles.php
<articles>
<article id="1" title="Apple releases iPhone">
Apple Computer is going to release the iPhone on June 29th at 6PM.</article>
<article id="2" title="Google release Gears">
Google, Inc. of Mountain View California has released a new toolkit for web developers...</article>
</articles>
I added another article about the iPhone just to make it interesting, and maybe pick up a few Google hits.
Implementing the Gears Page
To implement the Gears-enabled viewing page I'm going to need two JavaScript libraries. The first is Protoype.js, which makes writing the Ajax request to get the article data a breeze. And the second is the Gears JavaScript library, gears_init.js, which provides me access to the Gears database. The gears_init.js file comes with the download of the development kit from Google. I've referenced both of these libraries in the head section of the index.html file shown in Listing 5.
Listing 5. index.html <html>
<head>
<script type="text/javascript" src="gears_init.js"></script>
<script type="text/javascript" src="prototype.js"></script>
</head>
<body onload="initializedb()">
<table width="100%">
<tr><td width="20%" valign="top">
<table width="100%" id="elArticles">
</table>
</td><td width="80%" valign="top">
<div id="elContent"></div>
</td></tr></table>
<a href="javascript:void sync();">Go Online</a>
<script>
var db;
function sync()
{
new Ajax.Request( 'articles.php', { method: 'get',
onSuccess: function( transport ) {
var articleTags = transport.responseXML.getElementsByTagName( 'article' );
for( var a = 0; a < articleTags.length; a++ ) {
addArticle( parseInt( articleTags[a].getAttribute('id') ),
articleTags[a].getAttribute('title'),
articleTags[a].firstChild.nodeValue );
}
showArticles();
} } );
}
function initializedb() {
if (!window.google || !google.gears)
return;
try {
db = google.gears.factory.create('beta.database', '1.0');
} catch (ex) {
alert('Could not create database: ' + ex.message);
}
if (db) {
db.open('gearsintro');
db.execute('create table if not exists articles' +
' ( article_id int, title varchar(255), content text )');
}
showArticles();
}
function showArticle( id )
{
var rs = db.execute( 'select content from articles where article_id = ?', [ id ] );
var found = 0;
while (rs.isValidRow()) { $('elContent').innerHTML = rs.field(0); rs.next(); }
rs.close();
}
function showArticles()
{
while( $('elArticles').rows.length > 0 )
$('elArticles').deleteRow( -1 );
var rs = db.execute( 'select * from articles' );
while (rs.isValidRow())
{
var elTR = $('elArticles').insertRow( -1 );
var elTD = elTR.insertCell( -1 );
elTD.onmouseover = function() { this.style.background = '#eee'; };
elTD.onmouseout = function() { this.style.background = 'none'; };
elTD.id = rs.field( 0 );
elTD.onmouseup = function() { showArticle( this.id ); };
elTD.appendChild( document.createTextNode( rs.field(1) ) );
rs.next();
}
rs.close();
}
function addArticle( id, title, content )
{
var rs = db.execute( 'select * from articles where article_id = ?', [ id ] );
var found = 0;
while (rs.isValidRow()) { found++; rs.next(); }
rs.close();
if ( found == 0 )
db.execute('insert into articles values (?, ?, ?)', [id, title, content]);
}
</script>
</body>
</html>