1
00:00:04,660 --> 00:00:07,000
Alright so moving on now. We're going

2
00:00:07,000 --> 00:00:09,160
to talk about onUpgrade, the function,

3
00:00:09,160 --> 00:00:11,500
and also some testing. So the other

4
00:00:11,500 --> 00:00:12,760
function we had to implement, if you

5
00:00:12,760 --> 00:00:14,980
recall, to our, in our AppDatabase

6
00:00:14,980 --> 00:00:18,640
class was onUpgrade. And if we take

7
00:00:18,640 --> 00:00:22,480
a look at that, looking at the

8
00:00:22,480 --> 00:00:26,500
documentation - let's scroll this up so

9
00:00:26,500 --> 00:00:29,619
we can see it - it gets past the version

10
00:00:29,619 --> 00:00:32,020
of the database that Android finds. So

11
00:00:32,020 --> 00:00:33,460
the documentation explains that this

12
00:00:33,460 --> 00:00:35,110
function's called when the database

13
00:00:35,110 --> 00:00:37,150
needs to be upgraded.

14
00:00:37,150 --> 00:00:39,400
Now when the function's called, it

15
00:00:39,400 --> 00:00:41,320
gets passed the version of the database

16
00:00:41,320 --> 00:00:43,930
that Android finds, and the current

17
00:00:43,930 --> 00:00:46,420
version. So we passed the current version

18
00:00:46,420 --> 00:00:48,490
number into the super method in the

19
00:00:48,490 --> 00:00:50,800
constructor, so the SQLiteOpen

20
00:00:50,800 --> 00:00:52,900
Helper class can track the versions for

21
00:00:52,900 --> 00:00:54,940
us. Now we're obviously just starting

22
00:00:54,940 --> 00:00:57,130
out so this is version 1, so there's

23
00:00:57,130 --> 00:00:58,930
nothing to upgrade. We'll be adding some

24
00:00:58,930 --> 00:01:00,670
more tables and views as we develop the

25
00:01:00,670 --> 00:01:02,500
app, so I'm going to be discussing the on

26
00:01:02,500 --> 00:01:04,869
Upgrade function in more detail when

27
00:01:04,869 --> 00:01:05,920
we've actually got an upgrade to

28
00:01:05,920 --> 00:01:07,780
perform. For now though what we're going

29
00:01:07,780 --> 00:01:09,009
to do is, we're just going to of add some

30
00:01:09,009 --> 00:01:13,840
dummy code and some logging. Alright so I'm

31
00:01:13,840 --> 00:01:16,210
going to start with some logging, Log

32
00:01:16,210 --> 00:01:18,789
.d parentheses TAG comma double quotes

33
00:01:18,789 --> 00:01:27,609
onUpgrade colon starts. Alright, and

34
00:01:27,609 --> 00:01:30,280
we're going to type when in parentheses,

35
00:01:30,280 --> 00:01:34,539
old Version, and open a code block and

36
00:01:34,539 --> 00:01:37,149
then we're going to type 1 dash greater than sign

37
00:01:37,149 --> 00:01:39,999
and a code block. And I'm just going to put a

38
00:01:39,999 --> 00:01:43,030
comment in there, "upgrade logic from

39
00:01:43,030 --> 00:01:46,389
version 1". Then outside of that what we're

40
00:01:46,389 --> 00:01:48,939
going to do is, do an else dash greater

41
00:01:48,939 --> 00:01:51,999
than, and we're going do throw Illegal

42
00:01:51,999 --> 00:01:55,600
StateException, in the parentheses, on

43
00:01:55,600 --> 00:01:57,999
Upgrade parentheses in double quotes,

44
00:01:57,999 --> 00:02:04,810
with unknown newVersion colon space, and

45
00:02:04,810 --> 00:02:06,899
that's going to be $newVersion.

46
00:02:06,899 --> 00:02:09,729
Alright. Now we can create a new instance

47
00:02:09,729 --> 00:02:12,400
of our AppDdatabase class in Main

48
00:02:12,400 --> 00:02:14,680
Activity's onCreate method, and request

49
00:02:14,680 --> 00:02:16,300
a database connection to test that it

50
00:02:16,300 --> 00:02:19,500
works. So let's go back to our MainActivity,

51
00:02:19,500 --> 00:02:22,000
and specifically the onCreate method -

52
00:02:22,000 --> 00:02:24,670
we're going to do just that. So I'm going

53
00:02:24,670 --> 00:02:27,040
to start typing this code below the set

54
00:02:27,040 --> 00:02:30,160
SupportActionBar - give it a space

55
00:02:30,160 --> 00:02:32,500
there. So I'm going to start typing val

56
00:02:32,500 --> 00:02:38,800
appDatabase equals AppDatabase dot

57
00:02:38,800 --> 00:02:41,910
getInstance, then this in parenthesis.

58
00:02:41,910 --> 00:02:45,880
Then we're going to type val db equals 

59
00:02:45,880 --> 00:02:51,340
appDatabase.readableDatabase. Then next

60
00:02:51,340 --> 00:02:54,700
line, val cursor is equal to db.raw

61
00:02:54,700 --> 00:02:56,920
query, and in parentheses I'm going to

62
00:02:56,920 --> 00:03:04,060
type SELECT * FROM Tasks comma then

63
00:03:04,060 --> 00:03:06,640
null - that's the second argument. Then I'm going to

64
00:03:06,640 --> 00:03:11,050
do a Log.d parentheses TAG comma

65
00:03:11,050 --> 00:03:12,280
and I'm just going to do a series of

66
00:03:12,280 --> 00:03:17,230
asterisks there, and I'm gonna take

67
00:03:17,230 --> 00:03:20,260
the opportunity now to add our tag at the

68
00:03:20,260 --> 00:03:24,370
start of the file. So private const val TAG

69
00:03:24,370 --> 00:03:29,320
equals MainActivity. Okay, and then below

70
00:03:29,320 --> 00:03:32,130
the log entry we're going to do cursor

71
00:03:32,130 --> 00:03:36,280
dot use. Open a code block, and then

72
00:03:36,280 --> 00:03:37,270
we're going to type on the next line,

73
00:03:37,270 --> 00:03:43,530
while parentheses it.moveToNext,

74
00:03:43,530 --> 00:03:46,930
another code block. And a comment here

75
00:03:46,930 --> 00:03:48,360
that were going to "Cycle through all

76
00:03:48,360 --> 00:03:54,990
records", and then we're going to type with

77
00:03:54,990 --> 00:03:59,410
parentheses cursor. Open yet another

78
00:03:59,410 --> 00:04:01,930
code block and type val id equals get

79
00:04:01,930 --> 00:04:06,730
Long zero in parentheses, and val name is

80
00:04:06,730 --> 00:04:10,980
equal to getString, 1 in parentheses,

81
00:04:10,980 --> 00:04:16,870
val description equals getString, 2 in

82
00:04:16,870 --> 00:04:20,560
parentheses and then sortOrder, val sort

83
00:04:20,560 --> 00:04:25,750
Order equals getString, 3 in parentheses.

84
00:04:25,750 --> 00:04:28,510
And I'm going to type val result is

85
00:04:28,510 --> 00:04:32,469
equal to, in double quotes, ID colon

86
00:04:32,469 --> 00:04:38,169
space and $id full stop and name colon space

87
00:04:38,169 --> 00:04:40,389
dollar name. Then I'm going to go space

88
00:04:40,389 --> 00:04:45,340
there, then description colon dollar

89
00:04:45,340 --> 00:04:51,219
description in sort order colon $ sort

90
00:04:51,219 --> 00:04:54,219
Order. Then we're going to add another log

91
00:04:54,219 --> 00:04:57,629
there, so Log.d parentheses TAG comma.

92
00:04:57,629 --> 00:05:03,249
It's going to be onCreate reading data

93
00:05:03,249 --> 00:05:07,870
$result, and then finally what I'm

94
00:05:07,870 --> 00:05:10,060
going to do, is take a copy of this, these

95
00:05:10,060 --> 00:05:11,979
Asterisks, and I'm going to add that

96
00:05:11,979 --> 00:05:15,449
just above the fab.setOnClickListener there.

97
00:05:15,449 --> 00:05:18,129
Alright so what's this code doing? Well

98
00:05:18,129 --> 00:05:19,689
after getting an instance of AppDdatabase,

99
00:05:19,689 --> 00:05:22,210
we run a query and log the task details.

100
00:05:22,210 --> 00:05:24,249
This is very similar to the code we've

101
00:05:24,249 --> 00:05:26,319
seen previously. We won't be performing

102
00:05:26,319 --> 00:05:28,659
queries like this in the app though. This is

103
00:05:28,659 --> 00:05:30,550
just a test that our AppDatabase class

