Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
J
jio
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Eugene Shen
jio
Commits
7f5f4e44
Commit
7f5f4e44
authored
Jul 17, 2013
by
Tristan Cavelier
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
gidstorage added + tests (wip)
parent
a68b440b
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
479 additions
and
0 deletions
+479
-0
examples/jio_dashboard.html
examples/jio_dashboard.html
+2
-0
src/jio.storage/gidstorage.js
src/jio.storage/gidstorage.js
+384
-0
test/jiotests.js
test/jiotests.js
+91
-0
test/jiotests_withoutrequirejs.html
test/jiotests_withoutrequirejs.html
+2
-0
No files found.
examples/jio_dashboard.html
View file @
7f5f4e44
...
...
@@ -164,6 +164,8 @@ var clearlog = function () {
</script>
<script
type=
"text/javascript"
src=
"../src/jio.storage/splitstorage.js"
>
</script>
<script
type=
"text/javascript"
src=
"../src/jio.storage/gidstorage.js"
>
</script>
<script
type=
"text/javascript"
src=
"../lib/sjcl/sjcl.min.js"
></script>
<script
type=
"text/javascript"
>
<!--
...
...
src/jio.storage/gidstorage.js
0 → 100644
View file @
7f5f4e44
/*
* JIO extension for resource global identifier management.
* Copyright (C) 2013 Nexedi SA
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*global jIO: true, localStorage: true, setTimeout: true,
complex_queries: true */
/**
* JIO GID Storage. Type = 'gid'.
* Identifies document with their global identifier représentation
*
* Sub storages must support complex queries.
*
* Storage Description:
*
* {
* "type": "gid",
* "sub_storage": {<storage description>},
* "constraints": {
* "default": {
* "identifier": "list", // ['a', 1]
* "type": "DCMIType", // 'Text'
* "title": "string" // 'something blue'
* },
* "Text": {
* "format": "contentType" // contains 'text/plain;charset=utf-8'
* },
* "Image": {
* "version": "json" // value as is
* }
* }
* }
*/
(
function
()
{
var
dcmi_types
,
metadata_actions
,
content_type_re
dcmi_types
=
{
'
Collection
'
:
'
Collection
'
,
'
Dataset
'
:
'
Dataset
'
,
'
Event
'
:
'
Event
'
,
'
Image
'
:
'
Image
'
,
'
InteractiveResource
'
:
'
InteractiveResource
'
,
'
MovingImage
'
:
'
MovingImage
'
,
'
PhysicalObject
'
:
'
PhysicalObject
'
,
'
Service
'
:
'
Service
'
,
'
Software
'
:
'
Software
'
,
'
Sound
'
:
'
Sound
'
,
'
StillImage
'
:
'
StillImage
'
,
'
Text
'
:
'
Text
'
};
metadata_actions
=
{
json
:
function
(
value
)
{
return
value
;
},
string
:
function
(
value
)
{
if
(
typeof
value
===
'
string
'
)
{
return
value
;
}
},
list
:
function
(
value
)
{
var
i
,
new_value
=
[];
if
(
Array
.
isArray
(
value
))
{
for
(
i
=
0
;
i
<
value
.
length
;
i
+=
1
)
{
if
(
typeof
value
[
i
]
===
'
object
'
)
{
new_value
[
new_value
.
length
]
=
value
[
i
].
content
;
}
else
{
new_value
[
new_value
.
length
]
=
value
[
i
];
}
}
}
else
if
(
value
!==
undefined
)
{
value
=
[
value
];
}
return
value
;
},
DCMIType
:
function
(
value
)
{
return
dcmi_types
[
value
];
},
contentType
:
function
(
value
)
{
var
i
;
if
(
!
Array
.
isArray
(
value
))
{
value
=
[
value
];
}
for
(
i
=
0
;
i
<
value
.
length
;
i
+=
1
)
{
if
(
value
[
i
]
===
'
object
'
)
{
if
(
content_type_re
.
test
(
value
[
i
].
content
))
{
return
value
[
i
].
content
;
}
}
else
{
if
(
content_type_re
.
test
(
value
[
i
]))
{
return
value
[
i
];
}
}
}
}
};
content_type_re
=
/^
([
a-z
]
+
\/[
a-zA-Z0-9
\+\-\.]
+
)(?:\s
*;
\s
*charset
\s
*=
\s
*
([
a-zA-Z0-9
\-]
+
))?
$/
;
function
Metadata
(
metadata
)
{
if
(
typeof
metadata
===
'
object
'
&&
!
Array
.
isArray
(
metadata
))
{
this
.
metadata
=
metadata
;
}
else
{
this
.
metadata
=
{};
}
Metadata
.
prototype
.
update
.
call
(
this
,
metadata
);
}
Metadata
.
prototype
.
update
=
function
(
metadata
)
{
var
k
;
for
(
k
in
metadata
)
{
if
(
metadata
.
hasOwnProperty
(
k
))
{
if
(
metadata
[
k
]
!==
undefined
)
{
if
(
k
[
0
]
===
'
_
'
)
{
this
.
metadata
[
k
]
=
JSON
.
parse
(
JSON
.
stringify
(
metadata
[
k
]));
}
else
{
this
.
metadata
[
k
]
=
Metadata
.
normalizeValue
(
metadata
[
k
]);
}
}
}
}
return
this
;
};
Metadata
.
prototype
.
get
=
function
(
key
)
{
return
this
.
metadata
[
key
];
};
Metadata
.
prototype
.
set
=
function
(
key
,
value
)
{
if
(
value
===
undefined
)
{
delete
this
.
metadata
[
key
];
return
this
;
}
if
(
key
[
0
]
===
'
_
'
)
{
this
.
metadata
[
key
]
=
value
;
}
else
{
this
.
metadata
[
key
]
=
Metadata
.
normalizeValue
(
value
);
}
return
this
;
};
Metadata
.
normalizeArray
=
function
(
value
)
{
var
i
;
if
(
value
.
length
===
0
)
{
return
;
}
value
=
value
.
slice
();
i
=
0
;
while
(
i
<
value
.
length
)
{
if
(
typeof
value
[
i
]
===
'
object
'
&&
!
Array
.
isArray
(
value
[
i
]))
{
value
[
i
]
=
Metadata
.
normalizeObject
(
value
[
i
]);
if
(
value
[
i
]
===
undefined
)
{
value
.
splice
(
i
,
1
);
}
else
{
i
+=
1
;
}
}
else
if
((
typeof
value
[
i
]
===
'
string
'
)
||
(
isNaN
(
value
[
i
])
&&
typeof
value
[
i
]
===
'
number
'
))
{
i
+=
1
;
}
else
{
value
.
splice
(
i
,
1
);
}
}
if
(
value
.
length
===
1
)
{
return
value
[
0
];
}
return
value
;
};
Metadata
.
normalizeObject
=
function
(
value
)
{
var
i
,
count
=
0
,
new_value
=
{};
for
(
i
in
value
)
{
if
(
value
.
hasOwnProperty
(
i
))
{
if
((
typeof
value
[
i
]
===
'
string
'
)
||
(
isNaN
(
value
[
i
])
&&
typeof
value
[
i
]
===
'
number
'
))
{
new_value
[
i
]
=
value
[
i
];
count
+=
1
;
}
}
}
if
(
new_value
.
content
===
undefined
)
{
return
;
}
if
(
count
===
1
)
{
return
new_value
.
content
;
}
return
new_value
;
};
Metadata
.
normalizeValue
=
function
(
value
)
{
if
((
typeof
value
===
'
string
'
)
||
(
isNaN
(
value
)
&&
typeof
value
===
'
number
'
))
{
return
value
;
}
if
(
Array
.
isArray
(
value
))
{
return
Metadata
.
normalizeArray
(
value
);
}
if
(
typeof
value
===
'
object
'
)
{
return
Metadata
.
normalizeObject
(
value
);
}
};
function
gidFormat
(
metadata
,
constraints
)
{
var
types
,
i
,
meta_key
,
result
=
{},
tmp
;
types
=
[
'
default
'
,
metadata
.
type
];
for
(
i
=
0
;
i
<
types
.
length
;
i
+=
1
)
{
for
(
meta_key
in
constraints
[
types
[
i
]])
{
if
(
constraints
[
types
[
i
]].
hasOwnProperty
(
meta_key
))
{
tmp
=
metadata_actions
[
constraints
[
types
[
i
]][
meta_key
]
](
metadata
[
meta_key
]);
if
(
tmp
===
undefined
)
{
return
;
}
result
[
meta_key
]
=
tmp
;
}
}
}
return
JSON
.
stringify
(
result
);
}
function
gidToComplexQuery
(
gid
,
contraints
)
{
var
k
,
i
,
result
=
[],
meta
,
content
;
if
(
typeof
gid
===
'
string
'
)
{
gid
=
JSON
.
parse
(
gid
);
}
for
(
k
in
gid
)
{
if
(
gid
.
hasOwnProperty
(
k
))
{
meta
=
gid
[
k
];
if
(
!
Array
.
isArray
(
meta
))
{
meta
=
[
meta
];
}
for
(
i
=
0
;
i
<
meta
.
length
;
i
+=
1
)
{
content
=
meta
[
i
];
if
(
typeof
content
===
'
object
'
)
{
content
=
content
.
content
;
}
result
[
result
.
length
]
=
{
"
type
"
:
"
simple
"
,
"
operator
"
:
"
=
"
,
"
key
"
:
k
,
"
value
"
:
content
};
}
}
}
return
{
"
type
"
:
"
complex
"
,
"
operator
"
:
"
AND
"
,
"
query_list
"
:
result
};
}
function
gidParse
(
gid
,
constraints
)
{
var
object
;
try
{
object
=
JSON
.
parse
(
gid
);
}
catch
(
e
)
{
return
;
}
if
(
gid
!==
gidFormat
(
object
,
constraints
))
{
return
;
}
return
object
;
}
function
gidStorage
(
spec
,
my
)
{
var
that
=
my
.
basicStorage
(
spec
,
my
),
priv
=
{};
priv
.
sub_storage
=
spec
.
sub_storage
;
priv
.
constraints
=
spec
.
constraints
||
{
"
default
"
:
{
"
identifier
"
:
"
list
"
,
"
type
"
:
"
DCMIType
"
}
};
that
.
specToStore
=
function
()
{
return
{
"
sub_storage
"
:
priv
.
sub_storage
,
"
constraints
"
:
priv
.
constraints
};
};
that
.
post
=
function
(
command
)
{
setTimeout
(
function
()
{
var
gid
,
complex_query
,
doc
=
command
.
cloneDoc
();
gid
=
gidFormat
(
doc
,
priv
.
constraints
);
if
(
gid
===
undefined
||
(
doc
.
_id
&&
gid
!==
doc
.
_id
))
{
return
that
.
error
({
"
status
"
:
409
,
"
statusText
"
:
"
Conflict
"
,
"
error
"
:
"
conflict
"
,
"
message
"
:
"
Cannot post document
"
,
"
reason
"
:
"
metadata should respect constraints
"
});
}
complex_query
=
gidToComplexQuery
(
gid
);
that
.
addJob
(
'
allDocs
'
,
priv
.
sub_storage
,
{},
{
"
query
"
:
complex_query
,
"
wildcard_character
"
:
null
},
function
(
response
)
{
var
doc
;
if
(
response
.
total_rows
!==
0
)
{
return
that
.
error
({
"
status
"
:
409
,
"
statusText
"
:
"
Conflict
"
,
"
error
"
:
"
conflict
"
,
"
message
"
:
"
Cannot post document
"
,
"
reason
"
:
"
Document already exist
"
});
}
doc
=
command
.
cloneDoc
();
delete
doc
.
_id
;
that
.
addJob
(
'
post
'
,
priv
.
sub_storage
,
doc
,
{
},
function
(
response
)
{
response
.
id
=
gid
;
that
.
success
(
response
);
},
function
(
err
)
{
err
.
message
=
"
Cannot post document
"
;
that
.
error
(
err
);
});
},
function
(
err
)
{
err
.
message
=
"
Cannot post document
"
;
that
.
error
(
err
);
});
});
};
that
.
get
=
function
(
command
)
{
setTimeout
(
function
()
{
var
gid_object
,
complex_query
;
gid_object
=
gidParse
(
command
.
cloneDoc
().
_id
,
priv
.
constraints
);
if
(
gid_object
===
undefined
)
{
return
that
.
error
({
"
status
"
:
409
,
"
statusText
"
:
"
Conflict
"
,
"
error
"
:
"
conflict
"
,
"
message
"
:
"
Cannot post document
"
,
"
reason
"
:
"
metadata should respect constraints
"
});
}
complex_query
=
gidToComplexQuery
(
gid_object
);
that
.
addJob
(
'
allDocs
'
,
priv
.
sub_storage
,
{},
{
"
query
"
:
complex_query
,
"
wildcard_character
"
:
null
},
function
(
response
)
{
if
(
response
.
total_rows
===
0
)
{
return
that
.
error
({
"
status
"
:
404
,
"
statusText
"
:
"
Not Found
"
,
"
error
"
:
"
not_found
"
,
"
message
"
:
"
Cannot get document
"
,
"
reason
"
:
"
missing
"
});
}
// XXX
},
function
(
err
)
{
err
.
message
=
"
Cannot post document
"
;
that
.
error
(
err
);
});
});
};
return
that
;
}
jIO
.
addStorageType
(
'
gid
'
,
gidStorage
);
}());
test/jiotests.js
View file @
7f5f4e44
...
...
@@ -7963,6 +7963,97 @@ test("AllDocs", function () {
o
.
jio
.
stop
();
});
module
(
"
JIO GID Storage
"
);
test
(
"
Post
"
,
function
()
{
var
o
=
generateTools
(
this
);
o
.
localstorage_spec
=
{
"
type
"
:
"
local
"
,
"
username
"
:
"
one
"
,
"
application_name
"
:
"
gid storage post test
"
};
o
.
local_jio
=
JIO
.
newJio
(
o
.
localstorage_spec
);
o
.
jio
=
JIO
.
newJio
({
"
type
"
:
"
gid
"
,
"
sub_storage
"
:
o
.
localstorage_spec
,
"
constraints
"
:
{
"
default
"
:
{
"
identifier
"
:
"
list
"
}
}
});
o
.
local_jio
.
put
({
"
_id
"
:
"
blue
"
,
"
identifier
"
:
"
a
"
});
o
.
local_jio
.
put
({
"
_id
"
:
"
green
"
,
"
identifier
"
:
[
"
ac
"
,
"
b
"
]});
o
.
clock
.
tick
(
2000
);
o
.
local_jio
.
stop
();
o
.
spy
(
o
,
'
status
'
,
409
,
'
Post document without respecting constraints
'
+
'
-> conflicts
'
);
o
.
jio
.
post
({},
o
.
f
);
o
.
tick
(
o
);
o
.
spy
(
o
,
'
status
'
,
409
,
'
Post existent document -> conflict
'
);
o
.
jio
.
post
({
"
identifier
"
:
"
a
"
},
o
.
f
);
o
.
tick
(
o
);
o
.
spy
(
o
,
'
value
'
,
{
"
id
"
:
"
{
\"
identifier
\"
:[
\"
a%
\"
]}
"
,
"
ok
"
:
true
},
'
Post respecting constraints
'
);
o
.
jio
.
post
({
"
identifier
"
:
"
a%
"
},
o
.
f
);
o
.
tick
(
o
);
o
.
spy
(
o
,
'
status
'
,
409
,
'
Post same document respecting constraints
'
+
'
-> conflicts
'
);
o
.
jio
.
post
({
"
identifier
"
:
"
a%
"
},
o
.
f
);
o
.
tick
(
o
);
o
.
jio
.
stop
();
});
test
(
"
Get
"
,
function
()
{
var
o
=
generateTools
(
this
);
o
.
localstorage_spec
=
{
"
type
"
:
"
local
"
,
"
username
"
:
"
one
"
,
"
application_name
"
:
"
gid storage get test
"
};
o
.
local_jio
=
JIO
.
newJio
(
o
.
localstorage_spec
);
o
.
jio
=
JIO
.
newJio
({
"
type
"
:
"
gid
"
,
"
sub_storage
"
:
o
.
localstorage_spec
,
"
constraints
"
:
{
"
default
"
:
{
"
identifier
"
:
"
list
"
}
}
});
o
.
local_jio
.
put
({
"
_id
"
:
"
blue
"
,
"
identifier
"
:
"
a
"
});
o
.
local_jio
.
put
({
"
_id
"
:
"
green
"
,
"
identifier
"
:
[
"
ac
"
,
"
b
"
]});
o
.
clock
.
tick
(
2000
);
o
.
local_jio
.
stop
();
o
.
spy
(
o
,
'
status
'
,
404
,
'
Get inexistent document
'
);
o
.
jio
.
get
({
"
_id
"
:
"
{
\"
identifier
\"
:[
\"
b
\"
]}
"
},
o
.
f
);
o
.
tick
(
o
);
o
.
spy
(
o
,
'
value
'
,
{
"
_id
"
:
"
blue
"
,
"
identifier
"
:
"
a
"
},
'
Get document
'
);
o
.
jio
.
get
({
"
_id
"
:
"
{
\"
identifier
\"
:[
\"
a
\"
]}
"
},
o
.
f
);
o
.
tick
(
o
);
o
.
jio
.
stop
();
});
};
// end thisfun
if
(
window
.
requirejs
)
{
...
...
test/jiotests_withoutrequirejs.html
View file @
7f5f4e44
...
...
@@ -40,6 +40,8 @@
</script>
<script
type=
"text/javascript"
src=
"../src/jio.storage/splitstorage.js"
>
</script>
<script
type=
"text/javascript"
src=
"../src/jio.storage/gidstorage.js"
>
</script>
<script
type=
"text/javascript"
src=
"./jiotests.js"
></script>
</body>
</html>
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