%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /usr/share/ibus-table/engine/__pycache__/
Upload File :
Create Path :
Current File : //usr/share/ibus-table/engine/__pycache__/tabsqlitedb.cpython-312.pyc

�

��Xe
���dZddlmZddlmZddlmZddlmZddlmZddlmZddlmZdd	l	Z	dd	l
mZdd	lZdd	l
Z
dd	lZdd	lZdd	lZdd	lZdd	lZdd	lZdd	lZej*d
�Zed�adZdZGd
�d�ZGd�d�Zy	)z7
Module for ibus-table to access the sqlite3 databases
�)�List)�Tuple)�Iterable)�Dict)�Union)�Optional)�CallableNz
ibus-table�1.00u!“”‘’《》〈〉〔〕「」『』【】〖〗()[]{}.。,、;:?!…—·ˉˇ¨々~‖∶"'`|⒈⒉⒊⒋⒌⒍⒎⒏⒐⒑⒒⒓⒔⒕⒖⒗⒘⒙⒚⒛АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯЁⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫ⒈⒉⒊⒋⒌⒍⒎⒏⒐⒑⒒⒓⒔⒕⒖⒗⒘⒙⒚⒛㎎㎏㎜㎝㎞㎡㏄㏎㏑㏒㏕ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ⑴⑵⑶⑷⑸⑹⑺⑻⑼⑽⑾⑿⒀⒁⒂⒃⒄⒅⒆⒇€$¢£¥¤→↑←↓↖↗↘↙ァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅテデトドナニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵヶーヽヾぁあぃいぅうぇえぉおかがきぎぱくぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはばひびぴふぶぷへべぺほぼぽまみむめもゃやゅゆょよらりるれろゎわゐゑをん゛゜ゝゞ勹灬冫艹屮辶刂匚阝廾丨虍彐卩钅冂冖宀疒肀丿攵凵犭亻彡饣礻扌氵纟亠囗忄讠衤廴尢夂丶āáǎàōóǒòêēéěèīíǐìǖǘǚǜüūúǔù+-<=>±×÷∈∏∑∕√∝∞∟∠∣∥∧∨∩∪∫∮∴∵∶∷∽≈≌≒≠≡≤≥≦≧≮≯⊕⊙⊥⊿℃°‰♂♀§№☆★○●◎◇◆□■△▲※〓#&@\^_ ̄абвгдежзийклмнопрстуфхцчшщъыьэюяёⅰⅱⅲⅳⅴⅵⅶⅷⅸⅹβγδεζηαικλμνξοπρστυφθψω①②③④⑤⑥⑦⑧⑨⑩①②③④⑤⑥⑦⑧⑨⑩㈠㈡㈢㈣㈤㈥㈦㈧㈨㈩㈠㈡㈢㈣㈤㈥㈦㈧㈨㈩ㄅㄆㄇㄈㄉㄊㄋㄌㄍㄎㄏㄐㄑㄒㄓㄔㄕㄖㄗㄘㄙㄧㄨㄩㄚㄛㄜㄝㄞㄟㄠㄡㄢㄣㄤㄥㄦc��eZdZdZ		d
deejjdeee	e	fddfd�Z
de	de	fd�Zde	fd	�Zy)�
ImePropertiesz=
    A class to cache the properties of an input method.
    N�db�default_properties�returnc���|�i}|sy||_d}	|j|�j�}D]}|d|j|d<�y#tj	d�Y�6xYw)ul
        “db” is the handle of the sqlite3 database file obtained by
        sqlite3.connect().
        NzSELECT attr, val FROM main.ime;z'Cannot get ime properties from database�r)�ime_property_cache�execute�fetchall�LOGGER�	exception)�selfr
r�sqlstr�results�results      �+/usr/share/ibus-table/engine/tabsqlitedb.py�__init__zImeProperties.__init__Ws����%�!#����"4���2��	H��j�j��(�1�1�3�G��	;�F�17���D�#�#�F�1�I�.�	;��	H����F�G�s�A�A'�keyc�>�||jvr|j|Sy)z�
        Return the value for a key from the property cache

        :param key: The key to lookup in the property cache
        �)r)rrs  r�getzImeProperties.getls&���$�)�)�)��*�*�3�/�/��c�2�dt|j�zS)Nzime_property_cache = %s)�reprr�rs r�__str__zImeProperties.__str__vs��(�$�t�/F�/F�*G�G�Gr!)NN)
�__name__�
__module__�__qualname__�__doc__r�sqlite3�dbapi2�
Connectionr�strrr r%�r!rrrSso���
7;�;?�;�����2�2�3�;�!)��c�3�h�� 8�;�EI�;�*�s��s��H��Hr!rc��eZdZdZ				dNdededededdf
d�Z					dOd	ed
ededed
eddfd�ZdPd�Z	dPd�Z
dQd	eddfd�ZdPd�ZdPd�Z
defd�Zdefd�Zdefd�Zdefd�Zdefd�Zdeddfd�Zdeeeefddfd�Zdeeeefeeeeeeffffd�Zdeefd�Zdefd�Zdefd�Z	dRd eeeeeefdeddfd!�Z						dSd	ed
ed"ededed
eddfd#�Zd$eeeefddfd%�Z 	dRd&eeeeefdeddfd'�Z!	dRd(eeeefdeddfd)�Z"dPd*�Z#d+eddfd,�Z$dTd+ed-eddfd.�Z%d
ede&fd/�Z'			dUd0ed1eeeeeefd2edeeeeeeffd3�Z(							dVd	ed4ed2ed5ed6ed7ed8edeeeeeeffd9�Z)				dWd	ed2ed5ed6edeeeeeeff
d:�Z*	dQd;edeeeeffd<�Z+dPd=�Z,d>eddfd?�Z-d>ede.eeeffd@�Z/d>edefdA�Z0dBedefdC�Z1d
edefdD�Z2	dXd	ed
edefdE�Z3dXd	ed
edefdF�Z4			dYd	ed
ed8eddfdG�Z5d
edeefdH�Z6				dZd	ed
eded
eddf
dI�Z7dPdJ�Z8		d[dKedLedeeeeeeffdM�Z9y)\�TabSqliteDbu�Phrase database for tables

    The phrases table in the database has columns with the names:

    “id”, “tabkeys”, “phrase”, “freq”, “user_freq”

    There are 2 databases, sysdb, userdb.

    sysdb: System database for the input method, for example something
           like /usr/share/ibus-table/tables/wubi-jidian86.db
           “user_freq” is always 0 in a system database.  “freq”
           is some number in a system database indicating a frequency
           of use of that phrase relative to the other phrases in that
           database.

    user_db: Database on disk where the phrases used or defined by the
           user are stored. “user_freq” is a counter which counts how
           many times that combination of “tabkeys” and “phrase” has
           been used. “freq” is equal to 0 for all combinations of
           “tabkeys” and “phrase” where an entry for that phrase is
           already in the system database which starts with the same
           “tabkeys”.
           For combinations of “tabkeys” and “phrase” which do not exist
           at all in the system database, “freq” is equal to -1 to
           indidated that this is a user defined phrase.
    �filename�user_db�create_database�	unit_testrNc�l�	tttjd���ag|_||_||_	|j�|s)tjj|j�r%tj|j�|_nt!d|jz�	|jj#d�|jj#d�|jj#d�|jj#d�|jj#d�|jj#d	�|jj#d
