Example #1
0
 /**
  * Runs a lighter but convenient update operation that's faster than the using row objects
  *
  * @TODO this should be a patch on nooku fw for when you're saving rowsets
  *
  * @author Stian Didriksen <*****@*****.**>
  * @param  KDatabaseRowsetInterface | array
  * @param  KDatabaseTableInterface
  * @return status
  */
 public function update($rows, KDatabaseTableAbstract $table, $dbprefix = false)
 {
     if (!$dbprefix) {
         $dbprefix = KFactory::get('lib.joomla.config')->getValue('dbprefix');
     }
     $mysqli = KFactory::get('lib.koowa.database.adapter.mysqli')->getConnection();
     $statement = false;
     $base = $table->getDatabase()->quoteName($dbprefix . $table->getBase());
     $columns = $table->getColumns(true);
     $primaries = $table->getPrimaryKey();
     foreach ($rows as $id => $row) {
         //@TODO Do not import rows that are without ids, they can cause duplicate key errors
         //if(!isset($row['id'])) continue;
         //Reverse map first
         $row = $table->mapColumns($row, true);
         //Add missing columns for the sake of the prepared statement query
         foreach ($columns as $field => $column) {
             if (!isset($row[$field])) {
                 $row[$field] = $column->default !== NULL ? $column->default : '';
             }
         }
         //Filter out any extra columns.
         $data = array_intersect_key($row, $columns);
         //Get the primaries
         $where = array_intersect_key($row, $primaries);
         //Set the id back, to allow changing the primary key as used in the smf_users converter on the people table
         if (isset($where['id'])) {
             $where['id'] = (int) $id;
         }
         $where = $table->mapColumns($where);
         //Get the data and apply the column mappings
         $data = $table->mapColumns($data);
         //The key order is vital!
         ksort($data);
         ksort($where);
         //try {
         //Create the prepared statements that the other (likely 500 rows) will reuse
         if (!$statement) {
             foreach ($data as $key => $val) {
                 $vals[] = $key . '=?';
             }
             foreach ($where as $key => $val) {
                 $keys[] = $key . ' = ?';
             }
             $query = 'UPDATE ' . $base . ' SET ' . implode(', ', $vals) . ' WHERE ' . implode(' AND ', $keys);
             $statement = $mysqli->prepare($query) or die('failed to prepare query statement: ' . $query);
             //if($base == $table->getDatabase()->quoteName($dbprefix.'ninjaboard_people')) echo $query, "\n";
         }
         $params = array('');
         foreach ($data as $key => $val) {
             $params[0] .= false !== filter_var($val, FILTER_VALIDATE_INT) ? 'i' : 's';
             $params[] = is_array($val) ? json_encode($val) : $val;
         }
         foreach ($where as $key => $val) {
             $params[0] .= false !== filter_var($val, FILTER_VALIDATE_INT) ? 'i' : 's';
             $params[] = is_array($val) ? json_encode($val) : $val;
         }
         //if($base == $table->getDatabase()->quoteName($dbprefix.'ninjaboard_people')) echo implode($params, ', '), "\n";
         //Bind the params to the prepared statement in a dynamic fashion
         call_user_func_array(array($statement, 'bind_param'), $this->refValues($params));
         //Execute the prepared statement, it's super fast!
         //@TODO throw exception here
         if (!$statement->execute()) {
             echo $statement->error, "\n", 'with the bindings: ' . implode(', ', $params), "\n", 'and the following query:', $query, "\n";
         }
         /*
         			} catch(KDatabaseException $e) {
         			    // The following is for a query used should we get a duplicate key error
         			    $query = $table->getDatabase()->getQuery();
         			    foreach($table->getPrimaryKey() as $key => $column) {
         			        $query->where($column->name, '=', $table->filter(array($key => $row[$key]), true));
         			    }
         			
         				$table->getDatabase()->update($table->getBase(), KConfig::toData($data), $query);
         			}
         			//*/
     }
     //printf("%d Row inserted.\n", $statement->affected_rows);
     /* */
     if ($statement) {
         $statement->close();
     }
 }