wsjp.py 6.62 KB
# -*- coding: utf-8 -*-
from django.db import connection
from dictionary.models import LexemeAttributeValue, LexemeInflectionPattern, \
    LexemeAttribute


BASE_QUERY = '''
    select distinct pref||rdzen||zak||suf slowo, %(haslo_tab)s, hom,
      l.pos,
      case when l.pos in ('subst','osc','v') then p.charfl else '' end
      as rodzaj, podparad, %(row)s, col, rowspan, colspan, kskl
    from
      odmieniasie o
      join leksemy l on (o.l_id = l.id)
      left outer join dictionary_lexemeav refl
        on (l.id = refl.lexeme_id and refl.attribute_value_id in (%(refl)s))
      join wzory on (o.w_id = wzory.id)
      join typywzorow tw on (wzory.typ = tw.id)
      join paradygmatywsjp p
        on (%%s = p.charfl and wzory.typ = p.typr and l.pos = p.pos)
      join zakonczenia z on (o.w_id = z.w_id and p.efobaz = z.efobaz)
    where slownik in ('SGJP', 'WSJP') and
      o.id=%%s and %(leks_clause)s and wariant=%%s
'''

NESTED_BASE = '''
    select rdzen||zak||suf slowo, %(haslo)s, g.hom, l.pos,
      case when l.pos = 'ppas' then p.charfl else '' end as rodzaj,
      podparad, row, col, rowspan, colspan, kskl
    from
      leksemy l
      join odsylacze ods on l.id = l_id_od
      join typyodsylaczy tods on ods.typods_id = tods.id
      join leksemy g on l_id_do = g.id
      left outer join dictionary_lexemeav refl
        on (g.id = refl.lexeme_id and refl.attribute_value_id in (%(refl)s))
      join odmieniasie o
        on case when l.pos = 'ppas' then g.id else l.id end = o.l_id
      join wzory on (o.w_id = wzory.id)
      join paradygmatywsjp p
        on (%%s = p.charfl and wzory.typ = p.typr and l.pos = p.pos)
      join zakonczenia z on (o.w_id = z.w_id and p.efobaz = z.efobaz)
    where l.slownik in ('SGJP', 'WSJP') and
      g.id=%%s and %(main_clause)s
'''

ZLOZ = LexemeAttribute.objects.get(name=u'forma złoż.')
POPRZ = LexemeAttribute.objects.get(name=u'forma poprz.')
ASPEKT = LexemeAttribute.objects.get(name=u'aspekt')
WLASC = LexemeAttribute.objects.get(name=u'właściwy')

def get_charfl(lip):
    l = lip.lexeme
    pos = l.part_of_speech_id
    if pos == 'adj':
        zloz = l.attribute_value(ZLOZ).value == u'obecna'
        poprz = l.attribute_value(POPRZ).value == u'obecna'
        if not zloz and not poprz:
            return '0-'
        elif zloz and poprz:
            return '3+'
        else: # jest złoż, nie ma poprz
            return ''
    elif pos in ('ger', 'ppas'):
        return l.attribute_value(ASPEKT).value
    elif pos == 'osc':
        return 'f'
    elif pos == 'pred':
        return 'qndk'
    elif pos == 'subst':
        return lip.gender.symbol
    elif pos == 'v':
        wlasc = l.attribute_value(WLASC).value
        return ('q' if wlasc == 'Q' else '') + l.attribute_value(ASPEKT).value
    else:
        return ''


def make_data(entry):
    refls = dict(LexemeAttributeValue.objects.filter(
        attribute__name=u'zwrotność').values_list('pk', 'value'))
    refl_ids = ', '.join(str(pk) for pk in refls)
    refls_rev = dict(LexemeAttributeValue.objects.filter(
        attribute__name=u'zwrotność').values_list('value', 'pk'))
    nonrefl = [refls_rev[v] for v in (u'—', u'(się)', u'(sobie)')]
    nonrefl_ids = ', '.join(str(pk) for pk in nonrefl)
    empty_refl = refls_rev[u'—']
    lips = LexemeInflectionPattern.objects.filter(lexeme__entry=entry)
    if not lips:
        return []
    subqueries = []
    params = []
    for lip in lips:
        charfl = get_charfl(lip)
        pattern = lip.pattern
        fnuni = pattern.endings.filter(base_form_label__symbol='pl:gen:fnuni').exists()
        funi = pattern.endings.filter(base_form_label__symbol='pl:gen:funi').exists()
        if fnuni and not funi:
            row = '''case when row = 5 and col = 3 then 4 else row end'''
        else:
            row = 'row'
        common_fields = {
            'refl': refl_ids,
            'row': row,
        }
        query_parts = [
            (
                BASE_QUERY,
                {
                    'haslo_tab': 'haslo',
                    'haslo': 'haslo',
                    'leks_clause': '''l.pos not in ('skrl','skrw') and
                        (l.pos != 'v' or refl.attribute_value_id in (%s))''' % nonrefl_ids,
                },
                [charfl, lip.id, '1']
            ),
            # czasowniki sięiczne:
            (
                BASE_QUERY,
                {
                    'haslo_tab': u"haslo||' się'",
                    'haslo': 'haslo',
                    'leks_clause': '''(l.pos='v' and refl.attribute_value_id <> %s)''',
                },
                [charfl, lip.id, empty_refl, 's']
            ),
            # czasowniki zanegowane:
            (
                BASE_QUERY,
                {
                    'haslo_tab': "'nie '||haslo",
                    'haslo': "'nie '||haslo",
                    'leks_clause': '''l.pos='v' and refl.attribute_value_id in (%s)'''
                                   % nonrefl_ids,
                },
                [charfl, lip.id, 'n']
            ),
            # czasowniki sięiczne zanegowane:
            (
                BASE_QUERY,
                {
                    'haslo_tab': u"'nie '||haslo||' się'",
                    'haslo': "'nie '||haslo",
                    'leks_clause': '''(l.pos='v' and refl.attribute_value_id <> %s)''',
                },
                [charfl, lip.id, empty_refl, 'ns']
            ),
            # wymagające gniazdowania: adjcom, advcom i ppas
            (
                NESTED_BASE,
                {
                    'haslo': 'g.haslo',
                    'main_clause': '''typods in ('comadj','comadv','ppasver') and
                        l.pos in ('adjcom','advcom','ppas') and
                        (l.pos != 'ppas' or refl.attribute_value_id in (%s))'''
                                   % nonrefl_ids,
                },
                [charfl, lip.lexeme_id]
            ),
            # imiesłowy bierne czasowników sięicznych:
            (
                NESTED_BASE,
                {
                    'haslo': u"g.haslo||' się'",
                    'main_clause': '''(typods ='ppasver' and l.pos ='ppas' and
                        refl.attribute_value_id <> %s)''',
                },
                [charfl, lip.lexeme_id, empty_refl]
            )
        ]
        subqueries.extend(
            qp[0] % dict(common_fields.items() + qp[1].items())
            for qp in query_parts)
        for qp in query_parts:
            params += qp[2]
    cursor = connection.cursor()
    cursor.execute(' union all '.join(subqueries) + '''
        order by haslo, hom, rodzaj, podparad, row, col, kskl, slowo
    ''', params)
    return list(cursor)