logo search
Программирование на языке Ruby

10.2.4. Обеспечение устойчивости объектов с помощью библиотеки pStore

Библиотека PStore реализует хранение объектов Ruby в файле. Объект класса PStore может содержать несколько иерархий объектов Ruby. У каждой иерархии есть корень, идентифицируемый ключом. Иерархии считываются с диска в начале транзакции и записываются обратно на диск в конце.

require "pstore"

# Сохранить.

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

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

                 "salary" => 48000 }

end

# Восстановить.

require "pstore"

db = Pstore.new("employee.dat")

emp = nil

db.transaction { emp = db["params"] }

Обычно внутри блока транзакции используется переданный ему объект PStore. Но можно получить и сам вызывающий объект, как показано в примере выше.

Эта техника ориентирована на транзакции; в начале блока обрабатываемые данные читаются с диска. А в конце прозрачно для программиста записываются на диск.

Мы можем завершить транзакцию досрочно, вызвав метод commit или abort. В первом случае все изменения сохраняются, во втором отбрасываются. Рассмотрим более длинный пример:

require "pstore"

# Предполагается, что существует файл с двумя объектами.

store = PStore.new("objects")

store.transaction do |s|

 a = s["my_array"] h = s["my_hash"]

 # Опущен воображаемый код, манипулирующий объектами

 # a, h и т. д.

 # Предполагается, что переменная "condition" может

 # принимать значения 1, 2, 3...

 case condition

  when 1

   puts "Отмена."

   s.abort # Изменения будут потеряны.

  when 2

   puts "Фиксируем и выходим."

   s.commit # Изменения будут сохранены.

  when 3

   # Ничего не делаем...

 end

 puts "Транзакция дошла до конца."

 # Изменения будут сохранены.

end

Внутри транзакции можно вызвать метод roots, который вернет массив корней (или метод root?, чтобы проверить принадлежность). Есть также метод delete, удаляющий корень.

store.transaction do |s|

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

 if s.root?("my_tree")

  puts "Найдено my_tree."

 else

  puts "He найдено # my_tree."

 end

 s.delete("my_hash")

 list2 = s.roots # ["my_array"]

end