This commit is contained in:
parent
da0bff519b
commit
7a8afb20bc
3 changed files with 68 additions and 45 deletions
25
README.md
25
README.md
|
|
@ -349,12 +349,11 @@ Note that only fields that are specified in the request will be updated.
|
|||
|
||||
### Update (with JSON array)
|
||||
|
||||
Alternatively you can send a JSON array containing multiple JSON objects in the body. Each of the records must contain the primary key field.
|
||||
The call returns an array of the rows affected.
|
||||
Alternatively you can send a JSON array containing multiple JSON objects in the body. The call returns an array of the rows affected.
|
||||
|
||||
```
|
||||
PUT http://localhost/api.php/categories
|
||||
[{"id":"1","name":"Internet"},{"id":"2","name":"Programming"}]
|
||||
PUT http://localhost/api.php/categories/1,2
|
||||
[{"name":"Internet"},{""name":"Programming"}]
|
||||
```
|
||||
|
||||
Output:
|
||||
|
|
@ -363,6 +362,8 @@ Output:
|
|||
[1,1]
|
||||
```
|
||||
|
||||
The number of primary key values in the URL should match the number of elements in the JSON array.
|
||||
|
||||
This call uses a transaction and will either update all or no records. If the transaction fails it will return 'null'.
|
||||
|
||||
### Delete
|
||||
|
|
@ -379,6 +380,22 @@ Output:
|
|||
1
|
||||
```
|
||||
|
||||
### Delete (multiple)
|
||||
|
||||
The DELETE verb can also be used to delete multiple records. The call returns the rows affected for each primary key value specified in the URL.
|
||||
|
||||
```
|
||||
DELETE http://localhost/api.php/categories/1,2
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```
|
||||
[1,1]
|
||||
```
|
||||
|
||||
This call uses a transaction and will either delete all or no records. If the transaction fails it will return 'null'.
|
||||
|
||||
## Relations
|
||||
|
||||
The explanation of this feature is based on the data structure from the ```blog.sql``` database file. This database is a very simple blog data structure with corresponding foreign key relations between the tables. These foreign key constraints are required as the relationship detection is based on them, not on column naming.
|
||||
|
|
|
|||
69
api.php
69
api.php
|
|
@ -1078,8 +1078,8 @@ class PHP_CRUD_API {
|
|||
return $fields;
|
||||
}
|
||||
|
||||
protected function processKeyParameter($action,$key,$tables,$database) {
|
||||
if ($action == 'list') return false;
|
||||
protected function processKeyParameter($key,$tables,$database) {
|
||||
if (!$key) return false;
|
||||
$fields = $this->findPrimaryKeys($tables[0],$database);
|
||||
if (count($fields)!=1) $this->exitWith404('1pk');
|
||||
return array($key,$fields[0]);
|
||||
|
|
@ -1254,13 +1254,8 @@ class PHP_CRUD_API {
|
|||
$ids = array();
|
||||
$this->db->beginTransaction();
|
||||
foreach ($inputs as $input) {
|
||||
$input = (array)$input;
|
||||
$keys = implode(',',str_split(str_repeat('!', count($input))));
|
||||
$values = implode(',',str_split(str_repeat('?', count($input))));
|
||||
$params = array_merge(array_keys($input),array_values($input));
|
||||
array_unshift($params, $tables[0]);
|
||||
$result = $this->db->query('INSERT INTO ! ('.$keys.') VALUES ('.$values.')',$params);
|
||||
if (!$result) {
|
||||
$result = $this->createObject($input,$tables);
|
||||
if ($result===null) {
|
||||
$this->db->rollbackTransaction();
|
||||
return null;
|
||||
}
|
||||
|
|
@ -1293,38 +1288,19 @@ class PHP_CRUD_API {
|
|||
protected function updateObjects($key,$inputs,$filters,$tables) {
|
||||
if (!$inputs) return false;
|
||||
$keyField = $key[1];
|
||||
$keys = array();
|
||||
foreach ($inputs as $i=>$input) {
|
||||
if (isset($input->$keyField)) {
|
||||
$keys[$i] = $input->$keyField;
|
||||
unset($inputs[$i]->$keyField);
|
||||
} else {
|
||||
$this->exitWith404('subject');
|
||||
}
|
||||
$keys = explode(',',$key[0]);
|
||||
if (count($inputs)!=count($keys)) {
|
||||
$this->exitWith404('subject');
|
||||
}
|
||||
$rows = array();
|
||||
$this->db->beginTransaction();
|
||||
foreach ($inputs as $i=>$input) {
|
||||
$input = (array)$input;
|
||||
$table = $tables[0];
|
||||
$sql = 'UPDATE ! SET ';
|
||||
$params = array($table);
|
||||
foreach (array_keys($input) as $j=>$k) {
|
||||
if ($j) $sql .= ',';
|
||||
$v = $input[$k];
|
||||
$sql .= '!=?';
|
||||
$params[] = $k;
|
||||
$params[] = $v;
|
||||
}
|
||||
$newFilters = $filters;
|
||||
$this->addFilter($newFilters,$table,'and',$keyField,'eq',$keys[$i]);
|
||||
$this->addWhereFromFilters($newFilters[$table],$sql,$params);
|
||||
$result = $this->db->query($sql,$params);
|
||||
if (!$result) {
|
||||
$result = $this->updateObject(array($keys[$i],$keyField),$input,$filters,$tables);
|
||||
if ($result===null) {
|
||||
$this->db->rollbackTransaction();
|
||||
return null;
|
||||
}
|
||||
$rows[] = $this->db->affectedRows($result);
|
||||
$rows[] = $result;
|
||||
}
|
||||
$this->db->commitTransaction();
|
||||
return $rows;
|
||||
|
|
@ -1341,6 +1317,23 @@ class PHP_CRUD_API {
|
|||
return $this->db->affectedRows($result);
|
||||
}
|
||||
|
||||
protected function deleteObjects($key,$filters,$tables) {
|
||||
$keyField = $key[1];
|
||||
$keys = explode(',',$key[0]);
|
||||
$rows = array();
|
||||
$this->db->beginTransaction();
|
||||
foreach ($keys as $key) {
|
||||
$result = $this->deleteObject(array($key,$keyField),$filters,$tables);
|
||||
if ($result===null) {
|
||||
$this->db->rollbackTransaction();
|
||||
return null;
|
||||
}
|
||||
$rows[] = $result;
|
||||
}
|
||||
$this->db->commitTransaction();
|
||||
return $rows;
|
||||
}
|
||||
|
||||
protected function findRelations($tables,$database,$auto_include) {
|
||||
$tableset = array();
|
||||
$collect = array();
|
||||
|
|
@ -1491,7 +1484,7 @@ class PHP_CRUD_API {
|
|||
extract($settings);
|
||||
|
||||
$table = $this->parseRequestParameter($request, 'a-zA-Z0-9\-_');
|
||||
$key = $this->parseRequestParameter($request, 'a-zA-Z0-9\-_'); // auto-increment or uuid
|
||||
$key = $this->parseRequestParameter($request, 'a-zA-Z0-9\-_,'); // auto-increment or uuid
|
||||
$action = $this->mapMethodToAction($method,$key);
|
||||
$include = $this->parseGetParameter($get, 'include', 'a-zA-Z0-9\-_,');
|
||||
$page = $this->parseGetParameter($get, 'page', '0-9,');
|
||||
|
|
@ -1502,7 +1495,7 @@ class PHP_CRUD_API {
|
|||
$transform = $this->parseGetParameter($get, 'transform', 't1');
|
||||
|
||||
$tables = $this->processTableAndIncludeParameters($database,$table,$include,$action);
|
||||
$key = $this->processKeyParameter($action,$key,$tables,$database);
|
||||
$key = $this->processKeyParameter($key,$tables,$database);
|
||||
$satisfy = $this->processSatisfyParameter($tables,$satisfy);
|
||||
$filters = $this->processFiltersParameter($tables,$satisfy,$filters);
|
||||
$page = $this->processPageParameter($page);
|
||||
|
|
@ -1520,6 +1513,7 @@ class PHP_CRUD_API {
|
|||
if ($tenancy_function) $this->applyTenancyFunction($tenancy_function,$action,$database,$fields,$filters);
|
||||
if ($column_authorizer) $this->applyColumnAuthorizer($column_authorizer,$action,$database,$fields);
|
||||
|
||||
$multi = strpos($key[0],',')!==false;
|
||||
if (strlen($post)) {
|
||||
// input
|
||||
$multi = $post[0]=='[';
|
||||
|
|
@ -1703,7 +1697,8 @@ class PHP_CRUD_API {
|
|||
protected function deleteCommand($parameters) {
|
||||
extract($parameters);
|
||||
$this->startOutput();
|
||||
echo json_encode($this->deleteObject($key,$filters,$tables));
|
||||
if ($multi) echo json_encode($this->deleteObjects($key,$filters,$tables));
|
||||
else echo json_encode($this->deleteObject($key,$filters,$tables));
|
||||
}
|
||||
|
||||
protected function listCommand($parameters) {
|
||||
|
|
|
|||
|
|
@ -643,14 +643,14 @@ class PHP_CRUD_API_Test extends PHPUnit_Framework_TestCase
|
|||
$test = new API($this);
|
||||
$test->get('/tags?transform=1');
|
||||
$test->expect('{"tags":[{"id":"1","name":"funny"},{"id":"2","name":"important"}]}');
|
||||
$test->put('/tags','[{"id":"1","name":"funny"},{"id":"2","name":"important"}]');
|
||||
$test->put('/tags/1,2','[{"name":"funny"},{"name":"important"}]');
|
||||
$test->expect('[0,0]');
|
||||
}
|
||||
|
||||
public function testUpdateMultipleTagsWithoutId()
|
||||
public function testUpdateMultipleTagsTooManyIds()
|
||||
{
|
||||
$test = new API($this);
|
||||
$test->put('/tags','[{"id":"1","name":"funny!!!"},{"name":"important"}]');
|
||||
$test->put('/tags/1,2,3','[{"name":"funny!!!"},{"name":"important"}]');
|
||||
$test->expect(false,'Not found (subject)');
|
||||
$test->get('/tags?transform=1');
|
||||
$test->expect('{"tags":[{"id":"1","name":"funny"},{"id":"2","name":"important"}]}');
|
||||
|
|
@ -659,9 +659,20 @@ class PHP_CRUD_API_Test extends PHPUnit_Framework_TestCase
|
|||
public function testUpdateMultipleTagsWithoutFields()
|
||||
{
|
||||
$test = new API($this);
|
||||
$test->put('/tags','[{"id":"1","name":"funny!!!"},{"id":"2"}]');
|
||||
$test->put('/tags/1,2','[{"name":"funny!!!"},{}]');
|
||||
$test->expect('null');
|
||||
$test->get('/tags?transform=1');
|
||||
$test->expect('{"tags":[{"id":"1","name":"funny"},{"id":"2","name":"important"}]}');
|
||||
}
|
||||
|
||||
public function testDeleteMultipleTags()
|
||||
{
|
||||
$test = new API($this);
|
||||
$test->post('/tags','[{"name":"extra"},{"name":"more"}]');
|
||||
$test->expect('[3,4]');
|
||||
$test->delete('/tags/3,4');
|
||||
$test->expect('[1,1]');
|
||||
$test->get('/tags?transform=1');
|
||||
$test->expect('{"tags":[{"id":"1","name":"funny"},{"id":"2","name":"important"}]}');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue