Generates python code (or class objects if code is false)
    based on SQL queries on the table names given in the list
    tables.

    code -- if given -- should be an dictionary containing these
    keys to be inserted into generated code:
         'database':  database name
         'module':    database module name
         'connect':   string to be inserted into module.connect()

def generateFromTables(tables, cursor, getLinks=1, code=0):
    """Generates python code (or class objects if code is false)
    based on SQL queries on the table names given in the list
    tables.

    code -- if given -- should be an dictionary containing these
    keys to be inserted into generated code:
         'database':  database name
         'module':    database module name
         'connect':   string to be inserted into module.connect()
    """
    curs = cursor()
    forgetters = {}
    class _Wrapper(forgetSQL.Forgetter):
        _autosave = False
        pass
    _Wrapper.cursor = cursor
    for table in tables:
        # capitalize the table name to make it look like a class
        name = table.capitalize()
        # Define the class by instanciating the meta class to
        # the given name (requires Forgetter to be new style)
        forgetter = _Wrapper.__class__(name, (_Wrapper,), {})
        # Register it
        forgetters[name] = forgetter
        forgetter._sqlTable = table
        forgetter._sqlLinks = {}
        forgetter._sqlFields = {}
        forgetter._shortView = ()
        forgetter._descriptions = {}
        forgetter._userClasses = {}

        # Get columns
        curs.execute("SELECT * FROM %s LIMIT 1" % table)
        columns = [column[0] for column in curs.description]
        # convert to dictionary and register in forgetter
        for column in columns:
            forgetter._sqlFields[column] = column

    if getLinks:
        # Try to find links between tables (!)
        # Note the big O factor with this ...

        for (tableName, forgetter) in forgetters.items():
            for (key, column) in forgetter._sqlFields.items():
                # A column refering to another table would most likely
                # be called otherColumnID or just otherColumn. We'll
                # lowercase below when performing the test.
                possTable = re.sub(r'_?id$', '', column)

                # all tables (ie. one of the forgetters) are candidates
                foundLink = False
                for candidate in forgetters.keys():
                    if candidate.lower() == possTable.lower():
                        if possTable.lower() == tableName.lower():
                            # It's our own primary key!
                            forgetter._sqlPrimary = (column,)
                            break

                        # Woooh! First - let's replace 'blapp_id' with 'blapp'
                        # as the attribute name to indicate that it would
                        # contain the Blapp instance, not just
                        # some ID.
                        del forgetter._sqlFields[key]
                        forgetter._sqlFields[possTable] = column

                        # And.. we'll need to know which class we refer to
                        forgetter._userClasses[possTable] = candidate
                        break # we've found our candidate

    if code:
        if code['module'] == "MySQLdb":
            code['class'] = 'forgetSQL.MysqlForgetter'
        else:
            code['class'] = 'forgetSQL.Forgetter'
        code['date'] = time.strftime('%Y-%m-%d')
        print '''
"""Database wrappers %(database)s
Autogenerated by forgetsql-generate %(date)s.
"""

import forgetSQL

#import %(module)s

class _Wrapper(%(class)s):
    """Just a simple wrapper class so that you may
    easily change stuff for all forgetters. Typically
    this involves subclassing MysqlForgetter instead."""

    # Only save changes on .save()
    _autosave = False

    # Example database connection (might lack password)
    #_dbModule = %(module)s
    #_dbConnection = %(module)s.connect(%(connect)s)
    #def cursor(cls):
    #    return cls._dbConnection.cursor()
    #cursor = classmethod(cursor)

''' % code
        items = forgetters.items()
        items.sort()
        for (name, forgetter) in items:
            print "class %s(_Wrapper):" % name
            for (key, value) in forgetter.__dict__.items():
                if key.find('__') == 0:
                    continue
                nice = pprint.pformat(value)
                # Get some indention
                nice = nice.replace('\n', '\n             ' + ' '*len(key))
                print '        %s = ' % key, nice
            print ""
        print '''

# Prepare them all. We need to send in our local
# namespace.
forgetSQL.prepareClasses(locals())
'''
    else:
        prepareClasses(forgetters)
        return forgetters