mirror of https://gitee.com/bigwinds/arangodb
removed "createCollection" attribute from APIs
This commit is contained in:
parent
3e781e82dd
commit
8e090e642e
|
@ -63,7 +63,7 @@ creation operations. The boundary used in this example is
|
||||||
Content-type: application/x-arango-batchpart
|
Content-type: application/x-arango-batchpart
|
||||||
Content-Id: 1
|
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}
|
{"a":1,"b":2,"c":3}
|
||||||
--XXXsubpartXXX
|
--XXXsubpartXXX
|
||||||
|
|
|
@ -10,7 +10,7 @@ are needed or allowed in this data section.
|
||||||
*Examples*
|
*Examples*
|
||||||
|
|
||||||
```js
|
```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" ]
|
[ "firstName", "lastName", "age", "gender" ]
|
||||||
[ "Joe", "Public", 42, "male" ]
|
[ "Joe", "Public", 42, "male" ]
|
||||||
[ "Jane", "Doe", 31, "female" ]
|
[ "Jane", "Doe", 31, "female" ]
|
||||||
|
@ -36,9 +36,6 @@ errors occurred.
|
||||||
|
|
||||||
!SECTION Importing into Edge Collections
|
!SECTION Importing into Edge Collections
|
||||||
|
|
||||||
Please note that when importing documents into an [edge collection](../Glossary/README.md#edge-collection), it is
|
Please note that when importing documents into an [edge collection](../Glossary/README.md#edge-collection),
|
||||||
mandatory that all imported documents contain the *_from* and *_to* attributes,
|
it is mandatory that all imported documents contain the *_from* and *_to* attributes,
|
||||||
and that these contain references to existing collections.
|
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.
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ the data are line-wise JSON documents (type = documents) or a JSON array (type =
|
||||||
*Examples*
|
*Examples*
|
||||||
|
|
||||||
```js
|
```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 }
|
{ "name" : "test", "gender" : "male", "age" : 39 }
|
||||||
{ "type" : "bird", "name" : "robin" }
|
{ "type" : "bird", "name" : "robin" }
|
||||||
|
|
||||||
|
|
|
@ -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.
|
contained in the body of the POST request.
|
||||||
|
|
||||||
The *collection* query parameter must be used to specify the target collection for
|
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
|
the import. Importing data into a non-existing collection will produce an error.
|
||||||
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 *waitForSync* query parameter can be set to *true* to make the import only
|
The *waitForSync* query parameter can be set to *true* to make the import only
|
||||||
return if all documents have been synced to disk.
|
return if all documents have been synced to disk.
|
||||||
|
|
|
@ -5,25 +5,25 @@ a document. Any document can be retrieved using its unique URI:
|
||||||
|
|
||||||
http://server:port/_api/document/<document-handle>
|
http://server:port/_api/document/<document-handle>
|
||||||
|
|
||||||
Edges are a special variation of documents, and to work with edges, the above URL
|
Edges are a special variation of documents. To access an edge use the same
|
||||||
format changes to:
|
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*
|
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:
|
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
|
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
|
default database will be used. To explicitly specify the database context, use
|
||||||
the following URL schema:
|
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*:
|
*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.
|
**Note**: that the following examples use the short URL format for brevity.
|
||||||
|
|
||||||
|
|
|
@ -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
|
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
|
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.
|
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`
|
Collections can still be created easily via a separate call to POST `/_api/collection`
|
||||||
as before.
|
as before.
|
||||||
|
|
|
@ -15,16 +15,6 @@ subsequent lines.
|
||||||
@RESTQUERYPARAM{collection,string,required}
|
@RESTQUERYPARAM{collection,string,required}
|
||||||
The collection name.
|
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}
|
@RESTQUERYPARAM{fromPrefix,string,optional}
|
||||||
An optional prefix for the values in `_from` attributes. If specified, the
|
An optional prefix for the values in `_from` attributes. If specified, the
|
||||||
value is automatically prepended to each `_from` input value. This allows
|
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);
|
db._drop(cn);
|
||||||
@END_EXAMPLE_ARANGOSH_RUN
|
@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`
|
Importing into an edge collection, with attributes `_from`, `_to` and `name`
|
||||||
|
|
||||||
@EXAMPLE_ARANGOSH_RUN{RestImportCsvEdge}
|
@EXAMPLE_ARANGOSH_RUN{RestImportCsvEdge}
|
||||||
|
|
|
@ -24,16 +24,6 @@ the following values:
|
||||||
@RESTQUERYPARAM{collection,string,required}
|
@RESTQUERYPARAM{collection,string,required}
|
||||||
The collection name.
|
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}
|
@RESTQUERYPARAM{fromPrefix,string,optional}
|
||||||
An optional prefix for the values in `_from` attributes. If specified, the
|
An optional prefix for the values in `_from` attributes. If specified, the
|
||||||
value is automatically prepended to each `_from` input value. This allows
|
value is automatically prepended to each `_from` input value. This allows
|
||||||
|
@ -222,33 +212,6 @@ Using the auto type detection
|
||||||
db._drop(cn);
|
db._drop(cn);
|
||||||
@END_EXAMPLE_ARANGOSH_RUN
|
@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`
|
Importing into an edge collection, with attributes `_from`, `_to` and `name`
|
||||||
|
|
||||||
@EXAMPLE_ARANGOSH_RUN{RestImportJsonEdge}
|
@EXAMPLE_ARANGOSH_RUN{RestImportJsonEdge}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
@startDocuBlock API_EDGE_CREATE
|
@startDocuBlock API_EDGE_CREATE
|
||||||
@brief creates an edge
|
@brief creates an edge
|
||||||
|
|
||||||
@RESTHEADER{POST /_api/edge,Create edge}
|
@RESTHEADER{POST /_api/document,Create edge}
|
||||||
|
|
||||||
@RESTALLBODYPARAM{edge-document,json,required}
|
@RESTALLBODYPARAM{edge-document,json,required}
|
||||||
A JSON representation of the edge document must be passed as the body of
|
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}
|
@RESTQUERYPARAM{collection,string,required}
|
||||||
Creates a new edge in the collection identified by *collection* name.
|
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}
|
@RESTQUERYPARAM{waitForSync,boolean,optional}
|
||||||
Wait until the edge document has been synced to disk.
|
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
|
representation of the document must be passed as the body of the POST
|
||||||
request.
|
request.
|
||||||
|
|
||||||
The *from* and *to* handles are immutable once the edge has been created.
|
In all other respects the method works like *POST /_api/document* for
|
||||||
|
documents.
|
||||||
In all other respects the method works like *POST /document*.
|
|
||||||
|
|
||||||
@RESTRETURNCODES
|
@RESTRETURNCODES
|
||||||
|
|
||||||
|
@ -68,7 +59,7 @@ Create an edge and read it back:
|
||||||
var g = new Graph("graph", "vertices", "edges");
|
var g = new Graph("graph", "vertices", "edges");
|
||||||
g.addVertex(1);
|
g.addVertex(1);
|
||||||
g.addVertex(2);
|
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" });
|
var response = logCurlRequest("POST", url, { "name": "Emil" });
|
||||||
|
|
||||||
|
@ -77,7 +68,7 @@ Create an edge and read it back:
|
||||||
logJsonResponse(response);
|
logJsonResponse(response);
|
||||||
var body = response.body.replace(/\\/g, '');
|
var body = response.body.replace(/\\/g, '');
|
||||||
var edge_id = JSON.parse(body)._id;
|
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);
|
assert(response2.code === 200);
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
@startDocuBlock API_EDGE_DELETE
|
@startDocuBlock API_EDGE_DELETE
|
||||||
@brief deletes an edge
|
@brief deletes an edge
|
||||||
|
|
||||||
@RESTHEADER{DELETE /_api/edge/{document-handle}, Deletes edge}
|
@RESTHEADER{DELETE /_api/document/{document-handle}, Deletes edge}
|
||||||
|
|
||||||
@RESTURLPARAMETERS
|
@RESTURLPARAMETERS
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
@startDocuBlock API_EDGE_READ
|
@startDocuBlock API_EDGE_READ
|
||||||
@brief reads a single edge
|
@brief reads a single edge
|
||||||
|
|
||||||
@RESTHEADER{GET /_api/edge/{document-handle}, Read edge}
|
@RESTHEADER{GET /_api/document/{document-handle}, Read edge}
|
||||||
|
|
||||||
@RESTURLPARAMETERS
|
@RESTURLPARAMETERS
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
@startDocuBlock API_EDGE_READ_ALL
|
@startDocuBlock API_EDGE_READ_ALL
|
||||||
@brief reads all edges from collection
|
@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
|
@RESTQUERYPARAMETERS
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
@startDocuBlock API_EDGE_READ_HEAD
|
@startDocuBlock API_EDGE_READ_HEAD
|
||||||
@brief reads a single edge 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
|
@RESTURLPARAMETERS
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
@startDocuBlock API_EDGE_REPLACE
|
@startDocuBlock API_EDGE_REPLACE
|
||||||
@brief replaces an edge
|
@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}
|
@RESTALLBODYPARAM{edge,json,required}
|
||||||
A JSON representation of the new edge data.
|
A JSON representation of the new edge data.
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
@startDocuBlock API_EDGE_UPDATES
|
@startDocuBlock API_EDGE_UPDATES
|
||||||
@brief updates an edge
|
@brief updates an edge
|
||||||
|
|
||||||
@RESTHEADER{PATCH /_api/edge/{document-handle}, Patches edge}
|
@RESTHEADER{PATCH /_api/document/{document-handle}, Patches edge}
|
||||||
|
|
||||||
@RESTALLBODYPARAM{document,json,required}
|
@RESTALLBODYPARAM{document,json,required}
|
||||||
A JSON representation of the edge update.
|
A JSON representation of the edge update.
|
||||||
|
|
|
@ -116,23 +116,6 @@ HttpHandler::status_t RestImportHandler::execute() {
|
||||||
return status_t(HANDLER_DONE);
|
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
|
/// @brief create a position string
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -355,10 +338,6 @@ bool RestImportHandler::createFromJson(std::string const& type) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!checkCreateCollection(collectionName, getCollectionType())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool linewise;
|
bool linewise;
|
||||||
|
|
||||||
if (type == "documents") {
|
if (type == "documents") {
|
||||||
|
@ -588,10 +567,6 @@ bool RestImportHandler::createFromKeyValueList() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!checkCreateCollection(collectionName, getCollectionType())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// read line number (optional)
|
// read line number (optional)
|
||||||
int64_t lineNumber = 0;
|
int64_t lineNumber = 0;
|
||||||
std::string const& lineNumValue = _request->value("line", found);
|
std::string const& lineNumValue = _request->value("line", found);
|
||||||
|
|
|
@ -68,11 +68,6 @@ class RestImportHandler : public RestVocbaseBaseHandler {
|
||||||
status_t execute() override final;
|
status_t execute() override final;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief determine the collection type from the request
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
TRI_col_type_e getCollectionType();
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief create a position string
|
/// @brief create a position string
|
||||||
|
|
|
@ -199,49 +199,6 @@ void RestVocbaseBaseHandler::generateDeleted(
|
||||||
generate20x(result, collectionName, type, options);
|
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
|
/// @brief generates a HTTP 20x response
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -145,20 +145,6 @@ class RestVocbaseBaseHandler : public RestBaseHandler {
|
||||||
|
|
||||||
std::string assembleDocumentId(std::string const&, std::string const&, bool);
|
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
|
/// @brief generates a HTTP 201 or 202 response
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -29,17 +29,18 @@
|
||||||
#include "Logger/Logger.h"
|
#include "Logger/Logger.h"
|
||||||
#include "Basics/tri-strings.h"
|
#include "Basics/tri-strings.h"
|
||||||
#include "Basics/VelocyPackHelper.h"
|
#include "Basics/VelocyPackHelper.h"
|
||||||
|
#include "Rest/GeneralResponse.h"
|
||||||
#include "Rest/HttpRequest.h"
|
#include "Rest/HttpRequest.h"
|
||||||
#include "SimpleHttpClient/SimpleHttpClient.h"
|
#include "SimpleHttpClient/SimpleHttpClient.h"
|
||||||
#include "SimpleHttpClient/SimpleHttpResult.h"
|
#include "SimpleHttpClient/SimpleHttpResult.h"
|
||||||
|
|
||||||
|
#include <velocypack/Builder.h>
|
||||||
#include <velocypack/Iterator.h>
|
#include <velocypack/Iterator.h>
|
||||||
#include <velocypack/velocypack-aliases.h>
|
#include <velocypack/velocypack-aliases.h>
|
||||||
|
|
||||||
using namespace arangodb;
|
using namespace arangodb;
|
||||||
using namespace arangodb::basics;
|
using namespace arangodb::basics;
|
||||||
using namespace arangodb::httpclient;
|
using namespace arangodb::httpclient;
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief helper function to determine if a field value is an integer
|
/// @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
|
/// @brief return the collection-related URL part
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
std::string ImportHelper::getCollectionUrlPart() {
|
std::string ImportHelper::getCollectionUrlPart() const {
|
||||||
std::string part("collection=" + StringUtils::urlEncode(_collectionName));
|
return std::string("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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -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() {
|
void ImportHelper::sendCsvBuffer() {
|
||||||
if (_hasError) {
|
if (_hasError) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!checkCreateCollection()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
std::unordered_map<std::string, std::string> headerFields;
|
std::unordered_map<std::string, std::string> headerFields;
|
||||||
std::string url("/_api/import?" + getCollectionUrlPart() + "&line=" +
|
std::string url("/_api/import?" + getCollectionUrlPart() + "&line=" +
|
||||||
|
@ -630,6 +660,11 @@ void ImportHelper::sendCsvBuffer() {
|
||||||
if (!_toCollectionPrefix.empty()) {
|
if (!_toCollectionPrefix.empty()) {
|
||||||
url += "&toPrefix=" + StringUtils::urlEncode(_toCollectionPrefix);
|
url += "&toPrefix=" + StringUtils::urlEncode(_toCollectionPrefix);
|
||||||
}
|
}
|
||||||
|
if (_firstChunk && _overwrite) {
|
||||||
|
url += "&overwrite=true";
|
||||||
|
}
|
||||||
|
|
||||||
|
_firstChunk = false;
|
||||||
|
|
||||||
std::unique_ptr<SimpleHttpResult> result(_client->request(
|
std::unique_ptr<SimpleHttpResult> result(_client->request(
|
||||||
GeneralRequest::RequestType::POST, url, _outputBuffer.c_str(),
|
GeneralRequest::RequestType::POST, url, _outputBuffer.c_str(),
|
||||||
|
@ -646,6 +681,10 @@ void ImportHelper::sendJsonBuffer(char const* str, size_t len, bool isObject) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!checkCreateCollection()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// build target url
|
// build target url
|
||||||
std::string url("/_api/import?" + getCollectionUrlPart() +
|
std::string url("/_api/import?" + getCollectionUrlPart() +
|
||||||
"&details=true&onDuplicate=" +
|
"&details=true&onDuplicate=" +
|
||||||
|
@ -662,6 +701,11 @@ void ImportHelper::sendJsonBuffer(char const* str, size_t len, bool isObject) {
|
||||||
if (!_toCollectionPrefix.empty()) {
|
if (!_toCollectionPrefix.empty()) {
|
||||||
url += "&toPrefix=" + StringUtils::urlEncode(_toCollectionPrefix);
|
url += "&toPrefix=" + StringUtils::urlEncode(_toCollectionPrefix);
|
||||||
}
|
}
|
||||||
|
if (_firstChunk && _overwrite) {
|
||||||
|
url += "&overwrite=true";
|
||||||
|
}
|
||||||
|
|
||||||
|
_firstChunk = false;
|
||||||
|
|
||||||
std::unordered_map<std::string, std::string> headerFields;
|
std::unordered_map<std::string, std::string> headerFields;
|
||||||
std::unique_ptr<SimpleHttpResult> result(_client->request(
|
std::unique_ptr<SimpleHttpResult> result(_client->request(
|
||||||
|
|
|
@ -203,12 +203,13 @@ class ImportHelper {
|
||||||
|
|
||||||
void reportProgress(int64_t, int64_t, double&);
|
void reportProgress(int64_t, int64_t, double&);
|
||||||
|
|
||||||
std::string getCollectionUrlPart();
|
std::string getCollectionUrlPart() const;
|
||||||
void beginLine(size_t row);
|
void beginLine(size_t row);
|
||||||
void addField(char const*, size_t, size_t row, size_t column, bool escaped);
|
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,
|
void addLastField(char const*, size_t, size_t row, size_t column,
|
||||||
bool escaped);
|
bool escaped);
|
||||||
|
|
||||||
|
bool checkCreateCollection();
|
||||||
void sendCsvBuffer();
|
void sendCsvBuffer();
|
||||||
void sendJsonBuffer(char const* str, size_t len, bool isObject);
|
void sendJsonBuffer(char const* str, size_t len, bool isObject);
|
||||||
void handleResult(httpclient::SimpleHttpResult* result);
|
void handleResult(httpclient::SimpleHttpResult* result);
|
||||||
|
|
Loading…
Reference in New Issue