Welcome back, everyone, to the DriveSinker project. In the previous video, we built a couple more functions in the tracker implementation over here. We built the `walkProjectTree` function. This is going to walk the entire project tree on Google Drive and build a mapping of every single file and folder on Google Drive with our local files and folders.
We also fixed a major issue in the subfolders implementation that we had before, where we were using the subfolder name instead of the subfolder path, and that was introducing a couple of bugs in our program. And so we fixed that, and we also built this `mapSubfolders` function over here to make sure that we're reusing subfolders that already exist on Google Drive.
Now we're like 80 to 90% done with this new sync algorithm that we've been building for the last couple of videos, but there's still a couple of more things we need to implement. So right now, we use the project tree function and the `shouldUpload` function over here to check whether we should upload new files or not, right? To upload new files that have not been uploaded yet.
But we're not overriding any files, even though we use the `shouldUpload` function over here to compare the file checksums and see whether we should upload the file or not. We're not overriding the file. We're creating a new file. We're uploading a new file.
If the checksums don't match over here, then we'll get `shouldUpload` equals true, right? And then we'll upload the new file over there instead of uploading or instead of overwriting the existing file on Google Drive. So that's one thing we need to fix. We need to overwrite existing files with new changes instead of creating new duplicate files, right? That's one thing.
And the second thing is we need to delete ghost files. Now, ghost files, ghost files are basically just files that have been left on Google Drive, but they don't have a replica on our local machine. So basically, if I upload my entire project over here to Google Drive, and then let's say I delete a couple of files over here, right? They would not get deleted on Google Drive, not with our current implementation. They would just end up being ghost files that just sit in the project on Google Drive, not doing anything at all, right?
And so to fix that, we need to also make sure that we delete ghost files from the project every time we sync. So depending on how much time I have in this video, I going to implement all of these things, and hopefully we can keep the video shorter than, like, 10 minutes. I try not to go longer than that. But with all that being said, that was my intro. Let's get started.
First thing I'm gonna do is just make sure that everything in my Google Drive is empty and we're starting fresh. I'm gonna upload everything to Google Drive. Okay, and since my Google Drive is empty right now, this is going to upload every single file and not skip anything. So we're going to let that run for a bit.
The first thing we're going to implement is overriding existing files. And to do that, we're going to go to `api.sync.go` down here in the `walkthrough` function. We're going to go down, down, down where we upload files here in our upload file function. This is where we actually create new files and upload the file contents, right? And this is where we actually have to implement overriding the existing files.
First of all, let me just move all of the file opening stuff up here at the very top. And then let me just create a query over here to search for the file that already exists. So we've done this plenty of times, guys. You should know how this works by now.
`fmt.Sprintf` name that's not name wrapped in single quotes is equal to this and the parent name over here wrapped in single quotes in parents and trash equals false. And then let's pass in our arguments over here. We want to pass in the name of the file and also its parent ID, which we get in the arguments up here. So we can just use that.
And I'll even, I'll even add a comment over here saying something like, "If it already exists, overwrite it."
Now we're going to use this query to search for the file if it already exists, right? So let's do `drive.api.files.list.q`, passing the query, dot page size. There we go. And this will be one, and then `.do` to run the entire thing. And then let's create a variable to hold this. I'll call it `searchResp`.
And of course, before anything else, make sure to handle the error. If there is an error, let's just return it and let the caller decide how to deal with it.
Now let's see if a file actually exists, and to do that, we can just do if length `searchResp.files` is equal to one. And then we can add a log over here and say something like, "File," and then the file name, "already exists. Overriding." Just so we know what's going on, right? And of course, make sure to add a new line as well and pass in the file name over here.
Or actually, instead of the file name, we can actually just pass in the path, and that will probably be a lot better because the file names can be duplicates, right? But the path is going to be unique per file, so let's pass that in instead.
And then let's fetch the, fetch the actual file on Google Drive. I'll call it `driveFile`, and this will be `searchResp.files` and then the first element in here. And then let's create a new file with new metadata. This will be a reference to `drive.File`, and this will just be empty over here.
And then I'll say if underscore error equals `drive.api.files.update`, and here we need to pass in the first of all, the file ID of the file we're trying to update. So that, I guess, is going to be `drive.driveFile.ID`. And then we need to pass the new metadata of the file, and that's just going to be `newFile`, right? We're not changing any of the metadata, so this is just an empty `drive.File` struct over here because I'm not changing any metadata. I don't want to change any metadata. I just want to update the file content, right? Like the raw bytes in the file.
So we're going to pass in `mediaF`. That's the file that we have open up here. And then we'll say `.do` to run the entire thing. And we'll say if error does not equal to nil, then for now, I just want to print the error on screen, not log it, but just print it if there is an actual error. Then I can actually see it on the screen, and we'll also return the error. There we go.
And then over here, if everything went smoothly, we'll just return nil. Otherwise, over here, if the file doesn't exist, then we'll just create a new one, right? We'll create the file metadata, we'll upload it on Google Drive, and everything just like we did before, right? But if the file already exists, then we're going to update the file contents directly, right? We're going to overwrite the file, and that's pretty much all we need to do to implement the overriding functionality.
And by the way, the project upload has already finished that we started at the beginning of the video, and all of the stuff over here has been updated.
Let's actually do some testing over here. Let's try to upload the entire project again and see if it works perfectly or not. Now, since we have changed pretty much nothing in this application except for the sync and tracker files, I guess it should not upload any new files except for the `sync.go` file because we actually added some new code over here, right? In this upload file function.
And you can already see it says, "File sync.go over here already exists. Overriding." And we can actually go over to the project on Google Drive in `api/sync.go` and see if it actually did that.
So this is the `sync.go` file. This is the code over here. If I keep scrolling all the way down to the upload file function, you can see it actually added all of the new code over here as well, right? Maybe I should zoom in so you guys can see. Oops, I think I just zoomed in a bit too much, but yeah, you can see that in the upload file function over here, it added all of the new code as well that we just wrote literally just now, right? Is that not amazing?
So as you can see, overriding files works. You can literally make changes to the files over here, and then you can upload the project onto Google Drive, and it's going to overwrite the files with the new code that you've written. So this is amazing, and we've already done like some of the work over here.
Now the next thing I wanted to build was functionality to delete ghost files. Now sadly, the video is getting a bit too long as well, so I'm gonna have to stop over here. I'm trying to keep every video in like the 10 to 15 minute range. As you can see, we're about to go past that now.
So I'm gonna stop recording over here, and in the very next video, we're going to build the delete ghosts functionality. So I want to be able to delete the ghost files if I delete some files in my local project. I do not want to see them in Google Drive just taking up empty space, right? We're going to build all of that stuff in the very next video.
But, um, thank you for watching this one, and I hope you learned something new. This was a very short video, I guess. We just built the overriding files functionality. So if you enjoyed this, press like. If you want to subscribe, press subscribe. Guys, we're going to be building all sorts of cool stuff on this channel. So if you haven't subscribed already, go make sure you do that. Scroll down, click the subscribe button, and see you in the next video.