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.

