# Path: libeclectus/util.py
# def cachedproperty(fget):
#     def fget_wrapper(self):
#         try: return fget_wrapper._cached
#         except AttributeError:
#             fget_wrapper._cached = value = fget(self)
#             return value
#     def fdel(self):
#         try: del fget_wrapper._cached
#         except AttributeError: pass
#     return property(fget_wrapper, fdel=fdel, doc=fget.__doc__)
# 
# def getDatabaseConfiguration(databaseUrl=None):
#     configuration = {}
#     if databaseUrl:
#         configuration['sqlalchemy.url'] = databaseUrl
#         if databaseUrl.startswith('sqlite://'):
#             configuration['attach'] = ([getDatabaseUrl()]
#                 + getAttachableDatabases())
#     else:
#         configuration['sqlalchemy.url'] = getDatabaseUrl()
#         configuration['attach'] = getAttachableDatabases()
#     return configuration


import re
from sqlalchemy import select
from sqlalchemy.sql import and_, or_
from cjklib.dbconnector import getDBConnector
from cjklib.characterlookup import CharacterLookup
from cjklib import exception
from libeclectus.util import cachedproperty, getDatabaseConfiguration
        @rtype: list of tuples
        @return: list of pairs of matching characters and their glyph
        @todo Impl: Once mapping of similar radical forms exist (e.g. 言 and 訁)
            include here.
        """
        equivCharTable = self.getEquivalentCharTable(componentList,
            includeEquivalentRadicalForms, includeSimilarCharacters)

        characters = self.getCharactersForEquivalentComponents(equivCharTable,
            resultIncludeRadicalForms=resultIncludeRadicalForms,
            includeAllGlyphs=includeAllGlyphs)

        # TODO once we require use an OrderedSet for this, see
        #   http://code.activestate.com/recipes/576694/
        seenChars = set()
        charList = []
        for char, _ in characters:
            if char not in seenChars:
                charList.append(char)
            seenChars.add(char)

        return charList

    def getComponentsWithResults(self, componentList,
        includeEquivalentRadicalForms=False, includeSimilarCharacters=False):
        u"""
        Gets a list of minimal components which can be added to the given list
        of components so that the narrower search will still yield results.

        If option C{includeEquivalentRadicalForms} is set, all equivalent forms

# Path: libeclectus/util.py
# def cachedproperty(fget):
#     def fget_wrapper(self):
#         try: return fget_wrapper._cached
#         except AttributeError:
#             fget_wrapper._cached = value = fget(self)
#             return value
#     def fdel(self):
#         try: del fget_wrapper._cached
#         except AttributeError: pass
#     return property(fget_wrapper, fdel=fdel, doc=fget.__doc__)
# 
# def getDatabaseConfiguration(databaseUrl=None):
#     configuration = {}
#     if databaseUrl:
#         configuration['sqlalchemy.url'] = databaseUrl
#         if databaseUrl.startswith('sqlite://'):
#             configuration['attach'] = ([getDatabaseUrl()]
#                 + getAttachableDatabases())
#     else:
#         configuration['sqlalchemy.url'] = getDatabaseUrl()
#         configuration['attach'] = getAttachableDatabases()
#     return configuration


# Path: libeclectus/chardb.py
import re
from sqlalchemy import select
from sqlalchemy.sql import and_, or_
from cjklib.dbconnector import getDBConnector
from cjklib.characterlookup import CharacterLookup
from cjklib import exception
from libeclectus.util import cachedproperty, getDatabaseConfiguration

        @rtype: list of tuples
        @return: list of pairs of matching characters and their glyph
        @todo Impl: Once mapping of similar radical forms exist (e.g. 言 and 訁)
            include here.
        """
        equivCharTable = self.getEquivalentCharTable(componentList,
            includeEquivalentRadicalForms, includeSimilarCharacters)

        characters = self.getCharactersForEquivalentComponents(equivCharTable,
            resultIncludeRadicalForms=resultIncludeRadicalForms,
            includeAllGlyphs=includeAllGlyphs)

        # TODO once we require use an OrderedSet for this, see
        #   http://code.activestate.com/recipes/576694/
        seenChars = set()
        charList = []
        for char, _ in characters:
            if char not in seenChars:
                charList.append(char)
            seenChars.add(char)

        return charList

    def getComponentsWithResults(self, componentList,
        includeEquivalentRadicalForms=False, includeSimilarCharacters=False):
        u"""
        Gets a list of minimal components which can be added to the given list
        of components so that the narrower search will still yield results.

        If option C{includeEquivalentRadicalForms} is set, all equivalent forms

        will be searched for when a Kangxi radical is given.