/// <summary> /// Initializes a new instance of the <see cref="Database" /> class. /// </summary> /// <param name="dataPath">The database directory path.</param> public Database(string dataPath = null) { if (String.IsNullOrWhiteSpace(dataPath)) { var appPath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); dataPath = Path.Combine(appPath, DATA_DIRECTORY_NAME); } DataPath = dataPath; EnsureDataDirectoryExists(DataPath); _log.Info($"Data Path: {DataPath}"); IndexBasePath = Path.Combine(DataPath, INDEX_DIRECTORY_NAME); EnsureIndexDirectoryExists(IndexBasePath); _log.Info($"Index Base Path: {IndexBasePath}"); DocumentStorage = new LightningDocumentStorage(DataPath); _collections = new ConcurrentDictionary<string, Collection>(); var persistedSchemas = DocumentStorage.GetAllAsync(Schema.COLLECTION_NAME).Result.Select(d => d.ToSchema()); foreach (var schema in persistedSchemas) { var collection = new Collection(schema, this); _collections.TryAdd(schema.Name, collection); } var schemaPersistenceIntervalSeconds = Double.Parse(ConfigurationManager.AppSettings["Schema.PersistenceIntervalSeconds"] ?? "1"); _schemaPersistenceTimer = new Timer(_ => Task.Run(async () => await PersistSchemas().ConfigureAwait(false)), null, TimeSpan.FromSeconds(schemaPersistenceIntervalSeconds), TimeSpan.FromSeconds(schemaPersistenceIntervalSeconds)); }
/// <summary> /// Persists the Schema of the specified Collection to a special _schemas Collection. /// </summary> /// <param name="collection">The collection.</param> /// <returns></returns> private async Task PersistSchema(Collection collection) { try { var liveSchemaDocument = collection.Schema.ToDocument(); var savedSchemaDocument = await this[Schema.COLLECTION_NAME].GetAsync(liveSchemaDocument._id.Value); var isSchemaUpdated = false; if (savedSchemaDocument == null) { await this[Schema.COLLECTION_NAME].InsertAsync(liveSchemaDocument); isSchemaUpdated = true; } else { if (liveSchemaDocument != savedSchemaDocument) { await this[Schema.COLLECTION_NAME].UpdateAsync(liveSchemaDocument); isSchemaUpdated = true; } } if (isSchemaUpdated) { savedSchemaDocument = await this[Schema.COLLECTION_NAME].GetAsync(liveSchemaDocument._id.Value); collection.Schema._id = savedSchemaDocument._id; collection.Schema._createdTimestamp = savedSchemaDocument._createdTimestamp; collection.Schema._modifiedTimestamp = savedSchemaDocument._modifiedTimestamp; } } catch (Exception ex) { _log.Error(ex); } }
/// <summary> /// Gets the <see cref="Collection"/> with the specified name. /// </summary> /// <value> /// The <see cref="Collection"/> with the specified name. /// </value> /// <param name="name">The name of the Document Collection.</param> /// <returns></returns> public Collection this [string name] { get { if (String.IsNullOrWhiteSpace(name)) throw new ArgumentException("name cannot be null or blank"); Collection collection = null; if (!_collections.ContainsKey(name)) { lock (_collections) { if (!_collections.ContainsKey(name)) { collection = new Collection(name, this); _collections.TryAdd(name, collection); } } } _collections.TryGetValue(name, out collection); if (collection == null || collection.IsDropped) throw new InvalidOperationException($"The Document Collection '{name}' does not exist."); return collection; } }