1 # SPDX-License-Identifier: GPL-3.0-or-later
 
   3 # This file is part of Nominatim. (https://nominatim.org)
 
   5 # Copyright (C) 2025 by the Nominatim developer community.
 
   6 # For a full list of authors see the git log.
 
   8 Functions for creating a tokenizer or initialising the right one for an
 
  11 A tokenizer is something that is bound to the lifetime of a database. It
 
  12 can be chosen and configured before the initial import but then needs to
 
  13 be used consistently when querying and updating the database.
 
  15 This module provides the functions to create and configure a new tokenizer
 
  16 as well as instantiating the appropriate tokenizer for updating an existing
 
  19 from typing import Optional
 
  22 from pathlib import Path
 
  24 from ..errors import UsageError
 
  25 from ..db import properties
 
  26 from ..db.connection import connect
 
  27 from ..config import Configuration
 
  28 from ..tokenizer.base import AbstractTokenizer, TokenizerModule
 
  30 LOG = logging.getLogger()
 
  33 def _import_tokenizer(name: str) -> TokenizerModule:
 
  34     """ Load the tokenizer.py module from project directory.
 
  36     src_file = Path(__file__).parent / (name + '_tokenizer.py')
 
  37     if not src_file.is_file():
 
  38         LOG.fatal("No tokenizer named '%s' available. "
 
  39                   "Check the setting of NOMINATIM_TOKENIZER.", name)
 
  40         raise UsageError('Tokenizer not found')
 
  42     return importlib.import_module('nominatim_db.tokenizer.' + name + '_tokenizer')
 
  45 def create_tokenizer(config: Configuration, init_db: bool = True,
 
  46                      module_name: Optional[str] = None) -> AbstractTokenizer:
 
  47     """ Create a new tokenizer as defined by the given configuration.
 
  49         The tokenizer data and code is copied into the 'tokenizer' directory
 
  50         of the project directory and the tokenizer loaded from its new location.
 
  52     if module_name is None:
 
  53         module_name = config.TOKENIZER
 
  55     # Import and initialize the tokenizer.
 
  56     tokenizer_module = _import_tokenizer(module_name)
 
  58     tokenizer = tokenizer_module.create(config.get_libpq_dsn())
 
  59     tokenizer.init_new_db(config, init_db=init_db)
 
  61     with connect(config.get_libpq_dsn()) as conn:
 
  62         properties.set_property(conn, 'tokenizer', module_name)
 
  67 def get_tokenizer_for_db(config: Configuration) -> AbstractTokenizer:
 
  68     """ Instantiate a tokenizer for an existing database.
 
  70         The function looks up the appropriate tokenizer in the database
 
  73     with connect(config.get_libpq_dsn()) as conn:
 
  74         name = properties.get_property(conn, 'tokenizer')
 
  77         LOG.fatal("Tokenizer was not set up properly. Database property missing.")
 
  78         raise UsageError('Cannot initialize tokenizer.')
 
  80     tokenizer_module = _import_tokenizer(name)
 
  82     tokenizer = tokenizer_module.create(config.get_libpq_dsn())
 
  83     tokenizer.init_from_project(config)