首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 开源 FAQ 第二书店 博文视点 程序员
频道: 研发 数据库 中间件 信息化 视频 .NET Java 游戏 移动 服务: 人才 外包 培训
    图书品种:235680
       
热门搜索: ASP.NET Ajax Spring Hibernate Java

10.3  使用KirbyBase

KirbyBase是所有程序员都应学会使用的小型库之一,当前它还不是Ruby的标准库,如果是的话,它用途可能更大。

KirbyBase是Jamey Cribbs开发的(显然是以他的狗命名的),虽然从很多方面说它都是一个功能齐备的数据库,但基于几个原因,将它放在这里介绍,而不是同MySQL和Oracle一起介绍。

首先,它不是独立的应用程序。它是一个纯粹的Ruby库,离开Ruby就毫无用处。其次,它完全不知道SQL,因此,如果由于种种原因需要依赖于SQL,则不适合使用它。第三,如果应用程序非常复杂,则KirbyBase的功能和速度是个问题。

尽管如此,还是有很多让人喜欢KirbyBase的原因。它是个单文件的纯Ruby库,不需要安装和配置。它是跨平台的,其数据文件也在不同平台之间交换。它的数据不会同时存储到内存中,从这种意义上说它是一个“真正的”数据库。

它使用起来很容易,且有到小型DBI的Ruby风格接口。一般而言,数据库对应于一个目录,而表格对应于一个文件。它生成的表是人类可读(及可编辑)的,也可以选择将其加密(旨在防止编辑)。它能够识别Ruby对象,可智能地存储和检索对象。

最后,依靠一个dRuby接口,它能够在分布模式下运行。访问远程机器和本地机器的KirbyBase数据一样简单。

要打开数据库,首先需要指出它是否是本地的,接下来的两个参数通常为nil,第四个参数指定数据库文件所在的目录(默认为当前目录)。

要创建表,可对数据库调用create_table,并将表名(以符号方式)传递给它(磁盘中的文件名将基于该名称),然后传递一系列表示字段名和类型的符号对。

require 'kirbybase'

db = KirbyBase.new(:local, nil, nil, "mydata")

books = db.create_table(:books,             # name of table

                             :title, :String,  # field, type, ...

                             :author, :String)

当前,KirbyBase能够识别的字段类型包括String、Integer、Float、Boolean、Time、Date、DateTime、Memo、Blob和YAML。在读者阅读本书时,可能还有其他类型。

要将数据插入表,可调用insert方法。可传递一个值列表、散列或任何与给定字段名对应的对象。

books.insert("The Case for Mars","Robert Zubrin")

books.insert(:title => "Democracy in America",

               :author => "Alexis de Tocqueville")

Book = Struct.new(:title, :author)

book = Book.new("The Ruby Way","Hal Fulton")

books.insert(book)

在所有这些情况下,insert方法都将返回新记录的行id(可使用它或忽略它)。这是个“隐藏的”自动递增字段,它存在于每个表的每条记录中。

使用select方法选择记录,如果没有指定参数,它将选择表中每条记录的每个字段。通过将参数指定为符号,可只选择特定的字段。如果指定了代码块,它将用于决定要选择哪些记录(很像数组的find_all方法)。

list1 = people.select                 # All people, all fields

list2 = people.select(:name,:age)   # All people, name/age only

list3 = people.select(:name) {|x| x.age >= 18 && x.age < 30 }

# Names of all people 18 to 30

在代码块中可执行任何操作,这意味着可使用Ruby正则表达式来查询(而不是像典型的面向SQL的数据库那样)。

KirbyBase结果集可根据多个键进行排序,可以是升序,也可以是降序。要按降序排列,可在键名前面加上负号(这是因为在Symbol中有一个一元负号方法)。

sorted = people.select.sort(:name,-:age)

# sort ascending by name, descending by age

结果集还有一个有趣的特性,可以提供对结果进行“横切”的数组,开始这可能有点不好理解。

假设有一个由人组成的结果集,其中每条记录都存储了姓名、年龄、身高和体重。当然,结果集可以像数组一样索引,但它还有与字段同名的方法,这些方法只存储由相应字段的值组成的数组,例如:

list = people.select(:name,:age,:height,:weight)

p list[0]            # All info for person 0

p list[1].age       # Age for person 1

p list[2].height    # Height for person 2

ages  = list.age    # Array: Ages for all people

names = list.name  # Array: Names for all people

KirbyBase有一些报告打印功能,只需对结果集调用to_report即可,如下所示:

rpt = books.select.sort(:title).to_report

puts rpt

# Output:

# recno | title                   | author

# ----------------------------------------------------

#      2 | Democracy in America | Alexis de Tocqueville

#      1 | The Case for Mars     | Robert Zubrin

#      3 | The Ruby Way           | Hal Fulton

可将表的encrypt存取器设置为true,从而使表不能像纯文本那样读取和编辑。注意,这是基于Vigenere加密的——不是毫无用处,但也不是非常安全,因此只将其用做防止编辑的手段,而不应将其用于隐藏敏感数据。通常应在创建表时使用代码块来设置它:

db.create_table(:mytable, f1, :String, f2, :Date) {|t| t.encrypt =true }

远程访问是一种有趣的功能,这里简要地介绍其工作原理。下面是一个示例服务器:

require 'kirbybase'

require 'drb'

host = 'localhost'

port = 44444

db = KirbyBase.new(:server)   # Create an instance of the database.

DRb.start_service("druby://#{host}:#{port}", db)

DRb.thread.join

这是一个简单的dRuby(参见第20章)应用程序。在客户端连接到该数据库时,应指定:client而不是通常的:local。

db = KirbyBase.new(:client,'localhost',44444)

# All other code remains the same.

还可执行一些常规操作:更新或删除记录、删除表等。另外,还有更复杂的特性在这里没有介绍,如一对多链接、计算字段、自定义记录类,详情请参阅RubyForge的KirbyBase文档。

查看所有评论(0)条】

最近评论



正在载入评论列表...
热点评论