Skip to content

Commit db78b90

Browse files
committed
Make connection to the sqlite db from another process
This is because currently pygeodiff bundles its own sqlite3 library different from python's sqlite3 library, and that's causing clashes.
1 parent c543499 commit db78b90

File tree

2 files changed

+46
-3
lines changed

2 files changed

+46
-3
lines changed

mergin/test/sqlite_con.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
"""
2+
A script to be used with AnotherSqliteConn in test_client.py to simulate
3+
an open connection to a sqlite3 database from a different process.
4+
"""
5+
6+
import sqlite3
7+
import sys
8+
9+
con = sqlite3.connect(sys.argv[1])
10+
cursor = con.cursor()
11+
while True:
12+
cmd = input()
13+
sys.stderr.write(cmd + "\n")
14+
if cmd == 'stop': break
15+
cursor.execute(cmd)

mergin/test/test_client.py

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import logging
22
import os
33
import tempfile
4+
import subprocess
45
import shutil
56
from datetime import datetime, timedelta
67
import pytest
@@ -847,6 +848,32 @@ def _is_file_updated(filename, changes_dict):
847848
return False
848849

849850

851+
class AnotherSqliteConn:
852+
""" This simulates another app (e.g. QGIS) having a connection open, potentially
853+
with some active reader/writer.
854+
855+
Note: we use a subprocess here instead of just using sqlite3 module from python
856+
because pygeodiff and python's sqlite3 module have their own sqlite libraries,
857+
and this does not work well when they are used in a single process. But if we
858+
use another process, things are fine. This is a limitation of how we package
859+
pygeodiff currently.
860+
"""
861+
def __init__(self, filename):
862+
self.proc = subprocess.Popen(
863+
['python3', os.path.join(os.path.dirname(__file__), 'sqlite_con.py'), filename],
864+
stdin=subprocess.PIPE,
865+
stderr=subprocess.PIPE)
866+
867+
def run(self, cmd):
868+
self.proc.stdin.write(cmd.encode()+b'\n')
869+
self.proc.stdin.flush()
870+
871+
def close(self):
872+
out,err = self.proc.communicate(b'stop\n')
873+
if self.proc.returncode != 0:
874+
raise ValueError("subprocess error:\n" + err.decode('utf-8'))
875+
876+
850877
def test_push_gpkg_schema_change(mc):
851878
""" Test that changes in GPKG get picked up if there were recent changes to it by another
852879
client and at the same time geodiff fails to find changes (a new table is added)
@@ -880,9 +907,8 @@ def test_push_gpkg_schema_change(mc):
880907
mp.log.info(' // make changes to DB')
881908

882909
# open a connection and keep it open (qgis does this with a pool of connections too)
883-
con2 = sqlite3.connect(test_gpkg)
884-
cursor2 = con2.cursor()
885-
cursor2.execute('select count(*) from simple;')
910+
acon2 = AnotherSqliteConn(test_gpkg)
911+
acon2.run('select count(*) from simple;')
886912

887913
# add a new table to ensure that geodiff will fail due to unsupported change
888914
# (this simulates an independent reader/writer like GDAL)
@@ -921,6 +947,8 @@ def test_push_gpkg_schema_change(mc):
921947
# OLD: fails here
922948
_check_test_table(test_gpkg_verify)
923949

950+
acon2.close()
951+
924952

925953
@pytest.mark.parametrize("extra_connection", [False, True])
926954
def test_rebase_local_schema_change(mc, extra_connection):

0 commit comments

Comments
 (0)