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

Ability to define normalization of undefined query #725

Conversation

jrschumacher
Copy link
Contributor

Add setting to datasource normalizeUndefinedInQuery to determine how
it will handle undefined values. Options:

  • setNull : converts undefined to null
  • throwError : throw an error on undefined value
  • strip : strip the key where undefined value is found

Defualt operation is to strip the key.

Add setting to datasource `normalizeUndefinedInQuery` to determine how
it will handle undefined values. Options:

- setNull : converts undefined to null
- throwError : throw an error on undefined value
- strip : strip the key where undefined value is found

Defualt operation is to strip the key.
@slnode
Copy link

slnode commented Sep 30, 2015

Can one of the admins verify this patch? To accept patch and trigger a build add comment ".ok\W+to\W+test."

@bajtos
Copy link
Member

bajtos commented Oct 1, 2015

@slnode ok to test

@bajtos
Copy link
Member

bajtos commented Oct 1, 2015

Hi @jrschumacher, thank you for the patch!

I would personally prefer different option names.

  1. IMO we should rename throwError to throw to make it consistent with the existing model option strict which allows the value throw - see https://github.com/strongloop/loopback-datasource-juggler/blob/c4de830bfe4e4a4aa704b467c4d6c037665bb091/lib/model.js#L227-L228.
  2. I'd prefer nullify over setNull, but I admit this is subjective.
  3. As for strip, I'd rather use remove or delete, but again, this is subjective too.

Few more ideas to consider:

  • Should we make this option configurable at Model level too?
  • Should we take into account Model option persistUndefinedAsNull (Add model setting "persistUndefinedAsNull" #542) and set handleUndefined='setNull' when normalizeUndefinedInQuery is not explicitly set?

I'm fine to leave those two out of scope of this PR though.

@bajtos
Copy link
Member

bajtos commented Oct 1, 2015

@raymondfeng since you are more familiar with the issue being fixed, I'd like to leave review & approval for you to make.

@jrschumacher
Copy link
Contributor Author

@bajtos I'm happy to change the naming. Will fix later today also I'll look into exploring the model level settings. Questions regarding that: if you set data source level should model level overwrite? Is there an order of precedence?

@jrschumacher
Copy link
Contributor Author

@bajtos regarding the persistUndefinedToNull would it be better to change the datasource setting name to be similar in naming? Or does persist refer more to the longevity of the data in the datasource rather than the transient query?

@raymondfeng
Copy link
Contributor

Here is my take:

  1. Make the configuration available at multiple levels (preferably app & datasource level)
    1. app (server/config.json, global to all models within the app)
    2. datasource (connector settings, global to all models within the same ds. I'm not sure if it's necessary)
    3. model (model settings, local to the model)
    4. options for model methods (local to the request. I'm not sure if it's necessary)
  2. Name/value of the config property:
    • normalizeUndefinedInQuery
      • throw
      • nullify
      • skip (or ignore)

@jrschumacher
Copy link
Contributor Author

@raymondfeng got it

@jrschumacher
Copy link
Contributor Author

@raymondfeng I think the connector level will be valuable to MongoDB users. So maybe if you have a RDBM or redis datasource you will want the stripping effect but with MongoDB the stripping created some serious issues.

@bajtos
Copy link
Member

bajtos commented Oct 1, 2015

👍 for @raymondfeng proposal.

if you set data source level should model level overwrite? Is there an order of precedence?

Yes, more-specific level should override less-specific level. I.e. model level overrides datasource level.

regarding the persistUndefinedToNull would it be better to change the datasource setting name to be similar in naming? Or does persist refer more to the longevity of the data in the datasource rather than the transient query?

You name is fine. persistUndefinedAsNull is a different thing - it controls how well-known fields with no value are persisted.

@jrschumacher
Copy link
Contributor Author

@raymondfeng @bajtos could I get some help on how to fetch the app settings? I've created a method to get settings based on priority but need to add app settings: https://github.com/strongloop/loopback-datasource-juggler/pull/725/files#diff-d717a01e40d8164976e4468af1bce663R942

@raymondfeng
Copy link
Contributor

this.app.get('propName') should work

@jrschumacher
Copy link
Contributor Author

@raymondfeng I've done this, but I don't know how to add the tests for this. There doesn't seem to be a global app object.

@bajtos
Copy link
Member

bajtos commented Oct 5, 2015

I'd rather not use app in the juggler, it's a concept from loopback. Since loopback-datasource-juggler is a dependee of loopback, it should not access loopback-specific properties, as that would break encapsulation and isolation of this component. Instead, loopback should inject normalizeUndefinedInQuery when attaching a model to an app - see https://github.com/strongloop/loopback/blob/e68cd8fc87730404a78e1475b828886e3582bd6f/lib/application.js#L156-L159 and https://github.com/strongloop/loopback/blob/e68cd8fc87730404a78e1475b828886e3582bd6f/lib/application.js#L156-L159

@bajtos
Copy link
Member

bajtos commented Oct 5, 2015

Another approach is to override datasource settings when creating a new datasource in an app - see https://github.com/strongloop/loopback/blob/e68cd8fc87730404a78e1475b828886e3582bd6f/lib/application.js#L221-L227

@jrschumacher
Copy link
Contributor Author

@bajtos then is there anything else that's needed from me here? I'm not sure why the above tests fail. Locally all the tests pass.

@bajtos
Copy link
Member

bajtos commented Oct 5, 2015

Hmm, the tests are failing with this error:

  1) util.removeUndefined Remove undefined values from the query object:

      AssertionError: expected { where: { x: 1 } } deepEqual { where: { x: 1, y: null } }
      + expected - actual

       {
         "where": {
           "x": 1
      +    "y": [null]
         }
       }

      at Context.<anonymous> (test/util.test.js:71:12)

Could you please rebase your feature branch on top of the current master and run the tests locally again?

return ds.settings[key];
}

// @TODO: Check for settings in app
Copy link
Member

Choose a reason for hiding this comment

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

Please remove per the conversation above.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@bajtos am I just removing the TODO or all of it?

Copy link
Member

Choose a reason for hiding this comment

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

Just the TODO. It would be nice if you could send a patch to LoopBack which will apply app settings to newly created datasources, but that's not necessary to get this patch landed.

@jrschumacher
Copy link
Contributor Author

@bajtos yep I'll rebase.

Regarding the settings. Shall I still get model and datasource but do it in the normalize method?

@bajtos
Copy link
Member

bajtos commented Oct 5, 2015

Shall I still get model and datasource but do it in the normalize method?

Your current approach LGTM, I left few mostly stylistic comments to address.

Added method to get settings based on priority
@jrschumacher jrschumacher force-pushed the feature-normalize-undefined-in-query branch from ef43a73 to 5c40e48 Compare October 5, 2015 21:29
@jrschumacher
Copy link
Contributor Author

@bajtos okay I think I handled all the issues you mentioned.

@jrschumacher
Copy link
Contributor Author

It would be nice if you could send a patch to LoopBack which will apply app settings to newly created datasources, but that's not necessary to get this patch landed.

I'll consider this, but its not going to be anytime soon. Also I took note of the references you mentioned, but I have to say I'm a bit at a loss exactly what you're asking me to do. Is this specific to this setting or is it for all settings?

@bajtos
Copy link
Member

bajtos commented Oct 7, 2015

Landed via 98fb3c6, thank you for the contribution!

Also I took note of the references you mentioned, but I have to say I'm a bit at a loss exactly what you're asking me to do. Is this specific to this setting or is it for all settings?

I'd modify app.datasource() to apply this specific setting only.

@bajtos
Copy link
Member

bajtos commented Oct 7, 2015

Released as [email protected]

@jrschumacher
Copy link
Contributor Author

Glad to help!

On Oct 7, 2015, 16:01 -0400, Miroslav Bajtoš[email protected], wrote:

Released [email protected]


Reply to this email directly orview it on GitHub(#725 (comment)).

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.

5 participants