From: Sean McEligot Date: 2005-03-05T01:31:41+09:00 Subject: Re: A wish: Simple database > 1. Distributed as part of Ruby > 2. Need not store entire db in memory > 3. No SQL requirement > 4. No special efficiency requirement > 5. Available cross-platform > 6. Database files are readable cross-platform I just started on this YAML based database this week. The code is below. I'm not sure where I'm going with this yet. It does not meet requirement 2. I'm going to do a *dbm version also. That one will meet requirment 2, but not 6. I'm also working a C++ database with sleepycat here http://dbapi.sourceforge.net/ but that isn't ruby and the ruby bindings aren't checked in. Here's my simple yaml db. Maybe it will give you some ideas. #! /usr/bin/env ruby require 'yaml' $ydb_default_directory = "~" class Ydb def initialize(dbname, directory=$ydb_default_directory) @directory = File.expand_path(directory) @dbname = dbname @db = {} @modified = false end def load filename = db_filename if File.exists?(filename) then @db= YAML.load_file(filename) end @modified = false end def open load end def db_filename if not File.directory?(@directory) p "mkdir: #{@directory}" Dir.mkdir(@directory) end File.join(@directory, @dbname+".yaml") end def []=(key,val) @db[key]=val end def [](key) @db[key] end def put(key,val) @db[key]=val end def put(obj) @modified||@modified = true if block_given? key = yield obj else key = obj.pk end @db[key]=obj end def has_key?(key) @db.has_key(keyk) end def each @db.each do |name, path| yield name, path end end def save if @modified then File.open( db_filename, 'w' ) do |out| YAML.dump( @db, out ) end end end def close save end def keys @db.keys end def values @db.values end def index(name) ix = Ydb.new("#{@dbame}-#{name}") @db.keys.each do |key| val= @db[key] skey = yield val ix[key] = key end return ix end def index! ix = {} @db.values.each do |val| key = yield val p "#{key}=#{val}" ix[key] = val end return ix end end class TestItem attr_accessor :id attr_accessor :fname attr_accessor :lname def initialize(id, fname, lname) @id = id @fname = fname @lname = lname end def pk @id end def to_s "#{id}:#{fname} #{lname}" end end def main if ARGV.length == 3 then db = Ydb.new("test") db.open row = TestItem.new(ARGV[0], ARGV[1], ARGV[2]) db.put(row) db.close end db = Ydb.new("test") db.open db.each do |k,v| p "#{k}=#{v}" end by_fname =db.index! do |i| i.fname end by_lname =db.index! do |i| i.lname end p "first names: #{by_fname.keys.join(" ")}" p "last names: #{by_lname.keys.join(" ")}" p "fdb" fdb=db.index("fname") do |i| i.fname end fdb.each do |k,v| p "#{k}=#{v}" end db.close end if __FILE__ == $0 main end