How to override the Laravel Illuminate Database Connection.php run method?

Asked

Viewed 67 times

1

I need to customize the callback function call in the run() method of the Connection.php class, located in the frameword Laravel src Illuminate Database Connection.php

The problem is that it is in the project vendor folder, which means it is not the best place to make the change.

Could someone shed some light on how I can do that? The project contains several classes and numerous query operations scattered within the project. And since we now need to change the calls to API, the best place to change is in this method [run()]. The commented line

// $result = $this->runQueryCallback($query, $bindings, $callback);

contains the original package call. My change is for the API calling function, which already returns the data similarly to "runQueryCallbck"

$result = execSqlApiFirebird($query);

Here is the complete method:

/**
 * Run a SQL statement and log its execution context.
 *
 * @param  string  $query
 * @param  array  $bindings
 * @param  \Closure  $callback
 * @return mixed
 *
 * @throws \Illuminate\Database\QueryException
 */
protected function run($query, $bindings, Closure $callback)
{
    $this->reconnectIfMissingConnection();

    $start = microtime(true);

    // Here we will run this query. If an exception occurs we'll determine if it was
    // caused by a connection that has been lost. If that is the cause, we'll try
    // to re-establish connection and re-run the query with a fresh connection.
    try {
        $query = str_replace(array('?'), array('\'%s\''), $query);
        $query = vsprintf($query, $bindings);
        // dump($query);
        // $result = $this->runQueryCallback($query, $bindings, $callback);
        $result = execSqlApiFirebird($query);
        // dd($result);
    } catch (QueryException $e) {
        $result = $this->handleQueryException(
            $e, $query, $bindings, $callback
        );
    }

    // Once we have run the query we will calculate the time that it took to run and
    // then log the query, bindings, and execution time so we will report them on
    // the event that the developer needs them. We'll log time in milliseconds.
    $this->logQuery(
        $query, $bindings, $this->getElapsedTime($start)
    );
    // dump($result);
    return $result;
}
  • Well if there is logic that you need to do, it is with inheritance usually the packages do this kind of approach and in the class that inherits rewrite the methods or even create new ones, but, I wanted to know the following, because it is wanting to do this?

  • Considering the size of the project, you’d have to redo a lot of consultation. I imagine I should be able to rewrite the run() method of this class in a way that is not a huge gambit. The goal would be to intercept all queries in SQL and send to API and configure the return as the function already does. I don’t know how to do this, I’ve been in trouble for days... Maybe, I don’t know, but I’m wasting my time trying to shorten the work of redoing everything... what do you think? Do you know any way to change behavior without being a snitch?

  • https://answall.com/questions/148766/como-ver-as-queries-que-foram-executadas-pelo-eloquent-em-laravel take a look at this!

  • I tried to see if I could do something, but the more technical mechanics of the Laravel is very complex for me... The idea of using middleware is sensational, but I have no idea how to manipulate the connection even

  • the tricky thing is to know what exactly you want to do, your question opens many points.

  • In the API I send the entire sql to be executed, so that the project may have been built in Firebird, mysql, postgresql, etc... With this, it will no longer be necessary to configure database on the system. Just send request to api, which returns the data. For this to work, I need to modify the run() function, which instead of running "$result = $this->runQueryCallback($query, $bindings, $callback);", runs "$result = execSqlApiFirebird($query);". But this change is being made in the wrong place...

  • I don’t know if I could explain it right, but basically this is: intercept the final stage of the query, with sql mounted on the run point in the database, but run the call in the API... I couldn’t find an answer, so in the meantime, I’m changing the calls on the controllers... I’m doing it the painful way...

  • Do you want to send only SQL? in the result of your API?

  • this, for example: DB::table("products")->get() === "select * from products" then will mount until you get to the run() function and send this sql to api, which will bring the data in the same way it would normally. The API is ready. This modification in the run() method that is breaking my legs

  • is known to have toSql()? example User::where('id', 1)->toSql()?

  • Yeah, that would be the way I started to do it... the slow way... There are many calls to do this, not to mention that if you do: User::Where(xxx, xxx)->Count(), we do not have toSql(), which means more demand... You think I’m doing the right thing? Redo all calls, doing: execSqlApiFirebird(User::Where('id', 1)->toSql())... That is, modify practically this in some 50 thousand lines

  • Sincerity do not know if you are right and also I do not know why you only need SQL? because you need?

  • the api gets the full sql... Projects, in some cases, are made available on the Client side, with obfuscated source code. It turns out that in some cases, the PDO >> Firebird connection is impossible... Then, after scanning the internet for solution, they decided to do via API; solution implemented at the same time. Delphi libraries are apparently more active and less buggy than some Firebird libraries. Now we have the solution... But I wanted a less laborious way to go over everything in the projects...

  • Basically, we create a database interface, where we can configure any database through this API. If we were to work in the traditional way (not take the server in the client), it would not be necessary all this.

Show 9 more comments

1 answer

0


I decided to build endpoint in API and linking directly to Controller the calls. There I build the objects and forgetfulness the Eloquent (It would be interesting to implement this modification, because the MVC would be intact throughout the project).
But in a company that seeks results, less is more. I ended up doing it the way I know rather than continuing to look for other ways.
Who knows in the near future I solve it right? = D
For now, it is better to deliver quick result and keep the job. rsrs

Browser other questions tagged

You are not signed in. Login or sign up in order to post.