From cf2c8cb29385db8bdee00dec384be7598bf3cf17 Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Thu, 15 Sep 2022 12:25:15 +0200 Subject: [PATCH] sql: load Evolution.parts lazily from database (#69109) --- tests/test_sql.py | 30 ++++++++++++++++++++++ wcs/sql.py | 63 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 92 insertions(+), 1 deletion(-) diff --git a/tests/test_sql.py b/tests/test_sql.py index 925c65329..f80a82b6f 100644 --- a/tests/test_sql.py +++ b/tests/test_sql.py @@ -1,5 +1,6 @@ import datetime import io +import pickle import random import string import time @@ -2248,3 +2249,32 @@ def test_sql_import_zip_create_tables(pub): assert table_exists(cur, formdef.table_name) conn.commit() cur.close() + + +def test_lazyevolutionlist(): + dump = pickle.dumps([1, 2]) + + lazy = sql.LazyEvolutionList(dump) + assert len(lazy) == 2 + + lazy = sql.LazyEvolutionList(dump) + assert str(lazy).startswith('[') + + lazy = sql.LazyEvolutionList(dump) + lazy[0] = 'x' + assert lazy[0] == 'x' + + lazy = sql.LazyEvolutionList(dump) + del lazy[0] + assert len(lazy) == 1 + + lazy = sql.LazyEvolutionList(dump) + lazy += [1] + assert len(lazy) == 3 + assert lazy[2] == 1 + + lazy = sql.LazyEvolutionList(dump) + assert 1 in lazy + + lazy = sql.LazyEvolutionList(dump) + assert list(pickle.loads(pickle.dumps(lazy))) == list(lazy) diff --git a/wcs/sql.py b/wcs/sql.py index ac9425d35..33269b16a 100644 --- a/wcs/sql.py +++ b/wcs/sql.py @@ -102,6 +102,67 @@ def like_escape(value): return value +class LazyEvolutionList(list): + def __init__(self, dump): + self.dump = dump + + def _load(self): + try: + dump = super().__getattribute__('dump') + except AttributeError: + pass + else: + super().__setitem__(slice(0), pickle.loads(dump)) + del self.dump + + def __getattribute__(self, name): + super().__getattribute__('_load')() + return super().__getattribute__(name) + + def __bool__(self): + self._load() + return bool(len(self)) + + def __iter__(self): + self._load() + return super().__iter__() + + def __len__(self): + self._load() + return super().__len__() + + def __reversed__(self): + self._load() + return super().__reversed__() + + def __str__(self): + self._load() + return super().__str__() + + def __getitem__(self, index): + self._load() + return super().__getitem__(index) + + def __setitem__(self, index, value): + self._load() + return super().__setitem__(index, value) + + def __delitem__(self, index): + self._load() + return super().__delitem__(index) + + def __iadd__(self, values): + self._load() + return super().__add__(values) + + def __contains__(self, value): + self._load() + return super().__contains__(value) + + def __reduce__(self): + return (list, (), None, iter(self)) + + def pickle_loads(value): if hasattr(value, 'tobytes'): value = value.tobytes() @@ -2576,7 +2637,7 @@ class SqlDataMixin(SqlMixin): if o.time: o.time = o.time.timetuple() if row[6]: - o.parts = pickle_loads(row[6]) + o.parts = LazyEvolutionList(row[6]) return o def set_evolution(self, value): -- 2.37.2