Skip to content
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

fix: remove jsonb_array and fix jsonb data types such that it can be used in schema design and graphql api #4409

Merged
merged 35 commits into from
Nov 27, 2024

Conversation

mswertz
Copy link
Member

@mswertz mswertz commented Oct 29, 2024

closes #4405

todo:

  • remove any jsonb_array function
  • add jsonb to schema design and graphql (it clearly never has worked in practice)

out of scope:

  • because jsonb has never worked in graphql we assume no migrations are needed.

@mswertz mswertz marked this pull request as draft October 29, 2024 13:27
@mswertz mswertz marked this pull request as ready for review October 29, 2024 14:12
@mswertz mswertz changed the title fix: remove json array because that is unnecessary and breaks CSV fix: remove json array because that is unnecessary and breaks CSV and RDF Oct 29, 2024
@mswertz mswertz requested a review from svandenhoek October 29, 2024 16:24
Copy link
Member

@esthervanenckevort esthervanenckevort left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code looks fine, but is missing a migration step. I would expect a JSONB_ARRAY to be converted to a JSON Object containing an array of JSON objects.

@mswertz mswertz changed the title fix: remove json array because that is unnecessary and breaks CSV and RDF fix: remove jsonb_array and fix jsonb data types such that it can be used in schema design and graphql api Nov 6, 2024
@mswertz
Copy link
Member Author

mswertz commented Nov 18, 2024

Code looks fine, but is missing a migration step. I would expect a JSONB_ARRAY to be converted to a JSON Object containing an array of JSON objects.

Not needed, was not useable.

@mswertz mswertz dismissed esthervanenckevort’s stale review November 18, 2024 08:55

json has never worked so can't be anything to migrate

@svandenhoek
Copy link
Contributor

svandenhoek commented Nov 18, 2024

If #4323 ends up getting merged before this PR, be sure to remove the following lines after merging with master:

entry(ColumnType.JSONB_ARRAY, RdfColumnType.SKIP), // Unsupported.

ColumnType.JSONB_ARRAY.name(), // TODO: Remove if deprecated.
"{\"c\":3},{\"d\":4,\"e\":5}",

// TODO: Remove if deprecated.
() -> Assertions.assertEquals(Set.of(), retrieveValues(ColumnType.JSONB_ARRAY.name())),

#4323 contains a test that validates whether each ColumnType has a mapper to RDF, so pre-emptively removing JSON_ARRAY from src would cause a failing test and removing test code with source code still present seems illogical.

EDIT: Might be some more conflicts as I see JSONB is renamed to JSON. We'll see when we get there then 🙂

Copy link
Contributor

@svandenhoek svandenhoek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found some things that might need to be adjusted/improved before we merge it:

input expected actual
{"key":"value"};alert("test") error (not valid json) "{\"key\":\"value\"};alert(\"test\")"
"{"key":"value"};alert("test")" error (not valid json) "\"{\"key\":\"value\"};alert(\"test\")\""
{}alert("test") error (not valid json) "{}alert(\"test\")"
"alert("test") error (not valid json) "\"alert(\"test\")"
  • Consider adding tests that include primitives as well ("", "string", -1, true, null), see also https://datatracker.ietf.org/doc/html/rfc7159#section-3
    • null is converted to an empty field (should stay null)
  • {"key":"value1", "key":"value2"} yields {"key":"value2"}. While technically correct, an error or warning would be preferred.

@mswertz
Copy link
Member Author

mswertz commented Nov 20, 2024

Found some things that might need to be adjusted/improved before we merge it:

input expected actual
{"key":"value"};alert("test") error (not valid json) "{\"key\":\"value\"};alert(\"test\")"
"{"key":"value"};alert("test")" error (not valid json) "\"{\"key\":\"value\"};alert(\"test\")\""
{}alert("test") error (not valid json) "{}alert(\"test\")"
"alert("test") error (not valid json) "\"alert(\"test\")"

  • Consider adding tests that include primitives as well ("", "string", -1, true, null), see also https://datatracker.ietf.org/doc/html/rfc7159#section-3

    • null is converted to an empty field (should stay null)
  • {"key":"value1", "key":"value2"} yields {"key":"value2"}. While technically correct, an error or warning would be preferred.

Grotendeels goede punten; uitdaging is dat "string" ook valide json is. Maar we zouden kunnen zeggen dat als het resultaat van de parse geen Map of List is dat we dan het niet valide vinden?

@svandenhoek
Copy link
Contributor

@mswertz: Normaliter zou ik voorstander zijn van de RFC standaarden zo goed mogelijk te volgen, al is er hier wel een punt te maken dat qua usecase we zelf al datatypes hebben voor string/int/boolean (behalve null?) waardoor we liever willen dat een gebruiker dat gebruikt i.p.v. een JSON met enkel 1 primitive. Stel wel voor dat we dan:

  • Dit helder in de documentatie zetten:
* json : validates json format (must be an array or object!)
  • Bij back-end checken of de root node een array/object is, bijvoorbeeld:
JsonNode tree = objectMapper.readTree(jsonString);
    if(!tree.isArray() && !tree.isObject()) {
        throw new MolgenisException("JSON is not an array/object.");
    }

@mswertz
Copy link
Member Author

mswertz commented Nov 21, 2024

@mswertz: Normaliter zou ik voorstander zijn van de RFC standaarden zo goed mogelijk te volgen, al is er hier wel een punt te maken dat qua usecase we zelf al datatypes hebben voor string/int/boolean (behalve null?) waardoor we liever willen dat een gebruiker dat gebruikt i.p.v. een JSON met enkel 1 primitive. Stel wel voor dat we dan:

  • Dit helder in de documentatie zetten:
* json : validates json format (must be an array or object!)
  • Bij back-end checken of de root node een array/object is, bijvoorbeeld:
JsonNode tree = objectMapper.readTree(jsonString);
    if(!tree.isArray() && !tree.isObject()) {
        throw new MolgenisException("JSON is not an array/object.");
    }

yes, kun jij dat doen of wil je dat ik het doe?

@mswertz mswertz marked this pull request as draft November 21, 2024 21:17
@svandenhoek
Copy link
Contributor

svandenhoek commented Nov 26, 2024

Changes:

  • Updated docs
  • Fixed a bug (serialize must throw CoercingSerializeException and not MolgenisException)
  • Added back-end validation (through TypeUtils.toJsonb())
    • Validates on trailing data
    • Validates on uniqueness (remove if performance hit is too big)
    • Validation now also works when editing existing field
  • Added front-end validation
    • Does not validate in key-uniqueness (relies on back-end for this)
    • TODO: textarea compains about :value="modelValue" (though TextInput.vue also does it this way but is not labeled as lang="ts"). Might need some fixing before merge or simply use input instead of textarea.
    • TODO:
      export const isValueType = (column: IColumn) => {
      does not include UUID in isValueType(). Should UUID and/or JSON included here? UUID was present, just not in the same order as fieldTypes from that same file.

Copy link
Member Author

@mswertz mswertz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good, one question left. I cannot approve so if you agree with comment can you then approve yourself?

}

export function isJsonObjectOrArray(parsedJson: any) {
if (typeof parsedJson === "object") {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doesn't check if it is an array?

Copy link
Contributor

@svandenhoek svandenhoek Nov 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should allow arrays, see for example: https://jsbin.com/paperodivi/1/edit?html,output

While null is also an object, it does fail in the form (probably due to if(!parsed)):
Scherm­afbeelding 2024-11-26 om 13 58 50

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll have a quick look if I can fix null giving the correct error message though (no array/object instead of invalid JSON).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test code for front-end now also added:

describe("isJsonObjectOrArray", () => {
test("only JSON object/array should return true (after parsing from JSON string)", () => {
expect(isJsonObjectOrArray(JSON.parse('{"key":"value"}'))).toBe(true);
expect(isJsonObjectOrArray(JSON.parse('["string1", "string2"]'))).toBe(true);
expect(isJsonObjectOrArray(JSON.parse('{"key1":{"key2":["value1", "value2"]}}'))).toBe(true);
expect(isJsonObjectOrArray(JSON.parse('"string"'))).toBe(false);
expect(isJsonObjectOrArray(JSON.parse('1'))).toBe(false);
expect(isJsonObjectOrArray(JSON.parse('true'))).toBe(false);
expect(isJsonObjectOrArray(JSON.parse('false'))).toBe(false);
expect(isJsonObjectOrArray(JSON.parse('null'))).toBe(false);
});
});

Copy link
Contributor

@chinook25 chinook25 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good, just some small thingies.

@svandenhoek
Copy link
Contributor

@mswertz: I approved and @chinook25 did another review and that feedback is included as well.

@mswertz mswertz marked this pull request as ready for review November 27, 2024 18:11
@mswertz mswertz merged commit 1b4b502 into master Nov 27, 2024
6 checks passed
@mswertz mswertz deleted the fix/remove_json_array branch November 27, 2024 18:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

fix: remove ColumnType.JSONB_ARRAY because does not function as expected
4 participants