OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "content/browser/media_gallery/media_gallery_database.h" | |
6 | |
7 #include <algorithm> | |
8 | |
9 #include "base/file_path.h" | |
10 #include "base/logging.h" | |
11 #include "sql/diagnostic_error_delegate.h" | |
12 #include "sql/statement.h" | |
13 #include "sql/transaction.h" | |
14 | |
15 #define MEDIA_GALLERY_COLLECTION_ROW_FIELDS \ | |
16 " collections.id, collections.path, collections.last_modified_time, " \ | |
17 "collections.entry_count, collections.all_parsed " | |
18 | |
19 #define COLLECTION_TABLE_NAME "collections" | |
vandebo (ex-Chrome)
2012/03/05 23:16:03
You've hard coded the column creation, what's the
tpayne
2012/03/06 01:52:37
Done.
| |
20 | |
21 std::ostream& operator<<(std::ostream& out, | |
vandebo (ex-Chrome)
2012/03/05 23:16:03
In anonymous namespace?
tpayne
2012/03/06 01:52:37
Done.
| |
22 const media_gallery::MediaGalleryDatabase::CollectionRow& row) { | |
23 out << "Collection" | |
24 << " id " << row.GetId() | |
25 << " path " << row.GetPath().value() | |
26 << " last modified time " << row.GetLastModifiedTime().ToInternalValue() | |
27 << " entry count " << row.GetEntryCount() | |
28 << " all parsed " << (row.IsAllParsed() ? "true" : "false") << std::endl; | |
29 return out; | |
30 } | |
31 | |
32 namespace media_gallery { | |
33 | |
34 namespace { | |
35 | |
36 static const int kCurrentVersionNumber = 1; | |
37 static const int kCompatibleVersionNumber = 1; | |
38 static const char kMediaGalleryDatabaseName[] = "media_gallery.db"; | |
vandebo (ex-Chrome)
2012/03/05 23:16:03
nit: we might want to use a "hidden" name, i.e. st
tpayne
2012/03/06 01:52:37
Done.
| |
39 | |
40 class HistogramName { | |
41 public: | |
42 static const char* name() { | |
43 return "Sqlite.MediaGallery.Error"; | |
44 } | |
45 }; | |
46 | |
47 } // namespace | |
48 | |
49 MediaGalleryDatabase::MediaGalleryDatabase() { } | |
50 | |
51 MediaGalleryDatabase::~MediaGalleryDatabase() { } | |
52 | |
53 sql::InitStatus MediaGalleryDatabase::Init(const FilePath& database_dir) { | |
54 // Set the exceptional sqlite error handler. | |
55 db_.set_error_delegate(new sql::DiagnosticErrorDelegate<HistogramName>()); | |
56 | |
57 // Set the database page size to something a little larger to give us | |
58 // better performance (we're typically seek rather than bandwidth limited). | |
59 // This only has an effect before any tables have been created, otherwise | |
60 // this is a NOP. Must be a power of 2 and a max of 8192. | |
61 db_.set_page_size(4096); | |
62 | |
63 // Increase the cache size. The page size, plus a little extra, times this | |
64 // value, tells us how much memory the cache will use maximum. | |
65 // 6000 * 4MB = 24MB | |
vandebo (ex-Chrome)
2012/03/05 23:16:03
are you calling 4MB the page size here? set_page_
tpayne
2012/03/06 01:52:37
This is copied verbatim from url_database. Looks l
| |
66 db_.set_cache_size(6000); | |
67 | |
68 if (!db_.Open(database_dir.Append(kMediaGalleryDatabaseName))) | |
69 return sql::INIT_FAILURE; | |
70 | |
71 return InitInternal(&db_); | |
72 } | |
73 | |
74 sql::InitStatus MediaGalleryDatabase::InitInternal(sql::Connection* db) { | |
75 // Wrap the rest of init in a tranaction. This will prevent the database from | |
76 // getting corrupted if we crash in the middle of initialization or migration. | |
77 sql::Transaction committer(db); | |
78 if (!committer.Begin()) | |
79 return sql::INIT_FAILURE; | |
80 | |
81 // Prime the cache. | |
82 db->Preload(); | |
83 | |
84 // Create the tables and indices. | |
85 if (!meta_table_.Init(db, GetCurrentVersion(), kCompatibleVersionNumber)) | |
86 return sql::INIT_FAILURE; | |
87 | |
88 if (!CreateCollectionsTable(db)) { | |
89 return sql::INIT_FAILURE; | |
90 } | |
91 | |
92 // Version check. | |
93 sql::InitStatus version_status = EnsureCurrentVersion(); | |
94 if (version_status != sql::INIT_OK) | |
95 return version_status; | |
96 | |
97 return committer.Commit() ? sql::INIT_OK : sql::INIT_FAILURE; | |
98 } | |
99 | |
100 sql::InitStatus MediaGalleryDatabase::EnsureCurrentVersion() { | |
101 // We can't read databases newer than we were designed for. | |
102 if (meta_table_.GetCompatibleVersionNumber() > kCurrentVersionNumber) { | |
103 LOG(WARNING) << "Media Gallery database is too new."; | |
104 return sql::INIT_TOO_NEW; | |
105 } | |
106 int cur_version = meta_table_.GetVersionNumber(); | |
107 if (cur_version == 0) { | |
108 LOG(WARNING) << "Initializing the Media Gallery database."; | |
109 | |
110 ++cur_version; | |
vandebo (ex-Chrome)
2012/03/05 23:16:03
set it to kCurrentVersionNumber.
tpayne
2012/03/06 01:52:37
Once we have migration code, that's not going to b
| |
111 meta_table_.SetVersionNumber(cur_version); | |
112 meta_table_.SetCompatibleVersionNumber( | |
113 std::min(cur_version, kCompatibleVersionNumber)); | |
114 } | |
115 return sql::INIT_OK; | |
116 } | |
117 | |
118 // static | |
119 int MediaGalleryDatabase::GetCurrentVersion() { | |
vandebo (ex-Chrome)
2012/03/05 23:16:03
Why a method to return a constant?
tpayne
2012/03/06 01:52:37
I don't know. I cribbed this from url_database.cc.
| |
120 return kCurrentVersionNumber; | |
121 } | |
122 | |
123 COLLECTIONID MediaGalleryDatabase::CreateCollectionRow( | |
124 CollectionRow* row) { | |
125 const char* sql = "INSERT INTO " COLLECTION_TABLE_NAME | |
126 "(path, last_modified_time, entry_count, all_parsed) " | |
127 "VALUES(?, ?, ?, ?)"; | |
128 | |
129 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, sql)); | |
130 statement.BindString(0, row->GetPath().value().c_str()); | |
131 statement.BindInt64(1, row->GetLastModifiedTime().ToInternalValue()); | |
132 statement.BindInt(2, row->GetEntryCount()); | |
133 statement.BindInt(3, row->IsAllParsed() ? 1 : 0); | |
134 | |
135 if (!statement.Run()) { | |
136 VLOG(0) << "Failed to add collection " << row->GetPath().value() | |
137 << " to table media_gallery.collections"; | |
138 return 0; | |
139 } | |
140 return row->id_ = GetDB().GetLastInsertRowId(); | |
141 } | |
142 | |
143 bool MediaGalleryDatabase::GetCollectionRow(COLLECTIONID id, | |
144 CollectionRow* row) { | |
145 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, | |
146 "SELECT" MEDIA_GALLERY_COLLECTION_ROW_FIELDS | |
147 "FROM " COLLECTION_TABLE_NAME " WHERE id=?")); | |
148 statement.BindInt64(0, id); | |
149 | |
150 if (statement.Step()) { | |
151 FillCollectionRow(statement, row); | |
152 return true; | |
153 } | |
154 return false; | |
155 } | |
156 | |
157 // Convenience method to fill a row from a statement. Must be in sync with the | |
158 // columns in MEDIA_GALLERY_COLLECTION_ROW_FIELDS | |
159 void MediaGalleryDatabase::FillCollectionRow(const sql::Statement& s, | |
160 CollectionRow* i) { | |
161 DCHECK(i); | |
162 i->id_ = s.ColumnInt64(0); | |
163 i->path_ = FilePath(s.ColumnString(1)); | |
164 i->last_modified_time_ = base::Time::FromInternalValue(s.ColumnInt64(2)); | |
165 i->entry_count_ = s.ColumnInt(3); | |
166 i->all_parsed_ = s.ColumnInt(4) != 0; | |
167 } | |
168 | |
169 bool MediaGalleryDatabase::CreateCollectionsTable(sql::Connection* db) { | |
170 const char* name = COLLECTION_TABLE_NAME; | |
171 if (db->DoesTableExist(name)) | |
172 return true; | |
173 | |
174 const char *sql = "CREATE TABLE " COLLECTION_TABLE_NAME | |
175 " (id INTEGER PRIMARY KEY," | |
176 "path LONGVARCHAR NOT NULL," | |
177 "last_modified_time INTEGER NOT NULL," | |
178 "entry_count INTEGER DEFAULT 0 NOT NULL," | |
179 "all_parsed INTEGER DEFAULT 0 NOT NULL)"; | |
180 return db->Execute(sql); | |
181 } | |
182 | |
183 } // namespace media_gallery | |
OLD | NEW |