#
# Import modules from a database
#
import sys, db, marshal
conn = db.conn()
curs = conn.cursor()

curs.execute("select modName from module where modPyVersion=%s", (sys.hexversion, ))
impdict = {}
for n in [x[0] for x in curs.fetchall()]:
    impdict[n] = 1

class DBmodule(type(sys)):
    def __repr__(self):
        return "<DBmodule '%s' from '%s'>" % (self.__name__, self.__file__)

class dbimporter(object):

    def __init__(self, item, *args, **kw):
        if item != "*db*":
            raise ImportError
        #print "dbimporter: item:", id(self), item, "args:", args, "keywords:", kw
        #print "Accepted", item

    def find_module(self, fullname, path=None):
        #print "%x: find_module: %s from %s" % (id(self), fullname, path)
        if fullname not in impdict:
            #print "Bailed on", fullname
            return None
        else:
            #print "found", fullname, "in db"
            return self

    def load_module(self, modname):
        #print "%x: load_module: %s" % (id(self), modname)
        if modname in sys.modules:
            return sys.modules[modname]
        curs.execute("select modCode, modPackage, modFilePath from module where modName=%s", (modname, ))
        row = curs.fetchone() # should only BE one ...S
        if not row:
            #print modname, "not found in db"
            raise ImportError, "DB module %s not found in modules"
        code, package, path = row
        code = marshal.loads(code)
        module = DBmodule(modname)
        sys.modules[modname] = module
        module.__name__ = modname
        module.__file__ = path # was "db:%s" % modname
        module.__loader__ = self
        if package:
            module.__path__ = ["*db*"]
        exec code in module.__dict__
        #print modname, "loaded:", module, "pkg:", package

        return module


def install():
    sys.path_hooks.append(dbimporter)
    sys.path_importer_cache.clear() # probably not necessary
    sys.path.insert(0, "*db*") # probably not needed with a metea-path hook?


