1
00:00:04,830 --> 00:00:06,660
Alright so as I mentioned in the,

2
00:00:06,660 --> 00:00:08,280
towards the end of the previous video,

3
00:00:08,280 --> 00:00:10,710
we've currently got two rows and I've

4
00:00:10,710 --> 00:00:12,120
got them on the screen there. They've got

5
00:00:12,120 --> 00:00:14,490
a sort order of 2. So let's see how we

6
00:00:14,490 --> 00:00:16,650
can use the selection parameters to

7
00:00:16,650 --> 00:00:19,110
update several rows at once. So I'm going

8
00:00:19,110 --> 00:00:21,720
to go back to our code. Now once again,

9
00:00:21,720 --> 00:00:23,130
what I'll do is create a new function,

10
00:00:23,130 --> 00:00:25,110
and I'm going to put that above our test

11
00:00:25,110 --> 00:00:27,840
Update function just so that we can

12
00:00:27,840 --> 00:00:30,689
actually see what we're doing, and see

13
00:00:30,689 --> 00:00:32,040
some of the output as well. So we'll go

14
00:00:32,040 --> 00:00:35,870
back up. So I'm going to put that just below

15
00:00:35,870 --> 00:00:39,019
the onCreate method that we've got here,

16
00:00:39,019 --> 00:00:42,390
and I'll call this one testUpdateTwo because

17
00:00:42,390 --> 00:00:44,280
obviously we need a unique function name.

18
00:00:44,280 --> 00:00:46,109
Alright so what we're going to do here - the

19
00:00:46,109 --> 00:00:46,920
change we're going to make - we're going

20
00:00:46,920 --> 00:00:48,870
to change the Sort Order but we're going

21
00:00:48,870 --> 00:00:51,390
to change that for two entries. Actually 

22
00:00:51,390 --> 00:00:52,739
we're going to change the description as well.

23
00:00:52,739 --> 00:00:54,570
So the entries I'm going to put in there,

24
00:00:54,570 --> 00:00:56,519
firstly there's the Sort Order, so TASK

25
00:00:56,519 --> 00:00:58,920
_SORT_ORDER. I'm going to set

26
00:00:58,920 --> 00:01:01,499
that to 99 - that's a number so no

27
00:01:01,499 --> 00:01:04,019
double quotes - and the description, we'll

28
00:01:04,019 --> 00:01:07,490
also change that to Completed for both.

29
00:01:07,490 --> 00:01:11,340
Alright next, outside of the apply code

30
00:01:11,340 --> 00:01:14,660
block, we need to add a val selection

31
00:01:14,660 --> 00:01:19,140
equals, it's going TasksContract dot

32
00:01:19,140 --> 00:01:23,150
Columns.TASK_SORT_ORDER

33
00:01:23,150 --> 00:01:26,670
and plus and double quotes a space

34
00:01:26,670 --> 00:01:29,670
equals 2 double quotes. That's going

35
00:01:29,670 --> 00:01:31,230
to be our selection criteria there, to

36
00:01:31,230 --> 00:01:33,300
choose which records, or which rows rather

37
00:01:33,300 --> 00:01:35,130
we want to update. I'm going to comment

38
00:01:35,130 --> 00:01:37,950
out the taskUri for the id 4,

39
00:01:37,950 --> 00:01:40,140
and what I'm going to do is change - and I'll

40
00:01:40,140 --> 00:01:41,280
just bring this up on the screen so we

41
00:01:41,280 --> 00:01:42,750
can see it a bit better - rowsAffected

42
00:01:42,750 --> 00:01:45,780
should now be contentResolver dot

43
00:01:45,780 --> 00:01:47,670
updates still. We're going to go back now

44
00:01:47,670 --> 00:01:49,860
instead of taskUri. We're

45
00:01:49,860 --> 00:01:51,540
going to call just our regular Tasks

46
00:01:51,540 --> 00:01:54,390
Contract.CONTENT_

47
00:01:54,390 --> 00:01:56,220
URI. Then we're going to pass, and I'll put

48
00:01:56,220 --> 00:01:57,420
this on a separate line so it's easy

49
00:01:57,420 --> 00:01:58,020
to read,

50
00:01:58,020 --> 00:02:02,220
null and selection criteria. And actually I'll put

51
00:02:02,220 --> 00:02:04,440
values on the next line as well, and we

52
00:02:04,440 --> 00:02:06,210
can leave the TAG - logging tagging - as it

53
00:02:06,210 --> 00:02:08,848
is there on line 65 showing how many rows

54
00:02:08,848 --> 00:02:11,160
were affected. And obviously then, we need

55
00:02:11,160 --> 00:02:13,310
to go back up into our onCreate method,

56
00:02:13,310 --> 00:02:16,290
comment out the original testUpdate

57
00:02:16,290 --> 00:02:19,000
function - I said onCreate method

58
00:02:19,000 --> 00:02:21,240
but of course it's a function - and test

59
00:02:21,240 --> 00:02:26,730
UpdateTwo, we want to call that. Alright so

60
00:02:26,730 --> 00:02:30,490
we'll run this again, go back to our log

61
00:02:30,490 --> 00:02:34,240
cat, and you can see that I've made a

62
00:02:34,240 --> 00:02:36,040
critical error there, and this is

63
00:02:36,040 --> 00:02:38,170
something that you will almost certainly

64
00:02:38,170 --> 00:02:41,020
do in your career. And you can see what

65
00:02:41,020 --> 00:02:42,790
I've done is I haven't actually set the

66
00:02:42,790 --> 00:02:44,890
selection criteria, so consequently

67
00:02:44,890 --> 00:02:47,470
what's happened is, all the records in

68
00:02:47,470 --> 00:02:49,540
the table have been updated. You can see 

69
00:02:49,540 --> 00:02:52,120
Sort order 99 is set for all four, and also

70
00:02:52,120 --> 00:02:54,130
the description has been set for all

71
00:02:54,130 --> 00:02:55,840
four. What I should've done, if we come back

72
00:02:55,840 --> 00:02:57,010
down here and have a look under test

73
00:02:57,010 --> 00:03:00,730
UpdateTwo, we defined the selection to be

74
00:03:00,730 --> 00:03:02,890
the SORT_ORDER, TASK_SORT_ORDER with a

75
00:03:02,890 --> 00:03:05,530
value of 2, but then I didn't use it in

76
00:03:05,530 --> 00:03:07,180
our contentResolver.update. So what

77
00:03:07,180 --> 00:03:08,920
I should have done is actually added

78
00:03:08,920 --> 00:03:10,720
that under the WHERE clause, effectively

79
00:03:10,720 --> 00:03:14,950
under this first argument, selection. But

80
00:03:14,950 --> 00:03:16,570
at this point in time I've now updated

81
00:03:16,570 --> 00:03:18,310
the database, so what I'm going to do is

82
00:03:18,310 --> 00:03:20,560
quickly pause the video. I'm going to go back

83
00:03:20,560 --> 00:03:22,450
to the state that the database was in

84
00:03:22,450 --> 00:03:25,150
prior to this call to the testUpdateTwo

85
00:03:25,150 --> 00:03:27,310
function, and then we'll continue. But a

86
00:03:27,310 --> 00:03:29,019
good lessen there, especially in

87
00:03:29,019 --> 00:03:31,420
situations like this, to really check and

88
00:03:31,420 --> 00:03:33,610
make sure that you put the changes in to

89
00:03:33,610 --> 00:03:34,959
avoid doing just what I did there, which

90
00:03:34,959 --> 00:03:37,000
was, of course, updating all records. So

91
00:03:37,000 --> 00:03:39,630
I'll be back shortly and we'll continue.

92
00:03:39,630 --> 00:03:43,030
Okay so I'm back now, and what I've done

93
00:03:43,030 --> 00:03:44,680
is I've restored it to the state now,

94
00:03:44,680 --> 00:03:46,810
where we're at just after we called the

95
00:03:46,810 --> 00:03:49,360
first update, the testUpdateTwo function.

96
00:03:49,360 --> 00:03:50,680
So you can see that at the moment we've

97
00:03:50,680 --> 00:03:52,390
got 4 records - number of rows returned

98
00:03:52,390 --> 00:03:55,299
4 - but also you can see that we've

99
00:03:55,299 --> 00:03:58,150
got our fourth record set to Name equals,

100
00:03:58,150 --> 00:04:00,640
Task names, Content Provider: Description:

101
00:04:00,640 --> 00:04:03,040
Record content providers video. So that's

102
00:04:03,040 --> 00:04:05,530
the status of the database just prior to

103
00:04:05,530 --> 00:04:08,769
us calling that second testUpdateTwo.

104
00:04:08,769 --> 00:04:10,090
So you can see now that I've got selection

105
00:04:10,090 --> 00:04:12,280
defined for the WHERE clause for the

106
00:04:12,280 --> 00:04:14,829
update - it's that argument - and then in

107
00:04:14,829 --> 00:04:16,209
terms of what we're going to execute up

108
00:04:16,209 --> 00:04:18,040
here in our onCreate function, it's

109
00:04:18,040 --> 00:04:21,250
about to execute testUpdateTwo. So let's

110
00:04:21,250 --> 00:04:23,020
give that another go now and just make

111
00:04:23,020 --> 00:04:25,030
sure that it actually works, or check

112
00:04:25,030 --> 00:04:28,780
that it works.

113
00:04:28,780 --> 00:04:30,490
Alright so that's a lot better this

114
00:04:30,490 --> 00:04:31,840
time now that I've added the selection

115
00:04:31,840 --> 00:04:34,180
criteria. You can see that firstly, that

116
00:04:34,180 --> 00:04:36,040
the log entries report, those two records

117
00:04:36,040 --> 00:04:38,590
are updated - number of records updated is

118
00:04:38,590 --> 00:04:41,050
equal to two - and we're going to also see,

119
00:04:41,050 --> 00:04:42,340
if you look down here, changes now to

120
00:04:42,340 --> 00:04:43,960
just the two entries down the bottom

121
00:04:43,960 --> 00:04:48,730
there; Sort order 99 set for the entries,

122
00:04:48,730 --> 00:04:50,740
that had prior to this, the Sort order of

123
00:04:50,740 --> 00:04:53,980
2, namely Tasks ID for Android N and

124
00:04:53,980 --> 00:04:56,920
also the newly created id 4, which was

125
00:04:56,920 --> 00:04:58,870
our Content Provider. So in other words,

126
00:04:58,870 --> 00:05:00,730
the bulk update updating more than one

127
00:05:00,730 --> 00:05:03,730
entry at a time has worked. Alright so

128
00:05:03,730 --> 00:05:06,460
that's how to use the selection, and

129
00:05:06,460 --> 00:05:09,580
we'll go back to our function again, by

130
00:05:09,580 --> 00:05:11,500
passing this selection which is

131
00:05:11,500 --> 00:05:12,880
effectively the WHERE clause on what

132
00:05:12,880 --> 00:05:15,370
records in this case, or what rows I

133
00:05:15,370 --> 00:05:17,410
should say, to update. But what is this fourth

134
00:05:17,410 --> 00:05:20,770
argument, this selectionArgs, used for?

135
00:05:20,770 --> 00:05:23,470
What's that all about? Well selectionArgs

136
00:05:23,470 --> 00:05:26,080
is a string array of values that are

137
00:05:26,080 --> 00:05:28,540
used in the selection criteria, and they're

138
00:05:28,540 --> 00:05:30,940
used to prevent SQL injection attacks.

139
00:05:30,940 --> 00:05:33,610
So a SQL injection attack is where an

140
00:05:33,610 --> 00:05:35,920
attacker causes specially crafted

141
00:05:35,920 --> 00:05:38,740
SQL statements to be executed against

142
00:05:38,740 --> 00:05:40,960
the database. Now if your code accepts

143
00:05:40,960 --> 00:05:43,660
selection criteria from user input, then

144
00:05:43,660 --> 00:05:45,370
the user could type in something quite

145
00:05:45,370 --> 00:05:48,670
dodgy. So as for example, the code

146
00:05:48,670 --> 00:05:50,590
that we've defined on line 60 there, if

147
00:05:50,590 --> 00:05:53,800
we'd got the value 2 in this case, from

148
00:05:53,800 --> 00:05:55,630
user input, then they could have entered

149
00:05:55,630 --> 00:05:57,100
something more than just 2. They could

150
00:05:57,100 --> 00:05:58,360
have entered something effectively like

151
00:05:58,360 --> 00:06:05,440
equals 2 semicolon drop table tasks. Now

152
00:06:05,440 --> 00:06:07,180
this won't work - we'd have to be a bit

153
00:06:07,180 --> 00:06:09,490
cleverer to fool the system - but it is

154
00:06:09,490 --> 00:06:11,770
possible to do. So let's actually run the

155
00:06:11,770 --> 00:06:14,080
app with that code, just to see what

156
00:06:14,080 --> 00:06:15,880
happens, and we should get an error

157
00:06:15,880 --> 00:06:20,430
message but let's just run that anyway.

