1
0
Fork 0

removed "createCollection" attribute from APIs

This commit is contained in:
Jan Steemann 2016-05-12 15:17:45 +02:00
parent 3e781e82dd
commit 8e090e642e
21 changed files with 91 additions and 218 deletions

View File

@ -63,7 +63,7 @@ creation operations. The boundary used in this example is
Content-type: application/x-arango-batchpart
Content-Id: 1
POST /_api/document?collection=xyz&createCollection=true HTTP/1.1
POST /_api/document?collection=xyz HTTP/1.1
{"a":1,"b":2,"c":3}
--XXXsubpartXXX

View File

@ -10,7 +10,7 @@ are needed or allowed in this data section.
*Examples*
```js
curl --data-binary @- -X POST --dump - "http://localhost:8529/_api/import?collection=test&createCollection=true"
curl --data-binary @- -X POST --dump - "http://localhost:8529/_api/import?collection=test"
[ "firstName", "lastName", "age", "gender" ]
[ "Joe", "Public", 42, "male" ]
[ "Jane", "Doe", 31, "female" ]
@ -36,9 +36,6 @@ errors occurred.
!SECTION Importing into Edge Collections
Please note that when importing documents into an [edge collection](../Glossary/README.md#edge-collection), it is
mandatory that all imported documents contain the *_from* and *_to* attributes,
Please note that when importing documents into an [edge collection](../Glossary/README.md#edge-collection),
it is mandatory that all imported documents contain the *_from* and *_to* attributes,
and that these contain references to existing collections.
Please also note that it is not possible to create a new edge collection on the
fly using the *createCollection* parameter.

View File

@ -42,7 +42,7 @@ the data are line-wise JSON documents (type = documents) or a JSON array (type =
*Examples*
```js
curl --data-binary @- -X POST --dump - "http://localhost:8529/_api/import?type=documents&collection=test&createCollection=true"
curl --data-binary @- -X POST --dump - "http://localhost:8529/_api/import?type=documents&collection=test"
{ "name" : "test", "gender" : "male", "age" : 39 }
{ "type" : "bird", "name" : "robin" }

View File

@ -19,10 +19,7 @@ sent to this URL using an HTTP POST request. The data to import must be
contained in the body of the POST request.
The *collection* query parameter must be used to specify the target collection for
the import. The optional query parameter *createCollection* can be used to create
a non-existing collection during the import. If not used, importing data into a
non-existing collection will produce an error. Please note that the *createCollection*
flag can only be used to create document collections, not [edge collections](../Glossary/README.md#edge-collection).
the import. Importing data into a non-existing collection will produce an error.
The *waitForSync* query parameter can be set to *true* to make the import only
return if all documents have been synced to disk.

View File

@ -5,25 +5,25 @@ a document. Any document can be retrieved using its unique URI:
http://server:port/_api/document/<document-handle>
Edges are a special variation of documents, and to work with edges, the above URL
format changes to:
Edges are a special variation of documents. To access an edge use the same
URL format as for a document:
http://server:port/_api/edge/<document-handle>
http://server:port/_api/document/<document-handle>
For example, assumed that the document handle, which is stored in the *_id*
attribute of the edge, is *demo/362549736*, then the URL of that edge is:
http://localhost:8529/_api/edge/demo/362549736
http://localhost:8529/_api/document/demo/362549736
The above URL scheme does not specify a [database name](../Glossary/README.md#database-name) explicitly, so the
default database will be used. To explicitly specify the database context, use
the following URL schema:
http://server:port/_db/<database-name>/_api/edge/<document-handle>
http://server:port/_db/<database-name>/_api/document/<document-handle>
*Example*:
http://localhost:8529/_db/mydb/_api/edge/demo/362549736
http://localhost:8529/_db/mydb/_api/document/demo/362549736
**Note**: that the following examples use the short URL format for brevity.

View File

@ -409,6 +409,7 @@ not support the URL parameter "createCollection" anymore. In previous versions o
ArangoDB this parameter could be used to automatically create a collection upon
insertion of the first document. It is now required that the target collection already
exists when using this API, otherwise it will return an HTTP 404 error.
The same is true for the import API at POST `/_api/import`.
Collections can still be created easily via a separate call to POST `/_api/collection`
as before.

View File

@ -15,16 +15,6 @@ subsequent lines.
@RESTQUERYPARAM{collection,string,required}
The collection name.
@RESTQUERYPARAM{createCollection,boolean,optional}
If this parameter has a value of `true` or `yes`, then the collection is
created if it does not yet exist. Other values will be ignored so the
collection must be present for the operation to succeed.
@RESTQUERYPARAM{createCollectionType,string,optional}
If this parameter has a value of `document` or `edge`, it will determine
the type of collection that is going to be created when the `createCollection`
option is set to `true`. The default value is `document`.
@RESTQUERYPARAM{fromPrefix,string,optional}
An optional prefix for the values in `_from` attributes. If specified, the
value is automatically prepended to each `_from` input value. This allows
@ -158,30 +148,6 @@ line in the import data is empty
db._drop(cn);
@END_EXAMPLE_ARANGOSH_RUN
Importing two documents into a new collection
@EXAMPLE_ARANGOSH_RUN{RestImportCsvCreate}
var cn = "products";
db._drop(cn);
db._create(cn);
var body = '[ "value1", "value2" ]\n' +
'[ 1234, null ]\n' +
'[ "foo", "bar" ]\n' +
'[534.55, true ]';
var response = logCurlRequestRaw('POST', "/_api/import?collection=" + cn + "&createCollection=true", body);
assert(response.code === 201);
var r = JSON.parse(response.body)
assert(r.created === 3);
assert(r.errors === 0);
assert(r.empty === 0);
logJsonResponse(response);
db._drop(cn);
@END_EXAMPLE_ARANGOSH_RUN
Importing into an edge collection, with attributes `_from`, `_to` and `name`
@EXAMPLE_ARANGOSH_RUN{RestImportCsvEdge}

View File

@ -24,16 +24,6 @@ the following values:
@RESTQUERYPARAM{collection,string,required}
The collection name.
@RESTQUERYPARAM{createCollection,boolean,optional}
If this parameter has a value of `true` or `yes`, then the collection is
created if it does not yet exist. Other values will be ignored so the
collection must be present for the operation to succeed.
@RESTQUERYPARAM{createCollectionType,string,optional}
If this parameter has a value of `document` or `edge`, it will determine
the type of collection that is going to be created when the `createCollection`
option is set to `true`. The default value is `document`.
@RESTQUERYPARAM{fromPrefix,string,optional}
An optional prefix for the values in `_from` attributes. If specified, the
value is automatically prepended to each `_from` input value. This allows
@ -222,33 +212,6 @@ Using the auto type detection
db._drop(cn);
@END_EXAMPLE_ARANGOSH_RUN
Importing documents into a new collection from a JSON array
@EXAMPLE_ARANGOSH_RUN{RestImportJsonCreate}
db._flushCache();
var cn = "products";
db._drop(cn);
db._create(cn);
db._flushCache();
var body = [
{ id: "12553", active: true },
{ id: "4433", active: false },
{ id: "55932", count: 4334 },
];
var response = logCurlRequestRaw('POST', "/_api/import?collection=" + cn + "&createCollection=true&type=list", body);
assert(response.code === 201);
var r = JSON.parse(response.body);
assert(r.created === 3);
assert(r.errors === 0);
assert(r.empty === 0);
logJsonResponse(response);
db._drop(cn);
@END_EXAMPLE_ARANGOSH_RUN
Importing into an edge collection, with attributes `_from`, `_to` and `name`
@EXAMPLE_ARANGOSH_RUN{RestImportJsonEdge}

View File

@ -2,7 +2,7 @@
@startDocuBlock API_EDGE_CREATE
@brief creates an edge
@RESTHEADER{POST /_api/edge,Create edge}
@RESTHEADER{POST /_api/document,Create edge}
@RESTALLBODYPARAM{edge-document,json,required}
A JSON representation of the edge document must be passed as the body of
@ -14,14 +14,6 @@ the *_key* attribute if needed.
@RESTQUERYPARAM{collection,string,required}
Creates a new edge in the collection identified by *collection* name.
@RESTQUERYPARAM{createCollection,boolean,optional}
If this parameter has a value of *true* or *yes*, then the collection is
created if it does not yet exist. Other values will be ignored so the
collection must be present for the operation to succeed.
**Note**: This flag is not supported in a cluster. Using it will result in an
error.
@RESTQUERYPARAM{waitForSync,boolean,optional}
Wait until the edge document has been synced to disk.
@ -36,9 +28,8 @@ Creates a new edge document in the collection named *collection*. A JSON
representation of the document must be passed as the body of the POST
request.
The *from* and *to* handles are immutable once the edge has been created.
In all other respects the method works like *POST /document*.
In all other respects the method works like *POST /_api/document* for
documents.
@RESTRETURNCODES
@ -68,7 +59,7 @@ Create an edge and read it back:
var g = new Graph("graph", "vertices", "edges");
g.addVertex(1);
g.addVertex(2);
var url = "/_api/edge/?collection=edges&from=vertices/1&to=vertices/2";
var url = "/_api/document/?collection=edges&from=vertices/1&to=vertices/2";
var response = logCurlRequest("POST", url, { "name": "Emil" });
@ -77,7 +68,7 @@ Create an edge and read it back:
logJsonResponse(response);
var body = response.body.replace(/\\/g, '');
var edge_id = JSON.parse(body)._id;
var response2 = logCurlRequest("GET", "/_api/edge/" + edge_id);
var response2 = logCurlRequest("GET", "/_api/document/" + edge_id);
assert(response2.code === 200);

View File

@ -2,7 +2,7 @@
@startDocuBlock API_EDGE_DELETE
@brief deletes an edge
@RESTHEADER{DELETE /_api/edge/{document-handle}, Deletes edge}
@RESTHEADER{DELETE /_api/document/{document-handle}, Deletes edge}
@RESTURLPARAMETERS

View File

@ -2,7 +2,7 @@
@startDocuBlock API_EDGE_READ
@brief reads a single edge
@RESTHEADER{GET /_api/edge/{document-handle}, Read edge}
@RESTHEADER{GET /_api/document/{document-handle}, Read edge}
@RESTURLPARAMETERS

View File

@ -2,7 +2,7 @@
@startDocuBlock API_EDGE_READ_ALL
@brief reads all edges from collection
@RESTHEADER{GET /_api/edge, Read all edges from collection}
@RESTHEADER{GET /_api/document, Read all edges from collection}
@RESTQUERYPARAMETERS

View File

@ -2,7 +2,7 @@
@startDocuBlock API_EDGE_READ_HEAD
@brief reads a single edge head
@RESTHEADER{HEAD /_api/edge/{document-handle}, Read edge header}
@RESTHEADER{HEAD /_api/document/{document-handle}, Read edge header}
@RESTURLPARAMETERS

View File

@ -2,7 +2,7 @@
@startDocuBlock API_EDGE_REPLACE
@brief replaces an edge
@RESTHEADER{PUT /_api/edge/{document-handle},replaces an edge}
@RESTHEADER{PUT /_api/document/{document-handle},replaces an edge}
@RESTALLBODYPARAM{edge,json,required}
A JSON representation of the new edge data.

View File

@ -2,7 +2,7 @@
@startDocuBlock API_EDGE_UPDATES
@brief updates an edge
@RESTHEADER{PATCH /_api/edge/{document-handle}, Patches edge}
@RESTHEADER{PATCH /_api/document/{document-handle}, Patches edge}
@RESTALLBODYPARAM{document,json,required}
A JSON representation of the edge update.

View File

@ -116,23 +116,6 @@ HttpHandler::status_t RestImportHandler::execute() {
return status_t(HANDLER_DONE);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief determine the collection type from the request
////////////////////////////////////////////////////////////////////////////////
TRI_col_type_e RestImportHandler::getCollectionType() {
// extract the collection type from the request
bool found;
std::string const& collectionType =
_request->value("createCollectionType", found);
if (found && !collectionType.empty() && collectionType == "edge") {
return TRI_COL_TYPE_EDGE;
}
return TRI_COL_TYPE_DOCUMENT;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief create a position string
////////////////////////////////////////////////////////////////////////////////
@ -355,10 +338,6 @@ bool RestImportHandler::createFromJson(std::string const& type) {
return false;
}
if (!checkCreateCollection(collectionName, getCollectionType())) {
return false;
}
bool linewise;
if (type == "documents") {
@ -588,10 +567,6 @@ bool RestImportHandler::createFromKeyValueList() {
return false;
}
if (!checkCreateCollection(collectionName, getCollectionType())) {
return false;
}
// read line number (optional)
int64_t lineNumber = 0;
std::string const& lineNumValue = _request->value("line", found);

View File

@ -68,11 +68,6 @@ class RestImportHandler : public RestVocbaseBaseHandler {
status_t execute() override final;
private:
//////////////////////////////////////////////////////////////////////////////
/// @brief determine the collection type from the request
//////////////////////////////////////////////////////////////////////////////
TRI_col_type_e getCollectionType();
//////////////////////////////////////////////////////////////////////////////
/// @brief create a position string

View File

@ -199,49 +199,6 @@ void RestVocbaseBaseHandler::generateDeleted(
generate20x(result, collectionName, type, options);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief check if a collection needs to be created on the fly
///
/// this method will check the "createCollection" attribute of the request. if
/// it is set to true, it will verify that the named collection actually exists.
/// if the collection does not yet exist, it will create it on the fly.
/// if the "createCollection" attribute is not set or set to false, nothing will
/// happen, and the collection name will not be checked
////////////////////////////////////////////////////////////////////////////////
bool RestVocbaseBaseHandler::checkCreateCollection(std::string const& name,
TRI_col_type_e type) {
bool found;
std::string const& valueStr = _request->value("createCollection", found);
if (!found) {
// "createCollection" parameter not specified
return true;
}
if (!StringUtils::boolean(valueStr)) {
// "createCollection" parameter specified, but with non-true value
return true;
}
if (ServerState::instance()->isCoordinator() ||
ServerState::instance()->isDBServer()) {
// create-collection is not supported in a cluster
generateTransactionError(name, TRI_ERROR_CLUSTER_UNSUPPORTED, "");
return false;
}
TRI_vocbase_col_t* collection =
TRI_FindCollectionByNameOrCreateVocBase(_vocbase, name, type);
if (collection == nullptr) {
generateTransactionError(name, TRI_errno(), "");
return false;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief generates a HTTP 20x response
////////////////////////////////////////////////////////////////////////////////

View File

@ -145,20 +145,6 @@ class RestVocbaseBaseHandler : public RestBaseHandler {
std::string assembleDocumentId(std::string const&, std::string const&, bool);
//////////////////////////////////////////////////////////////////////////////
/// @brief check if a collection needs to be created on the fly
///
/// this method will check the "createCollection" attribute of the request. if
/// it is set to true, it will verify that the named collection actually
/// exists.
/// if the collection does not yet exist, it will create it on the fly.
/// if the "createCollection" attribute is not set or set to false, nothing
/// will
/// happen, and the collection name will not be checked
//////////////////////////////////////////////////////////////////////////////
bool checkCreateCollection(std::string const&, TRI_col_type_e);
//////////////////////////////////////////////////////////////////////////////
/// @brief generates a HTTP 201 or 202 response
//////////////////////////////////////////////////////////////////////////////

View File

@ -29,17 +29,18 @@
#include "Logger/Logger.h"
#include "Basics/tri-strings.h"
#include "Basics/VelocyPackHelper.h"
#include "Rest/GeneralResponse.h"
#include "Rest/HttpRequest.h"
#include "SimpleHttpClient/SimpleHttpClient.h"
#include "SimpleHttpClient/SimpleHttpResult.h"
#include <velocypack/Builder.h>
#include <velocypack/Iterator.h>
#include <velocypack/velocypack-aliases.h>
using namespace arangodb;
using namespace arangodb::basics;
using namespace arangodb::httpclient;
using namespace std;
////////////////////////////////////////////////////////////////////////////////
/// @brief helper function to determine if a field value is an integer
@ -429,26 +430,8 @@ void ImportHelper::reportProgress(int64_t totalLength, int64_t totalRead,
/// @brief return the collection-related URL part
////////////////////////////////////////////////////////////////////////////////
std::string ImportHelper::getCollectionUrlPart() {
std::string part("collection=" + StringUtils::urlEncode(_collectionName));
if (_firstChunk) {
if (_createCollection) {
part += "&createCollection=yes";
}
if (!_createCollectionType.empty()) {
part += "&createCollectionType=" + _createCollectionType;
}
if (_overwrite) {
part += "&overwrite=yes";
}
_firstChunk = false;
}
return part;
std::string ImportHelper::getCollectionUrlPart() const {
return std::string("collection=" + StringUtils::urlEncode(_collectionName));
}
////////////////////////////////////////////////////////////////////////////////
@ -614,10 +597,57 @@ void ImportHelper::addLastField(char const* field, size_t fieldLength,
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief check if we must create the target collection, and create it if
/// required
////////////////////////////////////////////////////////////////////////////////
bool ImportHelper::checkCreateCollection() {
if (!_firstChunk || !_createCollection) {
return true;
}
std::string const url("/_api/collection");
VPackBuilder builder;
builder.openObject();
builder.add("name", VPackValue(_collectionName));
builder.add("type", VPackValue(_createCollectionType == "edge" ? 3 : 2));
builder.close();
std::string data = builder.slice().toJson();
std::unordered_map<std::string, std::string> headerFields;
std::unique_ptr<SimpleHttpResult> result(_client->request(
GeneralRequest::RequestType::POST, url, data.c_str(),
data.size(), headerFields));
if (result == nullptr) {
return false;
}
auto code = static_cast<GeneralResponse::ResponseCode>(result->getHttpReturnCode());
if (code == GeneralResponse::ResponseCode::CONFLICT ||
code == GeneralResponse::ResponseCode::OK ||
code == GeneralResponse::ResponseCode::CREATED ||
code == GeneralResponse::ResponseCode::ACCEPTED) {
// collection already exists or was created successfully
return true;
}
LOG(ERR) << "unable to create collection '" << _collectionName << "', server returned status code: " << static_cast<int>(code);
_hasError = true;
return false;
}
void ImportHelper::sendCsvBuffer() {
if (_hasError) {
return;
}
if (!checkCreateCollection()) {
return;
}
std::unordered_map<std::string, std::string> headerFields;
std::string url("/_api/import?" + getCollectionUrlPart() + "&line=" +
@ -630,6 +660,11 @@ void ImportHelper::sendCsvBuffer() {
if (!_toCollectionPrefix.empty()) {
url += "&toPrefix=" + StringUtils::urlEncode(_toCollectionPrefix);
}
if (_firstChunk && _overwrite) {
url += "&overwrite=true";
}
_firstChunk = false;
std::unique_ptr<SimpleHttpResult> result(_client->request(
GeneralRequest::RequestType::POST, url, _outputBuffer.c_str(),
@ -646,6 +681,10 @@ void ImportHelper::sendJsonBuffer(char const* str, size_t len, bool isObject) {
return;
}
if (!checkCreateCollection()) {
return;
}
// build target url
std::string url("/_api/import?" + getCollectionUrlPart() +
"&details=true&onDuplicate=" +
@ -662,6 +701,11 @@ void ImportHelper::sendJsonBuffer(char const* str, size_t len, bool isObject) {
if (!_toCollectionPrefix.empty()) {
url += "&toPrefix=" + StringUtils::urlEncode(_toCollectionPrefix);
}
if (_firstChunk && _overwrite) {
url += "&overwrite=true";
}
_firstChunk = false;
std::unordered_map<std::string, std::string> headerFields;
std::unique_ptr<SimpleHttpResult> result(_client->request(

View File

@ -203,12 +203,13 @@ class ImportHelper {
void reportProgress(int64_t, int64_t, double&);
std::string getCollectionUrlPart();
std::string getCollectionUrlPart() const;
void beginLine(size_t row);
void addField(char const*, size_t, size_t row, size_t column, bool escaped);
void addLastField(char const*, size_t, size_t row, size_t column,
bool escaped);
bool checkCreateCollection();
void sendCsvBuffer();
void sendJsonBuffer(char const* str, size_t len, bool isObject);
void handleResult(httpclient::SimpleHttpResult* result);