Browse Source

check for JSON1 extesnion in Sqlite on startup

Nick Sweeting 4 years ago
parent
commit
185d2f9f9b
1 changed files with 18 additions and 1 deletions
  1. 18 1
      archivebox/config.py

+ 18 - 1
archivebox/config.py

@@ -29,6 +29,7 @@ import json
 import getpass
 import getpass
 import platform
 import platform
 import shutil
 import shutil
+import sqlite3
 import django
 import django
 
 
 from hashlib import md5
 from hashlib import md5
@@ -1071,12 +1072,27 @@ def setup_django(out_dir: Path=None, check_db=False, config: ConfigDict=CONFIG,
         assert (config['PACKAGE_DIR'] / 'core' / 'settings.py').exists(), 'settings.py was not found at archivebox/core/settings.py'
         assert (config['PACKAGE_DIR'] / 'core' / 'settings.py').exists(), 'settings.py was not found at archivebox/core/settings.py'
         os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'core.settings')
         os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'core.settings')
 
 
+        # Check to make sure JSON extension is available in our Sqlite3 instance
+        try:
+            cursor = sqlite3.connect(':memory:').cursor()
+            cursor.execute('SELECT JSON(\'{"a": "b"}\')')
+        except sqlite3.OperationalError as exc:
+            stderr('[X] Your SQLite3 version is missing the required JSON1 extension', color='red')
+            hint([
+                'Upgrade your Python version or install the extension manually:',
+                'https://code.djangoproject.com/wiki/JSON1Extension'
+            ])
+
         if in_memory_db:
         if in_memory_db:
-            # Put the db in memory and run migrations in case any command requires it
+            # some commands (e.g. oneshot) dont store a long-lived sqlite3 db file on disk.
+            # in those cases we create a temporary in-memory db and run the migrations
+            # immediately to get a usable in-memory-database at startup
             os.environ.setdefault("ARCHIVEBOX_DATABASE_NAME", ":memory:")
             os.environ.setdefault("ARCHIVEBOX_DATABASE_NAME", ":memory:")
             django.setup()
             django.setup()
             call_command("migrate", interactive=False, verbosity=0)
             call_command("migrate", interactive=False, verbosity=0)
         else:
         else:
+            # Otherwise use default sqlite3 file-based database and initialize django
+            # without running migrations automatically (user runs them manually by calling init)
             django.setup()
             django.setup()
             
             
 
 
@@ -1088,6 +1104,7 @@ def setup_django(out_dir: Path=None, check_db=False, config: ConfigDict=CONFIG,
             ts = datetime.now().strftime('%Y-%m-%d__%H:%M:%S')
             ts = datetime.now().strftime('%Y-%m-%d__%H:%M:%S')
             f.write(f"\n> {command}; ts={ts} version={config['VERSION']} docker={config['IN_DOCKER']} is_tty={config['IS_TTY']}\n")
             f.write(f"\n> {command}; ts={ts} version={config['VERSION']} docker={config['IN_DOCKER']} is_tty={config['IS_TTY']}\n")
 
 
+
         if check_db:
         if check_db:
             # Enable WAL mode in sqlite3
             # Enable WAL mode in sqlite3
             from django.db import connection
             from django.db import connection