6565logger = logging .getLogger (__name__ )
6666
6767tbl_index = None # Module-level index of all scripts.
68+ proc_aliases = set () # Set of alias tables already created.
69+ aliases = {} # Map of language to alias.
6870
6971
7072class Token (str ):
@@ -165,7 +167,9 @@ def init_db():
165167 conn .executescript (fh .read ())
166168
167169 # Populate tables.
168- global tbl_index
170+ global tbl_index , proc_aliases , aliases
171+ proc_aliases = set ()
172+ aliases = {}
169173 with open (path .join (path .dirname (TABLE_DIR ), "index.yml" )) as fh :
170174 tbl_index = load (fh , Loader = Loader )
171175 try :
@@ -205,6 +209,10 @@ def populate_table(conn, tname, tdata):
205209 """
206210 logger .info (f"Populating table: { tname } " )
207211
212+ check_q = "SELECT id FROM tbl_language WHERE name = ?"
213+ if conn .execute (check_q , (tname ,)).fetchone ():
214+ return
215+
208216 res = conn .execute (
209217 """INSERT INTO tbl_language (
210218 name, label, marc_code, description
@@ -217,6 +225,20 @@ def populate_table(conn, tname, tdata):
217225 tid = res .lastrowid
218226
219227 data = load_table (tname )
228+ if "alias_of" in data :
229+ # If an alias, insert the alias ID.
230+ ref_name = data ["alias_of" ]
231+ logger .info (f"{ tname } is an alias of { ref_name } ." )
232+ ref_data = conn .execute (check_q , (ref_name ,)).fetchone ()
233+ # Check if the ref table has already been populated.
234+ if not ref_data :
235+ populate_table (conn , ref_name , tbl_index [ref_name ])
236+ ref_data = conn .execute (check_q , (ref_name ,)).fetchone ()
237+ ref_id = ref_data [0 ]
238+ conn .execute (
239+ "UPDATE tbl_language SET ref_id = ? WHERE id = ?" ,
240+ (ref_id , tid ))
241+
220242 flags = 0
221243 if "script_to_roman" in data :
222244 flags |= FEAT_S2R
@@ -340,16 +362,20 @@ def load_table(tname):
340362 The table file is parsed into an in-memory configuration that contains
341363 the language & script metadata and parsing rules.
342364 """
365+ if "alias_of" in tbl_index .get (tname , {}):
366+ conf_name = tbl_index [tname ]["alias_of" ]
367+ aliases [tname ] = conf_name
343368
344- try :
345- fname = path .join (TABLE_DIR , tbl_index [tname ]["conf" ])
346- except KeyError :
347- # If no `conf` key is provided, use the conventional table name + .yml.
348- fname = path .join (TABLE_DIR , tname + ".yml" )
369+ return {"alias_of" : conf_name }
370+
371+ else :
372+ # If no `alias_of` key is provided, use the regular table name + .yml.
373+ conf_name = tname
374+
375+ fname = path .join (TABLE_DIR , conf_name + ".yml" )
349376 if not access (fname , R_OK ):
350377 raise ValueError (
351378 f"No transliteration table `{ fname } ` found for { tname } !" )
352-
353379 with open (fname ) as fh :
354380 tdata = load (fh , Loader = Loader )
355381
@@ -568,9 +594,13 @@ def get_language(lang):
568594
569595def get_lang_general (conn , lang ):
570596 """ Language general attributes. """
597+ ref_q = "SELECT id, ref_id FROM tbl_language WHERE name = ?"
598+ ref_data = conn .execute (ref_q , (lang ,)).fetchone ()
599+ lang_id = ref_data [1 ] if ref_data [1 ] else ref_data [0 ]
600+
571601 lang_q = conn .execute (
572602 """SELECT id, name, label, features, marc_code, description
573- FROM tbl_language WHERE name = ?""" , (lang ,))
603+ FROM tbl_language WHERE id = ?""" , (lang_id ,))
574604 lang_data = lang_q .fetchone ()
575605
576606 if not lang_data :
@@ -579,7 +609,7 @@ def get_lang_general(conn, lang):
579609 return {
580610 "id" : lang_data [0 ],
581611 "data" : {
582- "name" : lang_data [ 1 ] ,
612+ "name" : lang ,
583613 "label" : lang_data [2 ],
584614 "has_s2r" : bool (lang_data [3 ] & FEAT_S2R ),
585615 "has_r2s" : bool (lang_data [3 ] & FEAT_R2S ),
@@ -591,6 +621,7 @@ def get_lang_general(conn, lang):
591621
592622
593623def get_lang_normalize (conn , lang_id ):
624+ lang_id = _get_ref (conn , lang_id )
594625 qry = conn .execute (
595626 """SELECT src, dest FROM tbl_normalize
596627 WHERE lang_id = ?""" ,
@@ -602,6 +633,7 @@ def get_lang_ignore(conn, lang_id):
602633 """
603634 Ignore list as a tuple.
604635 """
636+ lang_id = _get_ref (conn , lang_id )
605637 qry = conn .execute (
606638 """SELECT rule, features FROM tbl_ignore
607639 WHERE lang_id = ?""" ,
@@ -618,6 +650,7 @@ def get_lang_map(conn, lang_id, t_dir):
618650
619651 Generator of tuples (source, destination).
620652 """
653+ lang_id = _get_ref (conn , lang_id )
621654 qry = conn .execute (
622655 """SELECT src, dest FROM tbl_trans_map
623656 WHERE lang_id = ? AND dir = ?
@@ -630,6 +663,7 @@ def get_lang_map(conn, lang_id, t_dir):
630663
631664def get_lang_options (conn , lang_id ):
632665 """ Language options as a tuple of dictionaries. """
666+ lang_id = _get_ref (conn , lang_id )
633667 qry = conn .execute (
634668 """SELECT name, label, description, dtype, options, default_v
635669 FROM tbl_option
@@ -650,6 +684,7 @@ def get_lang_options(conn, lang_id):
650684
651685
652686def get_lang_hooks (conn , lang_id , t_dir ):
687+ lang_id = _get_ref (conn , lang_id )
653688 """ Language hooks in sorting order. """
654689 hooks = defaultdict (list )
655690
@@ -672,9 +707,18 @@ def get_lang_hooks(conn, lang_id, t_dir):
672707
673708
674709def get_lang_dcap (conn , lang_id ):
710+ lang_id = _get_ref (conn , lang_id )
675711 qry = conn .execute (
676712 """SELECT rule
677713 FROM tbl_double_cap WHERE lang_id = ?""" ,
678714 (lang_id ,))
679715
680716 return tuple (row [0 ] for row in qry )
717+
718+
719+ def _get_ref (conn , lang_id ):
720+ ref_data = conn .execute (
721+ """SELECT ref_id FROM tbl_language WHERE id = ?""" ,
722+ (lang_id ,)).fetchone ()
723+
724+ return ref_data [0 ] if ref_data and ref_data [0 ] else lang_id
0 commit comments