104
00:05:30,550 --> 00:05:33,580
is behaving as it should. Now I've added

105
00:05:33,580 --> 00:05:35,169
a row of asterisks as you saw there,

106
00:05:35,169 --> 00:05:37,180
before and after our data, because the

107
00:05:37,180 --> 00:05:39,069
new logcat makes it harder to spot

108
00:05:39,069 --> 00:05:42,039
our data. Alright, so now let's run our

109
00:05:42,039 --> 00:05:43,810
application. So I'm going to click on the

110
00:05:43,810 --> 00:05:47,649
button to start it, and I'm going to

111
00:05:47,649 --> 00:05:50,469
open our logcat, just so we can take a

112
00:05:50,469 --> 00:05:52,779
look and see what's happened. So firstly,

113
00:05:52,779 --> 00:05:54,669
the getInstance function returns a new

114
00:05:54,669 --> 00:05:56,289
instance of our singleton AppDatabase

115
00:05:56,289 --> 00:05:58,360
class, and we can see the constructor

116
00:05:58,360 --> 00:06:01,839
being called, here. We've got our App

117
00:06:01,839 --> 00:06:03,460
Database initializing on the next line,

118
00:06:03,460 --> 00:06:06,490
and then onCreate starting, and if you

119
00:06:06,490 --> 00:06:09,339
recall onCreate - that function's called

120
00:06:09,339 --> 00:06:10,479
for us because the android framework

121
00:06:10,479 --> 00:06:12,310
detects that the database doesn't

122
00:06:12,310 --> 00:06:14,800
already exist. So onCreate was called, as

123
00:06:14,800 --> 00:06:16,300
we can see there, and there's our SQL

124
00:06:16,300 --> 00:06:19,479
code. That's the code that creates the

125
00:06:19,479 --> 00:06:21,610
database when that onCreate

126
00:06:21,610 --> 00:06:23,469
function's called for us, because the

127
00:06:23,469 --> 00:06:25,779
Android framework detected that the

128
00:06:25,779 --> 00:06:28,060
database didn't already exist. So, so far

129
00:06:28,060 --> 00:06:30,339
so good. This is really showing us what

130
00:06:30,339 --> 00:06:33,069
we expected to be shown, or in other

131
00:06:33,069 --> 00:06:34,870
words, the functionalities working as

132
00:06:34,870 --> 00:06:36,909
expected. But what we want to do now is

133
00:06:36,909 --> 00:06:38,409
check that the database really was

134
00:06:38,409 --> 00:06:41,529
created, and does in fact contain our

135
00:06:41,529 --> 00:06:43,839
Tasks table. So what we're going to do

136
00:06:43,839 --> 00:06:45,550
now is close the logcat.

137
00:06:45,550 --> 00:06:48,610
I'm going to open Terminal. We're going

138
00:06:48,610 --> 00:06:50,140
to have a look at the database on the

139
00:06:50,140 --> 00:06:52,450
emulator. So I'm going to start by typing adb

140
00:06:52,450 --> 00:06:57,190
devices. Now most of the time when you do

141
00:06:57,190 --> 00:06:59,170
that, you'll only have a single device

142
00:06:59,170 --> 00:07:01,420
showing here. But I've got an emulator

143
00:07:01,420 --> 00:07:04,540
and my one-plus Android phone connected,

144
00:07:04,540 --> 00:07:06,640
and I've done it that way just so you

145
00:07:06,640 --> 00:07:09,130
can see how to use adb shell when

146
00:07:09,130 --> 00:07:10,470
there's more than one device available.

147
00:07:10,470 --> 00:07:12,730
But you'll get an error if you try to

148
00:07:12,730 --> 00:07:14,650
use adb commands with more than one

149
00:07:14,650 --> 00:07:17,170
device connected to the computer, whether

150
00:07:17,170 --> 00:07:19,020
they're emulators or physical devices.

151
00:07:19,020 --> 00:07:22,150
Now the reason for the error is that adb

152
00:07:22,150 --> 00:07:24,520
doesn't know which device you want to

153
00:07:24,520 --> 00:07:26,950
use. If there's only one it doesn't have

154
00:07:26,950 --> 00:07:28,480
a problem, but if you've got more than

155
00:07:28,480 --> 00:07:30,730
one then you have to specify which

156
00:07:30,730 --> 00:07:33,460
device you want to use. We do that with

157
00:07:33,460 --> 00:07:36,790
the dash s switch. So my emulator is showing

158
00:07:36,790 --> 00:07:39,820
up as emulator-5554, so the

159
00:07:39,820 --> 00:07:42,340
command I need to type here is adb

160
00:07:42,340 --> 00:07:50,040
space -s space emulator-5554

161
00:07:50,040 --> 00:07:54,550
space shell. So basically you can see

162
00:07:54,550 --> 00:07:56,830
that's connected now to the emulator, and

163
00:07:56,830 --> 00:07:58,000
whenever you've got more than one device

164
00:07:58,000 --> 00:08:00,270
connected just use -s and the device

165
00:08:00,270 --> 00:08:01,420
ID

166
00:08:01,420 --> 00:08:04,210
immediately after adb, and, which

167
00:08:04,210 --> 00:08:05,890
specifies which device should be used.

168
00:08:05,890 --> 00:08:08,140
Alright, so we're connected now to shell

169
00:08:08,140 --> 00:08:11,980
on our emulator, so let's type su. We

170
00:08:11,980 --> 00:08:14,740
need that super user mode, and that

171
00:08:14,740 --> 00:08:16,180
probably won't work if you're using a

172
00:08:16,180 --> 00:08:18,520
physical device, unless you've got root

173
00:08:18,520 --> 00:08:20,740
access and you've also installed the su

174
00:08:20,740 --> 00:08:23,080
command. So if you're testing this app on

175
00:08:23,080 --> 00:08:25,900
a physical device, you'll probably have

176
00:08:25,900 --> 00:08:27,850
to skip this step. But don't worry though,

177
00:08:27,850 --> 00:08:28,780
were already confirming that the

178
00:08:28,780 --> 00:08:31,150
database has been created. If it hadn't

179
00:08:31,150 --> 00:08:32,980
been then we would have seen errors in

180
00:08:32,980 --> 00:08:35,169
the logcat. Now we saw in an earlier

181
00:08:35,169 --> 00:08:37,720
video that the databases

182
00:08:37,720 --> 00:08:39,940
are created in the apps directory, in

183
00:08:39,940 --> 00:08:42,460
/data/data in a database

184
00:08:42,460 --> 00:08:44,590
directory. So make a note of your package

185
00:08:44,590 --> 00:08:46,510
name, because that's also the name of the

186
00:08:46,510 --> 00:08:48,550
apps home directory if you're using a

187
00:08:48,550 --> 00:08:50,590
different package name to me. In my case

188
00:08:50,590 --> 00:08:52,810
I'm going to type cd /data, that's 

189
00:08:52,810 --> 00:08:55,630
forward slash, /data again. That's

190
00:08:55,630 --> 00:08:57,490
going to be learnprogramming.academy

191
00:08:57,490 --> 00:08:58,880
dot tasktimer.

192
00:08:58,880 --> 00:08:59,990
You can see that coming up automatically

193
00:08:59,990 --> 00:09:02,540
when I clicked, when I pressed tab, and I'm

194
00:09:02,540 --> 00:09:05,240
going to go into databases. Alright, so now

195
00:09:05,240 --> 00:09:06,770
that I've done that I'm going to type 

196
00:09:06,770 --> 00:09:12,740
sqlite3 Tasktimer.db, and then

197
00:09:12,740 --> 00:09:16,670
I'm going to type .schema, and

198
00:09:16,670 --> 00:09:19,190
there's our Tasks table. Now remember

199
00:09:19,190 --> 00:09:21,320
that Android is a Linux operating system

200
00:09:21,320 --> 00:09:23,270
and the file and directory names are

201
00:09:23,270 --> 00:09:25,820
case sensitive. So if your Task timer

202
00:09:25,820 --> 00:09:27,290
database didn't open,

203
00:09:27,290 --> 00:09:29,540
make sure you've used the correct case

204
00:09:29,540 --> 00:09:31,880
for the name. Now this should be exactly

205
00:09:31,880 --> 00:09:33,740
the same as the database underscore name

206
00:09:33,740 --> 00:09:36,800
field in the AppDatabase class. Now while

207
00:09:36,800 --> 00:09:38,150
we're here, I'm going to add some records

208
00:09:38,150 --> 00:09:39,950
to the database. Now we're going to write

209
00:09:39,950 --> 00:09:41,870
the code to display the tasks before the

210
00:09:41,870 --> 00:09:44,060
code to add them, so these sample rows

