Skip to content

Pagination and count for new SubjectEntity queries#578

Merged
jhweir merged 14 commits intodevfrom
Ad4mModel-updates
Mar 21, 2025
Merged

Pagination and count for new SubjectEntity queries#578
jhweir merged 14 commits intodevfrom
Ad4mModel-updates

Conversation

@lucksus
Copy link
Copy Markdown
Member

@lucksus lucksus commented Mar 20, 2025

Enhanced Query Builder and SubjectEntity with Pagination and Count Features

This PR adds comprehensive pagination and count functionality to both the SubjectEntity class and SubjectQueryBuilder, providing flexible options for handling large datasets and implementing real-time counters.

New Features

SubjectEntity Static Methods

  • Added findAllAndCount() for getting results with total count
  • Added paginate() for direct pagination without query builder
  • Added count() method with query support

Function-Chaining - Query Builder Methods

  • Added paginate() method for one-time pagination queries
  • Added paginateSubscribe() for real-time pagination updates
  • Added count() and countSubscribe() for count operations
  • All methods return rich metadata including total counts and page information

Renaming of Query Builder terminals

  • run() -> get()
  • subscribeAndRun() -> subscribe()

Examples

Using SubjectEntity Static Methods

Find All with Count

// Get limited results with total count
const { results, totalCount } = await Recipe.findAllAndCount(perspective, {
  where: { category: "Dessert" },
  limit: 10
});
console.log(`Showing 10 of ${totalCount} dessert recipes`);

Direct Pagination

// Get a specific page of results
const page = await Recipe.paginate(perspective, 10, 1, {
  where: { category: "Main Course" }
});
console.log(`Page ${page.pageNumber} of recipes`);
console.log(`Showing ${page.results.length} of ${page.totalCount} items`);

Simple Count

// Get total count with filters
const activeCount = await Recipe.count(perspective, {
  where: { status: "active" }
});
console.log(`Active recipes: ${activeCount}`);

Using chained functions

Basic Pagination

// Get first page of active recipes
const page = await Recipe.query(perspective)
  .where({ status: "active" })
  .paginate(10, 1);
console.log(`Showing ${page.results.length} of ${page.totalCount} recipes`);
console.log(`Page ${page.pageNumber}, size: ${page.pageSize}`);

Real-time Pagination

// Subscribe to updates on the current page
await Recipe.query(perspective)
  .where({ status: "cooking" })
  .paginateSubscribe(10, 1, page => {
    console.log("Currently cooking:");
    page.results.forEach(recipe => {
      console.log(`- ${recipe.name} (${recipe.status})`);
  });
  console.log(`Page ${page.pageNumber} of ${Math.ceil(page.totalCount / page.pageSize)}`);
});

Count Operations

// Get total count
const totalDesserts = await Recipe.query(perspective)
  .where({ category: "Dessert" })
  .count();
// Subscribe to count updates
await Recipe.query(perspective)
  .where({ status: "active" })
  .countSubscribe(count => {
    console.log(Active recipes: ${count});
  });

Complex Queries

// Using static method
const { results: topDesserts, totalCount } = await Recipe.findAllAndCount(perspective, {
  where: {
    category: "Dessert",
    rating: { gt: 4 }
  },
  order: { rating: "DESC" },
  limit: 10
});
// Using query builder with real-time updates
await Recipe.query(perspective)
  .where({
    category: "Main",
    status: "active",
    difficulty: { lte: 3 }
  })
  .order({ createdAt: "DESC" })
  .paginateSubscribe(20, 1, page => {
    updateUI(page.results);
    updatePagination(page.pageNumber, page.totalCount, page.pageSize);
  });

Implementation Details

Shared Features

  • All methods support full query capabilities including:
    • Complex where conditions
    • Ordering
    • Property/collection selection
    • Offset/limit pagination
  • Consistent return types across static and builder methods
  • Full TypeScript support with proper generics

Static Methods

  • Direct access for simple use cases
  • Optimized for single-shot queries
  • Consistent with existing findAll pattern

Query Builder

  • Fluent interface for complex queries
  • Support for real-time subscriptions
  • Chainable methods for query construction
  • Enhanced type safety

Pagination Implementation

  • Uses Prolog's skipN and takeN predicates
  • Efficient count queries
  • Consistent page numbering (1-based)
  • Rich metadata in results

@jhweir jhweir merged commit fdba43f into dev Mar 21, 2025
2 checks passed
@lucksus lucksus deleted the Ad4mModel-updates branch August 22, 2025 12:14
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.

2 participants