Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Doctrine Json Functions Laravel Package

scienta/doctrine-json-functions

Adds JSON function support to Doctrine ORM DQL by registering custom function nodes for multiple databases. Use MySQL/MariaDB, PostgreSQL, SQLite (json1), or SQL Server JSON functions directly in DQL with platform validation.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Leverages Doctrine ORM’s extensibility: The package integrates seamlessly with Doctrine’s DQL parser, enabling JSON operations without requiring raw SQL. This aligns well with Laravel’s Eloquent (which is built on Doctrine ORM), making it a natural fit for applications using Eloquent or raw Doctrine queries.
  • Database-agnostic design: Supports MySQL, PostgreSQL, SQLite, and SQL Server, allowing TPMs to standardize JSON query logic across multi-database environments. This is critical for applications with mixed database backends or planned migrations.
  • Query Builder compatibility: Functions work with both DQL and QueryBuilder, ensuring compatibility with Laravel’s query builder syntax (e.g., where(), orWhere()).

Integration Feasibility

  • Minimal boilerplate: Registration requires adding custom string functions to Doctrine’s configuration (via addCustomStringFunction or Symfony’s doctrine.yaml). For Laravel, this can be centralized in a service provider or config file.
  • Laravel-specific considerations:
    • Eloquent: Works natively with Eloquent’s QueryBuilder (e.g., Model::whereJsonContains('column', 'value')).
    • Raw SQL: For complex cases, raw SQL can bypass DQL limitations (e.g., PostgreSQL’s ->> operator), but this package provides DQL alternatives.
    • Database connections: Laravel’s connection switching (e.g., connection('pgsql')) must align with the package’s platform checks to avoid runtime errors.
  • Type safety: Boolean-returning functions (e.g., JSON_CONTAINS) require explicit comparison (= 1 or = true), which may need wrapper methods in Laravel repositories to abstract this.

Technical Risk

  • Database version dependencies: Functions like JSON_VALUE in MySQL 8.0.21+ or MariaDB-specific functions may break if the underlying database version is unsupported. Mitigation: Validate database versions during deployment (e.g., via migrations or CI checks).
  • Performance overhead: JSON functions can be resource-intensive. Mitigation: Benchmark queries in staging; consider indexing JSON paths (e.g., PostgreSQL’s jsonb_path_ops).
  • Laravel-specific quirks:
    • Eloquent macros: May need custom macros to simplify syntax (e.g., whereJsonExtract()).
    • Query caching: Doctrine’s query cache may not handle dynamic JSON functions optimally. Mitigation: Test with Laravel’s query cache or disable for JSON-heavy queries.
  • Boolean function limitations: Doctrine’s lack of native boolean DQL functions forces explicit comparisons, which could lead to bugs if overlooked. Mitigation: Enforce coding standards (e.g., static analysis rules) or create helper traits.

Key Questions

  1. Database strategy:
    • Are all target databases supported by this package? If not, what’s the fallback (e.g., raw SQL)?
    • How will database version upgrades be managed (e.g., CI checks for minimum versions)?
  2. Laravel integration depth:
    • Should this be wrapped in a Laravel-specific package (e.g., laravel-doctrine-json) to abstract Doctrine config?
    • Will Eloquent macros or repository methods be added to simplify usage (e.g., User::whereJsonContains('roles', 'admin'))?
  3. Performance:
    • Are JSON columns indexed? If not, will query performance degrade at scale?
    • Should materialized views or application-side caching be considered for complex JSON queries?
  4. Testing:
    • How will integration tests cover multi-database scenarios (e.g., MySQL vs. PostgreSQL)?
    • Are there plans to add Laravel-specific test cases (e.g., Eloquent QueryBuilder scenarios)?
  5. Maintenance:
    • Who will monitor for Doctrine ORM version compatibility (e.g., if Doctrine 3.x breaks backward compatibility)?
    • How will new JSON functions (e.g., PostgreSQL’s JSONB_TYPEOF) be adopted?

Integration Approach

Stack Fit

  • Laravel + Eloquent: The package integrates natively with Eloquent’s QueryBuilder, enabling JSON queries via DQL. Example:
    // MySQL/PostgreSQL
    $users = User::whereJsonContains('metadata', '"premium"')
                ->whereJsonExtract('metadata', '$.tier', '>=' => 3)
                ->get();
    
  • Symfony/Doctrine: If the Laravel app uses raw Doctrine ORM (e.g., for complex queries), the package’s Symfony bundle config can be adapted.
  • Database drivers: Laravel’s database abstraction layer must support the target database’s JSON functions. For example:
    • MySQL 5.7+ for JSON_EXTRACT.
    • PostgreSQL 9.3+ for JSONB_EXISTS.
  • Caching: Laravel’s query cache (e.g., Redis) may not cache JSON function results optimally. Workaround: Use application-level caching for frequent JSON queries.

Migration Path

  1. Phase 1: Proof of Concept
    • Install the package in a staging environment.
    • Test basic functions (e.g., JSON_EXTRACT, JSON_CONTAINS) with existing queries.
    • Validate performance against raw SQL equivalents.
  2. Phase 2: Configuration
    • Register required functions in Laravel’s Doctrine config (via a service provider or config/doctrine.php).
    • Example for MySQL:
      // app/Providers/DoctrineServiceProvider.php
      public function registerFunctions()
      {
          $config = new \Doctrine\ORM\Configuration();
          $config->addCustomStringFunction(
              \Scienta\DoctrineJsonFunctions\Query\AST\Functions\Mysql\JsonExtract::FUNCTION_NAME,
              \Scienta\DoctrineJsonFunctions\Query\AST\Functions\Mysql\JsonExtract::class
          );
          // Repeat for other functions...
      }
      
  3. Phase 3: Eloquent Integration
    • Create query scopes or macros to simplify syntax:
      // app/Models/User.php
      public function scopeWhereJsonContains($query, $column, $value)
      {
          return $query->where("JSON_CONTAINS($column, :value) = 1", ['value' => json_encode($value)]);
      }
      
  4. Phase 4: Testing
    • Write integration tests for each database platform.
    • Test edge cases (e.g., malformed JSON, nested paths).
  5. Phase 5: Rollout
    • Gradually replace raw SQL JSON queries with DQL equivalents.
    • Monitor query performance and database load.

Compatibility

  • Laravel versions: Compatible with Laravel 10+ (PHP 8.1+) due to Doctrine ORM 2.19/3.x support.
  • Database compatibility:
    • MySQL/MariaDB: Full support for listed functions.
    • PostgreSQL: Requires jsonb type for optimal performance. Test json vs. jsonb behavior.
    • SQLite: Requires the json1 extension (enabled by default in Laravel’s SQLite driver).
    • SQL Server: Limited to JSON_VALUE; other functions may need raw SQL.
  • Doctrine ORM: Must match the package’s requirements (^2.19 or ^3). Risk: Upgrading Doctrine may require re-testing.

Sequencing

  1. Prioritize high-impact queries: Start with frequently used JSON queries (e.g., filtering by nested attributes).
  2. Database-specific rollout:
    • Begin with a single database (e.g., MySQL) to validate the approach.
    • Expand to PostgreSQL/SQLite once the first phase is stable.
  3. Deprecate raw SQL: Replace ad-hoc SQL JSON functions with DQL equivalents over time.
  4. Document patterns: Create internal docs for common use cases (e.g., "How to query nested arrays").

Operational Impact

Maintenance

  • Dependency management:
    • Monitor for updates to scienta/doctrine-json-functions and Doctrine ORM.
    • Pin versions in composer.json to avoid breaking changes.
  • Configuration drift:
    • Centralize Doctrine function registration in a single location (e.g., service provider) to avoid duplication.
    • Use environment variables or config files to toggle functions per environment (e.g., disable JSON_VALUE in MySQL < 8.0.21).
  • Boolean function quirks:
    • Enforce coding standards to ensure boolean functions are always compared to = 1 or = true.
    • Consider a Laravel helper to auto-wrap boolean JSON functions:
      // app/Helpers/JsonQuery.php
      public static function boolJsonFunction(string $function, ...$args): string
      {
          return "$function(...) = 1";
      }
      

Support

  • Debugging:
    • JSON function errors may surface as "unknown function" or "syntax error" in DQL. Tooling: Use Doctrine’s SQL logging (config('database.log_queries' => true)) to inspect generated SQL.
    • Database-specific errors (e.g., "JSON path not found") require checking the underlying database logs.
  • Common issues:
    • Path syntax: JSON paths in DQL must use
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor
spatie/laravel-javascript-views