blob: d7b21d016633364f34f879ccba093c35b960648b [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"
Mike Lockwood335dd2b2010-05-19 10:33:39 -040019#include "MtpUtils.h"
Mike Lockwood16864ba2010-05-11 17:16:59 -040020#include "SqliteDatabase.h"
21#include "SqliteStatement.h"
22
23#include <stdio.h>
Mike Lockwoodfceef462010-05-14 15:35:17 -040024#include <stdlib.h>
Mike Lockwood16864ba2010-05-11 17:16:59 -040025#include <sqlite3.h>
26
Mike Lockwood7850ef92010-05-14 10:10:36 -040027namespace android {
28
Mike Lockwoodfceef462010-05-14 15:35:17 -040029#define FILE_ID_COLUMN 1
30#define FILE_PATH_COLUMN 2
31#define FILE_FORMAT_COLUMN 3
32#define FILE_PARENT_COLUMN 4
33#define FILE_STORAGE_COLUMN 5
34#define FILE_SIZE_COLUMN 6
35#define FILE_MODIFIED_COLUMN 7
Mike Lockwood16864ba2010-05-11 17:16:59 -040036
Mike Lockwoodfceef462010-05-14 15:35:17 -040037#define AUDIO_ID_COLUMN 1
38#define AUDIO_TITLE_COLUMN 2
39#define AUDIO_ARTIST_COLUMN 3
40#define AUDIO_ALBUM_COLUMN 4
41#define AUDIO_ALBUM_ARTIST_COLUMN 5
42#define AUDIO_GENRE_COLUMN 6
43#define AUDIO_COMPOSER_COLUMN 7
44#define AUDIO_TRACK_NUMBER_COLUMN 8
45#define AUDIO_YEAR_COLUMN 9
46#define AUDIO_DURATION_COLUMN 10
47#define AUDIO_USE_COUNT_COLUMN 11
48#define AUDIO_SAMPLE_RATE_COLUMN 12
49#define AUDIO_NUM_CHANNELS_COLUMN 13
50#define AUDIO_AUDIO_WAVE_CODEC_COLUMN 14
51#define AUDIO_AUDIO_BIT_RATE_COLUMN 15
52
53#define FILE_TABLE_CREATE "CREATE TABLE IF NOT EXISTS files (" \
Mike Lockwood16864ba2010-05-11 17:16:59 -040054 "_id INTEGER PRIMARY KEY," \
55 "path TEXT," \
56 "format INTEGER," \
57 "parent INTEGER," \
58 "storage INTEGER," \
59 "size INTEGER," \
Mike Lockwoodfceef462010-05-14 15:35:17 -040060 "date_modified INTEGER" \
61 ");"
62
63#define AUDIO_TABLE_CREATE "CREATE TABLE IF NOT EXISTS audio (" \
64 "id INTEGER PRIMARY KEY," \
65 "title TEXT," \
66 "artist TEXT," \
67 "album TEXT," \
68 "album_artist TEXT," \
69 "genre TEXT," \
70 "composer TEXT," \
71 "track_number INTEGER," \
72 "year INTEGER," \
73 "duration INTEGER," \
74 "use_count INTEGER," \
75 "sample_rate INTEGER," \
76 "num_channels INTEGER," \
77 "audio_wave_codec TEXT," \
78 "audio_bit_rate INTEGER" \
Mike Lockwood16864ba2010-05-11 17:16:59 -040079 ");"
80
81#define PATH_INDEX_CREATE "CREATE INDEX IF NOT EXISTS path_index on files(path);"
82
Mike Lockwoodfceef462010-05-14 15:35:17 -040083#define FILE_ID_QUERY "SELECT _id,format FROM files WHERE path = ?;"
Mike Lockwood16864ba2010-05-11 17:16:59 -040084#define FILE_PATH_QUERY "SELECT path,size FROM files WHERE _id = ?"
85
Mike Lockwoodfceef462010-05-14 15:35:17 -040086#define GET_OBJECT_INFO_QUERY "SELECT storage,format,parent,path,size,date_modified FROM files WHERE _id = ?;"
87#define FILE_INSERT "INSERT INTO files VALUES(?,?,?,?,?,?,?);"
88#define FILE_DELETE "DELETE FROM files WHERE _id = ?;"
89
90#define AUDIO_INSERT "INSERT INTO audio VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);"
91#define AUDIO_DELETE "DELETE FROM audio WHERE id = ?;"
Mike Lockwood16864ba2010-05-11 17:16:59 -040092
Mike Lockwood16864ba2010-05-11 17:16:59 -040093struct PropertyTableEntry {
94 MtpObjectProperty property;
95 int type;
96 const char* columnName;
97};
98
99static const PropertyTableEntry kPropertyTable[] = {
100 { MTP_PROPERTY_PARENT_OBJECT, MTP_TYPE_UINT32, "parent" },
101 { MTP_PROPERTY_STORAGE_ID, MTP_TYPE_UINT32, "storage" },
102 { MTP_PROPERTY_OBJECT_FORMAT, MTP_TYPE_UINT32, "format" },
103 { MTP_PROPERTY_OBJECT_FILE_NAME, MTP_TYPE_STR, "path" },
104 { MTP_PROPERTY_OBJECT_SIZE, MTP_TYPE_UINT64, "size" },
Mike Lockwood16864ba2010-05-11 17:16:59 -0400105 { MTP_PROPERTY_DATE_MODIFIED, MTP_TYPE_STR, "date_modified" },
106};
107
108static bool getPropertyInfo(MtpObjectProperty property, int& type, const char*& columnName) {
109 int count = sizeof(kPropertyTable) / sizeof(kPropertyTable[0]);
110 const PropertyTableEntry* entry = kPropertyTable;
111 for (int i = 0; i < count; i++, entry++) {
112 if (entry->property == property) {
113 type = entry->type;
114 columnName = entry->columnName;
115 return true;
116 }
117 }
118 return false;
119}
120
121
Mike Lockwoodfceef462010-05-14 15:35:17 -0400122
Mike Lockwood16864ba2010-05-11 17:16:59 -0400123MtpDatabase::MtpDatabase()
124 : mFileIdQuery(NULL),
Mike Lockwooda177ae12010-06-14 09:11:19 -0700125 mFilePathQuery(NULL),
Mike Lockwood16864ba2010-05-11 17:16:59 -0400126 mObjectInfoQuery(NULL),
127 mFileInserter(NULL),
Mike Lockwoodfceef462010-05-14 15:35:17 -0400128 mFileDeleter(NULL),
129 mAudioInserter(NULL),
130 mAudioDeleter(NULL)
Mike Lockwood16864ba2010-05-11 17:16:59 -0400131{
132}
133
134MtpDatabase::~MtpDatabase() {
135}
136
137bool MtpDatabase::open(const char* path, bool create) {
138 if (!SqliteDatabase::open(path, create))
139 return false;
140
Mike Lockwoodfceef462010-05-14 15:35:17 -0400141 // create tables and indices if necessary
142 if (!exec(FILE_TABLE_CREATE)) {
143 fprintf(stderr, "could not create file table\n");
Mike Lockwood16864ba2010-05-11 17:16:59 -0400144 return false;
145 }
146 if (!exec(PATH_INDEX_CREATE)) {
Mike Lockwoodfceef462010-05-14 15:35:17 -0400147 fprintf(stderr, "could not path index on file table\n");
Mike Lockwood16864ba2010-05-11 17:16:59 -0400148 return false;
149 }
Mike Lockwoodfceef462010-05-14 15:35:17 -0400150 if (!exec(AUDIO_TABLE_CREATE)) {
151 fprintf(stderr, "could not create file table\n");
152 return false;
153 }
154
155 if (!mFileIdQuery) {
156 mFileIdQuery = new SqliteStatement(this);
157 if (!mFileIdQuery->prepare(FILE_ID_QUERY)) {
158 fprintf(stderr, "could not compile FILE_ID_QUERY\n");
159 exit(-1);
160 }
161 }
162 if (!mFilePathQuery) {
163 mFilePathQuery = new SqliteStatement(this);
164 if (!mFilePathQuery->prepare(FILE_PATH_QUERY)) {
165 fprintf(stderr, "could not compile FILE_PATH_QUERY\n");
166 exit(-1);
167 }
168 }
169 if (!mObjectInfoQuery) {
170 mObjectInfoQuery = new SqliteStatement(this);
171 if (!mObjectInfoQuery->prepare(GET_OBJECT_INFO_QUERY)) {
172 fprintf(stderr, "could not compile GET_OBJECT_INFO_QUERY\n");
173 exit(-1);
174 }
175 }
176 if (!mFileInserter) {
177 mFileInserter = new SqliteStatement(this);
178 if (!mFileInserter->prepare(FILE_INSERT)) {
179 fprintf(stderr, "could not compile FILE_INSERT\n");
180 exit(-1);
181 }
182 }
183 if (!mFileDeleter) {
184 mFileDeleter = new SqliteStatement(this);
185 if (!mFileDeleter->prepare(FILE_DELETE)) {
186 fprintf(stderr, "could not compile FILE_DELETE\n");
187 exit(-1);
188 }
189 }
190 if (!mAudioInserter) {
191 mAudioInserter = new SqliteStatement(this);
192 if (!mAudioInserter->prepare(AUDIO_INSERT)) {
193 fprintf(stderr, "could not compile AUDIO_INSERT\n");
194 exit(-1);
195 }
196 }
197 if (!mAudioDeleter) {
198 mAudioDeleter = new SqliteStatement(this);
199 if (!mAudioDeleter->prepare(AUDIO_DELETE)) {
200 fprintf(stderr, "could not compile AUDIO_DELETE\n");
201 exit(-1);
202 }
203 }
204
Mike Lockwood16864ba2010-05-11 17:16:59 -0400205 return true;
206}
207
Mike Lockwoodfceef462010-05-14 15:35:17 -0400208uint32_t MtpDatabase::getTableForFile(MtpObjectFormat format) {
209 switch (format) {
210 case MTP_FORMAT_AIFF:
211 case MTP_FORMAT_WAV:
212 case MTP_FORMAT_MP3:
213 case MTP_FORMAT_FLAC:
214 case MTP_FORMAT_UNDEFINED_AUDIO:
215 case MTP_FORMAT_WMA:
216 case MTP_FORMAT_OGG:
217 case MTP_FORMAT_AAC:
218 case MTP_FORMAT_AUDIBLE:
219 return kObjectHandleTableAudio;
220 case MTP_FORMAT_AVI:
221 case MTP_FORMAT_MPEG:
222 case MTP_FORMAT_ASF:
223 case MTP_FORMAT_UNDEFINED_VIDEO:
224 case MTP_FORMAT_WMV:
225 case MTP_FORMAT_MP4_CONTAINER:
226 case MTP_FORMAT_MP2:
227 case MTP_FORMAT_3GP_CONTAINER:
228 return kObjectHandleTableVideo;
229 case MTP_FORMAT_DEFINED:
230 case MTP_FORMAT_EXIF_JPEG:
231 case MTP_FORMAT_TIFF_EP:
232 case MTP_FORMAT_FLASHPIX:
233 case MTP_FORMAT_BMP:
234 case MTP_FORMAT_CIFF:
235 case MTP_FORMAT_GIF:
236 case MTP_FORMAT_JFIF:
237 case MTP_FORMAT_CD:
238 case MTP_FORMAT_PICT:
239 case MTP_FORMAT_PNG:
240 case MTP_FORMAT_TIFF:
241 case MTP_FORMAT_TIFF_IT:
242 case MTP_FORMAT_JP2:
243 case MTP_FORMAT_JPX:
244 case MTP_FORMAT_WINDOWS_IMAGE_FORMAT:
245 return kObjectHandleTableImage;
246 case MTP_FORMAT_ABSTRACT_AUDIO_PLAYLIST:
247 case MTP_FORMAT_ABSTRACT_AV_PLAYLIST:
248 case MTP_FORMAT_ABSTRACT_VIDEO_PLAYLIST:
249 case MTP_FORMAT_WPL_PLAYLIST:
250 case MTP_FORMAT_M3U_PLAYLIST:
251 case MTP_FORMAT_MPL_PLAYLIST:
252 case MTP_FORMAT_ASX_PLAYLIST:
253 case MTP_FORMAT_PLS_PLAYLIST:
254 return kObjectHandleTablePlaylist;
255 default:
256 return kObjectHandleTableFile;
257 }
258}
259
260MtpObjectHandle MtpDatabase::getObjectHandle(const char* path) {
261 mFileIdQuery->reset();
262 mFileIdQuery->bind(1, path);
263 if (mFileIdQuery->step()) {
264 int row = mFileIdQuery->getColumnInt(0);
265 if (row > 0) {
266 MtpObjectFormat format = mFileIdQuery->getColumnInt(1);
267 row |= getTableForFile(format);
268 return row;
269 }
270 }
271
272 return 0;
273}
274
Mike Lockwood16864ba2010-05-11 17:16:59 -0400275MtpObjectHandle MtpDatabase::addFile(const char* path,
276 MtpObjectFormat format,
277 MtpObjectHandle parent,
278 MtpStorageID storage,
279 uint64_t size,
Mike Lockwood16864ba2010-05-11 17:16:59 -0400280 time_t modified) {
Mike Lockwoodfceef462010-05-14 15:35:17 -0400281 mFileInserter->bind(FILE_PATH_COLUMN, path);
282 mFileInserter->bind(FILE_FORMAT_COLUMN, format);
283 mFileInserter->bind(FILE_PARENT_COLUMN, parent);
284 mFileInserter->bind(FILE_STORAGE_COLUMN, storage);
285 mFileInserter->bind(FILE_SIZE_COLUMN, size);
286 mFileInserter->bind(FILE_MODIFIED_COLUMN, modified);
Mike Lockwood16864ba2010-05-11 17:16:59 -0400287 mFileInserter->step();
288 mFileInserter->reset();
Mike Lockwoodfceef462010-05-14 15:35:17 -0400289 int result = lastInsertedRow();
290 return (result <= 0 ? kInvalidObjectHandle : result);
291}
292
293MtpObjectHandle MtpDatabase::addAudioFile(MtpObjectHandle handle) {
294 mAudioInserter->bind(AUDIO_ID_COLUMN, handle);
295 mAudioInserter->step();
296 mAudioInserter->reset();
297 int result = lastInsertedRow();
298 handle |= kObjectHandleTableAudio;
299 return (result > 0 ? handle : kInvalidObjectHandle);
300}
301
302MtpObjectHandle MtpDatabase::addAudioFile(MtpObjectHandle handle,
303 const char* title,
304 const char* artist,
305 const char* album,
306 const char* albumArtist,
307 const char* genre,
308 const char* composer,
309 const char* mimeType,
310 int track,
311 int year,
312 int duration) {
313 mAudioInserter->bind(AUDIO_ID_COLUMN, handle);
314 if (title) mAudioInserter->bind(AUDIO_TITLE_COLUMN, title);
315 if (artist) mAudioInserter->bind(AUDIO_ARTIST_COLUMN, artist);
316 if (album) mAudioInserter->bind(AUDIO_ALBUM_COLUMN, album);
317 if (albumArtist) mAudioInserter->bind(AUDIO_ALBUM_ARTIST_COLUMN, albumArtist);
318 if (genre) mAudioInserter->bind(AUDIO_GENRE_COLUMN, genre);
319 if (composer) mAudioInserter->bind(AUDIO_COMPOSER_COLUMN, composer);
320 if (track) mAudioInserter->bind(AUDIO_TRACK_NUMBER_COLUMN, track);
321 if (year) mAudioInserter->bind(AUDIO_YEAR_COLUMN, year);
322 if (duration) mAudioInserter->bind(AUDIO_DURATION_COLUMN, duration);
323 mAudioInserter->step();
324 mAudioInserter->reset();
325 int result = lastInsertedRow();
326 if (result <= 0)
327 return kInvalidObjectHandle;
328 result |= kObjectHandleTableAudio;
329 return result;
Mike Lockwood16864ba2010-05-11 17:16:59 -0400330}
331
332MtpObjectHandleList* MtpDatabase::getObjectList(MtpStorageID storageID,
333 MtpObjectFormat format,
334 MtpObjectHandle parent) {
335 bool whereStorage = (storageID != 0xFFFFFFFF);
336 bool whereFormat = (format != 0);
337 bool whereParent = (parent != 0);
338 char intBuffer[20];
339
Mike Lockwoodfceef462010-05-14 15:35:17 -0400340 MtpString query("SELECT _id,format FROM files");
Mike Lockwood16864ba2010-05-11 17:16:59 -0400341 if (whereStorage || whereFormat || whereParent)
342 query += " WHERE";
343 if (whereStorage) {
344 snprintf(intBuffer, sizeof(intBuffer), "%d", storageID);
345 query += " storage = ";
346 query += intBuffer;
347 }
348 if (whereFormat) {
349 snprintf(intBuffer, sizeof(intBuffer), "%d", format);
350 if (whereStorage)
351 query += " AND";
352 query += " format = ";
353 query += intBuffer;
354 }
355 if (whereParent) {
Mike Lockwoodfceef462010-05-14 15:35:17 -0400356 if (parent != MTP_PARENT_ROOT)
357 parent &= kObjectHandleIndexMask;
Mike Lockwood16864ba2010-05-11 17:16:59 -0400358 snprintf(intBuffer, sizeof(intBuffer), "%d", parent);
359 if (whereStorage || whereFormat)
360 query += " AND";
361 query += " parent = ";
362 query += intBuffer;
363 }
364 query += ";";
365
366 SqliteStatement stmt(this);
367 printf("%s\n", (const char *)query);
368 stmt.prepare(query);
369
370 MtpObjectHandleList* list = new MtpObjectHandleList();
371 while (!stmt.isDone()) {
372 if (stmt.step()) {
373 int index = stmt.getColumnInt(0);
374 printf("stmt.getColumnInt returned %d\n", index);
Mike Lockwoodfceef462010-05-14 15:35:17 -0400375 if (index > 0) {
376 MtpObjectFormat format = stmt.getColumnInt(1);
377 index |= getTableForFile(format);
Mike Lockwood16864ba2010-05-11 17:16:59 -0400378 list->push(index);
Mike Lockwoodfceef462010-05-14 15:35:17 -0400379 }
Mike Lockwood16864ba2010-05-11 17:16:59 -0400380 }
381 }
382 printf("list size: %d\n", list->size());
383 return list;
384}
385
Mike Lockwoodfceef462010-05-14 15:35:17 -0400386
Mike Lockwood16864ba2010-05-11 17:16:59 -0400387MtpResponseCode MtpDatabase::getObjectProperty(MtpObjectHandle handle,
388 MtpObjectProperty property,
389 MtpDataPacket& packet) {
390 int type;
391 const char* columnName;
392 char intBuffer[20];
393
Mike Lockwoodfceef462010-05-14 15:35:17 -0400394 if (handle != MTP_PARENT_ROOT)
395 handle &= kObjectHandleIndexMask;
396
Mike Lockwood16864ba2010-05-11 17:16:59 -0400397 if (!getPropertyInfo(property, type, columnName))
398 return MTP_RESPONSE_INVALID_OBJECT_PROP_CODE;
399 snprintf(intBuffer, sizeof(intBuffer), "%d", handle);
400
401 MtpString query("SELECT ");
402 query += columnName;
403 query += " FROM files WHERE _id = ";
404 query += intBuffer;
405 query += ";";
406
407 SqliteStatement stmt(this);
408 printf("%s\n", (const char *)query);
409 stmt.prepare(query);
410
411 if (!stmt.step())
412 return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
413
414 switch (type) {
415 case MTP_TYPE_INT8:
416 packet.putInt8(stmt.getColumnInt(0));
417 break;
418 case MTP_TYPE_UINT8:
419 packet.putUInt8(stmt.getColumnInt(0));
420 break;
421 case MTP_TYPE_INT16:
422 packet.putInt16(stmt.getColumnInt(0));
423 break;
424 case MTP_TYPE_UINT16:
425 packet.putUInt16(stmt.getColumnInt(0));
426 break;
427 case MTP_TYPE_INT32:
428 packet.putInt32(stmt.getColumnInt(0));
429 break;
430 case MTP_TYPE_UINT32:
431 packet.putUInt32(stmt.getColumnInt(0));
432 break;
433 case MTP_TYPE_INT64:
434 packet.putInt64(stmt.getColumnInt64(0));
435 break;
436 case MTP_TYPE_UINT64:
437 packet.putUInt64(stmt.getColumnInt64(0));
438 break;
439 case MTP_TYPE_STR:
440 packet.putString(stmt.getColumnString(0));
441 break;
442 default:
443 fprintf(stderr, "unsupported object type\n");
444 return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
445 }
446 return MTP_RESPONSE_OK;
447}
448
449MtpResponseCode MtpDatabase::getObjectInfo(MtpObjectHandle handle,
450 MtpDataPacket& packet) {
451 char date[20];
452
Mike Lockwoodfceef462010-05-14 15:35:17 -0400453 if (handle != MTP_PARENT_ROOT)
454 handle &= kObjectHandleIndexMask;
Mike Lockwood16864ba2010-05-11 17:16:59 -0400455
Mike Lockwoodfceef462010-05-14 15:35:17 -0400456 mObjectInfoQuery->reset();
Mike Lockwood16864ba2010-05-11 17:16:59 -0400457 mObjectInfoQuery->bind(1, handle);
458 if (!mObjectInfoQuery->step())
459 return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
460
461 MtpStorageID storageID = mObjectInfoQuery->getColumnInt(0);
462 MtpObjectFormat format = mObjectInfoQuery->getColumnInt(1);
463 MtpObjectHandle parent = mObjectInfoQuery->getColumnInt(2);
464 // extract name from path. do we want a separate database entry for this?
465 const char* name = mObjectInfoQuery->getColumnString(3);
466 const char* lastSlash = strrchr(name, '/');
467 if (lastSlash)
468 name = lastSlash + 1;
469 int64_t size = mObjectInfoQuery->getColumnInt64(4);
Mike Lockwoodfceef462010-05-14 15:35:17 -0400470 time_t modified = mObjectInfoQuery->getColumnInt(5);
Mike Lockwood16864ba2010-05-11 17:16:59 -0400471 int associationType = (format == MTP_FORMAT_ASSOCIATION ?
472 MTP_ASSOCIATION_TYPE_GENERIC_FOLDER :
473 MTP_ASSOCIATION_TYPE_UNDEFINED);
474
475 printf("storageID: %d, format: %d, parent: %d\n", storageID, format, parent);
476
477 packet.putUInt32(storageID);
478 packet.putUInt16(format);
479 packet.putUInt16(0); // protection status
480 packet.putUInt32((size > 0xFFFFFFFFLL ? 0xFFFFFFFF : size));
481 packet.putUInt16(0); // thumb format
482 packet.putUInt32(0); // thumb compressed size
483 packet.putUInt32(0); // thumb pix width
484 packet.putUInt32(0); // thumb pix height
485 packet.putUInt32(0); // image pix width
486 packet.putUInt32(0); // image pix height
487 packet.putUInt32(0); // image bit depth
488 packet.putUInt32(parent);
489 packet.putUInt16(associationType);
490 packet.putUInt32(0); // association desc
491 packet.putUInt32(0); // sequence number
492 packet.putString(name); // file name
Mike Lockwoodfceef462010-05-14 15:35:17 -0400493 packet.putEmptyString();
Mike Lockwood16864ba2010-05-11 17:16:59 -0400494 formatDateTime(modified, date, sizeof(date));
495 packet.putString(date); // date modified
496 packet.putEmptyString(); // keywords
497
498 return MTP_RESPONSE_OK;
499}
500
501bool MtpDatabase::getObjectFilePath(MtpObjectHandle handle,
502 MtpString& filePath,
503 int64_t& fileLength) {
Mike Lockwoodfceef462010-05-14 15:35:17 -0400504 if (handle != MTP_PARENT_ROOT)
505 handle &= kObjectHandleIndexMask;
506 mFilePathQuery->reset();
Mike Lockwood16864ba2010-05-11 17:16:59 -0400507 mFilePathQuery->bind(1, handle);
508 if (!mFilePathQuery->step())
509 return false;
510
511 const char* path = mFilePathQuery->getColumnString(0);
512 if (!path)
513 return false;
514 filePath = path;
515 fileLength = mFilePathQuery->getColumnInt64(1);
516 return true;
517}
518
519bool MtpDatabase::deleteFile(MtpObjectHandle handle) {
Mike Lockwoodfceef462010-05-14 15:35:17 -0400520 uint32_t table = handle & kObjectHandleTableMask;
521 handle &= kObjectHandleIndexMask;
Mike Lockwood16864ba2010-05-11 17:16:59 -0400522 mFileDeleter->bind(1, handle);
523 mFileDeleter->step();
524 mFileDeleter->reset();
Mike Lockwoodfceef462010-05-14 15:35:17 -0400525 if (table == kObjectHandleTableAudio) {
526 mAudioDeleter->bind(1, handle);
527 mAudioDeleter->step();
528 mAudioDeleter->reset();
529 }
530
Mike Lockwood16864ba2010-05-11 17:16:59 -0400531 return true;
532}
533
Mike Lockwoodfceef462010-05-14 15:35:17 -0400534MtpObjectHandle* MtpDatabase::getFileList(int& outCount) {
535 MtpObjectHandle* result = NULL;
536 int count = 0;
537 SqliteStatement stmt(this);
538 stmt.prepare("SELECT count(*) FROM files;");
539
540 MtpObjectHandleList* list = new MtpObjectHandleList();
541 if (stmt.step())
542 count = stmt.getColumnInt(0);
543
544 if (count > 0) {
545 result = new MtpObjectHandle[count];
546 memset(result, 0, count * sizeof(*result));
547 SqliteStatement stmt2(this);
548 stmt2.prepare("SELECT _id,format FROM files;");
549
550 for (int i = 0; i < count; i++) {
551 if (!stmt2.step()) {
552 printf("getFileList ended early\n");
553 count = i;
554 break;
555 }
556 MtpObjectHandle handle = stmt2.getColumnInt(0);
557 MtpObjectFormat format = stmt2.getColumnInt(1);
558 handle |= getTableForFile(format);
559 result[i] = handle;
560 }
561 }
562 outCount = count;
563 return result;
564}
565
Mike Lockwood16864ba2010-05-11 17:16:59 -0400566/*
567 for getObjectPropDesc
568
569 packet.putUInt16(property);
570 packet.putUInt16(dataType);
571 packet.putUInt8(getSet);
572 // default value DTS
573 packet.putUInt32(groupCode);
574 packet.putUInt8(formFlag);
575 // form, variable
576*/
Mike Lockwood7850ef92010-05-14 10:10:36 -0400577
578} // namespace android