Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
J
jio
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Cédric Le Ninivin
jio
Commits
fa7a5f07
Commit
fa7a5f07
authored
Jan 16, 2013
by
Tristan Cavelier
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
replicaterevisionstorage.js post command added + tests
parent
9268d81a
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
404 additions
and
0 deletions
+404
-0
src/jio.storage/replicaterevisionstorage.js
src/jio.storage/replicaterevisionstorage.js
+210
-0
test/jiotests.js
test/jiotests.js
+194
-0
No files found.
src/jio.storage/replicaterevisionstorage.js
0 → 100644
View file @
fa7a5f07
/*jslint indent: 2, maxlen: 80, nomen: true */
/*global jIO: true */
/**
* JIO Replicate Revision Storage.
* It manages storages that manage revisions and conflicts.
* Description:
* {
* "type": "replicaterevision",
* "storage_list": [
* <sub storage description>,
* ...
* ]
* }
*/
jIO
.
addStorageType
(
'
replicaterevision
'
,
function
(
spec
,
my
)
{
"
use strict
"
;
var
that
,
priv
=
{};
spec
=
spec
||
{};
that
=
my
.
basicStorage
(
spec
,
my
);
priv
.
storage_list_key
=
"
storage_list
"
;
priv
.
storage_list
=
spec
[
priv
.
storage_list_key
];
my
.
env
=
my
.
env
||
spec
.
env
||
{};
that
.
specToStore
=
function
()
{
var
o
=
{};
o
[
priv
.
storage_list_key
]
=
priv
.
storage_list
;
o
.
env
=
my
.
env
;
return
o
;
};
/**
* Generate a new uuid
* @method generateUuid
* @return {string} The new uuid
*/
priv
.
generateUuid
=
function
()
{
var
S4
=
function
()
{
var
i
,
string
=
Math
.
floor
(
Math
.
random
()
*
0x10000
/* 65536 */
).
toString
(
16
);
for
(
i
=
string
.
length
;
i
<
4
;
i
+=
1
)
{
string
=
"
0
"
+
string
;
}
return
string
;
};
return
S4
()
+
S4
()
+
"
-
"
+
S4
()
+
"
-
"
+
S4
()
+
"
-
"
+
S4
()
+
"
-
"
+
S4
()
+
S4
()
+
S4
();
};
/**
* Generates a hash code of a string
* @method hashCode
* @return {string} The next revision
*/
priv
.
getNextRevision
=
function
(
docid
)
{
my
.
env
[
docid
].
id
+=
1
;
return
my
.
env
[
docid
].
id
.
toString
();
};
/**
* Checks a revision format
* @method checkRevisionFormat
* @param {string} revision The revision string
* @return {boolean} True if ok, else false
*/
priv
.
checkRevisionFormat
=
function
(
revision
)
{
return
(
/^
[
0-9a-zA-Z_
]
+$/
.
test
(
revision
));
};
/**
* Initalize document environment object
* @method initEnv
* @param {string} docid The document id
* @return {object} The reference to the environment
*/
priv
.
initEnv
=
function
(
docid
)
{
my
.
env
[
docid
]
=
{
"
id
"
:
0
,
"
distant_revisions
"
:
{},
"
my_revisions
"
:
{},
"
last_revisions
"
:
[]
};
return
my
.
env
[
docid
];
};
/**
* Post the document metadata to all sub storages
* @method post
* @param {object} command The JIO command
*/
that
.
post
=
function
(
command
)
{
var
functions
=
{},
doc_env
,
revs_info
,
doc
,
my_rev
;
functions
.
begin
=
function
()
{
doc
=
command
.
cloneDoc
();
if
(
typeof
doc
.
_rev
===
"
string
"
&&
!
priv
.
checkRevisionFormat
(
doc
.
_rev
))
{
that
.
error
({
"
status
"
:
31
,
"
statusText
"
:
"
Wrong Revision Format
"
,
"
error
"
:
"
wrong_revision_format
"
,
"
message
"
:
"
The document previous revision does not match
"
+
"
^[0-9]+-[0-9a-zA-Z]+$
"
,
"
reason
"
:
"
Previous revision is wrong
"
});
return
;
}
if
(
typeof
doc
.
_id
!==
"
string
"
)
{
doc
.
_id
=
priv
.
generateUuid
();
}
if
(
priv
.
update_doctree_allowed
===
undefined
)
{
priv
.
update_doctree_allowed
=
true
;
}
doc_env
=
my
.
env
[
doc
.
_id
];
if
(
doc_env
&&
doc_env
.
id
)
{
if
(
!
priv
.
update_doctree_allowed
)
{
that
.
error
({
"
status
"
:
409
,
"
statusText
"
:
"
Conflict
"
,
"
error
"
:
"
conflict
"
,
"
message
"
:
"
Cannot update a document
"
,
"
reason
"
:
"
Document update conflict
"
});
return
;
}
}
else
{
doc_env
=
priv
.
initEnv
(
doc
.
_id
);
}
my_rev
=
priv
.
getNextRevision
(
doc
.
_id
);
functions
.
sendDocument
();
};
functions
.
sendDocumentIndex
=
function
(
method
,
index
,
callback
)
{
var
wrapped_callback_success
,
wrapped_callback_error
;
wrapped_callback_success
=
function
(
response
)
{
callback
(
method
,
index
,
undefined
,
response
);
};
wrapped_callback_error
=
function
(
err
)
{
callback
(
method
,
index
,
err
,
undefined
);
};
if
(
typeof
doc
.
_rev
===
"
string
"
&&
doc_env
.
my_revisions
[
doc
.
_rev
]
!==
undefined
)
{
doc
.
_rev
=
doc_env
.
my_revisions
[
doc
.
_rev
][
index
];
}
that
.
addJob
(
method
,
priv
.
storage_list
[
index
],
doc
,
command
.
cloneOption
(),
wrapped_callback_success
,
wrapped_callback_error
);
};
functions
.
sendDocument
=
function
()
{
var
i
;
doc_env
.
my_revisions
[
my_rev
]
=
doc_env
.
my_revisions
[
my_rev
]
||
[];
doc_env
.
my_revisions
[
my_rev
].
length
=
priv
.
storage_list
.
length
;
for
(
i
=
0
;
i
<
priv
.
storage_list
.
length
;
i
+=
1
)
{
functions
.
sendDocumentIndex
(
doc_env
.
last_revisions
[
i
]
===
"
unique_
"
+
i
?
"
put
"
:
"
post
"
,
i
,
functions
.
checkSendResult
);
}
};
functions
.
checkSendResult
=
function
(
method
,
index
,
err
,
response
)
{
if
(
err
)
{
if
(
err
.
status
===
409
)
{
if
(
method
!==
"
put
"
)
{
functions
.
sendDocumentIndex
(
"
put
"
,
index
,
functions
.
checkSendResult
);
return
;
}
}
functions
.
updateEnv
(
index
,
undefined
);
functions
.
error
(
err
);
return
;
}
// success
functions
.
updateEnv
(
index
,
response
.
rev
||
"
unique_
"
+
index
);
functions
.
success
({
"
ok
"
:
true
,
"
id
"
:
doc
.
_id
,
"
rev
"
:
my_rev
});
};
functions
.
updateEnv
=
function
(
index
,
revision
)
{
doc_env
.
last_revisions
[
index
]
=
revision
;
doc_env
.
my_revisions
[
my_rev
][
index
]
=
revision
;
doc_env
.
distant_revisions
[
revision
]
=
my_rev
;
};
functions
.
success
=
function
(
response
)
{
if
(
!
functions
.
success_called_once
)
{
functions
.
success_called_once
=
true
;
that
.
success
(
response
);
}
};
functions
.
error_count
=
0
;
functions
.
error
=
function
(
err
)
{
functions
.
error_count
+=
1
;
if
(
functions
.
error_count
===
priv
.
storage_list
.
length
)
{
that
.
error
(
err
);
}
};
functions
.
begin
();
};
return
that
;
});
test/jiotests.js
View file @
fa7a5f07
...
@@ -1813,6 +1813,200 @@ test ("Scenario", function(){
...
@@ -1813,6 +1813,200 @@ test ("Scenario", function(){
});
});
module
(
"
JIO Replicate Revision Storage
"
);
var
testReplicateRevisionStorageGenerator
=
function
(
sinon
,
jio_description
,
document_name_have_revision
)
{
var
o
=
generateTools
(
sinon
),
leavesAction
,
generateLocalPath
;
o
.
jio
=
JIO
.
newJio
(
jio_description
);
generateLocalPath
=
function
(
storage_description
)
{
return
"
jio/localstorage/
"
+
storage_description
.
username
+
"
/
"
+
storage_description
.
application_name
;
};
leavesAction
=
function
(
action
,
storage_description
,
param
)
{
var
i
;
if
(
param
===
undefined
)
{
param
=
{};
}
else
{
param
=
clone
(
param
);
}
if
(
storage_description
.
storage_list
!==
undefined
)
{
// it is the replicate revision storage tree
for
(
i
=
0
;
i
<
storage_description
.
storage_list
.
length
;
i
+=
1
)
{
leavesAction
(
action
,
storage_description
.
storage_list
[
i
],
param
);
}
}
else
if
(
storage_description
.
sub_storage
!==
undefined
)
{
// it is the revision storage tree
param
.
revision
=
true
;
leavesAction
(
action
,
storage_description
.
sub_storage
,
param
);
}
else
{
// it is the storage tree leaf
param
[
storage_description
.
type
]
=
true
;
action
(
storage_description
,
param
);
}
};
o
.
leavesAction
=
function
(
action
)
{
leavesAction
(
action
,
jio_description
);
};
// post a new document without id
o
.
doc
=
{
"
title
"
:
"
post document without id
"
};
o
.
revision
=
{
"
start
"
:
0
,
"
ids
"
:
[]};
o
.
spy
(
o
,
"
status
"
,
undefined
,
"
Post document (without id)
"
);
o
.
jio
.
post
(
o
.
doc
,
function
(
err
,
response
)
{
o
.
f
.
apply
(
arguments
);
o
.
response_rev
=
(
err
||
response
).
rev
;
if
(
isUuid
((
err
||
response
).
id
))
{
ok
(
true
,
"
Uuid format
"
);
o
.
uuid
=
(
err
||
response
).
id
;
}
else
{
deepEqual
((
err
||
response
).
id
,
"
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
"
,
"
Uuid format
"
);
}
});
o
.
tick
(
o
);
// check document
o
.
doc
.
_id
=
o
.
uuid
;
o
.
rev
=
"
1
"
;
o
.
local_rev
=
"
1-
"
+
generateRevisionHash
(
o
.
doc
,
o
.
revision
);
o
.
leavesAction
(
function
(
storage_description
,
param
)
{
var
suffix
=
""
,
doc
=
clone
(
o
.
doc
);
if
(
param
.
revision
)
{
deepEqual
(
o
.
response_rev
,
o
.
rev
,
"
Check revision
"
);
doc
.
_id
+=
"
.
"
+
o
.
local_rev
;
suffix
=
"
.
"
+
o
.
local_rev
;
}
deepEqual
(
localstorage
.
getItem
(
generateLocalPath
(
storage_description
)
+
"
/
"
+
o
.
uuid
+
suffix
),
doc
,
"
Check document
"
);
});
// post a new document with id
o
.
doc
=
{
"
_id
"
:
"
post1
"
,
"
title
"
:
"
post new doc with id
"
};
o
.
rev
=
"
1
"
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
post1
"
,
"
rev
"
:
o
.
rev
},
"
Post document (with id)
"
);
o
.
jio
.
post
(
o
.
doc
,
o
.
f
);
o
.
tick
(
o
);
// check document
o
.
local_rev
=
"
1-
"
+
generateRevisionHash
(
o
.
doc
,
o
.
revision
);
o
.
leavesAction
(
function
(
storage_description
,
param
)
{
var
suffix
=
""
,
doc
=
clone
(
o
.
doc
);
if
(
param
.
revision
)
{
doc
.
_id
+=
"
.
"
+
o
.
local_rev
;
suffix
=
"
.
"
+
o
.
local_rev
;
}
deepEqual
(
localstorage
.
getItem
(
generateLocalPath
(
storage_description
)
+
"
/post1
"
+
suffix
),
doc
,
"
Check document
"
);
});
// post same document without revision
o
.
doc
=
{
"
_id
"
:
"
post1
"
,
"
title
"
:
"
post same document without revision
"
};
o
.
rev
=
"
2
"
;
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
post1
"
,
"
rev
"
:
o
.
rev
},
"
Post same document (without revision)
"
);
o
.
jio
.
post
(
o
.
doc
,
o
.
f
);
o
.
tick
(
o
);
// check document
o
.
local_rev
=
"
1-
"
+
generateRevisionHash
(
o
.
doc
,
o
.
revision
);
o
.
leavesAction
(
function
(
storage_description
,
param
)
{
var
suffix
=
""
,
doc
=
clone
(
o
.
doc
);
if
(
param
.
revision
)
{
doc
.
_id
+=
"
.
"
+
o
.
local_rev
;
suffix
=
"
.
"
+
o
.
local_rev
;
}
deepEqual
(
localstorage
.
getItem
(
generateLocalPath
(
storage_description
)
+
"
/post1
"
+
suffix
),
doc
,
"
Check document
"
);
});
// post a new revision
o
.
doc
=
{
"
_id
"
:
"
post1
"
,
"
title
"
:
"
post new revision
"
,
"
_rev
"
:
o
.
rev
};
o
.
rev
=
"
3
"
;
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
post1
"
,
"
rev
"
:
o
.
rev
},
"
Post document (with revision)
"
);
o
.
jio
.
post
(
o
.
doc
,
o
.
f
);
o
.
tick
(
o
);
// check document
o
.
revision
.
start
+=
1
;
o
.
revision
.
ids
.
unshift
(
o
.
local_rev
.
split
(
"
-
"
).
slice
(
1
).
join
(
"
-
"
));
o
.
doc
.
_rev
=
o
.
local_rev
;
o
.
local_rev
=
"
2-
"
+
generateRevisionHash
(
o
.
doc
,
o
.
revision
);
o
.
leavesAction
(
function
(
storage_description
,
param
)
{
var
suffix
=
""
,
doc
=
clone
(
o
.
doc
);
delete
doc
.
_rev
;
if
(
param
.
revision
)
{
doc
.
_id
+=
"
.
"
+
o
.
local_rev
;
suffix
=
"
.
"
+
o
.
local_rev
;
}
deepEqual
(
localstorage
.
getItem
(
generateLocalPath
(
storage_description
)
+
"
/post1
"
+
suffix
),
doc
,
"
Check document
"
);
});
o
.
jio
.
stop
();
};
test
(
"
[Local Storage] Scenario
"
,
function
()
{
testReplicateRevisionStorageGenerator
(
this
,
{
"
type
"
:
"
replicaterevision
"
,
"
storage_list
"
:
[{
"
type
"
:
"
local
"
,
"
username
"
:
"
ureploc
"
,
"
application_name
"
:
"
areploc
"
}]
});
});
test
(
"
[Revision + Local Storage] Scenario
"
,
function
()
{
testReplicateRevisionStorageGenerator
(
this
,
{
"
type
"
:
"
replicaterevision
"
,
"
storage_list
"
:
[{
"
type
"
:
"
revision
"
,
"
sub_storage
"
:
{
"
type
"
:
"
local
"
,
"
username
"
:
"
ureprevloc
"
,
"
application_name
"
:
"
areprevloc
"
}
}]
});
});
test
(
"
[Revision + Local Storage, Local Storage] Scenario
"
,
function
()
{
testReplicateRevisionStorageGenerator
(
this
,
{
"
type
"
:
"
replicaterevision
"
,
"
storage_list
"
:
[{
"
type
"
:
"
revision
"
,
"
sub_storage
"
:
{
"
type
"
:
"
local
"
,
"
username
"
:
"
ureprevlocloc
"
,
"
application_name
"
:
"
areprevlocloc
"
}
},{
"
type
"
:
"
local
"
,
"
username
"
:
"
ureprevlocloc2
"
,
"
application_name
"
:
"
areprevlocloc2
"
}]
});
});
/*
/*
module ('Jio DAVStorage');
module ('Jio DAVStorage');
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment