Esempio n. 1
0
 /**
  * {@inheritdoc}
  */
 protected function addToTransaction($record = null, $id = null, $extras = null, $rollback = false, $continue = false, $single = false)
 {
     $fields = ArrayUtils::get($extras, ApiOptions::FIELDS);
     $ssFilters = ArrayUtils::get($extras, 'ss_filters');
     $updates = ArrayUtils::get($extras, 'updates');
     $idFields = ArrayUtils::get($extras, 'id_fields');
     $needToIterate = $single || $continue || 1 < count($this->tableIdsInfo);
     $requireMore = ArrayUtils::getBool($extras, 'require_more');
     $client = $this->parent->getGuzzleClient();
     $out = [];
     switch ($this->getAction()) {
         case Verbs::POST:
             $parsed = $this->parseRecord($record, $this->tableFieldsInfo, $ssFilters);
             if (empty($parsed)) {
                 throw new BadRequestException('No valid fields were found in record.');
             }
             $native = json_encode($parsed);
             $result = $this->parent->callGuzzle('POST', 'sobjects/' . $this->transactionTable . '/', null, $native, $client);
             if (!ArrayUtils::getBool($result, 'success', false)) {
                 $msg = json_encode(ArrayUtils::get($result, 'errors'));
                 throw new InternalServerErrorException("Record insert failed for table '{$this->transactionTable}'.\n" . $msg);
             }
             $id = ArrayUtils::get($result, 'id');
             // add via record, so batch processing can retrieve extras
             return $requireMore ? parent::addToTransaction($id) : [$idFields => $id];
         case Verbs::PUT:
         case Verbs::MERGE:
         case Verbs::PATCH:
             if (!empty($updates)) {
                 $record = $updates;
             }
             $parsed = $this->parseRecord($record, $this->tableFieldsInfo, $ssFilters, true);
             if (empty($parsed)) {
                 throw new BadRequestException('No valid fields were found in record.');
             }
             static::removeIds($parsed, $idFields);
             $native = json_encode($parsed);
             $result = $this->parent->callGuzzle('PATCH', 'sobjects/' . $this->transactionTable . '/' . $id, null, $native, $client);
             if ($result && !ArrayUtils::getBool($result, 'success', false)) {
                 $msg = ArrayUtils::get($result, 'errors');
                 throw new InternalServerErrorException("Record update failed for table '{$this->transactionTable}'.\n" . $msg);
             }
             // add via record, so batch processing can retrieve extras
             return $requireMore ? parent::addToTransaction($id) : [$idFields => $id];
         case Verbs::DELETE:
             $result = $this->parent->callGuzzle('DELETE', 'sobjects/' . $this->transactionTable . '/' . $id, null, null, $client);
             if ($result && !ArrayUtils::getBool($result, 'success', false)) {
                 $msg = ArrayUtils::get($result, 'errors');
                 throw new InternalServerErrorException("Record delete failed for table '{$this->transactionTable}'.\n" . $msg);
             }
             // add via record, so batch processing can retrieve extras
             return $requireMore ? parent::addToTransaction($id) : [$idFields => $id];
         case Verbs::GET:
             if (!$needToIterate) {
                 return parent::addToTransaction(null, $id);
             }
             $fields = $this->buildFieldList($this->transactionTable, $fields, $idFields);
             $result = $this->parent->callGuzzle('GET', 'sobjects/' . $this->transactionTable . '/' . $id, ['fields' => $fields]);
             if (empty($result)) {
                 throw new NotFoundException("Record with identifier '" . print_r($id, true) . "' not found.");
             }
             $out = $result;
             break;
     }
     return $out;
 }
Esempio n. 2
0
 /**
  * {@inheritdoc}
  */
 protected function addToTransaction($record = null, $id = null, $extras = null, $rollback = false, $continue = false, $single = false)
 {
     $ssFilters = ArrayUtils::get($extras, 'ss_filters');
     $fields = ArrayUtils::get($extras, ApiOptions::FIELDS);
     $idFields = ArrayUtils::get($extras, 'id_fields');
     $updates = ArrayUtils::get($extras, 'updates');
     $out = [];
     switch ($this->getAction()) {
         case Verbs::POST:
             $parsed = $this->parseRecord($record, $this->tableFieldsInfo, $ssFilters);
             if (empty($parsed)) {
                 throw new BadRequestException('No valid fields were found in record.');
             }
             $native = $this->formatAttributes($parsed);
             $result = $this->parent->getConnection()->putItem([static::TABLE_INDICATOR => $this->transactionTable, 'Item' => $native, 'Expected' => [$idFields[0] => ['Exists' => false]]]);
             if ($rollback) {
                 $key = static::buildKey($this->tableIdsInfo, $record);
                 $this->addToRollback($key);
             }
             $out = static::cleanRecord($record, $fields, $idFields);
             break;
         case Verbs::PUT:
             if (!empty($updates)) {
                 // only update by full records can use batching
                 $updates[$idFields[0]] = $id;
                 $record = $updates;
             }
             $parsed = $this->parseRecord($record, $this->tableFieldsInfo, $ssFilters, true);
             if (empty($parsed)) {
                 throw new BadRequestException('No valid fields were found in record.');
             }
             $native = $this->formatAttributes($parsed);
             if (!$continue && !$rollback) {
                 return parent::addToTransaction($native, $id);
             }
             $options = $rollback ? ReturnValue::ALL_OLD : ReturnValue::NONE;
             $result = $this->parent->getConnection()->putItem([static::TABLE_INDICATOR => $this->transactionTable, 'Item' => $native, 'ReturnValues' => $options]);
             if ($rollback) {
                 $temp = $result['Attributes'];
                 if (!empty($temp)) {
                     $this->addToRollback($temp);
                 }
             }
             $out = static::cleanRecord($record, $fields, $idFields);
             break;
         case Verbs::PATCH:
             if (!empty($updates)) {
                 $updates[$idFields[0]] = $id;
                 $record = $updates;
             }
             $parsed = $this->parseRecord($record, $this->tableFieldsInfo, $ssFilters, true);
             if (empty($parsed)) {
                 throw new BadRequestException('No valid fields were found in record.');
             }
             $key = static::buildKey($this->tableIdsInfo, $parsed, true);
             $native = $this->formatAttributes($parsed, true);
             // simple insert request
             $options = $rollback ? ReturnValue::ALL_OLD : ReturnValue::ALL_NEW;
             $result = $this->parent->getConnection()->updateItem([static::TABLE_INDICATOR => $this->transactionTable, 'Key' => $key, 'AttributeUpdates' => $native, 'ReturnValues' => $options]);
             $temp = $result['Attributes'];
             if ($rollback) {
                 $this->addToRollback($temp);
                 // merge old record with new changes
                 $new = array_merge($this->unformatAttributes($temp), $updates);
                 $out = static::cleanRecord($new, $fields, $idFields);
             } else {
                 $temp = $this->unformatAttributes($temp);
                 $out = static::cleanRecord($temp, $fields, $idFields);
             }
             break;
         case Verbs::DELETE:
             if (!$continue && !$rollback) {
                 return parent::addToTransaction(null, $id);
             }
             $record = [$idFields[0] => $id];
             $key = static::buildKey($this->tableIdsInfo, $record);
             $result = $this->parent->getConnection()->deleteItem([static::TABLE_INDICATOR => $this->transactionTable, 'Key' => $key, 'ReturnValues' => ReturnValue::ALL_OLD]);
             $temp = $result['Attributes'];
             if ($rollback) {
                 $this->addToRollback($temp);
             }
             $temp = $this->unformatAttributes($temp);
             $out = static::cleanRecord($temp, $fields, $idFields);
             break;
         case Verbs::GET:
             $record = [$idFields[0] => $id];
             $key = static::buildKey($this->tableIdsInfo, $record);
             $scanProperties = [static::TABLE_INDICATOR => $this->transactionTable, 'Key' => $key, 'ConsistentRead' => true];
             $fields = static::buildAttributesToGet($fields, $idFields);
             if (!empty($fields)) {
                 $scanProperties['AttributesToGet'] = $fields;
             }
             $result = $this->parent->getConnection()->getItem($scanProperties);
             $result = $result['Item'];
             if (empty($result)) {
                 throw new NotFoundException('Record not found.');
             }
             // Grab value from the result object like an array
             $out = $this->unformatAttributes($result);
             break;
         default:
             break;
     }
     return $out;
 }
Esempio n. 3
0
 /**
  * {@inheritdoc}
  */
 protected function addToTransaction($record = null, $id = null, $extras = null, $rollback = false, $continue = false, $single = false)
 {
     $ssFilters = ArrayUtils::get($extras, 'ss_filters');
     $fields = ArrayUtils::get($extras, ApiOptions::FIELDS);
     $requireMore = ArrayUtils::get($extras, 'require_more');
     $updates = ArrayUtils::get($extras, 'updates');
     // convert to native format
     $id = static::idToMongoId($id);
     $fieldArray = $rollback ? null : static::buildFieldArray($fields);
     $out = [];
     switch ($this->getAction()) {
         case Verbs::POST:
             $parsed = $this->parseRecord($record, $this->tableFieldsInfo, $ssFilters);
             if (empty($parsed)) {
                 throw new BadRequestException('No valid fields were found in record.');
             }
             if (!$continue && !$rollback && !$single) {
                 return parent::addToTransaction($parsed, $id);
             }
             $result = $this->collection->insert($parsed);
             static::processResult($result);
             $out = static::cleanRecord($parsed, $fields, static::DEFAULT_ID_FIELD);
             if ($rollback) {
                 $this->addToRollback(static::recordAsId($parsed, static::DEFAULT_ID_FIELD));
             }
             break;
         case Verbs::PUT:
             if (!empty($updates)) {
                 $parsed = $this->parseRecord($updates, $this->tableFieldsInfo, $ssFilters, true);
                 $updates = $parsed;
             } else {
                 $parsed = $this->parseRecord($record, $this->tableFieldsInfo, $ssFilters, true);
             }
             if (empty($parsed)) {
                 throw new BadRequestException('No valid fields were found in record.');
             }
             // only update/patch by ids can use batching
             if (!$continue && !$rollback && !$single && !empty($updates)) {
                 return parent::addToTransaction(null, $id);
             }
             $options = ['new' => !$rollback];
             if (empty($updates)) {
                 $out = static::cleanRecord($record, $fields, static::DEFAULT_ID_FIELD);
                 static::removeIds($parsed, static::DEFAULT_ID_FIELD);
                 $updates = $parsed;
             } else {
                 $record = $updates;
                 $record[static::DEFAULT_ID_FIELD] = $id;
                 $out = static::cleanRecord($record, $fields, static::DEFAULT_ID_FIELD);
             }
             // simple update overwrite existing record
             $filter = [static::DEFAULT_ID_FIELD => $id];
             $criteria = $this->buildCriteriaArray($filter, null, $ssFilters);
             $result = $this->collection->findAndModify($criteria, $updates, $fieldArray, $options);
             if (empty($result)) {
                 throw new NotFoundException("Record with id '{$id}' not found.");
             }
             if ($rollback) {
                 $this->addToRollback($result);
             } else {
                 $out = static::fromMongoObjects($result);
             }
             break;
         case Verbs::MERGE:
         case Verbs::PATCH:
             if (!empty($updates)) {
                 $parsed = $this->parseRecord($updates, $this->tableFieldsInfo, $ssFilters, true);
                 $updates = $parsed;
             } else {
                 $parsed = $this->parseRecord($record, $this->tableFieldsInfo, $ssFilters, true);
             }
             if (empty($parsed)) {
                 throw new BadRequestException('No valid fields were found in record.');
             }
             // only update/patch by ids can use batching
             if (!$continue && !$rollback && !$single && !empty($updates)) {
                 return parent::addToTransaction(null, $id);
             }
             $options = ['new' => !$rollback];
             if (empty($updates)) {
                 static::removeIds($parsed, static::DEFAULT_ID_FIELD);
                 $updates = $parsed;
             }
             $updates = ['$set' => $updates];
             // simple merge with existing record
             $filter = [static::DEFAULT_ID_FIELD => $id];
             $criteria = $this->buildCriteriaArray($filter, null, $ssFilters);
             $result = $this->collection->findAndModify($criteria, $updates, $fieldArray, $options);
             if (empty($result)) {
                 throw new NotFoundException("Record with id '{$id}' not found.");
             }
             if ($rollback) {
                 $this->addToRollback($result);
                 // need to retrieve the full record here
                 if ($requireMore) {
                     $result = $this->collection->findOne($criteria, $fieldArray);
                 } else {
                     $result = [static::DEFAULT_ID_FIELD => $id];
                 }
             }
             $out = static::fromMongoObjects($result);
             break;
         case Verbs::DELETE:
             if (!$continue && !$rollback && !$single) {
                 return parent::addToTransaction(null, $id);
             }
             $options = ['remove' => true];
             // simple delete existing record
             $filter = [static::DEFAULT_ID_FIELD => $id];
             $criteria = $this->buildCriteriaArray($filter, null, $ssFilters);
             $result = $this->collection->findAndModify($criteria, null, $fieldArray, $options);
             if (empty($result)) {
                 throw new NotFoundException("Record with id '{$id}' not found.");
             }
             if ($rollback) {
                 $this->addToRollback($result);
                 $out = static::cleanRecord($record, $fields, static::DEFAULT_ID_FIELD);
             } else {
                 $out = static::fromMongoObjects($result);
             }
             break;
         case Verbs::GET:
             if ($continue && !$single) {
                 return parent::addToTransaction(null, $id);
             }
             $filter = [static::DEFAULT_ID_FIELD => $id];
             $criteria = $this->buildCriteriaArray($filter, null, $ssFilters);
             $result = $this->collection->findOne($criteria, $fieldArray);
             if (empty($result)) {
                 throw new NotFoundException("Record with id '{$id}' not found.");
             }
             $out = static::fromMongoObjects($result);
             break;
     }
     return $out;
 }
Esempio n. 4
0
 /**
  * {@inheritdoc}
  */
 protected function addToTransaction($record = null, $id = null, $extras = null, $rollback = false, $continue = false, $single = false)
 {
     $ssFilters = ArrayUtils::get($extras, 'ss_filters');
     $fields = ArrayUtils::get($extras, ApiOptions::FIELDS);
     $requireMore = ArrayUtils::get($extras, 'require_more');
     $updates = ArrayUtils::get($extras, 'updates');
     $partitionKey = ArrayUtils::get($extras, static::PARTITION_KEY);
     if (!is_array($id)) {
         $id = [static::ROW_KEY => $id, static::PARTITION_KEY => $partitionKey];
     }
     if (!empty($partitionKey)) {
         $id[static::PARTITION_KEY] = $partitionKey;
     }
     if (!empty($updates)) {
         foreach ($id as $field => $value) {
             if (!isset($updates[$field])) {
                 $updates[$field] = $value;
             }
         }
         $record = $updates;
     } elseif (!empty($record)) {
         if (!empty($partitionKey)) {
             $record[static::PARTITION_KEY] = $partitionKey;
         }
     }
     if (!empty($record)) {
         $forUpdate = false;
         switch ($this->getAction()) {
             case Verbs::PUT:
             case Verbs::MERGE:
             case Verbs::PATCH:
                 $forUpdate = true;
                 break;
         }
         $record = $this->parseRecord($record, $this->tableFieldsInfo, $ssFilters, $forUpdate);
         if (empty($record)) {
             throw new BadRequestException('No valid fields were found in record.');
         }
         $entity = static::parseRecordToEntity($record);
     } else {
         $entity = static::parseRecordToEntity($id);
     }
     $partKey = $entity->getPartitionKey();
     if (empty($partKey)) {
         throw new BadRequestException('No valid partition key found in request.');
     }
     $rowKey = $entity->getRowKey();
     if (empty($rowKey)) {
         throw new BadRequestException('No valid row key found in request.');
     }
     // only allow batch if rollback and same partition
     $batch = $rollback && !empty($partitionKey);
     $out = [];
     switch ($this->getAction()) {
         case Verbs::POST:
             if ($batch) {
                 if (!isset($this->batchOps)) {
                     $this->batchOps = new BatchOperations();
                 }
                 $this->batchOps->addInsertEntity($this->transactionTable, $entity);
                 // track record for output
                 return parent::addToTransaction($record);
             }
             /** @var InsertEntityResult $result */
             $result = $this->parent->getConnection()->insertEntity($this->transactionTable, $entity);
             if ($rollback) {
                 $this->addToRollback($entity);
             }
             $out = static::parseEntityToRecord($result->getEntity(), $fields);
             break;
         case Verbs::PUT:
             if ($batch) {
                 if (!isset($this->batchOps)) {
                     $this->batchOps = new BatchOperations();
                 }
                 $this->batchOps->addUpdateEntity($this->transactionTable, $entity);
                 // track record for output
                 return parent::addToTransaction($record);
             }
             if ($rollback) {
                 $old = $this->parent->getConnection()->getEntity($this->transactionTable, $entity->getRowKey(), $entity->getPartitionKey());
                 $this->addToRollback($old);
             }
             /** @var UpdateEntityResult $result */
             $this->parent->getConnection()->updateEntity($this->transactionTable, $entity);
             $out = static::parseEntityToRecord($entity, $fields);
             break;
         case Verbs::MERGE:
         case Verbs::PATCH:
             if ($batch) {
                 if (!isset($this->batchOps)) {
                     $this->batchOps = new BatchOperations();
                 }
                 $this->batchOps->addMergeEntity($this->transactionTable, $entity);
                 // track id for output
                 return parent::addToTransaction(null, $rowKey);
             }
             if ($rollback || $requireMore) {
                 $old = $this->parent->getConnection()->getEntity($this->transactionTable, $rowKey, $partKey);
                 if ($rollback) {
                     $this->addToRollback($old);
                 }
                 if ($requireMore) {
                     $out = array_merge(static::parseEntityToRecord($old, $fields), static::parseEntityToRecord($entity, $fields));
                 }
             }
             $out = empty($out) ? static::parseEntityToRecord($entity, $fields) : $out;
             /** @var UpdateEntityResult $result */
             $this->parent->getConnection()->mergeEntity($this->transactionTable, $entity);
             break;
         case Verbs::DELETE:
             if ($batch) {
                 if (!isset($this->batchOps)) {
                     $this->batchOps = new BatchOperations();
                 }
                 $this->batchOps->addDeleteEntity($this->transactionTable, $partKey, $rowKey);
                 // track id for output
                 return parent::addToTransaction(null, $rowKey);
             }
             if ($rollback || $requireMore) {
                 $old = $this->parent->getConnection()->getEntity($this->transactionTable, $partKey, $rowKey);
                 if ($rollback) {
                     $this->addToRollback($old);
                 }
                 if ($requireMore) {
                     $out = static::parseEntityToRecord($old, $fields);
                 }
             }
             $this->parent->getConnection()->deleteEntity($this->transactionTable, $partKey, $rowKey);
             $out = empty($out) ? static::parseEntityToRecord($entity, $fields) : $out;
             break;
         case Verbs::GET:
             if (!empty($partitionKey)) {
                 // track id for output
                 return parent::addToTransaction(null, $rowKey);
             }
             /** @var GetEntityResult $result */
             $result = $this->parent->getConnection()->getEntity($this->transactionTable, $partKey, $rowKey);
             $out = static::parseEntityToRecord($result->getEntity(), $fields);
             break;
     }
     return $out;
 }
