Source of file MySQLDAL.php

Size: 25,307 Bytes - Last Modified: 2019-07-22T06:17:07+00:00

C:/xampp/htdocs/PodTube/src/classes/DB/MySQLDAL.php

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
Covered by 2 test(s):
  • MySQLDALTest::testMakeDB
  • MySQLDALTest::testUpdateDB
74
Covered by 2 test(s):
  • MySQLDALTest::testMakeDB
  • MySQLDALTest::testUpdateDB
757677
Covered by 2 test(s):
  • MySQLDALTest::testMakeDB
  • MySQLDALTest::testUpdateDB
78798081
Covered by 2 test(s):
  • MySQLDALTest::testMakeDB
  • MySQLDALTest::testUpdateDB
8283
Covered by 2 test(s):
  • MySQLDALTest::testMakeDB
  • MySQLDALTest::testUpdateDB
84
Covered by 2 test(s):
  • MySQLDALTest::testMakeDB
  • MySQLDALTest::testUpdateDB
858687888990
Covered by 2 test(s):
  • MySQLDALTest::testMakeDB
  • MySQLDALTest::testUpdateDB
919293949596979899100101
Covered by 5 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
102
Covered by 5 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
103
Covered by 5 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
104
Covered by 5 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
105
Covered by 5 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
106107108
Covered by 5 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
109110111
Covered by 5 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
112113
Covered by 5 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
114115116117118119120121122123124125126127128
Covered by 5 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
129
Covered by 5 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
130
Covered by 5 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
131
Covered by 5 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
132
Covered by 5 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
133
Covered by 5 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
134
Covered by 5 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
135
Covered by 5 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
136
Covered by 5 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
137
Covered by 5 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
138
Covered by 5 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
139
Covered by 5 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
140
Covered by 5 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
141142
Covered by 5 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
143
Covered by 5 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
144
Covered by 2 test(s):
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testUpdateUserEmailPasswordCodes
145146
Covered by 5 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
147
Covered by 2 test(s):
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testUpdateUserEmailPasswordCodes
148149
Covered by 5 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
150151
Covered by 5 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
152153154155156157158159160161162163
Covered by 2 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdateUser
164
Covered by 2 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdateUser
165
Covered by 2 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdateUser
166
Covered by 2 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdateUser
167
Covered by 2 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdateUser
168169170
Covered by 2 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdateUser
171172173
Covered by 2 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdateUser
174175
Covered by 2 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdateUser
176177178179180181182183184185186187188189190191
Covered by 10 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
192193
Covered by 10 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
194
Covered by 10 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
195
Covered by 10 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
196
Covered by 10 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
197
Covered by 10 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
198199200
Covered by 10 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
201
Covered by 10 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
202203
Covered by 1 test(s):
  • SQLiteTest::testAddUser
204205
Covered by 1 test(s):
  • SQLiteTest::testAddUser
206207208209210211212213214215216217218219220221
Covered by 10 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
222223
Covered by 10 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
224
Covered by 10 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
225
Covered by 10 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
226
Covered by 10 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
227
Covered by 10 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
228229230
Covered by 10 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
231
Covered by 10 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
232233
Covered by 1 test(s):
  • SQLiteTest::testAddUser
234235
Covered by 1 test(s):
  • SQLiteTest::testAddUser
236237238239240241242243244245246247248249250
Covered by 10 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
251252
Covered by 10 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
253254255
Covered by 10 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
256
Covered by 10 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
257
Covered by 10 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
258
Covered by 10 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
259
Covered by 10 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
260
Covered by 10 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
261
Covered by 10 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
262
Covered by 10 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
263
Covered by 10 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
264
Covered by 10 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
265
Covered by 10 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
266
Covered by 10 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
267268269270
Covered by 10 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
271272273274275276
Covered by 10 test(s):
  • SQLiteTest::testAddUser
  • SQLiteTest::testUpdatePassword
  • SQLiteTest::testUpdateUser
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
  • SQLiteTest::testSetFeedText
  • SQLiteTest::testUpdateUserEmailPasswordCodes
277278279280281282283284285286287288289
Covered by 5 test(s):
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
290
Covered by 5 test(s):
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
291
Covered by 5 test(s):
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
292
Covered by 5 test(s):
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
293
Covered by 5 test(s):
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
294
Covered by 5 test(s):
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
295296297
Covered by 3 test(s):
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
298299300301
Covered by 5 test(s):
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
302303304
Covered by 5 test(s):
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
305
Covered by 5 test(s):
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
306
Covered by 5 test(s):
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
307
Covered by 5 test(s):
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
308
Covered by 5 test(s):
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
309
Covered by 5 test(s):
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
310
Covered by 5 test(s):
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
311
Covered by 5 test(s):
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
312
Covered by 5 test(s):
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
313
Covered by 5 test(s):
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
314
Covered by 5 test(s):
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
315
Covered by 5 test(s):
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
316317
Covered by 5 test(s):
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
  • SQLiteTest::testGetPrunableVideos
318319320321322323324325326327328329330331332333334
Covered by 1 test(s):
  • SQLiteTest::testUpdateVideo
335
Covered by 1 test(s):
  • SQLiteTest::testUpdateVideo
336
Covered by 1 test(s):
  • SQLiteTest::testUpdateVideo
337338
Covered by 1 test(s):
  • SQLiteTest::testUpdateVideo
339
Covered by 1 test(s):
  • SQLiteTest::testUpdateVideo
340
Covered by 1 test(s):
  • SQLiteTest::testUpdateVideo
341
Covered by 1 test(s):
  • SQLiteTest::testUpdateVideo
342
Covered by 1 test(s):
  • SQLiteTest::testUpdateVideo
343
Covered by 1 test(s):
  • SQLiteTest::testUpdateVideo
344
Covered by 1 test(s):
  • SQLiteTest::testUpdateVideo
345
Covered by 1 test(s):
  • SQLiteTest::testUpdateVideo
346
Covered by 1 test(s):
  • SQLiteTest::testUpdateVideo
347
Covered by 1 test(s):
  • SQLiteTest::testUpdateVideo