158
00:06:20,430 --> 00:06:22,630
And what I should've done, I didn't quite

159
00:06:22,630 --> 00:06:24,730
change that properly. It should have been

160
00:06:24,730 --> 00:06:27,100
equals two, then I need to actually change

161
00:06:27,100 --> 00:06:30,700
that to put a right brace, a right

162
00:06:30,700 --> 00:06:32,620
parentheses. Let's just try running that

163
00:06:32,620 --> 00:06:38,850
again.

164
00:06:38,850 --> 00:06:40,990
This time we get an error. This is the

165
00:06:40,990 --> 00:06:42,820
error that I was trying to show you, and

166
00:06:42,820 --> 00:06:44,290
if we scroll over and take a look at the

167
00:06:44,290 --> 00:06:48,040
error, we get a syntax error as you can

168
00:06:48,040 --> 00:06:50,380
see there, trying to do it that way. But

169
00:06:50,380 --> 00:06:51,520
if we go back to what it was before,

170
00:06:51,520 --> 00:06:54,190
equals two, and we remove the parentheses,

171
00:06:54,190 --> 00:06:55,660
the right parentheses for some

172
00:06:55,660 --> 00:06:57,400
reason, that's clearly not going to work

173
00:06:57,400 --> 00:06:59,290
either. You saw what happened last time -

174
00:06:59,290 --> 00:07:02,470
we didn't get any output at all. So again,

175
00:07:02,470 --> 00:07:04,750
depending on how you try and do this, if

176
00:07:04,750 --> 00:07:06,910
you were setting what the user's actually

177
00:07:06,910 --> 00:07:08,590
typed in here, you may actually get a

178
00:07:08,590 --> 00:07:11,440
SQL exception pop up. The point here

179
00:07:11,440 --> 00:07:12,640
I'm trying to make here, is that

180
00:07:12,640 --> 00:07:14,860
Android Studio and the code that Android

181
00:07:14,860 --> 00:07:16,390
is developing, is getting a lot smarter

182
00:07:16,390 --> 00:07:19,030
at trying to figure out this code and

183
00:07:19,030 --> 00:07:20,410
trying to see whether someone's trying

184
00:07:20,410 --> 00:07:22,540
to do a SQL injection attack.

185
00:07:22,540 --> 00:07:24,760
Basically, what the point here is that a

186
00:07:24,760 --> 00:07:27,400
few years ago, removing the extra right

187
00:07:27,400 --> 00:07:29,950
parentheses that I did there would have

188
00:07:29,950 --> 00:07:33,040
been enough to have deleted the entire table

189
00:07:33,040 --> 00:07:34,360
from the database, but there's now

190
00:07:34,360 --> 00:07:35,950
prevention stopping that from happening

191
00:07:35,950 --> 00:07:38,200
these days, which is good. Basically

192
00:07:38,200 --> 00:07:39,850
database systems are getting wise to

193
00:07:39,850 --> 00:07:41,830
this sort of thing. So even if you did

194
00:07:41,830 --> 00:07:43,780
delete the extra right parentheses

195
00:07:43,780 --> 00:07:45,550
from the string, the tables won't be

196
00:07:45,550 --> 00:07:46,630
dropped and you saw when I ran this

197
00:07:46,630 --> 00:07:47,979
that they actually weren't dropped.

198
00:07:47,979 --> 00:07:49,720
SQLite won't execute multiple

199
00:07:49,720 --> 00:07:52,630
queries in a single call to a query. But

200
00:07:52,630 --> 00:07:55,090
even so, with that said, it is possible to

201
00:07:55,090 --> 00:07:56,200
come up with statements that are

202
00:07:56,200 --> 00:07:58,750
formatted so that something like a drop

203
00:07:58,750 --> 00:08:00,880
table command will be executed. So

204
00:08:00,880 --> 00:08:01,960
getting back to what we were talking about

205
00:08:01,960 --> 00:08:05,289
here, the selectionArgs parameter, the

206
00:08:05,289 --> 00:08:07,960
values provided in that selectionArgs

207
00:08:07,960 --> 00:08:10,750
parameter are sanitized to reduce the

208
00:08:10,750 --> 00:08:13,150
risk of SQL injection attacks, so it's

209
00:08:13,150 --> 00:08:15,370
definitely worth using them if your

210
00:08:15,370 --> 00:08:17,950
criteria uses values that a user has

211
00:08:17,950 --> 00:08:20,289
typed into your app. So all we have to do to

212
00:08:20,289 --> 00:08:22,720
use that parameter is to replace the

213
00:08:22,720 --> 00:08:24,640
values in the selection string with a

214
00:08:24,640 --> 00:08:26,919
question mark, and then put the actual

215
00:08:26,919 --> 00:08:30,430
values into another array. Then we can

216
00:08:30,430 --> 00:08:32,320
pass that array as the final parameter

217
00:08:32,320 --> 00:08:34,630
to that function. So let's actually have

218
00:08:34,630 --> 00:08:36,159
a look at how to do that, so if you're

219
00:08:36,159 --> 00:08:37,450
faced with that scenario you'll know

220
00:08:37,450 --> 00:08:40,809
what to do. So after selection, we're

221
00:08:40,809 --> 00:08:42,250
going to delete that so it's just set back to

222
00:08:42,250 --> 00:08:44,410
equal, but instead of two it's going to be

223
00:08:44,410 --> 00:08:48,430
equal question mark. Then on the next line

224
00:08:48,430 --> 00:08:50,310
it's going to be val

225
00:08:50,310 --> 00:08:55,800
selectionArgs is equal to arrayOf

226
00:08:55,800 --> 00:09:00,100
parentheses double quotes 99, rows

227
00:09:00,100 --> 00:09:01,420
affected we're going to leave, and I'm

228
00:09:01,420 --> 00:09:03,550
going to delete this, those two lines

229
00:09:03,550 --> 00:09:05,980
there, and selectionArgs, we're now going

230
00:09:05,980 --> 00:09:10,780
to pass selectionArgs. And just so we

231
00:09:10,780 --> 00:09:12,160
can see that it has been an update I'm

232
00:09:12,160 --> 00:09:14,950
going to change TASK_SORT_ORDER to 999.

233
00:09:14,950 --> 00:09:17,050
I'm going to change the TASK_DESCRIPTION

234
00:09:17,050 --> 00:09:19,930
to For deletion so we can actually see

235
00:09:19,930 --> 00:09:21,460
that this has actually worked. And

236
00:09:21,460 --> 00:09:23,260
obviously I'm not using 99 there because

237
00:09:23,260 --> 00:09:24,640
we've already updated that in a previous

238
00:09:24,640 --> 00:09:27,250
update call. Now we've only provided a

239
00:09:27,250 --> 00:09:29,980
single argument here for TASK_SORT_ORDER

240
00:09:29,980 --> 00:09:31,050
because that's our selection criteria,

241
00:09:31,050 --> 00:09:33,520
but it's still expecting an array, and

242
00:09:33,520 --> 00:09:36,790
notice also that the 99 is in double

243
00:09:36,790 --> 00:09:39,130
quotes in this case because we're adding it to

244
00:09:39,130 --> 00:09:41,500
an array. Now when the SQL statement's

245
00:09:41,500 --> 00:09:43,930
built up to perform the update, each of

246
00:09:43,930 --> 00:09:46,210
the values in args is used to replace

247
00:09:46,210 --> 00:09:47,980
the question marks in the selection. And

248
00:09:47,980 --> 00:09:50,230
they're replaced in order, and you have

249
00:09:50,230 --> 00:09:51,490
to make sure that there are the same

250
00:09:51,490 --> 00:09:53,380
number of args values as there are

251
00:09:53,380 --> 00:09:55,150
question marks. So when I run the app

252
00:09:55,150 --> 00:10:03,550
again now, number of rows updated equals

253
00:10:03,550 --> 00:10:05,470
2, and we've now got two entries down

254
00:10:05,470 --> 00:10:07,540
the bottom here; description is For

255
00:10:07,540 --> 00:10:09,880
deletion and the Sort order is 999 for

256
00:10:09,880 --> 00:10:11,770
both of them. So you've actually got a

257
00:10:11,770 --> 00:10:14,290
choice in how you specify a selection

258
00:10:14,290 --> 00:10:17,260
criteria when using the Content Provider.

259
00:10:17,260 --> 00:10:20,050
If all the values for the criteria come

260
00:10:20,050 --> 00:10:22,150
from inside your code, then it doesn't

261
00:10:22,150 --> 00:10:24,040
really matter which way or which 

262
00:10:24,040 --> 00:10:26,140
approach, which method you use, but even

263
00:10:26,140 --> 00:10:28,180
so it is worth getting into the habit of

264
00:10:28,180 --> 00:10:30,490
using selectionArgs like we've actually

265
00:10:30,490 --> 00:10:32,320
used here. So I'd suggest you do that,

266
00:10:32,320 --> 00:10:34,810
again using that with a combination of 

267
00:10:34,810 --> 00:10:37,080
the question marks for your selection.

268
00:10:37,080 --> 00:10:39,160
Alright so the last thing we now need to

269
00:10:39,160 --> 00:10:41,380
know how to do, or to test rather, is

270
00:10:41,380 --> 00:10:43,360
deletion, and as you'd expect this works

271
00:10:43,360 --> 00:10:45,970
very similarly to updating, except we

272
00:10:45,970 --> 00:10:47,710
don't have to specify the ContentValues.

273
00:10:47,710 --> 00:10:51,580
So I'm going to copy the testUpdate code. Let's

274
00:10:51,580 --> 00:10:55,090
just grab that. I'm going to put it up

275
00:10:55,090 --> 00:10:58,870
the top here and we'll call this one

276
00:10:58,870 --> 00:11:03,300
testDelete.

277
00:11:03,300 --> 00:11:06,730
So in terms of what we need to add, we don't

278
00:11:06,730 --> 00:11:08,860
need to pass a ContentValues object at

279
00:11:08,860 --> 00:11:10,480
all so I'm going to delete that. All we

280
00:11:10,480 --> 00:11:12,870
need to do is have a URI set to

281
00:11:12,870 --> 00:11:15,700
specify the ID we want to delete. In this

282
00:11:15,700 --> 00:11:17,470
case, this is for a single deletion or

283
00:11:17,470 --> 00:11:21,250
pass id 3; rows affected, the deletion

284
00:11:21,250 --> 00:11:23,260
call hasn't got ContentValues because

285
00:11:23,260 --> 00:11:25,420
we're deleting not updating, so I can

286
00:11:25,420 --> 00:11:28,900
delete that second argument. And obviously

287
00:11:28,900 --> 00:11:30,730
update now has changed to delete -

288
00:11:30,730 --> 00:11:33,070
we're calling the delete function from

289
00:11:33,070 --> 00:11:35,080
our Content Provider. Number of rows

290
00:11:35,080 --> 00:11:40,090
deleted is then our rows affected. So

291
00:11:40,090 --> 00:11:41,860
that's the testDelete. That's pretty

292
00:11:41,860 --> 00:11:43,450
straightforward. Then we just need to

293
00:11:43,450 --> 00:11:45,400
go to our onCreate in this case, and

294
00:11:45,400 --> 00:11:47,470
I'm going to comment out testUpdateTwo,

295
00:11:47,470 --> 00:11:49,810
and we're going to call our testDelete

296
00:11:49,810 --> 00:11:52,690
function that we just wrote. So run the

297
00:11:52,690 --> 00:11:58,510
app again and we'll check our log. Number

298
00:11:58,510 --> 00:12:01,210
of rows deleted equals one, and we've now

299
00:12:01,210 --> 00:12:02,620
only got three entries as you can see

300
00:12:02,620 --> 00:12:06,700
here; IDs 1, 2 and 4, and

301
00:12:06,700 --> 00:12:08,620
obviously we specified ID 3 and

302
00:12:08,620 --> 00:12:10,540
that got deleted. And you can see

303
00:12:10,540 --> 00:12:13,150
there, by the way, the deletion, there's our

304
00:12:13,150 --> 00:12:16,600
URI and it's got 3 as the ID passed

305
00:12:16,600 --> 00:12:18,550
on the end of it. Alright, so the Kotlin

306
00:12:18,550 --> 00:12:19,990
task basically got deleted there so

307
00:12:19,990 --> 00:12:21,850
that's working fine. Now we can also

308
00:12:21,850 --> 00:12:25,030
specify a URI without an ID, and instead

309
00:12:25,030 --> 00:12:27,400
use a selection to specify which row or

310
00:12:27,400 --> 00:12:29,800
rows to delete, just like when we updated

311
00:12:29,800 --> 00:12:31,930
several rows earlier in the video. So

312
00:12:31,930 --> 00:12:35,110
let's go and do that. So I'll come down here

313
00:12:35,110 --> 00:12:38,230
and I'll take a, and what I'll do is I'll

314
00:12:38,230 --> 00:12:40,390
take a copy of testUpdateTwo, because this

