1
00:00:04,680 --> 00:00:06,629
Alright so let's talk about the App

2
00:00:06,629 --> 00:00:09,629
Database class. So in the previous video

3
00:00:09,629 --> 00:00:13,020
we created a Tasks Contract class that

4
00:00:13,020 --> 00:00:15,959
defines the column names for our Tasks

5
00:00:15,959 --> 00:00:18,810
table. Now that might seem a little bit

6
00:00:18,810 --> 00:00:20,910
over the top just to declare a few

7
00:00:20,910 --> 00:00:23,250
string constants, but as we create more

8
00:00:23,250 --> 00:00:25,740
code you'll see why we've bothered

9
00:00:25,740 --> 00:00:28,350
creating this. In this video we'll create

10
00:00:28,350 --> 00:00:31,170
the database class that will handle

11
00:00:31,170 --> 00:00:34,079
creating our database. And it'll also

12
00:00:34,079 --> 00:00:36,690
provide the database object that our

13
00:00:36,690 --> 00:00:39,149
Content Provider is going to need when

14
00:00:39,149 --> 00:00:41,820
it comes to access the database. So let's

15
00:00:41,820 --> 00:00:44,130
start by creating the App Database class.

16
00:00:44,130 --> 00:00:45,870
I'm going to right click on the package,

17
00:00:45,870 --> 00:00:50,070
New, Kotlin File/Class and AppDatabase

18
00:00:50,070 --> 00:00:53,700
being the name. Now I'm going to make

19
00:00:53,700 --> 00:00:56,129
this internal, because the only thing

20
00:00:56,129 --> 00:00:57,719
that should ever use this class will be

21
00:00:57,719 --> 00:01:00,059
our Content Provider. I'm going to type 

22
00:01:00,059 --> 00:01:04,078
internal class AppDatabase, left and

23
00:01:04,078 --> 00:01:06,420
right curly braces. In fact, what I'll do

24
00:01:06,420 --> 00:01:08,310
is, I'll add a comment to that effect at

25
00:01:08,310 --> 00:01:11,010
the start of the class. I'm going to add

26
00:01:11,010 --> 00:01:13,220
it here and we're going to say "Basic

27
00:01:13,220 --> 00:01:18,960
database class for the application." and

28
00:01:18,960 --> 00:01:21,000
"The only class that should use this is

29
00:01:21,000 --> 00:01:27,590
Approvider", 

30
00:01:27,590 --> 00:01:29,600
and Approvider's going to be in left

31
00:01:29,600 --> 00:01:31,270
and right square brackets.

32
00:01:31,270 --> 00:01:33,619
And notice how that got highlighted when

33
00:01:33,619 --> 00:01:35,030
I typed that in left and right square

34
00:01:35,030 --> 00:01:36,710
brackets, but more on that 

35
00:01:36,710 --> 00:01:39,049
in a moment. So when you start a comment

36
00:01:39,049 --> 00:01:40,909
with a forward slash and two stars or

37
00:01:40,909 --> 00:01:43,100
two asterisks, that indicates what's

38
00:01:43,100 --> 00:01:45,709
known as a doc comment - also known as a

39
00:01:45,709 --> 00:01:48,140
KDoc. And it's very similar to the

40
00:01:48,140 --> 00:01:50,990
Java doc comments, but some things such

41
00:01:50,990 --> 00:01:53,869
as links have been simplified. Now you

42
00:01:53,869 --> 00:01:54,920
may have noticed this type of

43
00:01:54,920 --> 00:01:57,079
comment in the Android Java source code

44
00:01:57,079 --> 00:01:58,640
that we've looked at. There's quite a

45
00:01:58,640 --> 00:02:00,860
formal structure to these doc comments,

46
00:02:00,860 --> 00:02:02,810
and you may have noticed this when we

47
00:02:02,810 --> 00:02:05,360
looked at documentation previously in

48
00:02:05,360 --> 00:02:06,950
this course for a method slash function.

49
00:02:06,950 --> 00:02:09,889
So the content looks like a formatted

50
00:02:09,889 --> 00:02:11,239
version of the comments in the source

51
00:02:11,239 --> 00:02:13,400
code, and there is a reason for that.

52
00:02:13,400 --> 00:02:15,500
That's because the documentation is

53
00:02:15,500 --> 00:02:17,780
generated from those comments using the

54
00:02:17,780 --> 00:02:20,540
Java doc tool. Now in Kotlin the same

55
00:02:20,540 --> 00:02:23,569
applies but, the tool's called Dokka. Now

56
00:02:23,569 --> 00:02:25,579
I won't be discussing doc comments in

57
00:02:25,579 --> 00:02:28,040
this course, but I'll start using them to

58
00:02:28,040 --> 00:02:29,560
comment some of the code that we write.

