-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow deserialization of the base 'Query' type #16388
Conversation
…erived type gets deactivated.
@gvkries what will happen when a feature is enabled, disable, and then enabled again? A user will create queries (SqlQuery), then disabled the Sql feature, updates the document, then enable Sql feature. Will then lose the SqlQuery data previously provided? |
I think adding the default constructor alone my be enough without the next for the handler. Can you please try that out? |
No, the query should be kept intact, because the feature event handler will fix it. Basically the sequence would be:
Maybe there is a more elegant way to do this. |
@gvkries Did you try to only add a default constructor without the event handler? I think if the serializer is able to serialize, everything will work as expected without having to worry about fixing the document |
No, that is not enough. If you re-serialize a E.g. a original Lucene query may look lke:
After Lucene gets deactivated and the query is deserialized and serialized as a
|
I think that would be enough. The data will still be in the database but won't be mapped to a concrete type. In addition to that, I would also not sure these queries on the UI to prevent someone from modifying that record until that feature is enabled again. |
That is a good addition, but the handler is still required because even if the feature gets re-enabled, the |
Note the missing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sebastienros can you think of a better idea here to eliminate the QueriesDocumentUpdater
class?
{ | ||
var document = await _documentManager.GetOrCreateMutableAsync(); | ||
|
||
if (!ValidateDocument(document) && FixupDocument(document)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think !ValidateDocument(document)
is unnecessary and should be removed. I think using FixupDocument
will be enough since we'll only iterate once instead of possible two. Also maybe call this method RepairDocument
instead.
// Check for any query that has no specific type information and try to fix it up with a derived type. | ||
// The type information is lost if a user edits the document while it contains a query for a feature that | ||
// has been disabled. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
decorate this method with this comment instead of the body.
if (query.GetType() == typeof(Query)) | ||
{ | ||
var sample = _querySources.FirstOrDefault(x => x.Name == query.Source)?.Create(); | ||
|
||
if (sample != null) | ||
{ | ||
var json = JObject.FromObject(query); | ||
|
||
document.Queries[kv.Key] = (Query)json.ToObject(sample.GetType()); | ||
hasChanged = true; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Save indentation
if (query.GetType() == typeof(Query)) | |
{ | |
var sample = _querySources.FirstOrDefault(x => x.Name == query.Source)?.Create(); | |
if (sample != null) | |
{ | |
var json = JObject.FromObject(query); | |
document.Queries[kv.Key] = (Query)json.ToObject(sample.GetType()); | |
hasChanged = true; | |
} | |
} | |
if (query.GetType() != typeof(Query)) | |
{ | |
continue; | |
} | |
var sample = _querySources.FirstOrDefault(x => x.Name == query.Source)?.Create(); | |
if (sample != null) | |
{ | |
var json = JObject.FromObject(query); | |
document.Queries[kv.Key] = (Query)json.ToObject(sample.GetType()); | |
hasChanged = true; | |
} |
Suggestion is to split the QueriesDocument into separate documents (one for each query) using a migration. A mitigation to the problem could be to delete the queries when the feature is disabled. |
If a feature with an
IQuerySource
that has been saved to aQueriesDocument
gets deactivated, deserializing the document will fail because the base typeQuery
cannot be deserialized.This PR fixes this by adding a parameterless constructor to
Query
itself. It also ensures that any previously saved data from the queries document is preserved by using an JSON extension property.Because I found no way to preserve the original type information when the base
Query
type gets re-serialized, I added an feature event handler, that fixes missing type information in theQueriesDocument
when a previously used feature is reactivated.Fixes #16372
/cc @MikeAlhayek