Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
jio_mebibou
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
Alexandra Rogova
jio_mebibou
Commits
d9db77a0
Commit
d9db77a0
authored
Aug 21, 2013
by
Tristan Cavelier
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
built file removed
parent
1c6ccb5b
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
0 additions
and
4456 deletions
+0
-4456
complex_queries.js
complex_queries.js
+0
-1607
jio.js
jio.js
+0
-2849
No files found.
complex_queries.js
deleted
100644 → 0
View file @
1c6ccb5b
/*
* Copyright 2013, Nexedi SA
* Released under the LGPL license.
* http://www.gnu.org/licenses/lgpl.html
*/
/**
* Provides some function to use complex queries with item list
*
* @module complex_queries
*/
// define([module_name], [dependencies], module);
(
function
(
dependencies
,
module
)
{
"
use strict
"
;
if
(
typeof
define
===
'
function
'
&&
define
.
amd
)
{
return
define
(
dependencies
,
module
);
}
if
(
typeof
exports
===
'
object
'
)
{
return
module
(
exports
);
}
window
.
complex_queries
=
{};
module
(
window
.
complex_queries
);
}([
'
exports
'
],
function
(
to_export
)
{
"
use strict
"
;
/**
* Add a secured (write permission denied) property to an object.
*
* @param {Object} object The object to fill
* @param {String} key The object key where to store the property
* @param {Any} value The value to store
*/
function
_export
(
key
,
value
)
{
Object
.
defineProperty
(
to_export
,
key
,
{
"
configurable
"
:
false
,
"
enumerable
"
:
true
,
"
writable
"
:
false
,
"
value
"
:
value
});
}
/**
* Parse a text request to a json query object tree
*
* @param {String} string The string to parse
* @return {Object} The json query tree
*/
function
parseStringToObject
(
string
)
{
/*
Default template driver for JS/CC generated parsers running as
browser-based JavaScript/ECMAScript applications.
WARNING: This parser template will not run as console and has lesser
features for debugging than the console derivates for the
various JavaScript platforms.
Features:
- Parser trace messages
- Integrated panic-mode error recovery
Written 2007, 2008 by Jan Max Meyer, J.M.K S.F. Software Technologies
This is in the public domain.
*/
var
NODEJS__dbg_withtrace
=
false
;
var
NODEJS__dbg_string
=
new
String
();
function
__NODEJS_dbg_print
(
text
)
{
NODEJS__dbg_string
+=
text
+
"
\n
"
;
}
function
__NODEJS_lex
(
info
)
{
var
state
=
0
;
var
match
=
-
1
;
var
match_pos
=
0
;
var
start
=
0
;
var
pos
=
info
.
offset
+
1
;
do
{
pos
--
;
state
=
0
;
match
=
-
2
;
start
=
pos
;
if
(
info
.
src
.
length
<=
start
)
return
19
;
do
{
switch
(
state
)
{
case
0
:
if
(
(
info
.
src
.
charCodeAt
(
pos
)
>=
0
&&
info
.
src
.
charCodeAt
(
pos
)
<=
8
)
||
(
info
.
src
.
charCodeAt
(
pos
)
>=
10
&&
info
.
src
.
charCodeAt
(
pos
)
<=
31
)
||
info
.
src
.
charCodeAt
(
pos
)
==
33
||
(
info
.
src
.
charCodeAt
(
pos
)
>=
35
&&
info
.
src
.
charCodeAt
(
pos
)
<=
39
)
||
(
info
.
src
.
charCodeAt
(
pos
)
>=
42
&&
info
.
src
.
charCodeAt
(
pos
)
<=
57
)
||
info
.
src
.
charCodeAt
(
pos
)
==
59
||
(
info
.
src
.
charCodeAt
(
pos
)
>=
63
&&
info
.
src
.
charCodeAt
(
pos
)
<=
64
)
||
(
info
.
src
.
charCodeAt
(
pos
)
>=
66
&&
info
.
src
.
charCodeAt
(
pos
)
<=
77
)
||
(
info
.
src
.
charCodeAt
(
pos
)
>=
80
&&
info
.
src
.
charCodeAt
(
pos
)
<=
254
)
)
state
=
1
;
else
if
(
info
.
src
.
charCodeAt
(
pos
)
==
9
)
state
=
2
;
else
if
(
info
.
src
.
charCodeAt
(
pos
)
==
40
)
state
=
3
;
else
if
(
info
.
src
.
charCodeAt
(
pos
)
==
41
)
state
=
4
;
else
if
(
info
.
src
.
charCodeAt
(
pos
)
==
60
||
info
.
src
.
charCodeAt
(
pos
)
==
62
)
state
=
5
;
else
if
(
info
.
src
.
charCodeAt
(
pos
)
==
34
)
state
=
11
;
else
if
(
info
.
src
.
charCodeAt
(
pos
)
==
79
)
state
=
12
;
else
if
(
info
.
src
.
charCodeAt
(
pos
)
==
32
)
state
=
13
;
else
if
(
info
.
src
.
charCodeAt
(
pos
)
==
61
)
state
=
14
;
else
if
(
info
.
src
.
charCodeAt
(
pos
)
==
65
)
state
=
18
;
else
if
(
info
.
src
.
charCodeAt
(
pos
)
==
78
)
state
=
19
;
else
state
=
-
1
;
break
;
case
1
:
if
(
(
info
.
src
.
charCodeAt
(
pos
)
>=
0
&&
info
.
src
.
charCodeAt
(
pos
)
<=
31
)
||
info
.
src
.
charCodeAt
(
pos
)
==
33
||
(
info
.
src
.
charCodeAt
(
pos
)
>=
35
&&
info
.
src
.
charCodeAt
(
pos
)
<=
39
)
||
(
info
.
src
.
charCodeAt
(
pos
)
>=
42
&&
info
.
src
.
charCodeAt
(
pos
)
<=
57
)
||
(
info
.
src
.
charCodeAt
(
pos
)
>=
59
&&
info
.
src
.
charCodeAt
(
pos
)
<=
254
)
)
state
=
1
;
else
if
(
info
.
src
.
charCodeAt
(
pos
)
==
58
)
state
=
6
;
else
state
=
-
1
;
match
=
10
;
match_pos
=
pos
;
break
;
case
2
:
if
(
(
info
.
src
.
charCodeAt
(
pos
)
>=
0
&&
info
.
src
.
charCodeAt
(
pos
)
<=
31
)
||
info
.
src
.
charCodeAt
(
pos
)
==
33
||
(
info
.
src
.
charCodeAt
(
pos
)
>=
35
&&
info
.
src
.
charCodeAt
(
pos
)
<=
39
)
||
(
info
.
src
.
charCodeAt
(
pos
)
>=
42
&&
info
.
src
.
charCodeAt
(
pos
)
<=
57
)
||
(
info
.
src
.
charCodeAt
(
pos
)
>=
59
&&
info
.
src
.
charCodeAt
(
pos
)
<=
254
)
)
state
=
1
;
else
if
(
info
.
src
.
charCodeAt
(
pos
)
==
58
)
state
=
6
;
else
state
=
-
1
;
match
=
1
;
match_pos
=
pos
;
break
;
case
3
:
state
=
-
1
;
match
=
3
;
match_pos
=
pos
;
break
;
case
4
:
state
=
-
1
;
match
=
4
;
match_pos
=
pos
;
break
;
case
5
:
if
(
info
.
src
.
charCodeAt
(
pos
)
==
61
)
state
=
14
;
else
state
=
-
1
;
match
=
11
;
match_pos
=
pos
;
break
;
case
6
:
state
=
-
1
;
match
=
8
;
match_pos
=
pos
;
break
;
case
7
:
state
=
-
1
;
match
=
9
;
match_pos
=
pos
;
break
;
case
8
:
if
(
(
info
.
src
.
charCodeAt
(
pos
)
>=
0
&&
info
.
src
.
charCodeAt
(
pos
)
<=
31
)
||
info
.
src
.
charCodeAt
(
pos
)
==
33
||
(
info
.
src
.
charCodeAt
(
pos
)
>=
35
&&
info
.
src
.
charCodeAt
(
pos
)
<=
39
)
||
(
info
.
src
.
charCodeAt
(
pos
)
>=
42
&&
info
.
src
.
charCodeAt
(
pos
)
<=
57
)
||
(
info
.
src
.
charCodeAt
(
pos
)
>=
59
&&
info
.
src
.
charCodeAt
(
pos
)
<=
254
)
)
state
=
1
;
else
if
(
info
.
src
.
charCodeAt
(
pos
)
==
58
)
state
=
6
;
else
state
=
-
1
;
match
=
6
;
match_pos
=
pos
;
break
;
case
9
:
if
(
(
info
.
src
.
charCodeAt
(
pos
)
>=
0
&&
info
.
src
.
charCodeAt
(
pos
)
<=
31
)
||
info
.
src
.
charCodeAt
(
pos
)
==
33
||
(
info
.
src
.
charCodeAt
(
pos
)
>=
35
&&
info
.
src
.
charCodeAt
(
pos
)
<=
39
)
||
(
info
.
src
.
charCodeAt
(
pos
)
>=
42
&&
info
.
src
.
charCodeAt
(
pos
)
<=
57
)
||
(
info
.
src
.
charCodeAt
(
pos
)
>=
59
&&
info
.
src
.
charCodeAt
(
pos
)
<=
254
)
)
state
=
1
;
else
if
(
info
.
src
.
charCodeAt
(
pos
)
==
58
)
state
=
6
;
else
state
=
-
1
;
match
=
5
;
match_pos
=
pos
;
break
;
case
10
:
if
(
(
info
.
src
.
charCodeAt
(
pos
)
>=
0
&&
info
.
src
.
charCodeAt
(
pos
)
<=
31
)
||
info
.
src
.
charCodeAt
(
pos
)
==
33
||
(
info
.
src
.
charCodeAt
(
pos
)
>=
35
&&
info
.
src
.
charCodeAt
(
pos
)
<=
39
)
||
(
info
.
src
.
charCodeAt
(
pos
)
>=
42
&&
info
.
src
.
charCodeAt
(
pos
)
<=
57
)
||
(
info
.
src
.
charCodeAt
(
pos
)
>=
59
&&
info
.
src
.
charCodeAt
(
pos
)
<=
254
)
)
state
=
1
;
else
if
(
info
.
src
.
charCodeAt
(
pos
)
==
58
)
state
=
6
;
else
state
=
-
1
;
match
=
7
;
match_pos
=
pos
;
break
;
case
11
:
if
(
info
.
src
.
charCodeAt
(
pos
)
==
34
)
state
=
7
;
else
if
(
(
info
.
src
.
charCodeAt
(
pos
)
>=
0
&&
info
.
src
.
charCodeAt
(
pos
)
<=
33
)
||
(
info
.
src
.
charCodeAt
(
pos
)
>=
35
&&
info
.
src
.
charCodeAt
(
pos
)
<=
91
)
||
(
info
.
src
.
charCodeAt
(
pos
)
>=
93
&&
info
.
src
.
charCodeAt
(
pos
)
<=
254
)
)
state
=
11
;
else
if
(
info
.
src
.
charCodeAt
(
pos
)
==
92
)
state
=
15
;
else
state
=
-
1
;
break
;
case
12
:
if
(
(
info
.
src
.
charCodeAt
(
pos
)
>=
0
&&
info
.
src
.
charCodeAt
(
pos
)
<=
31
)
||
info
.
src
.
charCodeAt
(
pos
)
==
33
||
(
info
.
src
.
charCodeAt
(
pos
)
>=
35
&&
info
.
src
.
charCodeAt
(
pos
)
<=
39
)
||
(
info
.
src
.
charCodeAt
(
pos
)
>=
42
&&
info
.
src
.
charCodeAt
(
pos
)
<=
57
)
||
(
info
.
src
.
charCodeAt
(
pos
)
>=
59
&&
info
.
src
.
charCodeAt
(
pos
)
<=
81
)
||
(
info
.
src
.
charCodeAt
(
pos
)
>=
83
&&
info
.
src
.
charCodeAt
(
pos
)
<=
254
)
)
state
=
1
;
else
if
(
info
.
src
.
charCodeAt
(
pos
)
==
58
)
state
=
6
;
else
if
(
info
.
src
.
charCodeAt
(
pos
)
==
82
)
state
=
8
;
else
state
=
-
1
;
match
=
10
;
match_pos
=
pos
;
break
;
case
13
:
state
=
-
1
;
match
=
1
;
match_pos
=
pos
;
break
;
case
14
:
state
=
-
1
;
match
=
11
;
match_pos
=
pos
;
break
;
case
15
:
if
(
(
info
.
src
.
charCodeAt
(
pos
)
>=
0
&&
info
.
src
.
charCodeAt
(
pos
)
<=
254
)
)
state
=
11
;
else
state
=
-
1
;
break
;
case
16
:
if
(
(
info
.
src
.
charCodeAt
(
pos
)
>=
0
&&
info
.
src
.
charCodeAt
(
pos
)
<=
31
)
||
info
.
src
.
charCodeAt
(
pos
)
==
33
||
(
info
.
src
.
charCodeAt
(
pos
)
>=
35
&&
info
.
src
.
charCodeAt
(
pos
)
<=
39
)
||
(
info
.
src
.
charCodeAt
(
pos
)
>=
42
&&
info
.
src
.
charCodeAt
(
pos
)
<=
57
)
||
(
info
.
src
.
charCodeAt
(
pos
)
>=
59
&&
info
.
src
.
charCodeAt
(
pos
)
<=
67
)
||
(
info
.
src
.
charCodeAt
(
pos
)
>=
69
&&
info
.
src
.
charCodeAt
(
pos
)
<=
254
)
)
state
=
1
;
else
if
(
info
.
src
.
charCodeAt
(
pos
)
==
58
)
state
=
6
;
else
if
(
info
.
src
.
charCodeAt
(
pos
)
==
68
)
state
=
9
;
else
state
=
-
1
;
match
=
10
;
match_pos
=
pos
;
break
;
case
17
:
if
(
(
info
.
src
.
charCodeAt
(
pos
)
>=
0
&&
info
.
src
.
charCodeAt
(
pos
)
<=
31
)
||
info
.
src
.
charCodeAt
(
pos
)
==
33
||
(
info
.
src
.
charCodeAt
(
pos
)
>=
35
&&
info
.
src
.
charCodeAt
(
pos
)
<=
39
)
||
(
info
.
src
.
charCodeAt
(
pos
)
>=
42
&&
info
.
src
.
charCodeAt
(
pos
)
<=
57
)
||
(
info
.
src
.
charCodeAt
(
pos
)
>=
59
&&
info
.
src
.
charCodeAt
(
pos
)
<=
83
)
||
(
info
.
src
.
charCodeAt
(
pos
)
>=
85
&&
info
.
src
.
charCodeAt
(
pos
)
<=
254
)
)
state
=
1
;
else
if
(
info
.
src
.
charCodeAt
(
pos
)
==
58
)
state
=
6
;
else
if
(
info
.
src
.
charCodeAt
(
pos
)
==
84
)
state
=
10
;
else
state
=
-
1
;
match
=
10
;
match_pos
=
pos
;
break
;
case
18
:
if
(
(
info
.
src
.
charCodeAt
(
pos
)
>=
0
&&
info
.
src
.
charCodeAt
(
pos
)
<=
31
)
||
info
.
src
.
charCodeAt
(
pos
)
==
33
||
(
info
.
src
.
charCodeAt
(
pos
)
>=
35
&&
info
.
src
.
charCodeAt
(
pos
)
<=
39
)
||
(
info
.
src
.
charCodeAt
(
pos
)
>=
42
&&
info
.
src
.
charCodeAt
(
pos
)
<=
57
)
||
(
info
.
src
.
charCodeAt
(
pos
)
>=
59
&&
info
.
src
.
charCodeAt
(
pos
)
<=
77
)
||
(
info
.
src
.
charCodeAt
(
pos
)
>=
79
&&
info
.
src
.
charCodeAt
(
pos
)
<=
254
)
)
state
=
1
;
else
if
(
info
.
src
.
charCodeAt
(
pos
)
==
58
)
state
=
6
;
else
if
(
info
.
src
.
charCodeAt
(
pos
)
==
78
)
state
=
16
;
else
state
=
-
1
;
match
=
10
;
match_pos
=
pos
;
break
;
case
19
:
if
(
(
info
.
src
.
charCodeAt
(
pos
)
>=
0
&&
info
.
src
.
charCodeAt
(
pos
)
<=
31
)
||
info
.
src
.
charCodeAt
(
pos
)
==
33
||
(
info
.
src
.
charCodeAt
(
pos
)
>=
35
&&
info
.
src
.
charCodeAt
(
pos
)
<=
39
)
||
(
info
.
src
.
charCodeAt
(
pos
)
>=
42
&&
info
.
src
.
charCodeAt
(
pos
)
<=
57
)
||
(
info
.
src
.
charCodeAt
(
pos
)
>=
59
&&
info
.
src
.
charCodeAt
(
pos
)
<=
78
)
||
(
info
.
src
.
charCodeAt
(
pos
)
>=
80
&&
info
.
src
.
charCodeAt
(
pos
)
<=
254
)
)
state
=
1
;
else
if
(
info
.
src
.
charCodeAt
(
pos
)
==
58
)
state
=
6
;
else
if
(
info
.
src
.
charCodeAt
(
pos
)
==
79
)
state
=
17
;
else
state
=
-
1
;
match
=
10
;
match_pos
=
pos
;
break
;
}
pos
++
;
}
while
(
state
>
-
1
);
}
while
(
1
>
-
1
&&
match
==
1
);
if
(
match
>
-
1
)
{
info
.
att
=
info
.
src
.
substr
(
start
,
match_pos
-
start
);
info
.
offset
=
match_pos
;
}
else
{
info
.
att
=
new
String
();
match
=
-
1
;
}
return
match
;
}
function
__NODEJS_parse
(
src
,
err_off
,
err_la
)
{
var
sstack
=
new
Array
();
var
vstack
=
new
Array
();
var
err_cnt
=
0
;
var
act
;
var
go
;
var
la
;
var
rval
;
var
parseinfo
=
new
Function
(
""
,
"
var offset; var src; var att;
"
);
var
info
=
new
parseinfo
();
/* Pop-Table */
var
pop_tab
=
new
Array
(
new
Array
(
0
/* begin' */
,
1
),
new
Array
(
13
/* begin */
,
1
),
new
Array
(
12
/* search_text */
,
1
),
new
Array
(
12
/* search_text */
,
2
),
new
Array
(
12
/* search_text */
,
3
),
new
Array
(
14
/* and_expression */
,
1
),
new
Array
(
14
/* and_expression */
,
3
),
new
Array
(
15
/* boolean_expression */
,
2
),
new
Array
(
15
/* boolean_expression */
,
1
),
new
Array
(
16
/* expression */
,
3
),
new
Array
(
16
/* expression */
,
2
),
new
Array
(
16
/* expression */
,
1
),
new
Array
(
17
/* value */
,
2
),
new
Array
(
17
/* value */
,
1
),
new
Array
(
18
/* string */
,
1
),
new
Array
(
18
/* string */
,
1
)
);
/* Action-Table */
var
act_tab
=
new
Array
(
/* State 0 */
new
Array
(
7
/* "NOT" */
,
5
,
3
/* "LEFT_PARENTHESE" */
,
7
,
8
/* "COLUMN" */
,
8
,
11
/* "OPERATOR" */
,
10
,
10
/* "WORD" */
,
12
,
9
/* "STRING" */
,
13
),
/* State 1 */
new
Array
(
19
/* "$" */
,
0
),
/* State 2 */
new
Array
(
19
/* "$" */
,
-
1
),
/* State 3 */
new
Array
(
6
/* "OR" */
,
14
,
7
/* "NOT" */
,
5
,
3
/* "LEFT_PARENTHESE" */
,
7
,
8
/* "COLUMN" */
,
8
,
11
/* "OPERATOR" */
,
10
,
10
/* "WORD" */
,
12
,
9
/* "STRING" */
,
13
,
19
/* "$" */
,
-
2
,
4
/* "RIGHT_PARENTHESE" */
,
-
2
),
/* State 4 */
new
Array
(
5
/* "AND" */
,
16
,
19
/* "$" */
,
-
5
,
7
/* "NOT" */
,
-
5
,
3
/* "LEFT_PARENTHESE" */
,
-
5
,
8
/* "COLUMN" */
,
-
5
,
11
/* "OPERATOR" */
,
-
5
,
10
/* "WORD" */
,
-
5
,
9
/* "STRING" */
,
-
5
,
6
/* "OR" */
,
-
5
,
4
/* "RIGHT_PARENTHESE" */
,
-
5
),
/* State 5 */
new
Array
(
3
/* "LEFT_PARENTHESE" */
,
7
,
8
/* "COLUMN" */
,
8
,
11
/* "OPERATOR" */
,
10
,
10
/* "WORD" */
,
12
,
9
/* "STRING" */
,
13
),
/* State 6 */
new
Array
(
19
/* "$" */
,
-
8
,
7
/* "NOT" */
,
-
8
,
3
/* "LEFT_PARENTHESE" */
,
-
8
,
8
/* "COLUMN" */
,
-
8
,
11
/* "OPERATOR" */
,
-
8
,
10
/* "WORD" */
,
-
8
,
9
/* "STRING" */
,
-
8
,
6
/* "OR" */
,
-
8
,
5
/* "AND" */
,
-
8
,
4
/* "RIGHT_PARENTHESE" */
,
-
8
),
/* State 7 */
new
Array
(
7
/* "NOT" */
,
5
,
3
/* "LEFT_PARENTHESE" */
,
7
,
8
/* "COLUMN" */
,
8
,
11
/* "OPERATOR" */
,
10
,
10
/* "WORD" */
,
12
,
9
/* "STRING" */
,
13
),
/* State 8 */
new
Array
(
3
/* "LEFT_PARENTHESE" */
,
7
,
8
/* "COLUMN" */
,
8
,
11
/* "OPERATOR" */
,
10
,
10
/* "WORD" */
,
12
,
9
/* "STRING" */
,
13
),
/* State 9 */
new
Array
(
19
/* "$" */
,
-
11
,
7
/* "NOT" */
,
-
11
,
3
/* "LEFT_PARENTHESE" */
,
-
11
,
8
/* "COLUMN" */
,
-
11
,
11
/* "OPERATOR" */
,
-
11
,
10
/* "WORD" */
,
-
11
,
9
/* "STRING" */
,
-
11
,
6
/* "OR" */
,
-
11
,
5
/* "AND" */
,
-
11
,
4
/* "RIGHT_PARENTHESE" */
,
-
11
),
/* State 10 */
new
Array
(
10
/* "WORD" */
,
12
,
9
/* "STRING" */
,
13
),
/* State 11 */
new
Array
(
19
/* "$" */
,
-
13
,
7
/* "NOT" */
,
-
13
,
3
/* "LEFT_PARENTHESE" */
,
-
13
,
8
/* "COLUMN" */
,
-
13
,
11
/* "OPERATOR" */
,
-
13
,
10
/* "WORD" */
,
-
13
,
9
/* "STRING" */
,
-
13
,
6
/* "OR" */
,
-
13
,
5
/* "AND" */
,
-
13
,
4
/* "RIGHT_PARENTHESE" */
,
-
13
),
/* State 12 */
new
Array
(
19
/* "$" */
,
-
14
,
7
/* "NOT" */
,
-
14
,
3
/* "LEFT_PARENTHESE" */
,
-
14
,
8
/* "COLUMN" */
,
-
14
,
11
/* "OPERATOR" */
,
-
14
,
10
/* "WORD" */
,
-
14
,
9
/* "STRING" */
,
-
14
,
6
/* "OR" */
,
-
14
,
5
/* "AND" */
,
-
14
,
4
/* "RIGHT_PARENTHESE" */
,
-
14
),
/* State 13 */
new
Array
(
19
/* "$" */
,
-
15
,
7
/* "NOT" */
,
-
15
,
3
/* "LEFT_PARENTHESE" */
,
-
15
,
8
/* "COLUMN" */
,
-
15
,
11
/* "OPERATOR" */
,
-
15
,
10
/* "WORD" */
,
-
15
,
9
/* "STRING" */
,
-
15
,
6
/* "OR" */
,
-
15
,
5
/* "AND" */
,
-
15
,
4
/* "RIGHT_PARENTHESE" */
,
-
15
),
/* State 14 */
new
Array
(
7
/* "NOT" */
,
5
,
3
/* "LEFT_PARENTHESE" */
,
7
,
8
/* "COLUMN" */
,
8
,
11
/* "OPERATOR" */
,
10
,
10
/* "WORD" */
,
12
,
9
/* "STRING" */
,
13
),
/* State 15 */
new
Array
(
19
/* "$" */
,
-
3
,
4
/* "RIGHT_PARENTHESE" */
,
-
3
),
/* State 16 */
new
Array
(
7
/* "NOT" */
,
5
,
3
/* "LEFT_PARENTHESE" */
,
7
,
8
/* "COLUMN" */
,
8
,
11
/* "OPERATOR" */
,
10
,
10
/* "WORD" */
,
12
,
9
/* "STRING" */
,
13
),
/* State 17 */
new
Array
(
19
/* "$" */
,
-
7
,
7
/* "NOT" */
,
-
7
,
3
/* "LEFT_PARENTHESE" */
,
-
7
,
8
/* "COLUMN" */
,
-
7
,
11
/* "OPERATOR" */
,
-
7
,
10
/* "WORD" */
,
-
7
,
9
/* "STRING" */
,
-
7
,
6
/* "OR" */
,
-
7
,
5
/* "AND" */
,
-
7
,
4
/* "RIGHT_PARENTHESE" */
,
-
7
),
/* State 18 */
new
Array
(
4
/* "RIGHT_PARENTHESE" */
,
23
),
/* State 19 */
new
Array
(
19
/* "$" */
,
-
10
,
7
/* "NOT" */
,
-
10
,
3
/* "LEFT_PARENTHESE" */
,
-
10
,
8
/* "COLUMN" */
,
-
10
,
11
/* "OPERATOR" */
,
-
10
,
10
/* "WORD" */
,
-
10
,
9
/* "STRING" */
,
-
10
,
6
/* "OR" */
,
-
10
,
5
/* "AND" */
,
-
10
,
4
/* "RIGHT_PARENTHESE" */
,
-
10
),
/* State 20 */
new
Array
(
19
/* "$" */
,
-
12
,
7
/* "NOT" */
,
-
12
,
3
/* "LEFT_PARENTHESE" */
,
-
12
,
8
/* "COLUMN" */
,
-
12
,
11
/* "OPERATOR" */
,
-
12
,
10
/* "WORD" */
,
-
12
,
9
/* "STRING" */
,
-
12
,
6
/* "OR" */
,
-
12
,
5
/* "AND" */
,
-
12
,
4
/* "RIGHT_PARENTHESE" */
,
-
12
),
/* State 21 */
new
Array
(
19
/* "$" */
,
-
4
,
4
/* "RIGHT_PARENTHESE" */
,
-
4
),
/* State 22 */
new
Array
(
19
/* "$" */
,
-
6
,
7
/* "NOT" */
,
-
6
,
3
/* "LEFT_PARENTHESE" */
,
-
6
,
8
/* "COLUMN" */
,
-
6
,
11
/* "OPERATOR" */
,
-
6
,
10
/* "WORD" */
,
-
6
,
9
/* "STRING" */
,
-
6
,
6
/* "OR" */
,
-
6
,
4
/* "RIGHT_PARENTHESE" */
,
-
6
),
/* State 23 */
new
Array
(
19
/* "$" */
,
-
9
,
7
/* "NOT" */
,
-
9
,
3
/* "LEFT_PARENTHESE" */
,
-
9
,
8
/* "COLUMN" */
,
-
9
,
11
/* "OPERATOR" */
,
-
9
,
10
/* "WORD" */
,
-
9
,
9
/* "STRING" */
,
-
9
,
6
/* "OR" */
,
-
9
,
5
/* "AND" */
,
-
9
,
4
/* "RIGHT_PARENTHESE" */
,
-
9
)
);
/* Goto-Table */
var
goto_tab
=
new
Array
(
/* State 0 */
new
Array
(
13
/* begin */
,
1
,
12
/* search_text */
,
2
,
14
/* and_expression */
,
3
,
15
/* boolean_expression */
,
4
,
16
/* expression */
,
6
,
17
/* value */
,
9
,
18
/* string */
,
11
),
/* State 1 */
new
Array
(
),
/* State 2 */
new
Array
(
),
/* State 3 */
new
Array
(
12
/* search_text */
,
15
,
14
/* and_expression */
,
3
,
15
/* boolean_expression */
,
4
,
16
/* expression */
,
6
,
17
/* value */
,
9
,
18
/* string */
,
11
),
/* State 4 */
new
Array
(
),
/* State 5 */
new
Array
(
16
/* expression */
,
17
,
17
/* value */
,
9
,
18
/* string */
,
11
),
/* State 6 */
new
Array
(
),
/* State 7 */
new
Array
(
12
/* search_text */
,
18
,
14
/* and_expression */
,
3
,
15
/* boolean_expression */
,
4
,
16
/* expression */
,
6
,
17
/* value */
,
9
,
18
/* string */
,
11
),
/* State 8 */
new
Array
(
16
/* expression */
,
19
,
17
/* value */
,
9
,
18
/* string */
,
11
),
/* State 9 */
new
Array
(
),
/* State 10 */
new
Array
(
18
/* string */
,
20
),
/* State 11 */
new
Array
(
),
/* State 12 */
new
Array
(
),
/* State 13 */
new
Array
(
),
/* State 14 */
new
Array
(
12
/* search_text */
,
21
,
14
/* and_expression */
,
3
,
15
/* boolean_expression */
,
4
,
16
/* expression */
,
6
,
17
/* value */
,
9
,
18
/* string */
,
11
),
/* State 15 */
new
Array
(
),
/* State 16 */
new
Array
(
14
/* and_expression */
,
22
,
15
/* boolean_expression */
,
4
,
16
/* expression */
,
6
,
17
/* value */
,
9
,
18
/* string */
,
11
),
/* State 17 */
new
Array
(
),
/* State 18 */
new
Array
(
),
/* State 19 */
new
Array
(
),
/* State 20 */
new
Array
(
),
/* State 21 */
new
Array
(
),
/* State 22 */
new
Array
(
),
/* State 23 */
new
Array
(
)
);
/* Symbol labels */
var
labels
=
new
Array
(
"
begin'
"
/* Non-terminal symbol */
,
"
WHITESPACE
"
/* Terminal symbol */
,
"
WHITESPACE
"
/* Terminal symbol */
,
"
LEFT_PARENTHESE
"
/* Terminal symbol */
,
"
RIGHT_PARENTHESE
"
/* Terminal symbol */
,
"
AND
"
/* Terminal symbol */
,
"
OR
"
/* Terminal symbol */
,
"
NOT
"
/* Terminal symbol */
,
"
COLUMN
"
/* Terminal symbol */
,
"
STRING
"
/* Terminal symbol */
,
"
WORD
"
/* Terminal symbol */
,
"
OPERATOR
"
/* Terminal symbol */
,
"
search_text
"
/* Non-terminal symbol */
,
"
begin
"
/* Non-terminal symbol */
,
"
and_expression
"
/* Non-terminal symbol */
,
"
boolean_expression
"
/* Non-terminal symbol */
,
"
expression
"
/* Non-terminal symbol */
,
"
value
"
/* Non-terminal symbol */
,
"
string
"
/* Non-terminal symbol */
,
"
$
"
/* Terminal symbol */
);
info
.
offset
=
0
;
info
.
src
=
src
;
info
.
att
=
new
String
();
if
(
!
err_off
)
err_off
=
new
Array
();
if
(
!
err_la
)
err_la
=
new
Array
();
sstack
.
push
(
0
);
vstack
.
push
(
0
);
la
=
__NODEJS_lex
(
info
);
while
(
true
)
{
act
=
25
;
for
(
var
i
=
0
;
i
<
act_tab
[
sstack
[
sstack
.
length
-
1
]].
length
;
i
+=
2
)
{
if
(
act_tab
[
sstack
[
sstack
.
length
-
1
]][
i
]
==
la
)
{
act
=
act_tab
[
sstack
[
sstack
.
length
-
1
]][
i
+
1
];
break
;
}
}
if
(
NODEJS__dbg_withtrace
&&
sstack
.
length
>
0
)
{
__NODEJS_dbg_print
(
"
\n
State
"
+
sstack
[
sstack
.
length
-
1
]
+
"
\n
"
+
"
\t
Lookahead:
"
+
labels
[
la
]
+
"
(
\"
"
+
info
.
att
+
"
\"
)
\n
"
+
"
\t
Action:
"
+
act
+
"
\n
"
+
"
\t
Source:
\"
"
+
info
.
src
.
substr
(
info
.
offset
,
30
)
+
(
(
info
.
offset
+
30
<
info
.
src
.
length
)
?
"
...
"
:
""
)
+
"
\"\n
"
+
"
\t
Stack:
"
+
sstack
.
join
()
+
"
\n
"
+
"
\t
Value stack:
"
+
vstack
.
join
()
+
"
\n
"
);
}
//Panic-mode: Try recovery when parse-error occurs!
if
(
act
==
25
)
{
if
(
NODEJS__dbg_withtrace
)
__NODEJS_dbg_print
(
"
Error detected: There is no reduce or shift on the symbol
"
+
labels
[
la
]
);
err_cnt
++
;
err_off
.
push
(
info
.
offset
-
info
.
att
.
length
);
err_la
.
push
(
new
Array
()
);
for
(
var
i
=
0
;
i
<
act_tab
[
sstack
[
sstack
.
length
-
1
]].
length
;
i
+=
2
)
err_la
[
err_la
.
length
-
1
].
push
(
labels
[
act_tab
[
sstack
[
sstack
.
length
-
1
]][
i
]]
);
//Remember the original stack!
var
rsstack
=
new
Array
();
var
rvstack
=
new
Array
();
for
(
var
i
=
0
;
i
<
sstack
.
length
;
i
++
)
{
rsstack
[
i
]
=
sstack
[
i
];
rvstack
[
i
]
=
vstack
[
i
];
}
while
(
act
==
25
&&
la
!=
19
)
{
if
(
NODEJS__dbg_withtrace
)
__NODEJS_dbg_print
(
"
\t
Error recovery
\n
"
+
"
Current lookahead:
"
+
labels
[
la
]
+
"
(
"
+
info
.
att
+
"
)
\n
"
+
"
Action:
"
+
act
+
"
\n\n
"
);
if
(
la
==
-
1
)
info
.
offset
++
;
while
(
act
==
25
&&
sstack
.
length
>
0
)
{
sstack
.
pop
();
vstack
.
pop
();
if
(
sstack
.
length
==
0
)
break
;
act
=
25
;
for
(
var
i
=
0
;
i
<
act_tab
[
sstack
[
sstack
.
length
-
1
]].
length
;
i
+=
2
)
{
if
(
act_tab
[
sstack
[
sstack
.
length
-
1
]][
i
]
==
la
)
{
act
=
act_tab
[
sstack
[
sstack
.
length
-
1
]][
i
+
1
];
break
;
}
}
}
if
(
act
!=
25
)
break
;
for
(
var
i
=
0
;
i
<
rsstack
.
length
;
i
++
)
{
sstack
.
push
(
rsstack
[
i
]
);
vstack
.
push
(
rvstack
[
i
]
);
}
la
=
__NODEJS_lex
(
info
);
}
if
(
act
==
25
)
{
if
(
NODEJS__dbg_withtrace
)
__NODEJS_dbg_print
(
"
\t
Error recovery failed, terminating parse process...
"
);
break
;
}
if
(
NODEJS__dbg_withtrace
)
__NODEJS_dbg_print
(
"
\t
Error recovery succeeded, continuing
"
);
}
/*
if( act == 25 )
break;
*/
//Shift
if
(
act
>
0
)
{
if
(
NODEJS__dbg_withtrace
)
__NODEJS_dbg_print
(
"
Shifting symbol:
"
+
labels
[
la
]
+
"
(
"
+
info
.
att
+
"
)
"
);
sstack
.
push
(
act
);
vstack
.
push
(
info
.
att
);
la
=
__NODEJS_lex
(
info
);
if
(
NODEJS__dbg_withtrace
)
__NODEJS_dbg_print
(
"
\t
New lookahead symbol:
"
+
labels
[
la
]
+
"
(
"
+
info
.
att
+
"
)
"
);
}
//Reduce
else
{
act
*=
-
1
;
if
(
NODEJS__dbg_withtrace
)
__NODEJS_dbg_print
(
"
Reducing by producution:
"
+
act
);
rval
=
void
(
0
);
if
(
NODEJS__dbg_withtrace
)
__NODEJS_dbg_print
(
"
\t
Performing semantic action...
"
);
switch
(
act
)
{
case
0
:
{
rval
=
vstack
[
vstack
.
length
-
1
];
}
break
;
case
1
:
{
result
=
vstack
[
vstack
.
length
-
1
];
}
break
;
case
2
:
{
rval
=
vstack
[
vstack
.
length
-
1
];
}
break
;
case
3
:
{
rval
=
mkComplexQuery
(
'
OR
'
,[
vstack
[
vstack
.
length
-
2
],
vstack
[
vstack
.
length
-
1
]]);
}
break
;
case
4
:
{
rval
=
mkComplexQuery
(
'
OR
'
,[
vstack
[
vstack
.
length
-
3
],
vstack
[
vstack
.
length
-
1
]]);
}
break
;
case
5
:
{
rval
=
vstack
[
vstack
.
length
-
1
]
;
}
break
;
case
6
:
{
rval
=
mkComplexQuery
(
'
AND
'
,[
vstack
[
vstack
.
length
-
3
],
vstack
[
vstack
.
length
-
1
]]);
}
break
;
case
7
:
{
rval
=
mkNotQuery
(
vstack
[
vstack
.
length
-
1
]);
}
break
;
case
8
:
{
rval
=
vstack
[
vstack
.
length
-
1
];
}
break
;
case
9
:
{
rval
=
vstack
[
vstack
.
length
-
2
];
}
break
;
case
10
:
{
simpleQuerySetKey
(
vstack
[
vstack
.
length
-
1
],
vstack
[
vstack
.
length
-
2
].
split
(
'
:
'
).
slice
(
0
,
-
1
).
join
(
'
:
'
));
rval
=
vstack
[
vstack
.
length
-
1
];
}
break
;
case
11
:
{
rval
=
vstack
[
vstack
.
length
-
1
];
}
break
;
case
12
:
{
vstack
[
vstack
.
length
-
1
].
operator
=
vstack
[
vstack
.
length
-
2
]
;
rval
=
vstack
[
vstack
.
length
-
1
];
}
break
;
case
13
:
{
rval
=
vstack
[
vstack
.
length
-
1
];
}
break
;
case
14
:
{
rval
=
mkSimpleQuery
(
''
,
vstack
[
vstack
.
length
-
1
]);
}
break
;
case
15
:
{
rval
=
mkSimpleQuery
(
''
,
vstack
[
vstack
.
length
-
1
].
split
(
'
"
'
).
slice
(
1
,
-
1
).
join
(
'
"
'
));
}
break
;
}
if
(
NODEJS__dbg_withtrace
)
__NODEJS_dbg_print
(
"
\t
Popping
"
+
pop_tab
[
act
][
1
]
+
"
off the stack...
"
);
for
(
var
i
=
0
;
i
<
pop_tab
[
act
][
1
];
i
++
)
{
sstack
.
pop
();
vstack
.
pop
();
}
go
=
-
1
;
for
(
var
i
=
0
;
i
<
goto_tab
[
sstack
[
sstack
.
length
-
1
]].
length
;
i
+=
2
)
{
if
(
goto_tab
[
sstack
[
sstack
.
length
-
1
]][
i
]
==
pop_tab
[
act
][
0
]
)
{
go
=
goto_tab
[
sstack
[
sstack
.
length
-
1
]][
i
+
1
];
break
;
}
}
if
(
act
==
0
)
break
;
if
(
NODEJS__dbg_withtrace
)
__NODEJS_dbg_print
(
"
\t
Pushing non-terminal
"
+
labels
[
pop_tab
[
act
][
0
]
]
);
sstack
.
push
(
go
);
vstack
.
push
(
rval
);
}
if
(
NODEJS__dbg_withtrace
)
{
alert
(
NODEJS__dbg_string
);
NODEJS__dbg_string
=
new
String
();
}
}
if
(
NODEJS__dbg_withtrace
)
{
__NODEJS_dbg_print
(
"
\n
Parse complete.
"
);
alert
(
NODEJS__dbg_string
);
}
return
err_cnt
;
}
var
arrayExtend
=
function
()
{
var
j
,
i
,
newlist
=
[],
list_list
=
arguments
;
for
(
j
=
0
;
j
<
list_list
.
length
;
j
+=
1
)
{
for
(
i
=
0
;
i
<
list_list
[
j
].
length
;
i
+=
1
)
{
newlist
.
push
(
list_list
[
j
][
i
]);
}
}
return
newlist
;
},
mkSimpleQuery
=
function
(
key
,
value
,
operator
)
{
return
{
"
type
"
:
"
simple
"
,
"
operator
"
:
"
=
"
,
"
key
"
:
key
,
"
value
"
:
value
};
},
mkNotQuery
=
function
(
query
)
{
if
(
query
.
operator
===
"
NOT
"
)
{
return
query
.
query_list
[
0
];
}
return
{
"
type
"
:
"
complex
"
,
"
operator
"
:
"
NOT
"
,
"
query_list
"
:
[
query
]};
},
mkComplexQuery
=
function
(
operator
,
query_list
)
{
var
i
,
query_list2
=
[];
for
(
i
=
0
;
i
<
query_list
.
length
;
i
+=
1
)
{
if
(
query_list
[
i
].
operator
===
operator
)
{
query_list2
=
arrayExtend
(
query_list2
,
query_list
[
i
].
query_list
);
}
else
{
query_list2
.
push
(
query_list
[
i
]);
}
}
return
{
type
:
"
complex
"
,
operator
:
operator
,
query_list
:
query_list2
};
},
simpleQuerySetKey
=
function
(
query
,
key
)
{
var
i
;
if
(
query
.
type
===
"
complex
"
)
{
for
(
i
=
0
;
i
<
query
.
query_list
.
length
;
++
i
)
{
simpleQuerySetKey
(
query
.
query_list
[
i
],
key
);
}
return
true
;
}
if
(
query
.
type
===
"
simple
"
&&
!
query
.
key
)
{
query
.
key
=
key
;
return
true
;
}
return
false
;
},
error_offsets
=
[],
error_lookaheads
=
[],
error_count
=
0
,
result
;
if
((
error_count
=
__NODEJS_parse
(
string
,
error_offsets
,
error_lookaheads
))
>
0
)
{
var
i
;
for
(
i
=
0
;
i
<
error_count
;
i
+=
1
)
{
throw
new
Error
(
"
Parse error near
\"
"
+
string
.
substr
(
error_offsets
[
i
])
+
"
\"
, expecting
\"
"
+
error_lookaheads
[
i
].
join
()
+
"
\"
"
);
}
}
return
result
;
}
// parseStringToObject
_export
(
'
parseStringToObject
'
,
parseStringToObject
);
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*global _export: true */
/**
* Escapes regexp special chars from a string.
*
* @param {String} string The string to escape
* @return {String} The escaped string
*/
function
stringEscapeRegexpCharacters
(
string
)
{
if
(
typeof
string
===
"
string
"
)
{
return
string
.
replace
(
/
([\\\.\$\[\]\(\)\{\}\^\?\*\+\-])
/g
,
"
\\
$1
"
);
}
throw
new
TypeError
(
"
complex_queries.stringEscapeRegexpCharacters():
"
+
"
Argument no 1 is not of type 'string'
"
);
}
_export
(
"
stringEscapeRegexpCharacters
"
,
stringEscapeRegexpCharacters
);
/**
* Convert metadata values to array of strings. ex:
*
* "a" -> ["a"],
* {"content": "a"} -> ["a"]
*
* @param {Any} value The metadata value
* @return {Array} The value in string array format
*/
function
metadataValueToStringArray
(
value
)
{
var
i
,
new_value
=
[];
if
(
value
===
undefined
)
{
return
undefined
;
}
if
(
!
Array
.
isArray
(
value
))
{
value
=
[
value
];
}
for
(
i
=
0
;
i
<
value
.
length
;
i
+=
1
)
{
if
(
typeof
value
[
i
]
===
'
object
'
)
{
new_value
[
i
]
=
value
[
i
].
content
;
}
else
{
new_value
[
i
]
=
value
[
i
];
}
}
return
new_value
;
}
/**
* A sort function to sort items by key
*
* @param {String} key The key to sort on
* @param {String} [way="ascending"] 'ascending' or 'descending'
* @return {Function} The sort function
*/
function
sortFunction
(
key
,
way
)
{
if
(
way
===
'
descending
'
)
{
return
function
(
a
,
b
)
{
// this comparison is 5 times faster than json comparison
var
i
,
l
;
a
=
metadataValueToStringArray
(
a
[
key
])
||
[];
b
=
metadataValueToStringArray
(
b
[
key
])
||
[];
l
=
a
.
length
>
b
.
length
?
a
.
length
:
b
.
length
;
for
(
i
=
0
;
i
<
l
;
i
+=
1
)
{
if
(
a
[
i
]
===
undefined
)
{
return
1
;
}
if
(
b
[
i
]
===
undefined
)
{
return
-
1
;
}
if
(
a
[
i
]
>
b
[
i
])
{
return
-
1
;
}
if
(
a
[
i
]
<
b
[
i
])
{
return
1
;
}
}
return
0
;
};
}
if
(
way
===
'
ascending
'
)
{
return
function
(
a
,
b
)
{
// this comparison is 5 times faster than json comparison
var
i
,
l
;
a
=
metadataValueToStringArray
(
a
[
key
])
||
[];
b
=
metadataValueToStringArray
(
b
[
key
])
||
[];
l
=
a
.
length
>
b
.
length
?
a
.
length
:
b
.
length
;
for
(
i
=
0
;
i
<
l
;
i
+=
1
)
{
if
(
a
[
i
]
===
undefined
)
{
return
-
1
;
}
if
(
b
[
i
]
===
undefined
)
{
return
1
;
}
if
(
a
[
i
]
>
b
[
i
])
{
return
1
;
}
if
(
a
[
i
]
<
b
[
i
])
{
return
-
1
;
}
}
return
0
;
};
}
throw
new
TypeError
(
"
complex_queries.sortFunction():
"
+
"
Argument 2 must be 'ascending' or 'descending'
"
);
}
/**
* Clones all native object in deep. Managed types: Object, Array, String,
* Number, Boolean, null.
*
* @param {A} object The object to clone
* @return {A} The cloned object
*/
function
deepClone
(
object
)
{
var
i
,
cloned
;
if
(
Array
.
isArray
(
object
))
{
cloned
=
[];
for
(
i
=
0
;
i
<
object
.
length
;
i
+=
1
)
{
cloned
[
i
]
=
deepClone
(
object
[
i
]);
}
return
cloned
;
}
if
(
typeof
object
===
"
object
"
)
{
cloned
=
{};
for
(
i
in
object
)
{
if
(
object
.
hasOwnProperty
(
i
))
{
cloned
[
i
]
=
deepClone
(
object
[
i
]);
}
}
return
cloned
;
}
return
object
;
}
/**
* Inherits the prototype methods from one constructor into another. The
* prototype of `constructor` will be set to a new object created from
* `superConstructor`.
*
* @param {Function} constructor The constructor which inherits the super one
* @param {Function} superConstructor The super constructor
*/
function
inherits
(
constructor
,
superConstructor
)
{
constructor
.
super_
=
superConstructor
;
constructor
.
prototype
=
Object
.
create
(
superConstructor
.
prototype
,
{
"
constructor
"
:
{
"
configurable
"
:
true
,
"
enumerable
"
:
false
,
"
writable
"
:
true
,
"
value
"
:
constructor
}
});
}
/**
* Does nothing
*/
function
emptyFunction
()
{}
/**
* Filter a list of items, modifying them to select only wanted keys. If
* `clone` is true, then the method will act on a cloned list.
*
* @param {Array} select_option Key list to keep
* @param {Array} list The item list to filter
* @param {Boolean} [clone=false] If true, modifies a clone of the list
* @return {Array} The filtered list
*/
function
select
(
select_option
,
list
,
clone
)
{
var
i
,
j
,
new_item
;
if
(
!
Array
.
isArray
(
select_option
))
{
throw
new
TypeError
(
"
complex_queries.select():
"
+
"
Argument 1 is not of type Array
"
);
}
if
(
!
Array
.
isArray
(
list
))
{
throw
new
TypeError
(
"
complex_queries.select():
"
+
"
Argument 2 is not of type Array
"
);
}
if
(
clone
===
true
)
{
list
=
deepClone
(
list
);
}
for
(
i
=
0
;
i
<
list
.
length
;
i
+=
1
)
{
new_item
=
{};
for
(
j
=
0
;
j
<
select_option
.
length
;
j
+=
1
)
{
new_item
[
select_option
[
j
]]
=
list
[
i
][
select_option
[
j
]];
}
for
(
j
in
new_item
)
{
if
(
new_item
.
hasOwnProperty
(
j
))
{
list
[
i
]
=
new_item
;
break
;
}
}
}
return
list
;
}
_export
(
'
select
'
,
select
);
/**
* Sort a list of items, according to keys and directions. If `clone` is true,
* then the method will act on a cloned list.
*
* @param {Array} sort_on_option List of couples [key, direction]
* @param {Array} list The item list to sort
* @param {Boolean} [clone=false] If true, modifies a clone of the list
* @return {Array} The filtered list
*/
function
sortOn
(
sort_on_option
,
list
,
clone
)
{
var
sort_index
;
if
(
!
Array
.
isArray
(
sort_on_option
))
{
throw
new
TypeError
(
"
complex_queries.sortOn():
"
+
"
Argument 1 is not of type 'array'
"
);
}
if
(
clone
)
{
list
=
deepClone
(
list
);
}
for
(
sort_index
=
sort_on_option
.
length
-
1
;
sort_index
>=
0
;
sort_index
-=
1
)
{
list
.
sort
(
sortFunction
(
sort_on_option
[
sort_index
][
0
],
sort_on_option
[
sort_index
][
1
]
));
}
return
list
;
}
_export
(
'
sortOn
'
,
sortOn
);
/**
* Limit a list of items, according to index and length. If `clone` is true,
* then the method will act on a cloned list.
*
* @param {Array} limit_option A couple [from, length]
* @param {Array} list The item list to limit
* @param {Boolean} [clone=false] If true, modifies a clone of the list
* @return {Array} The filtered list
*/
function
limit
(
limit_option
,
list
,
clone
)
{
if
(
!
Array
.
isArray
(
limit_option
))
{
throw
new
TypeError
(
"
complex_queries.limit():
"
+
"
Argument 1 is not of type 'array'
"
);
}
if
(
!
Array
.
isArray
(
list
))
{
throw
new
TypeError
(
"
complex_queries.limit():
"
+
"
Argument 2 is not of type 'array'
"
);
}
if
(
clone
)
{
list
=
deepClone
(
list
);
}
list
.
splice
(
0
,
limit_option
[
0
]);
if
(
limit_option
[
1
])
{
list
.
splice
(
limit_option
[
1
]);
}
return
list
;
}
_export
(
'
limit
'
,
limit
);
/**
* Convert a search text to a regexp.
*
* @param {String} string The string to convert
* @param {String} [wildcard_character=undefined] The wildcard chararter
* @return {RegExp} The search text regexp
*/
function
convertStringToRegExp
(
string
,
wildcard_character
)
{
if
(
typeof
string
!==
'
string
'
)
{
throw
new
TypeError
(
"
complex_queries.convertStringToRegExp():
"
+
"
Argument 1 is not of type 'string'
"
);
}
if
(
wildcard_character
===
undefined
||
wildcard_character
===
null
||
wildcard_character
===
''
)
{
return
new
RegExp
(
"
^
"
+
stringEscapeRegexpCharacters
(
string
)
+
"
$
"
);
}
if
(
typeof
wildcard_character
!==
'
string
'
||
wildcard_character
.
length
>
1
)
{
throw
new
TypeError
(
"
complex_queries.convertStringToRegExp():
"
+
"
Optional argument 2 must be a string of length <= 1
"
);
}
return
new
RegExp
(
"
^
"
+
stringEscapeRegexpCharacters
(
string
).
replace
(
new
RegExp
(
stringEscapeRegexpCharacters
(
wildcard_character
),
'
g
'
),
'
.*
'
)
+
"
$
"
);
}
_export
(
'
convertStringToRegExp
'
,
convertStringToRegExp
);
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*global _export: true, ComplexQuery: true, SimpleQuery: true, Query: true,
parseStringToObject: true */
var
query_class_dict
=
{};
/**
* Provides static methods to create Query object
*
* @class QueryFactory
*/
function
QueryFactory
()
{}
/**
* Creates Query object from a search text string or a serialized version
* of a Query.
*
* @method create
* @static
* @param {Object,String} object The search text or the serialized version
* of a Query
* @return {Query} A Query object
*/
QueryFactory
.
create
=
function
(
object
)
{
if
(
object
===
""
)
{
return
new
Query
();
}
if
(
typeof
object
===
"
string
"
)
{
object
=
parseStringToObject
(
object
);
}
if
(
typeof
(
object
||
{}).
type
===
"
string
"
&&
query_class_dict
[
object
.
type
])
{
return
new
query_class_dict
[
object
.
type
](
object
);
}
throw
new
TypeError
(
"
QueryFactory.create():
"
+
"
Argument 1 is not a search text or a parsable object
"
);
};
_export
(
"
QueryFactory
"
,
QueryFactory
);
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*global parseStringToObject: true, emptyFunction: true, sortOn: true, limit:
true, select: true, _export: true, stringEscapeRegexpCharacters: true,
deepClone: true */
/**
* The query to use to filter a list of objects.
* This is an abstract class.
*
* @class Query
* @constructor
*/
function
Query
()
{
/**
* Called before parsing the query. Must be overridden!
*
* @method onParseStart
* @param {Object} object The object shared in the parse process
* @param {Object} option Some option gave in parse()
*/
this
.
onParseStart
=
emptyFunction
;
/**
* Called when parsing a simple query. Must be overridden!
*
* @method onParseSimpleQuery
* @param {Object} object The object shared in the parse process
* @param {Object} option Some option gave in parse()
*/
this
.
onParseSimpleQuery
=
emptyFunction
;
/**
* Called when parsing a complex query. Must be overridden!
*
* @method onParseComplexQuery
* @param {Object} object The object shared in the parse process
* @param {Object} option Some option gave in parse()
*/
this
.
onParseComplexQuery
=
emptyFunction
;
/**
* Called after parsing the query. Must be overridden!
*
* @method onParseEnd
* @param {Object} object The object shared in the parse process
* @param {Object} option Some option gave in parse()
*/
this
.
onParseEnd
=
emptyFunction
;
}
/**
* Filter the item list with matching item only
*
* @method exec
* @param {Array} item_list The list of object
* @param {Object} [option] Some operation option
* @param {String} [option.wildcard_character="%"] The wildcard character
* @param {Array} [option.select_list] A object keys to retrieve
* @param {Array} [option.sort_on] Couples of object keys and "ascending"
* or "descending"
* @param {Array} [option.limit] Couple of integer, first is an index and
* second is the length.
*/
Query
.
prototype
.
exec
=
function
(
item_list
,
option
)
{
var
i
=
0
;
if
(
!
Array
.
isArray
(
item_list
))
{
throw
new
TypeError
(
"
Query().exec(): Argument 1 is not of type 'array'
"
);
}
if
(
option
===
undefined
)
{
option
=
{};
}
if
(
typeof
option
!==
'
object
'
)
{
throw
new
TypeError
(
"
Query().exec():
"
+
"
Optional argument 2 is not of type 'object'
"
);
}
if
(
option
.
wildcard_character
===
undefined
)
{
option
.
wildcard_character
=
'
%
'
;
}
while
(
i
<
item_list
.
length
)
{
if
(
!
this
.
match
(
item_list
[
i
],
option
.
wildcard_character
))
{
item_list
.
splice
(
i
,
1
);
}
else
{
i
+=
1
;
}
}
if
(
option
.
sort_on
)
{
sortOn
(
option
.
sort_on
,
item_list
);
}
if
(
option
.
limit
)
{
limit
(
option
.
limit
,
item_list
);
}
select
(
option
.
select_list
||
[],
item_list
);
};
/**
* Test if an item matches this query
*
* @method match
* @param {Object} item The object to test
* @return {Boolean} true if match, false otherwise
*/
Query
.
prototype
.
match
=
function
(
item
,
wildcard_character
)
{
return
true
;
};
/**
* Browse the Query in deep calling parser method in each step.
*
* `onParseStart` is called first, on end `onParseEnd` is called.
* It starts from the simple queries at the bottom of the tree calling the
* parser method `onParseSimpleQuery`, and go up calling the
* `onParseComplexQuery` method.
*
* @method parse
* @param {Object} option Any options you want (except 'parsed')
* @return {Any} The parse result
*/
Query
.
prototype
.
parse
=
function
(
option
)
{
var
that
=
this
,
object
;
/**
* The recursive parser.
*
* @param {Object} object The object shared in the parse process
* @param {Object} options Some options usable in the parseMethods
* @return {Any} The parser result
*/
function
recParse
(
object
,
option
)
{
var
i
,
query
=
object
.
parsed
;
if
(
query
.
type
===
"
complex
"
)
{
for
(
i
=
0
;
i
<
query
.
query_list
.
length
;
i
+=
1
)
{
object
.
parsed
=
query
.
query_list
[
i
];
recParse
(
object
,
option
);
query
.
query_list
[
i
]
=
object
.
parsed
;
}
object
.
parsed
=
query
;
that
.
onParseComplexQuery
(
object
,
option
);
}
else
if
(
query
.
type
===
"
simple
"
)
{
that
.
onParseSimpleQuery
(
object
,
option
);
}
}
object
=
{
"
parsed
"
:
JSON
.
parse
(
JSON
.
stringify
(
that
.
serialized
()))};
that
.
onParseStart
(
object
,
option
);
recParse
(
object
,
option
);
that
.
onParseEnd
(
object
,
option
);
return
object
.
parsed
;
};
/**
* Convert this query to a parsable string.
*
* @method toString
* @return {String} The string version of this query
*/
Query
.
prototype
.
toString
=
function
()
{
return
""
;
};
/**
* Convert this query to an jsonable object in order to be remake thanks to
* QueryFactory class.
*
* @method serialized
* @return {Object} The jsonable object
*/
Query
.
prototype
.
serialized
=
function
()
{
return
undefined
;
};
_export
(
"
Query
"
,
Query
);
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*global Query: true, inherits: true, query_class_dict: true, _export: true,
convertStringToRegExp: true */
/**
* The SimpleQuery inherits from Query, and compares one metadata value
*
* @class SimpleQuery
* @extends Query
* @param {Object} [spec={}] The specifications
* @param {String} [spec.operator="="] The compare method to use
* @param {String} spec.key The metadata key
* @param {String} spec.value The value of the metadata to compare
*/
function
SimpleQuery
(
spec
)
{
Query
.
call
(
this
);
/**
* Operator to use to compare object values
*
* @attribute operator
* @type String
* @default "="
* @optional
*/
this
.
operator
=
spec
.
operator
||
"
=
"
;
/**
* Key of the object which refers to the value to compare
*
* @attribute key
* @type String
*/
this
.
key
=
spec
.
key
;
/**
* Value is used to do the comparison with the object value
*
* @attribute value
* @type String
*/
this
.
value
=
spec
.
value
;
}
inherits
(
SimpleQuery
,
Query
);
/**
* #crossLink "Query/match:method"
*/
SimpleQuery
.
prototype
.
match
=
function
(
item
,
wildcard_character
)
{
return
this
[
this
.
operator
](
item
[
this
.
key
],
this
.
value
,
wildcard_character
);
};
/**
* #crossLink "Query/toString:method"
*/
SimpleQuery
.
prototype
.
toString
=
function
()
{
return
(
this
.
key
?
this
.
key
+
"
:
"
:
""
)
+
(
this
.
operator
||
"
=
"
)
+
'
"
'
+
this
.
value
+
'
"
'
;
};
/**
* #crossLink "Query/serialized:method"
*/
SimpleQuery
.
prototype
.
serialized
=
function
()
{
return
{
"
type
"
:
"
simple
"
,
"
operator
"
:
this
.
operator
,
"
key
"
:
this
.
key
,
"
value
"
:
this
.
value
};
};
/**
* Comparison operator, test if this query value matches the item value
*
* @method =
* @param {String} object_value The value to compare
* @param {String} comparison_value The comparison value
* @param {String} wildcard_character The wildcard_character
* @return {Boolean} true if match, false otherwise
*/
SimpleQuery
.
prototype
[
"
=
"
]
=
function
(
object_value
,
comparison_value
,
wildcard_character
)
{
var
value
,
i
;
if
(
!
Array
.
isArray
(
object_value
))
{
object_value
=
[
object_value
];
}
for
(
i
=
0
;
i
<
object_value
.
length
;
i
+=
1
)
{
value
=
object_value
[
i
];
if
(
typeof
value
===
'
object
'
)
{
value
=
value
.
content
;
}
if
(
comparison_value
===
undefined
)
{
if
(
value
===
undefined
)
{
return
true
;
}
return
false
;
}
if
(
value
===
undefined
)
{
return
false
;
}
if
(
convertStringToRegExp
(
comparison_value
.
toString
(),
wildcard_character
).
test
(
value
.
toString
())
)
{
return
true
;
}
}
return
false
;
};
/**
* Comparison operator, test if this query value does not match the item value
*
* @method !=
* @param {String} object_value The value to compare
* @param {String} comparison_value The comparison value
* @param {String} wildcard_character The wildcard_character
* @return {Boolean} true if not match, false otherwise
*/
SimpleQuery
.
prototype
[
"
!=
"
]
=
function
(
object_value
,
comparison_value
,
wildcard_character
)
{
var
value
,
i
;
if
(
!
Array
.
isArray
(
object_value
))
{
object_value
=
[
object_value
];
}
for
(
i
=
0
;
i
<
object_value
.
length
;
i
+=
1
)
{
value
=
object_value
[
i
];
if
(
typeof
value
===
'
object
'
)
{
value
=
value
.
content
;
}
if
(
comparison_value
===
undefined
)
{
if
(
value
===
undefined
)
{
return
false
;
}
return
true
;
}
if
(
value
===
undefined
)
{
return
true
;
}
if
(
convertStringToRegExp
(
comparison_value
.
toString
(),
wildcard_character
).
test
(
value
.
toString
())
)
{
return
false
;
}
}
return
true
;
};
/**
* Comparison operator, test if this query value is lower than the item value
*
* @method <
* @param {Number, String} object_value The value to compare
* @param {Number, String} comparison_value The comparison value
* @return {Boolean} true if lower, false otherwise
*/
SimpleQuery
.
prototype
[
"
<
"
]
=
function
(
object_value
,
comparison_value
)
{
var
value
;
if
(
!
Array
.
isArray
(
object_value
))
{
object_value
=
[
object_value
];
}
value
=
object_value
[
0
];
if
(
typeof
value
===
'
object
'
)
{
value
=
value
.
content
;
}
return
value
<
comparison_value
;
};
/**
* Comparison operator, test if this query value is equal or lower than the
* item value
*
* @method <=
* @param {Number, String} object_value The value to compare
* @param {Number, String} comparison_value The comparison value
* @return {Boolean} true if equal or lower, false otherwise
*/
SimpleQuery
.
prototype
[
"
<=
"
]
=
function
(
object_value
,
comparison_value
)
{
var
value
;
if
(
!
Array
.
isArray
(
object_value
))
{
object_value
=
[
object_value
];
}
value
=
object_value
[
0
];
if
(
typeof
value
===
'
object
'
)
{
value
=
value
.
content
;
}
return
value
<=
comparison_value
;
};
/**
* Comparison operator, test if this query value is greater than the item
* value
*
* @method >
* @param {Number, String} object_value The value to compare
* @param {Number, String} comparison_value The comparison value
* @return {Boolean} true if greater, false otherwise
*/
SimpleQuery
.
prototype
[
"
>
"
]
=
function
(
object_value
,
comparison_value
)
{
var
value
;
if
(
!
Array
.
isArray
(
object_value
))
{
object_value
=
[
object_value
];
}
value
=
object_value
[
0
];
if
(
typeof
value
===
'
object
'
)
{
value
=
value
.
content
;
}
return
value
>
comparison_value
;
};
/**
* Comparison operator, test if this query value is equal or greater than the
* item value
*
* @method >=
* @param {Number, String} object_value The value to compare
* @param {Number, String} comparison_value The comparison value
* @return {Boolean} true if equal or greater, false otherwise
*/
SimpleQuery
.
prototype
[
"
>=
"
]
=
function
(
object_value
,
comparison_value
)
{
var
value
;
if
(
!
Array
.
isArray
(
object_value
))
{
object_value
=
[
object_value
];
}
value
=
object_value
[
0
];
if
(
typeof
value
===
'
object
'
)
{
value
=
value
.
content
;
}
return
value
>=
comparison_value
;
};
query_class_dict
.
simple
=
SimpleQuery
;
_export
(
"
SimpleQuery
"
,
SimpleQuery
);
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*global Query: true, query_class_dict: true, inherits: true,
_export: true, QueryFactory: true */
/**
* The ComplexQuery inherits from Query, and compares one or several metadata
* values.
*
* @class ComplexQuery
* @extends Query
* @param {Object} [spec={}] The specifications
* @param {String} [spec.operator="AND"] The compare method to use
* @param {String} spec.key The metadata key
* @param {String} spec.value The value of the metadata to compare
*/
function
ComplexQuery
(
spec
)
{
Query
.
call
(
this
);
/**
* Logical operator to use to compare object values
*
* @attribute operator
* @type String
* @default "AND"
* @optional
*/
this
.
operator
=
spec
.
operator
||
"
AND
"
;
/**
* The sub Query list which are used to query an item.
*
* @attribute query_list
* @type Array
* @default []
* @optional
*/
this
.
query_list
=
spec
.
query_list
||
[];
this
.
query_list
=
this
.
query_list
.
map
(
QueryFactory
.
create
);
}
inherits
(
ComplexQuery
,
Query
);
/**
* #crossLink "Query/match:method"
*/
ComplexQuery
.
prototype
.
match
=
function
(
item
,
wildcard_character
)
{
return
this
[
this
.
operator
](
item
,
wildcard_character
);
};
/**
* #crossLink "Query/toString:method"
*/
ComplexQuery
.
prototype
.
toString
=
function
()
{
var
str_list
=
[
"
(
"
],
this_operator
=
this
.
operator
;
this
.
query_list
.
forEach
(
function
(
query
)
{
str_list
.
push
(
query
.
toString
());
str_list
.
push
(
this_operator
);
});
str_list
.
pop
();
// remove last operator
str_list
.
push
(
"
)
"
);
return
str_list
.
join
(
"
"
);
};
/**
* #crossLink "Query/serialized:method"
*/
ComplexQuery
.
prototype
.
serialized
=
function
()
{
var
s
=
{
"
type
"
:
"
complex
"
,
"
operator
"
:
this
.
operator
,
"
query_list
"
:
[]
};
this
.
query_list
.
forEach
(
function
(
query
)
{
s
.
query_list
.
push
(
query
.
serialized
());
});
return
s
;
};
/**
* Comparison operator, test if all sub queries match the
* item value
*
* @method AND
* @param {Object} item The item to match
* @param {String} wildcard_character The wildcard character
* @return {Boolean} true if all match, false otherwise
*/
ComplexQuery
.
prototype
.
AND
=
function
(
item
,
wildcard_character
)
{
var
i
;
for
(
i
=
0
;
i
<
this
.
query_list
.
length
;
i
+=
1
)
{
if
(
!
this
.
query_list
[
i
].
match
(
item
,
wildcard_character
))
{
return
false
;
}
}
return
true
;
};
/**
* Comparison operator, test if one of the sub queries matches the
* item value
*
* @method OR
* @param {Object} item The item to match
* @param {String} wildcard_character The wildcard character
* @return {Boolean} true if one match, false otherwise
*/
ComplexQuery
.
prototype
.
OR
=
function
(
item
,
wildcard_character
)
{
var
i
;
for
(
i
=
0
;
i
<
this
.
query_list
.
length
;
i
+=
1
)
{
if
(
this
.
query_list
[
i
].
match
(
item
,
wildcard_character
))
{
return
true
;
}
}
return
false
;
};
/**
* Comparison operator, test if the sub query does not match the
* item value
*
* @method NOT
* @param {Object} item The item to match
* @param {String} wildcard_character The wildcard character
* @return {Boolean} true if one match, false otherwise
*/
ComplexQuery
.
prototype
.
NOT
=
function
(
item
,
wildcard_character
)
{
return
!
this
.
query_list
[
0
].
match
(
item
,
wildcard_character
);
};
query_class_dict
.
complex
=
ComplexQuery
;
_export
(
"
ComplexQuery
"
,
ComplexQuery
);
return
to_export
;
}));
jio.js
deleted
100644 → 0
View file @
1c6ccb5b
/*
* Copyright 2013, Nexedi SA
* Released under the LGPL license.
* http://www.gnu.org/licenses/lgpl.html
*/
// define([module_name], [dependencies], module);
(
function
(
dependencies
,
module
)
{
"
use strict
"
;
if
(
typeof
define
===
'
function
'
&&
define
.
amd
)
{
return
define
(
dependencies
,
module
);
}
if
(
typeof
exports
===
'
object
'
)
{
return
module
(
exports
,
require
(
'
md5
'
));
}
window
.
jIO
=
{};
module
(
window
.
jIO
,
{
hex_md5
:
hex_md5
});
}([
'
exports
'
,
'
md5
'
],
function
(
exports
,
md5
)
{
"
use strict
"
;
var
localstorage
,
hex_md5
=
md5
.
hex_md5
;
if
(
typeof
localStorage
!==
"
undefined
"
)
{
localstorage
=
{
getItem
:
function
(
item
)
{
var
value
=
localStorage
.
getItem
(
item
);
return
value
===
null
?
null
:
JSON
.
parse
(
value
);
},
setItem
:
function
(
item
,
value
)
{
return
localStorage
.
setItem
(
item
,
JSON
.
stringify
(
value
));
},
removeItem
:
function
(
item
)
{
return
localStorage
.
removeItem
(
item
);
},
clone
:
function
()
{
return
JSON
.
parse
(
JSON
.
stringify
(
localStorage
));
}
};
}
else
{
(
function
()
{
var
pseudo_localStorage
=
{};
localstorage
=
{
getItem
:
function
(
item
)
{
var
value
=
pseudo_localStorage
[
item
];
return
value
===
undefined
?
null
:
JSON
.
parse
(
value
);
},
setItem
:
function
(
item
,
value
)
{
pseudo_localStorage
[
item
]
=
JSON
.
stringify
(
value
);
},
removeItem
:
function
(
item
)
{
delete
pseudo_localStorage
[
item
];
},
clone
:
function
()
{
return
JSON
.
parse
(
JSON
.
stringify
(
pseudo_localStorage
));
}
};
}());
}
/*jslint indent:2, maxlen: 80, sloppy: true */
var
jioException
=
function
(
spec
,
my
)
{
var
that
=
{};
spec
=
spec
||
{};
my
=
my
||
{};
that
.
name
=
'
jioException
'
;
that
.
message
=
spec
.
message
||
'
Unknown Reason.
'
;
that
.
toString
=
function
()
{
return
that
.
name
+
'
:
'
+
that
.
message
;
};
return
that
;
};
var
invalidCommandState
=
function
(
spec
,
my
)
{
var
that
=
jioException
(
spec
,
my
),
command
=
spec
.
command
;
spec
=
spec
||
{};
that
.
name
=
'
invalidCommandState
'
;
that
.
toString
=
function
()
{
return
that
.
name
+
'
:
'
+
command
.
getLabel
()
+
'
,
'
+
that
.
message
;
};
return
that
;
};
var
invalidStorage
=
function
(
spec
,
my
)
{
var
that
=
jioException
(
spec
,
my
),
type
=
spec
.
storage
.
getType
();
spec
=
spec
||
{};
that
.
name
=
'
invalidStorage
'
;
that
.
toString
=
function
()
{
return
that
.
name
+
'
:
'
+
'
Type "
'
+
type
+
'
",
'
+
that
.
message
;
};
return
that
;
};
var
invalidStorageType
=
function
(
spec
,
my
)
{
var
that
=
jioException
(
spec
,
my
),
type
=
spec
.
type
;
that
.
name
=
'
invalidStorageType
'
;
that
.
toString
=
function
()
{
return
that
.
name
+
'
:
'
+
type
+
'
,
'
+
that
.
message
;
};
return
that
;
};
var
jobNotReadyException
=
function
(
spec
,
my
)
{
var
that
=
jioException
(
spec
,
my
);
that
.
name
=
'
jobNotReadyException
'
;
return
that
;
};
var
tooMuchTriesJobException
=
function
(
spec
,
my
)
{
var
that
=
jioException
(
spec
,
my
);
that
.
name
=
'
tooMuchTriesJobException
'
;
return
that
;
};
var
invalidJobException
=
function
(
spec
,
my
)
{
var
that
=
jioException
(
spec
,
my
);
that
.
name
=
'
invalidJobException
'
;
return
that
;
};
var
jio
=
function
(
spec
)
{
/*jslint indent: 2, maxlen: 80, sloppy: true */
/*global command: true, jobManager: true, job: true */
var
storage
=
function
(
spec
,
my
)
{
var
that
=
{},
priv
=
{};
spec
=
spec
||
{};
my
=
my
||
{};
// Attributes //
priv
.
type
=
spec
.
type
||
''
;
// Methods //
Object
.
defineProperty
(
that
,
"
getType
"
,
{
configurable
:
false
,
enumerable
:
false
,
writable
:
false
,
value
:
function
()
{
return
priv
.
type
;
}
});
/**
* Execute the command on this storage.
* @method execute
* @param {object} command The command
*/
that
.
execute
=
function
(
command
)
{
that
.
success
=
command
.
success
;
that
.
error
=
command
.
error
;
that
.
retry
=
command
.
retry
;
that
.
end
=
command
.
end
;
if
(
that
.
validate
(
command
))
{
command
.
executeOn
(
that
);
}
};
/**
* Override this function to validate specifications.
* @method isValid
* @return {boolean} true if ok, else false.
*/
that
.
isValid
=
function
()
{
return
true
;
};
that
.
validate
=
function
()
{
var
mess
=
that
.
validateState
();
if
(
mess
)
{
that
.
error
({
"
status
"
:
0
,
"
statusText
"
:
"
Invalid Storage
"
,
"
error
"
:
"
invalid_storage
"
,
"
message
"
:
mess
,
"
reason
"
:
mess
});
return
false
;
}
return
true
;
};
/**
* Returns a serialized version of this storage.
* @method serialized
* @return {object} The serialized storage.
*/
that
.
serialized
=
function
()
{
var
o
=
that
.
specToStore
()
||
{};
o
.
type
=
that
.
getType
();
return
o
;
};
/**
* Returns an object containing spec to store on localStorage, in order to
* be restored later if something wrong happen.
* Override this method!
* @method specToStore
* @return {object} The spec to store
*/
that
.
specToStore
=
function
()
{
return
{};
};
/**
* Validate the storage state. It returns a empty string all is ok.
* @method validateState
* @return {string} empty: ok, else error message.
*/
that
.
validateState
=
function
()
{
return
''
;
};
that
.
post
=
function
()
{
setTimeout
(
function
()
{
that
.
error
({
"
status
"
:
0
,
"
statusText
"
:
"
Not Implemented
"
,
"
error
"
:
"
not_implemented
"
,
"
message
"
:
"
\"
Post
\"
command is not implemented
"
,
"
reason
"
:
"
Command not implemented
"
});
});
};
that
.
put
=
function
()
{
setTimeout
(
function
()
{
that
.
error
({
"
status
"
:
0
,
"
statusText
"
:
"
Not Implemented
"
,
"
error
"
:
"
not_implemented
"
,
"
message
"
:
"
\"
Put
\"
command is not implemented
"
,
"
reason
"
:
"
Command not implemented
"
});
});
};
that
.
putAttachment
=
function
()
{
setTimeout
(
function
()
{
that
.
error
({
"
status
"
:
0
,
"
statusText
"
:
"
Not Implemented
"
,
"
error
"
:
"
not_implemented
"
,
"
message
"
:
"
\"
PutAttachment
\"
command is not implemented
"
,
"
reason
"
:
"
Command not implemented
"
});
});
};
that
.
get
=
function
()
{
setTimeout
(
function
()
{
that
.
error
({
"
status
"
:
0
,
"
statusText
"
:
"
Not Implemented
"
,
"
error
"
:
"
not_implemented
"
,
"
message
"
:
"
\"
Get
\"
command is not implemented
"
,
"
reason
"
:
"
Command not implemented
"
});
});
};
that
.
allDocs
=
function
()
{
setTimeout
(
function
()
{
that
.
error
({
"
status
"
:
0
,
"
statusText
"
:
"
Not Implemented
"
,
"
error
"
:
"
not_implemented
"
,
"
message
"
:
"
\"
AllDocs
\"
command is not implemented
"
,
"
reason
"
:
"
Command not implemented
"
});
});
};
that
.
remove
=
function
()
{
setTimeout
(
function
()
{
that
.
error
({
"
status
"
:
0
,
"
statusText
"
:
"
Not Implemented
"
,
"
error
"
:
"
not_implemented
"
,
"
message
"
:
"
\"
Remove
\"
command is not implemented
"
,
"
reason
"
:
"
Command not implemented
"
});
});
};
that
.
check
=
function
(
command
)
{
setTimeout
(
function
()
{
that
.
success
({
"
ok
"
:
true
,
"
id
"
:
command
.
getDocId
()});
});
};
that
.
repair
=
function
(
command
)
{
setTimeout
(
function
()
{
that
.
success
({
"
ok
"
:
true
,
"
id
"
:
command
.
getDocId
()});
});
};
that
.
success
=
function
()
{};
that
.
retry
=
function
()
{};
that
.
error
=
function
()
{};
that
.
end
=
function
()
{};
// terminate the current job.
priv
.
newCommand
=
function
(
method
,
spec
)
{
var
o
=
spec
||
{};
o
.
label
=
method
;
return
command
(
o
,
my
);
};
priv
.
storage
=
my
.
storage
;
delete
my
.
storage
;
that
.
addJob
=
function
(
method
,
storage_spec
,
doc
,
option
,
success
,
error
)
{
var
command_opt
=
{
doc
:
doc
,
options
:
option
,
callbacks
:
{
success
:
success
,
error
:
error
}
};
jobManager
.
addJob
(
job
({
storage
:
priv
.
storage
(
storage_spec
||
{}),
command
:
priv
.
newCommand
(
method
,
command_opt
)
},
my
));
};
return
that
;
};
/*jslint indent: 2, maxlen: 80, sloppy: true */
/*global command: true */
var
allDocsCommand
=
function
(
spec
,
my
)
{
var
that
=
command
(
spec
,
my
);
spec
=
spec
||
{};
my
=
my
||
{};
// Attributes //
// Methods //
that
.
getLabel
=
function
()
{
return
'
allDocs
'
;
};
that
.
executeOn
=
function
(
storage
)
{
storage
.
allDocs
(
that
);
};
that
.
canBeRestored
=
function
()
{
return
false
;
};
that
.
validateState
=
function
()
{
return
true
;
};
return
that
;
};
/*jslint indent: 2, maxlen: 80, sloppy: true */
/*global command: true */
var
checkCommand
=
function
(
spec
,
my
)
{
var
that
=
command
(
spec
,
my
);
spec
=
spec
||
{};
my
=
my
||
{};
// Methods //
that
.
getLabel
=
function
()
{
return
'
check
'
;
};
that
.
validateState
=
function
()
{
if
(
!
(
typeof
that
.
getDocId
()
===
"
string
"
&&
that
.
getDocId
()
!==
""
))
{
that
.
error
({
"
status
"
:
20
,
"
statusText
"
:
"
Document Id Required
"
,
"
error
"
:
"
document_id_required
"
,
"
message
"
:
"
The document id is not provided
"
,
"
reason
"
:
"
Document id is undefined
"
});
return
false
;
}
return
true
;
};
that
.
executeOn
=
function
(
storage
)
{
storage
.
check
(
that
);
};
that
.
canBeRestored
=
function
()
{
return
false
;
};
return
that
;
};
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*global postCommand: true, putCommand: true, getCommand: true,
removeCommand: true, allDocsCommand: true,
getAttachmentCommand: true, removeAttachmentCommand: true,
putAttachmentCommand: true, failStatus: true, doneStatus: true,
checkCommand: true, repairCommand: true,
hex_md5: true */
var
command
=
function
(
spec
,
my
)
{
var
that
=
{},
priv
=
{};
spec
=
spec
||
{};
my
=
my
||
{};
priv
.
commandlist
=
{
'
post
'
:
postCommand
,
'
put
'
:
putCommand
,
'
get
'
:
getCommand
,
'
remove
'
:
removeCommand
,
'
allDocs
'
:
allDocsCommand
,
'
getAttachment
'
:
getAttachmentCommand
,
'
putAttachment
'
:
putAttachmentCommand
,
'
removeAttachment
'
:
removeAttachmentCommand
,
'
check
'
:
checkCommand
,
'
repair
'
:
repairCommand
};
// creates the good command thanks to his label
if
(
spec
.
label
&&
priv
.
commandlist
[
spec
.
label
])
{
priv
.
label
=
spec
.
label
;
delete
spec
.
label
;
return
priv
.
commandlist
[
priv
.
label
](
spec
,
my
);
}
priv
.
tried
=
0
;
priv
.
doc
=
spec
.
doc
||
{};
if
(
typeof
priv
.
doc
!==
"
object
"
)
{
priv
.
doc
=
{
"
_id
"
:
priv
.
doc
.
toString
()
};
}
priv
.
option
=
spec
.
options
||
{};
priv
.
callbacks
=
spec
.
callbacks
||
{};
priv
.
success
=
[
priv
.
callbacks
.
success
||
function
()
{}];
priv
.
error
=
[
priv
.
callbacks
.
error
||
function
()
{}];
priv
.
retry
=
function
()
{
that
.
error
({
status
:
13
,
statusText
:
'
Fail Retry
'
,
error
:
'
fail_retry
'
,
message
:
'
Impossible to retry.
'
,
reason
:
'
Impossible to retry.
'
});
};
priv
.
end
=
function
()
{};
priv
.
on_going
=
false
;
// Methods //
/**
* Returns a serialized version of this command.
* @method serialized
* @return {object} The serialized command.
*/
that
.
serialized
=
function
()
{
var
o
=
{};
o
.
label
=
that
.
getLabel
();
o
.
tried
=
priv
.
tried
;
o
.
doc
=
that
.
cloneDoc
();
o
.
option
=
that
.
cloneOption
();
return
o
;
};
/**
* Returns the label of the command.
* @method getLabel
* @return {string} The label.
*/
that
.
getLabel
=
function
()
{
return
'
command
'
;
};
/**
* Gets the document id
* @method getDocId
* @return {string} The document id
*/
that
.
getDocId
=
function
()
{
return
priv
.
doc
.
_id
;
};
/**
* Gets the attachment id
* @method getAttachmentId
* @return {string} The attachment id
*/
that
.
getAttachmentId
=
function
()
{
return
priv
.
doc
.
_attachment
;
};
/**
* Returns the data of the attachment
* @method getAttachmentData
* @return {string} The data
*/
that
.
getAttachmentData
=
function
()
{
return
priv
.
doc
.
_data
||
""
;
};
/**
* Returns the data length of the attachment
* @method getAttachmentLength
* @return {number} The length
*/
that
.
getAttachmentLength
=
function
()
{
return
(
priv
.
doc
.
_data
||
""
).
length
;
};
/**
* Returns the mimetype of the attachment
* @method getAttachmentMimeType
* @return {string} The mimetype
*/
that
.
getAttachmentMimeType
=
function
()
{
return
priv
.
doc
.
_mimetype
;
};
/**
* Generate the md5sum of the attachment data
* @method md5SumAttachmentData
* @return {string} The md5sum
*/
that
.
md5SumAttachmentData
=
function
()
{
return
hex_md5
(
priv
.
doc
.
_data
||
""
);
};
/**
* Returns an information about the document.
* @method getDocInfo
* @param {string} infoname The info name.
* @return The info value.
*/
that
.
getDocInfo
=
function
(
infoname
)
{
return
priv
.
doc
[
infoname
];
};
/**
* Returns the value of an option.
* @method getOption
* @param {string} optionname The option name.
* @return The option value.
*/
that
.
getOption
=
function
(
optionname
)
{
return
priv
.
option
[
optionname
];
};
/**
* Validates the storage.
* @param {object} storage The storage.
*/
that
.
validate
=
function
(
storage
)
{
if
(
typeof
priv
.
doc
.
_id
===
"
string
"
&&
priv
.
doc
.
_id
===
""
)
{
that
.
error
({
"
status
"
:
21
,
"
statusText
"
:
"
Invalid Document Id
"
,
"
error
"
:
"
invalid_document_id
"
,
"
message
"
:
"
The document id is invalid
"
,
"
reason
"
:
"
empty
"
});
return
false
;
}
if
(
!
that
.
validateState
())
{
return
false
;
}
return
storage
.
validate
();
};
/*
* Extend this function
*/
that
.
validateState
=
function
()
{
return
true
;
};
/**
* Check if the command can be retried.
* @method canBeRetried
* @return {boolean} The result
*/
that
.
canBeRetried
=
function
()
{
return
(
priv
.
option
.
max_retry
===
undefined
||
priv
.
option
.
max_retry
===
0
||
priv
.
tried
<
priv
.
option
.
max_retry
);
};
/**
* Gets the number time the command has been tried.
* @method getTried
* @return {number} The number of time the command has been tried
*/
that
.
getTried
=
function
()
{
return
priv
.
tried
;
};
/**
* Delegate actual excecution the storage.
* @param {object} storage The storage.
*/
that
.
execute
=
function
(
storage
)
{
if
(
!
priv
.
on_going
)
{
if
(
that
.
validate
(
storage
))
{
priv
.
tried
+=
1
;
priv
.
on_going
=
true
;
storage
.
execute
(
that
);
}
}
};
/**
* Execute the good method from the storage.
* Override this function.
* @method executeOn
* @param {object} storage The storage.
*/
that
.
executeOn
=
function
(
storage
)
{};
that
.
success
=
function
(
return_value
)
{
var
i
;
priv
.
on_going
=
false
;
for
(
i
=
0
;
i
<
priv
.
success
.
length
;
i
+=
1
)
{
priv
.
success
[
i
](
return_value
);
}
priv
.
end
(
doneStatus
());
priv
.
success
=
[];
priv
.
error
=
[];
};
that
.
retry
=
function
(
return_error
)
{
priv
.
on_going
=
false
;
if
(
that
.
canBeRetried
())
{
priv
.
retry
();
}
else
{
that
.
error
(
return_error
);
}
};
that
.
error
=
function
(
return_error
)
{
var
i
;
priv
.
on_going
=
false
;
for
(
i
=
0
;
i
<
priv
.
error
.
length
;
i
+=
1
)
{
priv
.
error
[
i
](
return_error
);
}
priv
.
end
(
failStatus
());
priv
.
success
=
[];
priv
.
error
=
[];
};
that
.
end
=
function
()
{
priv
.
end
(
doneStatus
());
};
that
.
addCallbacks
=
function
(
success
,
error
)
{
if
(
arguments
.
length
>
1
)
{
priv
.
success
.
push
(
success
||
function
()
{});
priv
.
error
.
push
(
error
||
function
()
{});
}
else
{
priv
.
success
.
push
(
function
(
response
)
{
(
success
||
function
()
{})(
undefined
,
response
);
});
priv
.
error
.
push
(
function
(
err
)
{
(
success
||
function
()
{})(
err
,
undefined
);
});
}
};
that
.
onSuccessDo
=
function
(
fun
)
{
if
(
fun
)
{
priv
.
success
=
fun
;
}
else
{
return
priv
.
success
;
}
};
that
.
onErrorDo
=
function
(
fun
)
{
if
(
fun
)
{
priv
.
error
=
fun
;
}
else
{
return
priv
.
error
;
}
};
that
.
onEndDo
=
function
(
fun
)
{
priv
.
end
=
fun
;
};
that
.
onRetryDo
=
function
(
fun
)
{
priv
.
retry
=
fun
;
};
/**
* Is the command can be restored by another JIO : yes.
* @method canBeRestored
* @return {boolean} true
*/
that
.
canBeRestored
=
function
()
{
return
true
;
};
/**
* Clones the command and returns it.
* @method clone
* @return {object} The cloned command.
*/
that
.
clone
=
function
()
{
return
command
(
that
.
serialized
(),
my
);
};
/**
* Clones the command options and returns the clone version.
* @method cloneOption
* @return {object} The clone of the command options.
*/
that
.
cloneOption
=
function
()
{
return
JSON
.
parse
(
JSON
.
stringify
(
priv
.
option
));
};
/**
* Clones the document and returns the clone version.
* @method cloneDoc
* @return {object} The clone of the document.
*/
that
.
cloneDoc
=
function
()
{
return
JSON
.
parse
(
JSON
.
stringify
(
priv
.
doc
));
};
return
that
;
};
/*jslint indent: 2, maxlen: 80, sloppy: true */
/*global command: true */
var
getAttachmentCommand
=
function
(
spec
,
my
)
{
var
that
=
command
(
spec
,
my
);
spec
=
spec
||
{};
my
=
my
||
{};
// Attributes //
// Methods //
that
.
getLabel
=
function
()
{
return
'
getAttachment
'
;
};
that
.
executeOn
=
function
(
storage
)
{
storage
.
getAttachment
(
that
);
};
that
.
validateState
=
function
()
{
if
(
!
(
typeof
that
.
getDocId
()
===
"
string
"
&&
that
.
getDocId
()
!==
""
))
{
that
.
error
({
"
status
"
:
20
,
"
statusText
"
:
"
Document Id Required
"
,
"
error
"
:
"
document_id_required
"
,
"
message
"
:
"
The document id is not provided
"
,
"
reason
"
:
"
Document id is undefined
"
});
return
false
;
}
if
(
typeof
that
.
getAttachmentId
()
!==
"
string
"
)
{
that
.
error
({
"
status
"
:
22
,
"
statusText
"
:
"
Attachment Id Required
"
,
"
error
"
:
"
attachment_id_required
"
,
"
message
"
:
"
The attachment id must be set
"
,
"
reason
"
:
"
Attachment id not set
"
});
return
false
;
}
if
(
that
.
getAttachmentId
()
===
""
)
{
that
.
error
({
"
status
"
:
23
,
"
statusText
"
:
"
Invalid Attachment Id
"
,
"
error
"
:
"
invalid_attachment_id
"
,
"
message
"
:
"
The attachment id must not be an empty string
"
,
"
reason
"
:
"
Attachment id is empty
"
});
}
return
true
;
};
return
that
;
};
/*jslint indent: 2, maxlen: 80, sloppy: true */
/*global command: true */
var
getCommand
=
function
(
spec
,
my
)
{
var
that
=
command
(
spec
,
my
);
spec
=
spec
||
{};
my
=
my
||
{};
// Attributes //
// Methods //
that
.
getLabel
=
function
()
{
return
'
get
'
;
};
that
.
validateState
=
function
()
{
if
(
!
(
typeof
that
.
getDocId
()
===
"
string
"
&&
that
.
getDocId
()
!==
""
))
{
that
.
error
({
"
status
"
:
20
,
"
statusText
"
:
"
Document Id Required
"
,
"
error
"
:
"
document_id_required
"
,
"
message
"
:
"
The document id is not provided
"
,
"
reason
"
:
"
Document id is undefined
"
});
return
false
;
}
return
true
;
};
that
.
executeOn
=
function
(
storage
)
{
storage
.
get
(
that
);
};
that
.
canBeRestored
=
function
()
{
return
false
;
};
return
that
;
};
/*jslint indent: 2, maxlen: 80, sloppy: true */
/*global command: true */
var
postCommand
=
function
(
spec
,
my
)
{
var
that
=
command
(
spec
,
my
);
spec
=
spec
||
{};
my
=
my
||
{};
// Methods //
that
.
getLabel
=
function
()
{
return
'
post
'
;
};
that
.
validateState
=
function
()
{
return
true
;
};
that
.
executeOn
=
function
(
storage
)
{
storage
.
post
(
that
);
};
return
that
;
};
/*jslint indent: 2, maxlen: 80, sloppy: true */
/*global command: true */
var
putAttachmentCommand
=
function
(
spec
,
my
)
{
var
that
=
command
(
spec
,
my
);
spec
=
spec
||
{};
my
=
my
||
{};
// Attributes //
// Methods //
that
.
getLabel
=
function
()
{
return
'
putAttachment
'
;
};
that
.
executeOn
=
function
(
storage
)
{
storage
.
putAttachment
(
that
);
};
that
.
validateState
=
function
()
{
if
(
!
(
typeof
that
.
getDocId
()
===
"
string
"
&&
that
.
getDocId
()
!==
""
))
{
that
.
error
({
"
status
"
:
20
,
"
statusText
"
:
"
Document Id Required
"
,
"
error
"
:
"
document_id_required
"
,
"
message
"
:
"
The document id is not provided
"
,
"
reason
"
:
"
Document id is undefined
"
});
return
false
;
}
if
(
typeof
that
.
getAttachmentId
()
!==
"
string
"
)
{
that
.
error
({
"
status
"
:
22
,
"
statusText
"
:
"
Attachment Id Required
"
,
"
error
"
:
"
attachment_id_required
"
,
"
message
"
:
"
The attachment id must be set
"
,
"
reason
"
:
"
Attachment id not set
"
});
return
false
;
}
if
(
that
.
getAttachmentId
()
===
""
)
{
that
.
error
({
"
status
"
:
23
,
"
statusText
"
:
"
Invalid Attachment Id
"
,
"
error
"
:
"
invalid_attachment_id
"
,
"
message
"
:
"
The attachment id must not be an empty string
"
,
"
reason
"
:
"
Attachment id is empty
"
});
}
return
true
;
};
return
that
;
};
/*jslint indent: 2, maxlen: 80, sloppy: true */
/*global command: true */
var
putCommand
=
function
(
spec
,
my
)
{
var
that
=
command
(
spec
,
my
);
spec
=
spec
||
{};
my
=
my
||
{};
// Methods //
that
.
getLabel
=
function
()
{
return
'
put
'
;
};
that
.
validateState
=
function
()
{
if
(
!
(
typeof
that
.
getDocId
()
===
"
string
"
&&
that
.
getDocId
()
!==
""
))
{
that
.
error
({
"
status
"
:
20
,
"
statusText
"
:
"
Document Id Required
"
,
"
error
"
:
"
document_id_required
"
,
"
message
"
:
"
The document id is not provided
"
,
"
reason
"
:
"
Document id is undefined
"
});
return
false
;
}
return
true
;
};
that
.
executeOn
=
function
(
storage
)
{
storage
.
put
(
that
);
};
return
that
;
};
/*jslint indent: 2, maxlen: 80, sloppy: true */
/*global command: true */
var
removeAttachmentCommand
=
function
(
spec
,
my
)
{
var
that
=
command
(
spec
,
my
);
spec
=
spec
||
{};
my
=
my
||
{};
// Attributes //
// Methods //
that
.
getLabel
=
function
()
{
return
'
removeAttachment
'
;
};
that
.
executeOn
=
function
(
storage
)
{
storage
.
removeAttachment
(
that
);
};
that
.
validateState
=
function
()
{
if
(
!
(
typeof
that
.
getDocId
()
===
"
string
"
&&
that
.
getDocId
()
!==
""
))
{
that
.
error
({
"
status
"
:
20
,
"
statusText
"
:
"
Document Id Required
"
,
"
error
"
:
"
document_id_required
"
,
"
message
"
:
"
The document id is not provided
"
,
"
reason
"
:
"
Document id is undefined
"
});
return
false
;
}
if
(
typeof
that
.
getAttachmentId
()
!==
"
string
"
)
{
that
.
error
({
"
status
"
:
22
,
"
statusText
"
:
"
Attachment Id Required
"
,
"
error
"
:
"
attachment_id_required
"
,
"
message
"
:
"
The attachment id must be set
"
,
"
reason
"
:
"
Attachment id not set
"
});
return
false
;
}
if
(
that
.
getAttachmentId
()
===
""
)
{
that
.
error
({
"
status
"
:
23
,
"
statusText
"
:
"
Invalid Attachment Id
"
,
"
error
"
:
"
invalid_attachment_id
"
,
"
message
"
:
"
The attachment id must not be an empty string
"
,
"
reason
"
:
"
Attachment id is empty
"
});
}
return
true
;
};
return
that
;
};
/*jslint indent: 2, maxlen: 80, sloppy: true */
/*global command: true */
var
removeCommand
=
function
(
spec
,
my
)
{
var
that
=
command
(
spec
,
my
);
spec
=
spec
||
{};
my
=
my
||
{};
// Attributes //
// Methods //
that
.
getLabel
=
function
()
{
return
'
remove
'
;
};
that
.
validateState
=
function
()
{
if
(
!
(
typeof
that
.
getDocId
()
===
"
string
"
&&
that
.
getDocId
()
!==
""
))
{
that
.
error
({
"
status
"
:
20
,
"
statusText
"
:
"
Document Id Required
"
,
"
error
"
:
"
document_id_required
"
,
"
message
"
:
"
The document id is not provided
"
,
"
reason
"
:
"
Document id is undefined
"
});
return
false
;
}
return
true
;
};
that
.
executeOn
=
function
(
storage
)
{
storage
.
remove
(
that
);
};
return
that
;
};
/*jslint indent: 2, maxlen: 80, sloppy: true */
/*global command: true */
var
repairCommand
=
function
(
spec
,
my
)
{
var
that
=
command
(
spec
,
my
);
spec
=
spec
||
{};
my
=
my
||
{};
// Methods //
that
.
getLabel
=
function
()
{
return
'
repair
'
;
};
that
.
validateState
=
function
()
{
if
(
!
(
typeof
that
.
getDocId
()
===
"
string
"
&&
that
.
getDocId
()
!==
""
))
{
that
.
error
({
"
status
"
:
20
,
"
statusText
"
:
"
Document Id Required
"
,
"
error
"
:
"
document_id_required
"
,
"
message
"
:
"
The document id is not provided
"
,
"
reason
"
:
"
Document id is undefined
"
});
return
false
;
}
return
true
;
};
that
.
executeOn
=
function
(
storage
)
{
storage
.
repair
(
that
);
};
return
that
;
};
/*jslint indent: 2, maxlen: 80, sloppy: true */
/*global jobStatus: true */
var
doneStatus
=
function
(
spec
,
my
)
{
var
that
=
jobStatus
(
spec
,
my
);
spec
=
spec
||
{};
my
=
my
||
{};
// Attributes //
// Methods //
that
.
getLabel
=
function
()
{
return
'
done
'
;
};
that
.
canStart
=
function
()
{
return
false
;
};
that
.
canRestart
=
function
()
{
return
false
;
};
that
.
isDone
=
function
()
{
return
true
;
};
return
that
;
};
/*jslint indent: 2, maxlen: 80, sloppy: true */
/*global jobStatus: true */
var
failStatus
=
function
(
spec
,
my
)
{
var
that
=
jobStatus
(
spec
,
my
);
spec
=
spec
||
{};
my
=
my
||
{};
// Attributes //
// Methods //
that
.
getLabel
=
function
()
{
return
'
fail
'
;
};
that
.
canStart
=
function
()
{
return
false
;
};
that
.
canRestart
=
function
()
{
return
true
;
};
return
that
;
};
/*jslint indent: 2, maxlen: 80, sloppy: true */
/*global jobStatus: true */
var
initialStatus
=
function
(
spec
,
my
)
{
var
that
=
jobStatus
(
spec
,
my
);
spec
=
spec
||
{};
my
=
my
||
{};
// Attributes //
// Methods //
that
.
getLabel
=
function
()
{
return
"
initial
"
;
};
that
.
canStart
=
function
()
{
return
true
;
};
that
.
canRestart
=
function
()
{
return
true
;
};
return
that
;
};
/*jslint indent: 2, maxlen: 80, sloppy: true */
/*global jobStatus: true */
var
jobStatus
=
function
(
spec
,
my
)
{
var
that
=
{};
spec
=
spec
||
{};
my
=
my
||
{};
// Attributes //
// Methods //
that
.
getLabel
=
function
()
{
return
'
job status
'
;
};
that
.
canStart
=
function
()
{};
that
.
canRestart
=
function
()
{};
that
.
serialized
=
function
()
{
return
{
"
label
"
:
that
.
getLabel
()};
};
that
.
isWaitStatus
=
function
()
{
return
false
;
};
that
.
isDone
=
function
()
{
return
false
;
};
return
that
;
};
/*jslint indent: 2, maxlen: 80, sloppy: true */
/*global jobStatus: true */
var
onGoingStatus
=
function
(
spec
,
my
)
{
var
that
=
jobStatus
(
spec
,
my
);
spec
=
spec
||
{};
my
=
my
||
{};
// Attributes //
// Methods //
that
.
getLabel
=
function
()
{
return
'
on going
'
;
};
that
.
canStart
=
function
()
{
return
false
;
};
that
.
canRestart
=
function
()
{
return
false
;
};
return
that
;
};
/*jslint indent: 2, maxlen: 80, sloppy: true */
/*global jobStatus: true, jobManager: true */
var
waitStatus
=
function
(
spec
,
my
)
{
var
that
=
jobStatus
(
spec
,
my
),
priv
=
{};
spec
=
spec
||
{};
my
=
my
||
{};
// Attributes //
priv
.
job_id_array
=
spec
.
job_id_array
||
[];
priv
.
threshold
=
0
;
// Methods //
/**
* Returns the label of this status.
* @method getLabel
* @return {string} The label: 'wait'.
*/
that
.
getLabel
=
function
()
{
return
'
wait
'
;
};
/**
* Refresh the job id array to wait.
* @method refreshJobIdArray
*/
priv
.
refreshJobIdArray
=
function
()
{
var
tmp_job_id_array
=
[],
i
;
for
(
i
=
0
;
i
<
priv
.
job_id_array
.
length
;
i
+=
1
)
{
if
(
jobManager
.
jobIdExists
(
priv
.
job_id_array
[
i
]))
{
tmp_job_id_array
.
push
(
priv
.
job_id_array
[
i
]);
}
}
priv
.
job_id_array
=
tmp_job_id_array
;
};
/**
* The status must wait for the job end before start again.
* @method waitForJob
* @param {object} job The job to wait for.
*/
that
.
waitForJob
=
function
(
job
)
{
var
i
;
for
(
i
=
0
;
i
<
priv
.
job_id_array
.
length
;
i
+=
1
)
{
if
(
priv
.
job_id_array
[
i
]
===
job
.
getId
())
{
return
;
}
}
priv
.
job_id_array
.
push
(
job
.
getId
());
};
/**
* The status stops to wait for this job.
* @method dontWaitForJob
* @param {object} job The job to stop waiting for.
*/
that
.
dontWaitForJob
=
function
(
job
)
{
var
i
,
tmp_job_id_array
=
[];
for
(
i
=
0
;
i
<
priv
.
job_id_array
.
length
;
i
+=
1
)
{
if
(
priv
.
job_id_array
[
i
]
!==
job
.
getId
())
{
tmp_job_id_array
.
push
(
priv
.
job_id_array
[
i
]);
}
}
priv
.
job_id_array
=
tmp_job_id_array
;
};
/**
* The status must wait for some milliseconds.
* @method waitForTime
* @param {number} ms The number of milliseconds
*/
that
.
waitForTime
=
function
(
ms
)
{
priv
.
threshold
=
Date
.
now
()
+
ms
;
};
/**
* The status stops to wait for some time.
* @method stopWaitForTime
*/
that
.
stopWaitForTime
=
function
()
{
priv
.
threshold
=
0
;
};
that
.
canStart
=
function
()
{
priv
.
refreshJobIdArray
();
return
(
priv
.
job_id_array
.
length
===
0
&&
Date
.
now
()
>=
priv
.
threshold
);
};
that
.
canRestart
=
function
()
{
return
that
.
canStart
();
};
that
.
serialized
=
function
()
{
return
{
"
label
"
:
that
.
getLabel
(),
"
waitfortime
"
:
priv
.
threshold
,
"
waitforjob
"
:
priv
.
job_id_array
};
};
/**
* Checks if this status is waitStatus
* @method isWaitStatus
* @return {boolean} true
*/
that
.
isWaitStatus
=
function
()
{
return
true
;
};
return
that
;
};
/*jslint indent: 2, maxlen: 80, sloppy: true */
/*global jobIdHandler: true, initialStatus: true, invalidJobException: true,
waitStatus: true, failStatus: true, tooMuchTriesJobException: true,
jobManager: true, jobNotReadyException: true, onGoingStatus: true */
var
job
=
function
(
spec
)
{
var
that
=
{},
priv
=
{};
spec
=
spec
||
{};
priv
.
id
=
jobIdHandler
.
nextId
();
priv
.
command
=
spec
.
command
;
priv
.
storage
=
spec
.
storage
;
priv
.
status
=
initialStatus
();
priv
.
date
=
new
Date
();
// Initialize //
if
(
!
priv
.
storage
)
{
throw
invalidJobException
({
job
:
that
,
message
:
'
No storage set
'
});
}
if
(
!
priv
.
command
)
{
throw
invalidJobException
({
job
:
that
,
message
:
'
No command set
'
});
}
// Methods //
/**
* Returns the job command.
* @method getCommand
* @return {object} The job command.
*/
that
.
getCommand
=
function
()
{
return
priv
.
command
;
};
that
.
getStatus
=
function
()
{
return
priv
.
status
;
};
that
.
getId
=
function
()
{
return
priv
.
id
;
};
that
.
getStorage
=
function
()
{
return
priv
.
storage
;
};
that
.
getDate
=
function
()
{
return
priv
.
date
;
};
/**
* Checks if the job is ready.
* @method isReady
* @return {boolean} true if ready, else false.
*/
that
.
isReady
=
function
()
{
if
(
priv
.
command
.
getTried
()
===
0
)
{
return
priv
.
status
.
canStart
();
}
return
priv
.
status
.
canRestart
();
};
/**
* Returns a serialized version of this job.
* @method serialized
* @return {object} The serialized job.
*/
that
.
serialized
=
function
()
{
return
{
id
:
priv
.
id
,
date
:
priv
.
date
.
getTime
(),
status
:
priv
.
status
.
serialized
(),
command
:
priv
.
command
.
serialized
(),
storage
:
priv
.
storage
.
serialized
()
};
};
/**
* Tells the job to wait for another one.
* @method waitForJob
* @param {object} job The job to wait for.
*/
that
.
waitForJob
=
function
(
job
)
{
if
(
priv
.
status
.
getLabel
()
!==
'
wait
'
)
{
priv
.
status
=
waitStatus
({});
}
priv
.
status
.
waitForJob
(
job
);
};
/**
* Tells the job to do not wait for a job.
* @method dontWaitForJob
* @param {object} job The other job.
*/
that
.
dontWaitFor
=
function
(
job
)
{
if
(
priv
.
status
.
getLabel
()
===
'
wait
'
)
{
priv
.
status
.
dontWaitForJob
(
job
);
}
};
/**
* Tells the job to wait for a while.
* @method waitForTime
* @param {number} ms Time to wait in millisecond.
*/
that
.
waitForTime
=
function
(
ms
)
{
if
(
priv
.
status
.
getLabel
()
!==
'
wait
'
)
{
priv
.
status
=
waitStatus
({});
}
priv
.
status
.
waitForTime
(
ms
);
};
/**
* Tells the job to do not wait for a while anymore.
* @method stopWaitForTime
*/
that
.
stopWaitForTime
=
function
()
{
if
(
priv
.
status
.
getLabel
()
===
'
wait
'
)
{
priv
.
status
.
stopWaitForTime
();
}
};
that
.
eliminated
=
function
()
{
priv
.
command
.
error
({
status
:
10
,
statusText
:
'
Stopped
'
,
error
:
'
stopped
'
,
message
:
'
This job has been stopped by another one.
'
,
reason
:
'
this job has been stopped by another one
'
});
};
that
.
notAccepted
=
function
()
{
priv
.
command
.
onEndDo
(
function
()
{
priv
.
status
=
failStatus
();
jobManager
.
terminateJob
(
that
);
});
priv
.
command
.
error
({
status
:
11
,
statusText
:
'
Not Accepted
'
,
error
:
'
not_accepted
'
,
message
:
'
This job is already running.
'
,
reason
:
'
this job is already running
'
});
};
/**
* Updates the date of the job with the another one.
* @method update
* @param {object} job The other job.
*/
that
.
update
=
function
(
job
)
{
priv
.
command
.
addCallbacks
(
job
.
getCommand
().
onSuccessDo
()[
0
],
job
.
getCommand
().
onErrorDo
()[
0
]);
priv
.
date
=
new
Date
(
job
.
getDate
().
getTime
());
};
/**
* Executes this job.
* @method execute
*/
that
.
execute
=
function
()
{
if
(
!
that
.
getCommand
().
canBeRetried
())
{
throw
tooMuchTriesJobException
({
job
:
that
,
message
:
'
The job was invoked too much time.
'
});
}
if
(
!
that
.
isReady
())
{
throw
jobNotReadyException
({
job
:
that
,
message
:
'
Can not execute this job.
'
});
}
priv
.
status
=
onGoingStatus
();
priv
.
command
.
onRetryDo
(
function
()
{
var
ms
=
priv
.
command
.
getTried
();
ms
=
ms
*
ms
*
200
;
if
(
ms
>
10000
)
{
ms
=
10000
;
}
that
.
waitForTime
(
ms
);
});
priv
.
command
.
onEndDo
(
function
(
status
)
{
priv
.
status
=
status
;
jobManager
.
terminateJob
(
that
);
});
priv
.
command
.
execute
(
priv
.
storage
);
};
return
that
;
};
/*jslint indent: 2, maxlen: 80, sloppy: true */
/*global announcement: true */
var
announcement
=
function
(
spec
,
my
)
{
var
that
=
{},
callback_a
=
[],
announcer
=
spec
.
announcer
||
{};
spec
=
spec
||
{};
my
=
my
||
{};
// Methods //
that
.
add
=
function
(
callback
)
{
callback_a
.
push
(
callback
);
};
that
.
remove
=
function
(
callback
)
{
var
i
,
tmp_callback_a
=
[];
for
(
i
=
0
;
i
<
callback_a
.
length
;
i
+=
1
)
{
if
(
callback_a
[
i
]
!==
callback
)
{
tmp_callback_a
.
push
(
callback_a
[
i
]);
}
}
callback_a
=
tmp_callback_a
;
};
that
.
register
=
function
()
{
announcer
.
register
(
that
);
};
that
.
unregister
=
function
()
{
announcer
.
unregister
(
that
);
};
that
.
trigger
=
function
(
args
)
{
var
i
;
for
(
i
=
0
;
i
<
callback_a
.
length
;
i
+=
1
)
{
callback_a
[
i
].
apply
(
null
,
args
);
}
};
return
that
;
};
/*jslint indent: 2, maxlen: 80, sloppy: true */
/*global localstorage: true, setInterval: true, clearInterval: true */
var
activityUpdater
=
(
function
(
spec
,
my
)
{
var
that
=
{},
priv
=
{};
spec
=
spec
||
{};
my
=
my
||
{};
priv
.
id
=
spec
.
id
||
0
;
priv
.
interval
=
400
;
priv
.
interval_id
=
null
;
// Methods //
/**
* Update the last activity date in the localStorage.
* @method touch
*/
priv
.
touch
=
function
()
{
localstorage
.
setItem
(
'
jio/id/
'
+
priv
.
id
,
Date
.
now
());
};
/**
* Sets the jio id into the activity.
* @method setId
* @param {number} id The jio id.
*/
that
.
setId
=
function
(
id
)
{
priv
.
id
=
id
;
};
/**
* Sets the interval delay between two updates.
* @method setIntervalDelay
* @param {number} ms In milliseconds
*/
that
.
setIntervalDelay
=
function
(
ms
)
{
priv
.
interval
=
ms
;
};
/**
* Gets the interval delay.
* @method getIntervalDelay
* @return {number} The interval delay.
*/
that
.
getIntervalDelay
=
function
()
{
return
priv
.
interval
;
};
/**
* Starts the activity updater. It will update regulary the last activity
* date in the localStorage to show to other jio instance that this instance
* is active.
* @method start
*/
that
.
start
=
function
()
{
if
(
!
priv
.
interval_id
)
{
priv
.
touch
();
priv
.
interval_id
=
setInterval
(
function
()
{
priv
.
touch
();
},
priv
.
interval
);
}
};
/**
* Stops the activity updater.
* @method stop
*/
that
.
stop
=
function
()
{
if
(
priv
.
interval_id
!==
null
)
{
clearInterval
(
priv
.
interval_id
);
priv
.
interval_id
=
null
;
}
};
return
that
;
}());
/*jslint indent: 2, maxlen: 80, sloppy: true */
/*global announcement: true */
var
announcer
=
(
function
(
spec
,
my
)
{
var
that
=
{},
announcement_o
=
{};
spec
=
spec
||
{};
my
=
my
||
{};
// Methods //
that
.
register
=
function
(
name
)
{
if
(
!
announcement_o
[
name
])
{
announcement_o
[
name
]
=
announcement
();
}
};
that
.
unregister
=
function
(
name
)
{
if
(
announcement_o
[
name
])
{
delete
announcement_o
[
name
];
}
};
that
.
at
=
function
(
name
)
{
return
announcement_o
[
name
];
};
that
.
on
=
function
(
name
,
callback
)
{
that
.
register
(
name
);
that
.
at
(
name
).
add
(
callback
);
};
that
.
trigger
=
function
(
name
,
args
)
{
that
.
at
(
name
).
trigger
(
args
);
};
return
that
;
}());
/*jslint indent: 2, maxlen: 80, sloppy: true */
var
jobIdHandler
=
(
function
(
spec
)
{
var
that
=
{},
id
=
0
;
spec
=
spec
||
{};
// Methods //
that
.
nextId
=
function
()
{
id
=
id
+
1
;
return
id
;
};
return
that
;
}());
/*jslint indent: 2, maxlen: 80, sloppy: true */
/*global localstorage: true, setInterval: true, clearInterval: true,
command: true, job: true, jobRules: true */
var
jobManager
=
(
function
(
spec
)
{
var
that
=
{},
job_array_name
=
'
jio/job_array
'
,
priv
=
{};
spec
=
spec
||
{};
// Attributes //
priv
.
id
=
spec
.
id
;
priv
.
interval_id
=
null
;
priv
.
interval
=
200
;
priv
.
job_array
=
[];
// Methods //
/**
* Get the job array name in the localStorage
* @method getJobArrayName
* @return {string} The job array name
*/
priv
.
getJobArrayName
=
function
()
{
return
job_array_name
+
'
/
'
+
priv
.
id
;
};
/**
* Returns the job array from the localStorage
* @method getJobArray
* @return {array} The job array.
*/
priv
.
getJobArray
=
function
()
{
return
localstorage
.
getItem
(
priv
.
getJobArrayName
())
||
[];
};
/**
* Does a backup of the job array in the localStorage.
* @method copyJobArrayToLocal
*/
priv
.
copyJobArrayToLocal
=
function
()
{
var
new_a
=
[],
i
;
for
(
i
=
0
;
i
<
priv
.
job_array
.
length
;
i
+=
1
)
{
new_a
.
push
(
priv
.
job_array
[
i
].
serialized
());
}
localstorage
.
setItem
(
priv
.
getJobArrayName
(),
new_a
);
};
/**
* Removes a job from the current job array.
* @method removeJob
* @param {object} job The job object.
*/
priv
.
removeJob
=
function
(
job
)
{
var
i
,
tmp_job_array
=
[];
for
(
i
=
0
;
i
<
priv
.
job_array
.
length
;
i
+=
1
)
{
if
(
priv
.
job_array
[
i
]
!==
job
)
{
tmp_job_array
.
push
(
priv
.
job_array
[
i
]);
}
}
priv
.
job_array
=
tmp_job_array
;
priv
.
copyJobArrayToLocal
();
};
/**
* Sets the job manager id.
* @method setId
* @param {number} id The id.
*/
that
.
setId
=
function
(
id
)
{
priv
.
id
=
id
;
};
/**
* Starts listening to the job array, executing them regulary.
* @method start
*/
that
.
start
=
function
()
{
var
i
;
if
(
priv
.
interval_id
===
null
)
{
priv
.
interval_id
=
setInterval
(
function
()
{
priv
.
restoreOldJio
();
for
(
i
=
0
;
i
<
priv
.
job_array
.
length
;
i
+=
1
)
{
that
.
execute
(
priv
.
job_array
[
i
]);
}
},
priv
.
interval
);
}
};
/**
* Stops listening to the job array.
* @method stop
*/
that
.
stop
=
function
()
{
if
(
priv
.
interval_id
!==
null
)
{
clearInterval
(
priv
.
interval_id
);
priv
.
interval_id
=
null
;
if
(
priv
.
job_array
.
length
===
0
)
{
localstorage
.
removeItem
(
priv
.
getJobArrayName
());
}
}
};
/**
* Try to restore an the inactive older jio instances.
* It will restore the on going or initial jobs from their job array
* and it will add them to this job array.
* @method restoreOldJio
*/
priv
.
restoreOldJio
=
function
()
{
var
i
,
jio_id_a
;
priv
.
lastrestore
=
priv
.
lastrestore
||
0
;
if
(
priv
.
lastrestore
>
(
Date
.
now
())
-
2000
)
{
return
;
}
jio_id_a
=
localstorage
.
getItem
(
'
jio/id_array
'
)
||
[];
for
(
i
=
0
;
i
<
jio_id_a
.
length
;
i
+=
1
)
{
priv
.
restoreOldJioId
(
jio_id_a
[
i
]);
}
priv
.
lastrestore
=
Date
.
now
();
};
/**
* Try to restore an old jio according to an id.
* @method restoreOldJioId
* @param {number} id The jio id.
*/
priv
.
restoreOldJioId
=
function
(
id
)
{
var
jio_date
;
jio_date
=
localstorage
.
getItem
(
'
jio/id/
'
+
id
)
||
0
;
if
(
new
Date
(
jio_date
).
getTime
()
<
(
Date
.
now
()
-
10000
))
{
// 10 sec
priv
.
restoreOldJobFromJioId
(
id
);
priv
.
removeOldJioId
(
id
);
priv
.
removeJobArrayFromJioId
(
id
);
}
};
/**
* Try to restore all jobs from another jio according to an id.
* @method restoreOldJobFromJioId
* @param {number} id The jio id.
*/
priv
.
restoreOldJobFromJioId
=
function
(
id
)
{
var
i
,
command_object
,
jio_job_array
;
jio_job_array
=
localstorage
.
getItem
(
'
jio/job_array/
'
+
id
)
||
[];
for
(
i
=
0
;
i
<
jio_job_array
.
length
;
i
+=
1
)
{
command_object
=
command
(
jio_job_array
[
i
].
command
);
if
(
command_object
.
canBeRestored
())
{
that
.
addJob
(
job
({
storage
:
that
.
storage
(
jio_job_array
[
i
].
storage
),
command
:
command_object
}));
}
}
};
/**
* Removes a jio instance according to an id.
* @method removeOldJioId
* @param {number} id The jio id.
*/
priv
.
removeOldJioId
=
function
(
id
)
{
var
i
,
jio_id_array
,
new_array
=
[];
jio_id_array
=
localstorage
.
getItem
(
'
jio/id_array
'
)
||
[];
for
(
i
=
0
;
i
<
jio_id_array
.
length
;
i
+=
1
)
{
if
(
jio_id_array
[
i
]
!==
id
)
{
new_array
.
push
(
jio_id_array
[
i
]);
}
}
localstorage
.
setItem
(
'
jio/id_array
'
,
new_array
);
localstorage
.
removeItem
(
'
jio/id/
'
+
id
);
};
/**
* Removes a job array from a jio instance according to an id.
* @method removeJobArrayFromJioId
* @param {number} id The jio id.
*/
priv
.
removeJobArrayFromJioId
=
function
(
id
)
{
localstorage
.
removeItem
(
'
jio/job_array/
'
+
id
);
};
/**
* Executes a job.
* @method execute
* @param {object} job The job object.
*/
that
.
execute
=
function
(
job
)
{
try
{
job
.
execute
();
}
catch
(
e
)
{
switch
(
e
.
name
)
{
case
'
jobNotReadyException
'
:
break
;
// do nothing
case
'
tooMuchTriesJobException
'
:
break
;
// do nothing
default
:
throw
e
;
}
}
priv
.
copyJobArrayToLocal
();
};
/**
* Checks if a job exists in the job array according to a job id.
* @method jobIdExists
* @param {number} id The job id.
* @return {boolean} true if exists, else false.
*/
that
.
jobIdExists
=
function
(
id
)
{
var
i
;
for
(
i
=
0
;
i
<
priv
.
job_array
.
length
;
i
+=
1
)
{
if
(
priv
.
job_array
[
i
].
getId
()
===
id
)
{
return
true
;
}
}
return
false
;
};
/**
* Terminate a job. It only remove it from the job array.
* @method terminateJob
* @param {object} job The job object
*/
that
.
terminateJob
=
function
(
job
)
{
priv
.
removeJob
(
job
);
};
/**
* Adds a job to the current job array.
* @method addJob
* @param {object} job The new job.
*/
that
.
addJob
=
function
(
job
)
{
var
result_array
=
that
.
validateJobAccordingToJobList
(
priv
.
job_array
,
job
);
priv
.
appendJob
(
job
,
result_array
);
};
/**
* Generate a result array containing action string to do with the good job.
* @method validateJobAccordingToJobList
* @param {array} job_array A job array.
* @param {object} job The new job to compare with.
* @return {array} A result array.
*/
that
.
validateJobAccordingToJobList
=
function
(
job_array
,
job
)
{
var
i
,
result_array
=
[];
for
(
i
=
0
;
i
<
job_array
.
length
;
i
+=
1
)
{
result_array
.
push
(
jobRules
.
validateJobAccordingToJob
(
job_array
[
i
],
job
));
}
return
result_array
;
};
/**
* It will manage the job in order to know what to do thanks to a result
* array. The new job can be added to the job array, but it can also be
* not accepted. It is this method which can tells jobs to wait for another
* one, to replace one or to eliminate some while browsing.
* @method appendJob
* @param {object} job The job to append.
* @param {array} result_array The result array.
*/
priv
.
appendJob
=
function
(
job
,
result_array
)
{
var
i
;
if
(
priv
.
job_array
.
length
!==
result_array
.
length
)
{
throw
new
RangeError
(
"
Array out of bound
"
);
}
for
(
i
=
0
;
i
<
result_array
.
length
;
i
+=
1
)
{
if
(
result_array
[
i
].
action
===
'
dont accept
'
)
{
return
job
.
notAccepted
();
}
}
for
(
i
=
0
;
i
<
result_array
.
length
;
i
+=
1
)
{
switch
(
result_array
[
i
].
action
)
{
case
'
eliminate
'
:
result_array
[
i
].
job
.
eliminated
();
priv
.
removeJob
(
result_array
[
i
].
job
);
break
;
case
'
update
'
:
result_array
[
i
].
job
.
update
(
job
);
priv
.
copyJobArrayToLocal
();
return
;
case
'
wait
'
:
job
.
waitForJob
(
result_array
[
i
].
job
);
break
;
default
:
break
;
}
}
priv
.
job_array
.
push
(
job
);
priv
.
copyJobArrayToLocal
();
};
that
.
serialized
=
function
()
{
var
a
=
[],
i
,
job_array
=
priv
.
job_array
||
[];
for
(
i
=
0
;
i
<
job_array
.
length
;
i
+=
1
)
{
a
.
push
(
job_array
[
i
].
serialized
());
}
return
a
;
};
return
that
;
}());
/*jslint indent: 2, maxlen: 80, sloppy: true */
var
jobRules
=
(
function
()
{
var
that
=
{},
priv
=
{};
priv
.
compare
=
{};
priv
.
action
=
{};
Object
.
defineProperty
(
that
,
"
eliminate
"
,
{
configurable
:
false
,
enumerable
:
false
,
writable
:
false
,
value
:
function
()
{
return
'
eliminate
'
;
}
});
Object
.
defineProperty
(
that
,
"
update
"
,
{
configurable
:
false
,
enumerable
:
false
,
writable
:
false
,
value
:
function
()
{
return
'
update
'
;
}
});
Object
.
defineProperty
(
that
,
"
dontAccept
"
,
{
configurable
:
false
,
enumerable
:
false
,
writable
:
false
,
value
:
function
()
{
return
'
dont accept
'
;
}
});
Object
.
defineProperty
(
that
,
"
wait
"
,
{
configurable
:
false
,
enumerable
:
false
,
writable
:
false
,
value
:
function
()
{
return
'
wait
'
;
}
});
Object
.
defineProperty
(
that
,
"
ok
"
,
{
configurable
:
false
,
enumerable
:
false
,
writable
:
false
,
value
:
function
()
{
return
'
none
'
;
}
});
that
.
default_action
=
that
.
ok
;
that
.
default_compare
=
function
(
job1
,
job2
)
{
return
job1
.
getId
()
!==
job2
.
getId
()
&&
job1
.
getStatus
().
getLabel
()
!==
"
done
"
&&
job1
.
getStatus
().
getLabel
()
!==
"
fail
"
&&
JSON
.
stringify
(
job1
.
getStorage
().
serialized
())
===
JSON
.
stringify
(
job2
.
getStorage
().
serialized
());
};
// Compare Functions //
Object
.
defineProperty
(
that
,
"
sameDocumentId
"
,
{
configurable
:
false
,
enumerable
:
false
,
writable
:
false
,
value
:
function
(
job1
,
job2
)
{
return
job1
.
getCommand
().
getDocId
()
===
job2
.
getCommand
().
getDocId
();
}
});
Object
.
defineProperty
(
that
,
"
sameRevision
"
,
{
configurable
:
false
,
enumerable
:
false
,
writable
:
false
,
value
:
function
(
job1
,
job2
)
{
return
job1
.
getCommand
().
getDocInfo
(
"
_rev
"
)
===
job2
.
getCommand
().
getDocInfo
(
"
_rev
"
);
}
});
Object
.
defineProperty
(
that
,
"
sameAttachmentId
"
,
{
configurable
:
false
,
enumerable
:
false
,
writable
:
false
,
value
:
function
(
job1
,
job2
)
{
return
job1
.
getCommand
().
getAttachmentId
()
===
job2
.
getCommand
().
getAttachmentId
();
}
});
Object
.
defineProperty
(
that
,
"
sameDocument
"
,
{
configurable
:
false
,
enumerable
:
false
,
writable
:
false
,
value
:
function
(
job1
,
job2
)
{
return
JSON
.
stringify
(
job1
.
getCommand
().
cloneDoc
())
===
JSON
.
stringify
(
job2
.
getCommand
().
cloneDoc
());
}
});
Object
.
defineProperty
(
that
,
"
sameOption
"
,
{
configurable
:
false
,
enumerable
:
false
,
writable
:
false
,
value
:
function
(
job1
,
job2
)
{
return
JSON
.
stringify
(
job1
.
getCommand
().
cloneOption
())
===
JSON
.
stringify
(
job2
.
getCommand
().
cloneOption
());
}
});
// Methods //
/**
* Returns an action according the jobs given in parameters.
* @method getAction
* @param {object} job1 The already existant job.
* @param {object} job2 The job to compare with.
* @return {string} An action string.
*/
priv
.
getAction
=
function
(
job1
,
job2
)
{
var
method1
,
method2
,
tmp
=
priv
.
action
,
i
,
j
,
condition_list
=
[],
res
;
method1
=
job1
.
getCommand
().
getLabel
();
method2
=
job2
.
getCommand
().
getLabel
();
tmp
=
tmp
[
method1
]
=
tmp
[
method1
]
||
{};
tmp
=
tmp
[
method2
]
=
tmp
[
method2
]
||
[];
for
(
i
=
0
;
i
<
tmp
.
length
;
i
+=
1
)
{
// browsing all method1 method2 rules
condition_list
=
tmp
[
i
].
condition_list
;
res
=
true
;
for
(
j
=
0
;
j
<
condition_list
.
length
;
j
+=
1
)
{
// test all the rule's conditions
if
(
!
condition_list
[
j
](
job1
,
job2
))
{
res
=
false
;
break
;
}
}
if
(
res
)
{
// if all respects condition list, then action
return
tmp
[
i
].
rule
();
}
}
return
that
.
default_action
();
};
/**
* Checks if the two jobs are comparable.
* @method canCompare
* @param {object} job1 The already existant job.
* @param {object} job2 The job to compare with.
* @return {boolean} true if comparable, else false.
*/
priv
.
canCompare
=
function
(
job1
,
job2
)
{
var
method1
,
method2
;
method1
=
job1
.
getCommand
().
getLabel
();
method2
=
job2
.
getCommand
().
getLabel
();
if
(
priv
.
compare
[
method1
]
&&
priv
.
compare
[
method1
][
method2
])
{
return
priv
.
compare
[
method1
][
method2
](
job1
,
job2
);
}
return
that
.
default_compare
(
job1
,
job2
);
};
/**
* Returns an action string to show what to do if we want to add a job.
* @method validateJobAccordingToJob
* @param {object} job1 The current job.
* @param {object} job2 The new job.
* @return {string} The action string.
*/
Object
.
defineProperty
(
that
,
"
validateJobAccordingToJob
"
,
{
configurable
:
false
,
enumerable
:
false
,
writable
:
false
,
value
:
function
(
job1
,
job2
)
{
if
(
priv
.
canCompare
(
job1
,
job2
))
{
return
{
action
:
priv
.
getAction
(
job1
,
job2
),
job
:
job1
};
}
return
{
action
:
that
.
default_action
(
job1
,
job2
),
job
:
job1
};
}
});
/**
* Adds a rule the action rules.
* @method addActionRule
* @param {string} method1 The action label from the current job.
* @param {boolean} ongoing Is this action is on going or not?
* @param {string} method2 The action label from the new job.
* @param {function} rule The rule that return an action string.
*/
Object
.
defineProperty
(
that
,
"
addActionRule
"
,
{
configurable
:
false
,
enumerable
:
false
,
writable
:
false
,
value
:
function
(
method1
,
method2
,
condition_list
,
rule
)
{
var
tmp
=
priv
.
action
;
tmp
=
tmp
[
method1
]
=
tmp
[
method1
]
||
{};
tmp
=
tmp
[
method2
]
=
tmp
[
method2
]
||
[];
tmp
.
push
({
"
condition_list
"
:
condition_list
,
"
rule
"
:
rule
});
}
});
/**
* Adds a rule the compare rules.
* @method addCompareRule
* @param {string} method1 The action label from the current job.
* @param {string} method2 The action label from the new job.
* @param {function} rule The rule that return a boolean
* - true if job1 and job2 can be compared, else false.
*/
Object
.
defineProperty
(
that
,
"
addCompareRule
"
,
{
configurable
:
false
,
enumerable
:
false
,
writable
:
false
,
value
:
function
(
method1
,
method2
,
rule
)
{
priv
.
compare
[
method1
]
=
priv
.
compare
[
method1
]
||
{};
priv
.
compare
[
method1
][
method2
]
=
rule
;
}
});
////////////////////////////////////////////////////////////////////////////
// Adding some rules
/*
Rules
original job |job to add |condition |action
post post same doc update
" " same docid, same rev wait
" put " "
" putA " "
" remove " "
" removeA " "
put post same docid, same rev wait
" put same doc update
" " same docid, same rev wait
" putA " "
" remove " "
" removeA " "
putA post same docid, same rev wait
" put " "
" putA same doc update
" " same docid, same rev, same attmt wait
" remove same docid, same rev "
" removeA same docid, same rev, same attmt "
remove post same docid, same rev wait
" put " "
" putA " "
" remove " update
" removeA " wait
removeA post same docid, same rev wait
" put " "
" putA same docid, same rev, same attmt "
" remove same docid, same rev "
" removeA same doc update
" removeA same docid, same rev, same attmt wait
get get same doc, same options update
getA getA same doc, same options update
allDocs allDocs same doc, same options update
*/
that
.
addActionRule
(
"
post
"
,
"
post
"
,
[
that
.
sameDocument
],
that
.
update
);
that
.
addActionRule
(
"
post
"
,
"
post
"
,
[
that
.
sameDocumentId
,
that
.
sameRevision
],
that
.
wait
);
that
.
addActionRule
(
"
post
"
,
"
put
"
,
[
that
.
sameDocumentId
,
that
.
sameRevision
],
that
.
wait
);
that
.
addActionRule
(
"
post
"
,
"
putAttachment
"
,
[
that
.
sameDocumentId
,
that
.
sameRevision
],
that
.
wait
);
that
.
addActionRule
(
"
post
"
,
"
remove
"
,
[
that
.
sameDocumentId
,
that
.
sameRevision
],
that
.
wait
);
that
.
addActionRule
(
"
post
"
,
"
removeAttachment
"
,
[
that
.
sameDocumentId
,
that
.
sameRevision
],
that
.
wait
);
that
.
addActionRule
(
"
put
"
,
"
post
"
,
[
that
.
sameDocumentId
,
that
.
sameRevision
],
that
.
wait
);
that
.
addActionRule
(
"
put
"
,
"
put
"
,
[
that
.
sameDocument
],
that
.
update
);
that
.
addActionRule
(
"
put
"
,
"
put
"
,
[
that
.
sameDocumentId
,
that
.
sameRevision
],
that
.
wait
);
that
.
addActionRule
(
"
put
"
,
"
putAttachment
"
,
[
that
.
sameDocumentId
,
that
.
sameRevision
],
that
.
wait
);
that
.
addActionRule
(
"
put
"
,
"
remove
"
,
[
that
.
sameDocumentId
,
that
.
sameRevision
],
that
.
wait
);
that
.
addActionRule
(
"
put
"
,
"
removeAttachment
"
,
[
that
.
sameDocumentId
,
that
.
sameRevision
],
that
.
wait
);
that
.
addActionRule
(
"
putAttachment
"
,
"
post
"
,
[
that
.
sameDocumentId
,
that
.
sameRevision
],
that
.
wait
);
that
.
addActionRule
(
"
putAttachment
"
,
"
put
"
,
[
that
.
sameDocumentId
,
that
.
sameRevision
],
that
.
wait
);
that
.
addActionRule
(
"
putAttachment
"
,
"
putAttachment
"
,
[
that
.
sameDocument
],
that
.
update
);
that
.
addActionRule
(
"
putAttachment
"
,
"
putAttachment
"
,
[
that
.
sameDocumentId
,
that
.
sameRevision
,
that
.
sameAttachmentId
],
that
.
wait
);
that
.
addActionRule
(
"
putAttachment
"
,
"
remove
"
,
[
that
.
sameDocumentId
,
that
.
sameRevision
],
that
.
wait
);
that
.
addActionRule
(
"
putAttachment
"
,
"
removeAttachment
"
,
[
that
.
sameDocumentId
,
that
.
sameRevision
,
that
.
sameAttachmentId
],
that
.
wait
);
that
.
addActionRule
(
"
remove
"
,
"
post
"
,
[
that
.
sameDocumentId
,
that
.
sameRevision
],
that
.
wait
);
that
.
addActionRule
(
"
remove
"
,
"
put
"
,
[
that
.
sameDocumentId
,
that
.
sameRevision
],
that
.
wait
);
that
.
addActionRule
(
"
remove
"
,
"
putAttachment
"
,
[
that
.
sameDocumentId
,
that
.
sameRevision
],
that
.
wait
);
that
.
addActionRule
(
"
remove
"
,
"
remove
"
,
[
that
.
sameDocumentId
,
that
.
sameRevision
],
that
.
update
);
that
.
addActionRule
(
"
remove
"
,
"
removeAttachment
"
,
[
that
.
sameDocumentId
,
that
.
sameRevision
],
that
.
wait
);
that
.
addActionRule
(
"
removeAttachment
"
,
"
post
"
,
[
that
.
sameDocumentId
,
that
.
sameRevision
],
that
.
wait
);
that
.
addActionRule
(
"
removeAttachment
"
,
"
put
"
,
[
that
.
sameDocumentId
,
that
.
sameRevision
],
that
.
wait
);
that
.
addActionRule
(
"
removeAttachment
"
,
"
putAttachment
"
,
[
that
.
sameDocumentId
,
that
.
sameRevision
,
that
.
sameAttachmentId
],
that
.
wait
);
that
.
addActionRule
(
"
removeAttachment
"
,
"
remove
"
,
[
that
.
sameDocumentId
,
that
.
sameRevision
],
that
.
wait
);
that
.
addActionRule
(
"
removeAttachment
"
,
"
removeAttachment
"
,
[
that
.
sameDocument
],
that
.
update
);
that
.
addActionRule
(
"
removeAttachment
"
,
"
removeAttachment
"
,
[
that
.
sameDocumentId
,
that
.
sameRevision
,
that
.
sameAttachmentId
],
that
.
wait
);
that
.
addActionRule
(
"
get
"
,
"
get
"
,
[
that
.
sameDocument
,
that
.
sameOption
],
that
.
update
);
that
.
addActionRule
(
"
getAttachment
"
,
"
getAttachment
"
,
[
that
.
sameDocument
,
that
.
sameOption
],
that
.
update
);
that
.
addActionRule
(
"
allDocs
"
,
"
allDocs
"
,
[
that
.
sameDocument
,
that
.
sameOption
],
that
.
update
);
// end adding rules
////////////////////////////////////////////////////////////////////////////
return
that
;
}());
/*jslint indent: 2, maxlen: 80, sloppy: true */
/*global spec: true, localstorage: true,
activityUpdater: true, jobManager: true, storage: true,
storage_type_object: true, invalidStorageType: true, jobRules: true,
job: true, postCommand: true, putCommand: true, getCommand:true,
allDocsCommand: true, putAttachmentCommand: true,
getAttachmentCommand: true, removeAttachmentCommand: true,
removeCommand: true, checkCommand: true, repairCommand: true */
// Class jio
var
that
=
{},
priv
=
{},
jio_id_array_name
=
'
jio/id_array
'
;
spec
=
spec
||
{};
// Attributes //
priv
.
id
=
null
;
priv
.
storage_spec
=
spec
;
priv
.
environments
=
{};
// initialize //
priv
.
init
=
function
()
{
// Initialize the jio id and add the new id to the list
if
(
priv
.
id
===
null
)
{
var
i
,
jio_id_a
=
localstorage
.
getItem
(
jio_id_array_name
)
||
[];
priv
.
id
=
1
;
for
(
i
=
0
;
i
<
jio_id_a
.
length
;
i
+=
1
)
{
if
(
jio_id_a
[
i
]
>=
priv
.
id
)
{
priv
.
id
=
jio_id_a
[
i
]
+
1
;
}
}
jio_id_a
.
push
(
priv
.
id
);
localstorage
.
setItem
(
jio_id_array_name
,
jio_id_a
);
activityUpdater
.
setId
(
priv
.
id
);
jobManager
.
setId
(
priv
.
id
);
}
};
// Methods //
/**
* Returns a storage from a storage description.
* @method storage
* @param {object} spec The specifications.
* @param {object} my The protected object.
* @param {string} forcetype Force storage type
* @return {object} The storage object.
*/
Object
.
defineProperty
(
that
,
"
storage
"
,
{
configurable
:
false
,
enumerable
:
false
,
writable
:
false
,
value
:
function
(
spec
,
my
,
forcetype
)
{
var
spec_str
,
type
;
spec
=
spec
||
{};
my
=
my
||
{};
my
.
basicStorage
=
storage
;
spec_str
=
JSON
.
stringify
(
spec
);
// environment initialization
priv
.
environments
[
spec_str
]
=
priv
.
environments
[
spec_str
]
||
{};
my
.
env
=
priv
.
environments
[
spec_str
];
my
.
storage
=
that
.
storage
;
// NOTE : or proxy storage
type
=
forcetype
||
spec
.
type
||
'
base
'
;
if
(
type
===
'
base
'
)
{
return
storage
(
spec
,
my
);
}
if
(
!
storage_type_object
[
type
])
{
throw
invalidStorageType
({
"
type
"
:
type
,
"
message
"
:
"
Storage does not exists.
"
});
}
return
storage_type_object
[
type
](
spec
,
my
);
}
});
jobManager
.
storage
=
that
.
storage
;
Object
.
defineProperty
(
that
,
"
start
"
,
{
configurable
:
false
,
enumerable
:
false
,
writable
:
false
,
value
:
function
()
{
priv
.
init
();
activityUpdater
.
start
();
jobManager
.
start
();
}
});
Object
.
defineProperty
(
that
,
"
stop
"
,
{
configurable
:
false
,
enumerable
:
false
,
writable
:
false
,
value
:
function
()
{
jobManager
.
stop
();
}
});
Object
.
defineProperty
(
that
,
"
close
"
,
{
configurable
:
false
,
enumerable
:
false
,
writable
:
false
,
value
:
function
()
{
activityUpdater
.
stop
();
jobManager
.
stop
();
priv
.
id
=
null
;
}
});
/**
* Returns the jio id.
* @method getId
* @return {number} The jio id.
*/
Object
.
defineProperty
(
that
,
"
getId
"
,
{
configurable
:
false
,
enumerable
:
false
,
writable
:
false
,
value
:
function
()
{
return
priv
.
id
;
}
});
/**
* Returns the jio job rules object used by the job manager.
* @method getJobRules
* @return {object} The job rules object
*/
Object
.
defineProperty
(
that
,
"
getJobRules
"
,
{
configurable
:
false
,
enumerable
:
false
,
writable
:
false
,
value
:
function
()
{
return
jobRules
;
}
});
/**
* Checks if the storage description is valid or not.
* @method validateStorageDescription
* @param {object} description The description object.
* @return {boolean} true if ok, else false.
*/
Object
.
defineProperty
(
that
,
"
validateStorageDescription
"
,
{
configurable
:
false
,
enumerable
:
false
,
writable
:
false
,
value
:
function
(
description
)
{
return
that
.
storage
(
description
).
isValid
();
}
});
Object
.
defineProperty
(
that
,
"
getJobArray
"
,
{
configurable
:
false
,
enumerable
:
false
,
writable
:
false
,
value
:
function
()
{
return
jobManager
.
serialized
();
}
});
priv
.
makeCallbacks
=
function
(
param
,
callback1
,
callback2
)
{
param
.
callback
=
function
(
err
,
val
)
{
if
(
err
)
{
param
.
error
(
err
);
}
else
{
param
.
success
(
val
);
}
};
param
.
success
=
function
(
val
)
{
param
.
callback
(
undefined
,
val
);
};
param
.
error
=
function
(
err
)
{
param
.
callback
(
err
,
undefined
);
};
if
(
typeof
callback1
===
'
function
'
)
{
if
(
typeof
callback2
===
'
function
'
)
{
param
.
success
=
callback1
;
param
.
error
=
callback2
;
}
else
{
param
.
callback
=
callback1
;
}
}
else
{
param
.
callback
=
function
()
{};
}
};
priv
.
parametersToObject
=
function
(
list
,
default_options
)
{
var
k
,
i
=
0
,
callbacks
=
[],
param
=
{
"
options
"
:
{}};
for
(
i
=
0
;
i
<
list
.
length
;
i
+=
1
)
{
if
(
typeof
list
[
i
]
===
'
object
'
)
{
// this is the option
param
.
options
=
list
[
i
];
for
(
k
in
default_options
)
{
if
((
typeof
default_options
[
k
])
!==
(
typeof
list
[
i
][
k
]))
{
param
.
options
[
k
]
=
default_options
[
k
];
}
}
}
if
(
typeof
list
[
i
]
===
'
function
'
)
{
// this is a callback
callbacks
.
push
(
list
[
i
]);
}
}
priv
.
makeCallbacks
(
param
,
callbacks
[
0
],
callbacks
[
1
]);
return
param
;
};
priv
.
addJob
=
function
(
commandCreator
,
spec
)
{
jobManager
.
addJob
(
job
({
"
storage
"
:
that
.
storage
(
priv
.
storage_spec
),
"
command
"
:
commandCreator
(
spec
)
}));
};
/**
* Post a document.
* @method post
* @param {object} doc The document object. Contains at least:
* - {string} _id The document id (optional)
* For revision managing: choose at most one of the following informations:
* - {string} _rev The revision we want to update
* - {string} _revs_info The revision information we want the document to have
* - {string} _revs The revision history we want the document to have
* @param {object} options (optional) Contains some options:
* - {number} max_retry The number max of retries, 0 = infinity.
* @param {function} callback (optional) The callback(err,response).
* @param {function} error (optional) The callback on error, if this
* callback is given in parameter, "callback" is changed as "success",
* called on success.
*/
Object
.
defineProperty
(
that
,
"
post
"
,
{
configurable
:
false
,
enumerable
:
false
,
writable
:
false
,
value
:
function
(
doc
,
options
,
success
,
error
)
{
var
param
=
priv
.
parametersToObject
(
[
options
,
success
,
error
],
{
max_retry
:
0
}
);
priv
.
addJob
(
postCommand
,
{
doc
:
doc
,
options
:
param
.
options
,
callbacks
:
{
success
:
param
.
success
,
error
:
param
.
error
}
});
}
});
/**
* Put a document.
* @method put
* @param {object} doc The document object. Contains at least:
* - {string} _id The document id
* For revision managing: choose at most one of the following informations:
* - {string} _rev The revision we want to update
* - {string} _revs_info The revision information we want the document to have
* - {string} _revs The revision history we want the document to have
* @param {object} options (optional) Contains some options:
* - {number} max_retry The number max of retries, 0 = infinity.
* @param {function} callback (optional) The callback(err,response).
* @param {function} error (optional) The callback on error, if this
* callback is given in parameter, "callback" is changed as "success",
* called on success.
*/
Object
.
defineProperty
(
that
,
"
put
"
,
{
configurable
:
false
,
enumerable
:
false
,
writable
:
false
,
value
:
function
(
doc
,
options
,
success
,
error
)
{
var
param
=
priv
.
parametersToObject
(
[
options
,
success
,
error
],
{
max_retry
:
0
}
);
priv
.
addJob
(
putCommand
,
{
doc
:
doc
,
options
:
param
.
options
,
callbacks
:
{
success
:
param
.
success
,
error
:
param
.
error
}
});
}
});
/**
* Get a document.
* @method get
* @param {string} doc The document object. Contains at least:
* - {string} _id The document id
* For revision managing:
* - {string} _rev The revision we want to get. (optional)
* @param {object} options (optional) Contains some options:
* - {number} max_retry The number max of retries, 0 = infinity.
* For revision managing:
* - {boolean} revs Include revision history of the document.
* - {boolean} revs_info Include list of revisions, and their availability.
* - {boolean} conflicts Include a list of conflicts.
* @param {function} callback (optional) The callback(err,response).
* @param {function} error (optional) The callback on error, if this
* callback is given in parameter, "callback" is changed as "success",
* called on success.
*/
Object
.
defineProperty
(
that
,
"
get
"
,
{
configurable
:
false
,
enumerable
:
false
,
writable
:
false
,
value
:
function
(
doc
,
options
,
success
,
error
)
{
var
param
=
priv
.
parametersToObject
(
[
options
,
success
,
error
],
{
max_retry
:
3
}
);
priv
.
addJob
(
getCommand
,
{
doc
:
doc
,
options
:
param
.
options
,
callbacks
:
{
success
:
param
.
success
,
error
:
param
.
error
}
});
}
});
/**
* Remove a document.
* @method remove
* @param {object} doc The document object. Contains at least:
* - {string} _id The document id
* For revision managing:
* - {string} _rev The revision we want to remove
* @param {object} options (optional) Contains some options:
* - {number} max_retry The number max of retries, 0 = infinity.
* @param {function} callback (optional) The callback(err,response).
* @param {function} error (optional) The callback on error, if this
* callback is given in parameter, "callback" is changed as "success",
* called on success.
*/
Object
.
defineProperty
(
that
,
"
remove
"
,
{
configurable
:
false
,
enumerable
:
false
,
writable
:
false
,
value
:
function
(
doc
,
options
,
success
,
callback
)
{
var
param
=
priv
.
parametersToObject
(
[
options
,
success
,
callback
],
{
max_retry
:
0
}
);
priv
.
addJob
(
removeCommand
,
{
doc
:
doc
,
options
:
param
.
options
,
callbacks
:
{
success
:
param
.
success
,
error
:
param
.
error
}
});
}
});
/**
* Get a list of documents.
* @method allDocs
* @param {object} options (optional) Contains some options:
* - {number} max_retry The number max of retries, 0 = infinity.
* - {boolean} include_docs Include document metadata
* @param {function} callback (optional) The callback(err,response).
* @param {function} error (optional) The callback on error, if this
* callback is given in parameter, "callback" is changed as "success",
* called on success.
*/
Object
.
defineProperty
(
that
,
"
allDocs
"
,
{
configurable
:
false
,
enumerable
:
false
,
writable
:
false
,
value
:
function
(
options
,
success
,
error
)
{
var
param
=
priv
.
parametersToObject
(
[
options
,
success
,
error
],
{
max_retry
:
3
}
);
priv
.
addJob
(
allDocsCommand
,
{
options
:
param
.
options
,
callbacks
:
{
success
:
param
.
success
,
error
:
param
.
error
}
});
}
});
/**
* Get an attachment from a document.
* @method gettAttachment
* @param {object} doc The document object. Contains at least:
* - {string} _id The document id
* - {string} _attachment The attachment id
* For revision managing:
* - {string} _rev The document revision
* @param {object} options (optional) Contains some options:
* - {number} max_retry The number max of retries, 0 = infinity.
* @param {function} callback (optional) The callback(err,respons)
* @param {function} error (optional) The callback on error, if this
* callback is given in parameter, "callback" is changed as "success",
* called on success.
*/
Object
.
defineProperty
(
that
,
"
getAttachment
"
,
{
configurable
:
false
,
enumerable
:
false
,
writable
:
false
,
value
:
function
(
doc
,
options
,
success
,
error
)
{
var
param
=
priv
.
parametersToObject
(
[
options
,
success
,
error
],
{
max_retry
:
3
}
);
priv
.
addJob
(
getAttachmentCommand
,
{
doc
:
doc
,
options
:
param
.
options
,
callbacks
:
{
success
:
param
.
success
,
error
:
param
.
error
}
});
}
});
/**
* Put an attachment to a document.
* @method putAttachment
* @param {object} doc The document object. Contains at least:
* - {string} _id The document id
* - {string} _attachment The attachment id
* - {string} _data The attachment data
* - {string} _mimetype The attachment mimetype
* For revision managing:
* - {string} _rev The document revision
* @param {object} options (optional) Contains some options:
* - {number} max_retry The number max of retries, 0 = infinity.
* @param {function} callback (optional) The callback(err,respons)
* @param {function} error (optional) The callback on error, if this
* callback is given in parameter, "callback" is changed as "success",
* called on success.
*/
Object
.
defineProperty
(
that
,
"
putAttachment
"
,
{
configurable
:
false
,
enumerable
:
false
,
writable
:
false
,
value
:
function
(
doc
,
options
,
success
,
error
)
{
var
param
=
priv
.
parametersToObject
(
[
options
,
success
,
error
],
{
max_retry
:
0
}
);
priv
.
addJob
(
putAttachmentCommand
,
{
doc
:
doc
,
options
:
param
.
options
,
callbacks
:
{
success
:
param
.
success
,
error
:
param
.
error
}
});
}
});
/**
* Put an attachment to a document.
* @method putAttachment
* @param {object} doc The document object. Contains at least:
* - {string} _id The document id
* - {string} _attachment The attachment id
* For revision managing:
* - {string} _rev The document revision
* @param {object} options (optional) Contains some options:
* - {number} max_retry The number max of retries, 0 = infinity.
* @param {function} callback (optional) The callback(err,respons)
* @param {function} error (optional) The callback on error, if this
* callback is given in parameter, "callback" is changed as "success",
* called on success.
*/
Object
.
defineProperty
(
that
,
"
removeAttachment
"
,
{
configurable
:
false
,
enumerable
:
false
,
writable
:
false
,
value
:
function
(
doc
,
options
,
success
,
error
)
{
var
param
=
priv
.
parametersToObject
(
[
options
,
success
,
error
],
{
max_retry
:
0
}
);
priv
.
addJob
(
removeAttachmentCommand
,
{
doc
:
doc
,
options
:
param
.
options
,
callbacks
:
{
success
:
param
.
success
,
error
:
param
.
error
}
});
}
});
/**
* Check a document.
* @method check
* @param {object} doc The document object. Contains at least:
* - {string} _id The document id
* @param {object} options (optional) Contains some options:
* - {number} max_retry The number max of retries, 0 = infinity.
* @param {function} callback (optional) The callback(err,response).
* @param {function} error (optional) The callback on error, if this
* callback is given in parameter, "callback" is changed as "success",
* called on success.
*/
Object
.
defineProperty
(
that
,
"
check
"
,
{
configurable
:
false
,
enumerable
:
false
,
writable
:
false
,
value
:
function
(
doc
,
options
,
success
,
callback
)
{
var
param
=
priv
.
parametersToObject
(
[
options
,
success
,
callback
],
{
max_retry
:
3
}
);
priv
.
addJob
(
checkCommand
,
{
doc
:
doc
,
options
:
param
.
options
,
callbacks
:
{
success
:
param
.
success
,
error
:
param
.
error
}
});
}
});
/**
* Repair a document.
* @method repair
* @param {object} doc The document object. Contains at least:
* - {string} _id The document id
* @param {object} options (optional) Contains some options:
* - {number} max_retry The number max of retries, 0 = infinity.
* @param {function} callback (optional) The callback(err,response).
* @param {function} error (optional) The callback on error, if this
* callback is given in parameter, "callback" is changed as "success",
* called on success.
*/
Object
.
defineProperty
(
that
,
"
repair
"
,
{
configurable
:
false
,
enumerable
:
false
,
writable
:
false
,
value
:
function
(
doc
,
options
,
success
,
callback
)
{
var
param
=
priv
.
parametersToObject
(
[
options
,
success
,
callback
],
{
max_retry
:
3
}
);
priv
.
addJob
(
repairCommand
,
{
doc
:
doc
,
options
:
param
.
options
,
callbacks
:
{
success
:
param
.
success
,
error
:
param
.
error
}
});
}
});
return
that
;
};
// End Class jio
/*jslint indent: 2, maxlen: 80, sloppy: true */
/*global exports, jio, invalidStorageType */
var
storage_type_object
=
{
// -> 'key':constructorFunction
'
base
'
:
function
()
{
// overriden by jio
return
undefined
;
}
};
/**
* Creates a new jio instance.
* @method newJio
* @param {object} spec The storage description
* @return {object} The new Jio instance.
*/
Object
.
defineProperty
(
exports
,
"
newJio
"
,
{
configurable
:
false
,
enumerable
:
true
,
writable
:
false
,
value
:
function
(
spec
)
{
var
storage
=
spec
,
instance
=
null
;
if
(
typeof
storage
===
'
string
'
)
{
storage
=
JSON
.
parse
(
storage
);
}
else
{
storage
=
JSON
.
stringify
(
storage
);
if
(
storage
!==
undefined
)
{
storage
=
JSON
.
parse
(
storage
);
}
}
storage
=
storage
||
{
type
:
'
base
'
};
instance
=
jio
(
storage
);
instance
.
start
();
return
instance
;
}
});
/**
* Add a storage type to jio.
* @method addStorageType
* @param {string} type The storage type
* @param {function} constructor The associated constructor
*/
Object
.
defineProperty
(
exports
,
"
addStorageType
"
,
{
configurable
:
false
,
enumerable
:
true
,
writable
:
false
,
value
:
function
(
type
,
constructor
)
{
constructor
=
constructor
||
function
()
{
return
null
;
};
if
(
storage_type_object
[
type
])
{
throw
invalidStorageType
({
type
:
type
,
message
:
'
Already known.
'
});
}
storage_type_object
[
type
]
=
constructor
;
}
});
}));
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