private static BaseMetadata readMetadataFromDatabase(string location, ReadOptions options, CancellationToken token, int timeoutSeconds) { BaseMetadata metadata = null; using (MetadataDbCommands metadataCommands = new MetadataDbCommands()) { metadata = metadataCommands.findMetadataByLocation(location); if (metadata != null) { metadata.IsImported = true; if (options.HasFlag(ReadOptions.LEAVE_STREAM_OPENED_AFTER_READ)) { Stream data = FileUtils.waitForFileAccess(location, FileAccess.Read, FILE_OPEN_ASYNC_TIMEOUT_MS, token); metadata.Data = data; } // check if metadata stored in the database is outdated FileInfo info = new FileInfo(location); info.Refresh(); if (info.Exists == false) { metadata.MetadataReadError = new FileNotFoundException("File not found", location); return(metadata); } if ((info.LastWriteTime - metadata.LastModifiedDate) > TimeSpan.FromSeconds(10)) { // metadata is outdated so update in database Logger.Log.Info("Updated: " + location + " - Database timestamp: " + metadata.LastModifiedDate.ToString() + " Disk timestamp: " + info.LastWriteTime.ToString()); int id = metadata.Id; metadata = MetadataFileFactory.read(location, options, token, timeoutSeconds); if (metadata != null) { metadata.IsImported = true; metadata.Id = id; write(metadata, WriteOptions.WRITE_TO_DATABASE, null); } } if (info.Attributes.HasFlag(FileAttributes.ReadOnly)) { metadata.IsReadOnly = true; } } } return(metadata); }
public static void write(BaseMetadata metadata, WriteOptions options, CancellableOperationProgressBase progress = null) { if (options.HasFlag(WriteOptions.AUTO) || options.HasFlag(WriteOptions.WRITE_TO_DISK)) { MetadataFileFactory.write(metadata, progress); } if (metadata.IsImported && (options.HasFlag(WriteOptions.AUTO) || options.HasFlag(WriteOptions.WRITE_TO_DATABASE))) { using (MetadataDbCommands metadataCommands = new MetadataDbCommands()) { metadata = metadataCommands.update(metadata); } } metadata.IsModified = false; }
/// <summary> /// Returns null when metadata does not exist /// UnknownMetadata when metadata is not recognized /// </summary> /// <param name="location"></param> /// <param name="options"></param> /// <param name="token"></param> /// <returns></returns> public static BaseMetadata read(string location, ReadOptions options, CancellationToken token, int timeoutSeconds = 60) { limitConcurrentReadsSemaphore.Wait(token); try { // initialize metadata with a dummy in case of exceptions BaseMetadata metadata = null; if (string.IsNullOrEmpty(location) || token.IsCancellationRequested == true) { return(metadata); } else if (FileUtils.isUrl(location)) { metadata = readMetadataFromWeb(location, options, token, timeoutSeconds); } else { if (options.HasFlag(ReadOptions.AUTO) || options.HasFlag(ReadOptions.READ_FROM_DATABASE)) { metadata = readMetadataFromDatabase(location, options, token, timeoutSeconds); } if ((metadata == null && options.HasFlag(ReadOptions.AUTO)) || options.HasFlag(ReadOptions.READ_FROM_DISK)) { metadata = MetadataFileFactory.read(location, options, token, timeoutSeconds); } } metadata.IsModified = false; return(metadata); } catch (OperationCanceledException) { // convert operationcanceled to taskcanceled when the token aborts waiting for the semaphore throw new TaskCanceledException(); } finally { limitConcurrentReadsSemaphore.Release(); } }