Skip to content

Comments

Fix issue #135: Implement lazy query initialization#136

Merged
tamurashingo merged 1 commit intodevelopfrom
issue-135-lazy-query-initialization
Jan 26, 2026
Merged

Fix issue #135: Implement lazy query initialization#136
tamurashingo merged 1 commit intodevelopfrom
issue-135-lazy-query-initialization

Conversation

@tamurashingo
Copy link
Owner

Problem

An error occurred when using the query macro before executing initialize-table-information.

This prevented pre-defining queries for performance optimization like this:

(defparameter *blog-query*
  (query <blog>
    :as :blog
    :columns ((blog :id :title))
    :where (:> (:blog :star) :min-star)))

Solution

Implemented lazy initialization using the placeholder pattern:

  1. Introduction of <query-placeholder> class

    • When query macro is called before initialization, returns a placeholder instance
    • Placeholder has the same interface as the actual <query> instance
  2. Initialization state management

    • *table-information-initialized*: Flag indicating whether initialization is complete
    • *query-initialization-callbacks*: List of callbacks to execute lazily
  3. Transparent delegation

    • Placeholder delegates method calls like execute-query, generate-query, set-* to the actual <query>
    • Displays clear error message when used before initialization

Changes

Added

  • src/environment.lisp: Added variables for initialization state management
  • src/model/query.lisp: Added <query-placeholder> class and delegation methods
  • test/model/query-lazy-initialization.lisp: Added tests for lazy initialization

Modified

  • src/model/query.lisp: Modified query macro to behave based on initialization state
  • src/model/query.lisp: Converted set-* functions to generic functions
  • src/model/base-model.lisp: Modified initialize-table-information to execute callbacks

Usage Example

;; During application load (no error)
(defparameter *blog-query*
  (query <blog>
    :as :blog
    :columns ((blog :id :title))
    :where (:> (:blog :star) :min-star)))
;; => Returns <query-placeholder>

;; Attempting to use before initialization causes error
;; (execute-query *blog-query* '(:min-star 5))
;; => Error: "Query not initialized. Call initialize-table-information first."

;; Initialize
(initialize-table-information)
;; => Placeholder is converted to actual <query> instance

;; After initialization, works transparently
(execute-query *blog-query* '(:min-star 5))
;; => Works correctly

;; Queries defined after initialization return <query> instances immediately as before
(defparameter *user-query*
  (query <user>
    :as :user
    :columns ((user :id :name))))
;; => Returns <query> instance directly

Tests

Added 5 new tests (27 assertions):

  • ✓ Placeholder is created before initialization
  • ✓ Error occurs when used before initialization
  • ✓ Actual query is created after initialization
  • ✓ Placeholder works correctly after initialization
  • ✓ Multiple placeholders are all initialized

All 63 existing tests also pass successfully.

Breaking Changes

None. Existing code works without changes.

Related Issue

Closes #135

- Add *table-information-initialized* flag to track initialization state
- Add *query-initialization-callbacks* list to store delayed query initializations
- Create <query-placeholder> class for queries created before initialization
- Modify query macro to create placeholders when table info not initialized
- Update initialize-table-information to execute callbacks after initialization
- Convert set-* functions to generic functions with placeholder delegation
- Add comprehensive tests for lazy initialization behavior

This allows defining query instances with defparameter before calling
initialize-table-information, fixing the error that occurred when
queries were defined during application load time.
@tamurashingo tamurashingo merged commit d6f7bdd into develop Jan 26, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Error when using query macro before initialize-table-information

1 participant