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

Preserve custom type of auto-generated id property #4270

Merged
merged 1 commit into from
Feb 18, 2020
Merged

Preserve custom type of auto-generated id property #4270

merged 1 commit into from
Feb 18, 2020

Conversation

frbuceta
Copy link
Contributor

@frbuceta frbuceta commented Dec 6, 2019

Implements #3602

Checklist

👉 Read and sign the CLA (Contributor License Agreement) 👈

  • npm test passes on your machine
  • New tests added or existing tests modified to cover all changes
  • Code conforms with the style guide
  • API Documentation in code was updated
  • Documentation in /docs/site was updated
  • Affected artifact templates in packages/cli were updated
  • Affected example projects in examples/* were updated

👉 Check out how to submit a PR 👈

@frbuceta
Copy link
Contributor Author

frbuceta commented Dec 8, 2019

Can someone help me with the test? It seems not to be happening correctly

@derdeka
Copy link
Contributor

derdeka commented Dec 11, 2019

Can someone help me with the test? It seems not to be happening correctly

The changes looks reasonable to me and local unit test works successfully.

TASK=test-repository-mongodb and TASK=test-repository-mysql fail in travis ci.
The useDefaultIdType=false seems not to be used by the juggler.
For mysql the following ddl is still created:

CREATE TABLE `User` (
`id` TEXT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`name` VARCHAR(512) NULL,
`roles` TEXT NULL,
`address` TEXT NULL
)

Type TEXT ad AUTO_INCREMENT are not a valid combination.

@frbuceta
Copy link
Contributor Author

Can someone help me with the test? It seems not to be happening correctly

The changes looks reasonable to me and local unit test works successfully.

TASK=test-repository-mongodb and TASK=test-repository-mysql fail in travis ci.
The useDefaultIdType=false seems not to be used by the juggler.
For mysql the following ddl is still created:

CREATE TABLE `User` (
`id` TEXT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`name` VARCHAR(512) NULL,
`roles` TEXT NULL,
`address` TEXT NULL
)

Type TEXT ad AUTO_INCREMENT are not a valid combination.

I certainly did not know that I took code from outside the repository to test, thanks for your help.
As always here I am constantly learning

@@ -106,6 +106,11 @@ export class ModelDefinition {
const definition = (definitionOrType as PropertyDefinition).type
? (definitionOrType as PropertyDefinition)
: {type: definitionOrType};

if (definition.id === true && definition.generated === true) {
Copy link
Member

Choose a reason for hiding this comment

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

To be safe, I am proposing to extend this check to apply useDefaultIdType: false only when an explicit type is provided.

This property should set useDefaultIdType: false:

@property({
  type: 'string',
  id: true,
  generated: true
})
id: string;

This property should NOT set useDefaultIdType: false:

@property({
  id: true,
  generated: true
})
id: string | number;

Thoughts?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, it seems right to me. I just implemented it

@bajtos
Copy link
Member

bajtos commented Dec 13, 2019

Thank you @frbuceta for the pull request, this is great!

Type TEXT ad AUTO_INCREMENT are not a valid combination.

Yeah, this is a problem we have recently discovered too, see #2398. I think we need to fix our connectors to correctly support auto-generated string ids (primary keys) before we can move forward with this pull request.

@agnes512 you were looking in to #2398, what do you think?

@bajtos
Copy link
Member

bajtos commented Dec 13, 2019

TASK=test-repository-mongodb and TASK=test-repository-mysql fail in travis ci.
The useDefaultIdType=false seems not to be used by the juggler.

On the second thought, I think this is a bug in the way how our shared test suite is creating models.

The way how this test suite is supposed to work, is that the connector specifies what type is used for primary keys (number vs. string) and the test suite honors that type when defining new models.

I suspect the code building User model is not taking into account database-specific type and always uses string.

AFAICT, User.id property is defined here:

https://github.com/strongloop/loopback-next/blob/4995057ad4c938d6751c329632eb44130ac1567a/packages/repository-tests/src/crud/nested-model-properties.suite.ts#L91-L95

Here is the correct definition of the PK property in a different model:

https://github.com/strongloop/loopback-next/blob/4995057ad4c938d6751c329632eb44130ac1567a/packages/repository-tests/src/crud/create-retrieve.suite.ts#L36-L42

I think we need to add type: features.idType to User.id definition, that should hopefully fix the problem you are observing.

@agnes512
Copy link
Contributor

AUTO_INCREMENT can only apply to type INT. And generated along with useDefaultIdType are not enough for auto-generate string type attribute. We need to rework at connector level to allow so.

I am working on Postgres: allow string type attribute to be auto-generated . That PR is proposing to use uuid_generate_v4() as a default function once the model is set to:

  @property({
    id: true, //optional
    type: 'string'
    generated: true,
    useDefaultIdType: false,
    postgresql: {
      dataType: 'uuid',
    },
  })
  id: String;

I've tested it locally, this solution works in repository-tests with postgresql.

Once it's done, we can rework the MySQL connector with a similar solution. Please share your idea there if you have any 😄

@derdeka
Copy link
Contributor

derdeka commented Dec 13, 2019

That PR is proposing to use uuid_generate_v4() as a default function

What if someone wants to have a different generator function? (e.g. different UUID version or database extension, different function name)
I think the ddl generation should respect the defaultFn if present.

@agnes512
Copy link
Contributor

agnes512 commented Dec 13, 2019

What if someone wants to have a different generator function? (e.g. different UUID version or database extension, different function name)

That's doable. It will be user's responsibility to provide valid extension and defaultFn.
And if the extension and defaultFn are not provided at the same time, it'd use uuid_generate_v4(). @derdeka WDYT?

@frbuceta
Copy link
Contributor Author

TASK=test-repository-mongodb and TASK=test-repository-mysql fail in travis ci.
The useDefaultIdType=false seems not to be used by the juggler.

On the second thought, I think this is a bug in the way how our shared test suite is creating models.

The way how this test suite is supposed to work, is that the connector specifies what type is used for primary keys (number vs. string) and the test suite honors that type when defining new models.

I suspect the code building User model is not taking into account database-specific type and always uses string.

AFAICT, User.id property is defined here:

https://github.com/strongloop/loopback-next/blob/4995057ad4c938d6751c329632eb44130ac1567a/packages/repository-tests/src/crud/nested-model-properties.suite.ts#L91-L95

Here is the correct definition of the PK property in a different model:

https://github.com/strongloop/loopback-next/blob/4995057ad4c938d6751c329632eb44130ac1567a/packages/repository-tests/src/crud/create-retrieve.suite.ts#L36-L42

I think we need to add type: features.idType to User.id definition, that should hopefully fix the problem you are observing.

I've tried this but it doesn't work. Right now with the only one I have problems with is mongo.

if (
definition.id === true &&
definition.generated === true &&
definition.type === 'string'
Copy link
Member

Choose a reason for hiding this comment

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

I am afraid we misunderstood each other. Here is what I meant:

Suggested change
definition.type === 'string'
definition.type !== undefined

Either way, please add a new test to verify that useDefaultIdType is not set when definition.type was not provided (and was not inferred from TypeScript metadata either).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There is no model in the tests of the type as undefined, how should I generate a model with these features?

packages/repository/src/model.ts Outdated Show resolved Hide resolved
@bajtos
Copy link
Member

bajtos commented Jan 7, 2020

TASK=test-repository-mongodb and TASK=test-repository-mysql fail in travis ci.

On the second thought, I think this is a bug in the way how our shared test suite is creating models.
I think we need to add type: features.idType to User.id definition, that should hopefully fix the problem you are observing.

I've tried this but it doesn't work. Right now with the only one I have problems with is mongo.

Hmm...

@agnes512 IIRC, you were dealing with similar issues recently, while working on inclusion resolvers. Can you please help @frbuceta to find a way how to make repository tests pass against MongoDB?

@frbuceta
Copy link
Contributor Author

frbuceta commented Jan 7, 2020

Thanks for your help @agnes512

});
const order = await orderRepo.create({
description: 'an order',
customerId: parent.id,
});

const result = await customerRepo.find({
include: [{relation: 'orders'}, {relation: 'customers'}],
Copy link
Contributor

Choose a reason for hiding this comment

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

While I was fixing the CI failure, I think the flag might somehow break how we deal with ObjectId in MongoDB. Before we were able to traverse related instances with ObjectId. Not sure it has something to do with the type.

@achrinza achrinza added the Repository Issues related to @loopback/repository package label Jan 19, 2020
@bajtos
Copy link
Member

bajtos commented Feb 17, 2020

@agnes512 @frbuceta what's the status of this pull request? I see that the CI is green and the code looks reasonable, even if not all edge cases may be covered by tests. Should we perhaps proceed to land the changes as they are now?

@bajtos bajtos removed their assignment Feb 17, 2020
@agnes512 agnes512 merged commit dc7ff7f into loopbackio:master Feb 18, 2020
@frbuceta frbuceta deleted the feat/preserve-custom-id-type branch February 27, 2020 00:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Repository Issues related to @loopback/repository package
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants