private void Attach(bool force) { if (force == false && _attached) { return; } Task.Factory.StartNew(async() => { await _locker.WaitAsync(); try { if (force == false && _attached) { return; } var database = await _databaseLandlord.TryGetOrCreateResourceStore(_databaseName); database.Changes.OnIndexChange += AddIndexIfNecessary; await AddIndexesFromDatabase(database); _attached = true; } finally { _locker.Release(); } }); }
protected override TData GetData() { if (Landlord.IsDatabaseLoaded(DatabaseName)) { return(GetData(Landlord.TryGetOrCreateResourceStore(DatabaseName).Result)); } return(default(TData)); }
private void GenerateNewDatabaseId(string databaseName) { Task <DocumentDatabase> databaseTask; if (DatabasesLandlord.TryGetOrCreateResourceStore(databaseName, out databaseTask) == false) { return; } var database = databaseTask.Result; database.TransactionalStorage.ChangeId(); }
private void AddReplicationBundleAndDisableReplicationDestinations(string databaseName) { Task <DocumentDatabase> databaseTask; if (DatabasesLandlord.TryGetOrCreateResourceStore(databaseName, out databaseTask) == false) { return; } var database = databaseTask.Result; var replicationDocumentAsJson = database.Documents.Get(Constants.RavenReplicationDestinations, null); if (replicationDocumentAsJson != null) { var replicationDocument = replicationDocumentAsJson.DataAsJson.JsonDeserialization <ReplicationDocument>(); foreach (var destination in replicationDocument.Destinations) { destination.Disabled = true; } database .Documents .Put(Constants.RavenReplicationDestinations, null, RavenJObject.FromObject(replicationDocument), new RavenJObject(), null); } var databaseDocumentAsJson = DatabasesLandlord.SystemDatabase.Documents.Get(Constants.Database.Prefix + databaseName, null); var databaseDocument = databaseDocumentAsJson.DataAsJson.JsonDeserialization <DatabaseDocument>(); var bundles = databaseDocument.Settings[Constants.ActiveBundles].GetSemicolonSeparatedValues(); bundles.Add("Replication"); databaseDocument.Settings[Constants.ActiveBundles] = string.Join(";", bundles); DatabasesLandlord .SystemDatabase .Documents .Put( Constants.Database.Prefix + databaseName, null, RavenJObject.FromObject(databaseDocument), new RavenJObject { { "Raven-Temp-Allow-Bundles-Change", true } }, null); }
public override bool SetupRequestToProperDatabase(RequestManager rm) { var tenantId = DatabaseName; if (string.IsNullOrWhiteSpace(tenantId) || tenantId == "<system>") { landlord.LastRecentlyUsed.AddOrUpdate("System", SystemTime.UtcNow, (s, time) => SystemTime.UtcNow); var args = new BeforeRequestWebApiEventArgs { Controller = this, IgnoreRequest = false, TenantId = "System", Database = landlord.SystemDatabase }; rm.OnBeforeRequest(args); if (args.IgnoreRequest) { return(false); } return(true); } Task <DocumentDatabase> resourceStoreTask; bool hasDb; try { hasDb = landlord.TryGetOrCreateResourceStore(tenantId, out resourceStoreTask); } catch (Exception e) { var msg = "Could not open database named: " + tenantId; Logger.WarnException(msg, e); throw new HttpException(503, msg, e); } if (hasDb) { try { if (resourceStoreTask.Wait(TimeSpan.FromSeconds(30)) == false) { var msg = "The database " + tenantId + " is currently being loaded, but after 30 seconds, this request has been aborted. Please try again later, database loading continues."; Logger.Warn(msg); throw new HttpException(503, msg); } var args = new BeforeRequestWebApiEventArgs() { Controller = this, IgnoreRequest = false, TenantId = tenantId, Database = resourceStoreTask.Result }; rm.OnBeforeRequest(args); if (args.IgnoreRequest) { return(false); } } catch (Exception e) { string exceptionMessage = e.Message; var aggregateException = e as AggregateException; if (aggregateException != null) { exceptionMessage = aggregateException.ExtractSingleInnerException().Message; } var msg = "Could not open database named: " + tenantId + Environment.NewLine + exceptionMessage; Logger.WarnException(msg, e); throw new HttpException(503, msg, e); } landlord.LastRecentlyUsed.AddOrUpdate(tenantId, SystemTime.UtcNow, (s, time) => SystemTime.UtcNow); } else { var msg = "Could not find a database named: " + tenantId; Logger.Warn(msg); throw new HttpException(503, msg); } return(true); }
public async Task Run() { using var _ = _client; using var messageBuilder = new MessageBuilder(); Stream stream = _client.GetStream(); stream = await HandleInitialMessage(stream, messageBuilder); var reader = PipeReader.Create(stream); var writer = PipeWriter.Create(stream); if (_clientOptions == null) //TODO pfyasu maybe unused when cancel message will be implemented { return; } if (_clientOptions.TryGetValue("database", out string databaseName) == false) { await writer.WriteAsync(messageBuilder.ErrorResponse( PgSeverity.Fatal, PgErrorCodes.ConnectionFailure, "Failed to connect to database", "Missing database name in the connection string"), _token); return; } var database = await _databasesLandlord.TryGetOrCreateResourceStore(databaseName); if (database == null) { await writer.WriteAsync(messageBuilder.ErrorResponse( PgSeverity.Fatal, PgErrorCodes.ConnectionFailure, "Failed to connect to database", $"Database '{databaseName}' does not exist"), _token); return; } string username = null; try { username = _clientOptions["user"]; using var transaction = new PgTransaction(database, new MessageReader(), username); if (_serverCertificate != null) { // Authentication is required only when running in secured mode await writer.WriteAsync(messageBuilder.AuthenticationCleartextPassword(), _token); var authMessage = await transaction.MessageReader.GetUninitializedMessage(reader, _token); await authMessage.Init(transaction.MessageReader, reader, _token); await authMessage.Handle(transaction, messageBuilder, reader, writer, _token); } else { await writer.WriteAsync(messageBuilder.AuthenticationOk(), _token); } await writer.WriteAsync(messageBuilder.ParameterStatusMessages(PgConfig.ParameterStatusList), _token); await writer.WriteAsync(messageBuilder.BackendKeyData(_processId, _identifier), _token); await writer.WriteAsync(messageBuilder.ReadyForQuery(transaction.State), _token); while (_token.IsCancellationRequested == false) { var message = await transaction.MessageReader.GetUninitializedMessage(reader, _token); try { await message.Init(transaction.MessageReader, reader, _token); await message.Handle(transaction, messageBuilder, reader, writer, _token); } catch (PgErrorException e) { await message.HandleError(e, transaction, messageBuilder, writer, _token); } } } catch (PgFatalException e) { if (Logger.IsInfoEnabled) { Logger.Info($"{e.Message} (fatal pg error code {e.ErrorCode}). {GetSourceConnectionDetails(username)}", e); } await writer.WriteAsync(messageBuilder.ErrorResponse( PgSeverity.Fatal, e.ErrorCode, e.Message, e.ToString()), _token); } catch (PgErrorException e) { if (Logger.IsInfoEnabled) { Logger.Info($"{e.Message} (pg error code {e.ErrorCode}). {GetSourceConnectionDetails(username)}", e); } // Shouldn't get to this point, PgErrorExceptions shouldn't be fatal await writer.WriteAsync(messageBuilder.ErrorResponse( PgSeverity.Error, e.ErrorCode, e.Message, e.ToString()), _token); } catch (PgTerminateReceivedException) { // Terminate silently } catch (QueryParser.ParseException e) { if (Logger.IsInfoEnabled) { Logger.Info("Invalid RQL query", e); } try { await writer.WriteAsync(messageBuilder.ErrorResponse( PgSeverity.Error, PgErrorCodes.InvalidSqlStatementName, e.ToString()), _token); } catch (Exception) { // ignored } } catch (Exception e) { if (Logger.IsInfoEnabled) { Logger.Info($"Unexpected internal pg error. {GetSourceConnectionDetails(username)}", e); } try { await writer.WriteAsync(messageBuilder.ErrorResponse( PgSeverity.Fatal, PgErrorCodes.InternalError, e.ToString()), _token); } catch (Exception) { // ignored } } }