protected override async Task HandleMessage(PgTransaction transaction, MessageBuilder messageBuilder, PipeWriter writer, CancellationToken token) { if (!string.IsNullOrEmpty(StatementName)) { throw new PgErrorException(PgErrorCodes.FeatureNotSupported, "Named statements are not supported."); } // Extract optional parameter types (e.g. $1::int4) var foundParamTypes = new List <string>(); var cleanQueryText = ParamRegex.Replace(Query, new MatchEvaluator((Match match) => { foundParamTypes.Add(match.Groups["type"].Value); return(""); })); if (ParametersDataTypes.Length < foundParamTypes.Count) { var arr = ParametersDataTypes; ParametersDataTypes = new int[foundParamTypes.Count]; arr.CopyTo(ParametersDataTypes.AsSpan()); } for (int i = 0; i < foundParamTypes.Count; i++) { if (ParametersDataTypes[i] == 0) { ParametersDataTypes[i] = PgType.Parse(foundParamTypes[i]).Oid; } } transaction.Init(cleanQueryText, ParametersDataTypes); await writer.WriteAsync(messageBuilder.ParseComplete(), token); }
protected override async Task HandleMessage(PgTransaction transaction, MessageBuilder messageBuilder, PipeWriter writer, CancellationToken token) { var serverStore = transaction.DocumentDatabase.ServerStore; var databaseName = transaction.DocumentDatabase.Name; DatabaseRecord databaseRecord; using (serverStore.ContextPool.AllocateOperationContext(out TransactionOperationContext context)) using (context.OpenReadTransaction()) databaseRecord = serverStore.Cluster.ReadDatabase(context, databaseName, out long index); var users = databaseRecord?.Integrations?.PostgreSql?.Authentication?.Users; var user = users?.SingleOrDefault(x => x.Username.Equals(transaction.Username, StringComparison.OrdinalIgnoreCase)); if (user == null) { await writer.WriteAsync(messageBuilder.ErrorResponse(ErrorSeverity, InvalidRoleSpecification, RoleDoesNotExistErrorMessage(transaction.Username)), token); return; } if (Password.Equals(user.Password) == false) { await writer.WriteAsync(messageBuilder.ErrorResponse(ErrorSeverity, InvalidPasswordErrorCode, PasswordAuthFailedErrorMessage(transaction.Username)), token); return; } await writer.WriteAsync(messageBuilder.AuthenticationOk(), token); }
public virtual async Task HandleError(PgErrorException e, PgTransaction transaction, MessageBuilder messageBuilder, PipeWriter writer, CancellationToken token) { // Should assume none of the members are properly initialized await writer.WriteAsync(messageBuilder.ErrorResponse( PgSeverity.Error, e.ErrorCode, e.Message, e.ToString()), token); }
public override async Task Handle(PgTransaction transaction, MessageBuilder messageBuilder, PipeReader reader, PipeWriter writer, CancellationToken token) { if (transaction.State == TransactionState.Failed && this is not Sync) { return; } await base.Handle(transaction, messageBuilder, reader, writer, token); }
protected override async Task HandleMessage(PgTransaction transaction, MessageBuilder messageBuilder, PipeWriter writer, CancellationToken token) { if (transaction.State == TransactionState.Idle) { throw new PgErrorException(PgErrorCodes.NoActiveSqlTransaction, "Execute message was received when no transaction is taking place."); } await transaction.Execute(messageBuilder, writer, token); }
protected override async Task HandleMessage(PgTransaction transaction, MessageBuilder messageBuilder, PipeWriter writer, CancellationToken token) { // Note: It's not an error to close a non existing named portal/statement if (string.IsNullOrEmpty(ObjectName)) { transaction.Close(); } await writer.WriteAsync(messageBuilder.CloseComplete(), token); }
protected override async Task HandleMessage(PgTransaction transaction, MessageBuilder messageBuilder, PipeWriter writer, CancellationToken token) { // TODO: Maybe support multiple SELECT statements in one query - requires parsing the SQL using var query = PgQuery.CreateInstance(QueryString, null, transaction.DocumentDatabase); var schema = await query.Init(true); if (schema.Count != 0) { await writer.WriteAsync(messageBuilder.RowDescription(schema), token); } await query.Execute(messageBuilder, writer, token); await writer.WriteAsync(messageBuilder.ReadyForQuery(transaction.State), token); }
protected override async Task HandleMessage(PgTransaction transaction, MessageBuilder messageBuilder, PipeWriter writer, CancellationToken token) { // TODO: Maybe support named statements/portals if (!string.IsNullOrEmpty(StatementName) || !string.IsNullOrEmpty(PortalName)) { throw new PgErrorException(PgErrorCodes.FeatureNotSupported, "Named statements/portals are not supported."); } if (ParameterFormatCodes.Length != Parameters.Count && ParameterFormatCodes.Length != 0 && ParameterFormatCodes.Length != 1) { throw new PgErrorException(PgErrorCodes.ProtocolViolation, $"Parameter format code amount is {ParameterFormatCodes.Length} when expected " + $"to be 0, 1 or equal to the parameters count {Parameters.Count}."); } transaction.Bind(Parameters, ParameterFormatCodes, ResultColumnFormatCodes); await writer.WriteAsync(messageBuilder.BindComplete(), token); }
protected override async Task HandleMessage(PgTransaction transaction, MessageBuilder messageBuilder, PipeWriter writer, CancellationToken token) { if (transaction.State == TransactionState.Idle) { throw new PgErrorException(PgErrorCodes.NoActiveSqlTransaction, "Describe message was received when no transaction is taking place."); } if (!string.IsNullOrEmpty(ObjectName)) { throw new PgErrorException(PgErrorCodes.FeatureNotSupported, "Describe: Named statements/portals are not supported."); } var(schema, parameterDataTypes) = await transaction.Describe(); if (PgObjectType == PgObjectType.PreparedStatement) { await writer.WriteAsync(messageBuilder.ParameterDescription(parameterDataTypes), token); } var response = schema.Count == 0 ? messageBuilder.NoData() : messageBuilder.RowDescription(schema); await writer.WriteAsync(response, token); }
protected override Task HandleMessage(PgTransaction transaction, MessageBuilder messageBuilder, PipeWriter writer, CancellationToken token) { throw new PgTerminateReceivedException(); }
protected abstract Task HandleMessage(PgTransaction transaction, MessageBuilder messageBuilder, PipeWriter writer, CancellationToken token);
public virtual async Task Handle(PgTransaction transaction, MessageBuilder messageBuilder, PipeReader reader, PipeWriter writer, CancellationToken token) { await HandleMessage(transaction, messageBuilder, writer, token); }
protected override async Task HandleMessage(PgTransaction transaction, MessageBuilder messageBuilder, PipeWriter writer, CancellationToken token) { transaction.Sync(); await writer.WriteAsync(messageBuilder.ReadyForQuery(transaction.State), token); }
protected override async Task HandleMessage(PgTransaction transaction, MessageBuilder messageBuilder, PipeWriter writer, CancellationToken token) { await writer.FlushAsync(token); }
public override async Task HandleError(PgErrorException e, PgTransaction transaction, MessageBuilder messageBuilder, PipeWriter writer, CancellationToken token) { transaction.Fail(); await base.HandleError(e, transaction, messageBuilder, writer, token); }
public override async Task HandleError(PgErrorException e, PgTransaction transaction, MessageBuilder messageBuilder, PipeWriter writer, CancellationToken token) { await base.HandleError(e, transaction, messageBuilder, writer, token); await writer.WriteAsync(messageBuilder.ReadyForQuery(transaction.State), token); }