@Test
  public void testBulkSQLUpdate() throws Exception {
    Owner owner = this.createOwner();

    Content c1 = this.createContent("c1", "content 1", owner);
    Content c2 = this.createContent("c2", "content 2", owner);
    Content c3 = this.createContent("c3", "content 3", owner);

    Map<Object, Object> values = new HashMap<Object, Object>();
    values.put("content 1", "update 1");
    values.put("content 2", "update 2");
    values.put("content ?", "should not exist");

    int result = this.testContentCurator.bulkSQLUpdate(Content.DB_TABLE, "name", values, null);

    // Note:
    // This looks like it should be 2, and technically that's what's happening here, but with
    // the way the bulk updater works, even the non-matching columns are getting updated to
    // themselves.
    assertEquals(3, result);

    testContentCurator.refresh(c1, c2, c3);

    assertEquals("update 1", c1.getName());
    assertEquals("update 2", c2.getName());
    assertEquals("content 3", c3.getName());
  }
  @Test
  public void testBulkSQLUpdateWithMultipleCriteria() {
    Owner owner = this.createOwner();

    Content c1 = this.createContent("c1", "content 1", owner);
    Content c2 = this.createContent("c2", "content 2", owner);
    Content c3 = this.createContent("c3", "content 3", owner);

    Map<Object, Object> values = new HashMap<Object, Object>();
    values.put("content 1", "update 1");
    values.put("content 2", "update 2");
    values.put("content ?", "should not exist");

    Map<String, Object> criteria = new HashMap<String, Object>();
    criteria.put("name", values.keySet());
    criteria.put("content_id", "c2");

    int result = this.testContentCurator.bulkSQLUpdate(Content.DB_TABLE, "name", values, criteria);

    // Unlike the base test where the result count is 3, this filters by only the values we
    // intend to update, so it should be 1.
    assertEquals(1, result);

    testContentCurator.refresh(c1, c2, c3);

    assertEquals("content 1", c1.getName());
    assertEquals("update 2", c2.getName());
    assertEquals("content 3", c3.getName());
  }
  @Test
  @Parameters(method = "largeValueSetSizes")
  public void testBulkSQLUpdateWithLargeValueSets(int count, int skip) {
    Owner owner = this.createOwner();

    for (int i = 1; i <= count; ++i) {
      this.createContent("c" + i, "content-" + i, owner);
    }

    Map<Object, Object> values = new LinkedHashMap<Object, Object>();

    for (int i = 1; i <= count; ++i) {
      // We want every odd value to be unaffected, but we still want a fake update entry
      // for the query
      values.put("content-" + (i % 2 == skip ? i : "X" + i), "update-" + i);
    }

    int result = this.testContentCurator.bulkSQLUpdate(Content.DB_TABLE, "name", values, null);
    assertEquals(count, result);

    testContentCurator.clear();

    for (int i = 1; i <= count; ++i) {
      Content content = this.ownerContentCurator.getContentById(owner, "c" + i);

      if (i % 2 == skip) {
        assertEquals("update-" + i, content.getName());
      } else {
        assertEquals("content-" + i, content.getName());
      }
    }
  }
  @Test
  public void testBulkSQLUpdateWithEmptyValues() throws Exception {
    Owner owner = this.createOwner();

    Content c1 = this.createContent("c1", "content 1", owner);
    Content c2 = this.createContent("c2", "content 2", owner);
    Content c3 = this.createContent("c3", "content 3", owner);

    Map<Object, Object> values = new HashMap<Object, Object>();

    int result = this.testContentCurator.bulkSQLUpdate(Content.DB_TABLE, "name", values, null);

    assertEquals(0, result);

    testContentCurator.refresh(c1, c2, c3);

    assertEquals("content 1", c1.getName());
    assertEquals("content 2", c2.getName());
    assertEquals("content 3", c3.getName());
  }
  @Test
  @Parameters(method = "largeValueSetAndCriteriaSizes")
  public void testBulkSQLUpdateWithLargeValueSetAndCriteriaList(
      int valueCount, int criteriaListSize) {
    Owner owner = this.createOwner();

    Map<Object, Object> values = new HashMap<Object, Object>();

    for (int i = 1; i <= valueCount; ++i) {
      this.createContent("c" + i, "content-" + i, owner);

      // We want every odd value to be unaffected, but we still want a fake update entry
      // for the query
      values.put("content-" + (i % 2 == 0 ? i : "X" + i), "update-" + i);
    }

    Map<String, Object> criteria = new HashMap<String, Object>();
    List<String> valueList = new LinkedList<String>();
    criteria.put("name", valueList);

    for (int i = 1; i <= criteriaListSize; ++i) {
      valueList.add("content-" + (i % 2 == 0 ? i : "X" + i));
    }

    int result = this.testContentCurator.bulkSQLUpdate(Content.DB_TABLE, "name", values, criteria);
    assertEquals(valueCount / 2, result);

    testContentCurator.clear();

    for (int i = 1; i <= valueCount; ++i) {
      Content content = this.ownerContentCurator.getContentById(owner, "c" + i);

      if (i % 2 == 0) {
        assertEquals("update-" + i, content.getName());
      } else {
        assertEquals("content-" + i, content.getName());
      }
    }
  }