Commit Graph

37 Commits (main)

Author SHA1 Message Date
Steven 8770b186e4 fix: add Unicode case-insensitive search for SQLite (#5559)
Add custom memos_unicode_lower() SQLite function to enable proper
case-insensitive text search for non-English languages (Cyrillic,
Greek, CJK, etc.).

Previously, SQLite's LOWER() only worked for ASCII characters due to
modernc.org/sqlite lacking ICU extension. This caused searches for
non-English text to be case-sensitive (e.g., searching 'блины' wouldn't
find 'Блины').

Changes:
- Add store/db/sqlite/functions.go with Unicode case folding function
- Register custom function using golang.org/x/text/cases.Fold()
- Update filter renderer to use custom function for SQLite dialect
- Add test for Unicode case-insensitive search
- Make golang.org/x/text a direct dependency

Fixes #5559
3 weeks ago
Johnny af2a2588bf chore(test): add edge case tests for user settings shortcuts and JSON fields 1 month ago
Johnny dc7ec8a8ad feat: allow setting custom timestamps when creating memos and comments
Allow API users to set custom create_time, update_time, and display_time
when creating memos and comments. This enables importing historical data
with accurate timestamps.

Changes:
- Update proto definitions: change create_time and update_time from
  OUTPUT_ONLY to OPTIONAL to allow setting on creation
- Modify CreateMemo service to handle custom timestamps from request
- Update database drivers (SQLite, MySQL, PostgreSQL) to support
  inserting custom timestamps when provided
- Add comprehensive test coverage for custom timestamp functionality
- Maintain backward compatibility: auto-generated timestamps still
  work when custom values are not provided
- Fix golangci-lint issues in plugin/filter (godot and revive)

Fixes #5483
1 month ago
Johnny cbf46a2988 feat(filter): add CEL list comprehension support for tag filtering
Add support for CEL exists() comprehension with startsWith, endsWith, and
contains predicates to enable powerful tag filtering patterns.

Features:
- tags.exists(t, t.startsWith("prefix")) - Match tags by prefix
- tags.exists(t, t.endsWith("suffix")) - Match tags by suffix
- tags.exists(t, t.contains("substring")) - Match tags by substring
- Negation: !tags.exists(...) to exclude matching tags
- Works with all operators (AND, OR, NOT) and other filters

Implementation:
- Added ListComprehensionCondition IR type for comprehension expressions
- Parser detects exists() macro and extracts predicates
- Renderer generates optimized SQL for SQLite, MySQL, PostgreSQL
- Proper NULL/empty array handling across all database dialects
- Helper functions reduce code duplication

Design decisions:
- Only exists() supported (all() rejected at parse time with clear error)
- Only simple predicates (matches() excluded to avoid regex complexity)
- Fail-fast validation with helpful error messages

Tests:
- Comprehensive test suite covering all predicates and edge cases
- Tests for NULL/empty arrays, combined filters, negation
- Real-world use case test for Issue #5480 (archive workflow)
- All tests pass on SQLite, MySQL, PostgreSQL

Closes #5480
1 month ago
Johnny d326c71078 refactor(db): rename tables for clarity - resource→attachment, system_setting→instance_setting 2 months ago
Johnny d68ca84832 fix: delete unused attachments by using filter 2 months ago
Johnny bd02de9895
chore: add store tests (#5397) 2 months ago
Johnny 78aa41336a feat: implement attachment filtering functionality 2 months ago
Steven 07a030ddfd fix(postgres): update tag filtering SQL to ensure proper type casting for LIKE comparisons 3 months ago
Steven 424f11f227 fix(store): fix PostgreSQL tag filtering type inference error
Resolves issue where tag filtering in PostgreSQL databases failed with "operator does not exist: jsonb ~~ unknown" error. The hierarchical tag filtering feature introduced in commit 5e47f25b generated SQL with implicit type placeholders that PostgreSQL couldn't infer.

The fix explicitly casts the LIKE comparison placeholder to text (::text) in the PostgreSQL dialect, ensuring proper type resolution for the query parameter.

Fixes #5275

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
3 months ago
Steven 5e47f25bf5 feat(store): add hierarchical tag filtering support
Tag filters now support hierarchical matching where searching for a tag (e.g., "book") will match both the exact tag and any tags with that prefix (e.g., "book/fiction", "book/non-fiction"). This applies across all database backends (SQLite, MySQL, PostgreSQL) with corresponding test updates.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
4 months ago
Steven e0b1153269 fix(web): resolve MobX observable reactivity issue in filter computation
Fixes filtering functionality that was broken due to improper use of
useMemo with MobX observables. The issue occurred because useMemo's
dependency array uses reference equality, but MobX observable arrays
are mutated in place (reference doesn't change when items are added/removed).

Changes:
- Remove useMemo from filter computation in Home, UserProfile, and Archived pages
- Calculate filters directly in render since components are already MobX observers
- Fix typo: memoFitler -> memoFilter in Archived.tsx

This ensures filters are recalculated whenever memoFilterStore.filters changes,
making tag clicks and other filter interactions work correctly.

Fixes #5189

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
4 months ago
Johnny bc7decf642 refactor: remove unused constants 4 months ago
Copilot b685ffacdf refactor: memo filter
- Updated memo and reaction filtering logic to use a unified engine for compiling filter expressions into SQL statements.
- Removed redundant filter parsing and conversion code from ListMemoRelations, ListReactions, and ListAttachments methods.
- Introduced IDList and UIDList fields in FindMemo and FindReaction structs to support filtering by multiple IDs.
- Removed old filter test files for reactions and attachments, as the filtering logic has been centralized.
- Updated tests for memo filtering to reflect the new SQL statement compilation approach.
- Ensured that unsupported user filters return an error in ListUsers method.
4 months ago
Steven c3d4f8e9d1 feat: implement user-specific SQL converter for filtering in user service 6 months ago
Johnny 7cc2df9254 chore: fix linter 6 months ago
varsnotwars 4eb5b67baf
feat: attachments by id (#5008) 6 months ago
Neo 6b507ff600
fix: pinned shortcut comparison operators (#4987) 7 months ago
varsnotwars f4bdfa28a0
feat: filter/method for reactions by content_id (#4969) 7 months ago
Colin Holzman 8319516d1a
fix: boolean filters (#4966) 7 months ago
johnnyjoy 506b477d50 fix: get user by username 7 months ago
Colin Holzman aae7ec8d1f
fix: calendar filter (#4942) 7 months ago
Maximilian Krauß 4d6042e35f
fix(tags): ensure JSON array elements are properly formatted in SQL queries (#4944) 7 months ago
johnnyjoy 9ea2f9f686 fix: linter 7 months ago
johnnyjoy ed23cbc011 refactor: memo filter 7 months ago
johnnyjoy b55904a428 feat: support more filter factors 7 months ago
Johnny 9b15936873 refactor: clean unused fields 8 months ago
Johnny 778a5eb184 refactor: memo filter 8 months ago
Steven a317f9e653 fix: linter 9 months ago
Steven de3e55c2e6 feat: support `now()` time functions 9 months ago
Steven b89d8f5342 feat: implement hasTaskList filter 9 months ago
Johnny e3a4f49c5c feat: implement creator_id factor 12 months ago
Johnny 925e97882e feat: support pinned factor 12 months ago
johnnyjoy e0e735d14d feat: support memo filter for mysql and postgres 1 year ago
johnnyjoy b9a0c56163 feat: support more factors in filter 1 year ago
johnnyjoy 58a867e4da fix: linter warning 1 year ago
johnnyjoy 2d731c5cc5 feat: memo filter for sqlite 1 year ago