�|jj)d�id
d�dd�dd�dd�dd�ddt+j,�z�ddt/j0d�z�dd�dd�dd�dd�dd�d d!�d"d#�d$d%�d&d'�d(d)�id*d�d+d,�d-d.�d/d.�d0d.�d1d.�d2d.�d3d.�d4d.�d5d,�d6d7�d8d9�d:d�d;d�d<d=�d>d�d?d,��d,d@dA��|_|rwdB}dC}t5|j2�D][}||j2|dD�}|jj#||�j7�r�@|jj#||��]t9|j|j2�E�|_t|j:j=d ��|_|j:j=d�|_ |jC�|_"|jG�|_$|j:j=d/�jK�d,k(|_&|jO�|_(|jS�|_*|jW�|_,tjZt]j^�dF�}	tjja|j�jcdGdH�}
tjZ|	|
�|_2|s|jg�|r|ry|dIk7�r-tjh|	��sxtjjkdJ�}tjh|��r,tjltjj[|dK�tjn�r3tjptjj[|dK��tjltjj[|dL�tjn�r3tjptjj[|dL��tsjt||	�tsjv|�tjx|	|�ntjz|	dM�N�tjZ|	|�}tj||�st$jdO|��n\	|j�|�}gdP�}
|�*|dQt�k7s|j�|�t�|
�k7�rt$jdR|�|�.t$jdS�|j�|dT�U�|_n�|dQt�k7r:t$jdVt�|dQ�|j�||dQ�U�|_nS|j�|�t�|
�k7r6t$jdWt�|
�|j�|��g|_t/j0dX�}t$jdY||z�tjj}|�rtj�|||z�tjj}|dZz�rtj�|dZz|dZz|z�tjj}|d[z�rtj�|d[z|d[z|z�t$jd\|�|j�|�t$jd]�nt$jd^|�	t$jd`|�|jj)da|z�|j�dc�|jr�g}|jD]$}|j�|d|dd|de|dfdg���&dh}	|jj�||�|jj��|jj#dj�|j�dc�|j��y#t
tf$rtd�aY�	�gwxYw#t$j'd�Y��:xYw#t$j'd_�Y��UxYw#t$jdb|�t/j0dX�}t$jdY||z�tjj}|�rtj�|||z�tjj}|dZz�rtj�|dZz|dZz|z�tjj}|d[z�rtj�|d[z|d[z|z�t$jd\|�|j�|�|jj)da|z�Y��kxYw#t$j'di�Y��xYw)kN�IBUS_TABLE_DEBUG_LEVELrzCannot open database file %szPRAGMA encoding = "UTF-8";z"PRAGMA case_sensitive_like = true;zPRAGMA page_size = 4096;zPRAGMA cache_size = 20000;zPRAGMA temp_store = MEMORY;z$PRAGMA journal_size_limit = 1000000;zPRAGMA synchronous = NORMAL;z!Error while initializing databasez:CREATE TABLE IF NOT EXISTS main.ime (attr TEXT, val TEXT);�namerz
name.zh_cnz
name.zh_hkz
name.zh_tw�author�somebody�uuidz%s�
serial_numberz%Y%m%d�iconzibus-table.svg�license�LGPL�	languages�language_filter�valid_input_chars�abcdefghijklmnopqrstuvwxyz�max_key_length�4�commit_keys�space�select_keys�1,2,3,4,5,6,7,8,9,0�page_up_keysz!Page_Up,KP_Page_Up,KP_Prior,minus�page_down_keysz$Page_Down,KP_Page_Down,KP_Next,equal�
status_prompt�def_full_width_punct�true�def_full_width_letter�false�user_can_define_phrase�pinyin_mode�suggestion_mode�dynamic_adjust�auto_select�auto_commit�
auto_wildcard�descriptionzA IME under IBus Table�layout�us�symbol�rules�least_commit_length�0�start_chars�orientationz{})�always_show_lookup�char_promptsz9
            SELECT val FROM main.ime WHERE attr = :attr;zC
            INSERT INTO main.ime (attr, val) VALUES (:attr, :val);��attr�val�r
r�tables�.dbz.cache�:memory:z~/.ibus/tablesz	debug.logzsetup-debug.logT)�exist_okz(The user database %s does not exist yet.)�id�tabkeys�phrase�freq�	user_freq�versionz.The user database %s seems to be incompatible.z0There is no version information in the database.�0.0)�old_database_versionz�The version of the database does not match (too old or too new?). ibus-table wants version=%s But the  database actually has version=%sz�The number of columns of the database does not match. ibus-table expects %s columns. But the database actually has %s columns. But the versions of the databases are identical. This should never happen!z-%Y-%m-%d_%H:%M:%Sz+Renaming the incompatible database to "%s".z-shmz-walz$Creating a new, empty database "%s".z�If user phrases were successfully recovered from the old, incompatible database, they will be used to initialize the new database.zCompatible database %s found.z-Unexpected error trying to find user databasezConnect to the database %s.a�
                ATTACH DATABASE "%s" AS user_db;
                PRAGMA user_db.encoding = "UTF-8";
                PRAGMA user_db.case_sensitive_like = true;
                PRAGMA user_db.page_size = 4096;
                PRAGMA user_db.cache_size = 20000;
                PRAGMA user_db.temp_store = MEMORY;
                PRAGMA user_db.journal_mode = WAL;
                PRAGMA user_db.journal_size_limit = 1000000;
                PRAGMA user_db.synchronous = NORMAL;
            zCould not open the database %s.r2r���rkrlrmrnz�
            INSERT INTO user_db.phrases (tabkeys, phrase, freq, user_freq)
            VALUES (:tabkeys, :phrase, :freq, :user_freq)
            zError inserting old phrases�PRAGMA wal_checkpoint;)M�intr-�os�getenv�DEBUG_LEVEL�	TypeError�
ValueError�old_phrasesr1�_user_db�reset_phrases_cache�path�isfiler*�connectr
�printrrr�
executescriptr:�uuid4�time�strftime�_default_ime_attributes�sortedrr�ime_propertiesr �_mlen�_snum�
is_chinese�_is_chinese�is_cjk�_is_cjk�lowerrP�	get_rulesr[�get_possible_tabkeys_lengths�possible_tabkeys_lengths�get_start_chars�
startchars�join�ibus_table_location�	data_home�basename�replace�
cache_path�load_phrases_cache�isdir�
expanduser�access�F_OK�unlink�shutil�copytree�rmtree�symlink�makedirs�exists�debug�get_database_desc�DATABASE_VERSION�%get_number_of_columns_of_phrase_table�len�extract_user_phrases�rename�init_user_db�
create_tables�append�executemany�commit�create_indexes�generate_userdb_desc)rr1r2r3r4�
select_sqlstr�
insert_sqlstrrc�sqlargs�tables_path�
cache_name�old_tables_path�desc�phrase_table_column_names�	timestamp�sqlargs_old_phrasesrlrs                  rrzTabSqliteDb.__init__�sT
��	!��c�"�)�)�,D�"E�F�G�K�=?��� ��
���
�� � �"��b�g�g�n�n�T�]�]�;�18������1O�D�G��0�$�-�-�?�@�
	B��G�G�O�O�8�9��G�G�O�O�@�A��G�G�O�O�6�7��G�G�O�O�8�9��G�G�O�O�9�:��G�G�O�O�B�C��G�G�O�O�:�;�	
�����H�	J�*(
��2�*(
���*(
�
��*(
�
��	*(
�

�Z�*(
�
�4�$�*�*�,�&�
*(
�
�D�4�=�=��#:�:�*(
�
�#�*(
�
�f�*(
�
��*(
�
�b�*(
�
 � <�*(
�
�S�*(
�
�'�*(
� 
�/�!*(
�"
�>�#*(
�$
�C�%*(
�&
�B�'*(
�(
#�6�)*(
�*
$�G�+*(
�,
%�W�-*(
�.
�'�/*(
�0
�g�1*(
�2
�W�3*(
�4
�'�5*(
�6
�'�7*(
�8
�V�9*(
�<
�2�=*(
�>
�T�?*(
�@
�R�A*(
�B
�B�C*(
�D
"�#�E*(
�F
�"�G*(
�H
�&�I*(
�J"(��M*(
��$�V�<�M�F�M��t�;�;�<�
<�� ��7�7��=����w�w���}�g�>�G�G�I��G�G�O�O�M�7�;�

<�,��w�w�#�;�;�=�����,�,�0�0�1A�B�C��
��(�(�,�,�_�=��
��?�?�,����{�{�}���'+�':�':�'>�'>�$�(&�&+�e�g��(8��#��^�^�%��
�(,�(I�(I�(K��%��.�.�0����i�i� 3� =� =� ?��J���W�W�%�%�d�m�m�4�<�<�U�H�M�
��)�)�K��<�����#�#�%��/�
��j� ��:�:�k�*�"$�'�'�"4�"4�5E�"F���:�:�o�.��y�y������+�[�":�;=�7�7�D��	�	�"�'�'�,�,���"L�M��y�y������+�->�"@�AC���J��	�	�"�'�'�,�,�+�->�#@�A��O�O�O�[�A��M�M�/�2��J�J�{�O�<��K�K��d�;��i�i��W�5�G��;�;�w�'����>��I�AI��1�1�'�:�D�1H�-���#�I��2B�B� $� J� J� '�!)�#&�'@�#A�!B����L�#�%� �<�"�L�L�!0�1�04�/H�/H� '�e�0I�0E�D�,�!�)�_�0@�@�"�L�L�!L�!1�$�y�/�C�04�/H�/H� '�d�9�o�0I�0O�D�,�"�H�H� '�)�!$�%>�!?�@�#�L�L�!<�!$�$=� >� $� J� J�$+�!-�
.�02�D�,�$(�M�M�2F�$G�	����I�#�I�-�/��7�7�>�>�'�2��I�I�g�w�y�/@�A��7�7�>�>�'�&�.�9��I�I�g�f�n�g�f�n�Y�6N�O��7�7�>�>�'�&�.�9��I�I�g�f�n�g�f�n�Y�6N�O����B�G�M��)�)�'�2����;�<����;�W�F�%	��L�L�-�w�
8��G�G�!�!�
#��
#�

�F	
���9�%����DF���*�*�
.��#�*�*� &�q�	�%�a�y�#�A�Y�"(��)�-�.�
.��F�
@����#�#�F�,?�@�
�G�G�N�N���G�G�O�O�4�5�	
���I�&��!�!�#��_�:�&�	!��a�&�K�	!��(	B����@�A��rI��$�$�G�I��$	��L�L�:�G�D��
�
�&:�;�I��L�L�F� ��*�
,��w�w�~�~�g�&��	�	�'�7�9�#4�5��w�w�~�~�g�f�n�-��	�	�'�&�.�'�&�.��*B�C��w�w�~�~�g�f�n�-��	�	�'�&�.�'�&�.��*B�C��L�L�?��I����g�&��G�G�!�!�
#��
#�

��4
@�� � �!>�?�sD�'e3�7B=f�If1�74g�l�3f�f�f.�1g�El�l3rkrlrn�databaser�c�4�tdkDrtjd||||�|r|syd|z}|||d�}	|jj	||�|r|jj�|j
|�y#tjd�YyxYw)zupdate phrase freqsrz-tabkeys=%s phrase=%s user_freq=%s database=%sNzu
        UPDATE %s.phrases SET user_freq = :user_freq
        WHERE tabkeys = :tabkeys AND phrase = :phrase
        ;)rnrkrlz,Unexpected error updating phrase in user_db.)ryrr�r
rr��invalidate_phrases_cacher)rrkrlrnr�r�rr�s        r�
update_phrasezTabSqliteDb.update_phrase�s�����?��L�L�?����H�
6��f��
����!*�%�#�%��	M��G�G�O�O�F�G�,������� ��)�)�'�2��	M����K�L�s�A	A>�>Bc��|j�|j�y|jj�|jj	d�y)z1
        Trigger a checkpoint operation.
        Nru)�save_phrases_cacher}r
r�rr$s r�
sync_usrdbzTabSqliteDb.sync_usrdb�s<��	
���!��=�=� �������������0�1r!c�N�tdkDrtjd�i|_y)z.
        Make the phrases cache empty
        rzreset_phrases_cache()N)ryrr��_phrases_cacher$s rr~zTabSqliteDb.reset_phrases_cache�s ����?��L�L�0�1�Y[��r!c��tdkDrtjd�td|jdz�D]?}|j
j
|d|�s�"|j
j|d|��Ay)u�
        Delete all phrases starting with “tabkeys” from
        the phrases cache.

        :param tabkeys: The keys typed
        rzinvalidate_phrases_cache()rN)ryrr��ranger�r�r �pop)rrk�is   rr�z$TabSqliteDb.invalidate_phrases_cache�sj����?��L�L�5�6��q�$�*�*�q�.�)�	6�A��"�"�&�&�w�q��|�4��#�#�'�'���!��5�	6r!c�(�tdkDrtjd�	tjt|jd��|_|jjd�}|r||jk7ri|_yy#t$r.tdkDr"tjd|j�YyYyt$r.tdkDr"tjd|j�YyYytjd|j�YyxYw)	z.
        Load phrases cache from disk
        rzload_phrases_cache()�rr;zFile %s not foundzPermission error reading %szUnknown error reading %sN)ryrr��json�load�openr�r�r r��FileNotFoundError�PermissionError)r�snums  rr�zTabSqliteDb.load_phrases_cache�s�����?��L�L�/�0�	F�"&�)�)�D����#�,F�"G�D���&�&�*�*�?�;�D��D�D�J�J�.�&(��#�/�� �	:��Q�����'����:���	D��Q�����1�4�?�?�D��	F��L�L�3�T�_�_�E�s�A!B�2D�91D�.!Dc�^�tdkDrtjd�	|j|jd<|j
dz}t
j|jt|d��tj||j
�y#tjd�YyxYw)z.
        Save phrases cache from disk
        rzsave_phrases_cache()r;z.tmp�wz)Unexpected error in save_phrases_cache().N)ryrr�r�r�r�r��dumpr�rwr�r)r�_cache_paths  rr�zTabSqliteDb.save_phrases_caches�����?��L�L�/�0�	J�37�:�:�D����0��/�/�F�2�K�
�I�I�d�)�)�4��S�+A�B��J�J�{�D�O�O�4��	J����H�I�s�A2B�B,c��|jjd�}|r<|jd�}|D]&}|j�j	d�dk7s�&yy)zg
        Check whether this input method is classified as Chinese
        in the the database.
        r?�,�zh���TF)r�r �splitr��find)rr?�langs�langs    rr�zTabSqliteDb.is_chineses[��
�'�'�+�+�K�8�	���O�O�C�(�E��
 ���:�:�<�$�$�T�*�b�0��
 �r!c��|jjd�}|rA|jd�}|D]+}dD]$}|j�j	|�s�#y�-y)zx
        Check whether this input method is classified as Chinese,
        Japanese, or Korean in the database.
        r?r�)r��ja�koTF)r�r r��strip�
startswith)r�
languages_strr?�languager�s     rr�zTabSqliteDb.is_cjksh��
�+�+�/�/��<�
��%�+�+�C�0�I�%�
$��.�$�D��~�~�'�2�2�4�8�#�$�
$�r!c�^�|jjd�}|dvrt|d�Sy)a�
        Get the default Chinese mode from the database

        0 means to show simplified Chinese only
        1 means to show traditional Chinese only
        2 means to show all characters but show simplified Chinese first
        3 means to show all characters but show traditional Chinese first
        4 means to show all characters

        If no mode is specified in the database, return 4 to avoid all
        filtering of characters.
        r@)�cm0�cm1�cm2�cm3�cm4r��)r�r rv)rr@s  r�get_chinese_modezTabSqliteDb.get_chinese_mode+s7���-�-�1�1�2C�D���A�A���r�*�+�+�r!c�B�|jjd�}|r|Sy)zK
        Get the keys used to select a candidate from the database
        rGrH�r�r )r�rets  r�get_select_keyszTabSqliteDb.get_select_keys=s%���!�!�%�%�m�4����J�$r!c�v�	t|jjd��S#ttf$rYywxYw)zAGet the default orientation of the lookup table from the databaser_r)rvr�r rzr{r$s r�get_orientationzTabSqliteDb.get_orientationFs:��	��t�*�*�.�.�}�=�>�>���:�&�	��	�s�#&�8�8c�B�|dk(r`d|z}|jj|�d|z}|jj|�d|z}|jj|�d|z}|jj|�|jj�y)z%Create tables that contain all phrase�mainzp
            CREATE TABLE IF NOT EXISTS %s.goucima
            (zi TEXT PRIMARY KEY, goucima TEXT);
            zp
            CREATE TABLE IF NOT EXISTS %s.pinyin
            (pinyin TEXT, zi TEXT, freq INTEGER);
            zk
            CREATE TABLE IF NOT EXISTS %s.suggestion
            (phrase TEXT, freq INTEGER);
            z�
        CREATE TABLE IF NOT EXISTS %s.phrases
        (id INTEGER PRIMARY KEY, tabkeys TEXT, phrase TEXT,
        freq INTEGER, user_freq INTEGER);
        N)r
rr�)rr�rs   rr�zTabSqliteDb.create_tablesMs����v�����F�
�G�G�O�O�F�#����F�
�G�G�O�O�F�#����F�
�G�G�O�O�F�#���	��
	
������������r!�attrsc�|�d}d}d}|D]m\}}||d�}|jj||�j�r|jj||��R|jj||��o|jj�t	|j|j
��|_t|jjd��|_	|j�|_|jjd�j�dk(|_
|j�|_y	)
z�Update or insert attributes in ime table, attrs is a iterable object
        Like [(attr,val), (attr,val), ...]

        This is called only by tabcreatedb.py.
        z+SELECT val from main.ime WHERE attr = :attrz2UPDATE main.ime SET val = :val WHERE attr = :attr;z6INSERT INTO main.ime (attr, val) VALUES (:attr, :val);rbrerCrPrMN)r
rrr�rr�r�rvr r�r�r�r�rPr�r[)rr�r��
update_sqlstrr�rcrdr�s        r�
update_imezTabSqliteDb.update_imehs��F�
�L�
�D�	��	8�I�D�#�#�C�0�G��w�w���}�g�6�?�?�A������
�w�7������
�w�7�	8�	
������+��w�w�#�;�;�=�����,�,�0�0�1A�B�C��
��?�?�,���'+�':�':�'>�'>�$�(&�&+�e�g��(8��#��^�^�%��
r!c
��i}tjd�}tjd�}|jsiS	|jj	d�}g}|r|j�j
d�}|D�]}|j|�}|r�g}|jd�dk(rt|jd��|d<|jd	�j
d
�}	t|	�|jkDrtd|z�|S|	D]Y}
|j|
�}|s�|jt|jd��t|jd��f��[||t|jd��<��td|z��� 	|S#t$rtj!d
�Y|SwxYw)a�Get phrase construct rules

        Example:

        The wubi-jidian86.txt table source contains:

        RULES = ce2:p11+p12+p21+p22;ce3:p11+p21+p31+p32;ca4:p11+p21+p31+p-11

        and the return value of this function becomes:

        {2: [(1, 1), (1, 2), (2, 1), (2, 2)],
         3: [(1, 1), (2, 1), (3, 1), (3, 2)],
         'above': 4,
         4: [(1, 1), (2, 1), (3, 1), (-1, 1)]}
        zc([ea])(\d):(.*)zp(-{0,1}\d)(-{0,1}\d)r[�;r�arr�abovers�+zrule: "%s" over max key lengthznot a legal rule: "%s"z Unexpected error in get_rules().)�re�compilerPr�r r�r��match�grouprvr�r�r�r��	Exceptionrr)rr[�patt_r�patt_p�
_rules_str�_rules�rule�res�cms�_cms�_cm�cm_ress            rr�zTabSqliteDb.get_rules�s��� KM�����/�0�����4�5���*�*��I�	A��,�,�0�0��9�J� "�F��#�)�)�+�1�1�#�6���
:���l�l�4�(����C��y�y��|�s�*�),�S�Y�Y�q�\�):��g���9�9�Q�<�-�-�c�2�D��4�y�4�:�:�-��>��D�E���� $�?��!'���c�!2��!��J�J��F�L�L��O�(<�(+�F�L�L��O�(<�(>�?�?�
03�E�#�c�i�i��l�+�,��2�D�8�9�#
:�(����	A����?�@���	A�s�CF �F �(A5F � G�Gc�x�|jrE|jd}td|dz�D�cgc]}t|j|���c}ddS	t|jjd��}|dkDr"tt||jdz��SgScc}w#ttf$rd}Y�AwxYw)u�Return a list of the possible lengths for tabkeys in this table.

        Example:

        If the table source has rules like:

            RULES = ce2:p11+p12+p21+p22;ce3:p11+p21+p22+p31;ca4:p11+p21+p31+p41

        self._rules will be set to

            self._rules = {
                2: [(1, 1), (1, 2), (2, 1), (2, 2)],
                3: [(1, 1), (1, 2), (2, 1), (3, 1)],
                4: [(1, 1), (2, 1), (3, 1), (-1, 1)],
                'above': 4}

        and then this function returns “[4, 4, 4]”

        Or, if the table source has no RULES but LEAST_COMMIT_LENGTH=2
        and MAX_KEY_LENGTH = 4, then it returns “[2, 3, 4]”

        I cannot find any tables which use LEAST_COMMIT_LENGTH though.
        r�rrrNr\r)
