Cayenne
  1. Cayenne
  2. CAY-1241

Add method to ExpressionFactory to match against the primary key of an object or list of objects

    Details

    • Type: Improvement Improvement
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 3.0M6
    • Fix Version/s: 3.0 beta 1, 3.0
    • Component/s: Core Library
    • Labels:
      None

      Description

      It would be helpful to have a method in ExpressionFactory that build an expression using matchDbExp() to match an object's primary keys.

      This can be helpful in excluding a single or list of known objects from the result of a query.

      1. patch.txt
        2 kB
        Laurentiu Cocanu

        Activity

        Hide
        Laurentiu Cocanu added a comment -

        A possible solution to this issue (also in the attached patch):

        /**

        • Creates an expression that matches the primary key of object in <code>ObjectId</code>'s <code>IdSnapshot</code> for the argument <code>object</code>.
          */
          public static Expression matchObject(CayenneDataObject object) {
          ObjectId obid = object.getObjectId();

        Map<String, Object> objectIdKeys = obid.getIdSnapshot();

        Iterator<String> it = objectIdKeys.keySet().iterator();

        String key = it.next();
        Object value = objectIdKeys.get(key);
        Expression exp = ExpressionFactory.matchDbExp(key, value);

        while(it.hasNext())

        { key = it.next(); value = objectIdKeys.get(key); exp = exp.andExp(ExpressionFactory.matchDbExp(key, value)); }

        return exp;
        }

        /**

        • Creates an expression that matches any of the objects contained in the list <code>objects</code>
          */
          public static Expression matchObjects(List<CayenneDataObject> objects) {
          Iterator<CayenneDataObject> it = objects.iterator();
          Expression exp = matchObject(it.next());
          while(it.hasNext()) { exp = exp.orExp(matchObject(it.next())); }

        return exp;
        }

        Show
        Laurentiu Cocanu added a comment - A possible solution to this issue (also in the attached patch): /** Creates an expression that matches the primary key of object in <code>ObjectId</code>'s <code>IdSnapshot</code> for the argument <code>object</code>. */ public static Expression matchObject(CayenneDataObject object) { ObjectId obid = object.getObjectId(); Map<String, Object> objectIdKeys = obid.getIdSnapshot(); Iterator<String> it = objectIdKeys.keySet().iterator(); String key = it.next(); Object value = objectIdKeys.get(key); Expression exp = ExpressionFactory.matchDbExp(key, value); while(it.hasNext()) { key = it.next(); value = objectIdKeys.get(key); exp = exp.andExp(ExpressionFactory.matchDbExp(key, value)); } return exp; } /** Creates an expression that matches any of the objects contained in the list <code>objects</code> */ public static Expression matchObjects(List<CayenneDataObject> objects) { Iterator<CayenneDataObject> it = objects.iterator(); Expression exp = matchObject(it.next()); while(it.hasNext()) { exp = exp.orExp(matchObject(it.next())); } return exp; }
        Hide
        Andrus Adamchik added a comment -

        The idea is great. A few suggestions on the API to make it look similar to the existing methods, etc.:

        • s/CayenneDataObject/Persistent/
        • s/matchObject/matchExp/
        • s/matchObjects/matchAllExp|matchAnyExp/

        Note to myself or whoever is going to apply this - please write unit tests.

        Show
        Andrus Adamchik added a comment - The idea is great. A few suggestions on the API to make it look similar to the existing methods, etc.: s/CayenneDataObject/Persistent/ s/matchObject/matchExp/ s/matchObjects/matchAllExp|matchAnyExp/ Note to myself or whoever is going to apply this - please write unit tests.
        Hide
        Laurentiu Cocanu added a comment -

        What about this new version?

        /**

        • Creates an expression that matches the primary key of object in <code>ObjectId</code>'s <code>IdSnapshot</code> for the argument <code>object</code>.
          */
          public static Expression matchObject(Persistent object) {
          ObjectId obid = object.getObjectId();
          Map<String, ?> map = obid.getIdSnapshot();

        List<Expression> pairs = new ArrayList<Expression>(map.size());

        for (Map.Entry<String, ?> entry : map.entrySet())

        { Expression exp = expressionOfType(Expression.AND); exp.setOperand(0, new ASTObjPath(entry.getKey())); exp.setOperand(1, wrapPathOperand(entry.getValue())); pairs.add(exp); }

        return joinExp(Expression.AND, pairs);
        }

        /**

        • Creates an expression that matches any of the objects contained in the list <code>objects</code>
          */
          public static Expression matchObjects(List<Persistent> objects) {

        List<Expression> pairs = new ArrayList<Expression>(objects.size());

        for (Persistent object : objects)

        { pairs.add(matchObject(object)); }

        return joinExp(Expression.OR, pairs);
        }

        Soon I'll come with some unit tests too.

        Show
        Laurentiu Cocanu added a comment - What about this new version? /** Creates an expression that matches the primary key of object in <code>ObjectId</code>'s <code>IdSnapshot</code> for the argument <code>object</code>. */ public static Expression matchObject(Persistent object) { ObjectId obid = object.getObjectId(); Map<String, ?> map = obid.getIdSnapshot(); List<Expression> pairs = new ArrayList<Expression>(map.size()); for (Map.Entry<String, ?> entry : map.entrySet()) { Expression exp = expressionOfType(Expression.AND); exp.setOperand(0, new ASTObjPath(entry.getKey())); exp.setOperand(1, wrapPathOperand(entry.getValue())); pairs.add(exp); } return joinExp(Expression.AND, pairs); } /** Creates an expression that matches any of the objects contained in the list <code>objects</code> */ public static Expression matchObjects(List<Persistent> objects) { List<Expression> pairs = new ArrayList<Expression>(objects.size()); for (Persistent object : objects) { pairs.add(matchObject(object)); } return joinExp(Expression.OR, pairs); } Soon I'll come with some unit tests too.
        Hide
        Øyvind Harboe added a comment -

        Could someone provide a pointer to where the ExpressionFactory junit tests are so we can add a test for these new methods?

        Show
        Øyvind Harboe added a comment - Could someone provide a pointer to where the ExpressionFactory junit tests are so we can add a test for these new methods?
        Show
        Andrey Razumovsky added a comment - e.g. here http://svn.apache.org/repos/asf/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/exp/ExpressionFactoryTest.java

          People

          • Assignee:
            Andrey Razumovsky
            Reporter:
            Øyvind Harboe
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development