59
00:02:29,560 --> 00:02:32,060
Now you find loads of information

60
00:02:32,060 --> 00:02:34,160
on-line, including the Kotlin

61
00:02:34,160 --> 00:02:38,739
documentation. Let's go and check that out.

62
00:02:38,739 --> 00:02:40,670
So this here you can see, that's

63
00:02:40,670 --> 00:02:43,160
information about documenting Kotlin

64
00:02:43,160 --> 00:02:46,579
code. And actually I planned to show

65
00:02:46,579 --> 00:02:49,160
you this KDoc appearing when we used

66
00:02:49,160 --> 00:02:51,079
the AppDatabase class in our code,

67
00:02:51,079 --> 00:02:54,260
but unfortunately the Dokka plug-in for

68
00:02:54,260 --> 00:02:56,410
Android studio is currently broken.

69
00:02:56,410 --> 00:02:58,819
Hopefully they'll fix it soon, but as of

70
00:02:58,819 --> 00:03:00,799
the time I'm recording this video, it

71
00:03:00,799 --> 00:03:03,230
causes the Gradle builds to

72
00:03:03,230 --> 00:03:05,630
crash which means that you can't compile

73
00:03:05,630 --> 00:03:07,220
and run your apps. That's pretty severe,

74
00:03:07,220 --> 00:03:09,169
so for that reason we're not going to

75
00:03:09,169 --> 00:03:11,269
use it. So although we can't see it

76
00:03:11,269 --> 00:03:13,370
working, it's still a good idea to

77
00:03:13,370 --> 00:03:16,400
include doc comments in your classes. So

78
00:03:16,400 --> 00:03:17,859
I'll just switch back to Android Studio.

79
00:03:17,859 --> 00:03:20,870
Now these KDoc strings

80
00:03:20,870 --> 00:03:23,780
are parsed by Android Studio, and

81
00:03:23,780 --> 00:03:25,340
we've actually got a warning over here. We can

82
00:03:25,340 --> 00:03:27,079
see if we hover over this AppProvider

83
00:03:27,079 --> 00:03:28,940
in square brackets, and also the warning

84
00:03:28,940 --> 00:03:30,919
over here in the gutter that we can't

85
00:03:30,919 --> 00:03:33,590
resolve - symbol AppProvider. That's

86
00:03:33,590 --> 00:03:35,209
because it hasn't been written yet, so

87
00:03:35,209 --> 00:03:36,439
don't worry about that warning at the

88
00:03:36,439 --> 00:03:38,239
moment. Alright but getting back to this

89
00:03:38,239 --> 00:03:40,700
class, this AppDatabase class will

90
00:03:40,700 --> 00:03:41,420
extend

91
00:03:41,420 --> 00:03:43,640
the SQLiteOpenHelper class that

92
00:03:43,640 --> 00:03:45,590
Android provides to make using sqlite

93
00:03:45,590 --> 00:03:47,330
databases easier. So let's go

94
00:03:47,330 --> 00:03:48,080
ahead and add that -

95
00:03:48,080 --> 00:03:51,230
so the colon after the AppDatabase space

96
00:03:51,230 --> 00:03:55,989
and SQLiteOpenHelper parentheses.

97
00:03:55,989 --> 00:03:58,160
Now we've got some errors at the moment.

98
00:03:58,160 --> 00:04:00,500
The SQLiteOpenHelper class has

99
00:04:00,500 --> 00:04:02,000
some abstract methods that we need to

100
00:04:02,000 --> 00:04:04,130
implement. It's got no idea whether, or

101
00:04:04,130 --> 00:04:05,840
what the structure of our database

102
00:04:05,840 --> 00:04:08,030
should be, for example, so it leaves it up

103
00:04:08,030 --> 00:04:09,769
to our class to implement the onCreate

104
00:04:09,769 --> 00:04:12,590
function. But before implementing that

105
00:04:12,590 --> 00:04:14,300
function and also the onUpgrade

106
00:04:14,300 --> 00:04:16,760
function, there's another error because

107
00:04:16,760 --> 00:04:18,620
the SQLiteOpenHelper class needs

108
00:04:18,620 --> 00:04:23,120
some arguments in its constructor. You

109
00:04:23,120 --> 00:04:24,350
can see when I hover over to that

110
00:04:24,350 --> 00:04:26,570
warning, or that error rather, that

111
00:04:26,570 --> 00:04:28,400
makes it clearer that we need to do 

112
00:04:28,400 --> 00:04:30,320
that. So it needs some arguments to

113
00:04:30,320 --> 00:04:32,990
its constructor. So those are a context -

114
00:04:32,990 --> 00:04:35,720
the name and version of our database - and

115
00:04:35,720 --> 00:04:37,729
also something called a CursorFactory.