r[r�r�rvr�r rzr{�listr�)r�max_len�x�least_commit_lens    rr�z(TabSqliteDb.get_possible_tabkeys_lengths�s���0�:�:��j�j��)�G�05�a����0C�D�1�C��
�
�1�
�&�D�Q�G�G�	!�"��#�#�'�'�(=�>� @���a����.��
�
�Q��?�@�@��	��E���:�&�	!� ��	!�s�B �$B%�%B9�8B9c�8�|jjd�S)z"return possible start chars of IMEr^r�r$s rr�zTabSqliteDb.get_start_chars�s���"�"�&�&�}�5�5r!c�<�|jjd�}|S)z6Get the characters which engine should not change freq�no_check_charsr�)r�_charss  r�get_no_check_charszTabSqliteDb.get_no_check_chars�s���$�$�(�(�)9�:���
r!�phrasesc��tdkDr(tjdtt	|���dd|iz}g}|D].\}}}}|j||||d��|j
|��0|jj||�|jj�|jjd�y)u�Add many phrases to database fast. Used by tabcreatedb.py when
        creating the system database from scratch.

        “phrases” is a iterable object which looks like:

            [(tabkeys, phrase, freq ,user_freq),
             (tabkeys, phrase, freq, user_freq), ...]

        This function does not check whether phrases are already
        there.  As this function is only used while creating the
        system database, it is not really necessary to check whether
        phrases are already there because the database is initially
        empty anyway. And the caller should take care that the
        “phrases” argument does not contain duplicates.

        rzlen(phrases)=%s��
        INSERT INTO %(database)s.phrases
        (tabkeys, phrase, freq, user_freq)
        VALUES (:tabkeys, :phrase, :freq, :user_freq);
        r�rtruN)ryrr�r�rr�r�r
r�r�r)	rrr�r��insert_sqlargsrkrlrmrns	         r�add_phraseszTabSqliteDb.add_phrases�s���(��?��L�L�*�C��W�
�,>�?���8�$�	%�
�
��29�	3�.�W�f�d�I��!�!�"� ��&�	#(�
)�

�)�)�'�2�
	3�	
