mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'sharding' of ssh://github.com/triAGENS/ArangoDB into sharding
This commit is contained in:
commit
c1ac5eeecf
|
@ -358,6 +358,7 @@ SHELL_COMMON = \
|
|||
@top_srcdir@/js/common/tests/shell-collection.js \
|
||||
@top_srcdir@/js/common/tests/shell-collection-volatile.js \
|
||||
@top_srcdir@/js/common/tests/shell-crypto.js \
|
||||
@top_srcdir@/js/common/tests/shell-noncluster-collection.js \
|
||||
@top_srcdir@/js/common/tests/shell-noncluster-database.js \
|
||||
@top_srcdir@/js/common/tests/shell-document.js \
|
||||
@top_srcdir@/js/common/tests/shell-download.js \
|
||||
|
|
|
@ -2298,11 +2298,20 @@ template<bool WR, bool WD> static bool ChecksumCalculator (TRI_doc_mptr_t const*
|
|||
/// If the optional argument @FA{withData} is set to @LIT{true}, then the
|
||||
/// actual document data is also checksummed. Including the document data in
|
||||
/// checksumming will make the calculation slower, but is more accurate.
|
||||
///
|
||||
/// Note: this method is not available in a cluster.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static v8::Handle<v8::Value> JS_ChecksumCollection (v8::Arguments const& argv) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
#ifdef TRI_ENABLE_CLUSTER
|
||||
if (ServerState::instance()->isCoordinator()) {
|
||||
// renaming a collection in a cluster is unsupported
|
||||
TRI_V8_EXCEPTION(scope, TRI_ERROR_CLUSTER_UNSUPPORTED);
|
||||
}
|
||||
#endif
|
||||
|
||||
TRI_vocbase_col_t const* col;
|
||||
col = TRI_UnwrapClass<TRI_vocbase_col_t>(argv.Holder(), TRI_GetVocBaseColType());
|
||||
|
||||
|
|
|
@ -7204,6 +7204,8 @@ static v8::Handle<v8::Value> JS_RemoveVocbaseCol (v8::Arguments const& argv) {
|
|||
///
|
||||
/// If renaming fails for any reason, an error is thrown.
|
||||
///
|
||||
/// Note: this method is not available in a cluster.
|
||||
///
|
||||
/// @EXAMPLES
|
||||
///
|
||||
/// @verbinclude shell_collection-rename
|
||||
|
@ -7216,7 +7218,14 @@ static v8::Handle<v8::Value> JS_RenameVocbaseCol (v8::Arguments const& argv) {
|
|||
TRI_V8_EXCEPTION_USAGE(scope, "rename(<name>)");
|
||||
}
|
||||
|
||||
string name = TRI_ObjectToString(argv[0]);
|
||||
#ifdef TRI_ENABLE_CLUSTER
|
||||
if (ServerState::instance()->isCoordinator()) {
|
||||
// renaming a collection in a cluster is unsupported
|
||||
TRI_V8_EXCEPTION(scope, TRI_ERROR_CLUSTER_UNSUPPORTED);
|
||||
}
|
||||
#endif
|
||||
|
||||
string const name = TRI_ObjectToString(argv[0]);
|
||||
|
||||
// second parameter "override" is to override renaming restrictions, e.g.
|
||||
// renaming from a system collection name to a non-system collection name and
|
||||
|
@ -7417,11 +7426,20 @@ static v8::Handle<v8::Value> JS_RevisionVocbaseCol (v8::Arguments const& argv) {
|
|||
/// read-only datafile). The purpose of the rotation is to include the
|
||||
/// datafile in a following compaction run and perform earlier garbage
|
||||
/// collection.
|
||||
///
|
||||
/// Note: this method is not available in a cluster.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static v8::Handle<v8::Value> JS_RotateVocbaseCol (v8::Arguments const& argv) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
#ifdef TRI_ENABLE_CLUSTER
|
||||
if (ServerState::instance()->isCoordinator()) {
|
||||
// renaming a collection in a cluster is unsupported
|
||||
TRI_V8_EXCEPTION(scope, TRI_ERROR_CLUSTER_UNSUPPORTED);
|
||||
}
|
||||
#endif
|
||||
|
||||
v8::Handle<v8::Object> err;
|
||||
TRI_vocbase_col_t const* collection = UseCollection(argv.Holder(), &err);
|
||||
|
||||
|
|
|
@ -750,6 +750,8 @@ function get_api_collections (req, res) {
|
|||
///
|
||||
/// - `revision`: The collection revision id as a string.
|
||||
///
|
||||
/// Note: this method is not available in a cluster.
|
||||
///
|
||||
/// @RESTRETURNCODES
|
||||
///
|
||||
/// @RESTRETURNCODE{400}
|
||||
|
@ -1301,6 +1303,8 @@ function put_api_collection_rename (req, res, collection) {
|
|||
///
|
||||
/// - `result`: will be `true` if rotation succeeded
|
||||
///
|
||||
/// Note: this method is not available in a cluster.
|
||||
///
|
||||
/// @RESTRETURNCODES
|
||||
///
|
||||
/// @RESTRETURNCODE{400}
|
||||
|
|
|
@ -311,6 +311,8 @@ function get_api_index (req, res) {
|
|||
/// `ignoreNull` is true, then documents with a null in `location` or at
|
||||
/// least one null in `latitude` or `longitude` are ignored.
|
||||
///
|
||||
/// Note: unique indexes on non-shard keys are not supported in a cluster.
|
||||
///
|
||||
/// @RESTRETURNCODES
|
||||
///
|
||||
/// @RESTRETURNCODE{200}
|
||||
|
@ -386,6 +388,8 @@ function get_api_index (req, res) {
|
|||
///
|
||||
/// - `unique`: If `true`, then create a unique index.
|
||||
///
|
||||
/// Note: unique indexes on non-shard keys are not supported in a cluster.
|
||||
///
|
||||
/// @RESTRETURNCODES
|
||||
///
|
||||
/// @RESTRETURNCODE{200}
|
||||
|
@ -466,6 +470,8 @@ function get_api_index (req, res) {
|
|||
///
|
||||
/// - `unique`: If `true`, then create a unique index.
|
||||
///
|
||||
/// Note: unique indexes on non-shard keys are not supported in a cluster.
|
||||
///
|
||||
/// @RESTRETURNCODES
|
||||
///
|
||||
/// @RESTRETURNCODE{200}
|
||||
|
@ -674,6 +680,9 @@ function get_api_index (req, res) {
|
|||
/// - fulltext indexes
|
||||
/// - bitarray indexes
|
||||
///
|
||||
/// Note also that unique indexes on non-shard keys are not supported in a
|
||||
/// cluster.
|
||||
///
|
||||
/// @RESTRETURNCODES
|
||||
///
|
||||
/// @RESTRETURNCODE{200}
|
||||
|
|
|
@ -318,6 +318,7 @@ ArangoCollection.prototype.properties = function (properties) {
|
|||
var attributes = {
|
||||
"doCompact": true,
|
||||
"journalSize": true,
|
||||
"isVolatile": false,
|
||||
"waitForSync": true,
|
||||
"shardKeys": false,
|
||||
"numberOfShards": false,
|
||||
|
@ -350,15 +351,13 @@ ArangoCollection.prototype.properties = function (properties) {
|
|||
|
||||
var result = { };
|
||||
for (a in attributes) {
|
||||
if (attributes.hasOwnProperty(a) && requestResult.hasOwnProperty(a)) {
|
||||
if (attributes.hasOwnProperty(a) &&
|
||||
requestResult.hasOwnProperty(a) &&
|
||||
requestResult[a] !== undefined) {
|
||||
result[a] = requestResult[a];
|
||||
}
|
||||
}
|
||||
|
||||
if (requestResult.keyOptions !== undefined) {
|
||||
result.keyOptions = requestResult.keyOptions;
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,6 +1,70 @@
|
|||
.scenarioImage{
|
||||
@extend %clickable;
|
||||
height : 70%;
|
||||
width : auto;
|
||||
|
||||
.machineClass {
|
||||
@extend %clear-float;
|
||||
padding: 10px;
|
||||
float: left;
|
||||
background-color: #E1E1E1;
|
||||
width: 311px;
|
||||
height: 175px;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.scenarioBox {
|
||||
position: absolute;
|
||||
margin-top: 10px;
|
||||
width: auto;
|
||||
height: 65px;
|
||||
left: 10px;
|
||||
right: 10px;
|
||||
@include border-radius(3px 3px 0 0);
|
||||
border: 1px solid rgba(0, 0, 0, 0.19);
|
||||
background-color: white;
|
||||
|
||||
&.bottomBox {
|
||||
bottom: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.scenarioBoxHeader {
|
||||
width: auto;
|
||||
height: 5px;
|
||||
line-height: 5px;
|
||||
text-align: right;
|
||||
margin-top: -5px;
|
||||
padding-bottom: 5px;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.19);
|
||||
}
|
||||
|
||||
.scenarioBoxText {
|
||||
width: auto;
|
||||
font-size: 30px;
|
||||
font-weight: 700;
|
||||
text-align: center;
|
||||
margin-top: 17px;
|
||||
}
|
||||
|
||||
.scenarioMachine {
|
||||
@extend %pull-left;
|
||||
position: relative;
|
||||
margin-right: 20px;
|
||||
height: 177px;
|
||||
width: 87px;
|
||||
@include border-radius(3px 3px 0 0);
|
||||
border: 1px solid rgba(0, 0, 0, 0.19);
|
||||
background-color: white;
|
||||
&:last-child {
|
||||
margin-right: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.scenarioSingleMachine {
|
||||
@extend %clear-float;
|
||||
border-radius: 3px 3px 0 0;
|
||||
border: 1px solid rgba(0, 0, 0, 0.19);
|
||||
background-color: white;
|
||||
|
||||
.scenarioMachine {
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,13 +3,13 @@ body, input, textarea, .page-title span, .pingback a.url {
|
|||
font-family: 'Open Sans', sans-serif !important;
|
||||
font-weight: 400; }
|
||||
|
||||
ul.link-dropdown-menu, ul.user-dropdown-menu, ul.gv-dropdown-menu, div.navlogo, ul.navlist li, div.footer-left, li.tile, li.bigtile, li.tile a span.add-Icon, li.bigtile a span.add-Icon {
|
||||
ul.link-dropdown-menu, ul.user-dropdown-menu, ul.gv-dropdown-menu, div.navlogo, ul.navlist li, div.footer-left, li.tile, li.bigtile, li.tile a span.add-Icon, li.bigtile a span.add-Icon, .scenarioMachine {
|
||||
float: left; }
|
||||
|
||||
div.navmenu, div.footer-right, li.tile div.iconSet span, li.bigtile div.iconSet span {
|
||||
float: right; }
|
||||
|
||||
ul.tileList:after, div.resizecontainer:after {
|
||||
ul.tileList:after, div.resizecontainer:after, .machineClass:after, .scenarioSingleMachine:after {
|
||||
clear: both;
|
||||
content: ".";
|
||||
display: block;
|
||||
|
@ -17,7 +17,7 @@ ul.tileList:after, div.resizecontainer:after {
|
|||
height: 0px;
|
||||
visibility: hidden; }
|
||||
|
||||
.addButton, .deleteButton, a.headerButton, div.toolbox > div.gv_action_button, li.tile div.iconSet span, li.bigtile div.iconSet span, .contentDiv .icon, div.headerDropdown.headerDropdown input[type=checkbox].css-checkbox + label.css-label, .scenarioImage {
|
||||
.addButton, .deleteButton, a.headerButton, div.toolbox > div.gv_action_button, li.tile div.iconSet span, li.bigtile div.iconSet span, .contentDiv .icon, div.headerDropdown.headerDropdown input[type=checkbox].css-checkbox + label.css-label {
|
||||
cursor: pointer; }
|
||||
|
||||
nav.navbar, footer.footer {
|
||||
|
@ -780,6 +780,61 @@ select.filterSelect {
|
|||
margin-top: 1px;
|
||||
margin-left: 10px !important; }
|
||||
|
||||
.scenarioImage {
|
||||
height: 70%;
|
||||
width: auto; }
|
||||
.machineClass {
|
||||
padding: 10px;
|
||||
float: left;
|
||||
background-color: #E1E1E1;
|
||||
width: 311px;
|
||||
height: 175px;
|
||||
margin-left: 8px; }
|
||||
|
||||
.scenarioBox {
|
||||
position: absolute;
|
||||
margin-top: 10px;
|
||||
width: auto;
|
||||
height: 65px;
|
||||
left: 10px;
|
||||
right: 10px;
|
||||
-moz-border-radius: 3px 3px 0 0;
|
||||
-webkit-border-radius: 3px 3px 0 0;
|
||||
border-radius: 3px 3px 0 0;
|
||||
border: 1px solid rgba(0, 0, 0, 0.19);
|
||||
background-color: white; }
|
||||
.scenarioBox.bottomBox {
|
||||
bottom: 10px; }
|
||||
|
||||
.scenarioBoxHeader {
|
||||
width: auto;
|
||||
height: 5px;
|
||||
line-height: 5px;
|
||||
text-align: right;
|
||||
margin-top: -5px;
|
||||
padding-bottom: 5px;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.19); }
|
||||
|
||||
.scenarioBoxText {
|
||||
width: auto;
|
||||
font-size: 30px;
|
||||
font-weight: 700;
|
||||
text-align: center;
|
||||
margin-top: 17px; }
|
||||
|
||||
.scenarioMachine {
|
||||
position: relative;
|
||||
margin-right: 20px;
|
||||
height: 177px;
|
||||
width: 87px;
|
||||
-moz-border-radius: 3px 3px 0 0;
|
||||
-webkit-border-radius: 3px 3px 0 0;
|
||||
border-radius: 3px 3px 0 0;
|
||||
border: 1px solid rgba(0, 0, 0, 0.19);
|
||||
background-color: white; }
|
||||
.scenarioMachine:last-child {
|
||||
margin-right: 0px; }
|
||||
|
||||
.scenarioSingleMachine {
|
||||
border-radius: 3px 3px 0 0;
|
||||
border: 1px solid rgba(0, 0, 0, 0.19);
|
||||
background-color: white; }
|
||||
.scenarioSingleMachine .scenarioMachine {
|
||||
border: 1px solid transparent; }
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//shared
|
||||
@import "shared";
|
||||
// the images used in the planner
|
||||
@import "plannerImages";
|
||||
@import "plannerImages";
|
||||
|
|
|
@ -1,52 +1,96 @@
|
|||
<script id="planScenarioSelector.ejs" type="text/template">
|
||||
<ul class="thumbnails2">
|
||||
<div class="headerBar">
|
||||
<a class="arangoHeader">Cluster Management</a>
|
||||
<div class="headerButtonBar pull-right">
|
||||
<ul class="headerButtonList">
|
||||
<li class="enabled">
|
||||
|
||||
<% var box = function(c, btm) { %>
|
||||
<div class="scenarioBox<%=btm?' bottomBox':''%>">
|
||||
<div class="scenarioBoxHeader">...</div>
|
||||
<div class="scenarioBoxText"><%=c%></div>
|
||||
</div>
|
||||
<% }
|
||||
var row = function(c, d, noHead) { %>
|
||||
<div class="scenarioMachine">
|
||||
<% if (!noHead) { %>
|
||||
<div class="scenarioBoxHeader">...</div>
|
||||
<% } %>
|
||||
<%
|
||||
if (c) {box("C");}
|
||||
if (d) {box("D", true);}
|
||||
%>
|
||||
</div>
|
||||
<%
|
||||
}
|
||||
%>
|
||||
|
||||
|
||||
<ul class="thumbnails2">
|
||||
<div class="headerBar">
|
||||
<a class="arangoHeader">Cluster Management</a>
|
||||
<div class="headerButtonBar pull-right">
|
||||
<ul class="headerButtonList">
|
||||
<li class="enabled">
|
||||
<a id="importConnectInfo" class="headerButton">
|
||||
<span class="icon_arangodb_youtube" title="Connect to Cluster"></span>
|
||||
</a>
|
||||
<a id="importRunInfo" class="headerButton">
|
||||
<span class="icon_arangodb_export" title="Upload Cluster Information"></span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="runinfoDropdownImport" class="dropdownImport">
|
||||
<div class="queryline">
|
||||
<input id="importRunInfoFile" name="importRunInfo" type="file" accept="application/json" />
|
||||
<button id="confirmRunInfoImport" class="button-success btn-old-padding" style="float:right">
|
||||
<img id="uploadIndicator" style="display: none;" src="img/ajax-loader.gif"/>Import Plan
|
||||
</button>
|
||||
<div id="runinfoDropdownImport" class="dropdownImport">
|
||||
<div class="queryline">
|
||||
<input id="importRunInfoFile" name="importRunInfo" type="file" accept="application/json" />
|
||||
<button id="confirmRunInfoImport" class="button-success btn-old-padding" style="float:right">
|
||||
<img id="uploadIndicator" style="display: none;" src="img/ajax-loader.gif"/>Import Plan
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="connectDropdownImport" class="dropdownImport">
|
||||
<div class="queryline">
|
||||
<input id="connectInfoFile" name="connectionInfo" type="file" accept="application/json" />
|
||||
<button id="confirmConnectImport" class="button-success btn-old-padding" style="float:right">
|
||||
<img id="connectIndicator" style="display: none;" src="img/ajax-loader.gif"/>Connect to Cluster
|
||||
</button>
|
||||
<div id="connectDropdownImport" class="dropdownImport">
|
||||
<div class="queryline">
|
||||
<input id="connectInfoFile" name="connectionInfo" type="file" accept="application/json" />
|
||||
<button id="confirmConnectImport" class="button-success btn-old-padding" style="float:right">
|
||||
<img id="connectIndicator" style="display: none;" src="img/ajax-loader.gif"/>Connect to Cluster
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<div class="tileList">
|
||||
<legend class="gv_inner">Please select a cluster scenario:</legend>
|
||||
<div class="tileList">
|
||||
<legend class="gv_inner">Please select a cluster scenario:</legend>
|
||||
|
||||
<li class="bigtile" id="multiServerSymmetrical">
|
||||
<img src="img/multiMachineSym.png" class="scenarioImage" alt="">
|
||||
<li class="bigtile" id="multiServerSymmetrical">
|
||||
<div id="multiMachineSym" class="machineClass">
|
||||
<%
|
||||
row(true, true);
|
||||
row(true, true);
|
||||
row(true, true);
|
||||
%>
|
||||
</div>
|
||||
<h5 class="collectionName">Multi Machine Symmetrical</h5>
|
||||
</li>
|
||||
<li class="bigtile" id="multiServerAsymmetrical">
|
||||
<img src="img/multiMachineAsym.png" class="scenarioImage" alt="">
|
||||
</li>
|
||||
<li class="bigtile" id="multiServerAsymmetrical">
|
||||
<div id="multiMachineAsym" class="machineClass">
|
||||
<%
|
||||
row(true, true);
|
||||
row(false, true);
|
||||
row(true, false);
|
||||
%>
|
||||
</div>
|
||||
<h5 class="collectionName">Multi Machine Asymmetrical</h5>
|
||||
</li>
|
||||
<li class="bigtile" id="singleServer">
|
||||
<img src="img/singleMachine.png" class="scenarioImage" alt="">
|
||||
</li>
|
||||
<li class="bigtile" id="singleServer">
|
||||
<div id="singleMachine" class="machineClass">
|
||||
<div class="scenarioSingleMachine">
|
||||
<div class="scenarioBoxHeader">...</div>
|
||||
<%
|
||||
row(true, true, true);
|
||||
row(true, true, true);
|
||||
row(true, false, true);
|
||||
%>
|
||||
</div>
|
||||
</div>
|
||||
<h5 class="collectionName">Single Machine</h5>
|
||||
</li>
|
||||
</div>
|
||||
</li>
|
||||
</div>
|
||||
|
||||
</script>
|
||||
|
|
|
@ -317,6 +317,7 @@ ArangoCollection.prototype.properties = function (properties) {
|
|||
var attributes = {
|
||||
"doCompact": true,
|
||||
"journalSize": true,
|
||||
"isVolatile": false,
|
||||
"waitForSync": true,
|
||||
"shardKeys": false,
|
||||
"numberOfShards": false,
|
||||
|
@ -349,15 +350,13 @@ ArangoCollection.prototype.properties = function (properties) {
|
|||
|
||||
var result = { };
|
||||
for (a in attributes) {
|
||||
if (attributes.hasOwnProperty(a) && requestResult.hasOwnProperty(a)) {
|
||||
if (attributes.hasOwnProperty(a) &&
|
||||
requestResult.hasOwnProperty(a) &&
|
||||
requestResult[a] !== undefined) {
|
||||
result[a] = requestResult[a];
|
||||
}
|
||||
}
|
||||
|
||||
if (requestResult.keyOptions !== undefined) {
|
||||
result.keyOptions = requestResult.keyOptions;
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
|
|
|
@ -631,64 +631,6 @@ function CollectionSuite () {
|
|||
db._drop(cn);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief rotate
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testRotate : function () {
|
||||
var cn = "example";
|
||||
|
||||
db._drop(cn);
|
||||
var c1 = db._create(cn);
|
||||
|
||||
c1.save({ _key: "test1" });
|
||||
var f = c1.figures();
|
||||
assertEqual(0, f.datafiles.count);
|
||||
|
||||
c1.rotate();
|
||||
|
||||
// must wait so the synchroniser can catch up
|
||||
require("internal").wait(5);
|
||||
|
||||
f = c1.figures();
|
||||
assertEqual(1, f.datafiles.count);
|
||||
|
||||
c1.save({ _key: "test2" });
|
||||
c1.rotate();
|
||||
|
||||
// must wait so the synchroniser can catch up
|
||||
require("internal").wait(5);
|
||||
|
||||
f = c1.figures();
|
||||
// we may have one or two datafiles, depending on the compaction
|
||||
assertTrue(f.datafiles.count >= 1);
|
||||
|
||||
c1.unload();
|
||||
|
||||
db._drop(cn);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief rotate w/o journal
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testRotateNoJournal : function () {
|
||||
var cn = "example";
|
||||
|
||||
db._drop(cn);
|
||||
var c1 = db._create(cn);
|
||||
|
||||
try {
|
||||
c1.rotate();
|
||||
fail();
|
||||
}
|
||||
catch (err) {
|
||||
assertEqual(ERRORS.ERROR_ARANGO_NO_JOURNAL.code, err.errorNum);
|
||||
}
|
||||
|
||||
db._drop(cn);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief figures
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -784,329 +726,6 @@ function CollectionSuite () {
|
|||
db._drop(cn);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief rename loaded collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testRenameLoaded : function () {
|
||||
var cn = "example";
|
||||
var nn = "example2";
|
||||
|
||||
db._drop(cn);
|
||||
db._drop(nn);
|
||||
var c1 = db._create(cn);
|
||||
|
||||
c1.save({ a : 1 });
|
||||
|
||||
assertTypeOf("string", c1._id);
|
||||
assertEqual(cn, c1.name());
|
||||
assertTypeOf("number", c1.status());
|
||||
assertEqual(ArangoCollection.TYPE_DOCUMENT, c1.type());
|
||||
assertTypeOf("number", c1.type());
|
||||
|
||||
var id = c1._id;
|
||||
|
||||
c1.rename(nn);
|
||||
|
||||
assertEqual(id, c1._id);
|
||||
assertEqual(nn, c1.name());
|
||||
assertTypeOf("number", c1.status());
|
||||
assertEqual(ArangoCollection.TYPE_DOCUMENT, c1.type());
|
||||
assertTypeOf("number", c1.type());
|
||||
|
||||
var c2 = db._collection(cn);
|
||||
|
||||
assertEqual(null, c2);
|
||||
|
||||
db._drop(nn);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief rename unloaded collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testRenameUnloaded : function () {
|
||||
var cn = "example";
|
||||
var nn = "example2";
|
||||
|
||||
db._drop(cn);
|
||||
db._drop(nn);
|
||||
var c1 = db._create(cn);
|
||||
|
||||
c1.save({ a : 1 });
|
||||
c1.unload();
|
||||
|
||||
assertTypeOf("string", c1._id);
|
||||
assertEqual(cn, c1.name());
|
||||
assertTypeOf("number", c1.status());
|
||||
assertEqual(ArangoCollection.TYPE_DOCUMENT, c1.type());
|
||||
assertTypeOf("number", c1.type());
|
||||
|
||||
var id = c1._id;
|
||||
|
||||
c1.rename(nn);
|
||||
|
||||
assertEqual(id, c1._id);
|
||||
assertEqual(nn, c1.name());
|
||||
assertTypeOf("number", c1.status());
|
||||
assertEqual(ArangoCollection.TYPE_DOCUMENT, c1.type());
|
||||
assertTypeOf("number", c1.type());
|
||||
|
||||
var c2 = db._collection(cn);
|
||||
|
||||
assertEqual(null, c2);
|
||||
|
||||
db._drop(nn);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief rename a collection to an already existing collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testRenameExisting : function () {
|
||||
var cn1 = "example";
|
||||
var cn2 = "example2";
|
||||
|
||||
db._drop(cn1);
|
||||
db._drop(cn2);
|
||||
var c1 = db._create(cn1);
|
||||
db._create(cn2);
|
||||
|
||||
try {
|
||||
c1.rename(cn2);
|
||||
}
|
||||
catch (err) {
|
||||
assertEqual(ERRORS.ERROR_ARANGO_DUPLICATE_NAME.code, err.errorNum);
|
||||
}
|
||||
db._drop(cn1);
|
||||
db._drop(cn2);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test checksum
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testChecksum : function () {
|
||||
var cn = "example";
|
||||
|
||||
db._drop(cn);
|
||||
var c1 = db._create(cn);
|
||||
|
||||
// empty collection, checksum should be 0
|
||||
var r1 = c1.checksum(true);
|
||||
assertTypeOf("string", r1.revision);
|
||||
assertTrue(r1.revision !== "");
|
||||
assertTrue(r1.revision.match(/^[0-9]+$/));
|
||||
assertTypeOf("number", r1.checksum);
|
||||
assertEqual(0, r1.checksum);
|
||||
|
||||
// inserting a doc, checksum should change
|
||||
c1.save({ a : 1 });
|
||||
var r2 = c1.checksum(true);
|
||||
assertNotEqual(r1.revision, r2.revision);
|
||||
assertTypeOf("string", r2.revision);
|
||||
assertTrue(r2.revision !== "");
|
||||
assertTrue(r2.revision.match(/^[0-9]+$/));
|
||||
assertTypeOf("number", r2.checksum);
|
||||
assertNotEqual(0, r2.checksum);
|
||||
|
||||
// inserting another doc, checksum should change
|
||||
c1.save({ a : 2 });
|
||||
var r3 = c1.checksum(true);
|
||||
assertNotEqual(r1.revision, r3.revision);
|
||||
assertNotEqual(r2.revision, r3.revision);
|
||||
assertTypeOf("string", r3.revision);
|
||||
assertTrue(r3.revision !== "");
|
||||
assertTrue(r3.revision.match(/^[0-9]+$/));
|
||||
assertTypeOf("number", r3.checksum);
|
||||
assertNotEqual(0, r3.checksum);
|
||||
assertNotEqual(r2.checksum, r3.checksum);
|
||||
|
||||
// test after unloading
|
||||
c1.unload();
|
||||
var r4 = c1.checksum(true);
|
||||
assertTypeOf("string", r4.revision);
|
||||
assertEqual(r3.revision, r4.revision);
|
||||
assertTypeOf("number", r4.checksum);
|
||||
assertNotEqual(0, r4.checksum);
|
||||
assertEqual(r3.checksum, r4.checksum);
|
||||
|
||||
// test withData
|
||||
var r5 = c1.checksum(true, true);
|
||||
assertTypeOf("string", r5.revision);
|
||||
assertEqual(r4.revision, r5.revision);
|
||||
assertTypeOf("number", r5.checksum);
|
||||
assertNotEqual(0, r5.checksum);
|
||||
assertNotEqual(r4.checksum, r5.checksum);
|
||||
|
||||
// test after truncation
|
||||
c1.truncate();
|
||||
var r6 = c1.checksum(true);
|
||||
assertTypeOf("string", r6.revision);
|
||||
assertNotEqual(r4.revision, r6.revision);
|
||||
assertNotEqual(r5.revision, r6.revision);
|
||||
assertTypeOf("number", r6.checksum);
|
||||
assertEqual(0, r6.checksum);
|
||||
|
||||
db._drop(cn);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test checksum
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testChecksumEdge : function () {
|
||||
var cn = "example";
|
||||
var vn = "example2";
|
||||
|
||||
db._drop(cn);
|
||||
db._drop(vn);
|
||||
db._create(vn);
|
||||
var c1 = db._createEdgeCollection(cn);
|
||||
|
||||
var r1 = c1.checksum(true);
|
||||
assertTypeOf("string", r1.revision);
|
||||
assertTrue(r1.revision !== "");
|
||||
assertTrue(r1.revision.match(/^[0-9]+$/));
|
||||
assertTypeOf("number", r1.checksum);
|
||||
assertEqual(0, r1.checksum);
|
||||
|
||||
c1.save(vn + "/1", vn + "/2", { a : 1 });
|
||||
var r2 = c1.checksum(true);
|
||||
assertNotEqual(r1.revision, r2.revision);
|
||||
assertTypeOf("string", r2.revision);
|
||||
assertTrue(r2.revision !== "");
|
||||
assertTrue(r2.revision.match(/^[0-9]+$/));
|
||||
assertTypeOf("number", r2.checksum);
|
||||
assertNotEqual(0, r2.checksum);
|
||||
|
||||
c1.save(vn + "/1", vn + "/2", { a : 2 });
|
||||
var r3 = c1.checksum(true);
|
||||
assertNotEqual(r1.revision, r3.revision);
|
||||
assertNotEqual(r2.revision, r3.revision);
|
||||
assertTypeOf("string", r3.revision);
|
||||
assertTrue(r3.revision !== "");
|
||||
assertTrue(r3.revision.match(/^[0-9]+$/));
|
||||
assertTypeOf("number", r3.checksum);
|
||||
assertNotEqual(0, r3.checksum);
|
||||
assertNotEqual(r2.checksum, r3.checksum);
|
||||
|
||||
c1.unload();
|
||||
var r4 = c1.checksum(true);
|
||||
assertTypeOf("string", r4.revision);
|
||||
assertEqual(r3.revision, r4.revision);
|
||||
assertTypeOf("number", r4.checksum);
|
||||
assertEqual(r3.checksum, r4.checksum);
|
||||
|
||||
// test withData
|
||||
var r5 = c1.checksum(true, true);
|
||||
assertTypeOf("string", r5.revision);
|
||||
assertEqual(r4.revision, r5.revision);
|
||||
assertTypeOf("number", r5.checksum);
|
||||
assertNotEqual(0, r5.checksum);
|
||||
assertNotEqual(r4.checksum, r5.checksum);
|
||||
|
||||
// test after truncation
|
||||
c1.truncate();
|
||||
var r6 = c1.checksum(true);
|
||||
assertTypeOf("string", r6.revision);
|
||||
assertNotEqual(r4.revision, r6.revision);
|
||||
assertNotEqual(r5.revision, r6.revision);
|
||||
assertTypeOf("number", r6.checksum);
|
||||
assertEqual(0, r6.checksum);
|
||||
|
||||
db._drop(cn);
|
||||
db._drop(vn);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test checksum two different collections
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testChecksumDifferent : function () {
|
||||
var cn1 = "example";
|
||||
var cn2 = "example2";
|
||||
|
||||
db._drop(cn1);
|
||||
db._drop(cn2);
|
||||
var c1 = db._create(cn1);
|
||||
var c2 = db._create(cn2);
|
||||
|
||||
// collections are empty, checksums are identical
|
||||
var cs1 = c1.checksum().checksum;
|
||||
var cs2 = c2.checksum().checksum;
|
||||
|
||||
assertEqual(cs1, cs2);
|
||||
|
||||
c1.save({ _key: "foobar", value: 123 });
|
||||
c2.save({ _key: "foobar", value: 123 });
|
||||
|
||||
// keys are the same
|
||||
cs1 = c1.checksum().checksum;
|
||||
cs2 = c2.checksum().checksum;
|
||||
|
||||
assertEqual(cs1, cs2);
|
||||
|
||||
// data is the same
|
||||
cs1 = c1.checksum(false, true).checksum;
|
||||
cs2 = c2.checksum(false, true).checksum;
|
||||
|
||||
assertEqual(cs1, cs2);
|
||||
|
||||
// revisions are different
|
||||
cs1 = c1.checksum(true, false).checksum;
|
||||
cs2 = c2.checksum(true, false).checksum;
|
||||
|
||||
assertNotEqual(cs1, cs2);
|
||||
|
||||
// revisions are still different
|
||||
cs1 = c1.checksum(true, true).checksum;
|
||||
cs2 = c2.checksum(true, true).checksum;
|
||||
|
||||
assertNotEqual(cs1, cs2);
|
||||
|
||||
// update document in c1, keep data
|
||||
c1.replace("foobar", { value: 123 });
|
||||
|
||||
// keys are still the same
|
||||
cs1 = c1.checksum().checksum;
|
||||
cs2 = c2.checksum().checksum;
|
||||
|
||||
assertEqual(cs1, cs2);
|
||||
|
||||
// data is still the same
|
||||
cs1 = c1.checksum(false, true).checksum;
|
||||
cs2 = c2.checksum(false, true).checksum;
|
||||
|
||||
assertEqual(cs1, cs2);
|
||||
|
||||
// revisions are still different
|
||||
cs1 = c1.checksum(true, false).checksum;
|
||||
cs2 = c2.checksum(true, false).checksum;
|
||||
|
||||
// update document in c1, changing data
|
||||
c1.replace("foobar", { value: 124 });
|
||||
|
||||
// keys are still the same
|
||||
cs1 = c1.checksum().checksum;
|
||||
cs2 = c2.checksum().checksum;
|
||||
|
||||
assertEqual(cs1, cs2);
|
||||
|
||||
// data is not the same
|
||||
cs1 = c1.checksum(false, true).checksum;
|
||||
cs2 = c2.checksum(false, true).checksum;
|
||||
|
||||
assertNotEqual(cs1, cs2);
|
||||
|
||||
// revisions are still different
|
||||
cs1 = c1.checksum(true, false).checksum;
|
||||
cs2 = c2.checksum(true, false).checksum;
|
||||
|
||||
db._drop(cn1);
|
||||
db._drop(cn2);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test revision id
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1417,69 +1036,17 @@ function CollectionSuite () {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testSystemSpecial : function () {
|
||||
[ '_trx', '_users' ].forEach(function(cn) {
|
||||
var c = db._collection(cn);
|
||||
var cn = "_users";
|
||||
var c = db._collection(cn);
|
||||
|
||||
// drop
|
||||
try {
|
||||
c.drop();
|
||||
fail();
|
||||
}
|
||||
catch (err1) {
|
||||
assertEqual(ERRORS.ERROR_FORBIDDEN.code, err1.errorNum);
|
||||
}
|
||||
|
||||
// rename
|
||||
var cn = "example";
|
||||
db._drop(cn);
|
||||
|
||||
try {
|
||||
c.rename(cn);
|
||||
fail();
|
||||
}
|
||||
catch (err2) {
|
||||
assertEqual(ERRORS.ERROR_FORBIDDEN.code, err2.errorNum);
|
||||
}
|
||||
|
||||
// unload is allowed
|
||||
c.unload();
|
||||
|
||||
});
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test special properties of replication collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testSpecialReplication : function () {
|
||||
var repl = db._collection('_replication');
|
||||
|
||||
// drop is not allowed
|
||||
// drop
|
||||
try {
|
||||
repl.drop();
|
||||
c.drop();
|
||||
fail();
|
||||
}
|
||||
catch (err1) {
|
||||
assertEqual(ERRORS.ERROR_FORBIDDEN.code, err1.errorNum);
|
||||
}
|
||||
|
||||
// rename is not allowed
|
||||
try {
|
||||
var cn = "example";
|
||||
db._drop(cn);
|
||||
repl.rename(cn);
|
||||
}
|
||||
catch (err2) {
|
||||
assertEqual(ERRORS.ERROR_FORBIDDEN.code, err2.errorNum);
|
||||
}
|
||||
|
||||
// unload is not allowed
|
||||
try {
|
||||
repl.unload();
|
||||
}
|
||||
catch (err3) {
|
||||
assertEqual(ERRORS.ERROR_FORBIDDEN.code, err3.errorNum);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -0,0 +1,518 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test the collection interface
|
||||
///
|
||||
/// @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 2012, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var jsunity = require("jsunity");
|
||||
|
||||
var arangodb = require("org/arangodb");
|
||||
var internal = require("internal");
|
||||
|
||||
var ArangoCollection = arangodb.ArangoCollection;
|
||||
var db = arangodb.db;
|
||||
var ERRORS = arangodb.errors;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- collection methods
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test suite: collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function CollectionSuite () {
|
||||
return {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief rotate
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testRotate : function () {
|
||||
var cn = "example";
|
||||
|
||||
db._drop(cn);
|
||||
var c1 = db._create(cn);
|
||||
|
||||
c1.save({ _key: "test1" });
|
||||
var f = c1.figures();
|
||||
assertEqual(0, f.datafiles.count);
|
||||
|
||||
c1.rotate();
|
||||
|
||||
// must wait so the synchroniser can catch up
|
||||
require("internal").wait(5);
|
||||
|
||||
f = c1.figures();
|
||||
assertEqual(1, f.datafiles.count);
|
||||
|
||||
c1.save({ _key: "test2" });
|
||||
c1.rotate();
|
||||
|
||||
// must wait so the synchroniser can catch up
|
||||
require("internal").wait(5);
|
||||
|
||||
f = c1.figures();
|
||||
// we may have one or two datafiles, depending on the compaction
|
||||
assertTrue(f.datafiles.count >= 1);
|
||||
|
||||
c1.unload();
|
||||
|
||||
db._drop(cn);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief rotate w/o journal
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testRotateNoJournal : function () {
|
||||
var cn = "example";
|
||||
|
||||
db._drop(cn);
|
||||
var c1 = db._create(cn);
|
||||
|
||||
try {
|
||||
c1.rotate();
|
||||
fail();
|
||||
}
|
||||
catch (err) {
|
||||
assertEqual(ERRORS.ERROR_ARANGO_NO_JOURNAL.code, err.errorNum);
|
||||
}
|
||||
|
||||
db._drop(cn);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief rename loaded collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testRenameLoaded : function () {
|
||||
var cn = "example";
|
||||
var nn = "example2";
|
||||
|
||||
db._drop(cn);
|
||||
db._drop(nn);
|
||||
var c1 = db._create(cn);
|
||||
|
||||
c1.save({ a : 1 });
|
||||
|
||||
assertTypeOf("string", c1._id);
|
||||
assertEqual(cn, c1.name());
|
||||
assertTypeOf("number", c1.status());
|
||||
assertEqual(ArangoCollection.TYPE_DOCUMENT, c1.type());
|
||||
assertTypeOf("number", c1.type());
|
||||
|
||||
var id = c1._id;
|
||||
|
||||
c1.rename(nn);
|
||||
|
||||
assertEqual(id, c1._id);
|
||||
assertEqual(nn, c1.name());
|
||||
assertTypeOf("number", c1.status());
|
||||
assertEqual(ArangoCollection.TYPE_DOCUMENT, c1.type());
|
||||
assertTypeOf("number", c1.type());
|
||||
|
||||
var c2 = db._collection(cn);
|
||||
|
||||
assertEqual(null, c2);
|
||||
|
||||
db._drop(nn);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief rename unloaded collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testRenameUnloaded : function () {
|
||||
var cn = "example";
|
||||
var nn = "example2";
|
||||
|
||||
db._drop(cn);
|
||||
db._drop(nn);
|
||||
var c1 = db._create(cn);
|
||||
|
||||
c1.save({ a : 1 });
|
||||
c1.unload();
|
||||
|
||||
assertTypeOf("string", c1._id);
|
||||
assertEqual(cn, c1.name());
|
||||
assertTypeOf("number", c1.status());
|
||||
assertEqual(ArangoCollection.TYPE_DOCUMENT, c1.type());
|
||||
assertTypeOf("number", c1.type());
|
||||
|
||||
var id = c1._id;
|
||||
|
||||
c1.rename(nn);
|
||||
|
||||
assertEqual(id, c1._id);
|
||||
assertEqual(nn, c1.name());
|
||||
assertTypeOf("number", c1.status());
|
||||
assertEqual(ArangoCollection.TYPE_DOCUMENT, c1.type());
|
||||
assertTypeOf("number", c1.type());
|
||||
|
||||
var c2 = db._collection(cn);
|
||||
|
||||
assertEqual(null, c2);
|
||||
|
||||
db._drop(nn);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief rename a collection to an already existing collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testRenameExisting : function () {
|
||||
var cn1 = "example";
|
||||
var cn2 = "example2";
|
||||
|
||||
db._drop(cn1);
|
||||
db._drop(cn2);
|
||||
var c1 = db._create(cn1);
|
||||
db._create(cn2);
|
||||
|
||||
try {
|
||||
c1.rename(cn2);
|
||||
}
|
||||
catch (err) {
|
||||
assertEqual(ERRORS.ERROR_ARANGO_DUPLICATE_NAME.code, err.errorNum);
|
||||
}
|
||||
db._drop(cn1);
|
||||
db._drop(cn2);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test checksum
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testChecksum : function () {
|
||||
var cn = "example";
|
||||
|
||||
db._drop(cn);
|
||||
var c1 = db._create(cn);
|
||||
|
||||
// empty collection, checksum should be 0
|
||||
var r1 = c1.checksum(true);
|
||||
assertTypeOf("string", r1.revision);
|
||||
assertTrue(r1.revision !== "");
|
||||
assertTrue(r1.revision.match(/^[0-9]+$/));
|
||||
assertTypeOf("number", r1.checksum);
|
||||
assertEqual(0, r1.checksum);
|
||||
|
||||
// inserting a doc, checksum should change
|
||||
c1.save({ a : 1 });
|
||||
var r2 = c1.checksum(true);
|
||||
assertNotEqual(r1.revision, r2.revision);
|
||||
assertTypeOf("string", r2.revision);
|
||||
assertTrue(r2.revision !== "");
|
||||
assertTrue(r2.revision.match(/^[0-9]+$/));
|
||||
assertTypeOf("number", r2.checksum);
|
||||
assertNotEqual(0, r2.checksum);
|
||||
|
||||
// inserting another doc, checksum should change
|
||||
c1.save({ a : 2 });
|
||||
var r3 = c1.checksum(true);
|
||||
assertNotEqual(r1.revision, r3.revision);
|
||||
assertNotEqual(r2.revision, r3.revision);
|
||||
assertTypeOf("string", r3.revision);
|
||||
assertTrue(r3.revision !== "");
|
||||
assertTrue(r3.revision.match(/^[0-9]+$/));
|
||||
assertTypeOf("number", r3.checksum);
|
||||
assertNotEqual(0, r3.checksum);
|
||||
assertNotEqual(r2.checksum, r3.checksum);
|
||||
|
||||
// test after unloading
|
||||
c1.unload();
|
||||
var r4 = c1.checksum(true);
|
||||
assertTypeOf("string", r4.revision);
|
||||
assertEqual(r3.revision, r4.revision);
|
||||
assertTypeOf("number", r4.checksum);
|
||||
assertNotEqual(0, r4.checksum);
|
||||
assertEqual(r3.checksum, r4.checksum);
|
||||
|
||||
// test withData
|
||||
var r5 = c1.checksum(true, true);
|
||||
assertTypeOf("string", r5.revision);
|
||||
assertEqual(r4.revision, r5.revision);
|
||||
assertTypeOf("number", r5.checksum);
|
||||
assertNotEqual(0, r5.checksum);
|
||||
assertNotEqual(r4.checksum, r5.checksum);
|
||||
|
||||
// test after truncation
|
||||
c1.truncate();
|
||||
var r6 = c1.checksum(true);
|
||||
assertTypeOf("string", r6.revision);
|
||||
assertNotEqual(r4.revision, r6.revision);
|
||||
assertNotEqual(r5.revision, r6.revision);
|
||||
assertTypeOf("number", r6.checksum);
|
||||
assertEqual(0, r6.checksum);
|
||||
|
||||
db._drop(cn);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test checksum
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testChecksumEdge : function () {
|
||||
var cn = "example";
|
||||
var vn = "example2";
|
||||
|
||||
db._drop(cn);
|
||||
db._drop(vn);
|
||||
db._create(vn);
|
||||
var c1 = db._createEdgeCollection(cn);
|
||||
|
||||
var r1 = c1.checksum(true);
|
||||
assertTypeOf("string", r1.revision);
|
||||
assertTrue(r1.revision !== "");
|
||||
assertTrue(r1.revision.match(/^[0-9]+$/));
|
||||
assertTypeOf("number", r1.checksum);
|
||||
assertEqual(0, r1.checksum);
|
||||
|
||||
c1.save(vn + "/1", vn + "/2", { a : 1 });
|
||||
var r2 = c1.checksum(true);
|
||||
assertNotEqual(r1.revision, r2.revision);
|
||||
assertTypeOf("string", r2.revision);
|
||||
assertTrue(r2.revision !== "");
|
||||
assertTrue(r2.revision.match(/^[0-9]+$/));
|
||||
assertTypeOf("number", r2.checksum);
|
||||
assertNotEqual(0, r2.checksum);
|
||||
|
||||
c1.save(vn + "/1", vn + "/2", { a : 2 });
|
||||
var r3 = c1.checksum(true);
|
||||
assertNotEqual(r1.revision, r3.revision);
|
||||
assertNotEqual(r2.revision, r3.revision);
|
||||
assertTypeOf("string", r3.revision);
|
||||
assertTrue(r3.revision !== "");
|
||||
assertTrue(r3.revision.match(/^[0-9]+$/));
|
||||
assertTypeOf("number", r3.checksum);
|
||||
assertNotEqual(0, r3.checksum);
|
||||
assertNotEqual(r2.checksum, r3.checksum);
|
||||
|
||||
c1.unload();
|
||||
var r4 = c1.checksum(true);
|
||||
assertTypeOf("string", r4.revision);
|
||||
assertEqual(r3.revision, r4.revision);
|
||||
assertTypeOf("number", r4.checksum);
|
||||
assertEqual(r3.checksum, r4.checksum);
|
||||
|
||||
// test withData
|
||||
var r5 = c1.checksum(true, true);
|
||||
assertTypeOf("string", r5.revision);
|
||||
assertEqual(r4.revision, r5.revision);
|
||||
assertTypeOf("number", r5.checksum);
|
||||
assertNotEqual(0, r5.checksum);
|
||||
assertNotEqual(r4.checksum, r5.checksum);
|
||||
|
||||
// test after truncation
|
||||
c1.truncate();
|
||||
var r6 = c1.checksum(true);
|
||||
assertTypeOf("string", r6.revision);
|
||||
assertNotEqual(r4.revision, r6.revision);
|
||||
assertNotEqual(r5.revision, r6.revision);
|
||||
assertTypeOf("number", r6.checksum);
|
||||
assertEqual(0, r6.checksum);
|
||||
|
||||
db._drop(cn);
|
||||
db._drop(vn);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test checksum two different collections
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testChecksumDifferent : function () {
|
||||
var cn1 = "example";
|
||||
var cn2 = "example2";
|
||||
|
||||
db._drop(cn1);
|
||||
db._drop(cn2);
|
||||
var c1 = db._create(cn1);
|
||||
var c2 = db._create(cn2);
|
||||
|
||||
// collections are empty, checksums are identical
|
||||
var cs1 = c1.checksum().checksum;
|
||||
var cs2 = c2.checksum().checksum;
|
||||
|
||||
assertEqual(cs1, cs2);
|
||||
|
||||
c1.save({ _key: "foobar", value: 123 });
|
||||
c2.save({ _key: "foobar", value: 123 });
|
||||
|
||||
// keys are the same
|
||||
cs1 = c1.checksum().checksum;
|
||||
cs2 = c2.checksum().checksum;
|
||||
|
||||
assertEqual(cs1, cs2);
|
||||
|
||||
// data is the same
|
||||
cs1 = c1.checksum(false, true).checksum;
|
||||
cs2 = c2.checksum(false, true).checksum;
|
||||
|
||||
assertEqual(cs1, cs2);
|
||||
|
||||
// revisions are different
|
||||
cs1 = c1.checksum(true, false).checksum;
|
||||
cs2 = c2.checksum(true, false).checksum;
|
||||
|
||||
assertNotEqual(cs1, cs2);
|
||||
|
||||
// revisions are still different
|
||||
cs1 = c1.checksum(true, true).checksum;
|
||||
cs2 = c2.checksum(true, true).checksum;
|
||||
|
||||
assertNotEqual(cs1, cs2);
|
||||
|
||||
// update document in c1, keep data
|
||||
c1.replace("foobar", { value: 123 });
|
||||
|
||||
// keys are still the same
|
||||
cs1 = c1.checksum().checksum;
|
||||
cs2 = c2.checksum().checksum;
|
||||
|
||||
assertEqual(cs1, cs2);
|
||||
|
||||
// data is still the same
|
||||
cs1 = c1.checksum(false, true).checksum;
|
||||
cs2 = c2.checksum(false, true).checksum;
|
||||
|
||||
assertEqual(cs1, cs2);
|
||||
|
||||
// revisions are still different
|
||||
cs1 = c1.checksum(true, false).checksum;
|
||||
cs2 = c2.checksum(true, false).checksum;
|
||||
|
||||
// update document in c1, changing data
|
||||
c1.replace("foobar", { value: 124 });
|
||||
|
||||
// keys are still the same
|
||||
cs1 = c1.checksum().checksum;
|
||||
cs2 = c2.checksum().checksum;
|
||||
|
||||
assertEqual(cs1, cs2);
|
||||
|
||||
// data is not the same
|
||||
cs1 = c1.checksum(false, true).checksum;
|
||||
cs2 = c2.checksum(false, true).checksum;
|
||||
|
||||
assertNotEqual(cs1, cs2);
|
||||
|
||||
// revisions are still different
|
||||
cs1 = c1.checksum(true, false).checksum;
|
||||
cs2 = c2.checksum(true, false).checksum;
|
||||
|
||||
db._drop(cn1);
|
||||
db._drop(cn2);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test system collection dropping / renaming / unloading
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testSystemSpecial : function () {
|
||||
[ '_trx', '_users' ].forEach(function(cn) {
|
||||
var c = db._collection(cn);
|
||||
|
||||
// drop
|
||||
try {
|
||||
c.drop();
|
||||
fail();
|
||||
}
|
||||
catch (err1) {
|
||||
assertEqual(ERRORS.ERROR_FORBIDDEN.code, err1.errorNum);
|
||||
}
|
||||
|
||||
// rename
|
||||
var cn = "example";
|
||||
db._drop(cn);
|
||||
|
||||
try {
|
||||
c.rename(cn);
|
||||
fail();
|
||||
}
|
||||
catch (err2) {
|
||||
assertEqual(ERRORS.ERROR_FORBIDDEN.code, err2.errorNum);
|
||||
}
|
||||
|
||||
// unload is allowed
|
||||
c.unload();
|
||||
|
||||
});
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test special properties of replication collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testSpecialReplication : function () {
|
||||
var repl = db._collection('_replication');
|
||||
|
||||
// drop is not allowed
|
||||
try {
|
||||
repl.drop();
|
||||
fail();
|
||||
}
|
||||
catch (err1) {
|
||||
assertEqual(ERRORS.ERROR_FORBIDDEN.code, err1.errorNum);
|
||||
}
|
||||
|
||||
// rename is not allowed
|
||||
try {
|
||||
var cn = "example";
|
||||
db._drop(cn);
|
||||
repl.rename(cn);
|
||||
}
|
||||
catch (err2) {
|
||||
assertEqual(ERRORS.ERROR_FORBIDDEN.code, err2.errorNum);
|
||||
}
|
||||
|
||||
// unload is not allowed
|
||||
try {
|
||||
repl.unload();
|
||||
}
|
||||
catch (err3) {
|
||||
assertEqual(ERRORS.ERROR_FORBIDDEN.code, err3.errorNum);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- main
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief executes the test suites
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
jsunity.run(CollectionSuite);
|
||||
|
||||
return jsunity.done();
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @}\\)"
|
||||
// End:
|
||||
|
Loading…
Reference in New Issue