/*
 * $Header: /esup-portail/injac/applications/SlideServer/Packages/esup-serveur-WebDav-3/update/slide/add-ons/stores/uPortalStore/src/stores/org/apache/slide/store/impl/rdbms/MySql41RDBMSAdapter.java,v 1.1 2005/02/08 09:23:45 tbellemb Exp $
 * $Revision: 1.1 $
 * $Date: 2005/02/08 09:23:45 $
 *
 * ====================================================================
 *
 * Copyright 1999-2003 The Apache Software Foundation 
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
package org.apache.slide.store.impl.rdbms;


import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import org.apache.slide.common.Service;
import org.apache.slide.common.ServiceAccessException;
import org.apache.slide.common.Uri;
import org.apache.slide.content.NodeRevisionDescriptor;
import org.apache.slide.content.NodeRevisionNumber;
import org.apache.slide.store.impl.rdbms.MySqlRDBMSAdapter;
import org.apache.slide.structure.ObjectNode;
import org.apache.slide.structure.ObjectNotFoundException;
import org.apache.slide.util.logger.Logger;

/**
 * Adapter for MySQL 4.1. DELETE semantics are somewhat deviant
 * from MySQL 4.0. Table names should be referred to by their alias.
 * 
 */
public class MySql41RDBMSAdapter extends MySqlRDBMSAdapter {

  /**
   * @param service
   * @param logger
   */
  public MySql41RDBMSAdapter(Service service, Logger logger) {
    super(service, logger);
  }
  
  /*
   * @see org.apache.slide.store.impl.rdbms.RDBMSAdapter#removeObject(
   *  java.sql.Connection, org.apache.slide.common.Uri, 
   *  org.apache.slide.structure.ObjectNode)
   */
  public void removeObject(Connection connection, Uri uri, ObjectNode object)
      throws ServiceAccessException, ObjectNotFoundException {
    PreparedStatement statement = null;
    try {
      clearBinding(connection, uri);
      
      // delete links
      try {
        statement =
          connection.prepareStatement(
          "delete l from LINKS l, URI u where l.URI_ID = u.URI_ID and u.URI_STRING = ?");
        statement.setString(1, uri.toString());
        statement.executeUpdate();
      } finally {
        close(statement);
      }
      // delete version history
      // FIXME: Is this true??? Should the version history be removed if the object is removed???
      try {
        statement =
          connection.prepareStatement(
          "delete vh from VERSION_HISTORY vh, URI u where vh.URI_ID = u.URI_ID and u.URI_STRING = ?");
        statement.setString(1, uri.toString());
        statement.executeUpdate();
      } 
      finally {
        close(statement);
      }
      // delete version
      try {
        statement =
          connection.prepareStatement(
          "delete v from VERSION v, URI u where v.URI_ID = u.URI_ID and u.URI_STRING = ?");
        statement.setString(1, uri.toString());
        statement.executeUpdate();
      } 
      finally {
        close(statement);
      }
      // delete the object itself
      try {
        statement =
          connection.prepareStatement(
          "delete o from OBJECT o, URI u where o.URI_ID = u.URI_ID and u.URI_STRING = ?");
        statement.setString(1, uri.toString());
        statement.executeUpdate();
      } 
      finally {
        close(statement);
      }
      // finally delete the uri
      try {
        statement = connection.prepareStatement("delete from URI where URI_STRING = ?");
        statement.setString(1, uri.toString());
        statement.executeUpdate();
      } 
      finally {
        close(statement);
      }
    } 
    catch (SQLException e) {
      throw createException(e, uri.toString());
    }
  }
  
