public virtual void AddConditions(IDynamoCommonQuery dynamoQ, IDataQuery q) { if (q.Conditions.Count == 0) { return; } var dbConditions = new List <DataConditionExpression>(); var args = new Dictionary <string, object>(); var sb = StringBuilderCache.Allocate(); var isMultipleWithOrTerm = q.Conditions.Any(x => x.Term == QueryTerm.Or) && q.Conditions.Count > 1; foreach (var condition in q.Conditions) { var fmt = DynamoQueryConditions.GetExpressionFormat(condition.QueryCondition.Alias); var multiFmt = DynamoQueryConditions.GetMultiExpressionFormat(condition.QueryCondition.Alias); if (fmt == null && multiFmt == null && isMultipleWithOrTerm) { throw new NotSupportedException( $"DynamoDB does not support {condition.QueryCondition.Alias} filter with multiple OR queries"); } if (fmt == null && multiFmt == null) { continue; } dbConditions.Add(condition); if (sb.Length > 0) { sb.Append(condition.Term == QueryTerm.Or ? " OR " : " AND "); } if (fmt != null) { var pId = "p" + args.Count; args[pId] = condition.Value; sb.Append(string.Format(fmt, dynamoQ.GetFieldLabel(condition.Field.Name), ":" + pId)); } else { var multiExpr = GetMultiConditionExpression(dynamoQ, condition, multiFmt, args); sb.Append(multiExpr); } } var filter = StringBuilderCache.Retrieve(sb); if (filter.Length > 0) { dynamoQ.AddFilter(filter, args); } q.Conditions.RemoveAll(dbConditions.Contains); }
public override IEnumerable <T> GetDataSource(IDataQuery q) { if (cache != null) { return(cache); } var keyCondition = q.Conditions.FirstOrDefault(x => x.Field != null && x.Field.Name.EqualsIgnoreCase(modelDef.HashKey.Name) && x.QueryCondition.Alias == ConditionAlias.Equals); if (keyCondition == null) { var scanExpr = CreateScanExpresion(); AddConditions(scanExpr, q); return(cache = GetResults(scanExpr, q.Offset, q.Rows)); } var rangeCondition = modelDef.RangeKey != null ? q.Conditions.FirstOrDefault(x => x.Field != null && x.Field.Name.EqualsIgnoreCase(modelDef.RangeKey.Name)) : null; var rangeField = rangeCondition != null ? modelDef.RangeKey.Name : null; var queryExpr = CreateQueryExpression(); var args = new Dictionary <string, object>(); var hashFmt = DynamoQueryConditions.GetExpressionFormat(keyCondition.QueryCondition.Alias); var dynamoFmt = string.Format(hashFmt, queryExpr.GetFieldLabel(modelDef.HashKey.Name), ":k0"); args["k0"] = keyCondition.Value; if (rangeCondition == null) { foreach (var index in modelDef.LocalIndexes) { rangeCondition = q.Conditions.FirstOrDefault(x => x.Field != null && x.Field.Name.EqualsIgnoreCase(index.RangeKey.Name)); if (rangeCondition != null) { rangeField = index.RangeKey.Name; queryExpr.IndexName = index.Name; break; } } } if (rangeCondition != null) { var rangeFmt = DynamoQueryConditions.GetExpressionFormat(rangeCondition.QueryCondition.Alias); if (rangeFmt != null) { dynamoFmt += " AND " + string.Format(hashFmt, queryExpr.GetFieldLabel(rangeField), ":k1"); args["k1"] = rangeCondition.Value; } else { var multiFmt = DynamoQueryConditions.GetMultiExpressionFormat(rangeCondition.QueryCondition.Alias); if (multiFmt != null) { var multiExpr = GetMultiConditionExpression(queryExpr, rangeCondition, multiFmt, args, argPrefix: "k"); dynamoFmt += " AND " + multiExpr; } } } queryExpr.KeyCondition(dynamoFmt, args); q.Conditions.RemoveAll(x => x == keyCondition || x == rangeCondition); AddConditions(queryExpr, q); return(cache = GetResults(queryExpr, q.Offset, q.Rows)); }