Skip to content

Releases: bluedynamics/plone-pgcatalog

v1.0.0b18

11 Mar 01:40
a92fd63

Choose a tag to compare

v1.0.0b18 Pre-release
Pre-release

Fixed

  • Fix computed index extraction (is_folderish, is_default_page,
    sortable_title, etc.) always returning null. IPGCatalogTool
    extended both ICatalogTool and IPloneCatalogTool, causing
    ICatalogTool to come first in the interface resolution order.
    CMFCore's IndexableObjectWrapper (which does not resolve
    plone.indexer adapters) won over the plone.indexer wrapper.
    Fixed by extending IPloneCatalogTool only — ICatalogTool is
    already provided via IZCatalog.

v1.0.0b17

09 Mar 23:27
f814294

Choose a tag to compare

v1.0.0b17 Pre-release
Pre-release

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() with psycopg.sql composition

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 ERROR level with actionable context
  • CAT-L1: Fallback connection pool registers atexit close hook
  • Install step now runs clearFindAndRebuild() after catalog replacement, fixing empty navigation/search on fresh installs

v1.0.0b16

09 Mar 15:20
8dd487e

Choose a tag to compare

v1.0.0b16 Pre-release
Pre-release
  • 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

03 Mar 00:18
a9c4238

Choose a tag to compare

v1.0.0b15 Pre-release
Pre-release

Changes

  • Fix GenericSetup toolset step: protect PlonePGCatalogTool from being replaced by CMFPlone's importToolset handler. Override the toolset import step via overrides.zcml to 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

02 Mar 21:22
395b5cb

Choose a tag to compare

v1.0.0b14 Pre-release
Pre-release

What's Changed

Fixed

  • Fix new objects not being indexed in PostgreSQL.
    ZODB assigns object IDs (_p_oid) during Connection.commit(), which runs
    after before_commit hooks (where the IndexQueue flushes). All new objects
    therefore have _p_oid=None at catalog_object() call time, causing the
    catalog to silently skip them. The fix stores pending catalog data directly
    in obj.__dict__ under the _pgcatalog_pending key when no OID is available
    yet; CatalogStateProcessor.process() pops and uses it during store() so
    the annotation is never persisted to the database.
    Fixes #27.

Full Changelog: v1.0.0b13...v1.0.0b14

v1.0.0b13

25 Feb 21:59
3a35f59

Choose a tag to compare

v1.0.0b13 Pre-release
Pre-release

What's Changed