116
00:04:37,729 --> 00:04:40,340
Now the database name and version can be

117
00:04:40,340 --> 00:04:43,010
declared as constants, and I'll also add

118
00:04:43,010 --> 00:04:44,540
a constant tag for logging, so let's go

119
00:04:44,540 --> 00:04:46,729
ahead and do that. I'll add those above

120
00:04:46,729 --> 00:04:49,850
the class definition here, so private

121
00:04:49,850 --> 00:04:55,010
const Val TAG is equal to, in double

122
00:04:55,010 --> 00:04:58,910
quotes, AppDatabase. Then next we've got

123
00:04:58,910 --> 00:05:02,539
private const Val DATABASE underscore

124
00:05:02,539 --> 00:05:05,780
NAME in uppercase, which unsurprisingly

125
00:05:05,780 --> 00:05:08,150
is our database name. That was Task

126
00:05:08,150 --> 00:05:12,260
Timer.db, and we also want a

127
00:05:12,260 --> 00:05:14,900
const for the version; private const

128
00:05:14,900 --> 00:05:17,840
val DATABASE_VERSION, again in

129
00:05:17,840 --> 00:05:21,680
uppercase, equals 3. And now that

130
00:05:21,680 --> 00:05:24,200
we've done that we can expand on the

131
00:05:24,200 --> 00:05:27,080
class definition line on line 19.

132
00:05:27,080 --> 00:05:29,390
So let's first add a constructor for App

133
00:05:29,390 --> 00:05:33,560
Database - so after the AppDatabase type

134
00:05:33,560 --> 00:05:35,930
constructor. Then in parentheses we're

135
00:05:35,930 --> 00:05:37,610
going to type context in lower case,

136
00:05:37,610 --> 00:05:40,520
colon Contexts with a capital C,

137
00:05:40,520 --> 00:05:43,639
which is using the Android, or coming

138
00:05:43,639 --> 00:05:46,310
from android.content. And if we scroll up

139
00:05:46,310 --> 00:05:47,810
we can see now that import has

140
00:05:47,810 --> 00:05:48,410
been added.

141
00:05:48,410 --> 00:05:50,900
Then over to the right for the 

142
00:05:50,900 --> 00:05:52,760
SQLiteOpenHelper, we need to pass those

143
00:05:52,760 --> 00:05:54,620
parameters now. So the

144
00:05:54,620 --> 00:05:57,620
first one is going to be context - let's

145
00:05:57,620 --> 00:06:00,470
add that. Next we want to pass the

146
00:06:00,470 --> 00:06:03,770
DATABASE_NAME. Next we're going to pass a

147
00:06:03,770 --> 00:06:05,419
null and I'll talk about that shortly -

148
00:06:05,419 --> 00:06:07,520
the CursorFactory - and lastly the

149
00:06:07,520 --> 00:06:10,220
DATABASE_VERSION. So that's fixed

150
00:06:10,220 --> 00:06:12,949
one of those errors now, and if we hover over

151
00:06:12,949 --> 00:06:14,479
here now, it's now just complaining about

152
00:06:14,479 --> 00:06:16,790
the fact we haven't implemented the

153
00:06:16,790 --> 00:06:19,639
methods. Alright, so what we've done

154
00:06:19,639 --> 00:06:21,500
here, is when our AppDatabase instance

155
00:06:21,500 --> 00:06:23,720
is created it'll be passed a context

156
00:06:23,720 --> 00:06:25,970
now. That's needed as the first argument

157
00:06:25,970 --> 00:06:28,580
in the SQLiteOpenHelper

158
00:06:28,580 --> 00:06:30,740
constructor, which we've now added. The

159
00:06:30,740 --> 00:06:32,810
DATABASE_NAME as the second argument is

160
00:06:32,810 --> 00:06:34,669
obvious, and we'll see why we need a

161
00:06:34,669 --> 00:06:36,169
version later which was the fourth

162
00:06:36,169 --> 00:06:38,660
argument, later in the course. But for the

163
00:06:38,660 --> 00:06:40,520
CursorFactory - the third argument - I've

164
00:06:40,520 --> 00:06:43,550
specified null. You can create your own

165
00:06:43,550 --> 00:06:45,680
class to create custom cursors if you

166
00:06:45,680 --> 00:06:48,770
wish, and one reason for doing that is if

167
00:06:48,770 --> 00:06:50,600
you wanted to log the SQL queries

168
00:06:50,600 --> 00:06:53,810
before they're executed. for example. But

169
00:06:53,810 --> 00:06:55,699
the Cursor class included in Android is

170
00:06:55,699 --> 00:06:58,280
fine, so we're just passing null for that

171
00:06:58,280 --> 00:06:59,900
third argument so that we can use that.

172
00:06:59,900 --> 00:07:02,210
Alright, so at this point I'm going to

173
00:07:02,210 --> 00:07:04,880
do something slightly strange now, and I

174
00:07:04,880 --> 00:07:06,200
don't recommend you doing this in

175
00:07:06,200 --> 00:07:08,539
production code. For reasons that will

176
00:07:08,539 --> 00:07:10,970
become apparent shortly, it'll be useful

177
00:07:10,970 --> 00:07:12,650
to see when a new instance of this class

178
00:07:12,650 --> 00:07:16,010
is created. To do that, what I'm going to

179
00:07:16,010 --> 00:07:17,900
do is add an init block that does

180
00:07:17,900 --> 00:07:19,729
nothing more than log when it's called.

181
00:07:19,729 --> 00:07:21,950
And that's going to be very useful for

182
00:07:21,950 --> 00:07:24,260
us to see what's going on, but as I

183
00:07:24,260 --> 00:07:26,510
mentioned isn't a good idea to use in

184
00:07:26,510 --> 00:07:28,039
your apps. So we're going to go ahead and

185
00:07:28,039 --> 00:07:31,910
add this init block, so it's an init, then add a left

186
00:07:31,910 --> 00:07:34,940
and right curly brace. Then within there

187
00:07:34,940 --> 00:07:36,800
we're just going to add a log - so Log.d

188
00:07:36,800 --> 00:07:39,830
parentheses TAG comma, then in double quotes

189
00:07:39,830 --> 00:07:47,810
AppDatabase colon initializing. OK. Now

190
00:07:47,810 --> 00:07:49,250
we've still got that error because we

191
00:07:49,250 --> 00:07:50,660
haven't implemented those abstract

192
00:07:50,660 --> 00:07:53,210
classes, so let's get Android Studio to

193
00:07:53,210 --> 00:07:57,919
generate those for us. So we'll implement

194
00:07:57,919 --> 00:08:02,750
both onCreate and onUpgrade. Now

195
00:08:02,750 --> 00:08:04,789
the SQLiteOpenHelper class can do

196
00:08:04,789 --> 00:08:07,130
a lot for us, but it can't know the

197
00:08:07,130 --> 00:08:08,129
SQL commands that are

198
00:08:08,129 --> 00:08:11,429
needed to create our database, nor how to

199
00:08:11,429 --> 00:08:12,899
upgrade it from one version to another.

200
00:08:12,899 --> 00:08:15,270
So in other words we have to provide the

201
00:08:15,270 --> 00:08:18,269
implementation of those two methods, and

202
00:08:18,269 --> 00:08:19,409
that's why they're abstract in the

203
00:08:19,409 --> 00:08:22,529
SQLiteOpenHelper class. Alright, so

204
00:08:22,529 --> 00:08:24,749
we've implemented at the moment, empty

205
00:08:24,749 --> 00:08:26,009
versions of both of those that have

206
00:08:26,009 --> 00:08:28,709
only got a TODO in there. And when an

207
00:08:28,709 --> 00:08:31,080
instance of this class is created, the

208
00:08:31,080 --> 00:08:34,229
code in its superclass - which is

209
00:08:34,229 --> 00:08:36,630
SQLiteOpenHelper - will check to see if

210
00:08:36,630 --> 00:08:39,240
the database already exists. Now if

211
00:08:39,240 --> 00:08:41,849
it doesn't exist, our onCreate function

212
00:08:41,849 --> 00:08:44,068
will be called. Now this is where we'll

213
00:08:44,068 --> 00:08:46,800
execute the SQL statements to create

214
00:08:46,800 --> 00:08:49,350
the tables, views and other objects in

215
00:08:49,350 --> 00:08:52,110
our database. At the moment though, we're

216
00:08:52,110 --> 00:08:54,870
focusing on the Tasks table, and we

217
00:08:54,870 --> 00:08:56,550
created the SQL for that in the

218
00:08:56,550 --> 00:08:58,680
previous video. So I'm just going to paste

219
00:08:58,680 --> 00:09:01,110
that in as a comment, so we've got a

220
00:09:01,110 --> 00:09:03,480
reference point for the SQL code we're

221
00:09:03,480 --> 00:09:06,750
ultimately going to be creating. Alright,

222
00:09:06,750 --> 00:09:08,480
and I'll just delete the TODO there.

223
00:09:08,480 --> 00:09:11,730
We'll paste that in as a comment. Alright,

224
00:09:11,730 --> 00:09:13,139
so what we're going to do next is build

225
00:09:13,139 --> 00:09:16,079
up the necessary string to create this

226
00:09:16,079 --> 00:09:18,180
SQL statement, but let's work on that

227
00:09:18,180 --> 00:09:21,380
in the next video.