211
00:09:44,060 --> 00:09:45,860
will let us see that the display code's

212
00:09:45,860 --> 00:09:47,720
working when we get to that point in

213
00:09:47,720 --> 00:09:49,760
development. So I'm going to type

214
00:09:49,760 --> 00:09:55,340
INSERT INTO Tasks parentheses Name comma

215
00:09:55,340 --> 00:10:01,520
Description VALUES parentheses Task

216
00:10:01,520 --> 00:10:03,440
Timer single quotes comma, single

217
00:10:03,440 --> 00:10:08,420
quote for Tasktimer app creation, and

218
00:10:08,420 --> 00:10:10,070
close off the single quote, right

219
00:10:10,070 --> 00:10:13,010
parentheses and semicolon. Then next one,

220
00:10:13,010 --> 00:10:15,880
we'll do INSERT INTO Tasks again,

221
00:10:15,880 --> 00:10:18,010
parentheses, it's going to be Name

222
00:10:18,010 --> 00:10:22,280
Description and SortOrder, separated by

223
00:10:22,280 --> 00:10:24,500
commas, and another parentheses to close

224
00:10:24,500 --> 00:10:26,800
it off - a right one - then VALUES

225
00:10:26,800 --> 00:10:29,120
parentheses. We're going to go with

226
00:10:29,120 --> 00:10:33,140
Android Java single quotes comma,

227
00:10:33,140 --> 00:10:37,480
single quotes again, Android Java course

228
00:10:37,480 --> 00:10:40,520
single quote comma, two right parentheses

229
00:10:40,520 --> 00:10:43,760
and semicolon. Alright, the third I'm

230
00:10:43,760 --> 00:10:46,990
going to type INSERT INTO Tasks

231
00:10:46,990 --> 00:10:50,680
parentheses Name comma Description comma

232
00:10:50,680 --> 00:10:54,790
and SortOrder comma right parentheses,

233
00:10:54,790 --> 00:10:58,850
VALUES and parentheses again. This time I'm going

234
00:10:58,850 --> 00:11:02,960
to type Android Kotlin and I'm going to type

235
00:11:02,960 --> 00:11:07,339
Android Kotlin course - which of course

236
00:11:07,339 --> 00:11:10,100
is this one - comma zero right parentheses

237
00:11:10,100 --> 00:11:11,070
and

238
00:11:11,070 --> 00:11:14,850
semicolon. Then we do a SELECT * FROM Tasks to

239
00:11:14,850 --> 00:11:17,400
make sure that the records are there. We

240
00:11:17,400 --> 00:11:19,290
can see the records are there. So at this

241
00:11:19,290 --> 00:11:21,480
point our database is looking fine. So

242
00:11:21,480 --> 00:11:22,530
we're going to quit sqlite by

243
00:11:22,530 --> 00:11:26,160
typing .exit, then we're going to leave

244
00:11:26,160 --> 00:11:28,320
super user mode by typing exit, without the

245
00:11:28,320 --> 00:11:30,450
dot time. Then we're going to log

246
00:11:30,450 --> 00:11:31,830
out of the Android shell by typing exit

247
00:11:31,830 --> 00:11:35,840
once more. Then I can type exit one more time

248
00:11:35,840 --> 00:11:39,090
and that closes the Terminal window. Al

249
00:11:39,090 --> 00:11:40,410
right, so now there's some data in the

250
00:11:40,410 --> 00:11:42,630
database. We should see it logged in the

251
00:11:42,630 --> 00:11:45,030
logcat when we run the app again, so let's

252
00:11:45,030 --> 00:11:46,920
go and try running that and see that it

253
00:11:46,920 --> 00:11:54,690
works. We'll open logcat. Alright so

254
00:11:54,690 --> 00:11:56,280
that's looking good. Our AppDatabase

255
00:11:56,280 --> 00:11:58,500
class created the database, and is now

256
00:11:58,500 --> 00:12:00,210
providing a database connection that we

257
00:12:00,210 --> 00:12:02,850
can use. We've now got the Tasks Contract

258
00:12:02,850 --> 00:12:05,430
and AppDatabase classes working. The

259
00:12:05,430 --> 00:12:07,290
next step is to create the Content

260
00:12:07,290 --> 00:12:09,660
Provider that we use to access the data

261
00:12:09,660 --> 00:12:11,790
in the database, and we'll start work on

262
00:12:11,790 --> 00:12:14,960
that in the next video.

