Simple Ruby DB apps/programs ...

U

Useko Netsumi

I was wondering if there are some example of small Ruby(1.8.1) Database
Apps/Programs. Preferably using Relational Database such as MySQL(4 or
5) or Oracle.

I'd love to see some example of storing name(first,last),
address(addr1,addr2,city,zip),phone(home,work,mobile), and a photo image.

It took me a while to write it in PHP but perhaps I can do it in Ruby
more cleanly while learning this great language.

Thanks

/useko
 
A

Andreas Schwarz

Useko said:
I was wondering if there are some example of small Ruby(1.8.1) Database
Apps/Programs. Preferably using Relational Database such as MySQL(4 or
5) or Oracle.

I'd love to see some example of storing name(first,last),
address(addr1,addr2,city,zip),phone(home,work,mobile), and a photo image.

It took me a while to write it in PHP but perhaps I can do it in Ruby
more cleanly while learning this great language.

You should take a look at http://lafcadio.rubyforge.org/. I didn't try
it yet, but it seems to be a very easy and interesting way to create
small DB applications.
 
G

gabriele renzi

I was wondering if there are some example of small Ruby(1.8.1) Database
Apps/Programs. Preferably using Relational Database such as MySQL(4 or
5) or Oracle.

I'd love to see some example of storing name(first,last),
address(addr1,addr2,city,zip),phone(home,work,mobile), and a photo image.

It took me a while to write it in PHP but perhaps I can do it in Ruby
more cleanly while learning this great language.

I think there are samples in <insert your favorite dbms> libraries,
and there are samples for sure in ruby-dbi. I think that may help you.
even these :
http://www.ruby-doc.org/articles/index.rb/2003/July/30#95_MysqlDuBois
http://www.ruby-doc.org/articles/index.rb/2003/Mar/29#94_Dbi

may help you. Always look at ruby-doc.org ;)
 
C

Carl Youngblood

Useko said:
I was wondering if there are some example of small Ruby(1.8.1) Database
Apps/Programs. Preferably using Relational Database such as MySQL(4 or
5) or Oracle.

I'd love to see some example of storing name(first,last),
address(addr1,addr2,city,zip),phone(home,work,mobile), and a photo image.

It took me a while to write it in PHP but perhaps I can do it in Ruby
more cleanly while learning this great language.

Thanks

/useko

My favorite DBMS for small client apps is sqlite. No other DB comes
close to it in terms of convenience and speed, as long as you're not
running a distributed type of an application with hundreds of clients
accessing the database at once. There is no need for a database server
at all. All necessary code for accessing the database is compiled in,
and databases are just plain old files. And it is ACID-compliant.
Check out this ruby extension for it here:

http://sqlite-ruby.sourceforge.net/

Carl
 
U

Useko Netsumi

Carl said:
My favorite DBMS for small client apps is sqlite. No other DB comes
close to it in terms of convenience and speed, as long as you're not
running a distributed type of an application with hundreds of clients
accessing the database at once. There is no need for a database server
at all. All necessary code for accessing the database is compiled in,
and databases are just plain old files. And it is ACID-compliant. Check
out this ruby extension for it here:

http://sqlite-ruby.sourceforge.net/

Carl

Thanks to all.

Perhaps y'all can give me some advice. My apps are running a web photo
apps with mutiple tables in the database. I do not store the image in
the DB but just the /image/file/path and other textual information such
as location, date, time, who took the pictures, and comment fields.
User(s) can only browse, search, and list the information for now. And,
I do not expect more than 20 users accessing it at any given time. Will
it work with SQLITE? Or do I need MySQL or more advanced(more expensive)
RDBMS to handle those tasks.

Thanks

/useko
 
A

Ara.T.Howard

Date: Mon, 05 Jan 2004 19:25:27 -0500
From: Useko Netsumi <[email protected]>
Reply-To: (e-mail address removed)
Newsgroups: comp.lang.ruby
Subject: Re: Simple Ruby DB apps/programs ...



Thanks to all.

Perhaps y'all can give me some advice. My apps are running a web photo
apps with mutiple tables in the database. I do not store the image in
the DB but just the /image/file/path and other textual information such
as location, date, time, who took the pictures, and comment fields.
User(s) can only browse, search, and list the information for now. And,
I do not expect more than 20 users accessing it at any given time. Will
it work with SQLITE? Or do I need MySQL or more advanced(more expensive)
RDBMS to handle those tasks.

Thanks

/useko

i use pstore for alot of web stuff - it works fine:

~/eg/ruby > cat photo.rb
require 'pstore'

class DB
def initialize path = 'photo.db'
@pstore = PStore.new path
end
def []= name, record
address, phone = record

@pstore.transaction do
@pstore[name] = [address, phone]
end
end
def [] name
@pstore.transaction(read_only = true){ @pstore[name] }
end
def each(&block)
@pstore.transaction do
@pstore.roots.each{|name| block.call(name, @pstore[name])}
end
end
def << record
first,last,addr1,addr2,city,zip,home,work,mobile = record
name = Name[first, last]
address = Address[addr1,addr2,city,zip]
phone = Phone[home,work,mobile]
self[name] = [address, phone]
end

Name = Struct.new "Name", :first, :last
Address = Struct.new "Address", :addr1, :addr2, :city, :zip
Phone = Struct.new "Phone", :home, :work, :mobile

[Name, Address, Phone].each{|c| class << c; alias [] new; end}
end

if $0 == __FILE__
db = DB.new

records = [
%w(john doe foo bar boulder 80304 1 2 3),
%w(jane doe bar foo boulder 80305 3 2 1),
]

records.each{|record| db << record}

john = DB::Name['john', 'doe']
jane = DB::Name['jane', 'doe']

db.each do |name, address, phone|
printf "name: %s\naddress: %s\nphone: %s\n\n",
name.inspect, address.inspect, phone.inspect
end

p db[john]
p db[jane]
end


~/eg/ruby > ruby photo.rb

