From f30ba2d33e1f40cbd8b542876aa00d9a28a726f3 Mon Sep 17 00:00:00 2001
From: David W Bitner <bitner@dbspatial.com>
Date: Mon, 16 Sep 2024 11:06:31 -0500
Subject: [PATCH 1/2] add setting to be able to install tipg functions outside
 of the pg_temp schema

---
 tipg/collections.py | 16 +++++++++++-----
 tipg/database.py    | 11 ++++++++---
 tipg/settings.py    |  2 ++
 3 files changed, 21 insertions(+), 8 deletions(-)

diff --git a/tipg/collections.py b/tipg/collections.py
index b003f771..d04a1da2 100644
--- a/tipg/collections.py
+++ b/tipg/collections.py
@@ -25,7 +25,13 @@
 from tipg.filter.filters import bbox_to_wkt
 from tipg.logger import logger
 from tipg.model import Extent
-from tipg.settings import FeaturesSettings, MVTSettings, TableConfig, TableSettings
+from tipg.settings import (
+    FeaturesSettings,
+    MVTSettings,
+    PostgresSettings,
+    TableConfig,
+    TableSettings,
+)
 
 from fastapi import FastAPI
 
@@ -904,9 +910,9 @@ async def get_collection_index(  # noqa: C901
 ) -> Catalog:
     """Fetch Table and Functions index."""
     schemas = schemas or ["public"]
-
+    PostgresSettings()
     query = """
-        SELECT pg_temp.tipg_catalog(
+        SELECT {pg_settings.tipg_schema}.tipg_catalog(
             :schemas,
             :tables,
             :exclude_tables,
@@ -934,7 +940,7 @@ async def get_collection_index(  # noqa: C901
             spatial_extent=spatial_extent,
             datetime_extent=datetime_extent,
         )
-
+        PostgresSettings()
         catalog: Dict[str, Collection] = {}
         table_settings = TableSettings()
         table_confs = table_settings.table_config
@@ -945,7 +951,7 @@ async def get_collection_index(  # noqa: C901
             table_id = table["schema"] + "." + table["name"]
             confid = table["schema"] + "_" + table["name"]
 
-            if table_id == "pg_temp.tipg_catalog":
+            if table_id == "{pg_settings.tipg_schema}.tipg_catalog":
                 continue
 
             table_conf = table_confs.get(confid, TableConfig())
diff --git a/tipg/database.py b/tipg/database.py
index e7cac221..a3560e75 100644
--- a/tipg/database.py
+++ b/tipg/database.py
@@ -37,6 +37,7 @@ def __init__(
 
     async def __call__(self, conn: asyncpg.Connection):
         """Create connection."""
+        settings = PostgresSettings()
         await conn.set_type_codec(
             "json", encoder=orjson.dumps, decoder=orjson.loads, schema="pg_catalog"
         )
@@ -46,7 +47,7 @@ async def __call__(self, conn: asyncpg.Connection):
 
         # Note: we add `pg_temp as the first element of the schemas list to make sure
         # we register the custom functions and `dbcatalog` in it.
-        schemas = ",".join(["pg_temp", *self.schemas])
+        schemas = ",".join([settings.tipg_schema, *self.schemas])
         logger.debug(f"Looking for Tables and Functions in {schemas} schemas")
 
         await conn.execute(
@@ -61,10 +62,14 @@ async def __call__(self, conn: asyncpg.Connection):
 
         # Register custom SQL functions/table/views in pg_temp
         for sqlfile in self.user_sql_files:
-            await conn.execute(sqlfile.read_text())
+            await conn.execute(
+                sqlfile.read_text().replace("pg_temp", settings.tipg_schema)
+            )
 
         # Register TiPG functions in `pg_temp`
-        await conn.execute(DB_CATALOG_FILE.read_text())
+        await conn.execute(
+            DB_CATALOG_FILE.read_text().replace("pg_temp", settings.tipg_schema)
+        )
 
 
 async def connect_to_db(
diff --git a/tipg/settings.py b/tipg/settings.py
index f57855bf..17570dac 100644
--- a/tipg/settings.py
+++ b/tipg/settings.py
@@ -141,6 +141,8 @@ class PostgresSettings(BaseSettings):
 
     model_config = {"env_file": ".env", "extra": "ignore"}
 
+    tipg_schema: str = Field("pg_temp", regex=r"[a-zA-Z][a-zA-Z0-9_-]*")
+
     # https://github.com/tiangolo/full-stack-fastapi-postgresql/blob/master/%7B%7Bcookiecutter.project_slug%7D%7D/backend/app/app/core/config.py#L42
     @field_validator("database_url", mode="before")
     def assemble_db_connection(

From b5f751d4c1e5bd74438d6418f233e640c1ad8d99 Mon Sep 17 00:00:00 2001
From: David W Bitner <bitner@dbspatial.com>
Date: Mon, 16 Sep 2024 12:06:47 -0500
Subject: [PATCH 2/2] get tests to pass

---
 tipg/collections.py | 7 +++----
 tipg/settings.py    | 2 +-
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/tipg/collections.py b/tipg/collections.py
index d04a1da2..c0c4fb4d 100644
--- a/tipg/collections.py
+++ b/tipg/collections.py
@@ -910,8 +910,8 @@ async def get_collection_index(  # noqa: C901
 ) -> Catalog:
     """Fetch Table and Functions index."""
     schemas = schemas or ["public"]
-    PostgresSettings()
-    query = """
+    pg_settings = PostgresSettings()
+    query = f"""
         SELECT {pg_settings.tipg_schema}.tipg_catalog(
             :schemas,
             :tables,
@@ -940,7 +940,6 @@ async def get_collection_index(  # noqa: C901
             spatial_extent=spatial_extent,
             datetime_extent=datetime_extent,
         )
-        PostgresSettings()
         catalog: Dict[str, Collection] = {}
         table_settings = TableSettings()
         table_confs = table_settings.table_config
@@ -951,7 +950,7 @@ async def get_collection_index(  # noqa: C901
             table_id = table["schema"] + "." + table["name"]
             confid = table["schema"] + "_" + table["name"]
 
-            if table_id == "{pg_settings.tipg_schema}.tipg_catalog":
+            if table_id.split(".").pop() == "tipg_catalog":
                 continue
 
             table_conf = table_confs.get(confid, TableConfig())
diff --git a/tipg/settings.py b/tipg/settings.py
index 17570dac..86f607a0 100644
--- a/tipg/settings.py
+++ b/tipg/settings.py
@@ -141,7 +141,7 @@ class PostgresSettings(BaseSettings):
 
     model_config = {"env_file": ".env", "extra": "ignore"}
 
-    tipg_schema: str = Field("pg_temp", regex=r"[a-zA-Z][a-zA-Z0-9_-]*")
+    tipg_schema: str = Field("pg_temp", pattern=r"[a-zA-Z][a-zA-Z0-9_-]*")
 
     # https://github.com/tiangolo/full-stack-fastapi-postgresql/blob/master/%7B%7Bcookiecutter.project_slug%7D%7D/backend/app/app/core/config.py#L42
     @field_validator("database_url", mode="before")