�����M�>�:������������0�1r!rmc�.�tdkDrtjd||||�|r|sydd|iz}||d�}|jj	||�j�}	|	r"tdkDrtjd|||	�ydd|iz}
||||d	�}tdkDrtjd
|
|�	|jj	|
|�|r|jj
�|j|�y#tjd�YyxYw)zaAdd phrase to database, phrase is a object of
        (tabkeys, phrase, freq ,user_freq)
        rz4add_phrase tabkeys=%s phrase=%s freq=%s user_freq=%sNzk
        SELECT * FROM %(database)s.phrases
        WHERE tabkeys = :tabkeys AND phrase = :phrase;
        r��rkrlzKselect_sqlstr=%(sql)s select_sqlargs=%(arg)s already there!: results=%(r)s rrtz"insert_sqlstr=%s insert_sqlargs=%sz Unexpected error in add_phrase())	ryrr�r
rrr�r�r)rrkrlrmrnr�r�r��select_sqlargsrr�rs            r�
add_phrasezTabSqliteDb.add_phrases-����?��L�L�'����y�
2��f����8�$�%�
�&-��?���'�'�/�/�-��@�I�I�K����Q�����5�!�>�7�<�
���8�$�	%�
����"�	$��
��?��L�L�4��~�
/�	A��G�G�O�O�M�>�:������� ��)�)�'�2��	A����?�@�s
�1A	C;�;D�goucimasc�X�d}g}|D]\}}|j||d���	|jj�|jj||�|jj�|jj	d�y#t
j
d�YyxYw)zyAdd goucima into database, goucimas is iterable object
        Like goucimas = [(zi,goucima), (zi,goucima), ...]
        zP
        INSERT INTO main.goucima (zi, goucima) VALUES (:zi, :goucima);
        )�zi�goucimaruz"Unexpected error in add_goucima().N)r�r
r�r�rrr)rr#rr�r%r&s      r�add_goucimazTabSqliteDb.add_goucima@s�������#�	;�K�B���N�N�"��9�:�	;�	C��G�G�N�N���G�G�����0��G�G�N�N���G�G�O�O�4�5��	C����A�B�s�A+B�B)�pinyinsc	��d|z}d}|D]~\}}}|dz
}|jdd�jdd�jdd	�jd
d�jdd
�}	|jj||||d����|jj
�y#t$rtjd||||�Y��wxYw)zxAdd pinyin to database, pinyins is a iterable object
        Like: [(zi,pinyin, freq), (zi, pinyin, freq), ...]
        zX
        INSERT INTO %s.pinyin (pinyin, zi, freq) VALUES (:pinyin, :zi, :freq);
        rr�1�!�2�@�3�#rD�$�5�%)�pinyinr%rmzHError when inserting into pinyin table. count=%s pinyin=%s zi=%s freq=%sN)r�r
rrrrr�)rr(r�r�countr3r%rms        r�
add_pinyinzTabSqliteDb.add_pinyinRs��������� '�	-��F�B���Q�J�E��^�^��S��!�'����%�g��S�"�")�'���#&�&-�g� #�S�'*�	
�
-�������v�R��F�H�	-� 	
��������
-�� � �7��6�2�t�-�
-�s�) B&�&"C�
C�suggestionsc���d|z}d}|D]*\}}|dz
}	|jj|||d���,|jj�y#t$rtj	d|||�Y�kwxYw)z�Add suggestion phrase to database, suggestions is a iterable object
        Like: [(phrase, freq), (phrase, freq), ...]
        zS
        INSERT INTO %s.suggestion (phrase, freq) VALUES (:phrase, :freq);
        rr)rlrmzFError when inserting into suggestion table. count=%s phrase=%s freq=%sN)r
rrrrr�)rr6r�rr4rlrms       r�add_suggestionzTabSqliteDb.add_suggestionos���������'�		)�L�F�D��Q�J�E�
)�������v�t�<�>�		)�	
��������
)�� � �1��6�4�)�
)�s�A�!A6�5A6c��d}|jj|�|jjd�|jj�y)ze
        Optimize the database by copying the contents
        to temporary tables and back.
        a�
            CREATE TABLE tmp AS SELECT * FROM main.phrases;
            DELETE FROM main.phrases;
            INSERT INTO main.phrases SELECT * FROM tmp ORDER BY
            tabkeys ASC, phrase ASC, user_freq DESC, freq DESC, id ASC;
            DROP TABLE tmp;
            CREATE TABLE tmp AS SELECT * FROM main.goucima;
            DELETE FROM main.goucima;
            INSERT INTO main.goucima SELECT * FROM tmp ORDER BY zi, goucima;
            DROP TABLE tmp;
            CREATE TABLE tmp AS SELECT * FROM main.pinyin;
            DELETE FROM main.pinyin;
            INSERT INTO main.pinyin SELECT * FROM tmp ORDER BY pinyin ASC, freq DESC;
            DROP TABLE tmp;
            CREATE TABLE tmp as SELECT * FROM main.suggestion;
            DELETE FROM main.suggestion;
            INSERT INTO main.suggestion SELECT * FROM tmp ORDER by phrase ASC, freq DESC;
            DROP TABLE tmp;
            zVACUUM;N)r
r�r�)rrs  r�optimize_databasezTabSqliteDb.optimize_database�s=��
��&	
�����f�%������i�(������r!�	_databasec�B�tdkDrtjd�yy)z�Drop the indexes in the database to reduce its size

        We do not use any indexes at the moment, therefore this
        function does nothing.
        rzdrop_indexes()N�ryrr�)rr;s  r�drop_indexeszTabSqliteDb.drop_indexes�s����?��L�L�)�*�r!�_commitc�B�tdkDrtjd�yy)u�Create indexes for the database.

        We do not use any indexes at the moment, therefore
        this function does nothing. We used indexes before,
        but benchmarking showed that none of them was really
        speeding anything up, therefore we deleted all of them
        to get much smaller databases (about half the size).

        If some index turns out to be very useful in future, it could
        be created here (and dropped in “drop_indexes()”).
        rzcreate_indexes()Nr=)rr;r?s   rr�zTabSqliteDb.create_indexes�s����?��L�L�+�,�r!c�N�	|jd�}|S#t$rd}Y|SwxYw)z�
        Encode a string in Big5 or, if that is not possible,
        return something higher than any Big5 code.

        :param phrase: String to be encoded in Big5 encoding
        �Big5���)�encode�UnicodeEncodeError)rrl�big5s   r�	big5_codezTabSqliteDb.big5_code�s7��	��=�=��(�D����"�	��D���	�s��$�$�
typed_tabkeys�
candidates�chinese_modec�Z�����d}tjj|j�j	dd�}d��|dvr|j
�|jr�fd��nd��|dvr,|jr |d	k(rd
�nd	�t|����fd���d
|St|���fd���d
|S)u 
        “candidates” is an array containing something like:
        [(tabkeys, phrase, freq, user_freq), ...]

        “typed_tabkeys” is key sequence the user really typed, which
        maybe only the beginning part of the “tabkeys” in a matched
        candidate.
        �drgrc��y�NrCr.�rs r�<lambda>z-TabSqliteDb.best_candidates.<locals>.<lambda>���r!��cangjie3�cangjie5zcangjie-bigz
