mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'devel' of github.com:triAGENS/ArangoDB into devel
This commit is contained in:
commit
c1fec4c5b0
|
@ -1,6 +1,8 @@
|
|||
v1.2.alpha (XXXX-XX-XX)
|
||||
-----------------------
|
||||
|
||||
* added collection.revision() method to determine whether a collection has changed
|
||||
|
||||
* issue #346: adaptively determine NUMBER_HEADERS_PER_BLOCK
|
||||
|
||||
* issue #338: arangosh cursor positioning problems
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
arango> db.example.document("1432124/2873916");
|
||||
{ "_id" : "1432124/2873916", "_rev" : 2873916, "Hallo" : "World" }
|
|
@ -1,5 +0,0 @@
|
|||
arango> db.example.document("12345");
|
||||
JavaScript exception in file '(arango)' at 1,12:
|
||||
[ArangoError 10: bad parameter: <document-identifier> must be a document identifier]
|
||||
!db.example.document("12345");
|
||||
! ^
|
|
@ -1,5 +0,0 @@
|
|||
arango> db.example.document("1432124/123456");
|
||||
JavaScript exception in file '(arango)' at 1,12:
|
||||
[ArangoError 1202: document not found: document not found]
|
||||
!db.example.document("1432124/123456");
|
||||
! ^
|
|
@ -1,9 +0,0 @@
|
|||
arango> col = db.examples;
|
||||
[ArangoCollection 91022, "examples" (status new born)]
|
||||
arango> col.save({ "Hallo" : "World" });
|
||||
{ "_id" : "91022/1532814", "_rev" : 1532814 }
|
||||
arango> col.count();
|
||||
1
|
||||
arango> col.truncate();
|
||||
arango> col.count();
|
||||
0
|
|
@ -1,4 +0,0 @@
|
|||
arango> db.example.getIndexes().map(function(x) { return x.id; });
|
||||
["93013/0"]
|
||||
arango> db.example.index("93013/0");
|
||||
{ "id" : "93013/0", "type" : "primary", "fields" : ["_id"] }
|
|
@ -1,10 +0,0 @@
|
|||
arango> a1 = db.example.save({ a : 1 });
|
||||
{ "_id" : "116308/3449537", "_rev" : 3449537 }
|
||||
arango> db.example.document(a1);
|
||||
{ "_id" : "116308/3449537", "_rev" : 3449537, "a" : 1 }
|
||||
arango> db.example.delete(a1);
|
||||
true
|
||||
arango> db.example.document(a1);
|
||||
JavaScript exception in file '(arango)' at 1,12: [ArangoError 1202: document not found: document not found]
|
||||
!db.example.document(a1);
|
||||
! ^
|
|
@ -1,14 +0,0 @@
|
|||
arango> a1 = db.example.save({ a : 1 });
|
||||
{ "_id" : "116308/3857139", "_rev" : 3857139 }
|
||||
arango> a2 = db.example.replace(a1, { a : 2 });
|
||||
{ "_id" : "116308/3857139", "_rev" : 3922675, "_oldRev" : 3857139 }
|
||||
arango> db.example.delete(a1);
|
||||
JavaScript exception in file '(arango)' at 1,18: [ArangoError 1200: conflict: cannot delete document]
|
||||
!db.example.delete(a1);
|
||||
! ^
|
||||
arango> db.example.delete(a1, true);
|
||||
true
|
||||
arango> db.example.document(a1);
|
||||
JavaScript exception in file '(arango)' at 1,12: [ArangoError 1202: document not found: document not found]
|
||||
!db.example.document(a1);
|
||||
! ^
|
|
@ -1,14 +0,0 @@
|
|||
arango> a1 = db.example.save({ a : 1 });
|
||||
{ "_id" : "116308/4042634", "_rev" : 4042634 }
|
||||
arango> a2 = db._replace(a1, { a : 2 });
|
||||
{ "_id" : "116308/4042634", "_rev" : 4108170, "_oldRev" : 4042634 }
|
||||
arango> db._delete(a1);
|
||||
JavaScript exception in file '(arango)' at 1,4: [ArangoError 1200: conflict: cannot delete document]
|
||||
!db._delete(a1);
|
||||
! ^
|
||||
arango> db._delete(a1, true);
|
||||
true
|
||||
arango> db._document(a1);
|
||||
JavaScript exception in file '(arango)' at 1,4: [ArangoError 1202: document not found: document not found]
|
||||
!db._document(a1);
|
||||
! ^
|
|
@ -1,10 +0,0 @@
|
|||
arango> a1 = db.example.save({ a : 1 });
|
||||
{ "_id" : "116308/4214943", "_rev" : 4214943 }
|
||||
arango> db._delete(a1);
|
||||
true
|
||||
arango> db._delete(a1);
|
||||
JavaScript exception in file '(arango)' at 1,4: [ArangoError 1202: document not found: cannot delete document]
|
||||
!db._delete(a1);
|
||||
! ^
|
||||
arango> db._delete(a1, true);
|
||||
false
|
|
@ -28,7 +28,8 @@ DOXYGEN = \
|
|||
Doxygen/js/actions/system/api-simple.c \
|
||||
Doxygen/js/actions/system/api-system.c \
|
||||
Doxygen/js/common/bootstrap/modules.c \
|
||||
Doxygen/js/common/bootstrap/print.c \
|
||||
Doxygen/js/common/bootstrap/module-console.c \
|
||||
Doxygen/js/common/bootstrap/module-fs.c \
|
||||
Doxygen/js/common/modules/graph.c \
|
||||
Doxygen/js/common/modules/jsunity.c \
|
||||
Doxygen/js/common/modules/simple-query-basics.c \
|
||||
|
@ -36,6 +37,7 @@ DOXYGEN = \
|
|||
Doxygen/js/common/modules/users.c \
|
||||
Doxygen/js/server/modules/org/arangodb/actions.c \
|
||||
Doxygen/js/server/modules/simple-query.c \
|
||||
Doxygen/js/server/ArangoCollection.c \
|
||||
Doxygen/js/server/server.c
|
||||
|
||||
################################################################################
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
Module "fs" {#JSModuleFs}
|
||||
=========================
|
||||
|
||||
@EMBEDTOC{JSModuleFsTOC}
|
||||
|
||||
The implementation follows the CommonJS specification
|
||||
@EXTREF{http://wiki.commonjs.org/wiki/Filesystem/A/0,Filesystem/A/0}.
|
||||
|
||||
@anchor JSModuleFsExists
|
||||
@copydetails JS_Exists
|
||||
|
||||
@anchor JSModuleFsIsDirectory
|
||||
@copydetails JS_IsDirectory
|
||||
|
||||
@anchor JSModuleFsListTree
|
||||
@copydetails JS_ListTree
|
||||
|
||||
@anchor JSModuleFsMove
|
||||
@copydetails JS_Move
|
||||
|
||||
@anchor JSModuleFsRemove
|
||||
@copydetails JS_Remove
|
|
@ -0,0 +1,9 @@
|
|||
TOC {#JSModuleFsTOC}
|
||||
====================
|
||||
|
||||
- @ref JSModuleFs
|
||||
- @ref JSModuleFsExists "fs.exists"
|
||||
- @ref JSModuleFsIsDirectory "fs.isDirectory"
|
||||
- @ref JSModuleFsListTree "fs.listTree"
|
||||
- @ref JSModuleFsMove "fs.move"
|
||||
- @ref JSModuleFsRemove "fs.remove"
|
|
@ -305,7 +305,7 @@ A Simple Action {#UserManualActionsContentAction}
|
|||
|
||||
The simplest dynamic action is:
|
||||
|
||||
{ action: { controller: "org/arangodb/actions", do: "echoRequest" } }
|
||||
{ action: { do: "org/arangodb/actions/echoRequest" } }
|
||||
|
||||
It is not possible to store functions directly in the routing table, but you can
|
||||
call functions defined in modules. In the above example the function can be
|
||||
|
@ -324,7 +324,7 @@ For example
|
|||
|
||||
arangosh> db._routing.save({
|
||||
........> url: "/hello/echo",
|
||||
........> action: { controller: "org/arangodb/actions", do: "echoRequest" } });
|
||||
........> action: { do: "org/arangodb/actions/echoRequest" } });
|
||||
|
||||
Reload the routing and check
|
||||
|
||||
|
@ -645,3 +645,99 @@ should win in this case:
|
|||
........> ]
|
||||
........> });
|
||||
|
||||
Application Deployment {#UserManualActionsApplicationDeployment}
|
||||
================================================================
|
||||
|
||||
Using single routes or @ref UserManualActionsAdvancedBundles "bundles" can be
|
||||
become a bit messy in large applications. Therefore a deployment tool exists
|
||||
inside _arangosh_ to simplify the task. This tool was inspired by the ArangoDB
|
||||
deployment tool `https://github.com/kaerus/arangodep` written in node.js by
|
||||
kaerus.
|
||||
|
||||
An application is a bunch of routes, static pages stored in collections, and
|
||||
small scriptlets stored modules.
|
||||
|
||||
In order to create an application, chose a suitable name, e. g. reverse domain
|
||||
name plus the application name and call `createApp`:
|
||||
|
||||
arangosh> var deploy = require("org/arangodb/deploy");
|
||||
arangosh> var app = deploy.createApp("org.example.simple");
|
||||
|
||||
Normally content will either be stored in collections or dynamically
|
||||
calculated. But sometimes it is convenient to store the content directly in the
|
||||
routing table, e. g. to deliver a version number.
|
||||
|
||||
arangosh> app.mountStaticContent("/version", {
|
||||
........> version: "1.2.3", major: 1, minor: 2, patch: 3 });
|
||||
[ArangoApp "org.example.simple" at ""]
|
||||
|
||||
Save the application
|
||||
|
||||
arangosh> app.save();
|
||||
[ArangoApp "org.example.simple" at ""]
|
||||
|
||||
and use the browser to check the result
|
||||
|
||||
http://localhost:8529/version
|
||||
|
||||
You can also specify the content-type
|
||||
|
||||
arangosh> app.mountStaticContent("/author",
|
||||
........> "Frank Celler",
|
||||
........> "text/plain").save();
|
||||
[ArangoApp "org.example.simple" at ""]
|
||||
|
||||
and check at
|
||||
|
||||
http://localhost:8529/author
|
||||
|
||||
If you have more than one application, putting version under `/` might lead to
|
||||
conflicts. It is therefore possible to use a common prefix for the application.
|
||||
|
||||
arangosh> app.setPrefix("/example").save();
|
||||
[ArangoApp "org.example.simple" at "/example"]
|
||||
|
||||
Now check
|
||||
|
||||
http://localhost:8529/example/version
|
||||
http://localhost:8529/example/author
|
||||
|
||||
Deploying Static Pages {#UserManualActionsDeployingStaticPages}
|
||||
---------------------------------------------------------------
|
||||
|
||||
Most of the time, static html pages and JavaScript content will be delivered by
|
||||
your web-server. But sometimes it is convenient to deliver these directly from
|
||||
within ArangoDB. For example, to provide a small admin interface for you
|
||||
application.
|
||||
|
||||
Assume that all data is stored underneath a directory "/tmp/example" and we want
|
||||
to store the content in a collection "org_example_simple_content".
|
||||
|
||||
First connect the url path to the collection.
|
||||
|
||||
arangosh> app.mountStaticPages("/static", "org_example_simple_content").save();
|
||||
[ArangoApp "org.example.simple" at "/example"]
|
||||
|
||||
Next create a file `index.html` at `/tmp/example/index.html".
|
||||
|
||||
<html>
|
||||
<body>
|
||||
Hallo World!
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Create the collection and upload this into the collection
|
||||
|
||||
arangosh> require("org/arangodb").db._createDocumentCollection("org_example_simple_content");
|
||||
[ArangoCollection 224910918055, "org_example_simple_content" (type document, status loaded)]
|
||||
|
||||
arangosh> app.uploadStaticPages("/static", "/tmp/example");
|
||||
imported '/index.html' of type 'text/html; charset=utf-8'
|
||||
[ArangoApp "org.example.simple" at "/example"]
|
||||
|
||||
Check the index file
|
||||
|
||||
http://localhost:8529/example/static/index.html
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -25,3 +25,5 @@ TOC {#UserManualActionsTOC}
|
|||
- @ref UserManualActionsAdvancedRedirects
|
||||
- @ref UserManualActionsAdvancedBundles
|
||||
- @ref UserManualActionsAdvancedMiddleware
|
||||
- @ref UserManualActionsApplicationDeployment
|
||||
- @ref UserManualActionsDeployingStaticPages
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
Handling Documents {#ShellDocument}
|
||||
===================================
|
||||
|
||||
@NAVIGATE_ShellDocument
|
||||
@EMBEDTOC{ShellDocumentTOC}
|
||||
|
||||
This is an introduction to ArangoDB's interface for documents and how handle
|
||||
documents from the JavaScript shell _arangosh_. For other languages see
|
||||
the corresponding language API.
|
||||
|
||||
Documents, Identifiers, Handles {#ShellDocumentIntro}
|
||||
=====================================================
|
||||
|
||||
@copydoc GlossaryDocument
|
||||
|
||||
For example:
|
||||
|
||||
{
|
||||
"_id" : "demo/2345678",
|
||||
"_rev" : "3456789",
|
||||
"_key" : "2345678",
|
||||
"firstName" : "Hugo",
|
||||
"lastName" : "Schlonz",
|
||||
"address" : {
|
||||
"street" : "Strasse 1",
|
||||
"city" : "Hier"
|
||||
},
|
||||
"hobbies" : [
|
||||
"swimming",
|
||||
"biking",
|
||||
"programming"
|
||||
]
|
||||
}
|
||||
|
||||
All documents contain special attributes: the document handle in `_id`, the
|
||||
document's unique key in `_key` and and the etag aka document revision in
|
||||
`_rev`. The value of the `_key` attribute can be specified by the user when
|
||||
creating a document. `_id` and `_key` values are immutable once the document
|
||||
has been created. The `_rev` value is maintained by ArangoDB autonomously.
|
||||
|
||||
@copydoc GlossaryDocumentHandle
|
||||
|
||||
@copydoc GlossaryDocumentIdentifier
|
||||
|
||||
@copydoc GlossaryDocumentRevision
|
||||
|
||||
@copydoc GlossaryDocumentEtag
|
||||
|
||||
Address and ETag of an Document {#ShellDocumentResource}
|
||||
========================================================
|
||||
|
||||
All documents in ArangoDB have a document handle. This handle uniquely defines a
|
||||
document and is managed by ArangoDB. The interface allows you to access the
|
||||
documents of a collection as:
|
||||
|
||||
db.@FA{collection}.documet(@FA{document-handle})
|
||||
|
||||
For example: Assume that the document handle, which is stored in the `_id` field
|
||||
of the document, is `demo/362549` and the document lives in a collection
|
||||
named @FA{demo}, then that document can be accessed as:
|
||||
|
||||
db.demo.document("demo/362549736")
|
||||
|
||||
Because the document handle is unique within the database, you
|
||||
can leave out the @FA{collection} and use the shortcut:
|
||||
|
||||
db._document("demo/362549736")
|
||||
|
||||
Each document also has a document revision or etag with is returned in the
|
||||
`_rev` field when requesting a document. The document's key is returned in the
|
||||
`_key` attribute.
|
||||
|
||||
@CLEARPAGE
|
||||
Working with Documents {#ShellDocumentShell}
|
||||
============================================
|
||||
|
||||
Collection Methods {#ShellDocumentCollectionMethods}
|
||||
----------------------------------------------------
|
||||
|
||||
@anchor ShellDocumentRead
|
||||
@copydetails JS_DocumentVocbaseCol
|
||||
|
||||
@CLEARPAGE
|
||||
@anchor ShellDocumentCreate
|
||||
@copydetails JS_SaveVocbaseCol
|
||||
|
||||
@CLEARPAGE
|
||||
@anchor ShellDocumentReplace
|
||||
@copydetails JS_ReplaceVocbaseCol
|
||||
|
||||
@CLEARPAGE
|
||||
@anchor ShellDocumentUpdate
|
||||
@copydetails JS_UpdateVocbaseCol
|
||||
|
||||
@CLEARPAGE
|
||||
@anchor ShellDocumentRemove
|
||||
@copydetails JS_RemoveVocbaseCol
|
||||
|
||||
@CLEARPAGE
|
||||
@anchor ShellDocumentRemoveByExample
|
||||
@copydetails JSF_ArangoCollection_prototype_removeByExample
|
||||
|
||||
@CLEARPAGE
|
||||
Database Methods {#ShellDocumentDatabaseMethods}
|
||||
------------------------------------------------
|
||||
|
||||
@anchor ShellDocumentDbRead
|
||||
@copydetails JS_DocumentVocbase
|
||||
|
||||
@CLEARPAGE
|
||||
@anchor ShellDocumentDbReplace
|
||||
@copydetails JS_ReplaceVocbase
|
||||
|
||||
@CLEARPAGE
|
||||
@anchor ShellDocumentDbUpdate
|
||||
@copydetails JS_UpdateVocbase
|
||||
|
||||
@CLEARPAGE
|
||||
@anchor ShellDocumentDbRemove
|
||||
@copydetails JS_RemoveVocbase
|
|
@ -0,0 +1,19 @@
|
|||
TOC {#ShellDocumentTOC}
|
||||
=======================
|
||||
|
||||
- @ref ShellDocument
|
||||
- @ref ShellDocumentIntro
|
||||
- @ref ShellDocumentResource
|
||||
- @ref ShellDocumentShell
|
||||
- @ref ShellDocumentCollectionMethods
|
||||
- @ref ShellDocumentRead "collection.document"
|
||||
- @ref ShellDocumentCreate "collection.save"
|
||||
- @ref ShellDocumentReplace "collection.replace"
|
||||
- @ref ShellDocumentUpdate "collection.update"
|
||||
- @ref ShellDocumentRemove "collection.remove"
|
||||
- @ref ShellDocumentRemoveByExample "collection.removeByExample"
|
||||
- @ref ShellDocumentDatabaseMethods
|
||||
- @ref ShellDocumentDbRead "db._document"
|
||||
- @ref ShellDocumentDbReplace "db._replace"
|
||||
- @ref ShellDocumentDbUpdate "db._update"
|
||||
- @ref ShellDocumentDbRemove "db._remove"
|
|
@ -197,26 +197,26 @@ TAB_SIZE = 8
|
|||
|
||||
# function definition
|
||||
ALIASES = \
|
||||
"FUN{1}=@latexonly\functionsignature{@endlatexonly@htmlonly<div class=\"functionsignature\">@endhtmlonly@xmlonly XMLMISSING @endxmlonly\1@latexonly}@endlatexonly@htmlonly</div>@endhtmlonly@xmlonly XMLMISSING @endxmlonly" \
|
||||
"FUN{2}=@latexonly\functionsignature{@endlatexonly@htmlonly<div class=\"functionsignature\">@endhtmlonly@xmlonly XMLMISSING @endxmlonly\1, \2@latexonly}@endlatexonly@htmlonly</div>@endhtmlonly@xmlonly XMLMISSING @endxmlonly" \
|
||||
"FUN{3}=@latexonly\functionsignature{@endlatexonly@htmlonly<div class=\"functionsignature\">@endhtmlonly@xmlonly XMLMISSING @endxmlonly\1, \2, \3@latexonly}@endlatexonly@htmlonly</div>@endhtmlonly@xmlonly XMLMISSING @endxmlonly" \
|
||||
"FUN{4}=@latexonly\functionsignature{@endlatexonly@htmlonly<div class=\"functionsignature\">@endhtmlonly@xmlonly XMLMISSING @endxmlonly\1, \2, \3, \4@latexonly}@endlatexonly@htmlonly</div>@endhtmlonly@xmlonly XMLMISSING @endxmlonly" \
|
||||
"FUN{5}=@latexonly\functionsignature{@endlatexonly@htmlonly<div class=\"functionsignature\">@endhtmlonly@xmlonly XMLMISSING @endxmlonly\1, \2, \3, \4, \5@latexonly}@endlatexonly@htmlonly</div>@endhtmlonly@xmlonly XMLMISSING @endxmlonly" \
|
||||
"FUN{6}=@latexonly\functionsignature{@endlatexonly@htmlonly<div class=\"functionsignature\">@endhtmlonly@xmlonly XMLMISSING @endxmlonly\1, \2, \3, \4, \5, \6@latexonly}@endlatexonly@htmlonly</div>@endhtmlonly@xmlonly XMLMISSING @endxmlonly" \
|
||||
"FUN{7}=@latexonly\functionsignature{@endlatexonly@htmlonly<div class=\"functionsignature\">@endhtmlonly@xmlonly XMLMISSING @endxmlonly\1, \2, \3, \4, \5, \6, \7@latexonly}@endlatexonly@htmlonly</div>@endhtmlonly@xmlonly XMLMISSING @endxmlonly" \
|
||||
"FA{1}=@latexonly\functionargument{@endlatexonly@htmlonly<span class=\"functionargument\">@endhtmlonly@xmlonly XMLMISSING @endxmlonly\1@latexonly}@endlatexonly@htmlonly</span>@endhtmlonly@xmlonly XMLMISSING @endxmlonly" \
|
||||
"FN{1}=@latexonly\functionname{@endlatexonly@htmlonly<span class=\"functionname\">@endhtmlonly@xmlonly XMLMISSING @endxmlonly\1@latexonly}@endlatexonly@htmlonly</span>@endhtmlonly@xmlonly XMLMISSING @endxmlonly"
|
||||
"FUN{1}=@latexonly\functionsignature{@endlatexonly@htmlonly<div class=\"functionsignature\">@endhtmlonly@xmlonly <!--- XMLMISSING --> @endxmlonly\1@latexonly}@endlatexonly@htmlonly</div>@endhtmlonly@xmlonly <!--- XMLMISSING --> @endxmlonly" \
|
||||
"FUN{2}=@latexonly\functionsignature{@endlatexonly@htmlonly<div class=\"functionsignature\">@endhtmlonly@xmlonly <!--- XMLMISSING --> @endxmlonly\1, \2@latexonly}@endlatexonly@htmlonly</div>@endhtmlonly@xmlonly <!--- XMLMISSING --> @endxmlonly" \
|
||||
"FUN{3}=@latexonly\functionsignature{@endlatexonly@htmlonly<div class=\"functionsignature\">@endhtmlonly@xmlonly <!--- XMLMISSING --> @endxmlonly\1, \2, \3@latexonly}@endlatexonly@htmlonly</div>@endhtmlonly@xmlonly <!--- XMLMISSING --> @endxmlonly" \
|
||||
"FUN{4}=@latexonly\functionsignature{@endlatexonly@htmlonly<div class=\"functionsignature\">@endhtmlonly@xmlonly <!--- XMLMISSING --> @endxmlonly\1, \2, \3, \4@latexonly}@endlatexonly@htmlonly</div>@endhtmlonly@xmlonly <!--- XMLMISSING --> @endxmlonly" \
|
||||
"FUN{5}=@latexonly\functionsignature{@endlatexonly@htmlonly<div class=\"functionsignature\">@endhtmlonly@xmlonly <!--- XMLMISSING --> @endxmlonly\1, \2, \3, \4, \5@latexonly}@endlatexonly@htmlonly</div>@endhtmlonly@xmlonly <!--- XMLMISSING --> @endxmlonly" \
|
||||
"FUN{6}=@latexonly\functionsignature{@endlatexonly@htmlonly<div class=\"functionsignature\">@endhtmlonly@xmlonly <!--- XMLMISSING --> @endxmlonly\1, \2, \3, \4, \5, \6@latexonly}@endlatexonly@htmlonly</div>@endhtmlonly@xmlonly <!--- XMLMISSING --> @endxmlonly" \
|
||||
"FUN{7}=@latexonly\functionsignature{@endlatexonly@htmlonly<div class=\"functionsignature\">@endhtmlonly@xmlonly <!--- XMLMISSING --> @endxmlonly\1, \2, \3, \4, \5, \6, \7@latexonly}@endlatexonly@htmlonly</div>@endhtmlonly@xmlonly <!--- XMLMISSING --> @endxmlonly" \
|
||||
"FA{1}=@latexonly\functionargument{@endlatexonly@htmlonly<span class=\"functionargument\">@endhtmlonly@xmlonly <!--- XMLMISSING --> @endxmlonly\1@latexonly}@endlatexonly@htmlonly</span>@endhtmlonly@xmlonly <!--- XMLMISSING --> @endxmlonly" \
|
||||
"FN{1}=@latexonly\functionname{@endlatexonly@htmlonly<span class=\"functionname\">@endhtmlonly@xmlonly <!--- XMLMISSING --> @endxmlonly\1@latexonly}@endlatexonly@htmlonly</span>@endhtmlonly@xmlonly <!--- XMLMISSING --> @endxmlonly"
|
||||
|
||||
# command line option
|
||||
ALIASES += \
|
||||
"CMDOPT{1}=@latexonly\commandlineoption{@endlatexonly@htmlonly<div class=\"commandlineoption\">@endhtmlonly@xmlonly XMLMISSING @endxmlonly\1@latexonly}@endlatexonly@htmlonly</div>@endhtmlonly@xmlonly XMLMISSING @endxmlonly" \
|
||||
"CA{1}=@latexonly\commandlineargument{@endlatexonly@htmlonly<span class=\"commandlineargument\">@endhtmlonly@xmlonly XMLMISSING @endxmlonly\1@latexonly}@endlatexonly@htmlonly</span>@endhtmlonly@xmlonly XMLMISSING @endxmlonly" \
|
||||
"CO{1}=@latexonly\commandoption{@endlatexon\@htmlonly<span class=\"commandoption\">@endhtmlonly@xmlonly XMLMISSING @endxmlonly\1@latexonly}@endlatexonly@htmlonly</span>@endhtmlonly@xmlonly XMLMISSING @endxmlonly"
|
||||
"CMDOPT{1}=@latexonly\commandlineoption{@endlatexonly@htmlonly<div class=\"commandlineoption\">@endhtmlonly@xmlonly <!--- XMLMISSING --> @endxmlonly\1@latexonly}@endlatexonly@htmlonly</div>@endhtmlonly@xmlonly <!--- XMLMISSING --> @endxmlonly" \
|
||||
"CA{1}=@latexonly\commandlineargument{@endlatexonly@htmlonly<span class=\"commandlineargument\">@endhtmlonly@xmlonly <!--- XMLMISSING --> @endxmlonly\1@latexonly}@endlatexonly@htmlonly</span>@endhtmlonly@xmlonly <!--- XMLMISSING --> @endxmlonly" \
|
||||
"CO{1}=@latexonly\commandoption{@endlatexonly@htmlonly<span class=\"commandoption\">@endhtmlonly@xmlonly <!--- XMLMISSING --> @endxmlonly\1@latexonly}@endlatexonly@htmlonly</span>@endhtmlonly@xmlonly <!--- XMLMISSING --> @endxmlonly"
|
||||
|
||||
# rest calls
|
||||
ALIASES += \
|
||||
"RESTHEADER{2}=@latexonly\restheader{@endlatexonly@htmlonly<div class=\"restheader\">@endhtmlonly@xmlonly XMLMISSING @endxmlonly\1@latexonly,@endlatexonly@htmlonly<div class=\"restheaderremark\">(@endhtmlonly@xmlonly XMLMISSING @endxmlonly\2@latexonly}@endlatexonly@htmlonly)</div></div>@endhtmlonly@xmlonly XMLMISSING @endxmlonly" \
|
||||
"REST{1}=@latexonly\restcall{@endlatexonly@htmlonly<div class=\"restcall\">@endhtmlonly@xmlonly XMLMISSING @endxmlonly\1@latexonly}@endlatexonly@htmlonly</div>@endhtmlonly@xmlonly XMLMISSING @endxmlonly"
|
||||
"RESTHEADER{2}=@latexonly\restheader{@endlatexonly@htmlonly<div class=\"restheader\">@endhtmlonly@xmlonly <!--- XMLMISSING --> @endxmlonly\1@latexonly,@endlatexonly@htmlonly<div class=\"restheaderremark\">(@endhtmlonly@xmlonly <!--- XMLMISSING --> @endxmlonly\2@latexonly}@endlatexonly@htmlonly)</div></div>@endhtmlonly@xmlonly <!--- XMLMISSING --> @endxmlonly" \
|
||||
"REST{1}=@latexonly\restcall{@endlatexonly@htmlonly<div class=\"restcall\">@endhtmlonly@xmlonly <!--- XMLMISSING --> @endxmlonly\1@latexonly}@endlatexonly@htmlonly</div>@endhtmlonly@xmlonly <!--- XMLMISSING --> @endxmlonly"
|
||||
|
||||
# navigation
|
||||
ALIASES += \
|
||||
|
@ -227,7 +227,7 @@ ALIASES += \
|
|||
|
||||
# glossary
|
||||
ALIASES += \
|
||||
"GE{1}=@latexonly\glossaryentry{@endlatexonly@htmlonly<span class=\"glossaryentry\">@endhtmlonly@xmlonly XMLMISSING @endxmlonly\1@latexonly}@endlatexonly@htmlonly</span>@endhtmlonly@xmlonly XMLMISSING @endxmlonly"
|
||||
"GE{1}=@latexonly\glossaryentry{@endlatexonly@htmlonly<span class=\"glossaryentry\">@endhtmlonly@xmlonly <!--- XMLMISSING --> @endxmlonly\1@latexonly}@endlatexonly@htmlonly</span>@endhtmlonly@xmlonly <!--- XMLMISSING --> @endxmlonly"
|
||||
|
||||
# examples
|
||||
ALIASES += \
|
||||
|
@ -723,7 +723,8 @@ WARN_LOGFILE =
|
|||
INPUT = @srcdir@/Documentation/DbaManual \
|
||||
@srcdir@/Documentation/InstallationManual \
|
||||
@srcdir@/Documentation/Manual \
|
||||
@srcdir@/Documentation/UserManual \
|
||||
@srcdir@/Documentation/RefManual \
|
||||
@srcdir@/Documentation/UserManual \
|
||||
@srcdir@/Doxygen/js \
|
||||
@srcdir@/arangod \
|
||||
@srcdir@/lib
|
||||
|
|
|
@ -324,8 +324,7 @@ clean-local:
|
|||
|
||||
built-sources: \
|
||||
build_posix.h \
|
||||
@top_srcdir@/js/common/bootstrap/errors.js \
|
||||
$(JAVASCRIPT_HEADER)
|
||||
@top_srcdir@/js/common/bootstrap/errors.js
|
||||
|
||||
################################################################################
|
||||
### @brief tags file
|
||||
|
|
|
@ -4,22 +4,6 @@
|
|||
## --SECTION-- JAVASCRIPT
|
||||
## -----------------------------------------------------------------------------
|
||||
|
||||
################################################################################
|
||||
### @brief JavaScript source code as header
|
||||
################################################################################
|
||||
|
||||
JAVASCRIPT_HEADER = \
|
||||
js/common/bootstrap/js-errors.h \
|
||||
js/common/bootstrap/js-modules.h \
|
||||
js/common/bootstrap/js-monkeypatches.h \
|
||||
js/common/bootstrap/js-print.h \
|
||||
js/client/js-client.h \
|
||||
js/server/js-server.h \
|
||||
js/server/js-version-check.h \
|
||||
js/server/js-ahuacatl.h
|
||||
|
||||
BUILT_SOURCES += $(JAVASCRIPT_HEADER)
|
||||
|
||||
################################################################################
|
||||
### @brief JavaScript modules for browser
|
||||
################################################################################
|
||||
|
|
|
@ -58,7 +58,7 @@ describe ArangoDB do
|
|||
# create collection with one document
|
||||
@cid = ArangoDB.create_collection(cn)
|
||||
|
||||
cmd = "/_api/document?collection=#{@cid}"
|
||||
cmd = "/_api/document?collection=#{cn}"
|
||||
body = "{ \"Hello\" : \"World\" }"
|
||||
doc = ArangoDB.log_post("#{prefix}", cmd, :body => body)
|
||||
|
||||
|
|
|
@ -374,6 +374,7 @@ static void OptimisePaths (const TRI_aql_node_t* const fcallNode,
|
|||
len = strlen(lookFor);
|
||||
}
|
||||
else {
|
||||
// "any" will not be optimised
|
||||
lookFor = NULL;
|
||||
len = 0;
|
||||
}
|
||||
|
@ -395,6 +396,110 @@ static void OptimisePaths (const TRI_aql_node_t* const fcallNode,
|
|||
hint = (TRI_aql_collection_hint_t*) (TRI_AQL_NODE_DATA(vertexCollection));
|
||||
hint->_ranges = TRI_AddAccessAql(context, hint->_ranges, fieldAccess);
|
||||
}
|
||||
|
||||
if (args->_members._length <= 4 &&
|
||||
TRI_EqualString(name, ".edges.LENGTH()")) {
|
||||
// length restriction, can only be applied if length parameters are not already set
|
||||
TRI_aql_node_t* argNode;
|
||||
TRI_json_t* value;
|
||||
double minValue = 0.0;
|
||||
double maxValue = 0.0;
|
||||
bool useMin = false;
|
||||
bool useMax = false;
|
||||
|
||||
if (fieldAccess->_type == TRI_AQL_ACCESS_EXACT) {
|
||||
value = fieldAccess->_value._value;
|
||||
|
||||
if (value != NULL && value->_type == TRI_JSON_NUMBER) {
|
||||
// LENGTH(p.edges) == const
|
||||
minValue = maxValue = value->_value._number;
|
||||
useMin = useMax = true;
|
||||
}
|
||||
}
|
||||
else if (fieldAccess->_type == TRI_AQL_ACCESS_RANGE_SINGLE) {
|
||||
value = fieldAccess->_value._singleRange._value;
|
||||
|
||||
if (value != NULL && value->_type == TRI_JSON_NUMBER) {
|
||||
// LENGTH(p.edges) operator const
|
||||
if (fieldAccess->_value._singleRange._type == TRI_AQL_RANGE_LOWER_INCLUDED) {
|
||||
minValue = value->_value._number;
|
||||
useMin = true;
|
||||
}
|
||||
else if (fieldAccess->_value._singleRange._type == TRI_AQL_RANGE_UPPER_INCLUDED) {
|
||||
maxValue = value->_value._number;
|
||||
useMax = true;
|
||||
}
|
||||
else if (fieldAccess->_value._singleRange._type == TRI_AQL_RANGE_LOWER_EXCLUDED) {
|
||||
if ((double) ((int) value->_value._number) == value->_value._number) {
|
||||
minValue = value->_value._number + 1.0;
|
||||
useMin = true;
|
||||
}
|
||||
}
|
||||
else if (fieldAccess->_value._singleRange._type == TRI_AQL_RANGE_UPPER_EXCLUDED) {
|
||||
if ((double) ((int) value->_value._number) == value->_value._number) {
|
||||
maxValue = value->_value._number - 1.0;
|
||||
useMax = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (fieldAccess->_type == TRI_AQL_ACCESS_RANGE_DOUBLE) {
|
||||
// LENGTH(p.edges) > const && LENGTH(p.edges) < const
|
||||
value = fieldAccess->_value._between._lower._value;
|
||||
|
||||
if (value != NULL && value->_type == TRI_JSON_NUMBER) {
|
||||
if (fieldAccess->_value._between._lower._type == TRI_AQL_RANGE_LOWER_INCLUDED) {
|
||||
minValue = value->_value._number;
|
||||
useMin = true;
|
||||
}
|
||||
else if (fieldAccess->_value._between._lower._type == TRI_AQL_RANGE_LOWER_EXCLUDED) {
|
||||
if ((double) ((int) value->_value._number) == value->_value._number) {
|
||||
minValue = value->_value._number + 1.0;
|
||||
useMin = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
value = fieldAccess->_value._between._upper._value;
|
||||
|
||||
if (value != NULL && value->_type == TRI_JSON_NUMBER) {
|
||||
if (fieldAccess->_value._between._upper._type == TRI_AQL_RANGE_UPPER_INCLUDED) {
|
||||
maxValue = value->_value._number;
|
||||
useMax = true;
|
||||
}
|
||||
else if (fieldAccess->_value._between._upper._type == TRI_AQL_RANGE_UPPER_EXCLUDED) {
|
||||
if ((double) ((int) value->_value._number) == value->_value._number) {
|
||||
maxValue = value->_value._number - 1.0;
|
||||
useMax = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (useMin || useMax) {
|
||||
// minLength and maxLength are parameters 5 & 6
|
||||
// add as many null value nodes as are missing
|
||||
while (args->_members._length < 4) {
|
||||
argNode = TRI_CreateNodeValueNullAql(context);
|
||||
if (argNode) {
|
||||
TRI_PushBackVectorPointer(&args->_members, (void*) argNode);
|
||||
}
|
||||
}
|
||||
|
||||
// add min and max values to the function call argument list
|
||||
argNode = TRI_CreateNodeValueIntAql(context, useMin ? (int64_t) minValue : (int64_t) 0);
|
||||
if (argNode) {
|
||||
// min value node
|
||||
TRI_PushBackVectorPointer(&args->_members, (void*) argNode);
|
||||
|
||||
argNode = TRI_CreateNodeValueIntAql(context, useMax ? (int64_t) maxValue : (int64_t) (1024 * 1024));
|
||||
if (argNode) {
|
||||
// max value node
|
||||
TRI_PushBackVectorPointer(&args->_members, (void*) argNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -119,37 +119,37 @@
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// @anchor HttpCollectionCreate
|
||||
/// @copydetails JSF_POST_api_collection
|
||||
/// @copydetails JSF_post_api_collection
|
||||
///
|
||||
/// @anchor HttpCollectionDelete
|
||||
/// @copydetails JSF_DELETE_api_collection
|
||||
/// @copydetails JSF_delete_api_collection
|
||||
///
|
||||
/// @anchor HttpCollectionTruncate
|
||||
/// @copydetails JSF_PUT_api_collection_truncate
|
||||
/// @copydetails JSF_put_api_collection_truncate
|
||||
///
|
||||
/// @subsection HttpCollectionReading Getting Information about a Collection
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// @anchor HttpCollectionRead
|
||||
/// @copydetails JSF_GET_api_collection
|
||||
/// @copydetails JSF_get_api_collection
|
||||
///
|
||||
/// @anchor HttpCollectionReadAll
|
||||
/// @copydetails JSF_GET_api_collections
|
||||
/// @copydetails JSF_get_api_collections
|
||||
///
|
||||
/// @subsection HttpCollectionChanging Modifying a Collection
|
||||
/////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// @anchor HttpCollectionLoad
|
||||
/// @copydetails JSF_PUT_api_collection_load
|
||||
/// @copydetails JSF_put_api_collection_load
|
||||
///
|
||||
/// @anchor HttpCollectionUnload
|
||||
/// @copydetails JSF_PUT_api_collection_unload
|
||||
/// @copydetails JSF_put_api_collection_unload
|
||||
///
|
||||
/// @anchor HttpCollectionProperties
|
||||
/// @copydetails JSF_PUT_api_collection_properties
|
||||
/// @copydetails JSF_put_api_collection_properties
|
||||
///
|
||||
/// @anchor HttpCollectionRename
|
||||
/// @copydetails JSF_PUT_api_collection_rename
|
||||
/// @copydetails JSF_put_api_collection_rename
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Local Variables:
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief module "fs"
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2012 triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Dr. Frank Celler
|
||||
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @page JSModuleFsTOC
|
||||
///
|
||||
/// <ol>
|
||||
/// <li>@ref JSModuleFsExists "fs.exists"</li>
|
||||
/// </ol>
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @page JSModuleFs Module "fs"
|
||||
///
|
||||
/// The implementation follows the CommonJS specification
|
||||
/// <a href="http://wiki.commonjs.org/wiki/Filesystem/A/0">Filesystem/A/0</a>.
|
||||
///
|
||||
/// <hr>
|
||||
/// @copydoc JSModuleFsTOC
|
||||
/// <hr>
|
||||
///
|
||||
/// @anchor JSModuleFsExists
|
||||
/// @copydetails JS_Exists
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @\\}\\)"
|
||||
// End:
|
|
@ -1,186 +0,0 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief arango shell
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2012 triagens GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Dr. Frank Celler
|
||||
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- HANDLING DOCUMENTS
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @page ShellDocumentTOC
|
||||
///
|
||||
/// <ul>
|
||||
/// <li>@ref ShellDocument
|
||||
/// <ul>
|
||||
/// <li>@ref ShellDocumentIntro</li>
|
||||
/// <li>@ref ShellDocumentResource</li>
|
||||
/// <li>@ref ShellDocumentShell
|
||||
/// @copydetails ShellDocumentCallsTOC
|
||||
/// </li>
|
||||
/// </ul>
|
||||
/// </li>
|
||||
/// </ul>
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @page ShellDocumentCallsTOC
|
||||
///
|
||||
/// <ul>
|
||||
/// <li>@ref ShellDocumentCollectionMethods
|
||||
/// <ul>
|
||||
/// <li>@ref ShellDocumentRead "collection.document"</li>
|
||||
/// <li>@ref ShellDocumentCreate "collection.save"</li>
|
||||
/// <li>@ref ShellDocumentReplace "collection.replace"</li>
|
||||
/// <li>@ref ShellDocumentUpdate "collection.update"</li>
|
||||
/// <li>@ref ShellDocumentDelete "collection.remove"</li>
|
||||
/// </ul>
|
||||
/// </li>
|
||||
/// <li>@ref ShellDocumentDatabaseMethods
|
||||
/// <ul>
|
||||
/// <li>@ref ShellDocumentDbRead "db._document"</li>
|
||||
/// <li>@ref ShellDocumentDbReplace "db._replace"</li>
|
||||
/// <li>@ref ShellDocumentDbUpdate "db._update"</li>
|
||||
/// <li>@ref ShellDocumentDbDelete "db._remove"</li>
|
||||
/// </ul>
|
||||
/// </li>
|
||||
/// </ul>
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @page ShellDocument Handling Documents
|
||||
///
|
||||
/// @NAVIGATE_ShellDocument
|
||||
///
|
||||
/// This is an introduction to ArangoDB's interface for documents and how handle
|
||||
/// documents from the JavaScript shell @LIT{arangosh}. For other languages see
|
||||
/// the corresponding language API.
|
||||
///
|
||||
/// @EMBEDTOC{ShellDocumentTOC}
|
||||
///
|
||||
/// @section ShellDocumentIntro Documents, Identifiers, Handles
|
||||
///////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// @copydoc GlossaryDocument
|
||||
///
|
||||
/// For example:
|
||||
///
|
||||
/// @verbinclude document1
|
||||
///
|
||||
/// All documents contain special attributes: the document handle in @LIT{_id},
|
||||
/// the document's unique key in @LIT{_key} and and the etag aka document
|
||||
/// revision in @LIT{_rev}. The value of the @LIT{_key} attribute can be
|
||||
/// specified by the user when creating a document.
|
||||
/// @LIT{_id} and @LIT{_key} values are immutable once the document has been
|
||||
/// created. The @LIT{_rev} value is maintained by ArangoDB autonomously.
|
||||
///
|
||||
/// @copydoc GlossaryDocumentHandle
|
||||
///
|
||||
/// @copydoc GlossaryDocumentKey
|
||||
///
|
||||
/// @copydoc GlossaryDocumentRevision
|
||||
///
|
||||
/// @copydoc GlossaryDocumentEtag
|
||||
///
|
||||
/// @section ShellDocumentResource Address and ETag of an Document
|
||||
//////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// All documents in ArangoDB have a document handle. This handle uniquely
|
||||
/// defines a document and is managed by ArangoDB. The interface allows
|
||||
/// you to access the documents of a collection as:
|
||||
///
|
||||
/// @LIT{db.@FA{collection}.documet(@FA{document-handle})}
|
||||
///
|
||||
/// For example: Assume that the document handle, which is stored in
|
||||
/// the @LIT{_id} attribute of the document, is @LIT{demo/362549736}
|
||||
/// and the document lives in a collection named @FA{demo}, then
|
||||
/// that document can be accessed as:
|
||||
///
|
||||
/// @LIT{db.demo.document("demo/362549736")}
|
||||
///
|
||||
/// Because the document handle is unique within the database, you
|
||||
/// can leave out the @FA{collection} and use the shortcut:
|
||||
///
|
||||
/// @LIT{db._document("demo/362549736")}
|
||||
///
|
||||
/// Each document also has a document revision or etag with is returned
|
||||
/// in the @LIT{_rev} attribute when requesting a document. The document's
|
||||
/// key is returned in the @LIT{_key} attribute.
|
||||
///
|
||||
/// @CLEARPAGE
|
||||
/// @section ShellDocumentShell Working with Documents
|
||||
//////////////////////////////////////////////////////
|
||||
///
|
||||
/// @subsection ShellDocumentCollectionMethods Collection Methods
|
||||
/////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// @anchor ShellDocumentRead
|
||||
/// @copydetails JS_DocumentVocbaseCol
|
||||
///
|
||||
/// @CLEARPAGE
|
||||
/// @anchor ShellDocumentCreate
|
||||
/// @copydetails JS_SaveVocbaseCol
|
||||
///
|
||||
/// @CLEARPAGE
|
||||
/// @anchor ShellDocumentReplace
|
||||
/// @copydetails JS_ReplaceVocbaseCol
|
||||
///
|
||||
/// @CLEARPAGE
|
||||
/// @anchor ShellDocumentUpdate
|
||||
/// @copydetails JS_UpdateVocbaseCol
|
||||
///
|
||||
/// @CLEARPAGE
|
||||
/// @anchor ShellDocumentDelete
|
||||
/// @copydetails JS_RemoveVocbaseCol
|
||||
///
|
||||
/// @CLEARPAGE
|
||||
/// @subsection ShellDocumentDatabaseMethods Database Methods
|
||||
/////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// @anchor ShellDocumentDbRead
|
||||
/// @copydetails JS_DocumentVocbase
|
||||
///
|
||||
/// @CLEARPAGE
|
||||
/// @anchor ShellDocumentDbReplace
|
||||
/// @copydetails JS_ReplaceVocbase
|
||||
///
|
||||
/// @CLEARPAGE
|
||||
/// @anchor ShellDocumentDbUpdate
|
||||
/// @copydetails JS_UpdateVocbase
|
||||
///
|
||||
/// @CLEARPAGE
|
||||
/// @anchor ShellDocumentDbDelete
|
||||
/// @copydetails JS_RemoveVocbase
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Local Variables:
|
||||
// mode: c++
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @\\}\\)"
|
||||
// End:
|
|
@ -1,5 +1,5 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief installation guide
|
||||
/// @brief simple queries
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
|
|
|
@ -280,7 +280,7 @@ bool RestDocumentHandler::createDocument () {
|
|||
}
|
||||
|
||||
// find and load collection given by name or identifier
|
||||
SelfContainedWriteTransaction<RestTransactionContext> trx(_vocbase, collection, getCollectionType(), create);
|
||||
SelfContainedWriteTransaction<RestTransactionContext> trx(_vocbase, collection, create, getCollectionType());
|
||||
|
||||
// .............................................................................
|
||||
// inside write transaction
|
||||
|
@ -402,7 +402,7 @@ bool RestDocumentHandler::readSingleDocument (bool generateBody) {
|
|||
string key = suffix[1];
|
||||
|
||||
// find and load collection given by name or identifier
|
||||
SingleCollectionReadOnlyTransaction<StandaloneTransaction<RestTransactionContext> > trx(_vocbase, collection, getCollectionType());
|
||||
SingleCollectionReadOnlyTransaction<StandaloneTransaction<RestTransactionContext> > trx(_vocbase, collection);
|
||||
|
||||
// .............................................................................
|
||||
// inside read transaction
|
||||
|
@ -486,7 +486,7 @@ bool RestDocumentHandler::readAllDocuments () {
|
|||
string collection = _request->value("collection", found);
|
||||
|
||||
// find and load collection given by name or identifier
|
||||
SingleCollectionReadOnlyTransaction<StandaloneTransaction<RestTransactionContext> > trx(_vocbase, collection, getCollectionType());
|
||||
SingleCollectionReadOnlyTransaction<StandaloneTransaction<RestTransactionContext> > trx(_vocbase, collection);
|
||||
|
||||
vector<string> ids;
|
||||
|
||||
|
@ -757,7 +757,7 @@ bool RestDocumentHandler::modifyDocument (bool isPatch) {
|
|||
TRI_doc_update_policy_e policy = extractUpdatePolicy();
|
||||
|
||||
// find and load collection given by name or identifier
|
||||
SelfContainedWriteTransaction<RestTransactionContext> trx(_vocbase, collection, getCollectionType(), false);
|
||||
SelfContainedWriteTransaction<RestTransactionContext> trx(_vocbase, collection);
|
||||
|
||||
TRI_doc_mptr_t* document = 0;
|
||||
TRI_voc_rid_t rid = 0;
|
||||
|
@ -918,7 +918,7 @@ bool RestDocumentHandler::deleteDocument () {
|
|||
}
|
||||
|
||||
// find and load collection given by name or identifier
|
||||
SelfContainedWriteTransaction<RestTransactionContext> trx(_vocbase, collection, getCollectionType(), false);
|
||||
SelfContainedWriteTransaction<RestTransactionContext> trx(_vocbase, collection);
|
||||
TRI_voc_rid_t rid = 0;
|
||||
|
||||
// .............................................................................
|
||||
|
|
|
@ -163,7 +163,7 @@ bool RestEdgeHandler::createDocument () {
|
|||
}
|
||||
|
||||
// find and load collection given by name or identifier
|
||||
SelfContainedWriteTransaction<RestTransactionContext> trx(_vocbase, collection, getCollectionType(), create);
|
||||
SelfContainedWriteTransaction<RestTransactionContext> trx(_vocbase, collection, create, getCollectionType());
|
||||
|
||||
// .............................................................................
|
||||
// inside write transaction
|
||||
|
|
|
@ -205,7 +205,7 @@ bool RestImportHandler::createByDocumentsLines () {
|
|||
bool create = found ? StringUtils::boolean(valueStr) : false;
|
||||
|
||||
// find and load collection given by name or identifier
|
||||
ImportTransaction<StandaloneTransaction<RestTransactionContext> > trx(_vocbase, collection, TRI_COL_TYPE_DOCUMENT, create);
|
||||
ImportTransaction<StandaloneTransaction<RestTransactionContext> > trx(_vocbase, collection, create, TRI_COL_TYPE_DOCUMENT);
|
||||
|
||||
// .............................................................................
|
||||
// inside write transaction
|
||||
|
@ -350,7 +350,7 @@ bool RestImportHandler::createByDocumentsList () {
|
|||
bool create = found ? StringUtils::boolean(valueStr) : false;
|
||||
|
||||
// find and load collection given by name or identifier
|
||||
ImportTransaction<StandaloneTransaction<RestTransactionContext> > trx(_vocbase, collection, TRI_COL_TYPE_DOCUMENT, create);
|
||||
ImportTransaction<StandaloneTransaction<RestTransactionContext> > trx(_vocbase, collection, create, TRI_COL_TYPE_DOCUMENT);
|
||||
|
||||
// .............................................................................
|
||||
// inside write transaction
|
||||
|
@ -498,7 +498,7 @@ bool RestImportHandler::createByKeyValueList () {
|
|||
}
|
||||
|
||||
// find and load collection given by name or identifier
|
||||
ImportTransaction<StandaloneTransaction<RestTransactionContext> > trx(_vocbase, collection, TRI_COL_TYPE_DOCUMENT, create);
|
||||
ImportTransaction<StandaloneTransaction<RestTransactionContext> > trx(_vocbase, collection, create, TRI_COL_TYPE_DOCUMENT);
|
||||
|
||||
// .............................................................................
|
||||
// inside write transaction
|
||||
|
|
|
@ -953,7 +953,7 @@ mrb_value MR_ArangoDatabase_Collection (mrb_state* mrb, mrb_value self) {
|
|||
// looking at "mruby.h" I assume that is the way to unwrap the pointer
|
||||
rdata = (struct RData*) mrb_object(self);
|
||||
vocbase = (TRI_vocbase_t*) rdata->data;
|
||||
collection = TRI_FindCollectionByNameVocBase(vocbase, name, false);
|
||||
collection = TRI_LookupCollectionByNameVocBase(vocbase, name);
|
||||
|
||||
if (collection == NULL) {
|
||||
printf("unknown collection (TODO raise error)\n");
|
||||
|
|
|
@ -64,7 +64,7 @@ namespace triagens {
|
|||
if (_trx != 0) {
|
||||
if (_trx->_status == TRI_TRANSACTION_RUNNING) {
|
||||
// auto abort
|
||||
abort();
|
||||
this->abort();
|
||||
}
|
||||
|
||||
TRI_FreeTransaction(_trx);
|
||||
|
|
|
@ -62,10 +62,10 @@ namespace triagens {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ImportTransaction (TRI_vocbase_t* const vocbase,
|
||||
const string& collectionName,
|
||||
const TRI_col_type_e collectionType,
|
||||
const bool createCollection) :
|
||||
SingleCollectionWriteTransaction<T, UINT64_MAX>(vocbase, collectionName, collectionType, createCollection, "ImportTransaction") {
|
||||
const string& name,
|
||||
const bool create,
|
||||
const TRI_col_type_e createType) :
|
||||
SingleCollectionWriteTransaction<T, UINT64_MAX>(vocbase, name, create, createType) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -64,10 +64,35 @@ namespace triagens {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SelfContainedWriteTransaction (TRI_vocbase_t* const vocbase,
|
||||
const string& collectionName,
|
||||
const TRI_col_type_e collectionType,
|
||||
const bool createCollection) :
|
||||
SingleCollectionWriteTransaction<StandaloneTransaction<C>, 1>(vocbase, collectionName, collectionType, createCollection, "SelfContainedWriteTransaction") {
|
||||
const string& name) :
|
||||
SingleCollectionWriteTransaction<StandaloneTransaction<C>, 1>(vocbase, name) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create the transaction, using a collection object
|
||||
///
|
||||
/// A self contained write transaction operates on a single collection and may
|
||||
/// execute at most one write operation
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SelfContainedWriteTransaction (TRI_vocbase_t* const vocbase,
|
||||
const string& name,
|
||||
const TRI_col_type_e createType) :
|
||||
SingleCollectionWriteTransaction<StandaloneTransaction<C>, 1>(vocbase, name, createType) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create the transaction, using a collection object
|
||||
///
|
||||
/// A self contained write transaction operates on a single collection and may
|
||||
/// execute at most one write operation
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SelfContainedWriteTransaction (TRI_vocbase_t* const vocbase,
|
||||
const string& name,
|
||||
const bool create,
|
||||
const TRI_col_type_e createType) :
|
||||
SingleCollectionWriteTransaction<StandaloneTransaction<C>, 1>(vocbase, name, create, createType) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -62,9 +62,8 @@ namespace triagens {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SingleCollectionReadOnlyTransaction (TRI_vocbase_t* const vocbase,
|
||||
const string& collectionName,
|
||||
const TRI_col_type_e collectionType) :
|
||||
SingleCollectionTransaction<T>(vocbase, collectionName, collectionType, false, "SingleCollectionReadOnlyTransaction", TRI_TRANSACTION_READ) {
|
||||
const string& name) :
|
||||
SingleCollectionTransaction<T>(vocbase, name, TRI_TRANSACTION_READ) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -71,16 +71,29 @@ namespace triagens {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SingleCollectionTransaction (TRI_vocbase_t* const vocbase,
|
||||
const string& collectionName,
|
||||
const TRI_col_type_e collectionType,
|
||||
const bool createCollection,
|
||||
const string& trxName,
|
||||
const TRI_transaction_type_e type) :
|
||||
Transaction<T>(vocbase, trxName),
|
||||
_collectionName(collectionName),
|
||||
_collectionType(collectionType),
|
||||
_createCollection(createCollection),
|
||||
_type(type),
|
||||
const string& name,
|
||||
const TRI_transaction_type_e accessType) :
|
||||
Transaction<T>(vocbase, new TransactionCollectionsList(vocbase, name, accessType)),
|
||||
_name(name),
|
||||
_collection(0) {
|
||||
}
|
||||
|
||||
SingleCollectionTransaction (TRI_vocbase_t* const vocbase,
|
||||
const string& name,
|
||||
const TRI_transaction_type_e accessType,
|
||||
const TRI_col_type_e createType) :
|
||||
Transaction<T>(vocbase, new TransactionCollectionsList(vocbase, name, accessType, createType)),
|
||||
_name(name),
|
||||
_collection(0) {
|
||||
}
|
||||
|
||||
SingleCollectionTransaction (TRI_vocbase_t* const vocbase,
|
||||
const string& name,
|
||||
const TRI_transaction_type_e accessType,
|
||||
const bool create,
|
||||
const TRI_col_type_e createType) :
|
||||
Transaction<T>(vocbase, new TransactionCollectionsList(vocbase, name, accessType, create, createType)),
|
||||
_name(name),
|
||||
_collection(0) {
|
||||
}
|
||||
|
||||
|
@ -89,103 +102,6 @@ namespace triagens {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
virtual ~SingleCollectionTransaction () {
|
||||
if (! this->isEmbedded()) {
|
||||
if (this->_trx != 0) {
|
||||
if (this->status() == TRI_TRANSACTION_RUNNING) {
|
||||
// auto abort
|
||||
this->abort();
|
||||
}
|
||||
}
|
||||
|
||||
releaseCollection();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- virtual protected functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup ArangoDB
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
protected:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief use the underlying collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int useCollections () {
|
||||
if (_collection != 0) {
|
||||
// we already used this collectino, nothing to do
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
if (_collectionName.empty()) {
|
||||
// name is empty. cannot open the collection
|
||||
return TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND;
|
||||
}
|
||||
|
||||
// open or create the collection
|
||||
if (isdigit(_collectionName[0])) {
|
||||
TRI_voc_cid_t id = triagens::basics::StringUtils::uint64(_collectionName);
|
||||
|
||||
_collection = TRI_LookupCollectionByIdVocBase(this->_vocbase, id);
|
||||
}
|
||||
else {
|
||||
if (_collectionType == TRI_COL_TYPE_DOCUMENT) {
|
||||
_collection = TRI_FindDocumentCollectionByNameVocBase(this->_vocbase, _collectionName.c_str(), _createCollection);
|
||||
}
|
||||
else if (_collectionType == TRI_COL_TYPE_EDGE) {
|
||||
_collection = TRI_FindEdgeCollectionByNameVocBase(this->_vocbase, _collectionName.c_str(), _createCollection);
|
||||
}
|
||||
}
|
||||
|
||||
if (_collection == 0) {
|
||||
// collection not found
|
||||
return TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND;
|
||||
}
|
||||
|
||||
int res = TRI_UseCollectionVocBase(this->_vocbase, const_cast<TRI_vocbase_col_s*>(_collection));
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
_collection = 0;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
LOGGER_TRACE << "using collection " << _collectionName;
|
||||
assert(_collection->_collection != 0);
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief add all collections to the transaction (only one)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int addCollections () {
|
||||
if (this->isEmbedded()) {
|
||||
assert(_collection == 0);
|
||||
|
||||
_collection = TRI_CheckCollectionTransaction(this->_trx, _collectionName.c_str(), type());
|
||||
if (_collection == 0) {
|
||||
return TRI_ERROR_TRANSACTION_UNREGISTERED_COLLECTION;
|
||||
}
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
else {
|
||||
assert(_collection != 0);
|
||||
|
||||
int res = TRI_AddCollectionTransaction(this->_trx, _collectionName.c_str(), type(), _collection);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -207,8 +123,8 @@ namespace triagens {
|
|||
/// @brief return the name of the underlying collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline string collectionName () {
|
||||
return _collectionName;
|
||||
const string collectionName () const {
|
||||
return _name;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -216,6 +132,12 @@ namespace triagens {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline TRI_primary_collection_t* primaryCollection () {
|
||||
if (_collection == 0) {
|
||||
const vector<TransactionCollection*> collections = this->_collections->getCollections();
|
||||
_collection = TRI_GetCollectionTransaction(this->_trx, collections[0]->getName().c_str());
|
||||
}
|
||||
|
||||
assert(_collection != 0);
|
||||
assert(_collection->_collection != 0);
|
||||
return _collection->_collection;
|
||||
}
|
||||
|
@ -240,7 +162,11 @@ namespace triagens {
|
|||
/// @brief get the underlying collection's id
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline TRI_voc_cid_t cid () const {
|
||||
inline TRI_voc_cid_t cid () {
|
||||
if (_collection == 0) {
|
||||
_collection = TRI_GetCollectionTransaction(this->_trx, this->collectionName().c_str());
|
||||
}
|
||||
|
||||
assert(_collection != 0);
|
||||
return _collection->_cid;
|
||||
}
|
||||
|
@ -283,43 +209,6 @@ namespace triagens {
|
|||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup ArangoDB
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
private:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief release the underlying collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int releaseCollection () {
|
||||
// unuse underlying collection
|
||||
if (_collection != 0) {
|
||||
TRI_ReleaseCollectionVocBase(this->_vocbase, _collection);
|
||||
_collection = 0;
|
||||
}
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief get the transaction type
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline TRI_transaction_type_e type () const {
|
||||
return _type;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private variables
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -332,28 +221,10 @@ namespace triagens {
|
|||
private:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief name of the collection that is worked on
|
||||
/// @brief name of the collection used
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const string _collectionName;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief the type of the collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const TRI_col_type_e _collectionType;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief whether or not to create the collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const bool _createCollection;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief transaction type (READ | WRITE)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const TRI_transaction_type_e _type;
|
||||
string _name;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief data structure for the single collection used
|
||||
|
|
|
@ -70,11 +70,33 @@ namespace triagens {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SingleCollectionWriteTransaction (TRI_vocbase_t* const vocbase,
|
||||
const string& collectionName,
|
||||
const TRI_col_type_e collectionType,
|
||||
const bool createCollection,
|
||||
const string& trxName) :
|
||||
SingleCollectionTransaction<T>(vocbase, collectionName, collectionType, createCollection, trxName, TRI_TRANSACTION_WRITE),
|
||||
const string& name) :
|
||||
SingleCollectionTransaction<T>(vocbase, name, TRI_TRANSACTION_WRITE),
|
||||
_numWrites(0),
|
||||
_synchronous(false) {
|
||||
|
||||
if (N == 1) {
|
||||
this->addHint(TRI_TRANSACTION_HINT_SINGLE_OPERATION);
|
||||
}
|
||||
}
|
||||
|
||||
SingleCollectionWriteTransaction (TRI_vocbase_t* const vocbase,
|
||||
const string& name,
|
||||
const TRI_col_type_e createType) :
|
||||
SingleCollectionTransaction<T>(vocbase, name, TRI_TRANSACTION_WRITE, createType),
|
||||
_numWrites(0),
|
||||
_synchronous(false) {
|
||||
|
||||
if (N == 1) {
|
||||
this->addHint(TRI_TRANSACTION_HINT_SINGLE_OPERATION);
|
||||
}
|
||||
}
|
||||
|
||||
SingleCollectionWriteTransaction (TRI_vocbase_t* const vocbase,
|
||||
const string& name,
|
||||
const bool create,
|
||||
const TRI_col_type_e createType) :
|
||||
SingleCollectionTransaction<T>(vocbase, name, TRI_TRANSACTION_WRITE, create, createType),
|
||||
_numWrites(0),
|
||||
_synchronous(false) {
|
||||
|
||||
|
|
|
@ -35,13 +35,24 @@
|
|||
#include "Logger/Logger.h"
|
||||
#include "Utils/CollectionReadLock.h"
|
||||
#include "Utils/CollectionWriteLock.h"
|
||||
#include "Utils/TransactionCollectionsList.h"
|
||||
#include "Utils/TransactionCollection.h"
|
||||
|
||||
#if TRI_ENABLE_TRX
|
||||
//#define TRX_LOG LOGGER_INFO << __FUNCTION__ << ":" << __LINE__ << " "
|
||||
#define TRX_LOG if (false) std::cout
|
||||
#else
|
||||
#define TRX_LOG if (false) std::cout
|
||||
#endif
|
||||
|
||||
|
||||
namespace triagens {
|
||||
namespace arango {
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- class Transaction
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template<typename T>
|
||||
class Transaction : public T {
|
||||
|
@ -79,22 +90,27 @@ namespace triagens {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Transaction (TRI_vocbase_t* const vocbase,
|
||||
const string& trxName) :
|
||||
TransactionCollectionsList* collections) :
|
||||
T(),
|
||||
_vocbase(vocbase),
|
||||
_trxName(trxName),
|
||||
_collections(collections),
|
||||
_hints(0),
|
||||
_setupError(TRI_ERROR_NO_ERROR) {
|
||||
assert(_vocbase != 0);
|
||||
|
||||
int res = createTransaction();
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
this->_setupError = res;
|
||||
assert(_vocbase != 0);
|
||||
|
||||
TRX_LOG << "creating transaction";
|
||||
|
||||
int res = _collections->getError();
|
||||
if (res == TRI_ERROR_NO_ERROR) {
|
||||
res = createTransaction();
|
||||
}
|
||||
|
||||
#ifdef TRI_ENABLE_TRX
|
||||
// LOGGER_INFO << "created transaction " << this->_trxName;
|
||||
#endif
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
// setting up the transaction failed
|
||||
TRX_LOG << "creating transaction failed";
|
||||
this->_setupError = res;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -102,11 +118,17 @@ namespace triagens {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
virtual ~Transaction () {
|
||||
freeTransaction();
|
||||
|
||||
#ifdef TRI_ENABLE_TRX
|
||||
// LOGGER_INFO << "destroyed transaction " << this->_trxName;
|
||||
#endif
|
||||
TRX_LOG << "destroying transaction";
|
||||
|
||||
if (this->_trx != 0 && ! this->isEmbedded()) {
|
||||
if (this->status() == TRI_TRANSACTION_RUNNING) {
|
||||
// auto abort
|
||||
this->abort();
|
||||
}
|
||||
freeTransaction();
|
||||
}
|
||||
|
||||
delete _collections;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -129,6 +151,7 @@ namespace triagens {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int begin () {
|
||||
TRX_LOG << "beginning transaction";
|
||||
if (this->_setupError != TRI_ERROR_NO_ERROR) {
|
||||
return this->_setupError;
|
||||
}
|
||||
|
@ -140,25 +163,23 @@ namespace triagens {
|
|||
int res;
|
||||
|
||||
if (this->isEmbedded()) {
|
||||
res = addCollections();
|
||||
res = this->checkCollections();
|
||||
return res;
|
||||
}
|
||||
|
||||
// ! this->isEmbedded()
|
||||
|
||||
if (status() != TRI_TRANSACTION_CREATED) {
|
||||
return TRI_ERROR_TRANSACTION_INVALID_STATE;
|
||||
}
|
||||
|
||||
// register usage of the underlying collections
|
||||
res = useCollections();
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
return res;
|
||||
}
|
||||
|
||||
res = addCollections();
|
||||
res = this->addCollections();
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
return res;
|
||||
}
|
||||
|
||||
TRX_LOG << "calling transaction start";
|
||||
return TRI_StartTransaction(this->_trx, _hints);
|
||||
}
|
||||
|
||||
|
@ -167,21 +188,28 @@ namespace triagens {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int commit () {
|
||||
if (this->_trx == 0 || status() != TRI_TRANSACTION_RUNNING) {
|
||||
// not created or not running
|
||||
TRX_LOG << "committing transaction";
|
||||
|
||||
if (this->_trx == 0 || this->status() != TRI_TRANSACTION_RUNNING) {
|
||||
// transaction not created or not running
|
||||
return TRI_ERROR_TRANSACTION_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (this->isEmbedded()) {
|
||||
// return instantly if the transaction is embedded
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
int res;
|
||||
|
||||
|
||||
if (this->_trx->_type == TRI_TRANSACTION_READ) {
|
||||
// a read transaction just finishes
|
||||
TRX_LOG << "commit - finishing read transaction";
|
||||
res = TRI_FinishTransaction(this->_trx);
|
||||
}
|
||||
else {
|
||||
// a write transaction commits
|
||||
TRX_LOG << "commit - committing write transaction";
|
||||
res = TRI_CommitTransaction(this->_trx);
|
||||
}
|
||||
|
||||
|
@ -193,12 +221,13 @@ namespace triagens {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int abort () {
|
||||
TRX_LOG << "aborting transaction";
|
||||
if (this->_trx == 0) {
|
||||
// transaction not created
|
||||
return TRI_ERROR_TRANSACTION_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (status() != TRI_TRANSACTION_RUNNING) {
|
||||
if (this->status() != TRI_TRANSACTION_RUNNING) {
|
||||
return TRI_ERROR_TRANSACTION_INVALID_STATE;
|
||||
}
|
||||
|
||||
|
@ -217,14 +246,14 @@ namespace triagens {
|
|||
return TRI_ERROR_TRANSACTION_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (status() != TRI_TRANSACTION_RUNNING) {
|
||||
if (this->status() != TRI_TRANSACTION_RUNNING) {
|
||||
return TRI_ERROR_TRANSACTION_INVALID_STATE;
|
||||
}
|
||||
|
||||
int res;
|
||||
if (errorNumber == TRI_ERROR_NO_ERROR) {
|
||||
// there was no previous error, so we'll commit
|
||||
res = commit();
|
||||
res = this->commit();
|
||||
}
|
||||
else {
|
||||
// there was a previous error, so we'll abort
|
||||
|
@ -236,14 +265,6 @@ namespace triagens {
|
|||
return res;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief return the name of the transaction
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline string name () const {
|
||||
return this->_trxName;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief get the "vocbase"
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -574,33 +595,6 @@ namespace triagens {
|
|||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- virtual protected methods
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup ArangoDB
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
protected:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief use all collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
virtual int useCollections () = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief add all collections to the transaction
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
virtual int addCollections () = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private methods
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -612,6 +606,64 @@ namespace triagens {
|
|||
|
||||
private:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief check all collections to the transaction
|
||||
///
|
||||
/// this method is called in case the transaction is embedded. its purpose is
|
||||
/// to validate if all collections have been previously registered in the
|
||||
/// current transaction
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int checkCollections () {
|
||||
assert(this->isEmbedded());
|
||||
|
||||
TRX_LOG << "checking collections";
|
||||
|
||||
const vector<TransactionCollection*>& collections = _collections->getCollections();
|
||||
|
||||
for (size_t i = 0; i < collections.size(); ++i) {
|
||||
TransactionCollection* c = collections[i];
|
||||
TRI_vocbase_col_t* collection = TRI_CheckCollectionTransaction(this->_trx, c->getName().c_str(), c->getAccessType());
|
||||
|
||||
if (collection == 0) {
|
||||
return TRI_ERROR_TRANSACTION_UNREGISTERED_COLLECTION;
|
||||
}
|
||||
}
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief add all collections to the transaction
|
||||
///
|
||||
/// this method is called in case the transaction is not embedded. its purpose is
|
||||
/// to validate if all collections have been previously registered in the
|
||||
/// current transaction
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int addCollections () {
|
||||
assert(! this->isEmbedded());
|
||||
|
||||
TRX_LOG << "adding collections";
|
||||
|
||||
const vector<TransactionCollection*>& collections = _collections->getCollections();
|
||||
|
||||
for (size_t i = 0; i < collections.size(); ++i) {
|
||||
TransactionCollection* c = collections[i];
|
||||
|
||||
TRX_LOG << "adding collection " << c->getName();
|
||||
int res = TRI_AddCollectionTransaction(this->_trx, c->getName().c_str(), c->getAccessType());
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
TRX_LOG << "all collections added";
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create transaction
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -622,12 +674,20 @@ namespace triagens {
|
|||
return TRI_ERROR_TRANSACTION_NESTED;
|
||||
}
|
||||
|
||||
TRX_LOG << "creating embedded transaction";
|
||||
this->_trx = this->getParent();
|
||||
|
||||
if (this->_trx == 0) {
|
||||
TRX_LOG << "creating embedded transaction failed";
|
||||
return TRI_ERROR_TRANSACTION_INVALID_STATE;
|
||||
}
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
TRX_LOG << "creating standalone transaction";
|
||||
this->_trx = TRI_CreateTransaction(_vocbase->_transactionContext, TRI_TRANSACTION_READ_REPEATABLE);
|
||||
|
||||
if (this->_trx == 0) {
|
||||
return TRI_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -642,9 +702,9 @@ namespace triagens {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int freeTransaction () {
|
||||
if (this->isEmbedded()) {
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
assert(! this->isEmbedded());
|
||||
|
||||
TRX_LOG << "freeing standalone transaction";
|
||||
|
||||
if (this->_trx != 0) {
|
||||
this->unregisterTransaction();
|
||||
|
@ -677,6 +737,12 @@ namespace triagens {
|
|||
|
||||
TRI_vocbase_t* const _vocbase;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief the collections participating in the transaction
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TransactionCollectionsList* _collections;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -692,12 +758,6 @@ namespace triagens {
|
|||
|
||||
private:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief transaction name
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
string _trxName;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief transaction hints
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -709,7 +769,7 @@ namespace triagens {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int _setupError;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief transaction collection wrapper
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2004-2012 triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Jan Steemann
|
||||
/// @author Copyright 2011-2012, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef TRIAGENS_UTILS_TRANSACTION_COLLECTION_H
|
||||
#define TRIAGENS_UTILS_TRANSACTION_COLLECTION_H 1
|
||||
|
||||
#include "Basics/Common.h"
|
||||
|
||||
#include "VocBase/collection.h"
|
||||
#include "VocBase/transaction.h"
|
||||
|
||||
namespace triagens {
|
||||
namespace arango {
|
||||
|
||||
class TransactionCollection {
|
||||
|
||||
private:
|
||||
TransactionCollection (const TransactionCollection&);
|
||||
TransactionCollection& operator= (const TransactionCollection&);
|
||||
|
||||
public:
|
||||
TransactionCollection (const string& name, TRI_transaction_type_e accessType) :
|
||||
_name(name),
|
||||
_accessType(accessType),
|
||||
_createType(TRI_COL_TYPE_DOCUMENT),
|
||||
_create(false) {
|
||||
}
|
||||
|
||||
TransactionCollection (const string& name, TRI_col_type_e createType) :
|
||||
_name(name),
|
||||
_accessType(TRI_TRANSACTION_WRITE),
|
||||
_createType(TRI_COL_TYPE_DOCUMENT),
|
||||
_create(true) {
|
||||
}
|
||||
|
||||
~TransactionCollection () {
|
||||
}
|
||||
|
||||
inline const string getName () const {
|
||||
return _name;
|
||||
}
|
||||
|
||||
inline TRI_transaction_type_e getAccessType () const {
|
||||
return _accessType;
|
||||
}
|
||||
|
||||
inline void setAccessType (TRI_transaction_type_e accessType) {
|
||||
_accessType = accessType;
|
||||
}
|
||||
|
||||
inline bool getCreateFlag () const {
|
||||
return _create;
|
||||
}
|
||||
|
||||
inline TRI_col_type_e getCreateType () const {
|
||||
return _createType;
|
||||
}
|
||||
|
||||
private:
|
||||
string _name;
|
||||
|
||||
TRI_transaction_type_e _accessType;
|
||||
|
||||
TRI_col_type_e _createType;
|
||||
|
||||
bool _create;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|/// @page\\|// --SECTION--\\|/// @\\}\\)"
|
||||
// End:
|
|
@ -0,0 +1,195 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief transaction collections list
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2004-2012 triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Jan Steemann
|
||||
/// @author Copyright 2011-2012, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef TRIAGENS_UTILS_TRANSACTION_COLLECTION_LIST_H
|
||||
#define TRIAGENS_UTILS_TRANSACTION_COLLECTION_LIST_H 1
|
||||
|
||||
#include "Basics/Common.h"
|
||||
|
||||
#include "VocBase/collection.h"
|
||||
#include "VocBase/transaction.h"
|
||||
#include "VocBase/vocbase.h"
|
||||
|
||||
#include "Utils/TransactionCollection.h"
|
||||
|
||||
|
||||
namespace triagens {
|
||||
namespace arango {
|
||||
|
||||
class TransactionCollectionsList {
|
||||
typedef map<string, TransactionCollection*> ListType;
|
||||
|
||||
private:
|
||||
TransactionCollectionsList& operator= (const TransactionCollectionsList&);
|
||||
TransactionCollectionsList (const TransactionCollectionsList&);
|
||||
|
||||
public:
|
||||
TransactionCollectionsList () :
|
||||
_collections() {
|
||||
}
|
||||
|
||||
TransactionCollectionsList (TRI_vocbase_t* const vocbase,
|
||||
const string& name,
|
||||
TRI_transaction_type_e accessType) :
|
||||
_vocbase(vocbase),
|
||||
_collections(),
|
||||
_error(TRI_ERROR_NO_ERROR) {
|
||||
addCollection(name, accessType, false);
|
||||
}
|
||||
|
||||
TransactionCollectionsList (TRI_vocbase_t* const vocbase,
|
||||
const string& name,
|
||||
TRI_transaction_type_e accessType,
|
||||
const TRI_col_type_e createType) :
|
||||
_vocbase(vocbase),
|
||||
_collections(),
|
||||
_error(TRI_ERROR_NO_ERROR) {
|
||||
addCollection(name, accessType, true, createType);
|
||||
}
|
||||
|
||||
TransactionCollectionsList (TRI_vocbase_t* const vocbase,
|
||||
const string& name,
|
||||
TRI_transaction_type_e accessType,
|
||||
const bool create,
|
||||
const TRI_col_type_e createType) :
|
||||
_vocbase(vocbase),
|
||||
_collections(),
|
||||
_error(TRI_ERROR_NO_ERROR) {
|
||||
addCollection(name, accessType, create, createType);
|
||||
}
|
||||
|
||||
TransactionCollectionsList (TRI_vocbase_t* const vocbase,
|
||||
const vector<string>& readCollections,
|
||||
const vector<string>& writeCollections) :
|
||||
_vocbase(vocbase),
|
||||
_collections() {
|
||||
for (size_t i = 0; i < readCollections.size(); ++i) {
|
||||
addCollection(readCollections[i], TRI_TRANSACTION_READ, false);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < writeCollections.size(); ++i) {
|
||||
addCollection(writeCollections[i], TRI_TRANSACTION_WRITE, false);
|
||||
}
|
||||
}
|
||||
|
||||
~TransactionCollectionsList () {
|
||||
ListType::iterator it;
|
||||
|
||||
for (it = _collections.begin(); it != _collections.end(); ++it) {
|
||||
delete (*it).second;
|
||||
}
|
||||
|
||||
_collections.clear();
|
||||
}
|
||||
|
||||
inline int getError () const {
|
||||
return _error;
|
||||
}
|
||||
|
||||
const vector<TransactionCollection*> getCollections () {
|
||||
ListType::iterator it;
|
||||
vector<TransactionCollection*> collections;
|
||||
|
||||
for (it = _collections.begin(); it != _collections.end(); ++it) {
|
||||
collections.push_back((*it).second);
|
||||
}
|
||||
|
||||
return collections;
|
||||
}
|
||||
|
||||
void addCollection (const string& name,
|
||||
TRI_transaction_type_e type,
|
||||
bool create,
|
||||
TRI_col_type_e createType = TRI_COL_TYPE_DOCUMENT) {
|
||||
ListType::iterator it;
|
||||
string realName;
|
||||
|
||||
if (name.empty()) {
|
||||
_error = TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND;
|
||||
return;
|
||||
}
|
||||
|
||||
if (isdigit(name[0])) {
|
||||
// name is passed as a string with the collection id
|
||||
|
||||
// look up the collection name for the id
|
||||
TRI_voc_cid_t id = triagens::basics::StringUtils::uint64(name);
|
||||
|
||||
char* n = TRI_GetCollectionNameByIdVocBase(_vocbase, id);
|
||||
if (n == 0) {
|
||||
_error = TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND;
|
||||
return;
|
||||
}
|
||||
|
||||
realName = string(n);
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, n);
|
||||
}
|
||||
else {
|
||||
// name is passed as a "real" name
|
||||
realName = name;
|
||||
}
|
||||
|
||||
it = _collections.find(realName);
|
||||
if (it != _collections.end()) {
|
||||
TransactionCollection* c = (*it).second;
|
||||
|
||||
if (type == TRI_TRANSACTION_WRITE && type != c->getAccessType()) {
|
||||
// upgrade the type
|
||||
c->setAccessType(type);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
// check whether the collection exists. if not, create it
|
||||
if (( create && TRI_FindCollectionByNameOrBearVocBase(_vocbase, realName.c_str(), createType) == NULL) ||
|
||||
(! create && TRI_LookupCollectionByNameVocBase(_vocbase, realName.c_str()) == NULL)) {
|
||||
_error = TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND;
|
||||
return;
|
||||
}
|
||||
|
||||
_collections[realName] = new TransactionCollection(realName, type);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
TRI_vocbase_t* _vocbase;
|
||||
|
||||
ListType _collections;
|
||||
|
||||
int _error;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|/// @page\\|// --SECTION--\\|/// @\\}\\)"
|
||||
// End:
|
|
@ -61,9 +61,7 @@ namespace triagens {
|
|||
UserTransaction (TRI_vocbase_t* const vocbase,
|
||||
const vector<string>& readCollections,
|
||||
const vector<string>& writeCollections) :
|
||||
Transaction<T>(vocbase, "UserTransaction"),
|
||||
_readCollections(readCollections),
|
||||
_writeCollections(writeCollections) {
|
||||
Transaction<T>(vocbase, new TransactionCollectionsList(vocbase, readCollections, writeCollections)) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -71,99 +69,8 @@ namespace triagens {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
~UserTransaction () {
|
||||
if (this->_trx != 0) {
|
||||
if (this->status() == TRI_TRANSACTION_RUNNING) {
|
||||
// auto abort
|
||||
this->abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- virtual protected functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup ArangoDB
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
protected:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief use all collections
|
||||
/// this is a no op, as using is done when trx is started
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int useCollections () {
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief release all collections in use
|
||||
/// this is a no op, as releasing is done when trx is finished
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int releaseCollections () {
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief add all collections to the transaction
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int addCollections () {
|
||||
int res;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < _readCollections.size(); ++i) {
|
||||
res = TRI_AddCollectionTransaction(this->_trx, _readCollections[i].c_str(), TRI_TRANSACTION_READ, 0);
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < _writeCollections.size(); ++i) {
|
||||
res = TRI_AddCollectionTransaction(this->_trx, _writeCollections[i].c_str(), TRI_TRANSACTION_WRITE, 0);
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private variables
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup ArangoDB
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief collections that are opened in read mode
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
vector<string> _readCollections;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief collections that are opened in write mode
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
vector<string> _writeCollections;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -640,15 +640,18 @@ void ApplicationV8::stop () {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool ApplicationV8::prepareV8Instance (const size_t i) {
|
||||
static char const* files[] = { "common/bootstrap/modules.js",
|
||||
"common/bootstrap/monkeypatches.js",
|
||||
"common/bootstrap/print.js",
|
||||
"common/bootstrap/errors.js",
|
||||
"server/ahuacatl.js",
|
||||
"server/server.js",
|
||||
"server/ArangoCollection.js",
|
||||
"server/ArangoStructure.js"
|
||||
};
|
||||
vector<string> files;
|
||||
|
||||
files.push_back("common/bootstrap/modules.js");
|
||||
files.push_back("common/bootstrap/module-internal.js");
|
||||
files.push_back("common/bootstrap/module-fs.js");
|
||||
files.push_back("common/bootstrap/module-console.js");
|
||||
files.push_back("common/bootstrap/monkeypatches.js");
|
||||
files.push_back("common/bootstrap/errors.js");
|
||||
files.push_back("server/ahuacatl.js");
|
||||
files.push_back("server/server.js");
|
||||
files.push_back("server/ArangoCollection.js");
|
||||
files.push_back("server/ArangoStructure.js");
|
||||
|
||||
LOGGER_TRACE << "initialising V8 context #" << i;
|
||||
|
||||
|
@ -687,7 +690,7 @@ bool ApplicationV8::prepareV8Instance (const size_t i) {
|
|||
TRI_InitV8Shell(context->_context);
|
||||
|
||||
// load all init files
|
||||
for (size_t j = 0; j < sizeof(files) / sizeof(files[0]); ++j) {
|
||||
for (size_t j = 0; j < files.size(); ++j) {
|
||||
bool ok = _startupLoader.loadScript(context->_context, files[j]);
|
||||
|
||||
if (! ok) {
|
||||
|
|
|
@ -416,7 +416,7 @@ static HttpResponse* ExecuteActionVocbase (TRI_vocbase_t* vocbase,
|
|||
collection = TRI_LookupCollectionByIdVocBase(vocbase, TRI_UInt64String(v.c_str()));
|
||||
}
|
||||
else {
|
||||
collection = TRI_FindCollectionByNameVocBase(vocbase, v.c_str(), false);
|
||||
collection = TRI_LookupCollectionByNameVocBase(vocbase, v.c_str());
|
||||
}
|
||||
|
||||
if (collection != 0) {
|
||||
|
@ -428,7 +428,7 @@ static HttpResponse* ExecuteActionVocbase (TRI_vocbase_t* vocbase,
|
|||
}
|
||||
|
||||
case TRI_ACT_COLLECTION_NAME: {
|
||||
TRI_vocbase_col_t const* collection = TRI_FindCollectionByNameVocBase(vocbase, v.c_str(), false);
|
||||
TRI_vocbase_col_t const* collection = TRI_LookupCollectionByNameVocBase(vocbase, v.c_str());
|
||||
|
||||
if (collection != 0) {
|
||||
valuesObject->Set(v8::String::New(k.c_str()), TRI_WrapCollection(collection));
|
||||
|
|
|
@ -1741,7 +1741,7 @@ static v8::Handle<v8::Value> JS_AllQuery (v8::Arguments const& argv) {
|
|||
uint32_t total = 0;
|
||||
vector<TRI_doc_mptr_t*> docs;
|
||||
|
||||
SingleCollectionReadOnlyTransaction<EmbeddableTransaction<V8TransactionContext> > trx(col->_vocbase, col->_name, (TRI_col_type_e) col->_type);
|
||||
SingleCollectionReadOnlyTransaction<EmbeddableTransaction<V8TransactionContext> > trx(col->_vocbase, col->_name);
|
||||
|
||||
int res = trx.begin();
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
|
|
|
@ -764,7 +764,7 @@ static v8::Handle<v8::Value> DocumentVocbaseCol (const bool useCollection,
|
|||
assert(key);
|
||||
|
||||
|
||||
SingleCollectionReadOnlyTransaction<EmbeddableTransaction<V8TransactionContext> > trx(col->_vocbase, col->_name, (TRI_col_type_e) col->_type);
|
||||
SingleCollectionReadOnlyTransaction<EmbeddableTransaction<V8TransactionContext> > trx(col->_vocbase, col->_name);
|
||||
int res = trx.begin();
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
return scope.Close(v8::ThrowException(TRI_CreateErrorObject(res, "cannot fetch document", true)));
|
||||
|
@ -849,7 +849,7 @@ static v8::Handle<v8::Value> ReplaceVocbaseCol (const bool useCollection,
|
|||
assert(key);
|
||||
|
||||
|
||||
SingleCollectionWriteTransaction<EmbeddableTransaction<V8TransactionContext>, 1> trx(col->_vocbase, col->_name, (TRI_col_type_e) col->_type, false, "ReplaceVocbase");
|
||||
SingleCollectionWriteTransaction<EmbeddableTransaction<V8TransactionContext>, 1> trx(col->_vocbase, col->_name);
|
||||
int res = trx.begin();
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
return scope.Close(v8::ThrowException(TRI_CreateErrorObject(res, "cannot replace document", true)));
|
||||
|
@ -903,11 +903,11 @@ static v8::Handle<v8::Value> ReplaceVocbaseCol (const bool useCollection,
|
|||
/// above. The optional @FA{waitForSync} parameter can be used to force
|
||||
/// synchronisation of the document creation operation to disk even in case
|
||||
/// that the @LIT{waitForSync} flag had been disabled for the entire collection.
|
||||
/// Thus, the @FA{waitForSync} URL parameter can be used to force synchronisation
|
||||
/// Thus, the @FA{waitForSync} parameter can be used to force synchronisation
|
||||
/// of just specific operations. To use this, set the @FA{waitForSync} parameter
|
||||
/// to @LIT{true}. If the @FA{waitForSync} parameter is not specified or set to
|
||||
/// @LIT{false}, then the collection's default @LIT{waitForSync} behavior is
|
||||
/// applied. The @FA{waitForSync} URL parameter cannot be used to disable
|
||||
/// applied. The @FA{waitForSync} parameter cannot be used to disable
|
||||
/// synchronisation for collections that have a default @LIT{waitForSync} value
|
||||
/// of @LIT{true}.
|
||||
///
|
||||
|
@ -984,11 +984,11 @@ static v8::Handle<v8::Value> SaveVocbaseCol (SingleCollectionWriteTransaction<Em
|
|||
/// The optional @FA{waitForSync} parameter can be used to force
|
||||
/// synchronisation of the document creation operation to disk even in case
|
||||
/// that the @LIT{waitForSync} flag had been disabled for the entire collection.
|
||||
/// Thus, the @FA{waitForSync} URL parameter can be used to force synchronisation
|
||||
/// Thus, the @FA{waitForSync} parameter can be used to force synchronisation
|
||||
/// of just specific operations. To use this, set the @FA{waitForSync} parameter
|
||||
/// to @LIT{true}. If the @FA{waitForSync} parameter is not specified or set to
|
||||
/// @LIT{false}, then the collection's default @LIT{waitForSync} behavior is
|
||||
/// applied. The @FA{waitForSync} URL parameter cannot be used to disable
|
||||
/// applied. The @FA{waitForSync} parameter cannot be used to disable
|
||||
/// synchronisation for collections that have a default @LIT{waitForSync} value
|
||||
/// of @LIT{true}.
|
||||
///
|
||||
|
@ -1155,7 +1155,7 @@ static v8::Handle<v8::Value> UpdateVocbaseCol (const bool useCollection,
|
|||
}
|
||||
|
||||
|
||||
SingleCollectionWriteTransaction<EmbeddableTransaction<V8TransactionContext>, 1> trx(col->_vocbase, col->_name, (TRI_col_type_e) col->_type, false, "UpdateVocbase");
|
||||
SingleCollectionWriteTransaction<EmbeddableTransaction<V8TransactionContext>, 1> trx(col->_vocbase, col->_name);
|
||||
int res = trx.begin();
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
return scope.Close(v8::ThrowException(TRI_CreateErrorObject(res, "cannot update document", true)));
|
||||
|
@ -1256,7 +1256,7 @@ static v8::Handle<v8::Value> RemoveVocbaseCol (const bool useCollection,
|
|||
assert(key);
|
||||
|
||||
|
||||
SingleCollectionWriteTransaction<EmbeddableTransaction<V8TransactionContext>, 1> trx(col->_vocbase, col->_name, (TRI_col_type_e) col->_type, false, "DeleteVocbase");
|
||||
SingleCollectionWriteTransaction<EmbeddableTransaction<V8TransactionContext>, 1> trx(col->_vocbase, col->_name);
|
||||
int res = trx.begin();
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
return scope.Close(v8::ThrowException(TRI_CreateErrorObject(res, "cannot delete document", true)));
|
||||
|
@ -3311,10 +3311,7 @@ static v8::Handle<v8::Value> JS_DatafilesVocbaseCol (v8::Arguments const& argv)
|
|||
/// An error is thrown if there @LIT{_rev} does not longer match the current
|
||||
/// revision of the document.
|
||||
///
|
||||
/// An error is thrown if the document does not exist.
|
||||
///
|
||||
/// The document must be part of the @FA{collection}; otherwise, an error
|
||||
/// is thrown.
|
||||
/// An error is also thrown if the document does not exist.
|
||||
///
|
||||
/// @FUN{@FA{collection}.document(@FA{document-handle})}
|
||||
///
|
||||
|
@ -3325,15 +3322,30 @@ static v8::Handle<v8::Value> JS_DatafilesVocbaseCol (v8::Arguments const& argv)
|
|||
///
|
||||
/// Returns the document for a document-handle:
|
||||
///
|
||||
/// @TINYEXAMPLE{shell-read-document,read document from a collection}
|
||||
/// @code
|
||||
/// arango> db.example.document("1432124/2873916");
|
||||
/// { "_id" : "1432124/2873916", "_rev" : 2873916, "Hallo" : "World" }
|
||||
/// @endcode
|
||||
///
|
||||
/// An error is raised if the document is unknown:
|
||||
///
|
||||
/// @TINYEXAMPLE{shell-read-document-not-found,unknown handle}
|
||||
/// @code
|
||||
/// arango> db.example.document("1432124/123456");
|
||||
/// JavaScript exception in file '(arango)' at 1,12:
|
||||
/// [ArangoError 1202: document not found: document not found]
|
||||
/// !db.example.document("1432124/123456");
|
||||
/// ! ^
|
||||
/// @endcode
|
||||
///
|
||||
/// An error is raised if the handle is invalid:
|
||||
///
|
||||
/// @TINYEXAMPLE{shell-read-document-bad-handle,invalid handle}
|
||||
/// @code
|
||||
/// arango> db.example.document("12345");
|
||||
/// JavaScript exception in file '(arango)' at 1,12:
|
||||
/// [ArangoError 10: bad parameter: <document-identifier> must be a document identifier]
|
||||
/// !db.example.document("12345");
|
||||
/// ! ^
|
||||
/// @endcode
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static v8::Handle<v8::Value> JS_DocumentVocbaseCol (v8::Arguments const& argv) {
|
||||
|
@ -4462,6 +4474,7 @@ static v8::Handle<v8::Value> JS_NameVocbaseCol (v8::Arguments const& argv) {
|
|||
return scope.Close(v8::ThrowException(v8::String::New("illegal collection pointer")));
|
||||
}
|
||||
|
||||
// TODO: protect this against race conditions (parallel rename operation)
|
||||
return scope.Close(v8::String::New(collection->_name));
|
||||
}
|
||||
|
||||
|
@ -4624,29 +4637,29 @@ static v8::Handle<v8::Value> JS_PropertiesVocbaseCol (v8::Arguments const& argv)
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief deletes a document
|
||||
/// @brief removes a document
|
||||
///
|
||||
/// @FUN{@FA{collection}.remove(@FA{document})}
|
||||
///
|
||||
/// Deletes a document. If there is revision mismatch, then an error is thrown.
|
||||
/// Removes a document. If there is revision mismatch, then an error is thrown.
|
||||
///
|
||||
/// @FUN{@FA{collection}.remove(@FA{document}, true)}
|
||||
///
|
||||
/// Deletes a document. If there is revision mismatch, then mismatch
|
||||
/// is ignored and document is deleted. The function returns
|
||||
/// @LIT{true} if the document existed and was deleted. It returns
|
||||
/// @LIT{false}, if the document was already deleted.
|
||||
/// Removes a document. If there is revision mismatch, then mismatch is ignored
|
||||
/// and document is deleted. The function returns @LIT{true} if the document
|
||||
/// existed and was deleted. It returns @LIT{false}, if the document was already
|
||||
/// deleted.
|
||||
///
|
||||
/// @FUN{@FA{collection}.remove(@FA{document}, true, @FA{waitForSync})}
|
||||
///
|
||||
/// The optional @FA{waitForSync} parameter can be used to force
|
||||
/// synchronisation of the document deletion operation to disk even in case
|
||||
/// that the @LIT{waitForSync} flag had been disabled for the entire collection.
|
||||
/// Thus, the @FA{waitForSync} URL parameter can be used to force synchronisation
|
||||
/// of just specific operations. To use this, set the @FA{waitForSync} parameter
|
||||
/// to @LIT{true}. If the @FA{waitForSync} parameter is not specified or set to
|
||||
/// @LIT{false}, then the collection's default @LIT{waitForSync} behavior is
|
||||
/// applied. The @FA{waitForSync} URL parameter cannot be used to disable
|
||||
/// The optional @FA{waitForSync} parameter can be used to force synchronisation
|
||||
/// of the document deletion operation to disk even in case that the
|
||||
/// @LIT{waitForSync} flag had been disabled for the entire collection. Thus,
|
||||
/// the @FA{waitForSync} parameter can be used to force synchronisation of just
|
||||
/// specific operations. To use this, set the @FA{waitForSync} parameter to
|
||||
/// @LIT{true}. If the @FA{waitForSync} parameter is not specified or set to
|
||||
/// @LIT{false}, then the collection's default @LIT{waitForSync} behavior is
|
||||
/// applied. The @FA{waitForSync} parameter cannot be used to disable
|
||||
/// synchronisation for collections that have a default @LIT{waitForSync} value
|
||||
/// of @LIT{true}.
|
||||
///
|
||||
|
@ -4657,13 +4670,39 @@ static v8::Handle<v8::Value> JS_PropertiesVocbaseCol (v8::Arguments const& argv)
|
|||
///
|
||||
/// @EXAMPLES
|
||||
///
|
||||
/// Delete a document:
|
||||
/// Remove a document:
|
||||
///
|
||||
/// @TINYEXAMPLE{shell_remove-document,delete a document}
|
||||
/// @code
|
||||
/// arango> a1 = db.example.save({ a : 1 });
|
||||
/// { "_id" : "116308/3449537", "_rev" : 3449537 }
|
||||
/// arango> db.example.document(a1);
|
||||
/// { "_id" : "116308/3449537", "_rev" : 3449537, "a" : 1 }
|
||||
/// arango> db.example.remove(a1);
|
||||
/// true
|
||||
/// arango> db.example.document(a1);
|
||||
/// JavaScript exception in file '(arango)' at 1,12: [ArangoError 1202: document not found: document not found]
|
||||
/// !db.example.document(a1);
|
||||
/// ! ^
|
||||
/// @endcode
|
||||
///
|
||||
/// Delete a document with a conflict:
|
||||
/// Remove a document with a conflict:
|
||||
///
|
||||
/// @TINYEXAMPLE{shell_remove-document-conflict,delete a document}
|
||||
/// @code
|
||||
/// arango> a1 = db.example.save({ a : 1 });
|
||||
/// { "_id" : "116308/3857139", "_rev" : 3857139 }
|
||||
/// arango> a2 = db.example.replace(a1, { a : 2 });
|
||||
/// { "_id" : "116308/3857139", "_rev" : 3922675, "_oldRev" : 3857139 }
|
||||
/// arango> db.example.remove(a1);
|
||||
/// JavaScript exception in file '(arango)' at 1,18: [ArangoError 1200: conflict: cannot remove document]
|
||||
/// !db.example.remove(a1);
|
||||
/// ! ^
|
||||
/// arango> db.example.remove(a1, true);
|
||||
/// true
|
||||
/// arango> db.example.document(a1);
|
||||
/// JavaScript exception in file '(arango)' at 1,12: [ArangoError 1202: document not found: document not found]
|
||||
/// !db.example.document(a1);
|
||||
/// ! ^
|
||||
/// @endcode
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static v8::Handle<v8::Value> JS_RemoveVocbaseCol (v8::Arguments const& argv) {
|
||||
|
@ -4743,11 +4782,11 @@ static v8::Handle<v8::Value> JS_RenameVocbaseCol (v8::Arguments const& argv) {
|
|||
/// The optional @FA{waitForSync} parameter can be used to force
|
||||
/// synchronisation of the document replacement operation to disk even in case
|
||||
/// that the @LIT{waitForSync} flag had been disabled for the entire collection.
|
||||
/// Thus, the @FA{waitForSync} URL parameter can be used to force synchronisation
|
||||
/// Thus, the @FA{waitForSync} parameter can be used to force synchronisation
|
||||
/// of just specific operations. To use this, set the @FA{waitForSync} parameter
|
||||
/// to @LIT{true}. If the @FA{waitForSync} parameter is not specified or set to
|
||||
/// @LIT{false}, then the collection's default @LIT{waitForSync} behavior is
|
||||
/// applied. The @FA{waitForSync} URL parameter cannot be used to disable
|
||||
/// applied. The @FA{waitForSync} parameter cannot be used to disable
|
||||
/// synchronisation for collections that have a default @LIT{waitForSync} value
|
||||
/// of @LIT{true}.
|
||||
///
|
||||
|
@ -4789,11 +4828,11 @@ static v8::Handle<v8::Value> JS_ReplaceVocbaseCol (v8::Arguments const& argv) {
|
|||
/// The optional @FA{waitForSync} parameter can be used to force
|
||||
/// synchronisation of the document update operation to disk even in case
|
||||
/// that the @LIT{waitForSync} flag had been disabled for the entire collection.
|
||||
/// Thus, the @FA{waitForSync} URL parameter can be used to force synchronisation
|
||||
/// Thus, the @FA{waitForSync} parameter can be used to force synchronisation
|
||||
/// of just specific operations. To use this, set the @FA{waitForSync} parameter
|
||||
/// to @LIT{true}. If the @FA{waitForSync} parameter is not specified or set to
|
||||
/// @LIT{false}, then the collection's default @LIT{waitForSync} behavior is
|
||||
/// applied. The @FA{waitForSync} URL parameter cannot be used to disable
|
||||
/// applied. The @FA{waitForSync} parameter cannot be used to disable
|
||||
/// synchronisation for collections that have a default @LIT{waitForSync} value
|
||||
/// of @LIT{true}.
|
||||
///
|
||||
|
@ -4854,7 +4893,7 @@ static v8::Handle<v8::Value> JS_SaveVocbaseCol (v8::Arguments const& argv) {
|
|||
return scope.Close(v8::ThrowException(TRI_CreateErrorObject(TRI_ERROR_INTERNAL)));
|
||||
}
|
||||
|
||||
SingleCollectionWriteTransaction<EmbeddableTransaction<V8TransactionContext>, 1> trx(col->_vocbase, col->_name, (TRI_col_type_e) col->_type, false, "SaveVocbase");
|
||||
SingleCollectionWriteTransaction<EmbeddableTransaction<V8TransactionContext>, 1> trx(col->_vocbase, col->_name);
|
||||
|
||||
int res = trx.begin();
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
|
@ -4946,6 +4985,37 @@ static v8::Handle<v8::Value> JS_StatusVocbaseCol (v8::Arguments const& argv) {
|
|||
return scope.Close(v8::Number::New((int) status));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief returns the revision id of a collection
|
||||
/// the revision id is updated when the document data in a collection changes
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static v8::Handle<v8::Value> JS_RevisionVocbaseCol (v8::Arguments const& argv) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
v8::Handle<v8::Object> err;
|
||||
TRI_vocbase_col_t const* collection = UseCollection(argv.Holder(), &err);
|
||||
|
||||
if (collection == 0) {
|
||||
return scope.Close(v8::ThrowException(err));
|
||||
}
|
||||
|
||||
TRI_primary_collection_t* primary = collection->_collection;
|
||||
|
||||
if (! TRI_IS_DOCUMENT_COLLECTION(collection->_type)) {
|
||||
TRI_ReleaseCollection(collection);
|
||||
return scope.Close(v8::ThrowException(TRI_CreateErrorObject(TRI_ERROR_INTERNAL, "unknown collection type")));
|
||||
}
|
||||
|
||||
primary->beginRead(primary);
|
||||
TRI_voc_rid_t rid = primary->base._info._rid;
|
||||
primary->endRead(primary);
|
||||
|
||||
TRI_ReleaseCollection(collection);
|
||||
|
||||
return scope.Close(v8::Number::New(rid));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief truncates a collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -4960,7 +5030,7 @@ static v8::Handle<v8::Value> JS_TruncateVocbaseCol (v8::Arguments const& argv) {
|
|||
return scope.Close(v8::ThrowException(TRI_CreateErrorObject(TRI_ERROR_INTERNAL)));
|
||||
}
|
||||
|
||||
SingleCollectionWriteTransaction<EmbeddableTransaction<V8TransactionContext>, UINT64_MAX> trx(col->_vocbase, col->_name, (TRI_col_type_e) col->_type, false, "TruncateVocbase");
|
||||
SingleCollectionWriteTransaction<EmbeddableTransaction<V8TransactionContext>, UINT64_MAX> trx(col->_vocbase, col->_name);
|
||||
int res = trx.begin();
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
return scope.Close(v8::ThrowException(TRI_CreateErrorObject(res, "cannot truncate collection", true)));
|
||||
|
@ -5160,12 +5230,7 @@ static v8::Handle<v8::Value> MapGetVocBase (v8::Local<v8::String> name,
|
|||
// look up the value if it exists
|
||||
TRI_vocbase_col_t const* collection;
|
||||
|
||||
if (collectionType == TRI_COL_TYPE_EDGE) {
|
||||
collection = TRI_FindEdgeCollectionByNameVocBase(vocbase, key.c_str(), true);
|
||||
}
|
||||
else {
|
||||
collection = TRI_FindDocumentCollectionByNameVocBase(vocbase, key.c_str(), true);
|
||||
}
|
||||
collection = TRI_FindCollectionByNameOrBearVocBase(vocbase, key.c_str(), (TRI_col_type_t) collectionType);
|
||||
|
||||
// if the key is not present return an empty handle as signal
|
||||
if (collection == 0) {
|
||||
|
@ -5247,7 +5312,7 @@ static v8::Handle<v8::Value> JS_CollectionVocbase (v8::Arguments const& argv) {
|
|||
else {
|
||||
string name = TRI_ObjectToString(val);
|
||||
|
||||
collection = TRI_FindCollectionByNameVocBase(vocbase, name.c_str(), false);
|
||||
collection = TRI_LookupCollectionByNameVocBase(vocbase, name.c_str());
|
||||
}
|
||||
|
||||
if (collection == 0) {
|
||||
|
@ -5345,7 +5410,7 @@ static v8::Handle<v8::Value> JS_CompletionsVocbase (v8::Arguments const& argv) {
|
|||
///
|
||||
/// @FUN{db._create(@FA{collection-name}, @FA{properties})}
|
||||
///
|
||||
/// @FA{properties} must be an object, with the following attribues:
|
||||
/// @FA{properties} must be an object with the following attributes:
|
||||
///
|
||||
/// - @LIT{waitForSync} (optional, default @LIT{false}): If @LIT{true} creating
|
||||
/// a document will only return after the data was synced to disk.
|
||||
|
@ -5415,7 +5480,7 @@ static v8::Handle<v8::Value> JS_CreateDocumentCollectionVocbase (v8::Arguments c
|
|||
///
|
||||
/// @FUN{db._createEdgeCollection(@FA{collection-name}, @FA{properties})}
|
||||
///
|
||||
/// @FA{properties} must be an object, with the following attribues:
|
||||
/// @FA{properties} must be an object with the following attributes:
|
||||
///
|
||||
/// - @LIT{waitForSync} (optional, default @LIT{false}): If @LIT{true} creating
|
||||
/// a document will only return after the data was synced to disk.
|
||||
|
@ -5435,46 +5500,72 @@ static v8::Handle<v8::Value> JS_CreateEdgeCollectionVocbase (v8::Arguments const
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief deletes a document
|
||||
/// @brief removes a document
|
||||
///
|
||||
/// @FUN{@FA{db}._remove(@FA{document})}
|
||||
///
|
||||
/// Deletes a document. If there is revision mismatch, then an error is thrown.
|
||||
/// Removes a document. If there is revision mismatch, then an error is thrown.
|
||||
///
|
||||
/// @FUN{@FA{db}._remove(@FA{document}, true)}
|
||||
///
|
||||
/// Deletes a document. If there is revision mismatch, then mismatch
|
||||
/// is ignored and document is deleted. The function returns
|
||||
/// @LIT{true} if the document existed and was deleted. It returns
|
||||
/// @LIT{false}, if the document was already deleted.
|
||||
/// Removes a document. If there is revision mismatch, then mismatch is ignored
|
||||
/// and document is deleted. The function returns @LIT{true} if the document
|
||||
/// existed and was deleted. It returns @LIT{false}, if the document was already
|
||||
/// deleted.
|
||||
///
|
||||
/// @FUN{@FA{db}._remove(@FA{document}, true, @FA{waitForSync})}
|
||||
///
|
||||
/// The optional @FA{waitForSync} parameter can be used to force
|
||||
/// synchronisation of the document deletion operation to disk even in case
|
||||
/// that the @LIT{waitForSync} flag had been disabled for the entire collection.
|
||||
/// Thus, the @FA{waitForSync} URL parameter can be used to force synchronisation
|
||||
/// of just specific operations. To use this, set the @FA{waitForSync} parameter
|
||||
/// to @LIT{true}. If the @FA{waitForSync} parameter is not specified or set to
|
||||
/// @LIT{false}, then the collection's default @LIT{waitForSync} behavior is
|
||||
/// applied. The @FA{waitForSync} URL parameter cannot be used to disable
|
||||
/// The optional @FA{waitForSync} parameter can be used to force synchronisation
|
||||
/// of the document deletion operation to disk even in case that the
|
||||
/// @LIT{waitForSync} flag had been disabled for the entire collection. Thus,
|
||||
/// the @FA{waitForSync} parameter can be used to force synchronisation of just
|
||||
/// specific operations. To use this, set the @FA{waitForSync} parameter to
|
||||
/// @LIT{true}. If the @FA{waitForSync} parameter is not specified or set to
|
||||
/// @LIT{false}, then the collection's default @LIT{waitForSync} behavior is
|
||||
/// applied. The @FA{waitForSync} parameter cannot be used to disable
|
||||
/// synchronisation for collections that have a default @LIT{waitForSync} value
|
||||
/// of @LIT{true}.
|
||||
///
|
||||
/// @FUN{@FA{db}._remove(@FA{document-handle}, @FA{data})}
|
||||
///
|
||||
/// As before. Instead of document a @FA{document-handle} can be passed as
|
||||
/// first argument.
|
||||
/// As before. Instead of document a @FA{document-handle} can be passed as first
|
||||
/// argument.
|
||||
///
|
||||
/// @EXAMPLES
|
||||
///
|
||||
/// Delete a document:
|
||||
/// Remove a document:
|
||||
///
|
||||
/// @TINYEXAMPLE{shell_remove-document-db,delete a document}
|
||||
/// @code
|
||||
/// arango> a1 = db.example.save({ a : 1 });
|
||||
/// { "_id" : "116308/4214943", "_rev" : 4214943 }
|
||||
/// arango> db._remove(a1);
|
||||
/// true
|
||||
/// arango> db._remove(a1);
|
||||
/// JavaScript exception in file '(arango)' at 1,4: [ArangoError 1202: document not found: cannot remove document]
|
||||
/// !db._remove(a1);
|
||||
/// ! ^
|
||||
/// arango> db._remove(a1, true);
|
||||
/// false
|
||||
/// @endcode
|
||||
///
|
||||
/// Delete a document with a conflict:
|
||||
/// Remove a document with a conflict:
|
||||
///
|
||||
/// @TINYEXAMPLE{shell_remove-document-conflict-db,delete a document}
|
||||
/// @code
|
||||
/// arango> a1 = db.example.save({ a : 1 });
|
||||
/// { "_id" : "116308/4042634", "_rev" : 4042634 }
|
||||
/// arango> a2 = db._replace(a1, { a : 2 });
|
||||
/// { "_id" : "116308/4042634", "_rev" : 4108170, "_oldRev" : 4042634 }
|
||||
/// arango> db._delete(a1);
|
||||
/// JavaScript exception in file '(arango)' at 1,4: [ArangoError 1200: conflict: cannot delete document]
|
||||
/// !db._delete(a1);
|
||||
/// ! ^
|
||||
/// arango> db._delete(a1, true);
|
||||
/// true
|
||||
/// arango> db._document(a1);
|
||||
/// JavaScript exception in file '(arango)' at 1,4: [ArangoError 1202: document not found: document not found]
|
||||
/// !db._document(a1);
|
||||
/// ! ^
|
||||
/// @endcode
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static v8::Handle<v8::Value> JS_RemoveVocbase (v8::Arguments const& argv) {
|
||||
|
@ -5534,11 +5625,11 @@ static v8::Handle<v8::Value> JS_DocumentVocbase (v8::Arguments const& argv) {
|
|||
/// The optional @FA{waitForSync} parameter can be used to force
|
||||
/// synchronisation of the document replacement operation to disk even in case
|
||||
/// that the @LIT{waitForSync} flag had been disabled for the entire collection.
|
||||
/// Thus, the @FA{waitForSync} URL parameter can be used to force synchronisation
|
||||
/// Thus, the @FA{waitForSync} parameter can be used to force synchronisation
|
||||
/// of just specific operations. To use this, set the @FA{waitForSync} parameter
|
||||
/// to @LIT{true}. If the @FA{waitForSync} parameter is not specified or set to
|
||||
/// @LIT{false}, then the collection's default @LIT{waitForSync} behavior is
|
||||
/// applied. The @FA{waitForSync} URL parameter cannot be used to disable
|
||||
/// applied. The @FA{waitForSync} parameter cannot be used to disable
|
||||
/// synchronisation for collections that have a default @LIT{waitForSync} value
|
||||
/// of @LIT{true}.
|
||||
///
|
||||
|
@ -5576,11 +5667,11 @@ static v8::Handle<v8::Value> JS_ReplaceVocbase (v8::Arguments const& argv) {
|
|||
/// The optional @FA{waitForSync} parameter can be used to force
|
||||
/// synchronisation of the document update operation to disk even in case
|
||||
/// that the @LIT{waitForSync} flag had been disabled for the entire collection.
|
||||
/// Thus, the @FA{waitForSync} URL parameter can be used to force synchronisation
|
||||
/// Thus, the @FA{waitForSync} parameter can be used to force synchronisation
|
||||
/// of just specific operations. To use this, set the @FA{waitForSync} parameter
|
||||
/// to @LIT{true}. If the @FA{waitForSync} parameter is not specified or set to
|
||||
/// @LIT{false}, then the collection's default @LIT{waitForSync} behavior is
|
||||
/// applied. The @FA{waitForSync} URL parameter cannot be used to disable
|
||||
/// applied. The @FA{waitForSync} parameter cannot be used to disable
|
||||
/// synchronisation for collections that have a default @LIT{waitForSync} value
|
||||
/// of @LIT{true}.
|
||||
///
|
||||
|
@ -6209,6 +6300,7 @@ v8::Handle<v8::Value> TRI_WrapShapedJson (TRI_vocbase_col_t const* collection,
|
|||
// store the document reference
|
||||
TRI_voc_rid_t rid = document->_rid;
|
||||
|
||||
// TODO: protect this against race conditions (parallel rename)
|
||||
result->Set(v8g->DidKey, DocumentId(collection->_name, document->_key), v8::ReadOnly);
|
||||
result->Set(v8g->RevKey, v8::Number::New(rid), v8::ReadOnly);
|
||||
result->Set(v8g->KeyKey, v8::String::New(document->_key), v8::ReadOnly);
|
||||
|
@ -6440,6 +6532,7 @@ TRI_v8_global_t* TRI_InitV8VocBridge (v8::Handle<v8::Context> context,
|
|||
TRI_AddMethodVocbase(rt, "name", JS_NameVocbaseCol);
|
||||
TRI_AddMethodVocbase(rt, "properties", JS_PropertiesVocbaseCol);
|
||||
TRI_AddMethodVocbase(rt, "remove", JS_RemoveVocbaseCol);
|
||||
TRI_AddMethodVocbase(rt, "revision", JS_RevisionVocbaseCol);
|
||||
TRI_AddMethodVocbase(rt, "rename", JS_RenameVocbaseCol);
|
||||
TRI_AddMethodVocbase(rt, "setAttribute", JS_SetAttributeVocbaseCol, true);
|
||||
TRI_AddMethodVocbase(rt, "status", JS_StatusVocbaseCol);
|
||||
|
|
|
@ -482,14 +482,15 @@ void TRI_InitCollectionInfo (TRI_vocbase_t* vocbase,
|
|||
assert(parameter);
|
||||
memset(parameter, 0, sizeof(TRI_col_info_t));
|
||||
|
||||
parameter->_version = TRI_COL_VERSION;
|
||||
parameter->_type = type;
|
||||
parameter->_cid = 0;
|
||||
parameter->_version = TRI_COL_VERSION;
|
||||
parameter->_type = type;
|
||||
parameter->_cid = 0;
|
||||
parameter->_rid = 0;
|
||||
|
||||
parameter->_deleted = false;
|
||||
parameter->_isVolatile = false;
|
||||
parameter->_isSystem = false;
|
||||
parameter->_maximalSize = (maximalSize / PageSize) * PageSize;
|
||||
parameter->_deleted = false;
|
||||
parameter->_isVolatile = false;
|
||||
parameter->_isSystem = false;
|
||||
parameter->_maximalSize = (maximalSize / PageSize) * PageSize;
|
||||
if (parameter->_maximalSize == 0 && maximalSize != 0) {
|
||||
parameter->_maximalSize = PageSize;
|
||||
}
|
||||
|
@ -501,7 +502,7 @@ void TRI_InitCollectionInfo (TRI_vocbase_t* vocbase,
|
|||
parameter->_options = options;
|
||||
}
|
||||
else {
|
||||
parameter->_options = 0;
|
||||
parameter->_options = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -513,13 +514,14 @@ void TRI_CopyCollectionInfo (TRI_col_info_t* dst, TRI_col_info_t* src) {
|
|||
assert(dst);
|
||||
memset(dst, 0, sizeof(TRI_col_info_t));
|
||||
|
||||
dst->_version = src->_version;
|
||||
dst->_type = src->_type;
|
||||
dst->_cid = src->_cid;
|
||||
dst->_version = src->_version;
|
||||
dst->_type = src->_type;
|
||||
dst->_cid = src->_cid;
|
||||
dst->_rid = src->_rid;
|
||||
|
||||
dst->_deleted = src->_deleted;
|
||||
dst->_isSystem = src->_isSystem;
|
||||
dst->_isVolatile = src->_isVolatile;
|
||||
dst->_deleted = src->_deleted;
|
||||
dst->_isSystem = src->_isSystem;
|
||||
dst->_isVolatile = src->_isVolatile;
|
||||
dst->_maximalSize = src->_maximalSize;
|
||||
TRI_CopyString(dst->_name, src->_name, sizeof(dst->_name));
|
||||
dst->_waitForSync = src->_waitForSync;
|
||||
|
@ -528,7 +530,7 @@ void TRI_CopyCollectionInfo (TRI_col_info_t* dst, TRI_col_info_t* src) {
|
|||
dst->_options = TRI_CopyJson(TRI_UNKNOWN_MEM_ZONE, src->_options);
|
||||
}
|
||||
else {
|
||||
dst->_options = 0;
|
||||
dst->_options = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -539,7 +541,7 @@ void TRI_CopyCollectionInfo (TRI_col_info_t* dst, TRI_col_info_t* src) {
|
|||
void TRI_FreeCollectionInfoOptions (TRI_col_info_t* parameter) {
|
||||
if (parameter->_options) {
|
||||
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, parameter->_options);
|
||||
parameter->_options = 0;
|
||||
parameter->_options = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -218,10 +218,11 @@ typedef struct TRI_col_info_s {
|
|||
TRI_col_version_t _version; // collection version
|
||||
TRI_col_type_e _type; // collection type
|
||||
TRI_voc_cid_t _cid; // collection identifier
|
||||
struct TRI_json_s* _options; // optional collection options
|
||||
TRI_voc_rid_t _rid; // last revision id
|
||||
TRI_voc_size_t _maximalSize; // maximal size of memory mapped file
|
||||
|
||||
char _name[TRI_COL_PATH_LENGTH]; // name of the collection
|
||||
struct TRI_json_s* _options; // optional collection options
|
||||
|
||||
// flags
|
||||
bool _deleted : 1; // if true, collection has been deleted
|
||||
|
@ -250,7 +251,7 @@ typedef struct TRI_collection_s {
|
|||
TRI_vector_pointer_t _datafiles; // all datafiles
|
||||
TRI_vector_pointer_t _journals; // all journals
|
||||
TRI_vector_pointer_t _compactors; // all compactor files
|
||||
TRI_vector_string_t _indexFiles; // all index filenames
|
||||
TRI_vector_string_t _indexFiles; // all index filenames
|
||||
}
|
||||
TRI_collection_t;
|
||||
|
||||
|
|
|
@ -143,6 +143,19 @@ static bool IsVisible (TRI_doc_mptr_t const* header,
|
|||
return (header != NULL && header->_validTo == 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief set the collection revision id with the marker's tick value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void CollectionRevisionUpdate (TRI_document_collection_t* document,
|
||||
const TRI_df_marker_t* const marker) {
|
||||
TRI_col_info_t* info = &document->base.base._info;
|
||||
|
||||
if (marker->_tick > info->_rid) {
|
||||
info->_rid = marker->_tick;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -295,6 +308,8 @@ static int WriteElement (TRI_document_collection_t* document,
|
|||
return res;
|
||||
}
|
||||
|
||||
CollectionRevisionUpdate(document, marker);
|
||||
|
||||
TRI_LOCK_JOURNAL_ENTRIES_DOC_COLLECTION(document);
|
||||
|
||||
journal->_written = ((char*) result) + marker->_size;
|
||||
|
@ -1437,6 +1452,8 @@ static bool OpenIterator (TRI_df_marker_t const* marker, void* data, TRI_datafil
|
|||
|
||||
primary = &collection->base;
|
||||
|
||||
CollectionRevisionUpdate(collection, marker);
|
||||
|
||||
// new or updated document
|
||||
if (marker->_type == TRI_DOC_MARKER_KEY_EDGE ||
|
||||
marker->_type == TRI_DOC_MARKER_KEY_DOCUMENT) {
|
||||
|
|
|
@ -505,8 +505,7 @@ void TRI_DumpTransactionContext (TRI_transaction_context_t* const context) {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static TRI_transaction_collection_t* CreateCollection (const char* const name,
|
||||
const TRI_transaction_type_e type,
|
||||
TRI_vocbase_col_t* initialiser) {
|
||||
const TRI_transaction_type_e type) {
|
||||
TRI_transaction_collection_t* collection;
|
||||
|
||||
collection = (TRI_transaction_collection_t*) TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_transaction_collection_t), false);
|
||||
|
@ -525,10 +524,9 @@ static TRI_transaction_collection_t* CreateCollection (const char* const name,
|
|||
|
||||
// initialise collection properties
|
||||
collection->_type = type;
|
||||
collection->_collection = initialiser;
|
||||
collection->_collection = NULL;
|
||||
collection->_globalInstance = NULL;
|
||||
collection->_locked = false;
|
||||
collection->_externalLock = (initialiser != NULL);
|
||||
|
||||
// initialise private copy of write transactions list
|
||||
InitTransactionList(&collection->_writeTransactions);
|
||||
|
@ -595,10 +593,8 @@ static int AcquireCollectionLocks (TRI_transaction_t* const trx) {
|
|||
for (i = 0; i < n; ++i) {
|
||||
TRI_transaction_collection_t* collection;
|
||||
|
||||
collection = TRI_AtVectorPointer(&trx->_collections, i);
|
||||
if (! collection->_externalLock) {
|
||||
collection->_collection = TRI_UseCollectionByNameVocBase(trx->_context->_vocbase, collection->_name);
|
||||
}
|
||||
collection = (TRI_transaction_collection_t*) TRI_AtVectorPointer(&trx->_collections, i);
|
||||
collection->_collection = TRI_UseCollectionByNameVocBase(trx->_context->_vocbase, collection->_name);
|
||||
|
||||
if (collection->_collection == NULL) {
|
||||
return TRI_errno();
|
||||
|
@ -655,9 +651,7 @@ static int ReleaseCollectionLocks (TRI_transaction_t* const trx) {
|
|||
}
|
||||
|
||||
// unuse collection
|
||||
if (! collection->_externalLock) {
|
||||
TRI_ReleaseCollectionVocBase(trx->_context->_vocbase, collection->_collection);
|
||||
}
|
||||
TRI_ReleaseCollectionVocBase(trx->_context->_vocbase, collection->_collection);
|
||||
|
||||
collection->_collection = NULL;
|
||||
}
|
||||
|
@ -1091,8 +1085,7 @@ TRI_vocbase_col_t* TRI_CheckCollectionTransaction (TRI_transaction_t* const trx,
|
|||
|
||||
int TRI_AddCollectionTransaction (TRI_transaction_t* const trx,
|
||||
const char* const name,
|
||||
const TRI_transaction_type_e type,
|
||||
TRI_vocbase_col_t* initialiser) {
|
||||
const TRI_transaction_type_e type) {
|
||||
TRI_transaction_collection_t* collection;
|
||||
size_t i, n;
|
||||
|
||||
|
@ -1116,7 +1109,7 @@ int TRI_AddCollectionTransaction (TRI_transaction_t* const trx,
|
|||
|
||||
if (res < 0) {
|
||||
// collection is not contained in vector
|
||||
collection = CreateCollection(name, type, initialiser);
|
||||
collection = CreateCollection(name, type);
|
||||
if (collection == NULL) {
|
||||
// out of memory
|
||||
return TRI_ERROR_OUT_OF_MEMORY;
|
||||
|
@ -1139,7 +1132,7 @@ int TRI_AddCollectionTransaction (TRI_transaction_t* const trx,
|
|||
}
|
||||
|
||||
// collection was not contained. now insert it
|
||||
collection = CreateCollection(name, type, initialiser);
|
||||
collection = CreateCollection(name, type);
|
||||
if (collection == NULL) {
|
||||
// out of memory
|
||||
return TRI_ERROR_OUT_OF_MEMORY;
|
||||
|
@ -1240,6 +1233,30 @@ int TRI_FinishTransaction (TRI_transaction_t* const trx) {
|
|||
return res;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief get the pointer to a collection after it has been initialised
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_vocbase_col_t* TRI_GetCollectionTransaction (const TRI_transaction_t* const trx,
|
||||
const char* const name) {
|
||||
size_t i, n;
|
||||
|
||||
assert(trx->_status == TRI_TRANSACTION_RUNNING);
|
||||
|
||||
n = trx->_collections._length;
|
||||
|
||||
// process collections in forward order
|
||||
for (i = 0; i < n; ++i) {
|
||||
TRI_transaction_collection_t* collection;
|
||||
|
||||
collection = (TRI_transaction_collection_t*) TRI_AtVectorPointer(&trx->_collections, i);
|
||||
if (TRI_EqualString(name, collection->_name)) {
|
||||
return collection->_collection;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -283,7 +283,6 @@ typedef struct TRI_transaction_collection_s {
|
|||
struct TRI_vocbase_col_s* _collection; // vocbase collection pointer
|
||||
TRI_transaction_collection_global_t* _globalInstance; // pointer to the global instance of the collection in the trx system
|
||||
bool _locked; // lock flag (used for write-transactions)
|
||||
bool _externalLock; // flag whether collection was locked externally
|
||||
}
|
||||
TRI_transaction_collection_t;
|
||||
|
||||
|
@ -395,8 +394,7 @@ struct TRI_vocbase_col_s* TRI_CheckCollectionTransaction (TRI_transaction_t* con
|
|||
|
||||
int TRI_AddCollectionTransaction (TRI_transaction_t* const,
|
||||
const char* const,
|
||||
const TRI_transaction_type_e,
|
||||
struct TRI_vocbase_col_s*);
|
||||
const TRI_transaction_type_e);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief start a transaction
|
||||
|
@ -422,6 +420,13 @@ int TRI_AbortTransaction (TRI_transaction_t* const);
|
|||
|
||||
int TRI_FinishTransaction (TRI_transaction_t* const);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief get the pointer to a collection after it has been initialised
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct TRI_vocbase_col_s* TRI_GetCollectionTransaction (const TRI_transaction_t* const,
|
||||
const char* const);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -815,7 +815,6 @@ static int ManifestCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t*
|
|||
|
||||
static TRI_vocbase_col_t* FindCollectionByNameVocBase (TRI_vocbase_t* vocbase,
|
||||
char const* name,
|
||||
bool bear,
|
||||
TRI_col_type_e type) {
|
||||
union { void const* v; TRI_vocbase_col_t* c; } found;
|
||||
|
||||
|
@ -827,15 +826,9 @@ static TRI_vocbase_col_t* FindCollectionByNameVocBase (TRI_vocbase_t* vocbase,
|
|||
return found.c;
|
||||
}
|
||||
|
||||
if (! bear) {
|
||||
TRI_set_errno(TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return BearCollectionVocBase(vocbase, name, type);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief loads an existing (document) collection
|
||||
///
|
||||
|
@ -1372,6 +1365,32 @@ TRI_vector_pointer_t TRI_CollectionsVocBase (TRI_vocbase_t* vocbase) {
|
|||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief get a collection name by a collection id
|
||||
///
|
||||
/// the name is fetched under a lock to make this thread-safe. returns NULL if
|
||||
/// the collection does not exist
|
||||
/// it is the caller's responsibility to free the name returned
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
char* TRI_GetCollectionNameByIdVocBase (TRI_vocbase_t* vocbase,
|
||||
const TRI_voc_cid_t id) {
|
||||
union { void const* v; TRI_vocbase_col_t* c; } found;
|
||||
char* name;
|
||||
|
||||
TRI_READ_LOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||
found.v = TRI_LookupByKeyAssociativePointer(&vocbase->_collectionsById, &id);
|
||||
if (found.v == NULL) {
|
||||
name = NULL;
|
||||
}
|
||||
else {
|
||||
name = TRI_DuplicateStringZ(TRI_UNKNOWN_MEM_ZONE, found.c->_name);
|
||||
}
|
||||
TRI_READ_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief looks up a (document) collection by name
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1401,27 +1420,13 @@ TRI_vocbase_col_t* TRI_LookupCollectionByIdVocBase (TRI_vocbase_t* vocbase, TRI_
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief finds a collection by name
|
||||
/// @brief finds a collection by name, optionally creates it
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_vocbase_col_t* TRI_FindCollectionByNameVocBase (TRI_vocbase_t* vocbase, char const* name, bool bear) {
|
||||
return TRI_FindDocumentCollectionByNameVocBase(vocbase, name, bear);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief finds a primary collection by name
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_vocbase_col_t* TRI_FindDocumentCollectionByNameVocBase (TRI_vocbase_t* vocbase, char const* name, bool bear) {
|
||||
return FindCollectionByNameVocBase(vocbase, name, bear, TRI_COL_TYPE_DOCUMENT);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief finds an edge collection by name
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_vocbase_col_t* TRI_FindEdgeCollectionByNameVocBase (TRI_vocbase_t* vocbase, char const* name, bool bear) {
|
||||
return FindCollectionByNameVocBase(vocbase, name, bear, TRI_COL_TYPE_EDGE);
|
||||
TRI_vocbase_col_t* TRI_FindCollectionByNameOrBearVocBase (TRI_vocbase_t* vocbase,
|
||||
char const* name,
|
||||
const TRI_col_type_t type) {
|
||||
return FindCollectionByNameVocBase(vocbase, name, (TRI_col_type_e) type);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -505,6 +505,16 @@ void TRI_DestroyVocBase (TRI_vocbase_t*);
|
|||
|
||||
TRI_vector_pointer_t TRI_CollectionsVocBase (TRI_vocbase_t*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief get a collection name by a collection id
|
||||
///
|
||||
/// the name is fetched under a lock to make this thread-safe. returns NULL if
|
||||
/// the collection does not exist
|
||||
/// it is the caller's responsibility to free the name returned
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
char* TRI_GetCollectionNameByIdVocBase (TRI_vocbase_t*, const TRI_voc_cid_t);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief looks up a (document) collection by name
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -518,22 +528,12 @@ TRI_vocbase_col_t* TRI_LookupCollectionByNameVocBase (TRI_vocbase_t*, char const
|
|||
TRI_vocbase_col_t* TRI_LookupCollectionByIdVocBase (TRI_vocbase_t*, TRI_voc_cid_t);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief finds a collection by name
|
||||
/// @brief finds a collection by name or creates it
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_vocbase_col_t* TRI_FindCollectionByNameVocBase (TRI_vocbase_t*, char const*, bool bear);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief finds a primary collection by name
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_vocbase_col_t* TRI_FindDocumentCollectionByNameVocBase (TRI_vocbase_t*, char const*, bool bear);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief finds an edge collection by name
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_vocbase_col_t* TRI_FindEdgeCollectionByNameVocBase (TRI_vocbase_t*, char const*, bool bear);
|
||||
TRI_vocbase_col_t* TRI_FindCollectionByNameOrBearVocBase (TRI_vocbase_t*,
|
||||
char const*,
|
||||
const TRI_col_type_t);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief creates a new (document) collection from parameter set
|
||||
|
|
|
@ -62,12 +62,6 @@ using namespace triagens::httpclient;
|
|||
using namespace triagens::v8client;
|
||||
using namespace triagens::arango;
|
||||
|
||||
#include "js/common/bootstrap/js-print.h"
|
||||
#include "js/common/bootstrap/js-modules.h"
|
||||
#include "js/common/bootstrap/js-monkeypatches.h"
|
||||
#include "js/common/bootstrap/js-errors.h"
|
||||
#include "js/client/js-client.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private variables
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -1341,30 +1335,33 @@ int main (int argc, char* argv[]) {
|
|||
|
||||
// load java script from js/bootstrap/*.h files
|
||||
if (StartupPath.empty()) {
|
||||
StartupLoader.defineScript("common/bootstrap/modules.js", JS_common_bootstrap_modules);
|
||||
StartupLoader.defineScript("common/bootstrap/monkeypatches.js", JS_common_bootstrap_monkeypatches);
|
||||
StartupLoader.defineScript("common/bootstrap/print.js", JS_common_bootstrap_print);
|
||||
StartupLoader.defineScript("common/bootstrap/errors.js", JS_common_bootstrap_errors);
|
||||
StartupLoader.defineScript("client/client.js", JS_client_client);
|
||||
}
|
||||
else {
|
||||
LOGGER_DEBUG << "using JavaScript startup files at '" << StartupPath << "'";
|
||||
StartupLoader.setDirectory(StartupPath);
|
||||
LOGGER_FATAL << "no 'javascript.startup-directory' has been supplied, giving up";
|
||||
TRI_FlushLogging();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
LOGGER_DEBUG << "using JavaScript startup files at '" << StartupPath << "'";
|
||||
StartupLoader.setDirectory(StartupPath);
|
||||
|
||||
context->Global()->Set(v8::String::New("ARANGO_QUIET"), v8::Boolean::New(BaseClient.quiet()), v8::ReadOnly);
|
||||
context->Global()->Set(v8::String::New("VALGRIND"), v8::Boolean::New((RUNNING_ON_VALGRIND) > 0));
|
||||
|
||||
// load all init files
|
||||
char const* files[] = {
|
||||
"common/bootstrap/modules.js",
|
||||
"common/bootstrap/monkeypatches.js",
|
||||
"common/bootstrap/print.js",
|
||||
"common/bootstrap/errors.js",
|
||||
"client/client.js"
|
||||
};
|
||||
vector<string> files;
|
||||
|
||||
files.push_back("common/bootstrap/modules.js");
|
||||
files.push_back("common/bootstrap/module-internal.js");
|
||||
files.push_back("common/bootstrap/module-fs.js");
|
||||
files.push_back("common/bootstrap/module-console.js");
|
||||
|
||||
if (JsLint.empty()) {
|
||||
files.push_back("common/bootstrap/monkeypatches.js");
|
||||
}
|
||||
|
||||
files.push_back("common/bootstrap/errors.js");
|
||||
files.push_back("client/client.js");
|
||||
|
||||
for (size_t i = 0; i < sizeof(files) / sizeof(files[0]); ++i) {
|
||||
for (size_t i = 0; i < files.size(); ++i) {
|
||||
bool ok = StartupLoader.loadScript(context, files[i]);
|
||||
|
||||
if (ok) {
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
#!/bin/bash
|
||||
NAME=`echo $1 | sed -e 's:^\(.*/\)*js/\(.*\)\.js$:\2:' | tr "/-" "__"`
|
||||
|
||||
#cat $1 \
|
||||
# | sed -e 's:\(["\]\):\\\1:g' \
|
||||
# | awk 'BEGIN {print "static string JS_'$NAME' = string(\"\") " } { print " + \"" $0 "\\n\"" } END { print ";"}'
|
||||
|
||||
cat $1 \
|
||||
| sed -e 's:\(["\]\):\\\1:g' \
|
||||
| awk 'BEGIN {print "const char* JS_'$NAME'[] = {" } { print " \"" $0 "\"," } END { print " \"//__end__\"\n};"}'
|
||||
|
|
@ -2,4 +2,5 @@
|
|||
endpoint = tcp://localhost:8529
|
||||
|
||||
[javascript]
|
||||
startup-directory = @PKGDATADIR@/js
|
||||
modules-path = @PKGDATADIR@/js/client/modules;@PKGDATADIR@/js/common/modules
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
[javascript]
|
||||
startup-directory = ./js
|
||||
modules-path = ./js/client/modules;./js/common/modules
|
||||
|
|
|
@ -27,13 +27,14 @@
|
|||
<script type="text/javascript" src="js/jquery.jeditable.js"></script>
|
||||
<script type="text/javascript" src="js/jquery.jeditable.autogrow.js"></script>
|
||||
<script type="text/javascript" src="js/master.js"></script>
|
||||
<script type="text/javascript" src="js/avocsh1.js"></script>
|
||||
<script type="text/javascript" src="js/print.js"></script>
|
||||
<script type="text/javascript" src="js/errors.js"></script>
|
||||
<script type="text/javascript" src="js/arangodb/browser.js"></script>
|
||||
<script type="text/javascript" src="js/arangodb/errors.js"></script>
|
||||
<script type="text/javascript" src="js/arangodb/module-internal.js"></script>
|
||||
<script type="text/javascript" src="js/arangodb/monkeypatches.js"></script>
|
||||
<script type="text/javascript" src="js/modules/simple-query-basics.js"></script>
|
||||
<script type="text/javascript" src="js/modules/simple-query.js"></script>
|
||||
<script type="text/javascript" src="js/modules/statement-basics.js"></script>
|
||||
<script type="text/javascript" src="js/client.js"></script>
|
||||
<script type="text/javascript" src="js/arangodb/client.js"></script>
|
||||
<style>
|
||||
a:link {color: #797979; text-decoration: none;}
|
||||
a:visited {color: #797979; text-decoration: none;}
|
||||
|
|
|
@ -1,11 +1,5 @@
|
|||
/*jslint indent: 2,
|
||||
nomen: true,
|
||||
maxlen: 100,
|
||||
sloppy: true,
|
||||
vars: true,
|
||||
white: true,
|
||||
plusplus: true */
|
||||
/*global module, ModuleCache, $ */
|
||||
/*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true, vars: true, white: true, plusplus: true */
|
||||
/*global $ */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief ArangoDB web browser shell
|
||||
|
@ -14,7 +8,7 @@
|
|||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2012 triagens GmbH, Cologne, Germany
|
||||
/// Copyright 2012-2013 triagens GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
|
@ -31,7 +25,8 @@
|
|||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Achim Brandt
|
||||
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
|
||||
/// @author Dr. Frank Celler
|
||||
/// @author Copyright 2012-2013, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -57,8 +52,31 @@ function Module (id) {
|
|||
this.definition = null;
|
||||
}
|
||||
|
||||
var ModuleCache = {};
|
||||
var module = ModuleCache["/"] = new Module("/");
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief module cache
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Module.prototype.ModuleCache = {};
|
||||
Module.prototype.ModuleCache["/internal"] = new Module("/internal");
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public variables
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup ArangoShell
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief global module
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var module = Module.prototype.ModuleCache["/"] = new Module("/");
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
|
@ -136,6 +154,23 @@ Module.prototype.normalise = function (path) {
|
|||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief sets a new module definition
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Module.prototype.define = function (path, definition) {
|
||||
|
||||
// first get rid of any ".." and "."
|
||||
path = this.normalise(path);
|
||||
|
||||
// check if you already know the module, return the exports
|
||||
if (! Module.prototype.ModuleCache.hasOwnProperty(path)) {
|
||||
Module.prototype.ModuleCache[path] = new Module(path);
|
||||
}
|
||||
|
||||
Module.prototype.ModuleCache[path].definition = definition;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief executes a definition or creates a new module descriptor
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -147,11 +182,11 @@ Module.prototype.require = function (path) {
|
|||
path = this.normalise(path);
|
||||
|
||||
// check if you already know the module, return the exports
|
||||
if (ModuleCache.hasOwnProperty(path)) {
|
||||
module = ModuleCache[path];
|
||||
if (Module.prototype.ModuleCache.hasOwnProperty(path)) {
|
||||
module = Module.prototype.ModuleCache[path];
|
||||
}
|
||||
else {
|
||||
module = ModuleCache[path] = new Module(path);
|
||||
module = Module.prototype.ModuleCache[path] = new Module(path);
|
||||
}
|
||||
|
||||
if (module.definition !== null) {
|
||||
|
@ -163,21 +198,22 @@ Module.prototype.require = function (path) {
|
|||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief sets a new module definition
|
||||
/// @brief global require function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Module.prototype.define = function (path, definition) {
|
||||
function require (path) {
|
||||
return module.require(path);
|
||||
}
|
||||
|
||||
// first get rid of any ".." and "."
|
||||
path = this.normalise(path);
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief global print function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// check if you already know the module, return the exports
|
||||
if (! ModuleCache.hasOwnProperty(path)) {
|
||||
ModuleCache[path] = new Module(path);
|
||||
}
|
||||
function print () {
|
||||
var internal = require("internal");
|
||||
|
||||
ModuleCache[path].definition = definition;
|
||||
};
|
||||
internal.print.apply(internal.print, arguments);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
|
@ -278,7 +314,6 @@ ArangoConnection.prototype._delete = function (url) {
|
|||
return msg;
|
||||
};
|
||||
|
||||
|
||||
ArangoConnection.prototype.DELETE = ArangoConnection.prototype._delete;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -416,13 +451,8 @@ var arango = new ArangoConnection();
|
|||
/// @brief module cache
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ModuleCache["/internal"] = new Module("/internal");
|
||||
|
||||
(function () {
|
||||
var internal = ModuleCache["/internal"].exports;
|
||||
|
||||
internal.start_pager = function() {};
|
||||
internal.stop_pager = function() {};
|
||||
var internal = Module.prototype.ModuleCache["/internal"].exports;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief global output buffer
|
||||
|
@ -430,6 +460,28 @@ ModuleCache["/internal"] = new Module("/internal");
|
|||
|
||||
internal.browserOutputBuffer = "";
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief escapes HTML
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.escapeHTML = (function() {
|
||||
var MAP = {
|
||||
'&': '&',
|
||||
'<': '<',
|
||||
'>': '>',
|
||||
'"': '"',
|
||||
"'": ''',
|
||||
"\n": '<br>',
|
||||
" ": ' '
|
||||
};
|
||||
|
||||
var repl = function(c) { return MAP[c]; };
|
||||
|
||||
return function(s) {
|
||||
return s.replace(/[&<>'"\n ]/g, repl); //'
|
||||
};
|
||||
}());
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief outputs text to shell window
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -459,7 +511,7 @@ ModuleCache["/internal"] = new Module("/internal");
|
|||
text = String(value);
|
||||
}
|
||||
|
||||
internal.browserOutputBuffer += escapeHTML(text);
|
||||
internal.browserOutputBuffer += internal.escapeHTML(text);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -484,51 +536,9 @@ ModuleCache["/internal"] = new Module("/internal");
|
|||
}());
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public functions
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup ArangoShell
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief escapes HTML
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var escapeHTML = (function() {
|
||||
var MAP = {
|
||||
'&': '&',
|
||||
'<': '<',
|
||||
'>': '>',
|
||||
'"': '"',
|
||||
"'": ''',
|
||||
"\n": '<br>',
|
||||
" ": ' '
|
||||
};
|
||||
|
||||
var repl = function(c) { return MAP[c]; };
|
||||
|
||||
return function(s) {
|
||||
return s.replace(/[&<>'"\n ]/g, repl); //'
|
||||
};
|
||||
}());
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief global require function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function require (path) {
|
||||
return module.require(path);
|
||||
}
|
||||
|
||||
function ARANGO_QUIET (path) {
|
||||
return false;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @}\\)"
|
|
@ -0,0 +1 @@
|
|||
../../../../js/client/client.js
|
|
@ -0,0 +1 @@
|
|||
../../../../js/common/bootstrap/errors.js
|
|
@ -0,0 +1 @@
|
|||
../../../../js/common/bootstrap/module-internal.js
|
|
@ -0,0 +1 @@
|
|||
../../../../js/common/bootstrap/monkeypatches.js
|
|
@ -1 +0,0 @@
|
|||
../../../js/client/client.js
|
|
@ -1 +0,0 @@
|
|||
../../../js/common/bootstrap/errors.js
|
|
@ -1190,7 +1190,8 @@ var lastFormatQuestion = true;
|
|||
command = data;
|
||||
}
|
||||
|
||||
var client = "arangosh> " + escapeHTML(data) + "<br>";
|
||||
var internal = require("internal");
|
||||
var client = "arangosh> " + internal.escapeHTML(data) + "<br>";
|
||||
|
||||
$('#avocshWindow').append('<b class="avocshClient">' + client + '</b>');
|
||||
evaloutput(command);
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
../../../js/common/bootstrap/print.js
|
|
@ -9,10 +9,26 @@
|
|||
################################################################################
|
||||
|
||||
JAVASCRIPT_JSLINT = \
|
||||
@srcdir@/html/admin/js/arangodb/browser.js \
|
||||
@srcdir@/js/actions/system/api-collection.js \
|
||||
@srcdir@/js/actions/system/api-structure.js \
|
||||
@srcdir@/js/client/modules/org/arangodb.js \
|
||||
@srcdir@/js/client/modules/org/arangodb/deploy.js \
|
||||
@srcdir@/js/common/bootstrap/errors.js \
|
||||
@srcdir@/js/common/bootstrap/module-console.js \
|
||||
@srcdir@/js/common/bootstrap/module-fs.js \
|
||||
@srcdir@/js/common/bootstrap/module-internal.js \
|
||||
@srcdir@/js/common/bootstrap/modules.js \
|
||||
@srcdir@/js/common/bootstrap/monkeypatches.js \
|
||||
@srcdir@/js/server/ArangoCollection.js \
|
||||
@srcdir@/js/server/ArangoStructure.js
|
||||
@srcdir@/js/server/ArangoStructure.js \
|
||||
@srcdir@/js/server/modules/org/arangodb.js \
|
||||
@srcdir@/js/server/modules/org/arangodb/actions.js \
|
||||
@srcdir@/js/server/modules/org/arangodb/actions/echoController.js \
|
||||
@srcdir@/js/server/modules/org/arangodb/actions/staticContentController.js \
|
||||
@srcdir@/js/server/modules/org/arangodb/formatter.js \
|
||||
@srcdir@/js/server/modules/org/arangodb/parser.js \
|
||||
@srcdir@/js/server/modules/org/arangodb/validator.js
|
||||
|
||||
################################################################################
|
||||
### @brief executes jslint
|
||||
|
@ -39,8 +55,6 @@ BUILT_SOURCES += @builddir@/.setup-js-directories
|
|||
|
||||
@builddir@/.setup-js-directories:
|
||||
@test -d html/admin/js/modules || mkdir -p html/admin/js/modules
|
||||
@test -d js/common/bootstrap || mkdir -p js/common/bootstrap
|
||||
@test -d js/client || mkdir -p js/client
|
||||
@touch $@
|
||||
|
||||
################################################################################
|
||||
|
@ -53,15 +67,6 @@ html/admin/js/modules/%.js: @srcdir@/js/common/modules/%.js .setup-js-directorie
|
|||
html/admin/js/modules/%.js: @srcdir@/js/client/modules/%.js .setup-js-directories
|
||||
(echo "module.define(\"`basename $< .js`\", function(exports, module) {" && cat $< && echo "});") > $@
|
||||
|
||||
js/js-%.h: @srcdir@/js/%.js .setup-js-directories
|
||||
@top_srcdir@/config/js2c.sh $< > $@
|
||||
|
||||
js/client/js-%.h: @srcdir@/js/client/%.js .setup-js-directories
|
||||
@top_srcdir@/config/js2c.sh $< > $@
|
||||
|
||||
js/common/bootstrap/js-%.h: @srcdir@/js/common/bootstrap/%.js .setup-js-directories
|
||||
@top_srcdir@/config/js2c.sh $< > $@
|
||||
|
||||
################################################################################
|
||||
### @brief cleanup
|
||||
################################################################################
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -158,7 +158,7 @@ function post_api_collection (req, res) {
|
|||
}
|
||||
|
||||
if (! body.hasOwnProperty("name")) {
|
||||
actions.resultBad(req, res, actions.ERROR_ARANGO_ILLEGAL_NAME,
|
||||
actions.resultBad(req, res, arangodb.ERROR_ARANGO_ILLEGAL_NAME,
|
||||
"name must be non-empty");
|
||||
return;
|
||||
}
|
||||
|
@ -393,7 +393,7 @@ function get_api_collection (req, res) {
|
|||
name = decodeURIComponent(req.suffix[0]);
|
||||
}
|
||||
|
||||
var collection = internal.db._collection(name);
|
||||
var collection = arangodb.db._collection(name);
|
||||
|
||||
if (collection === null) {
|
||||
actions.collectionNotFound(req, res, name);
|
||||
|
@ -670,7 +670,7 @@ function put_api_collection_rename (req, res, collection) {
|
|||
}
|
||||
|
||||
if (! body.hasOwnProperty("name")) {
|
||||
actions.resultBad(req, res, actions.ERROR_ARANGO_ILLEGAL_NAME,
|
||||
actions.resultBad(req, res, arangodb.ERROR_ARANGO_ILLEGAL_NAME,
|
||||
"name must be non-empty");
|
||||
return;
|
||||
}
|
||||
|
@ -701,7 +701,7 @@ function put_api_collection (req, res) {
|
|||
}
|
||||
|
||||
var name = decodeURIComponent(req.suffix[0]);
|
||||
var collection = internal.db._collection(name);
|
||||
var collection = arangodb.db._collection(name);
|
||||
|
||||
if (collection === null) {
|
||||
actions.collectionNotFound(req, res, name);
|
||||
|
@ -769,7 +769,7 @@ function delete_api_collection (req, res) {
|
|||
}
|
||||
else {
|
||||
var name = decodeURIComponent(req.suffix[0]);
|
||||
var collection = internal.db._collection(name);
|
||||
var collection = arangodb.db._collection(name);
|
||||
|
||||
if (collection === null) {
|
||||
actions.collectionNotFound(req, res, name);
|
||||
|
|
|
@ -26,21 +26,22 @@
|
|||
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup ArangoAPI
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
var arangodb = require("org/arangodb");
|
||||
var actions = require("org/arangodb/actions");
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- global variables
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
var actions = require("org/arangodb/actions");
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup ArangoAPI
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create a cursor and return the first results
|
||||
///
|
||||
|
@ -123,7 +124,7 @@ var actions = require("org/arangodb/actions");
|
|||
|
||||
function POST_api_cursor(req, res) {
|
||||
if (req.suffix.length != 0) {
|
||||
actions.resultNotFound(req, res, internal.errors.ERROR_CURSOR_NOT_FOUND.code, internal.errors.ERROR_CURSOR_NOT_FOUND.message);
|
||||
actions.resultNotFound(req, res, arangodb.ERROR_CURSOR_NOT_FOUND);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -143,7 +144,7 @@ function POST_api_cursor(req, res) {
|
|||
(json.batchSize == undefined));
|
||||
}
|
||||
else {
|
||||
actions.resultBad(req, res, actions.ERROR_QUERY_EMPTY);
|
||||
actions.resultBad(req, res, arangodb.ERROR_QUERY_EMPTY);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -196,9 +197,9 @@ function POST_api_cursor(req, res) {
|
|||
/// @verbinclude api-cursor-invalid-cursor-identifier
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function PUT_api_cursor(req, res) {
|
||||
function PUT_api_cursor (req, res) {
|
||||
if (req.suffix.length != 1) {
|
||||
actions.resultBad(req, res, actions.ERROR_HTTP_BAD_PARAMETER);
|
||||
actions.resultBad(req, res, arangodb.ERROR_HTTP_BAD_PARAMETER);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -206,7 +207,7 @@ function PUT_api_cursor(req, res) {
|
|||
var cursor = CURSOR(cursorId);
|
||||
|
||||
if (! (cursor instanceof ArangoCursor)) {
|
||||
actions.resultBad(req, res, actions.ERROR_CURSOR_NOT_FOUND);
|
||||
actions.resultBad(req, res, arangodb.ERROR_CURSOR_NOT_FOUND);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -253,13 +254,13 @@ function PUT_api_cursor(req, res) {
|
|||
|
||||
function DELETE_api_cursor(req, res) {
|
||||
if (req.suffix.length != 1) {
|
||||
actions.resultBad(req, res, actions.ERROR_HTTP_BAD_PARAMETER);
|
||||
actions.resultBad(req, res, arangodb.ERROR_HTTP_BAD_PARAMETER);
|
||||
return;
|
||||
}
|
||||
|
||||
var cursorId = decodeURIComponent(req.suffix[0]);
|
||||
if (! DELETE_CURSOR(cursorId)) {
|
||||
actions.resultNotFound(req, res, internal.errors.ERROR_CURSOR_NOT_FOUND.code, internal.errors.ERROR_CURSOR_NOT_FOUND.message);
|
||||
actions.resultNotFound(req, res, arangodb.ERROR_CURSOR_NOT_FOUND);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,8 +25,9 @@
|
|||
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var arangodb = require("org/arangodb");
|
||||
var actions = require("org/arangodb/actions");
|
||||
var internal = require("internal");
|
||||
|
||||
var API = "/_api/edges";
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -71,14 +72,14 @@ var API = "/_api/edges";
|
|||
|
||||
function GET_edges (req, res) {
|
||||
if (req.suffix.length !== 1) {
|
||||
actions.resultBad(req, res, actions.ERROR_HTTP_BAD_PARAMETER,
|
||||
actions.resultBad(req, res, arangodb.ERROR_HTTP_BAD_PARAMETER,
|
||||
"expect GET /" + API + "/<collection-identifer>?vertex=<vertex-handle>&direction=<direction>");
|
||||
return;
|
||||
}
|
||||
|
||||
var name = decodeURIComponent(req.suffix[0]);
|
||||
var id = parseInt(name) || name;
|
||||
var collection = internal.db._collection(id);
|
||||
var collection = arangodb.db._collection(id);
|
||||
|
||||
if (collection === null) {
|
||||
actions.collectionNotFound(req, res, name);
|
||||
|
@ -99,7 +100,7 @@ function GET_edges (req, res) {
|
|||
e = collection.outEdges(vertex);
|
||||
}
|
||||
else {
|
||||
actions.resultBad(req, res, actions.ERROR_HTTP_BAD_PARAMETER,
|
||||
actions.resultBad(req, res, arangodb.ERROR_HTTP_BAD_PARAMETER,
|
||||
"<direction> must be any, in, or out, not: " + JSON.stringify(direction));
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,9 @@
|
|||
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var arangodb = require("org/arangodb");
|
||||
var actions = require("org/arangodb/actions");
|
||||
|
||||
var API = "_api/index";
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -71,7 +73,7 @@ var API = "_api/index";
|
|||
|
||||
function GET_api_indexes (req, res) {
|
||||
var name = req.parameters.collection;
|
||||
var collection = internal.db._collection(name);
|
||||
var collection = arangodb.db._collection(name);
|
||||
|
||||
if (collection === null) {
|
||||
actions.collectionNotFound(req, res, name);
|
||||
|
@ -131,7 +133,7 @@ function GET_api_index (req, res) {
|
|||
|
||||
else if (req.suffix.length === 2) {
|
||||
var name = decodeURIComponent(req.suffix[0]);
|
||||
var collection = internal.db._collection(name);
|
||||
var collection = arangodb.db._collection(name);
|
||||
|
||||
if (collection === null) {
|
||||
actions.collectionNotFound(req, res, name);
|
||||
|
@ -149,7 +151,7 @@ function GET_api_index (req, res) {
|
|||
actions.resultOk(req, res, actions.HTTP_OK, index);
|
||||
}
|
||||
else {
|
||||
actions.resultBad(req, res, actions.ERROR_HTTP_BAD_PARAMETER,
|
||||
actions.resultBad(req, res, arangodb.ERROR_HTTP_BAD_PARAMETER,
|
||||
"expect GET /" + API + "/<index-handle>");
|
||||
}
|
||||
}
|
||||
|
@ -183,7 +185,7 @@ function GET_api_index (req, res) {
|
|||
|
||||
function POST_api_index_cap (req, res, collection, body) {
|
||||
if (! body.hasOwnProperty("size")) {
|
||||
actions.resultBad(req, res, actions.ERROR_HTTP_BAD_PARAMETER,
|
||||
actions.resultBad(req, res, arangodb.ERROR_HTTP_BAD_PARAMETER,
|
||||
"expecting a size");
|
||||
}
|
||||
|
||||
|
@ -260,7 +262,7 @@ function POST_api_index_geo (req, res, collection, body) {
|
|||
var fields = body.fields;
|
||||
|
||||
if (! (fields instanceof Array)) {
|
||||
actions.resultBad(req, res, actions.ERROR_HTTP_BAD_PARAMETER,
|
||||
actions.resultBad(req, res, arangodb.ERROR_HTTP_BAD_PARAMETER,
|
||||
"fields must be a list of attribute paths: " + fields);
|
||||
}
|
||||
|
||||
|
@ -316,7 +318,7 @@ function POST_api_index_geo (req, res, collection, body) {
|
|||
|
||||
// something is wrong
|
||||
else {
|
||||
actions.resultBad(req, res, actions.ERROR_HTTP_BAD_PARAMETER,
|
||||
actions.resultBad(req, res, arangodb.ERROR_HTTP_BAD_PARAMETER,
|
||||
"fields must be a list of attribute paths of length 1 or 2: " + fields);
|
||||
return;
|
||||
}
|
||||
|
@ -371,7 +373,7 @@ function POST_api_index_hash (req, res, collection, body) {
|
|||
var fields = body.fields;
|
||||
|
||||
if (! (fields instanceof Array)) {
|
||||
actions.resultBad(req, res, actions.ERROR_HTTP_BAD_PARAMETER,
|
||||
actions.resultBad(req, res, arangodb.ERROR_HTTP_BAD_PARAMETER,
|
||||
"fields must be a list of attribute paths: " + fields);
|
||||
}
|
||||
|
||||
|
@ -430,7 +432,7 @@ function POST_api_index_skiplist (req, res, collection, body) {
|
|||
var fields = body.fields;
|
||||
|
||||
if (! (fields instanceof Array)) {
|
||||
actions.resultBad(req, res, actions.ERROR_HTTP_BAD_PARAMETER,
|
||||
actions.resultBad(req, res, arangodb.ERROR_HTTP_BAD_PARAMETER,
|
||||
"fields must be a list of attribute paths: " + fields);
|
||||
}
|
||||
|
||||
|
@ -544,7 +546,7 @@ function POST_api_index_bitarray (req, res, collection, body) {
|
|||
var fields = body.fields;
|
||||
|
||||
if (! (fields instanceof Array)) {
|
||||
actions.resultBad(req, res, actions.ERROR_HTTP_BAD_PARAMETER,
|
||||
actions.resultBad(req, res, arangodb.ERROR_HTTP_BAD_PARAMETER,
|
||||
"fields must be a list of attribute paths: " + fields);
|
||||
}
|
||||
|
||||
|
@ -618,7 +620,7 @@ function POST_api_index (req, res) {
|
|||
}
|
||||
|
||||
var name = req.parameters.collection;
|
||||
var collection = internal.db._collection(name);
|
||||
var collection = arangodb.db._collection(name);
|
||||
|
||||
if (collection === null) {
|
||||
actions.collectionNotFound(req, res, name);
|
||||
|
@ -650,7 +652,7 @@ function POST_api_index (req, res) {
|
|||
POST_api_index_bitarray(req, res, collection, body);
|
||||
}
|
||||
else {
|
||||
actions.resultBad(req, res, actions.ERROR_HTTP_BAD_PARAMETER,
|
||||
actions.resultBad(req, res, arangodb.ERROR_HTTP_BAD_PARAMETER,
|
||||
"unknown index type '" + body.type + "'");
|
||||
}
|
||||
}
|
||||
|
@ -671,13 +673,13 @@ function POST_api_index (req, res) {
|
|||
|
||||
function DELETE_api_index (req, res) {
|
||||
if (req.suffix.length !== 2) {
|
||||
actions.resultBad(req, res, actions.ERROR_HTTP_BAD_PARAMETER,
|
||||
actions.resultBad(req, res, arangodb.ERROR_HTTP_BAD_PARAMETER,
|
||||
"expect DELETE /" + API + "/<index-handle>");
|
||||
return;
|
||||
}
|
||||
|
||||
var name = decodeURIComponent(req.suffix[0]);
|
||||
var collection = internal.db._collection(name);
|
||||
var collection = arangodb.db._collection(name);
|
||||
|
||||
if (collection === null) {
|
||||
actions.collectionNotFound(req, res, name);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
vars: true,
|
||||
white: true,
|
||||
plusplus: true */
|
||||
/*global require, exports */
|
||||
/*global require, exports, module */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief administration actions
|
||||
|
@ -34,10 +34,9 @@
|
|||
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
(function() {
|
||||
var actions = require("org/arangodb/actions");
|
||||
var internal = require("internal");
|
||||
var console = require("internal");
|
||||
var actions = require("org/arangodb/actions");
|
||||
var internal = require("internal");
|
||||
var console = require("console");
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- standard routing
|
||||
|
@ -52,75 +51,75 @@
|
|||
/// @brief routing function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function Routing (req, res) {
|
||||
var action;
|
||||
var execute;
|
||||
var next;
|
||||
var path = req.suffix.join("/");
|
||||
function Routing (req, res) {
|
||||
var action;
|
||||
var execute;
|
||||
var next;
|
||||
var path = req.suffix.join("/");
|
||||
|
||||
action = actions.firstRouting(req.requestType, req.suffix);
|
||||
action = actions.firstRouting(req.requestType, req.suffix);
|
||||
|
||||
execute = function () {
|
||||
if (action.route === undefined) {
|
||||
actions.resultNotImplemented(req, res, "unknown path '" + path + "'");
|
||||
return;
|
||||
}
|
||||
execute = function () {
|
||||
if (action.route === undefined) {
|
||||
actions.resultNotImplemented(req, res, "unknown path '" + path + "'");
|
||||
return;
|
||||
}
|
||||
|
||||
if (action.route.path !== undefined) {
|
||||
req.path = action.route.path;
|
||||
}
|
||||
else {
|
||||
delete req.path;
|
||||
}
|
||||
if (action.route.path !== undefined) {
|
||||
req.path = action.route.path;
|
||||
}
|
||||
else {
|
||||
delete req.path;
|
||||
}
|
||||
|
||||
if (action.prefix !== undefined) {
|
||||
req.prefix = action.prefix;
|
||||
}
|
||||
else {
|
||||
delete req.prefix;
|
||||
}
|
||||
if (action.prefix !== undefined) {
|
||||
req.prefix = action.prefix;
|
||||
}
|
||||
else {
|
||||
delete req.prefix;
|
||||
}
|
||||
|
||||
if (action.suffix !== undefined) {
|
||||
req.suffix = action.suffix;
|
||||
}
|
||||
else {
|
||||
delete req.suffix;
|
||||
}
|
||||
if (action.suffix !== undefined) {
|
||||
req.suffix = action.suffix;
|
||||
}
|
||||
else {
|
||||
delete req.suffix;
|
||||
}
|
||||
|
||||
if (action.urlParameters !== undefined) {
|
||||
req.urlParameters = action.urlParameters;
|
||||
}
|
||||
else {
|
||||
req.urlParameters = {};
|
||||
}
|
||||
if (action.urlParameters !== undefined) {
|
||||
req.urlParameters = action.urlParameters;
|
||||
}
|
||||
else {
|
||||
req.urlParameters = {};
|
||||
}
|
||||
|
||||
var func = action.route.callback.controller;
|
||||
if (func === null || typeof func !== 'function') {
|
||||
func = actions.errorFunction(action.route, 'Invalid callback definition found for route ' + JSON.stringify(action.route));
|
||||
}
|
||||
var func = action.route.callback.controller;
|
||||
if (func === null || typeof func !== 'function') {
|
||||
func = actions.errorFunction(action.route, 'Invalid callback definition found for route ' + JSON.stringify(action.route));
|
||||
}
|
||||
|
||||
try {
|
||||
func(req, res, action.route.callback.options, next);
|
||||
}
|
||||
catch (err) {
|
||||
actions.errorFunction(action.route, 'A runtime error occurred while executing an action: ' + String(err))(req, res, action.route.callback.options, next);
|
||||
}
|
||||
};
|
||||
|
||||
next = function () {
|
||||
action = actions.nextRouting(action);
|
||||
execute();
|
||||
};
|
||||
try {
|
||||
func(req, res, action.route.callback.options, next);
|
||||
}
|
||||
catch (err) {
|
||||
actions.errorFunction(action.route, 'A runtime error occurred while executing an action: ' + String(err))(req, res, action.route.callback.options, next);
|
||||
}
|
||||
};
|
||||
|
||||
next = function () {
|
||||
action = actions.nextRouting(action);
|
||||
execute();
|
||||
}
|
||||
};
|
||||
|
||||
actions.defineHttp({
|
||||
url : "",
|
||||
prefix : true,
|
||||
context : "admin",
|
||||
callback : Routing
|
||||
});
|
||||
execute();
|
||||
}
|
||||
|
||||
actions.defineHttp({
|
||||
url : "",
|
||||
prefix : true,
|
||||
context : "admin",
|
||||
callback : Routing
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief reloads the server authentication information
|
||||
|
@ -140,28 +139,29 @@
|
|||
/// @brief reloads the routing information
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : "_admin/routing/reload",
|
||||
context : "admin",
|
||||
prefix : false,
|
||||
callback : function (req, res) {
|
||||
internal.executeGlobalContextFunction("require(\"org/arangodb/actions\").reloadRouting()");
|
||||
actions.resultOk(req, res, actions.HTTP_OK);
|
||||
}
|
||||
});
|
||||
actions.defineHttp({
|
||||
url : "_admin/routing/reload",
|
||||
context : "admin",
|
||||
prefix : false,
|
||||
callback : function (req, res) {
|
||||
internal.executeGlobalContextFunction("require(\"org/arangodb/actions\").reloadRouting()");
|
||||
console.warn("about to flush the routing cache");
|
||||
actions.resultOk(req, res, actions.HTTP_OK);
|
||||
}
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief returns the current routing information
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : "_admin/routing/routes",
|
||||
context : "admin",
|
||||
prefix : false,
|
||||
callback : function (req, res) {
|
||||
actions.resultOk(req, res, actions.HTTP_OK, actions.routingCache());
|
||||
}
|
||||
});
|
||||
actions.defineHttp({
|
||||
url : "_admin/routing/routes",
|
||||
context : "admin",
|
||||
prefix : false,
|
||||
callback : function (req, res) {
|
||||
actions.resultOk(req, res, actions.HTTP_OK, actions.routingCache());
|
||||
}
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
|
@ -176,6 +176,21 @@
|
|||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief flushes the modules cache
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : "_admin/modules/flush",
|
||||
context : "admin",
|
||||
prefix : false,
|
||||
callback : function (req, res) {
|
||||
internal.executeGlobalContextFunction("require(\"internal\").flushModuleCache()");
|
||||
console.warn("about to flush the modules cache");
|
||||
actions.resultOk(req, res, actions.HTTP_OK);
|
||||
}
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @fn JSF_GET_admin_time
|
||||
/// @brief returns the system time
|
||||
|
@ -188,14 +203,14 @@
|
|||
/// current system time as a Unix timestamp with microsecond precision.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : "_admin/time",
|
||||
context : "admin",
|
||||
prefix : false,
|
||||
callback : function (req, res) {
|
||||
actions.resultOk(req, res, actions.HTTP_OK, { time : internal.time() });
|
||||
}
|
||||
});
|
||||
actions.defineHttp({
|
||||
url : "_admin/time",
|
||||
context : "admin",
|
||||
prefix : false,
|
||||
callback : function (req, res) {
|
||||
actions.resultOk(req, res, actions.HTTP_OK, { time : internal.time() });
|
||||
}
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @fn JSF_GET_admin_echo
|
||||
|
@ -214,16 +229,16 @@
|
|||
/// - @LIT{parameters}: list of URL parameters received
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : "_admin/echo",
|
||||
context : "admin",
|
||||
prefix : true,
|
||||
callback : function (req, res) {
|
||||
res.responseCode = actions.HTTP_OK;
|
||||
res.contentType = "application/json; charset=utf-8";
|
||||
res.body = JSON.stringify(req);
|
||||
}
|
||||
});
|
||||
actions.defineHttp({
|
||||
url : "_admin/echo",
|
||||
context : "admin",
|
||||
prefix : true,
|
||||
callback : function (req, res) {
|
||||
res.responseCode = actions.HTTP_OK;
|
||||
res.contentType = "application/json; charset=utf-8";
|
||||
res.body = JSON.stringify(req);
|
||||
}
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @fn JSF_GET_admin_status
|
||||
|
@ -260,24 +275,24 @@
|
|||
/// made which have required loading a memory page from disk.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : "_admin/status",
|
||||
context : "admin",
|
||||
actions.defineHttp({
|
||||
url : "_admin/status",
|
||||
context : "admin",
|
||||
|
||||
callback : function (req, res) {
|
||||
var result;
|
||||
callback : function (req, res) {
|
||||
var result;
|
||||
|
||||
try {
|
||||
result = {};
|
||||
result.system = SYS_PROCESS_STAT();
|
||||
try {
|
||||
result = {};
|
||||
result.system = internal.processStat();
|
||||
|
||||
actions.resultOk(req, res, actions.HTTP_OK, result);
|
||||
}
|
||||
catch (err) {
|
||||
actions.resultException(req, res, err);
|
||||
}
|
||||
actions.resultOk(req, res, actions.HTTP_OK, result);
|
||||
}
|
||||
});
|
||||
catch (err) {
|
||||
actions.resultException(req, res, err);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
|
@ -292,83 +307,81 @@
|
|||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function GET_admin_session (req, res) {
|
||||
var result;
|
||||
var realm;
|
||||
function GET_admin_session (req, res) {
|
||||
var result;
|
||||
var realm;
|
||||
|
||||
if (req.user === null) {
|
||||
realm = "basic realm=\"arangodb\"";
|
||||
if (req.user === null) {
|
||||
realm = "basic realm=\"arangodb\"";
|
||||
|
||||
res.responseCode = actions.HTTP_UNAUTHORIZED;
|
||||
res.headers = { "www-authenticate" : realm };
|
||||
}
|
||||
else {
|
||||
var user = internal.db._collection("_users").firstExample({ user : req.user });
|
||||
res.responseCode = actions.HTTP_UNAUTHORIZED;
|
||||
res.headers = { "www-authenticate" : realm };
|
||||
}
|
||||
else {
|
||||
var user = internal.db._collection("_users").firstExample({ user : req.user });
|
||||
|
||||
if (user === null) {
|
||||
actions.resultNotFound(req, res, internal.errors.ERROR_HTTP_NOT_FOUND.code, "unknown user '" + req.user + "'");
|
||||
}
|
||||
else {
|
||||
result = {
|
||||
user : user.user,
|
||||
permissions : user.permissions || []
|
||||
};
|
||||
|
||||
actions.resultOk(req, res, actions.HTTP_OK, result);
|
||||
}
|
||||
}
|
||||
if (user === null) {
|
||||
actions.resultNotFound(req, res, internal.errors.ERROR_HTTP_NOT_FOUND.code, "unknown user '" + req.user + "'");
|
||||
}
|
||||
else {
|
||||
result = {
|
||||
user : user.user,
|
||||
permissions : user.permissions || []
|
||||
};
|
||||
|
||||
function POST_admin_session (req, res) {
|
||||
actions.resultUnsupported(req, res);
|
||||
actions.resultOk(req, res, actions.HTTP_OK, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function PUT_admin_session (req, res) {
|
||||
actions.resultUnsupported(req, res);
|
||||
}
|
||||
function POST_admin_session (req, res) {
|
||||
actions.resultUnsupported(req, res);
|
||||
}
|
||||
|
||||
function DELETE_admin_session (req, res) {
|
||||
actions.resultUnsupported(req, res);
|
||||
}
|
||||
function PUT_admin_session (req, res) {
|
||||
actions.resultUnsupported(req, res);
|
||||
}
|
||||
|
||||
function DELETE_admin_session (req, res) {
|
||||
actions.resultUnsupported(req, res);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief session call dispatcher
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : "_admin/session",
|
||||
context : "admin",
|
||||
prefix : false,
|
||||
callback : function (req, res) {
|
||||
try {
|
||||
if (req.requestType === actions.GET) {
|
||||
GET_admin_session(req, res);
|
||||
}
|
||||
else if (req.requestType === actions.DELETE) {
|
||||
DELETE_admin_session(req, res);
|
||||
}
|
||||
else if (req.requestType === actions.POST) {
|
||||
POST_admin_session(req, res);
|
||||
}
|
||||
else if (req.requestType === actions.PUT) {
|
||||
PUT_admin_session(req, res);
|
||||
}
|
||||
else {
|
||||
actions.resultUnsupported(req, res);
|
||||
}
|
||||
actions.defineHttp({
|
||||
url : "_admin/session",
|
||||
context : "admin",
|
||||
prefix : false,
|
||||
callback : function (req, res) {
|
||||
try {
|
||||
if (req.requestType === actions.GET) {
|
||||
GET_admin_session(req, res);
|
||||
}
|
||||
catch (err) {
|
||||
actions.resultException(req, res, err);
|
||||
else if (req.requestType === actions.DELETE) {
|
||||
DELETE_admin_session(req, res);
|
||||
}
|
||||
else if (req.requestType === actions.POST) {
|
||||
POST_admin_session(req, res);
|
||||
}
|
||||
else if (req.requestType === actions.PUT) {
|
||||
PUT_admin_session(req, res);
|
||||
}
|
||||
else {
|
||||
actions.resultUnsupported(req, res);
|
||||
}
|
||||
}
|
||||
});
|
||||
catch (err) {
|
||||
actions.resultException(req, res, err);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
})();
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -377,4 +390,3 @@
|
|||
// mode: outline-minor
|
||||
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @\\}\\)"
|
||||
// End:
|
||||
|
||||
|
|
|
@ -118,7 +118,7 @@ function buildDocumentFromReq(req) {
|
|||
|
||||
function postKeyValue(req, res) {
|
||||
if (req.suffix.length < 2) {
|
||||
actions.resultBad(req, res, actions.ERROR_KEYVALUE_INVALID_KEY, actions.getErrorMessage(actions.ERROR_KEYVALUE_INVALID_KEY));
|
||||
actions.resultBad(req, res, arangodb.ERROR_KEYVALUE_INVALID_KEY);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -130,7 +130,7 @@ function postKeyValue(req, res) {
|
|||
}
|
||||
|
||||
if (req.requestBody == "") {
|
||||
actions.resultError(req, res, actions.HTTP_BAD, actions.ERROR_KEYVALUE_NO_VALUE, actions.getErrorMessage(actions.ERROR_KEYVALUE_NO_VALUE));
|
||||
actions.resultError(req, res, actions.HTTP_BAD, arangodb.ERROR_KEYVALUE_NO_VALUE, actions.getErrorMessage(arangodb.ERROR_KEYVALUE_NO_VALUE));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -139,7 +139,7 @@ function postKeyValue(req, res) {
|
|||
var oldDoc = internal.db._collection(collection).firstExample("$key", doc["$key"]);
|
||||
|
||||
if (oldDoc != undefined) {
|
||||
actions.resultError(req, res, actions.HTTP_BAD, actions.ERROR_KEYVALUE_KEY_EXISTS, actions.getErrorMessage(actions.ERROR_KEYVALUE_KEY_EXISTS));
|
||||
actions.resultError(req, res, actions.HTTP_BAD, arangodb.ERROR_KEYVALUE_KEY_EXISTS, actions.getErrorMessage(arangodb.ERROR_KEYVALUE_KEY_EXISTS));
|
||||
}
|
||||
else {
|
||||
var id = db[collection].save(doc);
|
||||
|
@ -161,7 +161,7 @@ function postKeyValue(req, res) {
|
|||
|
||||
function putKeyValue(req, res) {
|
||||
if (req.suffix.length < 2) {
|
||||
actions.resultBad(req, res, actions.ERROR_KEYVALUE_INVALID_KEY, actions.getErrorMessage(actions.ERROR_KEYVALUE_INVALID_KEY));
|
||||
actions.resultBad(req, res, arangodb.ERROR_KEYVALUE_INVALID_KEY);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -186,7 +186,7 @@ function putKeyValue(req, res) {
|
|||
actions.resultOk(req, res, actions.HTTP_CREATED, result);
|
||||
return;
|
||||
}
|
||||
actions.resultError(req, res, actions.HTTP_NOT_FOUND, actions.ERROR_KEYVALUE_KEY_NOT_FOUND, actions.getErrorMessage(actions.ERROR_KEYVALUE_KEY_NOT_FOUND));
|
||||
actions.resultError(req, res, actions.HTTP_NOT_FOUND, arangodb.ERROR_KEYVALUE_KEY_NOT_FOUND, actions.getErrorMessage(arangodb.ERROR_KEYVALUE_KEY_NOT_FOUND));
|
||||
}
|
||||
else {
|
||||
// get _id
|
||||
|
@ -203,7 +203,7 @@ function putKeyValue(req, res) {
|
|||
actions.resultOk(req, res, actions.HTTP_ACCEPTED, {"changed" : true});
|
||||
}
|
||||
else {
|
||||
actions.resultError(req, res, actions.HTTP_BAD, actions.ERROR_KEYVALUE_KEY_NOT_CHANGED, actions.getErrorMessage(actions.ERROR_KEYVALUE_KEY_NOT_CHANGED));
|
||||
actions.resultError(req, res, actions.HTTP_BAD, arangodb.ERROR_KEYVALUE_KEY_NOT_CHANGED, actions.getErrorMessage(arangodb.ERROR_KEYVALUE_KEY_NOT_CHANGED));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -217,7 +217,7 @@ function putKeyValue(req, res) {
|
|||
|
||||
function deleteKeyValue(req, res) {
|
||||
if (req.suffix.length < 2) {
|
||||
actions.resultBad(req, res, actions.ERROR_KEYVALUE_INVALID_KEY, actions.getErrorMessage(actions.ERROR_KEYVALUE_INVALID_KEY));
|
||||
actions.resultBad(req, res, arangodb.ERROR_KEYVALUE_INVALID_KEY);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -237,7 +237,7 @@ function deleteKeyValue(req, res) {
|
|||
var doc = internal.db._collection(collection).firstExample("$key", key);
|
||||
|
||||
if (doc == undefined) {
|
||||
actions.resultError(req, res, actions.HTTP_NOT_FOUND, actions.ERROR_KEYVALUE_KEY_NOT_FOUND, actions.getErrorMessage(actions.ERROR_KEYVALUE_KEY_NOT_FOUND));
|
||||
actions.resultError(req, res, actions.HTTP_NOT_FOUND, arangodb.ERROR_KEYVALUE_KEY_NOT_FOUND, actions.getErrorMessage(arangodb.ERROR_KEYVALUE_KEY_NOT_FOUND));
|
||||
}
|
||||
else {
|
||||
var id = doc._id;
|
||||
|
@ -245,7 +245,7 @@ function deleteKeyValue(req, res) {
|
|||
actions.resultOk(req, res, actions.HTTP_ACCEPTED, {"removed" : true});
|
||||
}
|
||||
else {
|
||||
actions.resultError(req, res, actions.HTTP_BAD, actions.ERROR_KEYVALUE_KEY_NOT_REMOVED, actions.getErrorMessage(actions.ERROR_KEYVALUE_KEY_NOT_REMOVED));
|
||||
actions.resultError(req, res, actions.HTTP_BAD, arangodb.ERROR_KEYVALUE_KEY_NOT_REMOVED, actions.getErrorMessage(arangodb.ERROR_KEYVALUE_KEY_NOT_REMOVED));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -261,7 +261,7 @@ function deleteKeyValue(req, res) {
|
|||
|
||||
function getKeyValue(req, res) {
|
||||
if (req.suffix.length < 2) {
|
||||
actions.resultBad(req, res, actions.ERROR_KEYVALUE_INVALID_KEY, actions.getErrorMessage(actions.ERROR_KEYVALUE_INVALID_KEY));
|
||||
actions.resultBad(req, res, arangodb.ERROR_KEYVALUE_INVALID_KEY);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -281,7 +281,7 @@ function getKeyValue(req, res) {
|
|||
var doc = internal.db._collection(collection).firstExample("$key", key);
|
||||
|
||||
if (doc == undefined) {
|
||||
actions.resultError(req, res, actions.HTTP_NOT_FOUND, actions.ERROR_KEYVALUE_KEY_NOT_FOUND, actions.getErrorMessage(actions.ERROR_KEYVALUE_KEY_NOT_FOUND));
|
||||
actions.resultError(req, res, actions.HTTP_NOT_FOUND, arangodb.ERROR_KEYVALUE_KEY_NOT_FOUND, actions.getErrorMessage(arangodb.ERROR_KEYVALUE_KEY_NOT_FOUND));
|
||||
}
|
||||
else {
|
||||
var headers = {};
|
||||
|
@ -367,7 +367,7 @@ actions.defineHttp({
|
|||
|
||||
function searchKeyValue(req, res) {
|
||||
if (req.suffix.length < 2) {
|
||||
actions.resultBad(req, res, actions.ERROR_KEYVALUE_INVALID_KEY, actions.getErrorMessage(actions.ERROR_KEYVALUE_INVALID_KEY));
|
||||
actions.resultBad(req, res, arangodb.ERROR_KEYVALUE_INVALID_KEY);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -76,6 +76,8 @@ function ArangoError (error) {
|
|||
(function () {
|
||||
var internal = require("internal");
|
||||
|
||||
internal.ArangoError = ArangoError;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief prints an error
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -386,12 +388,6 @@ function help () {
|
|||
(function () {
|
||||
var internal = require("internal");
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief be quiet
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.ARANGO_QUIET = ARANGO_QUIET;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief log function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -400,6 +396,16 @@ function help () {
|
|||
internal.output(level, ": ", msg, "\n");
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief flushes the module cache of the server
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.flushServerModules = function () {
|
||||
if (typeof arango !== 'undefined') {
|
||||
arango.POST("/_admin/modules/flush", "");
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief rebuilds the routing cache
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1703,7 +1709,7 @@ function ArangoCollection (database, data) {
|
|||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief delete a document in the collection, identified by its id
|
||||
/// @brief removes a document in the collection, identified by its id
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ArangoCollection.prototype.remove = function (id, overwrite) {
|
||||
|
@ -1748,7 +1754,26 @@ function ArangoCollection (database, data) {
|
|||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief replace a document in the collection, identified by its id
|
||||
/// @brief removes documents in the collection, identified by an example
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// TODO this is not optiomal, there should a HTTP call handling everything on
|
||||
// the server
|
||||
|
||||
ArangoCollection.prototype.removeByExample = function (example, waitForSync) {
|
||||
var documents;
|
||||
|
||||
documents = this.byExample(example);
|
||||
|
||||
while (documents.hasNext()) {
|
||||
var document = documents.next();
|
||||
|
||||
this.remove(document, true, waitForSync);
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief replaces a document in the collection, identified by its id
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ArangoCollection.prototype.replace = function (id, data, overwrite) {
|
||||
|
|
|
@ -1,10 +1,4 @@
|
|||
/*jslint indent: 2,
|
||||
nomen: true,
|
||||
maxlen: 100,
|
||||
sloppy: true,
|
||||
vars: true,
|
||||
white: true,
|
||||
plusplus: true */
|
||||
/*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true, vars: true, white: true, plusplus: true */
|
||||
/*global require, exports */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -46,6 +40,19 @@ var internal = require("internal");
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
exports.db = internal.db;
|
||||
exports.ArangoCollection = internal.ArangoCollection;
|
||||
exports.ArangoError = internal.ArangoError;
|
||||
|
||||
// copy error codes
|
||||
(function () {
|
||||
var name;
|
||||
|
||||
for (name in internal.errors) {
|
||||
if (internal.errors.hasOwnProperty(name)) {
|
||||
exports[name] = internal.errors[name].code;
|
||||
}
|
||||
}
|
||||
}());
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
|
|
|
@ -0,0 +1,512 @@
|
|||
/*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true, vars: true, white: true, plusplus: true, regexp: true, continue: true */
|
||||
/*global require, exports */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief deployment tools
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2013 triagens GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Dr. Frank Celler
|
||||
/// @author Copyright 2013, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var arangodb = require("org/arangodb");
|
||||
var fs = require("fs");
|
||||
var internal = require("internal");
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- ArangoApp
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- constructors and destructors
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup ArangoDeployment
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief application
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function ArangoApp (routing, description) {
|
||||
this._name = description.application;
|
||||
this._routing = routing;
|
||||
this._description = description;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup ArangoDeployment
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief guesses the content type
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function guessContentType (filename, content) {
|
||||
var re = /.*\.([^\.]*)$/;
|
||||
var match = re.exec(filename);
|
||||
var extension;
|
||||
|
||||
if (match === null) {
|
||||
return "text/plain; charset=utf-8";
|
||||
}
|
||||
|
||||
extension = match[1];
|
||||
|
||||
if (extension === "html") {
|
||||
return "text/html; charset=utf-8";
|
||||
}
|
||||
|
||||
if (extension === "xml") {
|
||||
return "application/xml; charset=utf-8";
|
||||
}
|
||||
|
||||
if (extension === "json") {
|
||||
return "application/json; charset=utf-8";
|
||||
}
|
||||
|
||||
if (extension === "js") {
|
||||
return "application/x-javascript; charset=utf-8";
|
||||
}
|
||||
|
||||
return "text/plain; charset=utf-8";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief normalizes a path
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function normalizePath (url) {
|
||||
if (url === "") {
|
||||
url = "/";
|
||||
}
|
||||
else if (url[0] !== '/') {
|
||||
url = "/" + url;
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief updates a routing entry
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ArangoApp.prototype.updateRoute = function (route) {
|
||||
var routes;
|
||||
var i;
|
||||
|
||||
routes = this._description.routes;
|
||||
|
||||
for (i = 0; i < routes.length; ++i) {
|
||||
if (routes[i].type === route.type && routes[i].key === route.key) {
|
||||
routes[i] = route;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
routes.push(route);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief prints an application
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ArangoApp.prototype._PRINT = function (route) {
|
||||
internal.output('[ArangoApp "', this._name, '" at "', this._description.urlPrefix, '"]');
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup ArangoDeployment
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief mounts one page directly
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ArangoApp.prototype.mountStaticContent = function (url, content, contentType) {
|
||||
var pages;
|
||||
var name;
|
||||
|
||||
if (url === "") {
|
||||
url = "/";
|
||||
}
|
||||
else if (url[0] !== '/') {
|
||||
url = "/" + url;
|
||||
}
|
||||
|
||||
if (typeof content !== "string") {
|
||||
content = JSON.stringify(content);
|
||||
|
||||
if (contentType === undefined) {
|
||||
contentType = "application/json; charset=utf-8";
|
||||
}
|
||||
}
|
||||
|
||||
if (contentType === undefined) {
|
||||
contentType = "text/html; charset=utf-8";
|
||||
}
|
||||
|
||||
pages = {
|
||||
type: "StaticContent",
|
||||
key: url,
|
||||
url: { match: url },
|
||||
content: {
|
||||
contentType: contentType,
|
||||
body: content,
|
||||
methods: [ "GET", "HEAD" ]
|
||||
}
|
||||
};
|
||||
|
||||
this.updateRoute(pages);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief mounts a bunch of static pages
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ArangoApp.prototype.mountStaticPages = function (url, collection) {
|
||||
var pages;
|
||||
var name;
|
||||
|
||||
if (typeof collection !== "string") {
|
||||
name = collection.name();
|
||||
}
|
||||
else {
|
||||
name = collection;
|
||||
}
|
||||
|
||||
url = normalizePath(url);
|
||||
|
||||
pages = {
|
||||
type: "StaticPages",
|
||||
key: url,
|
||||
url: { match: url + "/*" },
|
||||
action: {
|
||||
controller: "org/arangodb/actions/staticContentController",
|
||||
methods: [ "GET", "HEAD" ],
|
||||
options: {
|
||||
contentCollection: name,
|
||||
prefix: url,
|
||||
application: this._name
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.updateRoute(pages);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief mounts a simple action
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ArangoApp.prototype.mountAction = function (url, func, methods) {
|
||||
var pages;
|
||||
var name;
|
||||
|
||||
url = normalizePath(url);
|
||||
|
||||
if (methods === undefined) {
|
||||
methods = [ "GET", "HEAD" ];
|
||||
}
|
||||
|
||||
if (! (methods instanceof Array)) {
|
||||
var error = new arangodb.ArangoError();
|
||||
error.errorNum = arangodb.ERROR_BAD_PARAMETER;
|
||||
error.errorMessage = "methods must be a list of HTTP methods, i. e. [\"GET\"]";
|
||||
|
||||
throw error;
|
||||
}
|
||||
|
||||
pages = {
|
||||
type: "Action",
|
||||
key: url,
|
||||
url: { match: url },
|
||||
action: {
|
||||
'do': func,
|
||||
methods: methods,
|
||||
options: {
|
||||
path: url,
|
||||
application: this._name
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.updateRoute(pages);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief changes the common prefix
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ArangoApp.prototype.setPrefix = function (prefix) {
|
||||
if (prefix !== "" && prefix[prefix.length - 1] === '/') {
|
||||
prefix = prefix.slice(0, prefix.length - 1);
|
||||
}
|
||||
|
||||
if (prefix !== "" && prefix[0] !== '/') {
|
||||
prefix = "/" + prefix;
|
||||
}
|
||||
|
||||
if (prefix === "/") {
|
||||
prefix = "";
|
||||
}
|
||||
|
||||
this._description.urlPrefix = prefix;
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief gets the common prefix
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ArangoApp.prototype.prefix = function () {
|
||||
return this._description.urlPrefix;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief saves and reloads
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ArangoApp.prototype.save = function () {
|
||||
var doc;
|
||||
|
||||
doc = this._routing.replace(this._description, this._description);
|
||||
this._description = this._routing.document(doc);
|
||||
|
||||
internal.reloadRouting();
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief uploads content from filesystem
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ArangoApp.prototype.uploadStaticPages = function (prefix, path) {
|
||||
var doc;
|
||||
var files;
|
||||
var i;
|
||||
var route;
|
||||
var routes;
|
||||
var collection;
|
||||
var error;
|
||||
var name;
|
||||
var re = /.*\/([^\/]*)$/;
|
||||
|
||||
routes = this._description.routes;
|
||||
prefix = normalizePath(prefix);
|
||||
|
||||
for (i = 0; i < routes.length; ++i) {
|
||||
route = routes[i];
|
||||
|
||||
if (route.type === "StaticPages" && route.key === prefix) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (routes.length <= i) {
|
||||
error = new arangodb.ArangoError();
|
||||
error.errorNum = arangodb.ERROR_HTTP_NOT_FOUND;
|
||||
error.errorMessage = "cannot find path '" + prefix + "' in routing table";
|
||||
|
||||
throw error;
|
||||
}
|
||||
|
||||
files = fs.listTree(path);
|
||||
|
||||
name = route.action.options.contentCollection;
|
||||
collection = arangodb.db._collection(name);
|
||||
|
||||
if (collection === null) {
|
||||
arangodb.db._createDocumentCollection(name);
|
||||
collection = arangodb.db._collection(name);
|
||||
}
|
||||
|
||||
collection.ensureHashIndex("application", "prefix", "path");
|
||||
|
||||
collection.removeByExample({ application: this._name, prefix: prefix });
|
||||
|
||||
for (i = 0; i < files.length; ++i) {
|
||||
var content;
|
||||
var contentType;
|
||||
var file = path + "/" + files[i];
|
||||
var subpath = "/" + files[i];
|
||||
var filename;
|
||||
|
||||
if (fs.isDirectory(file)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
content = internal.read(file);
|
||||
|
||||
if (content === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
filename = re.exec(files[i]);
|
||||
|
||||
if (filename !== null) {
|
||||
filename = filename[1];
|
||||
}
|
||||
else {
|
||||
filename = files[i];
|
||||
}
|
||||
|
||||
contentType = guessContentType(file, content);
|
||||
|
||||
collection.save({
|
||||
application: this._name,
|
||||
prefix: prefix,
|
||||
path: subpath,
|
||||
content: content,
|
||||
contentType: contentType,
|
||||
filename: filename
|
||||
});
|
||||
|
||||
internal.print("imported '" + subpath + "' of type '" + contentType + "'");
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief creates a new app
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
exports.createApp = function (name) {
|
||||
var routing = arangodb.db._collection("_routing");
|
||||
var doc = routing.firstExample({ application: name });
|
||||
|
||||
if (doc !== null) {
|
||||
var error = new arangodb.ArangoError();
|
||||
error.errorNum = arangodb.ERROR_ARANGO_DUPLICATE_IDENTIFIER;
|
||||
error.errorMessage = "application name must be unique";
|
||||
|
||||
throw error;
|
||||
}
|
||||
|
||||
doc = routing.save({ application: name,
|
||||
urlPrefix: "",
|
||||
routes: [],
|
||||
middleware: [] });
|
||||
|
||||
return new ArangoApp(routing, routing.document(doc));
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief loads an existing app
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
exports.readApp = function (name) {
|
||||
var routing = arangodb.db._collection("_routing");
|
||||
var doc = routing.firstExample({ application: name });
|
||||
|
||||
if (doc === null) {
|
||||
var error = new arangodb.ArangoError();
|
||||
error.errorNum = arangodb.ERROR_ARANGO_DOCUMENT_NOT_FOUND;
|
||||
error.errorMessage = "application unknown";
|
||||
|
||||
throw error;
|
||||
}
|
||||
|
||||
return new ArangoApp(routing, doc);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief loads a module directory into the database
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
exports.uploadModules = function (prefix, path) {
|
||||
var i;
|
||||
var files;
|
||||
var re = /^(.*)\.js$/;
|
||||
|
||||
prefix = normalizePath(prefix);
|
||||
files = fs.listTree(path);
|
||||
|
||||
for (i = 0; i < files.length; ++i) {
|
||||
var content;
|
||||
var mpath;
|
||||
var file = path + "/" + files[i];
|
||||
|
||||
if (fs.isDirectory(file)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
mpath = re.exec(files[i]);
|
||||
|
||||
if (mpath === null) {
|
||||
internal.print("skipping file '" + files[i] + "' of unknown type, expecting .js");
|
||||
continue;
|
||||
}
|
||||
|
||||
mpath = prefix + "/" + mpath[1];
|
||||
|
||||
internal.defineModule(mpath, file);
|
||||
|
||||
internal.print("imported '" + mpath + "'");
|
||||
}
|
||||
|
||||
internal.flushServerModules();
|
||||
internal.wait(1);
|
||||
internal.reloadRouting();
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @\\}\\)"
|
||||
// End:
|
|
@ -0,0 +1,180 @@
|
|||
/*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true, vars: true, white: true, plusplus: true */
|
||||
/*global Module */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief module "console"
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2010-2013 triagens GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Dr. Frank Celler
|
||||
/// @author Copyright 2010-2013, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- Module "console"
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup V8ModuleConsole
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief console module
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
(function () {
|
||||
var internal = Module.prototype.ModuleCache["/internal"].exports;
|
||||
var console = Module.prototype.ModuleCache["/console"].exports;
|
||||
|
||||
console.getline = internal.getline;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief logs debug message
|
||||
///
|
||||
/// @FUN{console.debug(@FA{format}, @FA{argument1}, ...)}
|
||||
///
|
||||
/// Formats the arguments according to @FA{format} and logs the result as
|
||||
/// debug message.
|
||||
///
|
||||
/// String substitution patterns, which can be used in @FA{format}.
|
||||
///
|
||||
/// - @LIT{\%s} string
|
||||
/// - @LIT{\%d}, @LIT{\%i} integer
|
||||
/// - @LIT{\%f} floating point number
|
||||
/// - @LIT{\%o} object hyperlink
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
console.debug = function () {
|
||||
var msg;
|
||||
|
||||
try {
|
||||
msg = internal.sprintf.apply(internal.sprintf, arguments);
|
||||
}
|
||||
catch (err) {
|
||||
msg = err + ": " + arguments;
|
||||
}
|
||||
|
||||
internal.log("debug", msg);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief logs error message
|
||||
///
|
||||
/// @FUN{console.error(@FA{format}, @FA{argument1}, ...)}
|
||||
///
|
||||
/// Formats the arguments according to @FA{format} and logs the result as
|
||||
/// error message.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
console.error = function () {
|
||||
var msg;
|
||||
|
||||
try {
|
||||
msg = internal.sprintf.apply(internal.sprintf, arguments);
|
||||
}
|
||||
catch (err) {
|
||||
msg = err + ": " + arguments;
|
||||
}
|
||||
|
||||
internal.log("error", msg);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief logs info message
|
||||
///
|
||||
/// @FUN{console.info(@FA{format}, @FA{argument1}, ...)}
|
||||
///
|
||||
/// Formats the arguments according to @FA{format} and logs the result as
|
||||
/// info message.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
console.info = function () {
|
||||
var msg;
|
||||
|
||||
try {
|
||||
msg = internal.sprintf.apply(internal.sprintf, arguments);
|
||||
}
|
||||
catch (err) {
|
||||
msg = err + ": " + arguments;
|
||||
}
|
||||
|
||||
internal.log("info", msg);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief logs log message
|
||||
///
|
||||
/// @FUN{console.log(@FA{format}, @FA{argument1}, ...)}
|
||||
///
|
||||
/// Formats the arguments according to @FA{format} and logs the result as
|
||||
/// log message.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
console.log = function () {
|
||||
var msg;
|
||||
|
||||
try {
|
||||
msg = internal.sprintf.apply(internal.sprintf, arguments);
|
||||
}
|
||||
catch (err) {
|
||||
msg = err + ": " + arguments;
|
||||
}
|
||||
|
||||
internal.log("info", msg);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief logs warn message
|
||||
///
|
||||
/// @FUN{console.warn(@FA{format}, @FA{argument1}, ...)}
|
||||
///
|
||||
/// Formats the arguments according to @FA{format} and logs the result as
|
||||
/// warn message.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
console.warn = function () {
|
||||
var msg;
|
||||
|
||||
try {
|
||||
msg = internal.sprintf.apply(internal.sprintf, arguments);
|
||||
}
|
||||
catch (err) {
|
||||
msg = err + ": " + arguments;
|
||||
}
|
||||
|
||||
internal.log("warning", msg);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}());
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @}\\)"
|
||||
// End:
|
|
@ -0,0 +1,66 @@
|
|||
/*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true, vars: true, white: true, plusplus: true */
|
||||
/*global Module */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief module "js"
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2010-2013 triagens GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Dr. Frank Celler
|
||||
/// @author Copyright 2010-2013, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- Module "fs"
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup V8ModuleFS
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief file-system module
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
(function () {
|
||||
var internal = Module.prototype.ModuleCache["/internal"].exports;
|
||||
var fs = Module.prototype.ModuleCache["/fs"].exports;
|
||||
|
||||
fs.exists = internal.exists;
|
||||
fs.isDirectory = internal.isDirectory;
|
||||
fs.listTree = internal.listTree;
|
||||
fs.move = internal.move;
|
||||
fs.remove = internal.remove;
|
||||
}());
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @}\\)"
|
||||
// End:
|
|
@ -0,0 +1,727 @@
|
|||
/*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true, vars: true, white: true, plusplus: true, nonpropdel: true, proto: true */
|
||||
/*global require, module, Module, FS_MOVE, FS_REMOVE, FS_EXISTS, FS_IS_DIRECTORY, FS_LIST_TREE,
|
||||
SYS_EXECUTE, SYS_LOAD, SYS_LOG, SYS_LOG_LEVEL, SYS_OUTPUT, SYS_PROCESS_STAT, SYS_READ,
|
||||
SYS_SPRINTF, SYS_TIME, SYS_START_PAGER, SYS_STOP_PAGER, SYS_SHA256, SYS_WAIT, SYS_GETLINE,
|
||||
SYS_PARSE, ARANGO_QUIET, MODULES_PATH, COLOR_OUTPUT, COLOR_OUTPUT_RESET, COLOR_BRIGHT,
|
||||
COLOR_BLACK, COLOR_BOLD_BLACK, COLOR_BLINK, COLOR_BLUE, COLOR_BOLD_BLUE, COLOR_BOLD_GREEN,
|
||||
COLOR_RED, COLOR_BOLD_RED, COLOR_GREEN, COLOR_WHITE, COLOR_BOLD_WHITE, COLOR_YELLOW,
|
||||
COLOR_BOLD_YELLOW, PRETTY_PRINT */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief module "internal"
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2010-2013 triagens GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Dr. Frank Celler
|
||||
/// @author Copyright 2010-2013, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- Module "internal"
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup V8ModuleInternal
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief internal module
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
(function () {
|
||||
var internal = Module.prototype.ModuleCache["/internal"].exports;
|
||||
|
||||
// system functions
|
||||
if (typeof SYS_EXECUTE !== "undefined") {
|
||||
internal.execute = SYS_EXECUTE;
|
||||
delete SYS_EXECUTE;
|
||||
}
|
||||
|
||||
if (typeof SYS_GETLINE !== "undefined") {
|
||||
internal.getline = SYS_GETLINE;
|
||||
delete SYS_GETLINE;
|
||||
}
|
||||
|
||||
if (typeof SYS_LOAD !== "undefined") {
|
||||
internal.load = SYS_LOAD;
|
||||
delete SYS_LOAD;
|
||||
}
|
||||
|
||||
if (typeof SYS_LOG !== "undefined") {
|
||||
internal.log = SYS_LOG;
|
||||
delete SYS_LOG;
|
||||
}
|
||||
|
||||
if (typeof SYS_LOG_LEVEL !== "undefined") {
|
||||
internal.logLevel = SYS_LOG_LEVEL;
|
||||
delete SYS_LOG_LEVEL;
|
||||
}
|
||||
|
||||
if (typeof SYS_OUTPUT !== "undefined") {
|
||||
internal.output = SYS_OUTPUT;
|
||||
delete SYS_OUTPUT;
|
||||
}
|
||||
|
||||
if (typeof SYS_PARSE !== "undefined") {
|
||||
internal.parse= SYS_PARSE;
|
||||
delete SYS_PARSE;
|
||||
}
|
||||
|
||||
if (typeof SYS_PROCESS_STAT !== "undefined") {
|
||||
internal.processStat = SYS_PROCESS_STAT;
|
||||
delete SYS_PROCESS_STAT;
|
||||
}
|
||||
|
||||
if (typeof SYS_READ !== "undefined") {
|
||||
internal.read = SYS_READ;
|
||||
delete SYS_READ;
|
||||
}
|
||||
|
||||
if (typeof SYS_SHA256 !== "undefined") {
|
||||
internal.sha256 = SYS_SHA256;
|
||||
delete SYS_SHA256;
|
||||
}
|
||||
|
||||
if (typeof SYS_SPRINTF !== "undefined") {
|
||||
internal.sprintf = SYS_SPRINTF;
|
||||
delete SYS_SPRINTF;
|
||||
}
|
||||
|
||||
if (typeof SYS_TIME !== "undefined") {
|
||||
internal.time = SYS_TIME;
|
||||
delete SYS_TIME;
|
||||
}
|
||||
|
||||
if (typeof SYS_WAIT !== "undefined") {
|
||||
internal.wait = SYS_WAIT;
|
||||
delete SYS_WAIT;
|
||||
}
|
||||
|
||||
if (typeof FS_EXISTS !== "undefined") {
|
||||
internal.exists = FS_EXISTS;
|
||||
delete FS_EXISTS;
|
||||
}
|
||||
|
||||
if (typeof FS_IS_DIRECTORY !== "undefined") {
|
||||
internal.isDirectory = FS_IS_DIRECTORY;
|
||||
delete FS_IS_DIRECTORY;
|
||||
}
|
||||
|
||||
if (typeof FS_LIST_TREE !== "undefined") {
|
||||
internal.listTree = FS_LIST_TREE;
|
||||
delete FS_LIST_TREE;
|
||||
}
|
||||
|
||||
if (typeof FS_MOVE !== "undefined") {
|
||||
internal.move = FS_MOVE;
|
||||
delete FS_MOVE;
|
||||
}
|
||||
|
||||
if (typeof FS_REMOVE !== "undefined") {
|
||||
internal.remove = FS_REMOVE;
|
||||
delete FS_REMOVE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public constants
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup V8ModuleInternal
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief modules path
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.MODULES_PATH = "";
|
||||
|
||||
if (typeof MODULES_PATH !== "undefined") {
|
||||
internal.MODULES_PATH = MODULES_PATH;
|
||||
delete MODULES_PATH;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief quiet flag
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.ARANGO_QUIET = false;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief pretty print flag
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.PRETTY_PRINT = false;
|
||||
|
||||
if (typeof PRETTY_PRINT !== "undefined") {
|
||||
internal.PRETTY_PRINT = PRETTY_PRINT;
|
||||
delete PRETTY_PRINT;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief color constants
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.COLOR_OUTPUT = false;
|
||||
internal.COLOR_OUTPUT_DEFAULT = "";
|
||||
internal.COLOR_OUTPUT_RESET = "";
|
||||
internal.COLOR_BRIGHT = "";
|
||||
|
||||
if (typeof COLOR_OUTPUT !== "undefined") {
|
||||
internal.COLOR_OUTPUT = COLOR_OUTPUT;
|
||||
delete COLOR_OUTPUT;
|
||||
}
|
||||
|
||||
if (typeof COLOR_OUTPUT_RESET !== "undefined") {
|
||||
internal.COLOR_OUTPUT_RESET = COLOR_OUTPUT_RESET;
|
||||
delete COLOR_OUTPUT_RESET;
|
||||
}
|
||||
|
||||
if (typeof COLOR_BRIGHT !== "undefined") {
|
||||
internal.COLOR_BRIGHT = COLOR_BRIGHT;
|
||||
delete COLOR_BRIGHT;
|
||||
}
|
||||
|
||||
if (internal.COLOR_OUTPUT) {
|
||||
internal.COLOR_OUTPUT_DEFAULT = internal.COLOR_BRIGHT;
|
||||
|
||||
internal.COLOR_BLACK = COLOR_BLACK;
|
||||
delete COLOR_BLACK;
|
||||
|
||||
internal.COLOR_BOLD_BLACK = COLOR_BOLD_BLACK;
|
||||
delete COLOR_BOLD_BLACK;
|
||||
|
||||
internal.COLOR_BLINK = COLOR_BLINK;
|
||||
delete COLOR_BLINK;
|
||||
|
||||
internal.COLOR_BLUE = COLOR_BLUE;
|
||||
delete COLOR_BLUE;
|
||||
|
||||
internal.COLOR_BOLD_BLUE = COLOR_BOLD_BLUE;
|
||||
delete COLOR_BOLD_BLUE;
|
||||
|
||||
internal.COLOR_GREEN = COLOR_GREEN;
|
||||
delete COLOR_GREEN;
|
||||
|
||||
internal.COLOR_BOLD_GREEN = COLOR_BOLD_GREEN;
|
||||
delete COLOR_BOLD_GREEN;
|
||||
|
||||
internal.COLOR_RED = COLOR_RED;
|
||||
delete COLOR_RED;
|
||||
|
||||
internal.COLOR_BOLD_RED = COLOR_BOLD_RED;
|
||||
delete COLOR_BOLD_RED;
|
||||
|
||||
internal.COLOR_WHITE = COLOR_WHITE;
|
||||
delete COLOR_WHITE;
|
||||
|
||||
internal.COLOR_BOLD_WHITE = COLOR_BOLD_WHITE;
|
||||
delete COLOR_BOLD_WHITE;
|
||||
|
||||
internal.COLOR_YELLOW = COLOR_YELLOW;
|
||||
delete COLOR_YELLOW;
|
||||
|
||||
internal.COLOR_BOLD_YELLOW = COLOR_BOLD_YELLOW;
|
||||
delete COLOR_BOLD_YELLOW;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup V8ModuleInternal
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief prints objects to standard output
|
||||
///
|
||||
/// @FUN{internal.printShell(@FA{arg1}, @FA{arg2}, @FA{arg3}, ...)}
|
||||
///
|
||||
/// Only available in shell mode.
|
||||
///
|
||||
/// Prints the arguments. If an argument is an object having a
|
||||
/// function @FN{_PRINT}, then this function is called. Otherwise @FN{toJson} is
|
||||
/// used. A final newline is printed
|
||||
///
|
||||
/// @verbinclude fluent40
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.printShell = function () {
|
||||
var i;
|
||||
|
||||
for (i = 0; i < arguments.length; ++i) {
|
||||
if (0 < i) {
|
||||
internal.output(" ");
|
||||
}
|
||||
|
||||
if (typeof(arguments[i]) === "string") {
|
||||
internal.output(arguments[i]);
|
||||
}
|
||||
else {
|
||||
internal.printRecursive(arguments[i], [], "~", [], 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (internal.COLOR_OUTPUT) {
|
||||
internal.output(internal.COLOR_OUTPUT_DEFAULT);
|
||||
internal.output(internal.COLOR_OUTPUT_RESET);
|
||||
}
|
||||
|
||||
internal.output("\n");
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief quote cache
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.characterQuoteCache = {
|
||||
'\b': '\\b', // ASCII 8, Backspace
|
||||
'\t': '\\t', // ASCII 9, Tab
|
||||
'\n': '\\n', // ASCII 10, Newline
|
||||
'\f': '\\f', // ASCII 12, Formfeed
|
||||
'\r': '\\r', // ASCII 13, Carriage Return
|
||||
'\"': '\\"',
|
||||
'\\': '\\\\'
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief quotes a single character
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.quoteSingleJsonCharacter = function (c) {
|
||||
if (internal.characterQuoteCache.hasOwnProperty[c]) {
|
||||
return internal.characterQuoteCache[c];
|
||||
}
|
||||
|
||||
var charCode = c.charCodeAt(0);
|
||||
var result;
|
||||
|
||||
if (charCode < 16) {
|
||||
result = '\\u000';
|
||||
}
|
||||
else if (charCode < 256) {
|
||||
result = '\\u00';
|
||||
}
|
||||
else if (charCode < 4096) {
|
||||
result = '\\u0';
|
||||
}
|
||||
else {
|
||||
result = '\\u';
|
||||
}
|
||||
|
||||
result += charCode.toString(16);
|
||||
internal.characterQuoteCache[c] = result;
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief quotes a string character
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.quoteJsonString = function (str) {
|
||||
var quotable = /[\\\"\x00-\x1f]/g;
|
||||
return '"' + str.replace(quotable, internal.quoteSingleJsonCharacter) + '"';
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief prints objects to standard output without a new-line
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.printRecursive = function (value, seen, path, names, level) {
|
||||
var p;
|
||||
|
||||
if (seen === undefined) {
|
||||
seen = [];
|
||||
names = [];
|
||||
}
|
||||
|
||||
p = seen.indexOf(value);
|
||||
|
||||
if (0 <= p) {
|
||||
internal.output(names[p]);
|
||||
}
|
||||
else {
|
||||
if (value instanceof Object) {
|
||||
seen.push(value);
|
||||
names.push(path);
|
||||
}
|
||||
|
||||
if (value instanceof Object) {
|
||||
if (typeof value._PRINT === "function") {
|
||||
value._PRINT(seen, path, names, level);
|
||||
}
|
||||
else if (value instanceof Array) {
|
||||
internal.printArray(value, seen, path, names, level);
|
||||
}
|
||||
else if (value.__proto__ === Object.prototype) {
|
||||
internal.printObject(value, seen, path, names, level);
|
||||
}
|
||||
else if (typeof value.toString === "function") {
|
||||
internal.output(value.toString());
|
||||
}
|
||||
else {
|
||||
internal.printObject(value, seen, path, names, level);
|
||||
}
|
||||
}
|
||||
else if (value === undefined) {
|
||||
internal.output("undefined");
|
||||
}
|
||||
else {
|
||||
if (typeof(value) === "string") {
|
||||
internal.output(internal.quoteJsonString(value));
|
||||
}
|
||||
else {
|
||||
internal.output(String(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief JSON representation of an array
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.printArray = function (object, seen, path, names, level) {
|
||||
if (object.length === 0) {
|
||||
internal.output("[ ]");
|
||||
}
|
||||
else {
|
||||
var i;
|
||||
var sep = "";
|
||||
|
||||
internal.output("[");
|
||||
|
||||
var newLevel = level + 1;
|
||||
|
||||
for (i = 0; i < object.length; i++) {
|
||||
internal.output(sep);
|
||||
|
||||
internal.printIndent(newLevel);
|
||||
|
||||
internal.printRecursive(object[i],
|
||||
seen,
|
||||
path + "[" + i + "]",
|
||||
names,
|
||||
newLevel);
|
||||
sep = ", ";
|
||||
}
|
||||
|
||||
if (object.length > 1) {
|
||||
internal.output(" ");
|
||||
}
|
||||
|
||||
internal.printIndent(level);
|
||||
|
||||
internal.output("]");
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief prints an object
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.printObject = function (object, seen, path, names, level) {
|
||||
var sep = " ";
|
||||
var k;
|
||||
|
||||
internal.output("{");
|
||||
|
||||
var newLevel = level + 1;
|
||||
|
||||
for (k in object) {
|
||||
if (object.hasOwnProperty(k)) {
|
||||
var val = object[k];
|
||||
|
||||
internal.output(sep);
|
||||
|
||||
internal.printIndent(newLevel);
|
||||
|
||||
if (internal.COLOR_OUTPUT) {
|
||||
internal.output(internal.COLOR_OUTPUT_DEFAULT);
|
||||
internal.output(internal.quoteJsonString(k));
|
||||
internal.output(internal.COLOR_OUTPUT_RESET);
|
||||
internal.output(" : ");
|
||||
}
|
||||
else {
|
||||
internal.output(internal.quoteJsonString(k), " : ");
|
||||
}
|
||||
|
||||
internal.printRecursive(val,
|
||||
seen,
|
||||
path + "[" + k + "]",
|
||||
names,
|
||||
newLevel);
|
||||
sep = ", ";
|
||||
}
|
||||
}
|
||||
|
||||
if (sep === ", ") {
|
||||
internal.output(" ");
|
||||
}
|
||||
|
||||
internal.printIndent(level);
|
||||
|
||||
internal.output("}");
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief prints the ident for pretty printing
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.printIndent = function (level) {
|
||||
var j;
|
||||
|
||||
if (internal.PRETTY_PRINT) {
|
||||
internal.output("\n");
|
||||
|
||||
for (j = 0; j < level; ++j) {
|
||||
internal.output(" ");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief flushes the module cache
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.flushModuleCache = function() {
|
||||
module.unloadAll();
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public methods
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup V8ModuleInternal
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief global print
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.print = internal.printShell;
|
||||
|
||||
if (typeof internal.printBrowser === "function") {
|
||||
internal.print = internal.printBrowser;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief start pager
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.start_pager = function () {};
|
||||
|
||||
if (typeof SYS_START_PAGER !== "undefined") {
|
||||
internal.start_pager = SYS_START_PAGER;
|
||||
delete SYS_START_PAGER;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief stop pager
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.stop_pager = function () {};
|
||||
|
||||
if (typeof SYS_STOP_PAGER !== "undefined") {
|
||||
internal.stop_pager = SYS_STOP_PAGER;
|
||||
delete SYS_STOP_PAGER;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief encode password using SHA256
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.encodePassword = function (password) {
|
||||
var salt;
|
||||
var encoded;
|
||||
|
||||
salt = internal.sha256("time:" + internal.time());
|
||||
salt = salt.substr(0,8);
|
||||
|
||||
encoded = "$1$" + salt + "$" + internal.sha256(salt + password);
|
||||
|
||||
return encoded;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief extends a prototype
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.extend = function (target, source) {
|
||||
Object.getOwnPropertyNames(source)
|
||||
.forEach(function(propName) {
|
||||
Object.defineProperty(target, propName,
|
||||
Object.getOwnPropertyDescriptor(source, propName));
|
||||
});
|
||||
|
||||
return target;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief reads a file from the module path or the database
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.loadDatabaseFile = function (path) {
|
||||
var i;
|
||||
var mc;
|
||||
var n;
|
||||
|
||||
// try to load the file
|
||||
var paths = internal.MODULES_PATH;
|
||||
|
||||
for (i = 0; i < paths.length; ++i) {
|
||||
var p = paths[i];
|
||||
|
||||
if (p === "") {
|
||||
n = "." + path + ".js";
|
||||
}
|
||||
else {
|
||||
n = p + "/" + path + ".js";
|
||||
}
|
||||
|
||||
if (internal.exists(n)) {
|
||||
Module.prototype.ModuleExistsCache[path] = true;
|
||||
return { path : n, content : internal.read(n) };
|
||||
}
|
||||
}
|
||||
|
||||
// try to load the module from the database
|
||||
if (internal.db !== undefined) {
|
||||
mc = internal.db._collection("_modules");
|
||||
|
||||
if (mc !== null && typeof mc.firstExample === "function") {
|
||||
n = mc.firstExample({ path: path });
|
||||
|
||||
if (n !== null) {
|
||||
if (n.hasOwnProperty('content')) {
|
||||
Module.prototype.ModuleExistsCache[path] = true;
|
||||
return { path : "_collection/" + path, content : n.content };
|
||||
}
|
||||
|
||||
if (Module.prototype.ModuleExistsCache.hasOwnProperty("/console")) {
|
||||
var console = Module.prototype.ModuleExistsCache["/console"];
|
||||
console.error("found empty content in '%s'", JSON.stringify(n));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Module.prototype.ModuleExistsCache[path] = false;
|
||||
|
||||
throw "cannot find a file named '"
|
||||
+ path
|
||||
+ "' using the module path(s) '"
|
||||
+ internal.MODULES_PATH + "'";
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief loads a file from the file-system
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.loadFile = function (path) {
|
||||
var i;
|
||||
|
||||
// try to load the file
|
||||
var paths = internal.MODULES_PATH;
|
||||
|
||||
for (i = 0; i < paths.length; ++i) {
|
||||
var p = paths[i];
|
||||
var n;
|
||||
|
||||
if (p === "") {
|
||||
n = "." + path + ".js";
|
||||
}
|
||||
else {
|
||||
n = p + "/" + path + ".js";
|
||||
}
|
||||
|
||||
if (internal.exists(n)) {
|
||||
return internal.load(n);
|
||||
}
|
||||
}
|
||||
|
||||
throw "cannot find a file named '"
|
||||
+ path
|
||||
+ "' using the module path(s) '"
|
||||
+ internal.MODULES_PATH + "'";
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief defines a module
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.defineModule = function (path, file) {
|
||||
var content;
|
||||
var m;
|
||||
var mc;
|
||||
|
||||
content = internal.read(file);
|
||||
|
||||
mc = internal.db._collection("_modules");
|
||||
|
||||
if (mc === null) {
|
||||
mc = internal.db._create("_modules", { isSystem: true });
|
||||
}
|
||||
|
||||
path = module.normalise(path);
|
||||
m = mc.firstExample({ path: path });
|
||||
|
||||
if (m === null) {
|
||||
mc.save({ path: path, content: content });
|
||||
}
|
||||
else {
|
||||
mc.replace(m, { path: path, content: content });
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}());
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @}\\)"
|
||||
// End:
|
|
@ -1,17 +1,5 @@
|
|||
/*jslint indent: 2,
|
||||
nomen: true,
|
||||
maxlen: 100,
|
||||
sloppy: true,
|
||||
vars: true,
|
||||
white: true,
|
||||
plusplus: true */
|
||||
/*global
|
||||
require, module,
|
||||
SYS_EXECUTE, CONSOLE_ERROR, FS_MOVE, FS_REMOVE, FS_EXISTS, SYS_LOAD, SYS_LOG,
|
||||
SYS_LOG_LEVEL, SYS_OUTPUT, SYS_PROCESS_STAT, SYS_READ, SYS_SPRINTF, SYS_TIME,
|
||||
SYS_START_PAGER, SYS_STOP_PAGER, ARANGO_QUIET, MODULES_PATH, COLOR_OUTPUT,
|
||||
COLOR_OUTPUT_RESET, COLOR_BRIGHT, PRETTY_PRINT, SYS_SHA256, SYS_WAIT, SYS_GETLINE
|
||||
*/
|
||||
/*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true, vars: true, white: true, plusplus: true */
|
||||
/*global require, module: true */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief JavaScript server functions
|
||||
|
@ -63,6 +51,9 @@ function Module (id) {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Module.prototype.ModuleCache = {};
|
||||
Module.prototype.ModuleCache["/internal"] = new Module("/internal");
|
||||
Module.prototype.ModuleCache["/fs"] = new Module("/fs");
|
||||
Module.prototype.ModuleCache["/console"] = new Module("/console");
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief file exists cache
|
||||
|
@ -75,6 +66,7 @@ Module.prototype.ModuleExistsCache = {};
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Module.prototype.require = function (path) {
|
||||
var internal;
|
||||
var content;
|
||||
var f;
|
||||
var module;
|
||||
|
@ -82,6 +74,8 @@ Module.prototype.require = function (path) {
|
|||
var raw;
|
||||
var sandbox;
|
||||
|
||||
internal = this.ModuleCache["/internal"].exports;
|
||||
|
||||
// first get rid of any ".." and "."
|
||||
path = this.normalise(path);
|
||||
|
||||
|
@ -91,10 +85,10 @@ Module.prototype.require = function (path) {
|
|||
}
|
||||
|
||||
// locate file and read content
|
||||
raw = this.ModuleCache["/internal"].exports.readFile(path);
|
||||
raw = internal.loadDatabaseFile(path);
|
||||
|
||||
// test for parse errors first and fail early if a parse error detected
|
||||
if (! SYS_PARSE(raw.content, path)) {
|
||||
if (! internal.parse(raw.content, path)) {
|
||||
throw "Javascript parse error in file '" + path + "'";
|
||||
}
|
||||
|
||||
|
@ -105,7 +99,7 @@ Module.prototype.require = function (path) {
|
|||
+ raw.content
|
||||
+ "\n});";
|
||||
|
||||
f = SYS_EXECUTE(content, undefined, path);
|
||||
f = internal.execute(content, undefined, path);
|
||||
|
||||
if (f === undefined) {
|
||||
throw "cannot create context function";
|
||||
|
@ -118,6 +112,7 @@ Module.prototype.require = function (path) {
|
|||
this.ModuleCache["/internal"].exports.print);
|
||||
}
|
||||
catch (err) {
|
||||
delete this.ModuleCache[path];
|
||||
throw "Javascript exception in file '" + path + "': " + err.stack;
|
||||
}
|
||||
|
||||
|
@ -129,8 +124,8 @@ Module.prototype.require = function (path) {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Module.prototype.exists = function (path) {
|
||||
return this.ModuleExistsCache[path];
|
||||
}
|
||||
return Module.prototype.ModuleExistsCache[path];
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief normalises a path
|
||||
|
@ -194,12 +189,16 @@ Module.prototype.unload = function (path) {
|
|||
var norm = module.normalise(path);
|
||||
|
||||
if ( norm === "/"
|
||||
|| norm === "/internal"
|
||||
|| norm === "/console"
|
||||
|| norm === "/fs") {
|
||||
|| norm === "/internal"
|
||||
|| norm === "/fs"
|
||||
|| norm === "/org/arangodb"
|
||||
|| norm === "/org/arangodb/actions") {
|
||||
return;
|
||||
}
|
||||
|
||||
Module.prototype.ModuleCache["/console"].exports.info("UNLOADING %s", path);
|
||||
|
||||
delete this.ModuleCache[norm];
|
||||
};
|
||||
|
||||
|
@ -251,428 +250,19 @@ function require (path) {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
/// @brief global print function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- Module "fs"
|
||||
// -----------------------------------------------------------------------------
|
||||
function print () {
|
||||
var internal = require("internal");
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup V8ModuleFS
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief file-system module
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Module.prototype.ModuleCache["/fs"] = new Module("/fs");
|
||||
|
||||
(function () {
|
||||
var fs = Module.prototype.ModuleCache["/fs"].exports;
|
||||
|
||||
fs.exists = FS_EXISTS;
|
||||
fs.move = FS_MOVE;
|
||||
fs.remove = FS_REMOVE;
|
||||
}());
|
||||
internal.print.apply(internal.print, arguments);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- Module "internal"
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup V8ModuleInternal
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief internal module
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Module.prototype.ModuleCache["/internal"] = new Module("/internal");
|
||||
|
||||
(function () {
|
||||
var internal = Module.prototype.ModuleCache["/internal"].exports;
|
||||
var fs = Module.prototype.ModuleCache["/fs"].exports;
|
||||
|
||||
// system functions
|
||||
internal.execute = SYS_EXECUTE;
|
||||
internal.load = SYS_LOAD;
|
||||
internal.log = SYS_LOG;
|
||||
internal.logLevel = SYS_LOG_LEVEL;
|
||||
internal.output = SYS_OUTPUT;
|
||||
internal.processStat = SYS_PROCESS_STAT;
|
||||
internal.read = SYS_READ;
|
||||
internal.sprintf = SYS_SPRINTF;
|
||||
internal.time = SYS_TIME;
|
||||
internal.sha256 = SYS_SHA256;
|
||||
internal.wait = SYS_WAIT;
|
||||
|
||||
// password interface
|
||||
internal.encodePassword = function (password) {
|
||||
var salt;
|
||||
var encoded;
|
||||
|
||||
salt = internal.sha256("time:" + SYS_TIME());
|
||||
salt = salt.substr(0,8);
|
||||
|
||||
encoded = "$1$" + salt + "$" + internal.sha256(salt + password);
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// command line parameter
|
||||
internal.MODULES_PATH = "";
|
||||
|
||||
if (typeof MODULES_PATH !== "undefined") {
|
||||
internal.MODULES_PATH = MODULES_PATH;
|
||||
}
|
||||
|
||||
|
||||
// output
|
||||
internal.start_pager = function () {};
|
||||
internal.stop_pager = function () {};
|
||||
|
||||
internal.ARANGO_QUIET = false;
|
||||
|
||||
internal.COLOR_OUTPUT = false;
|
||||
internal.COLOR_OUTPUT_DEFAULT = "";
|
||||
internal.COLOR_OUTPUT_RESET = "";
|
||||
internal.COLOR_BRIGHT = "";
|
||||
|
||||
internal.PRETTY_PRINT = false;
|
||||
|
||||
if (typeof SYS_START_PAGER !== "undefined") {
|
||||
internal.start_pager = SYS_START_PAGER;
|
||||
}
|
||||
|
||||
if (typeof SYS_STOP_PAGER !== "undefined") {
|
||||
internal.stop_pager = SYS_STOP_PAGER;
|
||||
}
|
||||
|
||||
if (typeof COLOR_OUTPUT !== "undefined") {
|
||||
internal.COLOR_OUTPUT = COLOR_OUTPUT;
|
||||
}
|
||||
|
||||
if (typeof COLOR_OUTPUT_RESET !== "undefined") {
|
||||
internal.COLOR_OUTPUT_RESET = COLOR_OUTPUT_RESET;
|
||||
}
|
||||
|
||||
if (typeof COLOR_BRIGHT !== "undefined") {
|
||||
internal.COLOR_BRIGHT = COLOR_BRIGHT;
|
||||
}
|
||||
|
||||
if (typeof PRETTY_PRINT !== "undefined") {
|
||||
internal.PRETTY_PRINT = PRETTY_PRINT;
|
||||
}
|
||||
|
||||
if (internal.COLOR_OUTPUT) {
|
||||
internal.COLOR_OUTPUT_DEFAULT = internal.COLOR_BRIGHT;
|
||||
|
||||
internal.COLOR_BLACK = COLOR_BLACK;
|
||||
internal.COLOR_BOLD_BLACK = COLOR_BOLD_BLACK;
|
||||
internal.COLOR_BLINK = COLOR_BLINK;
|
||||
internal.COLOR_BLUE = COLOR_BLUE;
|
||||
internal.COLOR_BOLD_BLUE = COLOR_BOLD_BLUE;
|
||||
internal.COLOR_BRIGHT = COLOR_BRIGHT;
|
||||
internal.COLOR_GREEN = COLOR_GREEN;
|
||||
internal.COLOR_BOLD_GREEN = COLOR_BOLD_GREEN;
|
||||
internal.COLOR_RED = COLOR_RED;
|
||||
internal.COLOR_BOLD_RED = COLOR_BOLD_RED;
|
||||
internal.COLOR_WHITE = COLOR_WHITE;
|
||||
internal.COLOR_BOLD_WHITE = COLOR_BOLD_WHITE;
|
||||
internal.COLOR_YELLOW = COLOR_YELLOW;
|
||||
internal.COLOR_BOLD_YELLOW = COLOR_BOLD_YELLOW;
|
||||
internal.COLOR_OUTPUT_RESET = COLOR_OUTPUT_RESET;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief extends a prototype
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.extend = function (target, source) {
|
||||
Object.getOwnPropertyNames(source)
|
||||
.forEach(function(propName) {
|
||||
Object.defineProperty(target, propName,
|
||||
Object.getOwnPropertyDescriptor(source, propName));
|
||||
});
|
||||
|
||||
return target;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief reads a file from the module path or the database
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.readFile = function (path) {
|
||||
var i;
|
||||
var mc;
|
||||
var n;
|
||||
|
||||
// try to load the file
|
||||
var paths = internal.MODULES_PATH;
|
||||
|
||||
for (i = 0; i < paths.length; ++i) {
|
||||
var p = paths[i];
|
||||
|
||||
if (p === "") {
|
||||
n = "." + path + ".js";
|
||||
}
|
||||
else {
|
||||
n = p + "/" + path + ".js";
|
||||
}
|
||||
|
||||
if (fs.exists(n)) {
|
||||
Module.prototype.ModuleExistsCache[path] = true;
|
||||
return { path : n, content : internal.read(n) };
|
||||
}
|
||||
}
|
||||
|
||||
// try to load the module from the database
|
||||
if (internal.db !== undefined) {
|
||||
mc = internal.db._collection("_modules");
|
||||
|
||||
if (mc !== null && ("firstExample" in mc)) {
|
||||
n = mc.firstExample({ path: path });
|
||||
|
||||
if (n !== null) {
|
||||
if (n.hasOwnProperty('content')) {
|
||||
Module.prototype.ModuleExistsCache[path] = true;
|
||||
return { path : "_collection/" + path, content : n.content };
|
||||
}
|
||||
else {
|
||||
require("console").error("found empty content in '%s'", JSON.stringify(n));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Module.prototype.ModuleExistsCache[path] = false;
|
||||
|
||||
throw "cannot find a file named '"
|
||||
+ path
|
||||
+ "' using the module path(s) '"
|
||||
+ internal.MODULES_PATH + "'";
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief loads a file from the file-system
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.loadFile = function (path) {
|
||||
var i;
|
||||
|
||||
// try to load the file
|
||||
var paths = internal.MODULES_PATH;
|
||||
|
||||
for (i = 0; i < paths.length; ++i) {
|
||||
var p = paths[i];
|
||||
var n;
|
||||
|
||||
if (p === "") {
|
||||
n = "." + path + ".js";
|
||||
}
|
||||
else {
|
||||
n = p + "/" + path + ".js";
|
||||
}
|
||||
|
||||
if (fs.exists(n)) {
|
||||
return internal.load(n);
|
||||
}
|
||||
}
|
||||
|
||||
throw "cannot find a file named '"
|
||||
+ path
|
||||
+ "' using the module path(s) '"
|
||||
+ internal.MODULES_PATH + "'";
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief defines a module
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.defineModule = function (path, file) {
|
||||
var content;
|
||||
var m;
|
||||
var mc;
|
||||
|
||||
content = internal.read(file);
|
||||
|
||||
mc = internal.db._collection("_modules");
|
||||
|
||||
if (mc === null) {
|
||||
mc = internal.db._create("_modules", { isSystem: true });
|
||||
}
|
||||
|
||||
path = module.normalise(path);
|
||||
m = mc.firstExample({ path: path });
|
||||
|
||||
if (m === null) {
|
||||
mc.save({ path: path, module: content });
|
||||
}
|
||||
else {
|
||||
m.module = content;
|
||||
mc.replace(m, m);
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}());
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- Module "console"
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup V8ModuleConsole
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief console module
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Module.prototype.ModuleCache["/console"] = new Module("/console");
|
||||
|
||||
(function () {
|
||||
var internal = Module.prototype.ModuleCache["/internal"].exports;
|
||||
var console = Module.prototype.ModuleCache["/console"].exports;
|
||||
|
||||
console.getline = SYS_GETLINE;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief logs debug message
|
||||
///
|
||||
/// @FUN{console.debug(@FA{format}, @FA{argument1}, ...)}
|
||||
///
|
||||
/// Formats the arguments according to @FA{format} and logs the result as
|
||||
/// debug message.
|
||||
///
|
||||
/// String substitution patterns, which can be used in @FA{format}.
|
||||
///
|
||||
/// - @LIT{\%s} string
|
||||
/// - @LIT{\%d}, @LIT{\%i} integer
|
||||
/// - @LIT{\%f} floating point number
|
||||
/// - @LIT{\%o} object hyperlink
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
console.debug = function () {
|
||||
var msg;
|
||||
|
||||
try {
|
||||
msg = internal.sprintf.apply(internal.sprintf, arguments);
|
||||
}
|
||||
catch (err) {
|
||||
msg = err + ": " + arguments;
|
||||
}
|
||||
|
||||
internal.log("debug", msg);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief logs error message
|
||||
///
|
||||
/// @FUN{console.error(@FA{format}, @FA{argument1}, ...)}
|
||||
///
|
||||
/// Formats the arguments according to @FA{format} and logs the result as
|
||||
/// error message.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
console.error = function () {
|
||||
var msg;
|
||||
|
||||
try {
|
||||
msg = internal.sprintf.apply(internal.sprintf, arguments);
|
||||
}
|
||||
catch (err) {
|
||||
msg = err + ": " + arguments;
|
||||
}
|
||||
|
||||
internal.log("error", msg);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief logs info message
|
||||
///
|
||||
/// @FUN{console.info(@FA{format}, @FA{argument1}, ...)}
|
||||
///
|
||||
/// Formats the arguments according to @FA{format} and logs the result as
|
||||
/// info message.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
console.info = function () {
|
||||
var msg;
|
||||
|
||||
try {
|
||||
msg = internal.sprintf.apply(internal.sprintf, arguments);
|
||||
}
|
||||
catch (err) {
|
||||
msg = err + ": " + arguments;
|
||||
}
|
||||
|
||||
internal.log("info", msg);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief logs log message
|
||||
///
|
||||
/// @FUN{console.log(@FA{format}, @FA{argument1}, ...)}
|
||||
///
|
||||
/// Formats the arguments according to @FA{format} and logs the result as
|
||||
/// log message.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
console.log = function () {
|
||||
var msg;
|
||||
|
||||
try {
|
||||
msg = internal.sprintf.apply(internal.sprintf, arguments);
|
||||
}
|
||||
catch (err) {
|
||||
msg = err + ": " + arguments;
|
||||
}
|
||||
|
||||
internal.log("info", msg);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief logs warn message
|
||||
///
|
||||
/// @FUN{console.warn(@FA{format}, @FA{argument1}, ...)}
|
||||
///
|
||||
/// Formats the arguments according to @FA{format} and logs the result as
|
||||
/// warn message.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
console.warn = function () {
|
||||
var msg;
|
||||
|
||||
try {
|
||||
msg = internal.sprintf.apply(internal.sprintf, arguments);
|
||||
}
|
||||
catch (err) {
|
||||
msg = err + ": " + arguments;
|
||||
}
|
||||
|
||||
internal.log("warn", msg);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}());
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
/*jslint indent: 2,
|
||||
nomen: true,
|
||||
maxlen: 100,
|
||||
sloppy: true,
|
||||
plusplus: true */
|
||||
/*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true, plusplus: true */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Monkeypatches to built-in prototypes
|
||||
|
@ -27,10 +23,20 @@
|
|||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Dr. Frank Celler, Lucas Dohmen
|
||||
/// @author Dr. Frank Celler
|
||||
/// @author Lucas Dohmen
|
||||
/// @author Copyright 2011-2012, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- monkey-patches
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup V8Shell
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief remove last occurrence of element from an array
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -90,4 +96,17 @@ Object.defineProperty(Object.prototype, "propertyKeys", {
|
|||
return (element[0] !== '_' && element[0] !== '$');
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @}\\)"
|
||||
// End:
|
||||
|
|
|
@ -1,338 +0,0 @@
|
|||
/*jslint indent: 2,
|
||||
nomen: true,
|
||||
maxlen: 100,
|
||||
sloppy: true,
|
||||
vars: true,
|
||||
white: true,
|
||||
plusplus: true */
|
||||
/*global require, print */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief printing
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2010-2012 triagens GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Dr. Frank Celler
|
||||
/// @author Copyright 2011-2012, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
(function () {
|
||||
var internal = require("internal");
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- Module "internal"
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup V8Shell
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief prints objects to standard output
|
||||
///
|
||||
/// @FUN{internal.printShell(@FA{arg1}, @FA{arg2}, @FA{arg3}, ...)}
|
||||
///
|
||||
/// Only available in shell mode.
|
||||
///
|
||||
/// Prints the arguments. If an argument is an object having a
|
||||
/// function @FN{_PRINT}, then this function is called. Otherwise @FN{toJson} is
|
||||
/// used. A final newline is printed
|
||||
///
|
||||
/// @verbinclude fluent40
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.printShell = function () {
|
||||
var i;
|
||||
|
||||
for (i = 0; i < arguments.length; ++i) {
|
||||
if (0 < i) {
|
||||
internal.output(" ");
|
||||
}
|
||||
|
||||
if (typeof(arguments[i]) === "string") {
|
||||
internal.output(arguments[i]);
|
||||
}
|
||||
else {
|
||||
internal.printRecursive(arguments[i], [], "~", [], 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (internal.COLOR_OUTPUT) {
|
||||
internal.output(internal.COLOR_OUTPUT_DEFAULT);
|
||||
internal.output(internal.COLOR_OUTPUT_RESET);
|
||||
}
|
||||
|
||||
internal.output("\n");
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief quote cache
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.characterQuoteCache = {
|
||||
'\b': '\\b', // ASCII 8, Backspace
|
||||
'\t': '\\t', // ASCII 9, Tab
|
||||
'\n': '\\n', // ASCII 10, Newline
|
||||
'\f': '\\f', // ASCII 12, Formfeed
|
||||
'\r': '\\r', // ASCII 13, Carriage Return
|
||||
'\"': '\\"',
|
||||
'\\': '\\\\'
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief quotes a single character
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.quoteSingleJsonCharacter = function (c) {
|
||||
if (internal.characterQuoteCache.hasOwnProperty[c]) {
|
||||
return internal.characterQuoteCache[c];
|
||||
}
|
||||
|
||||
var charCode = c.charCodeAt(0);
|
||||
var result;
|
||||
|
||||
if (charCode < 16) {
|
||||
result = '\\u000';
|
||||
}
|
||||
else if (charCode < 256) {
|
||||
result = '\\u00';
|
||||
}
|
||||
else if (charCode < 4096) {
|
||||
result = '\\u0';
|
||||
}
|
||||
else {
|
||||
result = '\\u';
|
||||
}
|
||||
|
||||
result += charCode.toString(16);
|
||||
internal.characterQuoteCache[c] = result;
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief quotes a string character
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.quoteJsonString = function (str) {
|
||||
var quotable = /[\\\"\x00-\x1f]/g;
|
||||
return '"' + str.replace(quotable, internal.quoteSingleJsonCharacter) + '"';
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief prints objects to standard output without a new-line
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.printRecursive = function (value, seen, path, names, level) {
|
||||
var p;
|
||||
|
||||
if (seen === undefined) {
|
||||
seen = [];
|
||||
names = [];
|
||||
}
|
||||
|
||||
p = seen.indexOf(value);
|
||||
|
||||
if (0 <= p) {
|
||||
internal.output(names[p]);
|
||||
}
|
||||
else {
|
||||
if (value instanceof Object) {
|
||||
seen.push(value);
|
||||
names.push(path);
|
||||
}
|
||||
|
||||
if (value instanceof Object) {
|
||||
if ('_PRINT' in value) {
|
||||
value._PRINT(seen, path, names, level);
|
||||
}
|
||||
else if (value instanceof Array) {
|
||||
internal.printArray(value, seen, path, names, level);
|
||||
}
|
||||
else if (value.__proto__ === Object.prototype) {
|
||||
internal.printObject(value, seen, path, names, level);
|
||||
}
|
||||
else if ('toString' in value) {
|
||||
internal.output(value.toString());
|
||||
}
|
||||
else {
|
||||
internal.printObject(value, seen, path, names, level);
|
||||
}
|
||||
}
|
||||
else if (value === undefined) {
|
||||
internal.output("undefined");
|
||||
}
|
||||
else {
|
||||
if (typeof(value) === "string") {
|
||||
internal.output(internal.quoteJsonString(value));
|
||||
}
|
||||
else {
|
||||
internal.output(String(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief prints the ident for pretty printing
|
||||
///
|
||||
/// @FUN{internal.printIndent(@FA{level})}
|
||||
///
|
||||
/// Only available in shell mode.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.printIndent = function (level) {
|
||||
var j;
|
||||
|
||||
if (internal.PRETTY_PRINT) {
|
||||
internal.output("\n");
|
||||
|
||||
for (j = 0; j < level; ++j) {
|
||||
internal.output(" ");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief JSON representation of an array
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.printArray = function (object, seen, path, names, level) {
|
||||
if (object.length === 0) {
|
||||
internal.output("[ ]");
|
||||
}
|
||||
else {
|
||||
var i;
|
||||
var sep = "";
|
||||
|
||||
internal.output("[");
|
||||
|
||||
var newLevel = level + 1;
|
||||
|
||||
for (i = 0; i < object.length; i++) {
|
||||
internal.output(sep);
|
||||
|
||||
internal.printIndent(newLevel);
|
||||
|
||||
internal.printRecursive(object[i],
|
||||
seen,
|
||||
path + "[" + i + "]",
|
||||
names,
|
||||
newLevel);
|
||||
sep = ", ";
|
||||
}
|
||||
|
||||
if (object.length > 1) {
|
||||
internal.output(" ");
|
||||
}
|
||||
internal.printIndent(level);
|
||||
|
||||
internal.output("]");
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief prints an object
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.printObject = function (object, seen, path, names, level) {
|
||||
var sep = " ";
|
||||
var k;
|
||||
|
||||
internal.output("{");
|
||||
|
||||
var newLevel = level + 1;
|
||||
|
||||
for (k in object) {
|
||||
if (object.hasOwnProperty(k)) {
|
||||
var val = object[k];
|
||||
|
||||
internal.output(sep);
|
||||
|
||||
internal.printIndent(newLevel);
|
||||
|
||||
if (internal.COLOR_OUTPUT) {
|
||||
internal.output(internal.COLOR_OUTPUT_DEFAULT);
|
||||
internal.output(internal.quoteJsonString(k));
|
||||
internal.output(internal.COLOR_OUTPUT_RESET);
|
||||
internal.output(" : ");
|
||||
}
|
||||
else {
|
||||
internal.output(internal.quoteJsonString(k), " : ");
|
||||
}
|
||||
|
||||
internal.printRecursive(val,
|
||||
seen,
|
||||
path + "[" + k + "]",
|
||||
names,
|
||||
newLevel);
|
||||
sep = ", ";
|
||||
}
|
||||
}
|
||||
|
||||
if (sep == ", ") {
|
||||
internal.output(" ");
|
||||
}
|
||||
internal.printIndent(level);
|
||||
|
||||
internal.output("}");
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}());
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- global functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup V8Shell
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief global print
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// must be a variable definition for the browser
|
||||
if (typeof require("internal").printBrowser === "function") {
|
||||
print = require("internal").print = require("internal").printBrowser;
|
||||
}
|
||||
else {
|
||||
print = require("internal").print = require("internal").printShell;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @}\\)"
|
||||
// End:
|
|
@ -47,7 +47,7 @@ function RunTest (path, options) {
|
|||
var content;
|
||||
|
||||
try {
|
||||
content = SYS_READ(path);
|
||||
content = internal.read(path);
|
||||
}
|
||||
catch (err) {
|
||||
console.error("cannot load test file '%s'", path);
|
||||
|
|
|
@ -182,10 +182,12 @@
|
|||
// newcap true, if constructor names capitalization is ignored
|
||||
// node true, if Node.js globals should be predefined
|
||||
// nomen true, if names may have dangling _
|
||||
/// nonpropdel true, if delete should be allowed for non-properties
|
||||
// on true, if HTML event handlers should be allowed
|
||||
// passfail true, if the scan should stop on first error
|
||||
// plusplus true, if increment/decrement should be allowed
|
||||
// properties true, if all property names must be declared with /*properties*/
|
||||
// proto true, if __proto__ is allowed
|
||||
// regexp true, if the . should be allowed in regexp literals
|
||||
// rhino true, if the Rhino environment globals should be predefined
|
||||
// undef true, if variables can be declared out of order
|
||||
|
@ -274,7 +276,7 @@
|
|||
'min-height', 'min-width', missing_a, missing_a_after_b, missing_option,
|
||||
missing_property, missing_space_a_b, missing_url, missing_use_strict, mixed,
|
||||
mm, mode, move_invocation, move_var, n, name, name_function, nav,
|
||||
nested_comment, newcap, node, noframes, nomen, noscript, not,
|
||||
nested_comment, newcap, node, noframes, nomen, nonpropdel, noscript, not,
|
||||
not_a_constructor, not_a_defined, not_a_function, not_a_label, not_a_scope,
|
||||
not_greater, nud, number, object, octal_a, ol, on, opacity, open, optgroup,
|
||||
option, outer, outline, 'outline-color', 'outline-style', 'outline-width',
|
||||
|
@ -283,7 +285,7 @@
|
|||
'page-break-before', param, parameter_a_get_b, parameter_arguments_a,
|
||||
parameter_set_a, params, paren, parent, passfail, pc, plusplus, pop,
|
||||
position, postscript, pre, predef, print, progress, projection, properties,
|
||||
properties_report, property, prototype, pt, push, px, q, quote, quotes, r,
|
||||
properties_report, property, proto, prototype, pt, push, px, q, quote, quotes, r,
|
||||
radix, range, raw, read_only, reason, redefinition_a, regexp, replace,
|
||||
report, reserved, reserved_a, rhino, right, rp, rt, ruby, safe, samp,
|
||||
scanned_a_b, screen, script, search, second, section, select, shift,
|
||||
|
@ -356,10 +358,12 @@ var JSLINT = (function () {
|
|||
newcap : true,
|
||||
node : true,
|
||||
nomen : true,
|
||||
nonpropdel: true,
|
||||
on : true,
|
||||
passfail : true,
|
||||
plusplus : true,
|
||||
properties: true,
|
||||
proto : true,
|
||||
regexp : true,
|
||||
rhino : true,
|
||||
undef : true,
|
||||
|
@ -1218,8 +1222,12 @@ var JSLINT = (function () {
|
|||
)] || syntax['(error)']);
|
||||
if (type === '(identifier)') {
|
||||
the_token.identifier = true;
|
||||
if (value === '__iterator__' || value === '__proto__') {
|
||||
if (value === '__iterator__') {
|
||||
stop_at('reserved_a', line, from, value);
|
||||
} else if (value === '__proto__') {
|
||||
if (!option.proto) {
|
||||
stop_at('reserved_a', line, from, value);
|
||||
}
|
||||
} else if (!option.nomen &&
|
||||
(value.charAt(0) === '_' ||
|
||||
value.charAt(value.length - 1) === '_')) {
|
||||
|
@ -3419,8 +3427,10 @@ klass: do {
|
|||
prefix('delete', function () {
|
||||
one_space();
|
||||
var p = expression(0);
|
||||
if (!p || (p.id !== '.' && p.id !== '[')) {
|
||||
warn('deleted');
|
||||
if (!option.nonpropdel) {
|
||||
if (!p || (p.id !== '.' && p.id !== '[')) {
|
||||
warn('deleted');
|
||||
}
|
||||
}
|
||||
this.first = p;
|
||||
return this;
|
||||
|
|
|
@ -348,10 +348,10 @@ function RunTest (path) {
|
|||
var content;
|
||||
var f;
|
||||
|
||||
content = SYS_READ(path);
|
||||
content = internal.read(path);
|
||||
|
||||
content = "(function(jsUnity){jsUnity.attachAssertions();" + content + "})";
|
||||
f = SYS_EXECUTE(content, undefined, path);
|
||||
f = internal.execute(content, undefined, path);
|
||||
|
||||
if (f == undefined) {
|
||||
throw "cannot create context function";
|
||||
|
|
|
@ -38,7 +38,6 @@
|
|||
var internal = require("internal");
|
||||
var console = require("console");
|
||||
|
||||
var ArangoDatabase = internal.ArangoDatabase;
|
||||
var ArangoCollection = internal.ArangoCollection;
|
||||
var ArangoError = internal.ArangoError;
|
||||
|
||||
|
@ -121,7 +120,7 @@
|
|||
/// in a production environment.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ArangoCollection.prototype.toArray = function() {
|
||||
ArangoCollection.prototype.toArray = function () {
|
||||
return this.ALL(null, null).documents;
|
||||
};
|
||||
|
||||
|
@ -137,10 +136,20 @@
|
|||
///
|
||||
/// Truncates a collection:
|
||||
///
|
||||
/// @verbinclude shell_collection-truncate
|
||||
/// @code
|
||||
/// arango> col = db.examples;
|
||||
/// [ArangoCollection 91022, "examples" (status new born)]
|
||||
/// arango> col.save({ "Hallo" : "World" });
|
||||
/// { "_id" : "91022/1532814", "_rev" : 1532814 }
|
||||
/// arango> col.count();
|
||||
/// 1
|
||||
/// arango> col.truncate();
|
||||
/// arango> col.count();
|
||||
/// 0
|
||||
/// @endcode
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ArangoCollection.prototype.truncate = function() {
|
||||
ArangoCollection.prototype.truncate = function () {
|
||||
return internal.db._truncate(this);
|
||||
};
|
||||
|
||||
|
@ -153,10 +162,15 @@
|
|||
///
|
||||
/// @EXAMPLES
|
||||
///
|
||||
/// @verbinclude shell_index-read
|
||||
/// @code
|
||||
/// arango> db.example.getIndexes().map(function(x) { return x.id; });
|
||||
/// ["93013/0"]
|
||||
/// arango> db.example.index("93013/0");
|
||||
/// { "id" : "93013/0", "type" : "primary", "fields" : ["_id"] }
|
||||
/// @endcode
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ArangoCollection.prototype.index = function(id) {
|
||||
ArangoCollection.prototype.index = function (id) {
|
||||
var indexes = this.getIndexes();
|
||||
var i;
|
||||
|
||||
|
@ -182,14 +196,141 @@
|
|||
return null;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief iterators over some elements of a collection
|
||||
///
|
||||
/// @FUN{@FA{collection}.iterate(@FA{iterator}, @FA{options})}
|
||||
///
|
||||
/// Iterates over some elements of the collection and apply the function
|
||||
/// @FA{iterator} to the elements. The function will be called with the
|
||||
/// document as first argument and the current number (starting with 0)
|
||||
/// as second argument.
|
||||
///
|
||||
/// @FA{options} must be an object with the following attributes:
|
||||
///
|
||||
/// - @LIT{limit} (optional, default none): use at most @LIT{limit} documents.
|
||||
///
|
||||
/// - @LIT{probability} (optional, default all): a number between @LIT{0} and
|
||||
/// @LIT{1}. Documents are chosen with this probability.
|
||||
///
|
||||
/// @EXAMPLES
|
||||
///
|
||||
/// @code
|
||||
/// arango> db.example.getIndexes().map(function(x) { return x.id; });
|
||||
/// ["93013/0"]
|
||||
/// arango> db.example.index("93013/0");
|
||||
/// { "id" : "93013/0", "type" : "primary", "fields" : ["_id"] }
|
||||
/// @endcode
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ArangoCollection.prototype.iterate = function (iterator, options) {
|
||||
var probability = 1.0;
|
||||
var limit = null;
|
||||
var stmt;
|
||||
var cursor;
|
||||
var pos;
|
||||
|
||||
if (options !== undefined) {
|
||||
if (options.hasOwnProperty("probability")) {
|
||||
probability = options.probability;
|
||||
}
|
||||
|
||||
if (options.hasOwnProperty("limit")) {
|
||||
limit = options.limit;
|
||||
}
|
||||
}
|
||||
|
||||
if (limit === null) {
|
||||
if (probability >= 1.0) {
|
||||
stmt = internal.sprintf("FOR d IN %s RETURN d", this.name());
|
||||
}
|
||||
else {
|
||||
stmt = internal.sprintf("FOR d IN %s FILTER rand() >= @prob RETURN d", this.name());
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (typeof limit !== "number") {
|
||||
var error = new ArangoError();
|
||||
error.errorNum = internal.errors.ERROR_ILLEGAL_NUMBER.code;
|
||||
error.errorMessage = "expecting a number, got " + String(limit);
|
||||
|
||||
throw error;
|
||||
}
|
||||
|
||||
if (probability >= 1.0) {
|
||||
stmt = internal.sprintf("FOR d IN %s LIMIT %d RETURN d", this.name(), limit);
|
||||
}
|
||||
else {
|
||||
stmt = internal.sprintf("FOR d IN %s FILTER rand() >= @prob LIMIT %d RETURN d",
|
||||
this.name(), limit);
|
||||
}
|
||||
}
|
||||
|
||||
stmt = internal.db._createStatement({ query: stmt });
|
||||
|
||||
if (probability < 1.0) {
|
||||
stmt.bind("prob", probability);
|
||||
}
|
||||
|
||||
cursor = stmt.execute();
|
||||
pos = 0;
|
||||
|
||||
while (cursor.hasNext()) {
|
||||
var document = cursor.next();
|
||||
|
||||
iterator(document, pos);
|
||||
|
||||
pos++;
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief string representation of a collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ArangoCollection.prototype.toString = function(seen, path, names, level) {
|
||||
ArangoCollection.prototype.toString = function (seen, path, names, level) {
|
||||
return "[ArangoCollection " + this._id + "]";
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief removes documents matching an example
|
||||
///
|
||||
/// @FUN{@FA{collection}.removeByExample(@FA{example})}
|
||||
///
|
||||
/// Removes all document matching an example.
|
||||
///
|
||||
/// @FUN{@FA{collection}.removeByExample(@FA{document}, @FA{waitForSync})}
|
||||
///
|
||||
/// The optional @FA{waitForSync} parameter can be used to force synchronisation
|
||||
/// of the document deletion operation to disk even in case that the
|
||||
/// @LIT{waitForSync} flag had been disabled for the entire collection. Thus,
|
||||
/// the @FA{waitForSync} parameter can be used to force synchronisation of just
|
||||
/// specific operations. To use this, set the @FA{waitForSync} parameter to
|
||||
/// @LIT{true}. If the @FA{waitForSync} parameter is not specified or set to
|
||||
/// @LIT{false}, then the collection's default @LIT{waitForSync} behavior is
|
||||
/// applied. The @FA{waitForSync} parameter cannot be used to disable
|
||||
/// synchronisation for collections that have a default @LIT{waitForSync} value
|
||||
/// of @LIT{true}.
|
||||
///
|
||||
/// @EXAMPLES
|
||||
///
|
||||
/// @code
|
||||
/// arangod> db.content.removeByExample({ "domain": "de.celler" })
|
||||
/// @endcode
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ArangoCollection.prototype.removeByExample = function (example, waitForSync) {
|
||||
var documents;
|
||||
|
||||
documents = this.byExample(example);
|
||||
|
||||
while (documents.hasNext()) {
|
||||
var document = documents.next();
|
||||
|
||||
this.remove(document, true, waitForSync);
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -207,7 +348,7 @@
|
|||
/// @brief prints a collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ArangoCollection.prototype._PRINT = function() {
|
||||
ArangoCollection.prototype._PRINT = function () {
|
||||
var status = "unknown";
|
||||
var type = "unknown";
|
||||
|
||||
|
|
|
@ -0,0 +1,625 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief ArangoTraverser
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2011-2012 triagens GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Jan Steemann
|
||||
/// @author Copyright 2011-2012, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
(function () {
|
||||
var internal = require("internal"),
|
||||
console = require("console");
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- constructors and destructors
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup ArangoTraverser
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief traversal constructor
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function ArangoTraverser (edgeCollection,
|
||||
visitor,
|
||||
filter,
|
||||
expander) {
|
||||
if (typeof edgeCollection === "string") {
|
||||
edgeCollection = internal.db._collection(edgeCollection);
|
||||
}
|
||||
|
||||
if (! (edgeCollection instanceof ArangoCollection) ||
|
||||
edgeCollection.type() != internal.ArangoCollection.TYPE_EDGE) {
|
||||
throw "invalid edgeCollection";
|
||||
}
|
||||
|
||||
// properties
|
||||
this._edgeCollection = edgeCollection;
|
||||
|
||||
// callbacks
|
||||
this._visitor = visitor;
|
||||
this._filter = filter || IncludeAllFilter;
|
||||
this._expander = expander || OutboundExpander;
|
||||
|
||||
if (typeof this._visitor !== "function") {
|
||||
throw "invalid visitor";
|
||||
}
|
||||
|
||||
if (typeof this._filter !== "function") {
|
||||
throw "invalid filter";
|
||||
}
|
||||
|
||||
if (typeof this._expander !== "function") {
|
||||
throw "invalid expander";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public methods
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup ArangoTraverser
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief execute the traversal
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ArangoTraverser.prototype.traverse = function (startVertex,
|
||||
visitationStrategy,
|
||||
uniqueness,
|
||||
context,
|
||||
state) {
|
||||
// check the start vertex
|
||||
if (startVertex == undefined) {
|
||||
throw "invalid startVertex specified for traversal";
|
||||
}
|
||||
if (typeof startVertex == "string") {
|
||||
startVertex = internal.db._document(startVertex);
|
||||
}
|
||||
|
||||
// check the visitation strategy
|
||||
if (visitationStrategy !== ArangoTraverser.BREADTH_FIRST &&
|
||||
visitationStrategy !== ArangoTraverser.DEPTH_FIRST_PRE &&
|
||||
visitationStrategy !== ArangoTraverser.DEPTH_FIRST_POST) {
|
||||
throw "invalid visitationStrategy";
|
||||
}
|
||||
|
||||
// set user defined context & state
|
||||
this._context = context;
|
||||
this._state = state;
|
||||
|
||||
|
||||
// initialise the traversal strategy
|
||||
var levelState = InitLevelState(startVertex, function () {
|
||||
if (visitationStrategy === ArangoTraverser.BREADTH_FIRST) {
|
||||
return BreadthFirstSearch();
|
||||
}
|
||||
else if (visitationStrategy === ArangoTraverser.DEPTH_FIRST_PRE) {
|
||||
return DepthFirstPreSearch();
|
||||
}
|
||||
else {
|
||||
return DepthFirstPostSearch();
|
||||
}
|
||||
}());
|
||||
|
||||
// initialise uniqueness check attributes
|
||||
var uniquenessCheck = {
|
||||
vertices: uniqueness.vertices || ArangoTraverser.UNIQUE_NONE,
|
||||
edges: uniqueness.edges || ArangoTraverser.UNIQUE_NONE
|
||||
};
|
||||
|
||||
|
||||
// now execute the actual traversal...
|
||||
// iterate until we find the end
|
||||
while (true) {
|
||||
var currentElement = levelState.currentElement();
|
||||
var edge = currentElement.edge;
|
||||
var vertex = currentElement.vertex;
|
||||
|
||||
if (! ProcessVertex(this, vertex, levelState)) {
|
||||
// stop traversal because PRUNE was returned
|
||||
return;
|
||||
}
|
||||
|
||||
if (! levelState.next(this, levelState)) {
|
||||
// we're done
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup ArangoTraverser
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief initialise some internal state for the traversal
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function InitLevelState (startVertex, strategy) {
|
||||
return {
|
||||
level: 0,
|
||||
maxLevel: 0,
|
||||
index: 0,
|
||||
positions: [ 0 ],
|
||||
stack: [ [ { edge: null, vertex: startVertex, parentIndex: 0 } ] ],
|
||||
path: { edges: [ ], vertices: [ startVertex ] },
|
||||
visited: { edges: { }, vertices: { } },
|
||||
|
||||
next: function (traverser) {
|
||||
return strategy.next(traverser, this);
|
||||
},
|
||||
|
||||
currentElement: function () {
|
||||
return strategy.currentElement(this);
|
||||
},
|
||||
|
||||
elementAt: function (searchLevel, searchIndex) {
|
||||
return this.stack[searchLevel][searchIndex];
|
||||
},
|
||||
|
||||
numElements: function () {
|
||||
return this.stack[this.level].length;
|
||||
},
|
||||
|
||||
canDescend: function () {
|
||||
if (this.level >= this.maxLevel) {
|
||||
return false;
|
||||
}
|
||||
return (this.stack[this.level + 1].length > 0);
|
||||
},
|
||||
|
||||
isUniqueVertex: function (checkMode, vertex) {
|
||||
return this.isUnique(checkMode, this.visited.vertices, vertex._id);
|
||||
},
|
||||
|
||||
isUniqueEdge: function (checkMode, edge) {
|
||||
return this.isUnique(checkMode, this.visited.edges, edge._id);
|
||||
},
|
||||
|
||||
isUnique: function (checkMode, elementsSeen, element) {
|
||||
if (checkMode === ArangoTraverser.UNIQUE_NONE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
var seen = elementsSeen[element] || false;
|
||||
if (! seen) {
|
||||
// now mark the element as being visited
|
||||
elementsSeen[element] = true;
|
||||
}
|
||||
|
||||
return ! seen;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief implementation details for breadth-first strategy
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function BreadthFirstSearch () {
|
||||
return {
|
||||
// TODO: ADD UNIQUENESS CHECK HERE
|
||||
next: function (traverser, levelState) {
|
||||
var currentElement = levelState.elementAt(levelState.level, levelState.index);
|
||||
traverser._visitor(traverser, currentElement.vertex, levelState.path);
|
||||
|
||||
if (++levelState.index >= levelState.numElements()) {
|
||||
levelState.index = 0;
|
||||
if (++levelState.level > levelState.maxLevel) {
|
||||
// we're done
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
currentElement : function (levelState) {
|
||||
var path = levelState.path;
|
||||
var currentElement = levelState.elementAt(levelState.level, levelState.index);
|
||||
var element = currentElement;
|
||||
|
||||
for (var i = levelState.level; i > 0; --i) {
|
||||
path.edges[i - 1] = element.edge;
|
||||
path.vertices[i] = element.vertex;
|
||||
|
||||
element = levelState.elementAt(i - 1, element.parentIndex);
|
||||
}
|
||||
|
||||
return currentElement;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief implementation details for depth-first strategy
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function DepthFirstPreSearch () {
|
||||
return {
|
||||
next: function (traverser, levelState) {
|
||||
var position = levelState.positions[levelState.level];
|
||||
var currentElement = levelState.elementAt(levelState.level, position);
|
||||
|
||||
traverser._visitor(traverser, currentElement.vertex, levelState.path);
|
||||
|
||||
if (levelState.canDescend()) {
|
||||
++levelState.level;
|
||||
}
|
||||
else {
|
||||
while (++levelState.positions[levelState.level] >= levelState.numElements()) {
|
||||
|
||||
levelState.positions[levelState.level] = 0;
|
||||
delete levelState.stack[levelState.level];
|
||||
|
||||
levelState.path.vertices.pop();
|
||||
levelState.path.edges.pop();
|
||||
|
||||
if (levelState.level <= 1) {
|
||||
// we're done
|
||||
return false;
|
||||
}
|
||||
|
||||
levelState.level--;
|
||||
// TODO: make this a function
|
||||
levelState.maxLevel--;
|
||||
}
|
||||
}
|
||||
|
||||
var currentElement = levelState.stack[levelState.level][levelState.positions[levelState.level]];
|
||||
|
||||
levelState.path.edges[levelState.level - 1] = currentElement.edge;
|
||||
levelState.path.vertices[levelState.level] = currentElement.vertex;
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
currentElement : function (levelState) {
|
||||
var position = levelState.positions[levelState.level];
|
||||
var currentElement = levelState.elementAt(levelState.level, position);
|
||||
|
||||
return currentElement;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief implementation details for depth-first strategy
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function DepthFirstPostSearch () {
|
||||
return {
|
||||
next: function (traverser, levelState) {
|
||||
|
||||
var currentElement = levelState.stack[levelState.level][levelState.positions[levelState.level]];
|
||||
console.log("level " + levelState.level + ", ele: " + currentElement.vertex._id);
|
||||
|
||||
|
||||
while (levelState.canDescend()) {
|
||||
++levelState.level;
|
||||
|
||||
var currentElement = levelState.stack[levelState.level][levelState.positions[levelState.level]];
|
||||
console.log("desc, up is " + currentElement.vertex._id);
|
||||
levelState.path.edges[levelState.level - 1] = currentElement.edge;
|
||||
levelState.path.vertices[levelState.level] = currentElement.vertex;
|
||||
}
|
||||
|
||||
while (++levelState.positions[levelState.level] >= levelState.numElements()) {
|
||||
console.log("undesc");
|
||||
levelState.positions[levelState.level] = 0;
|
||||
delete levelState.stack[levelState.level];
|
||||
|
||||
if (levelState.level == 0) {
|
||||
// we're done
|
||||
return false;
|
||||
}
|
||||
|
||||
levelState.level--;
|
||||
// TODO: make this a function
|
||||
levelState.maxLevel--;
|
||||
// break;
|
||||
|
||||
}
|
||||
|
||||
var currentElement = levelState.stack[levelState.level][levelState.positions[levelState.level]];
|
||||
levelState.path.edges[levelState.level - 1] = currentElement.edge;
|
||||
levelState.path.vertices[levelState.level] = currentElement.vertex;
|
||||
|
||||
traverser._visitor(traverser, currentElement.vertex, levelState.path);
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
currentElement : function (levelState) {
|
||||
var position = levelState.positions[levelState.level];
|
||||
var currentElement = levelState.elementAt(levelState.level, position);
|
||||
|
||||
return currentElement;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief callback function that is executed for each vertex found
|
||||
///
|
||||
/// this function is applying the filter criteria and calls the visitor
|
||||
/// function for the vertex if it should be included in the traversal.
|
||||
/// it will then also fetch the connected edges for the vertex.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function ProcessVertex (traverser, vertex, levelState) {
|
||||
// check filter condition for vertex
|
||||
var filterResult = traverser._filter(traverser, vertex, levelState.path);
|
||||
|
||||
if (filterResult === ArangoTraverser.INCLUDE_AND_CONTINUE ||
|
||||
filterResult === ArangoTraverser.INCLUDE_AND_PRUNE) {
|
||||
|
||||
// get connected edges for vertex
|
||||
traverser._expander(traverser, vertex, levelState.path).forEach(function (connection) {
|
||||
var nextLevel = levelState.level + 1;
|
||||
|
||||
if (levelState.stack[nextLevel] == undefined) {
|
||||
levelState.stack[nextLevel] = [ ];
|
||||
levelState.positions[nextLevel] = 0;
|
||||
}
|
||||
|
||||
if (levelState.stack[nextLevel].length == 0) {
|
||||
++levelState.maxLevel;
|
||||
}
|
||||
connection.parentIndex = levelState.index;
|
||||
levelState.stack[nextLevel].push(connection);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// return true only if we should continue
|
||||
return (filterResult === ArangoTraverser.INCLUDE_AND_CONTINUE ||
|
||||
filterResult === ArangoTraverser.EXCLUDE_AND_CONTINUE);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief default filter function (if none specified)
|
||||
///
|
||||
/// this filter will simply include every vertex
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function IncludeAllFilter (traverser, vertex, path) {
|
||||
return ArangoTraverser.INCLUDE_AND_CONTINUE;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief default outbound expander function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function OutboundExpander (traverser, vertex, path) {
|
||||
var connections = [ ];
|
||||
|
||||
this._edgeCollection.outEdges(vertex._id).forEach(function (edge) {
|
||||
var vertex = internal.db._document(edge._to);
|
||||
connections.push({ edge: edge, vertex: vertex });
|
||||
});
|
||||
|
||||
return connections;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief default inbound expander function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function InboundExpander (traverser, vertex, path) {
|
||||
var connections = [ ];
|
||||
|
||||
this._edgeCollection.inEdges(vertex._id).forEach(function (edge) {
|
||||
var vertex = internal.db._document(edge._from);
|
||||
connections.push({ edge: edge, vertex: vertex });
|
||||
});
|
||||
|
||||
return connections;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public constants
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup ArangoTraverser
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief pre-order visits
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ArangoTraverser.VISIT_PREORDER = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief post-order visits
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ArangoTraverser.VISIT_POSTORDER = 1;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief element may be revisited
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ArangoTraverser.UNIQUE_NONE = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief element can only be revisited if not already in current path
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ArangoTraverser.UNIQUE_PATH = 1;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief element can only be revisited if not already visited
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ArangoTraverser.UNIQUE_GLOBAL = 2;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief visitation strategy breadth first
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ArangoTraverser.UNIQUE_NONE = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief visitation strategy breadth first
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ArangoTraverser.BREADTH_FIRST = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief visitation strategy depth first
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ArangoTraverser.DEPTH_FIRST_PRE = 1;
|
||||
ArangoTraverser.DEPTH_FIRST_POST = 2;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief include this node in the result and continue the traversal
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ArangoTraverser.INCLUDE_AND_CONTINUE = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief include this node in the result, but don’t continue the traversal
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ArangoTraverser.INCLUDE_AND_PRUNE = 1;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief exclude this node from the result, but continue the traversal
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ArangoTraverser.EXCLUDE_AND_CONTIUE = 2;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief exclude this node from the result and don’t continue the traversal
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ArangoTraverser.EXCLUDE_AND_PRUNE = 3;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var stringifyPath = function (path) {
|
||||
var result = "[";
|
||||
for (var i = 0; i < path.edges.length; ++i) {
|
||||
if (i > 0) {
|
||||
result += ", ";
|
||||
}
|
||||
result += path.edges[i].what;
|
||||
}
|
||||
|
||||
result += " ]";
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
var context = { someContext : true };
|
||||
var state = { someState : { } };
|
||||
|
||||
var visitor = function (traverser, vertex, path) {
|
||||
var result = path.edges.length + " ";
|
||||
for (var i = 0; i < path.edges.length; ++i) {
|
||||
result += " ";
|
||||
}
|
||||
result += "- " + vertex._id + " " + stringifyPath(path);
|
||||
console.log(result);
|
||||
};
|
||||
|
||||
var uniqueness = { vertices : ArangoTraverser.UNIQUE_GLOBAL, edges : ArangoTraverser.UNIQUE_NONE };
|
||||
|
||||
db.tusers.load();
|
||||
db.trelations.load();
|
||||
|
||||
var traverser = new ArangoTraverser("trelations", visitor);
|
||||
traverser.traverse("tusers/claudius", ArangoTraverser.DEPTH_FIRST_PRE, uniqueness, context, state);
|
||||
console.log("------------");
|
||||
var traverser = new ArangoTraverser("trelations", visitor);
|
||||
traverser.traverse("tusers/claudius", ArangoTraverser.DEPTH_FIRST_POST, uniqueness, context, state);
|
||||
console.log("------------");
|
||||
var traverser = new ArangoTraverser("trelations", visitor);
|
||||
traverser.traverse("tusers/claudius", ArangoTraverser.BREADTH_FIRST, uniqueness, context, state);
|
||||
|
||||
}());
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- MODULE EXPORTS
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup ArangoTraverser
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
exports.ArangoTraverser = ArangoTraverser;
|
||||
|
||||
exports.ArangoIncludeAllFilter = IncludeAllFilter;
|
||||
exports.ArangoOutboundExpander = OutboundExpander;
|
||||
exports.ArangoInboundExpander = InboundExpander;
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @\\}\\)"
|
||||
// End:
|
|
@ -2125,15 +2125,14 @@ function AHUACATL_GEO_WITHIN () {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function AHUACATL_GRAPH_PATHS () {
|
||||
var vertices = arguments[0];
|
||||
var vertices = arguments[0];
|
||||
var edgeCollection = arguments[1];
|
||||
var direction = arguments[2] != undefined ? arguments[2] : "outbound";
|
||||
var followCycles = arguments[3] ? arguments[3] : false;
|
||||
|
||||
var minLength = 0;
|
||||
var maxLength = 10;
|
||||
var direction = arguments[2] || "outbound";
|
||||
var followCycles = arguments[3] || false;
|
||||
var minLength = arguments[4] || 0;
|
||||
var maxLength = arguments[5] != undefined ? arguments[5] : 10;
|
||||
var searchDirection;
|
||||
|
||||
|
||||
AHUACATL_LIST(vertices);
|
||||
|
||||
// validate arguments
|
||||
|
@ -2145,7 +2144,6 @@ function AHUACATL_GRAPH_PATHS () {
|
|||
}
|
||||
else if (direction == "any") {
|
||||
searchDirection = 3;
|
||||
maxLength = 3;
|
||||
}
|
||||
else {
|
||||
AHUACATL_THROW(internal.errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "PATHS");
|
||||
|
|
|
@ -1,10 +1,4 @@
|
|||
/*jslint indent: 2,
|
||||
nomen: true,
|
||||
maxlen: 100,
|
||||
sloppy: true,
|
||||
vars: true,
|
||||
white: true,
|
||||
plusplus: true */
|
||||
/*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true, vars: true, white: true, plusplus: true */
|
||||
/*global require, exports */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -47,6 +41,18 @@ var internal = require("internal");
|
|||
|
||||
exports.db = internal.db;
|
||||
exports.ArangoCollection = internal.ArangoCollection;
|
||||
exports.ArangoError = internal.ArangoError;
|
||||
|
||||
// copy error codes
|
||||
(function () {
|
||||
var name;
|
||||
|
||||
for (name in internal.errors) {
|
||||
if (internal.errors.hasOwnProperty(name)) {
|
||||
exports[name] = internal.errors[name].code;
|
||||
}
|
||||
}
|
||||
}());
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
|
|
|
@ -1,10 +1,4 @@
|
|||
/*jslint indent: 2,
|
||||
nomen: true,
|
||||
maxlen: 100,
|
||||
sloppy: true,
|
||||
vars: true,
|
||||
white: true,
|
||||
plusplus: true */
|
||||
/*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true, vars: true, white: true, regexp: true plusplus: true */
|
||||
/*global require, exports, module */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -34,8 +28,10 @@
|
|||
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var arangodb = require("org/arangodb");
|
||||
var internal = require("internal");
|
||||
var console = require("console");
|
||||
var moduleExists = function(name) { return module.exists; };
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private variables
|
||||
|
@ -195,6 +191,7 @@ function lookupCallbackStatic (content) {
|
|||
type = content.contentType || "text/plain";
|
||||
body = content.body || "";
|
||||
methods = content.methods || [ exports.GET, exports.HEAD ];
|
||||
options = content.options || {};
|
||||
}
|
||||
|
||||
return {
|
||||
|
@ -245,11 +242,12 @@ function lookupCallbackAction (route, action) {
|
|||
func = module[name];
|
||||
}
|
||||
else {
|
||||
func = notImplementedFunction(route, "could not find action named '" + name + "' in module '" + joined + "'");
|
||||
func = notImplementedFunction(route, "could not find action named '"
|
||||
+ name + "' in module '" + joined + "'");
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
if (! module.exists(joined)) {
|
||||
if (! moduleExists(joined)) {
|
||||
func = notImplementedFunction(route,
|
||||
"an error occurred while loading action named '" + name
|
||||
+ "' in module '" + joined + "': " + String(err));
|
||||
|
@ -280,19 +278,19 @@ function lookupCallbackAction (route, action) {
|
|||
|
||||
return {
|
||||
controller: function (req, res, options, next) {
|
||||
var m;
|
||||
|
||||
// enum all HTTP methods
|
||||
for (var m in httpMethods) {
|
||||
if (! httpMethods.hasOwnProperty(m)) {
|
||||
continue;
|
||||
}
|
||||
for (m in httpMethods) {
|
||||
if (httpMethods.hasOwnProperty(m)) {
|
||||
if (req.requestType === httpMethods[m] && module.hasOwnProperty(m)) {
|
||||
func = module[m]
|
||||
|| errorFunction(route,
|
||||
"invalid definition for " + m + " action in action controller module '"
|
||||
+ action.controller + "'");
|
||||
|
||||
if (req.requestType == httpMethods[m] && module.hasOwnProperty(m)) {
|
||||
func = module[m]
|
||||
|| errorFunction(route,
|
||||
"invalid definition for " + m + " action in action controller module '"
|
||||
+ action.controller + "'");
|
||||
|
||||
return func(req, res, options, next);
|
||||
return func(req, res, options, next);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -311,16 +309,16 @@ function lookupCallbackAction (route, action) {
|
|||
methods: action.methods || exports.ALL_METHODS
|
||||
};
|
||||
}
|
||||
catch (err) {
|
||||
if (! module.exists(action.controller)) {
|
||||
catch (err1) {
|
||||
if (! moduleExists(action.controller)) {
|
||||
return notImplementedFunction(route,
|
||||
"cannot load/execute action controller module '"
|
||||
+ action.controller + ": " + String(err));
|
||||
+ action.controller + ": " + String(err1));
|
||||
}
|
||||
|
||||
return errorFunction(route,
|
||||
"cannot load/execute action controller module '"
|
||||
+ action.controller + ": " + String(err));
|
||||
+ action.controller + ": " + String(err1));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -348,27 +346,28 @@ function lookupCallbackAction (route, action) {
|
|||
catch (err) {
|
||||
efunc = errorFunction;
|
||||
|
||||
if (! module.exists(path)) {
|
||||
if (! moduleExists(path)) {
|
||||
efunc = notImplementedFunction;
|
||||
}
|
||||
|
||||
return efunc(route, "cannot load prefix controller: " + String(err))(req, res, options, next);
|
||||
return efunc(route, "cannot load prefix controller: " + String(err))(
|
||||
req, res, options, next);
|
||||
}
|
||||
|
||||
try {
|
||||
var m;
|
||||
|
||||
// enum all HTTP methods
|
||||
for (var m in httpMethods) {
|
||||
if (! httpMethods.hasOwnProperty(m)) {
|
||||
continue;
|
||||
}
|
||||
for (m in httpMethods) {
|
||||
if (httpMethods.hasOwnProperty(m)) {
|
||||
if (req.requestType === httpMethods[m] && module.hasOwnProperty(m)) {
|
||||
func = module[m]
|
||||
|| errorFunction(route,
|
||||
"Invalid definition for " + m + " action in prefix controller '"
|
||||
+ action.prefixController + "'");
|
||||
|
||||
if (req.requestType == httpMethods[m] && module.hasOwnProperty(m)) {
|
||||
func = module[m]
|
||||
|| errorFunction(route,
|
||||
"Invalid definition for " + m + " action in prefix controller '"
|
||||
+ action.prefixController + "'");
|
||||
|
||||
return func(req, res, options, next);
|
||||
return func(req, res, options, next);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -381,10 +380,11 @@ function lookupCallbackAction (route, action) {
|
|||
return func(req, res, options, next);
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
catch (err2) {
|
||||
return errorFunction(route,
|
||||
"Cannot load/execute prefix controller '"
|
||||
+ action.prefixController + "': " + String(err))(req, res, options, next);
|
||||
+ action.prefixController + "': " + String(err2))(
|
||||
req, res, options, next);
|
||||
}
|
||||
|
||||
next();
|
||||
|
@ -454,7 +454,7 @@ function defineRoutePart (route, subwhere, parts, pos, constraint, callback) {
|
|||
var ok;
|
||||
|
||||
part = parts[pos];
|
||||
if (part == undefined) {
|
||||
if (part === undefined) {
|
||||
// otherwise we'll get an exception below
|
||||
part = '';
|
||||
}
|
||||
|
@ -558,15 +558,20 @@ function flattenRouting (routes, path, urlParameters, depth, prefix) {
|
|||
var cur;
|
||||
var i;
|
||||
var k;
|
||||
var newUrlParameters;
|
||||
var parameter;
|
||||
var match;
|
||||
var result = [];
|
||||
|
||||
if (routes.hasOwnProperty('exact')) {
|
||||
for (k in routes.exact) {
|
||||
if (routes.exact.hasOwnProperty(k)) {
|
||||
newUrlParameters = urlParameters.shallowCopy;
|
||||
|
||||
cur = path + "/" + k.replace(/([\.\+\*\?\^\$\(\)\[\]])/g, "\\$1");
|
||||
result = result.concat(flattenRouting(routes.exact[k],
|
||||
cur,
|
||||
urlParameters.shallowCopy,
|
||||
newUrlParameters,
|
||||
depth + 1,
|
||||
false));
|
||||
}
|
||||
|
@ -575,14 +580,14 @@ function flattenRouting (routes, path, urlParameters, depth, prefix) {
|
|||
|
||||
if (routes.hasOwnProperty('parameters')) {
|
||||
for (i = 0; i < routes.parameters.length; ++i) {
|
||||
var parameter = routes.parameters[i];
|
||||
var newUrlParameters = urlParameters.shallowCopy;
|
||||
var match;
|
||||
parameter = routes.parameters[i];
|
||||
newUrlParameters = urlParameters.shallowCopy;
|
||||
|
||||
if (parameter.hasOwnProperty('constraint')) {
|
||||
var constraint = parameter.constraint;
|
||||
var pattern = /\/.*\//;
|
||||
|
||||
if (/\/.*\//.test(constraint)) {
|
||||
if (pattern.test(constraint)) {
|
||||
match = "/" + constraint.substr(1, constraint.length - 2);
|
||||
}
|
||||
else {
|
||||
|
@ -804,20 +809,25 @@ function getErrorMessage (code) {
|
|||
|
||||
function getJsonBody (req, res, code) {
|
||||
var body;
|
||||
var err;
|
||||
|
||||
try {
|
||||
body = JSON.parse(req.requestBody || "{}") || {};
|
||||
}
|
||||
catch (err) {
|
||||
exports.resultBad(req, res, exports.ERROR_HTTP_CORRUPTED_JSON, err);
|
||||
catch (err1) {
|
||||
exports.resultBad(req, res, arangodb.ERROR_HTTP_CORRUPTED_JSON, err1);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (! body || ! (body instanceof Object)) {
|
||||
if (code === undefined) {
|
||||
code = exports.ERROR_HTTP_CORRUPTED_JSON;
|
||||
code = arangodb.ERROR_HTTP_CORRUPTED_JSON;
|
||||
}
|
||||
|
||||
err = new internal.ArangoError();
|
||||
err.errorNum = code;
|
||||
err.errorMessage = "expecting a valid JSON object as body";
|
||||
|
||||
exports.resultBad(req, res, code, err);
|
||||
return undefined;
|
||||
}
|
||||
|
@ -841,6 +851,7 @@ function getJsonBody (req, res, code) {
|
|||
|
||||
function resultError (req, res, httpReturnCode, errorNum, errorMessage, headers, keyvals) {
|
||||
var i;
|
||||
var msg;
|
||||
|
||||
res.responseCode = httpReturnCode;
|
||||
res.contentType = "application/json; charset=utf-8";
|
||||
|
@ -852,6 +863,13 @@ function resultError (req, res, httpReturnCode, errorNum, errorMessage, headers,
|
|||
errorNum = httpReturnCode;
|
||||
}
|
||||
|
||||
if (errorMessage === undefined || errorMessage === null) {
|
||||
msg = getErrorMessage(errorNum);
|
||||
}
|
||||
else {
|
||||
msg = String(errorMessage);
|
||||
}
|
||||
|
||||
var result = {};
|
||||
|
||||
if (keyvals !== undefined) {
|
||||
|
@ -862,10 +880,10 @@ function resultError (req, res, httpReturnCode, errorNum, errorMessage, headers,
|
|||
}
|
||||
}
|
||||
|
||||
result["error"] = true;
|
||||
result["code"] = httpReturnCode;
|
||||
result["errorNum"] = errorNum;
|
||||
result["errorMessage"] = errorMessage;
|
||||
result.error = true;
|
||||
result.code = httpReturnCode;
|
||||
result.errorNum = errorNum;
|
||||
result.errorMessage = msg;
|
||||
|
||||
res.body = JSON.stringify(result);
|
||||
|
||||
|
@ -1087,7 +1105,8 @@ function firstRouting (type, parts) {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function badParameter (req, res, name) {
|
||||
resultError(req, res, exports.HTTP_BAD, exports.HTTP_BAD, "invalid value for parameter '" + name + "'");
|
||||
resultError(req, res, exports.HTTP_BAD, exports.HTTP_BAD,
|
||||
"invalid value for parameter '" + name + "'");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1130,13 +1149,6 @@ function resultOk (req, res, httpReturnCode, result, headers) {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function resultBad (req, res, code, msg, headers) {
|
||||
if (msg === undefined || msg === null) {
|
||||
msg = getErrorMessage(code);
|
||||
}
|
||||
else {
|
||||
msg = String(msg);
|
||||
}
|
||||
|
||||
resultError(req, res, exports.HTTP_BAD, code, msg, headers);
|
||||
}
|
||||
|
||||
|
@ -1149,7 +1161,7 @@ function resultBad (req, res, code, msg, headers) {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function resultNotFound (req, res, code, msg, headers) {
|
||||
resultError(req, res, exports.HTTP_NOT_FOUND, code, String(msg), headers);
|
||||
resultError(req, res, exports.HTTP_NOT_FOUND, code, msg, headers);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1164,8 +1176,8 @@ function resultNotImplemented (req, res, msg, headers) {
|
|||
resultError(req,
|
||||
res,
|
||||
exports.HTTP_NOT_IMPLEMENTED,
|
||||
exports.ERROR_NOT_IMPLEMENTED,
|
||||
String(msg),
|
||||
arangodb.ERROR_NOT_IMPLEMENTED,
|
||||
msg,
|
||||
headers);
|
||||
}
|
||||
|
||||
|
@ -1179,7 +1191,8 @@ function resultNotImplemented (req, res, msg, headers) {
|
|||
|
||||
function resultUnsupported (req, res, headers) {
|
||||
resultError(req, res,
|
||||
exports.HTTP_METHOD_NOT_ALLOWED, exports.ERROR_HTTP_METHOD_NOT_ALLOWED,
|
||||
exports.HTTP_METHOD_NOT_ALLOWED,
|
||||
arangodb.ERROR_HTTP_METHOD_NOT_ALLOWED,
|
||||
"Unsupported method",
|
||||
headers);
|
||||
}
|
||||
|
@ -1300,11 +1313,11 @@ function resultCursor (req, res, cursor, code, options) {
|
|||
};
|
||||
|
||||
if (cursorId) {
|
||||
result["id"] = cursorId;
|
||||
result.id = cursorId;
|
||||
}
|
||||
|
||||
if (hasCount) {
|
||||
result["count"] = count;
|
||||
result.count = count;
|
||||
}
|
||||
|
||||
if (code === undefined) {
|
||||
|
@ -1325,13 +1338,13 @@ function resultCursor (req, res, cursor, code, options) {
|
|||
function collectionNotFound (req, res, collection, headers) {
|
||||
if (collection === undefined) {
|
||||
resultError(req, res,
|
||||
exports.HTTP_BAD, exports.ERROR_HTTP_BAD_PARAMETER,
|
||||
exports.HTTP_BAD, arangodb.ERROR_HTTP_BAD_PARAMETER,
|
||||
"expecting a collection name or identifier",
|
||||
headers);
|
||||
}
|
||||
else {
|
||||
resultError(req, res,
|
||||
exports.HTTP_NOT_FOUND, exports.ERROR_ARANGO_COLLECTION_NOT_FOUND,
|
||||
exports.HTTP_NOT_FOUND, arangodb.ERROR_ARANGO_COLLECTION_NOT_FOUND,
|
||||
"unknown collection '" + collection + "'", headers);
|
||||
}
|
||||
}
|
||||
|
@ -1347,19 +1360,19 @@ function collectionNotFound (req, res, collection, headers) {
|
|||
function indexNotFound (req, res, collection, index, headers) {
|
||||
if (collection === undefined) {
|
||||
resultError(req, res,
|
||||
exports.HTTP_BAD, exports.ERROR_HTTP_BAD_PARAMETER,
|
||||
exports.HTTP_BAD, arangodb.ERROR_HTTP_BAD_PARAMETER,
|
||||
"expecting a collection name or identifier",
|
||||
headers);
|
||||
}
|
||||
else if (index === undefined) {
|
||||
resultError(req, res,
|
||||
exports.HTTP_BAD, exports.ERROR_HTTP_BAD_PARAMETER,
|
||||
exports.HTTP_BAD, arangodb.ERROR_HTTP_BAD_PARAMETER,
|
||||
"expecting an index identifier",
|
||||
headers);
|
||||
}
|
||||
else {
|
||||
resultError(req, res,
|
||||
exports.HTTP_NOT_FOUND, exports.ERROR_ARANGO_INDEX_NOT_FOUND,
|
||||
exports.HTTP_NOT_FOUND, arangodb.ERROR_ARANGO_INDEX_NOT_FOUND,
|
||||
"unknown index '" + index + "'", headers);
|
||||
}
|
||||
}
|
||||
|
@ -1373,20 +1386,20 @@ function indexNotFound (req, res, collection, index, headers) {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function resultException (req, res, err, headers) {
|
||||
if (err instanceof ArangoError) {
|
||||
if (err instanceof internal.ArangoError) {
|
||||
var num = err.errorNum;
|
||||
var msg = err.errorMessage;
|
||||
var code = exports.HTTP_BAD;
|
||||
|
||||
switch (num) {
|
||||
case exports.ERROR_INTERNAL: code = exports.HTTP_SERVER_ERROR; break;
|
||||
case arangodb.ERROR_INTERNAL: code = exports.HTTP_SERVER_ERROR; break;
|
||||
}
|
||||
|
||||
resultError(req, res, code, num, msg, headers);
|
||||
}
|
||||
else {
|
||||
resultError(req, res,
|
||||
exports.HTTP_SERVER_ERROR, exports.ERROR_HTTP_SERVER_ERROR,
|
||||
exports.HTTP_SERVER_ERROR, arangodb.ERROR_HTTP_SERVER_ERROR,
|
||||
String(err),
|
||||
headers);
|
||||
}
|
||||
|
@ -1570,15 +1583,6 @@ exports.HTTP_NOT_IMPLEMENTED = 501;
|
|||
exports.HTTP_BAD_GATEWAY = 502;
|
||||
exports.HTTP_SERVICE_UNAVAILABLE = 503;
|
||||
|
||||
// copy error codes
|
||||
var name;
|
||||
|
||||
for (name in internal.errors) {
|
||||
if (internal.errors.hasOwnProperty(name)) {
|
||||
exports[name] = internal.errors[name].code;
|
||||
}
|
||||
}
|
||||
|
||||
// load routing
|
||||
reloadRouting();
|
||||
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
/*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true, vars: true, white: true, plusplus: true */
|
||||
/*global require, exports */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief example controller
|
||||
/// @brief example echo controller
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
|
@ -27,17 +30,17 @@
|
|||
|
||||
var actions = require("org/arangodb/actions");
|
||||
|
||||
exports.head = function (req, res, next, options) {
|
||||
exports.head = function (req, res, options, next) {
|
||||
res.responseCode = actions.HTTP_OK;
|
||||
res.contentType = "application/json; charset=utf-8";
|
||||
res.body = "";
|
||||
}
|
||||
};
|
||||
|
||||
exports.do = function (req, res, next, options) {
|
||||
exports['do'] = function (req, res, options, next) {
|
||||
res.responseCode = actions.HTTP_OK;
|
||||
res.contentType = "application/json; charset=utf-8";
|
||||
res.body = JSON.stringify( { "request" : req, "options" : options });
|
||||
}
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
|
|
|
@ -0,0 +1,135 @@
|
|||
/*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true, vars: true, white: true, plusplus: true */
|
||||
/*global require, exports */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief deliver static content from collection
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2012 triagens GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Dr. Frank Celler
|
||||
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var arangodb = require("org/arangodb");
|
||||
var actions = require("org/arangodb/actions");
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup ArangoActions
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief locate content from collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function locateContent (req, options) {
|
||||
var path;
|
||||
var collection;
|
||||
|
||||
if (! options.hasOwnProperty("contentCollection")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
collection = arangodb.db._collection(options.contentCollection);
|
||||
|
||||
if (collection === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
path = "/" + req.suffix.join("/");
|
||||
|
||||
return collection.firstExample({
|
||||
path: path,
|
||||
prefix: options.prefix,
|
||||
application: options.application });
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup ArangoActions
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief locate content from collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
exports.head = function (req, res, options, next) {
|
||||
var content;
|
||||
|
||||
content = locateContent(req, options);
|
||||
|
||||
if (content === null) {
|
||||
res.responseCode = actions.HTTP_NOT_IMPLEMENTED;
|
||||
res.contentType = "text/plain";
|
||||
}
|
||||
else {
|
||||
res.responseCode = actions.HTTP_OK;
|
||||
res.contentType = content.contentType || "text/html";
|
||||
}
|
||||
|
||||
res.body = "";
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief get request
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
exports.get = function (req, res, options, next) {
|
||||
var content;
|
||||
|
||||
content = locateContent(req, options);
|
||||
|
||||
if (content === null) {
|
||||
res.responseCode = actions.HTTP_NOT_IMPLEMENTED;
|
||||
res.contentType = "text/plain";
|
||||
res.body = "path '" + req.suffix.join("/") + "' not implemented";
|
||||
}
|
||||
else {
|
||||
res.responseCode = actions.HTTP_OK;
|
||||
res.contentType = content.contentType || "text/html";
|
||||
res.body = content.content || "";
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @\\}\\)"
|
||||
// End:
|
|
@ -1,10 +1,4 @@
|
|||
/*jslint indent: 2,
|
||||
nomen: true,
|
||||
maxlen: 100,
|
||||
sloppy: true,
|
||||
vars: true,
|
||||
white: true,
|
||||
plusplus: true */
|
||||
/*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true, vars: true, white: true, plusplus: true */
|
||||
/*global require, exports */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -34,10 +28,17 @@
|
|||
/// @author Copyright 2011-2012, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var arangodb = require("org/arangodb");
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- number parsers
|
||||
// --SECTION-- number formatters
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup ArangoStructures
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief parses a number
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -57,8 +58,8 @@ exports.number = function (value, info, lang) {
|
|||
result = String(value);
|
||||
}
|
||||
else {
|
||||
error = new ArangoError();
|
||||
error.errorNum = internal.errors.ERROR_NOT_IMPLEMENTED.code;
|
||||
error = new arangodb.ArangoError();
|
||||
error.errorNum = arangodb.ERROR_NOT_IMPLEMENTED;
|
||||
error.errorMessage = "format '" + format + "' not implemented";
|
||||
|
||||
throw error;
|
||||
|
@ -69,7 +70,7 @@ exports.number = function (value, info, lang) {
|
|||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
|
|
|
@ -1,10 +1,4 @@
|
|||
/*jslint indent: 2,
|
||||
nomen: true,
|
||||
maxlen: 100,
|
||||
sloppy: true,
|
||||
vars: true,
|
||||
white: true,
|
||||
plusplus: true */
|
||||
/*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true, vars: true, white: true, plusplus: true */
|
||||
/*global require, exports */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -34,10 +28,17 @@
|
|||
/// @author Copyright 2011-2012, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var arangodb = require("org/arangodb");
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- number parsers
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup ArangoStructures
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief parses a number
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -51,7 +52,7 @@ exports.number = function (value, info, lang) {
|
|||
format = info.format;
|
||||
|
||||
if (format === "%d") {
|
||||
result = parseInt(value);
|
||||
result = parseInt(value, 10);
|
||||
}
|
||||
else if (format === "%f") {
|
||||
result = parseFloat(value);
|
||||
|
@ -63,8 +64,8 @@ exports.number = function (value, info, lang) {
|
|||
result = parseInt(value, 8);
|
||||
}
|
||||
else {
|
||||
error = new ArangoError();
|
||||
error.errorNum = internal.errors.ERROR_NOT_IMPLEMENTED.code;
|
||||
error = new arangodb.ArangoError();
|
||||
error.errorNum = arangodb.ERROR_NOT_IMPLEMENTED;
|
||||
error.errorMessage = "format '" + format + "' not implemented";
|
||||
|
||||
throw error;
|
||||
|
@ -75,15 +76,15 @@ exports.number = function (value, info, lang) {
|
|||
}
|
||||
|
||||
if (result === null || result === undefined || isNaN(result)) {
|
||||
error = new ArangoError();
|
||||
error.errorNum = internal.errors.ERROR_ARANGO_PARSER_FAILED;
|
||||
error = new arangodb.ArangoError();
|
||||
error.errorNum = arangodb.ERROR_ARANGO_PARSER_FAILED;
|
||||
error.errorMessage = "format '" + format + "' not implemented";
|
||||
|
||||
throw error;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
|
|
|
@ -1,10 +1,4 @@
|
|||
/*jslint indent: 2,
|
||||
nomen: true,
|
||||
maxlen: 100,
|
||||
sloppy: true,
|
||||
vars: true,
|
||||
white: true,
|
||||
plusplus: true */
|
||||
/*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true, vars: true, white: true, plusplus: true */
|
||||
/*global require, exports */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -34,23 +28,30 @@
|
|||
/// @author Copyright 2011-2012, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var arangodb = require("org/arangodb");
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- number validators
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup ArangoStructure
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief positive number
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
exports.positiveNumber = function (value, info, lang) {
|
||||
if (value <= 0.0) {
|
||||
error = new ArangoError();
|
||||
error.errorNum = internal.errors.ERROR_ARANGO_VALIDATION_FAILED.code;
|
||||
var error = new arangodb.ArangoError();
|
||||
error.errorNum = arangodb.ERROR_ARANGO_VALIDATION_FAILED;
|
||||
error.errorMessage = "number must be positive";
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief negative number
|
||||
|
@ -58,13 +59,13 @@ exports.positiveNumber = function (value, info, lang) {
|
|||
|
||||
exports.negativeNumber = function (value, info, lang) {
|
||||
if (0.0 <= value) {
|
||||
error = new ArangoError();
|
||||
error.errorNum = internal.errors.ERROR_ARANGO_VALIDATION_FAILED.code;
|
||||
var error = new arangodb.ArangoError();
|
||||
error.errorNum = arangodb.ERROR_ARANGO_VALIDATION_FAILED;
|
||||
error.errorMessage = "number must be negative";
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief zero
|
||||
|
@ -72,13 +73,13 @@ exports.negativeNumber = function (value, info, lang) {
|
|||
|
||||
exports.zeroNumber = function (value, info, lang) {
|
||||
if (value === 0.0) {
|
||||
error = new ArangoError();
|
||||
error.errorNum = internal.errors.ERROR_ARANGO_VALIDATION_FAILED.code;
|
||||
var error = new arangodb.ArangoError();
|
||||
error.errorNum = arangodb.ERROR_ARANGO_VALIDATION_FAILED;
|
||||
error.errorMessage = "number must be zero";
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief non-positive number
|
||||
|
@ -86,13 +87,13 @@ exports.zeroNumber = function (value, info, lang) {
|
|||
|
||||
exports.nonPositiveNumber = function (value, info, lang) {
|
||||
if (0.0 < value) {
|
||||
error = new ArangoError();
|
||||
error.errorNum = internal.errors.ERROR_ARANGO_VALIDATION_FAILED.code;
|
||||
var error = new arangodb.ArangoError();
|
||||
error.errorNum = arangodb.ERROR_ARANGO_VALIDATION_FAILED;
|
||||
error.errorMessage = "number must be non-positive";
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief non-negative number
|
||||
|
@ -100,13 +101,13 @@ exports.nonPositiveNumber = function (value, info, lang) {
|
|||
|
||||
exports.nonNegativeNumber = function (value, info, lang) {
|
||||
if (value < 0.0) {
|
||||
error = new ArangoError();
|
||||
error.errorNum = internal.errors.ERROR_ARANGO_VALIDATION_FAILED.code;
|
||||
var error = new arangodb.ArangoError();
|
||||
error.errorNum = arangodb.ERROR_ARANGO_VALIDATION_FAILED;
|
||||
error.errorMessage = "number must be non-negative";
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief zero
|
||||
|
@ -114,13 +115,13 @@ exports.nonNegativeNumber = function (value, info, lang) {
|
|||
|
||||
exports.nonZeroNumber = function (value, info, lang) {
|
||||
if (value !== 0.0) {
|
||||
error = new ArangoError();
|
||||
error.errorNum = internal.errors.ERROR_ARANGO_VALIDATION_FAILED.code;
|
||||
var error = new arangodb.ArangoError();
|
||||
error.errorNum = arangodb.ERROR_ARANGO_VALIDATION_FAILED;
|
||||
error.errorMessage = "number must be non-zero";
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
vars: true,
|
||||
white: true,
|
||||
plusplus: true */
|
||||
/*global require, db, edges, ModuleCache, Module,
|
||||
/*global require, db, edges, Module,
|
||||
ArangoCollection, ArangoDatabase,
|
||||
ArangoError, ShapedJson,
|
||||
SYS_DEFINE_ACTION */
|
||||
|
|
|
@ -92,9 +92,9 @@
|
|||
}
|
||||
|
||||
|
||||
if (FS_EXISTS(versionFile)) {
|
||||
if (internal.exists(versionFile)) {
|
||||
// VERSION file exists, read its contents
|
||||
var versionInfo = SYS_READ(versionFile);
|
||||
var versionInfo = internal.read(versionFile);
|
||||
|
||||
if (versionInfo != '') {
|
||||
var versionValues = JSON.parse(versionInfo);
|
||||
|
@ -342,13 +342,13 @@
|
|||
|
||||
var currentVersion = parseFloat(currentServerVersion[1]);
|
||||
|
||||
if (! FS_EXISTS(versionFile)) {
|
||||
if (! internal.exists(versionFile)) {
|
||||
console.info("No version information file found in database directory.");
|
||||
return runUpgrade(currentVersion);
|
||||
}
|
||||
|
||||
// VERSION file exists, read its contents
|
||||
var versionInfo = SYS_READ(versionFile);
|
||||
var versionInfo = internal.read(versionFile);
|
||||
if (versionInfo != '') {
|
||||
var versionValues = JSON.parse(versionInfo);
|
||||
if (versionValues && versionValues.version && ! isNaN(versionValues.version)) {
|
||||
|
|
|
@ -158,6 +158,58 @@ static void InitialiseLockFiles (void) {
|
|||
Initialised = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief lists the directory tree
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void ListTreeRecursively (char const* full,
|
||||
char const* path,
|
||||
TRI_vector_string_t* result) {
|
||||
size_t i;
|
||||
size_t j;
|
||||
TRI_vector_string_t dirs = TRI_FilesDirectory(full);
|
||||
|
||||
for (j = 0; j < 2; ++j) {
|
||||
for (i = 0; i < dirs._length; ++i) {
|
||||
char const* filename = dirs._buffer[i];
|
||||
char* newfull = TRI_Concatenate2File(full, filename);
|
||||
char* newpath;
|
||||
|
||||
if (*path) {
|
||||
newpath = TRI_Concatenate2File(path, filename);
|
||||
}
|
||||
else {
|
||||
newpath = TRI_DuplicateString(filename);
|
||||
}
|
||||
|
||||
if (j == 0) {
|
||||
if (TRI_IsDirectory(newfull)) {
|
||||
TRI_PushBackVectorString(result, newpath);
|
||||
|
||||
if (! TRI_IsSymbolicLink(newfull)) {
|
||||
ListTreeRecursively(newfull, newpath, result);
|
||||
}
|
||||
}
|
||||
else {
|
||||
TRI_FreeString(TRI_CORE_MEM_ZONE, newpath);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (! TRI_IsDirectory(newfull)) {
|
||||
TRI_PushBackVectorString(result, newpath);
|
||||
}
|
||||
else {
|
||||
TRI_FreeString(TRI_CORE_MEM_ZONE, newpath);
|
||||
}
|
||||
}
|
||||
|
||||
TRI_FreeString(TRI_CORE_MEM_ZONE, newfull);
|
||||
}
|
||||
}
|
||||
|
||||
TRI_DestroyVectorString(&dirs);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -233,6 +285,19 @@ bool TRI_IsDirectory (char const* path) {
|
|||
return (res == 0) && ((stbuf.st_mode & S_IFMT) == S_IFDIR);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief checks if path is a symbolic link
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TRI_IsSymbolicLink (char const* path) {
|
||||
struct stat stbuf;
|
||||
int res;
|
||||
|
||||
res = lstat(path, &stbuf);
|
||||
|
||||
return (res == 0) && ((stbuf.st_mode & S_IFMT) == S_IFLNK);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief checks if file exists
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -517,6 +582,21 @@ TRI_vector_string_t TRI_FilesDirectory (char const* path) {
|
|||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief lists the directory tree including files and directories
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_vector_string_t TRI_FullTreeDirectory (char const* path) {
|
||||
TRI_vector_string_t result;
|
||||
|
||||
TRI_InitVectorString(&result, TRI_CORE_MEM_ZONE);
|
||||
|
||||
TRI_PushBackVectorString(&result, TRI_DuplicateString(""));
|
||||
ListTreeRecursively(path, "", &result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief renames a file
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -69,6 +69,12 @@ int64_t TRI_SizeFile (char const* path);
|
|||
|
||||
bool TRI_IsDirectory (char const* path);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief checks if path is a symbolic link
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TRI_IsSymbolicLink (char const* path);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief checks if file exists
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -123,6 +129,12 @@ char* TRI_Concatenate3File (char const* path1, char const* path2, char const* na
|
|||
|
||||
TRI_vector_string_t TRI_FilesDirectory (char const* path);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief lists the directory tree including files and directories
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_vector_string_t TRI_FullTreeDirectory (char const* path);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief renames a file
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -223,8 +223,13 @@ bool ClientConnection::read (StringBuffer& stringBuffer) {
|
|||
|
||||
int lenRead = ::read(_socket, buffer, READBUFFER_SIZE - 1);
|
||||
|
||||
if (lenRead <= 0) {
|
||||
// error: stop reading
|
||||
if (lenRead == -1) {
|
||||
// error occurred
|
||||
return false;
|
||||
}
|
||||
|
||||
if (lenRead == 0) {
|
||||
// nothing more to read
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue