Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
J
jio-main
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
Hardik Juneja
jio-main
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
Show 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