DESTINATION ${CMAKE_INSTALL_BINDIR}
RENAME nominatim)
- foreach (submodule nominatim_core nominatim_db nominatim_api)
+ if (EXISTS ${PHP_BIN})
+ configure_file(${PROJECT_SOURCE_DIR}/cmake/paths-py.tmpl paths-py.installed)
+ else()
+ configure_file(${PROJECT_SOURCE_DIR}/cmake/paths-py-no-php.tmpl paths-py.installed)
+ endif()
+
+ foreach (submodule nominatim_db nominatim_api)
install(DIRECTORY src/${submodule}
DESTINATION ${NOMINATIM_LIBDIR}/lib-python
FILES_MATCHING PATTERN "*.py"
PATTERN "paths.py" EXCLUDE
PATTERN __pycache__ EXCLUDE)
+ install(FILES ${PROJECT_BINARY_DIR}/paths-py.installed
+ DESTINATION ${NOMINATIM_LIBDIR}/lib-python/${submodule}
+ RENAME paths.py)
endforeach()
- if (EXISTS ${PHP_BIN})
- configure_file(${PROJECT_SOURCE_DIR}/cmake/paths-py.tmpl paths-py.installed)
- else()
- configure_file(${PROJECT_SOURCE_DIR}/cmake/paths-py-no-php.tmpl paths-py.installed)
- endif()
- install(FILES ${PROJECT_BINARY_DIR}/paths-py.installed
- DESTINATION ${NOMINATIM_LIBDIR}/lib-python/nominatim_core
- RENAME paths.py)
-
install(DIRECTORY lib-sql DESTINATION ${NOMINATIM_LIBDIR})
install(FILES ${COUNTRY_GRID_FILE}
# Building of wheels
-build: build-core build-db build-api
+build: clean-build build-db build-api
-build-core:
- python3 -m build packaging/nominatim-core --outdir dist/
+clean-build:
+ rm -f dist/*
build-db:
python3 -m build packaging/nominatim-db --outdir dist/
bdd:
cd test/bdd; behave -DREMOVE_TEMPLATE=1
-.PHONY: tests mypy pytest lint bdd build build-core build-db build-api
+.PHONY: tests mypy pytest lint bdd build clean-build build-db build-api
To install Nominatim directly from the source tree into the virtual environment, run:
- /srv/nominatim-venv/bin/pip install packaging/nominatim-{core,db,api}
+ /srv/nominatim-venv/bin/pip install packaging/nominatim-{db,api}
#### Building in legacy CMake mode
## `Configuration` class
-::: nominatim_core.config.Configuration
+::: nominatim_api.Configuration
options:
members:
- get_bool
--- /dev/null
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of Nominatim. (https://nominatim.org)
+#
+# Copyright (C) 2024 by the Nominatim developer community.
+# For a full list of authors see the git log.
+"""
+Path settings for extra data used by Nominatim.
+"""
+from pathlib import Path
+
+PHPLIB_DIR = None
+DATA_DIR = None
+SQLLIB_DIR = None
+CONFIG_DIR = (Path(__file__) / '..' / 'resources' / 'settings').resolve()
"Operating System :: OS Independent",
]
dependencies = [
- "nominatim-core",
+ "python-dotenv",
+ "pyYAML>=5.1",
"SQLAlchemy>=1.4.31",
"psycopg",
"PyICU"
pattern = "NOMINATIM_API_VERSION = '(?P<version>[^']+)'"
[tool.hatch.build.targets.sdist]
-include = ["src/nominatim_api"]
+include = [
+ "src/nominatim_api",
+ "src/nominatim_db/config.py",
+ "settings",
+ "extra_src/paths.py"
+]
+
+exclude = [
+ "src/nominatim_api/config.py"
+]
[tool.hatch.build.targets.wheel]
packages = ["src/nominatim_api"]
+[tool.hatch.build.targets.wheel.force-include]
+"src/nominatim_db/config.py" = "nominatim_api/config.py"
+"extra_src/paths.py" = "nominatim_api/paths.py"
+"settings" = "nominatim_api/resources/settings"
+++ /dev/null
-../../COPYING
\ No newline at end of file
+++ /dev/null
-Nominatim - Core Package
-=========
-
-Nominatim is a tool to search OpenStreetMap data
-by name and address (geocoding) and to generate synthetic addresses of
-OSM points (reverse geocoding).
-
-This is the core pacakage containing resources and code shared by
-Nominatim's frontend `nominatim-api` and backend `nominatim-db`. You
-usually don't want to install this package directly.
-
-Documentation
-=============
-
-The documentation of the latest development version is in the
-`docs/` subdirectory. A HTML version can be found at
-https://nominatim.org/release-docs/develop/ .
-
-License
-=======
-
-The Python source code is available under a GPL license version 3 or later.
-The Lua configuration files for osm2pgsql are released under the
-Apache License, Version 2.0. All other files are under a GPLv2 license.
+++ /dev/null
-../../data
\ No newline at end of file
+++ /dev/null
-[project]
-name = "nominatim-core"
-description = "A tool for building a database of OpenStreetMap for geocoding and for searching the database. Base package for common resources for the project."
-readme = "README.md"
-requires-python = ">=3.7"
-license = 'GPL-3.0-or-later'
-maintainers = [
- { name = "Sarah Hoffmann", email = "lonvia@denofr.de" }
-]
-keywords = [ "geocoding", "OpenStreetMap", "search" ]
-classifiers = [
- "Programming Language :: Python :: 3",
- "License :: OSI Approved :: GNU General Public License (GPL)",
- "Operating System :: OS Independent",
-]
-dependencies = [
- "python-dotenv",
- "jinja2",
- "pyYAML>=5.1",
- "datrie"
-]
-dynamic = ["version"]
-
-[project.urls]
-Homepage = "https://nominatim.org"
-Issues = "https://github.com/osm-search/Nominatim/issues"
-
-[build-system]
-requires = ["hatchling"]
-build-backend = "hatchling.build"
-
-[tool.hatch.version]
-source = "code"
-path = "src/nominatim_core/version.py"
-expression = "NOMINATIM_CORE_VERSION"
-
-[tool.hatch.build.targets.sdist]
-include = [
- "src/nominatim_core",
- "lib-sql/**.sql",
- "settings",
- "data/words.sql",
- "extra_src/nominatim_core/paths.py"
-]
-artifacts = [
- "data/country_osm_grid.sql.gz"
-]
-exclude = [
- "src/nominatim_core/paths.py"
-]
-
-[tool.hatch.build.targets.wheel]
-packages = ["src/nominatim_core"]
-
-[tool.hatch.build.targets.wheel.force-include]
-"lib-sql" = "nominatim_core/resources/lib-sql"
-"settings" = "nominatim_core/resources/settings"
-"data/country_osm_grid.sql.gz" = "nominatim_core/resources/country_osm_grid.sql.gz"
-"data/words.sql" = "nominatim_core/resources/words.sql"
-"extra_src/nominatim_core/paths.py" = "nominatim_core/paths.py"
+++ /dev/null
-../../src
\ No newline at end of file
--- /dev/null
+../../data/
\ No newline at end of file
"Operating System :: OS Independent",
]
dependencies = [
- "nominatim-core",
"psycopg2-binary",
+ "python-dotenv",
+ "jinja2",
+ "pyYAML>=5.1",
+ "datrie",
"psutil",
"PyICU"
]
[project.urls]
Homepage = "https://nominatim.org"
Issues = "https://github.com/osm-search/Nominatim/issues"
+Documentation = "https://nominatim.org/release-docs/latest/"
[build-system]
requires = ["hatchling"]
pattern = "NOMINATIM_VERSION = parse_version.'(?P<version>[^-]+)"
[tool.hatch.build.targets.sdist]
-include = ["src/nominatim_db", "scripts"]
+include = [
+ "src/nominatim_db",
+ "scripts",
+ "lib-sql/**/*.sql",
+ "settings",
+ "data/words.sql",
+ "extra_src/nominatim_db/paths.py"
+]
+
+artifacts = [
+ "data/country_osm_grid.sql.gz"
+]
+
+exclude = [
+ "src/nominatim_db/paths.py"
+]
[tool.hatch.build.targets.wheel]
packages = ["src/nominatim_db"]
[tool.hatch.build.targets.wheel.shared-scripts]
"scripts" = "/"
+
+[tool.hatch.build.targets.wheel.force-include]
+"lib-sql" = "nominatim_db/resources/lib-sql"
+"settings" = "nominatim_db/resources/settings"
+"data/country_osm_grid.sql.gz" = "nominatim_db/resources/country_osm_grid.sql.gz"
+"data/words.sql" = "nominatim_db/resources/words.sql"
+"extra_src/nominatim_db/paths.py" = "nominatim_db/paths.py"
--- /dev/null
+../../settings/
\ No newline at end of file
# See also https://github.com/PyCQA/pylint/issues/6006
# pylint: disable=useless-import-alias
-from nominatim_core.errors import (UsageError as UsageError)
-from nominatim_core.config import (Configuration as Configuration)
+from .errors import (UsageError as UsageError)
+from .config import (Configuration as Configuration)
from .core import (NominatimAPI as NominatimAPI,
NominatimAPIAsync as NominatimAPIAsync)
--- /dev/null
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of Nominatim. (https://nominatim.org)
+#
+# Copyright (C) 2024 by the Nominatim developer community.
+# For a full list of authors see the git log.
+
+# This file is just a placeholder to make the config module available
+# during development. It will be replaced by nominatim_db/config.py on
+# installation.
+# pylint: skip-file
+from nominatim_db.config import *
import sqlalchemy as sa
from sqlalchemy.ext.asyncio import AsyncConnection
-from nominatim_core.typing import SaFromClause
-from nominatim_core.db.sqlalchemy_schema import SearchTables
-from nominatim_core.db.sqlalchemy_types import Geometry
+from .typing import SaFromClause
+from .sql.sqlalchemy_schema import SearchTables
+from .sql.sqlalchemy_types import Geometry
from .logging import log
T = TypeVar('T')
import sqlalchemy as sa
import sqlalchemy.ext.asyncio as sa_asyncio
-from nominatim_core.errors import UsageError
-from nominatim_core.db.sqlalchemy_schema import SearchTables
-from nominatim_core.db.async_core_library import PGCORE_LIB, PGCORE_ERROR
-from nominatim_core.config import Configuration
+from .errors import UsageError
+from .sql.sqlalchemy_schema import SearchTables
+from .sql.async_core_library import PGCORE_LIB, PGCORE_ERROR
+from .config import Configuration
from .sql import sqlite_functions, sqlalchemy_functions #pylint: disable=unused-import
from .connection import SearchConnection
from .status import get_status, StatusResult
import sqlalchemy as sa
-from nominatim_core.typing import SaColumn, SaRow, SaSelect
+from .typing import SaColumn, SaRow, SaSelect
from .connection import SearchConnection
from .logging import log
from . import types as ntyp
import sqlalchemy as sa
-from nominatim_core.typing import SaSelect, SaRow
-from nominatim_core.db.sqlalchemy_types import Geometry
+from .typing import SaSelect, SaRow
+from .sql.sqlalchemy_types import Geometry
from .types import Point, Bbox, LookupDetails
from .connection import SearchConnection
from .logging import log
import sqlalchemy as sa
-from nominatim_core.typing import SaColumn, SaSelect, SaFromClause, SaLabel, SaRow,\
- SaBind, SaLambdaSelect
-from nominatim_core.db.sqlalchemy_types import Geometry
+from .typing import SaColumn, SaSelect, SaFromClause, SaLabel, SaRow,\
+ SaBind, SaLambdaSelect
+from .sql.sqlalchemy_types import Geometry
from .connection import SearchConnection
from . import results as nres
from .logging import log
import sqlalchemy as sa
-from nominatim_core.typing import SaFromClause, SaColumn, SaExpression
-from nominatim_core.utils.json_writer import JsonWriter
+from ..typing import SaFromClause, SaColumn, SaExpression
+from ..utils.json_writer import JsonWriter
from .query import Token
from . import db_search_lookups as lookups
import sqlalchemy as sa
from sqlalchemy.ext.compiler import compiles
-from nominatim_core.typing import SaFromClause
-from nominatim_core.db.sqlalchemy_types import IntArray
+from ..typing import SaFromClause
+from ..sql.sqlalchemy_types import IntArray
# pylint: disable=consider-using-f-string
import sqlalchemy as sa
-from nominatim_core.typing import SaFromClause, SaScalarSelect, SaColumn, \
- SaExpression, SaSelect, SaLambdaSelect, SaRow, SaBind
-from nominatim_core.db.sqlalchemy_types import Geometry, IntArray
+from ..typing import SaFromClause, SaScalarSelect, SaColumn, \
+ SaExpression, SaSelect, SaLambdaSelect, SaRow, SaBind
+from ..sql.sqlalchemy_types import Geometry, IntArray
from ..connection import SearchConnection
from ..types import SearchDetails, DataLayer, GeometryFormat, Bbox
from .. import results as nres
import sqlalchemy as sa
-from nominatim_core.typing import SaRow
-from nominatim_core.db.sqlalchemy_types import Json
+from ..typing import SaRow
+from ..sql.sqlalchemy_types import Json
from ..connection import SearchConnection
from ..logging import log
from ..search import query as qmod
import sqlalchemy as sa
-from nominatim_core.typing import SaRow
+from ..typing import SaRow
from ..connection import SearchConnection
from ..logging import log
from . import query as qmod
from falcon.asgi import App, Request, Response
-from nominatim_core.config import Configuration
+from ...config import Configuration
from ...core import NominatimAPIAsync
from ... import v1 as api_impl
from ... import logging as loglib
from starlette.middleware.base import BaseHTTPMiddleware, RequestResponseEndpoint
from starlette.middleware.cors import CORSMiddleware
-from nominatim_core.config import Configuration
+from ...config import Configuration
from ...core import NominatimAPIAsync
from ... import v1 as api_impl
from ... import logging as loglib
import sqlalchemy as sa
from sqlalchemy.ext.compiler import compiles
-from nominatim_core.typing import SaColumn
+from ..typing import SaColumn
# pylint: disable=all
import sqlalchemy as sa
from .connection import SearchConnection
-from .version import NOMINATIM_API_VERSION, NominatimVersion, parse_version
+from .version import NOMINATIM_API_VERSION
@dataclasses.dataclass
class StatusResult:
message: str
software_version = NOMINATIM_API_VERSION
data_updated: Optional[dt.datetime] = None
- database_version: Optional[NominatimVersion] = None
+ database_version: Optional[str] = None
async def get_status(conn: SearchConnection) -> StatusResult:
# Database version
try:
- status.database_version = parse_version(await conn.get_property('database_version'))
+ status.database_version = await conn.get_property('database_version')
except ValueError:
pass
from struct import unpack
from binascii import unhexlify
-from nominatim_core.errors import UsageError
+from .errors import UsageError
from .localization import Locales
# pylint: disable=no-member,too-many-boolean-expressions,too-many-instance-attributes
--- /dev/null
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of Nominatim. (https://nominatim.org)
+#
+# Copyright (C) 2024 by the Nominatim developer community.
+# For a full list of authors see the git log.
+"""
+Type definitions for typing annotations.
+
+Complex type definitions are moved here, to keep the source files readable.
+"""
+from typing import Union, TYPE_CHECKING
+
+# pylint: disable=missing-class-docstring,useless-import-alias
+
+# SQLAlchemy introduced generic types in version 2.0 making typing
+# incompatible with older versions. Add wrappers here so we don't have
+# to litter the code with bare-string types.
+
+if TYPE_CHECKING:
+ from typing import Any
+ import sqlalchemy as sa
+ import os
+ from typing_extensions import (TypeAlias as TypeAlias)
+else:
+ TypeAlias = str
+
+StrPath = Union[str, 'os.PathLike[str]']
+
+SaLambdaSelect: TypeAlias = 'Union[sa.Select[Any], sa.StatementLambdaElement]'
+SaSelect: TypeAlias = 'sa.Select[Any]'
+SaScalarSelect: TypeAlias = 'sa.ScalarSelect[Any]'
+SaRow: TypeAlias = 'sa.Row[Any]'
+SaColumn: TypeAlias = 'sa.ColumnElement[Any]'
+SaExpression: TypeAlias = 'sa.ColumnElement[bool]'
+SaLabel: TypeAlias = 'sa.Label[Any]'
+SaFromClause: TypeAlias = 'sa.FromClause'
+SaSelectable: TypeAlias = 'sa.Selectable'
+SaBind: TypeAlias = 'sa.BindParameter[Any]'
+SaDialect: TypeAlias = 'sa.Dialect'
import collections
import datetime as dt
-from nominatim_core.utils.json_writer import JsonWriter
+from ..utils.json_writer import JsonWriter
from ..status import StatusResult
from ..results import DetailedResult, ReverseResults, SearchResults, \
AddressLines, AddressLine
"""
from typing import Mapping, Any, Optional, Tuple, Union
-from nominatim_core.utils.json_writer import JsonWriter
+from ..utils.json_writer import JsonWriter
from ..results import AddressLines, ReverseResults, SearchResults
from . import classtypes as cl
import sqlalchemy as sa
-from nominatim_core.errors import UsageError
-from nominatim_core.config import Configuration
+from ..errors import UsageError
+from ..config import Configuration
from .. import logging as loglib
from ..core import NominatimAPIAsync
from .format import dispatch as formatting
Version information for the Nominatim API.
"""
-# See also https://github.com/PyCQA/pylint/issues/6006
-# pylint: disable=useless-import-alias,unused-import
-
-from nominatim_core.version import (NominatimVersion as NominatimVersion,
- parse_version as parse_version)
-
NOMINATIM_API_VERSION = '4.4.99'
+++ /dev/null
-# SPDX-License-Identifier: GPL-3.0-or-later
-#
-# This file is part of Nominatim. (https://nominatim.org)
-#
-# Copyright (C) 2024 by the Nominatim developer community.
-# For a full list of authors see the git log.
-"""
-Version information for the Nominatim core package.
-"""
-from typing import NamedTuple, Optional
-
-__version__ = '4.4.99'
-NOMINATIM_CORE_VERSION = __version__
-
-class NominatimVersion(NamedTuple):
- """ Version information for Nominatim. We follow semantic versioning.
-
- Major, minor and patch_level refer to the last released version.
- The database patch level tracks important changes between releases
- and must always be increased when there is a change to the database or code
- that requires a migration.
-
- When adding a migration on the development branch, raise the patch level
- to 99 to make sure that the migration is applied when updating from a
- patch release to the next minor version. Patch releases usually shouldn't
- have migrations in them. When they are needed, then make sure that the
- migration can be reapplied and set the migration version to the appropriate
- patch level when cherry-picking the commit with the migration.
- """
-
- major: int
- minor: int
- patch_level: int
- db_patch_level: Optional[int]
-
- def __str__(self) -> str:
- if self.db_patch_level is None:
- return f"{self.major}.{self.minor}.{self.patch_level}"
-
- return f"{self.major}.{self.minor}.{self.patch_level}-{self.db_patch_level}"
-
- def release_version(self) -> str:
- """ Return the release version in semantic versioning format.
-
- The release version does not include the database patch version.
- """
- return f"{self.major}.{self.minor}.{self.patch_level}"
-
-
-def parse_version(version: str) -> NominatimVersion:
- """ Parse a version string into a version consisting of a tuple of
- four ints: major, minor, patch level, database patch level
-
- This is the reverse operation of `version_str()`.
- """
- parts = version.split('.')
- return NominatimVersion(*[int(x) for x in parts[:2] + parts[2].split('-')])
import argparse
from pathlib import Path
-from nominatim_core.config import Configuration
-from nominatim_core.errors import UsageError
+from .config import Configuration
+from .errors import UsageError
from .tools.exec_utils import run_php_server
from . import clicmd
from . import version
import argparse
import random
-from nominatim_core.errors import UsageError
-from nominatim_core.db.connection import connect
+from ..errors import UsageError
+from ..db.connection import connect
from .args import NominatimArgs
# Do not repeat documentation of subcommand classes.
import sys
from functools import reduce
-from nominatim_core.errors import UsageError
import nominatim_api as napi
import nominatim_api.v1 as api_output
from nominatim_api.v1.helpers import zoom_to_rank, deduplicate_results
from nominatim_api.v1.format import dispatch as formatting
import nominatim_api.logging as loglib
+from ..errors import UsageError
from .args import NominatimArgs
# Do not repeat documentation of subcommand classes.
import logging
from pathlib import Path
-from nominatim_core.errors import UsageError
-from nominatim_core.config import Configuration
-from nominatim_core.typing import Protocol
+from ..errors import UsageError
+from ..config import Configuration
+from ..typing import Protocol
LOG = logging.getLogger()
import asyncio
from pathlib import Path
-from nominatim_core.errors import UsageError
+from ..errors import UsageError
from .args import NominatimArgs
# Do not repeat documentation of subcommand classes.
import csv
import sys
-import sqlalchemy as sa
-
import nominatim_api as napi
from nominatim_api.results import create_from_placex_row, ReverseResult, add_result_details
from nominatim_api.types import LookupDetails
-from nominatim_core.errors import UsageError
+
+import sqlalchemy as sa # pylint: disable=C0411
+
+from ..errors import UsageError
from .args import NominatimArgs
# Do not repeat documentation of subcommand classes.
"""
import argparse
-from nominatim_core.db.connection import connect
+from ..db.connection import connect
from .args import NominatimArgs
# Do not repeat documentation of subcommand classes.
import psutil
-from nominatim_core.db import status
-from nominatim_core.db.connection import connect
+from ..db import status
+from ..db.connection import connect
from .args import NominatimArgs
# Do not repeat documentation of subcommand classes.
import logging
from pathlib import Path
-from nominatim_core.config import Configuration
-from nominatim_core.db.connection import connect
+from ..config import Configuration
+from ..db.connection import connect
from ..tokenizer.base import AbstractTokenizer
from .args import NominatimArgs
import socket
import time
-from nominatim_core.db import status
-from nominatim_core.db.connection import connect
-from nominatim_core.errors import UsageError
+from ..db import status
+from ..db.connection import connect
+from ..errors import UsageError
from .args import NominatimArgs
LOG = logging.getLogger()
import psutil
-from nominatim_core.errors import UsageError
-from nominatim_core.config import Configuration
-from nominatim_core.db.connection import connect
-from nominatim_core.db import status, properties
+from ..errors import UsageError
+from ..config import Configuration
+from ..db.connection import connect
+from ..db import status, properties
from ..tokenizer.base import AbstractTokenizer
from ..version import NOMINATIM_VERSION
from .args import NominatimArgs
import logging
from pathlib import Path
-from nominatim_core.errors import UsageError
-from nominatim_core.db.connection import connect
+from ..errors import UsageError
+from ..db.connection import connect
from ..tools.special_phrases.sp_importer import SPImporter, SpecialPhraseLoader
from ..tools.special_phrases.sp_wiki_loader import SPWikiLoader
from ..tools.special_phrases.sp_csv_loader import SPCsvLoader
import yaml
from dotenv import dotenv_values
-from psycopg2.extensions import parse_dsn
+
+try:
+ from psycopg2.extensions import parse_dsn
+except ModuleNotFoundError:
+ from psycopg.conninfo import conninfo_to_dict as parse_dsn # type: ignore[assignment]
from .typing import StrPath
from .errors import UsageError
from pathlib import Path
import psycopg2.extras
-from nominatim_core.db import utils as db_utils
-from nominatim_core.db.connection import connect, Connection
-from nominatim_core.errors import UsageError
-from nominatim_core.config import Configuration
+from ..db import utils as db_utils
+from ..db.connection import connect, Connection
+from ..errors import UsageError
+from ..config import Configuration
from ..tokenizer.base import AbstractTokenizer
def _flatten_name_list(names: Any) -> Dict[str, str]:
from typing import Any, Mapping, Optional, Set, Match
import re
-from nominatim_core.errors import UsageError
+from ..errors import UsageError
from . import country_info
class CountryPostcodeMatcher:
--- /dev/null
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of Nominatim. (https://nominatim.org)
+#
+# Copyright (C) 2024 by the Nominatim developer community.
+# For a full list of authors see the git log.
+"""
+Custom exception and error classes for Nominatim.
+"""
+
+class UsageError(Exception):
+ """ An error raised because of bad user input. This error will usually
+ not cause a stack trace to be printed unless debugging is enabled.
+ """
import psycopg2.extras
-from nominatim_core.typing import DictCursorResults
-from nominatim_core.db.async_connection import DBConnection, WorkerPool
-from nominatim_core.db.connection import connect, Connection, Cursor
+from ..typing import DictCursorResults
+from ..db.async_connection import DBConnection, WorkerPool
+from ..db.connection import connect, Connection, Cursor
from ..tokenizer.base import AbstractTokenizer
from .progress import ProgressLogger
from . import runners
from psycopg2 import sql as pysql
import psycopg2.extras
-from nominatim_core.typing import Query, DictCursorResult, DictCursorResults, Protocol
-from nominatim_core.db.async_connection import DBConnection
+from ..typing import Query, DictCursorResult, DictCursorResults, Protocol
+from ..db.async_connection import DBConnection
from ..data.place_info import PlaceInfo
from ..tokenizer.base import AbstractAnalyzer
from typing import List, Tuple, Dict, Any, Optional, Iterable
from pathlib import Path
-from nominatim_core.typing import Protocol
-from nominatim_core.config import Configuration
-from nominatim_core.db.connection import Connection
+from ..typing import Protocol
+from ..config import Configuration
+from ..db.connection import Connection
from ..data.place_info import PlaceInfo
class AbstractAnalyzer(ABC):
import importlib
from pathlib import Path
-from nominatim_core.errors import UsageError
-from nominatim_core.db import properties
-from nominatim_core.db.connection import connect
-from nominatim_core.config import Configuration
+from ..errors import UsageError
+from ..db import properties
+from ..db.connection import connect
+from ..config import Configuration
from ..tokenizer.base import AbstractTokenizer, TokenizerModule
LOG = logging.getLogger()
from icu import Transliterator
-from nominatim_core.config import flatten_config_list, Configuration
-from nominatim_core.db.properties import set_property, get_property
-from nominatim_core.db.connection import Connection
-from nominatim_core.errors import UsageError
+from ..config import flatten_config_list, Configuration
+from ..db.properties import set_property, get_property
+from ..db.connection import Connection
+from ..errors import UsageError
from .place_sanitizer import PlaceSanitizer
from .icu_token_analysis import ICUTokenAnalysis
from .token_analysis.base import AnalysisModule, Analyzer
from pathlib import Path
from textwrap import dedent
-from nominatim_core.db.connection import connect, Connection, Cursor
-from nominatim_core.config import Configuration
-from nominatim_core.db.utils import CopyBuffer
-from nominatim_core.db.sql_preprocessor import SQLPreprocessor
+from ..db.connection import connect, Connection, Cursor
+from ..config import Configuration
+from ..db.utils import CopyBuffer
+from ..db.sql_preprocessor import SQLPreprocessor
from ..data.place_info import PlaceInfo
from ..data.place_name import PlaceName
from .icu_rule_loader import ICURuleLoader
import psycopg2
import psycopg2.extras
-from nominatim_core.errors import UsageError
-from nominatim_core.db.connection import connect, Connection
-from nominatim_core.config import Configuration
-from nominatim_core.db import properties
-from nominatim_core.db import utils as db_utils
-from nominatim_core.db.sql_preprocessor import SQLPreprocessor
+from ..errors import UsageError
+from ..db.connection import connect, Connection
+from ..config import Configuration
+from ..db import properties
+from ..db import utils as db_utils
+from ..db.sql_preprocessor import SQLPreprocessor
from ..data.place_info import PlaceInfo
from .base import AbstractAnalyzer, AbstractTokenizer
"""
from typing import Optional, List, Mapping, Sequence, Callable, Any, Tuple
-from nominatim_core.errors import UsageError
-from nominatim_core.config import Configuration
+from ..errors import UsageError
+from ..config import Configuration
from .sanitizers.config import SanitizerConfig
from .sanitizers.base import SanitizerHandler, ProcessInfo
from ..data.place_name import PlaceName
"""
from typing import Optional, List, Mapping, Callable
-from nominatim_core.typing import Protocol, Final
+from ...typing import Protocol, Final
from ...data.place_info import PlaceInfo
from ...data.place_name import PlaceName
from .config import SanitizerConfig
from collections import UserDict
import re
-from nominatim_core.errors import UsageError
+from ...errors import UsageError
# working around missing generics in Python < 3.8
# See https://github.com/python/typing/issues/60#issuecomment-869757075
"""
from typing import Mapping, List, Any
-from nominatim_core.typing import Protocol
+from ...typing import Protocol
from ...data.place_name import PlaceName
class Analyzer(Protocol):
import itertools
import re
-from nominatim_core.config import flatten_config_list
-from nominatim_core.errors import UsageError
+from ...config import flatten_config_list
+from ...errors import UsageError
class ICUVariant(NamedTuple):
""" A single replacement rule for variant creation.
import datrie
-from nominatim_core.errors import UsageError
+from ...errors import UsageError
from ...data.place_name import PlaceName
from .config_variants import get_variant_config
from .generic_mutation import MutationVariantGenerator
import logging
import re
-from nominatim_core.errors import UsageError
+from ...errors import UsageError
LOG = logging.getLogger()
import logging
import urllib
-from nominatim_core.db.connection import connect
-from nominatim_core.utils.url_utils import get_url
+from ..db.connection import connect
+from ..utils.url_utils import get_url
from .exec_utils import run_osm2pgsql
LOG = logging.getLogger()
from psycopg2.extras import Json, register_hstore
from psycopg2 import DataError
-from nominatim_core.typing import DictCursorResult
-from nominatim_core.config import Configuration
-from nominatim_core.db.connection import connect, Cursor
-from nominatim_core.errors import UsageError
+from ..typing import DictCursorResult
+from ..config import Configuration
+from ..db.connection import connect, Cursor
+from ..errors import UsageError
from ..tokenizer import factory as tokenizer_factory
from ..data.place_info import PlaceInfo
from enum import Enum
from textwrap import dedent
-from nominatim_core.config import Configuration
-from nominatim_core.db.connection import connect, Connection
-from nominatim_core.db import properties
-from nominatim_core.errors import UsageError
+from ..config import Configuration
+from ..db.connection import connect, Connection
+from ..db import properties
+from ..errors import UsageError
from ..tokenizer import factory as tokenizer_factory
from . import freeze
from ..version import NOMINATIM_VERSION, parse_version
import psutil
from psycopg2.extensions import make_dsn, parse_dsn
-from nominatim_core.config import Configuration
-from nominatim_core.db.connection import connect
+from ..config import Configuration
+from ..db.connection import connect
from ..version import NOMINATIM_VERSION
import nominatim_api as napi
from nominatim_api.search.query_analyzer_factory import make_query_analyzer
-from nominatim_core.typing import SaSelect, SaRow
-from nominatim_core.db.sqlalchemy_types import Geometry, IntArray
+from nominatim_api.typing import SaSelect, SaRow
+from nominatim_api.sql.sqlalchemy_types import Geometry, IntArray
LOG = logging.getLogger()
import psutil
from psycopg2 import sql as pysql
-from nominatim_core.errors import UsageError
-from nominatim_core.config import Configuration
-from nominatim_core.db.connection import connect, get_pg_env, Connection
-from nominatim_core.db.async_connection import DBConnection
-from nominatim_core.db.sql_preprocessor import SQLPreprocessor
+from ..errors import UsageError
+from ..config import Configuration
+from ..db.connection import connect, get_pg_env, Connection
+from ..db.async_connection import DBConnection
+from ..db.sql_preprocessor import SQLPreprocessor
from .exec_utils import run_osm2pgsql
from ..version import POSTGRESQL_REQUIRED_VERSION, POSTGIS_REQUIRED_VERSION
import subprocess
import shutil
-from nominatim_core.typing import StrPath
-from nominatim_core.db.connection import get_pg_env
+from ..typing import StrPath
+from ..db.connection import get_pg_env
LOG = logging.getLogger()
from psycopg2 import sql as pysql
-from nominatim_core.db.connection import Connection
+from ..db.connection import Connection
UPDATE_TABLES = [
'address_levels',
from psycopg2 import sql as pysql
-from nominatim_core.errors import UsageError
-from nominatim_core.config import Configuration
-from nominatim_core.db import properties
-from nominatim_core.db.connection import connect, Connection
+from ..errors import UsageError
+from ..config import Configuration
+from ..db import properties
+from ..db.connection import connect, Connection
from ..version import NominatimVersion, NOMINATIM_VERSION, parse_version
from ..tokenizer import factory as tokenizer_factory
from . import refresh
from psycopg2 import sql as pysql
-from nominatim_core.db.connection import connect, Connection
-from nominatim_core.utils.centroid import PointsCentroid
+from ..db.connection import connect, Connection
+from ..utils.centroid import PointsCentroid
from ..data.postcode_format import PostcodeFormatter, CountryPostcodeMatcher
from ..tokenizer.base import AbstractAnalyzer, AbstractTokenizer
from psycopg2 import sql as pysql
-from nominatim_core.config import Configuration
-from nominatim_core.db.connection import Connection, connect
-from nominatim_core.db.utils import execute_file, CopyBuffer
-from nominatim_core.db.sql_preprocessor import SQLPreprocessor
+from ..config import Configuration
+from ..db.connection import Connection, connect
+from ..db.utils import execute_file, CopyBuffer
+from ..db.sql_preprocessor import SQLPreprocessor
from ..version import NOMINATIM_VERSION
LOG = logging.getLogger()
import requests
-from nominatim_core.errors import UsageError
-from nominatim_core.db import status
-from nominatim_core.db.connection import Connection, connect
+from ..errors import UsageError
+from ..db import status
+from ..db.connection import Connection, connect
from .exec_utils import run_osm2pgsql
try:
import csv
import os
-from nominatim_core.errors import UsageError
+from ...errors import UsageError
from .special_phrase import SpecialPhrase
class SPCsvLoader:
from psycopg2.sql import Identifier, SQL
-from nominatim_core.typing import Protocol
-from nominatim_core.config import Configuration
-from nominatim_core.db.connection import Connection
+from ...typing import Protocol
+from ...config import Configuration
+from ...db.connection import Connection
from .importer_statistics import SpecialPhrasesImporterStatistics
from .special_phrase import SpecialPhrase
from ...tokenizer.base import AbstractTokenizer
import re
import logging
-from nominatim_core.config import Configuration
-from nominatim_core.utils.url_utils import get_url
+from ...config import Configuration
+from ...utils.url_utils import get_url
from .special_phrase import SpecialPhrase
LOG = logging.getLogger()
from psycopg2.extras import Json
-from nominatim_core.config import Configuration
-from nominatim_core.db.connection import connect
-from nominatim_core.db.async_connection import WorkerPool
-from nominatim_core.db.sql_preprocessor import SQLPreprocessor
-from nominatim_core.errors import UsageError
+from ..config import Configuration
+from ..db.connection import connect
+from ..db.async_connection import WorkerPool
+from ..db.sql_preprocessor import SQLPreprocessor
+from ..errors import UsageError
from ..data.place_info import PlaceInfo
from ..tokenizer.base import AbstractAnalyzer, AbstractTokenizer
from . import freeze
Protocol = object
Final = 'Final'
TypedDict = dict
-
-
-# SQLAlchemy introduced generic types in version 2.0 making typing
-# incompatible with older versions. Add wrappers here so we don't have
-# to litter the code with bare-string types.
-
-if TYPE_CHECKING:
- import sqlalchemy as sa
- from typing_extensions import (TypeAlias as TypeAlias)
-else:
- TypeAlias = str
-
-SaLambdaSelect: TypeAlias = 'Union[sa.Select[Any], sa.StatementLambdaElement]'
-SaSelect: TypeAlias = 'sa.Select[Any]'
-SaScalarSelect: TypeAlias = 'sa.ScalarSelect[Any]'
-SaRow: TypeAlias = 'sa.Row[Any]'
-SaColumn: TypeAlias = 'sa.ColumnElement[Any]'
-SaExpression: TypeAlias = 'sa.ColumnElement[bool]'
-SaLabel: TypeAlias = 'sa.Label[Any]'
-SaFromClause: TypeAlias = 'sa.FromClause'
-SaSelectable: TypeAlias = 'sa.Selectable'
-SaBind: TypeAlias = 'sa.BindParameter[Any]'
-SaDialect: TypeAlias = 'sa.Dialect'
import logging
import urllib.request as urlrequest
-from ..version import NOMINATIM_CORE_VERSION
+from ..version import NOMINATIM_VERSION
LOG = logging.getLogger()
This version makes sure that an appropriate user agent is sent.
"""
- headers = {"User-Agent": f"Nominatim/{NOMINATIM_CORE_VERSION!s}"}
+ headers = {"User-Agent": f"Nominatim/{NOMINATIM_VERSION!s}"}
try:
request = urlrequest.Request(url, headers=headers)
"""
Version information for Nominatim.
"""
-from typing import Optional
+from typing import NamedTuple, Optional
# See also https://github.com/PyCQA/pylint/issues/6006
# pylint: disable=useless-import-alias,unused-import
-from nominatim_core.version import (NominatimVersion as NominatimVersion,
- parse_version as parse_version)
+class NominatimVersion(NamedTuple):
+ """ Version information for Nominatim. We follow semantic versioning.
+
+ Major, minor and patch_level refer to the last released version.
+ The database patch level tracks important changes between releases
+ and must always be increased when there is a change to the database or code
+ that requires a migration.
+
+ When adding a migration on the development branch, raise the patch level
+ to 99 to make sure that the migration is applied when updating from a
+ patch release to the next minor version. Patch releases usually shouldn't
+ have migrations in them. When they are needed, then make sure that the
+ migration can be reapplied and set the migration version to the appropriate
+ patch level when cherry-picking the commit with the migration.
+ """
+
+ major: int
+ minor: int
+ patch_level: int
+ db_patch_level: Optional[int]
+
+ def __str__(self) -> str:
+ if self.db_patch_level is None:
+ return f"{self.major}.{self.minor}.{self.patch_level}"
+
+ return f"{self.major}.{self.minor}.{self.patch_level}-{self.db_patch_level}"
+
+ def release_version(self) -> str:
+ """ Return the release version in semantic versioning format.
+
+ The release version does not include the database patch version.
+ """
+ return f"{self.major}.{self.minor}.{self.patch_level}"
+
+
+def parse_version(version: str) -> NominatimVersion:
+ """ Parse a version string into a version consisting of a tuple of
+ four ints: major, minor, patch level, database patch level
+
+ This is the reverse operation of `version_str()`.
+ """
+ parts = version.split('.')
+ return NominatimVersion(*[int(x) for x in parts[:2] + parts[2].split('-')])
+
NOMINATIM_VERSION = parse_version('4.4.99-1')
sys.path.insert(1, str((Path(__file__) / '..' / '..' / '..' / '..'/ 'src').resolve()))
from nominatim_db import cli
-from nominatim_core.config import Configuration
-from nominatim_core.db.connection import Connection
+from nominatim_db.config import Configuration
+from nominatim_db.db.connection import Connection
from nominatim_db.tools import refresh
from nominatim_db.tokenizer import factory as tokenizer_factory
from steps.utils import run_script
import sqlalchemy as sa
import nominatim_api as napi
-from nominatim_core.db.sql_preprocessor import SQLPreprocessor
+from nominatim_db.db.sql_preprocessor import SQLPreprocessor
from nominatim_api.search.query_analyzer_factory import make_query_analyzer
from nominatim_db.tools import convert_sqlite
import nominatim_api.logging as loglib
from collections import namedtuple
import nominatim_api.v1.server_glue as glue
-from nominatim_core.config import Configuration
+from nominatim_api.config import Configuration
class FakeError(BaseException):
assert result.status == 0
assert result.message == 'OK'
assert result.software_version == NOMINATIM_API_VERSION
- assert result.database_version == NominatimVersion(99, 5, 4, 2)
+ assert result.database_version == '99.5.4-2'
assert result.data_updated == import_date
"""
import pytest
-from nominatim_core.errors import UsageError
+from nominatim_api.errors import UsageError
import nominatim_api.types as typ
def test_no_params_defaults():
import nominatim_db.tools.refresh
import nominatim_db.tools.postcodes
import nominatim_db.indexer.indexer
-import nominatim_core.db.properties
+import nominatim_db.db.properties
class TestCliImportWithDb:
mock_func_factory(nominatim_db.tools.postcodes, 'update_postcodes'),
mock_func_factory(nominatim_db.indexer.indexer.Indexer, 'index_full'),
mock_func_factory(nominatim_db.tools.refresh, 'setup_website'),
- mock_func_factory(nominatim_core.db.properties, 'set_property')
+ mock_func_factory(nominatim_db.db.properties, 'set_property')
]
assert self.call_nominatim('import', '--continue', 'load-data') == 0
mock_func_factory(nominatim_db.data.country_info, 'create_country_names'),
mock_func_factory(nominatim_db.indexer.indexer.Indexer, 'index_full'),
mock_func_factory(nominatim_db.tools.refresh, 'setup_website'),
- mock_func_factory(nominatim_core.db.properties, 'set_property')
+ mock_func_factory(nominatim_db.db.properties, 'set_property')
]
assert self.call_nominatim('import', '--continue', 'indexing') == 0
mock_func_factory(nominatim_db.tools.database_import, 'create_search_indices'),
mock_func_factory(nominatim_db.data.country_info, 'create_country_names'),
mock_func_factory(nominatim_db.tools.refresh, 'setup_website'),
- mock_func_factory(nominatim_core.db.properties, 'set_property')
+ mock_func_factory(nominatim_db.db.properties, 'set_property')
]
assert self.call_nominatim('import', '--continue', 'db-postprocess') == 0
import nominatim_db.indexer.indexer
import nominatim_db.tools.replication
import nominatim_db.tools.refresh
-from nominatim_core.db import status
+from nominatim_db.db import status
@pytest.fixture
def tokenizer_mock(monkeypatch):
from pathlib import Path
import pytest
-from nominatim_core.config import Configuration, flatten_config_list
-from nominatim_core.errors import UsageError
+from nominatim_db.config import Configuration, flatten_config_list
+from nominatim_db.errors import UsageError
@pytest.fixture
def make_config():
import pytest
-from nominatim_core.config import Configuration
+from nominatim_db.config import Configuration
@pytest.fixture
def test_config(src_dir, tmp_path):
SRC_DIR = (Path(__file__) / '..' / '..' / '..').resolve()
sys.path.insert(0, str(SRC_DIR / 'src'))
-from nominatim_core.config import Configuration
-from nominatim_core.db import connection
-from nominatim_core.db.sql_preprocessor import SQLPreprocessor
+from nominatim_db.config import Configuration
+from nominatim_db.db import connection
+from nominatim_db.db.sql_preprocessor import SQLPreprocessor
import nominatim_db.tokenizer.factory
import dummy_tokenizer
import pytest
import psycopg2
-from nominatim_core.db.async_connection import DBConnection, DeadlockHandler
+from nominatim_db.db.async_connection import DBConnection, DeadlockHandler
@pytest.fixture
import pytest
import psycopg2
-from nominatim_core.db.connection import connect, get_pg_env
+from nominatim_db.db.connection import connect, get_pg_env
@pytest.fixture
def db(dsn):
"""
import pytest
-from nominatim_core.db import properties
+from nominatim_db.db import properties
@pytest.fixture
def property_factory(property_table, temp_db_cursor):
"""
import pytest
-from nominatim_core.db.sql_preprocessor import SQLPreprocessor
+from nominatim_db.db.sql_preprocessor import SQLPreprocessor
@pytest.fixture
def sql_factory(tmp_path):
import pytest
-import nominatim_core.db.status
-from nominatim_core.errors import UsageError
+import nominatim_db.db.status
+from nominatim_db.errors import UsageError
OSM_NODE_DATA = """\
<osm version="0.6" generator="OpenStreetMap server" copyright="OpenStreetMap and contributors" attribution="http://www.openstreetmap.org/copyright" license="http://opendatacommons.org/licenses/odbl/1-0/">
"""
def iso_date(date):
- return dt.datetime.strptime(date, nominatim_core.db.status.ISODATE_FORMAT)\
+ return dt.datetime.strptime(date, nominatim_db.db.status.ISODATE_FORMAT)\
.replace(tzinfo=dt.timezone.utc)
table_factory('osm2pgsql_properties', 'property TEXT, value TEXT',
content=(('current_timestamp', '2024-01-03T23:45:54Z'), ))
- date = nominatim_core.db.status.compute_database_date(temp_db_conn, offline=offline)
+ date = nominatim_db.db.status.compute_database_date(temp_db_conn, offline=offline)
assert date == iso_date('2024-01-03T23:45:54')
table_factory('osm2pgsql_properties', 'property TEXT, value TEXT')
with pytest.raises(UsageError, match='Cannot determine database date from data in offline mode'):
- nominatim_core.db.status.compute_database_date(temp_db_conn, offline=True)
+ nominatim_db.db.status.compute_database_date(temp_db_conn, offline=True)
def test_compute_database_date_place_empty(place_table, temp_db_conn):
with pytest.raises(UsageError):
- nominatim_core.db.status.compute_database_date(temp_db_conn)
+ nominatim_db.db.status.compute_database_date(temp_db_conn)
def test_compute_database_date_valid(monkeypatch, place_row, temp_db_conn):
requested_url.append(url)
return OSM_NODE_DATA
- monkeypatch.setattr(nominatim_core.db.status, "get_url", mock_url)
+ monkeypatch.setattr(nominatim_db.db.status, "get_url", mock_url)
- date = nominatim_core.db.status.compute_database_date(temp_db_conn)
+ date = nominatim_db.db.status.compute_database_date(temp_db_conn)
assert requested_url == ['https://www.openstreetmap.org/api/0.6/node/45673/1']
assert date == iso_date('2006-01-27T22:09:10')
requested_url.append(url)
return '<osm version="0.6" generator="OpenStre'
- monkeypatch.setattr(nominatim_core.db.status, "get_url", mock_url)
+ monkeypatch.setattr(nominatim_db.db.status, "get_url", mock_url)
with pytest.raises(UsageError):
- nominatim_core.db.status.compute_database_date(temp_db_conn)
+ nominatim_db.db.status.compute_database_date(temp_db_conn)
def test_set_status_empty_table(temp_db_conn, temp_db_cursor):
date = dt.datetime.fromordinal(1000000).replace(tzinfo=dt.timezone.utc)
- nominatim_core.db.status.set_status(temp_db_conn, date=date)
+ nominatim_db.db.status.set_status(temp_db_conn, date=date)
assert temp_db_cursor.row_set("SELECT * FROM import_status") == \
{(date, None, True)}
def test_set_status_filled_table(temp_db_conn, temp_db_cursor):
date = dt.datetime.fromordinal(1000000).replace(tzinfo=dt.timezone.utc)
- nominatim_core.db.status.set_status(temp_db_conn, date=date)
+ nominatim_db.db.status.set_status(temp_db_conn, date=date)
assert temp_db_cursor.table_rows('import_status') == 1
date = dt.datetime.fromordinal(1000100).replace(tzinfo=dt.timezone.utc)
- nominatim_core.db.status.set_status(temp_db_conn, date=date, seq=456, indexed=False)
+ nominatim_db.db.status.set_status(temp_db_conn, date=date, seq=456, indexed=False)
assert temp_db_cursor.row_set("SELECT * FROM import_status") == \
{(date, 456, False)}
def test_set_status_missing_date(temp_db_conn, temp_db_cursor):
date = dt.datetime.fromordinal(1000000).replace(tzinfo=dt.timezone.utc)
- nominatim_core.db.status.set_status(temp_db_conn, date=date)
+ nominatim_db.db.status.set_status(temp_db_conn, date=date)
assert temp_db_cursor.table_rows('import_status') == 1
- nominatim_core.db.status.set_status(temp_db_conn, date=None, seq=456, indexed=False)
+ nominatim_db.db.status.set_status(temp_db_conn, date=None, seq=456, indexed=False)
assert temp_db_cursor.row_set("SELECT * FROM import_status") == \
{(date, 456, False)}
def test_get_status_empty_table(temp_db_conn):
- assert nominatim_core.db.status.get_status(temp_db_conn) == (None, None, None)
+ assert nominatim_db.db.status.get_status(temp_db_conn) == (None, None, None)
def test_get_status_success(temp_db_conn):
date = dt.datetime.fromordinal(1000000).replace(tzinfo=dt.timezone.utc)
- nominatim_core.db.status.set_status(temp_db_conn, date=date, seq=667, indexed=False)
+ nominatim_db.db.status.set_status(temp_db_conn, date=date, seq=667, indexed=False)
- assert nominatim_core.db.status.get_status(temp_db_conn) == \
+ assert nominatim_db.db.status.get_status(temp_db_conn) == \
(date, 667, False)
@pytest.mark.parametrize("new_state", [True, False])
def test_set_indexed(temp_db_conn, temp_db_cursor, old_state, new_state):
date = dt.datetime.fromordinal(1000000).replace(tzinfo=dt.timezone.utc)
- nominatim_core.db.status.set_status(temp_db_conn, date=date, indexed=old_state)
- nominatim_core.db.status.set_indexed(temp_db_conn, new_state)
+ nominatim_db.db.status.set_status(temp_db_conn, date=date, indexed=old_state)
+ nominatim_db.db.status.set_indexed(temp_db_conn, new_state)
assert temp_db_cursor.scalar("SELECT indexed FROM import_status") == new_state
def test_set_indexed_empty_status(temp_db_conn, temp_db_cursor):
- nominatim_core.db.status.set_indexed(temp_db_conn, True)
+ nominatim_db.db.status.set_indexed(temp_db_conn, True)
assert temp_db_cursor.table_rows("import_status") == 0
date = dt.datetime.fromordinal(1000000).replace(tzinfo=dt.timezone.utc)
start = dt.datetime.now() - dt.timedelta(hours=1)
- nominatim_core.db.status.set_status(temp_db_conn, date=date, seq=56)
- nominatim_core.db.status.log_status(temp_db_conn, start, 'index')
+ nominatim_db.db.status.set_status(temp_db_conn, date=date, seq=56)
+ nominatim_db.db.status.log_status(temp_db_conn, start, 'index')
temp_db_conn.commit()
import pytest
-import nominatim_core.db.utils as db_utils
-from nominatim_core.errors import UsageError
+import nominatim_db.db.utils as db_utils
+from nominatim_db.errors import UsageError
def test_execute_file_success(dsn, temp_db_cursor, tmp_path):
tmpfile = tmp_path / 'test.sql'
Tokenizer for testing.
"""
from nominatim_db.data.place_info import PlaceInfo
-from nominatim_core.config import Configuration
+from nominatim_db.config import Configuration
def create(dsn, data_dir):
""" Create a new instance of the tokenizer provided by this module.
import psycopg2.extras
-from nominatim_core.db import properties
+from nominatim_db.db import properties
# This must always point to the mock word table for the default tokenizer.
from mock_icu_word_table import MockIcuWordTable as MockWordTable
"""
import pytest
-from nominatim_core.errors import UsageError
+from nominatim_db.errors import UsageError
from nominatim_db.tokenizer.sanitizers.config import SanitizerConfig
def test_string_list_default_empty():
from nominatim_db.tokenizer.place_sanitizer import PlaceSanitizer
from nominatim_db.data.place_info import PlaceInfo
-from nominatim_core.errors import UsageError
+from nominatim_db.errors import UsageError
class TestSplitName:
"""
import pytest
-from nominatim_core.db import properties
+from nominatim_db.db import properties
from nominatim_db.tokenizer import factory
-from nominatim_core.errors import UsageError
+from nominatim_db.errors import UsageError
from dummy_tokenizer import DummyTokenizer
from nominatim_db.tokenizer import icu_tokenizer
import nominatim_db.tokenizer.icu_rule_loader
-from nominatim_core.db import properties
-from nominatim_core.db.sql_preprocessor import SQLPreprocessor
+from nominatim_db.db import properties
+from nominatim_db.db.sql_preprocessor import SQLPreprocessor
from nominatim_db.data.place_info import PlaceInfo
from mock_icu_word_table import MockIcuWordTable
import yaml
from nominatim_db.tokenizer.icu_rule_loader import ICURuleLoader
-from nominatim_core.errors import UsageError
+from nominatim_db.errors import UsageError
from icu import Transliterator
from nominatim_db.data.place_info import PlaceInfo
from nominatim_db.tokenizer import legacy_tokenizer
-from nominatim_core.db import properties
-from nominatim_core.errors import UsageError
+from nominatim_db.db import properties
+from nominatim_db.errors import UsageError
from mock_legacy_word_table import MockLegacyWordTable
"""
import pytest
-from nominatim_core.errors import UsageError
+from nominatim_db.errors import UsageError
import nominatim_db.tokenizer.place_sanitizer as sanitizer
from nominatim_db.data.place_info import PlaceInfo
import nominatim_db.tokenizer.token_analysis.postcodes as module
from nominatim_db.data.place_name import PlaceName
-from nominatim_core.errors import UsageError
+from nominatim_db.errors import UsageError
DEFAULT_NORMALIZATION = """ :: NFD ();
'🜳' > ' ';
from icu import Transliterator
import nominatim_db.tokenizer.token_analysis.generic as module
-from nominatim_core.errors import UsageError
+from nominatim_db.errors import UsageError
DEFAULT_NORMALIZATION = """ :: NFD ();
'🜳' > ' ';
from icu import Transliterator
import nominatim_db.tokenizer.token_analysis.generic as module
-from nominatim_core.errors import UsageError
+from nominatim_db.errors import UsageError
DEFAULT_NORMALIZATION = """ '🜳' > ' ';
[[:Nonspacing Mark:] [:Cf:]] >;
"""
import pytest
-from nominatim_core.errors import UsageError
+from nominatim_db.errors import UsageError
from nominatim_db.tools import admin
from nominatim_db.tokenizer import factory
-from nominatim_core.db.sql_preprocessor import SQLPreprocessor
+from nominatim_db.db.sql_preprocessor import SQLPreprocessor
@pytest.fixture(autouse=True)
def create_placex_table(project_env, tokenizer_mock, temp_db_cursor, placex_table):
import psycopg2
from nominatim_db.tools import database_import
-from nominatim_core.errors import UsageError
+from nominatim_db.errors import UsageError
class TestDatabaseSetup:
DBNAME = 'test_nominatim_python_unittest'
import pytest
-from nominatim_core.config import Configuration
+from nominatim_db.config import Configuration
import nominatim_db.tools.exec_utils as exec_utils
def test_run_osm2pgsql(osm2pgsql_options):
from nominatim_db.tools.special_phrases.sp_importer import SPImporter
from nominatim_db.tools.special_phrases.sp_wiki_loader import SPWikiLoader
from nominatim_db.tools.special_phrases.special_phrase import SpecialPhrase
-from nominatim_core.errors import UsageError
+from nominatim_db.errors import UsageError
from cursor import CursorForTesting
import psycopg2.extras
from nominatim_db.tools import migration
-from nominatim_core.errors import UsageError
+from nominatim_db.errors import UsageError
import nominatim_db.version
from mock_legacy_word_table import MockLegacyWordTable
from osmium.replication.server import OsmosisState
import nominatim_db.tools.replication
-import nominatim_core.db.status as status
-from nominatim_core.errors import UsageError
+import nominatim_db.db.status as status
+from nominatim_db.errors import UsageError
OSM_NODE_DATA = """\
<osm version="0.6" generator="OpenStreetMap server" copyright="OpenStreetMap and contributors" attribution="http://www.openstreetmap.org/copyright" license="http://opendatacommons.org/licenses/odbl/1-0/">
"""
import pytest
-from nominatim_core.errors import UsageError
+from nominatim_db.errors import UsageError
from nominatim_db.tools.special_phrases.sp_csv_loader import SPCsvLoader
from nominatim_db.tools.special_phrases.special_phrase import SpecialPhrase
import pytest
from nominatim_db.tools import tiger_data, freeze
-from nominatim_core.errors import UsageError
+from nominatim_db.errors import UsageError
class MockTigerTable:
"""
import pytest
-from nominatim_core.utils.centroid import PointsCentroid
+from nominatim_db.utils.centroid import PointsCentroid
def test_empty_set():
c = PointsCentroid()
import pytest
-from nominatim_core.utils.json_writer import JsonWriter
+from nominatim_api.utils.json_writer import JsonWriter
@pytest.mark.parametrize("inval,outstr", [(None, 'null'),
(True, 'true'), (False, 'false'),
# Now install Nominatim using pip:
cd $USERHOME/Nominatim
- $USERHOME/nominatim-venv/bin/pip install packaging/nominatim-{core,db}
+ $USERHOME/nominatim-venv/bin/pip install packaging/nominatim-db
# Nominatim is now ready to use. The nominatim binary is available at
# `$USERHOME/venv/bin/nominatim`. If you want to have 'nominatim' in your