All right.
Next up, let's go ahead and modify our abstract schema, which right now is representing the abstract
document in the mongoose world.
Let's go ahead and start off by renaming this.
So instead of abstract schema, we're going to create an abstract entity, which is the same thing as
a document or schema in Mongoose so we can remove the schema decorator and the ID property.
Let's change the name to abstract entity and remove these imports to mongoose.
Now I want to add just one property called ID of type number, which is going to represent the primary
key of all our entities in our application.
So since this is a primary key, this is going to be a unique value that automatically increments each
time a new entity is created in that given table.
So let's go ahead and mark this as the primary generated column to indicate this.
So in type ORM, to actually save these entities to the database, we're going to actually be instantiating
new instances of this class, the abstract entity which we didn't have to do in mongoose.
So in order to make this easy, we'll go ahead and supply a common constructor that we can use when
we want to create a new entity out of a subset of properties that exist on that entity.
So in the constructor we'll take in the partial entity which will be of type partial, and then we'll
take in a T here.
So the abstract entity also takes in that T, and then inside the constructor we'll call object, dot
assign and reference this and then the entity.
So what this is going to do is it's going to take all of the properties on this partial entity being
provided to the constructor and assign them to the abstract entity, which just means that all the properties
that get passed in the constructor will be copied over to the newly created instance of this class,
making it very easy to create new entities.
We will see how this works in practice soon when we start saving entities.
So now that we've defined the abstract entity, let's go back to our abstract repository where of course
we can see it's having an issue because the abstract document no longer exists.
Let's refactor this abstract repository to move away from mongoose and instead work with type ORM.
So all of the repositories in our microservices will get this functionality.
Okay, so to start, let's remove this import to the abstract document.
And now in the abstract repository, instead of extending the abstract document here, let's change
this to be t extends abstract entity which we've just created and then pass in the t to this abstract
entity.
So this T here is going to be the entity that the.
Subclass of the abstract repository will be passing in, which will be extending the abstract entity.
We're going to keep the logger the same.
And now in the constructor, let's change this out to no longer take in a model.
Instead, we're going to go ahead and inject two separate dependencies to allow us to interact with
the SQL database.
The first is going to be private read only entity repository, and this is going to be of type repository
from type ORM, and we can pass in the T to get some type information around it.
So this entity repository is what we're going to be using to find different entities in the database
and get some type information around our queries, which is very similar to the model that we worked
with with Mongoose.
So additionally, we're also going to inject a private read only entity manager of type entity manager,
and the entity manager is going to allow us to save entities in our database using instances of the
entities that we've created.
So let's go ahead and get started with the async create method.
So now instead of taking in a document, we're going to be taking in an entity of type T, and we're
going to return a promise of type T.
Now we can remove everything in the create method and all we're going to do is simply return this dot
entity, manager, dot save.
And you can see here that this will save all of the given entities in the database.
If they don't exist, it will insert, otherwise it will update these entities.
So in a sense this will be doing an upsert for all the entities that are passed in.
So we'll pass in the entity and now we can create new entities in our database.
Let's move on to the find one method.
So let's get rid of the filter query as a parameter.
And our first parameter is going to be called where and this is going to be our where clause or our
query.
So this is going to be of type find options where from type ORM and we'll pass in the T as well.
So let's replace this line here and instead of getting a document we'll call const entity is equal to
await this dot entity repository dot find one.
And here we pass in an options object where we pass in that where clause which is going to allow us
to match a simple condition that's applied to match entities.
So now that we have this entity pulled back from the database, let's go ahead and check to see if it
exists.
So if the entity doesn't exist, we will say entity not found with where, and then we can provide the
where clause.
Let's also go ahead and change the promise Ms. of t document out with just a promise of type T And then
lastly, we're going to go ahead and return the entity instead of the document.
Also go ahead and change the not found exception to be an entity not found.
So now we have a find one.
Let's move on to find one and update.
This is going to look quite similar.
We'll take in the where clause which is find options where.
And then for the update parameter, we'll change this to partial entity, which is exactly what it's
going to be.
It's going to be a partial subset of our entity, which we want to update.
So this type is going to be called query deep partial entity and pass in our type of T.
So essentially this is going to be a subset of properties that exist on our entity that we want to be
updating.
And so we'll go ahead and change our update expression to a new const called update result.
And we'll set this equal to await this dot entity repository dot update.
And here we'll pass in our where clause as the criteria to find the entity to update and then we'll
pass in the partial entity.
So next, let's check to see if the update result Dot affected, which is going to be the number of
affected documents by the update statement is zero.
So if this is zero, which is what this expression will check for, then we want to warn that the entity
was not found with where and pass in our where clause.
We'll also change the exception to entity not found.
Then in order to get the most up to date entity, we'll return this dot find one which is the method
in this abstract repository and we'll pass in the same where clause to get the most up to date version
of this entity after the update was applied.
So lastly, these two remaining methods find and find one and delete are going to be very simple.
Async find is going to take in a different parameter here that we'll call where as we've done before,
this will be find options where as we are used to, we pass in the type of T and then we're simply going
to return this dot entity repository dot find by and pass in the where clause which is going to allow
us to find multiple entities that all match this where clause.
And finally, for find one and delete, we will have the where clause which is going to be find options
where of type T and instead of returning the deleted result we are going to call await this dot entity
repository, dot delete and pass in the where clause.