internal OracleParameter GetParameter(string name) { try { var param = _bindParameters[name]; return param.CreateOracleParameter(); } catch (KeyNotFoundException ex) { if (this.TolerateMissingParams) { // Create a dummy parameter with null value now var param = new BindParameter(); param.ParameterName = name; param.Size = 255; param.OracleDbType = OracleDbType.Varchar2; param.Direction = ParameterDirection.Input; _bindParameters.Add(param); return param.CreateOracleParameter(); } throw new KeyNotFoundException(string.Format("Parameter {0} has not been bound", name), ex); } }
private async Task QueryCore( bool async, string queryText, PostgresCommand command, CancellationToken cancellationToken) { BindParameter[] parameters = null; var parameterCount = command.Parameters.Count; try { if (parameterCount > 0) { parameters = ArrayPool <BindParameter> .GetArray(parameterCount); var encoding = ClientState.ClientEncoding; for (var i = 0; i < parameterCount; ++i) { var param = command.Parameters[i].Value; if (param == null) { parameters[i] = new BindParameter { ParameterByteCount = 0, Parameters = EmptyArray <byte> .Value }; continue; } // TODO: This allocation fest is terrible. Make this // write directly to the memorystream instead of having // intermittent buffers for everything. var paramString = param.ToString(); var maxBytes = encoding .GetMaxByteCount(paramString.Length); var paramBuffer = ArrayPool <byte> .GetArray(maxBytes); var actualBytes = encoding.GetBytes( paramString, 0, paramString.Length, paramBuffer, 0); parameters[i] = new BindParameter { ParameterByteCount = actualBytes, Parameters = paramBuffer }; } } WriteMessage(new ParseMessage { Query = queryText }); WriteMessage(new BindMessage { PreparedStatementName = "", ResultColumnFormatCodeCount = 1, ParameterCount = (short)parameterCount, Parameters = parameters, ResultColumnFormatCodes = QueryResultFormat == PostgresFormatCode.Binary ? _binaryFormatCode : _textFormatCode }); WriteMessage(new DescribeMessage { StatementTargetType = StatementTargetType.Portal }); WriteMessage(new ExecuteMessage { }); WriteMessage(new SyncMessage { }); await FlushWrites(async, cancellationToken) .ConfigureAwait(false); } finally { if (parameters != null) { for (var i = 0; i < parameterCount; ++i) { var param = parameters[i].Parameters; ArrayPool.Free(ref param); } } } }
/// <summary> /// Returns the parameter of the passed name. If it does not exist, creates the parameter /// </summary> /// <param name="field">Parameter name</param> /// <param name="dir">Bind Direction</param> /// <returns>Returns existing or newly created bind parameter</returns> /// <remarks> /// If it becomes necessary to create the parameter, only the direction and name are set. All other properties must be set by the caller. /// For existing parameters, the passed direction is merged with the existing direction. Thus if an input parameter is found, and the passed /// direction is output, then this parameter now becomes input/output. /// </remarks> internal BindParameter GetBindParameter(string field, ParameterDirection dir) { BindParameter param; if (_bindParameters.Contains(field)) { param = _bindParameters[field]; } else { param = new BindParameter(); param.ParameterName = field; param.Direction = dir; _bindParameters.Add(param); } if (dir == ParameterDirection.ReturnValue || dir == ParameterDirection.InputOutput) { param.Direction = dir; } else if (param.Direction != dir) { switch (param.Direction) { case ParameterDirection.Input: if (dir == ParameterDirection.Output) { param.Direction = ParameterDirection.InputOutput; } break; case ParameterDirection.InputOutput: break; case ParameterDirection.Output: if (dir == ParameterDirection.Input) { param.Direction = ParameterDirection.InputOutput; } break; case ParameterDirection.ReturnValue: throw new NotSupportedException(); default: throw new NotImplementedException(); } } return param; }