quick-classic�quick3�quick5c�:��t�|ddk(xr|ddv�S)Nr�z!@#$%)rv)rrHs �rrPz-TabSqliteDb.best_candidates.<locals>.<lambda>�s,����m�q��"�v�-�C�1�R�5�G�3C�D�D�r!c��y)Nrr.rOs rrPz-TabSqliteDb.best_candidates.<locals>.<lambda>�rQr!)rrrsrrrc����t�|dk(��|d�d|dz�tj|d�zd|dzt|d�|d�|dd�t	|dd�f	S)Nrr�rsrrr)rv�chinese_variants�detect_chinese_categoryr��ord)r�bitmask�code_point_function�pinyin_exact_match_functionrHs ����rrPz-TabSqliteDb.best_candidates.<locals>.<lambda>�s���� #�"/�1�Q�4�"7�! � �:�!�A�$�?� ��1��g�!(�"2�"J�"J�$%�a�D�#*�!*�+�!��1��g�!�!�A�$�i���d�1�!�A�$�q�'�:�!�!�A�$�q�'�l�!)�r!�rNc���t�|dk(��|d�d|dzd|dzt|d�|d�|dd�t|dd�fS)Nrr�rsrrr�rvr�r\)rr^r_rHs ���rrPz-TabSqliteDb.best_candidates.<locals>.<lambda>�sx����+�q��t�3���6�a��d�;��Q�q�T�'��Q�q�T�'��a��d�)��A�$�-�a��d�1�g�6��a��d�1�g�,�%�r!)rwrr�r1r�rGr�r�)	rrHrIrJ�maximum_number_of_candidates�engine_namer]r^r_s	 `    @@@r�best_candidateszTabSqliteDb.best_candidates�s����(+�$��g�g�&�&�t�}�}�5�=�=�e�R�H��6M���5�5�#'�.�.�����A�'�+8�'��6�!�d�&6�&6��q� �!��!���*���$;�:�%<�
<�&�j��
�7�6�
8�
	8r!�onechar�single_wildcard_char�multi_wildcard_charrVrSc�`�|sgS|jj|�}|r|Sd}	|rd}	|js|rdd|	iz}
ndd|	iz}
d}dD]}|||fvs�
|}�
|}
|
j|||z�}
d||fvr|
jd|dz�}
d	||fvr|
jd	|d	z�}
|r|
j|d	�}
|r|
j|d
�}
|r|
d
z
}
|
|d�}tdkDr t
j
d
|
t|��|jj|
|�j�}d}|dk(rd}n|dk(rd}|s|}n6g}|D]/}|tj|d�zs�|j|��1i}|D]U}|d|df}||vr|||<�|j||t|d||d�t|d||d�fzfg��W|j!||j#�|��}tdkDrt
j
dt|��||j|<|S)zE
        Get matching phrases for tabkeys from the database.
        rz AND length(phrase)=1 a�
            SELECT tabkeys, phrase, freq, user_freq FROM
            (
                SELECT tabkeys, phrase, freq, user_freq FROM main.phrases
                WHERE tabkeys LIKE :tabkeys ESCAPE :escapechar %(one_char_condition)s
                UNION ALL
                SELECT tabkeys, phrase, freq, user_freq FROM user_db.phrases
                WHERE tabkeys LIKE :tabkeys ESCAPE :escapechar %(one_char_condition)s
            )
            �one_char_conditionz�
            SELECT tabkeys, phrase, freq, user_freq FROM main.phrases
            WHERE tabkeys LIKE :tabkeys ESCAPE :escapechar %(one_char_condition)s
            u☺z!@#r2�_�%%)rk�
escapecharrzsqlstr=%s sqlargs=%sNrrrrs�rHrIrJzbest=%s)r�r rPr�ryrr�r#r
rrrZr[r��update�maxre�values)rrkrfrJrgrhrVrS�bestrjrrm�char�tabkeys_for_liker��unfiltered_resultsr]rr�phrase_frequenciesrs                     r�select_wordszTabSqliteDb.select_wordss�����I��"�"�&�&�w�/����K����!9���&�&�.�	�(�);�<�	=�F��(�);�<�=�F��
��	"�D��0�2E�F�F�!�
�	"�#��+�3�3��
�:�-�/���+�-@�A�A�/�7�7��Z��^�L���+�-@�A�A�/�7�7��Z��^�L���/�7�7�$�c� +���/�7�7�#�T� +�����$��.�j�I����?��L�L�/���g��G�!�W�W�_�_�V�W�=�F�F�H�����1���G�
�Q�
��G��(�G��G�,�
+���*�B�B�6�!�9�M�N��N�N�6�*�
+� ���	�F��!�9�f�Q�i�(�C��,�,�*0�"�3�'�"�)�)����F�1�I�'9�#�'>�q�'A�B��F�1�I�'9�#�'>�q�'A�B�D�D�,�+��	��#�#�!�)�0�0�2�%�$�'����?��L�L��D��J�/�'+����G�$��r!c��|sgSd}|}|r|j|d�}|r|j|d�}|dz
}d|i}|jj||�j�}d}	|dk(rd}	n|dk(rd}	g}
|D]L\}}}
|	s|
j	|||
df��|	tj|�zs�8|
j	|||
df��N|j||
|�	�S)
zh
        Get Chinese characters matching the pinyin given by tabkeys
        from the database.
        z}
        SELECT pinyin, zi, freq FROM main.pinyin WHERE pinyin LIKE :tabkeys
        ORDER BY freq DESC, pinyin ASC;
        rkrlrkNrrrrrn)r�r
rrr�rZr[re)rrkrJrgrhrrtr�rr]rvr3r%rms              r�#select_chinese_characters_by_pinyinz/TabSqliteDb.select_chinese_characters_by_pinyinos'����I���#���/�7�7�$�c� +���/�7�7�#�T� +���D� ���.�/���'�'�/�/�&�'�2�;�;�=�����1���G�
�Q�
��G�>@��")�	E��V�R���"�)�)�6�2�t�Q�*?�@��-�E�E�b�I�I�&�-�-�v�r�4��.C�D�	E��#�#�!�)�%�$�'�	'r!�prefixc
�$��|sgSd}|dz}d|i}|jj||�j�}i}|D]7\}}||vr||f||<�|j||t	|||d�ffg��9|j�}	tdkDrtjdt|	��d}
tjj|j�jdd�}d	��|d
vr|j�t!|	�fd���d
|
S)zK
        Get Chinese phrase matching the prefix from the database.
        z�
        SELECT phrase, freq FROM main.suggestion WHERE phrase LIKE :prefix
        ORDER BY length(phrase) DESC, freq DESC, phrase ASC;
        rlrzrz
candidates=%srLrgrc��yrNr.rOs rrPz9TabSqliteDb.select_suggestion_candidate.<locals>.<lambda>�rQr!rRc	���tt|d��d|dz�|dd��|dd�t|dd�t|dd�fS)Nrr�rrb)rr^s �rrPz9TabSqliteDb.select_suggestion_candidate.<locals>.<lambda>�se�����A�a�D�	�N�*��Q�q�T�'�-�a��d�1�g�6�-�a��d�1�g�6��a��d�1�g�,��a��d�1�g�,�	%�r!r`N)r
rrrorprqryrr�r#rwrr�r1r�rGr�)
rrzr�prefix_for_liker�rrvrlrmrIrcrdr^s
            @r�select_suggestion_candidatez'TabSqliteDb.select_suggestion_candidate�sF���
��I���!�4�-���_�-���'�'�/�/�&�'�2�;�;�=����#�	L�L�F�D��/�/�.4�d�^�"�6�*�"�)�)���s�4�);�F�)C�A�)F�G�H�J�K�L�		L�(�.�.�0�
���?��L�L��$�z�*:�;�'*�$��g�g�&�&�t�}�}�5�=�=�e�R�H��6M���5�5�#'�.�.���j�	�
�7�6�
8�
	8r!c�0�	d}|jj|�d}|jj|dtf�d}|jj|d�|jj	�y#t
j
d�YyxYw)z{
        Add a description table to the user database

        This adds the database version and  the create time
        zBCREATE TABLE IF NOT EXISTS user_db.desc (name PRIMARY KEY, value);z2INSERT OR IGNORE INTO user_db.desc  VALUES (?, ?);rozMINSERT OR IGNORE INTO user_db.desc  VALUES (?, DATETIME("now", "localtime"));)zcreate-timez+Unexpected error in generate_userdb_desc().N)r
r�rr�r�rr)r�	sqlstrings  rr�z TabSqliteDb.generate_userdb_desc�s���
	L�/�
