Quantcast
Channel: Recent Discussions — DataTables forums
Viewing all articles
Browse latest Browse all 82034

Bug: Editor ignores WHERE-clause in LEFTJOIN Update

$
0
0

I am using this statement to SELECT and UPDATE contract approvals. While the statement selects data from multiple tables it only updates one table called contract_has_rfa. The two key tables are contract and contract_has_rfa. There can be multiple rfa's for one contract, but only one for a contract and one user (unique index on contract_has_rfa.contract_id and contract_has_rfa.approver_id). The link to the contract table is through contract.id as a foreign key (contract_has_rfa.contract_id.
Contract_has_rfa is also linked to the user table with user.id which is contract_has_rfa.approver_id in contract_has_rfa.

The statement selects all contracts that are assigned to the respective user ($_SESSION['id']) for approval. This works fine. Only the assigned contracts are selected not all of them. When making the update (setting contract_has_rfa.status to 'W', 'N' or 'A') there is a bug: The UPDATE statement does NOT contain the approver_id in its WHERE clause. It only has the respective contract.id in its WHERE clause. Hence all rfa's get updated for the respective contract - even those assigned to a different user!
The bug is that the UPDATE statement generated by Editor ignores this WHERE clause in my PHP statement below:

 ->where( 'contract_has_rfa.approver_id', $_SESSION['id'] )

while the SELECT statement uses it. I used the debug option to check the UPDATE statement generated by Editor to verify this.

Is there a fix for this bug? I would like to avoid a work around if possible.

<?php

Editor::inst( $db, 'contract' )
->field(
    Field::inst( 'gov.name' )->set( false ),
    Field::inst( 'govdept.name' )->set( false ),
    Field::inst( 'creditor.name' )->set( false ),
    Field::inst( 'contract.id' )->set( false ),
    Field::inst( 'contract.description' )->set( false ),
    Field::inst( 'contract_has_rfa.status' )
        ->setFormatter( function ( $val, $data, $opts ) {
            if ($val === 'W' &&  $data['contractStatusAlias'] === 'N') {
                $val = 'N';
            }
            return $val;
        } ),        
    Field::inst( 'contract_has_rfa.status AS contractStatusAlias' )->set( false ),
    Field::inst( 'contract_has_rfa.update_time' )->set(Field::SET_BOTH)
                                                 ->setValue( date("Y-m-d H:i:s") ),
    Field::inst( 'contract_has_rfa.updater_id' )->set(Field::SET_BOTH)
                                                ->setValue( $_SESSION['id'] )
)
// show approvals if any                   
->join(
Mjoin::inst( 'user' )
    ->link( 'contract.id', 'contract_has_rfa.contract_id')
    ->link( 'user.id', 'contract_has_rfa.approver_id' )
    ->order( 'contract_has_rfa.status DESC, user.lastname ASC' )
    ->fields(
        Field::inst( 'user.firstname AS userFirstName' )->set( false ),
        Field::inst( 'user.lastname AS userLastName' )->set( false ),
        Field::inst( 'contract_has_rfa.status AS approvalStatus' )->set( false ),
        Field::inst( 'contract_has_rfa.update_time AS updateTime' )->set( false )
            ->getFormatter( function ( $val, $data, $opts ) {
                return getFormatterDateTime($val);                 
            } )
    )
)
->join(
Mjoin::inst( 'file' )
    ->link( 'contract.id', 'contract_has_file.contract_id' )
    ->link( 'file.id', 'contract_has_file.file_id' )
    ->fields(
        Field::inst( 'web_path' )->set( false ),
        Field::inst( 'name' )->set( false )               
    )
)
->leftJoin( 'govdept', 'contract.govdept_id', '=', 'govdept.id')
->leftJoin( 'gov', 'govdept.gov_id', '=', 'gov.id')
->leftJoin( 'creditor', 'contract.creditor_id', '=', 'creditor.id')
->leftJoin( 'contract_has_rfa', 'contract.id', '=', 'contract_has_rfa.contract_id')
->leftJoin( 'user', 'contract_has_rfa.approver_id', '=', 'user.id')
->where( 'contract_has_rfa.approver_id', $_SESSION['id'] )
->debug(true)
->process($_POST)            
->json();

This is the SQL for the UPDATE generated by Editor:

bindings: [{name: ":status", value: "A", type: null},…]
0:{name: ":status", value: "A", type: null}
name:":status"
type:null
value:"A"
1:{name: ":update_time", value: "2017-05-07 16:16:59", type: null}
name:":update_time"
type:null
value:"2017-05-07 16:16:59"
2:{name: ":updater_id", value: "37", type: null}
name:":updater_id"
type:null
value:"37"
3:{name: ":where_0", value: "25", type: null}
name:":where_0"
type:null
value:"25"
query:"UPDATE  `contract_has_rfa` 
SET  `status` = :status, `update_time` = :update_time, `updater_id` = :updater_id 
WHERE `contract_id` = :where_0 "

And this is the result in the table contract_has_rfa:

CONTRACT_HAS_RFA after update:
-
id  contract_id approver_id who status  update_time          updater_id creator_id
1       25          37        G   A      07.05.2017 16:16      37               6
2       25          12        G   A      07.05.2017 16:16      37               6

As you can see both rows where updated while only the first row should have been updated.


Viewing all articles
Browse latest Browse all 82034

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>