So I'm still in the file handlers dot go inside the cmd API folder.
And right now we want to work on this part, validating the user against the database.
Now that requires a couple of things.
As I said last time, we have to have some method here in our repository.
Something may be called get user by email and we want it to return a user and potentially an error.
But if you look over at our models folder in internal models, we only have one file here, moviegoer.
We don't have one for users.
So before we can do anything, we better define the user type.
So let's create a new file inside the models folder and I'll just call it user.
Go.
And this is in package models.
And we'll define a type type called user.
And it's a struct.
And the fields in this struct will match what's in the database.
And if you look in the database, of course we have a user's ID, which is an INT and in JSON because
we're going to be sending this back as Jason Jason, possibly we'll call it ID.
And the user has a first name in a last name.
So first name type string.
And in JSON, we'll call this first underscore name and then I'll duplicate it and call this one last
name.
Last name.
And in JSON, we'll call it last underscore name.
And then I'll duplicate it again.
This user has an email address.
We'll call it email.
And in JSON, we'll call it email and we'll duplicate it one more time.
And this one's called Password.
Even though it's not actually a password, it's actually a hash of a password, but I'll call it password.
And we have two more.
So one to the first one is called created at which I have to spell write created at.
And in JSON that's not going to be handed back at all.
So we'll use a hyphen.
And we have updated that.
And that's going to be a hyphen as well.
So let's save this to format it.
There is a structure we can store users in.
So the next step is to go over to Postgres underscore DB repo, which is in the internal folder in repository
in DB repo, this file right here and I have it open.
So I'll scroll to the bottom of this file and I'll create a new function which I'll call func with a
receiver m pointer to try that again.
Pointer to postgres db repo.
I'll call this one, get user by email and it requires one parameter which I'll call email of type string.
And it's going to return.
I'll return a pointer to models dot user models, dot user right there.
And it's also potentially going to return an error.
So.
We're going to need the context.
So just to save some time, I'll scroll to the top of this file or this function right here, and I'll
copy the context, context, logic, because I often mistype that and this will avoid that.
So now we have a context and we write a query, and the query is assign the value of and it's really
simple select.
I'm going to select ID, email, first underscore name, and these are what they're named in the database,
of course, last underscore, name and password and then a comma.
And on the next line I'll just tab in a bit and say created, add and updated as from users where email
is equal to dollar.
Sign one.
So that's our query.
Now, of course, we need to have a variable we can read our queries results into, so I'll declare
a var user of type muddles user and then I'll get my role when I call from the receiver.
M, dot db dot query row context.
We're making a query that returns at most one row and it requires the context which I defined there
in line 67 and the query and the substitution for that dollar sign, one which is email.
It's just the parameter I received as a call to this function.
So now I have a row so I can check for an error and let me give myself some room here.
I can check for an error when I call row dot scan and I'll put this on separate lines so it's more readable.
I'm going to read the first return value into user ID and then I'll duplicate this a few times just
to save some typing.
The second one is email.
The third one is first name, the fourth one is last name, the fifth one is password, the sixth one
is created at and the seventh one is updated.
And then we have to check for an error.
So if something went wrong, if error is not equal to nil and I return nil because I don't have a user
to return and because it's a pointer to models user, I can return nil and the error.
But if I get past that then I return.
I can't just return the user.
I have to return a reference to the user because I'm returning a pointer and nil.
So now I have this function get user by email, but I can't use it yet even though it exists in postgres
underscore db repo.
Remember I have to copy the entire function signature right here and go over to the file repository.
Go and tell this repository interface that this method exists.
So now I have the necessary function in postgres db repo, I have the necessary type in the file user
dot go and I've added the function signature to my repository, my database repo repository, which
is an interface which means I can go over to handlers dot go and I can try to validate the user against
the database just to make sure the user exists.
So what I'll do is declare a variable user while checking for an error when I call that function.
We just wrote app dot db dot get user by email and of course the email is now in request payload, which
I have to spell write request payload dot email and we'll check for an error if the error is not equal
to nil and I could not find that user in the database.
So I'll return app error JSON and I'll give it the response writer and I'll create an error errors dot
new and all I'm going to tell them is invalid credentials.
I don't want to give them too much information.
You tried to log in, it didn't work.
And again, I'll put in HTTP status bad request, even though I believe that's what it defaults to.
And I don't want this to go any further, so I'll just return.
We're done.
That part.
The next part is to validate the user's password.
And right now I have this user variable, which I'm not using, so my ID is helpfully telling me that
I can't compile the code because I have user declared but not used.
But what we'll do in the next lecture and we'll leave the code in a broken state at the end of this
one, just so you're aware of it.
What we'll do in the next lecture is we'll write a simple method attached to the user type that allows
me to verify that or validate the user's password, and we'll get started on that in the next lecture.