/** * Fix a primary column on a table, making sure that each source only has * one primary set. * * @param AIR2_Record $rec * @param boolean $delete */ function air2_fix_src_primary($rec, $delete = false) { $conn = AIR2_DBManager::get_master_connection(); $tbl = $rec->getTable()->getTableName(); // find column names $idcol = false; $fkcol = false; $flagcol = false; $updcol = false; $cols = $rec->getTable()->getColumnNames(); foreach ($cols as $col) { if (preg_match('/^[a-z]+_id$/', $col)) { $idcol = $col; } elseif (preg_match('/^[a-z]+_src_id$/', $col)) { $fkcol = $col; } elseif (preg_match('/_primary_flag$/', $col) || preg_match('/_home_flag$/', $col)) { $flagcol = $col; } elseif (preg_match('/_upd_dtim$/', $col)) { $updcol = $col; } } // sanity! if (!$idcol || !$fkcol || !$flagcol || !$updcol) { throw new Exception("Missing a column"); } // saved? or deleted? if (!$delete) { if ($rec[$flagcol]) { // unset everyone else $q = "update {$tbl} set {$flagcol}=0 where {$fkcol}=? and {$idcol}!=?"; $conn->exec($q, array($rec[$fkcol], $rec[$idcol])); } else { // check for existing primary $q = "select {$idcol}, {$flagcol} from {$tbl} where {$fkcol} = ?"; $rs = $conn->fetchAll($q, array($rec[$fkcol])); $has_primary = false; foreach ($rs as $row) { if ($row[$flagcol]) { $has_primary = true; } } // should I or someone else be primary? if (!$has_primary && count($rs) == 1) { // it's me! $q = "update {$tbl} set {$flagcol}=1 where {$fkcol}=? and {$idcol}=?"; $conn->exec($q, array($rec[$fkcol], $rec[$idcol])); //TODO: better solution? Can't figure out why refresh fails if ($rec->exists()) { try { $rec->refresh(); } catch (Doctrine_Record_Exception $e) { if ($e->getCode() == 0 && preg_match('/does not exist/i', $e->getMessage())) { // ignore, I guess } else { throw $e; //rethrow } } } } elseif (!$has_primary && count($rs) > 1) { // pick most recent that isn't me $q = "update {$tbl} set {$flagcol}=1 where {$fkcol}=? and {$idcol}!=?"; // find upd_dtim column $data = $rec->toArray(); foreach ($data as $key => $val) { if (preg_match('/upd_dtim$/', $key)) { $q .= " order by {$key} desc"; } } $conn->exec("{$q} limit 1", array($rec[$fkcol], $rec[$idcol])); } } } else { //deleted - pick most recent $q = "update {$tbl} set {$flagcol}=1 where {$fkcol}=? and {$idcol}!=?"; // find upd_dtim column $data = $rec->toArray(); foreach ($data as $key => $val) { if (preg_match('/upd_dtim$/', $key)) { $q .= " order by {$key} desc"; } } $conn->exec("{$q} limit 1", array($rec[$fkcol], $rec[$idcol])); } }