Ruby操纵外部数据(四)

3 、使用Marshal 完成有限制的" 深层拷贝"

Ruby没有深层拷贝"deep copy"操作符。方法dupclone不会总像你想像的那样工作。 对象可以包含嵌套的对象引用,它转向一个拷贝操作到Pick Up Sticks中。


我们提供了一个途径来处理一个有限制的深层拷贝( 它有限制,是因为它还以Marshal 为基础所以有同样内在限制)
def deep_copy(obj)

Marshal.load(Marshal.dump(obj))
end
a = deep_copy(b)


4 Better Object Persistence with PStore
PStore 库提供了文件为基础的Ruby 对象的永续存储。PStore 对象可以持有许多Ruby 对象层次。每个层次通过一个键有个被识别的根。开始时从磁盘文件上读取层次结束时写回文件。这儿是个例子:
require "pstore"


# save
db = PStore.new("employee.dat")
db.transaction do

db["params"] = { "name" => "Fred", "age" => 32,

"salary" => 48000 }
end
# retrieve
require "pstore"
db = PStore.new("employee.dat")
emp = nil
db.transaction {
emp = db["params"] }
典型地,我们将Pstore 对象传入到处理块内。但是,我们也可以直接使用调用者。
这个技术是事务导向的;块开始时,数据被从磁盘文件中取回并进行处理。然后,它被显式地写回到磁盘上。

在事务的中间,我们即可以中断也可放弃;但前者将保留我们做的修改,而后者将丢掉它们。参考Listing4.2这个更长的例子。

Listing 4.2 Using PStore
require "pstore"


store = PStore.new("objects")
store.transaction do |s|

a = s["my_array"]

h = s["my_hash"]

# Imaginary code omitted, manipulating

# a, h, etc.

# Assume a variable named "condition" having

# the value 1, 2, or 3...

case condition

when 1

puts "Oops... aborting."

s.abort
# Changes will be lost.

when 2

puts "Committing and jumping out."

s.commit
# Changes will be saved.

when 3

# Do nothing...

end

puts "We finished the transaction to the end."

# Changes will be saved.
end
在一个事务内部,你也可以使用方法roots 来返回根的数组( root? 测试成员) 。同样,delete 方法将有效地移除一个根。这儿个例子:
store.transaction do |s|

list = s.roots
# ["my_array","my_hash"]

if s.root?("my_tree")

puts "Found my_tree."

else

puts "Didn't find # my_tree."

end

s.delete("my_hash")

list2 = s.roots
# ["my_array"]
end


5 Using the dbm Library
dbm 库是一个简单依赖系统的,以字符为基础的哈希表的,以文件存储的机制。它存储键和关联的数据,两者必须是字符串。Ruby dbm 接口是被标准按装的。
要使用这个类,创建一个与文件名字关联的dbm 对象,并且你希望以字符为基础的哈希表工作。当你完成时,你应该关闭文件。这儿是个例子:
require 'dbm'


d = DBM.new("data")
d["123"] = "toodle-oo!"
puts d["123"]
# "toodle-oo!"
d.close
puts d["123"]
# RuntimeError: closed DBM file
e = DBM.open("data")
e["123"]
# "toodle-oo!"
w=e.to_hash
# { "123"=>"toodle-oo!"}
e.close
e["123"]
# RuntimeError: closed DBM file
w["123"]
# "toodle-oo!
这儿,dbm 被做为混插了Enumerable 的单独类实现的。两个类方法,new open ,是单态的,它的意思是任何时候,你的每个数据文件只可以有一个dbm 对象:
q=DBM.new("data.dbm")
#
f=DBM.open("data.dbm")
# Errno::EWOULDBLOCK:

#
Try again - "data.dbm"
它有34 个实例方法,很多都是别名或与Hash 方法类似。基本上,如果你能熟练地使用哈希表,你可以对一个dbm 对象应用同样的操作。
方法to_hash 将在内存中为哈希表文件制做一个拷贝,close 方法将永久地关闭与哈希表文件的连接。其余的方法和Hash 方法类似,但没有rehsh,sort,default, efault= 方法。to_s 方法只返回用字符串表示的对象ID






三、连接外部数据库

Ruby 可以连接由许多不同的人开发的,各种各样的数据库。这些范围从整体系统譬如Oracle 到对更小的MySQL

这些包的功能层会持续地被修改。请务必提到网上参考最新的信息。Ruby的应用文档(RAA)总是最好的起点。



1 、连接到MySQL
Ruby MySQL 接口是最稳定的和有完整功能的数据库接口。它是扩展的,必须在Ruby MySQL 被安装并运行后才可安装。如果你升级Ruby ,你将需要重新安装它。它的安装很简单,使用Ruby make 过程。

一旦你安装了它,可以有三个步骤来使用它。首先,在你的脚本中加载它;然后连接到数据库。最后,用你的表工作。连接请求通常使用的参数主机名,用户名,口令,数据库,等等,像这儿显示的:


require 'mysql'


m = Mysql.new("localhost","ruby","secret","maillist")
r = m.query("SELECT * FROM people ORDER BY name")
r.each_hash do |f|

print "#{ f['name']}
- #{ f['email']} "
end
这儿是部分输出:
John Doe - jdoe@rubynewbie.com
Fred Smith - smithf@rubyexpert.com
Don Jackson - don@perl2.com
Jenny Williams - jwill27@miss-code.com
类方法Mysql.new MysqlRes.each_hash 是非常有用的,还有随同的实例方法query
这个模块由四个类组成: Mysql, MysqlRes, MysqlField, MysqlError, 分别在README 文件中描述。我们在这儿总结了一些有用的方法,但你可以实际文档中找到更多信息。
类方法Mysql.new 接受几个字符串参数,所有都被定义为nil ,并且它返回一个connection 对象。参数是host,user,passwd,db,port,sock, flag new 的别名real_connect connect
方法create_db, select_db, drop_db 都接受数据库名称做为参数;它们用法显示在下面( 方法close 将关闭与服务端的连接)
m=Mysql.new("localhost","ruby","secret")
m.create_db("rtest")
# Create a new database
m.select_db("rtest2")
# Select a different database
m.drop_db("rtest")
# Delete a database
m.close
# Close the connection
The method 方法list_dbs 将返回有效的数据库名称列表在一个数组内:
dbs = m2.list_dbs
# ["people","places","things"]
query 接受一个字符串参数并缺省地返回一个MysqlRes 对象。这依赖于query_with_result 是如何被设置的,它可以返回一个Mysql 对象。
如果事件出现错误,错误号码可由errno 取回;换句话说,error 将返回实际的错误信息。这儿是个例子:
begin

r=m.query("create table rtable

(

id int not null auto_increment,

name varchar(35) not null,

desc varchar(128) not null,

unique id(id)

)")
# exception happens...
rescue

puts m.error

# Prints: You have an error in your SQL syntax

# near 'desc varchar(128) not null ,

#
unique id(id)

# )' at line 5"

puts m.errno

# Prints 1064

# ('desc' is reserved for descending order)
end
MysqlRes 内很少被使用的方法被总结列在下面:
1.
fetch_fields 从下一行中返回MysqlField 对象的数组。
2.
fetch_row 从下一行中返回字段值的数组。
3.
fetch_hash(with_table=false) 返回包含下一行的名称和值的哈希表。
4.
num_rows 返回结果集中行数。
5.
each 按次序返回字段值数组的迭代器。
6.
each_hash(with_table=false) 按次序返回一个{fieldname => fieldvalue} 样哈希表的迭代器。( 使用x['field name'] 来获取字段值。)
这儿是MysqlField 的一些实例方法:
1.
name 返回指定字段的名字。
2.
table 返回指定字段所属表的名字。
3.
length 返回字段定义长度。
4.
max_length 从结果集中返回长度最长的字段。
5.
hash Returns a hash with a name and values for name, table, def, type, length, max_length, flags, and decimals
这儿的材料总是代替不了在线文档的。更多信息可参考MySQL Web 站点 ( www.mysql.com) Ruby 应用文档。
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值