vitnasinec's avatar

Locale aware SQLite orderBy

another question somewhat related to my previous question https://laracasts.com/discuss/channels/laravel/locale-aware-collection-sorting

When using SQLite db how do I make Eloquent ->orderBy() sort these czech characters correctly like this?

['a', 'á', 'c', 'č', 'd', 'ď', 'e', 'é', 'ě', 'i', 'í', 'n', 'ň', 'o', 'ó', 'r', 'ř', 's', 'š', 't', 'ť', 'u', 'ú', 'ů', 'z', 'ž'];

Thanks

0 likes
1 reply
LaryAI's avatar
Level 58

SQLite, by default, does not support locale-specific collations directly in the way some other database systems like PostgreSQL do. However, you can work around this limitation by using a custom collation function if you are interfacing with SQLite through a programming language that supports it, such as Python. Unfortunately, this is not directly supported in PHP or through Laravel's Eloquent ORM when using SQLite.

For a pure Laravel solution, you might need to handle the sorting at the application level rather than the database level. Here's how you can achieve locale-aware sorting in your collection after retrieving the data from the database:

  1. Retrieve the data from the database.
  2. Use PHP's usort function with strcoll which compares strings based on the current locale.

First, ensure your locale is set correctly in your PHP script (this example sets it to Czech):

setlocale(LC_COLLATE, 'cs_CZ.utf8');

Then, you can retrieve your models and sort them in PHP:

use App\Models\YourModel;

$items = YourModel::all();

// Sort using a custom function and strcoll for locale-aware comparison
$sortedItems = $items->sort(function ($a, $b) {
    return strcoll($a->your_column, $b->your_column);
});

// Now $sortedItems is sorted according to Czech locale

This approach performs the sorting in PHP rather than in SQLite, which is a limitation but a necessary workaround due to the lack of direct support for locale-specific collations in SQLite through Laravel.

If performance becomes an issue due to PHP-side sorting (especially with large datasets), you might consider either switching to a database that supports locale-specific collations natively or reducing the dataset size before sorting in PHP.

Please or to participate in this conversation.