So we have a driver package set up, and now it's time to use that driver package to connect our application
to the database, and we're going to do that using the repository pattern.
So we already have one repository, if you recall.
And if we look at our main go file, we can see where that is.
And that's way down here where we create a new repository and that calls Handler's new repo.
And what we're going to do is add something to this repository, which is itself a repository, because
our my goal here is to set up my application in such a way that right now I'm going to use postgrads.
But if down the road I want to use, say, my as well or Maria DB or Oracle or some other database,
I can do so.
And when I make that change, I change as little of the application as possible.
And the repository pattern is ideal for that particular situation.
So what I'm going to do is I'm going to create a new package and I'm going to do it on my internal I'm
going to create a new package.
So I'll just create a new directory, which will be a package.
And I'm going to call that repository.
And inside of that, I'm going to create another package, so inside of the repository directory, I'll
create another directory which I'm going to call DB Repo, and at the root level of repository, not
inside the DP Rebo DB repo, but inside the repository folder.
I'll create a gopher and I will call that repository Dongo.
And I will add that to get and that file right now is very, very simple.
I'm just going to create a type in here, an interface type, and I'll call it database repo, which
is an interface, and right now it will be empty, will add something to that in a little while.
And inside of the DB repo folder, I'll create a new file.
And I will call that, not surprisingly, debri pogo, and I will add that to get as well.
Now inside of here, I'm going to create a type and that type will be the repository itself and the
type will be called Postgres Divi Repo.
And it's a struct and it will hold two things.
It will hold up an app, which will be a pointer to our config app config.
So it's going to hold that and it's also going to hold a database connection pool, which, as you know,
is a pointer to four postgrads of sequel.
DeeVee So that's a type which I'm currently not using.
Now I'm going to create a new function.
And just as we did with our other repository, this is created using a function which I'll call new
postgrads repoll.
And it will take a parameter, actually a couple of parameters, one I'll call Con because it's a connection
pool and it's a pointer to sequel DB and the other one is a and it's just a pointer to our config config
and it's going to return a repository database repo.
But our spell repository.
Right.
And just as we did with our other repository, we'll just return a reference to Postgrads Divi Rebo
and of course, that has to take two arguments in order to be populated at which we have as a parameter
we're passing here A and our DB, which will be our connection pool.
All right.
So now I have a means of passing this function, our connection pool and our app config and returning
a repository.
And because I'm now initializing this using new Postgres repo, it will be a connection pool that has
Postgres connection pool.
If I wanted to have another database, I would simply create a new type say type MySQL DB repo, which
would hold whatever is required for that are up configuring a connection pool for for my school.
And I'd create a new function called func new MySQL Repo and create that.
So now I have a means of swapping out my database very, very quickly.
All right.
So this is created now.
What am I going to do with this?
Well, let's go back to our main file.
May not go and down in the run function.
I want to initialize my database here.
I want to actually initialize my database repo.
And I can do that pretty easily.
I could say right after this Aptos session, I can just say connect to a database and what am I going
to do?
I'll write to the terminal log print line connecting to the database just to get some feedback and then
actually do the connection.
So I will call DB error, I'm going to get my connection pool and I get that from my driver package
that we created in the last lecture.
And the math on that is Connect sequel.
And then we have our DSN and our DSN.
I'm going to hardcoded right now.
We'll change that before we're finished with this project.
But right now I'm just going to hardcoded just to get it working.
So we'll do it just like we did in our last hour.
Test database application post equals localhost port equals five, four, three, two.
DB name is equal to bookings.
I think that's what I called it.
We'll find out in a minute.
User equals ticks and of course your username will be different and my password is currently empty.
So I'll just put a password in that I can leave it out, but eventually you're going to be connecting
to a database that has a password.
So we may as well take that into account right now.
So that will do our connection.
Then we test for our error.
If error is not equal to nil, what do I want to do?
I'll I'll just log fatele because if I can't connect to my database, bad things are happening and I'll
print the message.
Cannot connect to database dying because I'll die with that log fail.
Now that I have this connected, I have my database connection pool.
What am I going to do with it?
Well, if you recall, one of the things that I said we should do is close it when we're done with it
so I could write deferred DB Forclose DB dot SQL close.
But if I do that, what's going to happen?
I'm actually in a function called Run, which is called up here.
Very first thing I do in my main function is call that.
So if I open my connection to the database and then put defer close and then the run function is finished,
it will close the database connections immediately after the run finishes, which you know is no good
because I'll close my database connections right after opening them.
So that's not going to be helpful.
So what I need to do instead is have this not here, take it out and have this run function return more
than a potential error.
So I'll have it return.
What shall I have it return.
I shall have a return.
My driver DB So it's a pointer to driver DB and an error.
So now I got a few things to fix down here.
I can't return nothing.
Return just the air.
I have to return nil in the error because I couldn't create it.
Just die at this point and down here I'll return my DB so that will take care of the errors for the
run function.
But up here I can't just er have er equals run.
Instead I say db and error equals run and I'm not using DB right now, but if I get past this then I
want to defer DB sequel Duclos and now the database connection won't be closed until the main function
itself stops running, which means the application is stopped.
So that's very good.
So I've actually got this database connection right now, but I'm not doing anything with it and I need
to do something with it.
So what shall I do with it?
Well, back down here in the run function.
I need to ensure that my database connection is available and certainly to my handlers, possibly something
else, but certainly to my handlers.
So over in our handlers, what I'm going to do is change this repository and have it hold another repository.
So what am I going to put in here?
I call it DBI because of the database connection and it's a type repository that, again, repository
database repo.
And down here I'll actually accept a second parameter and it will not be a repository.
It will instead be a DB, which is a pointer to driver DB and I'll have to pass that in the main function.
But we'll do that in a minute.
And now I will populate my DB repository, not with DB because it's not a repository.
That's a pointer to driver DB.
Instead, I'll call that new pupi new postgrads repo function that I made in my DB Repo Golfo.
So I call DB Repo.
Debbie Repo new postcrisis repo, and it requires our connection, which is Debe, and it requires our
config.
So put that in there as well.
Probably don't need up config there, but it's not going to hurt.
It's not DIVI, it's DB DOT sequel there.
Now that matches the correct type.
So what I've done here, when I call New Repo, I'm going to pass it my app config, which is a pointer
to configure config.
I'm going to pass it in my database connection pool, which is a pointer to Driver DB which holds my
database connection pool.
And then I populate this repository type up here with all the information I received as parameters and
hand that back as a pointer to repository.
So I've created that.
Now we need to go back to our main function and you'll discover that we have an error.
And the error is I need to pass that second parameter, which is DB, and that should create our repository.
So with that one change, I think about what I've done here, I've now created this handlock, this
repo that I'm going to use in my handlers.
We have our application config available to all of our handlers and we can put whatever we want in there.
And we've also passed it.
This DB, which is not a database connection pool tied to a specific database.
Instead, it's a pointer to a driver.
And that driver can right now only handle postgrads.
But I can very easily, just by creating a new instance, a new a new function instead of new my new
postgrads, I can create a new MySQL function so I can have this repository for the handlers, hold
a repository that's of a type for Postgrads or MySQL or Oracle of Mongo DB or whatever I want.
Now let's see how this is all going to work.
You recall a little while ago, first of all, let's make sure this runs and run my application.
Okay, compile.
That's good.
I'm going to put one more log in there just to say that I actually connected to the database.
So log print line connected to database.
All right.
Again, just to get some feedback, so I'll clear the screen and run it again and everything past.
Good.
All right.
So now that I've done this, how can I use it?
How can I put some methods or some functions available to this repository for the database that I've
created and passed right here?
How can I actually use some functions in there?
Well, you may recall we have this interface that's of type database.
It's a type database repo.
That's an interface.
I'm going to create another file inside of the DB repo folder and I'm going to call it Postcrisis Dargo.
And here is where I will put any functions that I want to be available to that interface.
So I'll create a function, I'll call it, and it has to have a receiver and I'll call the receiver
for model.
And it's a type postgrads DB repo which links it to my postgrads repository and I'll call it all users.
And it's right now it's not going to take any parameters and it's just going to return a bool.
This is going to change.
This is just to show you how it works and I'll just have this return.
True.
So I've defined this all users function that has a receiver of postgrads DB repo.
So what I'm going to do is copy the function name and its return type and I'll paste it right into my
repository.
Now that I've done that, now that this function is listed in the interface and the function exists
with a receiver of postgrads DB repo and the function exists exists exactly as it's defined in the interface.
Now I can go to my handlers and I can choose any handler, say, the home function, for example.
And on that repository, I don't have access to the DB and I can call all users.
And that is really, really cool and very useful because all I have to do what I want to add new functionality
to that, be a member of the repository.
I'll get rid of this because we're not going to use it here.
All I have to do is defined my function in here with this receiver and add it to the repository.
And I have access to all of my database functions which will be writing in the in the coming lectures.
I have access to all of them right in my handlers just because I created that repository that holds
a database repository.
All right.
So in the next few lectures, we'll start thinking about what we need to be able to do in our database,
and we'll write some functions and then we'll update our handlers to use those functions.
We're getting closer.