Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
erp5
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
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Léo-Paul Géneau
erp5
Commits
9aff3608
Commit
9aff3608
authored
Jul 04, 2017
by
Vincent Bechu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
erp5_web_renderjs_ui: Release v3.19.0 Jio
parent
96a9d8c5
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
891 additions
and
799 deletions
+891
-799
bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_jio_js.js
...enderjs_ui/PathTemplateItem/web_page_module/rjs_jio_js.js
+889
-797
bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_jio_js.xml
...nderjs_ui/PathTemplateItem/web_page_module/rjs_jio_js.xml
+2
-2
No files found.
bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_jio_js.js
View file @
9aff3608
...
...
@@ -8428,6 +8428,15 @@ return new Parser;
CONFLICT_KEEP_REMOTE
=
2
,
CONFLICT_CONTINUE
=
3
;
function
SkipError
(
message
)
{
if
((
message
!==
undefined
)
&&
(
typeof
message
!==
"
string
"
))
{
throw
new
TypeError
(
'
You must pass a string.
'
);
}
this
.
message
=
message
||
"
Skip some asynchronous code
"
;
}
SkipError
.
prototype
=
new
Error
();
SkipError
.
prototype
.
constructor
=
SkipError
;
/****************************************************
Use a local jIO to read/write/search documents
Synchronize in background those document with a remote jIO.
...
...
@@ -8446,20 +8455,33 @@ return new Parser;
function
ReplicateStorage
(
spec
)
{
this
.
_query_options
=
spec
.
query
||
{};
if
(
spec
.
signature_hash_key
!==
undefined
)
{
this
.
_query_options
.
select_list
=
[
spec
.
signature_hash_key
];
}
this
.
_signature_hash_key
=
spec
.
signature_hash_key
;
this
.
_local_sub_storage
=
jIO
.
createJIO
(
spec
.
local_sub_storage
);
this
.
_remote_sub_storage
=
jIO
.
createJIO
(
spec
.
remote_sub_storage
);
this
.
_signature_hash
=
"
_replicate_
"
+
generateHash
(
stringify
(
spec
.
local_sub_storage
)
+
stringify
(
spec
.
remote_sub_storage
)
+
stringify
(
this
.
_query_options
)
);
this
.
_signature_sub_storage
=
jIO
.
createJIO
({
type
:
"
document
"
,
document_id
:
this
.
_signature_hash
,
sub_storage
:
spec
.
signature_storage
||
spec
.
local_sub_storage
});
if
(
spec
.
hasOwnProperty
(
'
signature_sub_storage
'
))
{
this
.
_signature_sub_storage
=
jIO
.
createJIO
(
spec
.
signature_sub_storage
);
this
.
_custom_signature_sub_storage
=
true
;
}
else
{
this
.
_signature_hash
=
"
_replicate_
"
+
generateHash
(
stringify
(
spec
.
local_sub_storage
)
+
stringify
(
spec
.
remote_sub_storage
)
+
stringify
(
this
.
_query_options
)
);
this
.
_signature_sub_storage
=
jIO
.
createJIO
({
type
:
"
query
"
,
sub_storage
:
{
type
:
"
document
"
,
document_id
:
this
.
_signature_hash
,
sub_storage
:
spec
.
local_sub_storage
}
});
this
.
_custom_signature_sub_storage
=
false
;
}
this
.
_use_remote_post
=
spec
.
use_remote_post
||
false
;
// Number of request we allow browser execution for attachments
...
...
@@ -8602,798 +8624,888 @@ return new Parser;
arguments
);
};
ReplicateStorage
.
prototype
.
repair
=
function
()
{
var
context
=
this
,
argument_list
=
arguments
,
skip_document_dict
=
{};
// Do not sync the signature document
skip_document_dict
[
context
.
_signature_hash
]
=
null
;
function
dispatchQueue
(
function_used
,
argument_list
,
number_queue
)
{
var
result_promise_list
=
[],
i
;
function
pushAndExecute
(
queue
)
{
queue
.
push
(
function
()
{
if
(
argument_list
.
length
>
0
)
{
var
argument_array
=
argument_list
.
shift
(),
sub_queue
=
new
RSVP
.
Queue
();
argument_array
[
0
]
=
sub_queue
;
function_used
.
apply
(
context
,
argument_array
);
pushAndExecute
(
queue
);
return
sub_queue
;
}
});
}
for
(
i
=
0
;
i
<
number_queue
;
i
+=
1
)
{
result_promise_list
.
push
(
new
RSVP
.
Queue
());
pushAndExecute
(
result_promise_list
[
i
]);
}
if
(
number_queue
>
1
)
{
return
RSVP
.
all
(
result_promise_list
);
}
return
result_promise_list
[
0
];
}
function
dispatchQueue
(
context
,
function_used
,
argument_list
,
number_queue
)
{
var
result_promise_list
=
[],
i
;
function
propagateAttachmentDeletion
(
skip_attachment_dict
,
destination
,
id
,
name
)
{
return
destination
.
removeAttachment
(
id
,
name
)
.
push
(
function
()
{
return
context
.
_signature_sub_storage
.
removeAttachment
(
id
,
name
);
})
function
pushAndExecute
(
queue
)
{
queue
.
push
(
function
()
{
skip_attachment_dict
[
name
]
=
null
;
if
(
argument_list
.
length
>
0
)
{
var
argument_array
=
argument_list
.
shift
(),
sub_queue
=
new
RSVP
.
Queue
();
argument_array
[
0
]
=
sub_queue
;
function_used
.
apply
(
context
,
argument_array
);
pushAndExecute
(
queue
);
return
sub_queue
;
}
});
}
function
propagateAttachmentModification
(
skip_attachment_dict
,
destination
,
blob
,
hash
,
id
,
name
)
{
return
destination
.
putAttachment
(
id
,
name
,
blob
)
.
push
(
function
()
{
return
context
.
_signature_sub_storage
.
putAttachment
(
id
,
name
,
JSON
.
stringify
({
hash
:
hash
}));
})
.
push
(
function
()
{
skip_attachment_dict
[
name
]
=
null
;
});
for
(
i
=
0
;
i
<
number_queue
;
i
+=
1
)
{
result_promise_list
.
push
(
new
RSVP
.
Queue
());
pushAndExecute
(
result_promise_list
[
i
]);
}
if
(
number_queue
>
1
)
{
return
RSVP
.
all
(
result_promise_list
);
}
return
result_promise_list
[
0
];
}
function
checkAndPropagateAttachment
(
skip_attachment_dict
,
status_hash
,
local_hash
,
blob
,
source
,
destination
,
id
,
name
,
conflict_force
,
conflict_revert
,
conflict_ignore
)
{
var
remote_blob
;
return
destination
.
getAttachment
(
id
,
name
)
.
push
(
function
(
result
)
{
remote_blob
=
result
;
return
jIO
.
util
.
readBlobAsArrayBuffer
(
remote_blob
);
})
.
push
(
function
(
evt
)
{
return
generateHashFromArrayBuffer
(
evt
.
target
.
result
);
},
function
(
error
)
{
if
((
error
instanceof
jIO
.
util
.
jIOError
)
&&
(
error
.
status_code
===
404
))
{
remote_blob
=
null
;
return
null
;
}
throw
error
;
})
.
push
(
function
(
remote_hash
)
{
if
(
local_hash
===
remote_hash
)
{
// Same modifications on both side
if
(
local_hash
===
null
)
{
// Deleted on both side, drop signature
return
context
.
_signature_sub_storage
.
removeAttachment
(
id
,
name
)
.
push
(
function
()
{
skip_attachment_dict
[
id
]
=
null
;
});
}
function
callAllDocsOnStorage
(
context
,
storage
,
cache
,
cache_key
)
{
return
new
RSVP
.
Queue
()
.
push
(
function
()
{
if
(
!
cache
.
hasOwnProperty
(
cache_key
))
{
return
storage
.
allDocs
(
context
.
_query_options
)
.
push
(
function
(
result
)
{
var
i
,
cache_entry
=
{};
for
(
i
=
0
;
i
<
result
.
data
.
total_rows
;
i
+=
1
)
{
cache_entry
[
result
.
data
.
rows
[
i
].
id
]
=
result
.
data
.
rows
[
i
].
value
;
}
cache
[
cache_key
]
=
cache_entry
;
});
}
})
.
push
(
function
()
{
return
cache
[
cache_key
];
});
}
return
context
.
_signature_sub_storage
.
putAttachment
(
id
,
name
,
JSON
.
stringify
({
hash
:
local_hash
}))
function
propagateAttachmentDeletion
(
context
,
skip_attachment_dict
,
destination
,
id
,
name
)
{
return
destination
.
removeAttachment
(
id
,
name
)
.
push
(
function
()
{
return
context
.
_signature_sub_storage
.
removeAttachment
(
id
,
name
);
})
.
push
(
function
()
{
skip_attachment_dict
[
name
]
=
null
;
});
}
function
propagateAttachmentModification
(
context
,
skip_attachment_dict
,
destination
,
blob
,
hash
,
id
,
name
)
{
return
destination
.
putAttachment
(
id
,
name
,
blob
)
.
push
(
function
()
{
return
context
.
_signature_sub_storage
.
putAttachment
(
id
,
name
,
JSON
.
stringify
({
hash
:
hash
}));
})
.
push
(
function
()
{
skip_attachment_dict
[
name
]
=
null
;
});
}
function
checkAndPropagateAttachment
(
context
,
skip_attachment_dict
,
status_hash
,
local_hash
,
blob
,
source
,
destination
,
id
,
name
,
conflict_force
,
conflict_revert
,
conflict_ignore
)
{
var
remote_blob
;
return
destination
.
getAttachment
(
id
,
name
)
.
push
(
function
(
result
)
{
remote_blob
=
result
;
return
jIO
.
util
.
readBlobAsArrayBuffer
(
remote_blob
);
})
.
push
(
function
(
evt
)
{
return
generateHashFromArrayBuffer
(
evt
.
target
.
result
);
},
function
(
error
)
{
if
((
error
instanceof
jIO
.
util
.
jIOError
)
&&
(
error
.
status_code
===
404
))
{
remote_blob
=
null
;
return
null
;
}
throw
error
;
})
.
push
(
function
(
remote_hash
)
{
if
(
local_hash
===
remote_hash
)
{
// Same modifications on both side
if
(
local_hash
===
null
)
{
// Deleted on both side, drop signature
return
context
.
_signature_sub_storage
.
removeAttachment
(
id
,
name
)
.
push
(
function
()
{
skip_
document_dict
[
id
]
=
null
;
skip_
attachment_dict
[
name
]
=
null
;
});
}
if
((
remote_hash
===
status_hash
)
||
(
conflict_force
===
true
))
{
// Modified only locally. No conflict or force
if
(
local_hash
===
null
)
{
// Deleted locally
return
propagateAttachmentDeletion
(
skip_attachment_dict
,
destination
,
id
,
name
);
}
return
propagateAttachmentModification
(
skip_attachment_dict
,
destination
,
blob
,
local_hash
,
id
,
name
);
}
return
context
.
_signature_sub_storage
.
putAttachment
(
id
,
name
,
JSON
.
stringify
({
hash
:
local_hash
}))
.
push
(
function
()
{
skip_attachment_dict
[
name
]
=
null
;
});
}
// Conflict cases
if
(
conflict_ignore
===
true
)
{
return
;
if
((
remote_hash
===
status_hash
)
||
(
conflict_force
===
true
))
{
// Modified only locally. No conflict or force
if
(
local_hash
===
null
)
{
// Deleted locally
return
propagateAttachmentDeletion
(
context
,
skip_attachment_dict
,
destination
,
id
,
name
);
}
return
propagateAttachmentModification
(
context
,
skip_attachment_dict
,
destination
,
blob
,
local_hash
,
id
,
name
);
}
if
((
conflict_revert
===
true
)
||
(
local_hash
===
null
))
{
// Automatically resolve conflict or force revert
if
(
remote_hash
===
null
)
{
// Deleted remotely
return
propagateAttachmentDeletion
(
skip_attachment_dict
,
source
,
id
,
name
);
}
return
propagateAttachmentModification
(
skip_attachment_dict
,
source
,
remote_blob
,
remote_hash
,
id
,
name
);
}
// Conflict cases
if
(
conflict_ignore
===
true
)
{
return
;
}
// Minimize conflict if it can be resolved
if
((
conflict_revert
===
true
)
||
(
local_hash
===
null
))
{
// Automatically resolve conflict or force revert
if
(
remote_hash
===
null
)
{
// Copy remote modification remotely
return
propagateAttachmentModification
(
skip_attachment_dict
,
destination
,
blob
,
local_hash
,
id
,
name
);
}
throw
new
jIO
.
util
.
jIOError
(
"
Conflict on '
"
+
id
+
"
' with attachment '
"
+
name
+
"
'
"
,
409
);
});
}
function
checkAttachmentSignatureDifference
(
queue
,
skip_attachment_dict
,
source
,
destination
,
id
,
name
,
conflict_force
,
conflict_revert
,
conflict_ignore
,
is_creation
,
is_modification
)
{
var
blob
,
status_hash
;
queue
.
push
(
function
()
{
// Optimisation to save a get call to signature storage
if
(
is_creation
===
true
)
{
return
RSVP
.
all
([
source
.
getAttachment
(
id
,
name
),
{
hash
:
null
}
]);
}
if
(
is_modification
===
true
)
{
return
RSVP
.
all
([
source
.
getAttachment
(
id
,
name
),
context
.
_signature_sub_storage
.
getAttachment
(
id
,
name
,
{
format
:
'
json
'
}
)
]);
// Deleted remotely
return
propagateAttachmentDeletion
(
context
,
skip_attachment_dict
,
source
,
id
,
name
);
}
throw
new
jIO
.
util
.
jIOError
(
"
Unexpected call of
"
+
"
checkAttachmentSignatureDifference
"
,
409
);
})
.
push
(
function
(
result_list
)
{
blob
=
result_list
[
0
];
status_hash
=
result_list
[
1
].
hash
;
return
jIO
.
util
.
readBlobAsArrayBuffer
(
blob
);
})
.
push
(
function
(
evt
)
{
var
array_buffer
=
evt
.
target
.
result
,
local_hash
=
generateHashFromArrayBuffer
(
array_buffer
);
if
(
local_hash
!==
status_hash
)
{
return
checkAndPropagateAttachment
(
skip_attachment_dict
,
status_hash
,
local_hash
,
blob
,
source
,
destination
,
id
,
name
,
conflict_force
,
conflict_revert
,
conflict_ignore
);
}
});
}
function
checkAttachmentLocalDeletion
(
queue
,
skip_attachment_dict
,
destination
,
id
,
name
,
source
,
conflict_force
,
conflict_revert
,
conflict_ignore
)
{
var
status_hash
;
queue
.
push
(
function
()
{
return
context
.
_signature_sub_storage
.
getAttachment
(
id
,
name
,
{
format
:
'
json
'
});
})
.
push
(
function
(
result
)
{
status_hash
=
result
.
hash
;
return
checkAndPropagateAttachment
(
skip_attachment_dict
,
status_hash
,
null
,
null
,
source
,
destination
,
id
,
name
,
conflict_force
,
conflict_revert
,
conflict_ignore
);
});
}
return
propagateAttachmentModification
(
context
,
skip_attachment_dict
,
source
,
remote_blob
,
remote_hash
,
id
,
name
);
}
function
pushDocumentAttachment
(
skip_attachment_dict
,
id
,
source
,
destination
,
options
)
{
var
queue
=
new
RSVP
.
Queue
(),
local_dict
=
{},
signature_dict
=
{};
// Minimize conflict if it can be resolved
if
(
remote_hash
===
null
)
{
// Copy remote modification remotely
return
propagateAttachmentModification
(
context
,
skip_attachment_dict
,
destination
,
blob
,
local_hash
,
id
,
name
);
}
throw
new
jIO
.
util
.
jIOError
(
"
Conflict on '
"
+
id
+
"
' with attachment '
"
+
name
+
"
'
"
,
409
);
});
}
return
queue
.
push
(
function
()
{
function
checkAttachmentSignatureDifference
(
queue
,
context
,
skip_attachment_dict
,
source
,
destination
,
id
,
name
,
conflict_force
,
conflict_revert
,
conflict_ignore
,
is_creation
,
is_modification
)
{
var
blob
,
status_hash
;
queue
.
push
(
function
()
{
// Optimisation to save a get call to signature storage
if
(
is_creation
===
true
)
{
return
RSVP
.
all
([
source
.
allAttachments
(
id
)
.
push
(
undefined
,
function
(
error
)
{
if
((
error
instanceof
jIO
.
util
.
jIOError
)
&&
(
error
.
status_code
===
404
))
{
return
{};
}
throw
error
;
}),
context
.
_signature_sub_storage
.
allAttachments
(
id
)
.
push
(
undefined
,
function
(
error
)
{
if
((
error
instanceof
jIO
.
util
.
jIOError
)
&&
(
error
.
status_code
===
404
))
{
return
{};
}
throw
error
;
})
source
.
getAttachment
(
id
,
name
),
{
hash
:
null
}
]);
})
.
push
(
function
(
result_list
)
{
var
is_modification
,
is_creation
,
key
,
argument_list
=
[];
for
(
key
in
result_list
[
0
])
{
if
(
result_list
[
0
].
hasOwnProperty
(
key
))
{
if
(
!
skip_attachment_dict
.
hasOwnProperty
(
key
))
{
local_dict
[
key
]
=
null
;
}
}
if
(
is_modification
===
true
)
{
return
RSVP
.
all
([
source
.
getAttachment
(
id
,
name
),
context
.
_signature_sub_storage
.
getAttachment
(
id
,
name
,
{
format
:
'
json
'
}
)
]);
}
throw
new
jIO
.
util
.
jIOError
(
"
Unexpected call of
"
+
"
checkAttachmentSignatureDifference
"
,
409
);
})
.
push
(
function
(
result_list
)
{
blob
=
result_list
[
0
];
status_hash
=
result_list
[
1
].
hash
;
return
jIO
.
util
.
readBlobAsArrayBuffer
(
blob
);
})
.
push
(
function
(
evt
)
{
var
array_buffer
=
evt
.
target
.
result
,
local_hash
=
generateHashFromArrayBuffer
(
array_buffer
);
if
(
local_hash
!==
status_hash
)
{
return
checkAndPropagateAttachment
(
context
,
skip_attachment_dict
,
status_hash
,
local_hash
,
blob
,
source
,
destination
,
id
,
name
,
conflict_force
,
conflict_revert
,
conflict_ignore
);
}
});
}
function
checkAttachmentLocalDeletion
(
queue
,
context
,
skip_attachment_dict
,
destination
,
id
,
name
,
source
,
conflict_force
,
conflict_revert
,
conflict_ignore
)
{
var
status_hash
;
queue
.
push
(
function
()
{
return
context
.
_signature_sub_storage
.
getAttachment
(
id
,
name
,
{
format
:
'
json
'
});
})
.
push
(
function
(
result
)
{
status_hash
=
result
.
hash
;
return
checkAndPropagateAttachment
(
context
,
skip_attachment_dict
,
status_hash
,
null
,
null
,
source
,
destination
,
id
,
name
,
conflict_force
,
conflict_revert
,
conflict_ignore
);
});
}
function
pushDocumentAttachment
(
context
,
skip_attachment_dict
,
id
,
source
,
destination
,
signature_allAttachments
,
options
)
{
var
local_dict
=
{},
signature_dict
=
{};
return
source
.
allAttachments
(
id
)
.
push
(
undefined
,
function
(
error
)
{
if
((
error
instanceof
jIO
.
util
.
jIOError
)
&&
(
error
.
status_code
===
404
))
{
return
{};
}
throw
error
;
})
.
push
(
function
(
source_allAttachments
)
{
var
is_modification
,
is_creation
,
key
,
argument_list
=
[];
for
(
key
in
source_allAttachments
)
{
if
(
source_allAttachments
.
hasOwnProperty
(
key
))
{
if
(
!
skip_attachment_dict
.
hasOwnProperty
(
key
))
{
local_dict
[
key
]
=
null
;
}
}
for
(
key
in
result_list
[
1
])
{
if
(
result_list
[
1
].
hasOwnProperty
(
key
)
)
{
if
(
!
skip_attachment_dict
.
hasOwnProperty
(
key
))
{
signature_dict
[
key
]
=
null
;
}
}
for
(
key
in
signature_allAttachments
)
{
if
(
signature_allAttachments
.
hasOwnProperty
(
key
))
{
if
(
!
skip_attachment_dict
.
hasOwnProperty
(
key
))
{
signature_dict
[
key
]
=
null
;
}
}
}
for
(
key
in
local_dict
)
{
if
(
local_dict
.
hasOwnProperty
(
key
))
{
is_modification
=
signature_dict
.
hasOwnProperty
(
key
)
&&
options
.
check_modification
;
is_creation
=
!
signature_dict
.
hasOwnProperty
(
key
)
&&
options
.
check_creation
;
if
(
is_modification
===
true
||
is_creation
===
true
)
{
for
(
key
in
local_dict
)
{
if
(
local_dict
.
hasOwnProperty
(
key
))
{
is_modification
=
signature_dict
.
hasOwnProperty
(
key
)
&&
options
.
check_modification
;
is_creation
=
!
signature_dict
.
hasOwnProperty
(
key
)
&&
options
.
check_creation
;
if
(
is_modification
===
true
||
is_creation
===
true
)
{
argument_list
.
push
([
undefined
,
context
,
skip_attachment_dict
,
source
,
destination
,
id
,
key
,
options
.
conflict_force
,
options
.
conflict_revert
,
options
.
conflict_ignore
,
is_creation
,
is_modification
]);
}
}
}
return
dispatchQueue
(
context
,
checkAttachmentSignatureDifference
,
argument_list
,
context
.
_parallel_operation_attachment_amount
);
})
.
push
(
function
()
{
var
key
,
argument_list
=
[];
if
(
options
.
check_deletion
===
true
)
{
for
(
key
in
signature_dict
)
{
if
(
signature_dict
.
hasOwnProperty
(
key
))
{
if
(
!
local_dict
.
hasOwnProperty
(
key
))
{
argument_list
.
push
([
undefined
,
skip_attachment_dict
,
source
,
destination
,
id
,
key
,
options
.
conflict_force
,
options
.
conflict_revert
,
options
.
conflict_ignore
,
is_creation
,
is_modification
]);
context
,
skip_attachment_dict
,
destination
,
id
,
key
,
source
,
options
.
conflict_force
,
options
.
conflict_revert
,
options
.
conflict_ignore
]);
}
}
}
return
dispatchQueue
(
checkAttachmentSignatureDifference
,
context
,
checkAttachmentLocalDeletion
,
argument_list
,
context
.
_parallel_operation_attachment_amount
);
})
.
push
(
function
()
{
var
key
,
argument_list
=
[];
if
(
options
.
check_deletion
===
true
)
{
for
(
key
in
signature_dict
)
{
if
(
signature_dict
.
hasOwnProperty
(
key
))
{
if
(
!
local_dict
.
hasOwnProperty
(
key
))
{
argument_list
.
push
([
undefined
,
skip_attachment_dict
,
destination
,
id
,
key
,
source
,
options
.
conflict_force
,
options
.
conflict_revert
,
options
.
conflict_ignore
]);
}
}
}
return
dispatchQueue
(
checkAttachmentLocalDeletion
,
argument_list
,
context
.
_parallel_operation_attachment_amount
);
}
});
}
function
repairDocumentAttachment
(
id
)
{
var
skip_attachment_dict
=
{};
return
new
RSVP
.
Queue
()
.
push
(
function
()
{
if
(
context
.
_check_local_attachment_modification
||
context
.
_check_local_attachment_creation
||
context
.
_check_local_attachment_deletion
)
{
return
pushDocumentAttachment
(
skip_attachment_dict
,
id
,
context
.
_local_sub_storage
,
context
.
_remote_sub_storage
,
{
conflict_force
:
(
context
.
_conflict_handling
===
CONFLICT_KEEP_LOCAL
),
conflict_revert
:
(
context
.
_conflict_handling
===
CONFLICT_KEEP_REMOTE
),
conflict_ignore
:
(
context
.
_conflict_handling
===
CONFLICT_CONTINUE
),
check_modification
:
context
.
_check_local_attachment_modification
,
check_creation
:
context
.
_check_local_attachment_creation
,
check_deletion
:
context
.
_check_local_attachment_deletion
}
);
}
})
.
push
(
function
()
{
if
(
context
.
_check_remote_attachment_modification
||
context
.
_check_remote_attachment_creation
||
context
.
_check_remote_attachment_deletion
)
{
return
pushDocumentAttachment
(
skip_attachment_dict
,
id
,
context
.
_remote_sub_storage
,
context
.
_local_sub_storage
,
{
use_revert_post
:
context
.
_use_remote_post
,
conflict_force
:
(
context
.
_conflict_handling
===
CONFLICT_KEEP_REMOTE
),
conflict_revert
:
(
context
.
_conflict_handling
===
CONFLICT_KEEP_LOCAL
),
conflict_ignore
:
(
context
.
_conflict_handling
===
CONFLICT_CONTINUE
),
check_modification
:
context
.
_check_remote_attachment_modification
,
check_creation
:
context
.
_check_remote_attachment_creation
,
check_deletion
:
context
.
_check_remote_attachment_deletion
}
);
}
});
}
function
propagateModification
(
source
,
destination
,
doc
,
hash
,
id
,
options
)
{
var
result
,
post_id
,
to_skip
=
true
;
if
(
options
===
undefined
)
{
options
=
{};
}
if
(
options
.
use_post
)
{
result
=
destination
.
post
(
doc
)
.
push
(
function
(
new_id
)
{
to_skip
=
false
;
post_id
=
new_id
;
return
source
.
put
(
post_id
,
doc
);
})
.
push
(
function
()
{
// Copy all attachments
// This is not related to attachment replication
// It's just about not losing user data
return
source
.
allAttachments
(
id
);
})
.
push
(
function
(
attachment_dict
)
{
var
key
,
copy_queue
=
new
RSVP
.
Queue
();
function
copyAttachment
(
name
)
{
copy_queue
.
push
(
function
()
{
return
source
.
getAttachment
(
id
,
name
);
})
.
push
(
function
(
blob
)
{
return
source
.
putAttachment
(
post_id
,
name
,
blob
);
});
}
}
});
}
for
(
key
in
attachment_dict
)
{
if
(
attachment_dict
.
hasOwnProperty
(
key
))
{
copyAttachment
(
key
);
}
function
repairDocumentAttachment
(
context
,
id
)
{
var
skip_attachment_dict
=
{};
return
new
RSVP
.
Queue
()
.
push
(
function
()
{
if
(
context
.
_check_local_attachment_modification
||
context
.
_check_local_attachment_creation
||
context
.
_check_local_attachment_deletion
||
context
.
_check_remote_attachment_modification
||
context
.
_check_remote_attachment_creation
||
context
.
_check_remote_attachment_deletion
)
{
return
context
.
_signature_sub_storage
.
allAttachments
(
id
);
}
return
{};
})
.
push
(
undefined
,
function
(
error
)
{
if
((
error
instanceof
jIO
.
util
.
jIOError
)
&&
(
error
.
status_code
===
404
))
{
return
{};
}
throw
error
;
})
.
push
(
function
(
signature_allAttachments
)
{
if
(
context
.
_check_local_attachment_modification
||
context
.
_check_local_attachment_creation
||
context
.
_check_local_attachment_deletion
)
{
return
pushDocumentAttachment
(
context
,
skip_attachment_dict
,
id
,
context
.
_local_sub_storage
,
context
.
_remote_sub_storage
,
signature_allAttachments
,
{
conflict_force
:
(
context
.
_conflict_handling
===
CONFLICT_KEEP_LOCAL
),
conflict_revert
:
(
context
.
_conflict_handling
===
CONFLICT_KEEP_REMOTE
),
conflict_ignore
:
(
context
.
_conflict_handling
===
CONFLICT_CONTINUE
),
check_modification
:
context
.
_check_local_attachment_modification
,
check_creation
:
context
.
_check_local_attachment_creation
,
check_deletion
:
context
.
_check_local_attachment_deletion
}
return
copy_queue
;
})
.
push
(
function
()
{
return
source
.
remove
(
id
);
})
.
push
(
function
()
{
return
context
.
_signature_sub_storage
.
remove
(
id
);
})
.
push
(
function
()
{
to_skip
=
true
;
return
context
.
_signature_sub_storage
.
put
(
post_id
,
{
"
hash
"
:
hash
});
})
.
push
(
function
()
{
skip_document_dict
[
post_id
]
=
null
;
});
}
else
{
result
=
destination
.
put
(
id
,
doc
)
.
push
(
function
()
{
return
context
.
_signature_sub_storage
.
put
(
id
,
{
"
hash
"
:
hash
)
.
push
(
function
()
{
return
signature_allAttachments
;
});
});
}
return
result
}
return
signature_allAttachments
;
})
.
push
(
function
(
signature_allAttachments
)
{
if
(
context
.
_check_remote_attachment_modification
||
context
.
_check_remote_attachment_creation
||
context
.
_check_remote_attachment_deletion
)
{
return
pushDocumentAttachment
(
context
,
skip_attachment_dict
,
id
,
context
.
_remote_sub_storage
,
context
.
_local_sub_storage
,
signature_allAttachments
,
{
use_revert_post
:
context
.
_use_remote_post
,
conflict_force
:
(
context
.
_conflict_handling
===
CONFLICT_KEEP_REMOTE
),
conflict_revert
:
(
context
.
_conflict_handling
===
CONFLICT_KEEP_LOCAL
),
conflict_ignore
:
(
context
.
_conflict_handling
===
CONFLICT_CONTINUE
),
check_modification
:
context
.
_check_remote_attachment_modification
,
check_creation
:
context
.
_check_remote_attachment_creation
,
check_deletion
:
context
.
_check_remote_attachment_deletion
}
);
}
});
}
function
propagateModification
(
context
,
source
,
destination
,
doc
,
hash
,
id
,
skip_document_dict
,
options
)
{
var
result
=
new
RSVP
.
Queue
(),
post_id
,
to_skip
=
true
;
if
(
options
===
undefined
)
{
options
=
{};
}
if
(
doc
===
null
)
{
result
.
push
(
function
()
{
if
(
to_skip
)
{
skip_document_dict
[
id
]
=
null
;
return
source
.
get
(
id
);
})
.
push
(
function
(
source_doc
)
{
doc
=
source_doc
;
},
function
(
error
)
{
if
((
error
instanceof
jIO
.
util
.
jIOError
)
&&
(
error
.
status_code
===
404
))
{
throw
new
SkipError
(
id
);
}
throw
error
;
});
}
function
propagateDeletion
(
destination
,
id
)
{
// Do not delete a document if it has an attachment
// ie, replication should prevent losing user data
// Synchronize attachments before, to ensure
// all of them will be deleted too
return
repairDocumentAttachment
(
id
)
if
(
options
.
use_post
)
{
result
.
push
(
function
()
{
return
destination
.
post
(
doc
);
})
.
push
(
function
(
new_id
)
{
to_skip
=
false
;
post_id
=
new_id
;
return
source
.
put
(
post_id
,
doc
);
})
.
push
(
function
()
{
return
destination
.
allAttachments
(
id
);
// Copy all attachments
// This is not related to attachment replication
// It's just about not losing user data
return
source
.
allAttachments
(
id
);
})
.
push
(
function
(
attachment_dict
)
{
if
(
JSON
.
stringify
(
attachment_dict
)
===
"
{}
"
)
{
return
destination
.
remove
(
id
)
var
key
,
copy_queue
=
new
RSVP
.
Queue
();
function
copyAttachment
(
name
)
{
copy_queue
.
push
(
function
()
{
return
context
.
_signature_sub_storage
.
remove
(
id
);
return
source
.
getAttachment
(
id
,
name
);
})
.
push
(
function
(
blob
)
{
return
source
.
putAttachment
(
post_id
,
name
,
blob
);
});
}
},
function
(
error
)
{
if
((
error
instanceof
jIO
.
util
.
jIOError
)
&&
(
error
.
status_code
===
404
))
{
return
;
for
(
key
in
attachment_dict
)
{
if
(
attachment_dict
.
hasOwnProperty
(
key
))
{
copyAttachment
(
key
);
}
}
throw
error
;
return
copy_queue
;
})
.
push
(
function
()
{
skip_document_dict
[
id
]
=
null
;
return
source
.
remove
(
id
);
})
.
push
(
function
()
{
return
context
.
_signature_sub_storage
.
remove
(
id
);
})
.
push
(
function
()
{
to_skip
=
true
;
return
context
.
_signature_sub_storage
.
put
(
post_id
,
{
"
hash
"
:
hash
});
})
.
push
(
function
()
{
skip_document_dict
[
post_id
]
=
null
;
});
}
function
checkAndPropagate
(
status_hash
,
local_hash
,
doc
,
source
,
destination
,
id
,
conflict_force
,
conflict_revert
,
conflict_ignore
,
options
)
{
return
destination
.
get
(
id
)
.
push
(
function
(
remote_doc
)
{
return
[
remote_doc
,
generateHash
(
stringify
(
remote_doc
))];
},
function
(
error
)
{
if
((
error
instanceof
jIO
.
util
.
jIOError
)
&&
(
error
.
status_code
===
404
))
{
return
[
null
,
null
];
}
else
{
result
.
push
(
function
()
{
// Drop signature if the destination document was empty
// but a signature exists
if
(
options
.
create_new_document
===
true
)
{
return
context
.
_signature_sub_storage
.
remove
(
id
);
}
throw
error
;
})
.
push
(
function
(
remote_list
)
{
var
remote_doc
=
remote_list
[
0
],
remote_hash
=
remote_list
[
1
];
if
(
local_hash
===
remote_hash
)
{
// Same modifications on both side
if
(
local_hash
===
null
)
{
// Deleted on both side, drop signature
return
context
.
_signature_sub_storage
.
remove
(
id
)
.
push
(
function
()
{
skip_document_dict
[
id
]
=
null
;
});
.
push
(
function
()
{
return
destination
.
put
(
id
,
doc
);
})
.
push
(
function
()
{
return
context
.
_signature_sub_storage
.
put
(
id
,
{
"
hash
"
:
hash
});
});
}
return
result
.
push
(
function
()
{
if
(
to_skip
)
{
skip_document_dict
[
id
]
=
null
;
}
})
.
push
(
undefined
,
function
(
error
)
{
if
(
error
instanceof
SkipError
)
{
return
;
}
throw
error
;
});
}
function
propagateDeletion
(
context
,
destination
,
id
,
skip_document_dict
)
{
// Do not delete a document if it has an attachment
// ie, replication should prevent losing user data
// Synchronize attachments before, to ensure
// all of them will be deleted too
return
repairDocumentAttachment
(
context
,
id
)
.
push
(
function
()
{
return
destination
.
allAttachments
(
id
);
})
.
push
(
function
(
attachment_dict
)
{
if
(
JSON
.
stringify
(
attachment_dict
)
===
"
{}
"
)
{
return
destination
.
remove
(
id
)
.
push
(
function
()
{
return
context
.
_signature_sub_storage
.
remove
(
id
);
});
}
},
function
(
error
)
{
if
((
error
instanceof
jIO
.
util
.
jIOError
)
&&
(
error
.
status_code
===
404
))
{
return
;
}
throw
error
;
})
.
push
(
function
()
{
skip_document_dict
[
id
]
=
null
;
});
}
function
checkAndPropagate
(
context
,
skip_document_dict
,
cache
,
destination_key
,
status_hash
,
local_hash
,
doc
,
source
,
destination
,
id
,
conflict_force
,
conflict_revert
,
conflict_ignore
,
options
)
{
return
new
RSVP
.
Queue
()
.
push
(
function
()
{
if
(
options
.
signature_hash_key
!==
undefined
)
{
return
callAllDocsOnStorage
(
context
,
destination
,
cache
,
destination_key
)
.
push
(
function
(
result
)
{
if
(
result
.
hasOwnProperty
(
id
))
{
return
[
null
,
result
[
id
][
options
.
signature_hash_key
]];
}
return
[
null
,
null
];
});
}
return
destination
.
get
(
id
)
.
push
(
function
(
remote_doc
)
{
return
[
remote_doc
,
generateHash
(
stringify
(
remote_doc
))];
},
function
(
error
)
{
if
((
error
instanceof
jIO
.
util
.
jIOError
)
&&
(
error
.
status_code
===
404
))
{
return
[
null
,
null
];
}
throw
error
;
});
})
return
context
.
_signature_sub_storage
.
put
(
id
,
{
"
hash
"
:
local_hash
})
.
push
(
function
(
remote_list
)
{
var
remote_doc
=
remote_list
[
0
],
remote_hash
=
remote_list
[
1
];
if
(
local_hash
===
remote_hash
)
{
// Same modifications on both side
if
(
local_hash
===
null
)
{
// Deleted on both side, drop signature
return
context
.
_signature_sub_storage
.
remove
(
id
)
.
push
(
function
()
{
skip_document_dict
[
id
]
=
null
;
});
}
if
((
remote_hash
===
status_hash
)
||
(
conflict_force
===
true
))
{
// Modified only locally. No conflict or force
if
(
local_hash
===
null
)
{
// Deleted locally
return
propagateDeletion
(
destination
,
id
);
}
return
propagateModification
(
source
,
destination
,
doc
,
local_hash
,
id
,
{
use_post
:
((
options
.
use_post
)
&&
(
remote_hash
===
null
))});
}
// Conflict cases
if
(
conflict_ignore
===
true
)
{
return
;
}
return
context
.
_signature_sub_storage
.
put
(
id
,
{
"
hash
"
:
local_hash
})
.
push
(
function
()
{
skip_document_dict
[
id
]
=
null
;
});
}
if
((
conflict_revert
===
true
)
||
(
local_hash
===
null
))
{
// Automatically resolve conflict or force revert
if
(
remote_hash
===
null
)
{
// Deleted remotely
return
propagateDeletion
(
source
,
id
);
}
return
propagateModification
(
destination
,
source
,
remote_doc
,
remote_hash
,
id
,
{
use_post
:
((
options
.
use_revert_post
)
&&
(
local_hash
===
null
))}
);
if
((
remote_hash
===
status_hash
)
||
(
conflict_force
===
true
))
{
// Modified only locally. No conflict or force
if
(
local_hash
===
null
)
{
// Deleted locally
return
propagateDeletion
(
context
,
destination
,
id
,
skip_document_dict
);
}
return
propagateModification
(
context
,
source
,
destination
,
doc
,
local_hash
,
id
,
skip_document_dict
,
{
use_post
:
((
options
.
use_post
)
&&
(
remote_hash
===
null
)),
create_new_document
:
((
remote_hash
===
null
)
&&
(
status_hash
!==
null
))
});
}
// Conflict cases
if
(
conflict_ignore
===
true
)
{
return
;
}
// Minimize conflict if it can be resolved
if
((
conflict_revert
===
true
)
||
(
local_hash
===
null
))
{
// Automatically resolve conflict or force revert
if
(
remote_hash
===
null
)
{
// Copy remote modification remotely
return
propagateModification
(
source
,
destination
,
doc
,
local_hash
,
id
,
{
use_post
:
options
.
use_post
});
// Deleted remotely
return
propagateDeletion
(
context
,
source
,
id
,
skip_document_dict
);
}
throw
new
jIO
.
util
.
jIOError
(
"
Conflict on '
"
+
id
+
"
':
"
+
stringify
(
doc
||
''
)
+
"
!==
"
+
stringify
(
remote_doc
||
''
),
409
);
});
}
return
propagateModification
(
context
,
destination
,
source
,
remote_doc
,
remote_hash
,
id
,
skip_document_dict
,
{
use_post
:
((
options
.
use_revert_post
)
&&
(
local_hash
===
null
)),
create_new_document
:
((
local_hash
===
null
)
&&
(
status_hash
!==
null
))}
);
}
function
checkLocalDeletion
(
queue
,
destination
,
id
,
source
,
conflict_force
,
conflict_revert
,
conflict_ignore
,
options
)
{
var
status_hash
;
queue
.
push
(
function
()
{
return
context
.
_signature_sub_storage
.
get
(
id
);
})
.
push
(
function
(
result
)
{
status_hash
=
result
.
hash
;
return
checkAndPropagate
(
status_hash
,
null
,
null
,
// Minimize conflict if it can be resolved
if
(
remote_hash
===
null
)
{
// Copy remote modification remotely
return
propagateModification
(
context
,
source
,
destination
,
doc
,
local_hash
,
id
,
skip_document_dict
,
{
use_post
:
options
.
use_post
,
create_new_document
:
(
status_hash
!==
null
)});
}
doc
=
doc
||
local_hash
;
remote_doc
=
remote_doc
||
remote_hash
;
throw
new
jIO
.
util
.
jIOError
(
"
Conflict on '
"
+
id
+
"
':
"
+
stringify
(
doc
)
+
"
!==
"
+
stringify
(
remote_doc
),
409
);
});
}
function
checkLocalDeletion
(
queue
,
context
,
skip_document_dict
,
cache
,
destination_key
,
destination
,
id
,
source
,
conflict_force
,
conflict_revert
,
conflict_ignore
,
options
)
{
var
status_hash
;
queue
.
push
(
function
()
{
return
context
.
_signature_sub_storage
.
get
(
id
);
})
.
push
(
function
(
result
)
{
status_hash
=
result
.
hash
;
return
checkAndPropagate
(
context
,
skip_document_dict
,
cache
,
destination_key
,
status_hash
,
null
,
null
,
source
,
destination
,
id
,
conflict_force
,
conflict_revert
,
conflict_ignore
,
options
);
});
}
function
checkSignatureDifference
(
queue
,
context
,
skip_document_dict
,
cache
,
destination_key
,
source
,
destination
,
id
,
conflict_force
,
conflict_revert
,
conflict_ignore
,
local_hash
,
status_hash
,
options
)
{
queue
.
push
(
function
()
{
if
(
local_hash
===
null
)
{
// Hash was not provided by the allDocs query
return
source
.
get
(
id
);
}
return
null
;
})
.
push
(
function
(
doc
)
{
if
(
local_hash
===
null
)
{
// Hash was not provided by the allDocs query
local_hash
=
generateHash
(
stringify
(
doc
));
}
if
(
local_hash
!==
status_hash
)
{
return
checkAndPropagate
(
context
,
skip_document_dict
,
cache
,
destination_key
,
status_hash
,
local_hash
,
doc
,
source
,
destination
,
id
,
conflict_force
,
conflict_revert
,
conflict_ignore
,
options
);
});
}
}
});
}
function
checkSignatureDifference
(
queue
,
source
,
destination
,
id
,
conflict_force
,
conflict_revert
,
conflict_ignore
,
is_creation
,
is_modification
,
getMethod
,
options
)
{
queue
.
push
(
function
()
{
// Optimisation to save a get call to signature storage
if
(
is_creation
===
true
)
{
return
RSVP
.
all
([
getMethod
(
id
),
{
hash
:
null
}
]);
}
if
(
is_modification
===
true
)
{
return
RSVP
.
all
([
getMethod
(
id
),
context
.
_signature_sub_storage
.
get
(
id
)
]);
}
throw
new
jIO
.
util
.
jIOError
(
"
Unexpected call of
"
+
"
checkSignatureDifference
"
,
409
);
})
.
push
(
function
(
result_list
)
{
var
doc
=
result_list
[
0
],
local_hash
=
generateHash
(
stringify
(
doc
)),
status_hash
=
result_list
[
1
].
hash
;
if
(
local_hash
!==
status_hash
)
{
return
checkAndPropagate
(
status_hash
,
local_hash
,
doc
,
source
,
destination
,
id
,
conflict_force
,
conflict_revert
,
conflict_ignore
,
options
);
}
});
function
pushStorage
(
context
,
skip_document_dict
,
skip_deleted_document_dict
,
cache
,
source_key
,
destination_key
,
source
,
destination
,
signature_allDocs
,
options
)
{
var
argument_list
=
[],
argument_list_deletion
=
[];
if
(
!
options
.
hasOwnProperty
(
"
use_post
"
))
{
options
.
use_post
=
false
;
}
function
checkBulkSignatureDifference
(
queue
,
source
,
destination
,
id_list
,
document_status_list
,
options
,
conflict_force
,
conflict_revert
,
conflict_ignore
)
{
queue
.
push
(
function
()
{
return
source
.
bulk
(
id_list
);
})
.
push
(
function
(
result_list
)
{
var
i
,
argument_list
=
[];
function
getResult
(
j
)
{
return
function
(
id
)
{
if
(
id
!==
id_list
[
j
].
parameter_list
[
0
])
{
throw
new
Error
(
"
Does not access expected ID
"
+
id
);
}
return
result_list
[
j
];
};
}
for
(
i
=
0
;
i
<
result_list
.
length
;
i
+=
1
)
{
argument_list
[
i
]
=
[
undefined
,
source
,
destination
,
id_list
[
i
].
parameter_list
[
0
],
conflict_force
,
conflict_revert
,
conflict_ignore
,
document_status_list
[
i
].
is_creation
,
document_status_list
[
i
].
is_modification
,
getResult
(
i
),
options
];
}
return
dispatchQueue
(
checkSignatureDifference
,
argument_list
,
options
.
operation_amount
);
});
if
(
!
options
.
hasOwnProperty
(
"
use_revert_post
"
))
{
options
.
use_revert_post
=
false
;
}
function
pushStorage
(
source
,
destination
,
options
)
{
var
queue
=
new
RSVP
.
Queue
(),
argument_list
=
[],
argument_list_deletion
=
[];
if
(
!
options
.
hasOwnProperty
(
"
use_post
"
))
{
options
.
use_post
=
false
;
}
if
(
!
options
.
hasOwnProperty
(
"
use_revert_post
"
))
{
options
.
use_revert_post
=
false
;
}
return
queue
.
push
(
function
()
{
return
RSVP
.
all
([
source
.
allDocs
(
context
.
_query_options
),
context
.
_signature_sub_storage
.
allDocs
()
]);
})
.
push
(
function
(
result_list
)
{
var
i
,
local_dict
=
{},
document_list
=
[],
document_status_list
=
[],
signature_dict
=
{},
is_modification
,
is_creation
,
key
;
for
(
i
=
0
;
i
<
result_list
[
0
].
data
.
total_rows
;
i
+=
1
)
{
if
(
!
skip_document_dict
.
hasOwnProperty
(
result_list
[
0
].
data
.
rows
[
i
].
id
))
{
local_dict
[
result_list
[
0
].
data
.
rows
[
i
].
id
]
=
i
;
return
callAllDocsOnStorage
(
context
,
source
,
cache
,
source_key
)
.
push
(
function
(
source_allDocs
)
{
var
i
,
local_dict
=
{},
signature_dict
=
{},
is_modification
,
is_creation
,
status_hash
,
local_hash
,
key
,
queue
=
new
RSVP
.
Queue
();
for
(
key
in
source_allDocs
)
{
if
(
source_allDocs
.
hasOwnProperty
(
key
))
{
if
(
!
skip_document_dict
.
hasOwnProperty
(
key
))
{
local_dict
[
key
]
=
source_allDocs
[
key
];
}
}
for
(
i
=
0
;
i
<
result_list
[
1
].
data
.
total_rows
;
i
+=
1
)
{
if
(
!
skip_document_dict
.
hasOwnProperty
(
result_list
[
1
].
data
.
rows
[
i
].
id
))
{
signature_dict
[
result_list
[
1
].
data
.
rows
[
i
].
id
]
=
i
;
}
}
/*
for (i = 0; i < source_allDocs.data.total_rows; i += 1) {
if (!skip_document_dict.hasOwnProperty(
source_allDocs.data.rows[i].id
)) {
local_dict[source_allDocs.data.rows[i].id] =
source_allDocs.data.rows[i].value;
}
i
=
0
;
for
(
key
in
local_dict
)
{
if
(
local_dict
.
hasOwnProperty
(
key
))
{
is_modification
=
signature_dict
.
hasOwnProperty
(
key
)
&&
options
.
check_modification
;
is_creation
=
!
signature_dict
.
hasOwnProperty
(
key
)
&&
options
.
check_creation
;
if
(
is_modification
===
true
||
is_creation
===
true
)
{
if
(
options
.
use_bulk_get
===
true
)
{
document_list
.
push
({
method
:
"
get
"
,
parameter_list
:
[
key
]
});
document_status_list
.
push
({
is_creation
:
is_creation
,
is_modification
:
is_modification
});
}
else
{
argument_list
[
i
]
=
[
undefined
,
source
,
destination
,
key
,
options
.
conflict_force
,
options
.
conflict_revert
,
options
.
conflict_ignore
,
is_creation
,
is_modification
,
source
.
get
.
bind
(
source
),
options
];
i
+=
1
;
}
*/
for
(
i
=
0
;
i
<
signature_allDocs
.
data
.
total_rows
;
i
+=
1
)
{
if
(
!
skip_document_dict
.
hasOwnProperty
(
signature_allDocs
.
data
.
rows
[
i
].
id
))
{
signature_dict
[
signature_allDocs
.
data
.
rows
[
i
].
id
]
=
signature_allDocs
.
data
.
rows
[
i
].
value
.
hash
;
}
}
for
(
key
in
local_dict
)
{
if
(
local_dict
.
hasOwnProperty
(
key
))
{
is_modification
=
signature_dict
.
hasOwnProperty
(
key
)
&&
options
.
check_modification
;
is_creation
=
!
signature_dict
.
hasOwnProperty
(
key
)
&&
options
.
check_creation
;
if
(
is_creation
===
true
)
{
status_hash
=
null
;
}
else
if
(
is_modification
===
true
)
{
status_hash
=
signature_dict
[
key
];
}
local_hash
=
null
;
if
(
options
.
signature_hash_key
!==
undefined
)
{
local_hash
=
local_dict
[
key
][
options
.
signature_hash_key
];
if
(
is_modification
===
true
)
{
// Bypass fetching all documents and calculating the sha
// Compare the select list values returned by allDocs calls
is_modification
=
false
;
if
(
local_hash
!==
status_hash
)
{
is_modification
=
true
;
}
}
}
if
(
is_modification
===
true
||
is_creation
===
true
)
{
argument_list
.
push
([
undefined
,
context
,
skip_document_dict
,
cache
,
destination_key
,
source
,
destination
,
key
,
options
.
conflict_force
,
options
.
conflict_revert
,
options
.
conflict_ignore
,
local_hash
,
status_hash
,
options
]);
}
}
queue
.
push
(
function
()
{
return
dispatchQueue
(
checkSignatureDifference
,
argument_list
,
options
.
operation_amount
);
});
if
(
options
.
check_deletion
===
true
)
{
i
=
0
;
for
(
key
in
signature_dict
)
{
if
(
signature_dict
.
hasOwnProperty
(
key
))
{
if
(
!
local_dict
.
hasOwnProperty
(
key
))
{
argument_list_deletion
[
i
]
=
[
undefined
,
destination
,
key
,
source
,
options
.
conflict_force
,
options
.
conflict_revert
,
options
.
conflict_ignore
,
options
];
i
+=
1
;
}
}
queue
.
push
(
function
()
{
return
dispatchQueue
(
context
,
checkSignatureDifference
,
argument_list
,
options
.
operation_amount
);
});
for
(
key
in
signature_dict
)
{
if
(
signature_dict
.
hasOwnProperty
(
key
))
{
if
(
!
local_dict
.
hasOwnProperty
(
key
))
{
if
(
options
.
check_deletion
===
true
)
{
argument_list_deletion
.
push
([
undefined
,
context
,
skip_document_dict
,
cache
,
destination_key
,
destination
,
key
,
source
,
options
.
conflict_force
,
options
.
conflict_revert
,
options
.
conflict_ignore
,
options
]);
}
else
{
skip_deleted_document_dict
[
key
]
=
null
;
}
}
queue
.
push
(
function
()
{
return
dispatchQueue
(
checkLocalDeletion
,
argument_list_deletion
,
options
.
operation_amount
);
});
}
if
((
options
.
use_bulk_get
===
true
)
&&
(
document_list
.
length
!==
0
))
{
checkBulkSignatureDifference
(
queue
,
source
,
destination
,
document_list
,
document_status_list
,
options
,
options
.
conflict_force
,
options
.
conflict_revert
,
options
.
conflict_ignore
);
}
});
}
function
repairDocument
(
queue
,
id
)
{
queue
.
push
(
function
()
{
return
repairDocumentAttachment
(
id
);
}
if
(
argument_list_deletion
.
length
!==
0
)
{
queue
.
push
(
function
()
{
return
dispatchQueue
(
context
,
checkLocalDeletion
,
argument_list_deletion
,
options
.
operation_amount
);
});
}
return
queue
;
});
}
}
function
repairDocument
(
queue
,
context
,
id
)
{
queue
.
push
(
function
()
{
return
repairDocumentAttachment
(
context
,
id
);
});
}
ReplicateStorage
.
prototype
.
repair
=
function
()
{
var
context
=
this
,
argument_list
=
arguments
,
skip_document_dict
=
{},
skip_deleted_document_dict
=
{},
cache
=
{};
return
new
RSVP
.
Queue
()
.
push
(
function
()
{
// Ensure that the document storage is usable
return
context
.
_signature_sub_storage
.
__storage
.
_sub_storage
.
get
(
context
.
_signature_hash
);
if
(
context
.
_custom_signature_sub_storage
===
false
)
{
// Do not sync the signature document
skip_document_dict
[
context
.
_signature_hash
]
=
null
;
return
context
.
_signature_sub_storage
.
__storage
.
_sub_storage
.
__storage
.
_sub_storage
.
get
(
context
.
_signature_hash
);
}
})
.
push
(
undefined
,
function
(
error
)
{
if
((
error
instanceof
jIO
.
util
.
jIOError
)
&&
(
error
.
status_code
===
404
))
{
return
context
.
_signature_sub_storage
.
__storage
.
_sub_storage
.
put
(
context
.
_signature_hash
,
{}
);
return
context
.
_signature_sub_storage
.
__storage
.
_sub_storage
.
__storage
.
_sub_storage
.
put
(
context
.
_signature_hash
,
{}
);
}
throw
error
;
})
...
...
@@ -9417,11 +9529,28 @@ return new Parser;
})
.
push
(
function
()
{
if
(
context
.
_check_local_modification
||
context
.
_check_local_creation
||
context
.
_check_local_deletion
||
context
.
_check_remote_modification
||
context
.
_check_remote_creation
||
context
.
_check_remote_deletion
)
{
return
context
.
_signature_sub_storage
.
allDocs
({
select_list
:
[
'
hash
'
]
});
}
})
.
push
(
function
(
signature_allDocs
)
{
if
(
context
.
_check_local_modification
||
context
.
_check_local_creation
||
context
.
_check_local_deletion
)
{
return
pushStorage
(
context
.
_local_sub_storage
,
return
pushStorage
(
context
,
skip_document_dict
,
skip_deleted_document_dict
,
cache
,
'
local
'
,
'
remote
'
,
context
.
_local_sub_storage
,
context
.
_remote_sub_storage
,
signature_allDocs
,
{
use_post
:
context
.
_use_remote_post
,
conflict_force
:
(
context
.
_conflict_handling
===
...
...
@@ -9433,28 +9562,25 @@ return new Parser;
check_modification
:
context
.
_check_local_modification
,
check_creation
:
context
.
_check_local_creation
,
check_deletion
:
context
.
_check_local_deletion
,
operation_amount
:
context
.
_parallel_operation_amount
operation_amount
:
context
.
_parallel_operation_amount
,
signature_hash_key
:
context
.
_signature_hash_key
})
.
push
(
function
()
{
return
signature_allDocs
;
});
}
return
signature_allDocs
;
})
.
push
(
function
()
{
// Autoactivate bulk if substorage implements it
// Keep it like this until the bulk API is stabilized
var
use_bulk_get
=
false
;
try
{
use_bulk_get
=
context
.
_remote_sub_storage
.
hasCapacity
(
"
bulk_get
"
);
}
catch
(
error
)
{
if
(
!
((
error
instanceof
jIO
.
util
.
jIOError
)
&&
(
error
.
status_code
===
501
)))
{
throw
error
;
}
}
.
push
(
function
(
signature_allDocs
)
{
if
(
context
.
_check_remote_modification
||
context
.
_check_remote_creation
||
context
.
_check_remote_deletion
)
{
return
pushStorage
(
context
.
_remote_sub_storage
,
context
.
_local_sub_storage
,
{
use_bulk_get
:
use_bulk_get
,
return
pushStorage
(
context
,
skip_document_dict
,
skip_deleted_document_dict
,
cache
,
'
remote
'
,
'
local
'
,
context
.
_remote_sub_storage
,
context
.
_local_sub_storage
,
signature_allDocs
,
{
use_revert_post
:
context
.
_use_remote_post
,
conflict_force
:
(
context
.
_conflict_handling
===
CONFLICT_KEEP_REMOTE
),
...
...
@@ -9465,7 +9591,8 @@ return new Parser;
check_modification
:
context
.
_check_remote_modification
,
check_creation
:
context
.
_check_remote_creation
,
check_deletion
:
context
.
_check_remote_deletion
,
operation_amount
:
context
.
_parallel_operation_amount
operation_amount
:
context
.
_parallel_operation_amount
,
signature_hash_key
:
context
.
_signature_hash_key
});
}
})
...
...
@@ -9481,17 +9608,25 @@ return new Parser;
return
context
.
_signature_sub_storage
.
allDocs
()
.
push
(
function
(
result
)
{
var
i
,
argument_list
=
[],
local_argument_list
=
[],
id
,
len
=
result
.
data
.
total_rows
;
for
(
i
=
0
;
i
<
len
;
i
+=
1
)
{
argument_list
.
push
(
[
undefined
,
result
.
data
.
rows
[
i
].
id
]
);
id
=
result
.
data
.
rows
[
i
].
id
;
// Do not synchronize attachment if one version of the document
// is deleted but not pushed to the other storage
if
(
!
skip_deleted_document_dict
.
hasOwnProperty
(
id
)
||
skip_document_dict
.
hasOwnProperty
(
id
))
{
local_argument_list
.
push
(
[
undefined
,
context
,
id
]
);
}
}
return
dispatchQueue
(
context
,
repairDocument
,
argument_list
,
local_
argument_list
,
context
.
_parallel_operation_amount
);
});
...
...
@@ -11154,56 +11289,6 @@ return new Parser;
});
};
ERP5Storage
.
prototype
.
bulk
=
function
(
request_list
)
{
var
i
,
storage
=
this
,
bulk_list
=
[];
for
(
i
=
0
;
i
<
request_list
.
length
;
i
+=
1
)
{
if
(
request_list
[
i
].
method
!==
"
get
"
)
{
throw
new
Error
(
"
ERP5Storage: not supported
"
+
request_list
[
i
].
method
+
"
in bulk
"
);
}
bulk_list
.
push
({
relative_url
:
request_list
[
i
].
parameter_list
[
0
],
view
:
storage
.
_default_view_reference
});
}
return
getSiteDocument
(
storage
)
.
push
(
function
(
site_hal
)
{
var
form_data
=
new
FormData
();
form_data
.
append
(
"
bulk_list
"
,
JSON
.
stringify
(
bulk_list
));
return
jIO
.
util
.
ajax
({
"
type
"
:
"
POST
"
,
"
url
"
:
site_hal
.
_actions
.
bulk
.
href
,
"
data
"
:
form_data
,
// "headers": {
// "Content-Type": "application/json"
// },
"
xhrFields
"
:
{
withCredentials
:
true
}
});
})
.
push
(
function
(
response
)
{
var
result_list
=
[],
hateoas
=
JSON
.
parse
(
response
.
target
.
responseText
);
function
pushResult
(
json
)
{
return
extractPropertyFromFormJSON
(
json
)
.
push
(
function
(
json2
)
{
return
convertJSONToGet
(
json2
);
});
}
for
(
i
=
0
;
i
<
hateoas
.
result_list
.
length
;
i
+=
1
)
{
result_list
.
push
(
pushResult
(
hateoas
.
result_list
[
i
]));
}
return
RSVP
.
all
(
result_list
);
});
};
ERP5Storage
.
prototype
.
post
=
function
(
data
)
{
var
context
=
this
,
new_id
;
...
...
@@ -11430,7 +11515,7 @@ return new Parser;
ERP5Storage
.
prototype
.
hasCapacity
=
function
(
name
)
{
return
((
name
===
"
list
"
)
||
(
name
===
"
query
"
)
||
(
name
===
"
select
"
)
||
(
name
===
"
limit
"
)
||
(
name
===
"
sort
"
))
||
(
name
===
"
bulk_get
"
)
;
(
name
===
"
sort
"
));
};
function
isSingleLocalRoles
(
parsed_query
)
{
...
...
@@ -12588,14 +12673,18 @@ return new Parser;
});
};
function
handleGet
(
request
,
resolve
,
reject
)
{
function
handleGet
(
store
,
id
,
resolve
,
reject
)
{
var
request
=
store
.
get
(
id
);
request
.
onerror
=
reject
;
request
.
onsuccess
=
function
()
{
if
(
request
.
result
)
{
resolve
(
request
.
result
);
}
else
{
// XXX How to get ID
reject
(
new
jIO
.
util
.
jIOError
(
"
Cannot find document
"
,
404
));
reject
(
new
jIO
.
util
.
jIOError
(
"
IndexedDB: cannot find object '
"
+
id
+
"
' in the '
"
+
store
.
name
+
"
' store
"
,
404
));
}
};
}
...
...
@@ -12606,7 +12695,8 @@ return new Parser;
return
new
RSVP
.
Promise
(
function
(
resolve
,
reject
)
{
var
transaction
=
openTransaction
(
db
,
[
"
metadata
"
],
"
readonly
"
);
handleGet
(
transaction
.
objectStore
(
"
metadata
"
).
get
(
id
),
transaction
.
objectStore
(
"
metadata
"
),
id
,
resolve
,
reject
);
...
...
@@ -12639,7 +12729,8 @@ return new Parser;
);
}
handleGet
(
transaction
.
objectStore
(
"
metadata
"
).
get
(
id
),
transaction
.
objectStore
(
"
metadata
"
),
id
,
getAttachments
,
reject
);
...
...
@@ -12767,7 +12858,8 @@ return new Parser;
result_list
.
push
(
result
);
}
i
+=
1
;
handleGet
(
store
.
get
(
buildKeyPath
([
id
,
name
,
i
])),
handleGet
(
store
,
buildKeyPath
([
id
,
name
,
i
]),
(
i
<=
end_index
)
?
getPart
(
i
)
:
resolver
,
reject
);
...
...
@@ -12776,8 +12868,8 @@ return new Parser;
getPart
(
start_index
-
1
)();
}
// XXX Should raise if key is not good
handleGet
(
transaction
.
objectStore
(
"
attachment
"
)
.
get
(
buildKeyPath
([
id
,
name
])
),
handleGet
(
transaction
.
objectStore
(
"
attachment
"
)
,
buildKeyPath
([
id
,
name
]
),
getBlob
,
reject
);
...
...
@@ -13007,12 +13099,12 @@ return new Parser;
})
.
push
(
function
(
dataURL
)
{
//string->arraybuffer
var
strLen
=
dataURL
.
currentT
arget
.
result
.
length
,
var
strLen
=
dataURL
.
t
arget
.
result
.
length
,
buf
=
new
ArrayBuffer
(
strLen
),
bufView
=
new
Uint8Array
(
buf
),
i
;
dataURL
=
dataURL
.
currentT
arget
.
result
;
dataURL
=
dataURL
.
t
arget
.
result
;
for
(
i
=
0
;
i
<
strLen
;
i
+=
1
)
{
bufView
[
i
]
=
dataURL
.
charCodeAt
(
i
);
}
...
...
@@ -13049,7 +13141,7 @@ return new Parser;
.
push
(
function
(
coded
)
{
var
initializaton_vector
;
coded
=
coded
.
currentT
arget
.
result
;
coded
=
coded
.
t
arget
.
result
;
initializaton_vector
=
new
Uint8Array
(
coded
.
slice
(
0
,
12
));
return
new
RSVP
.
Queue
()
.
push
(
function
()
{
...
...
@@ -13268,7 +13360,7 @@ return new Parser;
return
jIO
.
util
.
readBlobAsDataURL
(
blob
);
})
.
push
(
function
(
strBlob
)
{
argument_list
[
index
+
2
].
push
(
strBlob
.
currentT
arget
.
result
);
argument_list
[
index
+
2
].
push
(
strBlob
.
t
arget
.
result
);
return
;
});
}
...
...
@@ -13451,4 +13543,4 @@ return new Parser;
jIO
.
addStorage
(
'
websql
'
,
WebSQLStorage
);
}(
jIO
,
RSVP
,
Blob
,
openDatabase
));
}(
jIO
,
RSVP
,
Blob
,
openDatabase
));
\ No newline at end of file
bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_jio_js.xml
View file @
9aff3608
...
...
@@ -236,7 +236,7 @@
</item>
<item>
<key>
<string>
serial
</string>
</key>
<value>
<string>
9
59.8888.26905.39645
</string>
</value>
<value>
<string>
9
60.25571.62873.4317
</string>
</value>
</item>
<item>
<key>
<string>
state
</string>
</key>
...
...
@@ -254,7 +254,7 @@
</tuple>
<state>
<tuple>
<float>
149
4334109.43
</float>
<float>
149
9172288.9
</float>
<string>
UTC
</string>
</tuple>
</state>
...
...
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