Beispiel #1
0
 protected internal TypedQuery(
     QueryEnvironment environment, Action <IDbCommand> setupCommand,
     Func <IDataRecord, TRecord> recordConverter)
     : base(environment, setupCommand)
 {
     this.RecordConverter = recordConverter ?? throw new ArgumentNullException(nameof(recordConverter));
 }
Beispiel #2
0
 protected internal UntypedQuery(QueryEnvironment environment, Action <IDbCommand> setupCommand)
 {
     this.Environment        = environment ?? throw new ArgumentNullException(nameof(environment));
     this.SetupCommandAction = setupCommand ?? throw new ArgumentNullException(nameof(setupCommand));
 }
Beispiel #3
0
        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);
            }
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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);
            }
Beispiel #6
0
 public QueryBuilder(QueryEnvironment environment)
 {
     this.Environment = environment;
 }