Skip to content

Commit

Permalink
removeSchema with RegExp to remove multiple schemas or without argume…
Browse files Browse the repository at this point in the history
…nt to remove all schemas, closes #103
  • Loading branch information
epoberezkin committed Feb 28, 2016
1 parent f48efb5 commit 3aaeaf6
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 9 deletions.
4 changes: 2 additions & 2 deletions KEYWORDS.md
Original file line number Diff line number Diff line change
Expand Up @@ -599,13 +599,13 @@ __Examples__

1. _schema_: `{ "patternRequired": [ "f.*o" ] }`

_valid_: `{ "foo": 1 }`, `{ "-fo-": 1 }`, { "foo": 1, "bar": 2 }`, any non-object
_valid_: `{ "foo": 1 }`, `{ "-fo-": 1 }`, `{ "foo": 1, "bar": 2 }`, any non-object

_invalid_: `{}`, `{ "bar": 2 }`, `{ "Foo": 1 }`,

2. _schema_: `{ "patternRequired": [ "f.*o", "b.*r" ] }`

_valid_: { "foo": 1, "bar": 2 }`, `{ "foobar": 3 }`, any non-object
_valid_: `{ "foo": 1, "bar": 2 }`, `{ "foobar": 3 }`, any non-object

_invalid_: `{}`, `{ "foo": 1 }`, `{ "bar": 2 }`

Expand Down
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -669,11 +669,17 @@ Errors will be available at `ajv.errors`.
Retrieve compiled schema previously added with `addSchema` by the key passed to `addSchema` or by its full reference (id). Returned validating function has `schema` property with the reference to the original schema.


##### .removeSchema(Object schema|String key|String ref)
##### .removeSchema([Object schema|String key|String ref|RegExp pattern])

Remove added/cached schema. Even if schema is referenced by other schemas it can be safely removed as dependent schemas have local references.

Schema can be removed using key passed to `addSchema`, it's full reference (id) or using actual schema object that will be stable-stringified to remove schema from cache.
Schema can be removed using:
- key passed to `addSchema`
- it's full reference (id)
- RegExp that should match schema id or key (meta-schemas won't be removed)
- actual schema object that will be stable-stringified to remove schema from cache

If no parameter is passed all schemas but meta-schemas will be removed and the cache will be cleared.


##### <a name="api-addformat"></a>.addFormat(String name, String|RegExp|Function|Object format)
Expand Down Expand Up @@ -829,7 +835,7 @@ Defaults:
- _errorDataPath_: set `dataPath` to point to 'object' (default) or to 'property' (default behavior in versions before 2.0) when validating keywords `required`, `additionalProperties` and `dependencies`.
- _messages_: Include human-readable messages in errors. `true` by default. `false` can be passed when custom messages are used (e.g. with [ajv-i18n](https://github.com/epoberezkin/ajv-i18n)).
- _beautify_: format the generated function with [js-beautify](https://github.com/beautify-web/js-beautify) (the validating function is generated without line-breaks). `npm install js-beautify` to use this option. `true` or js-beautify options can be passed.
- _cache_: an optional instance of cache to store compiled schemas using stable-stringified schema as a key. For example, set-associative cache [sacjs](https://github.com/epoberezkin/sacjs) can be used. If not passed then a simple hash is used which is good enough for the common use case (a limited number of statically defined schemas). Cache should have methods `put(key, value)`, `get(key)` and `del(key)`.
- _cache_: an optional instance of cache to store compiled schemas using stable-stringified schema as a key. For example, set-associative cache [sacjs](https://github.com/epoberezkin/sacjs) can be used. If not passed then a simple hash is used which is good enough for the common use case (a limited number of statically defined schemas). Cache should have methods `put(key, value)`, `get(key)`, `del(key)` and `clear()`.


## Validation errors
Expand Down
33 changes: 29 additions & 4 deletions lib/ajv.js
Original file line number Diff line number Diff line change
Expand Up @@ -179,27 +179,52 @@ function Ajv(opts) {


/**
* Remove cached schema
* Even if schema is referenced by other schemas it still can be removed as other schemas have local references
* @param {String|Object} schemaKeyRef key, ref or schema object
* Remove cached schema(s).
* If no parameter is passed all schemas but meta-schemas are removed.
* If RegExp is passed all schemas with key/id matching pattern but meta-schemas are removed.
* Even if schema is referenced by other schemas it still can be removed as other schemas have local references.
* @param {String|Object|RegExp} schemaKeyRef key, ref, pattern to match key/ref or schema object
*/
function removeSchema(schemaKeyRef) {
switch (typeof schemaKeyRef) {
case 'undefined':
_removeAllSchemas(self._schemas);
_removeAllSchemas(self._refs);
self._cache.clear();
return;
case 'string':
var schemaObj = _getSchemaObj(schemaKeyRef);
if (schemaObj) self._cache.del(schemaObj.jsonStr);
delete self._schemas[schemaKeyRef];
delete self._refs[schemaKeyRef];
break;
return;
case 'object':
if (schemaKeyRef instanceof RegExp) {
_removeAllSchemas(self._schemas, schemaKeyRef);
_removeAllSchemas(self._refs, schemaKeyRef);
return;
}
var jsonStr = stableStringify(schemaKeyRef);
self._cache.del(jsonStr);
var id = schemaKeyRef.id;
if (id) {
id = resolve.normalizeId(id);
delete self._schemas[id];
delete self._refs[id];
}
}

}


function _removeAllSchemas(schemas, regex) {
for (var keyRef in schemas) {
var schemaObj = schemas[keyRef];
if (!schemaObj.meta && (!regex || regex.test(keyRef))) {
self._cache.del(schemaObj.jsonStr);
delete schemas[keyRef];
}
}
}


Expand Down
5 changes: 5 additions & 0 deletions lib/cache.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,8 @@ Cache.prototype.get = function Cache_get(key) {
Cache.prototype.del = function Cache_del(key) {
delete this._cache[key];
};


Cache.prototype.clear = function Cache_clear() {
this._cache = {};
};
38 changes: 38 additions & 0 deletions spec/ajv.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,44 @@ describe('Ajv', function () {
ajv.removeSchema('//e.com/int.json');
});
});

it('should remove all schemas but meta-schemas if called without an arguments', function() {
var schema1 = { id: '//e.com/int.json', type: 'integer' }
, str1 = stableStringify(schema1);
ajv.addSchema(schema1);
ajv._cache.get(str1) .should.be.an('object');

var schema2 = { type: 'integer' }
, str2 = stableStringify(schema2);
ajv.addSchema(schema2);
ajv._cache.get(str2) .should.be.an('object');

ajv.removeSchema();
should.not.exist(ajv._cache.get(str1));
should.not.exist(ajv._cache.get(str2));
});

it('should remove all schemas but meta-schemas with key/id matching pattern', function() {
var schema1 = { id: '//e.com/int.json', type: 'integer' }
, str1 = stableStringify(schema1);
ajv.addSchema(schema1);
ajv._cache.get(str1) .should.be.an('object');

var schema2 = { id: 'str.json', type: 'string' }
, str2 = stableStringify(schema2);
ajv.addSchema(schema2, '//e.com/str.json');
ajv._cache.get(str2) .should.be.an('object');

var schema3 = { type: 'integer' }
, str3 = stableStringify(schema3);
ajv.addSchema(schema3);
ajv._cache.get(str3) .should.be.an('object');

ajv.removeSchema(/e\.com/);
should.not.exist(ajv._cache.get(str1));
should.not.exist(ajv._cache.get(str2));
ajv._cache.get(str3) .should.be.an('object');
});
});


Expand Down

0 comments on commit 3aaeaf6

Please sign in to comment.