# Path: glottolog3/models.py
# class TreeClosureTable(Base):
#     __table_args__ = (UniqueConstraint('parent_pk', 'child_pk'),)
#     parent_pk = Column(Integer, ForeignKey('languoid.pk'))
#     child_pk = Column(Integer, ForeignKey('languoid.pk'))
#     depth = Column(Integer)


import json
import pathlib
from clld.db.meta import DBSession
from clld.db.models import common
from clldutils import misc
from clldutils.text import split_text
from glottolog3.models import TreeClosureTable
                **vskw)
        vkw = dict(id=idjoin(pid, slug(vid), dblang.id), name=vname, valueset=vs)
        if with_de:
            vkw['domainelement'] = data['DomainElement'][pid, vid]
        DBSession.add(common.Value(**vkw))


def idjoin(*args):
    if len(args) == 1 and isinstance(args[0], (tuple, list)):
        args = args[0]  # pragma: no cover
    return '-'.join(['{0}'.format(a) for a in args])


def slug(s, escape=False, **kw):
    # That's some weird stuff coming in with ElCat alternative names ...
    return misc.slug(''.join(hex(ord(c)) if escape else c for c in s if ord(c) != 2), **kw)


def recreate_treeclosure(session=None):
    """
    Denormalize ancestry, top-level and descendant counts for languoids.

    Recreates treeclosuretable and updates the following attributes of languoids:
    - family_pk
    - child_family_count
    - child_language_count
    - child_dialect_count
    """
    if session is None:
        session = DBSession

# Path: glottolog3/models.py
# class TreeClosureTable(Base):
#     __table_args__ = (UniqueConstraint('parent_pk', 'child_pk'),)
#     parent_pk = Column(Integer, ForeignKey('languoid.pk'))
#     child_pk = Column(Integer, ForeignKey('languoid.pk'))
#     depth = Column(Integer)


# Path: glottolog3/scripts/util.py
import json
import pathlib
from clld.db.meta import DBSession
from clld.db.models import common
from clldutils import misc
from clldutils.text import split_text
from glottolog3.models import TreeClosureTable

                **vskw)
        vkw = dict(id=idjoin(pid, slug(vid), dblang.id), name=vname, valueset=vs)
        if with_de:
            vkw['domainelement'] = data['DomainElement'][pid, vid]
        DBSession.add(common.Value(**vkw))


def idjoin(*args):
    if len(args) == 1 and isinstance(args[0], (tuple, list)):
        args = args[0]  # pragma: no cover
    return '-'.join(['{0}'.format(a) for a in args])


def slug(s, escape=False, **kw):
    # That's some weird stuff coming in with ElCat alternative names ...
    return misc.slug(''.join(hex(ord(c)) if escape else c for c in s if ord(c) != 2), **kw)


def recreate_treeclosure(session=None):
    """
    Denormalize ancestry, top-level and descendant counts for languoids.

    Recreates treeclosuretable and updates the following attributes of languoids:
    - family_pk
    - child_family_count
    - child_language_count
    - child_dialect_count
    """
    if session is None:
        session = DBSession

    session.execute(TreeClosureTable.__table__.delete())