  /*
   * @see org.apache.slide.store.impl.rdbms.RDBMSAdapter#removeRevisionContent(
   *  java.sql.Connection, org.apache.slide.common.Uri, 
   *  org.apache.slide.content.NodeRevisionDescriptor)
   */
  public void removeRevisionContent(Connection connection, Uri uri,
      NodeRevisionDescriptor revisionDescriptor) throws ServiceAccessException {
    try {
      PreparedStatement statement = null;
      try {
        statement =
          connection.prepareStatement(
          "delete vc from VERSION_CONTENT vc, VERSION_HISTORY vh, URI u where vc.VERSION_ID = vh.VERSION_ID and vh.REVISION_NO = ? and vh.URI_ID=u.URI_ID AND u.URI_STRING=?");
        statement.setString(1, revisionDescriptor.getRevisionNumber().toString());
        statement.setString(2, uri.toString());
        statement.executeUpdate();
      }
      finally {
        close(statement);
      }
    }
    catch (SQLException e) {
      throw createException(e, uri.toString());
    }
  }
  
  /*
   * @see org.apache.slide.store.impl.rdbms.RDBMSAdapter#removeRevisionDescriptor(
   *  java.sql.Connection, org.apache.slide.common.Uri, 
   *  org.apache.slide.content.NodeRevisionNumber)
   */
  public void removeRevisionDescriptor(Connection connection, Uri uri,
      NodeRevisionNumber revisionNumber) throws ServiceAccessException {
    PreparedStatement statement = null;
    try {
      try {
        statement =
          connection.prepareStatement(
          "delete vl from VERSION_LABELS vl, VERSION_HISTORY vh, URI u where vl.VERSION_ID = vh.VERSION_ID and vh.REVISION_NO = ? and vh.URI_ID = u.URI_ID AND u.URI_STRING = ?");
        statement.setString(1, revisionNumber.toString());
        statement.setString(2, uri.toString());
        statement.executeUpdate();
      } 
      finally {
        close(statement);
      }
      try {
        statement =
          connection.prepareStatement(
          "delete p from PROPERTIES p, VERSION_HISTORY vh, URI u where p.VERSION_ID = vh.VERSION_ID and vh.REVISION_NO = ? and vh.URI_ID = u.URI_ID AND u.URI_STRING = ?");
        statement.setString(1, revisionNumber.toString());
        statement.setString(2, uri.toString());
        statement.executeUpdate();
      } 
      finally {
        close(statement);
      }
    } 
    catch (SQLException e) {
      throw createException(e, uri.toString());
    }
  }
  
  /* 
   * @see org.apache.slide.store.impl.rdbms.RDBMSAdapter#removeRevisionDescriptors(
   *  java.sql.Connection, org.apache.slide.common.Uri)
   */
  public void removeRevisionDescriptors(Connection connection, Uri uri)
      throws ServiceAccessException {
    PreparedStatement statement = null;
    try {
      statement =
        connection.prepareStatement(
        "delete vp from VERSION_PREDS vp, VERSION_HISTORY vh, URI u where vp.VERSION_ID = vh.VERSION_ID and vh.URI_ID = u.URI_ID and u.URI_STRING = ?");
      statement.setString(1, uri.toString());
      statement.executeUpdate();
    } catch (SQLException e) {
      throw createException(e, uri.toString());
    } finally {
      close(statement);
    }
  }
  
  /*
   * @see org.apache.slide.store.impl.rdbms.StandardRDBMSAdapter#clearBinding(java.sql.Connection, org.apache.slide.common.Uri)
   */
  protected void clearBinding(Connection connection, Uri uri)
      throws ServiceAccessException, ObjectNotFoundException, SQLException {
    PreparedStatement statement = null;
    
    // clear this uri from having bindings and being bound 
    try {
      statement =
        connection.prepareStatement(
        "delete c from BINDING c, URI u where c.URI_ID = u.URI_ID and u.URI_STRING = ?");
      statement.setString(1, uri.toString());
      statement.executeUpdate();
    } 
    finally {
      close(statement);
    }
    
    try {
      statement =
        connection.prepareStatement(
        "delete c from PARENT_BINDING c, URI u where c.URI_ID = u.URI_ID and u.URI_STRING = ?");
      statement.setString(1, uri.toString());
      statement.executeUpdate();
    } 
    finally {
      close(statement);
    }
  }
}