-
Notifications
You must be signed in to change notification settings - Fork 17
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
flatten bindings for Telescope #78
flatten bindings for Telescope #78
Conversation
Is this change necessary still or was it resolved on the other side? |
Still need this in order to work with Telescope |
This exception is also something we encountered in our projects. In our case the structure of the bindings caused the new Laravel exception page to fail rendering with an 'array to string conversion' error. |
Can you give me some information for how to reproduce this? I've thrown exceptions in queries from things like fields missing and it all displays properly. I'm testing on Laravel 11.21.0 Also, it looks like the other PR was merged in which seemed like the goal was to handle the structure here. |
Aaaahh. I see now. Exception problem is only an issue if Telescope is installed, not in general. I've reproduced this now. |
It looks like this issue may be something that needs to be fixed in telescope. The bindings property is supposed to be an array, not a string. It seems like changing this would result in improperly typing this parameter.
https://laravel.com/api/11.x/Illuminate/Database/Events/QueryExecuted.html |
Correct. This PR is still passing an array to Telescope loops over that |
This is due to the syntax for FM find requests compared to other database engines: FM expects an object for each field: {
"query":[
{"Group": "=Surgeon"},
{"Work State" : "NY", "omit" : "true"}
]
} where other database engines would use a key/value pair for each field: // pseudo-code
{
"query":[
"Group": "Surgeon",
"Work State" : "NY"
]
} …and it occurs to me that we probably should keep |
The reason these are objects is because they're separate find requests, so just flattening them down into the same object destroys the "or" logic of multiple finds. I think some additional structure changes might be needed to support that as well. |
So we could flatten that example to this: [
"Group: =Surgeon",
"Work State: NY, omit: true",
] Would that work? or do you have a more detailed example of multiple |
Omit is definitely an issue, since the omit is for the entire find request, and not the individual binding. The following binding definitely isn't correct to reflect the search query:
In this case, it's omitting results which match the Work State AND group. Where are these bindings viewed, though? I see the "query" which still shows the actual FileMaker Data API query correctly. Clockwork shows it correctly as well and does not show the bindings. Maybe flattening doesn't matter? I wouldn't want to break the correct FM Query which shows up in the log, but I don't think changing this affects that either here or in Clockwork. |
Another thing to consider: Flattening this would cause multiple queries which search on the same field to overwrite the binding values of previous searches. The actual "SQL" query part being logged seems like it would still show the correct info, but the binding information would all be wrong. |
One thing that could help with not overwriting the bindings is to prefix each binding key with the index, so that the original queries could potentially be rebuilt. Ex:
Or something along those lines. |
@macbookandrew can you make a change to identify the request number as part of the flattening? That'll keep the bindings making sense, though they don't really apply to FM requests in the same way. |
Given this query: TimeEntry::query()
->where('date', '>=', now()->subWeek()->format('m/d/Y'))
->where('contact_id_worker', User::first()->filemaker_contact_id)
->orWhere('contact_id_worker', User::find(13)->filemaker_contact_id)
->whereNot('contact_id_worker', User::find(12)->filemaker_contact_id)
->limit(10)
->orderByDesc('id')
->get(); Here is the query logged in Telescope, using the changes on this branch: |
That part you're looking at is actually the "sql string" part of the event (which we just use to show API query info), not the bindings, which is why it still shows properly. I don't actually see the bindings appearing anywhere in the UI, interestingly. |
Huh…interesting. How do these changes show up in an app with Clockwork? Here’s why it fails with Telescope’s So even though Telescope is displaying the SQL string, it’s still parsing the bindings. |
I didn't see the bindings in Clockwork either. It's just the sql query string that shows as well. |
In that case, do you want me to change anything here? |
I think having the bindings still make sense would be good, so indicating which request they're from would prevent the data loss, even though it doesn't seem that important right now in our initial testing. Can you make the change to show the request index in each binding as mentioned above? |
Sure. Would you prefer this? [
"0: Date: >=08/30/2024, _kf_ContactIDWorker: 31195",
"1: _kf_ContactIDWorker: 17159",
"2: omit: true, _kf_ContactIDWorker: 10956"
] or this? [
"0: Date: >=08/30/2024",
"0: _kf_ContactIDWorker: 31195",
"1: _kf_ContactIDWorker: 17159",
"2: omit: true",
"2: _kf_ContactIDWorker: 10956",
] |
I think the array is supposed to be key-value pairs, not just an array of strings, but the second option is closer |
Here’s a similar MySQL query with bindings: "select * from `time_logs` where `spent_on` >= ? and `user_id` = ? or `user_id` = ? and not `user_id` = ? order by `id` desc limit 10"
[
0 => '2024-08-30',
1 => 1,
2 => 13,
3 => 12,
] And here’s the SQL and bindings produced by 5b79bb7: "select
Method: post
URL: https://myfilemakerdatabase.example.com/fmi/data/vLatest/databases/DatabaseName/layouts/TimeEntry/_find
Data: {
"query": [
{
"Date": ">=08\/30\/2024",
"_kf_ContactIDWorker": "31195"
},
{
"_kf_ContactIDWorker": "17159"
},
{
"omit": "true",
"_kf_ContactIDWorker": "10956"
}
],
"sort": [
{
"fieldName": "__kp_TimeEntryID",
"sortOrder": "descend"
}
],
"limit": 10
}"
[
0 => "0: Date: >=08/30/2024",
1 => "0: _kf_ContactIDWorker: 31195",
2 => "1: _kf_ContactIDWorker: 17159",
3 => "2: omit: true",
4 => "2: _kf_ContactIDWorker: 10956",
] |
I think it can go either way, depending on how your bindings are done: https://www.php.net/manual/en/pdostatement.bindvalue.php If you use '?' for your bindings it's just sequential in an array. If you use named bindings then you use key-value pairs. I think the "named bindings" methodology makes more sense for FM stuff since we do need to map to fields, and it would be easier for us to separate the field names and values for the purposes of rebuilding the queries from the bindings. it also makes reading all of that easier and is closer to the actual query being made. |
Makes sense. Updated results for 80fd004: [
"0: Date" => ">=08/30/2024",
"0: _kf_ContactIDWorker" => "31195",
"1: _kf_ContactIDWorker" => "17159",
"2: omit" => "true",
"2: _kf_ContactIDWorker" => "10956",
] |
released as 2.4.4 |
Awesome; thanks! |
Once laravel/telescope#1499 is merged, this will cause an error due to the deeper array syntax that FM queries use.
Before, the bindings result in this shape:
After: