# A handle object for convenience in opening a svn repository

import sys

# We need a bsddb linked to the same version of Berkeley DB as Subversion is
try:
  import bsddb3 as bsddb
except ImportError:
  import bsddb

# Publish the result
sys.modules['svnfs_bsddb'] = bsddb

from svnfs_bsddb.db import *

class Ctx:
  def __init__(self, dbhome, readonly=None):
    self.env = self.uuids_db = self.revs_db = self.txns_db = self.changes_db \
        = self.copies_db = self.nodes_db = self.reps_db = self.strings_db = \
        None
    try:
      self.env = DBEnv()
      self.env.set_lk_detect(DB_LOCK_RANDOM)
      self.env.set_get_returns_none(1)
      self.env.open(dbhome, DB_CREATE | DB_INIT_MPOOL | DB_INIT_TXN \
          | DB_INIT_LOCK | DB_INIT_LOG)
      def open_db(dbname):
        db = DB(self.env)
        dbflags = 0
        if readonly:
          dbflags = DB_RDONLY
        db.open(dbname, flags=dbflags)
        return db
      self.uuids_db   = open_db('uuids')
      self.revs_db    = open_db('revisions')
      self.txns_db    = open_db('transactions')
      self.changes_db = open_db('changes')
      self.copies_db  = open_db('copies')
      self.nodes_db   = open_db('nodes')
      self.reps_db    = open_db('representations')
      self.strings_db = open_db('strings')
    except:
      self.close()
      raise
  
  def close(self):
    def close_if_not_None(i):
      if i is not None:
        i.close()
    close_if_not_None(self.uuids_db   )    
    close_if_not_None(self.revs_db    )    
    close_if_not_None(self.txns_db    )    
    close_if_not_None(self.changes_db )    
    close_if_not_None(self.copies_db  )    
    close_if_not_None(self.nodes_db   )    
    close_if_not_None(self.reps_db    )    
    close_if_not_None(self.strings_db )    
    close_if_not_None(self.env        )    
    self.env = self.uuids_db = self.revs_db = self.txns_db = self.changes_db \
        = self.copies_db = self.nodes_db = self.reps_db = self.strings_db = \
        None

  # And now, some utility functions
  def get_whole_string(self, key):
    cur = self.strings_db.cursor()
    try:
      rec = cur.set(key)
      if rec is None:
        raise DBNotFoundError
      str = ""
      while rec:
        str = str + (rec[1] or "")
        rec = cur.next_dup()
    finally:
      cur.close()
    return str  

