Skip to content

Commit eebb6bc

Browse files
authored
Allow SharedPostgreSQL backend, also for new trees (#368)
1 parent 660cddf commit eebb6bc

File tree

6 files changed

+34
-11
lines changed

6 files changed

+34
-11
lines changed

Dockerfile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,10 @@ ENV GRAMPSWEB_EXPORT_DIR=/app/cache/export
4343
# install PostgreSQL addon
4444
RUN wget https://github.com/gramps-project/addons/archive/refs/heads/master.zip \
4545
&& unzip -p master.zip addons-master/gramps$GRAMPS_VERSION/download/PostgreSQL.addon.tgz | \
46-
tar -xvz -C /root/.gramps/gramps$GRAMPS_VERSION/plugins && rm master.zip
46+
tar -xvz -C /root/.gramps/gramps$GRAMPS_VERSION/plugins \
47+
&& unzip -p master.zip addons-master/gramps$GRAMPS_VERSION/download/SharedPostgreSQL.addon.tgz | \
48+
tar -xvz -C /root/.gramps/gramps$GRAMPS_VERSION/plugins \
49+
&& rm master.zip
4750

4851
# install gunicorn
4952
RUN python3 -m pip install --no-cache-dir --extra-index-url https://www.piwheels.org/simple \

gramps_webapi/api/resources/trees.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,7 @@ def get(self):
8585
return [get_tree_details(tree_id) for tree_id in tree_ids]
8686

8787
@use_args(
88-
{
89-
"name": fields.Str(required=True),
90-
},
88+
{"name": fields.Str(required=True)},
9189
location="json",
9290
)
9391
def post(self, args):
@@ -96,7 +94,13 @@ def post(self, args):
9694
abort(405)
9795
require_permissions([PERM_ADD_TREE])
9896
tree_id = str(uuid.uuid4())
99-
dbmgr = WebDbManager(dirname=tree_id, name=args["name"], create_if_missing=True)
97+
backend = current_app.config["NEW_DB_BACKEND"]
98+
dbmgr = WebDbManager(
99+
dirname=tree_id,
100+
name=args["name"],
101+
create_if_missing=True,
102+
create_backend=backend,
103+
)
100104
return {"name": args["name"], "tree_id": dbmgr.dirname}, 201
101105

102106

gramps_webapi/app.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
from flask_compress import Compress
2929
from flask_cors import CORS
3030
from flask_jwt_extended import JWTManager
31+
from gramps.gen.config import config as gramps_config
3132

3233
from .api import api_blueprint
3334
from .api.cache import thumbnail_cache
@@ -118,6 +119,11 @@ def create_app(config: Optional[Dict[str, Any]] = None):
118119
"files to users belonging to different trees!"
119120
)
120121

122+
if app.config["TREE"] == TREE_MULTI and app.config["NEW_DB_BACKEND"] != "sqlite":
123+
# needed in case a new postgres tree is to be created
124+
gramps_config.set("database.host", app.config["POSTGRES_HOST"])
125+
gramps_config.set("database.port", app.config["POSTGRES_PORT"])
126+
121127
# load JWT default settings
122128
app.config.from_object(DefaultConfigJWT)
123129

gramps_webapi/auth/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ def add_user(
6767
raise ValueError("Invalid or existing user") from exc
6868

6969

70-
def get_guid(name: str) -> None:
70+
def get_guid(name: str) -> str:
7171
"""Get the GUID of an existing user by username."""
7272
query = user_db.session.query(User.id) # pylint: disable=no-member
7373
user_id = query.filter_by(name=name).scalar()
@@ -76,7 +76,7 @@ def get_guid(name: str) -> None:
7676
return user_id
7777

7878

79-
def get_name(guid: str) -> None:
79+
def get_name(guid: str) -> str:
8080
"""Get the username of an existing user by GUID."""
8181
try:
8282
query = user_db.session.query(User.name) # pylint: disable=no-member

gramps_webapi/config.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,14 @@ class DefaultConfig(object):
4646
}
4747
POSTGRES_USER = None
4848
POSTGRES_PASSWORD = None
49+
POSTGRES_HOST = "localhost"
50+
POSTGRES_PORT = "5432"
4951
CELERY_CONFIG: Dict[str, str] = {}
5052
MEDIA_BASE_DIR = ""
5153
MEDIA_PREFIX_TREE = False
5254
REPORT_DIR = str(Path.cwd() / "report_cache")
5355
EXPORT_DIR = str(Path.cwd() / "export_cache")
56+
NEW_DB_BACKEND = "sqlite"
5457

5558

5659
class DefaultConfigJWT(object):

gramps_webapi/dbmanager.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
class WebDbManager:
4242
"""Database manager class based on Gramps CLI."""
4343

44-
ALLOWED_DB_BACKENDS = ["sqlite", "postgresql"]
44+
ALLOWED_DB_BACKENDS = ["sqlite", "postgresql", "sharedpostgresql"]
4545

4646
def __init__(
4747
self,
@@ -50,6 +50,7 @@ def __init__(
5050
username: Optional[str] = None,
5151
password: Optional[str] = None,
5252
create_if_missing: bool = True,
53+
create_backend: str = "sqlite",
5354
) -> None:
5455
"""Initialize given a family tree name or subdirectory name (path)."""
5556
if dirname:
@@ -65,6 +66,7 @@ def __init__(
6566
self.username = username
6667
self.password = password
6768
self.create_if_missing = create_if_missing
69+
self.create_backend = create_backend
6870
self.path = self._get_path()
6971
self._check_backend()
7072

@@ -111,8 +113,13 @@ def _get_path(self) -> str:
111113
self._create(path=path)
112114
return path
113115

114-
def _create(self, path: str, dbid: str = "sqlite") -> None:
116+
def _create(self, path: str) -> None:
115117
"""Create new database."""
118+
if self.create_backend not in self.ALLOWED_DB_BACKENDS:
119+
raise ValueError(
120+
f"Database backend '{self.create_backend}' not supported for new tree."
121+
)
122+
116123
if not self.name:
117124
raise ValueError("Cannot create database if name not specified.")
118125
os.mkdir(path)
@@ -123,12 +130,12 @@ def _create(self, path: str, dbid: str = "sqlite") -> None:
123130
name_file.write(self.name)
124131

125132
# create database
126-
make_database(dbid)
133+
make_database(self.create_backend)
127134

128135
# create dbid file
129136
backend_path = os.path.join(path, DBBACKEND)
130137
with open(backend_path, "w", encoding="utf8") as backend_file:
131-
backend_file.write(dbid)
138+
backend_file.write(self.create_backend)
132139

133140
def _check_backend(self) -> None:
134141
"""Check that the backend is among the allowed backends."""

0 commit comments

Comments
 (0)