Purpose
Make ERP5 be able to run with SQLite as a storage backend for both the SQL catalog and the activity
Context before the changes
ZSQLiteDA
ERP5's SQL layer was exclusively backed by MySQL through ZMySQLDA. There was no Zope database adapter for SQLite.
All catalog queries, activity queue tables and connection management assumed MySQL-specific SQL syntax, type handling, and transaction semantics.
CMFActivity / ActivityTool
The activity queue had three concrete MySQL-specific implementations:
SQLBase.py, SQLDict.py, SQLJoblib.py. The backend was hardwired with no abstraction layer.
Solution
ZSQLiteDA
A new ZSQLiteDA Zope product is introduced, implementing the same interface as ZMySQLDA:
CMFActivity backend proxy pattern
SQLBase.py, SQLDict.py, and SQLJoblib.py are converted into backend-agnostic proxy modules.
Each exposes a configure(erp5_catalog_storage) function that loads the appropriate backend
module (MySQL or SQLite) and copies all its public attributes onto itself:
New MySQLBase.py, MySQLDict.py, and MySQLDict.py provide the MySQL
implementations of the activity queue backend.
New SQLiteBase.py, SQLiteDict.py, and SQLiteJoblib.py provide the SQLite
implementations of the activity queue backend.
How it works
At process startup, before any request is served, Zope calls
AppInitializer.initialize(). ERP5Site.py monkey-patches this hook to read
erp5_catalog_storage from getConfiguration().product_config['initsite']
(defaulting to erp5_mysql_innodb_catalog in tests via the environment variable) and then calls:
Products.Database.configure(erp5_catalog_storage)
CMFActivity.Activity.configure(erp5_catalog_storage)
This is the configuration point for the entire storage backend. All proxy modules start with _backend = None and an empty namespace; After configure() runs they expose the full API of the selected backend.
Database layer
Products.Database.configure() loads either ZMySQLDA or ZSQLiteDA and copies all public attributes of their db and DA modules onto the corresponding proxy modules.
From this point, code that does from Products.Database.db import DB receives the correct DB class for the
selected backend, with no further changes required in callers.
Activity layer
CMFActivity.Activity.configure() applies the same attribute-copy pattern to SQLBase, SQLDict, and SQLJoblib,
then instantiates one object per queue type and writes them into ActivityTool.activity_dict.