blob: ab22dddb26592a117b25d7b01e4d65b0cdc11ac1 [file] [log] [blame]
Mike Lockwood16864ba2010-05-11 17:16:59 -04001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "MtpDatabase.h"
18#include "MtpDataPacket.h"
19#include "SqliteDatabase.h"
20#include "SqliteStatement.h"
21
22#include <stdio.h>
Mike Lockwoodfceef462010-05-14 15:35:17 -040023#include <stdlib.h>
Mike Lockwood16864ba2010-05-11 17:16:59 -040024#include <sqlite3.h>
25
Mike Lockwood7850ef92010-05-14 10:10:36 -040026namespace android {
27
Mike Lockwoodfceef462010-05-14 15:35:17 -040028#define FILE_ID_COLUMN 1
29#define FILE_PATH_COLUMN 2
30#define FILE_FORMAT_COLUMN 3
31#define FILE_PARENT_COLUMN 4
32#define FILE_STORAGE_COLUMN 5
33#define FILE_SIZE_COLUMN 6
34#define FILE_MODIFIED_COLUMN 7
Mike Lockwood16864ba2010-05-11 17:16:59 -040035
Mike Lockwoodfceef462010-05-14 15:35:17 -040036#define AUDIO_ID_COLUMN 1
37#define AUDIO_TITLE_COLUMN 2
38#define AUDIO_ARTIST_COLUMN 3
39#define AUDIO_ALBUM_COLUMN 4
40#define AUDIO_ALBUM_ARTIST_COLUMN 5
41#define AUDIO_GENRE_COLUMN 6
42#define AUDIO_COMPOSER_COLUMN 7
43#define AUDIO_TRACK_NUMBER_COLUMN 8
44#define AUDIO_YEAR_COLUMN 9
45#define AUDIO_DURATION_COLUMN 10
46#define AUDIO_USE_COUNT_COLUMN 11
47#define AUDIO_SAMPLE_RATE_COLUMN 12
48#define AUDIO_NUM_CHANNELS_COLUMN 13
49#define AUDIO_AUDIO_WAVE_CODEC_COLUMN 14
50#define AUDIO_AUDIO_BIT_RATE_COLUMN 15
51
52#define FILE_TABLE_CREATE "CREATE TABLE IF NOT EXISTS files (" \
Mike Lockwood16864ba2010-05-11 17:16:59 -040053 "_id INTEGER PRIMARY KEY," \
54 "path TEXT," \
55 "format INTEGER," \
56 "parent INTEGER," \
57 "storage INTEGER," \
58 "size INTEGER," \
Mike Lockwoodfceef462010-05-14 15:35:17 -040059 "date_modified INTEGER" \
60 ");"
61
62#define AUDIO_TABLE_CREATE "CREATE TABLE IF NOT EXISTS audio (" \
63 "id INTEGER PRIMARY KEY," \
64 "title TEXT," \
65 "artist TEXT," \
66 "album TEXT," \
67 "album_artist TEXT," \
68 "genre TEXT," \
69 "composer TEXT," \
70 "track_number INTEGER," \
71 "year INTEGER," \
72 "duration INTEGER," \
73 "use_count INTEGER," \
74 "sample_rate INTEGER," \
75 "num_channels INTEGER," \
76 "audio_wave_codec TEXT," \
77 "audio_bit_rate INTEGER" \
Mike Lockwood16864ba2010-05-11 17:16:59 -040078 ");"
79
80#define PATH_INDEX_CREATE "CREATE INDEX IF NOT EXISTS path_index on files(path);"
81
Mike Lockwoodfceef462010-05-14 15:35:17 -040082#define FILE_ID_QUERY "SELECT _id,format FROM files WHERE path = ?;"
Mike Lockwood16864ba2010-05-11 17:16:59 -040083#define FILE_PATH_QUERY "SELECT path,size FROM files WHERE _id = ?"
84
Mike Lockwoodfceef462010-05-14 15:35:17 -040085#define GET_OBJECT_INFO_QUERY "SELECT storage,format,parent,path,size,date_modified FROM files WHERE _id = ?;"
86#define FILE_INSERT "INSERT INTO files VALUES(?,?,?,?,?,?,?);"
87#define FILE_DELETE "DELETE FROM files WHERE _id = ?;"
88
89#define AUDIO_INSERT "INSERT INTO audio VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);"
90#define AUDIO_DELETE "DELETE FROM audio WHERE id = ?;"
Mike Lockwood16864ba2010-05-11 17:16:59 -040091
Mike Lockwood16864ba2010-05-11 17:16:59 -040092struct PropertyTableEntry {
93 MtpObjectProperty property;
94 int type;
95 const char* columnName;
96};
97
98static const PropertyTableEntry kPropertyTable[] = {
99 { MTP_PROPERTY_PARENT_OBJECT, MTP_TYPE_UINT32, "parent" },
100 { MTP_PROPERTY_STORAGE_ID, MTP_TYPE_UINT32, "storage" },
101 { MTP_PROPERTY_OBJECT_FORMAT, MTP_TYPE_UINT32, "format" },
102 { MTP_PROPERTY_OBJECT_FILE_NAME, MTP_TYPE_STR, "path" },
103 { MTP_PROPERTY_OBJECT_SIZE, MTP_TYPE_UINT64, "size" },
Mike Lockwood16864ba2010-05-11 17:16:59 -0400104 { MTP_PROPERTY_DATE_MODIFIED, MTP_TYPE_STR, "date_modified" },
105};
106
107static bool getPropertyInfo(MtpObjectProperty property, int& type, const char*& columnName) {
108 int count = sizeof(kPropertyTable) / sizeof(kPropertyTable[0]);
109 const PropertyTableEntry* entry = kPropertyTable;
110 for (int i = 0; i < count; i++, entry++) {
111 if (entry->property == property) {
112 type = entry->type;
113 columnName = entry->columnName;
114 return true;
115 }
116 }
117 return false;
118}
119
120
Mike Lockwoodfceef462010-05-14 15:35:17 -0400121
Mike Lockwood16864ba2010-05-11 17:16:59 -0400122MtpDatabase::MtpDatabase()
123 : mFileIdQuery(NULL),
124 mObjectInfoQuery(NULL),
125 mFileInserter(NULL),
Mike Lockwoodfceef462010-05-14 15:35:17 -0400126 mFileDeleter(NULL),
127 mAudioInserter(NULL),
128 mAudioDeleter(NULL)
Mike Lockwood16864ba2010-05-11 17:16:59 -0400129{
130}
131
132MtpDatabase::~MtpDatabase() {
133}
134
135bool MtpDatabase::open(const char* path, bool create) {
136 if (!SqliteDatabase::open(path, create))
137 return false;
138
Mike Lockwoodfceef462010-05-14 15:35:17 -0400139 // create tables and indices if necessary
140 if (!exec(FILE_TABLE_CREATE)) {
141 fprintf(stderr, "could not create file table\n");
Mike Lockwood16864ba2010-05-11 17:16:59 -0400142 return false;
143 }
144 if (!exec(PATH_INDEX_CREATE)) {
Mike Lockwoodfceef462010-05-14 15:35:17 -0400145 fprintf(stderr, "could not path index on file table\n");
Mike Lockwood16864ba2010-05-11 17:16:59 -0400146 return false;
147 }
Mike Lockwoodfceef462010-05-14 15:35:17 -0400148 if (!exec(AUDIO_TABLE_CREATE)) {
149 fprintf(stderr, "could not create file table\n");
150 return false;
151 }
152
153 if (!mFileIdQuery) {
154 mFileIdQuery = new SqliteStatement(this);
155 if (!mFileIdQuery->prepare(FILE_ID_QUERY)) {
156 fprintf(stderr, "could not compile FILE_ID_QUERY\n");
157 exit(-1);
158 }
159 }
160 if (!mFilePathQuery) {
161 mFilePathQuery = new SqliteStatement(this);
162 if (!mFilePathQuery->prepare(FILE_PATH_QUERY)) {
163 fprintf(stderr, "could not compile FILE_PATH_QUERY\n");
164 exit(-1);
165 }
166 }
167 if (!mObjectInfoQuery) {
168 mObjectInfoQuery = new SqliteStatement(this);
169 if (!mObjectInfoQuery->prepare(GET_OBJECT_INFO_QUERY)) {
170 fprintf(stderr, "could not compile GET_OBJECT_INFO_QUERY\n");
171 exit(-1);
172 }
173 }
174 if (!mFileInserter) {
175 mFileInserter = new SqliteStatement(this);
176 if (!mFileInserter->prepare(FILE_INSERT)) {
177 fprintf(stderr, "could not compile FILE_INSERT\n");
178 exit(-1);
179 }
180 }
181 if (!mFileDeleter) {
182 mFileDeleter = new SqliteStatement(this);
183 if (!mFileDeleter->prepare(FILE_DELETE)) {
184 fprintf(stderr, "could not compile FILE_DELETE\n");
185 exit(-1);
186 }
187 }
188 if (!mAudioInserter) {
189 mAudioInserter = new SqliteStatement(this);
190 if (!mAudioInserter->prepare(AUDIO_INSERT)) {
191 fprintf(stderr, "could not compile AUDIO_INSERT\n");
192 exit(-1);
193 }
194 }
195 if (!mAudioDeleter) {
196 mAudioDeleter = new SqliteStatement(this);
197 if (!mAudioDeleter->prepare(AUDIO_DELETE)) {
198 fprintf(stderr, "could not compile AUDIO_DELETE\n");
199 exit(-1);
200 }
201 }
202
Mike Lockwood16864ba2010-05-11 17:16:59 -0400203 return true;
204}
205
Mike Lockwoodfceef462010-05-14 15:35:17 -0400206uint32_t MtpDatabase::getTableForFile(MtpObjectFormat format) {
207 switch (format) {
208 case MTP_FORMAT_AIFF:
209 case MTP_FORMAT_WAV:
210 case MTP_FORMAT_MP3:
211 case MTP_FORMAT_FLAC:
212 case MTP_FORMAT_UNDEFINED_AUDIO:
213 case MTP_FORMAT_WMA:
214 case MTP_FORMAT_OGG:
215 case MTP_FORMAT_AAC:
216 case MTP_FORMAT_AUDIBLE:
217 return kObjectHandleTableAudio;
218 case MTP_FORMAT_AVI:
219 case MTP_FORMAT_MPEG:
220 case MTP_FORMAT_ASF:
221 case MTP_FORMAT_UNDEFINED_VIDEO:
222 case MTP_FORMAT_WMV:
223 case MTP_FORMAT_MP4_CONTAINER:
224 case MTP_FORMAT_MP2:
225 case MTP_FORMAT_3GP_CONTAINER:
226 return kObjectHandleTableVideo;
227 case MTP_FORMAT_DEFINED:
228 case MTP_FORMAT_EXIF_JPEG:
229 case MTP_FORMAT_TIFF_EP:
230 case MTP_FORMAT_FLASHPIX:
231 case MTP_FORMAT_BMP:
232 case MTP_FORMAT_CIFF:
233 case MTP_FORMAT_GIF:
234 case MTP_FORMAT_JFIF:
235 case MTP_FORMAT_CD:
236 case MTP_FORMAT_PICT:
237 case MTP_FORMAT_PNG:
238 case MTP_FORMAT_TIFF:
239 case MTP_FORMAT_TIFF_IT:
240 case MTP_FORMAT_JP2:
241 case MTP_FORMAT_JPX:
242 case MTP_FORMAT_WINDOWS_IMAGE_FORMAT:
243 return kObjectHandleTableImage;
244 case MTP_FORMAT_ABSTRACT_AUDIO_PLAYLIST:
245 case MTP_FORMAT_ABSTRACT_AV_PLAYLIST:
246 case MTP_FORMAT_ABSTRACT_VIDEO_PLAYLIST:
247 case MTP_FORMAT_WPL_PLAYLIST:
248 case MTP_FORMAT_M3U_PLAYLIST:
249 case MTP_FORMAT_MPL_PLAYLIST:
250 case MTP_FORMAT_ASX_PLAYLIST:
251 case MTP_FORMAT_PLS_PLAYLIST:
252 return kObjectHandleTablePlaylist;
253 default:
254 return kObjectHandleTableFile;
255 }
256}
257
258MtpObjectHandle MtpDatabase::getObjectHandle(const char* path) {
259 mFileIdQuery->reset();
260 mFileIdQuery->bind(1, path);
261 if (mFileIdQuery->step()) {
262 int row = mFileIdQuery->getColumnInt(0);
263 if (row > 0) {
264 MtpObjectFormat format = mFileIdQuery->getColumnInt(1);
265 row |= getTableForFile(format);
266 return row;
267 }
268 }
269
270 return 0;
271}
272
Mike Lockwood16864ba2010-05-11 17:16:59 -0400273MtpObjectHandle MtpDatabase::addFile(const char* path,
274 MtpObjectFormat format,
275 MtpObjectHandle parent,
276 MtpStorageID storage,
277 uint64_t size,
Mike Lockwood16864ba2010-05-11 17:16:59 -0400278 time_t modified) {
Mike Lockwoodfceef462010-05-14 15:35:17 -0400279 mFileInserter->bind(FILE_PATH_COLUMN, path);
280 mFileInserter->bind(FILE_FORMAT_COLUMN, format);
281 mFileInserter->bind(FILE_PARENT_COLUMN, parent);
282 mFileInserter->bind(FILE_STORAGE_COLUMN, storage);
283 mFileInserter->bind(FILE_SIZE_COLUMN, size);
284 mFileInserter->bind(FILE_MODIFIED_COLUMN, modified);
Mike Lockwood16864ba2010-05-11 17:16:59 -0400285 mFileInserter->step();
286 mFileInserter->reset();
Mike Lockwoodfceef462010-05-14 15:35:17 -0400287 int result = lastInsertedRow();
288 return (result <= 0 ? kInvalidObjectHandle : result);
289}
290
291MtpObjectHandle MtpDatabase::addAudioFile(MtpObjectHandle handle) {
292 mAudioInserter->bind(AUDIO_ID_COLUMN, handle);
293 mAudioInserter->step();
294 mAudioInserter->reset();
295 int result = lastInsertedRow();
296 handle |= kObjectHandleTableAudio;
297 return (result > 0 ? handle : kInvalidObjectHandle);
298}
299
300MtpObjectHandle MtpDatabase::addAudioFile(MtpObjectHandle handle,
301 const char* title,
302 const char* artist,
303 const char* album,
304 const char* albumArtist,
305 const char* genre,
306 const char* composer,
307 const char* mimeType,
308 int track,
309 int year,
310 int duration) {
311 mAudioInserter->bind(AUDIO_ID_COLUMN, handle);
312 if (title) mAudioInserter->bind(AUDIO_TITLE_COLUMN, title);
313 if (artist) mAudioInserter->bind(AUDIO_ARTIST_COLUMN, artist);
314 if (album) mAudioInserter->bind(AUDIO_ALBUM_COLUMN, album);
315 if (albumArtist) mAudioInserter->bind(AUDIO_ALBUM_ARTIST_COLUMN, albumArtist);
316 if (genre) mAudioInserter->bind(AUDIO_GENRE_COLUMN, genre);
317 if (composer) mAudioInserter->bind(AUDIO_COMPOSER_COLUMN, composer);
318 if (track) mAudioInserter->bind(AUDIO_TRACK_NUMBER_COLUMN, track);
319 if (year) mAudioInserter->bind(AUDIO_YEAR_COLUMN, year);
320 if (duration) mAudioInserter->bind(AUDIO_DURATION_COLUMN, duration);
321 mAudioInserter->step();
322 mAudioInserter->reset();
323 int result = lastInsertedRow();
324 if (result <= 0)
325 return kInvalidObjectHandle;
326 result |= kObjectHandleTableAudio;
327 return result;
Mike Lockwood16864ba2010-05-11 17:16:59 -0400328}
329
330MtpObjectHandleList* MtpDatabase::getObjectList(MtpStorageID storageID,
331 MtpObjectFormat format,
332 MtpObjectHandle parent) {
333 bool whereStorage = (storageID != 0xFFFFFFFF);
334 bool whereFormat = (format != 0);
335 bool whereParent = (parent != 0);
336 char intBuffer[20];
337
Mike Lockwoodfceef462010-05-14 15:35:17 -0400338 MtpString query("SELECT _id,format FROM files");
Mike Lockwood16864ba2010-05-11 17:16:59 -0400339 if (whereStorage || whereFormat || whereParent)
340 query += " WHERE";
341 if (whereStorage) {
342 snprintf(intBuffer, sizeof(intBuffer), "%d", storageID);
343 query += " storage = ";
344 query += intBuffer;
345 }
346 if (whereFormat) {
347 snprintf(intBuffer, sizeof(intBuffer), "%d", format);
348 if (whereStorage)
349 query += " AND";
350 query += " format = ";
351 query += intBuffer;
352 }
353 if (whereParent) {
Mike Lockwoodfceef462010-05-14 15:35:17 -0400354 if (parent != MTP_PARENT_ROOT)
355 parent &= kObjectHandleIndexMask;
Mike Lockwood16864ba2010-05-11 17:16:59 -0400356 snprintf(intBuffer, sizeof(intBuffer), "%d", parent);
357 if (whereStorage || whereFormat)
358 query += " AND";
359 query += " parent = ";
360 query += intBuffer;
361 }
362 query += ";";
363
364 SqliteStatement stmt(this);
365 printf("%s\n", (const char *)query);
366 stmt.prepare(query);
367
368 MtpObjectHandleList* list = new MtpObjectHandleList();
369 while (!stmt.isDone()) {
370 if (stmt.step()) {
371 int index = stmt.getColumnInt(0);
372 printf("stmt.getColumnInt returned %d\n", index);
Mike Lockwoodfceef462010-05-14 15:35:17 -0400373 if (index > 0) {
374 MtpObjectFormat format = stmt.getColumnInt(1);
375 index |= getTableForFile(format);
Mike Lockwood16864ba2010-05-11 17:16:59 -0400376 list->push(index);
Mike Lockwoodfceef462010-05-14 15:35:17 -0400377 }
Mike Lockwood16864ba2010-05-11 17:16:59 -0400378 }
379 }
380 printf("list size: %d\n", list->size());
381 return list;
382}
383
Mike Lockwoodfceef462010-05-14 15:35:17 -0400384
Mike Lockwood16864ba2010-05-11 17:16:59 -0400385MtpResponseCode MtpDatabase::getObjectProperty(MtpObjectHandle handle,
386 MtpObjectProperty property,
387 MtpDataPacket& packet) {
388 int type;
389 const char* columnName;
390 char intBuffer[20];
391
Mike Lockwoodfceef462010-05-14 15:35:17 -0400392 if (handle != MTP_PARENT_ROOT)
393 handle &= kObjectHandleIndexMask;
394
Mike Lockwood16864ba2010-05-11 17:16:59 -0400395 if (!getPropertyInfo(property, type, columnName))
396 return MTP_RESPONSE_INVALID_OBJECT_PROP_CODE;
397 snprintf(intBuffer, sizeof(intBuffer), "%d", handle);
398
399 MtpString query("SELECT ");
400 query += columnName;
401 query += " FROM files WHERE _id = ";
402 query += intBuffer;
403 query += ";";
404
405 SqliteStatement stmt(this);
406 printf("%s\n", (const char *)query);
407 stmt.prepare(query);
408
409 if (!stmt.step())
410 return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
411
412 switch (type) {
413 case MTP_TYPE_INT8:
414 packet.putInt8(stmt.getColumnInt(0));
415 break;
416 case MTP_TYPE_UINT8:
417 packet.putUInt8(stmt.getColumnInt(0));
418 break;
419 case MTP_TYPE_INT16:
420 packet.putInt16(stmt.getColumnInt(0));
421 break;
422 case MTP_TYPE_UINT16:
423 packet.putUInt16(stmt.getColumnInt(0));
424 break;
425 case MTP_TYPE_INT32:
426 packet.putInt32(stmt.getColumnInt(0));
427 break;
428 case MTP_TYPE_UINT32:
429 packet.putUInt32(stmt.getColumnInt(0));
430 break;
431 case MTP_TYPE_INT64:
432 packet.putInt64(stmt.getColumnInt64(0));
433 break;
434 case MTP_TYPE_UINT64:
435 packet.putUInt64(stmt.getColumnInt64(0));
436 break;
437 case MTP_TYPE_STR:
438 packet.putString(stmt.getColumnString(0));
439 break;
440 default:
441 fprintf(stderr, "unsupported object type\n");
442 return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
443 }
444 return MTP_RESPONSE_OK;
445}
446
447MtpResponseCode MtpDatabase::getObjectInfo(MtpObjectHandle handle,
448 MtpDataPacket& packet) {
449 char date[20];
450
Mike Lockwoodfceef462010-05-14 15:35:17 -0400451 if (handle != MTP_PARENT_ROOT)
452 handle &= kObjectHandleIndexMask;
Mike Lockwood16864ba2010-05-11 17:16:59 -0400453
Mike Lockwoodfceef462010-05-14 15:35:17 -0400454 mObjectInfoQuery->reset();
Mike Lockwood16864ba2010-05-11 17:16:59 -0400455 mObjectInfoQuery->bind(1, handle);
456 if (!mObjectInfoQuery->step())
457 return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
458
459 MtpStorageID storageID = mObjectInfoQuery->getColumnInt(0);
460 MtpObjectFormat format = mObjectInfoQuery->getColumnInt(1);
461 MtpObjectHandle parent = mObjectInfoQuery->getColumnInt(2);
462 // extract name from path. do we want a separate database entry for this?
463 const char* name = mObjectInfoQuery->getColumnString(3);
464 const char* lastSlash = strrchr(name, '/');
465 if (lastSlash)
466 name = lastSlash + 1;
467 int64_t size = mObjectInfoQuery->getColumnInt64(4);
Mike Lockwoodfceef462010-05-14 15:35:17 -0400468 time_t modified = mObjectInfoQuery->getColumnInt(5);
Mike Lockwood16864ba2010-05-11 17:16:59 -0400469 int associationType = (format == MTP_FORMAT_ASSOCIATION ?
470 MTP_ASSOCIATION_TYPE_GENERIC_FOLDER :
471 MTP_ASSOCIATION_TYPE_UNDEFINED);
472
473 printf("storageID: %d, format: %d, parent: %d\n", storageID, format, parent);
474
475 packet.putUInt32(storageID);
476 packet.putUInt16(format);
477 packet.putUInt16(0); // protection status
478 packet.putUInt32((size > 0xFFFFFFFFLL ? 0xFFFFFFFF : size));
479 packet.putUInt16(0); // thumb format
480 packet.putUInt32(0); // thumb compressed size
481 packet.putUInt32(0); // thumb pix width
482 packet.putUInt32(0); // thumb pix height
483 packet.putUInt32(0); // image pix width
484 packet.putUInt32(0); // image pix height
485 packet.putUInt32(0); // image bit depth
486 packet.putUInt32(parent);
487 packet.putUInt16(associationType);
488 packet.putUInt32(0); // association desc
489 packet.putUInt32(0); // sequence number
490 packet.putString(name); // file name
Mike Lockwoodfceef462010-05-14 15:35:17 -0400491 packet.putEmptyString();
Mike Lockwood16864ba2010-05-11 17:16:59 -0400492 formatDateTime(modified, date, sizeof(date));
493 packet.putString(date); // date modified
494 packet.putEmptyString(); // keywords
495
496 return MTP_RESPONSE_OK;
497}
498
499bool MtpDatabase::getObjectFilePath(MtpObjectHandle handle,
500 MtpString& filePath,
501 int64_t& fileLength) {
Mike Lockwoodfceef462010-05-14 15:35:17 -0400502 if (handle != MTP_PARENT_ROOT)
503 handle &= kObjectHandleIndexMask;
504 mFilePathQuery->reset();
Mike Lockwood16864ba2010-05-11 17:16:59 -0400505 mFilePathQuery->bind(1, handle);
506 if (!mFilePathQuery->step())
507 return false;
508
509 const char* path = mFilePathQuery->getColumnString(0);
510 if (!path)
511 return false;
512 filePath = path;
513 fileLength = mFilePathQuery->getColumnInt64(1);
514 return true;
515}
516
517bool MtpDatabase::deleteFile(MtpObjectHandle handle) {
Mike Lockwoodfceef462010-05-14 15:35:17 -0400518 uint32_t table = handle & kObjectHandleTableMask;
519 handle &= kObjectHandleIndexMask;
Mike Lockwood16864ba2010-05-11 17:16:59 -0400520 mFileDeleter->bind(1, handle);
521 mFileDeleter->step();
522 mFileDeleter->reset();
Mike Lockwoodfceef462010-05-14 15:35:17 -0400523 if (table == kObjectHandleTableAudio) {
524 mAudioDeleter->bind(1, handle);
525 mAudioDeleter->step();
526 mAudioDeleter->reset();
527 }
528
Mike Lockwood16864ba2010-05-11 17:16:59 -0400529 return true;
530}
531
Mike Lockwoodfceef462010-05-14 15:35:17 -0400532MtpObjectHandle* MtpDatabase::getFileList(int& outCount) {
533 MtpObjectHandle* result = NULL;
534 int count = 0;
535 SqliteStatement stmt(this);
536 stmt.prepare("SELECT count(*) FROM files;");
537
538 MtpObjectHandleList* list = new MtpObjectHandleList();
539 if (stmt.step())
540 count = stmt.getColumnInt(0);
541
542 if (count > 0) {
543 result = new MtpObjectHandle[count];
544 memset(result, 0, count * sizeof(*result));
545 SqliteStatement stmt2(this);
546 stmt2.prepare("SELECT _id,format FROM files;");
547
548 for (int i = 0; i < count; i++) {
549 if (!stmt2.step()) {
550 printf("getFileList ended early\n");
551 count = i;
552 break;
553 }
554 MtpObjectHandle handle = stmt2.getColumnInt(0);
555 MtpObjectFormat format = stmt2.getColumnInt(1);
556 handle |= getTableForFile(format);
557 result[i] = handle;
558 }
559 }
560 outCount = count;
561 return result;
562}
563
Mike Lockwood16864ba2010-05-11 17:16:59 -0400564/*
565 for getObjectPropDesc
566
567 packet.putUInt16(property);
568 packet.putUInt16(dataType);
569 packet.putUInt8(getSet);
570 // default value DTS
571 packet.putUInt32(groupCode);
572 packet.putUInt8(formFlag);
573 // form, variable
574*/
Mike Lockwood7850ef92010-05-14 10:10:36 -0400575
576} // namespace android