1 00:00:04,680 --> 00:00:07,290 Alright so the update method's almost 2 00:00:07,290 --> 00:00:10,050 the same as the query method. We have to 3 00:00:10,050 --> 00:00:12,360 allow all URIs because you can 4 00:00:12,360 --> 00:00:15,869 update a single record or all records in 5 00:00:15,869 --> 00:00:18,300 the table. And we don't return a cursor. 6 00:00:18,300 --> 00:00:20,849 Instead we use the databases update 7 00:00:20,849 --> 00:00:23,550 method just as we use the insert method 8 00:00:23,550 --> 00:00:26,609 in our insert function. The other 9 00:00:26,609 --> 00:00:28,560 difference to insert, is that an update 10 00:00:28,560 --> 00:00:31,199 statement can have a WHERE clause, and we 11 00:00:31,199 --> 00:00:33,480 saw that in the SQL videos earlier in 12 00:00:33,480 --> 00:00:35,700 this course. When I didn't specify a 13 00:00:35,700 --> 00:00:37,950 WHERE clause I ended up giving everyone 14 00:00:37,950 --> 00:00:41,040 the same email address. So the parameters 15 00:00:41,040 --> 00:00:43,320 to our update method are a combination of 16 00:00:43,320 --> 00:00:47,040 the insert and query parameters. We'll be 17 00:00:47,040 --> 00:00:48,510 looking at the ContentValues and 18 00:00:48,510 --> 00:00:51,030 selectionArgs parameters when we come 19 00:00:51,030 --> 00:00:52,950 to use them, so don't worry about them 20 00:00:52,950 --> 00:00:55,170 too much just yet. We'll just pass them 21 00:00:55,170 --> 00:00:57,930 on to the database update method. So I'm 22 00:00:57,930 --> 00:00:59,640 going to start off by taking a copy of 23 00:00:59,640 --> 00:01:02,340 those three lines that we've used in the 24 00:01:02,340 --> 00:01:05,220 other two functions; the two log lines and 25 00:01:05,220 --> 00:01:07,619 the match variable which is returning 26 00:01:07,619 --> 00:01:09,270 the value of uriMatcher.match. 27 00:01:09,270 --> 00:01:11,520 I'm going to paste that into our update 28 00:01:11,520 --> 00:01:14,790 method, and you can see again, that the 29 00:01:14,790 --> 00:01:16,920 parameters to this update method are a 30 00:01:16,920 --> 00:01:18,840 combination of the insert and query 31 00:01:18,840 --> 00:01:21,480 parameters. Alright, so once again as 32 00:01:21,480 --> 00:01:22,890 you can see, we're going to be using our 33 00:01:22,890 --> 00:01:25,409 uriMatcher. And the other thing we want to do is 34 00:01:25,409 --> 00:01:26,909 just type in a couple of other lines 35 00:01:26,909 --> 00:01:31,520 here. We've got val count: int and 36 00:01:31,520 --> 00:01:42,270 var selectionCriteria: string. Now 37 00:01:42,270 --> 00:01:44,490 when we successfully update rows, the 38 00:01:44,490 --> 00:01:46,140 database will let us know how many rows 39 00:01:46,140 --> 00:01:48,600 were updated, and we'll also have to deal 40 00:01:48,600 --> 00:01:50,729 with the selection criteria, so that's 41 00:01:50,729 --> 00:01:52,140 what these two variables that I've 42 00:01:52,140 --> 00:01:53,729 defined are actually for. So I'm going 43 00:01:53,729 --> 00:01:55,140 to add the when statement and start with 44 00:01:55,140 --> 00:01:57,299 the code for the Tasks table, so let's go 45 00:01:57,299 --> 00:01:59,490 ahead and do that. So when, and I'll just 46 00:01:59,490 --> 00:02:01,770 move this up, and you can see a bit more of the 47 00:02:01,770 --> 00:02:02,460 screen at once. 48 00:02:02,460 --> 00:02:07,500 So when parentheses match and left and 49 00:02:07,500 --> 00:02:09,030 right curly braces, and then I'm 50 00:02:09,030 --> 00:02:12,810 going to type TASKS arrow 51 00:02:12,810 --> 00:02:16,140 and open a code block, and the code for 52 00:02:16,140 --> 00:02:19,110 that's going to be val db equals AppDatabase 53 00:02:19,110 --> 00:02:22,680 dot getInstance. Then in parentheses it's 54 00:02:22,680 --> 00:02:26,010 going to be context, dot writable 55 00:02:26,010 --> 00:02:27,300 Database, because obviously we're writing 56 00:02:27,300 --> 00:02:29,700 to the database. And then we're going 57 00:02:29,700 --> 00:02:33,860 to do count equals db.update parentheses 58 00:02:33,860 --> 00:02:37,350 TasksContract.TABLE_ 59 00:02:37,350 --> 00:02:42,900 NAME comma values comma selection comma 60 00:02:42,900 --> 00:02:47,519 and then finally selectionArgs. So there's not 61 00:02:47,519 --> 00:02:49,380 really a lot to say about that. We get a 62 00:02:49,380 --> 00:02:51,690 writableDatabase object and we call its 63 00:02:51,690 --> 00:02:54,780 update method to perform the update. We 64 00:02:54,780 --> 00:02:57,030 have to specify the table name as well 65 00:02:57,030 --> 00:02:59,100 as the values to update, and we also 66 00:02:59,100 --> 00:03:01,769 specify the selection criteria that will 67 00:03:01,769 --> 00:03:04,350 be used in the SQL WHERE clause. Then 68 00:03:04,350 --> 00:03:05,730 we just pass on the values that were 69 00:03:05,730 --> 00:03:08,370 provided when our update function was 70 00:03:08,370 --> 00:03:11,550 called to the update method. And then the 71 00:03:11,550 --> 00:03:13,319 databases update method will return a 72 00:03:13,319 --> 00:03:14,910 count of the number of rows that were 73 00:03:14,910 --> 00:03:17,340 updated, so we'll use that as the return 74 00:03:17,340 --> 00:03:19,350 value for this method. At the moment you 75 00:03:19,350 --> 00:03:20,579 can see that I've saved that into the 76 00:03:20,579 --> 00:03:23,760 variable count. Now for some reason this 77 00:03:23,760 --> 00:03:26,190 return value is an int rather than a 78 00:03:26,190 --> 00:03:29,220 long, which is strange. The ID values are 79 00:03:29,220 --> 00:03:31,799 defined as long, so it's possible to 80 00:03:31,799 --> 00:03:33,780 perform an update that affects more rows 81 00:03:33,780 --> 00:03:36,200 and can be stored in an int variable. 82 00:03:36,200 --> 00:03:38,310 Unless there's more than two billion 83 00:03:38,310 --> 00:03:39,720 records I don't suppose it's something 84 00:03:39,720 --> 00:03:41,820 we need to worry about on an Android 85 00:03:41,820 --> 00:03:43,920 device. We'd run out of storage space 86 00:03:43,920 --> 00:03:45,630 most likely well before the int value 87 00:03:45,630 --> 00:03:48,209 could overflow, but you should get into 88 00:03:48,209 --> 00:03:50,549 the habit of noticing anomalies 89 00:03:50,549 --> 00:03:53,190 like this. Alright so that's the 90 00:03:53,190 --> 00:03:55,440 code for performing an update against 91 00:03:55,440 --> 00:03:57,600 the whole table. If, on the other hand, a 92 00:03:57,600 --> 00:04:00,269 single row only needs to be updated, we 93 00:04:00,269 --> 00:04:01,829 have to then include the row selection 94 00:04:01,829 --> 00:04:04,260 in the WHERE clause. So let's start 95 00:04:04,260 --> 00:04:08,190 writing some code for that scenario. So 96 00:04:08,190 --> 00:04:09,180 that's going to be, on the next line, 97 00:04:09,180 --> 00:04:13,230 TASKS_ID with our arrow and a 98 00:04:13,230 --> 00:04:16,789 code block, and we'll start by val db 99 00:04:16,789 --> 00:04:20,250 equals AppDatabase.getInstance 100 00:04:20,250 --> 00:04:24,120 parentheses context dot writable 101 00:04:24,120 --> 00:04:25,700 Database again. 102 00:04:25,700 --> 00:04:29,060 And we'll do a val id equals Tasks 103 00:04:29,060 --> 00:04:34,310 Contract.getId uri; selection 104 00:04:34,310 --> 00:04:39,890 Criteria, we're going to set that equal to double 105 00:04:39,890 --> 00:04:42,050 quotes $ left and right curly 106 00:04:42,050 --> 00:04:47,090 braces TasksContract.Columns dot 107 00:04:47,090 --> 00:04:50,810 ID. Then close off the right curly brace, 108 00:04:50,810 --> 00:04:55,430 equals $id, and then we're going to put 109 00:04:55,430 --> 00:04:57,340 a test in here. We're going to put if 110 00:04:57,340 --> 00:05:02,290 selection is not equal to null and 111 00:05:02,290 --> 00:05:09,410 selection.isNotEmpty, and then 112 00:05:09,410 --> 00:05:11,590 we're going to put selectionCriteria 113 00:05:11,590 --> 00:05:15,130 plus equals double quotes space AND 114 00:05:15,130 --> 00:05:17,660 space, and then in parentheses 115 00:05:17,660 --> 00:05:20,780 $selection. Enclose the parentheses 116 00:05:20,780 --> 00:05:23,870 as well and double quote. And outside of 117 00:05:23,870 --> 00:05:26,360 that if test, we're going to type count 118 00:05:26,360 --> 00:05:30,140 equals db.update parentheses, and 119 00:05:30,140 --> 00:05:33,410 it's going to be TasksContract dot, our TABLE 120 00:05:33,410 --> 00:05:37,100 _NAME comma values comma selection 121 00:05:37,100 --> 00:05:39,470 Criteria comma then selectionArgs, selectionArgs. 122 00:05:39,470 --> 00:05:42,980 Alright so what are we 123 00:05:42,980 --> 00:05:45,290 doing here? Well we start by getting the 124 00:05:45,290 --> 00:05:48,140 ID from the URI using the getId 125 00:05:48,140 --> 00:05:50,090 function that we wrote in the Tasks 126 00:05:50,090 --> 00:05:52,580 Contract class. We then have to build up a 127 00:05:52,580 --> 00:05:55,010 string containing the condition for the 128 00:05:55,010 --> 00:05:57,380 WHERE clause. So that looks simple. It's 129 00:05:57,380 --> 00:06:00,620 just underscore ID equals and the ID, and you 130 00:06:00,620 --> 00:06:03,050 can see that on line 185. But if we look 131 00:06:03,050 --> 00:06:05,360 at the parameters to this method, the 132 00:06:05,360 --> 00:06:07,310 caller could also have passed in an 133 00:06:07,310 --> 00:06:09,980 additional selection. They may, for 134 00:06:09,980 --> 00:06:12,290 example, want to update a row only if 135 00:06:12,290 --> 00:06:14,330 there's a certain value in one of the 136 00:06:14,330 --> 00:06:16,460 other columns. So our code has to include 137 00:06:16,460 --> 00:06:18,650 that condition as well. So therefore we 138 00:06:18,650 --> 00:06:20,600 check to see if the selection parameter 139 00:06:20,600 --> 00:06:22,910 contains something, then we add it to the 140 00:06:22,910 --> 00:06:25,700 selection criteria if and only if it 141 00:06:25,700 --> 00:06:28,220 does. So the selection criteria may end 142 00:06:28,220 --> 00:06:29,660 up with something like tasks dot 143 00:06:29,660 --> 00:06:33,440 underscore ID equals 8, and name equals 144 00:06:33,440 --> 00:06:36,590 single quotes Tim, for example. Now our 145 00:06:36,590 --> 00:06:38,540 database app won't need to use selection 146 00:06:38,540 --> 00:06:39,529 criteria like that, 147 00:06:39,529 --> 00:06:41,659 but you should allow conditions like 148 00:06:41,659 --> 00:06:43,489 that to be used when writing your 149 00:06:43,489 --> 00:06:46,369 content providers. Okay, so the code for 150 00:06:46,369 --> 00:06:48,559 the Timings table is practically 151 00:06:48,559 --> 00:06:50,599 identical to this, other than the fact 152 00:06:50,599 --> 00:06:52,159 we'll be using the TimingsContract 153 00:06:52,159 --> 00:06:55,189 class instead of the TasksContract. So 154 00:06:55,189 --> 00:06:57,319 I'm going to copy that code and make 155 00:06:57,319 --> 00:07:00,259 some changes based on the different 156 00:07:00,259 --> 00:07:04,059 table names. So it's going to be TASKS, 157 00:07:04,059 --> 00:07:06,049 instead of TASKS it's going to be 158 00:07:06,049 --> 00:07:10,339 TIMINGS, and for the TASKS_ID that's 159 00:07:10,339 --> 00:07:15,529 going to be TIMINGS_ID, and for Tasks 160 00:07:15,529 --> 00:07:17,589 Contract here that's going to be Timings 161 00:07:17,589 --> 00:07:20,229 Contract. 162 00:07:20,229 --> 00:07:22,459 TIMINGS_ID down here is 163 00:07:22,459 --> 00:07:25,489 going to be TimingsContract. Down here, 164 00:07:25,489 --> 00:07:26,749 also the count equals db. 165 00:07:26,749 --> 00:07:28,429 update, that will also be Timings 166 00:07:28,429 --> 00:07:30,709 Contract. Alright so that should be 167 00:07:30,709 --> 00:07:33,229 that. So to finish this function now, we 168 00:07:33,229 --> 00:07:35,599 just need to add the exception if 169 00:07:35,599 --> 00:07:37,489 there's an invalid URL, and then 170 00:07:37,489 --> 00:07:40,489 return the count of rows updated. So 171 00:07:40,489 --> 00:07:42,619 let's go ahead and do that. So below this 172 00:07:42,619 --> 00:07:45,769 TIMINGS_ID, we have one other scenario 173 00:07:45,769 --> 00:07:48,799 there and that's else with the arrow again, 174 00:07:48,799 --> 00:07:51,379 it's going to be throw Illegal 175 00:07:51,379 --> 00:07:53,869 ArgumentException, parentheses there 176 00:07:53,869 --> 00:07:57,559 double quotes Unknown uri colon 177 00:07:57,559 --> 00:08:00,049 $uri double quotes and right 178 00:08:00,049 --> 00:08:03,519 parenthesis. And then to close off the 179 00:08:03,519 --> 00:08:07,249 function, Log.d parentheses TAG comma 180 00:08:07,249 --> 00:08:11,559 double quotes there, Exiting update, 181 00:08:11,559 --> 00:08:15,799 returning $count, then double quote 182 00:08:15,799 --> 00:08:17,559 right parenthesis. Then we'll return 183 00:08:17,559 --> 00:08:20,509 count. Alright, so that's our update 184 00:08:20,509 --> 00:08:22,459 function now written. Now the delete 185 00:08:22,459 --> 00:08:23,899 function's almost identical to the 186 00:08:23,899 --> 00:08:25,639 update function. We just call the 187 00:08:25,639 --> 00:08:28,609 databases delete method, and it also 188 00:08:28,609 --> 00:08:30,769 doesn't have a ContentValues parameter 189 00:08:30,769 --> 00:08:32,659 to worry about. And you can see down the 190 00:08:32,659 --> 00:08:35,208 bottom of the screen there, the method, 191 00:08:35,208 --> 00:08:37,308 the function signature there. So I'm 192 00:08:37,308 --> 00:08:38,839 going to copy the code from the update 193 00:08:38,839 --> 00:08:43,519 method, basically everything, not 194 00:08:43,519 --> 00:08:44,779 including the function declaration 195 00:08:44,779 --> 00:08:46,670 self, just everything between the 196 00:08:46,670 --> 00:08:52,129 opening and closing braces, like so. I'll just 197 00:08:52,129 --> 00:08:52,850 copy that, 198 00:08:52,850 --> 00:08:55,430 I'm going to paste that in, over-writing 199 00:08:55,430 --> 00:08:59,300 the TODO, and basically in the function 200 00:08:59,300 --> 00:09:02,330 like so. Alright so we just need to make 201 00:09:02,330 --> 00:09:06,140 a few changes, and I should change this as well. 202 00:09:06,140 --> 00:09:07,580 I'm going to take the opportunity to change 203 00:09:07,580 --> 00:09:09,500 this because I didn't previously - update. 204 00:09:09,500 --> 00:09:11,110 I'm actually going to put update in there 205 00:09:11,110 --> 00:09:13,220 because that was copied from query 206 00:09:13,220 --> 00:09:14,450 initially. So we want to know where we're 207 00:09:14,450 --> 00:09:16,340 actually calling the update method - that 208 00:09:16,340 --> 00:09:17,510 would mean more than likely the insert 209 00:09:17,510 --> 00:09:19,160 one I've got wrong as well, update that 210 00:09:19,160 --> 00:09:24,620 to insert, query insert. And we'll just go 211 00:09:24,620 --> 00:09:27,440 up and check - query's obviously the one 212 00:09:27,440 --> 00:09:28,580 where it copied from so that's correct - 213 00:09:28,580 --> 00:09:30,680 but that should be all we need to do 214 00:09:30,680 --> 00:09:33,170 there. And we'll go down to our delete 215 00:09:33,170 --> 00:09:35,990 function. I'm also going to make sure that 216 00:09:35,990 --> 00:09:37,160 says delete as well, 217 00:09:37,160 --> 00:09:41,050 delete called, delete down there as well. 218 00:09:41,050 --> 00:09:42,920 Alright so we need to make a few changes 219 00:09:42,920 --> 00:09:47,660 here. So firstly for the Tasks table, it's 220 00:09:47,660 --> 00:09:49,700 not going to be db.update. In 221 00:09:49,700 --> 00:09:52,100 fact, what it's going to be is db dot 222 00:09:52,100 --> 00:09:55,670 delete, so I'm going to type delete there, and there's also 223 00:09:55,670 --> 00:09:57,020 another values argument there so I'm 224 00:09:57,020 --> 00:09:59,600 going to delete that out. So we've just got our 225 00:09:59,600 --> 00:10:02,510 TasksContract.TABLE_NAME, selection then 226 00:10:02,510 --> 00:10:05,300 selectionArgs. Then moving down to our 227 00:10:05,300 --> 00:10:07,520 TASKS_ID, the thing we need to 228 00:10:07,520 --> 00:10:09,140 change there is change the db dot 229 00:10:09,140 --> 00:10:13,460 update to a delete. Then we want to delete the 230 00:10:13,460 --> 00:10:16,280 values and the comma, and the two things, 231 00:10:16,280 --> 00:10:17,840 two parameters we want to leave in 232 00:10:17,840 --> 00:10:20,030 after the TABLE_NAME are selection 233 00:10:20,030 --> 00:10:22,550 Criteria and selectionArgs. And then we 234 00:10:22,550 --> 00:10:25,100 want to do the same for TIMINGS and 235 00:10:25,100 --> 00:10:27,500 TIMINGS_ID, and you can notice 236 00:10:27,500 --> 00:10:28,940 there that that's something I've 237 00:10:28,940 --> 00:10:31,070 actually missed there - TimingsContract. I 238 00:10:31,070 --> 00:10:32,990 need to fix that - it should be Tasks 239 00:10:32,990 --> 00:10:35,600 Contract so lucky I checked that - and we 240 00:10:35,600 --> 00:10:38,390 need to change this also, up here, so I'm 241 00:10:38,390 --> 00:10:42,140 going to make that a delete. I'm going to 242 00:10:42,140 --> 00:10:44,180 delete the values in the semi, in the 243 00:10:44,180 --> 00:10:46,790 comma as well to make that valid. Also 244 00:10:46,790 --> 00:10:50,180 down here I'm going to delete, convert it to 245 00:10:50,180 --> 00:10:51,860 delete, a call to the delete method 246 00:10:51,860 --> 00:10:54,440 instead of update, and also remove values 247 00:10:54,440 --> 00:10:57,560 comma from that line. And that should be 248 00:10:57,560 --> 00:10:58,850 that, but then the only other thing I 249 00:10:58,850 --> 00:11:00,260 need to do because I've found this problem 250 00:11:00,260 --> 00:11:02,900 in TIMINGS_ID and we copied 251 00:11:02,900 --> 00:11:05,240 that from the update method, that would 252 00:11:05,240 --> 00:11:06,200 mean that the code needs 253 00:11:06,200 --> 00:11:08,540 to be fixed here for TIMINGS_ID. 254 00:11:08,540 --> 00:11:12,320 So I'm going to change that to, from 255 00:11:12,320 --> 00:11:14,960 TimingsContract, paste in Timings 256 00:11:14,960 --> 00:11:16,940 Contract there instead of TasksContract. 257 00:11:16,940 --> 00:11:18,620 Now as it turns out that would have 258 00:11:18,620 --> 00:11:21,680 worked anyway because the TasksContract dot 259 00:11:21,680 --> 00:11:24,620 Columns.ID and TimingsContract dot 260 00:11:24,620 --> 00:11:26,420 Columns.ID were set to the same 261 00:11:26,420 --> 00:11:28,580 value, but obviously for some reason if we 262 00:11:28,580 --> 00:11:30,470 renamed it in the future this code 263 00:11:30,470 --> 00:11:31,730 would break. So it's best to get it right 264 00:11:31,730 --> 00:11:34,010 at the time we're actually writing 265 00:11:34,010 --> 00:11:35,330 the code if we can see that there's a 266 00:11:35,330 --> 00:11:37,130 fault there. Alright so let's bring our 267 00:11:37,130 --> 00:11:39,020 delete back on the screen again, our delete 268 00:11:39,020 --> 00:11:41,570 function, and what we've done now should 269 00:11:41,570 --> 00:11:43,280 be everything we need to do. We're just going to 270 00:11:43,280 --> 00:11:45,050 have a quick look now to make sure that 271 00:11:45,050 --> 00:11:46,540 we've got everything as it should be, and I 272 00:11:46,540 --> 00:11:48,770 think that looks pretty good to me. 273 00:11:48,770 --> 00:11:49,910 And obviously we'll find out if there's 274 00:11:49,910 --> 00:11:51,380 a problem when we go to test this 275 00:11:51,380 --> 00:11:53,390 anyway. So you can see that the delete 276 00:11:53,390 --> 00:11:55,460 function's pretty well doing much the 277 00:11:55,460 --> 00:11:57,860 same as the update function, and instead 278 00:11:57,860 --> 00:12:00,200 of updating rows its deleting them. So at 279 00:12:00,200 --> 00:12:01,570 this point that's our ContentProvider 280 00:12:01,570 --> 00:12:04,460 pretty well finished. You will see later 281 00:12:04,460 --> 00:12:06,050 though, that there's one more thing we 282 00:12:06,050 --> 00:12:08,300 need to do in all three functions that 283 00:12:08,300 --> 00:12:10,670 change the data; the insert, update and 284 00:12:10,670 --> 00:12:12,800 delete functions. But it's a simple 285 00:12:12,800 --> 00:12:14,390 change and I'll discuss that when we 286 00:12:14,390 --> 00:12:16,550 come to it. For now though, I'm going to 287 00:12:16,550 --> 00:12:18,260 stop the video here and then we're going 288 00:12:18,260 --> 00:12:20,540 to test these functions in the next one. 289 00:12:20,540 --> 00:12:24,160 So I'll see you in the next video.