�
�G�G�!�!�)�,�L�I��G�G�O�O�I�	�3C�'D�E�>�
�
�G�G�O�O�I�'8�9��G�G�N�N���	L����J�K�s�A9A<�<B�db_filec��|dk(rytj|�s7tj|�}|j	d�|j�yy)z�
        Initialize the user database unless it is an in-memory database

        :param db_file: Full path of the database file.
        :type db_file: String
        rhNax
                PRAGMA encoding = "UTF-8";
                PRAGMA case_sensitive_like = true;
                PRAGMA page_size = 4096;
                PRAGMA cache_size = 20000;
                PRAGMA temp_store = MEMORY;
                PRAGMA journal_mode = WAL;
                PRAGMA journal_size_limit = 1000000;
                PRAGMA synchronous = NORMAL;
            )rr�r*r�r�r�)rr�r
s   rr�zTabSqliteDb.init_user_db�sL���j� ���{�{�7�#�����)�B����	�	
�
�I�I�K�$r!c���tj|�sy	tj|�}i}|j	d�j�D]
}|d||d<�|j
�|S#YyxYw)z�
        Get the description table from the database

        :param db_file: Full path of the database file.
        :type db_file: String
        :rtype: Dictionary
        NzSELECT * FROM desc;rr)rr�r*r�rr�close)rr�r
r��rows     rr�zTabSqliteDb.get_database_desc�sv���{�{�7�#��	�����)�B��D��z�z�"7�8�A�A�C�
&��"�1�v��S��V��
&��H�H�J��K��	��s�AA0�0A4c�x�tj|�sy	tj|�}|j	d�j�}dj
|ddj��}tjd|�}|r+|jd�jd�}t|�Sy#YyxYw)a1
        Get the number of columns in the 'phrases' table in
        the database in db_file.

        Determines the number of columns by parsing this:

        sqlite> select sql from sqlite_master where name='phrases';
        CREATE TABLE phrases
                (id INTEGER PRIMARY KEY, tabkeys TEXT, phrase TEXT,
                freq INTEGER, user_freq INTEGER)
        sqlite>

        This result could be on a single line, as above, or on multiple
        lines.

        :param db_file: Full path of the database file.
        :rtype: Integer
        rz3select sql from sqlite_master where name='phrases';� z
.*\((.*)\)rr�)
rr�r*r�rrr��
splitlinesrrrr�r�)rr�r
�tp_res�stringr�tps       rr�z1TabSqliteDb.get_number_of_columns_of_phrase_tables���&�{�{�7�#��	�����)�B��Z�Z�E���h�j�
�
�X�X�f�Q�i��l�5�5�7�8�F��(�(�=�&�1�C���Y�Y�q�\�'�'��,���2�w����	��s�BB5�5B9r%c��|syd}|jj|d|i�j�}d}|r|dd}tdkDrtjd|�|S)zGet goucima of given characterrz0SELECT goucima FROM main.goucima WHERE zi = :zi;r%rrz
goucima=%s)r
rrryrr�)rr%rrr&s     r�get_goucimazTabSqliteDb.get_goucima1s]����C���'�'�/�/�&�4��*�5�>�>�@������a�j��m�G���?��L�L��w�/��r!c�z�tdkDr!tjd||j�|syt	|�dk(r|j|�S|jsyt	|�|jvr|jt	|�}nwt
|jdt�r8t	|�|jdkDr|j|jd}n"tjd||j�yt
|t�s:t	|�|jkDr"tjd||j�yd}t
|t�ry|D]9\}}|dkDr|dz}|dkDr|dz}|j||�|}|sy||z
}�;tdkDrtjd|�|S)	uRParse phrase to get its table code

        Example:

        Let’s assume we use wubi-jidian86. The rules in the source of
        that table are:

          RULES = ce2:p11+p12+p21+p22;ce3:p11+p21+p31+p32;ca4:p11+p21+p31+p-11

        “ce2” is a rule for phrases of length 2, “ce3” is a rule
        for phrases of length 3, “ca4” is a rule for phrases of
        length 4 *and* for all phrases with a length greater then
        4. “pnm” in such a rule means to use the n-th character of
        the phrase and take the m-th character of the table code of
        that character. I.e. “p-11” is the first character of the
        table code of the last character in the phrase.

        Let’s assume the phrase is “天下大事”. The goucima (構詞碼
        = “word formation keys”) for these 4 characters when
        using the wubi-jidian86 table are:

            character goucima
            天        gdi
            下        ghi
            大        dddd
            事        gkvh

        (If no special goucima are defined by the user, the longest
        encoding for a single character in a table is the goucima for
        that character).

        The length of the phrase “天下大事” is 4 characters,
        therefore the rule ca4:p11+p21+p31+p-11 applies, i.e. the
        table code for “天下大事” is calculated by using the first,
        second, third and last character of the phrase and taking the
        first character of the goucima for each of these. Therefore,
        the table code for “天下大事” is “ggdg”.

        rzphrase=%s rules%srr�z2No rule for this phrase length. phrase=%s rules=%sz6Rule exceeds maximum key length. rule=%s self._mlen=%srz
tabkeys=%s)	ryrr�r[r�r��
isinstancervr�)rrlr
rkr%�ma�tabkeys       r�parse_phrasezTabSqliteDb.parse_phrase>s���P��?��L�L�,�f�d�j�j�A����v�;�!���#�#�F�+�+��z�z���v�;�$�*�*�$��:�:�c�&�k�*�D�����G�,�c�2��f�+��
�
�7� 3�3��:�:�d�j�j��1�2�D��L�L�D���
�
�
$���$��$��T��T�Z�Z�)?��L�L�(�)-�t�z�z�
;�����d�C� ���	�H�R���A�v��a����A�v��a����%�%�f�R�j�1�"�5�F����v��G�	���?��L�L��w�/��r!c��tdkDrtjd||�|r|syd}|dz|d�}|jj	||�j�}tdkDrtjd|||�t
|�S)u�
        Checks whether “phrase” can be matched in the system database
        with a key sequence *starting* with “tabkeys”.
        r�tabkeys=%s phrase=%sFzf
        SELECT * FROM main.phrases
        WHERE tabkeys LIKE :tabkeys AND phrase = :phrase;
        rlr ztabkeys=%s phrase=%s results=%s)ryrr�r
rr�bool)rrkrlrr�rs      r�is_in_system_databasez!TabSqliteDb.is_in_system_database�s�����?��L�L�/��&�A��f����&�d�l�f�=���'�'�/�/�&�'�2�;�;�=����?��L�L�1����
*��G�}�r!c��tdkDrtjd||�|r|syd}||d�}|jj	||�j�}tdkDrtjd|�|rt
|dd�Sy)u
        Return how often a conversion result “phrase” for the typed keys
        “tabkeys” has been happened by checking the user database.

        :param tabkeys: The keys typed
        :param phrase: A conversion result for these tabkeys
        rr�rz�
        SELECT sum(user_freq) FROM user_db.phrases
        WHERE tabkeys = :tabkeys AND phrase = :phrase GROUP BY tabkeys, phrase;
        r z	result=%s)ryrr�r
rrrv)rrkrlrr�rs      r�user_frequencyzTabSqliteDb.user_frequency�s�����?��L�L�/��&�A��f����&��8���������1�:�:�<����?��L�L��f�-���v�a�y��|�$�$�r!c���tdkDrtjd||�|r|sy|jr	|tvry|so|j
r|jsy|j
|�}|sy|j||��ry|j||��dkDry|j||ddd��y|j||��rG|j||��}|dkDr|j|||dz�	�y|j||ddd��y|j
r|jsy|j
|�}|sy|j||��}|dkDr|j|||dz�	�y|j||ddd��y)
aAdjust user_freq in user database if necessary.

        Also, if the phrase is not in the system database, and it is a
        Chinese table, and defining user phrases is allowed, add it as
        a user defined phrase to the user database if it is not yet
        there.
        rztabkey=%s phrase=%sNr rr�r2)rkrlrmrnr�)rkrlrn)ryrr�r��CHINESE_NOCHECK_CHARSrPr�r�r�r"r�)rrkrlrSrns     r�check_phrasezTabSqliteDb.check_phrase�s�����?��L�L�.���@��f������*?� ?����.�.�d�6F�6F���'�'��/�G����)�)�'�&�)�I���"�"�7�6�"�B�Q�F���O�O���R�1�"�
�
$��)�)�'�&�)�I� �/�/���/�O�	��q�=��&�&� '��)�A�+�'�O��O�O� '��Q�!�!*�$�,��2�2�$�:J�:J���+�+�F�3���� �/�/���/�O�	��q�=��&�&� '��)�A�+�'�O��O�O� '��R�1�!*�$�,r!c��d}d|i}|jj||�j�}|D�cgc]}|d��	}}|Scc}w)uu
        Return the list of possible tabkeys for a phrase.

        For example, if “phrase” is “你” and the table is wubi-jidian.86.txt,
        the result will be ['wq', 'wqi', 'wqiy'] because that table
        contains the following 3 lines matching that phrase exactly:

        wq	你	597727619
        wqi	你	1490000000
        wqiy	你	1490000000
        zo
        SELECT tabkeys FROM main.phrases WHERE phrase = :phrase
        ORDER by length(tabkeys) ASC;
        rlr)r
rr)rrlrr�rr�list_of_possible_tabkeyss       r�find_zi_codezTabSqliteDb.find_zi_code�sU�����V�$���'�'�/�/�&�'�2�;�;�=��29�#:�Q�A�a�D�#:� �#:�'�'��$;s�Ac��tjd||||�|sy|rdd|iz}ndd|iz}||d�}|jj||�|r|jj	�|j|�y)z$Remove phrase from database
        z5Removing tabkeys=%s, phrase=%s, database=%s commit=%sNzu
            DELETE FROM %(database)s.phrases
            WHERE tabkeys = :tabkeys AND phrase = :phrase;
            r�z^
            DELETE FROM %(database)s.phrases
            WHERE phrase = :phrase;
            r )r�infor
rr�r�)rrkrlr�r��
delete_sqlstr�delete_sqlargss       r�
remove_phrasezTabSqliteDb.remove_phrases���	���K��V�X�v�	7������x�(�)�M�
��x�(�)�M�&-��?�������
�~�6���G�G�N�N���%�%�g�.r!c�8�tjd�	|jjd�|jj	�|jjd�|j�y#t$rtjd�YywxYw)zv
        Remove all phrases from the user database, i.e. delete all the
        data learned from user input.
        z,Removing all phrases from the user database.zDELETE FROM user_db.phrases;ruz4Unexpected error removing all phrases from database.N)rr�r
rr�r~rrr$s r�remove_all_phrases_from_user_dbz+TabSqliteDb.remove_all_phrases_from_user_db0sv��
	���B�C�	H��G�G�O�O�:�;��G�G�N�N���G�G�O�O�4�5��$�$�&���	H����F�
H�	H�s�A A8�8B�B�
database_filerqc�h�tjd�	tj|�}|j	d�|dk\ra|j	d�j�}|j
�t|d���}tjdt|��|ddSg}|j	d	�j�}|D]�}d
}d|di}|jj	||�j�}	|	r"|j|	dd|dd|d
f��Z|j|d�}
|
s�q|j|
|dd|d
f���|j
�t|d���}tjdt|��|ddS#tjd�gcYSxYw)z"extract user phrases from databasezBTrying to recover the phrases from the old, incompatible database.rur
z�
                    SELECT tabkeys, phrase, freq, sum(user_freq) FROM phrases
                    GROUP BY tabkeys, phrase, freq;
                    c�&�|d|d|d|dfS�Nrrrrrsr.rOs rrPz2TabSqliteDb.extract_user_phrases.<locals>.<lambda>Ts��A�a�D�!�A�$��!��a��d�+C�r!r`z3Recovered phrases from the old database: phrases=%sNz;SELECT phrase, sum(user_freq) FROM phrases GROUP BY phrase;z�
                SELECT tabkeys FROM main.phrases WHERE phrase = :phrase
                ORDER BY length(tabkeys) DESC;
                rlrrr�c�&�|d|d|d|dfSr�r.rOs rrPz2TabSqliteDb.extract_user_phrases.<locals>.<lambda>zs���!��a��d�A�a�D�!�A�$�'?�r!z8Recovered phrases from the very old database: phrases=%sz*Unexpected error in extract_user_phrases())
rr�r*r�rrr�r�r#r
r�r�r)rr�rqr
rrrrr��tabkeys_resultsrks           rr�z TabSqliteDb.extract_user_phrases?s���	���
%�	&�9	�����/�B��J�J�/�0�#�v�-��*�*���
�(�*�����
� ��!C�E�����I���M�#��q�z�!�
�G��j�j�2���h�j�
�"�
L����$�V�A�Y�/��"&�'�'�/�/��G�#%�%-�X�Z� �"��N�N�(��+�A�.��q�	�1�f�Q�i�H�J�#�/�/��q�	�:�G�� �������B��q�	�'J�K�+
L�,
�H�H�J���?�A�G��L�L��"�7�m�
-��1�:���	����I�J��I�s�BF�#BF�7AF�F1)rrFF)rrrr2T)rN)r)r�)rrrrr�T)T)rr.r�)rFr�rrFF)rr�rr)rr)rrF)rrr2T)rrp):r&r'r(r)r-r�rrvr�r�r~r�r�r�r�r�r�r�r�r�rrr�rrrr�r�r�rrr"r'r5r8r:r>r��bytesrGrerwryrr�r�rr�r�r�r�r�r�r�r�r�r�r�r.r!rr0r0ys����8��$)�#�X$��X$��X$�"�	X$�
�X$�
)-�X$�x���%��
M��M��M��	M�
�M��
M�%)�
M�:2�\�6��6�T�6�F�,J� �D������#��$%��%�����c��d��6&���s�C�x�� 9�&�d�&�8.�4��c�3�h���s�D��s�C�x��<Q�7Q�1R� R�S�.�`"�d�3�i�"�H6��6��C��#�%2��e�C��c�3�$6�7�8�%2��%2�(,�%2�R����"��6A��6A��6A��	6A�
�6A��
6A��6A�%)�6A�pC�H�U�3��8�_�$=�C�$�C�*#���e�C��c�M�2�3����(,��@#��!�%��S��/�2����(,��.�8+�c�+�d�+�
-��
-�d�
-�d�
-������"$�>@� !�	?8��?8�!��s�C��c�'9�!:�;�?8��	?8�'/�u�S�#�s�C�5G�/H�&I�	?8�F�!� !�(*�')�"'�#(�e��e��e��	e�
#&�e�"%�
e� �e�!�e�.6�e�C��c�3�<N�6O�-P�e�R� !�(*�')�+'��+'��+'�#&�	+'�
"%�+'�
/7�u�S�#�s�C�=O�7P�.Q�+'�\!#�-8��-8�'+�E�#�s�(�O�'<�-8�^L�*�C��D��0����$�s�C�x�.�1I��(#�S�#�S�#�J�c��c��R�3�R�3�R�j46����-0��:>��,�c����S��4��#(�	=,��=,��=,�!�	=,�.2�	=,�~(�3�(�4��9�(�.��%��/��/��/��	/�
�/�
%)�/�8
H�""$�(-�B��B�#&�B�
�e�C��c�3�&�'�	(�	Br!r0)r)�typingrrrrrrr	rw�os.pathrr�r*r:r�r�loggingr�rZr��	getLoggerrrvryr�r�rr0r.r!r�<module>r�s���.��������	��
����	�����	��	�	�<�	(���!�f����/��@$H�$H�LH�Hr!

Zerion Mini Shell 1.0