QueryConditionList and QueryNotConditionList to have the same abstract base class BaseQueryConditionList or implement IQueryConditionList

XMLWordPrintableJSON

    • Type: Improvement
    • Resolution: Done
    • Priority: Minor - P4
    • None
    • Affects Version/s: 1.1
    • Component/s: None
    • None
    • None
    • Minor Change
    • None
    • None
    • None
    • None
    • None
    • None

      QueryConditionList and QueryNotConditionList have a bunch of similar methods – All, ElemMatch, Exists, GT, GTE, In, LT, LTE, Mod, NE, NotIn, Size, Type. An application would like to build queries dynamically chaining them, say, in this way:

      BaseQueryConditionList GT(BaseQueryConditionList conditionList, BsonValue value)

      { return conditionList.GT(value); }

      This scenario is not possible now. The application has to (just for example):

      QueryComplete GT(QueryComplete conditionList, BsonValue value)

      { if (conditionList is QueryConditionList) return ((QueryConditionList)conditionList).GT(value); else if (conditionList is QueryNotConditionList) return ((QueryNotConditionList)conditionList).GT(value); else throw new InvalidArgumentException(); }

      This is equally awkward to write and not effective at runtime. The proposal is to derive these two classes from the same abstract class or introduce a common interface and make these classes to implement it.

      Related question about QueryConditionList and QueryNotConditionList. QueryConditionList has Within* methods, QueryNotConditionList does not. Is this difference intentional?

      ==

      Details and potential drawbacks. If we go with, say, the abstract base class then common methods should change their return values to that base class. That is:

      QueryConditionList All(BsonArray values) // QueryConditionList
      QueryNotConditionList All(BsonArray values) // QueryNotConditionList

      Should be:

      BaseQueryConditionList All(BsonArray values) // QueryConditionList
      BaseQueryConditionList All(BsonArray values) // QueryNotConditionList

      Is this going to be troublesome? Of course it is breaking (but it should not be difficult to adopt). As for the other drawbacks, I cannot see them (but I see many advantages). What do you think, who reads this?

      ==

      As far as I can see, many methods in these two classes have duplicated code. A base class could have them implemented in one place (virtual methods perhaps would not even be needed).
      Example:

      // MongoDB.Driver.Builders.QueryConditionList
      public QueryConditionList ElemMatch(IMongoQuery query)
      {
      this.conditions.Add("$elemMatch", query.ToBsonDocument<IMongoQuery>());
      return this;
      }
      // MongoDB.Driver.Builders.QueryNotConditionList
      public QueryNotConditionList ElemMatch(IMongoQuery query)
      {
      this.conditions.Add("$elemMatch", query.ToBsonDocument<IMongoQuery>());
      return this;
      }

      and etc.
      Instead, it could be the only method of BaseQueryConditionList:

      // MongoDB.Driver.Builders.BaseQueryConditionList
      public BaseQueryConditionList ElemMatch(IMongoQuery query)
      {
      this.conditions.Add("$elemMatch", query.ToBsonDocument<IMongoQuery>());
      return this;
      }

            Assignee:
            Robert Stam
            Reporter:
            Roman Kuzmin
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: