Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add whereLike clause to query builder #52147

Merged

Conversation

einar-hansen
Copy link
Contributor

Add whereLike and orWhereLike methods to Query Builder

This PR introduces new methods to the Query Builder for performing LIKE queries with better control over case sensitivity:

  • whereLike($column, $value, $caseSensitive = false): Performs a LIKE query with optional case sensitivity
  • whereNotLike($column, $value, $caseSensitive = false): Performs a NOT LIKE query with optional case sensitivity
  • orWhereLike($column, $value, $caseSensitive = false): Adds an OR LIKE clause with optional case sensitivity
  • orWhereNotLike($column, $value, $caseSensitive = false): Adds an OR NOT LIKE clause with optional case sensitivity

These methods provide a more intuitive and database-agnostic way to perform string matching queries. They work across all supported databases (MySQL, PostgreSQL, SQLite, and SQL Server) while handling the differences in case-sensitivity behavior. It is by default with case-sensitivity to false, as is the default behavior in MySQL and SQLite.

Benefits:

  1. Simplified API for common LIKE queries
  2. Consistent behavior across different database systems
  3. Explicit control over case sensitivity
  4. Improved readability and maintainability of query code

Example usage:
You want to find a user in the database by looking up its email address, and the user has registered its email address using capital letters in its names John.Doe@example.com.

If you are using Postgres in production, and SQLite for local development (like me), then you would need to use 'ilike' in Postgres, and 'like' in SQLite, forcing you to write something like this for searching case-insensitive.

$users = DB::table('users')
    ->when(DB::getDriverName() === 'pgsql',
        function (Builder $query): void {
            $query->where('email', 'ilike', 'john.doe@example.com');
        },
        function (Builder $query): void {
            $query->where('email', 'like', 'john.doe@example.com');
        },
    )->get()

After this PR you'll be able to achieve the same by the same query.

$users = DB::table('users')
    ->whereLike('email', 'john.doe@example.com')
    ->get();

or for case-sensitive search

$users = DB::table('users')
    ->whereLike('email', 'John.Doe@example.com', true)
    ->get();
  • Postgres uses ilike for case insensitive operations, and like for case sensitive.
  • MySQL uses like for case insensitive operations, and like binary for case sensitive.
  • SQLite uses like for case insensitive operations, and uses glob for case sensitive (converts the binding to use glob, replacing _ and %).
  • SqlServer uses the like operation by default. In SQL Server, case sensitivity is determined by the collation of the database or column, therefore this implementation is configured to throw an exception if you set the case-sensitivity flag to true.

@einar-hansen
Copy link
Contributor Author

Docs: laravel/docs#9765

@taylorotwell taylorotwell merged commit 95107a0 into laravel:11.x Jul 18, 2024
28 of 29 checks passed
@siarheipashkevich
Copy link
Contributor

siarheipashkevich commented Jul 19, 2024

@einar-hansen @taylorotwell what about whereAny method where we can use like operator?

and wherePivot

@christianschoenmakers
Copy link

Really like this new method!

What about adding an additional parameter to define how to search (start with, end with, any position).

whereLike('column', 'value', search: 'startWith') will search value%

whereLike('column', 'value', search: 'endWith') will search %value

whereLike('column', 'value', search: 'any') will search %value%

This option should be optional, so you can also use a custom like pattern (for example with _).

Not sure about the search parameter values yet, but I think you'll get the idea.

This will make your code more cleaner, because you don't need to format the strings with %'s by yourself.

What are your thoughts?

@einar-hansen
Copy link
Contributor Author

@einar-hansen @taylorotwell what about whereAny method where we can use like operator?

and wherePivot

I've now made a PR for this feature, called Add dynamic "where(Any|All|None)*" clauses to the query builder

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.

4 participants