예제 #1
0
static MRubyClientConnection* createConnection (mrb_state* mrb) {
  return new MRubyClientConnection(mrb,
                                   BaseClient.endpointServer(),
                                   BaseClient.username(),
                                   BaseClient.password(),
                                   BaseClient.requestTimeout(),
                                   BaseClient.connectTimeout(),
                                   ArangoClient::DEFAULT_RETRIES,
                                   false);
}
예제 #2
0
static int TryCreateDatabase (std::string const& name) {

  triagens::basics::Json json(triagens::basics::Json::Object);
  json("name", triagens::basics::Json(name));

  triagens::basics::Json user(triagens::basics::Json::Object);
  user("username", triagens::basics::Json(BaseClient.username()));
  user("passwd", triagens::basics::Json(BaseClient.password()));

  triagens::basics::Json users(triagens::basics::Json::Array);
  users.add(user);
  json("users", users);
                                               
  std::string const body(triagens::basics::JsonHelper::toString(json.json()));

  std::unique_ptr<SimpleHttpResult> response(Client->request(HttpRequest::HTTP_REQUEST_POST,
                                               "/_api/database",
                                               body.c_str(),
                                               body.size()));

  if (response == nullptr || ! response->isComplete()) {
    return TRI_ERROR_INTERNAL;
  }

  auto returnCode = response->getHttpReturnCode();

  if (returnCode == HttpResponse::OK ||
      returnCode == HttpResponse::CREATED) {
    // all ok
    return TRI_ERROR_NO_ERROR;
  }
  else if (returnCode == HttpResponse::UNAUTHORIZED ||
           returnCode == HttpResponse::FORBIDDEN) {
    // invalid authorization
    Client->setErrorMessage(GetHttpErrorMessage(response.get()), false);
    return TRI_ERROR_FORBIDDEN;
  }

  // any other error
  Client->setErrorMessage(GetHttpErrorMessage(response.get()), false);
  return TRI_ERROR_INTERNAL;
}
예제 #3
0
int main (int argc, char* argv[]) {
  int ret = EXIT_SUCCESS;

  arangodumpEntryFunction();

  TRIAGENS_C_INITIALISE(argc, argv);
  TRIAGENS_REST_INITIALISE(argc, argv);

  TRI_InitialiseLogging(false);
  
  // .............................................................................
  // set defaults
  // .............................................................................

  int err = 0;
  OutputDirectory = FileUtils::currentDirectory(&err).append(TRI_DIR_SEPARATOR_STR).append("dump");
  BaseClient.setEndpointString(Endpoint::getDefaultEndpoint());

  // .............................................................................
  // parse the program options
  // .............................................................................

  ParseProgramOptions(argc, argv);

  // use a minimum value for batches
  if (ChunkSize < 1024 * 128) {
    ChunkSize = 1024 * 128;
  }

  if (TickStart < TickEnd) {
    cerr << "invalid values for --tick-start or --tick-end" << endl;
    TRI_EXIT_FUNCTION(EXIT_FAILURE, NULL);
  }

  // .............................................................................
  // create output directory
  // .............................................................................

  bool isDirectory = false;
  if (OutputDirectory != "") {
    isDirectory = TRI_IsDirectory(OutputDirectory.c_str());
  }

  if (OutputDirectory == "" ||
      (TRI_ExistsFile(OutputDirectory.c_str()) && ! isDirectory)) {
    cerr << "cannot write to output directory '" << OutputDirectory << "'" << endl;
    TRI_EXIT_FUNCTION(EXIT_FAILURE, NULL);
  }

  if (isDirectory && ! Overwrite) {
    cerr << "output directory '" << OutputDirectory << "' already exists. use --overwrite to overwrite data in in it" << endl;
    TRI_EXIT_FUNCTION(EXIT_FAILURE, NULL);
  }

  // .............................................................................
  // set-up client connection
  // .............................................................................

  BaseClient.createEndpoint();

  if (BaseClient.endpointServer() == 0) {
    cerr << "invalid value for --server.endpoint ('" << BaseClient.endpointString() << "')" << endl;
    TRI_EXIT_FUNCTION(EXIT_FAILURE, NULL);
  }

  Connection = GeneralClientConnection::factory(BaseClient.endpointServer(),
                                                BaseClient.requestTimeout(),
                                                BaseClient.connectTimeout(),
                                                ArangoClient::DEFAULT_RETRIES,
                                                BaseClient.sslProtocol());
  
  if (Connection == 0) {
    cerr << "out of memory" << endl;
    TRI_EXIT_FUNCTION(EXIT_FAILURE, NULL);
  }
  
  Client = new SimpleHttpClient(Connection, BaseClient.requestTimeout(), false);

  if (Client == 0) {
    cerr << "out of memory" << endl;
    TRI_EXIT_FUNCTION(EXIT_FAILURE, NULL);
  }

  Client->setLocationRewriter(0, &rewriteLocation);
  Client->setUserNamePassword("/", BaseClient.username(), BaseClient.password());

  const string versionString = GetArangoVersion();

  if (! Connection->isConnected()) {
    cerr << "Could not connect to endpoint '" << BaseClient.endpointString() 
         << "', database: '" << BaseClient.databaseName() << "', username: '******'" << endl;
    cerr << "Error message: '" << Client->getErrorMessage() << "'" << endl;
    TRI_EXIT_FUNCTION(EXIT_FAILURE, NULL);
  }
    
  // successfully connected

  // validate server version 
  int major = 0;
  int minor = 0;

  if (sscanf(versionString.c_str(), "%d.%d", &major, &minor) != 2) {
    cerr << "Invalid server version '" << versionString << "'" << endl;
    TRI_EXIT_FUNCTION(EXIT_FAILURE, NULL);
  }

  if (major != 1 ||
      (major == 1 && minor < 4)) {
    // we can connect to 1.4 and higher only
    cerr << "Got an incompatible server version '" << versionString << "'" << endl;
    TRI_EXIT_FUNCTION(EXIT_FAILURE, NULL);
  }
  
  
  if (! isDirectory) {
    int res = TRI_CreateDirectory(OutputDirectory.c_str());

    if (res != TRI_ERROR_NO_ERROR) {
      cerr << "unable to create output directory '" << OutputDirectory << "': " << string(TRI_errno_string(res)) << endl;
      TRI_EXIT_FUNCTION(EXIT_FAILURE, NULL);
    }
  }


  if (Progress) {
    cout << "Connected to ArangoDB '" << BaseClient.endpointString() 
          << "', database: '" << BaseClient.databaseName() << "', username: '******'" << endl;
    
    cout << "Writing dump to output directory '" << OutputDirectory << "'" << endl;
  }
  
  memset(&Stats, 0, sizeof(Stats));

  string errorMsg = "";

  int res = StartBatch(errorMsg);

  if (res == TRI_ERROR_NO_ERROR) {
    res = RunDump(errorMsg);
  }
  
  if (BatchId > 0) {
    EndBatch();
  }
  
  if (Progress) {
    if (DumpData) {
      cout << "Processed " << Stats._totalCollections << " collection(s), " << 
              "wrote " << Stats._totalWritten << " byte(s) into datafiles, " << 
              "sent " << Stats._totalBatches << " batch(es)" << endl;
    }
    else {
      cout << "Processed " << Stats._totalCollections << " collection(s)" << endl;
    }
  }

  if (res != TRI_ERROR_NO_ERROR) {
    cerr << errorMsg << endl;
    ret = EXIT_FAILURE;
  }

  TRIAGENS_REST_SHUTDOWN;

  arangodumpExitFunction(ret, NULL);

  return ret;
}
예제 #4
0
int main (int argc, char* argv[]) {
  int ret = EXIT_SUCCESS;

  LocalEntryFunction();

  TRIAGENS_C_INITIALIZE(argc, argv);
  TRIAGENS_REST_INITIALIZE(argc, argv);

  TRI_InitializeLogging(false);

  // .............................................................................
  // set defaults
  // .............................................................................

  BaseClient.setEndpointString(Endpoint::getDefaultEndpoint());

  // .............................................................................
  // parse the program options
  // .............................................................................

  ParseProgramOptions(argc, argv);

  // use a minimum value for batches
  if (ChunkSize < 1024 * 128) {
    ChunkSize = 1024 * 128;
  }

  if (! InputDirectory.empty() &&
      InputDirectory.back() == TRI_DIR_SEPARATOR_CHAR) {
    // trim trailing slash from path because it may cause problems on ... Windows
    TRI_ASSERT(InputDirectory.size() > 0);
    InputDirectory.pop_back();
  }

  // .............................................................................
  // check input directory
  // .............................................................................

  if (InputDirectory == "" || ! TRI_IsDirectory(InputDirectory.c_str())) {
    cerr << "Error: input directory '" << InputDirectory << "' does not exist" << endl;
    TRI_EXIT_FUNCTION(EXIT_FAILURE, nullptr);
  }

  if (! ImportStructure && ! ImportData) {
    cerr << "Error: must specify either --create-collection or --import-data" << endl;
    TRI_EXIT_FUNCTION(EXIT_FAILURE, nullptr);
  }

  // .............................................................................
  // set-up client connection
  // .............................................................................

  BaseClient.createEndpoint();

  if (BaseClient.endpointServer() == nullptr) {
    cerr << "Error: invalid value for --server.endpoint ('" << BaseClient.endpointString() << "')" << endl;
    TRI_EXIT_FUNCTION(EXIT_FAILURE, nullptr);
  }

  Connection = GeneralClientConnection::factory(BaseClient.endpointServer(),
                                                BaseClient.requestTimeout(),
                                                BaseClient.connectTimeout(),
                                                ArangoClient::DEFAULT_RETRIES,
                                                BaseClient.sslProtocol());

  Client = new SimpleHttpClient(Connection, BaseClient.requestTimeout(), false);

  Client->setLocationRewriter(nullptr, &rewriteLocation);
  Client->setUserNamePassword("/", BaseClient.username(), BaseClient.password());

  string versionString = GetArangoVersion();
    
  if (CreateDatabase && LastErrorCode == TRI_ERROR_ARANGO_DATABASE_NOT_FOUND) {
    // database not found, but database creation requested
   
    std::string old = BaseClient.databaseName();
    cout << "Creating database '" << old << "'" << endl;

    BaseClient.setDatabaseName("_system");

    int res = TryCreateDatabase(old);

    if (res != TRI_ERROR_NO_ERROR) {
      cerr << "Could not create database '" << old << "'" << endl;
      cerr << "Error message: '" << Client->getErrorMessage() << "'" << endl;
      TRI_EXIT_FUNCTION(EXIT_FAILURE, nullptr);
    }

    // restore old database name
    BaseClient.setDatabaseName(old);

    // re-fetch version
    versionString = GetArangoVersion();
  }

  if (! Connection->isConnected()) {
    cerr << "Could not connect to endpoint " << BaseClient.endpointServer()->getSpecification() << endl;
    cerr << "Error message: '" << Client->getErrorMessage() << "'" << endl;
    TRI_EXIT_FUNCTION(EXIT_FAILURE, nullptr);
  }

  // successfully connected
  cout << "Server version: " << versionString << endl;

  // validate server version
  int major = 0;
  int minor = 0;

  if (sscanf(versionString.c_str(), "%d.%d", &major, &minor) != 2) {
    cerr << "Error: invalid server version '" << versionString << "'" << endl;
    TRI_EXIT_FUNCTION(EXIT_FAILURE, nullptr);
  }

  if (major < 1 ||
      major > 2 ||
      (major == 1 && minor < 4)) {
    // we can connect to 1.4, 2.0 and higher only
    cerr << "Error: got incompatible server version '" << versionString << "'" << endl;
    if (! Force) {
      TRI_EXIT_FUNCTION(EXIT_FAILURE, nullptr);
    }
  }

  if (major >= 2) {
    // Version 1.4 did not yet have a cluster mode
    ClusterMode = GetArangoIsCluster();
  }

  if (Progress) {
    cout << "Connected to ArangoDB '" << BaseClient.endpointServer()->getSpecification() << endl;
  }

  memset(&Stats, 0, sizeof(Stats));

  string errorMsg = "";

  int res;
  try {
    res = ProcessInputDirectory(errorMsg);
  }
  catch (std::exception const& ex) {
    cerr << "Error: caught exception " << ex.what() << endl;
    res = TRI_ERROR_INTERNAL;
  }
  catch (...) {
    cerr << "Error: caught unknown exception" << endl;
    res = TRI_ERROR_INTERNAL;
  }


  if (Progress) {
    if (ImportData) {
      cout << "Processed " << Stats._totalCollections << " collection(s), " <<
              "read " << Stats._totalRead << " byte(s) from datafiles, " <<
              "sent " << Stats._totalBatches << " batch(es)" << endl;
    }
    else if (ImportStructure) {
      cout << "Processed " << Stats._totalCollections << " collection(s)" << endl;
    }
  }


  if (res != TRI_ERROR_NO_ERROR) {
    if (! errorMsg.empty()) {
      cerr << "Error: " << errorMsg << endl;
    }
    ret = EXIT_FAILURE;
  }

  if (Client != nullptr) {
    delete Client;
  }

  TRIAGENS_REST_SHUTDOWN;

  LocalExitFunction(ret, nullptr);

  return ret;
}
예제 #5
0
int main (int argc, char* argv[]) {
  int ret = EXIT_SUCCESS;

  arangorestoreEntryFunction();

  TRIAGENS_C_INITIALISE(argc, argv);
  TRIAGENS_REST_INITIALISE(argc, argv);

  TRI_InitialiseLogging(false);

  // .............................................................................
  // set defaults
  // .............................................................................

  BaseClient.setEndpointString(Endpoint::getDefaultEndpoint());

  // .............................................................................
  // parse the program options
  // .............................................................................

  ParseProgramOptions(argc, argv);

  // use a minimum value for batches
  if (ChunkSize < 1024 * 128) {
    ChunkSize = 1024 * 128;
  }

  // .............................................................................
  // check input directory
  // .............................................................................

  if (InputDirectory == "" || ! TRI_IsDirectory(InputDirectory.c_str())) {
    cerr << "input directory '" << InputDirectory << "' does not exist" << endl;
    TRI_EXIT_FUNCTION(EXIT_FAILURE, NULL);
  }

  if (! ImportStructure && ! ImportData) {
    cerr << "must specify either --create-collection or --import-data" << endl;
    TRI_EXIT_FUNCTION(EXIT_FAILURE, NULL);
  }

  // .............................................................................
  // set-up client connection
  // .............................................................................

  BaseClient.createEndpoint();

  if (BaseClient.endpointServer() == 0) {
    cerr << "invalid value for --server.endpoint ('" << BaseClient.endpointString() << "')" << endl;
    TRI_EXIT_FUNCTION(EXIT_FAILURE, NULL);
  }

  Connection = GeneralClientConnection::factory(BaseClient.endpointServer(),
                                                BaseClient.requestTimeout(),
                                                BaseClient.connectTimeout(),
                                                ArangoClient::DEFAULT_RETRIES,
                                                BaseClient.sslProtocol());

  if (Connection == 0) {
    cerr << "out of memory" << endl;
    TRI_EXIT_FUNCTION(EXIT_FAILURE, NULL);
  }

  Client = new SimpleHttpClient(Connection, BaseClient.requestTimeout(), false);

  if (Client == 0) {
    cerr << "out of memory" << endl;
    TRI_EXIT_FUNCTION(EXIT_FAILURE, NULL);
  }

  Client->setLocationRewriter(0, &rewriteLocation);
  Client->setUserNamePassword("/", BaseClient.username(), BaseClient.password());

  const string versionString = GetArangoVersion();

  if (! Connection->isConnected()) {
    cerr << "Could not connect to endpoint " << BaseClient.endpointServer()->getSpecification() << endl;
    cerr << "Error message: '" << Client->getErrorMessage() << "'" << endl;
    TRI_EXIT_FUNCTION(EXIT_FAILURE, NULL);
  }

  // successfully connected
  cout << "Server version: " << versionString << endl;

  // validate server version
  int major = 0;
  int minor = 0;

  if (sscanf(versionString.c_str(), "%d.%d", &major, &minor) != 2) {
    cerr << "invalid server version '" << versionString << "'" << endl;
    TRI_EXIT_FUNCTION(EXIT_FAILURE, NULL);
  }

  if (major < 1 ||
      major > 2 ||
      (major == 1 && minor < 4)) {
    // we can connect to 1.4, 2.0 and higher only
    cerr << "got incompatible server version '" << versionString << "'" << endl;
    if (! Force) {
      TRI_EXIT_FUNCTION(EXIT_FAILURE, NULL);
    }
  }

  if (major >= 2) {
    // Version 1.4 did not yet have a cluster mode
    clusterMode = GetArangoIsCluster();
  }

  if (Progress) {
    cout << "Connected to ArangoDB '" << BaseClient.endpointServer()->getSpecification() << endl;
  }

  memset(&Stats, 0, sizeof(Stats));

  string errorMsg = "";
  int res = ProcessInputDirectory(errorMsg);

  if (Progress) {
    if (ImportData) {
      cout << "Processed " << Stats._totalCollections << " collection(s), " <<
              "read " << Stats._totalRead << " byte(s) from datafiles, " <<
              "sent " << Stats._totalBatches << " batch(es)" << endl;
    }
    else if (ImportStructure) {
      cout << "Processed " << Stats._totalCollections << " collection(s)" << endl;
    }
  }


  if (res != TRI_ERROR_NO_ERROR) {
    cerr << errorMsg << endl;
    ret = EXIT_FAILURE;
  }

  if (Client != 0) {
    delete Client;
  }

  TRIAGENS_REST_SHUTDOWN;

  arangorestoreExitFunction(ret, NULL);

  return ret;
}
예제 #6
0
int main (int argc, char* argv[]) {
    int ret = EXIT_SUCCESS;

    arangobEntryFunction();

    TRIAGENS_C_INITIALIZE(argc, argv);
    TRIAGENS_REST_INITIALIZE(argc, argv);

    TRI_InitializeLogging(false);

    BaseClient.setEndpointString(Endpoint::getDefaultEndpoint());

    // .............................................................................
    // parse the program options
    // .............................................................................

    ParseProgramOptions(argc, argv);

    // .............................................................................
    // set-up client connection
    // .............................................................................

    BaseClient.createEndpoint();

    if (BaseClient.endpointServer() == nullptr) {
        LOG_FATAL_AND_EXIT("invalid value for --server.endpoint ('%s')", BaseClient.endpointString().c_str());
    }

    BenchmarkOperation* testCase = GetTestCase(TestCase);

    if (testCase == nullptr) {
        LOG_FATAL_AND_EXIT("invalid test case name '%s'", TestCase.c_str());
        return EXIT_FAILURE; // will not be reached
    }

    Status("starting threads...");

    BenchmarkCounter<unsigned long> operationsCounter(0, (unsigned long) Operations);
    ConditionVariable startCondition;


    vector<Endpoint*> endpoints;
    vector<BenchmarkThread*> threads;

    const double stepSize = (double) Operations / (double) ThreadConcurrency;
    int64_t realStep = (int64_t) stepSize;
    if (stepSize - (double) ((int64_t) stepSize) > 0.0) {
        realStep++;
    }
    if (realStep % 1000 != 0) {
        realStep += 1000 - (realStep % 1000);
    }
    // add some more offset so we don't get into trouble with threads of different speed
    realStep += 10000;

    // start client threads
    for (int i = 0; i < ThreadConcurrency; ++i) {
        Endpoint* endpoint = Endpoint::clientFactory(BaseClient.endpointString());
        endpoints.push_back(endpoint);

        BenchmarkThread* thread = new BenchmarkThread(testCase,
                &startCondition,
                &UpdateStartCounter,
                i,
                (unsigned long) BatchSize,
                &operationsCounter,
                endpoint,
                BaseClient.databaseName(),
                BaseClient.username(),
                BaseClient.password(),
                BaseClient.requestTimeout(),
                BaseClient.connectTimeout(),
                BaseClient.sslProtocol(),
                KeepAlive,
                Async,
                verbose);

        threads.push_back(thread);
        thread->setOffset((size_t) (i * realStep));
        thread->start();
    }

    // give all threads a chance to start so they will not miss the broadcast
    while (GetStartCounter() < ThreadConcurrency) {
        usleep(5000);
    }


    if (Delay) {
        Status("sleeping (startup delay)...");
        sleep(10);
    }
    Status("executing tests...");

    double start = TRI_microtime();

    // broadcast the start signal to all threads
    {
        CONDITION_LOCKER(guard, startCondition);
        guard.broadcast();
    }

    const size_t stepValue = (Operations / 20);
    size_t nextReportValue = stepValue;

    if (nextReportValue < 100) {
        nextReportValue = 100;
    }

    while (1) {
        const size_t numOperations = operationsCounter.getDone();

        if (numOperations >= (size_t) Operations) {
            break;
        }

        if (Progress && numOperations >= nextReportValue) {
            LOG_INFO("number of operations: %d", (int) nextReportValue);
            nextReportValue += stepValue;
        }

        usleep(20000);
    }

    double time = TRI_microtime() - start;
    double requestTime = 0.0;

    for (int i = 0; i < ThreadConcurrency; ++i) {
        requestTime += threads[i]->getTime();
    }

    size_t failures = operationsCounter.failures();
    size_t incomplete = operationsCounter.incompleteFailures();

    cout << endl;
    cout << "Total number of operations: " << Operations <<
         ", keep alive: " << (KeepAlive ? "yes" : "no") <<
         ", async: " << (Async ? "yes" : "no")  <<
         ", batch size: " << BatchSize <<
         ", concurrency level (threads): " << ThreadConcurrency <<
         endl;

    cout << "Test case: " << TestCase <<
         ", complexity: " << Complexity <<
         ", database: '" << BaseClient.databaseName() <<
         "', collection: '" << Collection << "'" <<
         endl;

    cout << "Total request/response duration (sum of all threads): " << fixed << requestTime << " s" << endl;
    cout << "Request/response duration (per thread): " << fixed << (requestTime / (double) ThreadConcurrency) << " s" << endl;
    cout << "Time needed per operation: " << fixed << (time / Operations) << " s" << endl;
    cout << "Time needed per operation per thread: " << fixed << (time / (double) Operations * (double) ThreadConcurrency) << " s" << endl;
    cout << "Operations per second rate: " << fixed << ((double) Operations / time) << endl;
    cout << "Elapsed time since start: " << fixed << time << " s" << endl << endl;

    if (failures > 0) {
        cerr << "WARNING: " << failures << " arangob request(s) failed!!" << endl;
    }
    if (incomplete > 0) {
        cerr << "WARNING: " << incomplete << " arangob requests with incomplete results!!" << endl;
    }

    testCase->tearDown();

    for (int i = 0; i < ThreadConcurrency; ++i) {
        threads[i]->join();
        delete threads[i];
        delete endpoints[i];
    }

    delete testCase;

    TRIAGENS_REST_SHUTDOWN;

    if (failures > 0) {
        ret = EXIT_FAILURE;
    }

    arangobExitFunction(ret, nullptr);

    return ret;
}
예제 #7
0
int main (int argc, char* argv[]) {

  int ret = EXIT_SUCCESS;

  arangoimpEntryFunction();

  TRIAGENS_C_INITIALISE(argc, argv);
  TRIAGENS_REST_INITIALISE(argc, argv);

  TRI_InitialiseLogging(false);

  BaseClient.setEndpointString(Endpoint::getDefaultEndpoint());

  // .............................................................................
  // parse the program options
  // .............................................................................

  ParseProgramOptions(argc, argv);

  // .............................................................................
  // set-up client connection
  // .............................................................................

  BaseClient.createEndpoint();

  if (BaseClient.endpointServer() == 0) {
    cerr << "invalid value for --server.endpoint ('" << BaseClient.endpointString() << "')" << endl;
    TRI_EXIT_FUNCTION(EXIT_FAILURE, NULL);
  }

  ClientConnection = new V8ClientConnection(BaseClient.endpointServer(),
                                            BaseClient.databaseName(),
                                            BaseClient.username(),
                                            BaseClient.password(),
                                            BaseClient.requestTimeout(),
                                            BaseClient.connectTimeout(),
                                            ArangoClient::DEFAULT_RETRIES,
                                            BaseClient.sslProtocol(),
                                            false);

  if (! ClientConnection->isConnected() || 
      ClientConnection->getLastHttpReturnCode() != HttpResponse::OK) {
    cerr << "Could not connect to endpoint '" << BaseClient.endpointServer()->getSpecification() 
         << "', database: '" << BaseClient.databaseName() << "'" << endl;
    cerr << "Error message: '" << ClientConnection->getErrorMessage() << "'" << endl;
    TRI_EXIT_FUNCTION(EXIT_FAILURE, NULL);
  }

  // successfully connected
  cout << "Connected to ArangoDB '" << BaseClient.endpointServer()->getSpecification()
       << "', version " << ClientConnection->getVersion() << ", database: '" 
       << BaseClient.databaseName() << "', username: '******'" << endl;

  cout << "----------------------------------------" << endl;
  cout << "database:         " << BaseClient.databaseName() << endl;
  cout << "collection:       " << CollectionName << endl;
  cout << "create:           " << (CreateCollection ? "yes" : "no") << endl;
  cout << "file:             " << FileName << endl;
  cout << "type:             " << TypeImport << endl;

  if (TypeImport == "csv") {
    cout << "quote:            " << Quote << endl;
    cout << "separator:        " << Separator << endl;
  }

  cout << "connect timeout:  " << BaseClient.connectTimeout() << endl;
  cout << "request timeout:  " << BaseClient.requestTimeout() << endl;
  cout << "----------------------------------------" << endl;

  ImportHelper ih(ClientConnection->getHttpClient(), ChunkSize);

  // create colletion
  if (CreateCollection) {
    ih.setCreateCollection(true);
  }

  // quote
  if (Quote.length() <= 1) {
    ih.setQuote(Quote);
  }
  else {
    cerr << "Wrong length of quote character." << endl;
    TRI_EXIT_FUNCTION(EXIT_FAILURE, NULL);
  }

  // separator
  if (Separator.length() == 1) {
    ih.setSeparator(Separator);
  }
  else {
    cerr << "Separator must be exactly one character." << endl;
    TRI_EXIT_FUNCTION(EXIT_FAILURE, NULL);
  }

  // collection name
  if (CollectionName == "") {
    cerr << "Collection name is missing." << endl;
    TRI_EXIT_FUNCTION(EXIT_FAILURE, NULL);
  }

  // filename
  if (FileName == "") {
    cerr << "File name is missing." << endl;
    TRI_EXIT_FUNCTION(EXIT_FAILURE, NULL);
  }

  if (FileName != "-" && ! FileUtils::isRegularFile(FileName)) {
    if (! FileUtils::exists(FileName)) {
      cerr << "Cannot open file '" << FileName << "'. File not found." << endl;
    }
    else if (FileUtils::isDirectory(FileName)) {
      cerr << "Specified file '" << FileName << "' is a directory. Please use a regular file." << endl;
    }
    else {
      cerr << "Cannot open '" << FileName << "'. Invalid file type." << endl;
    }

    TRI_EXIT_FUNCTION(EXIT_FAILURE, NULL);
  }

  // progress
  if (Progress) {
    ih.setProgress(true);
  }

  // import type
  bool ok = false;

  if (TypeImport == "csv") {
    cout << "Starting CSV import..." << endl;
    ok = ih.importDelimited(CollectionName, FileName, ImportHelper::CSV);
  }

  else if (TypeImport == "tsv") {
    cout << "Starting TSV import..." << endl;
    ih.setQuote("");
    ih.setSeparator("\\t");
    ok = ih.importDelimited(CollectionName, FileName, ImportHelper::TSV);
  }

  else if (TypeImport == "json") {
    cout << "Starting JSON import..." << endl;
    ok = ih.importJson(CollectionName, FileName);
  }

  else {
    cerr << "Wrong type '" << TypeImport << "'." << endl;
    TRI_EXIT_FUNCTION(EXIT_FAILURE, NULL);
  }

  cout << endl;

  // give information about import
  if (ok) {
    cout << "created:          " << ih.getImportedLines() << endl;
    cout << "errors:           " << ih.getErrorLines() << endl;
    cout << "total:            " << ih.getReadLines() << endl;
  }
  else {
    cerr << "error message:    " << ih.getErrorMessage() << endl;
  }

  TRIAGENS_REST_SHUTDOWN;

  arangoimpExitFunction(ret, NULL);

  return ret;
}