Releases: bluedynamics/plone-pgcatalog
v1.0.0b18
Fixed
- Fix computed index extraction (
is_folderish,is_default_page,
sortable_title, etc.) always returningnull.IPGCatalogTool
extended bothICatalogToolandIPloneCatalogTool, causing
ICatalogToolto come first in the interface resolution order.
CMFCore'sIndexableObjectWrapper(which does not resolve
plone.indexer adapters) won over the plone.indexer wrapper.
Fixed by extendingIPloneCatalogToolonly —ICatalogToolis
already provided viaIZCatalog.
v1.0.0b17
Security
- CAT-Q1: Validate unknown query keys before SQL interpolation in
_process_index()fallback path - CAT-S1: Replace f-string DDL in
_ensure_text_indexes()withpsycopg.sqlcomposition
Changed
- CAT-P1:
reindex_index()now uses a server-side cursor with batched fetches
Fixed
- CAT-O1: Log extraction failures with field name and exception info
- CAT-O2: Startup degradation now logs at
ERRORlevel with actionable context - CAT-L1: Fallback connection pool registers
atexitclose hook - Install step now runs
clearFindAndRebuild()after catalog replacement, fixing empty navigation/search on fresh installs
v1.0.0b16
- Add "Blob Storage" ZMI tab to portal_catalog showing blob statistics
(total count, size, per-tier breakdown for PG/S3), a logarithmic size
distribution histogram, and S3 tiering threshold visualization.
Full Changelog: v1.0.0b15...v1.0.0b16
v1.0.0b15
Changes
- Fix GenericSetup toolset step: protect PlonePGCatalogTool from being replaced by CMFPlone's
importToolsethandler. Override thetoolsetimport step viaoverrides.zcmlto skip portal_catalog deletion when it is already a PlonePGCatalogTool. - Add unit tests for importToolset (6 tests covering all code paths).
See CHANGES.md for full changelog.
v1.0.0b14
What's Changed
Fixed
- Fix new objects not being indexed in PostgreSQL.
ZODB assigns object IDs (_p_oid) duringConnection.commit(), which runs
afterbefore_commithooks (where the IndexQueue flushes). All new objects
therefore have_p_oid=Noneatcatalog_object()call time, causing the
catalog to silently skip them. The fix stores pending catalog data directly
inobj.__dict__under the_pgcatalog_pendingkey when no OID is available
yet;CatalogStateProcessor.process()pops and uses it duringstore()so
the annotation is never persisted to the database.
Fixes #27.
Full Changelog: v1.0.0b13...v1.0.0b14
v1.0.0b13
What's Changed
Fixed
- Preserve original Python types for metadata columns (e.g.
brain.effective
now returns a ZopeDateTimeobject instead of an ISO string).
Non-JSON-native metadata values (DateTime, datetime, date, etc.) are
encoded via the Rust codec intoidx["@meta"]at write time and restored
on brain attribute access with per-brain caching. JSON-native values
(str, int, float, bool, None) remain in top-levelidxunchanged.
Backward compatible — old data without@metastill works.
Thanks @erral for the testing and report.
Fixes #23.
Full Changelog: v1.0.0b12...v1.0.0b13
v1.0.0b12
What's Changed
- Fix
clearFindAndRebuildproducing wrong paths (missing portal id prefix,
e.g./newsinstead of/Plone/news), indexingportal_catalogitself,
and not re-indexing the portal root object.
Now usesgetPhysicalPath()for authoritative paths,aq_base()for
identity comparison through Acquisition wrappers, and explicitly indexes
the portal root before traversal (matching Plone'sCatalogTool).
Thx @erral for reporting and checking. Fixes #21.
Full Changelog: v1.0.0b11...v1.0.0b12
v1.0.0b11
What's Changed
Fixed
-
Fix example
requirements.txt: use local editable path for
pgcatalog-exampleinstead of bare package name (not on PyPI).
Fixes #18. -
Fix ZMI "Update Catalog" and "Clear and Rebuild" buttons returning 404.
Added missingmanage_catalogReindexandmanage_catalogRebuildmethods.
Fixes #19. -
Fix
clearFindAndRebuildindexing non-content objects (e.g.acl_users).
Now filters for contentish objects only (those with areindexObjectmethod),
matching Plone'sCatalogToolbehavior.
Fixes #20.
Changed
-
uniqueValuesFor(name)is now a supported API (no longer deprecated).
It delegates tocatalog.Indexes[name].uniqueValues(). -
Move
driri.pyto addons_compat/ in @17
Full Changelog: 1.0.0b10...v1.0.0b11
1.0.0b10
What's Changed
Changed
-
Clean break from ZCatalog:
PlonePGCatalogToolno longer inherits
fromProducts.CMFPlone.CatalogTool(and transitivelyZCatalog,
ObjectManager, etc.). The new base classes areUniqueObject + Folder,
providing a minimal OFS container for index objects and lexicons while
eliminating the deep inheritance chain.This improves query performance by ~2x across most scenarios (reduced
Python-side overhead from attribute lookups, security checks, and
Acquisition wrapping) and write performance by ~5% (lighter commit path).A
_CatalogCompatpersistent object provides_catalog.indexesand
_catalog.schemafor backward compatibility with code that accesses
ZCatalog internal data structures. Existing ZODB instances with the old
_catalog(fullCatalogobject) continue to work without migration. -
ZCML override for eea.facetednavigation: Moved from
<includeOverrides>
insideconfigure.zcmlto a properoverrides.zcmlat the package root,
loaded by Zope'sfive:loadProductsOverrides. Fixes ZCML conflict errors
when both eea.facetednavigation and plone.pgcatalog are installed.
Added
-
eea.facetednavigation adapter:
PGFacetedCatalogin
addons_compat/eeafacetednavigation.py-- PG-backedIFacetedCatalog
that queriesidxJSONB directly for faceted counting. Dispatches by
IndexType(FIELD, KEYWORD, BOOLEAN, UUID, DATE) withIPGIndexTranslator
fallback. Falls back to the default BTree-based implementation when the
catalog is notIPGCatalogTool. Conditionally loaded only when
eea.facetednavigationis installed. -
Deprecated proxy methods:
search()proxies tosearchResults()and
uniqueValuesFor()proxies toIndexes[name].uniqueValues(), both
emittingDeprecationWarning. -
Blocked methods:
getAllBrains,searchAll,getobject,
getMetadataForUID,getMetadataForRID,getIndexDataForUID,
index_objectsraiseNotImplementedErrorwith descriptive messages. -
AccessControl security declarations: Comprehensive Zope security
matching ZCatalog's permission model.Search ZCatalogon read
methods (searchResults,__call__,getpath,getrid, etc.),
Manage ZCatalog Entrieson write methods (catalog_object,
uncatalog_object,refreshCatalog, etc.),Manage ZCatalogIndex Entrieson index management (addIndex,delIndex,addColumn,
delColumn,getIndexObjects).setPermissionDefaultassigns
default roles (Anonymousfor search,Managerfor management).
Private helpers (indexObject,reindexObject, etc.) declared
private. -
DateRangeInRangeIndex support: Native
IPGIndexTranslatorfor
Products.DateRangeInRangeIndexoverlap queries. Translates
catalog({'my_idx': {'start': dt1, 'end': dt2}})into a single SQL
overlap clause (obj_start <= q_end AND obj_end >= q_start).
Supports recurring events: when the underlying start index is a
DateRecurringIndex with RRULE, usesrrule."between"()with duration
offset for occurrence-level overlap detection. Auto-discovered at
startup — no configuration needed. Allows dropping the
Products.DateRangeInRangeIndexaddon while keeping the same query API.
Fixed
- Addon index preservation: Installing plone.pgcatalog on a site with
addon-provided catalog indexes (e.g. fromcollective.taxonomy,
plone.app.multilingual, etc.) no longer silently drops those index
definitions. The install step now snapshots all existing index definitions
and metadata columns before replacingportal_catalog, then restores
addon indexes after re-applying core Plone profiles. Removedtoolset.xml
in favour of a setuphandler-controlled replacement for correct timing.
Full Changelog: 1.0.0b9...1.0.0b10
v1.0.0b8
What's Changed
Changed
-
Module split:
config.pyhas been split into four focused modules:
pending.py(thread-local pending store + savepoint support),
pool.py(connection pool discovery + request-scoped connections),
processor.py(CatalogStateProcessor),
startup.py(IDatabaseOpenedWithRootsubscriber + registry sync).
config.pyis now a deprecation stub. -
Shared
ensure_date_param(): Deduplicated date coercion utility from
query.pyanddri.pyintocolumns.ensure_date_param(). -
__all__exports: Added explicit__all__topending.py,pool.py,
processor.py,startup.py,columns.py,backends.py,interfaces.py. -
Top-level imports: Removed unnecessary deferred imports across
catalog.py,processor.py,startup.py.
Added
-
verifyClass/verifyObjecttests forIPGIndexTranslatorimplementations. -
Shared
query_zoids()test helper inconftest.py.
Security
Security review fixes (addresses #11):
- CAT-C1: Replace f-string DDL in
BM25Backend.install_schema()with
psycopg.sql.SQL/Identifier/Literalcomposition. Validate language
codes againstLANG_TOKENIZER_MAPallowlist +validate_identifier()on
all generated column/index/tokenizer names. - CAT-H1: Clamp
sort_limit/b_sizeto_MAX_LIMIT(10,000) and
b_startto_MAX_OFFSET(1,000,000) to prevent resource exhaustion. - CAT-H2: Validate RRULE strings in
DateRecurringIndexTranslator.extract()
against RFC 5545 pattern and_MAX_RRULE_LENGTH(1,000) before storing. - CAT-H3: Truncate full-text search queries to
_MAX_SEARCH_LENGTH(1,000)
to prevent excessive tsvector parsing. - CAT-M1: Replace f-string SQL in
clear_catalog_data()with
psycopg.sql.Identifierfor extra column names. - CAT-M2: Add
conn.closedguard inrelease_request_connection()to
handle already-closed connections; document pool leak recovery in docstring. - CAT-M3: Add defensive
validate_identifier(index_name)in
DateRecurringIndexTranslator.query(). - CAT-L1: Simplify error messages to not expose internal limit values.
- CAT-L2: Add rate limiting guidance note in
searchResults()docstring. - CAT-L3: Normalize double slashes in
_validate_path().
Full Changelog: v1.0.0b7...v1.0.0b8