GithubHelp home page GithubHelp logo

arangodb / arangojs Goto Github PK

View Code? Open in Web Editor NEW
599.0 66.0 106.0 17.36 MB

The official ArangoDB JavaScript driver.

Home Page: https://arangodb.github.io/arangojs

License: Apache License 2.0

JavaScript 0.35% TypeScript 99.65%
arangodb database javascript nosql nodejs driver

arangojs's Introduction

ArangoDB JavaScript Driver

The official ArangoDB JavaScript client for Node.js and the browser.

license - APACHE-2.0 Tests

npm package status

Links

Install

With npm or yarn

npm install --save arangojs
## - or -
yarn add arangojs

For browsers

When using modern JavaScript tooling with a bundler and compiler (e.g. Babel), arangojs can be installed using npm or yarn like any other dependency.

You can also use jsDelivr CDN during development:

<script type="importmap">
  {
    "imports": {
      "arangojs": "https://cdn.jsdelivr.net/npm/[email protected]/esm/index.js?+esm"
    }
  }
</script>
<script type="module">
  import { Database } from "arangojs";
  const db = new Database();
  // ...
</script>

Basic usage example

Modern JavaScript/TypeScript with async/await and ES Modules:

import { Database, aql } from "arangojs";

const db = new Database();
const Pokemons = db.collection("my-pokemons");

async function main() {
  try {
    const pokemons = await db.query(aql`
      FOR pokemon IN ${Pokemons}
      FILTER pokemon.type == "fire"
      RETURN pokemon
    `);
    console.log("My pokemans, let me show you them:");
    for await (const pokemon of pokemons) {
      console.log(pokemon.name);
    }
  } catch (err) {
    console.error(err.message);
  }
}

main();

Using a different database:

const db = new Database({
  url: "http://127.0.0.1:8529",
  databaseName: "pancakes",
  auth: { username: "root", password: "hunter2" },
});

// The credentials can be swapped at any time
db.useBasicAuth("admin", "maplesyrup");

Old-school JavaScript with promises and CommonJS:

var arangojs = require("arangojs");
var Database = arangojs.Database;

var db = new Database();
var pokemons = db.collection("pokemons");

db.query({
  query: "FOR p IN @@c FILTER p.type == 'fire' RETURN p",
  bindVars: { "@c": "pokemons" },
})
  .then(function (cursor) {
    console.log("My pokemons, let me show you them:");
    return cursor.forEach(function (pokemon) {
      console.log(pokemon.name);
    });
  })
  .catch(function (err) {
    console.error(err.message);
  });

Note: The examples throughout this documentation use async/await and other modern language features like multi-line strings and template tags. When developing for an environment without support for these language features, substitute promises for await syntax as in the above example.

Compatibility

The arangojs driver is compatible with the latest stable version of ArangoDB available at the time of the driver release and remains compatible with the two most recent Node.js LTS versions in accordance with the official Node.js long-term support schedule. Versions of ArangoDB that have reached their end of life by the time of a driver release are explicitly not supported.

For a list of changes between recent versions of the driver, see the CHANGELOG.

Note: arangojs is only intended to be used in Node.js or a browser to access ArangoDB from outside the database. If you are looking for the ArangoDB JavaScript API for Foxx or for accessing ArangoDB from within the arangosh interactive shell, please refer to the documentation of the @arangodb module and the db object instead.

Error responses

If arangojs encounters an API error, it will throw an ArangoError with an errorNum property indicating the ArangoDB error code and the code property indicating the HTTP status code from the response body.

For any other non-ArangoDB error responses (4xx/5xx status code), it will throw an HttpError error with the status code indicated by the code property.

If the server response did not indicate an error but the response body could not be parsed, a regular SyntaxError may be thrown instead.

In all of these cases the server response object will be exposed as the response property on the error object.

If the request failed at a network level or the connection was closed without receiving a response, the underlying system error will be thrown instead.

Common issues

Missing functions or unexpected server errors

Please make sure you are using the latest version of this driver and that the version of the arangojs documentation you are reading matches that version.

Changes in the major version number of arangojs (e.g. 7.x.y -> 8.0.0) indicate backwards-incompatible changes in the arangojs API that may require changes in your code when upgrading your version of arangojs.

Additionally please ensure that your version of Node.js (or browser) and ArangoDB are supported by the version of arangojs you are trying to use. See the compatibility section for additional information.

Note: As of June 2018 ArangoDB 2.8 has reached its End of Life and is no longer supported in arangojs 7 and later. If your code needs to work with ArangoDB 2.8 you can continue using arangojs 6 and enable ArangoDB 2.8 compatibility mode by setting the config option arangoVersion: 20800 to enable the ArangoDB 2.8 compatibility mode in arangojs 6.

