On Tue, 30 Jan 2007 cmdjackryan / googlemail.com wrote:

> Michael Fellinger wrote:
>
>> 
>> This is just to show that Database itself should take responsibility
>> over creation/checking. It's just a small example but should give you
>> an idea.
>> Tell, don't do :)
>
> Ah, yes, that makes sense. I had to adapt your example to my needs, but that 
> is only a minor thing (I only use File to check if my SQLite database is 
> already existing, and if not, to have a set of SQLite statements create it, 
> which I probably place in their own class, as the SQL can change, and this 
> would provide easier maintenance, and a better re-usability of the code, 
> too).

hopefully you realize this code contains a race condition.  if you use a two
step process to check that the database is created and, if not, to create it -
you risk that another process might create it in between those two steps.  a
cleaner way to do it is to use execptions:


   harp:~ > cat a.rb
   require 'sqlite'

   class Database
     SCHEMA = <<-SCHEMA
       create table t(
         id int,
         data string
       );
     SCHEMA

     def initialize path
       @path = path
       @db = SQLite::Database.new @path
       setup
     end

     def setup
       @db.execute SCHEMA rescue nil
     ensure
       validate_schema
     end

     def validate_schema
       @db.execute 'select * from t limit 1'
     end
   end

   Database.new 'db'

here, the db is always created and initialized with the SCHEMA.  normally
trying to create the table twice would throw an error, which is ingored.
because ignoring this error might mask a real failure to set the db a
simplistic method, in this case, is used to make sure the database looks like
it's supposed to.  note that this whole thing is based on the knowledge that
sqlite uses it's own locking to ensure atmoicity.

in any case, the pattern of

   "try it and recover if it blows up"

is often a good solution where testing a condition and then acting on it
cannot be done in one step to avoid a race condition.

btw.  sqlite and ruby are a good combination - i use them heavily in my own
work.

kind regards.

-a
-- 
we can deny everything, except that we have the possibility of being better.
simply reflect on that.
- the dalai lama