Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

valentin_vranic's avatar

Problem with dynamically generated classes

Well, it's pretty heavy to show everything, but I'll try to make it clear. So I'm getting/filtering data like this:

public function filterDetails(): array
{
    $cdrInstance = new CdrArchiveDinamyc(Carbon::parse($this->fromDate)->format('Y-m-d'));
    .
    . here is the filtering logic
    .
    return [
        ...$builtQuery->selectRaw(
            'COUNT(*) AS `today_number_of_calls`, SUM(`call_cost`) AS `today_call_cost`'
        )->first()->toArray(),
        'items' => $summaryQuery->select('*')->get(),
    ];
}

Here with CdrArchiveDinamyc I'm determining which table and which connection to be used. If the date is today:

$this->table = 'cdr';
$this->connection = 'mysql_cdr';

If some other from the past then: $this->table = 'cdr_'.$archiveDate;

After I'm able to list the results, each into separate livewire component:

@foreach($this->filterDetails['items'] as $item)
@php($wasMachine = $item->billsec > 0 && $item->amd)
      <livewire:calls.call-details-row :$item :$wasMachine :key="$item->id"/>
@endforeach

And inside of the row view I'm trying to click like wire:click="setShowCdrDetails" and then I'm getting the error like:

SQLSTATE[HY000] [2002] No such file or directory
select * from `cdr` where `cdr`.`id` = 16037107846 limit 1

Which is silly, because the cdr does exists, and I see in debugbar that the connection is properly set.

Any ideas would be great!

Thanks, Vale

0 likes
8 replies
LaryAI's avatar
Level 58

It looks like the issue you're encountering is related to the dynamic determination of the table and connection in your CdrArchiveDinamyc class. The error SQLSTATE[HY000] [2002] No such file or directory suggests that there might be a problem with the database connection configuration or the way the connection is being set dynamically.

Here are a few steps to troubleshoot and potentially resolve the issue:

  1. Check Database Configuration: Ensure that the database connections are correctly configured in your config/database.php file. Specifically, check the mysql_cdr connection settings.

  2. Verify Dynamic Connection and Table Logic: Make sure that the logic for setting the table and connection in the CdrArchiveDinamyc class is correct and that it properly handles different dates.

  3. Ensure Livewire Component Uses Correct Connection: When you click on the Livewire component, ensure that the component is using the correct connection and table. You might need to pass the connection and table information to the Livewire component.

  4. Debugging: Add some debugging statements to verify that the correct connection and table are being used at each step.

Here is a refined version of your code with some additional debugging and improvements:

Key Points:

  1. Dynamic Connection and Table Setting: Ensure that the connection and table are set dynamically based on the date.
  2. Debugging: Add logging to verify that the correct connection and table are being used.
  3. Livewire Component: Ensure that the Livewire component uses the correct connection and table when fetching details.

By following these steps, you should be able to identify and resolve the issue with dynamically generated classes and database connections.

jaseofspades88's avatar

Why have two separate cdr tables when you could simply group and filter based on dates? I assume the schema is the same for all cdr tables?

valentin_vranic's avatar
valentin_vranic
OP
Best Answer
Level 5

Okay, I managed to solve it. My solution was, to pass the $date and $id to the component and make a #[Computed] property for the item() and call it like that.

Well the #[Computed] stuff most of the time solves my problem when dealing with complex data structures.

However in this case to get each item one-by-one I'm not sure is a good approach either, and it becomes too heavy after a while.

Chingy's avatar

@valentin_vranic If it's the same data all the time, Computed provides a persist param to persist the data in the cache along with ttl seconds.

Told you Computed is awesome :D

1 like
Tray2's avatar

@valentin_vranic Good that you have solved it, however I would suggest a few approaches I would use before splitting a single table into two.

One is to create a database view that covers the current day, and another that has the historical data.

The other is to use partitioned tables, where you can create a partition for each day if needed.

Here is an examples how I create a view to ease the complexity of my queries.

https://tray2.se/posts/use-a-view-instead-of-a-complex-eloquent-query-in-your-laravel-application

Here are some examples about partitioning.

https://www.devart.com/dbforge/mysql/studio/partition-mysql.html

A third option would be as you do, split a table into two one current and one history, then create a view that unions them both so that you can get just today from the table and everything from the view.

However, you are talking several millions of records, to the database that is nothing, with the proper indexes it runs fast enough without any splitting of tables.

According to Google, in InnoDB, with a limit on table size of 64 terabytes and a MySQL row-size limit of 65,535 there can be 1,073,741,824 rows. That would be the maximum number of records, each utilizing the maximum row-size limit. However, more records can be added if the row size is smaller.

1 like
valentin_vranic's avatar

@Tray2 thanks, very good blog posts, and good notes to reconsider some things. Well, currently I'm rewriting a legacy codebase to Laravel/Livewire and to reorganize the DB like that certainly could take place in our TODO list in the future. But currently we'll stick to this type of "logging"

Please or to participate in this conversation.