You can install an older version of arangojs using npm or yarn:

# for version 6.x.x
yarn add arangojs@6
# - or -
npm install --save arangojs@6

No code intelligence when using require instead of import

If you are using require to import the arangojs module in JavaScript, the default export might not be recognized as a function by the code intelligence of common editors like Visual Studio Code, breaking auto-complete and other useful features.

As a workaround, use the arangojs function exported by that module instead of calling the module itself:

  const arangojs = require("arangojs");

- const db = arangojs({
+ const db = arangojs.arangojs({
    url: ARANGODB_SERVER,
  });

Alternatively you can use the Database class directly:

  const arangojs = require("arangojs");
+ const Database = arangojs.Database;

- const db = arangojs({
+ const db = new Database({
    url: ARANGODB_SERVER,
  });

Or using object destructuring:

- const arangojs = require("arangojs");
+ const { Database } = require("arangojs");

- const db = arangojs({
+ const db = new Database({
    url: ARANGODB_SERVER,
  });

Error stack traces contain no useful information

Due to the async, queue-based behavior of arangojs, the stack traces generated when an error occur rarely provide enough information to determine the location in your own code where the request was initiated.

Using the precaptureStackTraces configuration option, arangojs will attempt to always generate stack traces proactively when a request is performed, allowing arangojs to provide more meaningful stack traces at the cost of an impact to performance even when no error occurs.

  const { Database } = require("arangojs");

  const db = new Database({
    url: ARANGODB_SERVER,
+   precaptureStackTraces: true,
  });

Note that arangojs will attempt to use Error.captureStackTrace if available and fall back to generating a stack trace by throwing an error. In environments that do not support the stack property on error objects, this option will still impact performance but not result in any additional information becoming available.

Node.js ReferenceError: window is not defined

If you compile your Node project using a build tool like Webpack, you may need to tell it to target the correct environment:

// webpack.config.js
+ "target": "node",

To support use in both browser and Node environments arangojs uses the package.json browser field, to substitute browser-specific implementations for certain modules. Build tools like Webpack will respect this field when targetting a browser environment and may need to be explicitly told you are targetting Node instead.

Node.js with self-signed HTTPS certificates

If you need to support self-signed HTTPS certificates in Node.js, you may have to override the global fetch agent. At the time of this writing, there is no official way to do this for the native fetch implementation in Node.js.

However as Node.js uses the undici module for its fetch implementation internally, you can override the global agent by adding undici as a dependency to your project and using its setGlobalDispatcher as follows:

import { Agent, setGlobalDispatcher } from "undici";

setGlobalDispatcher(
  new Agent({
    ca: [
      fs.readFileSync(".ssl/sub.class1.server.ca.pem"),
      fs.readFileSync(".ssl/ca.pem"),
    ],
  })
);

Although this is strongly discouraged, it's also possible to disable HTTPS certificate validation entirely, but note this has extremely dangerous security implications:

import { Agent, setGlobalDispatcher } from "undici";

setGlobalDispatcher(
  new Agent({
    rejectUnauthorized: false,
  })
);

When using arangojs in the browser, self-signed HTTPS certificates need to be trusted by the browser or use a trusted root certificate.

Streaming transactions leak

When using the transaction.step method it is important to be aware of the limitations of what a callback passed to this method is allowed to do.

const collection = db.collection(collectionName);
const trx = db.transaction(transactionId);

// WARNING: This code will not work as intended!
await trx.step(async () => {
  await collection.save(doc1);
  await collection.save(doc2); // Not part of the transaction!
});

// INSTEAD: Always perform a single operation per step:
await trx.step(() => collection.save(doc1));
await trx.step(() => collection.save(doc2));

Please refer to the documentation of this method for additional examples.

Streaming transactions timeout in cluster

Example messages: transaction not found, transaction already expired.

Transactions have different guarantees in a cluster.

When using arangojs in a cluster with load balancing, you may need to adjust the value of config.poolSize to accommodate the number of transactions you need to be able to run in parallel. The default value is likely to be too low for most cluster scenarios involving frequent streaming transactions.

Note: When using a high value for config.poolSize you may have to adjust the maximum number of threads in the ArangoDB configuration using the server.maximal-threads option to support larger numbers of concurrent transactions on the server side.

License

The Apache License, Version 2.0. For more information, see the accompanying LICENSE file.

Includes code from x3-linkedlist used under the MIT license.

arangojs's People

Contributors

13abylon avatar brabes avatar casdevs avatar ciscoheat avatar ctmakro avatar ctoesca avatar dependabot[bot] avatar dontrelax avatar dothebart avatar fceller avatar graetzer avatar greenkeeperio-bot avatar janwo avatar jsteemann avatar kvs85 avatar lodestone avatar maxkernbach avatar mpv1989 avatar neunhoef avatar oknoah avatar petitchevalroux avatar pluma avatar pluma4345 avatar samrg472 avatar simran-b avatar sleto-it avatar tombarton avatar uatuko avatar xescugc avatar ziink avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

arangojs's Issues

https performance

The driver performance over HTTPS is very poor.
The same query roundtrips are 4-5 times(!) faster with HTTP. In my simple tests the average query RTT was 41.6ms with HTTP, and 196.5ms with HTTPS on a remote server.
Is there any extra option to pass to the driver?
My environment:
arangoDB 2.6.0 (stable) and 2.5.2
iojs 2.3.1
arangojs 3.8.1

The performance of the web GUI is as fast with HTTPS than with HTTP.

support Foxx apps / arbitrary endpoints

Maybe something generic like:

db.endpoint(path)
  .get([path,] [qs,] cb)
  .put([path,] [data, [qs,]] cb)
  .patch([path,] [data, [qs,]] cb)
  .post([path,] [data, [qs,]] cb)
  .delete([path,] [qs,] cb)

"unknown path" responses from server on every API call

I'm just starting with arangodb and arangojs, so maybe I'm making a basic mistake, but arangojs is returning "unknown path" for every API call for me. Manual http requests from iojs to the server work fine.

I made an attempt at debugging, and found that the use of path.join in request.js was changing the slashes in the path to backslashes. Changing them back to slashes fixed the problem.

I'm running arangodb 2.6 with a fresh database and stock settings. I'm running arangojs 3.8.1 on iojs 1.8.1, and using the default Database constructor.

not able to get collection

I am using nodejs with Arangodb (databasename="nodetest1" and Collection="User")

var Database = require('arangojs');
var db = Database('http://127.0.0.1:8529');
//var mydb = db.use("nodetest1");
 db.query("FOR x IN User RETURN x", 
  function(err, cursor) {
  if (err) {
    console.log('error 1: %j', err);
  } else {
    cursor.all(function(err2, list) {
      if (err) {
        console.log('error 2: %j', err2);
      } else {
        console.log(list);
      }
    });
  }
});

getting error: [Circular]

Any help on this problem would be greatly appreciated!
Thank you in advance!

Bluebird promises log unhandled rejection errors

Bluebird is being "helpful" by logging rejected promises that don't have rejection handlers.

This leads to console noise when promises are silently discarded in favour of callbacks (e.g. when db.collection or db.edgeCollection with autoCreate=true determines that a collection doesn't exist).

This problem only occurs when bluebird is used as a promise polyfill via global.Promise = require('bluebird').

API merge with arangosh's JS scripts?

I'm thrilled that a new JS client is being developed for ArangoDB (not too happy with the current client's API, although it has the merit of existing).

I had a very interesting conversation with Lucas on the Google group about the different JS APIs being used with Arango, and most notably about the opportunity/possibility to merge this new development with the JS part of arangosh. I believe that, if possible, we should not design another API here. Arangosh's API is fine and it would be very nice to have the same on this client.

Now I know that the main difference between these two is arangosh being synchronous vs. the JS client being asynchronous. I didn't have much time to dig into arangosh's scripts yet, so I'm still wondering if there's a way to have the methods returning the result in arangosh and a corresponding promise in this client. The connection object is probably the key here, with each method building the HTTP request and the connection processing it either synchronously or asynchronously.

I would be happy to contribute to this new client, at least from a API design perspective and at best with code. But the technical considerations about the feasibility of merging with arangosh would best be managed by someone from the team!

Cheers
Thomas

Empty string convert to null automatically during db write

Hi,

I use arangojs to write some json data in DB like the following:

{ 
  "@id": "http://www.n-fuse.de/app.min.css",
  "@type": "http://www.n-fuse.de/classes/Object",
  "created": '2015-06-24T10:52:49.327Z',
  "size": 7714,
  "contentLanguage": "",
  "cacheControl": "",
  "contentDisposition": "",
  "contentEncoding": "7bit",
  "contentType": "text/css",
  "crc32c": "",
  "etag": "",
  "md5Hash": "",
  "name": "app.min.css",
  "prefix": "",
  "_key": "appmincss"
}

The Aql looks like this:

INSERT @node INTO @@collection LET nodes = NEW RETURN nodes

bindVars:

{ '@collection': 'docroot',
     node: 
      { '@id': 'http://www.n-fuse.de/app.min.css',
        '@type': 'http://www.n-fuse.de/classes/Object',
        created: '2015-06-24T10:52:49.327Z',
        creator: 'http://www.n-fuse.de/users/thomas.hoppe',
        size: 7714,
        contentLanguage: '',
        modified: '2015-06-24T10:52:49.327Z',
        cacheControl: '',
        contentDisposition: '',
        contentEncoding: '7bit',
        contentType: 'text/css',
        crc32c: '',
        etag: '',
        md5Hash: '',
        name: 'app.min.css',
        prefix: '',
        _key: 'appmincss' } }

However, after wrote into db, I found all properties with empty string is null instead. What's the reason?
I tried to use AQL explicitly with ArangoDB, it works. Therefore I guess it's an arangojs issue.

Graph EdgeCollection edge add not working

Looks like the API has been changed in ArangoDB, or something else is wrong. This should fix it:

--- graph.js.orig   2015-02-21 12:08:57.587976294 +0200
+++ graph.js    2015-02-21 12:10:41.895531469 +0200
@@ -127,11 +127,9 @@
   },
   save: function (data, fromId, toId, callback) {
     if (!callback) callback = noop;
-    this._gharial.post(data, {
-      collection: this.name,
-      from: this._documentHandle(fromId),
-      to: this._documentHandle(toId)
-    }, function (err, body) {
+    data['_from'] = this._documentHandle(fromId);
+    data['_to'] = this._documentHandle(toId);
+    this._gharial.post(data, function (err, body) {
       if (err) callback(err);
       else callback(null, body);
     });

There's probably other graph edge functions that are not working, but I haven't checked those.

Droping a Graph

I have found an error when trying to drop a graph. The code is the following:

  db.dropGraph(graphName)

The stack of the error is the following:

Unhandled rejection ArangoError: TypeError: Cannot read property '_properties' of undefined
  at new ArangoError (/path/to/project/node_modules/arangojs/lib/error.js:10:13)
  at Request._callback (/path/to/project/node_modules/arangojs/lib/connection.js:78:81)
  at Request.self.callback (/path/to/project/node_modules/arangojs/node_modules/request/request.js:368:22)
  at Request.emit (events.js:98:17)
  at Request.<anonymous> (/path/to/project/node_modules/arangojs/node_modules/request/request.js:1219:14)
  at Request.emit (events.js:117:20)
  at IncomingMessage.<anonymous> (/path/to/project/node_modules/arangojs/node_modules/request/request.js:1167:12)
  at IncomingMessage.emit (events.js:117:20)
  at _stream_readable.js:943:16
  at process._tickCallback (node.js:419:13)

The error behaves as following:

  • The error is raised even if the collection exists or not
  • Even though the error the Graph is droped

db.collection error handling

I'm using ArangoDB 2.6-alpha3, over HTTPS & HTTP authentication turned on with arangojs 3.8.1 driver.
When I invoke the above function with wrong or no pw, the callback called with error = null. When i use promises the success handler will be invoked. However the response has statusCode = 401

db.collection('collectionname',function(err,resp){
console.log('error: ',e);
console.log('response: ',r)
});

I've not checked more API calls for this bug.

Handle non-API errors (auth, net, etc)

Right now, if the authentication for the internal request fails, collection.document(id, cb) calls the callback without error and a blank string as data for the document. And cursor.all(cb) throws an exception:

foo/node_modules/arangojs/lib/cursor.js:48
      self._index = self._result.length;
                                ^
TypeError: Cannot read property 'length' of undefined
    at foo/node_modules/arangojs/lib/cursor.js:48:33
    at foo/node_modules/arangojs/lib/cursor.js:25:32
    at ArrayCursor.extend._more (foo/node_modules/arangojs/lib/cursor.js:32:25)
    at ArrayCursor.extend._drain (foo/node_modules/arangojs/lib/cursor.js:23:10)
    at ArrayCursor.extend.all (foo/node_modules/arangojs/lib/cursor.js:47:10)

Bulk Import bug

Hi,

type of import function should be defaults to "auto". However, if I do not give opts argument, and then import an array of document, I will become such error:

[ArangoError: no JSON string array found in first line]

I believe it's still a bug of request parameter. Please fix.

Bg,
Kevin

autoCreate collection sometimes fails

Hi,

I used database.collection function with autoCreate flag is true. Sometimes, I will get no error and a collection like this:

{ _connection: 
   { config: 
      { url: 'http://127.0.0.1:8529',
        databaseName: 'n-fuse',
        arangoVersion: 20300,
        agentOptions: [Object],
        headers: [Object] },
     _request: [Function: request] },
  _api: 
   { _connection: { config: [Object], _request: [Function: request] },
     _path: '_api',
     _headers: undefined } }

If I use this collection to call collection.import, I'll then got an error

[ArangoError: 'collection' is missing, expecting /_api/import?collection=<identifier>]
  message: '\'collection\' is missing, expecting /_api/import?collection=<identifier>',
  errorNum: 1204,
  code: 400,
  stack: 'ArangoError: \'collection\' is missing, expecting /_api/import?collection=<identifier>\n    at new ArangoError (/Invend/nfserver/node_modules/arangojs/lib/error.js:10:13)\n    at /Invend/nfserver/node_modules/arangojs/lib/connection.js:90:71\n    at /Invend/nfserver/node_modules/arangojs/lib/util/once.js:7:15\n    at IncomingMessage.<anonymous> (/Invend/nfserver/node_modules/arangojs/lib/util/request.js:23:9)\n    at IncomingMessage.emit (events.js:129:20)\n    at _stream_readable.js:908:16\n    at process._tickDomainCallback (node.js:381:11)']

I believe generally the returned collection should like this:

{ _connection: 
   { config: 
      { url: 'http://127.0.0.1:8529',
        databaseName: 'n-fuse',
        arangoVersion: 20300,
        agentOptions: [Object],
        headers: [Object] },
     _request: [Function: request] },
  _api: 
   { _connection: { config: [Object], _request: [Function: request] },
     _path: '_api',
     _headers: undefined },
  id: '2903076799',
  name: 'organizations',
  waitForSync: false,
  isVolatile: false,
  isSystem: false,
  status: 3,
  type: 2 }

I'm not sure whether it's an issue of arangojs or arangoDB server. Please check with this case.

Best regards,
Kevin

Bulk Import does not support JSON array document

Hi,

I found collection.import function does not support JSON array data. I think that's the reason of type parameter in the POST request

That's the error returned:

Error: no JSON array found in second line
      at new ArangoError (/Invend/server_arango/node_modules/arangojs/lib/error.js:12:13)
      at Request._callback (/Invend/server_arango/node_modules/arangojs/lib/connection.js:65:25)
      at Request.self.callback (/Invend/server_arango/node_modules/request/request.js:373:22)
      at Request.EventEmitter.emit (events.js:110:17)
      at Request.<anonymous> (/Invend/server_arango/node_modules/request/request.js:1318:14)
      at Request.EventEmitter.emit (events.js:129:20)
      at IncomingMessage.<anonymous> (/Invend/server_arango/node_modules/request/request.js:1266:12)
      at IncomingMessage.EventEmitter.emit (events.js:129:20)
      at _stream_readable.js:898:16
      at process._tickCallback (node.js:343:11)

According to the documentation https://docs.arangodb.com/HttpBulkImports/ImportingSelfContained.html , the function should has something like the following for enabling parse of two types of JSON documents on the server side

https://github.com/arangodb/arangojs/blob/master/lib/collection.js#L168

type: 'auto'

sort not working when using bindvars

Hey

I seem to not be able to pick up the sort function when using a AQL with a @sort binding

Here's a most basic example

db.query("FOR f IN films SORT @sort LIMIT 3 RETURN f.title", {sort: 'f.title asc'}, callback)

returns
[ 'Test Film 127933', 'Test Film 123403', 'Test Film 31017' ]

but

db.query("FOR f IN films SORT f.title asc LIMIT 3 RETURN f.title", callback)
returns
[ 'Test Film 1', 'Test Film 10', 'Test Film 100' ]

Is there something I'm doing wrong?
Turns out there is - key on the property e.g.

db.query("FOR f IN films SORT f.@sort @order LIMIT 3 RETURN f.title", {sort: title', order: 'asc'}, callback)

Support traversals

I'm not sure whether this is necessary as traversals can already be performed with AQL queries. I can't seem to find any documentation for traversals in ashikawa either.

@moonglum @fceller any thoughts on this?

`autoCreate` option for db.query function

Hi,

Maybe it's only a suggestion. Is it possible to implement some options like autoCreate in db.collection function for db.query function as well. If I use db.query to make some modification query, such as insert, arangoDB instance will always complain about collection not existing.

Bg,
Kevin

Error: connect EADDRNOTAVAIL - maxsockets being ignored?

Testing performance of saving docs and having the following error thrown every few thousand writes:

{ [Error: connect EADDRNOTAVAIL]
  code: 'EADDRNOTAVAIL',
  errno: 'EADDRNOTAVAIL',
  syscall: 'connect',
  request: 
   { domain: null,
     _events: { response: [Object], error: [Function] },
     _maxListeners: 10,
     output: [],
     outputEncodings: [],
     writable: true,
     _last: false,
     chunkedEncoding: false,
     shouldKeepAlive: true,
     useChunkedEncodingByDefault: true,
     sendDate: false,
     _headerSent: true,
     _header: 'POST /_db/loadtest/_api/document/?collection=load HTTP/1.1\r\ncontent-type: application/json\r\ncontent-length: 169\r\nx-arango-version: 20300\r\nHost: localhost:8000\r\nConnection: keep-alive\r\n\r\n',
     _hasBody: true,
     _trailer: '',
     finished: true,
     _hangupClose: false,
     socket: 
      { _connecting: false,
        _handle: null,
        _readableState: [Object],
        readable: false,
        domain: null,
        _events: [Object],
        _maxListeners: 10,
        _writableState: [Object],
        writable: false,
        allowHalfOpen: false,
        onend: [Function: socketOnEnd],
        destroyed: true,
        bytesRead: 0,
        _bytesDispatched: 0,
        _pendingData: 'POST /_db/loadtest/_api/document/?collection=load HTTP/1.1\r\ncontent-type: application/json\r\ncontent-length: 169\r\nx-arango-version: 20300\r\nHost: localhost:8000\r\nConnection: keep-alive\r\n\r\n{"id":16313,"type":9,"connections":[100,59,26,58],"positions":[{"time":"2015-06-20T10:49:32.749Z","type":9,"position":{"lat":-122.423246,"lng":37.779388,"radius":250}}]}',
        _pendingEncoding: 'utf8',
        parser: [Object],
        _httpMessage: [Circular],
        ondata: [Function: socketOnData],
        _idleNext: null,
        _idlePrev: null,
        _idleTimeout: -1 },
     connection: 
      { _connecting: false,
        _handle: null,
        _readableState: [Object],
        readable: false,
        domain: null,
        _events: [Object],
        _maxListeners: 10,
        _writableState: [Object],
        writable: false,
        allowHalfOpen: false,
        onend: [Function: socketOnEnd],
        destroyed: true,
        bytesRead: 0,
        _bytesDispatched: 0,
        _pendingData: 'POST /_db/loadtest/_api/document/?collection=load HTTP/1.1\r\ncontent-type: application/json\r\ncontent-length: 169\r\nx-arango-version: 20300\r\nHost: localhost:8000\r\nConnection: keep-alive\r\n\r\n{"id":16313,"type":9,"connections":[100,59,26,58],"positions":[{"time":"2015-06-20T10:49:32.749Z","type":9,"position":{"lat":-122.423246,"lng":37.779388,"radius":250}}]}',
        _pendingEncoding: 'utf8',
        parser: [Object],
        _httpMessage: [Circular],
        ondata: [Function: socketOnData],
        _idleNext: null,
        _idlePrev: null,
        _idleTimeout: -1 },
     agent: 
      { domain: null,
        _events: [Object],
        _maxListeners: 10,
        options: [Object],
        requests: {},
        sockets: [Object],
        maxSockets: 5,
        createConnection: [Function] },
     socketPath: undefined,
     method: 'POST',
     path: '/_db/loadtest/_api/document/?collection=load',
     _headers: 
      { 'content-type': 'application/json',
        'content-length': 169,
        'x-arango-version': 20300,
        host: 'localhost:8000' },
     _headerNames: 
      { 'content-type': 'content-type',
        'content-length': 'content-length',
        'x-arango-version': 'x-arango-version',
        host: 'Host' },
     parser: 
      { _headers: [],
        _url: '',
        onHeaders: [Function: parserOnHeaders],
        onHeadersComplete: [Function: parserOnHeadersComplete],
        onBody: [Function: parserOnBody],
        onMessageComplete: [Function: parserOnMessageComplete],
        socket: [Object],
        incoming: null,
        maxHeaderPairs: 2000,
        onIncoming: [Function: parserOnIncomingClient] } } }

I believe it has something to do with no more available sockets on my machine - but thought that {maxSockets: 5} would control that? I have changed maxSockets from 1 to 25 and keep having the same result. I see keepalive is enabled by default so assume new connections are not being fired up?
Below is the script I am using to test with:

var moment = require('moment'),
    opts = {maxSockets: 5},
    Agent = require('http').Agent;

var db = require('arangojs')({
    url: 'http://localhost:8000',
    databaseName: 'loadtest',
    agent: new Agent(opts)
});

var recs = 1000000,
    currentDoc = 0,
    type,
    start = new Date(),
    collection;

function save() {
    type = Math.round(Math.random() * 10) + 1;
    collection
        .save({
            'id': currentDoc,
            'type': type,
            'connections': [
                Math.round(Math.random() * 100) + 1,
                Math.round(Math.random() * 100) + 1,
                Math.round(Math.random() * 100) + 1,
                Math.round(Math.random() * 100) + 1
            ],
            'positions': [
                {
                    'time': new Date(),
                    'type': type,
                    'position': {'lat': -122.423246, 'lng': 37.779388, 'radius': 250}
                }
            ]
        },
        function (err, result) {
            if (err || result.error) {
                return console.error(err);
            }
            console.log('inserted ' + currentDoc + ' of ' + recs);
            if (currentDoc === recs) {
                return console.log('inserted ' + currentDoc + ' in ' + moment.utc(moment(new Date(), "DD/MM/YYYY HH:mm:ss").diff(moment(start, "DD/MM/YYYY HH:mm:ss"))).format("HH:mm:ss"));
            }
            currentDoc++;
            save();
        });
}

db.collection('load', function (err, result) {
    if (err) {
        console.error(err);
        return;
    }
    collection = result;
    save();
});

UPDATE:
Only seems to happen when durability is set to soft and the waitForSync is set to false on the collection - I assume then this is an arangodb issue and not a driver issue? or possibly both?

documentCollection.save not returning full document

The documentation for save() implies that the callback gets called with the full document (doc.some === 'data' in the documentation's example). However, I only get back the new meta attributes (when using promises, if that makes any difference).

{
  error: false,
  _id: 'whatever/1645465998905',
  _rev: '1645465998905',
  _key: '1645465998905'
}

Documentation is outdated

The documentation shown on the GitHub page (README.md) for this driver is wrong. This is quite frustrating for first time user. At least the source code is pretty well documented (although it would be good to have some kind of cookbook).

Errors in callbacks shouldn't be caught

db.collection('foo', function(error, collection) {
  if (error) return console.error(error);
  programmer.mistake();
  console.log(collection);
});

Where's my error?

https problem?

I'm trying to connect a remote arangodb from iojs. With plain http everything works properly. After switch the endpoint to ssl the driver fails to connect with a message ECONNRESET.
Handmade API calls with builtin https module works, after added certificates with:
require('ssl-root-cas').inject().addFile('.ssl/sub.class1.server.ca.pem');. The WEB GUI and the browserify bundle are working too.
Arango 2.6a3, arangojs 3.8, iojs 2.0.1, 2.2.1, certificate: StartSSL free cert (green padlock in all tested browsers)
I've to configure something, or is this a bug?

Add optional promise support

We will not ship a promise implementation with arangojs. One of the major concerns the 3.0 rewrite addressed was making the library a lot more lightweight -- adding more dependencies (or rolling our own implementations) is not going to happen.

However there is a rightful demand for a promise based API. I think it's possible to support promises as return values without relying on a polyfill or promise library directly for those who don't want to use them.

The most obvious solution would be to check for the existence of a global Promise function when an async function is called. This could be achieved using a simple helper function like this (using ES6 destructuring for readability):

function promisify (callback) {
  if (!callback) callback = noop;
  if (typeof Promise !== 'function') return {cb: callback};
  // ES6 Promise is supported
  var cb;
  var p = new Promise(function (resolve, reject) {
    cb = function (err, res) {
      if (err) reject(err);
      else resolve(res);
      callback(err, res);
    };
  });
  return {cb, p};
}

and used like this:

Database.prototype.createCollection = function (properties, callback) {
  var {cb, p} = promisify(callback);
  // … same logic as before …
  return p;
};

This would be entirely transparent for environments that don't support ES6 promises and result in miminal overhead in those that do. Non-ES6 environments could use a polyfill like es6-promise (require('es6-promise').polyfill();) or a custom ES6-compatible promise implementation like bluebird (global.Promise = require('bluebird');).

node.js + foxx session feature

Hi Guys,

I am currently developing an authentication and session scheme for hapi.js with foxx. To identify the request in foxx I have to send the session cookies with every request (of course). My question is how to obtain the session id in first place using the arangojs driver, since node.js wont keep automatically track on the cookies like the browser does. I was looking at the source code and couldn't find any way to access the response headers. So my only solution would be to make an own request at first to store the session id and then use the arangojs driver, but i dont want to build the url on my own. How is it supposed to work?

Thanks in advance!

How to get connection status ?

How can one get the connection and/or auth status (disconnected, connected, authentication failed etc.) with this driver ?

Options of Query API

Hi,

The Query API uses /_api/cursor for executing AQL. However, this interface should support some additional options, such as fullCount which might be useful for me.

Is it possible to extend the arangojs for supporting these options? or how can I count my result before limit clause is applied in the AQL?

Bg,
Kevin

collection.import opts argument is not optional as informed in the documentation

When calling collection.import(data, [opts,] callback) the opts argument is not being treated as optional as informed in the documentation.

For example, if you call import like:

collection.import([{name: 'abc'}], function(err){});

The following error is received on the callback:

[TypeError: Cannot read property 'type' of undefined]

My understanding is that the attribute opts.type is being expected in the implementation even when the opts is not being passed (see collection.js:189) :

ld: Boolean(opts.type !== 'array')

Query is empty

Hi,

I updated the new version 3.7, but I found my code doesn't work any more. After deep inspect, I found the new utils/request can get the correct request body like the following:

Request Body: {"query":"LET nodes = (FOR node IN @@collection RETURN node), includes = (FOR node IN @@collection RETURN node) RETURN {nodes: nodes, includes: includes}","bindVars":{"@collection":"resources"}}

However the arangoDB returns an error, query is empty... I have no idea what's the reason.

{ [ArangoError: query is empty]\n  name: \'ArangoError\',\n  message: \'query is empty\',\n  errorNum: 1502,\n  code: 400,\n  stack: \'ArangoError: query is empty\\n    at new ArangoError (/Invend/nfserver/node_modules/arangojs/lib/error.js:10:13)\\n    at /Invend/nfserver/node_modules/arangojs/lib/connection.js:85:71\\n    at /Invend/nfserver/node_modules/arangojs/lib/util/once.js:7:15\\n    at IncomingMessage.<anonymous> (/Invend/nfserver/node_modules/arangojs/lib/util/request.js:23:9)\\n    at IncomingMessage.emit (events.js:129:20)\\n    at _stream_readable.js:908:16\\n    at process._tickDomainCallback (node.js:381:11)\',\n  isException: true,\n  status: 400 }

Meanwhile, I found the test case for query with Aqb module is missing. Maybe that's the reason.

Best regards,
Kevin

Request headers for remote connection

I'm trying to a simple test call to look for all collections, with the arangodb being in another server:

config = {
    db: {
        url: 'http://test:[email protected]:8529'
    }
};

Database = require('arangojs');

var db = new Database(config.db);

db.collections(function (err, collections) {
    if (err) {
        return console.error(err);
    }
    console.log(collections);
});

But I keep getting an unknown path error.

'{"error":true,"code":404,"errorNum":404,"errorMessage":"unknown path \'\\\\_db\\\\_system\\\\_api\\\\collection?excludeSystem=true\'"}' } }

I have no trouble accessing the web interface, so I believe it's a headers issue, but I haven't found a workaround.

**Update: I tried installing arangodb in my local machine (windows 8) and I get the same result.

Connection management in express

What is the preferred method of managing connections in express.js? one connection at startup? Looking through the code, I couldn't see any connection pool management, but may have missed it.

Database `autoCreate` not works with 2.6.0

Hi,

After update to v2.6.0, I found the database connection with autoCreate options enabled does not work any more. I made some further inspect. The log told me

In this line, it gets an error with 404, and errorNum 1228.
https://github.com/arangodb/arangojs/blob/master/lib/database.js#L271
Then the code try to create a new database. However, no error is returned and no database is created.
I guess it might be the reason of default username and password for new arangodb. Nevertheless, some errors should be returned here about that at least.

Thx

Bg,
Kevin

Cursor with undefined result

Hi,

I made some queries to get documents based on AQL. Some of them will return no error and a cursor like this:

{ extra: undefined,
  _connection: 
   { config: 
      { url: 'http://127.0.0.1:8529',
        databaseName: 'n-fuse',
        arangoVersion: 20300,
        agentOptions: [Object],
        headers: [Object] },
     _request: [Function: request] },
  _api: 
   { _connection: { config: [Object], _request: [Function: request] },
     _path: '_api',
     _headers: undefined },
  _result: undefined,
  _hasMore: false,
  _id: undefined,
  _index: 0 }

First of all, I'm sure the collection and relevant document exists, but no document is found.
Second, even the document doesn't exist, the cursor should not have an undefined result, shouldn't it?
Last but not least, I call cursor.hasNext() to check whether I can advance the cursor or not. My code then hangs on at this step, no error, no returned value, and no exception. I believe it's the reason of undefined result. Even if I put another try/catch block here, I still can not see any exception.

p.s. this case does not occur each time...

Best regards,
Kevin

Avoid unnecessary roundtrips

I've been wondering for a while why collection() is an asynchronous method. It seems that it actually makes a roundtrip to the DB. But why?

db.collection('MyThings')
  .then(collection => collection.count())

So to get the number of MyThings it makes two roundtrips even though, theoretically, it should be just one? Or if I want to insert one document each into 10 different collections, I'd end up with 20 roundtrips?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.