Fixed

  • Preserve original Python types for metadata columns (e.g. brain.effective
    now returns a Zope DateTime object instead of an ISO string).
    Non-JSON-native metadata values (DateTime, datetime, date, etc.) are
    encoded via the Rust codec into idx["@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-level idx unchanged.
    Backward compatible — old data without @meta still works.
    Thanks @erral for the testing and report.
    Fixes #23.

Full Changelog: v1.0.0b12...v1.0.0b13

v1.0.0b12

25 Feb 15:21
3c7ddfd

Choose a tag to compare

v1.0.0b12 Pre-release
Pre-release

What's Changed

  • Fix clearFindAndRebuild producing wrong paths (missing portal id prefix,
    e.g. /news instead of /Plone/news), indexing portal_catalog itself,
    and not re-indexing the portal root object.
    Now uses getPhysicalPath() for authoritative paths, aq_base() for
    identity comparison through Acquisition wrappers, and explicitly indexes
    the portal root before traversal (matching Plone's CatalogTool).
    Thx @erral for reporting and checking. Fixes #21.

Full Changelog: v1.0.0b11...v1.0.0b12

v1.0.0b11

24 Feb 20:38
fb5d777

Choose a tag to compare

v1.0.0b11 Pre-release
Pre-release

What's Changed

Fixed

  • Fix example requirements.txt: use local editable path for
    pgcatalog-example instead of bare package name (not on PyPI).
    Fixes #18.

  • Fix ZMI "Update Catalog" and "Clear and Rebuild" buttons returning 404.
    Added missing manage_catalogReindex and manage_catalogRebuild methods.
    Fixes #19.

  • Fix clearFindAndRebuild indexing non-content objects (e.g. acl_users).
    Now filters for contentish objects only (those with a reindexObject method),
    matching Plone's CatalogTool behavior.
    Fixes #20.

Changed

  • uniqueValuesFor(name) is now a supported API (no longer deprecated).
    It delegates to catalog.Indexes[name].uniqueValues().

  • Move driri.py to addons_compat/ in @17

Full Changelog: 1.0.0b10...v1.0.0b11

1.0.0b10

23 Feb 16:00
f07f882

Choose a tag to compare

1.0.0b10 Pre-release
Pre-release

What's Changed

Changed

  • Clean break from ZCatalog: PlonePGCatalogTool no longer inherits
    from Products.CMFPlone.CatalogTool (and transitively ZCatalog,
    ObjectManager, etc.). The new base classes are UniqueObject + 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 _CatalogCompat persistent object provides _catalog.indexes and
    _catalog.schema for backward compatibility with code that accesses
    ZCatalog internal data structures. Existing ZODB instances with the old
    _catalog (full Catalog object) continue to work without migration.

  • ZCML override for eea.facetednavigation: Moved from <includeOverrides>
    inside configure.zcml to a proper overrides.zcml at the package root,
    loaded by Zope's five:loadProductsOverrides. Fixes ZCML conflict errors
    when both eea.facetednavigation and plone.pgcatalog are installed.

Added

  • eea.facetednavigation adapter: PGFacetedCatalog in
    addons_compat/eeafacetednavigation.py -- PG-backed IFacetedCatalog
    that queries idx JSONB directly for faceted counting. Dispatches by
    IndexType (FIELD, KEYWORD, BOOLEAN, UUID, DATE) with IPGIndexTranslator
    fallback. Falls back to the default BTree-based implementation when the
    catalog is not IPGCatalogTool. Conditionally loaded only when
    eea.facetednavigation is installed.

  • Deprecated proxy methods: search() proxies to searchResults() and
    uniqueValuesFor() proxies to Indexes[name].uniqueValues(), both
    emitting DeprecationWarning.

  • Blocked methods: getAllBrains, searchAll, getobject,
    getMetadataForUID, getMetadataForRID, getIndexDataForUID,
    index_objects raise NotImplementedError with descriptive messages.

  • AccessControl security declarations: Comprehensive Zope security
    matching ZCatalog's permission model. Search ZCatalog on read
    methods (searchResults, __call__, getpath, getrid, etc.),
    Manage ZCatalog Entries on write methods (catalog_object,
    uncatalog_object, refreshCatalog, etc.), Manage ZCatalogIndex Entries on index management (addIndex, delIndex, addColumn,
    delColumn, getIndexObjects). setPermissionDefault assigns
    default roles (Anonymous for search, Manager for management).
    Private helpers (indexObject, reindexObject, etc.) declared
    private.

  • DateRangeInRangeIndex support: Native IPGIndexTranslator for
    Products.DateRangeInRangeIndex overlap 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, uses rrule."between"() with duration
    offset for occurrence-level overlap detection. Auto-discovered at
    startup — no configuration needed. Allows dropping the
    Products.DateRangeInRangeIndex addon while keeping the same query API.

Fixed

  • Addon index preservation: Installing plone.pgcatalog on a site with
    addon-provided catalog indexes (e.g. from collective.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 replacing portal_catalog, then restores
    addon indexes after re-applying core Plone profiles. Removed toolset.xml
    in favour of a setuphandler-controlled replacement for correct timing.

Full Changelog: 1.0.0b9...1.0.0b10

v1.0.0b8

22 Feb 01:15
f12d864

Choose a tag to compare

v1.0.0b8 Pre-release
Pre-release

What's Changed

Changed

  • Module split: config.py has 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 (IDatabaseOpenedWithRoot subscriber + registry sync).
    config.py is now a deprecation stub.

  • Shared ensure_date_param(): Deduplicated date coercion utility from
    query.py and dri.py into columns.ensure_date_param().

  • __all__ exports: Added explicit __all__ to pending.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/verifyObject tests for IPGIndexTranslator implementations.

  • Shared query_zoids() test helper in conftest.py.

Security

Security review fixes (addresses #11):

  • CAT-C1: Replace f-string DDL in BM25Backend.install_schema() with
    psycopg.sql.SQL/Identifier/Literal composition. Validate language
    codes against LANG_TOKENIZER_MAP allowlist + validate_identifier() on
    all generated column/index/tokenizer names.
  • CAT-H1: Clamp sort_limit/b_size to _MAX_LIMIT (10,000) and
    b_start to _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.Identifier for extra column names.
  • CAT-M2: Add conn.closed guard in release_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