/** * @covers WindowsAzure\Table\TableRestProxy::batch * @covers WindowsAzure\Table\TableRestProxy::_createBatchRequestBody * @covers WindowsAzure\Table\TableRestProxy::_getOperationContext * @covers WindowsAzure\Table\TableRestProxy::_createOperationsContexts * @covers WindowsAzure\Table\TableRestProxy::_constructPutOrMergeEntityContext * @covers WindowsAzure\Table\Internal\MimeReaderWriter::encodeMimeMultipart * @covers WindowsAzure\Table\Internal\MimeReaderWriter::decodeMimeMultipart * @covers WindowsAzure\Table\Models\BatchResult::create * @covers WindowsAzure\Table\Models\BatchResult::_constructResponses * @covers WindowsAzure\Table\Models\BatchResult::_compareUsingContentId * @covers WindowsAzure\Common\Internal\ServiceRestProxy::sendContext */ public function testBatchWithMerge() { // Setup $name = 'batchwithmerge'; $this->createTable($name); $partitionKey = '123'; $rowKey = '456'; $expected = TestResources::getTestEntity($partitionKey, $rowKey); $this->restProxy->insertEntity($name, $expected); $result = $this->restProxy->queryEntities($name); $entities = $result->getEntities(); $expected = $entities[0]; $expected->addProperty('CustomerPlace', EdmType::STRING, 'Redmond'); $operations = new BatchOperations(); $operations->addMergeEntity($name, $expected); // Test $result = $this->restProxy->batch($operations); // Assert $entries = $result->getEntries(); $this->assertNotNull($entries[0]->getETag()); $result = $this->restProxy->queryEntities($name); $entities = $result->getEntities(); $actual = $entities[0]; $this->assertEquals($expected->getPartitionKey(), $actual->getPartitionKey()); $this->assertEquals($expected->getRowKey(), $actual->getRowKey()); $this->assertCount(count($expected->getProperties()), $actual->getProperties()); }
/** * {@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; }
/** * @covers WindowsAzure\Table\Models\BatchOperations::addMergeEntity * @covers WindowsAzure\Table\Models\BatchOperations::addOperation * @covers WindowsAzure\Table\Models\BatchOperations::getOperations */ public function testAddMergeEntity() { // Setup $table = 'mytable'; $entity = new Entity(); $operations = new BatchOperations(); // Test $operations->addMergeEntity($table, $entity); // Assert $this->assertCount(1, $operations->getOperations()); }
/** * @covers WindowsAzure\Table\TableRestProxy::batch * @covers WindowsAzure\Table\TableRestProxy::insertEntity */ public function testBatchAllOperationsTogetherWorks() { // Arrange $table = self::$testTable8; $partitionKey = '001'; // Insert a few entities to allow updating them in batch $entity1 = new Entity(); $entity1->setPartitionKey($partitionKey); $entity1->setRowKey('batchAllOperationsWorks-' . 1); $entity1->addProperty('test', EdmType::BOOLEAN, true); $entity1->addProperty('test2', EdmType::STRING, 'value'); $entity1->addProperty('test3', EdmType::INT32, 3); $entity1->addProperty('test4', EdmType::INT64, '12345678901'); $entity1->addProperty('test5', EdmType::DATETIME, new \DateTime()); $entity1 = $this->restProxy->insertEntity($table, $entity1)->getEntity(); $entity2 = new Entity(); $entity2->setPartitionKey($partitionKey); $entity2->setRowKey('batchAllOperationsWorks-' . 2); $entity2->addProperty('test', EdmType::BOOLEAN, true); $entity2->addProperty('test2', EdmType::STRING, 'value'); $entity2->addProperty('test3', EdmType::INT32, 3); $entity2->addProperty('test4', EdmType::INT64, '12345678901'); $entity2->addProperty('test5', EdmType::DATETIME, new \DateTime()); $entity2 = $this->restProxy->insertEntity($table, $entity2)->getEntity(); $entity3 = new Entity(); $entity3->setPartitionKey($partitionKey); $entity3->setRowKey('batchAllOperationsWorks-' . 3); $entity3->addProperty('test', EdmType::BOOLEAN, true); $entity3->addProperty('test2', EdmType::STRING, 'value'); $entity3->addProperty('test3', EdmType::INT32, 3); $entity3->addProperty('test4', EdmType::INT64, '12345678901'); $entity3->addProperty('test5', EdmType::DATETIME, new \DateTime()); $entity3 = $this->restProxy->insertEntity($table, $entity3)->getEntity(); $entity4 = new Entity(); $entity4->setPartitionKey($partitionKey); $entity4->setRowKey('batchAllOperationsWorks-' . 4); $entity4->addProperty('test', EdmType::BOOLEAN, true); $entity4->addProperty('test2', EdmType::STRING, 'value'); $entity4->addProperty('test3', EdmType::INT32, 3); $entity4->addProperty('test4', EdmType::INT64, '12345678901'); $entity4->addProperty('test5', EdmType::DATETIME, new \DateTime()); $entity4 = $this->restProxy->insertEntity($table, $entity4)->getEntity(); // Act $batchOperations = new BatchOperations(); $entity = new Entity(); $entity->setPartitionKey($partitionKey); $entity->setRowKey('batchAllOperationsWorks'); $entity->addProperty('test', EdmType::BOOLEAN, true); $entity->addProperty('test2', EdmType::STRING, 'value'); $entity->addProperty('test3', EdmType::INT32, 3); $entity->addProperty('test4', EdmType::INT64, '12345678901'); $entity->addProperty('test5', EdmType::DATETIME, new \DateTime()); $batchOperations->addInsertEntity($table, $entity); $batchOperations->addDeleteEntity($table, $entity1->getPartitionKey(), $entity1->getRowKey(), $entity1->getETag()); $entity2->addProperty('test3', EdmType::INT32, 5); $batchOperations->addUpdateEntity($table, $entity2); $entity3->addProperty('test3', EdmType::INT32, 5); $batchOperations->addMergeEntity($table, $entity3); $entity4->addProperty('test3', EdmType::INT32, 5); // Use different behavior in the emulator, as v1.6 does not support this method if (!$this->isEmulated()) { $batchOperations->addInsertOrReplaceEntity($table, $entity4); } else { $batchOperations->addUpdateEntity($table, $entity4); } $entity5 = new Entity(); $entity5->setPartitionKey($partitionKey); $entity5->setRowKey('batchAllOperationsWorks-' . 5); $entity5->addProperty('test', EdmType::BOOLEAN, true); $entity5->addProperty('test2', EdmType::STRING, 'value'); $entity5->addProperty('test3', EdmType::INT32, 3); $entity5->addProperty('test4', EdmType::INT64, '12345678901'); $entity5->addProperty('test5', EdmType::DATETIME, new \DateTime()); // Use different behavior in the emulator, as v1.6 does not support this method if ($this->isEmulated()) { $batchOperations->addInsertEntity($table, $entity5); } else { $batchOperations->addInsertOrMergeEntity($table, $entity5); } $result = $this->restProxy->batch($batchOperations); // Assert $this->assertNotNull($result, '$result'); $this->assertEquals(count($batchOperations->getOperations()), count($result->getEntries()), 'count($result->getEntries())'); $ents = $result->getEntries(); $this->assertTrue($ents[0] instanceof InsertEntityResult, '$result->getEntries()->get(0)->getClass()'); $this->assertTrue(is_string($ents[1]), '$result->getEntries()->get(1)->getClass()'); $this->assertTrue($ents[2] instanceof UpdateEntityResult, '$result->getEntries()->get(2)->getClass()'); $this->assertTrue($ents[3] instanceof UpdateEntityResult, '$result->getEntries()->get(3)->getClass()'); $this->assertTrue($ents[4] instanceof UpdateEntityResult, '$result->getEntries()->get(4)->getClass()'); if ($this->isEmulated()) { $this->assertTrue($ents[5] instanceof InsertEntityResult, '$result->getEntries()->get(5)->getClass()'); } else { $this->assertTrue($ents[5] instanceof UpdateEntityResult, '$result->getEntries()->get(5)->getClass()'); } }