创建数据库驱动的 Google Gadget






4.57/5 (12投票s)
本文演示如何创建一个自动刷新的谷歌桌面小工具,该工具从数据库中提取数据。

引言
这与我之前写的创建数据库驱动的 Vista 小工具的文章非常相似。原理没有改变,但存在一些明显的差异。抱歉本文与上一篇文章可能存在重复,我只是不想让那些只对其中一篇感兴趣的人必须阅读两篇文章。基本上,目标是创建一个从小工具中提取数据并显示它的小工具。
我使用的数据库是 Sybase iAnywhere 的 SQL Anywhere 10。为了访问数据库,小工具发出 HTTP 请求,使用 SQL Anywhere 可以轻松做到这一点,因为它有一个内置的 HTTP 服务器,允许将 SQL 查询作为 Web 服务公开。您可以从此处下载免费的 SQL Anywhere 开发人员版。
下面的源代码和解释将指导您创建本文随附的演示小工具。基本上,该小工具从 SQL Anywhere 10 附带的示例数据库中提取数据,并显示实时数据库统计信息以及 Customers
表中的数据列表。
背景
谷歌桌面小工具是一种用户友好、图形化程度很高的实用程序或小部件,允许用户查看有关正在运行的应用程序的关键信息。数据库驱动的解决方案可以使用小工具来显示存储在数据库中的重要应用程序信息。例如,您可以创建一个小型通知小工具,以通知用户某些数据库更改或收集数据库统计信息进行性能监控。作为谷歌桌面小工具的好处是,谷歌桌面适用于 Windows、Linux 和 Mac。我还没有真正在 Linux 或 Mac 上测试过这个小工具,但这里的代码是平台无关的,应该可以正常工作。我也很确定 SQL Anywhere 也适用于这些平台。
运行演示小工具
要运行演示,首先将文件解压缩到一个文件夹中。
通过运行以下命令启动 SQL Anywhere 10 演示数据库
> dbeng10 -n gadget "%SQLANYSAMP10%"\demo.db -xs http(port=8888)
然后,通过在解压的文件夹位置运行以下命令来安装脚本和 Web 服务
> dbisql -c "ENG=gadget;UID=dba;PWD=sql" demo.sql
最后,双击 sqlanywhere10.gg 文件来安装和加载演示小工具。
创建基本的谷歌小工具
小工具不过是一个微型 HTML 页面。当然,您可以使用 HTML 只是 Google Gadget API 定义的一个子集。花哨的外观是通过透明图像(PNG 或 GIF)实现的,样式是通过 CSS 实现的,功能是通过 JavaScript 实现的。Google 在此处详细介绍了如何开始。但我将只回顾您需要的基本知识。
清单文件
首先,您需要设置清单文件,它基本上只是为 Google Desktop 描述小工具,并为用户在安装小工具之前提供信息。清单文件 必须 具有 *.gmanifest 扩展名。
这是清单文件所需的所有内容。
<gadget minimumGoogleDesktopVersion="5.1.0.0">
<about>
<name>Your Gadget Title Here</name>
<description>Your Gadget Description Here</description>
<aboutText>Your Gadget About Text Here</aboutText>
<version>1.0.0.0</version>
<author>Your Name Here</author>
<authorWebsite>Your Website Here</authorWebsite>
<id>A UUID Here</id>
<copyright>Your Copyright Here</copyright>
<authorEmail>Your Email Here</authorEmail>
</about>
</gadget>
main.xml 文件
接下来,您需要实际定义 main.xml 文件,它是小工具的主体。格式化是通过使用标签的不同属性实现的,功能是通过使用 JavaScript 实现的。请记住,Google 只公开了有限的 HTML 标签子集供您使用。
<view height="300" width="180" onopen="loadMain();">
<div height="300" name="content" opacity="225" width="180" x="0" y="0"
background="#221122">
<div height="50" name="stats" width="170" x="5" y="50" autoscroll="true"
background="#332233"/>
<label height="32" name="label1" width="180" x="0" y="0" align="center"
bold="true" color="#FFFFFF" size="12" valign="middle">SQL Anywhere 10</label>
<label height="18" name="label2" width="170" x="5" y="32"
bold="true" color="#FFFFFF" valign="bottom">Database Statistics</label>
<div height="154" name="data" width="170" x="5" y="118"
autoscroll="true" background="#332233"/>
<label height="18" name="label3" width="170" x="5" y="100"
bold="true" color="#FFFFFF" valign="bottom">Customer Table Data</label>
<label height="16" name="page" width="56" x="64" y="277"
align="center" color="#FFFFFF">0 / 0 </label>
<button height="16" name="down" width="16" x="131" y="278"
onclick="pageDown()" downImage="img\buttonDown_Off.png"
image="img\buttonDown_Off.png" overImage="img\buttonDown_Off.png"/>
<button height="16" name="up" width="16" x="35" y="278"
onclick="pageUp()" downImage="img\buttonUp_Off.png"
image="img\buttonUp_Off.png" overImage="img\buttonUp_Off.png"/>
</div>
<script src="main.js" />
<script src="xml.js" />
</view>
需要注意的关键事项是
- 指向 main.js 和 xml.js JavaScript 文件的链接,
<script src="main.js"/>
- 三次调用 JavaScript 函数:
onopen="loadMain()"
、onclick="pageUp()"
和onclick="pageDown()"
main.js 和 xml.js 文件
最后,我们将完成 JavaScript 文件。这就是小工具的功能。我将只介绍用于实际从数据库中检索数据的代码。
全局变量已解释
var statsRequest; //XMLHTTP Request Object to request stats from the web service
var dataRequest; //XMLHTTP Request Object to request data from the web service
var maxDataItemsPerPage = 10; //Maximum number of companies to display per page
var currPage = -1; //Current Page
var numPages = 0; //Total Number of Pages
因为 main.xml 文件中设置了 onopen="loadMain()"
,所以当小工具加载时会调用此函数。
function loadMain()
{
refreshStats();
setInterval("refreshStats();", 500);
refreshData();
}
这将调用两个显示函数。统计信息将每 500 毫秒刷新一次。这就是实现小工具自动刷新的方式。JavaScript 将每 500 毫秒持续调用此函数。您可以根据需要设置刷新时间的长短。将调用以下函数。我将只介绍数据库数据函数,因为数据库统计函数几乎相同。
function refreshData()
{
var url = "https://:8888/GadgetData";
dataRequest = new XMLHttpRequest();
dataRequest.onreadystatechange = writeData;
dataRequest.open("GET", url, true);
dataRequest.send(null);
}
所需要做的就是创建一个 XMLHTTP 请求,该请求将从指定的 URL 检索 HTML 输出。为了在任何情况下都保持小工具响应,您需要将 statsRequest.open()
的第三个参数设置为 true
。这将使请求对象以非阻塞异步模式运行。您将看到 writeData()
被指定为请求状态更改时要调用的函数。
function writeData()
{
if(dataRequest.readyState == 4)
{
if(dataRequest.status == 200)
{
var y = 3;
var element;
var xml;
var items;
xml = new DataXml(dataRequest.responseXml);
items = xml.getItems("row");
for(var i = 0; i < items.length; i++)
{
element = data.appendElement("<label>" + items[i] + "</label>");
element.color = "#FFFFFF";
element.y = y;
y += 14;
}
}
}
}
一旦请求状态为“OK”,您所需要做的就是格式化数据并将其附加到现有的 data
div 中。
您会注意到创建了一个 DataXml
对象,所以我将介绍一下。您可以在 xml.js 中找到代码。
function DataXml(xml)
{
this.xml = xml;
}
DataXml.prototype.getItems = function(key)
{
var xml = this.xml;
var items = [];
var nodes = xml.getElementsByTagName(key);
for (var i = 0; i < nodes.length; i++)
{
items.push(nodes[i].getAttribute("CompanyName"));
}
return items;
}
这本质上只是一个简单的 XML 解析器。getItems()
成员函数返回一个公司名称数组。
在数据库中创建 Web 服务以提供 HTML
JavaScript 将尝试从上面指定的 URL 中提取数据。因此,您需要确保当小工具向该 URL 提交 HTTP 请求时,确实会返回一些 HTML。值得庆幸的是,SQL Anywhere 10 为您完成了所有工作,因此您所需要做的就是编写一些 SQL 语句来返回数据,它将处理其余部分。
连接到查询编辑器中的“演示”数据库后,运行 SQL 脚本 demo.sql。我将介绍该脚本在数据库数据检索方面的作用。设置数据库统计信息检索部分的脚本几乎相同。
CREATE PROCEDURE "DBA"."GetGadgetData"()
RESULT (CompanyName LONG VARCHAR)
BEGIN
SELECT REPLACE(HTML_ENCODE("CompanyName"), ''', '''')
FROM "GROUPO"."Customers"
ORDER BY "CompanyName";
END;
脚本所做的只是创建一个存储过程。使用 HTML_ENCODE
过程替换任何无效的 XML 符号。
最后,您所需要做的就是将存储过程转换为 Web 服务。这可以通过一个 SQL 语句完成
CREATE SERVICE "GadgetData" TYPE 'XML' AUTHORIZATION OFF USER "DBA" _
AS call GetGadgetData();
提交您的更改。您现在所需要做的就是部署小工具。
部署您的小工具
首先要做的是确保您的数据库正在运行 HTTP 侦听器。您可以在运行 SQL Anywhere 10 数据库时指定以下启动选项来完成此操作。您可以将端口设置为您喜欢的任何值,只需确保它与您之前在 JavaScript 文件中指定的 URL 中使用的端口相同。
> dbeng10.exe yourdb.db -xs http(port=8888)
-xs http(port=8888)
是实现魔法的部分。基本上,它告诉数据库引擎绑定到端口 8888 并侦听请求。当收到请求时,会根据关联的 SQL 语句或存储过程生成响应。
要安装您的小工具,只需双击 *.gmanifest 文件。
或者,只需将所有内容放入 zip 文件中,然后将文件重命名为 *.gg。双击它将自动安装和加载小工具!
关注点
尽管目标只是创建一个数据库驱动的谷歌小工具,但很明显(至少对我来说)SQL Anywhere 10 的 Web 服务功能为开发人员提供了一个强大的平台,可以对任何类型的应用程序进行数据库启用。我建议您在此处阅读更多有关其产品的信息。