Esempio n. 5
0
 /**
  * {@inheritdoc}
  */
 protected function addToTransaction($record = null, $id = null, $extras = null, $rollback = false, $continue = false, $single = false)
 {
     if ($rollback) {
         // sql transaction really only for rollback scenario, not batching
         if (!isset($this->transaction)) {
             $this->transaction = $this->dbConn->beginTransaction();
         }
     }
     $fields = ArrayUtils::get($extras, ApiOptions::FIELDS);
     $ssFilters = ArrayUtils::get($extras, 'ss_filters');
     $updates = ArrayUtils::get($extras, 'updates');
     $idFields = ArrayUtils::get($extras, 'id_fields');
     $needToIterate = $single || !$continue || 1 < count($this->tableIdsInfo);
     $related = ArrayUtils::get($extras, 'related');
     $requireMore = ArrayUtils::getBool($extras, 'require_more') || !empty($related);
     $allowRelatedDelete = ArrayUtils::getBool($extras, 'allow_related_delete', false);
     $relatedInfo = $this->describeTableRelated($this->transactionTable);
     $where = [];
     $params = [];
     if (is_array($id)) {
         foreach ($idFields as $name) {
             $where[] = $this->dbConn->quoteColumnName($name) . " = :pk_{$name}";
             $params[":pk_{$name}"] = ArrayUtils::get($id, $name);
         }
     } else {
         $name = ArrayUtils::get($idFields, 0);
         $where[] = $this->dbConn->quoteColumnName($name) . " = :pk_{$name}";
         $params[":pk_{$name}"] = $id;
     }
     $serverFilter = $this->buildQueryStringFromData($ssFilters, $params);
     if (!empty($serverFilter)) {
         $where[] = $serverFilter;
     }
     if (count($where) > 1) {
         array_unshift($where, 'AND');
     } else {
         $where = ArrayUtils::get($where, 0, null);
     }
     /** @var Command $command */
     $command = $this->dbConn->createCommand();
     $out = [];
     switch ($this->getAction()) {
         case Verbs::POST:
             $parsed = $this->parseRecord($record, $this->tableFieldsInfo, $ssFilters);
             if (empty($parsed)) {
                 throw new BadRequestException('No valid fields were found in record.');
             }
             $rows = $command->insert($this->transactionTable, $parsed);
             if (0 >= $rows) {
                 throw new InternalServerErrorException("Record insert failed.");
             }
             if (empty($id)) {
                 $id = [];
                 foreach ($this->tableIdsInfo as $info) {
                     $idName = $info->name;
                     if ($info->autoIncrement) {
                         $schema = $this->dbConn->getSchema()->getTable($this->transactionTable);
                         $sequenceName = $schema->sequenceName;
                         $id[$idName] = (int) $this->dbConn->getLastInsertID($sequenceName);
                     } else {
                         // must have been passed in with request
                         $id[$idName] = ArrayUtils::get($parsed, $idName);
                     }
                 }
             }
             if (!empty($relatedInfo)) {
                 $this->updateRelations($this->transactionTable, $record, $id, $relatedInfo, $allowRelatedDelete);
             }
             $idName = isset($this->tableIdsInfo, $this->tableIdsInfo[0], $this->tableIdsInfo[0]->name) ? $this->tableIdsInfo[0]->name : null;
             $out = is_array($id) ? $id : [$idName => $id];
             // add via record, so batch processing can retrieve extras
             if ($requireMore) {
                 parent::addToTransaction($id);
             }
             break;
         case Verbs::PUT:
         case Verbs::MERGE:
         case Verbs::PATCH:
             if (!empty($updates)) {
                 $record = $updates;
             }
             $parsed = $this->parseRecord($record, $this->tableFieldsInfo, $ssFilters, true);
             // only update by ids can use batching, too complicated with ssFilters and related update
             //                if ( !$needToIterate && !empty( $updates ) )
             //                {
             //                    return parent::addToTransaction( null, $id );
             //                }
             if (!empty($parsed)) {
                 $rows = $command->update($this->transactionTable, $parsed, $where, $params);
                 if (0 >= $rows) {
                     // could have just not updated anything, or could be bad id
                     $fields = empty($fields) ? $idFields : $fields;
                     $result = $this->parseFieldsForSqlSelect($fields, $this->tableFieldsInfo);
                     $bindings = ArrayUtils::get($result, 'bindings');
                     $fields = ArrayUtils::get($result, 'fields');
                     $fields = empty($fields) ? '*' : $fields;
                     $result = $this->recordQuery($this->transactionTable, $fields, $where, $params, $bindings, $extras);
                     if (empty($result)) {
                         throw new NotFoundException("Record with identifier '" . print_r($id, true) . "' not found.");
                     }
                 }
             }
             if (!empty($relatedInfo)) {
                 $this->updateRelations($this->transactionTable, $record, $id, $relatedInfo, $allowRelatedDelete);
             }
             $idName = isset($this->tableIdsInfo, $this->tableIdsInfo[0], $this->tableIdsInfo[0]->name) ? $this->tableIdsInfo[0]->name : null;
             $out = is_array($id) ? $id : [$idName => $id];
             // add via record, so batch processing can retrieve extras
             if ($requireMore) {
                 parent::addToTransaction($id);
             }
             break;
         case Verbs::DELETE:
             if (!$needToIterate) {
                 return parent::addToTransaction(null, $id);
             }
             // add via record, so batch processing can retrieve extras
             if ($requireMore) {
                 $fields = empty($fields) ? $idFields : $fields;
                 $result = $this->parseFieldsForSqlSelect($fields, $this->tableFieldsInfo);
                 $bindings = ArrayUtils::get($result, 'bindings');
                 $fields = ArrayUtils::get($result, 'fields');
                 $fields = empty($fields) ? '*' : $fields;
                 $result = $this->recordQuery($this->transactionTable, $fields, $where, $params, $bindings, $extras);
                 if (empty($result)) {
                     throw new NotFoundException("Record with identifier '" . print_r($id, true) . "' not found.");
                 }
                 $out = $result[0];
             }
             $rows = $command->delete($this->transactionTable, $where, $params);
             if (0 >= $rows) {
                 if (empty($out)) {
                     // could have just not updated anything, or could be bad id
                     $fields = empty($fields) ? $idFields : $fields;
                     $result = $this->parseFieldsForSqlSelect($fields, $this->tableFieldsInfo);
                     $bindings = ArrayUtils::get($result, 'bindings');
                     $fields = ArrayUtils::get($result, 'fields');
                     $fields = empty($fields) ? '*' : $fields;
                     $result = $this->recordQuery($this->transactionTable, $fields, $where, $params, $bindings, $extras);
                     if (empty($result)) {
                         throw new NotFoundException("Record with identifier '" . print_r($id, true) . "' not found.");
                     }
                 }
             }
             if (empty($out)) {
                 $idName = isset($this->tableIdsInfo, $this->tableIdsInfo[0], $this->tableIdsInfo[0]->name) ? $this->tableIdsInfo[0]->name : null;
                 $out = is_array($id) ? $id : [$idName => $id];
             }
             break;
         case Verbs::GET:
             if (!$needToIterate) {
                 return parent::addToTransaction(null, $id);
             }
             $fields = empty($fields) ? $idFields : $fields;
             $result = $this->parseFieldsForSqlSelect($fields, $this->tableFieldsInfo);
             $bindings = ArrayUtils::get($result, 'bindings');
             $fields = ArrayUtils::get($result, 'fields');
             $fields = empty($fields) ? '*' : $fields;
             $result = $this->recordQuery($this->transactionTable, $fields, $where, $params, $bindings, $extras);
             if (empty($result)) {
                 throw new NotFoundException("Record with identifier '" . print_r($id, true) . "' not found.");
             }
             $out = $result[0];
             break;
     }
     return $out;
 }
Esempio n. 6
0
 /**
  * {@inheritdoc}
  */
 protected function addToTransaction($record = null, $id = null, $extras = null, $rollback = false, $continue = false, $single = false)
 {
     $ssFilters = ArrayUtils::get($extras, 'ss_filters');
     $fields = ArrayUtils::get($extras, ApiOptions::FIELDS);
     $requireMore = ArrayUtils::get($extras, 'require_more');
     $updates = ArrayUtils::get($extras, 'updates');
     $out = [];
     switch ($this->getAction()) {
         case Verbs::POST:
             $record = $this->parseRecord($record, $this->tableFieldsInfo, $ssFilters);
             if (empty($record)) {
                 throw new BadRequestException('No valid fields were found in record.');
             }
             if ($rollback) {
                 return parent::addToTransaction($record, $id);
             }
             $result = $this->parent->getConnection()->asArray()->storeDoc((object) $record);
             if ($requireMore) {
                 // for returning latest _rev
                 $result = array_merge($record, $result);
             }
             $out = static::cleanRecord($result, $fields);
             break;
         case Verbs::PUT:
             if (!empty($updates)) {
                 // make sure record doesn't contain identifiers
                 unset($updates[static::DEFAULT_ID_FIELD]);
                 unset($updates[static::REV_FIELD]);
                 $parsed = $this->parseRecord($updates, $this->tableFieldsInfo, $ssFilters, true);
                 if (empty($parsed)) {
                     throw new BadRequestException('No valid fields were found in record.');
                 }
             }
             if ($rollback) {
                 return parent::addToTransaction($record, $id);
             }
             if (!empty($updates)) {
                 $record = $updates;
             }
             $parsed = $this->parseRecord($record, $this->tableFieldsInfo, $ssFilters, true);
             if (empty($parsed)) {
                 throw new BadRequestException('No valid fields were found in record.');
             }
             $old = null;
             if (!isset($record[static::REV_FIELD]) || $rollback) {
                 // unfortunately we need the rev, so go get the latest
                 $old = $this->parent->getConnection()->asArray()->getDoc($id);
                 $record[static::REV_FIELD] = ArrayUtils::get($old, static::REV_FIELD);
             }
             $result = $this->parent->getConnection()->asArray()->storeDoc((object) $record);
             if ($rollback) {
                 // keep the new rev
                 $old = array_merge($old, $result);
                 $this->addToRollback($old);
             }
             if ($requireMore) {
                 $result = array_merge($record, $result);
             }
             $out = static::cleanRecord($result, $fields);
             break;
         case Verbs::MERGE:
         case Verbs::PATCH:
             if (!empty($updates)) {
                 $record = $updates;
             }
             // make sure record doesn't contain identifiers
             unset($record[static::DEFAULT_ID_FIELD]);
             unset($record[static::REV_FIELD]);
             $parsed = $this->parseRecord($record, $this->tableFieldsInfo, $ssFilters, true);
             if (empty($parsed)) {
                 throw new BadRequestException('No valid fields were found in record.');
             }
             // only update/patch by ids can use batching
             if (!$single && !$continue && !$rollback) {
                 return parent::addToTransaction($parsed, $id);
             }
             // get all fields of record
             $old = $this->parent->getConnection()->asArray()->getDoc($id);
             // merge in changes from $record to $merge
             $record = array_merge($old, $record);
             // write back the changes
             $result = $this->parent->getConnection()->asArray()->storeDoc((object) $record);
             if ($rollback) {
                 // keep the new rev
                 $old = array_merge($old, $result);
                 $this->addToRollback($old);
             }
             if ($requireMore) {
                 $result = array_merge($record, $result);
             }
             $out = static::cleanRecord($result, $fields);
             break;
         case Verbs::DELETE:
             if (!$single && !$continue && !$rollback) {
                 return parent::addToTransaction(null, $id);
             }
             $old = $this->parent->getConnection()->asArray()->getDoc($id);
             if ($rollback) {
                 $this->addToRollback($old);
             }
             $this->parent->getConnection()->asArray()->deleteDoc((object) $record);
             $out = static::cleanRecord($old, $fields);
             break;
         case Verbs::GET:
             if (!$single) {
                 return parent::addToTransaction(null, $id);
             }
             $result = $this->parent->getConnection()->asArray()->getDoc($id);
             $out = static::cleanRecord($result, $fields);
             break;
     }
     return $out;
 }