Skip to content

PlantLogStore: add findEntries() content/metadata search query #271

Description

@HanSur94

Problem / motivation

PlantLogStore (libs/PlantLog/PlantLogStore.m) is the in-memory store for imported plant-log entries, but it exposes exactly one query method — getEntriesInRange(t0, t1) (:196), a time-window lookup. Its full public method set is just addEntries / mergeEntries / clear / getEntries / getEntriesInRange / getCount (header :14–21).

There is no content or metadata search. Yet a plant log is fundamentally a searchable operator record: each PlantLogEntry carries a char Message and a dynamic-field Metadata struct (e.g. MachineId, Operator) — PlantLogEntry.m:38–45. The core analysis workflow is "what was logged around this alarm / by this operator / about this pump?" — e.g. all entries whose message mentions trip, everything Operator = jdoe logged, all MachineId = M1 events.

Today the caller must pull the whole getEntries() array and hand-roll a loop over e.Message / e.Metadata.(field) — exactly the boilerplate getEntriesInRange already spares them on the time axis. This is a query asymmetry: the store can filter by when but not by what.

(Verified gap: grep -niE "filter|search|find\(|query|matches|contains" libs/PlantLog/*.m over non-comment lines returns only find(strcmpi(...)) parsing helpers — no message/metadata search anywhere in the lib.)

Proposed feature

A content/metadata search method on PlantLogStore, complementing the existing time-window query:

entries = store.findEntries('pump');                     % Message substring, case-insensitive
entries = store.findEntries('jdoe',  'Field', 'Operator'); % match a Metadata field value
entries = store.findEntries('^trip', 'Regexp', true);    % regex on Message

It returns a PlantLogEntry array — the same return shape as getEntries / getEntriesInRange — and [] when nothing matches, mirroring the lib's []-empty convention (PlantLogStore.m:50–58). It composes with getEntriesInRange (search, then range-window, or vice-versa).

Rough sketch

  • Lib / class: libs/PlantLog/PlantLogStore.m (single new public method).
  • Public API: entries = findEntries(obj, pattern, varargin)
    • pattern — char/string matched against Message (case-insensitive substring by default).
    • 'Field', name — match against the named Metadata field's value instead of Message (skip entries lacking the field).
    • 'IgnoreCase', tf (default true).
    • 'Regexp', tf (default false → plain substring via contains/strfind; trueregexpi/regexp).
  • Impl: guard isempty(obj.entries_) → return [] (same pattern as getEntriesInRange :208), build a logical mask over {obj.entries_.Message} (or the chosen metadata field) using base contains / regexpi / strcmpi, return obj.entries_(mask). Validate pattern and throw the lib's existing PlantLogStore:invalidInput / PlantLogStore:unknownOption IDs to match house error style.
  • Test: findEntries('pump') matches the two seeded "Pump on/off" entries; 'Field','Operator' filters by metadata; 'Regexp',true honours an anchored pattern; no-match and empty-store both return [].

Value

High. Finding the relevant entries in a long plant log is a primary sensor-analysis workflow, and the store already owns all the data in memory. The method removes per-caller boilerplate, pairs with the existing time-window query, and feeds the Plant-Log hover/live-tail UI and any future log widget.

Constraints check

  • Toolbox-free:contains, regexpi, strcmpi, strfind, cellfun are all base MATLAB/Octave.
  • Backward-compatible: ✅ brand-new method — no change to the constructor, properties, serialization, or any existing method; existing scripts and stores are untouched.
  • Pure MATLAB/Octave: ✅ respects the lib's []-empty convention (documented for Octave value-class compatibility at PlantLogStore.m:50–58).
  • Contracts: ✅ no DashboardWidget / Tag contract involved; self-contained in PlantLogStore.

Effort estimate

S — one method in one file plus one test.

Dedup

Clean. gh issue list --state all --search "PlantLog" → empty; --search "plant log search filter" → empty; no open PR touches PlantLog. The entire libs/PlantLog/ tree is unmined. Distinct from the event-query issues (#225 getEventsInRange, #228 by-severity/category, #245 summarize) — those are on EventStore, a separate store that "no plant-log entry ever crosses into" (PLOG-ST-01, PlantLogStore.m:9–10).


AI-proposed via /feature-scout — needs a human product decision before implementation.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions