| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "sql/mojo/mojo_vfs.h" | 5 #include "sql/mojo/mojo_vfs.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/rand_util.h" | 8 #include "base/rand_util.h" |
| 9 #include "base/strings/stringprintf.h" | 9 #include "base/strings/stringprintf.h" |
| 10 #include "base/trace_event/trace_event.h" |
| 10 #include "components/filesystem/public/interfaces/file.mojom.h" | 11 #include "components/filesystem/public/interfaces/file.mojom.h" |
| 11 #include "components/filesystem/public/interfaces/file_system.mojom.h" | 12 #include "components/filesystem/public/interfaces/file_system.mojom.h" |
| 12 #include "components/filesystem/public/interfaces/types.mojom.h" | 13 #include "components/filesystem/public/interfaces/types.mojom.h" |
| 13 #include "mojo/public/cpp/bindings/lib/template_util.h" | 14 #include "mojo/public/cpp/bindings/lib/template_util.h" |
| 14 #include "mojo/util/capture_util.h" | 15 #include "mojo/util/capture_util.h" |
| 15 #include "third_party/sqlite/sqlite3.h" | 16 #include "third_party/sqlite/sqlite3.h" |
| 16 | 17 |
| 17 using mojo::Capture; | 18 using mojo::Capture; |
| 18 | 19 |
| 19 namespace sql { | 20 namespace sql { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 // up. | 54 // up. |
| 54 filesystem::FilePtr file_ptr; | 55 filesystem::FilePtr file_ptr; |
| 55 }; | 56 }; |
| 56 | 57 |
| 57 filesystem::FilePtr& GetFSFile(sqlite3_file* vfs_file) { | 58 filesystem::FilePtr& GetFSFile(sqlite3_file* vfs_file) { |
| 58 return reinterpret_cast<MojoVFSFile*>(vfs_file)->file_ptr; | 59 return reinterpret_cast<MojoVFSFile*>(vfs_file)->file_ptr; |
| 59 } | 60 } |
| 60 | 61 |
| 61 int MojoVFSClose(sqlite3_file* file) { | 62 int MojoVFSClose(sqlite3_file* file) { |
| 62 DVLOG(1) << "MojoVFSClose(*)"; | 63 DVLOG(1) << "MojoVFSClose(*)"; |
| 64 TRACE_EVENT0("sql", "MojoVFSClose"); |
| 63 using filesystem::FilePtr; | 65 using filesystem::FilePtr; |
| 64 filesystem::FileError error = filesystem::FILE_ERROR_FAILED; | 66 filesystem::FileError error = filesystem::FILE_ERROR_FAILED; |
| 65 // Must call File::Close explicitly instead of just deleting the file, since | 67 // Must call File::Close explicitly instead of just deleting the file, since |
| 66 // otherwise we wouldn't have an object to wait on. | 68 // otherwise we wouldn't have an object to wait on. |
| 67 GetFSFile(file)->Close(mojo::Capture(&error)); | 69 GetFSFile(file)->Close(mojo::Capture(&error)); |
| 68 GetFSFile(file).WaitForIncomingResponse(); | 70 GetFSFile(file).WaitForIncomingResponse(); |
| 69 GetFSFile(file).~FilePtr(); | 71 GetFSFile(file).~FilePtr(); |
| 70 return SQLITE_OK; | 72 return SQLITE_OK; |
| 71 } | 73 } |
| 72 | 74 |
| 73 int MojoVFSRead(sqlite3_file* sql_file, | 75 int MojoVFSRead(sqlite3_file* sql_file, |
| 74 void* buffer, | 76 void* buffer, |
| 75 int size, | 77 int size, |
| 76 sqlite3_int64 offset) { | 78 sqlite3_int64 offset) { |
| 77 DVLOG(1) << "MojoVFSRead (" << size << " @ " << offset << ")"; | 79 DVLOG(1) << "MojoVFSRead (" << size << " @ " << offset << ")"; |
| 80 TRACE_EVENT0("sql", "MojoVFSRead"); |
| 78 filesystem::FileError error = filesystem::FILE_ERROR_FAILED; | 81 filesystem::FileError error = filesystem::FILE_ERROR_FAILED; |
| 79 mojo::Array<uint8_t> mojo_data; | 82 mojo::Array<uint8_t> mojo_data; |
| 80 GetFSFile(sql_file)->Read(size, offset, filesystem::WHENCE_FROM_BEGIN, | 83 GetFSFile(sql_file)->Read(size, offset, filesystem::WHENCE_FROM_BEGIN, |
| 81 Capture(&error, &mojo_data)); | 84 Capture(&error, &mojo_data)); |
| 82 GetFSFile(sql_file).WaitForIncomingResponse(); | 85 GetFSFile(sql_file).WaitForIncomingResponse(); |
| 83 | 86 |
| 84 if (error != filesystem::FILE_ERROR_OK) { | 87 if (error != filesystem::FILE_ERROR_OK) { |
| 85 // TODO(erg): Better implementation here. | 88 // TODO(erg): Better implementation here. |
| 86 NOTIMPLEMENTED(); | 89 NOTIMPLEMENTED(); |
| 87 return SQLITE_IOERR_READ; | 90 return SQLITE_IOERR_READ; |
| 88 } | 91 } |
| 89 | 92 |
| 90 if (mojo_data.size()) | 93 if (mojo_data.size()) |
| 91 memcpy(buffer, &mojo_data.front(), mojo_data.size()); | 94 memcpy(buffer, &mojo_data.front(), mojo_data.size()); |
| 92 if (mojo_data.size() == static_cast<size_t>(size)) | 95 if (mojo_data.size() == static_cast<size_t>(size)) |
| 93 return SQLITE_OK; | 96 return SQLITE_OK; |
| 94 | 97 |
| 95 // We didn't read the entire buffer. Fill the rest of the buffer with zeros. | 98 // We didn't read the entire buffer. Fill the rest of the buffer with zeros. |
| 96 memset(reinterpret_cast<char*>(buffer) + mojo_data.size(), 0, | 99 memset(reinterpret_cast<char*>(buffer) + mojo_data.size(), 0, |
| 97 size - mojo_data.size()); | 100 size - mojo_data.size()); |
| 98 | 101 |
| 99 return SQLITE_IOERR_SHORT_READ; | 102 return SQLITE_IOERR_SHORT_READ; |
| 100 } | 103 } |
| 101 | 104 |
| 102 int MojoVFSWrite(sqlite3_file* sql_file, | 105 int MojoVFSWrite(sqlite3_file* sql_file, |
| 103 const void* buffer, | 106 const void* buffer, |
| 104 int size, | 107 int size, |
| 105 sqlite_int64 offset) { | 108 sqlite_int64 offset) { |
| 106 DVLOG(1) << "MojoVFSWrite(*, " << size << ", " << offset << ")"; | 109 DVLOG(1) << "MojoVFSWrite(*, " << size << ", " << offset << ")"; |
| 110 TRACE_EVENT0("sql", "MojoVFSWrite"); |
| 107 mojo::Array<uint8_t> mojo_data(size); | 111 mojo::Array<uint8_t> mojo_data(size); |
| 108 memcpy(&mojo_data.front(), buffer, size); | 112 memcpy(&mojo_data.front(), buffer, size); |
| 109 | 113 |
| 110 filesystem::FileError error = filesystem::FILE_ERROR_FAILED; | 114 filesystem::FileError error = filesystem::FILE_ERROR_FAILED; |
| 111 uint32_t num_bytes_written = 0; | 115 uint32_t num_bytes_written = 0; |
| 112 GetFSFile(sql_file)->Write(mojo_data.Pass(), offset, | 116 GetFSFile(sql_file)->Write(mojo_data.Pass(), offset, |
| 113 filesystem::WHENCE_FROM_BEGIN, | 117 filesystem::WHENCE_FROM_BEGIN, |
| 114 Capture(&error, &num_bytes_written)); | 118 Capture(&error, &num_bytes_written)); |
| 115 GetFSFile(sql_file).WaitForIncomingResponse(); | 119 GetFSFile(sql_file).WaitForIncomingResponse(); |
| 116 if (error != filesystem::FILE_ERROR_OK) { | 120 if (error != filesystem::FILE_ERROR_OK) { |
| 117 // TODO(erg): Better implementation here. | 121 // TODO(erg): Better implementation here. |
| 118 NOTIMPLEMENTED(); | 122 NOTIMPLEMENTED(); |
| 119 return SQLITE_IOERR_WRITE; | 123 return SQLITE_IOERR_WRITE; |
| 120 } | 124 } |
| 121 if (num_bytes_written != static_cast<uint32_t>(size)) { | 125 if (num_bytes_written != static_cast<uint32_t>(size)) { |
| 122 NOTIMPLEMENTED(); | 126 NOTIMPLEMENTED(); |
| 123 return SQLITE_IOERR_WRITE; | 127 return SQLITE_IOERR_WRITE; |
| 124 } | 128 } |
| 125 | 129 |
| 126 return SQLITE_OK; | 130 return SQLITE_OK; |
| 127 } | 131 } |
| 128 | 132 |
| 129 int MojoVFSTruncate(sqlite3_file* sql_file, sqlite_int64 size) { | 133 int MojoVFSTruncate(sqlite3_file* sql_file, sqlite_int64 size) { |
| 130 DVLOG(1) << "MojoVFSTruncate(*, " << size << ")"; | 134 DVLOG(1) << "MojoVFSTruncate(*, " << size << ")"; |
| 135 TRACE_EVENT0("sql", "MojoVFSTruncate"); |
| 131 filesystem::FileError error = filesystem::FILE_ERROR_FAILED; | 136 filesystem::FileError error = filesystem::FILE_ERROR_FAILED; |
| 132 GetFSFile(sql_file)->Truncate(size, Capture(&error)); | 137 GetFSFile(sql_file)->Truncate(size, Capture(&error)); |
| 133 GetFSFile(sql_file).WaitForIncomingResponse(); | 138 GetFSFile(sql_file).WaitForIncomingResponse(); |
| 134 if (error != filesystem::FILE_ERROR_OK) { | 139 if (error != filesystem::FILE_ERROR_OK) { |
| 135 // TODO(erg): Better implementation here. | 140 // TODO(erg): Better implementation here. |
| 136 NOTIMPLEMENTED(); | 141 NOTIMPLEMENTED(); |
| 137 return SQLITE_IOERR_TRUNCATE; | 142 return SQLITE_IOERR_TRUNCATE; |
| 138 } | 143 } |
| 139 | 144 |
| 140 return SQLITE_OK; | 145 return SQLITE_OK; |
| 141 } | 146 } |
| 142 | 147 |
| 143 int MojoVFSSync(sqlite3_file* sql_file, int flags) { | 148 int MojoVFSSync(sqlite3_file* sql_file, int flags) { |
| 144 DVLOG(1) << "MojoVFSSync(*, " << flags << ")"; | 149 DVLOG(1) << "MojoVFSSync(*, " << flags << ")"; |
| 150 TRACE_EVENT0("sql", "MojoVFSSync"); |
| 145 filesystem::FileError error = filesystem::FILE_ERROR_FAILED; | 151 filesystem::FileError error = filesystem::FILE_ERROR_FAILED; |
| 146 GetFSFile(sql_file)->Flush(Capture(&error)); | 152 GetFSFile(sql_file)->Flush(Capture(&error)); |
| 147 GetFSFile(sql_file).WaitForIncomingResponse(); | 153 GetFSFile(sql_file).WaitForIncomingResponse(); |
| 148 if (error != filesystem::FILE_ERROR_OK) { | 154 if (error != filesystem::FILE_ERROR_OK) { |
| 149 // TODO(erg): Better implementation here. | 155 // TODO(erg): Better implementation here. |
| 150 NOTIMPLEMENTED(); | 156 NOTIMPLEMENTED(); |
| 151 return SQLITE_IOERR_FSYNC; | 157 return SQLITE_IOERR_FSYNC; |
| 152 } | 158 } |
| 153 | 159 |
| 154 return SQLITE_OK; | 160 return SQLITE_OK; |
| 155 } | 161 } |
| 156 | 162 |
| 157 int MojoVFSFileSize(sqlite3_file* sql_file, sqlite_int64* size) { | 163 int MojoVFSFileSize(sqlite3_file* sql_file, sqlite_int64* size) { |
| 158 DVLOG(1) << "MojoVFSFileSize(*)"; | 164 DVLOG(1) << "MojoVFSFileSize(*)"; |
| 165 TRACE_EVENT0("sql", "MojoVFSFileSize"); |
| 159 | 166 |
| 160 filesystem::FileError err = filesystem::FILE_ERROR_FAILED; | 167 filesystem::FileError err = filesystem::FILE_ERROR_FAILED; |
| 161 filesystem::FileInformationPtr file_info; | 168 filesystem::FileInformationPtr file_info; |
| 162 GetFSFile(sql_file)->Stat(Capture(&err, &file_info)); | 169 GetFSFile(sql_file)->Stat(Capture(&err, &file_info)); |
| 163 GetFSFile(sql_file).WaitForIncomingResponse(); | 170 GetFSFile(sql_file).WaitForIncomingResponse(); |
| 164 | 171 |
| 165 if (err != filesystem::FILE_ERROR_OK) { | 172 if (err != filesystem::FILE_ERROR_OK) { |
| 166 // TODO(erg): Better implementation here. | 173 // TODO(erg): Better implementation here. |
| 167 NOTIMPLEMENTED(); | 174 NOTIMPLEMENTED(); |
| 168 return SQLITE_IOERR_FSTAT; | 175 return SQLITE_IOERR_FSTAT; |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 229 MojoVFSSectorSize, /* xSectorSize */ | 236 MojoVFSSectorSize, /* xSectorSize */ |
| 230 MojoVFSDeviceCharacteristics, /* xDeviceCharacteristics */ | 237 MojoVFSDeviceCharacteristics, /* xDeviceCharacteristics */ |
| 231 }; | 238 }; |
| 232 | 239 |
| 233 int MojoVFSOpen(sqlite3_vfs* mojo_vfs, | 240 int MojoVFSOpen(sqlite3_vfs* mojo_vfs, |
| 234 const char* name, | 241 const char* name, |
| 235 sqlite3_file* file, | 242 sqlite3_file* file, |
| 236 int flags, | 243 int flags, |
| 237 int* pOutFlags) { | 244 int* pOutFlags) { |
| 238 DVLOG(1) << "MojoVFSOpen(*, " << name << ", *, " << flags << ")"; | 245 DVLOG(1) << "MojoVFSOpen(*, " << name << ", *, " << flags << ")"; |
| 246 TRACE_EVENT2("sql", "MojoVFSOpen", |
| 247 "name", name, |
| 248 "flags", flags); |
| 239 int open_flags = 0; | 249 int open_flags = 0; |
| 240 if (flags & SQLITE_OPEN_EXCLUSIVE) { | 250 if (flags & SQLITE_OPEN_EXCLUSIVE) { |
| 241 DCHECK(flags & SQLITE_OPEN_CREATE); | 251 DCHECK(flags & SQLITE_OPEN_CREATE); |
| 242 open_flags = filesystem::kFlagCreate; | 252 open_flags = filesystem::kFlagCreate; |
| 243 } else if (flags & SQLITE_OPEN_CREATE) { | 253 } else if (flags & SQLITE_OPEN_CREATE) { |
| 244 DCHECK(flags & SQLITE_OPEN_READWRITE); | 254 DCHECK(flags & SQLITE_OPEN_READWRITE); |
| 245 open_flags = filesystem::kFlagOpenAlways; | 255 open_flags = filesystem::kFlagOpenAlways; |
| 246 } else { | 256 } else { |
| 247 open_flags = filesystem::kFlagOpen; | 257 open_flags = filesystem::kFlagOpen; |
| 248 } | 258 } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 286 // |file| is actually a malloced buffer of size szOsFile. This means that we | 296 // |file| is actually a malloced buffer of size szOsFile. This means that we |
| 287 // need to manually use placement new to construct the C++ object which owns | 297 // need to manually use placement new to construct the C++ object which owns |
| 288 // the pipe to our file. | 298 // the pipe to our file. |
| 289 new (&GetFSFile(file)) filesystem::FilePtr(file_ptr.Pass()); | 299 new (&GetFSFile(file)) filesystem::FilePtr(file_ptr.Pass()); |
| 290 | 300 |
| 291 return SQLITE_OK; | 301 return SQLITE_OK; |
| 292 } | 302 } |
| 293 | 303 |
| 294 int MojoVFSDelete(sqlite3_vfs* mojo_vfs, const char* filename, int sync_dir) { | 304 int MojoVFSDelete(sqlite3_vfs* mojo_vfs, const char* filename, int sync_dir) { |
| 295 DVLOG(1) << "MojoVFSDelete(*, " << filename << ", " << sync_dir << ")"; | 305 DVLOG(1) << "MojoVFSDelete(*, " << filename << ", " << sync_dir << ")"; |
| 306 TRACE_EVENT2("sql", "MojoVFSDelete", |
| 307 "name", filename, |
| 308 "sync_dir", sync_dir); |
| 296 // TODO(erg): The default windows sqlite VFS has retry code to work around | 309 // TODO(erg): The default windows sqlite VFS has retry code to work around |
| 297 // antivirus software keeping files open. We'll probably have to do something | 310 // antivirus software keeping files open. We'll probably have to do something |
| 298 // like that in the far future if we ever support Windows. | 311 // like that in the far future if we ever support Windows. |
| 299 filesystem::FileError error = filesystem::FILE_ERROR_FAILED; | 312 filesystem::FileError error = filesystem::FILE_ERROR_FAILED; |
| 300 GetRootDirectory(mojo_vfs)->Delete(filename, 0, Capture(&error)); | 313 GetRootDirectory(mojo_vfs)->Delete(filename, 0, Capture(&error)); |
| 301 GetRootDirectory(mojo_vfs).WaitForIncomingResponse(); | 314 GetRootDirectory(mojo_vfs).WaitForIncomingResponse(); |
| 302 | 315 |
| 303 if (error == filesystem::FILE_ERROR_OK && sync_dir) { | 316 if (error == filesystem::FILE_ERROR_OK && sync_dir) { |
| 304 GetRootDirectory(mojo_vfs)->Flush(Capture(&error)); | 317 GetRootDirectory(mojo_vfs)->Flush(Capture(&error)); |
| 305 GetRootDirectory(mojo_vfs).WaitForIncomingResponse(); | 318 GetRootDirectory(mojo_vfs).WaitForIncomingResponse(); |
| 306 } | 319 } |
| 307 | 320 |
| 308 return error == filesystem::FILE_ERROR_OK ? SQLITE_OK : SQLITE_IOERR_DELETE; | 321 return error == filesystem::FILE_ERROR_OK ? SQLITE_OK : SQLITE_IOERR_DELETE; |
| 309 } | 322 } |
| 310 | 323 |
| 311 int MojoVFSAccess(sqlite3_vfs* mojo_vfs, | 324 int MojoVFSAccess(sqlite3_vfs* mojo_vfs, |
| 312 const char* filename, | 325 const char* filename, |
| 313 int flags, | 326 int flags, |
| 314 int* result) { | 327 int* result) { |
| 315 DVLOG(1) << "MojoVFSAccess(*, " << filename << ", " << flags << ", *)"; | 328 DVLOG(1) << "MojoVFSAccess(*, " << filename << ", " << flags << ", *)"; |
| 329 TRACE_EVENT2("sql", "MojoVFSAccess", |
| 330 "name", filename, |
| 331 "flags", flags); |
| 316 filesystem::FileError error = filesystem::FILE_ERROR_FAILED; | 332 filesystem::FileError error = filesystem::FILE_ERROR_FAILED; |
| 317 | 333 |
| 318 if (flags == SQLITE_ACCESS_READWRITE || flags == SQLITE_ACCESS_READ) { | 334 if (flags == SQLITE_ACCESS_READWRITE || flags == SQLITE_ACCESS_READ) { |
| 319 bool is_writable = false; | 335 bool is_writable = false; |
| 320 GetRootDirectory(mojo_vfs) | 336 GetRootDirectory(mojo_vfs) |
| 321 ->IsWritable(filename, Capture(&error, &is_writable)); | 337 ->IsWritable(filename, Capture(&error, &is_writable)); |
| 322 GetRootDirectory(mojo_vfs).WaitForIncomingResponse(); | 338 GetRootDirectory(mojo_vfs).WaitForIncomingResponse(); |
| 323 *result = is_writable; | 339 *result = is_writable; |
| 324 return SQLITE_OK; | 340 return SQLITE_OK; |
| 325 } | 341 } |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 426 | 442 |
| 427 CHECK(sqlite3_vfs_register(parent_, 1) == SQLITE_OK); | 443 CHECK(sqlite3_vfs_register(parent_, 1) == SQLITE_OK); |
| 428 CHECK(sqlite3_vfs_unregister(&mojo_vfs) == SQLITE_OK); | 444 CHECK(sqlite3_vfs_unregister(&mojo_vfs) == SQLITE_OK); |
| 429 } | 445 } |
| 430 | 446 |
| 431 filesystem::DirectoryPtr& ScopedMojoFilesystemVFS::GetDirectory() { | 447 filesystem::DirectoryPtr& ScopedMojoFilesystemVFS::GetDirectory() { |
| 432 return root_directory_; | 448 return root_directory_; |
| 433 } | 449 } |
| 434 | 450 |
| 435 } // namespace sql | 451 } // namespace sql |
| OLD | NEW |