Rollback all inserts when the import throws an error halfway
@param Garp_Model $model
@param Array $primaryKeys Collection of primary keys
@return Void
6936
public function rollback(Garp_Model $model, array $primaryKeys) {
        if (empty($primaryKeys)) {
            return;
        }
        $primaryCols = (array)$model->info(Zend_Db_Table::PRIMARY);
        $where = array();
        foreach ($primaryKeys as $pk) {
            $recordWhere = array();
            foreach ((array)$pk as $i => $key) {
                $recordWhere[] = $model->getAdapter()->quoteIdentifier(current($primaryCols)).' = '.
                                 $model->getAdapter()->quote($key);
            }
            $recordWhere = implode(' AND ', $recordWhere);
            $recordWhere = '('.$recordWhere.')';
            $where[] = $recordWhere;
            reset($primaryCols);
        }
        $where = implode(' OR ', $where);
        if (empty($where)) {
            return;
        }
        $model->delete($where);
    }
931450
protected function relations($model, $foreignKeyIds)
    {
        $relations = $model->getSoftCascade();

        if (empty($relations)) {
            return;
        }

        foreach ($relations as $relation) {
            extract($this->relationResolver($relation));
            $this->validateRelation($model, $relation);

            $modelRelation = $model->$relation();

            /**
             * Maintains compatibility fot get foreign key name on laravel old and new methods.
             *
             * @link https://github.com/laravel/framework/issues/20869
             */
            $fnUseGetForeignKey = array_intersect($this->fnGetForeignKey, get_class_methods($modelRelation));
            $fnUseGetForeignKey = reset($fnUseGetForeignKey);

            //Get foreign key and foreign key ids
            $foreignKeyUse = $modelRelation->{$fnUseGetForeignKey}();
            $foreignKeyIdsUse = $foreignKeyIds;

            //Many to many relations need to get related ids and related local key
            if ($modelRelation instanceof BelongsToMany) {
                extract($this->getBelongsToManyData($modelRelation, $foreignKeyUse, $foreignKeyIds));
            } elseif ($modelRelation instanceof MorphOneOrMany) {
                extract($this->getMorphManyData($modelRelation, $foreignKeyIds));
            }

            $affectedRows = $this->affectedRows($modelRelation, $foreignKeyUse, $foreignKeyIdsUse);

            if ($action === 'restrict' && $affectedRows > 0) {
                DB::rollBack(); //Rollback the transaction before throw exception
                throw (new SoftCascadeRestrictedException())->setModel(get_class($modelRelation->getModel()), $foreignKeyUse, $foreignKeyIdsUse->toArray());
            }

            $this->execute($modelRelation, $foreignKeyUse, $foreignKeyIdsUse, $affectedRows);
        }
    }
43543
public function revertModel($model)
    {
        if (!$model->is_destroy) {
            $model->destroy();
        }
        $this->pool[$model->core_name]->push($model);
    }
447378
protected function _insert(Garp_Model $model, array $cellData, array $mapping) {
        if (count($cellData) !== count($mapping)) {
            throw new Exception(
                "Cannot create rowdata from these keys and values.\nKeys:".
                implode(', ', $mapping)."\n".
                "Values:".implode(', ', $cellData)
            );
        }
        $data = array_combine($mapping, $cellData);
        // ignored columns have an empty key
        unset($data['']);
        return $model->insert($data);
    }
649471
public function rollBack()
    {
        if (!$this->getIsActive()) {
            // do nothing if transaction is not active: this could be the transaction is committed
            // but the event handler to "commitTransaction" throw an exception
            return;
        }

        $this->_level--;
        if ($this->_level === 0) {
            Log::debug('Roll back transaction' . __METHOD__);
            $this->db->pdo->rollBack();
            $this->db->trigger(Connection::EVENT_ROLLBACK_TRANSACTION);
            return;
        }

        $schema = $this->db->getSchema();
        if ($schema->supportsSavepoint()) {
            Log::debug('Roll back to savepoint ' . $this->_level . __METHOD__);
            $schema->rollBackSavepoint('LEVEL' . $this->_level);
        } else {
            Log::info('Transaction not rolled back: nested transaction not supported' . __METHOD__);
            // throw an exception to fail the outer transaction
            throw new Exception('Roll back failed: nested transaction not supported.');
        }
    }
