Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
jio
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Stefane Fermigier
jio
Commits
d2c42f76
Commit
d2c42f76
authored
Jan 30, 2013
by
Sebastien Robin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
for convenience, add the full jio.js which is built with the Makefile
parent
207db24a
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
3410 additions
and
0 deletions
+3410
-0
complex_queries.js
complex_queries.js
+901
-0
jio.js
jio.js
+2509
-0
No files found.
complex_queries.js
0 → 100644
View file @
d2c42f76
(
function
(
scope
)
{
"
use strict
"
;
Object
.
defineProperty
(
scope
,
"
ComplexQueries
"
,
{
configurable
:
false
,
enumerable
:
false
,
writable
:
false
,
value
:
{}
});
Object
.
defineProperty
(
scope
.
ComplexQueries
,
"
parse
"
,
{
configurable
:
false
,
enumerable
:
false
,
writable
:
false
,
value
:
function
(
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
_dbg_withtrace
=
false
;
var
_dbg_string
=
new
String
();
function
__dbg_print
(
text
)
{
_dbg_string
+=
text
+
"
\n
"
;
}
function
__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
__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
=
__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
(
_dbg_withtrace
&&
sstack
.
length
>
0
)
{
__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
(
_dbg_withtrace
)
__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
(
_dbg_withtrace
)
__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
=
__lex
(
info
);
}
if
(
act
==
25
)
{
if
(
_dbg_withtrace
)
__dbg_print
(
"
\t
Error recovery failed, terminating parse process...
"
);
break
;
}
if
(
_dbg_withtrace
)
__dbg_print
(
"
\t
Error recovery succeeded, continuing
"
);
}
/*
if( act == 25 )
break;
*/
//Shift
if
(
act
>
0
)
{
if
(
_dbg_withtrace
)
__dbg_print
(
"
Shifting symbol:
"
+
labels
[
la
]
+
"
(
"
+
info
.
att
+
"
)
"
);
sstack
.
push
(
act
);
vstack
.
push
(
info
.
att
);
la
=
__lex
(
info
);
if
(
_dbg_withtrace
)
__dbg_print
(
"
\t
New lookahead symbol:
"
+
labels
[
la
]
+
"
(
"
+
info
.
att
+
"
)
"
);
}
//Reduce
else
{
act
*=
-
1
;
if
(
_dbg_withtrace
)
__dbg_print
(
"
Reducing by producution:
"
+
act
);
rval
=
void
(
0
);
if
(
_dbg_withtrace
)
__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
:
{
simpleQuerySetId
(
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
(
_dbg_withtrace
)
__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
(
_dbg_withtrace
)
__dbg_print
(
"
\t
Pushing non-terminal
"
+
labels
[
pop_tab
[
act
][
0
]
]
);
sstack
.
push
(
go
);
vstack
.
push
(
rval
);
}
if
(
_dbg_withtrace
)
{
alert
(
_dbg_string
);
_dbg_string
=
new
String
();
}
}
if
(
_dbg_withtrace
)
{
__dbg_print
(
"
\n
Parse complete.
"
);
alert
(
_dbg_string
);
}
return
err_cnt
;
}
var
arrayExtend
=
function
()
{
var
j
,
i
,
newlist
=
[],
listoflists
=
arguments
;
for
(
j
=
0
;
j
<
listoflists
.
length
;
++
j
)
{
for
(
i
=
0
;
i
<
listoflists
[
j
].
length
;
++
i
)
{
newlist
.
push
(
listoflists
[
j
][
i
]);
}
}
return
newlist
;
};
var
mkSimpleQuery
=
function
(
id
,
value
,
operator
)
{
return
{
type
:
'
simple
'
,
operator
:
'
=
'
,
id
:
id
,
value
:
value
};
};
var
mkNotQuery
=
function
(
query
)
{
if
(
query
.
operator
===
'
NOT
'
)
{
return
query
.
query_list
[
0
];
}
return
{
type
:
'
complex
'
,
operator
:
'
NOT
'
,
query_list
:[
query
]};
};
var
mkComplexQuery
=
function
(
operator
,
query_list
)
{
var
i
,
query_list2
=
[];
for
(
i
=
0
;
i
<
query_list
.
length
;
++
i
)
{
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
};
};
var
simpleQuerySetId
=
function
(
query
,
id
)
{
var
i
;
if
(
query
.
type
===
'
complex
'
)
{
for
(
i
=
0
;
i
<
query
.
query_list
.
length
;
++
i
)
{
simpleQuerySetId
(
query
.
query_list
[
i
],
id
);
}
return
true
;
}
if
(
query
.
type
===
'
simple
'
&&
!
query
.
id
)
{
query
.
id
=
id
;
return
true
;
}
return
false
;
};
var
error_offsets
=
[];
var
error_lookaheads
=
[];
var
error_count
=
0
;
var
result
;
if
(
(
error_count
=
__parse
(
string
,
error_offsets
,
error_lookaheads
)
)
>
0
)
{
var
i
;
for
(
i
=
0
;
i
<
error_count
;
++
i
)
{
throw
new
Error
(
"
Parse error near
\"
"
+
string
.
substr
(
error_offsets
[
i
]
)
+
"
\"
, expecting
\"
"
+
error_lookaheads
[
i
].
join
()
+
"
\"
"
);
}
}
return
result
;
}
});
Object
.
defineProperty
(
scope
.
ComplexQueries
,
"
serialize
"
,{
configurable
:
false
,
enumerable
:
false
,
writable
:
false
,
value
:
function
(
query
){
var
str_list
=
[],
i
;
if
(
query
.
type
===
'
complex
'
)
{
str_list
.
push
(
'
(
'
);
for
(
i
=
0
;
i
<
query
.
query_list
.
length
;
++
i
)
{
str_list
.
push
(
scope
.
ComplexQueries
.
serialize
(
query
.
query_list
[
i
])
);
str_list
.
push
(
query
.
operator
);
}
str_list
.
length
--
;
str_list
.
push
(
'
)
'
);
return
str_list
.
join
(
'
'
);
}
else
if
(
query
.
type
===
'
simple
'
)
{
return
query
.
id
+
(
query
.
id
?
'
:
'
:
''
)
+
query
.
operator
+
'
"
'
+
query
.
value
+
'
"
'
;
}
return
query
;
}
});
Object
.
defineProperty
(
scope
.
ComplexQueries
,
"
query
"
,{
configurable
:
false
,
enumerable
:
false
,
writable
:
false
,
value
:
function
(
query
,
object_list
)
{
var
wildcard_character
=
typeof
query
.
wildcard_character
===
'
string
'
?
query
.
wildcard_character
:
'
%
'
,
operator_actions
=
{
'
=
'
:
function
(
value1
,
value2
)
{
value1
=
''
+
value1
;
return
value1
.
match
(
convertToRegexp
(
value2
,
wildcard_character
))
||
false
&&
true
;
},
'
!=
'
:
function
(
value1
,
value2
)
{
value1
=
''
+
value1
;
return
!
(
value1
.
match
(
convertToRegexp
(
value2
,
wildcard_character
)));
},
'
<
'
:
function
(
value1
,
value2
)
{
return
value1
<
value2
;
},
'
<=
'
:
function
(
value1
,
value2
)
{
return
value1
<=
value2
;
},
'
>
'
:
function
(
value1
,
value2
)
{
return
value1
>
value2
;
},
'
>=
'
:
function
(
value1
,
value2
)
{
return
value1
>=
value2
;
},
'
AND
'
:
function
(
item
,
query_list
)
{
var
i
;
for
(
i
=
0
;
i
<
query_list
.
length
;
++
i
)
{
if
(
!
itemMatchesQuery
(
item
,
query_list
[
i
]))
{
return
false
;
}
}
return
true
;
},
'
OR
'
:
function
(
item
,
query_list
)
{
var
i
;
for
(
i
=
0
;
i
<
query_list
.
length
;
++
i
)
{
if
(
itemMatchesQuery
(
item
,
query_list
[
i
]))
{
return
true
;
}
}
return
false
;
},
'
NOT
'
:
function
(
item
,
query_list
)
{
return
!
itemMatchesQuery
(
item
,
query_list
[
0
]);
}
},
convertToRegexp
=
function
(
string
)
{
return
subString
(
'
^
'
+
string
.
replace
(
new
RegExp
(
'
([
\\
{
\\
}
\\
(
\\
)
\\
^
\\
$
\\
&
\\
.
\\
*
\\
?
\\\
/
\\
+
\\
|
\\
[
\\
]
\\
-
\\\\
])
'
.
replace
(
wildcard_character
?
'
\\
'
+
wildcard_character
:
undefined
,
''
),
'
g
'
),
'
\\
$1
'
)
+
'
$
'
,(
wildcard_character
||
undefined
),
'
.*
'
);
},
subString
=
function
(
string
,
substring
,
newsubstring
)
{
var
res
=
''
,
i
=
0
;
if
(
substring
===
undefined
)
{
return
string
;
}
while
(
1
)
{
var
tmp
=
string
.
indexOf
(
substring
,
i
);
if
(
tmp
===
-
1
)
{
break
;
}
for
(;
i
<
tmp
;
++
i
)
{
res
+=
string
[
i
];
}
res
+=
newsubstring
;
i
+=
substring
.
length
;
}
for
(;
i
<
string
.
length
;
++
i
)
{
res
+=
string
[
i
];
}
return
res
;
},
itemMatchesQuery
=
function
(
item
,
query_object
)
{
var
i
;
if
(
query_object
.
type
===
'
complex
'
)
{
return
operator_actions
[
query_object
.
operator
](
item
,
query_object
.
query_list
);
}
else
{
if
(
query_object
.
id
)
{
if
(
typeof
item
[
query_object
.
id
]
!==
'
undefined
'
)
{
return
operator_actions
[
query_object
.
operator
](
item
[
query_object
.
id
],
query_object
.
value
);
}
else
{
return
false
;
}
}
else
{
return
true
;
}
}
},
select
=
function
(
list
,
select_list
)
{
var
i
;
if
(
select_list
.
length
===
0
)
{
return
;
}
for
(
i
=
0
;
i
<
list
.
length
;
++
i
)
{
var
list_value
=
{},
k
;
for
(
k
=
0
;
k
<
select_list
.
length
;
++
k
)
{
list_value
[
select_list
[
k
]]
=
list
[
i
][
select_list
[
k
]];
}
list
[
i
]
=
list_value
;
}
},
sortFunction
=
function
(
key
,
asc
)
{
if
(
asc
===
'
descending
'
)
{
return
function
(
a
,
b
)
{
return
a
[
key
]
<
b
[
key
]
?
1
:
a
[
key
]
>
b
[
key
]
?
-
1
:
0
;
};
}
return
function
(
a
,
b
)
{
return
a
[
key
]
>
b
[
key
]
?
1
:
a
[
key
]
<
b
[
key
]
?
-
1
:
0
;
};
},
mergeList
=
function
(
list
,
list_to_merge
,
index
)
{
var
i
,
j
;
for
(
i
=
index
,
j
=
0
;
i
<
list_to_merge
.
length
+
index
;
++
i
,
++
j
)
{
list
[
i
]
=
list_to_merge
[
j
];
}
},
sort
=
function
(
list
,
sort_list
)
{
var
i
,
tmp
,
key
,
asc
,
sortAndMerge
=
function
()
{
sort
(
tmp
,
sort_list
.
slice
(
1
));
mergeList
(
list
,
tmp
,
i
-
tmp
.
length
);
tmp
=
[
list
[
i
]];
};
if
(
list
.
length
<
2
)
{
return
;
}
if
(
sort_list
.
length
===
0
)
{
return
;
}
key
=
sort_list
[
0
][
0
];
asc
=
sort_list
[
0
][
1
];
list
.
sort
(
sortFunction
(
key
,
asc
));
tmp
=
[
list
[
0
]];
for
(
i
=
1
;
i
<
list
.
length
;
++
i
)
{
if
(
tmp
[
0
][
key
]
===
list
[
i
][
key
])
{
tmp
.
push
(
list
[
i
]);
}
else
{
sortAndMerge
();
}
}
sortAndMerge
();
},
limit
=
function
(
list
,
limit_list
)
{
var
i
;
if
(
typeof
limit_list
[
0
]
!==
'
undefined
'
)
{
if
(
typeof
limit_list
[
1
]
!==
'
undefined
'
)
{
if
(
list
.
length
>
limit_list
[
1
]
+
limit_list
[
0
])
{
list
.
length
=
limit_list
[
1
]
+
limit_list
[
0
];
}
list
.
splice
(
0
,
limit_list
[
0
]);
}
else
{
list
.
length
=
limit_list
[
0
];
}
}
},
////////////////////////////////////////////////////////////
result_list
=
[],
result_list_tmp
=
[],
j
;
object_list
=
object_list
||
[];
for
(
j
=
0
;
j
<
object_list
.
length
;
++
j
)
{
if
(
itemMatchesQuery
(
object_list
[
j
],
scope
.
ComplexQueries
.
parse
(
query
.
query
)
))
{
result_list
.
push
(
object_list
[
j
]);
}
}
if
(
query
.
filter
)
{
select
(
result_list
,
query
.
filter
.
select_list
||
[]);
sort
(
result_list
,
query
.
filter
.
sort_on
||
[]);
limit
(
result_list
,
query
.
filter
.
limit
||
[]);
}
return
result_list
;
}
});
}(
jIO
));
jio.js
0 → 100644
View file @
d2c42f76
(
function
(
scope
,
hex_md5
)
{
"
use strict
"
;
var
localstorage
;
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
)
{
delete
localStorage
[
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
(
pseudo_localStorage
[
item
]);
},
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
.
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
=
{
options
:
option
,
callbacks
:
{
success
:
success
,
error
:
error
}
};
if
(
doc
)
{
if
(
method
===
'
get
'
)
{
command_opt
.
docid
=
doc
;
}
else
{
command_opt
.
doc
=
doc
;
}
}
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, nomen: true */
/*global postCommand: true, putCommand: true, getCommand: true,
removeCommand: true, allDocsCommand: true,
putAttachmentCommand: true, failStatus: true, doneStatus: 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
,
'
putAttachment
'
:
putAttachmentCommand
};
// 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
.
docid
=
spec
.
docid
||
priv
.
doc
.
_id
;
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
()
{
if
(
typeof
priv
.
docid
!==
"
string
"
)
{
return
undefined
;
}
return
priv
.
docid
.
split
(
'
/
'
)[
0
];
};
/**
* Gets the attachment id
* @method getAttachmentId
* @return {string} The attachment id
*/
that
.
getAttachmentId
=
function
()
{
if
(
typeof
priv
.
docid
!==
"
string
"
)
{
return
undefined
;
}
return
priv
.
docid
.
split
(
'
/
'
)[
1
];
};
/**
* Returns the label of the command.
* @method getDoc
* @return {object} The document.
*/
that
.
getDoc
=
function
()
{
return
priv
.
doc
;
};
/**
* 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
.
docid
===
"
string
"
&&
!
priv
.
docid
.
match
(
"
^[^
\
/]+([
\
/][^
\
/]+)?$
"
))
{
that
.
error
({
status
:
21
,
statusText
:
'
Invalid Document Id
'
,
error
:
'
invalid_document_id
'
,
message
:
'
The document id must be like "abc" or "abc/def".
'
,
reason
:
'
The document id is no like "abc" or "abc/def"
'
});
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
)
{
priv
.
on_going
=
false
;
priv
.
success
(
return_value
);
priv
.
end
(
doneStatus
());
};
that
.
retry
=
function
(
return_error
)
{
priv
.
on_going
=
false
;
if
(
that
.
canBeRetried
())
{
priv
.
retry
();
}
else
{
that
.
error
(
return_error
);
}
};
that
.
error
=
function
(
return_error
)
{
priv
.
on_going
=
false
;
priv
.
error
(
return_error
);
priv
.
end
(
failStatus
());
};
that
.
end
=
function
()
{
priv
.
end
(
doneStatus
());
};
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
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
;
}
if
(
typeof
that
.
getAttachmentId
()
===
"
string
"
)
{
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
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
()
{
if
(
that
.
getAttachmentId
()
!==
undefined
)
{
that
.
error
({
"
status
"
:
21
,
"
statusText
"
:
"
Invalid Document Id
"
,
"
error
"
:
"
invalid_document_id
"
,
"
message
"
:
"
The document id contains '/' characters
"
+
"
which are forbidden
"
,
"
reason
"
:
"
Document id contains '/' character(s)
"
});
return
false
;
}
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
;
}
if
(
that
.
getAttachmentId
()
!==
undefined
)
{
that
.
error
({
"
status
"
:
21
,
"
statusText
"
:
"
Invalid Document Id
"
,
"
error
"
:
"
invalid_document_id
"
,
"
message
"
:
"
The document id contains '/' characters
"
+
"
which are forbidden
"
,
"
reason
"
:
"
Document id contains '/' character(s)
"
});
return
false
;
}
return
true
;
};
that
.
executeOn
=
function
(
storage
)
{
storage
.
put
(
that
);
};
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
;
}
if
(
typeof
that
.
getAttachmentId
()
===
"
string
"
)
{
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
false
;
}
}
return
true
;
};
that
.
executeOn
=
function
(
storage
)
{
storage
.
remove
(
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
.
error
({
status
:
12
,
statusText
:
'
Replaced
'
,
error
:
'
replaced
'
,
message
:
'
Job has been replaced by another one.
'
,
reason
:
'
job has been replaced by another one
'
});
priv
.
date
=
new
Date
(
job
.
getDate
().
getTime
());
priv
.
command
=
job
.
getCommand
();
priv
.
status
=
job
.
getStatus
();
};
/**
* 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
,
"
none
"
,
{
configurable
:
false
,
enumerable
:
false
,
writable
:
false
,
value
:
function
()
{
return
'
none
'
;
}
});
that
.
default_action
=
that
.
none
;
that
.
default_compare
=
function
(
job1
,
job2
)
{
return
(
job1
.
getCommand
().
getDocId
()
===
job2
.
getCommand
().
getDocId
()
&&
job1
.
getCommand
().
getDocInfo
(
'
_rev
'
)
===
job2
.
getCommand
().
getDocInfo
(
'
_rev
'
)
&&
job1
.
getCommand
().
getOption
(
'
rev
'
)
===
job2
.
getCommand
().
getOption
(
'
rev
'
)
&&
JSON
.
stringify
(
job1
.
getStorage
().
serialized
())
===
JSON
.
stringify
(
job2
.
getStorage
().
serialized
()));
};
// 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
j1label
,
j2label
,
j1status
;
j1label
=
job1
.
getCommand
().
getLabel
();
j2label
=
job2
.
getCommand
().
getLabel
();
j1status
=
(
job1
.
getStatus
().
getLabel
()
===
'
on going
'
?
'
on going
'
:
'
not on going
'
);
if
(
priv
.
action
[
j1label
]
&&
priv
.
action
[
j1label
][
j1status
]
&&
priv
.
action
[
j1label
][
j1status
][
j2label
])
{
return
priv
.
action
[
j1label
][
j1status
][
j2label
](
job1
,
job2
);
}
return
that
.
default_action
(
job1
,
job2
);
};
/**
* 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
job1label
=
job1
.
getCommand
().
getLabel
(),
job2label
=
job2
.
getCommand
().
getLabel
();
if
(
priv
.
compare
[
job1label
]
&&
priv
.
compare
[
job2label
])
{
return
priv
.
compare
[
job1label
][
job2label
](
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
,
ongoing
,
method2
,
rule
)
{
var
ongoing_s
=
(
ongoing
?
'
on going
'
:
'
not on going
'
);
priv
.
action
[
method1
]
=
priv
.
action
[
method1
]
||
{};
priv
.
action
[
method1
][
ongoing_s
]
=
priv
.
action
[
method1
][
ongoing_s
]
||
{};
priv
.
action
[
method1
][
ongoing_s
][
method2
]
=
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
/*
LEGEND:
- s: storage
- m: method
- n: name
- c: content
- o: options
- =: are equal
- !: are not equal
select ALL s= n=
removefailordone fail|done
/ elim repl nacc wait
Remove !ongoing Save 1 x x x
Save !ongoing Remove 1 x x x
GetList !ongoing GetList 0 1 x x
Remove !ongoing Remove 0 1 x x
Load !ongoing Load 0 1 x x
Save c= !ongoing Save 0 1 x x
Save c! !ongoing Save 0 1 x x
GetList ongoing GetList 0 0 1 x
Remove ongoing Remove 0 0 1 x
Remove ongoing Load 0 0 1 x
Remove !ongoing Load 0 0 1 x
Load ongoing Load 0 0 1 x
Save c= ongoing Save 0 0 1 x
Remove ongoing Save 0 0 0 1
Load ongoing Remove 0 0 0 1
Load ongoing Save 0 0 0 1
Load !ongoing Remove 0 0 0 1
Load !ongoing Save 0 0 0 1
Save ongoing Remove 0 0 0 1
Save ongoing Load 0 0 0 1
Save c! ongoing Save 0 0 0 1
Save !ongoing Load 0 0 0 1
GetList ongoing Remove 0 0 0 0
GetList ongoing Load 0 0 0 0
GetList ongoing Save 0 0 0 0
GetList !ongoing Remove 0 0 0 0
GetList !ongoing Load 0 0 0 0
GetList !ongoing Save 0 0 0 0
Remove ongoing GetList 0 0 0 0
Remove !ongoing GetList 0 0 0 0
Load ongoing GetList 0 0 0 0
Load !ongoing GetList 0 0 0 0
Save ongoing GetList 0 0 0 0
Save !ongoing GetList 0 0 0 0
For more information, see documentation
*/
that
.
addActionRule
(
'
post
'
,
true
,
'
post
'
,
that
.
dontAccept
);
that
.
addActionRule
(
'
post
'
,
true
,
'
put
'
,
that
.
wait
);
that
.
addActionRule
(
'
post
'
,
true
,
'
get
'
,
that
.
wait
);
that
.
addActionRule
(
'
post
'
,
true
,
'
remove
'
,
that
.
wait
);
that
.
addActionRule
(
'
post
'
,
true
,
'
putAttachment
'
,
that
.
wait
);
that
.
addActionRule
(
'
post
'
,
false
,
'
post
'
,
that
.
update
);
that
.
addActionRule
(
'
post
'
,
false
,
'
put
'
,
that
.
wait
);
that
.
addActionRule
(
'
post
'
,
false
,
'
get
'
,
that
.
wait
);
that
.
addActionRule
(
'
post
'
,
false
,
'
remove
'
,
that
.
eliminate
);
that
.
addActionRule
(
'
post
'
,
false
,
'
putAttachment
'
,
that
.
wait
);
that
.
addActionRule
(
'
put
'
,
true
,
'
post
'
,
that
.
dontAccept
);
that
.
addActionRule
(
'
put
'
,
true
,
'
put
'
,
that
.
wait
);
that
.
addActionRule
(
'
put
'
,
true
,
'
get
'
,
that
.
wait
);
that
.
addActionRule
(
'
put
'
,
true
,
'
remove
'
,
that
.
wait
);
that
.
addActionRule
(
'
put
'
,
true
,
'
putAttachment
'
,
that
.
wait
);
that
.
addActionRule
(
'
put
'
,
false
,
'
post
'
,
that
.
dontAccept
);
that
.
addActionRule
(
'
put
'
,
false
,
'
put
'
,
that
.
update
);
that
.
addActionRule
(
'
put
'
,
false
,
'
get
'
,
that
.
wait
);
that
.
addActionRule
(
'
put
'
,
false
,
'
remove
'
,
that
.
eliminate
);
that
.
addActionRule
(
'
put
'
,
false
,
'
putAttachment
'
,
that
.
wait
);
that
.
addActionRule
(
'
get
'
,
true
,
'
post
'
,
that
.
wait
);
that
.
addActionRule
(
'
get
'
,
true
,
'
put
'
,
that
.
wait
);
that
.
addActionRule
(
'
get
'
,
true
,
'
get
'
,
that
.
dontAccept
);
that
.
addActionRule
(
'
get
'
,
true
,
'
remove
'
,
that
.
wait
);
that
.
addActionRule
(
'
get
'
,
true
,
'
putAttachment
'
,
that
.
wait
);
that
.
addActionRule
(
'
get
'
,
false
,
'
post
'
,
that
.
wait
);
that
.
addActionRule
(
'
get
'
,
false
,
'
put
'
,
that
.
wait
);
that
.
addActionRule
(
'
get
'
,
false
,
'
get
'
,
that
.
update
);
that
.
addActionRule
(
'
get
'
,
false
,
'
remove
'
,
that
.
wait
);
that
.
addActionRule
(
'
get
'
,
false
,
'
putAttachment
'
,
that
.
wait
);
that
.
addActionRule
(
'
remove
'
,
true
,
'
post
'
,
that
.
wait
);
that
.
addActionRule
(
'
remove
'
,
true
,
'
get
'
,
that
.
dontAccept
);
that
.
addActionRule
(
'
remove
'
,
true
,
'
remove
'
,
that
.
dontAccept
);
that
.
addActionRule
(
'
remove
'
,
true
,
'
putAttachment
'
,
that
.
dontAccept
);
that
.
addActionRule
(
'
remove
'
,
false
,
'
post
'
,
that
.
eliminate
);
that
.
addActionRule
(
'
remove
'
,
false
,
'
put
'
,
that
.
dontAccept
);
that
.
addActionRule
(
'
remove
'
,
false
,
'
get
'
,
that
.
dontAccept
);
that
.
addActionRule
(
'
remove
'
,
false
,
'
remove
'
,
that
.
update
);
that
.
addActionRule
(
'
remove
'
,
false
,
'
putAttachment
'
,
that
.
dontAccept
);
that
.
addActionRule
(
'
allDocs
'
,
true
,
'
allDocs
'
,
that
.
dontAccept
);
that
.
addActionRule
(
'
allDocs
'
,
false
,
'
allDocs
'
,
that
.
update
);
that
.
addActionRule
(
'
putAttachment
'
,
true
,
'
post
'
,
that
.
dontAccept
);
that
.
addActionRule
(
'
putAttachment
'
,
true
,
'
put
'
,
that
.
wait
);
that
.
addActionRule
(
'
putAttachment
'
,
true
,
'
get
'
,
that
.
wait
);
that
.
addActionRule
(
'
putAttachment
'
,
true
,
'
remove
'
,
that
.
wait
);
that
.
addActionRule
(
'
putAttachment
'
,
true
,
'
putAttachment
'
,
that
.
wait
);
that
.
addActionRule
(
'
putAttachment
'
,
false
,
'
post
'
,
that
.
dontAccept
);
that
.
addActionRule
(
'
putAttachment
'
,
false
,
'
put
'
,
that
.
wait
);
that
.
addActionRule
(
'
putAttachment
'
,
false
,
'
get
'
,
that
.
wait
);
that
.
addActionRule
(
'
putAttachment
'
,
false
,
'
remove
'
,
that
.
eliminate
);
that
.
addActionRule
(
'
putAttachment
'
,
false
,
'
putAttachment
'
,
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,
removeCommand: 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), "/" are forbidden
* @param {object} options (optional) Contains some options:
* - {number} max_retry The number max of retries, 0 = infinity.
* - {boolean} revs Include revision history of the document.
* - {boolean} revs_info Retreive the revisions.
* - {boolean} conflicts Retreive the conflict list.
* @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, "/" are forbidden
* @param {object} options (optional) Contains some options:
* - {number} max_retry The number max of retries, 0 = infinity.
* - {boolean} revs Include revision history of the document.
* - {boolean} revs_info Retreive the revisions.
* - {boolean} conflicts Retreive the conflict list.
* @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} docid The document id: "doc_id" or "doc_id/attachmt_id".
* @param {object} options (optional) Contains some options:
* - {number} max_retry The number max of retries, 0 = infinity.
* - {string} rev The revision we want to get.
* - {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
(
id
,
options
,
success
,
error
)
{
var
param
=
priv
.
parametersToObject
(
[
options
,
success
,
error
],
{
max_retry
:
3
}
);
priv
.
addJob
(
getCommand
,
{
docid
:
id
,
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: "doc_id" or "doc_id/attachment_id"
* @param {object} options (optional) Contains some options:
* - {number} max_retry The number max of retries, 0 = infinity.
* - {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
,
"
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
* - {boolean} revs Include revision history of the document.
* - {boolean} revs_info Include revisions.
* - {boolean} conflicts Include 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
,
"
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
}
});
}
});
/**
* Put an attachment to a document.
* @method putAttachment
* @param {object} doc The document object. Contains at least:
* - {string} id The document id: "doc_id/attchment_id"
* - {string} data Base64 attachment data
* - {string} mimetype The attachment mimetype
* - {string} rev The attachment revision
* @param {object} options (optional) Contains some options:
* - {number} max_retry The number max of retries, 0 = infinity.
* - {boolean} revs Include revision history of the document.
* - {boolean} revs_info Include revisions.
* - {boolean} conflicts Include conflicts.
* @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
,
k
,
doc_with_underscores
=
{};
param
=
priv
.
parametersToObject
(
[
options
,
success
,
error
],
{
max_retry
:
0
}
);
for
(
k
in
doc
)
{
if
(
doc
.
hasOwnProperty
(
k
)
&&
k
.
match
(
'
[^_].*
'
))
{
doc_with_underscores
[
"
_
"
+
k
]
=
doc
[
k
];
}
}
priv
.
addJob
(
putAttachmentCommand
,
{
doc
:
doc_with_underscores
,
options
:
param
.
options
,
callbacks
:
{
success
:
param
.
success
,
error
:
param
.
error
}
});
}
});
return
that
;
};
// End Class jio
/*jslint indent: 2, maxlen: 80, sloppy: true */
/*global jio: true, invalidStorageType: true */
var
storage_type_object
=
{
// -> 'key':constructorFunction
'
base
'
:
function
()
{}
// overriden by jio
};
var
jioNamespace
=
(
function
(
spec
)
{
var
that
=
{};
spec
=
spec
||
{};
// Attributes //
// Methods //
/**
* Creates a new jio instance.
* @method newJio
* @param {object} spec The storage description
* @return {object} The new Jio instance.
*/
Object
.
defineProperty
(
that
,
"
newJio
"
,
{
configurable
:
false
,
enumerable
:
false
,
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
(
that
,
"
addStorageType
"
,
{
configurable
:
false
,
enumerable
:
false
,
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
;
}
});
return
that
;
}());
Object
.
defineProperty
(
scope
,
"
jIO
"
,
{
configurable
:
false
,
enumerable
:
false
,
writable
:
false
,
value
:
jioNamespace
});
}(
window
,
hex_md5
));
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