From a9e41cefb530d33de59a5422da2be54fb1470126 Mon Sep 17 00:00:00 2001
From: Brent O'Connor <epicserve@gmail.com>
Date: Sat, 2 Nov 2024 18:02:40 -0500
Subject: [PATCH] Urlencode option params and move params to one constant

---
 src/dj_beat_drop/new.py   | 62 ++++++++++++++++++++-------------------
 tests/test_new_command.py | 29 +++++++++---------
 2 files changed, 47 insertions(+), 44 deletions(-)

diff --git a/src/dj_beat_drop/new.py b/src/dj_beat_drop/new.py
index 6ced892..089455d 100644
--- a/src/dj_beat_drop/new.py
+++ b/src/dj_beat_drop/new.py
@@ -1,6 +1,7 @@
 import os
 import re
 import shutil
+import urllib.parse
 from pathlib import Path
 from textwrap import dedent
 
@@ -10,6 +11,17 @@
 from dj_beat_drop import utils
 from dj_beat_drop.utils import color
 
+EXTRA_SQLITE_PARAMS = {
+    "transaction_mode": "IMMEDIATE",
+    "init_command": (
+        "PRAGMA journal_mode = WAL;"
+        "PRAGMA synchronous = NORMAL;"
+        "PRAGMA mmap_size = 134217728;"
+        "PRAGMA journal_size_limit = 27103364;"
+        "PRAGMA cache_size = 2000"
+    ),
+}
+
 
 def rename_template_files(project_dir):
     # Rename .py-tpl files to .py
@@ -24,25 +36,26 @@ def replace_sqlite_config(content: str, django_version: str) -> str:
     if Version(django_version) < Version("5.1"):
         return content
 
+    init_command_str = "".join(
+        [f'                 "{param};"\n' for param in EXTRA_SQLITE_PARAMS["init_command"].split(";")]
+    )
     rtn_val = content
     rtn_val = re.sub(
         r"^DATABASES\s*=\s*\{.+?\}\n\}",
-        dedent(r'''DATABASES = {
-            'default': {
-                'ENGINE': 'django.db.backends.sqlite3',
-                'NAME': BASE_DIR / 'db.sqlite3',
-                'OPTIONS': {
-                    'transaction_mode': 'IMMEDIATE',
-                    'init_command': """
-                        PRAGMA journal_mode=WAL;
-                        PRAGMA synchronous=NORMAL;
-                        PRAGMA mmap_size = 134217728;
-                        PRAGMA journal_size_limit = 27103364;
-                        PRAGMA cache_size=2000;
-                    """,
-                },
-            }
-        }'''),
+        dedent(
+            "DATABASES = {\n"
+            "    'default': {\n"
+            "        'ENGINE': 'django.db.backends.sqlite3',\n"
+            "        'NAME': BASE_DIR / 'db.sqlite3',\n"
+            "        'OPTIONS': {\n"
+            f"            'transaction_mode': '{EXTRA_SQLITE_PARAMS['transaction_mode']}',\n"
+            '             \'init_command\': (\n'
+            f'{init_command_str}'
+            '              )\n'
+            "        }\n"
+            "    }\n"
+            "}\n"
+        ),
         rtn_val,
         flags=re.MULTILINE | re.DOTALL,
     )
@@ -78,21 +91,10 @@ def replace_settings_with_environs(content: str) -> str:
 
 def create_dot_envfile(project_dir, context: dict[str, str]):
     env_file_path = project_dir / ".env"
-    env_content = (
-        "DEBUG=True\n"
-        f"SECRET_KEY=\"{context['secret_key']}\"\n"
-        f'ALLOWED_HOSTS=\n'
-        f"DATABASE_URL=sqlite:///{project_dir / 'db.sqlite3'}"
-    )
+    sqlite_url = f"sqlite:///{project_dir / 'db.sqlite3'}"
     if Version(context["django_version"]) >= Version("5.1"):
-        env_content += (
-            "?transaction_mode=immediate"
-            "&init_command=PRAGMA journal_mode=WAL"
-            ";PRAGMA synchronous=NORMAL"
-            ";PRAGMA mmap_size=134217728"
-            ";PRAGMA journal_size_limit=27103364"
-            ";PRAGMA cache_size=2000"
-        )
+        sqlite_url += "?" + urllib.parse.urlencode(EXTRA_SQLITE_PARAMS)
+    env_content = f"DEBUG=True\nSECRET_KEY=\"{context['secret_key']}\"\nALLOWED_HOSTS=\nDATABASE_URL={sqlite_url}\n"
 
     with open(env_file_path, "w") as f:
         f.write(env_content)
diff --git a/tests/test_new_command.py b/tests/test_new_command.py
index 41b0cb1..01a6ae0 100644
--- a/tests/test_new_command.py
+++ b/tests/test_new_command.py
@@ -12,22 +12,23 @@
 
 ENV_SECRET_KEY_PATTERN = 'SECRET_KEY = env.str("SECRET_KEY")'  # noqa: S105
 SQLITE_OPTIONS_ENV = (
-    "?transaction_mode=immediate"
-    "&init_command=PRAGMA journal_mode=WAL"
-    ";PRAGMA synchronous=NORMAL"
-    ";PRAGMA mmap_size=134217728"
-    ";PRAGMA journal_size_limit=27103364"
-    ";PRAGMA cache_size=2000"
+    "?transaction_mode=IMMEDIATE"
+    "&init_command=PRAGMA+journal_mode+%3D+WAL"
+    "%3BPRAGMA+synchronous+%3D+NORMAL"
+    "%3BPRAGMA+mmap_size+%3D+134217728"
+    "%3BPRAGMA+journal_size_limit+%3D+27103364"
+    "%3BPRAGMA+cache_size+%3D+2000"
 )
-SQLITE_OPTIONS = dedent('''
+SQLITE_OPTIONS = dedent("""
     'transaction_mode': 'IMMEDIATE',
-    'init_command': """
-        PRAGMA journal_mode=WAL;
-        PRAGMA synchronous=NORMAL;
-        PRAGMA mmap_size = 134217728;
-        PRAGMA journal_size_limit = 27103364;
-        PRAGMA cache_size=2000;
-''')
+    'init_command': (
+        "PRAGMA journal_mode = WAL;"
+        "PRAGMA synchronous = NORMAL;"
+        "PRAGMA mmap_size = 134217728;"
+        "PRAGMA journal_size_limit = 27103364;"
+        "PRAGMA cache_size = 2000;"
+    )
+""")
 FILE_ASSERTIONS = {
     "manage.py": [
         "os.environ.setdefault('DJANGO_SETTINGS_MODULE', '{{ project_name }}.settings')",