name: #<struct Struct::Name first="john", last="doe">
address: [#<struct Struct::Address addr1="foo", addr2="bar", city="boulder", zip="80304">, #<struct Struct::phone home="1", work="2", mobile="3">]
phone: nil

name: #<struct Struct::Name first="jane", last="doe">
address: [#<struct Struct::Address addr1="bar", addr2="foo", city="boulder", zip="80305">, #<struct Struct::phone home="3", work="2", mobile="1">]
phone: nil

[#<struct Struct::Address addr1="foo", addr2="bar", city="boulder", zip="80304">, #<struct Struct::phone home="1", work="2", mobile="3">]
[#<struct Struct::Address addr1="bar", addr2="foo", city="boulder", zip="80305">, #<struct Struct::phone home="3", work="2", mobile="1">]


you can obviously just store the path to the photo this way... the thing with
pstore is that you can tailor the object to meet your needs: perhaps a hash
would be better: it's up to you. also check out madeleine (on RAA) for this
purpose.


-a
--

ATTN: please update your address books with address below!

===============================================================================
| EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
| PHONE :: 303.497.6469
| ADDRESS :: E/GC2 325 Broadway, Boulder, CO 80305-3328
| STP :: http://www.ngdc.noaa.gov/stp/
| NGDC :: http://www.ngdc.noaa.gov/
| NESDIS :: http://www.nesdis.noaa.gov/
| NOAA :: http://www.noaa.gov/
| US DOC :: http://www.commerce.gov/
|
| The difference between art and science is that science is what we
| understand well enough to explain to a computer.
| Art is everything else.
| -- Donald Knuth, "Discover"
|
| /bin/sh -c 'for l in ruby perl;do $l -e "print \"\x3a\x2d\x29\x0a\"";done'
===============================================================================
 
U

Useko Netsumi

Ara.T.Howard said:
Date: Mon, 05 Jan 2004 19:25:27 -0500
From: Useko Netsumi <[email protected]>
Reply-To: (e-mail address removed)
Newsgroups: comp.lang.ruby
Subject: Re: Simple Ruby DB apps/programs ...



Thanks to all.

Perhaps y'all can give me some advice. My apps are running a web photo
apps with mutiple tables in the database. I do not store the image in
the DB but just the /image/file/path and other textual information such
as location, date, time, who took the pictures, and comment fields.
User(s) can only browse, search, and list the information for now. And,
I do not expect more than 20 users accessing it at any given time. Will
it work with SQLITE? Or do I need MySQL or more advanced(more expensive)
RDBMS to handle those tasks.

Thanks

/useko


i use pstore for alot of web stuff - it works fine:

~/eg/ruby > cat photo.rb
require 'pstore'

class DB
def initialize path = 'photo.db'
@pstore = PStore.new path
end
def []= name, record
address, phone = record

@pstore.transaction do
@pstore[name] = [address, phone]
end
end
def [] name
@pstore.transaction(read_only = true){ @pstore[name] }
end
def each(&block)
@pstore.transaction do
@pstore.roots.each{|name| block.call(name, @pstore[name])}
end
end
def << record
first,last,addr1,addr2,city,zip,home,work,mobile = record
name = Name[first, last]
address = Address[addr1,addr2,city,zip]
phone = Phone[home,work,mobile]
self[name] = [address, phone]
end

Name = Struct.new "Name", :first, :last
Address = Struct.new "Address", :addr1, :addr2, :city, :zip
Phone = Struct.new "Phone", :home, :work, :mobile

[Name, Address, Phone].each{|c| class << c; alias [] new; end}
end

if $0 == __FILE__
db = DB.new

records = [
%w(john doe foo bar boulder 80304 1 2 3),
%w(jane doe bar foo boulder 80305 3 2 1),
]

records.each{|record| db << record}

john = DB::Name['john', 'doe']
jane = DB::Name['jane', 'doe']

db.each do |name, address, phone|
printf "name: %s\naddress: %s\nphone: %s\n\n",
name.inspect, address.inspect, phone.inspect
end

p db[john]
p db[jane]
end


~/eg/ruby > ruby photo.rb

name: #<struct Struct::Name first="john", last="doe">
address: [#<struct Struct::Address addr1="foo", addr2="bar", city="boulder", zip="80304">, #<struct Struct::phone home="1", work="2", mobile="3">]
phone: nil

name: #<struct Struct::Name first="jane", last="doe">
address: [#<struct Struct::Address addr1="bar", addr2="foo", city="boulder", zip="80305">, #<struct Struct::phone home="3", work="2", mobile="1">]
phone: nil

[#<struct Struct::Address addr1="foo", addr2="bar", city="boulder", zip="80304">, #<struct Struct::phone home="1", work="2", mobile="3">]
[#<struct Struct::Address addr1="bar", addr2="foo", city="boulder", zip="80305">, #<struct Struct::phone home="3", work="2", mobile="1">]


you can obviously just store the path to the photo this way... the thing with
pstore is that you can tailor the object to meet your needs: perhaps a hash
would be better: it's up to you. also check out madeleine (on RAA) for this
purpose.


-a

Thanks Ara, I'll definitely will try your example above. And check out
madeline as well.

One question though, have you tried the pstore for multi-user or this is
mainly for single user only? What happen if 2 or more user accessing the
same db at the same time? Thanks

/useko
 
M

Matt Armstrong

Useko Netsumi said:
Thanks Ara, I'll definitely will try your example above. And check
out madeline as well.

One question though, have you tried the pstore for multi-user or
this is mainly for single user only? What happen if 2 or more user
accessing the same db at the same time? Thanks

pstore.rb uses File.flock to lock the pstore database. This works if
file.flock works (i.e. it will fail when the pstore database is stored
on NFS).
 
U

Useko Netsumi

Thanks and please forgive my lack of knowledge of pstore.
pstore.rb uses File.flock to lock the pstore database.
So, does this mean that it can ONLY serve one users for add/update
record(s) in the DB and mutli-user for read/search?

Is pstore is widely use? Thanks

/useko
 
A

Ara.T.Howard

Date: Tue, 06 Jan 2004 00:18:42 -0500
From: Useko Netsumi <[email protected]>
Reply-To: (e-mail address removed)
Newsgroups: comp.lang.ruby
Subject: Re: Simple Ruby DB apps/programs ...

Ara.T.Howard said:
Date: Mon, 05 Jan 2004 19:25:27 -0500
From: Useko Netsumi <[email protected]>
Reply-To: (e-mail address removed)
Newsgroups: comp.lang.ruby
Subject: Re: Simple Ruby DB apps/programs ...

Carl Youngblood wrote:

Useko Netsumi wrote:


I was wondering if there are some example of small Ruby(1.8.1)
Database Apps/Programs. Preferably using Relational Database such as
MySQL(4 or 5) or Oracle.

I'd love to see some example of storing name(first,last),
address(addr1,addr2,city,zip),phone(home,work,mobile), and a photo image.

It took me a while to write it in PHP but perhaps I can do it in Ruby
more cleanly while learning this great language.

Thanks

/useko


My favorite DBMS for small client apps is sqlite. No other DB comes
close to it in terms of convenience and speed, as long as you're not
running a distributed type of an application with hundreds of clients
accessing the database at once. There is no need for a database server
at all. All necessary code for accessing the database is compiled in,
and databases are just plain old files. And it is ACID-compliant. Check
out this ruby extension for it here:

http://sqlite-ruby.sourceforge.net/

Carl


Thanks to all.

Perhaps y'all can give me some advice. My apps are running a web photo
apps with mutiple tables in the database. I do not store the image in
the DB but just the /image/file/path and other textual information such
as location, date, time, who took the pictures, and comment fields.
User(s) can only browse, search, and list the information for now. And,
I do not expect more than 20 users accessing it at any given time. Will
it work with SQLITE? Or do I need MySQL or more advanced(more expensive)
RDBMS to handle those tasks.

Thanks

/useko


i use pstore for alot of web stuff - it works fine:

~/eg/ruby > cat photo.rb
require 'pstore'

class DB
def initialize path = 'photo.db'
@pstore = PStore.new path
end
def []= name, record
address, phone = record

@pstore.transaction do
@pstore[name] = [address, phone]
end
end
def [] name
@pstore.transaction(read_only = true){ @pstore[name] }
end
def each(&block)
@pstore.transaction do
@pstore.roots.each{|name| block.call(name, @pstore[name])}
end
end
def << record
first,last,addr1,addr2,city,zip,home,work,mobile = record
name = Name[first, last]
address = Address[addr1,addr2,city,zip]
phone = Phone[home,work,mobile]
self[name] = [address, phone]
end

Name = Struct.new "Name", :first, :last
Address = Struct.new "Address", :addr1, :addr2, :city, :zip
Phone = Struct.new "Phone", :home, :work, :mobile

[Name, Address, Phone].each{|c| class << c; alias [] new; end}
end

if $0 == __FILE__
db = DB.new

records = [
%w(john doe foo bar boulder 80304 1 2 3),
%w(jane doe bar foo boulder 80305 3 2 1),
]

records.each{|record| db << record}

john = DB::Name['john', 'doe']
jane = DB::Name['jane', 'doe']

db.each do |name, address, phone|
printf "name: %s\naddress: %s\nphone: %s\n\n",
name.inspect, address.inspect, phone.inspect
end

p db[john]
p db[jane]
end


~/eg/ruby > ruby photo.rb

name: #<struct Struct::Name first="john", last="doe">
address: [#<struct Struct::Address addr1="foo", addr2="bar", city="boulder", zip="80304">, #<struct Struct::phone home="1", work="2", mobile="3">]
phone: nil

name: #<struct Struct::Name first="jane", last="doe">
address: [#<struct Struct::Address addr1="bar", addr2="foo", city="boulder", zip="80305">, #<struct Struct::phone home="3", work="2", mobile="1">]
phone: nil

[#<struct Struct::Address addr1="foo", addr2="bar", city="boulder", zip="80304">, #<struct Struct::phone home="1", work="2", mobile="3">]
[#<struct Struct::Address addr1="bar", addr2="foo", city="boulder", zip="80305">, #<struct Struct::phone home="3", work="2", mobile="1">]


you can obviously just store the path to the photo this way... the thing with
pstore is that you can tailor the object to meet your needs: perhaps a hash
would be better: it's up to you. also check out madeleine (on RAA) for this
purpose.


-a

Thanks Ara, I'll definitely will try your example above. And check out
madeline as well.
One question though, have you tried the pstore for multi-user or this is
mainly for single user only?

i have used it for multi-user in house applications. i seem to remember you
saying this was for a round 20 users or so - in which case it would be fine.
if you want more you really need to go with postgresql and 'set isolation
level serializable' or deal with transaction conflicts yourself. pstore uses
flock so it supports single writer many reader semantics. note that this is
the same as sqlite - it too uses flock and coarse grained locking internally.
What happen if 2 or more user accessing the same db at the same time? Thanks

one will block. this is generally pretty easy to deal with by simply
minimizing the amount of time you are writing to the database, for example
use:

value = cgi['value']

pstore.transaction do
pstore[:key] = value
end

vs.

pstore.transaction do
value = cgi['value']
pstore[:key] = value
end

unless you db/updates are _very_ big the time blocked will probably be about
what the connection time would be been if using a rdbms server.

and use read_only = true when possible. note that, if you really want true
concurency your cgi script will become pretty compilcated - especially for
multi page apps which can span several minutes... simply using mysql or
postgresql won't solve think for you.

i would reccomend this:

* abstract the database layer as a class which get records by key, adds
records, deletes records, etc.

* develop your app using pstore or other embedded db

move to a db server iff throughput becomes a problem. the ability to develop
quickly, back up your db using 'tar', move to a new server using 'scp', etc.
are real benefits - plus you do not move outside the ruby installation and
need to involve sysads (eek). rdbms are great but sometimes a little
overkill.

you also might want to check out 'bdb' which is very good and has transaction
support.

-a
--

ATTN: please update your address books with address below!

===============================================================================
| EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
| PHONE :: 303.497.6469
| ADDRESS :: E/GC2 325 Broadway, Boulder, CO 80305-3328
| STP :: http://www.ngdc.noaa.gov/stp/
| NGDC :: http://www.ngdc.noaa.gov/
| NESDIS :: http://www.nesdis.noaa.gov/
| NOAA :: http://www.noaa.gov/
| US DOC :: http://www.commerce.gov/
|
| The difference between art and science is that science is what we
| understand well enough to explain to a computer.
| Art is everything else.
| -- Donald Knuth, "Discover"
|
| /bin/sh -c 'for l in ruby perl;do $l -e "print \"\x3a\x2d\x29\x0a\"";done'
===============================================================================
 
M

Matt Armstrong

Useko Netsumi said:
Thanks and please forgive my lack of knowledge of pstore.


So, does this mean that it can ONLY serve one users for add/update
record(s) in the DB and mutli-user for read/search?
Yes.


Is pstore is widely use? Thanks

The old RAA used a pstore to store the data for every ruby project
listed (maybe the new one does too, I don't know). It works fine so
long as your data set is not large -- it reads the *whole* data set
into memory and writes it all back out each time it is opened/closed.
 
U

Useko Netsumi

Thanks.

By any chance, what web server technology do you use?
Apache/mod_ruby/eruby or other(java,php,etc)? Please advise
 
U

Useko Netsumi

Thanks Ara.

What web scripting language do you use to build the apps with pstore? Thanks

Ara.T.Howard said:
Date: Tue, 06 Jan 2004 00:18:42 -0500
From: Useko Netsumi <[email protected]>
Reply-To: (e-mail address removed)
Newsgroups: comp.lang.ruby
Subject: Re: Simple Ruby DB apps/programs ...

Ara.T.Howard said:
On Mon, 5 Jan 2004, Useko Netsumi wrote:


Date: Mon, 05 Jan 2004 19:25:27 -0500
From: Useko Netsumi <[email protected]>
Reply-To: (e-mail address removed)
Newsgroups: comp.lang.ruby
Subject: Re: Simple Ruby DB apps/programs ...

Carl Youngblood wrote:

Useko Netsumi wrote:


I was wondering if there are some example of small Ruby(1.8.1)
Database Apps/Programs. Preferably using Relational Database such as
MySQL(4 or 5) or Oracle.

I'd love to see some example of storing name(first,last),
address(addr1,addr2,city,zip),phone(home,work,mobile), and a photo image.

It took me a while to write it in PHP but perhaps I can do it in Ruby
more cleanly while learning this great language.

Thanks

/useko


My favorite DBMS for small client apps is sqlite. No other DB comes
close to it in terms of convenience and speed, as long as you're not
running a distributed type of an application with hundreds of clients
accessing the database at once. There is no need for a database server
at all. All necessary code for accessing the database is compiled in,
and databases are just plain old files. And it is ACID-compliant. Check
out this ruby extension for it here:

http://sqlite-ruby.sourceforge.net/

Carl


Thanks to all.

Perhaps y'all can give me some advice. My apps are running a web photo
apps with mutiple tables in the database. I do not store the image in
the DB but just the /image/file/path and other textual information such
as location, date, time, who took the pictures, and comment fields.
User(s) can only browse, search, and list the information for now. And,
I do not expect more than 20 users accessing it at any given time. Will
it work with SQLITE? Or do I need MySQL or more advanced(more expensive)
RDBMS to handle those tasks.

Thanks

/useko



i use pstore for alot of web stuff - it works fine:

~/eg/ruby > cat photo.rb
require 'pstore'

class DB
def initialize path = 'photo.db'
@pstore = PStore.new path
end
def []= name, record
address, phone = record

@pstore.transaction do
@pstore[name] = [address, phone]
end
end
def [] name
@pstore.transaction(read_only = true){ @pstore[name] }
end
def each(&block)
@pstore.transaction do
@pstore.roots.each{|name| block.call(name, @pstore[name])}
end
end
def << record
first,last,addr1,addr2,city,zip,home,work,mobile = record
name = Name[first, last]
address = Address[addr1,addr2,city,zip]
phone = Phone[home,work,mobile]
self[name] = [address, phone]
end

Name = Struct.new "Name", :first, :last
Address = Struct.new "Address", :addr1, :addr2, :city, :zip
Phone = Struct.new "Phone", :home, :work, :mobile

[Name, Address, Phone].each{|c| class << c; alias [] new; end}
end

if $0 == __FILE__
db = DB.new

records = [
%w(john doe foo bar boulder 80304 1 2 3),
%w(jane doe bar foo boulder 80305 3 2 1),
]

records.each{|record| db << record}

john = DB::Name['john', 'doe']
jane = DB::Name['jane', 'doe']

db.each do |name, address, phone|
printf "name: %s\naddress: %s\nphone: %s\n\n",
name.inspect, address.inspect, phone.inspect
end

p db[john]
p db[jane]
end


~/eg/ruby > ruby photo.rb

name: #<struct Struct::Name first="john", last="doe">
address: [#<struct Struct::Address addr1="foo", addr2="bar",
city="boulder", zip="80304">, #<struct Struct::phone home="1", work="2",
mobile="3">]
phone: nil

name: #<struct Struct::Name first="jane", last="doe">
address: [#<struct Struct::Address addr1="bar", addr2="foo",
city="boulder", zip="80305">, #<struct Struct::phone home="3", work="2",
mobile="1">]
phone: nil

[#<struct Struct::Address addr1="foo", addr2="bar", city="boulder",
zip="80304"> said:
[#<struct Struct::Address addr1="bar", addr2="foo", city="boulder",
zip="80305"> said:
you can obviously just store the path to the photo this way... the thing with
pstore is that you can tailor the object to meet your needs: perhaps a hash
would be better: it's up to you. also check out madeleine (on RAA) for this
purpose.


-a

Thanks Ara, I'll definitely will try your example above. And check out
madeline as well.
One question though, have you tried the pstore for multi-user or this is
mainly for single user only?

i have used it for multi-user in house applications. i seem to remember you
saying this was for a round 20 users or so - in which case it would be fine.
if you want more you really need to go with postgresql and 'set isolation
level serializable' or deal with transaction conflicts yourself. pstore uses
flock so it supports single writer many reader semantics. note that this is
the same as sqlite - it too uses flock and coarse grained locking internally.
What happen if 2 or more user accessing the same db at the same time?
Thanks

one will block. this is generally pretty easy to deal with by simply
minimizing the amount of time you are writing to the database, for example
use:

value = cgi['value']

pstore.transaction do
pstore[:key] = value
end

vs.

pstore.transaction do
value = cgi['value']
pstore[:key] = value
end

unless you db/updates are _very_ big the time blocked will probably be about
what the connection time would be been if using a rdbms server.

and use read_only = true when possible. note that, if you really want true
concurency your cgi script will become pretty compilcated - especially for
multi page apps which can span several minutes... simply using mysql or
postgresql won't solve think for you.

i would reccomend this:

* abstract the database layer as a class which get records by key, adds
records, deletes records, etc.

* develop your app using pstore or other embedded db

move to a db server iff throughput becomes a problem. the ability to develop
quickly, back up your db using 'tar', move to a new server using 'scp', etc.
are real benefits - plus you do not move outside the ruby installation and
need to involve sysads (eek). rdbms are great but sometimes a little
overkill.

you also might want to check out 'bdb' which is very good and has transaction
support.

-a
--

ATTN: please update your address books with address below!

============================================================================
===
| EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
| PHONE :: 303.497.6469
| ADDRESS :: E/GC2 325 Broadway, Boulder, CO 80305-3328
| STP :: http://www.ngdc.noaa.gov/stp/
| NGDC :: http://www.ngdc.noaa.gov/
| NESDIS :: http://www.nesdis.noaa.gov/
| NOAA :: http://www.noaa.gov/
| US DOC :: http://www.commerce.gov/
|
| The difference between art and science is that science is what we
| understand well enough to explain to a computer.
| Art is everything else.
| -- Donald Knuth, "Discover"
|
| /bin/sh -c 'for l in ruby perl;do $l -e "print \"\x3a\x2d\x29\x0a\"";done'============================================================================
===
 
J

Joel VanderWerf

Matt said:
The old RAA used a pstore to store the data for every ruby project
listed (maybe the new one does too, I don't know). It works fine so
long as your data set is not large -- it reads the *whole* data set
into memory and writes it all back out each time it is opened/closed.

These two problems are part of why I wrote fsdb (on RAA, and at
http://redshift.sourceforge.net/fsdb/). The basic idea is that you
select a directory to be your "database", and FSDB gives you a db object
that has a database interface and accessed that dir and it subdirs:

db = FSDB::Database.new('/tmp')
db['foo/bar'] = {:x => 1}
db.edit 'foo/bar' do |bar|
bar[:x] += 1 # inside transaction
end
db['foo/bar'][:x] # ==> 2

FSDB makes life easy if you have a pre-existing file structure with
various formats, and you want to treat them as a database. You can
define your own mapping from path strings to file formats (e.g., ".txt"
files are read as strings, ".obj" as marshalled objects, etc.;
naturally, you can use regexes.). Also, FSDB is thread-safe and
process-safe.

A quick comparison with PStore:

Like pstore, fsdb is:

- pure ruby, cross-platform (well, not quite there on windows yet--see
below)

- ruby license

- simple API

- simple implementation (though less so)

- transaction based, with abort capability

However, pstore has some drawbacks:

- not thread-safe (though it is process-safe, as far as flock goes)

- coarse granularity (transaction applies to whole pstore), does not
scale well

- uses marshalling, even if your data is is some other format that
doesn't require the overhead of marshalling (e.g., strings, binary data)

Other advantages of fsdb:

- can use YAML (or other formats) where you want to (e.g., in user
settings, but perhaps not for large ruby objects or binary data). It's
easy to specify a mapping from path patterns to data formats.

- thread-safe, so you can easily wire it up to a multithreaded server,
like drb (see examples/server.rb)

- objects in the database are just files, and so can be manipulated with
standard command line tools (including rsync, versioning tools, etc.).

- granularity is up to you: you can have lots of little objects, if you
want (there are tradeoffs, of course)

- scales as well as the fs does

- thoroughly stress-tested, partially unit-tested on linux and solaris.
On windows, all examples, benchmarks, and tests except the stress test
(tests/test-concurrency.rb) run correctly with the ruby 1.8.0
single-click installer edition. (The stress test does run on windows
with ruby 1.8.1 built with mingw, so I'm itching to get /\ndy's 1.8.1.)

- Can select fcntl-based locking (if platform supports it), which should
allow safe use with NFS mounts on linux

Disadvantages of fsdb:

- If you want indexes, you need to implement them on top of fsdb. You
could do:

db['name-index'] = RBTree.new

and define your own methods for adding/removing objects that also
updates the name-index. The name-index maps names (or other keys) to
paths in the db.

- Likewise, no SQL, out of the box.

- Efficiency and reliability depends on the fs. (My benchmarks get on
the order of 1000 transactions per sec on a 3 yr old linux box. Windows
seems a bit slower...)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,150
Latest member
MakersCBDReviews
Top