@Test
 public void testCreateSQLQuery() {
   assertEquals(
       "select distinct doc.space, doc.name from XWikiDocument as doc",
       store.createSQLQuery("select distinct doc.space, doc.name", ""));
   assertEquals(
       "select distinct doc.space, doc.name, doc.date from XWikiDocument as doc "
           + "where 1=1 order by doc.date desc",
       store.createSQLQuery(
           "select distinct doc.space, doc.name", "where 1=1 order by doc.date desc"));
 }
  /**
   * Save an XClass that has a Number property whose type has changed and there is an instance of
   * this class that has no value set for that Number property.
   *
   * @see <a href="http://jira.xwiki.org/browse/XWIKI-8649">XWIKI-8649: Error when changing the
   *     number type of a field from an application</a>
   */
  @Test
  public void saveXWikiDocWithXClassAndNumberPropertyTypeChange() throws Exception {
    // The number property whose type has changed from Double to Integer.
    IntegerProperty integerProperty = mock(IntegerProperty.class);
    NumberClass numberField = mock(NumberClass.class);
    when(numberField.newProperty()).thenReturn(integerProperty);
    when(numberField.getNumberType()).thenReturn("integer");

    // The XClass that has only the number property.
    List<NumberClass> fieldList = Collections.singletonList(numberField);
    BaseClass baseClass = mock(BaseClass.class);
    when(baseClass.getFieldList()).thenReturn(fieldList);

    // The document that is being saved.
    XWikiDocument document = mock(XWikiDocument.class);
    when(document.getXClass()).thenReturn(baseClass);

    // Assume there are two objects of the XClass previously defined: one that has no value set for
    // the number
    // property and one that has a value.
    Query query = mock(Query.class);
    DoubleProperty doubleProperty = mock(DoubleProperty.class);
    when(doubleProperty.getValue()).thenReturn(3.5);
    DoubleProperty doublePropertyUnset = mock(DoubleProperty.class, "unset");
    List<DoubleProperty> properties = Arrays.asList(doublePropertyUnset, doubleProperty);
    when(session.createQuery(anyString())).thenReturn(query);
    when(query.setString(anyInt(), anyString())).thenReturn(query);
    when(query.list()).thenReturn(properties);

    store.saveXWikiDoc(document, context);

    // 4 times, for each number type (Integer, Long, Double and Float).
    verify(integerProperty, times(4)).setValue(3);
  }
  @Test
  public void executeDeleteWikiStatementForPostgreSQLWhenInSchemaMode() throws Exception {
    HibernateSessionFactory sessionFactory = mocker.getInstance(HibernateSessionFactory.class);
    when(sessionFactory.getConfiguration().getProperty("xwiki.virtual_mode")).thenReturn("schema");

    Statement statement = mock(Statement.class);
    DatabaseProduct databaseProduct = DatabaseProduct.POSTGRESQL;

    store.executeDeleteWikiStatement(statement, databaseProduct, "schema");

    verify(statement).execute("DROP SCHEMA schema CASCADE");
  }
  @Test
  public void executeDeleteWikiStatementForPostgreSQLWhenInDatabaseMode() throws Exception {
    HibernateSessionFactory sessionFactory = mocker.getInstance(HibernateSessionFactory.class);
    when(sessionFactory.getConfiguration().getProperty("xwiki.virtual_mode"))
        .thenReturn("database");

    Statement statement = mock(Statement.class);
    DatabaseProduct databaseProduct = DatabaseProduct.POSTGRESQL;

    store.executeDeleteWikiStatement(statement, databaseProduct, "schema");

    verify(mocker.getMockedLogger())
        .warn("Subwiki deletion not yet supported in Database mode for PostgreSQL");
    verify(statement, never()).execute(any(String.class));
  }
 @Test
 public void testGetColumnsForSelectStatement() throws Exception {
   assertEquals(
       ", doc.date", store.getColumnsForSelectStatement("where 1=1 order by doc.date desc"));
   assertEquals(
       ", doc.date", store.getColumnsForSelectStatement("where 1=1 order by doc.date asc"));
   assertEquals(", doc.date", store.getColumnsForSelectStatement("where 1=1 order by doc.date"));
   assertEquals(
       ", description", store.getColumnsForSelectStatement("where 1=1 order by description desc"));
   assertEquals(
       ", ascendent", store.getColumnsForSelectStatement("where 1=1 order by ascendent asc"));
   assertEquals(
       ", doc.date, doc.name",
       store.getColumnsForSelectStatement("where 1=1 order by doc.date, doc.name"));
   assertEquals(
       ", doc.date, doc.name",
       store.getColumnsForSelectStatement("where 1=1 order by doc.date ASC, doc.name DESC"));
   assertEquals(
       "", store.getColumnsForSelectStatement(", BaseObject as obj where obj.name=doc.fullName"));
 }
  @Test
  public void testEndTransactionWhenSQLBatchUpdateExceptionThrown() throws Exception {
    SQLException sqlException2 = new SQLException("sqlexception2");
    sqlException2.setNextException(new SQLException("nextexception2"));

    SQLException sqlException1 = new SQLException("sqlexception1");
    sqlException1.initCause(sqlException2);
    sqlException1.setNextException(new SQLException("nextexception1"));

    // Assume the transaction is already created.
    when(context.get("hibtransaction")).thenReturn(transaction);
    doThrow(new HibernateException("exception1", sqlException1)).when(transaction).commit();

    try {
      store.endTransaction(context, true);
      fail("Should have thrown an exception here");
    } catch (HibernateException e) {
      assertEquals(
          "Failed to commit or rollback transaction. Root cause [\n"
              + "SQL next exception = [java.sql.SQLException: nextexception1]\n"
              + "SQL next exception = [java.sql.SQLException: nextexception2]]",
          e.getMessage());
    }
  }