Esempio n. 1
0
    def update(cls, key, src):
        """
        Make sure we have the most beautiful mapping for the given keyname in
        the table.
        """
        assert isinstance(key, str) and isinstance(src, unicode)
        conn, cursor = dbpool().connection(1)
        try:
            try:
                o = cls.get(conn, keyname=key)

                # We use the longest utf-8 encoded string, thinking that the
                # more accents the string has the more space it takes, and that
                # the more accents it has, the better.  This is rather
                # simplistic, but it seems to do what I need for location names.
                if len(src.encode('utf-8')) > len(o.srcname.encode('utf-8')):
                    cursor.execute(
                        '''
                       UPDATE location_pretty
                         SET srcname = %s
                         WHERE keyname = %s
                    ''', (src, key))
                    conn.commit()
            except MormError:
                cursor.execute(
                    '''
                   INSERT INTO location_pretty
                      (keyname, srcname)
                      VALUES (%s, %s)
                ''', (key, src))
                conn.commit()
        finally:
            conn.release()
Esempio n. 2
0
    def astree(cls):
        """
        Produce a tree of location names, from all the information in the
        database.  Return a tree of nodes, each consisting in (name, children)
        pairs (tuples).
        """
        conn, cursor = dbpool().connection(1)
        try:
            # Note: this is a terribly inefficient algorithm, and we don't care,
            # because it is meant to be used for debugging only.
            cursor.execute("""
               SELECT name FROM location_ordering
             """)
            dec = MormDecoder(cls, cursor)
            plocs = set()
            for o in dec.iter(cursor):
                resolved = cls.resolve([o.name])
                # This reduction here could be instead done in a single step.
                plocs.add(tuple(reversed(PrettyLocations.beautify(resolved))))

            locmap = {None: ('<World>', [])}
            for loclist in sorted(plocs):
                newname = loclist[-1]
                if len(loclist) == 1:
                    parent = None
                else:
                    parent = loclist[-2]
                l = locmap[newname] = (newname, [])
                locmap[parent][1].append(l)

            tree = locmap[None]

            return tree
        finally:
            conn.release()
Esempio n. 3
0
def drop_sql(schemas):
    """
    Drop the given list of schemes.
    """
    dbapi = dbpool().module()
    conn, cursor = dbpool().connection(1)
    try:
        cursor.execute("""
          SELECT table_name FROM information_schema.tables
        """)
        tables = set(x[0] for x in cursor.fetchall())

        names = [x for x, s in schemas if x in tables]
        for n in names:
            try:
                cursor.execute('DROP TABLE "%s" CASCADE' % n)
                conn.commit()
            except dbapi.Error:
                conn.rollback() # ignore errors due to dependencies.
    finally:
        conn.release()
Esempio n. 4
0
def drop_sql(schemas):
    """
    Drop the given list of schemes.
    """
    dbapi = dbpool().module()
    conn, cursor = dbpool().connection(1)
    try:
        cursor.execute("""
          SELECT table_name FROM information_schema.tables
        """)
        tables = set(x[0] for x in cursor.fetchall())

        names = [x for x, s in schemas if x in tables]
        for n in names:
            try:
                cursor.execute('DROP TABLE "%s" CASCADE' % n)
                conn.commit()
            except dbapi.Error:
                conn.rollback() # ignore errors due to dependencies.
    finally:
        conn.release()
Esempio n. 5
0
 def beautify(cls, keynames):
     """
     Given a sequence of keynames, find the prettier versions of those names
     and return a sequence of beautified words.  This essentially maps via
     the pretty words table map.
     """
     conn, cursor = dbpool().connection_ro(1)
     try:
         pnames = []
         for kname in keynames:
             o = cls.get(conn, keyname=kname)
             pnames.append(o.srcname)
         return pnames
     finally:
         conn.release()
Esempio n. 6
0
        def setUp(self):
            antipool.initpool(
                antipool.ConnectionPool(dbapi, database='test', user='******'))

            conn, cursor = dbpool().connection(1)
            for name, stype, entity in schemas:
                query = "DROP %s %s;" % (stype, name)
                try:
                    cursor.execute(query)
                    conn.commit()
                except dbapi.Error:
                    conn.rollback()

            for name, stype, entity in schemas:
                cursor.execute(entity)

            conn.commit()
Esempio n. 7
0
    def search(cls, terms):
        """
        Run a search on the keynames, and then resolve all the matching ones.
        Return a list of resolved sequences.
        """
        conn, cursor = dbpool().connection_ro(1)
        try:
            cursor.execute(
                """
              SELECT DISTINCT name FROM location_ordering
                WHERE name LIKE %s
            """, ('%%%s%%' % '%'.join(terms), ))
            it = [x[0] for x in cursor.fetchall()]
        finally:
            conn.release()

        return [Locations.resolve_name(name.decode('UTF-8')) for name in it]
Esempio n. 8
0
def initialize_sql(schemas):
    """
    Insures that the given schemas are created.
    """
    conn, cursor = dbpool().connection(1)
    try:
        cursor.execute("""
          SELECT table_name FROM information_schema.tables
        """)
        tables = set(x[0] for x in cursor.fetchall())

        for table_name, schema in schemas:
            if table_name not in tables:
                logging.info('Creating SQL schema %s' % table_name)
                cursor.execute(schema)

        conn.commit()
    finally:
        conn.release()
Esempio n. 9
0
def initialize_sql(schemas):
    """
    Insures that the given schemas are created.
    """
    conn, cursor = dbpool().connection(1)
    try:
        cursor.execute("""
          SELECT table_name FROM information_schema.tables
        """)
        tables = set(x[0] for x in cursor.fetchall())

        for table_name, schema in schemas:
            if table_name not in tables:
                logging.info('Creating SQL schema %s' % table_name)
                cursor.execute(schema)

        conn.commit()
    finally:
        conn.release()
Esempio n. 10
0
    def add(cls, location_field):
        """
        Given a string that represents a place in the world, split it and add
        its contents to the table of orderings.  Return a new location id for
        the given location field.  If you pass in strings, they will be assumed
        to be encoded in UTF-8 encoding (the better way is to do the decoding on
        your side and pass in unicode objects).
        """
        if not isinstance(location_field, unicode):
            location_field = location_field.decode('utf-8')

        keysrc_pairs = field2both(location_field)
        words = [x[0] for x in keysrc_pairs]

        conn, cursor = dbpool().connection(1)
        try:
            # FIXME: Eventually we want to be able to recycle the location
            # ids, because we're going to overflow.
            cursor.execute("""
               SELECT nextval('locid_seq');
             """)
            locid = cursor.fetchone()[0]

            it = izip([None] + words, words + [None])
            it.next()
            for w1, w2 in it:
                cursor.execute(
                    '''
                   INSERT INTO location_ordering
                      (locid, name, parent)
                      VALUES (%s,  %s, %s)
                ''', (locid, w1, w2))

            for key, src in keysrc_pairs:
                PrettyLocations.update(key, src)

            conn.commit()
            return locid
        finally:
            conn.release()
Esempio n. 11
0
    def resolve(cls, location_names):
        """
        Given a sequence of potentially incomplete location names, resolve the
        location into the full list of location names.  The full table is used
        to resolve the given name to its fullest.  If the result is ambiguous,
        return None; Otherwise return a sequence of the full list of names.
        """
        conn, cursor = dbpool().connection(1)
        try:
            # First fetch all the possible database relations starting from the
            # first name.  We do this to avoid querying the database twice for
            # nothing (we cache all the required information in a dict).
            firstname = location_names[0]

            rels = {}
            todo = [firstname]
            while todo:
                cur = todo.pop()
                if cur in rels:
                    continue

                cursor = conn.cursor()
                cursor.execute(
                    """
                   SELECT DISTINCT parent FROM location_ordering
                     WHERE name = %s
                 """, (cur, ))
                if cursor.rowcount > 0:
                    parents = [
                        x.parent
                        for x in cls.decoder(('parent', )).iter(cursor)
                    ]

                    rels[cur] = parents
                    todo.extend(parents)

        finally:
            conn.release()

        # Not found.
        if not rels:
            return []

        # Compute all the possible paths that end with None.  Detect cycles.
        def rec(curnode, path, paths):
            path.append(curnode)
            for sub in rels[curnode]:
                if sub is None:
                    paths.append(list(path))
                else:
                    rec(sub, path, paths)
            path.pop(-1)

        paths = []
        rec(firstname, [], paths)

        # Filter out the paths that are not supersets of our set of words.
        nameset = frozenset(location_names)
        paths = [x for x in paths if nameset.issubset(x)]

        # Take the longest.
        paths.sort(key=len, reverse=1)
        longest = paths[0]

        # Make sure all the other ones are subsets of the longest.
        longest_set = frozenset(longest)
        for other in paths[1:]:
            if not frozenset(other).issubset(longest_set):
                raise ValueError("Ambiguous path: %s" % other)

        return longest