All Downloads are FREE. Search and download functionalities are using the official Maven repository.

obvious.demo.transaction.TransactionDemo Maven / Gradle / Ivy

The newest version!
/*
* Copyright (c) 2011, INRIA
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in the
*       documentation and/or other materials provided with the distribution.
*     * Neither the name of INRIA nor the names of its contributors may
*       be used to endorse or promote products derived from this software
*       without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package obvious.demo.transaction;

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

import javax.swing.JFrame;

import obvious.ObviousException;
import obvious.ObviousRuntimeException;
import obvious.impl.TupleImpl;
import obvious.jdbc.data.JDBCObviousTable;
import obvious.prefuse.data.PrefuseObviousSchema;
import obvious.data.Schema;
import obvious.data.Table;
import obvious.data.event.TableListener;

/**
 * Transaction demo.
 * @author hemery
 *
 */
public final class TransactionDemo {

  /**
   * Constructor.
   */
  private TransactionDemo() { };

  /**
   * Main method.
   * @param args arguments of the main
   * @throws SQLException if something bad with the DB happens
   * @throws ObviousException if something bad happens
   */
  public static void main(String[] args) throws SQLException, ObviousException {
    JFrame frame = new LoginFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.pack();
    frame.setVisible(true);
  }

  /**
   * Fill table method.
   * @param url url of the database
   * @param user user name
   * @param password password
   * @param driver driver
   * @param tableName table name
   * @param key table primary key
   * @throws ObviousException if something bad happens
   */
  public static void fillTable(String url, String user,
      String password, String driver, String tableName,
      String key) throws ObviousException {
    Schema schema = new PrefuseObviousSchema();
    schema.addColumn("name", String.class, "Doe");
    schema.addColumn("firstName", String.class, "John");


    Table table = new JDBCObviousTable(
        schema, driver, url,
        user, password, tableName, key);
    Connection con = (Connection) table.getUnderlyingImpl(
        java.sql.Connection.class);
    table.addTableListener(new TriggerListener(con));
    table.addRow(new TupleImpl(schema, new Object[] {"avantTransac", "Jan"}));
    table.beginEdit(0);
    final int endLoop = 100;
    for (int i = 0; i < endLoop; i++) {
      table.addRow(new TupleImpl(schema, new Object[] {
          String.valueOf(endLoop + i), "charles"}));
    }
    System.out.println("1");
    table.addRow(new TupleImpl(schema, new Object[] {"dupont", "toto"}));
    System.out.println("2");
    table.addRow(new TupleImpl(schema, new Object[] {"dupont", "toto"}));
    System.out.println("3");
    table.endEdit(0);

    table.addRow(new TupleImpl(schema, new Object[] {"apresTransac", "Jan"}));

  }

  /**
   * A listener.
   * @author Hemery
   *
   */
  public static class TriggerListener implements TableListener {

    /**
     * The number of time beginEdit has been called minus the number of time
     * endEdit has been called.
     */
    private int inhibitNotify = 0;

    /**
     * JDBC connection.
     */
    private Connection con;

    /**
     * Constructor.
     * @param inCon JDBC connection
     */
    public TriggerListener(Connection inCon) {
      this.con = inCon;
      initTrigger();
    }


    /**
     * Inits the trigger.
     */
    private void initTrigger() {
      PreparedStatement cleanTrigger = null;
      PreparedStatement setTrigger = null;
      try {
        cleanTrigger = con.prepareStatement("DROP TRIGGER IF EXISTS sinceDate");
        cleanTrigger.executeUpdate();
        setTrigger = con.prepareStatement(
            "CREATE TRIGGER sinceDate "
            + "BEFORE INSERT ON person "
            + "FOR EACH ROW "
            + "BEGIN  "
            + "SET NEW.SINCE = now(); "
            + "END;");
        setTrigger.executeUpdate();
      } catch (Exception e) {
        throw new ObviousRuntimeException(e);
      } finally {
        try { cleanTrigger.close(); } catch (Exception e) {
          e.printStackTrace();
        }
        try { setTrigger.close(); } catch (Exception e) { e.printStackTrace(); }
      }
    }

    /**
     * Specifies that the following calls to tableChanged belong to the same
     * transaction.
     * 

* This method could be used when a large number of modification * are made on a Table and notifying everything would be time expansive. * For instance, it could disable notifications. The behavior of this * method clearly depends of the purpose of the Obvious implementation. *

* @param context an integer used, if needed, to identify the edition * context of the edit. * */ public void beginEdit(int context) { inhibitNotify++; // Starting the transaction. try { con.setAutoCommit(false); PreparedStatement stmt = con.prepareStatement("START TRANSACTION;"); stmt.executeUpdate(); stmt.close(); } catch (Exception e) { throw new ObviousRuntimeException(e); } } /** * Specifies that the calls to tableChanged belonging to the same * transaction are finished. *

* This function could be used to re-enabled notifications for the current * TableListener if they were disabled. It could also replay a stored * context of the period where the notifications where disabled. The * behavior of this method clearly depends of the purpose of the Obvious * implementation. *

* @param context an integer used, if needed, to retrieve the edition * context It could be used to execute further operations on the table * (for instance replaying sequence of events). * @return true if transaction succeed */ public boolean endEdit(int context) { boolean success = true; inhibitNotify--; if (inhibitNotify <= 0) { inhibitNotify = 0; } try { if (!checkInvariants()) { con.rollback(); success = false; } con.commit(); con.setAutoCommit(true); return success; } catch (Exception e) { throw new ObviousRuntimeException(e); } } /** * Notifies that a table has changed. * @param t the table that has changed * @param start the starting row index of the changed table region * @param end the ending row index of the changed table region * @param col the column that has changed, or * {@link EventConstants#ALL_COLUMNS} if the operation affects all * columns * @param type the type of modification */ public void tableChanged(Table t, int start, int end, int col, int type) { if (inhibitNotify != 0) { return; } else if (type == TableListener.DELETE) { return; } else if (type == TableListener.UPDATE) { return; } else if (type == TableListener.INSERT) { return; } else { return; } } /** * Checks invariant. * @return true if invariant are checked. */ public boolean checkInvariants() { PreparedStatement pStmt = null; ResultSet rslt = null; int minSize = 0; try { String request = "SELECT MIN( CHAR_LENGTH( NAME ) ) FROM person "; pStmt = con.prepareStatement(request); rslt = pStmt.executeQuery(); while (rslt.next()) { minSize = rslt.getInt(1); } } catch (SQLException e) { throw new ObviousRuntimeException(e); } finally { try { pStmt.close(); } catch (Exception e) { e.printStackTrace(); } try { rslt.close(); } catch (Exception e) { e.printStackTrace(); } } return minSize > 2; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy