So let's write a few routines to add records to or delete records from or get records from the database,
and let's think about the first one we want to do.
So I'm going to start the application.
So I'm running it.
We're now running the application is running.
Let's go to the application.
Localhost 880.
So what are some things I'm going to need to do here?
Well, obviously book now is one that I want to do and I would do my search for availability.
We'll do that one later.
Right now, let's just do a simple one.
Let's go to the Make Reservation page.
Here is a page where I am going to be posting some information and saving it to the database.
And there are things that I know I'm going to have basically when I look at my database structure by
opening the model.
So internal models, models and a reservation, everything down to here, all of this stuff needs to
be saved to the database.
This one room, which is actually a remodel, is not part of the database table for reservation, which
is called reservations.
So I need to be able to post information to my handler, pass it off to a database function and write
that reservation to the database.
So let's do that one first.
So I'm going to go back to my repository package inside DB repoll and open postcards, and I'm also
going to open the repository files.
So let's do this first will leave the all users there will come back and do something with that later
and clean it up.
But let's just write a routine that's going to write a reservation to the database.
So maybe I can just call that insert reservation and that will be a function that's going to take some
arguments.
And I could if I wanted to have one argument for every one of these things, but that would make for
a very long function.
So I'll have to put every one of those in as a parameter, it seems to me would make more sense to pass
a rez of type models reservation and return.
There's maybe one thing I'm going to return here, an error potentially.
OK, so now what?
I've added that to the repository.
Watch what happens when I try to run the application.
So I stop this there the screen and say run and it's going to fail and it's going to fail because this
is an interface and an interface is actually a contract that says, hey, if you're going to implement
this interface, which can go, you do by satisfying all of the necessary functions.
Well, my package, as it says right here in the error message, the type postgrads DB repo doesn't
implement the insert reservation method.
So we have to do that before we can compile it.
So just to make the program compiler able, let's go over here to our functions and say func M Postgrads
Repo Postcards, DB Repo insert reservation and that will take a raise which is of type models thought
reservation and it will return an error or nil if there's no error and we just say return nil.
And now that we've done this, even though we're not doing anything in this function, if I try to run
the program again.
Now it runs with no errors, so there you go.
That is an important thing to know.
You can't put functions in here and expect to have them available if you put it in postgrads.
Don't expect us to have a have this available to your application until you add its description to the
database repo interface.
OK, so what are we going to do in this function?
Well, we're going to have to obviously write a query, right?
So I'll write a query, but I'll call it a statement because I'm inserting something into the database
and that's going to be equal to insert into.
And what table in my answer to get into.
Well, let's have a look at our database structure.
We're inserting it into reservations, resins, derivations, and then describe the field you're going
to enter.
So I'm going to enter first name, last name, email and phone, first name, last name, email, phone,
start date and date, relighting start date.
And I'll just go to the next line.
End date, start date and date remedy created updated.
I got to have a comma here to.
Room I'd created at, updated at and then on the next line, I'll go with values and I'll use my placeholders.
Dollar sign, one dollar sign.
Two, how many are there?
One, two, three, four, five, six, seven, eight, nine dollar sign.
Three dollar sign for dollar sign, five dollar signs, six dollar signs, seven dollar sign, eight
dollar sign nine, and then I have to close the parentheses.
OK, so there's my statement.
Now, how do I actually execute that statement?
Well, last time around when we were inserting things into the database, we used the exact exact function
so I could actually just say if I wanted to m db dot exactly.
And then put in my statement and passing all of the arguments and I'm going to put them on separate
lines just to make this more readable, OK.
So my my first name would be read first name, my last name would be read last name and then Rezo email.
Resident phone rings resident start date resident Endi and resident remedy
and resident created at will.
If you don't want to bother doing that, I can if I want to.
But all I really care about what I'm asserting is the current time and date.
So I can just say time now and time dot now.
Oops, not a nanosecond now and that will take care of it.
What's this underlined for.
No, that's just an irritating thing.
If you don't like that underlining of the school like I don't you can get rid of it by going to goaland
if you're using goaland preferences and look for sequel school and summer here you'll find inspection's
where are inspections and look for school and just uncheck all sequels like that and say apply and OK,
because Goaland is trying to connect to my database itself.
I don't want it too.
So I just say, don't bother telling me about the fact that you can't connect to the database.
That's just an aside.
Now, this will actually work.
I can I can actually do this.
And of course, when I call this, I'm getting a result and an error.
I can ignore the result if I want to and just say error is assigned and then trap for an error.
If error is not equal to nil return error and that will actually work, there's no problem with that
whatsoever.
However, we're in a Web application and Web applications are unpredictable in one sense, for example,
the user might lose his or her connection to the Internet partway through this transaction.
And what happens then?
The user might just close their browser without warning in the midst of something that's taking place
with the database in the background.
So what we can do, what we want to have happen here, as we want to make sure that this transaction
doesn't stay open for the five minute lifetime that we have for transactions if nothing is happening.
So I'm going to take advantage of the context, something that was built in to go right around, go
one point eight, I think it was.
And it's called the context.
And we do that by at the very top of our function doing this context and cancel because I want to cancel
my context.
If something goes wrong, that's a sign, the value of context with time out.
OK, context with time out, and I'm going to pass it, a context that is always available anywhere
in your application called context dot background, and I'm going to give it a timeout and I'm going
to say, if this transaction takes longer than X number of seconds, DI, just cancel it and send a
capsule back and everything will go back to where it should be.
And I think that for our purposes, if you can't insert this transaction in three seconds, something
is seriously wrong with our application.
So I'll say three times time.
Second, which gives this a three second timeout.
OK, so now that this is here, I need to say defer.
Cancel.
That's all I need to do, except I'm not using this right now, because exactly this function is built
into the database package.
It doesn't know anything about context whatsoever, but this one does exact context.
So if I do that, the first argument is actually the context that I declared at the very beginning of
this function.
Now I have a much safer and more robust means of talking to the database.
So with virtually identical to what we did in our first experiments with the database, the only difference
is instead of calling exactly what I call exact context, and that's true for the other methods, for
ones, for updating and deleting, we can use the context there as well.
So I now have this function called insert reservation and I'll better give it a comment.
Inserts a reservation into the database.
We now have a means of storing it and that is extremely helpful.
So we can go back to our handler now and find the handler that does post reservation right here.
And instead of just building this, we're going to have to change our form.
I'm also going to want the start date, the end date.
And what other information am I putting in there?
I can't remember now.
So we have the first name, last name, email, phone.
We need the start date, the end date and the room ID.
The other two are created with our time now, which you shouldn't search the current date and time into
it.
So we'll have to change our form.
We can do that afterwards.
Let's just fix our handler.
So start date and end date, OK?
Now these are a little bit different because we're receiving our date as a string and we need to convert
it into the format that our model expects.
For example, if I try this, if I just say start date is ARG form doget start date, which doesn't
exist yet.
But it will it's going to it's going to die.
It says, well, hang on a second here.
Cannot use our form arget start date, which is type string as tight time dot time.
So what I need to do is get our start date and end date which I can do.
Like this SSD is a sign the value of that and ID for end date is a sign the value of end date.
I can store those strings right here and then I need to cast those strings over to a time.
Time now.
One of the things that I know I'm going to get my date formatted is going to come something like this
20-20 zero one zero one.
That will be the format that I get my date in my starting date.
Am I end it the way that Go handles dates and times is a little unusual and it might seem a little non-intuitive
at first.
Certainly I have to look this up almost every time I go back and work with dates.
So let me go over to my Web browser or I have open this blog post and I'll put a cop up, post a link
to this right on to the resources for this page.
This is how you pass and format dates and times Engo and if you look at it go takes an interesting approach
to parsing strings to time objects and formatting objects at strings.
And you can follow that link and it gives an example there, but it uses a non-standard reference time
engo.
The reference date and time are Monday, January the 2nd, at four minutes and five seconds after three
o'clock in the afternoon Mountain Standard Time in the year 2006.
And the reason they've gone with this is because using the standard method of writing dates in America,
it goes as follows zero one zero two zero three zero four 05 06 for 2006 and minus seven GMT for Mountain
Standard Time.
And apparently that's an easy way to remember dates.
It might be for other people.
It's not for me.
I have to look it up every time, so don't feel bad if you have to look it up as well.
Now, to convert our string to a time, it's a relatively straightforward approach once you know the
format.
So I'm going to copy this format here like this and just paste it in my comment like this so I have
a reference to it, OK?
And I need to do what I need to do is to describe the format that my date is coming in, using this
as a kind of reference.
OK, so I can do it as follows.
What I'm going to do is describe a layout and the layout will be a string that describes my date format
and the format I'm getting my date in.
The string that I'm receiving from my form will be in the form of the year and a half to use 2006 as
a reference here, followed by the month, which is zero one in the reference time, followed by the
date, which is zero two in reference time.
That's the format I'm getting my date in.
OK, now I want to pass SD and ID from what they are into times and I can do that as follows.
I can just say start.
Date and then potentially an error is assigned the value of time, don't pass my layout and the date
I want to pass, which is SD for start date, OK, and I can do the same thing for end date.
But it's not start date, this case, it's ended up passing and then need to for my errors, if error
is not equal to nil, then what do I want to do?
Helper's dot server error and an error.
So I'll just call my server error and the same thing here.
Now that I have the start date and end date, I can actually populate my model with start date and end
date.
Which will be ended.
OK, the last thing I need is my remedy and again, remedy in our model is actually an INT, so I need
to convert what I'm going to get from the form.
And I'm not passing that yet and I'm aware of it.
I need to convert that from a string into an ENT.
That's again, not that difficult.
So I can just say room ID is assigned and er potentially an error is assigned the value of and I use
a built in package as part of the standard library sirc invis sterkel a for alpha to integer and the
string and the string I'll get from my form as adon form dot get room ID.
I'll assume that's going to be the name of the parameter the past.
Just as I'm assuming the name of the parameter I'm going to get for start date is start underscore date
and end date and underscore date.
Once I have this I get an idea from my error.
Once I have this I could use my remedy like this room ID is remedy.
All right.
Now that I've built this reservation model, what I actually want to do is after my form validation,
making sure all of this is accurate, after my form validation, I actually want to write this information
to the database and I can do that by going m db dot insert reservation and passing in my reservation,
which I called reservation.
And of course this handles an error to us.
So I can say error equals.
If error is not equal to nil, then helper's that server error W and hair and that while she said that
to our database, so we can't test this until we actually go update our form, but we can do that and
we'll do it and we'll just put some some default values in there to make sure that it's working the
way we want.
And we'll test that and we'll do that in the next lecture.