348349
Covered by 1 test(s):
  • SQLiteTest::testUpdateVideo
350351352353354355356357358359360361362363364365366367368
Covered by 3 test(s):
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
369
Covered by 3 test(s):
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
370
Covered by 3 test(s):
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
371
Covered by 3 test(s):
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
372
Covered by 3 test(s):
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
373374
Covered by 3 test(s):
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
375
Covered by 3 test(s):
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
376377378379
Covered by 3 test(s):
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
380
Covered by 3 test(s):
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
381382383
Covered by 3 test(s):
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
384385386387388389390391392393394395396397398
Covered by 4 test(s):
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
399400
Covered by 4 test(s):
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
401
Covered by 4 test(s):
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
402
Covered by 4 test(s):
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
403
Covered by 4 test(s):
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
404
Covered by 4 test(s):
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
405
Covered by 4 test(s):
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
406
Covered by 4 test(s):
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
407
Covered by 4 test(s):
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
408
Covered by 4 test(s):
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
409
Covered by 4 test(s):
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
410
Covered by 4 test(s):
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
411412
Covered by 4 test(s):
  • SQLiteTest::testAddVideo
  • SQLiteTest::testUpdateVideo
  • SQLiteTest::testGetFeed
  • SQLiteTest::testGetFeedHistory
413414415416417418419420421422423424425
Covered by 1 test(s):
  • SQLiteTest::testGetFeedHistory
426
Covered by 1 test(s):
  • SQLiteTest::testGetFeedHistory
427
Covered by 1 test(s):
  • SQLiteTest::testGetFeedHistory
428
Covered by 1 test(s):
  • SQLiteTest::testGetFeedHistory
429
Covered by 1 test(s):
  • SQLiteTest::testGetFeedHistory
430431432
Covered by 1 test(s):
  • SQLiteTest::testGetFeedHistory
433
Covered by 1 test(s):
  • SQLiteTest::testGetFeedHistory
434
Covered by 1 test(s):
  • SQLiteTest::testGetFeedHistory
435436437
Covered by 1 test(s):
  • SQLiteTest::testGetFeedHistory
438439440441442443444445446447448449450451452453454455
Covered by 1 test(s):
  • SQLiteTest::testSetFeedText
456
Covered by 1 test(s):
  • SQLiteTest::testSetFeedText
457
Covered by 1 test(s):
  • SQLiteTest::testSetFeedText
458
Covered by 1 test(s):
  • SQLiteTest::testSetFeedText
459460
Covered by 1 test(s):
  • SQLiteTest::testSetFeedText
461462463464465466467468469470471472473474475
Covered by 1 test(s):
  • SQLiteTest::testUpdatePassword
476
Covered by 1 test(s):
  • SQLiteTest::testUpdatePassword
477
Covered by 1 test(s):
  • SQLiteTest::testUpdatePassword
478
Covered by 1 test(s):
  • SQLiteTest::testUpdatePassword
479480481482483484
Covered by 1 test(s):
  • SQLiteTest::testUpdatePassword
485486487488489490491492493
Covered by 1 test(s):
  • SQLiteTest::testUpdateUserEmailPasswordCodes
494495
Covered by 1 test(s):
  • SQLiteTest::testUpdateUserEmailPasswordCodes
496
Covered by 1 test(s):
  • SQLiteTest::testUpdateUserEmailPasswordCodes
497
Covered by 1 test(s):
  • SQLiteTest::testUpdateUserEmailPasswordCodes
498
Covered by 1 test(s):
  • SQLiteTest::testUpdateUserEmailPasswordCodes
499500501502503504
Covered by 1 test(s):
  • SQLiteTest::testUpdateUserEmailPasswordCodes
505506507508509510511512513514
Covered by 1 test(s):
  • SQLiteTest::testUpdateUser
515516517518
Covered by 1 test(s):
  • SQLiteTest::testUpdateUser
519
Covered by 1 test(s):
  • SQLiteTest::testUpdateUser
520
Covered by 1 test(s):
  • SQLiteTest::testUpdateUser
521
Covered by 1 test(s):
  • SQLiteTest::testUpdateUser
522
Covered by 1 test(s):
  • SQLiteTest::testUpdateUser
523
Covered by 1 test(s):
  • SQLiteTest::testUpdateUser
524
Covered by 1 test(s):
  • SQLiteTest::testUpdateUser
525
Covered by 1 test(s):
  • SQLiteTest::testUpdateUser
526
Covered by 1 test(s):
  • SQLiteTest::testUpdateUser
527
Covered by 1 test(s):
  • SQLiteTest::testUpdateUser
528
Covered by 1 test(s):
  • SQLiteTest::testUpdateUser
529
Covered by 1 test(s):
  • SQLiteTest::testUpdateUser
530
Covered by 1 test(s):
  • SQLiteTest::testUpdateUser
531
Covered by 1 test(s):
  • SQLiteTest::testUpdateUser
532533534535536537
Covered by 1 test(s):
  • SQLiteTest::testUpdateUser
538539540541542543544545546547
Covered by 2 test(s):
  • MySQLDALTest::testMakeDB
  • MySQLDALTest::testUpdateDB
548
Covered by 1 test(s):
  • MySQLDALTest::testMakeDB
549550551
Covered by 1 test(s):
  • MySQLDALTest::testMakeDB
552
Covered by 1 test(s):
  • MySQLDALTest::testMakeDB
553
Covered by 1 test(s):
  • MySQLDALTest::testMakeDB
554
Covered by 1 test(s):
  • MySQLDALTest::testMakeDB
555
Covered by 1 test(s):
  • MySQLDALTest::testMakeDB
556557
Covered by 1 test(s):
  • MySQLDALTest::testMakeDB
558
Covered by 1 test(s):
  • MySQLDALTest::testMakeDB
559560561562563
Covered by 1 test(s):
  • MySQLDALTest::testMakeDB
564
Covered by 1 test(s):
  • MySQLDALTest::testMakeDB
565566567568569
Covered by 1 test(s):
  • MySQLDALTest::testMakeDB
570571572
Covered by 1 test(s):
  • MySQLDALTest::testUpdateDB
573
Covered by 1 test(s):
  • MySQLDALTest::testUpdateDB
574575
Covered by 2 test(s):
  • MySQLDALTest::testMakeDB
  • MySQLDALTest::testUpdateDB
576577578579580581582583584585
Covered by 2 test(s):
  • MySQLDALTest::testMakeDB
  • MySQLDALTest::testUpdateDB
586
Covered by 2 test(s):
  • MySQLDALTest::testMakeDB
  • MySQLDALTest::testUpdateDB
587
Covered by 1 test(s):
  • MySQLDALTest::testMakeDB
588589590
Covered by 2 test(s):
  • MySQLDALTest::testMakeDB
  • MySQLDALTest::testUpdateDB
591592
Covered by 2 test(s):
  • MySQLDALTest::testMakeDB
  • MySQLDALTest::testUpdateDB
593
Covered by 1 test(s):
  • MySQLDALTest::testMakeDB
594595
Covered by 2 test(s):
  • MySQLDALTest::testMakeDB
  • MySQLDALTest::testUpdateDB
596
Covered by 1 test(s):
  • MySQLDALTest::testMakeDB
597598
Covered by 2 test(s):
  • MySQLDALTest::testMakeDB
  • MySQLDALTest::testUpdateDB
599
Covered by 1 test(s):
  • MySQLDALTest::testMakeDB
600601602
Covered by 2 test(s):
  • MySQLDALTest::testMakeDB
  • MySQLDALTest::testUpdateDB
603604605606607
Covered by 2 test(s):
  • MySQLDALTest::testUpdateDB
  • SQLiteTest::testMakeDB
608
Covered by 2 test(s):
  • MySQLDALTest::testUpdateDB
  • SQLiteTest::testMakeDB
609
Covered by 2 test(s):
  • MySQLDALTest::testUpdateDB
  • SQLiteTest::testMakeDB
610
Covered by 2 test(s):
  • MySQLDALTest::testUpdateDB
  • SQLiteTest::testMakeDB
611
Covered by 2 test(s):
  • MySQLDALTest::testUpdateDB
  • SQLiteTest::testMakeDB
612613614
Covered by 2 test(s):
  • MySQLDALTest::testUpdateDB
  • SQLiteTest::testMakeDB
615616617618619620621
Covered by 2 test(s):
  • MySQLDALTest::testUpdateDB
  • SQLiteTest::testMakeDB
622623624625626627628629630
Covered by 1 test(s):
  • MySQLDALTest::testUpdateDB
631
Covered by 1 test(s):
  • MySQLDALTest::testUpdateDB
632633
Covered by 1 test(s):
  • MySQLDALTest::testUpdateDB
634635636637638639640641642643644645646
Covered by 1 test(s):
  • MySQLDALTest::testUpdateDB
647648
Covered by 1 test(s):
  • MySQLDALTest::testUpdateDB
649650
Covered by 1 test(s):
  • MySQLDALTest::testUpdateDB
651652
Covered by 1 test(s):
  • MySQLDALTest::testUpdateDB
653
Covered by 1 test(s):
  • MySQLDALTest::testUpdateDB
654
Covered by 1 test(s):
  • MySQLDALTest::testUpdateDB
655656657
Covered by 1 test(s):
  • MySQLDALTest::testUpdateDB
658
Covered by 1 test(s):
  • MySQLDALTest::testUpdateDB
659660
Covered by 1 test(s):
  • MySQLDALTest::testUpdateDB
661662663664665
Covered by 1 test(s):
  • MySQLDALTest::testUpdateDB
666667668669670671672673674675676677
Covered by 3 test(s):
  • MySQLDALTest::testMakeDB
  • MySQLDALTest::testUpdateDB
  • SQLiteTest::testMakeDB
678
Covered by 3 test(s):
  • MySQLDALTest::testMakeDB
  • MySQLDALTest::testUpdateDB
  • SQLiteTest::testMakeDB
679
Covered by 3 test(s):
  • MySQLDALTest::testMakeDB
  • MySQLDALTest::testUpdateDB
  • SQLiteTest::testMakeDB
680
Covered by 3 test(s):
  • MySQLDALTest::testMakeDB
  • MySQLDALTest::testUpdateDB
  • SQLiteTest::testMakeDB
681682683684
Covered by 1 test(s):
  • MySQLDALTest::testUpdateDB
685
Covered by 1 test(s):
  • MySQLDALTest::testUpdateDB
686
Covered by 1 test(s):
  • MySQLDALTest::testUpdateDB
687
Covered by 1 test(s):
  • MySQLDALTest::testUpdateDB
688689690691692693694695696697698699700701702703704705
Covered by 2 test(s):
  • MySQLDALTest::testMakeDB
  • MySQLDALTest::testUpdateDB
706
Covered by 2 test(s):
  • MySQLDALTest::testMakeDB
  • MySQLDALTest::testUpdateDB
707
Covered by 2 test(s):
  • MySQLDALTest::testMakeDB
  • MySQLDALTest::testUpdateDB
708
Covered by 2 test(s):
  • MySQLDALTest::testMakeDB
  • MySQLDALTest::testUpdateDB
709
Covered by 2 test(s):
  • MySQLDALTest::testMakeDB
  • MySQLDALTest::testUpdateDB
710
Covered by 1 test(s):
  • MySQLDALTest::testUpdateDB
711712713
Covered by 2 test(s):
  • MySQLDALTest::testMakeDB
  • MySQLDALTest::testUpdateDB
714715716717718719720721722723724
Covered by 1 test(s):
  • MySQLDALTest::testUpdateDB
725
Covered by 1 test(s):
  • MySQLDALTest::testUpdateDB
726727
Covered by 1 test(s):
  • MySQLDALTest::testUpdateDB
728729730731732733734735736
Covered by 1 test(s):
  • SQLiteTest::testGetPrunableVideos
737
Covered by 1 test(s):
  • SQLiteTest::testGetPrunableVideos
738739740741742743
Covered by 1 test(s):
  • SQLiteTest::testGetPrunableVideos
744
Covered by 1 test(s):
  • SQLiteTest::testGetPrunableVideos
745746747748
Covered by 1 test(s):
  • SQLiteTest::testGetPrunableVideos
749750
Covered by 1 test(s):
  • SQLiteTest::testGetPrunableVideos
751
Covered by 1 test(s):
  • SQLiteTest::testGetPrunableVideos
752753754755
Covered by 1 test(s):
  • SQLiteTest::testGetPrunableVideos
756
Covered by 1 test(s):
  • SQLiteTest::testGetPrunableVideos
757
Covered by 1 test(s):
  • SQLiteTest::testGetPrunableVideos
758
Covered by 1 test(s):
  • SQLiteTest::testGetPrunableVideos
759760
Covered by 1 test(s):
  • SQLiteTest::testGetPrunableVideos
761
Covered by 1 test(s):
  • SQLiteTest::testGetPrunableVideos
762
Covered by 1 test(s):
  • SQLiteTest::testGetPrunableVideos
763764
Covered by 1 test(s):
  • SQLiteTest::testGetPrunableVideos
765766767
Covered by 1 test(s):
  • SQLiteTest::testGetPrunableVideos
768769770
<?php

namespace AudioDidact\DB;

use AudioDidact\User;
use AudioDidact\Video;

/**
 * Class MySQLDAL contains methods for communicating with a SQL database
 *
 */
class MySQLDAL extends DAL {
	/** @var string Database table for storing user information */
	protected $userTable = "users";
	/** @var string Database table for storing feed/video information */
	protected $feedTable = "feed";
	/** @var array|string SQL database table names */
	protected $myDBTables;
	/** @var  array|array array of the correct database table schemas keyed by table name */
	protected $correctSchemas;
	/**
	 * Correct layout of the user table
	 *
	 * @var array
	 */
	protected $userCorrect = [
		["Field" => "ID", "Type" => "int(11)", "Null" => "NO", "Key" => "PRI", "Default" => null, "Extra" => "auto_increment"],
		["Field" => "username", "Type" => "mediumtext", "Null" => "NO", "Key" => "", "Default" => null, "Extra" => ""],
		["Field" => "password", "Type" => "mediumtext", "Null" => "NO", "Key" => "", "Default" => null, "Extra" => ""],
		["Field" => "email", "Type" => "mediumtext", "Null" => "NO", "Key" => "", "Default" => null, "Extra" => ""],
		["Field" => "firstname", "Type" => "mediumtext", "Null" => "YES", "Key" => "", "Default" => null, "Extra" => ""],
		["Field" => "lastname", "Type" => "mediumtext", "Null" => "YES", "Key" => "", "Default" => null, "Extra" => ""],
		["Field" => "gender", "Type" => "mediumtext", "Null" => "YES", "Key" => "", "Default" => null, "Extra" => ""],
		["Field" => "webID", "Type" => "mediumtext", "Null" => "NO", "Key" => "", "Default" => null, "Extra" => ""],
		["Field" => "feedText", "Type" => "longtext", "Null" => "NO", "Key" => "", "Default" => null, "Extra" => ""],
		["Field" => "feedLength", "Type" => "int(11)", "Null" => "NO", "Key" => "", "Default" => null, "Extra" => ""],
		["Field" => "feedDetails", "Type" => "mediumtext", "Null" => "YES", "Key" => "", "Default" => null, "Extra" => ""],
		["Field" => "privateFeed", "Type" => "tinyint(1)", "Null" => "NO", "Key" => "", "Default" => null, "Extra" => ""],
		["Field" => "emailVerified", "Type" => "tinyint(1)", "Null" => "NO", "Key" => "", "Default" => "0", "Extra" => ""],
		["Field" => "emailVerificationCodes", "Type" => "text", "Null" => "YES", "Key" => "", "Default" => null, "Extra" => ""],
		["Field" => "passwordRecoveryCodes", "Type" => "text", "Null" => "YES", "Key" => "", "Default" => null, "Extra" => ""]
	];
	/**
	 * Correct layout of the feed table
	 *
	 * @var array
	 */
	protected $feedCorrect = [
		["Field" => "ID", "Type" => "int(11)", "Null" => "NO", "Key" => "PRI", "Default" => null, "Extra" => "auto_increment"],
		["Field" => "userID", "Type" => "int(11)", "Null" => "NO", "Key" => "", "Default" => null, "Extra" => ""],
		["Field" => "URL", "Type" => "text", "Null" => "YES", "Key" => "", "Default" => null, "Extra" => ""],
		["Field" => "orderID", "Type" => "int(11)", "Null" => "NO", "Key" => "", "Default" => null, "Extra" => ""],
		["Field" => "filename", "Type" => "mediumtext", "Null" => "YES", "Key" => "", "Default" => null, "Extra" => ""],
		["Field" => "thumbnailFilename", "Type" => "mediumtext", "Null" => "YES", "Key" => "", "Default" => null, "Extra" => ""],
		["Field" => "videoID", "Type" => "mediumtext", "Null" => "NO", "Key" => "", "Default" => null, "Extra" => ""],
		["Field" => "videoAuthor", "Type" => "text", "Null" => "NO", "Key" => "", "Default" => null, "Extra" => ""],
		["Field" => "description", "Type" => "text", "Null" => "YES", "Key" => "", "Default" => null, "Extra" => ""],
		["Field" => "videoTitle", "Type" => "text", "Null" => "NO", "Key" => "", "Default" => null, "Extra" => ""],
		["Field" => "duration", "Type" => "int(11)", "Null" => "YES", "Key" => "", "Default" => null, "Extra" => ""],
		["Field" => "isVideo", "Type" => "tinyint(1)", "Null" => "NO", "Key" => "", "Default" => "0", "Extra" => ""],
		["Field" => "timeAdded", "Type" => "timestamp", "Null" => "NO", "Key" => "", "Default" => "CURRENT_TIMESTAMP", "Extra" => ""]
	];

	/**
	 * MySQLDAL constructor.
	 * Sets up parent's PDO object using the parameters that are passed in.
	 *
	 * @param $pdoStr
	 * @param \PDO|null $p
	 * @internal param \PDO $pdo
	 */
	public function __construct($pdoStr, \PDO $p = null){
		$this->myDBTables = [$this->userTable, $this->feedTable];
		$this->correctSchemas = [$this->userTable => $this->userCorrect, $this->feedTable => $this->feedCorrect];

		try{
			if($p === null){
				parent::$PDO = new \PDO($pdoStr, DB_USER, DB_PASSWORD);
			}
			else{
				parent::$PDO = $p;
			}
			parent::$PDO->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
			parent::$PDO->query("SET time_zone = \"+00:00\";");
		}
		catch(\PDOException $e){
			echo 'ERROR: ' . $e->getMessage();
			throw $e;
		}
	}

	/**
	 * Gets the user by the database user id
	 *
	 * @param int $id
	 * @return null|User
	 * @throws \PDOException
	 */
	public function getUserByID($id){
		try{
			$p = parent::$PDO->prepare("SELECT * FROM $this->userTable WHERE ID=:id");
			$p->bindValue(":id", $id, \PDO::PARAM_INT);
			$p->execute();
			$rows = $p->fetchAll(\PDO::FETCH_ASSOC);
			if(count($rows) > 1){
				return null;
			}
			if(count($rows) == 0){
				return null;
			}
			$rows = $rows[0];

			return $this->setUser($rows);
		}
		catch(\PDOException $e){
			echo "ERROR: " . $e->getMessage();
			throw $e;
		}
	}

	/**
	 * Makes a new user object from a database select command.
	 *
	 * @param $row array Database row retrieved from another method
	 * @return User
	 */
	private function setUser($row){
		$user = new User();
		$user->setUserID($row["ID"]);
		$user->setUsername($row["username"]);
		$user->setPasswdDB($row["password"]);
		$user->setEmail($row["email"]);
		$user->setFname($row["firstname"]);
		$user->setLname($row["lastname"]);
		$user->setGender(intval($row["gender"]));
		$user->setWebID($row["webID"]);
		$user->setFeedText($row["feedText"]);
		$user->setFeedLength(intval($row["feedLength"]));
		if($row["feedDetails"] != ""){
			$user->setFeedDetails(json_decode($row["feedDetails"], true));
		}
		$user->setPrivateFeed($row["privateFeed"]);
		if($row["emailVerificationCodes"] != ""){
			$user->setEmailVerificationCodes(json_decode($row["emailVerificationCodes"], true));
		}
		if($row["passwordRecoveryCodes"] != ""){
			$user->setPasswordRecoveryCodes(json_decode($row["passwordRecoveryCodes"], true));
		}
		$user->setEmailVerified($row["emailVerified"]);

		return $user;
	}

	/**
	 * Gets a User object from a webID
	 *
	 * @param string $webID
	 * @return null|User
	 * @throws \PDOException
	 */
	public function getUserByWebID($webID){
		try{
			$p = parent::$PDO->prepare("SELECT * FROM $this->userTable WHERE webID=:id");
			$p->bindValue(":id", $webID, \PDO::PARAM_STR);
			$p->execute();
			$rows = $p->fetchAll(\PDO::FETCH_ASSOC);
			if(count($rows) > 1){
				return null;
			}
			if(count($rows) == 0){
				return null;
			}
			$rows = $rows[0];

			return $this->setUser($rows);
		}
		catch(\PDOException $e){
			echo "ERROR: " . $e->getMessage();
			throw $e;
		}
	}

	/**
	 * Gets a User from the database based on a username
	 *
	 * @param string $username
	 * @return null|User
	 * @throws \PDOException
	 */
	public function getUserByUsername($username){
		$username = mb_strtolower($username);
		try{
			$p = parent::$PDO->prepare("SELECT * FROM $this->userTable WHERE username=:username");
			$p->bindValue(":username", $username, \PDO::PARAM_STR);
			$p->execute();
			$rows = $p->fetchAll(\PDO::FETCH_ASSOC);
			if(count($rows) > 1){
				return null;
			}
			if(count($rows) == 0){
				return null;
			}
			$rows = $rows[0];

			return $this->setUser($rows);
		}
		catch(\PDOException $e){
			echo "ERROR: " . $e->getMessage();
			throw $e;
		}
	}

	/**
	 * Gets User from an email
	 *
	 * @param string $email
	 * @return null|User
	 * @throws \PDOException
	 */
	public function getUserByEmail($email){
		$email = mb_strtolower($email);
		try{
			$p = parent::$PDO->prepare("SELECT * FROM $this->userTable WHERE email=:email");
			$p->bindValue(":email", $email, \PDO::PARAM_STR);
			$p->execute();
			$rows = $p->fetchAll(\PDO::FETCH_ASSOC);
			if(count($rows) > 1){
				return null;
			}
			if(count($rows) == 0){
				return null;
			}
			$rows = $rows[0];

			return $this->setUser($rows);
		}
		catch(\PDOException $e){
			echo "ERROR: " . $e->getMessage();
			throw $e;
		}
	}

	/**
	 * Adds a User object to the database
	 *
	 * @param User $user
	 * @throws \Exception|\PDOException
	 */
	public function addUser(User $user){
		if(!$this->usernameExists($user->getUsername()) && !$this->emailExists($user->getEmail())){
			try{
				$p = parent::$PDO->prepare("INSERT INTO $this->userTable (username, password, email, firstname,
				lastname, gender, webID, feedLength, feedText, feedDetails, privateFeed) VALUES (:username,:password,:email,
				:fname,:lname,:gender,:webID,:feedLength, :feedText,:feedDetails,:privateFeed)");
				$p->bindValue(':username', $user->getUsername(), \PDO::PARAM_STR);
				$p->bindValue(':password', $user->getPasswd(), \PDO::PARAM_STR);
				$p->bindValue(':email', $user->getEmail(), \PDO::PARAM_STR);
				$p->bindValue(':fname', $user->getFname(), \PDO::PARAM_STR);
				$p->bindValue(':lname', $user->getLname(), \PDO::PARAM_STR);
				$p->bindValue(':gender', $user->getGender(), \PDO::PARAM_INT);
				$p->bindValue(':webID', $user->getWebID(), \PDO::PARAM_STR);
				$p->bindValue(':feedLength', $user->getFeedLength(), \PDO::PARAM_INT);
				$p->bindValue(':feedText', $user->getFeedText(), \PDO::PARAM_STR);
				$p->bindValue(':feedDetails', json_encode($user->getFeedDetails()), \PDO::PARAM_STR);
				$p->bindValue(':privateFeed', $user->isPrivateFeed(), \PDO::PARAM_BOOL);
				$p->execute();
			}
			catch(\PDOException $e){
				echo 'ERROR: ' . $e->getMessage();
				throw $e;
			}
		}
		else{
			throw new \Exception("Username or Email Address Already Exists!");
		}
	}

	/**
	 * Adds a video to the feed table
	 *
	 * @param Video $vid
	 * @param User $user
	 * @return bool
	 * @throws \PDOException
	 */
	public function addVideo(Video $vid, User $user){
		try{
			// Find the largest orderID and add 1 to it to use as the orderID of the newest video
			$p = parent::$PDO->prepare("SELECT * FROM $this->feedTable WHERE userID=:userid ORDER BY orderID DESC LIMIT 1");
			$p->bindValue(":userid", $user->getUserID(), \PDO::PARAM_INT);
			$p->execute();
			$rows = $p->fetchAll(\PDO::FETCH_ASSOC);
			if(count($rows) == 0){
				$order = 1;
			}
			else{
				$order = intval($rows[0]["orderID"]) + 1;
			}

			// Add the new Video to the user's feed
			$p = parent::$PDO->prepare("INSERT INTO $this->feedTable (userID, URL, videoID, videoAuthor, description,
			videoTitle, duration, orderID, filename, thumbnailFilename, isVideo) VALUES (:userID,:url,:videoID,
			:videoAuthor, :description, :videoTitle,:duration, :orderID, :filename, :thumbnailFilename, :isVideo)");
			$p->bindValue(":userID", $user->getUserID(), \PDO::PARAM_INT);
			$p->bindValue(":videoID", $vid->getId(), \PDO::PARAM_STR);
			$p->bindValue(":url", $vid->getURL(), \PDO::PARAM_STR);
			$p->bindValue(":videoAuthor", $vid->getAuthor(), \PDO::PARAM_STR);
			$p->bindValue(":description", $vid->getDesc(), \PDO::PARAM_STR);
			$p->bindValue(":videoTitle", $vid->getTitle(), \PDO::PARAM_STR);
			$p->bindValue(":duration", $vid->getDuration(), \PDO::PARAM_STR);
			$p->bindValue(":orderID", $order, \PDO::PARAM_INT);
			$p->bindValue(":filename", $vid->getFilename(), \PDO::PARAM_STR);
			$p->bindValue(":thumbnailFilename", $vid->getThumbnailFilename(), \PDO::PARAM_STR);
			$p->bindValue(":isVideo", $vid->isIsVideo(), \PDO::PARAM_BOOL);
			$p->execute();

			return true;
		}
		catch(\PDOException $e){
			echo "ERROR: " . $e->getMessage();
			throw $e;
		}
	}

	/**
	 * Updates an existing video in the video database for a specific user
	 *
	 * @param Video $vid
	 * @param User $user
	 * @return mixed
	 */
	public function updateVideo(Video $vid, User $user){
		try{
			$p = parent::$PDO->prepare("UPDATE $this->feedTable SET videoAuthor = :videoAuthor,"
				. "description = :description, videoTitle = :videoTitle, duration = :duration, filename = :filename,"
				. "thumbnailFilename = :thumbnailFilename, isVideo = :isVideo WHERE videoID = :videoID AND userID = :userID");

			$p->bindValue(":userID", $user->getUserID(), \PDO::PARAM_INT);
			$p->bindValue(":videoID", $vid->getId(), \PDO::PARAM_STR);
			$p->bindValue(":videoAuthor", $vid->getAuthor(), \PDO::PARAM_STR);
			$p->bindValue(":description", $vid->getDesc(), \PDO::PARAM_STR);
			$p->bindValue(":videoTitle", $vid->getTitle(), \PDO::PARAM_STR);
			$p->bindValue(":duration", $vid->getDuration(), \PDO::PARAM_STR);
			$p->bindValue(":filename", $vid->getFilename(), \PDO::PARAM_STR);
			$p->bindValue(":thumbnailFilename", $vid->getThumbnailFilename(), \PDO::PARAM_STR);
			$p->bindValue(":isVideo", $vid->isIsVideo(), \PDO::PARAM_BOOL);
			$p->execute();

			return true;
		}
		catch(\PDOException $e){
			echo "ERROR: " . $e->getMessage();
			throw $e;
		}
	}

	/**
	 * Returns an array of YouTube IDs that are in the feed
	 *
	 * @param User $user
	 * @return array|null
	 * @throws \PDOException
	 */
	public function getFeed(User $user){
		try{
			// Limit is not able to be a bound parameter, so I take the intval just to make sure nothing can get
			// injected
			$p = parent::$PDO->prepare("SELECT * FROM $this->feedTable WHERE userID=:userid ORDER BY orderID DESC LIMIT "
				. intval($user->getFeedLength()));
			$p->bindValue(":userid", $user->getUserID(), \PDO::PARAM_INT);
			$p->execute();
			$rows = $p->fetchAll(\PDO::FETCH_ASSOC);

			$returner = [];
			if(count($rows) < 1){
				return $returner;
			}

			foreach($rows as $row){
				$returner[] = $this->setVideo($row);
			}

			return $returner;
		}
		catch(\PDOException $e){
			echo "ERROR: " . $e->getMessage();
			throw $e;
		}
	}

	/**
	 * Makes a new video object from a database select command.
	 *
	 * @param $row array Database rows retrieved from another method
	 * @return Video
	 */
	private function setVideo($row){
		$vid = new Video();

		$vid->setAuthor($row["videoAuthor"]);
		$vid->setDesc($row["description"]);
		$vid->setId($row["videoID"]);
		$vid->setTime(strtotime($row["timeAdded"]));
		$vid->setDuration(intval($row["duration"]));
		$vid->setTitle($row["videoTitle"]);
		$vid->setOrder(intval($row["orderID"]));
		$vid->setURL($row["URL"]);
		$vid->setIsVideo(boolval($row["isVideo"]));
		$vid->setFilename($row["filename"]);
		$vid->setThumbnailFilename($row["thumbnailFilename"]);

		return $vid;
	}

	/**
	 * Gets all the videos from the database
	 *
	 * @param User $user
	 * @return mixed
	 */
	public function getFullFeedHistory(User $user){
		try{
			// Limit is not able to be a bound parameter, so I take the intval just to make sure nothing can get
			// injected
			$p = parent::$PDO->prepare("SELECT * FROM $this->feedTable WHERE userID=:userid ORDER BY orderID DESC");
			$p->bindValue(":userid", $user->getUserID(), \PDO::PARAM_INT);
			$p->execute();
			$rows = $p->fetchAll(\PDO::FETCH_ASSOC);
			if(count($rows) < 1){
				return [];
			}
			$returner = [];
			foreach($rows as $row){
				$returner[] = $this->setVideo($row);
			}

			return $returner;
		}
		catch(\PDOException $e){
			echo "ERROR: " . $e->getMessage();
			throw $e;
		}
	}

	/**
	 * Sets full feed text in the feed database
	 *
	 * @param User $user
	 * @param $feed
	 * @return bool
	 * @throws \PDOException
	 */
	public function setFeedText(User $user, $feed){
		try{
			$p = parent::$PDO->prepare("UPDATE $this->userTable set feedText=:feedText WHERE id=:userid");
			$p->bindValue(":userid", $user->getUserID(), \PDO::PARAM_INT);
			$p->bindValue(":feedText", $feed, \PDO::PARAM_STR);
			$p->execute();

			return true;
		}
		catch(\PDOException $e){
			echo "ERROR: " . $e->getMessage();
			throw $e;
		}
	}

	/**
	 * Updates only a user's password in the database
	 *
	 * @param User $user
	 */
	public function updateUserPassword(User $user){
		try{
			$p = parent::$PDO->prepare("UPDATE $this->userTable SET `password`=:passwd WHERE ID=:id");
			$p->bindValue(":passwd", $user->getPasswd(), \PDO::PARAM_STR);
			$p->bindValue(":id", $user->getUserID(), \PDO::PARAM_INT);
			$p->execute();
		}
		catch(\PDOException $e){
			echo "ERROR: " . $e->getMessage();
			throw $e;
		}
	}

	/**
	 * Updates only a user's email verification and password recovery codes in the database
	 *
	 * @param User $user
	 */
	public function updateUserEmailPasswordCodes(User $user){
		try{
			$p = parent::$PDO->prepare("UPDATE $this->userTable SET emailVerificationCodes=:email,
 				passwordRecoveryCodes=:pass WHERE ID=:id");
			$p->bindValue(":email", json_encode($user->getEmailVerificationCodes()), \PDO::PARAM_STR);
			$p->bindValue(":pass", json_encode($user->getPasswordRecoveryCodes()), \PDO::PARAM_STR);
			$p->bindValue(":id", $user->getUserID(), \PDO::PARAM_INT);
			$p->execute();
		}
		catch(\PDOException $e){
			echo "ERROR: " . $e->getMessage();
			throw $e;
		}
	}

	/**
	 * Updates the user database from a given \User object
	 *
	 * @param User $user
	 * @throws \PDOException
	 */
	public function updateUser(User $user){
		try{
			$p = parent::$PDO->prepare("UPDATE $this->userTable SET email=:email, firstname=:fname,
 			lastname=:lname, gender=:gender, feedLength=:feedLen, username=:uname, webID=:webID,
 			feedDetails=:feedDetails,privateFeed=:privateFeed,emailVerified=:emailVerified,emailVerificationCodes=:emailCodes,
 			passwordRecoveryCodes=:passCodes WHERE ID=:id");
			$p->bindValue(":id", $user->getUserID(), \PDO::PARAM_INT);
			$p->bindValue(":email", $user->getEmail(), \PDO::PARAM_STR);
			$p->bindValue(":fname", $user->getFname(), \PDO::PARAM_STR);
			$p->bindValue(":lname", $user->getLname(), \PDO::PARAM_STR);
			$p->bindValue(":gender", $user->getGender(), \PDO::PARAM_INT);
			$p->bindValue(":feedLen", $user->getFeedLength(), \PDO::PARAM_INT);
			$p->bindValue(":uname", $user->getUsername(), \PDO::PARAM_STR);
			$p->bindValue(":webID", $user->getWebID(), \PDO::PARAM_STR);
			$p->bindValue(":feedDetails", json_encode($user->getFeedDetails()), \PDO::PARAM_STR);
			$p->bindValue(":privateFeed", $user->isPrivateFeed(), \PDO::PARAM_BOOL);
			$p->bindValue(":emailVerified", $user->isEmailVerified(), \PDO::PARAM_BOOL);
			$p->bindValue(":emailCodes", json_encode($user->getEmailVerificationCodes()), \PDO::PARAM_STR);
			$p->bindValue(":passCodes", json_encode($user->getPasswordRecoveryCodes()), \PDO::PARAM_STR);
			$p->execute();
		}
		catch(\PDOException $e){
			echo "ERROR: " . $e->getMessage();
			throw $e;
		}
	}

	/**
	 * Generate the tables in the current database
	 *
	 * @param int $code
	 * @return void
	 * @throws \PDOException
	 */
	public function makeDB($code = 1){
		if($code == 1){
			$generalSetupSQL = "SET SQL_MODE = \"NO_AUTO_VALUE_ON_ZERO\";
							SET time_zone = \"+00:00\";";

			$sql = "";
			foreach($this->myDBTables as $tableName){
				$sql .= "CREATE TABLE `$tableName` (";
				foreach($this->correctSchemas[$tableName] as $column){
					$sql .= $this->makeColumnSQL($column) . ",";
				}
				$sql = mb_substr($sql, 0, mb_strlen($sql) - 1);
				$sql .= ") CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;";
			}

			try{
				// Execute all the statements
				$p = parent::$PDO->prepare($generalSetupSQL . $sql);
				$p->execute();
			}
			catch(\PDOException $e){
				echo "Database creation failed! " . $e->getMessage();
				error_log("Database creation failed! " . $e->getMessage());
				throw $e;
			}
		}
		else if($code == 2){
			$this->updateDBSchema();
		}
	}

	/**
	 * Generates SQL query to make a column. Returns something in the form of `columnName` columnType NULL/Not
	 * Default Key Extra
	 *
	 * @param $c array dictionary representing a column's correct schema
	 * @return string
	 */
	protected function makeColumnSQL($c){
		$columnText = "`" . $c["Field"] . "` " . $c["Type"];
		if($c["Null"] == "NO"){
			$columnText .= " NOT NULL";
		}
		else{
			$columnText .= " NULL";
		}
		if($c["Default"] != null){
			$columnText .= " DEFAULT " . $c["Default"];
		}
		if($c["Key"] == "PRI"){
			$columnText .= " PRIMARY KEY";
		}
		if($c["Extra"] == "auto_increment"){
			$columnText .= " " . $c["Extra"];
		}

		return $columnText;
	}

	protected function updateDBSchema(){
		try{
			$alterSQL = "";
			foreach($this->myDBTables as $tableName){
				$currentSchema = $this->describeTable($tableName);
				$alterSQL .= $this->makeAlterQuery([$tableName => $currentSchema],
					[$tableName => $this->correctSchemas[$tableName]]);
			}

			parent::$PDO->exec($alterSQL);
		}
		catch(\PDOException $e){
			echo "Database update failed! " . $e->getMessage();
			error_log("Database update failed! " . $e->getMessage());
			throw $e;
		}
	}

	/**
	 * Function to get layout of a specific table
	 *
	 * @param $table string Table to get layout of
	 * @return array
	 */
	protected function describeTable($table){
		$p = parent::$PDO->prepare("DESCRIBE $table");
		$p->execute();

		return $p->fetchAll(\PDO::FETCH_ASSOC);
	}

	/**
	 * Generates SQL query to add missing columns to the given tables
	 *
	 * @param $currentTables array dictionary in the form of ["tableName"=>[table_schema]] representing the values
	 * that are currently existing in the database
	 * @param $correctTables array dictionary in the form of ["tableName"=>[table_schema]] representing the correct
	 * values
	 * @return string
	 */
	protected function makeAlterQuery($currentTables, $correctTables){
		$sql = "";
		// Loop through the given tables
		foreach($correctTables as $tableName => $table){
			// Loop through all the columns in a table
			foreach($table as $i => $correct){
				// Check if the current column is in the existing database table
				if(!in_array($correct, $currentTables[$tableName], true)){
					$sql .= "ALTER TABLE `" . $tableName . "` ADD " . $this->makeColumnSQL($correct);
					if($i == 0){
						$sql .= " FIRST";
					}
					if($i > 0){
						$sql .= " AFTER `" . $table[$i - 1]["Field"] . "`";
					}
					$sql .= ";";
				}
			}
		}

		return $sql;
	}

	/**
	 * Verifies the currently connected database against the current schema
	 *
	 * @return int Returns 0 if all is well, 1 if the user table or feed table do not exist, and 2 if the tables exist
	 *     but the schema inside is wrong
	 * @throws \PDOException
	 */
	public function verifyDB(){
		try{
			$tables = $this->getDatabaseTables();
			foreach($this->myDBTables as $tableName){
				if(!in_array($tableName, $tables, true)){
					return 1;
				}
			}

			foreach($this->myDBTables as $tableName){
				$currentTableSchema = $this->describeTable($tableName);
				if(!$this->verifySchema($this->correctSchemas[$tableName], $currentTableSchema)){
					return 2;
				}
			}

			return 0;
		}
		catch(\PDOException $e){
			echo "ERROR: " . $e->getMessage();
			throw $e;
		}
	}

	/**
	 * Function to return a list of database tables
	 *
	 * @return array
	 */
	protected function getDatabaseTables(){
		$p = parent::$PDO->prepare("SHOW TABLES");
		$p->execute();
		$rows = $p->fetchAll(\PDO::FETCH_ASSOC);
		$tables = [];
		foreach($rows as $r){
			$tables[] = array_values($r)[0];
		}

		return $tables;
	}

	/**
	 * Checks if two arrays are equal to test that SQL schemas are compliant
	 *
	 * @param $correct
	 * @param $existing
	 * @return bool
	 */
	private function verifySchema($correct, $existing){
		sort($correct);
		sort($existing);

		return $correct == $existing;
	}

	/**
	 * Returns an array of video IDs that can be safely deleted
	 *
	 * @return array
	 */
	public function getPrunableVideos(){
		$feedTable = $this->feedTable;
		$userTable = $this->userTable;
		$pruneSQL = "SELECT `videoID`,
						MIN((MaxOrderID-orderID)>=feedLength) AS `isUnNeeded`
						FROM
							(SELECT
							`" . $feedTable . "`.`userID`,
							`" . $userTable . "`.`feedLength`,
							videoID,
							orderID
						  FROM
							`" . $feedTable . "`
						  INNER JOIN
							`" . $userTable . "` ON `" . $feedTable . "`.`userID` = `" . $userTable . "`.`ID`) Y
					    INNER JOIN (SELECT `userID`, MAX(`orderID`) AS MaxOrderID FROM `" . $feedTable . "` GROUP BY `userID`) AS X
					        ON X.userID=Y.`userID`
					    GROUP BY `videoID`
					    ORDER BY `isUnNeeded` DESC";
		$p = parent::$PDO->prepare($pruneSQL);
		$p->execute();
		$rows = $p->fetchAll(\PDO::FETCH_ASSOC);
		$pruneArray = [];

		foreach($rows as $r){
			if($r["isUnNeeded"] == 0){
				continue;
			}
			$pruneArray[] = $r["videoID"];
		}

		return $pruneArray;
	}

}