203645
public function update($models)
    {
        $this->initIndex($models->first());
        $this->tnt->selectIndex("{$models->first()->searchableAs()}.index");
        $index = $this->tnt->getIndex();
        $index->setPrimaryKey($models->first()->getKeyName());

        $index->indexBeginTransaction();
        $models->each(function ($model) use ($index) {
            $array = $model->toSearchableArray();

            if (empty($array)) {
                return;
            }

            if ($model->getKey()) {
                $index->update($model->getKey(), $array);
            } else {
                $index->insert($array);
            }
        });
        $index->indexEndTransaction();
    }
618982
public function save(Garp_Model $model, array $mapping, array $options) {
        $excelReader = $this->_getReader();
        $worksheet = $excelReader->getActiveSheet();
        $pks = array();
        $iterator = $worksheet->getRowIterator();
        foreach ($iterator as $i => $row) {
            // workaround cause those PHPExcel assholes start their arrays at index 1
            $n = $i-1;
            if ($n < $options['firstRow']) {
                continue;
            }

            $cellData = array();
            $cellIterator = $row->getCellIterator();
            $cellIterator->setIterateOnlyExistingCells(false);
            foreach ($cellIterator as $j => $cell) {
                $cellData[] = $cell->getValue();
            }
            try {
                // Sanity check: do not insert completely empty rows
                $check = implode('', $cellData);
                $check = trim($check);
                if (!$check) {
                    continue;
                }
                $primaryKey = $this->_insert($model, $cellData, $mapping);
                $pks[] = $primaryKey;
            } catch (Exception $e) {
                if (!$options['ignoreErrors']) {
                    $this->rollback($model, $pks);
                }
                throw $e;
            }
        }
        return true;
    }
177453
public function updateByPk(array $primary_key, array $updates)
    {
        $where = $this
            ->checkPrimaryKey($primary_key)
            ->getWhereFrom($primary_key)
            ;
        $parameters = $this->getParametersList($updates);
        $update_strings = [];

        foreach ($updates as $field_name => $new_value) {
            $update_strings[] = sprintf(
                "%s = %s",
                $this->escapeIdentifier($field_name),
                $parameters[$field_name]
            );
        }

        $sql = strtr(
            "update :relation set :update where :condition returning :projection",
            [
                ':relation'   => $this->getStructure()->getRelation(),
                ':update'     => join(', ', $update_strings),
                ':condition'  => (string) $where,
                ':projection' => $this->createProjection()->formatFieldsWithFieldAlias(),
            ]
        );

        $iterator = $this->query($sql, array_merge(array_values($updates), $where->getValues()));

        if ($iterator->isEmpty()) {
            return null;
        }

        return $iterator->current()->status(FlexibleEntityInterface::STATUS_EXIST);
    }
1155214
protected function insert()
    {
        $aggregate = $this->aggregate;

        $attributes = $aggregate->getRawAttributes();

        $keyName = $aggregate->getEntityMap()->getKeyName();

        // Check if the primary key is defined in the attributes
        if (array_key_exists($keyName, $attributes) && $attributes[$keyName] != null) {
            $this->query->insert($attributes);
        } else {
            // Prevent inserting with a null ID
            if (array_key_exists($keyName, $attributes)) {
                unset($attributes[$keyName]);
            }

            if (isset($attributes['attributes'])) {
                unset($attributes['attributes']);
            }

            $id = $this->query->insertGetId($attributes, $keyName);

            $aggregate->setEntityAttribute($keyName, $id);
        }
    }
