@@ -44,37 +44,16 @@ extern "C" WINBASEAPI BOOL WINAPI GetPhysicallyInstalledSystemMemory(PULONGLONG)
44
44
// See e.g.:
45
45
// https://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/TargetConditionals.h.auto.html
46
46
#elif defined(__APPLE__)
47
- #include < TargetConditionals.h> // NOLINT
48
- #if not(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE == 1) // NOLINT
49
- #include < libproc.h> // NOLINT
50
- #endif // NOLINT
47
+ #include < TargetConditionals.h>
48
+ #if not(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE == 1)
49
+ #include < libproc.h>
50
+ #endif
51
51
#elif defined(_WIN32)
52
52
#include < restartmanager.h>
53
53
#endif
54
54
55
55
namespace duckdb {
56
56
57
- static void AssertValidFileFlags (uint8_t flags) {
58
- #ifdef DEBUG
59
- bool is_read = flags & FileFlags::FILE_FLAGS_READ;
60
- bool is_write = flags & FileFlags::FILE_FLAGS_WRITE;
61
- bool is_create = (flags & FileFlags::FILE_FLAGS_FILE_CREATE) || (flags & FileFlags::FILE_FLAGS_FILE_CREATE_NEW);
62
- bool is_private = (flags & FileFlags::FILE_FLAGS_PRIVATE);
63
-
64
- // require either READ or WRITE (or both)
65
- D_ASSERT (is_read || is_write);
66
- // CREATE/Append flags require writing
67
- D_ASSERT (is_write || !(flags & FileFlags::FILE_FLAGS_APPEND));
68
- D_ASSERT (is_write || !(flags & FileFlags::FILE_FLAGS_FILE_CREATE));
69
- D_ASSERT (is_write || !(flags & FileFlags::FILE_FLAGS_FILE_CREATE_NEW));
70
- // cannot combine CREATE and CREATE_NEW flags
71
- D_ASSERT (!(flags & FileFlags::FILE_FLAGS_FILE_CREATE && flags & FileFlags::FILE_FLAGS_FILE_CREATE_NEW));
72
-
73
- // For is_private can only be set along with a create flag
74
- D_ASSERT (!is_private || is_create);
75
- #endif
76
- }
77
-
78
57
#ifndef _WIN32
79
58
bool LocalFileSystem::FileExists (const string &filename) {
80
59
if (!filename.empty ()) {
@@ -292,19 +271,19 @@ bool LocalFileSystem::IsPrivateFile(const string &path_p, FileOpener *opener) {
292
271
return true ;
293
272
}
294
273
295
- unique_ptr<FileHandle> LocalFileSystem::OpenFile (const string &path_p, uint8_t flags, FileLockType lock_type ,
296
- FileCompressionType compression, FileOpener * opener) {
274
+ unique_ptr<FileHandle> LocalFileSystem::OpenFile (const string &path_p, FileOpenFlags flags,
275
+ optional_ptr< FileOpener> opener) {
297
276
auto path = FileSystem::ExpandPath (path_p, opener);
298
- if (compression != FileCompressionType::UNCOMPRESSED) {
277
+ if (flags. Compression () != FileCompressionType::UNCOMPRESSED) {
299
278
throw NotImplementedException (" Unsupported compression type for default file system" );
300
279
}
301
280
302
- AssertValidFileFlags ( flags);
281
+ flags. Verify ( );
303
282
304
283
int open_flags = 0 ;
305
284
int rc;
306
- bool open_read = flags & FileFlags::FILE_FLAGS_READ ;
307
- bool open_write = flags & FileFlags::FILE_FLAGS_WRITE ;
285
+ bool open_read = flags. OpenForReading () ;
286
+ bool open_write = flags. OpenForWriting () ;
308
287
if (open_read && open_write) {
309
288
open_flags = O_RDWR;
310
289
} else if (open_read) {
@@ -316,18 +295,18 @@ unique_ptr<FileHandle> LocalFileSystem::OpenFile(const string &path_p, uint8_t f
316
295
}
317
296
if (open_write) {
318
297
// need Read or Write
319
- D_ASSERT (flags & FileFlags::FILE_FLAGS_WRITE );
298
+ D_ASSERT (flags. OpenForWriting () );
320
299
open_flags |= O_CLOEXEC;
321
- if (flags & FileFlags::FILE_FLAGS_FILE_CREATE ) {
300
+ if (flags. CreateFileIfNotExists () ) {
322
301
open_flags |= O_CREAT;
323
- } else if (flags & FileFlags::FILE_FLAGS_FILE_CREATE_NEW ) {
302
+ } else if (flags. OverwriteExistingFile () ) {
324
303
open_flags |= O_CREAT | O_TRUNC;
325
304
}
326
- if (flags & FileFlags::FILE_FLAGS_APPEND ) {
305
+ if (flags. OpenForAppending () ) {
327
306
open_flags |= O_APPEND;
328
307
}
329
308
}
330
- if (flags & FileFlags::FILE_FLAGS_DIRECT_IO ) {
309
+ if (flags. DirectIO () ) {
331
310
#if defined(__sun) && defined(__SVR4)
332
311
throw InvalidInputException (" DIRECT_IO not supported on Solaris" );
333
312
#endif
@@ -341,7 +320,7 @@ unique_ptr<FileHandle> LocalFileSystem::OpenFile(const string &path_p, uint8_t f
341
320
342
321
// Determine permissions
343
322
mode_t filesec;
344
- if (flags & FileFlags::FILE_FLAGS_PRIVATE ) {
323
+ if (flags. CreatePrivateFile () ) {
345
324
open_flags |= O_EXCL; // Ensure we error on existing files or the permissions may not set
346
325
filesec = 0600 ;
347
326
} else {
@@ -352,6 +331,9 @@ unique_ptr<FileHandle> LocalFileSystem::OpenFile(const string &path_p, uint8_t f
352
331
int fd = open (path.c_str (), open_flags, filesec);
353
332
354
333
if (fd == -1 ) {
334
+ if (flags.ReturnNullIfNotExists () && errno == ENOENT) {
335
+ return nullptr ;
336
+ }
355
337
throw IOException (" Cannot open file \" %s\" : %s" , {{" errno" , std::to_string (errno)}}, path, strerror (errno));
356
338
}
357
339
// #if defined(__DARWIN__) || defined(__APPLE__)
@@ -363,14 +345,14 @@ unique_ptr<FileHandle> LocalFileSystem::OpenFile(const string &path_p, uint8_t f
363
345
// }
364
346
// }
365
347
// #endif
366
- if (lock_type != FileLockType::NO_LOCK) {
348
+ if (flags. Lock () != FileLockType::NO_LOCK) {
367
349
// set lock on file
368
350
// but only if it is not an input/output stream
369
351
auto file_type = GetFileTypeInternal (fd);
370
352
if (file_type != FileType::FILE_TYPE_FIFO && file_type != FileType::FILE_TYPE_SOCKET) {
371
353
struct flock fl;
372
354
memset (&fl, 0 , sizeof fl);
373
- fl.l_type = lock_type == FileLockType::READ_LOCK ? F_RDLCK : F_WRLCK;
355
+ fl.l_type = flags. Lock () == FileLockType::READ_LOCK ? F_RDLCK : F_WRLCK;
374
356
fl.l_whence = SEEK_SET;
375
357
fl.l_start = 0 ;
376
358
fl.l_len = 0 ;
@@ -387,7 +369,7 @@ unique_ptr<FileHandle> LocalFileSystem::OpenFile(const string &path_p, uint8_t f
387
369
message = AdditionalProcessInfo (*this , fl.l_pid );
388
370
}
389
371
390
- if (lock_type == FileLockType::WRITE_LOCK) {
372
+ if (flags. Lock () == FileLockType::WRITE_LOCK) {
391
373
// maybe we can get a read lock instead and tell this to the user.
392
374
fl.l_type = F_RDLCK;
393
375
rc = fcntl (fd, F_SETLK, &fl);
@@ -776,20 +758,20 @@ bool LocalFileSystem::IsPrivateFile(const string &path_p, FileOpener *opener) {
776
758
return true ;
777
759
}
778
760
779
- unique_ptr<FileHandle> LocalFileSystem::OpenFile (const string &path_p, uint8_t flags, FileLockType lock_type ,
780
- FileCompressionType compression, FileOpener * opener) {
761
+ unique_ptr<FileHandle> LocalFileSystem::OpenFile (const string &path_p, FileOpenFlags flags,
762
+ optional_ptr< FileOpener> opener) {
781
763
auto path = FileSystem::ExpandPath (path_p, opener);
782
- if (compression != FileCompressionType::UNCOMPRESSED) {
764
+ if (flags. Compression () != FileCompressionType::UNCOMPRESSED) {
783
765
throw NotImplementedException (" Unsupported compression type for default file system" );
784
766
}
785
- AssertValidFileFlags ( flags);
767
+ flags. Verify ( );
786
768
787
769
DWORD desired_access;
788
770
DWORD share_mode;
789
771
DWORD creation_disposition = OPEN_EXISTING;
790
772
DWORD flags_and_attributes = FILE_ATTRIBUTE_NORMAL;
791
- bool open_read = flags & FileFlags::FILE_FLAGS_READ ;
792
- bool open_write = flags & FileFlags::FILE_FLAGS_WRITE ;
773
+ bool open_read = flags. OpenForReading () ;
774
+ bool open_write = flags. OpenForWriting () ;
793
775
if (open_read && open_write) {
794
776
desired_access = GENERIC_READ | GENERIC_WRITE;
795
777
share_mode = 0 ;
@@ -803,30 +785,33 @@ unique_ptr<FileHandle> LocalFileSystem::OpenFile(const string &path_p, uint8_t f
803
785
throw InternalException (" READ, WRITE or both should be specified when opening a file" );
804
786
}
805
787
if (open_write) {
806
- if (flags & FileFlags::FILE_FLAGS_FILE_CREATE ) {
788
+ if (flags. CreateFileIfNotExists () ) {
807
789
creation_disposition = OPEN_ALWAYS;
808
- } else if (flags & FileFlags::FILE_FLAGS_FILE_CREATE_NEW ) {
790
+ } else if (flags. OverwriteExistingFile () ) {
809
791
creation_disposition = CREATE_ALWAYS;
810
792
}
811
793
}
812
- if (flags & FileFlags::FILE_FLAGS_DIRECT_IO ) {
794
+ if (flags. DirectIO () ) {
813
795
flags_and_attributes |= FILE_FLAG_NO_BUFFERING;
814
796
}
815
797
auto unicode_path = WindowsUtil::UTF8ToUnicode (path.c_str ());
816
798
HANDLE hFile = CreateFileW (unicode_path.c_str (), desired_access, share_mode, NULL , creation_disposition,
817
799
flags_and_attributes, NULL );
818
800
if (hFile == INVALID_HANDLE_VALUE) {
801
+ if (flags.ReturnNullIfNotExists () && GetLastError () == ERROR_FILE_NOT_FOUND) {
802
+ return nullptr ;
803
+ }
819
804
auto error = LocalFileSystem::GetLastErrorAsString ();
820
805
821
806
auto better_error = AdditionalLockInfo (unicode_path);
822
807
if (!better_error.empty ()) {
823
808
throw IOException (better_error);
809
+ } else {
810
+ throw IOException (" Cannot open file \" %s\" : %s" , path.c_str (), error);
824
811
}
825
-
826
- throw IOException (" Cannot open file \" %s\" : %s" , path.c_str (), error);
827
812
}
828
813
auto handle = make_uniq<WindowsFileHandle>(*this , path.c_str (), hFile);
829
- if (flags & FileFlags::FILE_FLAGS_APPEND ) {
814
+ if (flags. OpenForAppending () ) {
830
815
auto file_size = GetFileSize (*handle);
831
816
SetFilePointer (*handle, file_size);
832
817
}
0 commit comments