315
00:12:40,390 --> 00:12:42,660
has got some code there that we can use

316
00:12:42,660 --> 00:12:46,120
which will be quite handy, even though

317
00:12:46,120 --> 00:12:50,320
we'll need to delete some of it. So we'll

318
00:12:50,320 --> 00:12:53,170
call that test deletion two, testDelete

319
00:12:53,170 --> 00:12:57,220
Two will do. So firstly, we don't need a

320
00:12:57,220 --> 00:12:58,660
ContentValues object so I'm going to

321
00:12:58,660 --> 00:13:01,240
delete that. Our selection, we're going to

322
00:13:01,240 --> 00:13:03,460
start off with TasksContract.Columns.

323
00:13:03,460 --> 00:13:05,200
Let's try deleting something by Task

324
00:13:05,200 --> 00:13:09,640
description, so dot TASK_

325
00:13:09,640 --> 00:13:12,130
DESCRIPTION, and we're going to leave it as

326
00:13:12,130 --> 00:13:14,350
plus, equals and then a

327
00:13:14,350 --> 00:13:16,330
question mark there. The selectionArgs

328
00:13:16,330 --> 00:13:19,570
this time, we going to, instead of 99, we're

329
00:13:19,570 --> 00:13:22,480
going to pass For deletion because if you

330
00:13:22,480 --> 00:13:25,720
remember we've currently got entries

331
00:13:25,720 --> 00:13:28,210
there For deletion. We've got that entry there.

332
00:13:28,210 --> 00:13:30,370
We've also got this one here, so IDs 2

333
00:13:30,370 --> 00:13:33,100
and 4 are currently set, or have the

334
00:13:33,100 --> 00:13:35,440
DESCRIPTION, TASK_DESCRIPTION set to

335
00:13:35,440 --> 00:13:37,600
For deletion. And then the rowsAffected

336
00:13:37,600 --> 00:13:39,760
line is going to be calling the delete

337
00:13:39,760 --> 00:13:42,310
and of the update, so I'm going to do

338
00:13:42,310 --> 00:13:45,520
that. So I'll change that to delete, so I'm going

339
00:13:45,520 --> 00:13:46,900
to leave that unchanged, CONTENT__URI.

340
00:13:46,900 --> 00:13:49,030
Then values, we haven't got that anymore

341
00:13:49,030 --> 00:13:51,430
so I'm going to delete that; selection

342
00:13:51,430 --> 00:13:53,470
and then selectionArgs are the two

343
00:13:53,470 --> 00:13:55,870
things that we've defined on line 58 and

344
00:13:55,870 --> 00:13:58,450
59, and we'll change this number of rows

345
00:13:58,450 --> 00:14:00,430
affected, updated rather, to Number of

346
00:14:00,430 --> 00:14:02,950
rows deleted. So that should be all we

347
00:14:02,950 --> 00:14:05,110
need to do, and we'll just go back up to

348
00:14:05,110 --> 00:14:09,310
onCreate, comment out testDelete, then

349
00:14:09,310 --> 00:14:11,980
we'll call our testDeleteTwo function.

350
00:14:11,980 --> 00:14:15,370
And let's try running that again to make

351
00:14:15,370 --> 00:14:20,020
sure it works. You can see here, Number of

352
00:14:20,020 --> 00:14:22,720
rows deleted equals 2, and looking at

353
00:14:22,720 --> 00:14:24,130
the number of entries in our database

354
00:14:24,130 --> 00:14:26,500
from our query, number of rows returned,

355
00:14:26,500 --> 00:14:28,630
rows in returned cursor equals 1. We've

356
00:14:28,630 --> 00:14:30,550
now just got the one entry which is ID

357
00:14:30,550 --> 00:14:33,190
1, which is our TaskTimer app creation

358
00:14:33,190 --> 00:14:34,690
with the description there - Sort order

359
00:14:34,690 --> 00:14:38,050
null ID 1. So that's our Content Provider

360
00:14:38,050 --> 00:14:40,090
now working - we've actually tested it. So

361
00:14:40,090 --> 00:14:41,830
in the next video, now that we've got a

362
00:14:41,830 --> 00:14:44,200
fully working Content Provider, we're

363
00:14:44,200 --> 00:14:45,430
going to start work on the user

364
00:14:45,430 --> 00:14:47,740
interface for this app. So I'll see you

365
00:14:47,740 --> 00:14:50,310
in the next video.