1308139
protected function insertTranslations(Model $mainModel, array $translations, array $insertedParentPKs)
    {
        if (!$translations) {
            return;
        }

        // The IDs of the model weren't known when preparing the bulk insert,
        // so we'll set the values of the foreign key now.
        $foreignKeyName = $mainModel->getRelationKey();

        $idKey = 0;

        foreach ($translations as &$translationsOfOneModel) {
            foreach ($translationsOfOneModel as &$translation) {
                $translation[$foreignKeyName] = $insertedParentPKs[$idKey];
            }

            $idKey++;
        }
        unset($translationsOfOneModel, $translation);

        // We'll flatten the records since they're grouped by model.
        $translations = Arr::flatten($translations, 1);

        foreach (array_chunk($translations, 500) as $chunk) {
            call_user_func([$mainModel->getTranslationModelName(), 'insert'], $chunk);
        }
    }
1242784
protected function _bindModels(Garp_Model_Db $model) {
        // Add HABTM related records
        $relations = $model->getConfiguration('relations');
        foreach ($relations as $key => $config) {
            if ($config['type'] !== 'hasAndBelongsToMany' && $config['type'] !== 'hasMany') {
                continue;
            }
            $otherModelName = 'Model_' . $config['model'];
            $otherModel = new $otherModelName();
            $multilingual = false;
            $modelFactory = new Garp_I18n_ModelFactory();

            if ($otherModel->getObserver('Translatable')) {
                $otherModel = $modelFactory->getModel($otherModel);
                $multilingual = true;
            }

            $otherModelAlias = $otherModel->getName();
            $bindingModel = null;
            if ($config['type'] === 'hasAndBelongsToMany') {
                $bindingModelName = 'Model_' . $config['bindingModel'];
                $bindingModel = new $bindingModelName;
                if ($multilingual) {
                    $refmapLocaliser = new Garp_Model_ReferenceMapLocalizer($bindingModel);
                    $refmapLocaliser->populate($otherModelName);
                }
                $otherModelAlias = 'm';
            }

            $labelFields = $otherModel->getListFields();
            $prefixedLabelFields = array();
            foreach ($labelFields as $labelField) {
                $prefixedLabelFields[] = "$otherModelAlias.$labelField";
            }
            $labelFields = 'CONCAT_WS(", ", ' . implode(', ', $prefixedLabelFields) . ')';

            // If the Translatable behavior would be effective,
            // the output would be in a localized array, which is overkill for this
            // purpose.
            $otherModel->unregisterObserver('Translatable');

            $options = array(
                'bindingModel' => $bindingModel,
                'modelClass' => $otherModel,
                'conditions' => $otherModel->select()
                    ->setIntegrityCheck(false)
                    ->from(
                        array($otherModelAlias => $otherModel->getName()),
                        array($config['label'] => $labelFields)
                    )
                    ->order("$otherModelAlias.id")
            );
            $model->bindModel($config['label'], $options);
        }
    }
860160
protected function drop($tables, bool $ignoreKeyConstraints = false) : void
    {
        if ($ignoreKeyConstraints) {
            $this->database->statement('SET FOREIGN_KEY_CHECKS=0;');
        }

        if (! is_array($tables)) {
            $tables = [$tables];
        }

        foreach ($tables as $table) {
            if ($this->tableExists($table)) {
                $this->schema->drop($table);
            }
        }

        if ($ignoreKeyConstraints) {
            $this->database->statement('SET FOREIGN_KEY_CHECKS=1;');
        }
    }
376960
public function afterInsert($model, $id)
    {
        if ($this->weak) {
            return;
        }

        $insert = $this->dsql();
        $insert->set($model->persistence->typecastSaveRow($model, $this->save_buffer));
        $this->save_buffer = [];
        $insert
            ->set(
                $this->foreign_field,
                isset($this->join) ? $this->join->id : $id
            );
        $insert->insert();
        $this->id = $this->owner->lastInsertID();
    }
1002003
def insert_model(self, model, *, upsert=None):
    
    pkname = model.primary_key_name
    include_keys = set(model.attrs.keys()).difference(model.exclude_keys_sql)

    if model.primary_key_is_auto:
      if pkname in include_keys:
        include_keys.remove(pkname)
    else:
      if isinstance(pkname, str):
        include_keys.add(pkname)
      else:
        include_keys.update(set(pkname))

    data = model.to_dict(include_keys=include_keys)
    returnings = []

    if model.primary_key_is_auto:
      returnings.append(pkname)
    if model.timestamps:
      returnings.extend(ts_name for ts_name in model.timestamps if ts_name)

    returning = ", ".join(returnings)
    cr = self.insert(model.table_name, data, returning=returning, upsert=upsert)

    if self.core.supports_returning_syntax:
      if returning:
        rec = cr.fetchone()
        if rec:
          for idx, attr_name in enumerate(returnings):
            setattr(model, attr_name, rec[idx])
    else:
      if model.primary_key_is_auto:
        setattr(model, model.primary_key_name, cr.lastrowid)

    return model
802957
protected function _getPrimaryKeysOfAffectedRows(Garp_Model_Db $model, $where) {
        if ($draftableObserver = $model->getObserver('Draftable')) {
            // Unregister so it doesn't screw up the upcoming fetch call
            $model->unregisterObserver($draftableObserver);
        }

        $pkExtractor = new Garp_Db_PrimaryKeyExtractor($model, $where);
        $pks = $pkExtractor->extract();
        if (count($pks)) {
            return array($pks);
        }
        $rows = $model->fetchAll($where);
        $pks = array();
        foreach ($rows as $row) {
            if (!$row->isConnected()) {
                $row->setTable($model);
            }
            $pks[] = (array)$row->getPrimaryKey();
        }
        if ($draftableObserver) {
            $model->registerObserver($draftableObserver);
        }
        return $pks;
    }
32888
final public function update(array $datas, $noApplyPrimaryKey = false) {
      if (is_array($datas) && count($datas)) {
         if (!is_array(@$datas[0])) {
            $datas = [$datas];
         }

         $this->connection();
         $this->columns();
         
         $this->last_sql = [];
         $this->placeholder_data = [];

         $where = $this->where;
         $whereTemp = str_replace('WHERE', '', $this->where);

         $rowCount = [];
         foreach ($datas as $data) {
            $placeholder = [];
            $isID = NULL;
            foreach($this->columnsData as $column) {
               if(isset($data[$column])) {
                  if($this->primaryKey==$column && $noApplyPrimaryKey===false) {
                     $isID = $data[$column];
                  } 
                  else {
                     $placeholder[$column] = "{$column}=NULL";
                     if ( gettype($data[$column])==='boolean' )
                        $placeholder[$column] = $data[$column] ? "{$column}=TRUE" : "{$column}=FALSE";
                     elseif ( $data[$column]!=='' && $data[$column]!==NULL ) {
                        $placeholder[$column] = "{$column}=?";
                        $this->placeholder_data[] = $data[$column];
                     }
                  }
               }
            }


            if($isID!==NULL) {
               $this->where = '';
               $this->where( $this->primaryKey, '=', $isID );
               if (trim($whereTemp)) {
                  $where = $this->where .' AND '. $whereTemp;
               }
               else {
                  $where = $this->where;
               }
            }

            $schema = '';
            if($this->driver=='pgsql' && $this->schema) {
               if (!preg_match('/\./', $this->table)) {
                  $schema = $this->schema ? $this->schema.'.' : '';	
               }
            }

            $placeholders = implode(",", $placeholder);
            $this->last_sql[] = $this->sql = "UPDATE {$schema}{$this->table} SET {$placeholders} {$where}";

            // $this->fetch(false);
            $this->fetch();

            $rowCount[] = $this->rowCount;

            $this->reset();

            if ( $this->tableOrig!==null ) {
               $this->table = $this->tableOrig;
            }

            $error = $this->error();
            if($error['message']) return false;
         }
         if ( count( $rowCount )===1 ) {
            $this->rowCount = $rowCount[0];
         }
         else {
            $this->rowCount = $rowCount;
         }
         
         return true;
      }
      return false;
   }
1001234
public function addEagerConstraints(array $models)
    {
        // We'll grab the primary key name of the related models since it could be set to
        // a non-standard name and not "id". We will then construct the constraint for
        // our eagerly loading query so it returns the proper models from execution.
        $key = $this->related->getTable().'.'.$this->ownerKey;

        $whereIn = $this->whereInMethod($this->related, $this->ownerKey);

        $this->query->{$whereIn}($key, $this->getEagerModelKeys($models));
    }