/**
  * Generate and write the database manipulation for all changed fields
  *
  * @param string $baseTable Base table
  * @param string $now Timestamp to use for the current time
  * @param bool $isNewRecord If this is a new record
  */
 protected function writeManipulation($baseTable, $now, $isNewRecord)
 {
     // Generate database manipulations for each class
     $manipulation = array();
     foreach (ClassInfo::ancestry(static::class, true) as $class) {
         $this->prepareManipulationTable($baseTable, $now, $isNewRecord, $manipulation, $class);
     }
     // Allow extensions to extend this manipulation
     $this->extend('augmentWrite', $manipulation);
     // New records have their insert into the base data table done first, so that they can pass the
     // generated ID on to the rest of the manipulation
     if ($isNewRecord) {
         $manipulation[$baseTable]['command'] = 'update';
     }
     // Perform the manipulation
     DB::manipulate($manipulation);
 }
 protected function overrideField($obj, $fieldName, $value, $fixtures = null)
 {
     $class = get_class($obj);
     $table = DataObject::getSchema()->tableForField($class, $fieldName);
     $value = $this->parseValue($value, $fixtures);
     DB::manipulate(array($table => array("command" => "update", "id" => $obj->ID, "class" => $class, "fields" => array($fieldName => $value))));
     $obj->{$fieldName} = $value;
 }
 /**
  * Add an item to this many_many relationship
  * Does so by adding an entry to the joinTable.
  *
  * @param mixed $item
  * @param array $extraFields A map of additional columns to insert into the joinTable.
  * Column names should be ANSI quoted.
  * @throws Exception
  */
 public function add($item, $extraFields = array())
 {
     // Ensure nulls or empty strings are correctly treated as empty arrays
     if (empty($extraFields)) {
         $extraFields = array();
     }
     // Determine ID of new record
     if (is_numeric($item)) {
         $itemID = $item;
     } elseif ($item instanceof $this->dataClass) {
         $itemID = $item->ID;
     } else {
         throw new InvalidArgumentException("ManyManyList::add() expecting a {$this->dataClass} object, or ID value", E_USER_ERROR);
     }
     // Validate foreignID
     $foreignIDs = $this->getForeignID();
     if (empty($foreignIDs)) {
         throw new Exception("ManyManyList::add() can't be called until a foreign ID is set", E_USER_WARNING);
     }
     // Apply this item to each given foreign ID record
     if (!is_array($foreignIDs)) {
         $foreignIDs = array($foreignIDs);
     }
     foreach ($foreignIDs as $foreignID) {
         // Check for existing records for this item
         if ($foreignFilter = $this->foreignIDWriteFilter($foreignID)) {
             // With the current query, simply add the foreign and local conditions
             // The query can be a bit odd, especially if custom relation classes
             // don't join expected tables (@see Member_GroupSet for example).
             $query = new SQLSelect("*", "\"{$this->joinTable}\"");
             $query->addWhere($foreignFilter);
             $query->addWhere(array("\"{$this->joinTable}\".\"{$this->localKey}\"" => $itemID));
             $hasExisting = $query->count() > 0;
         } else {
             $hasExisting = false;
         }
         // Blank manipulation
         $manipulation = array($this->joinTable => array('command' => $hasExisting ? 'update' : 'insert', 'fields' => array()));
         if ($hasExisting) {
             $manipulation[$this->joinTable]['where'] = array("\"{$this->joinTable}\".\"{$this->foreignKey}\"" => $foreignID, "\"{$this->joinTable}\".\"{$this->localKey}\"" => $itemID);
         }
         if ($extraFields && $this->extraFields) {
             // Write extra field to manipluation in the same way
             // that DataObject::prepareManipulationTable writes fields
             foreach ($this->extraFields as $fieldName => $fieldSpec) {
                 // Skip fields without an assignment
                 if (array_key_exists($fieldName, $extraFields)) {
                     $fieldObject = Object::create_from_string($fieldSpec, $fieldName);
                     $fieldObject->setValue($extraFields[$fieldName]);
                     $fieldObject->writeToManipulation($manipulation[$this->joinTable]);
                 }
             }
         }
         $manipulation[$this->joinTable]['fields'][$this->localKey] = $itemID;
         $manipulation[$this->joinTable]['fields'][$this->foreignKey] = $foreignID;
         DB::manipulate($manipulation);
     }
 }