protected internal TypedQuery( QueryEnvironment environment, Action <IDbCommand> setupCommand, Func <IDataRecord, TRecord> recordConverter) : base(environment, setupCommand) { this.RecordConverter = recordConverter ?? throw new ArgumentNullException(nameof(recordConverter)); }
protected internal UntypedQuery(QueryEnvironment environment, Action <IDbCommand> setupCommand) { this.Environment = environment ?? throw new ArgumentNullException(nameof(environment)); this.SetupCommandAction = setupCommand ?? throw new ArgumentNullException(nameof(setupCommand)); }
internal static void SetQueryToDbCommand(FormattableString query, IDbCommand command, QueryEnvironment environment) { Check.NotNullOrEmpty(query, nameof(query)); Check.NotNull(command, nameof(command)); Check.NotNull(environment, nameof(environment)); var formatStr = query.Format; if (query.ArgumentCount == 0) { command.CommandText = UnescapeBrackets(formatStr, environment.StringBuilderPool); return; } var sb = environment.StringBuilderPool?.Get() ?? new StringBuilder(); try { object?[] arguments = query.GetArguments(); var lastIndex = 0; var parameterCount = 0; for (var i = 0; i < formatStr.Length;) { var c = formatStr[i]; switch (c) { case '{': if (i + 1 >= formatStr.Length) { throw new FormatException("Unexpected EOS."); } if (formatStr[i + 1] == '{') { // {{ sb.Append(formatStr, lastIndex, i + 1 - lastIndex); lastIndex = i += 2; } else { sb.Append(formatStr, lastIndex, i - lastIndex); var formatItemMatch = s_formatItemPattern.Match(formatStr, i + 1, formatStr.Length - i - 1); if (!formatItemMatch.Success) { throw new FormatException("Invalid format item."); } var argIndex = int.Parse(formatItemMatch.Groups[1].Value, CultureInfo.InvariantCulture); if ((uint)argIndex >= (uint)arguments.Length) { throw new FormatException($"Invalid format index {argIndex}."); } var arg = arguments[argIndex]; switch (arg) { case TableReference tableRef: if (formatItemMatch.Groups[3].Success) { throw new FormatException("Cannot specify alignment to a table reference."); } WriteTableReference(tableRef, formatItemMatch.Groups[4].Value, sb, environment); break; case ColumnReference columnRef: if (formatItemMatch.Groups[3].Success) { throw new FormatException("Cannot specify alignment to a column reference."); } WriteColumnReference(columnRef, formatItemMatch.Groups[4].Value, sb, environment); break; case RawQuery rawQuery: sb.Append(rawQuery.Content); break; default: // TODO: Support IEnumerable if (formatItemMatch.Groups[2].Length > 0) { // If format is specified, the argument will become a formatted string. var itemFormat = formatItemMatch.Groups[2].Value; arg = string.Format(environment.FormatProvider, "{0" + itemFormat + "}", arg); } // Add IDbDataParameter to `command` var parameter = command.CreateParameter(); parameter.ParameterName = environment.SqlGenerator.AddParameterToQuery(parameterCount++, sb); environment.ValueConverter.ConvertTo(arg, parameter); command.Parameters.Add(parameter); break; } lastIndex = i = formatItemMatch.Index + formatItemMatch.Length; } break; case '}': // }} if (i + 1 >= formatStr.Length || formatStr[i + 1] != '}') { throw new FormatException(@"""}}"" is expected."); } sb.Append(formatStr, lastIndex, i + 1 - lastIndex); lastIndex = i += 2; break; default: i++; break; } } sb.Append(formatStr, lastIndex, formatStr.Length - lastIndex); command.CommandText = sb.ToString(); } finally { environment.StringBuilderPool?.Return(sb); } }
internal static FormattableString ExtractFormattableString(LambdaExpression lambda, QueryEnvironment environment) { Check.NotNull(lambda, nameof(lambda)); Check.NotNull(environment, nameof(environment)); var tableDictionary = new Dictionary <ParameterExpression, TableReference>(); foreach (var parameter in lambda.Parameters) { var tableMapper = environment.TableMapperProvider.GetTableByType(parameter.Type); if (tableMapper == null) { throw new ArgumentException($"A parameter `{parameter}` cannot be resolved as a table.", nameof(lambda)); } tableDictionary.Add(parameter, new TableReference(tableMapper)); } var rewritedExpr = new RewriteTableReferenceVisitor(tableDictionary).Visit(lambda.Body); var fs = Expression.Lambda <Func <FormattableString> >(rewritedExpr).Compile()(); if (fs == null) { throw new InvalidOperationException("The lambda expression returned null."); } ResolveTableAliases(fs); return(fs); }
private static void WriteTableReference(TableReference tableRef, string format, StringBuilder destination, QueryEnvironment environment) { if (string.IsNullOrEmpty(format)) { // Write table name or alias destination.Append(GetEscapedTableNameOrAlias(tableRef, environment)); } else if (format == "*") { // Write all columns of the table var alias = GetEscapedTableNameOrAlias(tableRef, environment); var first = true; foreach (var columnName in tableRef.TableMapper.GetColumnsNamesForSelect()) { if (first) { first = false; } else { destination.Append(", "); } destination.Append(alias).Append('.'); environment.SqlGenerator.EscapeIdentifier(columnName, destination); } } else if (s_tableAliasFormatStringPattern.Match(format) is Match aliasFormatMatch && aliasFormatMatch.Success) { // AS alias environment.SqlGenerator.EscapeIdentifier(tableRef.TableMapper.GetTableName(), destination); destination.Append(' ').Append(aliasFormatMatch.Groups[1].Value); }
public QueryBuilder(QueryEnvironment environment) { this.Environment = environment; }