Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
open-source
cwclientlibjs
Commits
495113e689ef
Commit
2ba2587e
authored
May 29, 2020
by
Laurent Wouters
Browse files
[client] Refactored usage of schema hash for caching
parent
992246fe7c80
Pipeline
#16305
failed with stages
in 4 minutes and 28 seconds
Changes
2
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
src/client.ts
View file @
495113e6
...
...
@@ -3,37 +3,9 @@
contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
*/
import
{
Schema
,
EntitySchema
,
getFromCardinality
,
getToCardinality
,
EntityAttributeSchema
,
EntityRelationSchema
,
}
from
'
./providers
'
;
require
(
'
isomorphic-fetch
'
);
import
CryptoJS
=
require
(
'
crypto-js
'
);
export
function
applySchema
(
jsonEntity
:
any
):
EntitySchema
{
const
adaptAttribute
=
(
attr
:
any
):
EntityAttributeSchema
=>
{
return
{...
attr
,
cardinality
:
getToCardinality
(
attr
.
cardinality
)};
};
const
adaptRelation
=
(
relation
:
any
):
EntityRelationSchema
=>
{
return
{
...
relation
,
fromCardinality
:
getFromCardinality
(
relation
.
fromCardinality
),
toCardinality
:
getToCardinality
(
relation
.
toCardinality
),
};
};
return
{
...
jsonEntity
,
attributes
:
jsonEntity
.
attributes
.
map
(
adaptAttribute
),
relationsTo
:
jsonEntity
.
relationsTo
.
map
(
adaptRelation
),
relationsFrom
:
jsonEntity
.
relationsFrom
.
map
(
adaptRelation
),
};
}
/**
* Gets the passed URL ensuring it ends with a slash
* @param url Th input URL
...
...
@@ -186,11 +158,17 @@ function doRequestFetch(
throw
myResponse
;
}
};
if
(
contentType
===
'
application/json
'
)
{
return
response
.
json
().
then
(
toHttpResponse
);
}
else
{
return
response
.
text
().
then
(
toHttpResponse
);
}
return
response
.
text
().
then
(
content
=>
{
if
(
contentType
===
'
application/json
'
&&
content
!==
null
&&
content
.
length
>
0
)
{
return
toHttpResponse
(
JSON
.
parse
(
content
));
}
else
{
return
toHttpResponse
(
content
);
}
});
});
}
...
...
@@ -348,7 +326,7 @@ function getOptionsWithDefault(
):
HttpRequestOptions
{
return
{
method
:
options
.
method
??
'
GET
'
,
content
:
options
.
content
??
''
,
content
:
options
.
content
??
null
,
contentType
:
options
.
contentType
??
'
application/json
'
,
accept
:
options
.
accept
??
'
application/json
'
,
headers
:
new
Headers
(),
...
...
@@ -684,6 +662,10 @@ export function rqlIoV2asSolutions(
* A client able to execute RQL queries
*/
export
interface
RqlClient
{
/**
* The underlying HTTP client
*/
readonly
httpClient
:
HttpClient
;
/**
* Executes a RQL query
* @param query The RQL query
...
...
@@ -712,15 +694,6 @@ export interface RqlClient {
params
:
{[
key
:
string
]:
any
},
viewId
:
string
):
Promise
<
any
>
;
/**
* Fetch the cubicweb schema from a server supporting cubicweb_rqlcontroller
*/
getSchema
():
Promise
<
Schema
>
;
/**
* Fetch the cubicweb schema hash from a server supporting cubicweb_rqlcontroller
*/
getSchemaHash
():
Promise
<
string
|
null
>
;
/**
* Executes RQL queries in a transaction through RQL/IO v1.0
* @param queries The queries
...
...
@@ -776,26 +749,6 @@ export class CwRqlClient implements RqlClient {
});
}
public
getSchema
():
Promise
<
Schema
>
{
return
this
.
httpClient
.
request
(
'
rqlio/schema/
'
,
{}).
then
(
response
=>
{
return
{
metadata
:
{
timestamp
:
new
Date
(),
},
entities
:
response
.
content
[
'
entities
'
].
map
(
applySchema
),
};
});
}
public
getSchemaHash
():
Promise
<
string
|
null
>
{
return
this
.
httpClient
.
request
(
'
rqlio/schema/
'
,
{
method
:
'
HEAD
'
,
responseHeaders
:
[
'
Etag
'
],
})
.
then
(
response
=>
response
.
headers
.
get
(
'
Etag
'
));
}
public
queryAndTransform
(
query
:
string
,
params
:
{[
key
:
string
]:
any
},
...
...
src/providers.ts
View file @
495113e6
...
...
@@ -3,7 +3,7 @@
contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
*/
import
{
RqlClient
,
RqlRow
,
RqlQuery
}
from
'
./client
'
;
import
{
RqlClient
,
RqlRow
,
RqlQuery
,
HttpClient
}
from
'
./client
'
;
/**
* A complete schema
...
...
@@ -251,7 +251,7 @@ function undefinedToNull<X>(x: X | undefined): X | null {
*/
export
interface
EntitySchemasLoader
{
load
():
Promise
<
Schema
>
;
getSchemaHash
():
Promise
<
string
|
null
>
;
getSchemaHash
():
Promise
<
string
>
;
}
/**
...
...
@@ -286,10 +286,6 @@ export class LocalStorageEntitySchemasLoader implements EntitySchemasLoader {
* @param isCacheUsable A validation function to check whether the cached schema is still usable
* @param onRetrieved A processing function to be applied on a schema that has been retrieved and is going to be stored in cache
*/
/**
* Promise used to fetch the most recent schema hash from the server
*/
public
readonly
getSchemaHash
:
()
=>
Promise
<
string
|
null
>
;
constructor
(
inner
:
EntitySchemasLoader
,
storageKey
:
string
,
...
...
@@ -335,48 +331,97 @@ export class LocalStorageEntitySchemasLoader implements EntitySchemasLoader {
});
}
public
getSchemaHash
():
Promise
<
string
>
{
return
this
.
inner
.
getSchemaHash
();
}
/**
* Loads from the inner loader
*/
private
loadFromInner
():
Promise
<
Schema
>
{
return
Promise
.
all
([
this
.
inner
.
load
().
then
(
this
.
onRetrieved
),
this
.
inner
.
getSchemaHash
(),
]).
then
(([
schema
,
hash
])
=>
{
if
(
window
!==
undefined
&&
hash
!==
null
)
{
window
.
localStorage
.
setItem
(
this
.
storageKey
,
JSON
.
stringify
(
schema
)
);
window
.
localStorage
.
setItem
(
this
.
hashStorageKey
,
hash
);
}
return
schema
;
});
return
this
.
inner
.
load
()
.
then
(
this
.
onRetrieved
)
.
then
(
schema
=>
{
if
(
window
!==
undefined
)
{
window
.
localStorage
.
setItem
(
this
.
storageKey
,
JSON
.
stringify
(
schema
)
);
window
.
localStorage
.
setItem
(
this
.
hashStorageKey
,
schema
.
metadata
.
hash
);
}
return
schema
!
;
});
}
}
/**
* A loader that performs RQL queries to retrieve the schemas
*/
export
class
Rql
EntitySchemasLoader
implements
EntitySchemasLoader
{
export
class
Http
EntitySchemasLoader
implements
EntitySchemasLoader
{
/**
* The
RQL
client to use
* The client to use
*/
public
readonly
rqlC
lient
:
Rql
Client
;
public
readonly
c
lient
:
Http
Client
;
constructor
(
rqlC
lient
:
Rql
Client
)
{
this
.
rqlC
lient
=
rqlC
lient
;
constructor
(
c
lient
:
Http
Client
)
{
this
.
c
lient
=
c
lient
;
}
/**
* Loads all entity schemas
*/
public
load
():
Promise
<
Schema
>
{
return
this
.
rqlClient
.
getSchema
();
return
this
.
client
.
request
(
'
rqlio/schema/
'
,
{
responseHeaders
:
[
'
Etag
'
],
})
.
then
(
response
=>
{
return
{
metadata
:
{
timestamp
:
new
Date
(),
hash
:
response
.
headers
.
get
(
'
Etag
'
),
},
entities
:
response
.
content
[
'
entities
'
].
map
(
this
.
applySchema
),
};
});
}
public
getSchemaHash
():
Promise
<
string
|
null
>
{
return
this
.
rqlClient
.
getSchemaHash
();
public
getSchemaHash
():
Promise
<
string
>
{
return
this
.
client
.
request
(
'
rqlio/schema/
'
,
{
method
:
'
HEAD
'
,
responseHeaders
:
[
'
Etag
'
],
})
.
then
(
response
=>
response
.
headers
.
get
(
'
Etag
'
)
!
);
}
/**
* Transforms the retrieve schema in JSON form into an entity schema
* @param jsonEntity The retrieved schema
*/
private
applySchema
(
jsonEntity
:
any
):
EntitySchema
{
const
adaptAttribute
=
(
attr
:
any
):
EntityAttributeSchema
=>
{
return
{...
attr
,
cardinality
:
getToCardinality
(
attr
.
cardinality
)};
};
const
adaptRelation
=
(
relation
:
any
):
EntityRelationSchema
=>
{
return
{
...
relation
,
fromCardinality
:
getFromCardinality
(
relation
.
fromCardinality
),
toCardinality
:
getToCardinality
(
relation
.
toCardinality
),
};
};
return
{
...
jsonEntity
,
attributes
:
jsonEntity
.
attributes
.
map
(
adaptAttribute
),
relationsTo
:
jsonEntity
.
relationsTo
.
map
(
adaptRelation
),
relationsFrom
:
jsonEntity
.
relationsFrom
.
map
(
adaptRelation
),
};
}
}
...
...
@@ -413,6 +458,10 @@ export class LoadableEntitySchemaProvider implements EntitySchemaProvider {
this
.
isLoaded
=
false
;
}
public
getSchemaHash
():
Promise
<
string
>
{
return
this
.
loader
.
getSchemaHash
();
}
/**
* Loads the content of the
*/
...
...
@@ -511,22 +560,11 @@ export class RqlEntitySchemaProvider extends LoadableEntitySchemaProvider {
*/
constructor
(
rqlClient
:
RqlClient
,
storageKey
?:
string
,
hashStorageKey
:
string
|
null
=
null
,
isCacheUsable
:
(
schema
:
Schema
)
=>
Promise
<
boolean
>
=
_
=>
new
Promise
((
resolve
,
_
)
=>
resolve
(
true
)),
onRetrieved
:
(
schema
:
Schema
)
=>
Promise
<
Schema
>
=
schema
=>
new
Promise
((
resolve
,
_
)
=>
resolve
(
schema
))
loader
:
EntitySchemasLoader
=
new
HttpEntitySchemasLoader
(
rqlClient
.
httpClient
)
)
{
super
(
storageKey
===
undefined
?
new
RqlEntitySchemasLoader
(
rqlClient
)
:
new
LocalStorageEntitySchemasLoader
(
new
RqlEntitySchemasLoader
(
rqlClient
),
storageKey
,
hashStorageKey
||
null
)
);
super
(
loader
);
this
.
rqlClient
=
rqlClient
;
}
...
...
@@ -544,10 +582,6 @@ export class RqlEntitySchemaProvider extends LoadableEntitySchemaProvider {
});
});
}
public
getSchemaHash
():
Promise
<
string
|
null
>
{
return
this
.
rqlClient
.
getSchemaHash
();
}
}
/**
...
...
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