/**
  * Attempts to move a tank_source into its source-record tables.
  *
  * @param TankSource $tsrc
  * @param Source  $src
  * @param array   $ops
  */
 protected function move_tank_source($tsrc, $src, $ops)
 {
     // start a transaction and track any conflicts
     $this->conn->beginTransaction();
     // move all related data out of the tank_source
     foreach (TankSource::$COLS as $name => $def) {
         $data = $tsrc->get_tank_data($name);
         if ($name == 'Source') {
             $op = isset($ops['Source']) ? $ops['Source'] : null;
             $this->resolve_conflicts($src, $data, $tsrc, $op);
         } else {
             $rec = new $name();
             // set the FK before resolving
             $col = $rec->getTable()->getRelation('Source')->getLocal();
             $rec->{$col} = $src->src_id;
             $op = isset($ops[$name]) ? $ops[$name] : null;
             $this->resolve_conflicts($rec, $data, $tsrc, $op);
             // cleanup
             $rec->free();
         }
     }
     // move tank_facts to src_facts
     $q = Doctrine_Query::create()->from('TankFact tf');
     $q->where('tf.tf_tsrc_id = ?', $tsrc->tsrc_id);
     $tfacts = $q->fetchArray();
     $q->free();
     foreach ($tfacts as $idx => $tf) {
         $new_fact = new SrcFact();
         $new_fact->sf_src_id = $src->src_id;
         $new_fact->sf_fact_id = $tf['tf_fact_id'];
         $f = 'Fact.' . $tf['tf_fact_id'];
         $op = isset($ops[$f]) ? $ops[$f] : null;
         foreach ($tf as $key => $val) {
             if (substr($key, 0, 2) != 'sf') {
                 unset($tf[$key]);
             }
         }
         $this->resolve_conflicts($new_fact, $tf, $tsrc, $op);
         $new_fact->free();
     }
     // move tank_vita to src_vita
     $q = Doctrine_Query::create()->from('TankVita tv');
     $q->where('tv.tv_tsrc_id = ?', $tsrc->tsrc_id);
     $tvita = $q->fetchArray();
     $q->free();
     foreach ($tvita as $idx => $tv) {
         $new_vita = new SrcVita();
         $new_vita->sv_src_id = $src->src_id;
         // unset non-"sv" keys
         foreach ($tv as $key => $val) {
             if (substr($key, 0, 2) != 'sv') {
                 unset($tv[$key]);
             }
         }
         // no ops allowed on vita (yet)
         $this->resolve_conflicts($new_vita, $tv, $tsrc);
         $new_vita->free();
     }
     // move any tank_response_sets for the tank_source
     $q = Doctrine_Query::create()->from('TankResponseSet trs');
     $q->leftJoin('trs.TankResponse tr');
     $q->where('trs.trs_tsrc_id = ?', $tsrc->tsrc_id);
     $trsets = $q->fetchArray();
     $q->free();
     foreach ($trsets as $trs) {
         $this->move_tank_response_set($trs, $src->src_id, $tsrc);
     }
     // process any tags on the source
     if ($tsrc->tsrc_tags || strlen($tsrc->tsrc_tags)) {
         $tags = $tsrc->tsrc_tags;
         $tags = explode(',', $tags);
         foreach ($tags as $tag) {
             Tag::make_tag($src->src_id, Tag::$TYPE_SOURCE, trim($tag));
         }
     }
     // commit or rollback based on any conflicts
     if ($tsrc->tsrc_status == TankSource::$STATUS_ERROR || $tsrc->tsrc_status == TankSource::$STATUS_CONFLICT) {
         $this->conn->rollback();
     } else {
         $this->conn->commit();
         $tsrc->tsrc_status = TankSource::$STATUS_DONE;
         $tsrc->tsrc_errors = null;
         //delete any errors/conflicts
     }
 }